//------------------------------------------------------------------ void CLam::AdjustLaserFPDirection(CItem* parent, Vec3 &dir, Vec3 &pos) { pos = parent->GetSlotHelperPos(eIGS_FirstPerson,m_laserHelperFP.c_str(),true); Quat lamRot = Quat(parent->GetSlotHelperRotation(eIGS_FirstPerson,m_laserHelperFP.c_str(),true)); dir = -lamRot.GetColumn0(); if(!m_lamparams.isLamRifle) dir = lamRot.GetColumn1(); CActor *pActor = parent->GetOwnerActor(); IMovementController * pMC = pActor ? pActor->GetMovementController() : NULL; if (pMC) { SMovementState info; pMC->GetMovementState(info); CWeapon* pWep = static_cast<CWeapon*>(parent->GetIWeapon()); if(pWep && (pWep->IsReloading() || (!pActor->CanFire() && !pWep->IsZoomed()))) return; if(dir.Dot(info.fireDirection)<0.985f) return; CCamera& camera = gEnv->pSystem->GetViewCamera(); pos = camera.GetPosition(); dir = camera.GetMatrix().GetColumn1(); dir.Normalize(); } }
void CAnimatedCharacter::RefreshAnimTarget() { if (m_pMannequinAGState) { IActorSystem* pActorSystem = CCryAction::GetCryAction()->GetIActorSystem(); assert(pActorSystem != NULL); IActor* pActor = pActorSystem->GetActor(GetEntity()->GetId()); IMovementController* pMovementController = pActor->GetMovementController(); m_pAnimTarget = pMovementController->GetExactPositioningTarget(); } }
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 CObstructionCheck::DoCheck( IActor* pOwnerActor, EntityId objectId ) { //Still waiting for last one, skip new one if (m_queuedPrimitiveId != 0) return; IMovementController* pMovementController = pOwnerActor ? pOwnerActor->GetMovementController() : NULL; if (pMovementController) { SMovementState movementState; pMovementController->GetMovementState(movementState); primitives::cylinder cylPrimitive; cylPrimitive.axis = movementState.eyeDirection; cylPrimitive.center = movementState.eyePosition - Vec3(0.0f, 0.0f, 0.15f) + (movementState.eyeDirection * 0.4f); cylPrimitive.hh = 0.6f; cylPrimitive.r = 0.25f; IEntity* pObjectEntity = gEnv->pEntitySystem->GetEntity(objectId); IPhysicalEntity* pObjectPhysics = pObjectEntity ? pObjectEntity->GetPhysics() : NULL; const int collisionEntityTypes = ent_static | ent_terrain | ent_rigid | ent_sleeping_rigid; int count = 0; IPhysicalEntity* skipList[3]; if(pOwnerActor) { skipList[count++] = pOwnerActor->GetEntity()->GetPhysics(); ICharacterInstance* pCharInstance = pOwnerActor->GetEntity()->GetCharacter(0); ISkeletonPose* pSkeletonPose(NULL); if(pCharInstance && (pSkeletonPose = pCharInstance->GetISkeletonPose())) { PREFAST_SUPPRESS_WARNING(6386); // fits in skiplist skipList[count++] = pSkeletonPose->GetCharacterPhysics(); } } if(pObjectPhysics) { skipList[count++] = pObjectPhysics; } m_queuedPrimitiveId = g_pGame->GetIntersectionTester().Queue(IntersectionTestRequest::HighestPriority, IntersectionTestRequest(cylPrimitive.type, cylPrimitive, ZERO, collisionEntityTypes, 0, geom_colltype0|geom_colltype_player, &skipList[0], count), functor(*this, &PickAndThrow::CObstructionCheck::IntersectionTestComplete)); } }
//------------------------------------------------------------------------ bool CPlant::GetPlantingParameters(Vec3& pos, Vec3& dir, Vec3& vel) const { // returns true if firing is allowed const float fBackwardAdjustment = 0.4f; //To ensure we throw from within our capsule - avoid throwing through walls if (CActor *pActor = m_pWeapon->GetOwnerActor()) { IMovementController *pMC = pActor->GetMovementController(); SMovementState info; if (pMC) pMC->GetMovementState(info); pos = m_pWeapon->GetWorldPos(); if (pMC) dir = info.eyeDirection; else dir = pActor->GetEntity()->GetWorldRotation().GetColumn1(); if(gEnv->bMultiplayer) { pos -= dir * fBackwardAdjustment; } if (IPhysicalEntity *pPE = pActor->GetEntity()->GetPhysics()) { pe_status_dynamics sv; if (pPE->GetStatus(&sv)) { if (sv.v.len2()>0.01f) { float dot=sv.v.GetNormalized().Dot(dir); if (dot<0.0f) dot=0.0f; vel=sv.v*dot; } } } return true; } return false; }
//-------------------------------------------------------- EntityId CMelee::GetNearestTarget() { CActor* pOwnerActor = m_pWeapon->GetOwnerActor(); if(pOwnerActor == NULL || (gEnv->bMultiplayer && m_slideKick)) return 0; CRY_ASSERT(pOwnerActor->IsClient()); IMovementController* pMovementController = pOwnerActor->GetMovementController(); if (!pMovementController) return 0; SMovementState moveState; pMovementController->GetMovementState(moveState); const Vec3 playerDir = moveState.aimDirection; const Vec3 playerPos = moveState.eyePosition; const float range = g_pGameCVars->pl_melee.melee_snap_target_select_range; const float angleLimit = cos_tpl(DEG2RAD(g_pGameCVars->pl_melee.melee_snap_angle_limit)); return m_collisionHelper.GetBestAutoAimTargetForUser(pOwnerActor->GetEntityId(), playerPos, playerDir, range, angleLimit); }
Vec3 CSpammer::GetWeaponDirection(const Vec3& firingPosition, const Vec3& probableHit) const { Vec3 direction(ZERO); if(gEnv->bServer) { CActor* pOwnerActor = m_pWeapon->GetOwnerActor(); IMovementController* pMC = pOwnerActor ? pOwnerActor->GetMovementController() : NULL; if (pMC) { SMovementState state; pMC->GetMovementState(state); direction = state.aimDirection; } else { return GetFiringDir(probableHit, firingPosition); } } return direction; }
//------------------------------------------------------------------------ bool CGameRules::OnInitiate(SHostMigrationInfo &hostMigrationInfo, uint32 &state) { if (!g_pGame->GetIGameFramework()->ShouldMigrateNub(hostMigrationInfo.m_session)) { return true; } CryLog("[Host Migration]: CGameRules::OnInitiate() Saving character for host migration started"); m_hostMigrationClientHasRejoined = false; IEntityScriptProxy *pScriptProxy = static_cast<IEntityScriptProxy *>(GetEntity()->GetProxy(ENTITY_PROXY_SCRIPT)); if (pScriptProxy) { if (string(pScriptProxy->GetState()) == "InGame") { m_hostMigrationTimeSinceGameStarted = (m_cachedServerTime - m_gameStartedTime); } } HostMigrationStopAddingPlayers(); if (gEnv->IsClient()) { if (!m_pHostMigrationParams) { m_pHostMigrationParams = new SHostMigrationClientRequestParams(); m_pHostMigrationClientParams = new SHostMigrationClientControlledParams(); } CPlayer *pPlayer = static_cast<CPlayer *>(g_pGame->GetIGameFramework()->GetClientActor()); if (pPlayer) { m_pHostMigrationClientParams->m_viewQuat = pPlayer->GetViewRotation(); m_pHostMigrationClientParams->m_position = pPlayer->GetEntity()->GetPos(); pe_status_living livStat; IPhysicalEntity *pPhysicalEntity = pPlayer->GetEntity()->GetPhysics(); if (pPhysicalEntity != NULL && (pPhysicalEntity->GetType() == PE_LIVING) && (pPhysicalEntity->GetStatus(&livStat) > 0)) { m_pHostMigrationClientParams->m_velocity = livStat.velUnconstrained; m_pHostMigrationClientParams->m_hasValidVelocity = true; CryLog(" velocity={%f,%f,%f}", m_pHostMigrationClientParams->m_velocity.x, m_pHostMigrationClientParams->m_velocity.y, m_pHostMigrationClientParams->m_velocity.z); } IMovementController *pMovementController = pPlayer->GetMovementController(); SMovementState movementState; pMovementController->GetMovementState(movementState); m_pHostMigrationClientParams->m_aimDirection = movementState.aimDirection; } else { CRY_ASSERT_MESSAGE(false, "Failed to find client actor when initiating a host migration"); gEnv->pNetwork->TerminateHostMigration(hostMigrationInfo.m_session); return false; } } g_pGame->SetHostMigrationState(CGame::eHMS_WaitingForPlayers); CCCPOINT(HostMigration_OnInitiate); return true; }
// returns true if firing is allowed bool CPlant::GetPlantingParameters(Vec3& pos, Vec3& dir, Vec3& vel) const { CActor *pActor = m_pWeapon->GetOwnerActor(); IMovementController *pMC = pActor?pActor->GetMovementController():0; SMovementState info; if (pMC) pMC->GetMovementState(info); if (m_pWeapon->GetStats().fp) pos = m_pWeapon->GetSlotHelperPos( eIGS_FirstPerson, m_plantparams.helper.c_str(), true); else if (pMC) pos = info.eyePosition+info.eyeDirection*0.25f; else pos = pActor->GetEntity()->GetWorldPos(); if (pMC) dir = info.eyeDirection; else dir = pActor->GetEntity()->GetWorldRotation().GetColumn1(); if (IPhysicalEntity *pPE=pActor->GetEntity()->GetPhysics()) { pe_status_dynamics sv; if (pPE->GetStatus(&sv)) { if (sv.v.len2()>0.01f) { float dot=sv.v.GetNormalized().Dot(dir); if (dot<0.0f) dot=0.0f; vel=sv.v*dot; } } } // if the ammo should be placed (claymore/mine) rather than thrown forward (c4), check if we can do so... if(m_plantparams.place_on_ground) { ray_hit hit; static const int objTypes = ent_static | ent_terrain; static const unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any; static IPhysicalEntity* pSkipEnts[10]; int nskip = CSingle::GetSkipEntities(m_pWeapon, pSkipEnts, 10); int res = gEnv->pPhysicalWorld->RayWorldIntersection(pos, 2.0f * dir, objTypes, flags, &hit, 1, pSkipEnts, nskip); if(!res) return false; else { // check surface normal - must be close to up if(hit.n.z < 0.8f) return false; // special case to stop stacking of claymores/mines (they are static so are hit by the ray) if(hit.pCollider && hit.pCollider->GetiForeignData() == PHYS_FOREIGN_ID_ENTITY) { IEntity * pEntity = (IEntity*)hit.pCollider->GetForeignData(PHYS_FOREIGN_ID_ENTITY); if(pEntity) { if(!m_pClaymoreClass) m_pClaymoreClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("claymoreexplosive"); if(!m_pAVMineClass) m_pAVMineClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("avexplosive"); if(pEntity->GetClass() == m_pClaymoreClass || pEntity->GetClass() == m_pAVMineClass) return false; } } // second check to see if there is another object in the way float hitDist = hit.dist; int res = gEnv->pPhysicalWorld->RayWorldIntersection(pos, 2.0f * dir, ent_all, flags, &hit, 1, pSkipEnts, nskip); if(res && hit.dist < hitDist-0.1f) { return false; } pos = hit.pt; } } return true; }
//-------------------------------------- void CThrow::DoDrop() { m_pWeapon->HideItem(true); if (m_throwableId) { IEntity *pEntity = gEnv->pEntitySystem->GetEntity(m_throwableId); if (pEntity) { IPhysicalEntity *pPE = pEntity->GetPhysics(); if (pPE && (pPE->GetType() == PE_RIGID || pPE->GetType() == PE_PARTICLE)) { Vec3 hit = GetProbableHit(WEAPON_HIT_RANGE); Vec3 pos = GetFiringPos(hit); CActor *pActor = m_pWeapon->GetOwnerActor(); IMovementController *pMC = pActor ? pActor->GetMovementController() : 0; if (pMC) { SMovementState info; pMC->GetMovementState(info); float speed = 2.5f; CPlayer *pPlayer = static_cast<CPlayer *>(m_pWeapon->GetOwnerActor()); if(info.aimDirection.z < -0.1f) { if(pPlayer) { if(SPlayerStats *pStats = static_cast<SPlayerStats *>(pPlayer->GetActorStats())) { if(pStats->grabbedHeavyEntity) { speed = 4.0f; } } } } if(CheckForIntersections(pPE, info.eyeDirection)) { Matrix34 newTM = pEntity->GetWorldTM(); newTM.SetTranslation(newTM.GetTranslation() - (info.eyeDirection * 0.4f)); pEntity->SetWorldTM(newTM, ENTITY_XFORM_POS); pe_action_set_velocity asv; asv.v = (-info.eyeDirection * speed); pPE->Action(&asv); } else { pe_action_set_velocity asv; asv.v = (info.eyeDirection * speed); pPE->Action(&asv); } SEntityEvent entityEvent; entityEvent.event = ENTITY_EVENT_PICKUP; entityEvent.nParam[0] = 0; if (pPlayer) { entityEvent.nParam[1] = pPlayer->GetEntityId(); } entityEvent.fParam[0] = speed; pEntity->SendEvent( entityEvent ); } } } if (m_throwableAction) { m_throwableAction->execute(m_pWeapon); } } }
void CMountedGunController::Update(EntityId mountedGunID, float frameTime) { CRY_ASSERT_MESSAGE(m_pControlledPlayer, "Controlled player not initialized"); CItem* pMountedGun = static_cast<CItem*>(gEnv->pGame->GetIGameFramework()->GetIItemSystem()->GetItem(mountedGunID)); bool canUpdateMountedGun = (pMountedGun != NULL) && (pMountedGun->GetStats().mounted); if (canUpdateMountedGun) { IMovementController * pMovementController = m_pControlledPlayer->GetMovementController(); assert(pMovementController); SMovementState info; pMovementController->GetMovementState(info); IEntity* pMountedGunEntity = pMountedGun->GetEntity(); const Matrix34& lastMountedGunWorldTM = pMountedGunEntity->GetWorldTM(); Vec3 desiredAimDirection = info.aimDirection.GetNormalized(); // AI can switch directions too fast, prevent snapping if(!m_pControlledPlayer->IsPlayer()) { const Vec3 currentDir = lastMountedGunWorldTM.GetColumn1(); const float dot = clamp(currentDir.Dot(desiredAimDirection), -1.0f, 1.0f); const float reqAngle = cry_acosf(dot); const float maxRotSpeed = 2.0f; const float maxAngle = frameTime * maxRotSpeed; if(fabs(reqAngle) > maxAngle) { const Vec3 axis = currentDir.Cross(desiredAimDirection); if(axis.GetLengthSquared() > 0.001f) // current dir and new dir are enough different { desiredAimDirection = currentDir.GetRotated(axis.GetNormalized(),sgn(reqAngle)*maxAngle); } } } bool isUserClient = m_pControlledPlayer->IsClient(); IEntity* pMountedGunParentEntity = pMountedGunEntity->GetParent(); IVehicle *pVehicle = NULL; if(pMountedGunParentEntity && m_pControlledPlayer) pVehicle = m_pControlledPlayer->GetLinkedVehicle(); CRecordingSystem* pRecordingSystem = g_pGame->GetRecordingSystem(); //For client update always, for others only when there is notable change if (!pVehicle && (isUserClient || (!desiredAimDirection.IsEquivalent(lastMountedGunWorldTM.GetColumn1(), 0.003f)))) { Quat rotation = Quat::CreateRotationVDir(desiredAimDirection, 0.0f); pMountedGunEntity->SetRotation(rotation); if (isUserClient && pRecordingSystem) { // Only record the gun position if you're using the gun. pRecordingSystem->OnMountedGunRotate(pMountedGunEntity, rotation); } } const Vec3 vInitialAimDirection = GetMountDirection(pMountedGun, pMountedGunParentEntity); assert( vInitialAimDirection.IsUnit() ); //Adjust gunner position and animations UpdateGunnerLocation(pMountedGun, pMountedGunParentEntity, vInitialAimDirection); const float aimrad = Ang3::CreateRadZ(Vec2(vInitialAimDirection),Vec2(-desiredAimDirection)); const float pitchLimit = sin_tpl(DEG2RAD(30.0f)); const float animHeight = fabs_tpl(clamp(desiredAimDirection.z * (float)__fres(pitchLimit), -1.0f, 1.0f)); const float aimUp = (float)__fsel(-desiredAimDirection.z, 0.0f, animHeight); const float aimDown = (float)__fsel(desiredAimDirection.z, 0.0f, animHeight); if (pRecordingSystem) { pRecordingSystem->OnMountedGunUpdate(m_pControlledPlayer, aimrad, aimUp, aimDown); } if(!m_pControlledPlayer->IsThirdPerson()) { UpdateFirstPersonAnimations(pMountedGun, desiredAimDirection); } if(m_pMovementAction) { const float aimUpParam = aimUp; const float aimDownParam = aimDown; const float aimMovementParam = CalculateAnimationTime(aimrad); m_pMovementAction->SetParam(MountedGunCRCs.aimUpParam, aimUpParam); m_pMovementAction->SetParam(MountedGunCRCs.aimDownParam, aimDownParam); m_pMovementAction->SetParam(MountedGunCRCs.aimMovementParam, aimMovementParam); } UpdateIKMounted(pMountedGun); } }
//------------------------------------------------------------------------ void CMelee::Update(float frameTime, uint32 frameId) { FUNCTION_PROFILER( GetISystem(), PROFILE_GAME ); bool requireUpdate = false; if (m_attacking) { requireUpdate = true; if (m_delayTimer > 0.0f) { m_delayTimer -= frameTime; if (m_delayTimer <= 0.0f) { m_delayTimer = 0.0f; } } else { if (!m_attacked) { m_attacked = true; CActor *pActor = m_pWeapon->GetOwnerActor(); if(!pActor) { return; } Vec3 pos(ZERO); Vec3 dir(ZERO); IMovementController *pMC = pActor->GetMovementController(); if (!pMC) { return; } float strength = 1.0f;//pActor->GetActorStrength(); SMovementState info; pMC->GetMovementState(info); pos = info.eyePosition; dir = info.eyeDirection; if (!PerformRayTest(pos, dir, strength, false)) if(!PerformCylinderTest(pos, dir, strength, false)) { ApplyCameraShake(false); } m_ignoredEntity = 0; m_meleeScale = 1.0f; m_pWeapon->RequestMeleeAttack(m_pWeapon->GetMeleeFireMode() == this, pos, dir); } } } if (requireUpdate) { m_pWeapon->RequireUpdate(eIUS_FireMode); } }
void CHeavyMountedWeapon::PerformRipOff(CActor* pOwner) { ExitZoom(true); UnlinkMountedGun(); SetUnMountedConfiguration(); // This needs to come after the call to UnlinkMountedGun otherwise killcam doesn't work properly AttachToHand(true); StopFire(); Physicalize(false, false); if (pOwner) { HandleHeavyWeaponPro(*pOwner); float speedOverride = 1.0f; if(pOwner->IsPlayer()) { CPlayer* pOwnerPlayer = static_cast<CPlayer*>(pOwner); speedOverride = pOwnerPlayer->GetModifiableValues().GetValue(kPMV_HeavyWeaponRipOffSpeedOverride); } PlayAction(GetFragmentIds().rip_off, 0, false, eIPAF_Default, speedOverride); m_rippingOff = true; m_stats.dropped = false; DoRipOffPrompt(GetOwnerId(), false); int timeDelay = GetCurrentAnimationTime(eIGS_Owner); timeDelay = (timeDelay > 0) ? timeDelay : 2000; int removeViewLimitDelay = int(timeDelay * 0.65f); GetScheduler()->TimerAction(timeDelay, CSchedulerAction<EndRippingOff>::Create(EndRippingOff(this)), false); GetScheduler()->TimerAction(removeViewLimitDelay, CSchedulerAction<RemoveViewLimitsAction>::Create(RemoveViewLimitsAction(this)), false); if(!pOwner->IsThirdPerson() && !(m_stats.viewmode&eIVM_FirstPerson)) { SetViewMode(eIVM_FirstPerson); } //Lock view in place during rip off SActorParams ¶ms = pOwner->GetActorParams(); Vec3 limitDir(ZERO); bool bUseMovementState = true; if (pOwner->IsClient() && (g_pGame->GetHostMigrationState() != CGame::eHMS_NotMigrating)) { // If this happens during a host migration, our aim direction may not have made it into the movement // controller yet, get it from the saved migration params instead const CGameRules::SHostMigrationClientControlledParams *pHostMigrationParams = g_pGame->GetGameRules()->GetHostMigrationClientParams(); if (pHostMigrationParams) { limitDir = pHostMigrationParams->m_aimDirection; bUseMovementState = false; } } if (bUseMovementState) { IMovementController *pMovementController = pOwner->GetMovementController(); SMovementState state; pMovementController->GetMovementState(state); limitDir = state.aimDirection; } params.viewLimits.SetViewLimit(limitDir, 0.01f, 0.01f, 0.01f, 0.01f, SViewLimitParams::eVLS_Item); pOwner->SetSpeedMultipler(SActorParams::eSMR_Item, 0.0f); if(!gEnv->bMultiplayer) pOwner->LockInteractor(GetEntityId(), false); } TriggerRespawn(); if (pOwner) { if (CRecordingSystem* pRecordingSystem = g_pGame->GetRecordingSystem()) { pRecordingSystem->OnWeaponRippedOff(this); } BATTLECHATTER(BC_Ripoff, GetOwnerId()); if(pOwner->IsClient()) { g_pGame->GetPersistantStats()->IncrementClientStats(EIPS_RipOffMountedWeapon); ClearInputFlag(eWeaponAction_Zoom); } } else { //--- If ripped off without an actor we should finish instantly m_rippingOff = false; m_rippedOff = true; } }
void CHUD::IndicateDamage(EntityId weaponId, Vec3 direction, bool onVehicle) { Vec3 vlookingDirection = FORWARD_DIRECTION; CGameFlashAnimation* pAnim = NULL; CActor *pPlayerActor = static_cast<CActor *>(gEnv->pGame->GetIGameFramework()->GetClientActor()); if(!pPlayerActor) return; if(IEntity *pEntity = gEnv->pEntitySystem->GetEntity(weaponId)) { if(pEntity->GetClass() == CItem::sGaussRifleClass) { m_animRadarCompassStealth.Invoke("GaussHit"); m_animPlayerStats.Invoke("GaussHit"); } } IMovementController *pMovementController = NULL; float fFront = 0.0f; float fRight = 0.0f; if(!onVehicle) { if(!g_pGameCVars->hud_chDamageIndicator) return; pMovementController = pPlayerActor->GetMovementController(); pAnim = m_pHUDCrosshair->GetFlashAnim(); } else if(IVehicle *pVehicle = pPlayerActor->GetLinkedVehicle()) { pMovementController = pVehicle->GetMovementController(); pAnim = &(m_pHUDVehicleInterface->m_animStats); } if(pMovementController && pAnim) { SMovementState sMovementState; pMovementController->GetMovementState(sMovementState); vlookingDirection = sMovementState.eyeDirection; } else return; if(!onVehicle) { //we use a static/world damage indicator and add the view rotation to the indicator animation now fFront = -(Vec3(0,-1,0).Dot(direction)); fRight = -(Vec3(-1, 0, 0).Dot(direction)); } else { Vec3 vRightDir = vlookingDirection.Cross(Vec3(0,0,1)); fFront = -vlookingDirection.Dot(direction); fRight = -vRightDir.Dot(direction); } if(fabsf(fFront) > 0.35f) { if(fFront > 0) pAnim->Invoke("setDamageDirection", 1); else pAnim->Invoke("setDamageDirection", 3); } if(fabsf(fRight) > 0.35f) { if(fRight > 0) pAnim->Invoke("setDamageDirection", 2); else pAnim->Invoke("setDamageDirection", 4); } if(fFront == 0.0f && fRight == 0.0f) { pAnim->Invoke("setDamageDirection", 1); pAnim->Invoke("setDamageDirection", 2); pAnim->Invoke("setDamageDirection", 3); pAnim->Invoke("setDamageDirection", 4); } m_fDamageIndicatorTimer = gEnv->pTimer->GetFrameStartTime().GetSeconds(); }
bool CDialogActorContext::DoLocalPlayerChecks(const float dt) { // don't check this every frame, but only every .2 secs m_checkPlayerTimeOut-=dt; if (m_checkPlayerTimeOut <= 0.0f) { do // a dummy loop to use break { float awareDistance; float awareDistanceSq; float awareAngle; m_pSession->GetPlayerAwarenessValues(awareDistance, awareAngle); awareDistanceSq=awareDistance*awareDistance; m_checkPlayerTimeOut = PLAYER_CHECKTIME; const float spotAngleCos = cos_tpl(DEG2RAD(awareAngle)); const CDialogSession::TActorContextMap& contextMap = m_pSession->GetAllContexts(); if (contextMap.size() == 1 && contextMap.begin()->first == m_actorID) { m_bIsAware = true; break; } // early out, when we don't have to do any checks if (awareDistance <= 0.0f && awareAngle <= 0.0f) { m_bIsAware = true; break; } IEntity* pThisEntity = m_pSession->GetActorEntity(m_actorID); if (!pThisEntity) { assert (false); m_bIsAware = true; break; } IMovementController* pMC = (m_pIActor != NULL) ? m_pIActor->GetMovementController() : NULL; if (!pMC) { assert (false); m_bIsAware = true; break; } SMovementState moveState; pMC->GetMovementState(moveState); Vec3 viewPos = moveState.eyePosition; Vec3 viewDir = moveState.eyeDirection; viewDir.z = 0.0f; viewDir.NormalizeSafe(); // check the player's position // check the player's view direction AABB groupBounds; groupBounds.Reset(); CDialogSession::TActorContextMap::const_iterator iter = contextMap.begin(); CDialogScript::SActorSet lookingAt = 0; while (iter != contextMap.end()) { if (iter->first != m_actorID) { IEntity* pActorEntity = m_pSession->GetActorEntity(iter->first); if (pActorEntity) { Vec3 vEntityPos = pActorEntity->GetWorldPos(); AABB worldBounds; pActorEntity->GetWorldBounds(worldBounds); groupBounds.Add(worldBounds); // calc if we look at it somehow Vec3 vEntityDir = vEntityPos - viewPos; vEntityDir.z = 0.0f; vEntityDir.NormalizeSafe(); if (viewDir.IsUnit() && vEntityDir.IsUnit()) { const float dot = clamp_tpl(viewDir.Dot(vEntityDir),-1.0f,+1.0f); // clamping should not be needed if (spotAngleCos <= dot) lookingAt.SetActor(iter->first); DiaLOG::Log(DiaLOG::eDebugC, "Angle to actor %d is %f deg", iter->first, RAD2DEG(acos_tpl(dot))); } } } ++iter; } const float distanceSq = pThisEntity->GetWorldPos().GetSquaredDistance(groupBounds.GetCenter()); CCamera& camera=gEnv->pSystem->GetViewCamera(); const bool bIsInAABB = camera.IsAABBVisible_F(groupBounds); const bool bIsInRange = distanceSq <= awareDistanceSq; const bool bIsLooking = contextMap.empty() || lookingAt.NumActors() > 0; m_bIsAwareLooking = awareAngle <= 0.0f || (bIsInAABB || bIsLooking); m_bIsAwareInRange = awareDistance <= 0.0f || bIsInRange; m_bIsAware = m_bIsAwareLooking && m_bIsAwareInRange; DiaLOG::Log(DiaLOG::eDebugB, "[DIALOG] LPC: %s awDist=%f awAng=%f AABBVis=%d IsLooking=%d InRange=%d [Distance=%f LookingActors=%d] Final=%saware", m_pSession->GetDebugName(), awareDistance, awareAngle, bIsInAABB, bIsLooking, bIsInRange, sqrt_tpl(distanceSq), lookingAt.NumActors(), m_bIsAware ? "" : "not "); } while (false); } if (m_bIsAware) { m_playerAwareTimeOut = m_pSession->GetPlayerAwarenessGraceTime(); } else { m_playerAwareTimeOut-= dt; if (m_playerAwareTimeOut <= 0) { return false; } } return true; }
//------------------------------------------------------------------------ void CMelee::Update(float frameTime, uint frameId) { FUNCTION_PROFILER( GetISystem(), PROFILE_GAME ); bool requireUpdate = false; if (m_attacking) { requireUpdate = true; if (m_delayTimer>0.0f) { m_delayTimer-=frameTime; if (m_delayTimer<=0.0f) m_delayTimer=0.0f; } else { if (!m_attacked) { m_attacked = true; CActor *pActor = m_pWeapon->GetOwnerActor(); if(!pActor) return; Vec3 pos(ZERO); Vec3 dir(ZERO); IMovementController * pMC = pActor->GetMovementController(); if (!pMC) return; float strength = 1.0f;//pActor->GetActorStrength(); if (pActor->GetActorClass() == CPlayer::GetActorClassType()) { CPlayer *pPlayer = (CPlayer *)pActor; if (CNanoSuit *pSuit = pPlayer->GetNanoSuit()) { ENanoMode curMode = pSuit->GetMode(); if (curMode == NANOMODE_STRENGTH) { strength = pActor->GetActorStrength(); strength = strength * (1.0f + 2.0f * pSuit->GetSlotValue(NANOSLOT_STRENGTH)* STRENGTH_MULT); if(!pPlayer->IsPlayer() && g_pGameCVars->g_difficultyLevel < 4) strength *= g_pGameCVars->g_AiSuitStrengthMeleeMult; } } } SMovementState info; pMC->GetMovementState(info); pos = info.eyePosition; dir = info.eyeDirection; if (!PerformRayTest(pos, dir, strength, false)) if(!PerformCylinderTest(pos, dir, strength, false)) ApplyCameraShake(false); m_ignoredEntity = 0; m_meleeScale = 1.0f; m_pWeapon->RequestMeleeAttack(m_pWeapon->GetMeleeFireMode()==this, pos, dir); } } } if (requireUpdate) m_pWeapon->RequireUpdate(eIUS_FireMode); }
void CPlayerRotation::Process(IItem* pCurrentItem, const SActorFrameMovementParams& movement, const SAimAccelerationParams& verticalAcceleration, float frameTime) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); // reset to the new impulse. m_angularImpulseDelta = m_angularImpulse; m_deltaAngles = movement.deltaAngles; PR_CHECKQNAN_FLT(m_deltaAngles); // Store the previous rotation to get the correct rotation for linked actors. const Quat previousBaseQuat = m_baseQuat; const Quat previousViewQuat = m_viewQuat; ProcessForcedLookDirection(m_viewQuatFinal, frameTime); ProcessAngularImpulses( frameTime ); ProcessLeanAndPeek( movement ); ProcessNormalRoll( frameTime ); bool shouldProcessTargetAssistance = ShouldProcessTargetAssistance(); if (shouldProcessTargetAssistance) { ProcessTargetAssistance( pCurrentItem ); } #if TALOS if(stricmp(g_pGameCVars->pl_talos->GetString(), m_player.GetEntity()->GetName()) == 0) { IMovementController* pMovementController = m_player.GetMovementController(); CRY_ASSERT(pMovementController); SMovementState moveState; pMovementController->GetMovementState(moveState); Vec3 playerView[4] = { m_viewQuat.GetColumn0(), // Right m_viewQuat.GetColumn1(), // Forward m_viewQuat.GetColumn2(), // Up moveState.eyePosition // Pos }; GetTalosInput(this, m_player, m_deltaAngles.x, m_deltaAngles.z, playerView, frameTime); } #endif float minAngle,maxAngle; GetStanceAngleLimits(verticalAcceleration, pCurrentItem, minAngle, maxAngle); ClampAngles( minAngle, maxAngle ); ProcessNormal( frameTime ); if(shouldProcessTargetAssistance) { IVehicle* pVehicle = m_player.GetLinkedVehicle(); if (pVehicle && GetCurrentItem(true)) { if (m_deltaAngles.x!=0.f) pVehicle->OnAction(eVAI_RotatePitchAimAssist, eAAM_Always, m_deltaAngles.x, m_player.GetEntity()->GetId()); if (m_deltaAngles.z!=0.f) pVehicle->OnAction(eVAI_RotateYawAimAssist, eAAM_Always, m_deltaAngles.z, m_player.GetEntity()->GetId()); } } //update freelook when linked to an entity ProcessLinkedState(m_player.m_linkStats, previousBaseQuat, previousViewQuat); //Recoil/Zoom sway offset for local player ProcessFinalViewEffects( minAngle, maxAngle ); m_frameViewAnglesOffset.Set(0.0f, 0.0f, 0.0f); m_forceLookVector.zero(); m_externalAngles.Set(0.f, 0.f, 0.f); NormalizeQuats(); }
void CPlayerRotation::ProcessTargetAssistance( IItem* pCurrentPlayerItem ) { // aim assistance float targetAimAssistAngleFollowH; float targetAimAssistAngleFollowV; float targetAimAssistAngleScale; IPlayerInput * pIPlayerInput = m_player.GetPlayerInput(); float absInput = 0.0f; float aimAssistPowerFactor = 1.0f; bool isUsingDedicatedInput = gEnv->IsDedicated(); #if (USE_DEDICATED_INPUT) isUsingDedicatedInput |= g_pGameCVars->g_playerUsesDedicatedInput ? true : false; #endif if(pIPlayerInput && !isUsingDedicatedInput) { CRY_ASSERT(pIPlayerInput->GetType() == IPlayerInput::PLAYER_INPUT); CPlayerInput * pPlayerInput = static_cast<CPlayerInput*>(pIPlayerInput); const Ang3 rawDeltas = pPlayerInput->GetRawControllerInput(); absInput = min((fabsf(rawDeltas.x) + fabsf(rawDeltas.z)) * 1.4f, 1.0f); aimAssistPowerFactor = 2.0f - absInput; } //Gather weapon info before processing target aim assistance bool playerWeaponIsRequestingSnap = false; CWeapon* pWeapon = GetCurrentWeapon( pCurrentPlayerItem ); if (pWeapon) { playerWeaponIsRequestingSnap = pWeapon->ShouldSnapToTarget(); } IMovementController* pMovementController = m_player.GetMovementController(); CRY_ASSERT(pMovementController); SMovementState moveState; pMovementController->GetMovementState(moveState); Vec3 playerView[4] = { m_viewQuat.GetColumn0(), // Right m_viewQuat.GetColumn1(), // Forward m_viewQuat.GetColumn2(), // Up moveState.eyePosition // Pos }; IVehicle* pVehicle = m_player.GetLinkedVehicle(); if (pVehicle) { Vec3 up(0.f,0.f,1.f); playerView[1] = moveState.eyeDirection; // Forward playerView[0] = (playerView[1].cross(up)).GetNormalizedSafe(); // Right playerView[2] = playerView[0].cross(playerView[1]); // Up } float fZoomAmount = 0.0f; TargetAimAssistance(pWeapon, targetAimAssistAngleFollowH, targetAimAssistAngleFollowV, targetAimAssistAngleScale, fZoomAmount, playerView); targetAimAssistAngleScale = powf(targetAimAssistAngleScale, aimAssistPowerFactor); //TODO: Fix so it's not using auto aim unless selected float fFollowAssistScale = (absInput * (1.0f - fZoomAmount)) + min(absInput * fZoomAmount * __fres(g_pGameCVars->aim_assistInputForFullFollow_Ironsight), 1.0f); m_deltaAngles.z = (m_deltaAngles.z * targetAimAssistAngleScale) + (absInput * targetAimAssistAngleFollowH); m_deltaAngles.x = (m_deltaAngles.x * targetAimAssistAngleScale) + (absInput * targetAimAssistAngleFollowV); const bool snapToTarget = (!gEnv->bMultiplayer && playerWeaponIsRequestingSnap && !m_snap_target_dir.IsZero()); const EntityId closeCombatSnapTargetId = g_pGame->GetAutoAimManager().GetCloseCombatSnapTarget(); if (closeCombatSnapTargetId) { Vec3 snapDirection = GetCloseCombatSnapTargetDirection(closeCombatSnapTargetId); if (!snapDirection.IsZero()) { const float blendSpeed = clamp_tpl( g_pGameCVars->pl_melee.melee_snap_blend_speed , 0.0f, 1.0f); m_deltaAngles.z = -asin_tpl(snapDirection * m_viewQuat.GetColumn0()) * blendSpeed; m_deltaAngles.x = asin_tpl(snapDirection * m_viewQuat.GetColumn2()) * blendSpeed; } } else if (snapToTarget) { const float zoomInTime = pWeapon->GetZoomInTime(); const float blendFactor = clamp_tpl(pow_tpl((1.0f-zoomInTime),2.0f), 0.0f, 1.0f); m_deltaAngles.z = -asin_tpl(m_snap_target_dir * m_viewQuat.GetColumn0()) * blendFactor; m_deltaAngles.x = asin_tpl(m_snap_target_dir * m_viewQuat.GetColumn2()) * blendFactor; } m_currently_snapping = playerWeaponIsRequestingSnap; #if !defined(_RELEASE) if(g_pGameCVars->ctrlr_OUTPUTDEBUGINFO) { float white[] = {1,1,1,1}; gEnv->pRenderer->Draw2dLabel( 20, 100, 1.4f, white, false, "Aim Acceleration & Assist\n absInput: %.6f", absInput ); } #endif }
//------------------------------------------------------------------------ bool CGameRules::OnInitiate(SHostMigrationInfo& hostMigrationInfo, uint32& state) { if (!g_pGame->GetIGameFramework()->ShouldMigrateNub(hostMigrationInfo.m_session)) { return true; } CryLog("[Host Migration]: CGameRules::OnInitiate() Saving character for host migration started"); m_hostMigrationClientHasRejoined = false; IEntityScriptProxy* pScriptProxy = static_cast<IEntityScriptProxy*>(GetEntity()->GetProxy(ENTITY_PROXY_SCRIPT)); if (pScriptProxy) { if (string(pScriptProxy->GetState()) == "InGame") { m_hostMigrationTimeSinceGameStarted = (m_cachedServerTime - m_gameStartedTime); } } HostMigrationStopAddingPlayers(); if (gEnv->IsClient()) { if (!m_pHostMigrationParams) { m_pHostMigrationParams = new SHostMigrationClientRequestParams(); m_pHostMigrationClientParams = new SHostMigrationClientControlledParams(); } IActor *pPlayer = g_pGame->GetIGameFramework()->GetClientActor(); if (pPlayer) { m_pHostMigrationClientParams->m_viewQuat = pPlayer->GetViewRotation(); m_pHostMigrationClientParams->m_position = pPlayer->GetEntity()->GetPos(); pe_status_living livStat; IPhysicalEntity *pPhysicalEntity = pPlayer->GetEntity()->GetPhysics(); if (pPhysicalEntity != NULL && (pPhysicalEntity->GetType() == PE_LIVING) && (pPhysicalEntity->GetStatus(&livStat) > 0)) { m_pHostMigrationClientParams->m_velocity = livStat.velUnconstrained; m_pHostMigrationClientParams->m_hasValidVelocity = true; CryLog(" velocity={%f,%f,%f}", m_pHostMigrationClientParams->m_velocity.x, m_pHostMigrationClientParams->m_velocity.y, m_pHostMigrationClientParams->m_velocity.z); } IInventory *pInventory = pPlayer->GetInventory(); m_pHostMigrationClientParams->m_numExpectedItems = 0; int numAmmoTypes = 0; m_pHostMigrationClientParams->m_pAmmoParams = new SHostMigrationClientControlledParams::SAmmoParams[numAmmoTypes]; m_pHostMigrationClientParams->m_numAmmoParams = numAmmoTypes; /*CryLog(" player has %i different ammo types", numAmmoTypes); for (int i = 0; i < numAmmoTypes; ++ i) { IEntityClass *pAmmoType = pInventory->GetAmmoType(i); int ammoCount = pInventory->GetAmmoCount(pAmmoType); m_pHostMigrationClientParams->m_pAmmoParams[i].m_pAmmoClass = pAmmoType; m_pHostMigrationClientParams->m_pAmmoParams[i].m_count = ammoCount; CryLog(" %s : %i", pAmmoType->GetName(), ammoCount); }* EntityId holseredItemId = pInventory->GetHolsteredItem(); if (holseredItemId) { IEntity *pHolsteredEntity = gEnv->pEntitySystem->GetEntity(holseredItemId); if (pHolsteredEntity) { m_pHostMigrationClientParams->m_pHolsteredItemClass = pHolsteredEntity->GetClass(); } }*/ IMovementController *pMovementController = pPlayer->GetMovementController(); if(pMovementController) { SMovementState movementState; pMovementController->GetMovementState(movementState); m_pHostMigrationClientParams->m_aimDirection = movementState.aimDirection; } /*CItem *pItem = static_cast<CItem*>(pPlayer->GetCurrentItem()); if (pItem) { m_pHostMigrationClientParams->m_pSelectedItemClass = pItem->GetEntity()->GetClass(); CryLog(" currently using item '%s", pItem->GetEntity()->GetName()); }*/ } else { CRY_ASSERT_MESSAGE(false, "Failed to find client actor when initiating a host migration"); gEnv->pNetwork->TerminateHostMigration(hostMigrationInfo.m_session); return false; } } g_pGame->SetHostMigrationState(CGame::eHMS_WaitingForPlayers); CCCPOINT(HostMigration_OnInitiate); return true; }
//------------------------------------------------------------------------ void CItem::UpdateMounted(float frameTime) { IRenderAuxGeom* pAuxGeom = gEnv->pRenderer->GetIRenderAuxGeom(); if (!m_ownerId || !m_stats.mounted) return; CActor *pActor = GetOwnerActor(); if (!pActor) return; CheckViewChange(); if (true) { if (IsClient()) { ICharacterInstance *pCharacter = GetEntity()->GetCharacter(eIGS_FirstPerson); if (pCharacter && !m_idleAnimation[eIGS_FirstPerson].empty() && pCharacter->GetISkeletonAnim()->GetNumAnimsInFIFO(0)<1) PlayAction(m_idleAnimation[eIGS_FirstPerson], 0, true); } // need to explicitly update characters at this point // cause the entity system update occered earlier, with the last position for (int i=0; i<eIGS_Last; i++) { if (GetEntity()->GetSlotFlags(i)&ENTITY_SLOT_RENDER) { ICharacterInstance *pCharacter = GetEntity()->GetCharacter(i); if (pCharacter) { Matrix34 mloc = GetEntity()->GetSlotLocalTM(i,false); Matrix34 m34 = GetEntity()->GetWorldTM()*mloc; QuatT renderLocation = QuatT(m34); pCharacter->GetISkeletonPose()->SetForceSkeletonUpdate(9); pCharacter->SkeletonPreProcess(renderLocation, renderLocation, GetISystem()->GetViewCamera(),0x55 ); pCharacter->SetPostProcessParameter(renderLocation, renderLocation, 0, 0.0f, 0x55 ); } } } // f32 fColor[4] = {1,1,0,1}; // f32 g_YLine=60.0f; // gEnv->pRenderer->Draw2dLabel( 1,g_YLine, 1.3f, fColor, false, "Mounted Gun Code" ); //adjust the orientation of the gun based on the aim-direction SMovementState info; IMovementController* pMC = pActor->GetMovementController(); pMC->GetMovementState(info); Vec3 dir = info.aimDirection.GetNormalized(); Matrix34 tm = Matrix33::CreateRotationVDir(dir); Vec3 vGunXAxis=tm.GetColumn0(); if (pActor->GetLinkedVehicle()==0) { if (pMC) { if(!pActor->IsPlayer()) { // prevent snapping direction Vec3 currentDir = GetEntity()->GetWorldRotation().GetColumn1(); float dot = currentDir.Dot(dir); dot = CLAMP(dot,-1,1); float reqAngle = cry_acosf(dot); const float maxRotSpeed = 2.0f; float maxAngle = frameTime * maxRotSpeed; if(fabs(reqAngle) > maxAngle) { Vec3 axis = currentDir.Cross(dir); if(axis.GetLengthSquared()>0.001f) // current dir and new dir are enough different dir = currentDir.GetRotated(axis.GetNormalized(),sgn(reqAngle)*maxAngle); } } //adjust the orientation of the gun based on the aim-direction tm = Matrix33::CreateRotationVDir(dir); Vec3 vWPos=GetEntity()->GetWorldPos(); tm.SetTranslation(vWPos); GetEntity()->SetWorldTM(tm); //set the new orientation of the mounted gun vGunXAxis=tm.GetColumn0(); Vec3 vInitialAimDirection = m_stats.mount_dir; Matrix33 vInitialPlayerOrientation = Matrix33::CreateRotationVDir(vInitialAimDirection); assert( vInitialAimDirection.IsUnit() ); Vec3 newp; if (pActor->IsThirdPerson()) { //third person f32 dist = m_mountparams.body_distance*1.3f; Vec3 oldp = pActor->GetEntity()->GetWorldPos(); newp = GetEntity()->GetWorldPos()-vInitialAimDirection*dist; //mounted gun newp.z = oldp.z; } else { //first person f32 fMoveBack = (1.0f+(dir.z*dir.z*dir.z*dir.z*4.0f))*0.75f; f32 dist = m_mountparams.eye_distance*fMoveBack; Vec3 oldp = pActor->GetEntity()->GetWorldPos(); newp = GetEntity()->GetWorldPos()-dir*dist; //mounted gun //newp.z -= 0.75f; newp.z = oldp.z; } Matrix34 actortm(pActor->GetEntity()->GetWorldTM()); //if (pActor->IsThirdPerson()) actortm=vInitialPlayerOrientation; actortm.SetTranslation(newp); pActor->GetEntity()->SetWorldTM(actortm, ENTITY_XFORM_USER); pActor->GetAnimationGraphState()->SetInput("Action","gunnerMounted"); //f32 g_YLine=80.0f; //gEnv->pRenderer->Draw2dLabel( 1,g_YLine, 1.3f, fColor, false, "Mounted Gun Active for FP and AI" ); if (ICharacterInstance *pCharacter = pActor->GetEntity()->GetCharacter(0)) { ISkeletonAnim *pSkeletonAnim = pCharacter->GetISkeletonAnim(); assert(pSkeletonAnim); uint32 numAnimsLayer = pSkeletonAnim->GetNumAnimsInFIFO(0); for(uint32 i=0; i<numAnimsLayer; i++) { CAnimation &animation = pSkeletonAnim->GetAnimFromFIFO(0, i); if (animation.m_AnimParams.m_nFlags & CA_MANUAL_UPDATE) { f32 aimrad = Ang3::CreateRadZ(Vec2(vInitialAimDirection),Vec2(dir)); animation.m_fAnimTime = clamp_tpl(aimrad/gf_PI,-1.0f,+1.0f)*0.5f+0.5f; //if (pActor->IsThirdPerson()==0) //animation.m_fAnimTime=0.6f; //Ivo & Benito: high advanced future code. don't ask what it is //Benito - Not needed any more ;) //f32 g_YLine=100.0f; //gEnv->pRenderer->Draw2dLabel( 1,g_YLine, 1.3f, fColor, false, "AnimTime: %f MyAimAngle: %f deg:% distance:%f", animation.m_fAnimTime, aimrad, RAD2DEG(aimrad),m_mountparams.body_distance ); } } } m_stats.mount_last_aimdir = dir; } } if (ICharacterInstance* pCharInstance = pActor->GetEntity()->GetCharacter(0)) { if (ISkeletonAnim* pSkeletonAnim = pCharInstance->GetISkeletonAnim()) { OldBlendSpace ap; if (GetAimBlending(ap)) { pSkeletonAnim->SetBlendSpaceOverride(eMotionParamID_TurnSpeed, 0.5f + 0.5f * ap.m_turn, true); } } } UpdateIKMounted(pActor, vGunXAxis*0.1f); RequireUpdate(eIUS_General); } }
//------------------------------------------------------ void CSingleTG::UpdateAutoAim(float frameTime) { static IGameObjectSystem *pGameObjectSystem = gEnv->pGame->GetIGameFramework()->GetIGameObjectSystem(); CActor *pOwner = m_pWeapon->GetOwnerActor(); if(!pOwner || !pOwner->IsPlayer()) return; // todo: use crosshair/aiming dir IMovementController *pMC = pOwner->GetMovementController(); if(!pMC) return; // re-get targets from gametokens UpdateTargets(); if(m_iSerializeIgnoreUpdate) //workaround serialization requested by design & RnD { m_iSerializeIgnoreUpdate--; if(m_iSerializeIgnoreUpdate <= 0) { m_iSerializeIgnoreUpdate = 0; StartLocking(m_idSerializeTarget, 0); m_fStareTime = m_fSerializeProgress; } return; } SMovementState state; pMC->GetMovementState(state); Vec3 aimDir = state.eyeDirection; Vec3 aimPos = state.eyePosition; float maxDistance = m_pShared->fireparams.autoaim_distance; ray_hit ray; IPhysicalEntity *pSkipEnts[10]; int nSkipEnts = GetSkipEntities(m_pWeapon, pSkipEnts, 10); const int objects = ent_all; const int flags = rwi_stop_at_pierceable|rwi_ignore_back_faces; int result = gEnv->pPhysicalWorld->RayWorldIntersection(aimPos, aimDir * 2.f * maxDistance, objects, flags, &ray, 1, pSkipEnts, nSkipEnts); bool hitValidTarget = false; IEntity *pEntity = 0; if(result && ray.pCollider) { pEntity = (IEntity *)ray.pCollider->GetForeignData(PHYS_FOREIGN_ID_ENTITY); if(pEntity && IsValidAutoAimTarget(pEntity,ray.partid)) hitValidTarget = true; } if(m_bLocked) m_autoaimTimeOut -= frameTime; if(hitValidTarget && (m_bLocked || m_bLocking)) { int value = (int)((m_fStareTime / m_pShared->fireparams.autoaim_locktime)*100.0f); } if(hitValidTarget && ray.dist <= maxDistance) { if(m_bLocked) { if((m_lockedTarget != pEntity->GetId()) && (m_lockedTarget != pEntity->UnmapAttachedChild(ray.partid)->GetId()) && m_autoaimTimeOut<=0.0f) StartLocking(pEntity->GetId(),ray.partid); } else { if(!m_bLocking || (m_lockedTarget!=pEntity->GetId()) && (m_lockedTarget!=pEntity->UnmapAttachedChild(ray.partid)->GetId())) StartLocking(pEntity->GetId(),ray.partid); else m_fStareTime += frameTime; } } else if(!hitValidTarget && m_bLocking) { m_pWeapon->RequestUnlock(); Unlock(); } else { // check if we're looking far away from our locked target if((m_bLocked && !(ray.dist<=maxDistance && CheckAutoAimTolerance(aimPos, aimDir))) || (!m_bLocked && m_lockedTarget && m_fStareTime != 0.0f)) { if(!m_pShared->fireparams.autoaim_timeout) { m_pWeapon->RequestUnlock(); Unlock(); } } } if(m_bLocking && !m_bLocked && m_fStareTime >= m_pShared->fireparams.autoaim_locktime && m_lockedTarget) m_pWeapon->RequestLock(m_lockedTarget); else if(m_bLocked && hitValidTarget && m_lockedTarget!=pEntity->GetId() && (m_lockedTarget != pEntity->UnmapAttachedChild(ray.partid)->GetId())) m_pWeapon->RequestLock(pEntity->GetId(),ray.partid); else if(m_bLocked) { // check if target still valid (can e.g. be killed) pEntity = gEnv->pEntitySystem->GetEntity(m_lockedTarget); if((pEntity && !IsValidAutoAimTarget(pEntity)) || (m_pShared->fireparams.autoaim_timeout && m_autoaimTimeOut<=0.0f)) { m_pWeapon->RequestUnlock(); Unlock(); } } }
//------------------------------------------------------------------------ IEntity *CWorkOnTarget::CanWork() { static Vec3 pos,dir; static ICVar *pAimDebug = gEnv->pConsole->GetCVar("g_aimdebug"); CActor *pActor=m_pWeapon->GetOwnerActor(); static IPhysicalEntity *pSkipEntities[10]; int nSkip = CSingle::GetSkipEntities(m_pWeapon, pSkipEntities, 10); IEntity *pEntity=0; float range=m_workparams.range; IMovementController *pMC = pActor ? pActor->GetMovementController() : 0; if(pMC) { SMovementState info; pMC->GetMovementState(info); pos = info.weaponPosition; if(!pActor->IsPlayer()) { dir = range * (info.fireTarget-pos).normalized(); } else { dir = range * info.fireDirection; // marcok: leave this alone if(g_pGameCVars->goc_enable && pActor->IsClient()) { CPlayer *pPlayer = (CPlayer *)pActor; pos = pPlayer->GetViewMatrix().GetTranslation(); } } } else { assert(0); } static ray_hit hit; if(gEnv->pPhysicalWorld->RayWorldIntersection(pos, dir, ent_all, rwi_stop_at_pierceable|rwi_ignore_back_faces, &hit, 1, pSkipEntities, nSkip)) { if(hit.pCollider && hit.pCollider->GetiForeignData() == PHYS_FOREIGN_ID_ENTITY) { if(pEntity = (IEntity *)hit.pCollider->GetForeignData(PHYS_FOREIGN_ID_ENTITY)) { if(CGameRules *pGameRules=g_pGame->GetGameRules()) { if(IScriptTable *pScriptTable=pGameRules->GetEntity()->GetScriptTable()) { HSCRIPTFUNCTION pfnCanWork=0; if(pScriptTable->GetValueType("CanWork")==svtFunction && pScriptTable->GetValue("CanWork", pfnCanWork)) { bool result=false; Script::CallReturn(gEnv->pScriptSystem, pfnCanWork, pScriptTable, ScriptHandle(pEntity->GetId()), ScriptHandle(m_pWeapon->GetOwnerId()), m_workparams.work_type.c_str(), result); gEnv->pScriptSystem->ReleaseFunc(pfnCanWork); if(result) return pEntity; } } } } } } return 0; }
//------------------------------------------------------------------------ IEntity *CWorkOnTarget::CanWork() { static Vec3 pos,dir; static ICVar* pAimDebug = gEnv->pConsole->GetCVar("g_aimdebug"); CActor *pActor=m_pWeapon->GetOwnerActor(); static IPhysicalEntity* pSkipEntities[10]; int nSkip = CSingle::GetSkipEntities(m_pWeapon, pSkipEntities, 10); IEntity *pEntity=0; float range=m_workparams.range; IMovementController * pMC = pActor ? pActor->GetMovementController() : 0; if (pMC) { SMovementState info; pMC->GetMovementState(info); pos = info.weaponPosition; if (!pActor->IsPlayer()) { dir = range * (info.fireTarget-pos).normalized(); } else { dir = range * info.fireDirection; // marcok: leave this alone if (g_pGameCVars->goc_enable && pActor->IsClient()) { CPlayer *pPlayer = (CPlayer*)pActor; pos = pPlayer->GetViewMatrix().GetTranslation(); } } } else { assert(0); } primitives::sphere sphere; sphere.center = pos; sphere.r = m_workparams.radius; Vec3 end = pos+dir; geom_contact *pContact=0; float dst=gEnv->pPhysicalWorld->PrimitiveWorldIntersection(sphere.type, &sphere, end-sphere.center, ent_all, &pContact, 0, (geom_colltype_player<<rwi_colltype_bit)|rwi_stop_at_pierceable, 0, 0, 0, pSkipEntities, nSkip); if (pContact && dst>=0.0f) { IPhysicalEntity *pCollider = gEnv->pPhysicalWorld->GetPhysicalEntityById(pContact->iPrim[0]); if(pCollider && pCollider->GetiForeignData() == PHYS_FOREIGN_ID_ENTITY) { if (pEntity = static_cast<IEntity *>(pCollider->GetForeignData(PHYS_FOREIGN_ID_ENTITY))) { if (CGameRules *pGameRules=g_pGame->GetGameRules()) { if (IScriptTable *pScriptTable=pGameRules->GetEntity()->GetScriptTable()) { HSCRIPTFUNCTION pfnCanWork=0; if (pScriptTable->GetValueType("CanWork")==svtFunction && pScriptTable->GetValue("CanWork", pfnCanWork)) { bool result=false; Script::CallReturn(gEnv->pScriptSystem, pfnCanWork, pScriptTable, ScriptHandle(pEntity->GetId()), ScriptHandle(m_pWeapon->GetOwnerId()), m_workparams.work_type.c_str(), result); gEnv->pScriptSystem->ReleaseFunc(pfnCanWork); if (result) return pEntity; } } } } } } return 0; }