void Serialize(SActivationInfo* pActInfo, TSerialize ser) { ser.Value("active", m_active); ser.Value("ammo", m_ammo); ser.Value("weaponId", m_weapId); if (ser.IsReading()) { if (m_active && m_weapId != 0) { IItemSystem* pItemSys = CCryAction::GetCryAction()->GetIItemSystem(); IItem* pItem = pItemSys->GetItem(m_weapId); if (!pItem || !pItem->GetIWeapon()) { GameWarning("[flow] CFlowNode_WeaponListener: Serialize no item/weapon."); return; } IWeapon* pWeapon = pItem->GetIWeapon(); // set weapon listener pWeapon->AddEventListener(this, "CFlowNode_WeaponListener"); // CryLog("[flow] CFlowNode_WeaponListener::Serialize() successfully created on '%s'", pItem->GetEntity()->GetName()); } else { Reset(); } } }
void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo ) { switch (event) { case (eFE_Activate): { if (!IsPortActive(pActInfo, 0)) return; IItemSystem* pItemSys = CCryAction::GetCryAction()->GetIItemSystem(); // get actor IActor* pActor = CCryAction::GetCryAction()->GetClientActor(); if (!pActor) return; IInventory *pInventory = pActor->GetInventory(); if (!pInventory) return; IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(GetPortString(pActInfo,1)); IItem* pItem = pItemSys->GetItem(pInventory->GetItemByClass(pClass)); if (!pItem || !pItem->GetIWeapon()) { pItem = pActor->GetCurrentItem(); if (!pItem || pItem->GetEntity()->GetClass() != pClass || !pItem->GetIWeapon()) { GameWarning("[flow] CFlowNode_WeaponAmmo: No item/weapon %s!", GetPortString(pActInfo,1).c_str()); return; } } IWeapon *pWeapon = pItem->GetIWeapon(); const string& ammoType = GetPortString(pActInfo,2); IEntityClass* pAmmoClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(ammoType.c_str()); CRY_ASSERT(pAmmoClass); IFireMode* pCurrentFireMode = pWeapon->GetFireMode(pWeapon->GetCurrentFireMode()); if (pCurrentFireMode) { int clipSize = pCurrentFireMode->GetClipSize(); int ammo = pWeapon->GetAmmoCount(pAmmoClass) + GetPortInt(pActInfo,3); ammo = CLAMP(ammo, 0, clipSize); pWeapon->SetAmmoCount(pAmmoClass, ammo); } ActivateOutput(pActInfo, 0, pWeapon->GetAmmoCount(pAmmoClass)); } break; } }
bool CHeavyMountedWeapon::CanUse(EntityId userId) const { EntityId ownerId = m_owner.GetId(); if (m_rippedOff) { CActor* pActor = GetActor(userId); if (pActor && pActor->IsSwimming()) return false; if (ownerId == 0 || ownerId == userId) return true; } else if(IActor* pActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(userId)) { IItem* pItem = pActor->GetCurrentItem(false); if(pItem) { if(pItem->IsBusy()) { return false; } if(IWeapon* pWeapon = pItem->GetIWeapon()) { if(pWeapon->IsReloading()) { return false; } } } } return BaseClass::CanUse(userId); }
//--------------------------------------------- CWeapon* CLaser::GetWeapon() const { IItem* pParentItem = m_pItemSystem->GetItem(GetParentId()); if(pParentItem == NULL) return 0; CWeapon* pParentWeapon = static_cast<CWeapon*>(pParentItem->GetIWeapon()); return pParentWeapon; }
bool CBitmapUi::CanDrawCrosshair() const { assert( m_pGameFramework != NULL ); if ( ! g_pGameCVars->g_show_crosshair ) { return false; } IActor* pPlayer = m_pGameFramework->GetClientActor(); if ( pPlayer == NULL ) { return false; } bool isPlayerDead = pPlayer->IsDead(); if ( isPlayerDead ) { return false; } bool thirdPersonMode = pPlayer->IsThirdPerson(); bool crosshairEnabledInThirdPerson = ( g_pGameCVars->g_show_crosshair_tp != 0 ); if ( thirdPersonMode && ! crosshairEnabledInThirdPerson ) { return false; } IItem* pItem = pPlayer->GetCurrentItem(); if ( pItem == NULL ) { return false; } IWeapon* pWeapon = pItem->GetIWeapon(); if ( pWeapon == NULL ) { return false; } bool carryingMeleeWeapon = pWeapon->CanMeleeAttack(); if ( carryingMeleeWeapon ) { return false; } bool isWeaponZoomed = pWeapon->IsZoomed(); bool usingWeaponSightForAiming = ( ! thirdPersonMode && isWeaponZoomed ); if ( usingWeaponSightForAiming ) { return false; } return true; }
CWeapon* CFlashLight::GetWeapon() const { IItem* pParentItem = m_pItemSystem->GetItem(GetParentId()); if (pParentItem == NULL) { return 0; } CWeapon* pParentWeapon = static_cast<CWeapon*>(pParentItem->GetIWeapon()); return pParentWeapon; }
CWeapon* CCinematicInput::GetWeapon(const CCinematicInput::Weapon& weaponClass) const { assert( (weaponClass >= 0) && (weaponClass < eWeapon_ClassCount) ); if (m_weapons[weaponClass].m_weaponId != 0) { IItem* pItem = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(m_weapons[weaponClass].m_weaponId); return (pItem != NULL) ? static_cast<CWeapon*>(pItem->GetIWeapon()) : NULL; } return NULL; }
//--------------------------------------- void CMiscAnnouncer::RemoveWeaponListener(EntityId weaponId) { DbgLog("CMiscAnnouncer::RemoveWeaponListener() weapon=%s", g_pGame->GetGameRules()->GetEntityName(weaponId)); IItem* pItem = gEnv->pGame->GetIGameFramework()->GetIItemSystem()->GetItem(weaponId); if(pItem) { IWeapon *pWeapon = pItem->GetIWeapon(); if(pWeapon) { pWeapon->RemoveEventListener(this); } } }
//------------------------------------------------------------------------ CWeapon *CScriptBind_Weapon::GetWeapon(IFunctionHandler *pH) { void *pThis = pH->GetThis(); if (pThis) { IItem *pItem = m_pGameFW->GetIItemSystem()->GetItem((EntityId)(UINT_PTR)pThis); if (pItem) { IWeapon *pWeapon=pItem->GetIWeapon(); if (pWeapon) return static_cast<CWeapon *>(pWeapon); } } return 0; }
//---------------------------------------------- void CC4Detonator::SelectC4() { if (CActor *pOwner = GetOwnerActor()) { EntityId c4Id = pOwner->GetInventory()->GetItemByClass(CItem::sC4Class); if (c4Id) { //Do not reselect C4 is there's no ammo IItem *pItem = m_pItemSystem->GetItem(c4Id); CWeapon *pWep = pItem ? static_cast<CWeapon *>(pItem->GetIWeapon()) : NULL; if(pWep && pWep->OutOfAmmo(false)) { return; } pOwner->SelectItemByName("C4", false); } } }
//------------------------------------------------------ void CWeapon::ForcePendingActions(uint8 blockedActions) { CItem::ForcePendingActions(blockedActions); CActor* pOwner = GetOwnerActor(); if(!pOwner || !pOwner->IsClient()) return; //Force start firing, if needed and possible if(m_requestedFire) { if(!IsDualWield() && !IsWeaponRaised()) { m_requestedFire = false; OnAction(GetOwnerId(),"attack1",eAAM_OnPress,0.0f); } else if(IsDualWield() && IsDualWieldMaster()) { IItem *slave = GetDualWieldSlave(); if(!IsWeaponRaised()) { m_requestedFire = false; OnAction(GetOwnerId(),"attack1",eAAM_OnPress,0.0f); } else if(slave && slave->GetIWeapon()) { CWeapon* dualwield = static_cast<CWeapon*>(slave); if(!dualwield->IsWeaponRaised()) { m_requestedFire = false; OnAction(GetOwnerId(),"attack1",eAAM_OnPress,0.0f); } } } } }
void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo ) { switch (event) { case eFE_Initialize: { m_actInfo = *pActInfo; Reset(); } break; case eFE_Activate: { IItemSystem* pItemSys = CCryAction::GetCryAction()->GetIItemSystem(); // create listener if (IsPortActive(pActInfo, IN_DISABLE)) { Reset(); } if (IsPortActive(pActInfo, IN_ENABLE)) { Reset(); IItem* pItem = 0; EntityId weaponId = GetPortEntityId(pActInfo, IN_WEAPONID); if (weaponId != 0) { pItem = pItemSys->GetItem(weaponId); } else { IActor* pActor = CCryAction::GetCryAction()->GetClientActor(); if (!pActor) return; IInventory *pInventory = pActor->GetInventory(); if (!pInventory) return; const string& weaponClass = GetPortString(pActInfo, IN_WEAPONCLASS); if (!weaponClass.empty()) { // get actor weapon by class IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(weaponClass); pItem = pItemSys->GetItem( pInventory->GetItemByClass(pClass) ); } else { // get current actor weapon pItem = pItemSys->GetItem(pInventory->GetCurrentItem()); } } if (!pItem || !pItem->GetIWeapon()) { GameWarning("[flow] CFlowNode_WeaponListener: no item/weapon."); return; } m_weapId = pItem->GetEntity()->GetId(); IWeapon* pWeapon = pItem->GetIWeapon(); // set initial ammo m_ammo = GetPortInt(pActInfo, IN_AMMO); if (m_ammo == 0) m_ammo = -1; // 0 input means infinite // set weapon listener pWeapon->AddEventListener(this, "CFlowNode_WeaponListener"); m_active = true; //CryLog("WeaponListener successfully created on %s", pItem->GetEntity()->GetName()); } break; } } }
void CHUDCrosshair::Update(float fDeltaTime) { if(m_bBroken) return; IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); IItemSystem *pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem(); if(!pClientActor || !pItemSystem) return; IInventory *pInventory = pClientActor->GetInventory(); if(!pInventory) return; IItem *pItem = pItemSystem->GetItem(pInventory->GetCurrentItem()); IWeapon *pWeapon = NULL; IWeapon *pSlaveWeapon = NULL; const float fAlternateIronSight = 0.03f; if(pItem) { pWeapon = pItem->GetIWeapon(); if(pItem->IsDualWieldMaster()) { if(IItem *pSlave=pItem->GetDualWieldSlave()) pSlaveWeapon = pSlave->GetIWeapon(); } } else if(IVehicle *pVehicle=pClientActor->GetLinkedVehicle()) { pItem = pItemSystem->GetItem(pVehicle->GetCurrentWeaponId(pClientActor->GetEntityId())); if(pItem) pWeapon = pItem->GetIWeapon(); } if(pWeapon) { float fMinSpread = 0.0f; float fMaxSpread = 0.0f; m_spread = 0.0f; if(IFireMode *pFireMode=pWeapon->GetFireMode(pWeapon->GetCurrentFireMode())) { fMinSpread = pFireMode->GetMinSpread(); fMaxSpread = pFireMode->GetMaxSpread(); m_spread = pFireMode->GetSpread(); } if(pSlaveWeapon) { if(IFireMode *pSlaveFireMode=pSlaveWeapon->GetFireMode(pSlaveWeapon->GetCurrentFireMode())) { fMinSpread += pSlaveFireMode->GetMinSpread(); fMaxSpread += pSlaveFireMode->GetMaxSpread(); m_spread += pSlaveFireMode->GetSpread(); } } CPlayer *pPlayer = static_cast<CPlayer*>(pClientActor); if(pPlayer && pPlayer->GetNanoSuit() && pPlayer->GetNanoSuit()->GetMode() == NANOMODE_STRENGTH) m_spread *=0.5; if(g_pGameCVars->hud_iAlternateCrosshairSpread) { if(m_spread < fMinSpread) m_spread = min(m_spread,g_pGameCVars->hud_fAlternateCrosshairSpreadCrouch) / g_pGameCVars->hud_fAlternateCrosshairSpreadCrouch; else m_spread = min(m_spread,g_pGameCVars->hud_fAlternateCrosshairSpreadNeutral) / g_pGameCVars->hud_fAlternateCrosshairSpreadNeutral; } else { m_spread = min((m_spread-fMinSpread),15.0f) / 15.0f; IZoomMode *pZoomMode = pWeapon->GetZoomMode(pWeapon->GetCurrentZoomMode()); if(pZoomMode && !pZoomMode->IsToggle() && (pZoomMode->IsZoomed() || pZoomMode->IsZooming())) { m_spread -= fAlternateIronSight; } else { m_spread = min(m_spread,1.0f); m_spread = max(m_spread,0.0f); } } } if(m_animCrossHair.GetVisible() && !g_pHUD->InSpectatorMode()) { //also disables the damage indicator if(/*g_pGameCVars->hud_crosshair>0 && m_iCrosshair > 0 &&*/ (g_pGameCVars->g_difficultyLevel<4 || gEnv->bMultiplayer)) { m_animCrossHair.GetFlashPlayer()->Advance(fDeltaTime); m_animCrossHair.GetFlashPlayer()->Render(); } if(m_animInterActiveIcons.GetVisible()) //if the crosshair is invisible, the use icon should be too { if(!m_bHideUseIconTemp) //hides the icon, when something is already grabbed/being used { m_animInterActiveIcons.GetFlashPlayer()->Advance(fDeltaTime); m_animInterActiveIcons.GetFlashPlayer()->Render(); } } } if(m_animFriendCross.GetVisible()) { m_animFriendCross.GetFlashPlayer()->Advance(fDeltaTime); m_animFriendCross.GetFlashPlayer()->Render(); } if(!g_pGameCVars->hud_iAlternateCrosshairSpread) { m_spread = max(m_spread,-fAlternateIronSight); m_spread = min(m_spread,1.0f); } if (m_smoothSpread != m_spread) { Interpolate(m_smoothSpread, m_spread, 20.0f, fDeltaTime); m_animCrossHair.Invoke("setRecoil", m_smoothSpread); } UpdateCrosshair(); }
void CPlayerView::ViewSpectatorTarget(SViewParams &viewParams) { CActor *pTarget = (CActor *)g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_in.stats_spectatorTarget); if(!pTarget) { return; } Matrix34 worldTM = pTarget->GetEntity()->GetWorldTM(); Vec3 worldPos = worldTM.GetTranslation(); worldPos.z += 1.5f; Ang3 worldAngles = Ang3::GetAnglesXYZ(Matrix33(worldTM)); float rot = worldAngles.z;// + m_rot; float distance = 3;//(m_defaultDistance != 0) ? m_defaultDistance : m_distance; if(IVehicle *pVehicle = pTarget->GetLinkedVehicle()) { AABB vehicleBox; pVehicle->GetEntity()->GetLocalBounds(vehicleBox); distance = 2.0f * vehicleBox.GetRadius(); } Vec3 goal; float zoom = 1.0f; goal.x = distance * zoom * cosf(rot + gf_PI * 1.5f) + worldPos.x; goal.y = distance * zoom * sinf(rot - gf_PI / 2.0f) + worldPos.y; AABB targetBounds; pTarget->GetEntity()->GetLocalBounds(targetBounds); goal.z = targetBounds.max.z; static float defaultOffset = 0.75f; float offset = defaultOffset; if(pTarget->GetLinkedVehicle()) { offset = 2.0f; } goal.z += pTarget->GetEntity()->GetWorldPos().z + offset; // store / interpolate the offset, not the world pos (reduces percieved jitter in vehicles) static Vec3 viewOffset(goal - worldPos); static Vec3 position(goal); static Vec3 entPos(worldPos); static EntityId lastSpectatorTarget(m_in.stats_spectatorTarget); // do a ray cast to check for camera intersection static ray_hit hit; IPhysicalEntity *pSkipEntities[10]; int nSkip = 0; IItem *pItem = pTarget->GetCurrentItem(); if (pItem) { CWeapon *pWeapon = (CWeapon *)pItem->GetIWeapon(); if (pWeapon) { nSkip = CSingle::GetSkipEntities(pWeapon, pSkipEntities, 10); } } else if(IVehicle *pVehicle = pTarget->GetLinkedVehicle()) { // vehicle drivers don't seem to have current items, so need to add the vehicle itself here nSkip = pVehicle->GetSkipEntities(pSkipEntities, 10); } const float wallSafeDistance = 0.2f; // how far to keep camera from walls Vec3 dir = goal - worldPos; primitives::sphere sphere; sphere.center = worldPos; sphere.r = wallSafeDistance; geom_contact *pContact = 0; float hitDist = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(sphere.type, &sphere, dir, ent_static | ent_terrain | ent_rigid | ent_sleeping_rigid, &pContact, 0, geom_colltype_player, 0, 0, 0, pSkipEntities, nSkip); // even when we have contact, keep the camera the same height above the target float minHeightDiff = dir.z; if(hitDist > 0 && pContact) { goal = worldPos + (hitDist * dir.GetNormalizedSafe()); if(goal.z - worldPos.z < minHeightDiff) { // can't move the camera far enough away from the player in this direction. Try moving it directly up a bit sphere.center = goal; // (move back just slightly to avoid colliding with the wall we've already found...) sphere.center -= dir.GetNormalizedSafe() * 0.05f; float newHitDist = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(sphere.type, &sphere, Vec3(0, 0, minHeightDiff), ent_static | ent_terrain | ent_rigid | ent_sleeping_rigid, &pContact, 0, geom_colltype_player, 0, 0, 0, pSkipEntities, nSkip); float raiseDist = minHeightDiff - (goal.z - worldPos.z) - wallSafeDistance; if(newHitDist != 0) { raiseDist = MIN(minHeightDiff, newHitDist); } raiseDist = MAX(0.0f, raiseDist); goal.z += raiseDist; worldPos.z += raiseDist * 0.8f; } } int thisFrameId = gEnv->pRenderer->GetFrameID(); static int frameNo(thisFrameId); if(thisFrameId - frameNo > 5) { // reset positions viewOffset = goal - worldPos; entPos = worldPos; position = goal; } if(lastSpectatorTarget != m_in.stats_spectatorTarget) { viewOffset = goal - worldPos; entPos = worldPos; position = goal; lastSpectatorTarget = m_in.stats_spectatorTarget; } frameNo = thisFrameId; if(pTarget->GetLinkedVehicle()) { Interpolate(viewOffset, goal - worldPos, 5.0f, viewParams.frameTime); entPos = worldPos; viewParams.position = worldPos + viewOffset; position = viewParams.position; } else { Vec3 camPosChange = goal - position; Vec3 entPosChange = worldPos - entPos; if(camPosChange.GetLengthSquared() > 100.0f) { position = goal; } if(entPosChange.GetLengthSquared() > 100.0f) { entPos = worldPos; } Interpolate(position, goal, 5.0f, viewParams.frameTime); Interpolate(entPos, worldPos, 5.0f, viewParams.frameTime); viewParams.position = position; } Matrix33 rotation = Matrix33::CreateRotationVDir((entPos - viewParams.position).GetNormalizedSafe()); viewParams.rotation = Quat(rotation); m_io.bUsePivot = true; m_io.stats_bobCycle = 0.0; }
//----------------------------------------------------------------------- bool CSpectacularKill::StartOnTarget(CActor* pTargetActor) { FUNCTION_PROFILER(gEnv->pSystem, PROFILE_GAME); CRY_ASSERT(pTargetActor); CRY_ASSERT_MESSAGE(!IsBusy(), "spectacular kill should not be initiated while a spectacular kill is already in progress"); SSpectacularKillAnimation anim; if (!IsBusy() && pTargetActor && GetValidAnim(pTargetActor, anim) && CanExecuteOnTarget(pTargetActor, anim)) { // Disable AI if (!pTargetActor->IsPlayer() && pTargetActor->GetEntity()->GetAI()) pTargetActor->GetEntity()->GetAI()->Event(AIEVENT_DISABLE, 0); if (!m_pOwner->IsPlayer() && m_pOwner->GetEntity()->GetAI()) m_pOwner->GetEntity()->GetAI()->Event(AIEVENT_DISABLE, 0); // make sure they aren't firing when the anim starts { IItem* pItem = pTargetActor->GetCurrentItem(); IWeapon* pWeapon = pItem ? pItem->GetIWeapon() : NULL; if (pWeapon) pWeapon->StopFire(); } { IItem* pItem = m_pOwner->GetCurrentItem(); IWeapon* pWeapon = pItem ? pItem->GetIWeapon() : NULL; if (pWeapon) pWeapon->StopFire(); } SActorStats* pStats = m_pOwner->GetActorStats(); if(pStats) { pStats->spectacularKillPartner = pTargetActor->GetEntityId(); } SActorStats* pTargetStats = pTargetActor->GetActorStats(); if(pTargetStats) { pTargetStats->spectacularKillPartner = m_pOwner->GetEntityId(); } const float slideTime = 0.2f; const char* pKillerAnim = anim.killerAnimation.c_str(); const char* pVictimAnim = anim.victimAnimation.c_str(); SCharacterParams killerParams(m_pOwner->GetAnimatedCharacter(), pKillerAnim, /*allowHPhysics*/false, slideTime); SCharacterParams targetParams(pTargetActor->GetAnimatedCharacter(), pVictimAnim, /*allowHPhysics*/false, slideTime); SCooperativeAnimParams animParams(/*forceStart*/true, /*looping*/ false, /*alignment*/ /*eAF_FirstActorNoRot*/eAF_FirstActor); animParams.bIgnoreCharacterDeath = true; animParams.bPreventFallingThroughTerrain = false; animParams.bNoCollisionsBetweenFirstActorAndRest = true; ICooperativeAnimationManager* pCooperativeAnimationManager = gEnv->pGame->GetIGameFramework()->GetICooperativeAnimationManager(); bool bStarted = pCooperativeAnimationManager->StartNewCooperativeAnimation(killerParams, targetParams, animParams); if (bStarted) { m_targetId = pTargetActor->GetEntityId(); m_isBusy = true; // Register the killing s_lastKillInfo.killerAnim = pKillerAnim; s_lastKillInfo.timeStamp = gEnv->pTimer->GetFrameStartTime().GetSeconds(); #ifndef _RELEASE // Clean persistant debug information IPersistantDebug* pPersistantDebug = BeginPersistantDebug(); // Send telemetry event CStatsRecordingMgr* pRecordingMgr = g_pGame->GetStatsRecorder(); IStatsTracker* pTracker = pRecordingMgr ? pRecordingMgr->GetStatsTracker(m_pOwner) : NULL; if (pTracker) { EGameStatisticEvent eventType = eGSE_SpectacularKill; if(pRecordingMgr->ShouldRecordEvent(eventType, m_pOwner)) { pTracker->Event(eventType, (anim.killerAnimation + " -> " + anim.victimAnimation).c_str()); } } #endif return true; } } return false; }
void CPlayerView::ViewDeathCamTarget(SViewParams &viewParams) { CActor* pTarget = (CActor*)g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_in.stats_spectatorTarget); if(!pTarget) return; Matrix34 targetWorldTM = pTarget->GetEntity()->GetWorldTM(); Vec3 camPos = viewParams.position; static float offset = 1.5f; camPos.z += offset; float heightOffset = 1.5f; const SStanceInfo* pSI = pTarget->GetStanceInfo(pTarget->GetStance()); if(pSI) { heightOffset = pSI->viewOffset.z; } Vec3 targetPos = targetWorldTM.GetTranslation(); targetPos.z += heightOffset; int thisFrameId = gEnv->pRenderer->GetFrameID(); static int frameNo(thisFrameId); static Vec3 oldCamPos(camPos); static Vec3 oldTargetPos(targetPos); static EntityId lastSpectatorTarget(m_in.stats_spectatorTarget); static float oldFOVScale(1.0f); // if more than a few frames have passed since our last update, invalidate the positions if(thisFrameId - frameNo > 5) { oldCamPos = viewParams.position; // interpolate from current camera pos oldTargetPos = targetPos; oldFOVScale = 1.0f; } // if target changed, reset positions if(lastSpectatorTarget != m_in.stats_spectatorTarget) { oldCamPos = camPos; oldTargetPos = targetPos; lastSpectatorTarget = m_in.stats_spectatorTarget; oldFOVScale = 1.0f; } frameNo = thisFrameId; // slight zoom after 2s float timeNow = gEnv->pTimer->GetCurrTime(); float distSq = (targetPos - camPos).GetLengthSquared(); float scale = 1.0f; if(timeNow - m_in.deathTime > 1.0f && distSq > 2500.0f) { // 1.0f at 50m, 0.3f at 100m+ scale = 1.0f - (distSq - 2500.0f)/25000.0f; scale = CLAMP(scale, 0.3f, 1.0f); } Interpolate(oldCamPos, camPos, 5.0f, viewParams.frameTime); Interpolate(oldTargetPos, targetPos, 5.0f, viewParams.frameTime); Interpolate(oldFOVScale, scale, 0.5f, viewParams.frameTime); viewParams.position = oldCamPos; Vec3 dir = (oldTargetPos - oldCamPos).GetNormalizedSafe(); Matrix33 rotation = Matrix33::CreateRotationVDir(dir); dir.z = 0.0f; // quick ray check to make sure there's not a wall in the way... IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_in.entityId); if (pActor) { static ray_hit hit; IPhysicalEntity* pSkipEntities[10]; int nSkip = 0; IItem* pItem = pActor->GetCurrentItem(); if (pItem) { CWeapon* pWeapon = (CWeapon*)pItem->GetIWeapon(); if (pWeapon) nSkip = CSingle::GetSkipEntities(pWeapon, pSkipEntities, 10); } if (gEnv->pPhysicalWorld->RayWorldIntersection(viewParams.position, -dir, ent_static|ent_terrain|ent_rigid, rwi_ignore_noncolliding | rwi_stop_at_pierceable, &hit, 1, pSkipEntities, nSkip)) { dir.zero(); } } viewParams.position -= dir; viewParams.fov = m_in.defaultFov*oldFOVScale*(gf_PI/180.0f);; viewParams.rotation = GetQuatFromMat33(rotation); m_io.bUsePivot = true; m_io.stats_bobCycle = 0.0; }
////////////////////////////////////////////////////////////////////////// // 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 CGameStateRecorder::OnGameplayEvent(IEntity *pEntity, const GameplayEvent &event) { EntityId id; if(!pEntity || !(id = pEntity->GetId())) { GameWarning("TimeDemo:GameState::OnGamePlayEvent: Entity not found"); return; } CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(!pActor) { GameWarning("TimeDemo:GameState::OnGamePlayEvent: Entity %s has no actor", pEntity->GetName()); return; } GameplayEvent event2 = event; event2.extra = 0;// event2 is the forwarded event, extra either will be not used by the listener or re-set as a string uint8 eType = event.event; bool bPlayer = (pActor->IsPlayer() && m_mode); if(bPlayer || m_mode==GPM_AllActors) { //items switch(eType) { case eGE_ItemPickedUp: { CheckInventory(pActor,0);//,*m_pRecordGameEventFtor); } break; case eGE_ItemDropped: { TItemName itemName = GetItemName(EntityId(event.extra)); if(!itemName ) //if(itemIdx < 0) break; event2.description = itemName; SendGamePlayEvent(pEntity,event2); IEntity* pItemEntity = gEnv->pEntitySystem->FindEntityByName(itemName); if(!pItemEntity) break; IItem* pItem = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(pItemEntity->GetId()); if(!pItem) break; IEntityClass* pItemClass = pItem->GetEntity()->GetClass(); if(pItemClass && !strcmpi(pItemClass->GetName(),"SOCOM")) { IItem* pCurrentItem = pActor->GetCurrentItem(); if(pCurrentItem) { IEntityClass* pCurrentItemClass = pCurrentItem->GetEntity()->GetClass(); if(pCurrentItemClass && !strcmpi(pCurrentItemClass->GetName(),"SOCOM")) { GameplayEvent event3; event3.event = eGE_ItemSelected; TItemName itemName = GetItemName(pCurrentItem->GetEntity()->GetId()); if(!itemName) break; event3.value = 0; event3.description = (const char*)itemName; SendGamePlayEvent(pEntity,event3); } } } } break; case eGE_WeaponFireModeChanged: { TItemName itemIdx = GetItemName(EntityId(event.extra)); if(!itemIdx)//if(itemIdx < 0) break; event2.description = (const char*)itemIdx; SendGamePlayEvent(pEntity,event2); } break; case eGE_ItemSelected: { EntityId itemId = EntityId(event.extra); TItemName itemIdx = GetItemName(itemId); if(itemId && !itemIdx) break; event2.value = 0; event2.description = (const char*)itemIdx; SendGamePlayEvent(pEntity,event2); } break; case eGE_AttachedAccessory: { if(!IsGrenade(event.description)) // NOT OffHandGrenade SendGamePlayEvent(pEntity,event2); } break; case eGE_AmmoCount: { const char* itemIdx = event.description; if(!itemIdx) break; TGameStates::iterator itGS; /*if(pActor->IsPlayer()) itGS = m_itSingleActorGameState; else */if(pActor->GetEntity()) itGS = m_GameStates.find(pActor->GetEntity()->GetId()); else break; if(itGS == m_GameStates.end()) break; SActorGameState& gstate = itGS->second; IEntity* pItemEntity = gEnv->pEntitySystem->FindEntityByName(itemIdx); if(!pItemEntity) break; IItem* pItem = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(pItemEntity->GetId()); if(!pItem) break; CWeapon* pWeapon = (CWeapon*)(pItem->GetIWeapon()); if(pWeapon && pWeapon->GetEntity()) { TItemContainer::iterator it = gstate.Items.find(itemIdx); if(it==gstate.Items.end()) break; SItemProperties& recItem = it->second; SWeaponAmmo weaponAmmo = pWeapon->GetFirstAmmo(); bool bGrenade = false; if(!weaponAmmo.pAmmoClass) { // special case for grenades if(IsAmmoGrenade((const char*)(event.extra))) { weaponAmmo.pAmmoClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass((const char*)event.extra); weaponAmmo.count = (int)event.value; bGrenade = true; } } for(; weaponAmmo.pAmmoClass ; weaponAmmo = pWeapon->GetNextAmmo()) { int ammoCount = weaponAmmo.count; const char* ammoClass; if(weaponAmmo.pAmmoClass && (ammoClass = weaponAmmo.pAmmoClass->GetName())) { TAmmoContainer& recAmmo = bGrenade? gstate.AmmoMags : recItem.Ammo; if(recAmmo.find(ammoClass) == recAmmo.end()) recAmmo.insert(std::make_pair(ammoClass,0)); if(ammoCount != recAmmo[ammoClass]) { event2.event = eGE_AmmoCount; event2.value = (float)ammoCount; if(event2.value < 0) event2.value = 0; event2.extra = (void*)ammoClass; event2.description = (const char*)itemIdx; SendGamePlayEvent(pEntity,event2); } } } } } break; case eGE_EntityGrabbed: { EntityId entityId = EntityId(event.extra); IEntity * pGrabbedEntity = gEnv->pEntitySystem->GetEntity(entityId); if(pGrabbedEntity) { event2.description = pGrabbedEntity->GetName(); SendGamePlayEvent(pEntity,event2); } } break; case eGE_WeaponReload: case eGE_ZoomedIn: case eGE_ZoomedOut: case eGE_HealthChanged: case eGE_ItemExchanged: SendGamePlayEvent(pEntity,event2); break; default: break; } } }
void CPlayerView::ViewSpectatorTarget(SViewParams &viewParams) { CActor* pTarget = (CActor*)g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_in.stats_spectatorTarget); if(!pTarget) return; IVehicle* pVehicle = pTarget->GetLinkedVehicle(); static float defaultOffset = 0.3f; static float viewHeight = 1.8f; Matrix34 worldTM = pTarget->GetEntity()->GetWorldTM(); Vec3 worldPos = worldTM.GetTranslation(); if(!pVehicle) { const SStanceInfo* stanceInfo = pTarget->GetStanceInfo(pTarget->GetStance()); if(stanceInfo) { Interpolate(viewHeight, stanceInfo->viewOffset.z, 5.0f, viewParams.frameTime); worldPos.z += viewHeight + defaultOffset; } else { worldPos.z += 1.8f; } } else { // use vehicle pos/ori worldTM = pVehicle->GetEntity()->GetWorldTM(); worldPos = pVehicle->GetEntity()->GetWorldPos(); worldPos.z += 1.5f; } Ang3 worldAngles = Ang3::GetAnglesXYZ(Matrix33(worldTM)); float distance = 3; // if freelook allowed, get orientation and distance from player entity if(g_pGameCVars->g_spectate_FixedOrientation == 0) { CPlayer* pThisPlayer = static_cast<CPlayer*>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_in.entityId)); if(!pThisPlayer) return; Matrix34 ownOrientation = pThisPlayer->GetEntity()->GetWorldTM(); worldAngles += Ang3::GetAnglesXYZ(Matrix33(ownOrientation)); distance = pThisPlayer->GetSpectatorZoom(); } if(pVehicle) { distance *= 4.0f; // air vehicles need bigger distance if(pVehicle->GetMovement() && pVehicle->GetMovement()->GetMovementType() == IVehicleMovement::eVMT_Air) distance *= 2.0f; } Vec3 goal; goal.x = distance * cos(worldAngles.z + gf_PI*1.5f) + worldPos.x; goal.y = distance * sin(worldAngles.z - gf_PI/2.0f) + worldPos.y; AABB targetBounds; pTarget->GetEntity()->GetLocalBounds(targetBounds); goal.z = targetBounds.max.z; float offset = defaultOffset; if(pVehicle) { if(pVehicle->GetMovement() && pVehicle->GetMovement()->GetMovementType() == IVehicleMovement::eVMT_Air) offset = 3.0f; else offset = 1.0f; } goal.z += pTarget->GetEntity()->GetWorldPos().z + offset; // store / interpolate the offset, not the world pos (reduces percieved jitter in vehicles) static Vec3 viewOffset(goal-worldPos); static Vec3 camPos(goal); static Vec3 entPos(worldPos); static EntityId lastSpectatorTarget(m_in.stats_spectatorTarget); // do a ray cast to check for camera intersection static ray_hit hit; IPhysicalEntity* pSkipEntities[10]; int nSkip = 0; if(pVehicle) { // vehicle drivers don't seem to have current items, so need to add the vehicle itself here nSkip = pVehicle->GetSkipEntities(pSkipEntities, 10); } else { IItem* pItem = pTarget->GetCurrentItem(); if (pItem) { CWeapon* pWeapon = (CWeapon*)pItem->GetIWeapon(); if (pWeapon) nSkip = CSingle::GetSkipEntities(pWeapon, pSkipEntities, 10); } } static float minDist = 0.4f; // how close we're allowed to get to the target static float wallSafeDistance = 0.3f; // how far to keep camera from walls Vec3 dir = goal - worldPos; primitives::sphere sphere; sphere.center = worldPos; sphere.r = wallSafeDistance; geom_contact *pContact = 0; float hitDist = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(sphere.type, &sphere, dir, ent_static|ent_terrain|ent_rigid|ent_sleeping_rigid, &pContact, 0, (geom_colltype_player<<rwi_colltype_bit) | rwi_stop_at_pierceable, 0, 0, 0, pSkipEntities, nSkip); // even when we have contact, keep the camera the same height above the target float minHeightDiff = dir.z; if(hitDist > 0 && pContact) { goal = worldPos + (hitDist * dir.GetNormalizedSafe()); if(goal.z - worldPos.z < minHeightDiff) { // can't move the camera far enough away from the player in this direction. Try moving it directly up a bit int numHits = 0; sphere.center = goal; // (move back just slightly to avoid colliding with the wall we've already found...) sphere.center -= dir.GetNormalizedSafe() * 0.05f; float newHitDist = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(sphere.type, &sphere, Vec3(0,0,minHeightDiff), ent_static|ent_terrain|ent_rigid|ent_sleeping_rigid, &pContact, 0, (geom_colltype_player<<rwi_colltype_bit) | rwi_stop_at_pierceable, 0, 0, 0, pSkipEntities, nSkip); float raiseDist = minHeightDiff - (goal.z - worldPos.z) - wallSafeDistance; if(newHitDist != 0) { raiseDist = MIN(minHeightDiff, newHitDist); } raiseDist = MAX(0.0f, raiseDist); goal.z += raiseDist; worldPos.z += raiseDist*0.8f; } } int thisFrameId = gEnv->pRenderer->GetFrameID(); static int frameNo(thisFrameId); if(thisFrameId - frameNo > 5) { // reset positions viewOffset = goal - worldPos; entPos = worldPos; camPos = goal; } if(lastSpectatorTarget != m_in.stats_spectatorTarget) { viewOffset = goal - worldPos; entPos = worldPos; camPos = goal; lastSpectatorTarget = m_in.stats_spectatorTarget; } frameNo = thisFrameId; static float interpSpeed = 5.0f; static float interpSpeed2 = 5.0f; static float interpSpeed3 = 8.0f; if(pVehicle) { Interpolate(viewOffset, goal-worldPos, interpSpeed, viewParams.frameTime); entPos = worldPos; viewParams.position = worldPos + viewOffset; camPos = viewParams.position; } else { Vec3 camPosChange = goal - camPos; Vec3 entPosChange = worldPos - entPos; if(camPosChange.GetLengthSquared() > 100.0f) camPos = goal; if(entPosChange.GetLengthSquared() > 100.0f) entPos = worldPos; Interpolate(camPos, goal, interpSpeed2, viewParams.frameTime); Interpolate(entPos, worldPos, interpSpeed3, viewParams.frameTime); viewParams.position = camPos; } Matrix33 rotation = Matrix33::CreateRotationVDir((entPos - viewParams.position).GetNormalizedSafe()); viewParams.rotation = GetQuatFromMat33(rotation); m_io.bUsePivot = true; m_io.stats_bobCycle = 0.0; }
// // Extract the various modifiers out into their own function. // // Aim is to make the code easier to understand and modify, as // well as to ease the addition of new modifiers. // void CPlayerView::ViewFirstPerson(SViewParams &viewParams) { //headbob Ang3 angOffset(0,0,0); Vec3 weaponOffset(0,0,0); Ang3 weaponAngleOffset(0,0,0); // jump/land spring effect. Adjust the eye and weapon pos as required. FirstPersonJump(viewParams,weaponOffset,weaponAngleOffset); //float standSpeed(GetStanceMaxSpeed(STANCE_STAND)); Vec3 vSpeed(0,0,0); if (m_in.standSpeed>0.001f) vSpeed = (m_in.stats_velocity / m_in.standSpeed); float vSpeedLen(vSpeed.len()); if (vSpeedLen>1.5f) vSpeed = vSpeed / vSpeedLen * 1.5f; float speedMul(0); if (m_in.standSpeed>0.001f) speedMul=(m_in.stats_flatSpeed / m_in.standSpeed * 1.1f); speedMul = min(1.5f,speedMul); bool crawling(m_in.stance==STANCE_PRONE /*&& m_in.stats_flatSpeed>0.1f*/ && m_in.stats_onGround>0.1f); bool weaponZoomed = false; bool weaponZomming = false; //Not crawling while in zoom mode IActor *owner = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_in.entityId); if(owner && owner->IsPlayer()) { IItem *pItem = owner->GetCurrentItem(); if(pItem) { CWeapon *pWeapon = static_cast<CWeapon*>(pItem->GetIWeapon()); if(pWeapon) { weaponZoomed = pWeapon->IsZoomed(); weaponZomming = pWeapon->IsZooming(); if(weaponZoomed||weaponZomming||pWeapon->IsModifying()) crawling = false; } } } // On the ground. if (m_in.stats_inAir < 0.1f /*&& m_in.stats_inWater < 0.1f*/) { //--- Bobbing. // bobCycle is a speed varying time step running (looping) from 0 to 1 // this feeds into a sin eqn creating a double horizontal figure of 8. // ( a lissajous figure with the vertical freq twice the horz freq ). // To tweak the total speed of the curve: // To tweak the effect speed has on the curve: float kSpeedToBobFactor=1.15f;//0.9f // To tweak the width of the bob: float kBobWidth=0.1f; // To tweak the height of the bob: float kBobHeight=0.05f; // To tweak the scale of strafing lag: (may need to manually adjust the strafing angle offsets as well.) const float kStrafeHorzScale=0.05f; kBobWidth = 0.15f; kBobHeight = 0.06f; m_io.stats_bobCycle += m_in.frameTime * kSpeedToBobFactor * speedMul;// * (m_in.bSprinting?1.25f:1.0f); //if player is standing set the bob to rest. (bobCycle reaches 1.0f within 1 second) if (speedMul < 0.1f) m_io.stats_bobCycle = min(m_io.stats_bobCycle + m_in.frameTime * 1.0f,1.0f); // bobCycle loops between 0 and 1 if (m_io.stats_bobCycle>1.0f) m_io.stats_bobCycle = m_io.stats_bobCycle - 1.0f; if (crawling) kBobWidth *= 2.0f * speedMul; else if (m_in.bSprinting) kBobWidth *= 1.25f * speedMul; //set the bob offset Vec3 bobDir(cry_sinf(m_io.stats_bobCycle*gf_PI*2.0f)*kBobWidth*speedMul,0,cry_sinf(m_io.stats_bobCycle*gf_PI*4.0f)*kBobHeight*speedMul); //not the bob offset for the weapon bobDir *= 0.25f; //if player is strafing shift a bit the weapon on left/right if (speedMul > 0.01f) { // right vector dot speed vector float dot(m_io.viewQuatFinal.GetColumn0() * vSpeed); bobDir.x -= dot * kStrafeHorzScale; // the faster we move right, the more the gun lags to the left and vice versa //tweak the right strafe for weapon laser if (dot>0.0f) weaponAngleOffset.z += dot * 1.5f; // kStrafeHorzScale else weaponAngleOffset.z -= dot * 2.0f; // kStrafeHorzScale weaponAngleOffset.y += dot * 5.0f; // kStrafeHorzScale } //CryLogAlways("bobDir.z: %f", bobDir.z); if (bobDir.z < 0.0f) { bobDir.x *= 1.0f; bobDir.y *= 1.0f; bobDir.z *= 0.35f; speedMul *= 0.65f; } else bobDir.z *= 1.85f; //CryLogAlways("bobDir.z: %f after", bobDir.z); weaponOffset += m_io.viewQuatFinal * bobDir; weaponOffset -= m_io.baseQuat.GetColumn2() * 0.035f * speedMul; weaponAngleOffset.y += cry_sinf(m_io.stats_bobCycle*gf_PI*2.0f) * speedMul * -1.5f; if (crawling) weaponAngleOffset.y *= 3.0f; weaponAngleOffset.x += speedMul * 1.5f; if (crawling) weaponAngleOffset.z += cry_sinf(m_io.stats_bobCycle*gf_PI*2.0f) * speedMul * 3.0f; //FIXME: viewAngles must include all the view offsets, otherwise aiming wont be precise. angOffset.x += cry_sinf(m_io.stats_bobCycle*gf_PI*4.0f)*0.7f*speedMul; if (crawling) { angOffset.x *= 2.5f; angOffset.y += cry_sinf(m_io.stats_bobCycle*gf_PI*2.0f)*1.25f*speedMul; angOffset.z -= cry_sinf(m_io.stats_bobCycle*gf_PI*2.0f)*2.5f*speedMul; } else if (m_in.bSprinting) { angOffset.x *= 2.5f; angOffset.y += cry_sinf(m_io.stats_bobCycle*gf_PI*2.0f)*1.0f*speedMul; angOffset.z -= cry_sinf(m_io.stats_bobCycle*gf_PI*2.0f)*2.25f*speedMul; } else if(m_in.stance==STANCE_CROUCH && !weaponZoomed && !weaponZomming) { weaponOffset.z += 0.035f; weaponOffset.y -= m_io.viewQuatFinal.GetColumn1().y * 0.03f; } else if(m_in.stance==STANCE_CROUCH && weaponZomming) { weaponOffset.z -= 0.07f; weaponOffset.y += m_io.viewQuatFinal.GetColumn1().y * 0.06f; } else { //angOffset.x *= 2.25f; //angOffset.y += cry_sinf(m_io.stats_bobCycle*gf_PI*2.0f)*0.5f*speedMul; //angOffset.z -= cry_sinf(m_io.stats_bobCycle*gf_PI*2.0f)*1.125f*speedMul; } } else { m_io.stats_bobCycle = 0; //while flying offset a bit the weapon model by the player speed if (m_in.stats_velocity.len2()>0.001f) { float dotFwd(m_io.viewQuatFinal.GetColumn1() * vSpeed); float dotSide(m_io.viewQuatFinal.GetColumn0() * vSpeed); float dotUp(m_io.viewQuatFinal.GetColumn2() * vSpeed); weaponOffset += m_io.viewQuatFinal * Vec3(dotSide * -0.05f,dotFwd * -0.035f,dotUp * -0.05f); weaponAngleOffset.x += dotUp * 2.0f; weaponAngleOffset.y += dotSide * 5.0f; weaponAngleOffset.z -= dotSide * 2.0f; } } //add some inertia to weapon due view direction change. float deltaDotSide(m_io.vFPWeaponLastDirVec * m_io.viewQuatFinal.GetColumn0()); float deltaDotUp(m_io.vFPWeaponLastDirVec * m_io.viewQuatFinal.GetColumn2()); weaponOffset += m_io.viewQuatFinal * Vec3(deltaDotSide * 0.1f + m_in.stats_leanAmount * 0.05f,0,deltaDotUp * 0.1f - fabs(m_in.stats_leanAmount) * 0.05f) * m_in.params_weaponInertiaMultiplier; weaponAngleOffset.x -= deltaDotUp * 5.0f * m_in.params_weaponInertiaMultiplier; weaponAngleOffset.z += deltaDotSide * 5.0f * m_in.params_weaponInertiaMultiplier; weaponAngleOffset.y += deltaDotSide * 5.0f * m_in.params_weaponInertiaMultiplier; if(m_in.stats_leanAmount<0.0f) weaponAngleOffset.y += m_in.stats_leanAmount * 5.0f; //the weapon model tries to stay parallel to the terrain when the player is freefalling/parachuting if (m_in.stats_inWater > 0.0f) weaponOffset -= m_io.viewQuat.GetColumn2() * 0.15f; if (m_in.stats_inWater>0.1f && !m_in.stats_headUnderWater) { Ang3 offset(m_io.viewQuatFinal); offset.z = 0; if (offset.x<0.0f) offset.x = 0; weaponAngleOffset -= offset*(180.0f/gf_PI)*0.75f; } else if (m_io.stats_inFreefall) { Ang3 offset(m_io.viewQuatFinal); offset.z = 0; weaponAngleOffset -= offset*(180.0f/gf_PI)*0.5f; } //same thing with crawling else if (crawling) { //FIXME:to optimize, looks like a bit too expensive Vec3 forward(m_io.viewQuatFinal.GetColumn1()); Vec3 up(m_io.baseQuat.GetColumn2()); Vec3 right(-(up % forward)); Matrix33 mat; mat.SetFromVectors(right,up%right,up); mat.OrthonormalizeFast(); Ang3 offset(m_io.viewQuatFinal.GetInverted() * Quat(mat)); weaponAngleOffset += offset*(180.0f/gf_PI)*0.5f; float lookDown(m_io.viewQuatFinal.GetColumn1() * m_io.baseQuat.GetColumn2()); weaponOffset += m_io.baseQuat * Vec3(0,-0.5f*max(-lookDown,0.0f),-0.05f); float scale = 0.5f;; if(weaponAngleOffset.x>0.0f) { scale = min(0.5f,weaponAngleOffset.x/15.0f); weaponAngleOffset.x *= scale; } else { scale = min(0.5f,-weaponAngleOffset.x/20.0f); weaponAngleOffset *= (1.0f-scale); weaponOffset *= scale; } //if(vSpeedLen>0.1f) //weaponAngleOffset += Ang3(-8.0f,0,-12.5f); } else if (m_in.bSprinting && vSpeedLen>0.5f) { weaponAngleOffset += Ang3(-20.0f,0,10.0f); weaponOffset += m_io.viewQuatFinal * Vec3(0.0f, -.01f, .1f); } else if (m_in.bLookingAtFriendlyAI && !weaponZomming && !weaponZoomed) { weaponAngleOffset += Ang3(-15.0f,0,8.0f); weaponOffset += m_io.viewQuatFinal * Vec3(0.0f, -.01f, .05f); } //apply some multipliers weaponOffset *= m_in.params_weaponBobbingMultiplier; angOffset *= m_io.bobMul * 0.25f; if (m_io.bobMul*m_io.bobMul!=1.0f) { weaponOffset *= m_io.bobMul; weaponAngleOffset *= m_io.bobMul; } float bobSpeedMult(1.0f); if(m_in.stats_inWater>0.1) bobSpeedMult = 0.75f; // m_io.viewQuatForWeapon *= Quat::CreateRotationXYZ(Ang3(rx,ry,rz)); Interpolate(m_io.vFPWeaponOffset,weaponOffset,3.95f*bobSpeedMult,m_in.frameTime); Interpolate(m_io.vFPWeaponAngleOffset,weaponAngleOffset,10.0f*bobSpeedMult,m_in.frameTime); Interpolate(m_io.vFPWeaponLastDirVec,m_io.viewQuatFinal.GetColumn1(),5.0f*bobSpeedMult,m_in.frameTime); Interpolate(m_io.angleOffset,angOffset,10.0f,m_in.frameTime,0.002f); if(weaponZomming) { m_io.vFPWeaponLastDirVec = m_io.viewQuatFinal.GetColumn1(); m_io.vFPWeaponOffset.Set(0.0f,0.0f,0.0f); m_io.vFPWeaponAngleOffset.Set(0.0f,0.0f,0.0f); m_io.bobOffset.Set(0.0f,0.0f,0.0f); } if (m_in.bSprinting) { float headBobScale = (m_in.stats_flatSpeed / m_in.standSpeed); headBobScale = min(1.0f, headBobScale); m_io.bobOffset = m_io.vFPWeaponOffset * 2.5f * g_pGameCVars->cl_headBob * headBobScale; float bobLenSq = m_io.bobOffset.GetLengthSquared(); float bobLenLimit = g_pGameCVars->cl_headBobLimit; if (bobLenSq > bobLenLimit*bobLenLimit) { float bobLen = sqrt_tpl(bobLenSq); m_io.bobOffset *= bobLenLimit/bobLen; } viewParams.position += m_io.bobOffset; } }
void CPlayerView::ViewThirdPerson(SViewParams &viewParams) { if (m_in.thirdPersonYaw>0.001f) { viewParams.rotation *= Quat::CreateRotationXYZ(Ang3(0,0,m_in.thirdPersonYaw * gf_PI/180.0f)); m_io.viewQuatFinal = viewParams.rotation; } if (g_pGameCVars->goc_enable) { Vec3 target(g_pGameCVars->goc_targetx, g_pGameCVars->goc_targety, g_pGameCVars->goc_targetz); static Vec3 current(target); Interpolate(current, target, 5.0f, m_in.frameTime); // make sure we don't clip through stuff that much Vec3 offsetX(0,0,0); Vec3 offsetY(0,0,0); Vec3 offsetZ(0,0,0); offsetX = m_io.viewQuatFinal.GetColumn0() * current.x; offsetY = m_io.viewQuatFinal.GetColumn1() * current.y; offsetZ = m_io.viewQuatFinal.GetColumn2() * current.z; IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_in.entityId); if (pActor) { static ray_hit hit; IPhysicalEntity* pSkipEntities[10]; int nSkip = 0; IItem* pItem = pActor->GetCurrentItem(); if (pItem) { CWeapon* pWeapon = (CWeapon*)pItem->GetIWeapon(); if (pWeapon) nSkip = CSingle::GetSkipEntities(pWeapon, pSkipEntities, 10); } float oldLen = offsetY.len(); Vec3 start = m_io.baseQuat * m_io.eyeOffsetView + viewParams.position+offsetX+offsetZ; if (gEnv->pPhysicalWorld->RayWorldIntersection(start, offsetY, ent_static|ent_terrain|ent_rigid, rwi_ignore_noncolliding | rwi_stop_at_pierceable, &hit, 1, pSkipEntities, nSkip)) { offsetY = hit.pt - start; if (offsetY.len()> 0.25f) { offsetY -= offsetY.GetNormalized()*0.25f; } current.y = current.y * (hit.dist/oldLen); } } //viewParams.position += m_io.viewQuatFinal.GetColumn0() * current.x; // right //viewParams.position += m_io.viewQuatFinal.GetColumn1() * current.y; // back //viewParams.position += m_io.viewQuatFinal.GetColumn2() * current.z; // up viewParams.position += offsetX + offsetY + offsetZ; } else { if (m_io.bUsePivot) viewParams.position += m_io.viewQuatFinal.GetColumn1() * m_in.params_viewDistance + m_io.viewQuatFinal.GetColumn2() * (0.25f + m_in.params_viewHeightOffset); else { viewParams.position += m_io.viewQuatFinal.GetColumn1() * -m_in.thirdPersonDistance + m_io.viewQuatFinal.GetColumn2() * (0.25f + m_in.params_viewHeightOffset); } } }
float CGameStateRecorder::RenderInfo(float y, bool bRecording) { float retY = 0; IRenderer *pRenderer = gEnv->pRenderer; if (bRecording) { float fColor[4] = {1,0,0,1}; pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false," Recording game state"); retY +=15; } else { const float xp = 300; const float xr = 400; const float xri = 600; float fColor[4] = {0,1,0,1}; float fColorWarning[4] = {1,1,0,1}; const char* actorName = m_demo_actorInfo->GetString(); CActor *pActor = GetActorOfName(actorName); if(pActor) { pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false," Game state - Actor: %s --------------------------------------------------",pActor->GetEntity()? pActor->GetEntity()->GetName(): "(no entity)"); retY +=15; if(m_itSingleActorGameState != m_GameStates.end() && pActor->GetEntity() && m_itSingleActorGameState->first == pActor->GetEntity()->GetId()) { ICVar *pVar = gEnv->pConsole->GetCVar( "demo_force_game_state" ); if(pVar) { int demo_forceGameState = pVar->GetIVal(); if(demo_forceGameState) { pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false,demo_forceGameState==1 ? " Override mode = (health, suit energy)" : " Override mode = (all)"); retY +=15; } } pRenderer->Draw2dLabel( xp,y+retY, 1.3f, fColor,false,"Current"); pRenderer->Draw2dLabel( xr,y+retY, 1.3f, fColor,false,"Recorded"); retY +=15; SActorGameState& gstate = m_itSingleActorGameState->second; float recordedHealth = (float)gstate.health; float health = (float)pActor->GetHealth(); bool bError = CHECK_MISMATCH(health, recordedHealth,10); pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false," Health:"); pRenderer->Draw2dLabel( xp,y+retY, 1.3f, bError? fColorWarning : fColor, false,"%d",(int)health); pRenderer->Draw2dLabel( xr,y+retY, 1.3f, bError? fColorWarning : fColor, false,"%d",(int)recordedHealth); retY +=15; // items pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false," Inventory ---------------------------------------------------------------------------------------"); retY +=15; pRenderer->Draw2dLabel( xp,y+retY, 1.3f, fColor,false,"Current"); pRenderer->Draw2dLabel( xri,y+retY, 1.3f, fColor,false,"Recorded"); retY +=15; CInventory *pInventory = (CInventory*)(pActor->GetInventory()); if(pInventory) { int nInvItems = pInventory->GetCount(); TItemContainer& Items = gstate.Items; int nRecItems = Items.size(); int maxItems = max(nRecItems,nInvItems); int i=0; EntityId curSelectedId = pActor->GetCurrentItemId(); TItemName curSelClass = GetItemName(curSelectedId); bool bSelectedError = !equal_strings(gstate.itemSelected,curSelClass); for(; i< nInvItems; i++) { IItem *pItem = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(pInventory->GetItem(i)); if(pItem) { TItemName szItemName = GetItemName(pItem->GetEntityId()); TItemContainer::iterator it = Items.find(szItemName); bError = it==Items.end(); pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false," %2d)",i+1); EntityId curId = pItem->GetEntityId(); TItemName curClass = GetItemName(curId); if(equal_strings(curClass,curSelClass) ) pRenderer->Draw2dLabel( xp-16,y+retY, 1.3f,bSelectedError ? fColorWarning:fColor, false, "[]"); if(equal_strings(szItemName, gstate.itemSelected)) pRenderer->Draw2dLabel( xri-16,y+retY, 1.3f,bSelectedError ? fColorWarning:fColor, false, "[]"); char itemName[32]; const char* originalItemName = pItem->GetEntity() ? pItem->GetEntity()->GetName():"(null)"; int length = strlen(originalItemName); length = min(length,31); strncpy(itemName,originalItemName,length); itemName[length]=0; pRenderer->Draw2dLabel( 1,y+retY, 1.3f, bError? fColorWarning : fColor, false," %s",itemName); if(bError) pRenderer->Draw2dLabel( xp,y+retY, 1.3f, fColorWarning, false, "Missing"); else { SItemProperties& recItem = it->second; CWeapon *pWeapon = (CWeapon*)(pItem->GetIWeapon()); IEntityClass* pItemClass = pItem->GetEntity()->GetClass(); if(pItemClass && !strcmpi(pItemClass->GetName(),"binoculars")) pWeapon = NULL; // no fire mode or ammo recorded for binocular (which is a weapon) if(pWeapon) { int idx = 0; // ammo float xa = 0; for(SWeaponAmmo weaponAmmo = pWeapon->GetFirstAmmo(); weaponAmmo.pAmmoClass ; weaponAmmo = pWeapon->GetNextAmmo()) { int ammoCount = weaponAmmo.count; const char* ammoClass; if(weaponAmmo.pAmmoClass && (ammoClass = weaponAmmo.pAmmoClass->GetName())) { TAmmoContainer::iterator it = recItem.Ammo.find(ammoClass); if(it!=recItem.Ammo.end()) { int recAmmoCount = recItem.Ammo[ammoClass]; bool bError2 = ammoCount!=recAmmoCount; pRenderer->Draw2dLabel( xp+xa,y+retY, 1.3f, bError2? fColorWarning : fColor, false,"Am%d:%d",idx,ammoCount); pRenderer->Draw2dLabel( xri+xa,y+retY, 1.3f, bError2? fColorWarning : fColor, false,"Am%d:%d",idx,recAmmoCount); xa += 50; ++idx; if(idx%5 ==0) { xa=0; retY+=15; } } } } // current fire mode int curFireModeIdx = pWeapon->GetCurrentFireMode(); int recFireModeIdx = recItem.fireMode; bool bError3 = curFireModeIdx!= recFireModeIdx; pRenderer->Draw2dLabel( xp+xa,y+retY, 1.3f, bError3? fColorWarning : fColor, false,"FMode:%d",curFireModeIdx); pRenderer->Draw2dLabel( xri+xa,y+retY, 1.3f, bError3? fColorWarning : fColor, false,"FMode:%d",recFireModeIdx); } else { pRenderer->Draw2dLabel( xp,y+retY, 1.3f, fColor, false, "Ok"); } } } retY +=15; } /// Accessories int nInvAccessories = pInventory->GetAccessoryCount(); TAccessoryContainer& Accessories = gstate.Accessories; int nRecAccessories = Accessories.size(); if(nRecAccessories) { pRenderer->Draw2dLabel( 1,y+retY, 1.3f, bError? fColorWarning : fColor, false," Accessories"); retY +=15; } for(int j=0 ; j< nInvAccessories; j++,i++) { const char* accessory = pInventory->GetAccessory(j); if(accessory && strlen(accessory)) { IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(accessory); if(pClass) { TItemName szItemName = pClass->GetName(); TAccessoryContainer::iterator it = Accessories.find(szItemName); bError = it==Accessories.end(); pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false," %2d)",i+1); char itemName[32]; int length = strlen(accessory); length = min(length,31); strncpy(itemName,accessory,length); itemName[length]=0; pRenderer->Draw2dLabel( 1,y+retY, 1.3f, bError? fColorWarning : fColor, false," %s",itemName); if(bError) pRenderer->Draw2dLabel( xp,y+retY, 1.3f, fColorWarning, false, "Missing"); else pRenderer->Draw2dLabel( xp,y+retY, 1.3f, fColor, false, "Ok"); retY +=15; } } } /// Ammo Mags TAmmoContainer& Ammo = gstate.AmmoMags; int nRecAmmo = Ammo.size(); int nInvAmmo = pInventory->GetAmmoPackCount(); if(nInvAmmo) { pRenderer->Draw2dLabel( 1,y+retY, 1.3f, bError? fColorWarning : fColor, false," Ammo Packs"); retY +=15; } pInventory->AmmoIteratorFirst(); for(int j=0 ; !pInventory->AmmoIteratorEnd(); j++, pInventory->AmmoIteratorNext()) { TAmmoContainer& Mags = gstate.AmmoMags; const IEntityClass* pAmmoClass = pInventory->AmmoIteratorGetClass(); if(pAmmoClass) { int invAmmoCount = pInventory->AmmoIteratorGetCount(); const char* ammoClassName = pAmmoClass->GetName(); bool bNotFound = Mags.find(ammoClassName) == Mags.end(); int recAmmoCount = bNotFound ? 0 :Mags[ammoClassName]; bool bError = bNotFound || invAmmoCount!= recAmmoCount; pRenderer->Draw2dLabel( 1,y+retY, 1.3f, bError? fColorWarning : fColor, false," %s:",ammoClassName); pRenderer->Draw2dLabel( xp,y+retY, 1.3f, bError? fColorWarning : fColor, false,"%d",invAmmoCount); if(bNotFound) pRenderer->Draw2dLabel( xr,y+retY, 1.3f, fColorWarning, false,"NotRecd"); else pRenderer->Draw2dLabel( xr,y+retY, 1.3f, bError? fColorWarning : fColor, false,"%d",recAmmoCount); retY +=15; } } } } else // m_itSingleActorGameState != m_GameStates.end() { pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false, "<<Not Recorded>>"); retY +=15; } } else // pActor { pRenderer->Draw2dLabel( 1,y+retY, 1.3f, fColor,false, "<<Actor %s not in the map>>",actorName ? actorName:"(no name)"); retY +=15; } } return retY; }
void CGameStateRecorder::OnRecordedGameplayEvent(IEntity *pEntity, const GameplayEvent &event, int currentFrame, bool bRecording) { EntityId id; m_currentFrame = currentFrame; int demo_forceGameState = 0; if(!bRecording) { ICVar *pVar = gEnv->pConsole->GetCVar( "demo_force_game_state" ); if(pVar) demo_forceGameState = pVar->GetIVal(); } if(!pEntity || !(id = pEntity->GetId())) return; if(m_IgnoredEvents.size()) if(event.event == m_IgnoredEvents[0]) { m_IgnoredEvents.erase(m_IgnoredEvents.begin()); return; } TGameStates::iterator itActor = m_GameStates.find(id); if(itActor == m_GameStates.end()) { m_GameStates.insert(std::make_pair(id,SActorGameState())); itActor = m_GameStates.find(id); } if(itActor == m_GameStates.end()) { GameWarning("TimeDemo:GameState: actor %s not found in records",pEntity->GetName()); return; } SActorGameState& gstate = itActor->second; switch(event.event) { case eGE_HealthChanged: { gstate.health = event.value; if(!m_bRecording) { CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor) { if(m_bLogWarning) { if(CHECK_MISMATCH(pActor->GetHealth(), gstate.health,10)) { if(!gstate.bHealthDifferent) { GameWarning("TimeDemo:GameState: Frame %d - Actor %s - HEALTH mismatch (%d, %d)",m_currentFrame,pEntity->GetName(), static_cast<int>(pActor->GetHealth()), static_cast<int>(gstate.health)); gstate.bHealthDifferent = true; } } else gstate.bHealthDifferent = false; } if( demo_forceGameState) pActor->SetHealth(gstate.health); } } } break; case eGE_WeaponFireModeChanged: { TItemName sel = (event.description); if(sel) { TItemContainer& Items = gstate.Items; TItemContainer::iterator iti = Items.find(sel); uint8 recFireModeIdx = uint8(event.value); if(iti != Items.end()) iti->second.fireMode = recFireModeIdx; CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor && pActor->GetInventory()) { IItem* pItem = pActor->GetInventory()->GetItemByName(sel); CWeapon* pWeapon; if(pItem && (pWeapon = (CWeapon*)(pItem->GetIWeapon()))) { int fireModeIdx = pWeapon->GetCurrentFireMode(); if(m_bLogWarning) { CheckDifference(recFireModeIdx,fireModeIdx,"TimeDemo:GameState: Frame %d - Actor %s - FIRE MODE mismatch for weapon %s (rec:%d, cur:%d)",pEntity,pItem->GetEntity() ? pItem->GetEntity()->GetName() : "(null)"); } if(demo_forceGameState==2 && fireModeIdx!= recFireModeIdx) pWeapon->SetCurrentFireMode(recFireModeIdx); } } } } break; case eGE_WeaponReload: { const char* ammoType = event.description; TAmmoContainer& ammoMags = gstate.AmmoMags; TAmmoContainer::iterator it = ammoMags.find(ammoType); if(it!=ammoMags.end()) { it->second -= (uint16)event.value; CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor) { CInventory* pInventory = (CInventory*)(pActor->GetInventory()); if(pInventory) { { IEntityClass* pAmmoClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(ammoType); if(pAmmoClass) { if(m_bLogWarning) CheckDifference(it->second,pInventory->GetAmmoCount(pAmmoClass),"TimeDemo:GameState: Frame %d - Actor %s - WEAPON RELOAD, ammo count mismatch for ammo class %s (rec:%d, cur:%d)",pEntity,ammoType); if(demo_forceGameState == 2) pInventory->SetAmmoCount(pAmmoClass,it->second); } } } } } } break; case eGE_ItemSelected: { TItemName itemName = event.description; gstate.itemSelected = itemName; if(itemName) { if( !bRecording && (event.value > 0 || demo_forceGameState==2)) // EVENT.VALUE > 0 means initialization { CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor && pActor->GetInventory()) { IItem* pItem = pActor->GetInventory()->GetItemByName(itemName); if(pItem) pActor->SelectItem(pItem->GetEntityId(),false); } } } if(m_bLogWarning) { CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor) { IItem* pItem = pActor->GetCurrentItem(); const char* curItemName= pItem && pItem->GetEntity() ? pItem->GetEntity()->GetName(): NULL; CheckDifferenceString(itemName,curItemName,"TimeDemo:GameState: Frame %d - Actor %s - SELECTED ITEM mismatch (rec:%s, cur:%s)",pEntity); } } break; } break; case eGE_ItemExchanged: { // prevent unwanted record/play mismatch error with current item during item exchanging // two unneeded game events are sent (selecting fists) m_IgnoredEvents.push_back(eGE_ItemSelected); m_IgnoredEvents.push_back(eGE_ItemSelected); } break; case eGE_ItemPickedUp: { TItemName sel = (TItemName)event.description; // gstate.itemSelected = sel; TItemContainer& Items = gstate.Items; TItemContainer::iterator it = Items.find(sel); if(it == Items.end()) { Items.insert(std::make_pair(sel,SItemProperties())); it = Items.find(sel); } if(it != Items.end()) { it->second.count++; CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor && !m_bRecording) { CInventory* pInventory = (CInventory*)(pActor->GetInventory()); if(pInventory) { // just check if the item is the inventory if(m_bLogWarning && !pInventory->GetItemByName(sel)) GameWarning("TimeDemo:GameState: Frame %d - Actor %s - Recorded PICKED UP ITEM class '%s' not found in current inventory",m_currentFrame,pEntity->GetName(),sel); if(demo_forceGameState == 2) { IEntity* pItemEntity = gEnv->pEntitySystem->FindEntityByName(sel); if(pItemEntity) pInventory->AddItem(pItemEntity->GetId()); else GameWarning("TimeDemo:GameState: Frame %d - Actor %s - PICKED UP ITEM entity %s not found in level",m_currentFrame,pEntity->GetName(),sel); } } } } else if(m_bLogWarning) { if(!sel) sel = "(null)"; GameWarning("TimeDemo:GameState: Frame %d - Actor %s - PICKED UP ITEM %s not found in recorded inventory",m_currentFrame,pEntity->GetName(),sel); } } break; case eGE_AmmoPickedUp: { uint16 ammoCount = (uint16)(event.value); TItemName sel = (TItemName)event.description; TAmmoContainer& Ammo = gstate.AmmoMags; TAmmoContainer::iterator it = Ammo.find(sel); if(it == Ammo.end()) Ammo.insert(std::make_pair(sel,ammoCount)); else it->second = ammoCount; if( !m_bRecording) { CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor) { CInventory* pInventory = (CInventory*)(pActor->GetInventory()); if(pInventory) { IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(sel); if(m_bLogWarning) CheckDifference(ammoCount,pInventory->GetAmmoCount(pClass),"TimeDemo:GameState: Frame %d - Actor %s - AMMO PICKEDUP: count mismatch for ammo class %s (rec:%d, cur:%d)", pEntity,sel); if(demo_forceGameState == 2) pInventory->SetAmmoCount(pClass,ammoCount); } } } } break; case eGE_AccessoryPickedUp: { TItemName sel = (TItemName)event.description; // gstate.itemSelected = sel; TAccessoryContainer& Accessories = gstate.Accessories; TAccessoryContainer::iterator it = Accessories.find(sel); if(it == Accessories.end()) { Accessories.insert(std::make_pair(sel,1)); } else it->second++; CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor) { CInventory* pInventory = (CInventory*)(pActor->GetInventory()); if(pInventory) { IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(sel); if(m_bLogWarning && !pInventory->HasAccessory(pClass)) GameWarning("TimeDemo:GameState: Frame %d - Actor %s - ACCESSORY PICKEDUP %s not found in current inventory", m_currentFrame, pEntity->GetName(),sel ? sel:"(null)"); if(demo_forceGameState == 2 && pClass) pInventory->AddAccessory(pClass);// doesn't actually add it if it's there already } } } break; case eGE_ItemDropped: { TItemName sel = (TItemName)event.description; //gstate.itemSelected = sel; TItemContainer& Items = gstate.Items; TItemContainer::iterator it = Items.find(sel); if(it != Items.end()) { it->second.count--; if(it->second.count<=0) Items.erase(it); if(demo_forceGameState == 2) { CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor) { CInventory* pInventory = (CInventory*)(pActor->GetInventory()); if(pInventory) { IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(sel); if(pClass) { EntityId itemId = pInventory->GetItemByClass(pClass); if(itemId) pInventory->RemoveItem(itemId); } } } } } else GameWarning("TimeDemo:GameState: Frame %d - Actor %s - ITEM DROPPED, wrong item selected (%s)",m_currentFrame,pEntity->GetName(),sel); } break; case eGE_AmmoCount: { TItemContainer& Items = gstate.Items; TItemName itemClassDesc = event.description; TItemContainer::iterator it = Items.find(itemClassDesc); if(it != Items.end()) { SItemProperties& item = it->second; const char* ammoClassDesc = (const char*)(event.extra); if(ammoClassDesc) { string szAmmoClassDesc(ammoClassDesc); bool bAmmoMag = IsAmmoGrenade(ammoClassDesc); TAmmoContainer& itemAmmo = bAmmoMag ? gstate.AmmoMags : item.Ammo; if(itemAmmo.find(szAmmoClassDesc)==itemAmmo.end()) itemAmmo.insert(std::make_pair(szAmmoClassDesc,int(event.value))); else itemAmmo[szAmmoClassDesc] = (uint16)event.value; if(!bRecording && (m_bLogWarning || demo_forceGameState==2)) { CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor) { CInventory* pInventory = (CInventory*)(pActor->GetInventory()); if(pInventory) { IItem* pItem = pInventory->GetItemByName(itemClassDesc); if(pItem) { CWeapon* pWeapon = (CWeapon*)(pItem->GetIWeapon()); if(pWeapon) { IEntityClass* pAmmoClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(ammoClassDesc); if(pAmmoClass) { if(m_bLogWarning) { int curAmmoCount = (bAmmoMag ? pInventory->GetAmmoCount(pAmmoClass) : pWeapon->GetAmmoCount(pAmmoClass)); CheckDifference( int(event.value),curAmmoCount,"TimeDemo:GameState: Frame %d - Actor %s - AMMO COUNT mismatch for ammo class %s (rec:%d, cur:%d)",pEntity,ammoClassDesc); } if(demo_forceGameState==2) pWeapon->SetAmmoCount(pAmmoClass,int(event.value)); } } } } } } } else GameWarning("TimeDemo:GameState: Frame %d - Actor %s - AMMO COUNT null ammoClass descriptor",m_currentFrame,pEntity->GetName()); } else GameWarning("TimeDemo:GameState: Frame %d - Actor %s - AMMO COUNT wrong item selected (%s)",m_currentFrame,pEntity->GetName(),itemClassDesc); } break; case eGE_AttachedAccessory: { // always force attachment of accessory to the current weapon // kind of a workaround, the HUD weapon modifier menu is spawned during timedemo playback // but it doesn't use recorded input events if(!bRecording) { CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor) { CInventory* pInventory = (CInventory*)(pActor->GetInventory()); if(pInventory) { const char* sel = event.description; IEntityClass* pClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass(sel); if(!sel) sel = "(null)"; if(!pInventory->HasAccessory(pClass)) { if(m_bLogWarning) GameWarning("TimeDemo:GameState: Frame %d - Actor %s - ATTACHED ACCESSORY %s not found in current inventory", m_currentFrame,pEntity->GetName(),sel); } else { CItem* pCurrentItem = (CItem*)(pActor->GetCurrentItem()); if(pCurrentItem) pCurrentItem->SwitchAccessory(sel); } } } } } break; case eGE_EntityGrabbed: { if(demo_forceGameState==2) { TItemName itemName = event.description; if(itemName) { IEntity * pGrabbedEntity = gEnv->pEntitySystem->FindEntityByName(itemName); if(pGrabbedEntity) { CActor *pActor = (CActor*)(gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(pActor) { IItem* pItem = GetItemOfName(pActor,itemName); if(!pItem) { // it's a pickable entity, won't end up in the inventory //(otherwise it would be managed by eGE_ItemPickedUp) COffHand* pOffHand = static_cast<COffHand*>(pActor->GetWeaponByClass(CItem::sOffHandClass)); if(pOffHand && !pOffHand->GetPreHeldEntityId()) pOffHand->ForcePickUp(pGrabbedEntity->GetId()); } } } } } } break; default: break; } }
virtual void ProcessEvent( EFlowEvent event,SActivationInfo *pActInfo ) { IVehicleSystem * pVehicleSystem = NULL; IVehicle * pVehicle = NULL; switch(event) { case eFE_Initialize: { pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, false); break; } case eFE_Activate: { if (!pActInfo->pEntity) return; pVehicleSystem = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem(); pVehicle = pVehicleSystem->GetVehicle(pActInfo->pEntity->GetId()); if (!pVehicleSystem || !pVehicle) return; string givenString = GetPortString(pActInfo, IN_PARTS); currentParam = givenString.substr(0,givenString.find_first_of(":")); currentSetting = givenString.substr(givenString.find_first_of(":")+1,(givenString.length()-givenString.find_first_of(":"))); column1 = 10.f; column2 = 100.f; if (IsPortActive(pActInfo,IN_SHOW)) pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, true); break; } case eFE_Update: { IRenderer * pRenderer = gEnv->pRenderer; pVehicleSystem = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem(); pVehicle = pVehicleSystem->GetVehicle(pActInfo->pEntity->GetId()); if(!pVehicleSystem || !pActInfo->pEntity || !pVehicle) return; pRenderer->Draw2dLabel(column1,10,GetPortFloat(pActInfo,IN_SIZE)+2.f,Col_Cyan,false,pActInfo->pEntity->GetName()); if(currentParam=="Seats") { loops = 0; for(uint32 i=0;i<pVehicle->GetSeatCount();i++) { IVehicleSeat * currentSeat; if(currentSetting=="All") { currentSeat = pVehicle->GetSeatById(i+1); } else { currentSeat = pVehicle->GetSeatById(pVehicle->GetSeatId(currentSetting)); i = pVehicle->GetSeatCount()-1; } loops += 1; // column 1 string pMessage = ("%s:", currentSeat->GetSeatName()); if (column2<pMessage.size()*8*GetPortFloat(pActInfo, IN_SIZE)) column2=pMessage.size()*8*GetPortFloat(pActInfo, IN_SIZE); pRenderer->Draw2dLabel(column1,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),Col_Cyan,false,pMessage); // column 2 if(currentSeat->GetPassenger(true)) { pMessage = ("- %s", gEnv->pEntitySystem->GetEntity(currentSeat->GetPassenger(true))->GetName()); pRenderer->Draw2dLabel(column2,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),Col_Cyan,false,pMessage); } } } else if(currentParam=="Wheels") { pRenderer->Draw2dLabel(column1,50.f,GetPortFloat(pActInfo,IN_SIZE)+1.f,Col_Red,false,"!"); } else if(currentParam=="Weapons") { loops = 0; for(int i=0;i<pVehicle->GetWeaponCount();i++) { IItemSystem * pItemSystem = gEnv->pGame->GetIGameFramework()->GetIItemSystem(); IWeapon * currentWeapon; EntityId currentEntityId; IItem * pItem; if(currentSetting=="All") { currentEntityId = pVehicle->GetWeaponId(i+1); } else { currentEntityId = gEnv->pEntitySystem->FindEntityByName(currentSetting)->GetId(); i = pVehicle->GetWeaponCount()-1; } if(!pItemSystem->GetItem(currentEntityId)) return; pItem = pItemSystem->GetItem(currentEntityId); currentWeapon = pItem->GetIWeapon(); loops += 1; // column 1 string pMessageName = string().Format("%s", gEnv->pEntitySystem->GetEntity(currentEntityId)->GetName()); pRenderer->Draw2dLabel(column1,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),Col_Cyan,false,pMessageName); if (column2<pMessageName.size()*8*GetPortFloat(pActInfo, IN_SIZE)) column2=pMessageName.size()*8*GetPortFloat(pActInfo, IN_SIZE); // column 2 string pMessageValue = string().Format("seat: %s firemode: %i", pVehicle->GetWeaponParentSeat(currentEntityId)->GetSeatName(), currentWeapon->GetCurrentFireMode()).c_str(); pRenderer->Draw2dLabel(column2,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),Col_Cyan,false,pMessageValue); } } else if(currentParam=="Components") { loops = 0; for(int i=0;i<pVehicle->GetComponentCount();i++) { IVehicleComponent * currentComponent; if(currentSetting=="All") { currentComponent = pVehicle->GetComponent(i); } else { currentComponent = pVehicle->GetComponent(currentSetting); i = pVehicle->GetComponentCount()-1; } loops += 1; ColorF labelColor; labelColor = ColorF(currentComponent->GetDamageRatio(),(1.f-currentComponent->GetDamageRatio()),0.f); // column 1 string pMessageName = string().Format("%s", currentComponent->GetComponentName()).c_str(); pRenderer->Draw2dLabel(column1,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),labelColor,false,pMessageName); if (column2<pMessageName.size()*8*GetPortFloat(pActInfo, IN_SIZE)) column2=pMessageName.size()*8*GetPortFloat(pActInfo, IN_SIZE); // column 2 string pMessageValue = string().Format("%5.2f (%3.2f)", currentComponent->GetDamageRatio()*currentComponent->GetMaxDamage(), currentComponent->GetDamageRatio()).c_str(); pRenderer->Draw2dLabel(column2,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),labelColor,false,pMessageValue); } } else { pRenderer->Draw2dLabel(column1,50.f,GetPortFloat(pActInfo,IN_SIZE)+1.f,Col_Red,false,"no component selected!"); } break; } } };
//-------------------------------------------------------------------- bool CWeapon::OnActionAttack(EntityId actorId, const ActionId& actionId, int activationMode, float value) { if(!m_modifying) { COffHand * offHandWeapon = NULL; bool isOffHandSelected = false; GetOffHandInfo(this,isOffHandSelected,&offHandWeapon); if(IsTwoHand()) { if(offHandWeapon && (offHandWeapon->GetOffHandState()&(eOHS_HOLDING_GRENADE|eOHS_SWITCHING_GRENADE|eOHS_PICKING_ITEM))) return false; } if (activationMode == eAAM_OnPress) { if(PreActionAttack(true)) return true; bool isDualWield = false; CWeapon *dualWield = NULL; GetDualWieldInfo(this,isDualWield,&dualWield); // EXPANSION: Dino has rewritten dual wield control! /*if (isDualWield) { m_fire_alternation = !m_fire_alternation; m_requestedFire = true; if (!m_fire_alternation && dualWield->OutOfAmmo(false) && dualWield->CanReload()) { dualWield->Reload(); return true; } else if(m_fire_alternation && OutOfAmmo(false) && CanReload()) { Reload(); return true; } if (m_fire_alternation || (!dualWield->CanFire() || !dualWield->IsSelected())) { if(!IsWeaponRaised() && CanFire()) StartFire(); else if(!dualWield->IsWeaponRaised() && dualWield->IsSelected()) dualWield->StartFire(); } else if (dualWield->CanFire()) { if(!dualWield->IsWeaponRaised() && dualWield->CanFire()) dualWield->StartFire(); else if(!IsWeaponRaised()) StartFire(); } }*/ // /EXPANSION if (isDualWield) { if (offHandWeapon && !(offHandWeapon->GetOffHandState() & (eOHS_INIT_STATE))) return false; m_fire_alternation = false; if (!dualWield->IsWeaponRaised())// && dualWield->CanFire()) { dualWield->StartFire(); } /* else if(dualWield->OutOfAmmo(false) && !dualWield->IsReloading()) { dualWield->Reload(); }*/ dualWield->m_requestedFire = true; } else { if(!m_weaponRaised) { StartFire(); } m_requestedFire = true; } } else if (activationMode == eAAM_OnRelease) { PreActionAttack(false); // EXP 1: Don't stop both slave and master simultaneously!!! //Stop slave if(IsDualWieldMaster()) { //FireSlave(actorId,false); CWeapon *dualWield = NULL; IItem *slave = GetDualWieldSlave(); if (slave && slave->GetIWeapon()) dualWield = static_cast<CWeapon *>(slave); if(dualWield) { dualWield->StopFire(); dualWield->m_requestedFire=false; } } else if (m_fm) { m_fm->StopFire(); m_requestedFire = false; } // StopFire(); // /EXP 1 } } return true; }
void CItem::AttachAccessory(const ItemString &name, bool attach, bool noanim, bool force, bool initialSetup) { if(!force && IsBusy()) return; bool anim = !noanim && m_stats.fp; SAccessoryParams *params = GetAccessoryParams(name); if(!params) return; if(attach) { if(!IsAccessoryHelperFree(params->attach_helper)) return; if(CItem *pAccessory = AddAccessory(name)) { pAccessory->Physicalize(false, false); pAccessory->SetViewMode(m_stats.viewmode); if(!initialSetup) pAccessory->m_bonusAccessoryAmmo.clear(); SetCharacterAttachment(eIGS_FirstPerson, params->attach_helper, pAccessory->GetEntity(), eIGS_FirstPerson, 0); SetBusy(true); AttachAction action(pAccessory, params); if(anim) { PlayAction(params->attach_action, 0, false, eIPAF_Default|eIPAF_NoBlend); m_scheduler.TimerAction(GetCurrentAnimationTime(eIGS_FirstPerson), CSchedulerAction<AttachAction>::Create(action), false); } else action.execute(this); } } else { if(CItem *pAccessory = GetAccessory(name)) { DetachAction action(pAccessory, params); if(anim) { StopLayer(params->attach_layer, eIPAF_Default|eIPAF_NoBlend); PlayAction(params->detach_action, 0, false, eIPAF_Default|eIPAF_NoBlend); m_scheduler.TimerAction(GetCurrentAnimationTime(eIGS_FirstPerson), CSchedulerAction<DetachAction>::Create(action), false); SetBusy(true); } else { SetBusy(true); action.execute(this); } } } //Skip all this for the offhand if(GetEntity()->GetClass()!=CItem::sOffHandClass) FixAccessories(params, attach); //Attach silencer to 2nd SOCOM ///////////////////////////////////////////////////////////// bool isDualWield = IsDualWieldMaster(); CItem *dualWield = 0; if(isDualWield) { IItem *slave = GetDualWieldSlave(); if(slave && slave->GetIWeapon()) dualWield = static_cast<CItem *>(slave); else isDualWield = false; } if(isDualWield) dualWield->AttachAccessory(name,attach,noanim); ////////////////////////////////////////////////////////////// //Luciano - send game event g_pGame->GetIGameFramework()->GetIGameplayRecorder()->Event(GetOwner(), GameplayEvent(eGE_AttachedAccessory, name, (float)attach, (void *)GetEntityId())); }
void CPlayerStateJump::Landed(CPlayer& player, const bool isHeavyWeapon, float fallSpeed) { #ifdef STATE_DEBUG bool remoteControlled = false; IVehicle* pVehicle = player.GetLinkedVehicle(); if(pVehicle) { IVehicleSeat* pVehicleSeat = pVehicle->GetSeatForPassenger(player.GetEntityId()); if(pVehicleSeat && pVehicleSeat->IsRemoteControlled()) { remoteControlled = true; } } CRY_ASSERT_MESSAGE( player.GetLinkedEntity()==NULL || remoteControlled, "Cannot 'land' when you're linked to another entity!" ); #endif const SPlayerStats& stats = player.m_stats; Vec3 playerPosition = player.GetEntity()->GetWorldPos(); IPhysicalEntity *phys = player.GetEntity()->GetPhysics(); IMaterialEffects *mfx = gEnv->pGame->GetIGameFramework()->GetIMaterialEffects(); const SActorPhysics& actorPhysics = player.GetActorPhysics(); int matID = actorPhysics.groundMaterialIdx != -1 ? actorPhysics.groundMaterialIdx : mfx->GetDefaultSurfaceIndex(); const float fHeightofEntity = playerPosition.z; const float worldWaterLevel = player.m_playerStateSwim_WaterTestProxy.GetWaterLevel(); TMFXEffectId effectId = mfx->GetEffectId("bodyfall", matID); if (effectId != InvalidEffectId) { SMFXRunTimeEffectParams params; Vec3 direction = Vec3(0,0,0); if (IMovementController *pMV = player.GetMovementController()) { SMovementState state; pMV->GetMovementState(state); direction = state.aimDirection; } params.pos = playerPosition + direction; //params.soundSemantic = eSoundSemantic_Player_Foley; float landFallParamVal = (float)__fsel( -(fallSpeed - 7.5f), 0.25f, 0.75f); params.AddAudioRtpc("landfall", landFallParamVal); const float speedParamVal = min(fabsf((actorPhysics.velocity.z * 0.1f)), 1.0f); params.AddAudioRtpc("speed", speedParamVal); mfx->ExecuteEffect(effectId, params); } bool heavyLanded = false; IItem* pCurrentItem = player.GetCurrentItem(); CWeapon* pCurrentWeapon = pCurrentItem ? static_cast<CWeapon*>(pCurrentItem->GetIWeapon()) : NULL; if (fallSpeed > 0.0f && player.IsPlayer()) { if(!gEnv->bMultiplayer) { const float verticalSpeed = fabs(fallSpeed); const float speedForHeavyLand = g_pGameCVars->pl_health.fallSpeed_HeavyLand; if ((verticalSpeed >= speedForHeavyLand) && (player.GetPickAndThrowEntity() == 0) && !player.IsDead()) { if ( !isHeavyWeapon ) { if (pCurrentWeapon) { pCurrentWeapon->FumbleGrenade(); pCurrentWeapon->CancelCharge(); } player.StartInteractiveActionByName("HeavyLand", false); } heavyLanded = true; } } } if(player.m_isClient) { if (fallSpeed > 0.0f) { const float fallIntensityMultiplier = stats.wasHit ? g_pGameCVars->pl_fall_intensity_hit_multiplier : g_pGameCVars->pl_fall_intensity_multiplier; const float fallIntensityMax = g_pGameCVars->pl_fall_intensity_max; const float fallTimeMultiplier = g_pGameCVars->pl_fall_time_multiplier; const float fallTimeMax = g_pGameCVars->pl_fall_time_max; const float zoomMultiplayer = (pCurrentWeapon && pCurrentWeapon->IsZoomed()) ? 0.2f : 1.0f; const float direction = ((cry_rand()%2)==0) ? -1.0f : 1.0f; const float intensity = clamp_tpl(fallIntensityMultiplier*fallSpeed*zoomMultiplayer, 0.0f, fallIntensityMax); const float shakeTime = clamp_tpl(fallTimeMultiplier*fallSpeed*zoomMultiplayer, 0.0f, fallTimeMax); const Vec3 rotation = Vec3(-0.5f, 0.15f*direction, 0.05f*direction); if (CScreenEffects* pGameScreenEffects = g_pGame->GetScreenEffects()) { pGameScreenEffects->CamShake(rotation*intensity, Vec3(0, 0, 0), shakeTime, shakeTime, 0.05f, CScreenEffects::eCS_GID_Player); } IForceFeedbackSystem* pForceFeedback = g_pGame->GetIGameFramework()->GetIForceFeedbackSystem(); assert(pForceFeedback); ForceFeedbackFxId fxId = pForceFeedback->GetEffectIdByName("landFF"); pForceFeedback->PlayForceFeedbackEffect(fxId, SForceFeedbackRuntimeParams(intensity, 0.0f)); if(fallSpeed > 7.0f) { player.PlaySound(CPlayer::ESound_Fall_Drop); } CPlayer::EPlayerSounds playerSound = heavyLanded ? CPlayer::ESound_Gear_HeavyLand : CPlayer::ESound_Gear_Land; player.PlaySound(playerSound, true); } CCCPOINT(PlayerMovement_LocalPlayerLanded); } if( gEnv->pAISystem ) { // Notify AI //If silent feet active, ignore here const float noiseSupression = 0.0f; const float fAISoundRadius = (g_pGameCVars->ai_perception.landed_baseRadius + (g_pGameCVars->ai_perception.landed_speedMultiplier * fallSpeed)) * (1.0f - noiseSupression); SAIStimulus stim(AISTIM_SOUND, AISOUND_MOVEMENT_LOUD, player.GetEntityId(), 0, player.GetEntity()->GetWorldPos() + player.GetEyeOffset(), ZERO, fAISoundRadius); gEnv->pAISystem->RegisterStimulus(stim); } // Record 'Land' telemetry stats. CStatsRecordingMgr::TryTrackEvent(&player, eGSE_Land, fallSpeed); if (fallSpeed > 0.0f) { player.CreateScriptEvent( heavyLanded ? "heavylanded" : "landed",stats.fallSpeed); } }
//---------------------------------------------------------------------------- void CHomingMissile::UpdateCruiseMissile(float frameTime) { IRenderer* pRenderer = gEnv->pRenderer; IRenderAuxGeom* pGeom = pRenderer->GetIRenderAuxGeom(); float color[4] = {1,1,1,1}; const static float step = 15.f; float y = 20.f; bool bDebug = g_pGameCVars->i_debug_projectiles > 0; if (m_targetId) { IEntity* pTarget = gEnv->pEntitySystem->GetEntity(m_targetId); if (pTarget) { AABB box; pTarget->GetWorldBounds(box); SetDestination( box.GetCenter() ); //if (bDebug) //pRenderer->Draw2dLabel(5.0f, y+=step, 1.5f, color, false, "Target Entity: %s", pTarget->GetName()); } } else { // update destination pos from weapon static IItemSystem* pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem(); IItem* pItem = pItemSystem->GetItem(m_weaponId); if (pItem && pItem->GetIWeapon()) { const Vec3& dest = pItem->GetIWeapon()->GetDestination(); SetDestination( dest ); //if (bDebug) //pRenderer->Draw2dLabel(5.0f, y+=step, 1.5f, color, false, "Weapon Destination: (%.1f %.1f %.1f)", dest.x, dest.y, dest.z); } } pe_status_dynamics status; if (!GetEntity()->GetPhysics()->GetStatus(&status)) return; float currentSpeed = status.v.len(); Vec3 currentPos = GetEntity()->GetWorldPos(); Vec3 goalDir(ZERO); if (!m_destination.IsZero()) { if((currentPos-m_destination).len2()<(m_detonationRadius*m_detonationRadius)) { Explode(true, true, m_destination, -status.v.normalized(), status.v, m_targetId); return; } if (bDebug) pGeom->DrawCone(m_destination, Vec3(0,0,-1), 2.5f, 7.f, ColorB(255,0,0,255)); float heightDiff = (m_cruiseAltitude-m_alignAltitude) - currentPos.z; if (!m_isCruising && heightDiff * sgn(status.v.z) > 0.f) { // if heading towards align altitude (but not yet reached) accelerate to max speed if (bDebug) pRenderer->Draw2dLabel(5.0f, y+=step, 1.5f, color, false, "[HomingMissile] accelerating (%.1f / %.1f)", currentSpeed, m_maxSpeed); } else if (!m_isCruising && heightDiff * sgnnz(status.v.z) < 0.f && (status.v.z<0 || status.v.z>0.25f)) { // align to cruise if (currentSpeed != 0) { goalDir = status.v; goalDir.z = 0; goalDir.normalize(); } if (bDebug) pRenderer->Draw2dLabel(5.0f, y+=step, 1.5f, color, false, "[HomingMissile] aligning"); } else { if (bDebug) pRenderer->Draw2dLabel(5.0f, y+=step, 1.5f, color, false, "[HomingMissile] cruising..."); // cruise m_isCruising = true; if (!m_destination.IsZero()) { float groundDistSq = m_destination.GetSquaredDistance2D(currentPos); float distSq = m_destination.GetSquaredDistance(currentPos); float descendDistSq = sqr(m_descendDistance); if (m_isDescending || groundDistSq <= descendDistSq) { if (bDebug) pRenderer->Draw2dLabel(5.0f, y+=step, 1.5f, color, false, "[HomingMissile] descending!"); if (distSq != 0) goalDir = (m_destination - currentPos).normalized(); else goalDir.zero(); m_isDescending = true; } else { Vec3 airPos = m_destination; airPos.z = currentPos.z; goalDir = airPos - currentPos; if (goalDir.len2() != 0) goalDir.Normalize(); } } } } float desiredSpeed = currentSpeed; if (currentSpeed < m_maxSpeed-0.1f) { desiredSpeed = min(m_maxSpeed, desiredSpeed + m_accel*frameTime); } Vec3 currentDir = status.v.GetNormalizedSafe(FORWARD_DIRECTION); Vec3 dir = currentDir; if (!goalDir.IsZero()) { float cosine = max(min(currentDir.Dot(goalDir), 0.999f), -0.999f); float goalAngle = RAD2DEG(acos_tpl(cosine)); float maxAngle = m_turnSpeed * frameTime; if (bDebug) { pGeom->DrawCone( currentPos, goalDir, 0.4f, 12.f, ColorB(255,0,0,255) ); pRenderer->Draw2dLabel(5.0f, y+=step, 1.5f, color, false, "[HomingMissile] goalAngle: %.2f", goalAngle); } if (goalAngle > maxAngle+0.05f) dir = (Vec3::CreateSlerp(currentDir, goalDir, maxAngle/goalAngle)).normalize(); else //if (goalAngle < 0.005f) dir = goalDir; } pe_action_set_velocity action; action.v = dir * desiredSpeed; GetEntity()->GetPhysics()->Action(&action); if (bDebug) { pGeom->DrawCone( currentPos, dir, 0.4f, 12.f, ColorB(128,128,0,255) ); pRenderer->Draw2dLabel(5.0f, y+=step, 1.5f, color, false, "[HomingMissile] currentSpeed: %.1f (max: %.1f)", currentSpeed, m_maxSpeed); } }