//========================== // V_FindIntermisionSpot //========================== cl_entity_t *V_FindIntermisionSpot( struct ref_params_s *pparams ) { int spotindex[MAX_SPOTS]; cl_entity_t *ent; // found intermission point int i, j; for( i = 0, j = 0; i < pparams->max_entities; i++ ) { ent = GET_ENTITY( i ); if( ent && ent->curstate.eflags & EFLAG_INTERMISSION ) { spotindex[j] = ent->index; if( ++j >= MAX_SPOTS ) break; // full } } // ok, we have list of intermission spots if( j != 0 ) { if( j > 1 ) j = RANDOM_LONG( 0, j ); ent = GET_ENTITY( spotindex[j-1] ); } else { // defaulted to player view ent = gEngfuncs.GetLocalPlayer(); } return ent; }
//========================== // V_CalcViewRoll //========================== void V_CalcViewRoll( struct ref_params_s *pparams ) { float sign, side, value; Vector right; cl_entity_t *viewentity = GET_ENTITY( pparams->viewentity ); if( !viewentity ) return; AngleVectors( viewentity->angles, NULL, right, NULL ); side = DotProduct( pparams->simvel, right ); sign = side < 0 ? -1 : 1; side = fabs( side ); value = pparams->movevars->rollangle; if( side < pparams->movevars->rollspeed ) side = side * value / pparams->movevars->rollspeed; else side = value; side = side * sign; pparams->viewangles[ROLL] += side; if( pparams->health <= 0 && ( pparams->viewheight[2] != 0 )) { // only roll the view if the player is dead and the viewheight[2] is nonzero // this is so deadcam in multiplayer will work. pparams->viewangles[ROLL] = 80; // dead view angle return; } }
/* ================ R_RenderScene RI.refdef must be set before the first call fast version of R_RenderScene: no colors, no texcords etc ================ */ void R_RenderShadowScene( const ref_params_t *pparams, const plight_t *pl ) { // set the worldmodel worldmodel = GET_ENTITY( 0 )->model; if( !worldmodel ) { ALERT( at_error, "R_RenderShadowView: NULL worldmodel\n" ); return; } RI.refdef = *pparams; r_stats.num_passes++; r_stats.num_drawed_ents = 0; tr.framecount++; R_ShadowPassSetupFrame( pl ); R_ShadowPassSetupGL( pl ); pglClear( GL_DEPTH_BUFFER_BIT ); R_MarkLeaves(); R_ShadowPassDrawWorld( pl ); R_DrawGrass( GRASS_PASS_SHADOW ); R_ShadowPassDrawSolidEntities( pl ); R_ShadowPassEndGL(); }
//========================== // V_CalcWaterLevel //========================== float V_CalcWaterLevel( struct ref_params_s *pparams ) { float waterOffset = 0.0f; if( pparams->waterlevel >= 2 ) { int waterEntity = WATER_ENTITY( pparams->simorg ); float waterDist = cl_waterdist->value; if( waterEntity >= 0 && waterEntity < pparams->max_entities ) { cl_entity_t *pwater = GET_ENTITY( waterEntity ); if( pwater && ( pwater->model != NULL )) waterDist += ( pwater->curstate.scale * 16.0f ); } Vector point = pparams->vieworg; // eyes are above water, make sure we're above the waves if( pparams->waterlevel == 2 ) { point.z -= waterDist; for( int i = 0; i < waterDist; i++ ) { int contents = POINT_CONTENTS( point ); if( contents > CONTENTS_WATER ) break; point.z += 1; } waterOffset = (point.z + waterDist) - pparams->vieworg[2]; } else { // eyes are under water. Make sure we're far enough under point[2] += waterDist; for( int i = 0; i < waterDist; i++ ) { int contents = POINT_CONTENTS( point ); if( contents <= CONTENTS_WATER ) break; point.z -= 1; } waterOffset = (point.z - waterDist) - pparams->vieworg[2]; } } return waterOffset; }
/* ============= R_ShadowPassDrawWorld ============= */ static void R_ShadowPassDrawWorld( const plight_t *pl ) { if( pl->flags & CF_NOWORLD_PROJECTION ) return; // no worldlight, no worldshadows // restore worldmodel RI.currententity = GET_ENTITY( 0 ); RI.currentmodel = RI.currententity->model; tr.modelorg = RI.vieworg; R_LoadIdentity(); R_RecursiveLightNode( worldmodel->nodes, pl->frustum, pl->clipflags ); R_LightStaticBrushes( pl ); R_DrawShadowChains(); }
//========================== // V_GetChaseOrigin //========================== void V_GetChaseOrigin( const Vector &angles, const Vector &origin, float distance, Vector &returnvec ) { Vector vecStart, vecEnd; pmtrace_t *trace; int maxLoops = 8; Vector forward, right, up; // trace back from the target using the player's view angles AngleVectors( angles, forward, right, up ); forward = -forward; vecStart = origin; vecEnd = vecStart + forward * distance; int ignoreent = -1; // first, ignore no entity cl_entity_t *ent = NULL; while( maxLoops > 0 ) { trace = gEngfuncs.PM_TraceLine( vecStart, vecEnd, PM_TRACELINE_PHYSENTSONLY, 2, ignoreent ); if( trace->ent <= 0 ) break; // we hit the world or nothing, stop trace ent = GET_ENTITY( PM_GetPhysEntInfo( trace->ent )); if( ent == NULL ) break; // hit non-player solid BSP, stop here if( ent->curstate.solid == SOLID_BSP && !ent->player ) break; // if close enought to end pos, stop, otherwise continue trace if(( vecEnd - trace->endpos ).Length() < 1.0f ) { break; } else { ignoreent = trace->ent; // ignore last hit entity vecStart = trace->endpos; } maxLoops--; } returnvec = trace->endpos + trace->plane.normal * 8; }
void gravity_system_update(GravitySystem* self) { GET_SYSTEM_COMPONENTS(self); for (u32 i = 0; i < components->count; ++i) { Entity entity = GET_ENTITY(i); GravityComponent* gravity = (GravityComponent*)GET_SYSTEM_COMPONENT(i); MovementComponent* movement = (MovementComponent*)GET_COMPONENT(entity, COMPONENT_MOVEMENT); REQUIRED_COMPONENTS(gravity, movement); Vec2 gravScale; vec2_copy_to(&gravity->gravAccel, &gravScale); vec2_scale(&gravScale, globals.time.delta, &gravScale); vec2_add(&movement->velocity, &gravScale, &movement->velocity); //printf("%f\n", movement->velocity.y); } }
////////////////////////////////////////////////////////////////////////// // IsMountedWeaponUsableWithTarget // A piece of game-code moved from CryAction when scriptbind_AI moved to the AI system ////////////////////////////////////////////////////////////////////////// int CScriptBind_Game::IsMountedWeaponUsableWithTarget(IFunctionHandler *pH) { int paramCount = pH->GetParamCount(); if(paramCount<2) { GameWarning("%s: too few parameters.", __FUNCTION__); return pH->EndFunction(); } GET_ENTITY(1); if(!pEntity) { GameWarning("%s: wrong entity id in parameter 1.", __FUNCTION__); return pH->EndFunction(); } IAIObject* pAI = pEntity->GetAI(); if (!pAI) { GameWarning("%s: Entity '%s' does not have AI.",__FUNCTION__, pEntity->GetName()); return pH->EndFunction(); } EntityId itemEntityId; ScriptHandle hdl2; if(!pH->GetParam(2,hdl2)) { GameWarning("%s: wrong parameter 2 format.", __FUNCTION__); return pH->EndFunction(); } itemEntityId = (EntityId)hdl2.n; if (!itemEntityId) { GameWarning("%s: wrong entity id in parameter 2.", __FUNCTION__); return pH->EndFunction(); } IGameFramework *pGameFramework = gEnv->pGame->GetIGameFramework(); IItem* pItem = pGameFramework->GetIItemSystem()->GetItem(itemEntityId); if (!pItem) { //gEnv->pAISystem->Warning("<CScriptBind> ", "entity in parameter 2 is not an item/weapon"); GameWarning("%s: entity in parameter 2 is not an item/weapon.", __FUNCTION__); return pH->EndFunction(); } float minDist = 7; bool bSkipTargetCheck = false; Vec3 targetPos(ZERO); if(paramCount > 2) { for(int i=3;i <= paramCount ; i++) { if(pH->GetParamType(i) == svtBool) pH->GetParam(i,bSkipTargetCheck); else if(pH->GetParamType(i) == svtNumber) pH->GetParam(i,minDist); else if(pH->GetParamType(i) == svtObject) pH->GetParam(i,targetPos); } } IAIActor* pAIActor = CastToIAIActorSafe(pAI); if (!pAIActor) { GameWarning("%s: entity '%s' in parameter 1 is not an AI actor.", __FUNCTION__, pEntity->GetName()); return pH->EndFunction(); } IEntity* pItemEntity = pItem->GetEntity(); if(!pItemEntity) return pH->EndFunction(); if(!pItem->GetOwnerId()) { // weapon is not used, check if it is on a vehicle IEntity* pParentEntity = pItemEntity->GetParent(); if(pParentEntity) { IAIObject* pParentAI = pParentEntity->GetAI(); if(pParentAI && pParentAI->GetAIType()==AIOBJECT_VEHICLE) { // (MATT) Feature was cut and code was tricky, hence ignore weapons in vehicles {2008/02/15:11:08:51} return pH->EndFunction(); } } } else if( pItem->GetOwnerId()!= pEntity->GetId()) // item is used by someone else? return pH->EndFunction(false); // check target if(bSkipTargetCheck) return pH->EndFunction(true); IAIObject* pTarget = pAIActor->GetAttentionTarget(); if(targetPos.IsZero()) { if(!pTarget) return pH->EndFunction(); targetPos = pTarget->GetPos(); } Vec3 targetDir(targetPos - pItemEntity->GetWorldPos()); Vec3 targetDirXY(targetDir.x, targetDir.y, 0); float length2D = targetDirXY.GetLength(); if(length2D < minDist || length2D<=0) return pH->EndFunction(); targetDirXY /= length2D;//normalize IWeapon* pWeapon = pItem->GetIWeapon(); bool vehicleGun = pWeapon && pWeapon->GetHostId(); if (!vehicleGun) { Vec3 mountedAngleLimits(pItem->GetMountedAngleLimits()); float yawRange = DEG2RAD(mountedAngleLimits.z); if(yawRange > 0 && yawRange < gf_PI) { float deltaYaw = pItem->GetMountedDir().Dot(targetDirXY); if(deltaYaw < cosf(yawRange)) return pH->EndFunction(false); } float minPitch = DEG2RAD(mountedAngleLimits.x); float maxPitch = DEG2RAD(mountedAngleLimits.y); //maxPitch = (maxPitch - minPitch)/2; //minPitch = -maxPitch; float pitch = atanf(targetDir.z / length2D); if ( pitch < minPitch || pitch > maxPitch ) return pH->EndFunction(false); } if(pTarget) { IEntity* pTargetEntity = pTarget->GetEntity(); if(pTargetEntity) { // check target distance and where he's going IPhysicalEntity *phys = pTargetEntity->GetPhysics(); if(phys) { pe_status_dynamics dyn; phys->GetStatus(&dyn); Vec3 velocity ( dyn.v); velocity.z = 0; float speed = velocity.GetLength2D(); if(speed>0) { //velocity /= speed; if(length2D< minDist * 0.75f && velocity.Dot(targetDirXY)<=0) return pH->EndFunction(false); } } } } return pH->EndFunction(true); }
void controller_system_update(ControllerSystem* self) { GET_SYSTEM_COMPONENTS(self); for (u32 i = 0; i < components->count; ++i) { Entity entity = GET_ENTITY(i); ControllerComponent* controller = (ControllerComponent*)GET_SYSTEM_COMPONENT(i); MovementComponent* movement = (MovementComponent*)GET_COMPONENT(entity, COMPONENT_MOVEMENT); TransformComponent* transform = (TransformComponent*)GET_COMPONENT(entity, COMPONENT_TRANSFORM); REQUIRED_COMPONENTS(transform, movement, controller); f32 x = 0; f32 y = 0; if (input_key(SDL_SCANCODE_LEFT)) { x -= 1.f; } if (input_key(SDL_SCANCODE_RIGHT)) { x += 1.f; } if (input_key(SDL_SCANCODE_UP)) { y -= 1.f; } if (input_key(SDL_SCANCODE_DOWN)) { y += 1.f; } //printf("%f\n", controller->moveSpeed); x *= controller->moveSpeed; y *= controller->moveSpeed; vec2_set(&movement->velocity, x, y); if (input_key_down(SDL_SCANCODE_Z)) { for (u32 i = 0; i < controller->bulletSourceCount; ++i) { bullet_source_on(&controller->bulletSources[i]); } } if (input_key_up(SDL_SCANCODE_Z)) { for (u32 i = 0; i < controller->bulletSourceCount; ++i) { bullet_source_off(&controller->bulletSources[i]); } } for (u32 i = 0; i < controller->bulletSourceCount; ++i) { bullet_source_update(&controller->bulletSources[i], globals.time.delta, self->super.entityManager, &transform->position); } //if (controller->fireTimer > 0.f) { // controller->fireTimer -= globals.time.delta; //} //if (input_key(SDL_SCANCODE_Z) && controller->fireTimer <= 0.f) { // Vec2 pos = vec2_clone(&transform->position); // pos.x += 64; // pos.y += 52; // entity_create_bullet(self->super.entityManager, // vec2_clone(&pos), // textures_get("player_bullet_1.png")); // controller->fireTimer = controller->fireDelay; //} } }
//========================== // V_CalcCameraRefdef //========================== void V_CalcCameraRefdef( struct ref_params_s *pparams ) { static float lasttime, oldz = 0; // get viewentity and monster eyeposition cl_entity_t *view = GET_ENTITY( pparams->viewentity ); if( view ) { pparams->vieworg = view->origin; pparams->viewangles = view->angles; // interpolate position for monsters if( view->curstate.movetype == MOVETYPE_STEP ) { float f; // don't do it if the goalstarttime hasn't updated in a while. // NOTE: Because we need to interpolate multiplayer characters, the interpolation time limit // was increased to 1.0 s., which is 2x the max lag we are accounting for. if(( GET_CLIENT_TIME() < view->curstate.animtime + 1.0f ) && ( view->curstate.animtime != view->latched.prevanimtime )) { f = (GET_CLIENT_TIME() - view->curstate.animtime) / (view->curstate.animtime - view->latched.prevanimtime); } if( !( view->curstate.effects & EF_NOINTERP )) { // ugly hack to interpolate angle, position. // current is reached 0.1 seconds after being set f = f - 1.0f; } else { f = 0.0f; } InterpolateOrigin( view->latched.prevorigin, view->origin, pparams->vieworg, f, true ); InterpolateAngles( view->latched.prevangles, view->angles, pparams->viewangles, f, true ); } studiohdr_t *viewmonster = (studiohdr_t *)IEngineStudio.Mod_Extradata( view->model ); if( viewmonster && view->curstate.eflags & EFLAG_SLERP ) { Vector forward; AngleVectors( pparams->viewangles, forward, NULL, NULL ); Vector viewpos = viewmonster->eyeposition; if( viewpos == g_vecZero ) viewpos = Vector( 0, 0, 8 ); // monster_cockroach pparams->vieworg += viewpos + forward * 8; // best value for humans pparams->fov_x = 100; // adjust fov for monster view pparams->fov_y = V_CalcFov( pparams->fov_x, pparams->viewport[2], pparams->viewport[3] ); } // this is smooth stair climbing in thirdperson mode but not affected for client model :( if( !pparams->smoothing && pparams->onground && view->origin[2] - oldz > 0.0f ) { float steptime; steptime = pparams->time - lasttime; if( steptime < 0 ) steptime = 0; oldz += steptime * 150.0f; if( oldz > view->origin[2] ) oldz = view->origin[2]; if( view->origin[2] - oldz > pparams->movevars->stepsize ) oldz = view->origin[2] - pparams->movevars->stepsize; pparams->vieworg[2] += oldz - view->origin[2]; } else { oldz = view->origin[2]; } lasttime = pparams->time; if( view->curstate.effects & EF_NUKE_ROCKET ) pparams->viewangles.x = -pparams->viewangles.x; // stupid quake bug! // g-cont. apply shake to camera gEngfuncs.V_CalcShake(); gEngfuncs.V_ApplyShake( pparams->vieworg, pparams->viewangles, 1.0f ); } }
/* ================= R_CullSurface cull invisible surfaces ================= */ bool R_CullSurfaceExt( msurface_t *surf, const mplane_t frustum[6], unsigned int clipflags ) { mextrasurf_t *info; cl_entity_t *e = RI.currententity; if( !surf || !surf->texinfo || !surf->texinfo->texture ) return true; if( surf->flags & SURF_WATERCSG && !( RI.currententity->curstate.effects & EF_NOWATERCSG )) return true; if( surf->flags & SURF_NOCULL ) return false; // don't cull transparent surfaces because we should be draw decals on them if( surf->pdecals && ( e->curstate.rendermode == kRenderTransTexture || e->curstate.rendermode == kRenderTransAdd )) return false; if( r_nocull->value ) return false; // world surfaces can be culled by vis frame too if( RI.currententity == GET_ENTITY( 0 ) && surf->visframe != tr.framecount ) return true; if( r_faceplanecull->value && glState.faceCull != 0 ) { if(!(surf->flags & SURF_DRAWTURB) || !RI.currentWaveHeight ) { if( surf->plane->normal != g_vecZero ) { float dist; if( RI.drawOrtho ) dist = surf->plane->normal[2]; else dist = PlaneDiff( tr.modelorg, surf->plane ); if( glState.faceCull == GL_FRONT || ( RI.params & RP_MIRRORVIEW )) { if( surf->flags & SURF_PLANEBACK ) { if( dist >= -BACKFACE_EPSILON ) return true; // wrong side } else { if( dist <= BACKFACE_EPSILON ) return true; // wrong side } } else if( glState.faceCull == GL_BACK ) { if( surf->flags & SURF_PLANEBACK ) { if( dist <= BACKFACE_EPSILON ) return true; // wrong side } else { if( dist >= -BACKFACE_EPSILON ) return true; // wrong side } } } } } info = SURF_INFO( surf, RI.currentmodel ); return ( clipflags && R_CullBoxExt( frustum, info->mins, info->maxs, clipflags )); }
void ManagerModel::ProcessCollisions(const std::vector<CollisionPair> &collisions) { for (const CollisionPair &pair : collisions) { Player *player = GET_ENTITY(Player, ENTITY_PLAYER, pair); Shot *shot = GET_ENTITY(Shot, ENTITY_BULLET, pair); Asteroid *asteroid = GET_ENTITY(Asteroid, ENTITY_ASTEROID, pair); HealthPackage *healthPackage = GET_ENTITY(HealthPackage, ENTITY_HEALTHPACKAGE, pair); EnemieBoss *enemieBoss = GET_ENTITY(EnemieBoss, ENTITY_ENEMIEBOSS, pair); EnemieBossShot *enemieBossShot = GET_ENTITY(EnemieBossShot, ENTITY_BULLETENEMIEBOSS, pair); if (player && asteroid) { int type = asteroid->mType; if (player->mHealth == player->defaultHealth / 2) { if (player->mFrameTimeIsHit <= 0) { AddExplosion(player->GetPosition(), ENTITY_PLAYER); SetHealth(0); RemoveEntity(player); RemoveEntity(asteroid); player->isHit = false; mLostRound = true; AddAsteroid(type, 2, Vec2(1, 1), Vec2(0)); } } else { player->Hit(); SetHealth(player->mHealth); AddExplosion(asteroid->GetPosition(), ENTITY_PLAYER); RemoveEntity(asteroid); AddAsteroid(type, 2, Vec2(1, 1), Vec2(0)); } } else if (asteroid && shot) { RemoveEntity(shot); if (asteroid->mHealth == asteroid->defaulthealth) { Vec2 pos = Vec2(asteroid->mPos.x, asteroid->mPos.y); float health = asteroid->defaulthealth / 2; int type = asteroid->mType; RemoveEntity(asteroid); AddScore(1); AddAsteroid(type, 2, Vec2(health / 100, health / 100), pos); } else if (asteroid->mHealth == asteroid->defaulthealth / 2) { AddExplosion(asteroid->GetPosition(), ENTITY_ASTEROID); if (mCountAsteroids == 4) { AddAsteroid(asteroid->mType, 2, Vec2(1, 1), Vec2(0)); mCountAsteroids = 0; } else { ++mCountAsteroids; } RemoveEntity(asteroid); AddScore(2); } } else if (healthPackage && player) { RemoveEntity(healthPackage); player->mHealth = player->defaultHealth; player->isHit = false; player->mFrameTimeIsHit = player->coolDownIsHit; } else if (enemieBoss && shot) { RemoveEntity(shot); enemieBoss->Hit(); AddScore(1); if (enemieBoss->mHealth <= 0) { RemoveEntity(enemieBoss); AddExplosion(enemieBoss->mPos, ENTITY_ENEMIEBOSS); } else { AddExplosion(enemieBoss->mPos, ENTITY_ASTEROID); } } else if (enemieBossShot && player) { if (player->mHealth == player->defaultHealth / 2) { if (player->mFrameTimeIsHit <= 0) { AddExplosion(player->GetPosition(), ENTITY_PLAYER); SetHealth(0); RemoveEntity(player); player->isHit = false; mLostRound = true; } } else { player->Hit(); SetHealth(player->mHealth); } } else if (player && enemieBoss) { RemoveEntity(player); AddExplosion(player->GetPosition(), ENTITY_PLAYER); player->isHit = true; mLostRound = true; } else if (asteroid && !player && !shot) { //RemoveEntity(pair.mEntityA); //RemoveEntity(pair.mEntityB); } } }