bool CSmartMine::ShouldStartTrackingEntity( const EntityId entityId ) const { // Always track player... if (entityId == g_pGame->GetIGameFramework()->GetClientActorId()) { return true; } // ... or any AI const SAutoaimTarget* pTargetInfo = g_pGame->GetAutoAimManager().GetTargetInfo( entityId ); if(pTargetInfo != NULL) { return (pTargetInfo->pActorWeak.lock() != NULL); } // Also track kickable and pickable objects IEntity* pEntity = gEnv->pEntitySystem->GetEntity( entityId ); IScriptTable* pScriptTable = (pEntity != NULL) ? pEntity->GetScriptTable() : NULL; if(pScriptTable != NULL) { SmartScriptTable propertiesTable; if(pScriptTable->GetValue("Properties", propertiesTable)) { int pickable = 0, kickable = 0; propertiesTable->GetValue("bPickable", pickable); propertiesTable->GetValue("bInteractLargeObject", kickable); if(pickable) { // Filter out items/weapons pickable = (g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(entityId) == NULL); } if (pickable || kickable) { //Check if object is moving IPhysicalEntity* pEntityPhysics = pEntity->GetPhysics(); if(pEntityPhysics != NULL) { pe_status_dynamics entityDynamics; if(pEntityPhysics->GetStatus(&entityDynamics)) { return (entityDynamics.v.len2() > 0.1f); } } } } } return false; }
//------------------------------------------------------------------------ void CVehicleDamageBehaviorImpulse::OnDamageEvent(EVehicleDamageBehaviorEvent event, const SVehicleDamageBehaviorEventParams& behaviorParams) { if (event == eVDBE_Hit || event == eVDBE_VehicleDestroyed || event == eVDBE_ComponentDestroyed) { IEntity* pEntity = m_pVehicle->GetEntity(); CRY_ASSERT(pEntity); IPhysicalEntity* pPhysEntity = pEntity->GetPhysics(); if (!pPhysEntity) return; pe_status_dynamics dyn; pPhysEntity->GetStatus(&dyn); float vehicleMass = dyn.mass; float r = cry_random(0.0f, 2.f); float impulseForce = cry_random(m_forceMin, m_forceMax) * vehicleMass; Vec3 impulseDir(m_impulseDir); if (!m_worldSpace) impulseDir = m_pVehicle->GetEntity()->GetWorldTM().TransformVector(impulseDir); pe_action_impulse actionImpulse; Vec3& impulse = actionImpulse.impulse; Vec3& angImpulse = actionImpulse.angImpulse; impulse = impulseDir * impulseForce; angImpulse = m_pVehicle->GetEntity()->GetWorldTM().TransformVector(m_angImpulse); if (r <= 0.75f) { float r1 = cry_random(-0.35f, 0.35f); angImpulse += dyn.v * r1 * max(1.0f, dyn.w.GetLength()); angImpulse *= vehicleMass; } else { float r1 = cry_random(-0.25f, 0.25f); float r2 = cry_random(-0.5f, 0.5f); impulse.z += abs(dyn.v.y) * r1 * vehicleMass; angImpulse.x += dyn.v.y * r2 * vehicleMass * max(1.0f, dyn.w.GetLength() * 1.5f); } if (m_pImpulseLocation) actionImpulse.point = m_pImpulseLocation->GetWorldSpaceTranslation(); pPhysEntity->Action(&actionImpulse); } }
//----------------------------------------------------------------------- void CSpectacularKill::DeathBlow(CActor& targetActor) { CRY_ASSERT_MESSAGE(m_isBusy, "spectacular kill should be in progress when triggering the death blow"); if (!m_isBusy) return; if (targetActor.IsDead()) return; Vec3 targetDir = targetActor.GetEntity()->GetForwardDir(); { HitInfo hitInfo; hitInfo.shooterId = m_pOwner->GetEntityId(); hitInfo.targetId = targetActor.GetEntityId(); hitInfo.damage = 99999.0f; // CERTAIN_DEATH hitInfo.dir = targetDir; hitInfo.normal = -hitInfo.dir; // this has to be in an opposite direction from the hitInfo.dir or the hit is ignored as a 'backface' hit hitInfo.type = CGameRules::EHitType::StealthKill; g_pGame->GetGameRules()->ClientHit(hitInfo); } // WARNING: RagDollize resets the entity's rotation! // [7/30/2010 davidr] FixMe: If the entity isn't dead here (because is immortal or any other reason) ragdollizing it will // leave it on an inconsistent state (usually only reproducible on debug scenarios) targetActor.GetGameObject()->SetAspectProfile(eEA_Physics, eAP_Ragdoll); // Give a small nudge in the hit direction to make the target fall over const SSpectacularKillParams* pSpectacularKillParams = GetParamsForClass(targetActor.GetEntity()->GetClass()); CRY_ASSERT(pSpectacularKillParams); if (pSpectacularKillParams && (pSpectacularKillParams->impulseScale > 0.0f) && (pSpectacularKillParams->impulseBone != -1)) { const float killDeathBlowVelocity = pSpectacularKillParams->impulseScale; // desired velocity after impulse in meters per second IPhysicalEntity* pTargetPhysics = targetActor.GetEntity()->GetPhysics(); if (pTargetPhysics) { pe_simulation_params simulationParams; pTargetPhysics->GetParams(&simulationParams); pe_action_impulse impulse; impulse.partid = pSpectacularKillParams->impulseBone; impulse.impulse = targetDir*killDeathBlowVelocity*simulationParams.mass; // RagDollize reset the entity's rotation so I have to use the value I cached earlier pTargetPhysics->Action(&impulse); } } m_deathBlowState = eDBS_Done; }
void CPlayerStateFly::OnExit( CPlayer& player ) { player.CreateScriptEvent("printhud",0,"FlyMode/NoClip OFF"); pe_player_dynamics simPar; IPhysicalEntity* piPhysics = player.GetEntity()->GetPhysics(); if (!piPhysics || piPhysics->GetParams(&simPar) == 0) { return; } CPlayerStateUtil::PhySetNoFly( player, simPar.gravity ); }
void CNetPlayerInput::UpdateInterpolation() { Vec3 desiredPosition = m_curInput.position; Vec3 desiredVelocity = m_curInput.deltaMovement * g_pGameCVars->pl_netSerialiseMaxSpeed; // Use the physics pos as the entity position is a frame behind at this point IPhysicalEntity * pent = m_pPlayer->GetEntity()->GetPhysics(); pe_status_pos psp; pent->GetStatus(&psp); Vec3 entPos = psp.pos; pe_status_living psl; psl.velGround.zero(); pent->GetStatus(&psl); float dt = gEnv->pTimer->GetFrameTime(); // New data? if (m_newInterpolation) m_lerper.AddNewPoint(m_curInput.position, desiredVelocity, entPos, m_curInput.standingOn); bool bInAirOrJumping = m_pPlayer->GetActorStats()->inAir > 0.01f || m_pPlayer->GetActorStats()->onGround < 0.01f; // Predict CNetLerper::SPrediction prediction; m_lerper.Update(gEnv->pTimer->GetFrameTime(), entPos, prediction, psl.velGround, bInAirOrJumping); // Update lerp velocity m_lerpVel = prediction.lerpVel; // Should Snap if (prediction.shouldSnap) { m_pPlayer->GetEntity()->SetPos(prediction.predictedPos); pe_action_set_velocity actionVel; actionVel.v = prediction.lerpVel; pent->Action(&actionVel); } #if !defined(_RELEASE) // Debug Draw if (g_pGameCVars->pl_debugInterpolation) m_lerper.DebugDraw(prediction, entPos, m_newInterpolation); else SAFE_DELETE(m_lerper.m_debug); #endif m_newInterpolation = false; }
void CGameRealtimeRemoteUpdateListener::CameraSync() { IGame *pGame = gEnv->pGame; if(!pGame) return; IGameFramework *pGameFramework=pGame->GetIGameFramework(); if(!pGameFramework) return; IViewSystem *pViewSystem=pGameFramework->GetIViewSystem(); if(!pViewSystem) return; IView *pView=pViewSystem->GetActiveView(); if(!pView) return; IEntity *pEntity = gEnv->pEntitySystem->GetEntity(pView->GetLinkedId()); if(!pEntity) return; IActor *pPlayer=pGameFramework->GetClientActor(); if ( !pPlayer ) return; IEntity * pPlayerEntity = pPlayer->GetEntity(); if (!pPlayerEntity) return; IPhysicalEntity * piPlayerPhysics = pPlayerEntity->GetPhysics(); if ( !piPlayerPhysics ) return; pe_player_dimensions dim; piPlayerPhysics->GetParams( &dim ); //TODO: only GDCE2011, in the future make this game magic constant be gone in LiveCreate 2.0 // game player view code has a complex position code path, the sync position should be // honoured by game code when live creaate camera sync is enabled m_Position.z -= 1.62f; pEntity->SetPos(m_Position); pPlayerEntity->Hide(false); pViewSystem->SetOverrideCameraRotation(true,Quat::CreateRotationVDir(m_ViewDirection)); pPlayerEntity->Hide(true); SEntityUpdateContext ctx; pPlayer->Update( ctx, 0 ); m_bCameraSync = true; }
void ResetVelocity(SActivationInfo* pActInfo) { IEntity* pGraphEntity = pActInfo->pEntity; if (pGraphEntity) { IPhysicalEntity* pPhysicalEntity = pGraphEntity->GetPhysics(); if (pPhysicalEntity && pPhysicalEntity->GetType() != PE_STATIC) { pe_action_set_velocity setVel; setVel.v.zero(); setVel.w.zero(); pPhysicalEntity->Action(&setVel); } } }
void CPlayerStateUtil::PhySetNoFly( CPlayer& player, const Vec3& gravity ) { IPhysicalEntity* pPhysEnt = player.GetEntity()->GetPhysics(); if (pPhysEnt != NULL) { pe_player_dynamics pd; pd.kAirControl = player.GetAirControl(); pd.kAirResistance = player.GetAirResistance(); pd.bSwimming = false; pd.gravity = gravity; player.m_actorPhysics.gravity = gravity; pPhysEnt->SetParams(&pd); } }
virtual void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo ) { switch (event) { case eFE_Initialize: pActInfo->pGraph->SetRegularlyUpdated( pActInfo->myID, true ); m_Activated = false; break; case eFE_Update: { bool bReset = GetPortBool(pActInfo, IN_RESET); bool bCondition = GetPortBool(pActInfo, IN_CONDITION); if(bReset) { ActivateOutput(pActInfo, OUT_SLEEPING, !bCondition); } else { if(bCondition != m_Activated) { IEntity * pEntity = pActInfo->pEntity; if (pEntity) { IPhysicalEntity * pPhysEntity = pEntity->GetPhysics(); if (pPhysEntity) { pe_status_awake psa; bool isSleeping = pPhysEntity->GetStatus( &psa ) ? false : true; ActivateOutput(pActInfo, OUT_SLEEPING, isSleeping); if(isSleeping) ActivateOutput(pActInfo, OUT_ONSLEEP, true); else ActivateOutput(pActInfo, OUT_ONAWAKE, true); } } m_Activated = bCondition; } } } } }
bool CCannonBall::RayTraceGeometry( const EventPhysCollision* pCollision, const Vec3& pos, const Vec3& hitDirection, SBackHitInfo* pBackHitInfo ) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); bool exitPointFound = false; IPhysicalEntity* pCollider = pCollision->pEntity[1]; assert(pCollider); pe_params_part partParams; partParams.partid = pCollision->partid[1]; pe_status_pos posStatus; if (pCollider->GetParams(&partParams) && pCollider->GetStatus(&posStatus)) { if (partParams.pPhysGeom && partParams.pPhysGeom->pGeom) { geom_world_data geomWorldData; geomWorldData.R = Matrix33(posStatus.q*partParams.q); geomWorldData.offset = posStatus.pos + (posStatus.q * partParams.pos); geomWorldData.scale = posStatus.scale * partParams.scale; geom_contact *pContacts; intersection_params intersectionParams; IGeometry* pRayGeometry = s_pRayWrapper->GetRay(pos, hitDirection); const Vec3 hitDirectionNormalized = hitDirection.GetNormalized(); { WriteLockCond lock; const int contactCount = partParams.pPhysGeom->pGeom->IntersectLocked(pRayGeometry,&geomWorldData,0,&intersectionParams,pContacts,lock); if (contactCount > 0) { float bestDistance = 10.0f; for (int i = (contactCount-1); (i >= 0) && (pContacts[i].t < bestDistance) && ((pContacts[i].n*hitDirectionNormalized) < 0); i--) { bestDistance = (float)pContacts[i].t; pBackHitInfo->pt = pContacts[i].pt; exitPointFound = true; } } } // lock } } s_pRayWrapper->ResetRay(); return exitPointFound; }
void CFists::RaiseWeapon(bool raise, bool faster /*= false*/) { //Only when colliding something while running if(raise && (GetCurrentAnimState()==eFAS_RUNNING || GetCurrentAnimState()==eFAS_JUMPING) && !IsWeaponRaised()) { if((m_fm && m_fm->IsFiring())||(m_melee && m_melee->IsFiring())) return; PlayAction(g_pItemStrings->raise); SetDefaultIdleAnimation( eIGS_FirstPerson,g_pItemStrings->idle_relaxed); SetWeaponRaised(true); //Also give the player some impulse into the opposite direction CActor *pPlayer = GetOwnerActor(); Vec3 pos; if(pPlayer) { IPhysicalEntity* playerPhysics = pPlayer->GetEntity()->GetPhysics(); if(playerPhysics) { IMovementController *pMC = pPlayer->GetMovementController(); if(pMC) { SMovementState state; pMC->GetMovementState(state); pe_action_impulse impulse; impulse.iApplyTime = 1; impulse.impulse = -state.eyeDirection*600.0f; playerPhysics->Action(&impulse); pos = state.eyePosition + state.eyeDirection*0.5f; } } } GetScheduler()->TimerAction(GetCurrentAnimationTime(eIGS_FirstPerson), CSchedulerAction<EndRaiseWeaponAction>::Create(EndRaiseWeaponAction(this)), true); //Sound and FX feedback CollisionFeeback(pos,m_currentAnimState); } else if(!raise) SetWeaponRaised(false); }
//------------------------------------------------------------------------ void CVehicleMovementTank::SetLatFriction(float latFric) { // todo: do calculation per-wheel? IPhysicalEntity* pPhysics = GetPhysics(); int numWheels = m_pVehicle->GetWheelCount(); pe_params_wheel params; params.kLatFriction = latFric; for (int i=0; i<numWheels; ++i) { params.iWheel = i; pPhysics->SetParams(¶ms, THREAD_SAFE); } m_latFriction = latFric; }
//------------------------------------------------------------------------ void CVehicleActionDeployRope::AttachOnRope(IEntity *pEntity) { assert(pEntity); if(!pEntity) return; IRopeRenderNode *pRopeUpper = GetRopeRenderNode(m_ropeUpperId); if(!pRopeUpper) return; assert(pRopeUpper->GetPointsCount() >= 2); IPhysicalEntity *pRopePhys = pRopeUpper->GetPhysics(); assert(pRopePhys); typedef std::vector <Vec3> TVec3Vector; TVec3Vector points; int pointCount; pe_status_rope ropeStatus; if(pRopePhys->GetStatus(&ropeStatus)) pointCount = ropeStatus.nSegments + 1; else pointCount = 0; if(pointCount < 2) return; points.resize(pointCount); ropeStatus.pPoints = &points[0]; if(pRopePhys->GetStatus(&ropeStatus)) { Matrix34 worldTM; worldTM.SetIdentity(); worldTM = Matrix33(m_pVehicle->GetEntity()->GetWorldTM()); worldTM.SetTranslation(ropeStatus.pPoints[1]); pEntity->SetWorldTM(worldTM); } pRopeUpper->LinkEndEntities(m_pVehicle->GetEntity()->GetPhysics(), pEntity->GetPhysics()); }
void CRecoil::RecoilImpulse(const Vec3& firingPos, const Vec3& firingDir) { if (m_recoilParams.impulse > 0.f) { EntityId id = (m_pWeapon->GetHostId()) ? m_pWeapon->GetHostId() : m_pWeapon->GetOwnerId(); IEntity* pEntity = gEnv->pEntitySystem->GetEntity(id); IPhysicalEntity* pPhysicalEntity = pEntity ? pEntity->GetPhysics() : NULL; if (pPhysicalEntity) { pe_action_impulse impulse; impulse.impulse = -firingDir * m_recoilParams.impulse; impulse.point = firingPos; pPhysicalEntity->Action(&impulse); } } }
void CIntersectionAssistanceUnit::DebugUpdate() const { if(g_pGameCVars->pl_pickAndThrow.intersectionAssistDebugEnabled) { IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_subjectEntityId); if(pEntity) { IPhysicalEntity *pPhysical = pEntity->GetPhysics(); if(pPhysical) { const float fFontSize = 1.2f; float drawColor[4] = {1.0f, 1.0f, 1.0f, 1.0f}; string sMsg(string().Format(" Entity ID: [%d]", m_subjectEntityId)); sMsg += string().Format("\n Entity Name: [%s]", pEntity->GetName()); sMsg += string().Format("\n EmbedTimer: [%.3f]", m_embedTimer); sMsg += string().Format("\n EmbedState: [%s]",(m_embedState == eES_None) ? "NONE" : (m_embedState == eES_Evaluating) ? "EVALUATING" : (m_embedState == eES_ReEvaluating) ? "REEVALUATING" : (m_embedState == eES_NotEmbedded) ? "NOT EMBEDDED" : (m_embedState == eES_Embedded) ? "EMBEDDED" : "UNKNOWN"); Vec3 vCurrTrans = m_entityStartingWPos - pEntity->GetWorldPos(); sMsg += string().Format("\n Translation: < %.3f, %.3f, %.3f >", vCurrTrans.x, vCurrTrans.y, vCurrTrans.z ); sMsg += string().Format("\n Trans magnitude: < %.3f >", vCurrTrans.GetLength() ); sMsg += string().Format("\n Trans per sec: < %.3f >", vCurrTrans.GetLength() / g_pGameCVars->pl_pickAndThrow.intersectionAssistTimePeriod ); sMsg += string().Format("\n Collision count: %u", m_collisionCount ); // RENDER Vec3 vDrawPos = pEntity->GetWorldPos() + Vec3(0.0f,0.0f,0.6f); gEnv->pRenderer->DrawLabelEx(vDrawPos, fFontSize, drawColor, true, true, sMsg.c_str()); // Box pe_params_bbox bbox; if(pPhysical->GetParams(&bbox)) { ColorB colDefault = ColorB( 127,127,127 ); ColorB embedded = ColorB(255, 0, 0); ColorB notEmbedded = ColorB(0, 255, 0); gEnv->pRenderer->GetIRenderAuxGeom()->DrawAABB( AABB(bbox.BBox[0],bbox.BBox[1]), Matrix34(IDENTITY), false, (m_embedState == eES_Embedded) ? embedded : (m_embedState == eES_NotEmbedded) ? notEmbedded : colDefault, eBBD_Faceted); } } } } }
//------------------------------------------------------------------------ void CVehicleMovementHelicopter::Physicalize() { CVehicleMovementBase::Physicalize(); IPhysicalEntity * pPhysicalEntity = GetPhysics(); pe_params_flags pf; pf.flagsOR = pef_ignore_areas; pPhysicalEntity->SetParams(&pf); pe_simulation_params simParams; simParams.iSimClass = SC_ACTIVE_RIGID; simParams.damping = 0.0f; simParams.dampingFreefall = 0.0f; simParams.gravity = Vec3(0.0f, 0.0f, 0.0f); simParams.minEnergy = 0.0f; pPhysicalEntity->SetParams(&simParams); }
void CLocalPlayerComponent::UpdateStumble( const float frameTime ) { IEntity * pEntity = m_rPlayer.GetEntity(); IPhysicalEntity * pPhysEntity = pEntity->GetPhysics(); if ( pPhysEntity ) { pe_status_dynamics dynamics; pPhysEntity->GetStatus( &dynamics ); if ( m_playerStumble.Update( frameTime, dynamics ) ) { pe_action_impulse ai; ai.impulse = m_playerStumble.GetCurrentActionImpulse(); pPhysEntity->Action( &ai ); } } }
//------------------------------------------------------------------------ void CVehicleActionEntityAttachment::Update(const float deltaTime) { if(m_isAttached) return; IEntitySystem *pEntitySystem = gEnv->pEntitySystem; assert(pEntitySystem); IEntity *pEntity = pEntitySystem->GetEntity(m_entityId); if(!pEntity) return; IPhysicalEntity *pPhysEntity = pEntity->GetPhysics(); if(!pPhysEntity) return; pe_simulation_params paramsSim; float gravity; if(pPhysEntity->GetParams(¶msSim)) gravity = abs(paramsSim.gravity.z); else gravity = 9.82f; pe_status_dynamics dyn; if(pPhysEntity->GetStatus(&dyn)) { pe_action_impulse impulse; impulse.impulse = Matrix33(pEntity->GetWorldTM()) * Vec3(0.0f, 0.0f, 1.0f) * g_parachuteForce * gravity; impulse.impulse = impulse.impulse - dyn.v; impulse.impulse *= dyn.mass * deltaTime; impulse.iSource = 3; pPhysEntity->Action(&impulse); } m_timer -= deltaTime; if(m_timer <= 0.0f || dyn.v.z >= 0.0f) m_pVehicle->SetObjectUpdate(this, IVehicle::eVOU_NoUpdate); }
void CPlayerInput::GetState( SSerializedPlayerInput& input ) { SMovementState movementState; m_pPlayer->GetMovementController()->GetMovementState( movementState ); Quat worldRot = m_pPlayer->GetBaseQuat(); input.stance = FigureOutStance(); // PLAYERPREDICTION if (g_pGameCVars->pl_serialisePhysVel) { //--- Serialise the physics vel instead, velocity over the NET_SERIALISE_PLAYER_MAX_SPEED will be clamped by the network so no guards here IPhysicalEntity* pEnt = m_pPlayer->GetEntity()->GetPhysics(); if (pEnt) { pe_status_dynamics dynStat; pEnt->GetStatus(&dynStat); input.deltaMovement = dynStat.v / g_pGameCVars->pl_netSerialiseMaxSpeed; input.deltaMovement.z = 0.0f; } } else { input.deltaMovement = worldRot.GetNormalized() * m_filteredDeltaMovement; // ensure deltaMovement has the right length input.deltaMovement = input.deltaMovement.GetNormalizedSafe(ZERO) * m_filteredDeltaMovement.GetLength(); } // ~PLAYERPREDICTION input.sprint = (((m_actions & ACTION_SPRINT) != 0) && !m_pPlayer->m_stats.bIgnoreSprinting); input.usinglookik = true; input.aiming = true; input.leanl = (m_actions & ACTION_LEANLEFT) != 0; input.leanr = (m_actions & ACTION_LEANRIGHT) != 0; input.lookDirection = movementState.eyeDirection; // PLAYERPREDICTION input.bodyDirection = movementState.entityDirection; // ~PLAYERPREDICTION m_lastPos = movementState.pos; }
void CDeflectorShield::ProcessCollision(const EventPhysCollision& pCollision) { int id = 0; IPhysicalEntity* pTarget = pCollision.pEntity[id]; if (pTarget == GetEntity()->GetPhysics()) { id = 1; pTarget = pCollision.pEntity[id]; } IEntity* pTargetEntity = (IEntity*)pTarget->GetForeignData(PHYS_FOREIGN_ID_ENTITY); if (pTargetEntity == 0) return; CProjectile* pProjectile = g_pGame->GetWeaponSystem()->GetProjectile(pTargetEntity->GetId()); if (pProjectile) ProcessProjectile(pProjectile, pCollision.pt, pCollision.n, pCollision.vloc[id].GetNormalized()); }
void CPlayerStateSwim::OnEnter( CPlayer& player ) { player.m_playerStateSwim_WaterTestProxy.OnEnterWater(player); IPhysicalEntity* pPhysEnt = player.GetEntity()->GetPhysics(); if (pPhysEnt != NULL) { // get current gravity before setting to zero. pe_player_dynamics simPar; if( pPhysEnt->GetParams(&simPar) != 0 ) { m_gravity = simPar.gravity; } CPlayerStateUtil::PhySetFly( player ); } m_lastWaterLevel = player.m_playerStateSwim_WaterTestProxy.GetWaterLevel(); m_lastWaterLevelTime = player.m_playerStateSwim_WaterTestProxy.GetWaterLevelTimeUpdated(); player.m_stats.inAir = 0.0f; if (player.IsClient()) { ICameraMode::AnimationSettings animationSettings; animationSettings.positionFactor = 1.0f; animationSettings.rotationFactor = GetSwimParams().m_stateSwim_animCameraFactor; player.GetPlayerCamera()->SetCameraModeWithAnimationBlendFactors( eCameraMode_PartialAnimationControlled, animationSettings, "Entering swim state" ); player.SendMusicLogicEvent(eMUSICLOGICEVENT_PLAYER_SWIM_ENTER); if (!player.IsCinematicFlagActive(SPlayerStats::eCinematicFlag_HolsterWeapon)) player.HolsterItem(true); if (gEnv->bMultiplayer) // any left hand holding in SP? { player.HideLeftHandObject(true); } } // Record 'Swim' telemetry stats. CStatsRecordingMgr::TryTrackEvent(&player, eGSE_Swim, true); }
//------------------------------------------------------------------------ int CScriptBind_Actor::IsFlying(IFunctionHandler *pH) { CActor *pActor = GetActor(pH); if (!pActor) return pH->EndFunction(); if (pActor) { pe_status_living livStat; IPhysicalEntity *pPhysEnt = pActor->GetEntity()->GetPhysics(); if (!pPhysEnt) return pH->EndFunction(); if(pPhysEnt->GetStatus(&livStat)) return pH->EndFunction(livStat.bFlying!=0); } return pH->EndFunction(); }
void CPlayerStateFly::OnEnter( CPlayer& player ) { pe_player_dynamics simPar; IPhysicalEntity* piPhysics = player.GetEntity()->GetPhysics(); if (!piPhysics || piPhysics->GetParams(&simPar) == 0) { return; } player.m_actorPhysics.velocity = player.m_actorPhysics.velocityUnconstrained.Set(0,0,0); player.m_actorPhysics.speed = player.m_stats.speedFlat = 0.0f; player.m_actorPhysics.groundMaterialIdx = -1; player.m_actorPhysics.gravity = simPar.gravity; player.m_stats.fallSpeed = 0.0f; player.m_stats.inFiring = 0; CPlayerStateUtil::PhySetFly( player ); }
void CBaseGrabHandler::IgnoreCollision(EntityId eID,unsigned int flags,bool ignore) { IEntity *pGrab = gEnv->pEntitySystem->GetEntity(eID); IPhysicalEntity *ppGrab = pGrab ? pGrab->GetPhysics() : NULL; if(!ppGrab) return; if(ignore) { // NOTE Dez 14, 2006: <pvl> this whole block just fills in // a request structure and passes it to physics IEntity *pEnt = m_pActor->GetEntity(); pe_action_add_constraint ac; ac.flags = constraint_inactive|constraint_ignore_buddy; ac.pBuddy = pEnt->GetPhysics(); ac.pt[0].Set(0,0,0); ICharacterInstance *pCharacter = pEnt->GetCharacter(0); IPhysicalEntity *pPhysEnt = pCharacter?pCharacter->GetISkeletonPose()->GetCharacterPhysics(-1):NULL; if(pPhysEnt) { pe_simulation_params sp; pPhysEnt->GetParams(&sp); if(sp.iSimClass <= 2) ac.pBuddy = pPhysEnt; } ppGrab->Action(&ac); } else { // NOTE Dez 14, 2006: <pvl> the same as the other branch - just // fill in a request and pass it to the physics engine pe_action_update_constraint uc; uc.bRemove = 1; ppGrab->Action(&uc); } // NOTE Dez 14, 2006: <pvl> flag manipulation is basically a legacy // code - probably not used anymore, scheduled for removal. if(flags) { pe_params_part pp; pp.flagsAND = pp.flagsColliderAND = ~flags; pp.flagsOR = pp.flagsColliderOR = flags * (ignore?0:1); pe_status_nparts status_nparts; for(pp.ipart = ppGrab->GetStatus(&status_nparts)-1; pp.ipart>=0; pp.ipart--) ppGrab->SetParams(&pp); } }
bool CStickyProjectile::IsValid() const { if (!IsStuck()) return false; if(m_parentId == 0) return true; pe_params_part part; part.partid = m_stuckPartId; IEntity* pEntity = gEnv->pEntitySystem->GetEntity(m_parentId); if(pEntity) { if (pEntity->IsHidden()) { return false; } if(ICharacterInstance* pCharacter = pEntity->GetCharacter(0)) { if(ISkeletonPose* pSkel = pCharacter->GetISkeletonPose()) { IPhysicalEntity* pSkelPhysics = pSkel->GetCharacterPhysics(); if (pSkelPhysics) { return pSkelPhysics->GetParams(&part) != 0; } } } else { IPhysicalEntity* pPhysics = pEntity->GetPhysics(); if (pPhysics) { return pPhysics->GetParams(&part) != 0; } } } return false; }
int CVehicleMovementAerodynamic::AddBox(Vec3 *_pvPos,Vec3 *_pvSize,float _fMass,int _iID/*=-1*/) { IPhysicalEntity* pPhysics = GetPhysics(); IGeomManager *pGeomManager = gEnv->pPhysicalWorld->GetGeomManager(); primitives::box Box; Box.Basis.SetIdentity(); Box.center.Set(0.0f,0.0f,0.0f); Box.size = (*_pvSize) / 2.0f; Box.bOriented = 0; IGeometry *pGeometry = pGeomManager->CreatePrimitive(primitives::box::type,&Box); phys_geometry *pPhysGeometry = pGeomManager->RegisterGeometry(pGeometry); pGeometry->Release(); pe_geomparams partpos; partpos.pos = *_pvPos; partpos.mass = _fMass; int id = pPhysics->AddGeometry(pPhysGeometry,&partpos,_iID); pGeomManager->UnregisterGeometry(pPhysGeometry); return id; }
void CLivingEntitySample::OnPrePhysicsUpdate() { IEntity* pEntity = GetEntity(); IPhysicalEntity* pPhysEntity = pEntity->GetPhysics(); if ( pPhysEntity == NULL ) { return; } // The desired speed is chosen with a value within the motion capabilities // of the walk animation used for this sample. const float desiredSpeed = 1.5f; const Vec3 desiredLocalDirection = CalculateDesiredLocalDirection(); const Vec3 desiredLocalVelocity = desiredLocalDirection * desiredSpeed; const Quat worldOrientation = pEntity->GetWorldRotation(); const Vec3 desiredWorldVelocity = worldOrientation * desiredLocalVelocity; pe_action_move pam; pam.dir = desiredWorldVelocity; pPhysEntity->Action( &pam ); }
////////////////////////////////////////////////////////////////////////// // 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); }
////////////////////////////////////////////////////////////////////////// // NOTE: This function must be thread-safe. Before adding stuff contact MarcoC. void CVehicleMovementHelicopter::ProcessMovement(const float deltaTime) { FUNCTION_PROFILER( GetISystem(), PROFILE_GAME ); IPhysicalEntity* pPhysics = GetPhysics(); assert(pPhysics); if (m_arcade.m_handling.maxSpeedForward>0.f) // Use the new handling code { CryAutoCriticalSection lk(m_lock); if (!m_isEnginePowered) return; CVehicleMovementBase::ProcessMovement(deltaTime); SVehiclePhysicsStatus* physStatus = &m_physStatus[k_physicsThread]; if(m_bApplyNoiseAsVelocity) { physStatus->v -= m_pNoise->m_posDifference; physStatus->w -= m_pNoise->m_angDifference; m_pNoise->Update(deltaTime); } /////////////////////////////////////////////////////////////// // Pass on the movement request to the active physics handler // NB: m_physStatus is update by this call SVehiclePhysicsHelicopterProcessParams params; params.pPhysics = pPhysics; params.pPhysStatus = physStatus; params.pInputAction = &m_inputAction; params.dt = deltaTime; params.haveDriver = (m_actorId!=0)||m_remotePilot; params.isAI = m_movementAction.isAI; params.aiRequiredVel = m_CurrentVel; m_arcade.ProcessMovement(params); // Network error adjustment m_netPosAdjust *= max(0.f, 1.f-deltaTime*k_netErrorPosScale); physStatus->v += m_netPosAdjust * k_netErrorPosScale; if(m_bApplyNoiseAsVelocity) { physStatus->v += m_pNoise->m_posDifference; physStatus->w += m_pNoise->m_angDifference; } //=============================================== // Commit the velocity back to the physics engine //=============================================== // if (fabsf(m_movementAction.rotateYaw)>0.05f || vel.GetLengthSquared()>0.001f || m_chassis.vel.GetLengthSquared()>0.001f || angVel.GetLengthSquared()>0.001f || angVel.GetLengthSquared()>0.001f) { pe_action_set_velocity setVelocity; setVelocity.v = physStatus->v; setVelocity.w = physStatus->w; pPhysics->Action(&setVelocity, 1); } /////////////////////////////////////////////////////////////// } else { if (m_isEnginePowered && pPhysics) { m_movementAction.isAI = true; pe_status_pos psp; pe_status_dynamics psd; if (!pPhysics->GetStatus(&psp) || !pPhysics->GetStatus(&psd)) return; UpdatePhysicsStatus(&m_physStatus[k_physicsThread], &psp, &psd); ProcessAI(deltaTime); } } }
void CVehicleMovementHelicopter::ProcessAI(const float deltaTime) { FUNCTION_PROFILER( GetISystem(), PROFILE_GAME ); CryAutoCriticalSection lk(m_lock); SVehiclePhysicsStatus* physStatus = &m_physStatus[k_physicsThread]; if (m_arcade.m_handling.maxSpeedForward>0.f) // Use the new handling code { //ResetActions(); m_movementAction.Clear(); m_movementAction.isAI = true; SVehiclePhysicsHelicopterProcessAIParams params; params.pPhysStatus = physStatus; params.pInputAction = &m_inputAction; params.pAiRequest = &m_aiRequest; params.dt = deltaTime; params.aiRequiredVel = m_CurrentVel; params.aiCurrentSpeed = m_CurrentSpeed; params.aiYawResponseScalar = m_yawResponseScalar; m_yawResponseScalar = 1.f; // Use helper class to process the AI input // It will return a requested velocity, and change the input m_arcade.ProcessAI(params); // Get the output velocity m_CurrentVel = params.aiRequiredVel; m_CurrentSpeed = params.aiCurrentSpeed; return; } ////////////////////// OLD DEPRECATED CODE :( ////////////////////////////////// m_movementAction.Clear(); ResetActions(); // Our current state const Vec3 worldPos = physStatus->pos; const Matrix33 worldMat( physStatus->q); const Matrix33 localMat( physStatus->q.GetInverted()); const Ang3 worldAngles = Ang3::GetAnglesXYZ(worldMat); const Ang3 localAngles = Ang3::GetAnglesXYZ(localMat); const Vec3 currentVel = physStatus->v; const Vec3 currentVel2D(currentVel.x, currentVel.y, 0.0f); m_CurrentSpeed = m_CurrentVel.len(); //currentVel.len(); float currentSpeed2d = currentVel2D.len(); // +ve direction mean rotation anti-clocwise about the z axis - 0 means along y float currentDir = worldAngles.z; // to avoid singularity const Vec3 vWorldDir = worldMat.GetRow(1); const Vec3 vSideWays = worldMat.GetRow(0); const Vec3 vWorldDir2D = Vec3( vWorldDir.x, vWorldDir.y, 0.0f ).GetNormalizedSafe(); // Our inputs float desiredSpeed = m_aiRequest.HasDesiredSpeed() ? m_aiRequest.GetDesiredSpeed() : 0.0f; Limit(desiredSpeed, -m_maxSpeed, m_maxSpeed); const Vec3 desiredMoveDir = m_aiRequest.HasMoveTarget() ? (m_aiRequest.GetMoveTarget() - worldPos).GetNormalizedSafe() : vWorldDir; Vec3 desiredMoveDir2D = Vec3(desiredMoveDir.x, desiredMoveDir.y, 0.0f); desiredMoveDir2D = desiredMoveDir2D.GetNormalizedSafe(desiredMoveDir2D); const Vec3 desiredVel = desiredMoveDir * desiredSpeed; const Vec3 desiredVel2D(desiredVel.x, desiredVel.y, 0.0f); Vec3 desiredLookDir(desiredMoveDir); if (m_aiRequest.HasDesiredBodyDirectionAtTarget()) { desiredLookDir = m_aiRequest.GetDesiredBodyDirectionAtTarget().GetNormalizedSafe(desiredMoveDir); } else if (m_aiRequest.HasLookTarget()) { desiredLookDir = (m_aiRequest.GetLookTarget() - worldPos).GetNormalizedSafe(desiredMoveDir); } //const Vec3 desiredLookDir = m_aiRequest.HasLookTarget() ? (m_aiRequest.GetLookTarget() - worldPos).GetNormalizedSafe() : desiredMoveDir; const Vec3 desiredLookDir2D = Vec3(desiredLookDir.x, desiredLookDir.y, 0.0f).GetNormalizedSafe(vWorldDir2D); Vec3 prediction = m_aiRequest.HasBodyTarget() ? m_aiRequest.GetBodyTarget() : ZERO; prediction = (prediction.IsEquivalent(ZERO)) ? desiredMoveDir2D : prediction - worldPos; prediction.z = 0.0f; float speedLimit = prediction.GetLength2D(); if(speedLimit > 0.0f) { prediction *= 1.0f / speedLimit; } Vec3 tempDir = currentVel2D.IsEquivalent(ZERO) ? localMat.GetRow(1) : currentVel2D; tempDir.z = 0.0f; tempDir.NormalizeFast(); float dotProd = tempDir.dot(prediction); Limit(dotProd, FLT_EPSILON, 1.0f); float accel = m_enginePowerMax * min(2.0f, 1.0f / dotProd); // * dotProd; if (!m_aiRequest.HasDesiredBodyDirectionAtTarget()) { dotProd *= dotProd; dotProd *= dotProd; float tempf = min(max(speedLimit * speedLimit, 2.0f), m_maxSpeed * dotProd); Limit(desiredSpeed, -tempf, tempf); } else if (dotProd < 0.0125f) { Limit(desiredSpeed, -m_maxSpeed * 0.25f, m_maxSpeed * 0.25f); } float posNeg = (float)__fsel(desiredSpeed - m_CurrentSpeed, 1.0f, -5.0f); if (desiredVel2D.GetLengthSquared() > FLT_EPSILON) { m_CurrentSpeed = m_CurrentSpeed + posNeg * accel * deltaTime; } else { m_CurrentSpeed = m_CurrentSpeed + posNeg * accel * deltaTime; } if (posNeg > 0.0f && m_CurrentSpeed > desiredSpeed) { m_CurrentSpeed = desiredSpeed; } else if (posNeg < 0.0f && m_CurrentSpeed < desiredSpeed) { m_CurrentSpeed = desiredSpeed; } // ---------------------------- Rotation ---------------------------- float desiredDir = (desiredLookDir2D.GetLengthSquared() > 0.0f) ? atan2f(-desiredLookDir2D.x, desiredLookDir2D.y) : atan2f(-vWorldDir2D.x, vWorldDir2D.y); while (currentDir < desiredDir - gf_PI) currentDir += 2.0f * gf_PI; while (currentDir > desiredDir + gf_PI) currentDir -= 2.0f * gf_PI; // ---------------------------- Yaw ---------------------------- Ang3 dirDiff(0.0f, 0.0f, desiredDir - currentDir); dirDiff.RangePI(); float absDiff = fabsf(dirDiff.z); float rotSpeed = (float)__fsel(dirDiff.z, m_yawPerRoll, -m_yawPerRoll); m_actionYaw = m_actionYaw + deltaTime * (rotSpeed - m_actionYaw); float temp = fabsf(m_actionYaw); float multiplier = ((absDiff / (temp + 0.001f)) + 1.0f) * 0.5f; m_actionYaw *= (float)__fsel(absDiff - temp, 1.0f, multiplier); // ---------------------------- Yaw ------------------------------ m_CurrentVel = desiredMoveDir * m_CurrentSpeed; // ---------------------------- Pitch ---------------------------- if (m_CurrentVel.GetLengthSquared2D() > 0.1f) { CalculatePitch(worldAngles, desiredMoveDir, currentSpeed2d, desiredSpeed, deltaTime); } else { Quat rot; rot.SetRotationVDir(desiredLookDir, 0.0f); float desiredXRot = Ang3::GetAnglesXYZ(rot).x + m_steeringDamage.x; m_actionPitch = worldAngles.x + (desiredXRot - worldAngles.x) * deltaTime/* * 10.0f*/; Limit(m_actionPitch, -m_maxPitchAngle * 2.0f, m_maxPitchAngle * 2.0f); } // ---------------------------- Roll ---------------------------- float rollSpeed = GetRollSpeed(); rollSpeed *= deltaTime; rollSpeed = (float)__fsel(absDiff - rollSpeed, rollSpeed, absDiff); float roll =(float) __fsel(dirDiff.z, -rollSpeed, rollSpeed); float speedPerUnit = 1.5f; float desiredRollSpeed = absDiff * speedPerUnit * (float)__fsel(dirDiff.z, 1.0f, -1.0f); desiredRollSpeed = -m_actionYaw * 2.5f; desiredRollSpeed += m_steeringDamage.y; m_actionRoll = m_actionRoll + deltaTime * (desiredRollSpeed - m_actionRoll); Limit(m_actionRoll, -m_maxRollAngle + m_steeringDamage.y, m_maxRollAngle - m_steeringDamage.y); m_actionRoll *= m_rollDamping; // ---------------------------- Roll ---------------------------- // ---------------------------- Convert and apply ---------------------------- Ang3 angles(m_actionPitch, m_actionRoll, worldAngles.z + deltaTime * m_actionYaw); pe_params_pos paramPos; paramPos.q.SetRotationXYZ(angles); paramPos.q.Normalize(); IPhysicalEntity * pPhysicalEntity = GetPhysics(); pPhysicalEntity->SetParams(¶mPos, 1); pe_action_set_velocity vel; vel.v = m_CurrentVel + m_netPosAdjust; pPhysicalEntity->Action(&vel, 1); // ---------------------------- Convert and apply ---------------------------- m_rpmScale = max(0.2f, cry_fabsf(m_CurrentSpeed / m_maxSpeed)); }