//------------------------------------------------------------------------- void CLam::ActivateLight(bool activate, bool aiRequest /* = false */) { //GameWarning("CLam::ActivateLight(%i)", activate); CItem *pParent = NULL; EntityId ownerId = 0; if (IItem *pOwnerItem = m_pItemSystem->GetItem(GetParentId())) { pParent = (CItem *)pOwnerItem; IWeapon *pWeapon = pOwnerItem->GetIWeapon(); if(pWeapon) ownerId = pOwnerItem->GetOwnerId(); } else { pParent = this; ownerId = GetOwnerId(); } IActor *pOwnerActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(ownerId); if (activate && !pOwnerActor) return; //Special FP stuff if(pOwnerActor && pOwnerActor->IsPlayer() && !m_lamparams.isFlashLight) return; //For AI must be deactivated by default (if they don't request) if(activate && !m_lightWasOn && !aiRequest && !pOwnerActor->IsPlayer()) return; m_lightActivated = activate; //Activate or deactivate effect if (!m_lightActivated) { AttachLAMLight(false, pParent, eIGS_FirstPerson); AttachLAMLight(false, pParent, eIGS_ThirdPerson); //GameWarning("Global light count = %d", s_lightCount); } else { uint8 id = pOwnerActor->IsThirdPerson() ? 1 : 0; if (m_lightID[id] == 0) { AttachLAMLight(true, pParent, id?eIGS_ThirdPerson:eIGS_FirstPerson); } } if (m_laserActivated || m_lightActivated) GetGameObject()->EnablePostUpdates(this); if (!m_laserActivated && !m_lightActivated) GetGameObject()->DisablePostUpdates(this); }
//------------------------------------------------------------------------ void CWeaponSystem::RefGun(IConsoleCmdArgs *args) { IGameFramework *pGF = gEnv->pGame->GetIGameFramework(); IItemSystem *pItemSystem = pGF->GetIItemSystem(); IActor *pActor = pGF->GetClientActor(); if(!pActor || !pActor->IsPlayer()) return; IInventory *pInventory = pActor->GetInventory(); if(!pInventory) return; // give & select the refgun EntityId itemId = pInventory->GetItemByClass(CItem::sRefWeaponClass); if(0 == itemId) { // if actor doesn't have it, only give it in editor if(!gEnv->IsEditor()) return; itemId = pItemSystem->GiveItem(pActor, CItem::sRefWeaponClass->GetName(), false, true, true); } pItemSystem->SetActorItem(pActor, itemId, true); }
bool CGameRulesSpawningBase::CanPlayerSpawnThisRound(const EntityId playerId) const { bool allowed=true; IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(playerId); if (pActor->IsPlayer()) { CGameRules *pGameRules = g_pGame->GetGameRules(); IGameRulesPlayerStatsModule *playerStats = pGameRules ? pGameRules->GetPlayerStatsModule() : NULL; if (playerStats) { const SGameRulesPlayerStat *stats = playerStats->GetPlayerStats(playerId); if (stats) { if (stats->flags & SGameRulesPlayerStat::PLYSTATFL_CANTSPAWNTHISROUND) { allowed=false; } } } } CryLog("CGameRulesSpawningBase::CanPlayerSpawnThisRound() player=%s allowed=%d", pActor->GetEntity()->GetName(), allowed); return allowed; }
//------------------------------------------------------------------------ void CVehicleMountedWeapon::StartUse(EntityId userId) { IVehicle *pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(m_vehicleId); if (!IsRippingOff() && pVehicle) { m_pOwnerSeat = pVehicle->GetWeaponParentSeat(GetEntityId()); m_pSeatUser = pVehicle->GetSeatForPassenger(userId); IActor* pOwner = GetOwnerActor(); if (pOwner && !pOwner->IsPlayer()) { SHUDEvent hudEvent(eHUDEvent_AddEntity); hudEvent.AddData((int)pVehicle->GetEntityId()); CHUDEventDispatcher::CallEvent(hudEvent); } ClearItemFlags(eIF_InformClientsAboutUse); } CHeavyMountedWeapon::StartUse(userId); CActor* pActor = GetOwnerActor(); if (pActor && pActor->IsPlayer()) { static_cast<CPlayer*>(pActor)->RefreshVisibilityState(); } }
//------------------------------------------------------------------------ void CVehicleWeapon::SetAmmoCount(IEntityClass* pAmmoType, int count) { IActor* pOwner = GetOwnerActor(); if (pOwner && !pOwner->IsPlayer() && count < m_ammo[pAmmoType]) return; CWeapon::SetAmmoCount(pAmmoType, count); }
//------------------------------------------------------------------------ void CVehicleMountedWeapon::SetAmmoCount(IEntityClass* pAmmoType, int count) { IActor* pOwner = GetOwnerActor(); if (pOwner && !pOwner->IsPlayer() && count < SWeaponAmmoUtils::GetAmmoCount(m_ammo, pAmmoType)) return; CHeavyMountedWeapon::SetAmmoCount(pAmmoType, count); }
EContextEstablishTaskResult OnStep( SContextEstablishState& state ) { bool allowPlayers = (m_what & eFS_Players) != 0; bool allowGameRules = (m_what & eFS_GameRules) != 0; bool allowOthers = (m_what & eFS_Others) != 0; EntityId gameRulesId = 0; if (IEntity * pGameRules = CCryAction::GetCryAction()->GetIGameRulesSystem()->GetCurrentGameRulesEntity()) gameRulesId = pGameRules->GetId(); // we are in the editor, and that means that there have been entities spawned already // that are not bound to the network context... so lets bind them! IEntityItPtr pIt = gEnv->pEntitySystem->GetEntityIterator(); while (IEntity * pEntity = pIt->Next()) { bool isOther = true; bool isPlayer = false; IActor* pActor = CCryAction::GetCryAction()->GetIActorSystem()->GetActor(pEntity->GetId()); if (pActor && pActor->IsPlayer()) { isPlayer = true; isOther = false; } if (isPlayer && !allowPlayers) continue; bool isGameRules = false; if (pEntity->GetId() == gameRulesId) { isGameRules = true; isOther = false; } if (isGameRules && !allowGameRules) continue; if (isOther && !allowOthers) continue; CGameObject * pGO = (CGameObject *) pEntity->GetProxy( ENTITY_PROXY_USER ); if (pGO) { if (pGO->IsBoundToNetwork()) pGO->BindToNetwork(eBTNM_Force); // force rebinding } SEntitySpawnParams fakeParams; fakeParams.id = pEntity->GetId(); fakeParams.nFlags = pEntity->GetFlags(); fakeParams.pClass = pEntity->GetClass(); fakeParams.qRotation = pEntity->GetRotation(); fakeParams.sName = pEntity->GetName(); fakeParams.vPosition = pEntity->GetPos(); fakeParams.vScale = pEntity->GetScale(); CCryAction::GetCryAction()->GetGameContext()->OnSpawn( pEntity, fakeParams ); } return eCETR_Ok; }
int CScriptBind_Game::IsPlayer(IFunctionHandler *pH, ScriptHandle entityId) { EntityId eId = (EntityId)entityId.n; if(eId == LOCAL_PLAYER_ENTITY_ID) return pH->EndFunction(true); IActor *pActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(eId); return pH->EndFunction(pActor && pActor->IsPlayer()); }
//------------------------------------------------------------------------ void CVehicleMountedWeapon::CorrectRipperEntityPosition(float timeStep) { IVehicle *pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(m_vehicleId); if(pVehicle) { const IEntity* pVehicleEnt = pVehicle->GetEntity(); Vec3 posDiff(ZERO); IActor* pOwner = GetOwnerActor(); if (pOwner && pOwner->IsPlayer()) { CPlayer* pPlayer = static_cast<CPlayer*>(pOwner); const Matrix34& wMat = pVehicleEnt->GetWorldTM(); Vec3 vehiclePos = wMat.GetTranslation(); Vec3 currWSpaceRipUserOffset = wMat.TransformPoint(m_localRipUserOffset); posDiff = currWSpaceRipUserOffset - m_previousWSpaceOffsetPosition; // Don't want to overwrite anyone else changes with an absolute 'set' pOwner->GetEntity()->SetPos(pOwner->GetEntity()->GetWorldPos() + posDiff); m_previousWSpaceOffsetPosition = currWSpaceRipUserOffset; //Update view limit direction based on change in vehicle rotation if(pPlayer->IsClient()) { SViewLimitParams &viewLimits = pPlayer->GetActorParams().viewLimits; if(viewLimits.GetViewLimitRangeH()) //Don't do this unless we are currently horizontally constrained { Quat vehicleRotation(wMat); Quat rotationChange = vehicleRotation * m_previousVehicleRotation.GetInverted(); Vec3 viewLimitDir = rotationChange * viewLimits.GetViewLimitDir(); viewLimitDir.z = 0.f; viewLimitDir.Normalize(); viewLimits.SetViewLimit(viewLimitDir, 0.01f, 0.01f, 0.f, 0.f, SViewLimitParams::eVLS_Item); m_previousVehicleRotation = vehicleRotation; } //Reset the pitch/roll view angles over time Quat viewDirFinal = pPlayer->GetViewQuatFinal(); Ang3 viewAngles(viewDirFinal); float xAdjustment = (float)__fsel(viewAngles.x, max(-viewAngles.x, -0.5f * timeStep), min(-viewAngles.x, 0.5f * timeStep)); float yAdjustment = (float)__fsel(viewAngles.y, max(-viewAngles.y, -0.5f * timeStep), min(-viewAngles.y, 0.5f * timeStep)); if(xAdjustment || yAdjustment) { pPlayer->AddViewAngles(Ang3(xAdjustment, yAdjustment, 0.f)); } } } } }
//------------------------------------------------------------------------ CAVMine::~CAVMine() { if(gEnv->bMultiplayer && gEnv->bServer) { IActor* pOwner = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_ownerId); if(pOwner && pOwner->IsPlayer()) { ((CPlayer*)pOwner)->RecordExplosiveDestroyed(GetEntityId(), 1); } } }
//--------------------------------- void CFOVEffect::Init() { IActor *client = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_ownerID); if (client && client->IsPlayer()) { CPlayer *player = (CPlayer *)client; SActorParams *params = player->GetActorParams(); m_startFOV = params->viewFoVScale; m_currentFOV = m_startFOV; } }
//--------------------------------- void CFOVEffect::Update(float point) { m_currentFOV = (point * (m_goalFOV - m_startFOV)) + m_startFOV; IActor *client = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_ownerID); if (client && client->IsPlayer()) { CPlayer *player = (CPlayer *)client; SActorParams *params = player->GetActorParams(); params->viewFoVScale = m_currentFOV; } }
bool PlayerIsInAir() { bool InAir = false; IActor* pClientActor = gEnv->pGame->GetIGameFramework()->GetClientActor(); if (pClientActor && pClientActor->IsPlayer()) { CPlayer* pPlayer = static_cast<CPlayer*>(pClientActor); InAir = pPlayer->IsInAir() || pPlayer->IsInFreeFallDeath(); } return InAir; }
//------------------------------------------------------------------------ void CVehicleWeapon::SetInventoryAmmoCount(IEntityClass* pAmmoType, int count) { IActor* pOwner = GetOwnerActor(); if (pOwner && !pOwner->IsPlayer() && m_pVehicle) { if (count < m_pVehicle->GetAmmoCount(pAmmoType)) return; } CWeapon::SetInventoryAmmoCount(pAmmoType, count); }
//------------------------------------------------------------------------ void CVehicleMountedWeapon::SetInventoryAmmoCount(IEntityClass* pAmmoType, int count) { IActor* pOwner = GetOwnerActor(); IVehicle *pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(m_vehicleId); if (pVehicle && pOwner && !pOwner->IsPlayer()) { if (count < pVehicle->GetAmmoCount(pAmmoType)) return; } CHeavyMountedWeapon::SetInventoryAmmoCount(pAmmoType, count); }
//------------------------------------------------------------------------ void CVehicleSeatActionMovement::StopUsing() { IActorSystem* pActorSystem = CCryAction::GetCryAction()->GetIActorSystem(); CRY_ASSERT(pActorSystem); IVehicleMovement* pMovement = m_pVehicle->GetMovement(); if (!pMovement) return; CRY_ASSERT(m_pSeat); // default to continuing for a bit m_delayedStop = 0.8f; IActor* pActor = pActorSystem->GetActor(m_pSeat->GetPassenger()); if (pActor && pActor->IsPlayer()) { // if stopped already don't go anywhere IPhysicalEntity* pPhys = m_pVehicle->GetEntity()->GetPhysics(); pe_status_dynamics status; if (pPhys && pPhys->GetStatus(&status)) { if (status.v.GetLengthSquared() < 25.0f) m_delayedStop = 0.0f; } if (m_actionForward > 0.0f) m_delayedStop = 1.5f; if (pMovement->GetMovementType() == IVehicleMovement::eVMT_Air) m_delayedStop *= 2.0f; m_pVehicle->SetObjectUpdate(this, IVehicle::eVOU_AlwaysUpdate); // prevent full pedal being kept pressed, but give it a bit pMovement->OnAction(eVAI_MoveForward, eAAM_OnPress, 0.1f); } else { if (pMovement->GetMovementType() == IVehicleMovement::eVMT_Air) { m_delayedStop = 0.0f; m_pVehicle->SetObjectUpdate(this, IVehicle::eVOU_AlwaysUpdate); } else { pMovement->StopDriving(); } } }
bool CHUDCrosshair::IsFriendlyEntity(IEntity *pEntity) { IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); CGameRules *pGameRules = g_pGame->GetGameRules(); if(!pEntity || !pClientActor || !pGameRules) return false; // Less than 2 teams means we are in a FFA based game. if(pGameRules->GetTeamCount() < 2) return false; bool bFriendly = false; int iClientTeam = pGameRules->GetTeam(pClientActor->GetEntityId()); // First, check if entity is a player IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pEntity->GetId()); if(pActor && pActor->IsPlayer()) { if(iClientTeam && (pGameRules->GetTeam(pActor->GetEntityId()) == iClientTeam)) { bFriendly = true; } } else { // Then, check if entity is a vehicle IVehicle *pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(pEntity->GetId()); if(pVehicle && pGameRules->GetTeam(pVehicle->GetEntityId()) == iClientTeam && pVehicle->GetStatus().passengerCount) { IActor *pDriver = pVehicle->GetDriver(); /*if(pDriver && pGameRules->GetTeam(pDriver->GetEntityId()) == iClientTeam) bFriendly = true; else bFriendly = false;*/ bFriendly = true; //fix for bad raycast if(pDriver && pDriver == pClientActor) bFriendly = false; } } return bFriendly; }
EContextEstablishTaskResult OnStep( SContextEstablishState& state ) { CScopedRemoveObjectUnlock unlockRemovals(CCryAction::GetCryAction()->GetGameContext()); if (m_skipGameRules || m_skipPlayers) { IEntityItPtr i = gEnv->pEntitySystem->GetEntityIterator(); while(!i->IsEnd()) { IEntity* pEnt = i->Next(); // skip gamerules if (m_skipGameRules) if (pEnt->GetId() == CCryAction::GetCryAction()->GetIGameRulesSystem()->GetCurrentGameRulesEntity()->GetId()) continue; // skip players if (m_skipPlayers) { IActor* pActor = CCryAction::GetCryAction()->GetIActorSystem()->GetActor(pEnt->GetId()); if (pActor && pActor->IsPlayer()) continue; } pEnt->ClearFlags(ENTITY_FLAG_UNREMOVABLE); // force remove all other entities gEnv->pEntitySystem->RemoveEntity(pEnt->GetId(), true); } if (!m_skipGameRules) gEnv->pEntitySystem->ReserveEntityId(1); } else { if(!gEnv->pSystem->IsSerializingFile()) gEnv->pEntitySystem->Reset(); gEnv->pEntitySystem->ReserveEntityId(1); } gEnv->pEntitySystem->ReserveEntityId( LOCAL_PLAYER_ENTITY_ID ); CActionGame::Get()->OnEntitySystemReset(); return eCETR_Ok; }
void CVehicleMountedWeapon::Use( EntityId userId ) { IVehicle *pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(m_vehicleId); if (!IsRippingOff() && pVehicle) { IActor* pUserActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(userId); if(pUserActor && pUserActor->IsPlayer()) { CPlayer* pPlayer = static_cast<CPlayer*>(pUserActor); IInteractor* pInteractor = pPlayer->GetInteractor(); pVehicle->OnUsed(userId, pInteractor->GetOverSlotIdx()); return; } } CHeavyMountedWeapon::Use(userId); }
void CStickyProjectile::NetSetStuck(CProjectile* pProjectile, bool stuck) { if(stuck && ((m_flags&eSF_IsStuck)==0)) { IEntity* pTargetEntity = gEnv->pEntitySystem->GetEntity(m_parentId); if(pTargetEntity) { if(ICharacterInstance* pTargetCharacter = pTargetEntity->GetCharacter(0)) { const char* boneName = pTargetCharacter->GetICharacterModel()->GetICharacterModelSkeleton()->GetJointNameByID(m_stuckJoint); if(AttachToCharacter(pProjectile, *pTargetEntity, *pTargetCharacter, boneName)) { IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTargetEntity->GetId()); m_flags |= eSF_IsStuck; m_flags |= pActor ? pActor->IsPlayer() ? eSF_StuckToPlayer : eSF_StuckToAI : 0; m_childId = pProjectile->GetEntityId(); } } } if((m_flags&eSF_IsStuck)==0) { IEntity* pProjectileEntity = pProjectile->GetEntity(); AttachTo(pProjectile, pTargetEntity); m_childId = pProjectileEntity->GetId(); if(pTargetEntity) //If we have a parent then the stuck position/rotation are local to the parent { pProjectileEntity->SetPos(m_stuckPos); pProjectileEntity->SetRotation(m_stuckRot); } else if(m_flags&eSF_OrientateToCollNormal) { Matrix34 mat; mat.SetTranslation(m_stuckPos); mat.SetRotation33(Matrix33(m_stuckRot)); pProjectileEntity->SetWorldTM(mat); } else { pProjectileEntity->SetPos(m_stuckPos); } m_flags |= eSF_IsStuck; } } }
void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo ) { if (event == eFE_Activate && IsPortActive(pActInfo, EIP_Trigger)) { IActor* pActor = GetInputActor( pActInfo ); if (!pActor) return; IInventory *pInventory = pActor->GetInventory(); if (!pInventory) return; const bool& addPack = GetPortBool(pActInfo, EIP_AddToggle); const string& packName = GetPortString(pActInfo, EIP_EquipmentPack); const bool& selectPrimary = GetPortBool(pActInfo, EIP_SelectPrimary); if (pActor->IsPlayer()) pInventory->RMIReqToServer_AddEquipmentPack( packName.c_str(), addPack, selectPrimary ); else { if (gEnv->bServer) CCryAction::GetCryAction()->GetIItemSystem()->GetIEquipmentManager()->GiveEquipmentPack( pActor, packName.c_str(), addPack, selectPrimary ); } // TODO: instant output activation, with delayed effective change in the inventory, it potentially could cause problems in rare situations ActivateOutput(pActInfo, EOP_Done, true); } else if (event == eFE_PrecacheResources) { const string& packName = GetPortString(pActInfo, 1); if (!packName.empty()) { IGameRules* pGameRules = CCryAction::GetCryAction()->GetIGameRulesSystem()->GetCurrentGameRules(); CRY_ASSERT_MESSAGE(pGameRules != NULL, "No game rules active, can not precache resources"); if (pGameRules) { pGameRules->PrecacheLevelResource(packName.c_str(), eGameResourceType_Loadout); } } } }
//------------------------------------------------------------------------ void CGameRulesHoldObjectiveBase::OnEntityEvent( IEntity *pEntity,SEntityEvent &event ) { EntityId insideId = (EntityId) event.nParam[0]; int teamId = g_pGame->GetGameRules()->GetTeam(insideId); IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(insideId); if (pActor != NULL && pActor->IsPlayer() && teamId) { SHoldEntityDetails *pDetails = NULL; for (int i = 0; i < HOLD_OBJECTIVE_MAX_ENTITIES; ++ i) { if (m_entities[i].m_id == pEntity->GetId()) { pDetails = &m_entities[i]; break; } } if (pDetails) { if (event.event == ENTITY_EVENT_ENTERAREA) { if (IsActorEligible(pActor)) { assert(teamId>0 && teamId<=NUM_TEAMS); stl::push_back_unique(pDetails->m_insideBoxEntities[teamId - 1], insideId); CryLog("CGameRulesHoldObjectiveBase::OnEntityEvent(), entity '%s' entered capture entity", pActor->GetEntity()->GetName()); } } else if (event.event == ENTITY_EVENT_LEAVEAREA) { assert(teamId>0 && teamId<=NUM_TEAMS); stl::find_and_erase(pDetails->m_insideBoxEntities[teamId - 1], insideId); CryLog("CGameRulesHoldObjectiveBase::OnEntityEvent(), entity '%s' left capture entity", pActor->GetEntity()->GetName()); } CheckCylinder(pDetails, g_pGame->GetIGameFramework()->GetClientActorId()); } } }
//------------------------------------------------------------------------ void CGameRulesHoldObjectiveBase::OnEntityKilled( const HitInfo &hitInfo ) { if (gEnv->bServer && !hitInfo.hitViaProxy) { if (IGameRulesScoringModule* pScoringModule=g_pGame->GetGameRules()->GetScoringModule()) { const int defKillPoints = pScoringModule->GetPlayerPointsByType(EGRST_HoldObj_DefensiveKill); const int offKillPoints = pScoringModule->GetPlayerPointsByType(EGRST_HoldObj_OffensiveKill); const bool hasDefKillScoring = (defKillPoints != 0); const bool hasOffKillScoring = (offKillPoints != 0); if (hasDefKillScoring || hasOffKillScoring) { IActor* pIShooter = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(hitInfo.shooterId); IActor* pITarget = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(hitInfo.targetId); if ((pIShooter != NULL && pIShooter->IsPlayer()) && (pITarget != NULL && pITarget->IsPlayer())) { CPlayer* pShooter = (CPlayer*) pIShooter; CPlayer* pTarget = (CPlayer*) pITarget; const int shooterTeam = g_pGame->GetGameRules()->GetTeam(hitInfo.shooterId); const int targetTeam = g_pGame->GetGameRules()->GetTeam(hitInfo.targetId); if ((shooterTeam == 1 || shooterTeam == 2) && (targetTeam == 1 || targetTeam == 2)) { // TODO check if scoring enabled for both teams? if (!pShooter->IsFriendlyEntity(hitInfo.targetId)) { for (int i=0; i<HOLD_OBJECTIVE_MAX_ENTITIES; i++) { const SHoldEntityDetails* pDetails = &m_entities[i]; if (pDetails->m_id) { if (hasDefKillScoring && stl::find(pDetails->m_insideEntities[shooterTeam - 1], hitInfo.shooterId)) { if (pDetails->m_controllingTeamId == shooterTeam) { SGameRulesScoreInfo scoreInfo (EGRST_HoldObj_DefensiveKill, defKillPoints); scoreInfo.AttachVictim(hitInfo.targetId); pScoringModule->OnPlayerScoringEventWithInfo(hitInfo.shooterId, &scoreInfo); break; } } if ((hasOffKillScoring /*|| hasDefKillScoring*/) && stl::find(pDetails->m_insideEntities[targetTeam - 1], hitInfo.targetId)) { if (pDetails->m_controllingTeamId == targetTeam) { SGameRulesScoreInfo scoreInfo (EGRST_HoldObj_OffensiveKill, offKillPoints); scoreInfo.AttachVictim(hitInfo.targetId); pScoringModule->OnPlayerScoringEventWithInfo(hitInfo.shooterId, &scoreInfo); break; } // [tlh] TODO? Team Design are having a think about this "targetWasInsideEnemys" case - aka. "The Contested Case" /* else { SGameRulesScoreInfo scoreInfo (EGRST_HoldObj_DefensiveKill, defKillPoints); scoreInfo.AttachVictim(hitInfo.targetId); pScoringModule->OnPlayerScoringEventWithInfo(hitInfo.shooterId, &scoreInfo); break; } */ } } } } } } } } } int targetTeamId = g_pGame->GetGameRules()->GetTeam(hitInfo.targetId); if (targetTeamId == 1 || targetTeamId == 2) { for (int i = 0; i < HOLD_OBJECTIVE_MAX_ENTITIES; ++ i) { SHoldEntityDetails *pDetails = &m_entities[i]; if (pDetails->m_id && stl::find_and_erase(pDetails->m_insideBoxEntities[targetTeamId - 1], hitInfo.targetId)) { CCCPOINT(HoldObjective_PlayerWithinRangeKilled); CheckCylinder(pDetails, g_pGame->GetIGameFramework()->GetClientActorId()); } } } }
// // 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 CGameAchievements::OnEntityKilled(const HitInfo &hitInfo) { // target must be an AI IActor* pTarget = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(hitInfo.targetId); if(!pTarget || pTarget->IsPlayer()) return; // shooter might be null, if this is a collision, but will be checked otherwise IActor* pShooter = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(hitInfo.shooterId); switch(CategoriseHit(hitInfo.type)) { case eCHT_Bullet: { // ignore AI shots if(!pShooter || !pShooter->IsPlayer()) break; CProjectile* pProjectile = g_pGame->GetWeaponSystem()->GetProjectile(hitInfo.projectileId); assert(pProjectile); const CTimeValue& spawnTime = pProjectile ? pProjectile->GetSpawnTime() : 0.0f; if(spawnTime == 0.0f) break; if(hitInfo.projectileId == m_lastPlayerKillBulletId && spawnTime == m_lastPlayerKillBulletSpawnTime) { // same projectile as previously, trigger the 'two kills one bullet' objective GiveAchievement(eA_SPFeature_OneBulletTwoKills); } else { // save for later m_lastPlayerKillBulletId = hitInfo.projectileId; m_lastPlayerKillBulletSpawnTime = spawnTime; } } break; case eCHT_Grenade: { if(!pShooter || !pShooter->IsPlayer()) break; CProjectile* pGrenade = g_pGame->GetWeaponSystem()->GetProjectile(hitInfo.projectileId); const CTimeValue& spawnTime = pGrenade ? pGrenade->GetSpawnTime() : 0.0f; if(spawnTime == 0.0f) break; if(hitInfo.projectileId == m_lastPlayerKillGrenadeId && spawnTime == m_lastPlayerKillGrenadeSpawnTime) { if(++m_killsWithOneGrenade == 3) { GiveAchievement(eA_SPFeature_OneGrenadeThreeKills); } } else { // save for later m_lastPlayerKillGrenadeId = hitInfo.projectileId; m_lastPlayerKillGrenadeSpawnTime = spawnTime; m_killsWithOneGrenade = 1; } } break; case eCHT_Collision: { CTimeValue now = gEnv->pTimer->GetFrameStartTime(); if(hitInfo.weaponId != 0 && hitInfo.weaponId == m_lastPlayerThrownObject && (now-m_lastPlayerThrownTime) < THROW_TIME_THRESHOLD) { // AI was killed by an object the player threw in the last x seconds... g_pGame->GetPersistantStats()->IncrementClientStats(EIPS_ThrownObjectKill, 1); } } break; default: break; } }
bool CStickyProjectile::StickToEntity( const SStickParams& stickParams, IEntity* pTargetEntity ) { IEntity* pProjectileEntity = stickParams.m_pProjectile->GetEntity(); ICharacterInstance* pCharInstance = pTargetEntity->GetCharacter(0); if( pCharInstance) { IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTargetEntity->GetId()); if (!pActor || (stickParams.m_bStickToFriendlies || !pActor->IsFriendlyEntity(stickParams.m_ownerId)) && (gEnv->bMultiplayer || !pActor->IsDead())) { m_stuckJoint = GetJointIdFromPartId(*pTargetEntity, stickParams.m_targetPartId); m_stuckNormal = stickParams.m_stickNormal; m_stuckPartId = stickParams.m_targetPartId; ICharacterModelSkeleton* pICharacterModelSkeleton = pCharInstance->GetICharacterModel()->GetICharacterModelSkeleton(); ISkeletonPose* pSkeleton = pCharInstance->GetISkeletonPose(); const char* boneName = pICharacterModelSkeleton->GetJointNameByID(m_stuckJoint); const QuatT jointWorld = QuatT(pTargetEntity->GetWorldTM()) * pSkeleton->GetAbsJointByID(m_stuckJoint); QuatT loc; CalculateLocationForStick( *pProjectileEntity, stickParams.m_stickPosition, stickParams.m_stickNormal, loc ); pProjectileEntity->SetWorldTM(Matrix34(loc)); // Get the local pos and rot. loc = jointWorld.GetInverted() * loc; m_stuckPos = loc.t; m_stuckRot = loc.q; // Attach. if(AttachToCharacter( stickParams.m_pProjectile, *pTargetEntity, *pCharInstance, boneName)) { m_flags |= eSF_IsStuck; m_flags |= pActor ? pActor->IsPlayer() ? eSF_StuckToPlayer : eSF_StuckToAI : 0; SetParentId(pTargetEntity->GetId()); m_childId = pProjectileEntity->GetId(); return true; } } } else { m_stuckNormal = stickParams.m_stickNormal; m_stuckPartId = stickParams.m_targetPartId; QuatT loc; CalculateLocationForStick( *pProjectileEntity, stickParams.m_stickPosition, stickParams.m_stickNormal, loc ); AttachTo(stickParams.m_pProjectile, pTargetEntity); pProjectileEntity->SetWorldTM(Matrix34(loc)); // Set as Stuck. SetParentId(pTargetEntity->GetId()); m_childId = pProjectileEntity->GetId(); m_flags |= eSF_IsStuck; //Store position and rotation relative to parent entity m_stuckPos = pProjectileEntity->GetPos(); m_stuckRot = pProjectileEntity->GetRotation(); return true; } return false; }
void CFlowNode_AISequenceAction_ApproachAndEnterVehicle::HandleSequenceEvent(AIActionSequence::SequenceEvent sequenceEvent) { switch(sequenceEvent) { case AIActionSequence::StartAction: { if (!m_actInfo.pEntity) { // the entity has gone for some reason, at least make sure the action gets finished properly and the FG continues UnregisterFromVehicleEvent(NULL); CancelSequenceAndActivateOutputPort(OutputPort_Done); return; } m_entityId = m_actInfo.pEntity->GetId(); m_vehicleId = GetPortEntityId(&m_actInfo, InputPort_VehicleId); m_seatNumber = GetPortInt(&m_actInfo, InputPort_SeatNumber); m_fast = GetPortBool(&m_actInfo, InputPort_Fast); const bool alsoCheckForCrewHostility = true; IVehicle* pVehicle = GetVehicle(alsoCheckForCrewHostility); if (!pVehicle) { CryLog("Actor %s failed to enter vehicle (specified vehicle not found or its crew is hostile towards the actor returned true)", m_actInfo.pEntity->GetName()); CancelSequenceAndActivateOutputPort(OutputPort_Done); return; } IVehicleSeat* pSeat = GetVehicleSeat(pVehicle); if (!pSeat) { CryLog("Actor %s failed to enter vehicle (bad seat number provided: %i)", m_actInfo.pEntity->GetName(), m_seatNumber); CancelSequenceAndActivateOutputPort(OutputPort_Done); return; } const IVehicleHelper* pEnterHelper = static_cast<CVehicleSeat*>(pSeat)->GetEnterHelper(); if (!pEnterHelper) { CryLog("Actor %s failed to enter vehicle (vehicle has no enter-helper)", m_actInfo.pEntity->GetName()); CancelSequenceAndActivateOutputPort(OutputPort_Done); return; } m_vehicleSeatEnterPosition = pEnterHelper->GetWorldSpaceTranslation(); assert(gEnv && gEnv->pGame && gEnv->pGame->GetIGameFramework() && gEnv->pGame->GetIGameFramework()->GetIActorSystem()); IActor* pActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_actInfo.pEntity->GetId()); // if it's the player, have him enter quickly (we assume that the user moved him close enough to the vehicle) if (pActor && pActor->IsPlayer()) { EnterVehicleSeat(true, pSeat); } else if (m_actInfo.pEntity->GetAI()) { if (m_fast) { TeleportToVehicleSeat(); EnterVehicleSeat(false, pSeat); } else { MovementRequest request; request.callback = functor(*this, &CFlowNode_AISequenceAction_ApproachAndEnterVehicle::MovementRequestCallback); request.entityID = m_actInfo.pEntity->GetId(); request.type = MovementRequest::MoveTo; request.destination = m_vehicleSeatEnterPosition; request.style.SetSpeed((MovementStyle::Speed)GetPortInt(&m_actInfo, InputPort_Speed)); request.style.SetStance((MovementStyle::Stance)GetPortInt(&m_actInfo, InputPort_Stance)); m_movementRequestID = gEnv->pAISystem->GetMovementSystem()->QueueRequest(request); } } else if (pActor) { pActor->HolsterItem(true); pActor->MountedGunControllerEnabled(false); pActor->GetGameObject()->SetAspectProfile(eEA_Physics, eAP_Alive); TeleportToVehicleSeat(); EnterVehicleSeat(GetAnimationTransitionEnabled(), pSeat); } else { CRY_ASSERT_MESSAGE(0, "no compatible entity was provided"); CryWarning(VALIDATOR_MODULE_AI, VALIDATOR_WARNING, "Actor %s failed to enter vehicle (no compatible entity was provided)", m_actInfo.pEntity->GetName()); CancelSequenceAndActivateOutputPort(OutputPort_Done); } } break; case AIActionSequence::SequenceStopped: { if (m_movementRequestID) { gEnv->pAISystem->GetMovementSystem()->CancelRequest(m_movementRequestID); m_movementRequestID = MovementRequestID::Invalid(); UnregisterFromVehicleEvent(NULL); } } break; } }
//------------------------------------------------------------------------- void CLam::ActivateLaser(bool activate, bool aiRequest /* = false */) { if (m_laserActivated == activate) return; CItem *pParent = NULL; EntityId ownerId = 0; bool ok = false; if (IItem *pOwnerItem = m_pItemSystem->GetItem(GetParentId())) { pParent = (CItem *)pOwnerItem; IWeapon *pWeapon = pOwnerItem->GetIWeapon(); if(pWeapon) ownerId = pOwnerItem->GetOwnerId(); ok = true; } else { pParent = this; ownerId = GetOwnerId(); } IActor *pOwnerActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(ownerId); if(!pOwnerActor) return; if(activate && !aiRequest && !pOwnerActor->IsPlayer()) return; //Special FP stuff if(pOwnerActor->IsPlayer() && !m_lamparams.isLaser) return; m_laserActivated = activate; //Activate or deactivate effect?? if (!m_laserActivated) { AttachLAMLaser(false, eIGS_FirstPerson); AttachLAMLaser(false, eIGS_ThirdPerson); } else { bool tp = pOwnerActor->IsThirdPerson(); if(!tp && ok) { SAccessoryParams *params = pParent->GetAccessoryParams(GetEntity()->GetClass()->GetName()); if (!params) return; m_laserHelperFP.clear(); m_laserHelperFP = params->attach_helper.c_str(); m_laserHelperFP.replace("_LAM",""); } AttachLAMLaser(true, tp?eIGS_ThirdPerson:eIGS_FirstPerson); } if (m_laserActivated || m_lightActivated) GetGameObject()->EnablePostUpdates(this); if (!m_laserActivated && !m_lightActivated) GetGameObject()->DisablePostUpdates(this); }
//-------------------------------------------------------------------------------------------------- // Name: SpawnScreenExplosionEffect // Desc: Spawns screen explosion effect //-------------------------------------------------------------------------------------------------- void CExplosionGameEffect::SpawnScreenExplosionEffect(const SExplosionContainer &explosionContainer) { // Disclaimer: this code was originally from GameRulesClientServer::ProcessClientExplosionScreenFX() const ExplosionInfo& explosionInfo = explosionContainer.m_explosionInfo; if(explosionInfo.pressure < 1.0f) return; IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); if(pClientActor != NULL && !pClientActor->IsDead()) { CPlayer* pPlayer = static_cast<CPlayer*>(pClientActor); bool hasFlashBangEffect = explosionInfo.blindAmount > 0.0f; // Flashbang friends and self?... if(hasFlashBangEffect) { bool flashBangSelf = true; bool flashBangFriends = false; #ifndef _RELEASE flashBangSelf = g_pGameCVars->g_flashBangSelf != 0; flashBangFriends = g_pGameCVars->g_flashBangFriends != 0; #endif bool ownFlashBang = pPlayer->GetEntityId() == explosionInfo.shooterId; if((!flashBangSelf && ownFlashBang) || // FlashBang self? ((g_pGame->GetGameRules()->GetFriendlyFireRatio()<=0.0f) && (!flashBangFriends) && (!ownFlashBang) && pPlayer->IsFriendlyEntity(explosionInfo.shooterId))) // FlashBang friends? { return; } } // Distance float dist = (pClientActor->GetEntity()->GetWorldPos() - explosionInfo.pos).len(); // Is the explosion in Player's FOV (let's suppose the FOV a bit higher, like 80) SMovementState state; if(IMovementController *pMV = pClientActor->GetMovementController()) { pMV->GetMovementState(state); } Vec3 eyeToExplosion = explosionInfo.pos - state.eyePosition; Vec3 eyeDir = pClientActor->GetLinkedVehicle() ? pPlayer->GetVehicleViewDir() : state.eyeDirection; eyeToExplosion.Normalize(); float eyeDirectionDP = eyeDir.Dot(eyeToExplosion); bool inFOV = (eyeDirectionDP > 0.68f); // All explosions have radial blur (default 30m radius) const float maxBlurDistance = (explosionInfo.maxblurdistance >0.0f) ? explosionInfo.maxblurdistance : 30.0f; if((maxBlurDistance > 0.0f) && (g_pGameCVars->g_radialBlur > 0.0f) && (explosionInfo.radius > 0.5f)) { if (inFOV && (dist < maxBlurDistance)) { const int intersectionObjTypes = ent_static | ent_terrain; const unsigned int intersectionFlags = rwi_stop_at_pierceable|rwi_colltype_any; m_deferredScreenEffects.RequestRayCast(CDeferredExplosionEffect::eDET_RadialBlur, explosionInfo.pos, -eyeToExplosion, dist, maxBlurDistance, intersectionObjTypes, intersectionFlags, NULL, 0); } } // Flashbang effect if(hasFlashBangEffect && ((dist < (explosionInfo.radius*g_pGameCVars->g_flashBangNotInFOVRadiusFraction)) || (inFOV && (dist < explosionInfo.radius)))) { ray_hit hit; const int intersectionObjTypes = ent_static | ent_terrain; const unsigned int intersectionFlags = rwi_stop_at_pierceable|rwi_colltype_any; const int intersectionMaxHits = 1; int collision = gEnv->pPhysicalWorld->RayWorldIntersection( explosionInfo.pos, -eyeToExplosion*dist, intersectionObjTypes, intersectionFlags, &hit, intersectionMaxHits); // If there was no obstacle between flashbang grenade and player if(!collision) { bool enabled = true; if(enabled) { CCCPOINT (FlashBang_Explode_BlindLocalPlayer); float timeScale = max(0.0f, 1 - (dist/explosionInfo.radius)); float lookingAt = max(g_pGameCVars->g_flashBangMinFOVMultiplier, (eyeDirectionDP + 1)*0.5f); float time = explosionInfo.flashbangScale * timeScale *lookingAt; // time is determined by distance to explosion CRY_ASSERT_MESSAGE(pClientActor->IsPlayer(),"Effect shouldn't be spawned if not a player"); SPlayerStats* pStats = static_cast<SPlayerStats*>(pPlayer->GetActorStats()); NET_BATTLECHATTER(BC_Blinded, pPlayer); if(pClientActor->GetEntityId() == explosionInfo.shooterId) { g_pGame->GetPersistantStats()->IncrementClientStats(EIPS_BlindSelf); } else { g_pGame->GetGameRules()->SuccessfulFlashBang(explosionInfo, time); } pPlayer->StartFlashbangEffects(time, explosionInfo.shooterId); gEnv->p3DEngine->SetPostEffectParam("Flashbang_Time", time); gEnv->p3DEngine->SetPostEffectParam("FlashBang_BlindAmount", explosionInfo.blindAmount); gEnv->p3DEngine->SetPostEffectParam("Flashbang_DifractionAmount", time); gEnv->p3DEngine->SetPostEffectParam("Flashbang_Active", 1.0f); CRecordingSystem *pRecordingSystem = g_pGame->GetRecordingSystem(); if (pRecordingSystem) { pRecordingSystem->OnPlayerFlashed(time, explosionInfo.blindAmount); } } } else { CCCPOINT (FlashBang_Explode_NearbyButBlockedByGeometry); } } else if(inFOV && (dist < explosionInfo.radius)) { if(explosionInfo.damage>10.0f || explosionInfo.pressure>100.0f) { // Add some angular impulse to the client actor depending on distance, direction... float dt = (1.0f - dist/explosionInfo.radius); dt = dt * dt; float angleZ = gf_PI*0.15f*dt; float angleX = gf_PI*0.15f*dt; if (pClientActor) { static_cast<CActor*>(pClientActor)->AddAngularImpulse(Ang3(cry_random(-angleX*0.5f,angleX),0.0f,cry_random(-angleZ,angleZ)),0.0f,dt*2.0f); } } } } }//-------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------ void CBullet::HandleEvent(const SGameObjectEvent &event) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); CProjectile::HandleEvent(event); if (event.event == eGFE_OnCollision) { if (m_destroying) return; EventPhysCollision *pCollision = reinterpret_cast<EventPhysCollision *>(event.ptr); if (!pCollision) return; IEntity *pTarget = pCollision->iForeignData[1]==PHYS_FOREIGN_ID_ENTITY ? (IEntity*)pCollision->pForeignData[1]:0; //Only process hits that have a target if(pTarget) { Vec3 dir(0, 0, 0); if (pCollision->vloc[0].GetLengthSquared() > 1e-6f) dir = pCollision->vloc[0].GetNormalized(); CGameRules *pGameRules = g_pGame->GetGameRules(); IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_ownerId); bool ok = true; if(!gEnv->bMultiplayer && pActor && pActor->IsPlayer()) { IActor* pAITarget = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTarget->GetId()); if(pAITarget && pTarget->GetAI() && pTarget->GetAI()->IsFriendly(pActor->GetEntity()->GetAI(), false)) { pGameRules->SetEntityToIgnore(pTarget->GetId()); ok = false; } } if(ok) { HitInfo hitInfo(m_ownerId, pTarget->GetId(), m_weaponId, (float)m_damage, 0.0f, pGameRules->GetHitMaterialIdFromSurfaceId(pCollision->idmat[1]), pCollision->partid[1], m_hitTypeId, pCollision->pt, dir, pCollision->n); hitInfo.remote = IsRemote(); hitInfo.projectileId = GetEntityId(); hitInfo.bulletType = m_pAmmoParams->bulletType; pGameRules->ClientHit(hitInfo); // Notify AI if (gEnv->pAISystem && !gEnv->bMultiplayer) { static int htMelee = pGameRules->GetHitTypeId("melee"); if (m_ownerId && m_hitTypeId != htMelee) { ISurfaceType *pSurfaceType = pGameRules->GetHitMaterial(hitInfo.material); const ISurfaceType::SSurfaceTypeAIParams* pParams = pSurfaceType ? pSurfaceType->GetAIParams() : 0; const float radius = pParams ? pParams->fImpactRadius : 2.5f; const float soundRadius = pParams ? pParams->fImpactSoundRadius : 20.0f; // Associate event with vehicle if the shooter is in a vehicle (tank cannon shot, etc) EntityId ownerId = m_ownerId; if (pActor && pActor->GetLinkedVehicle() && pActor->GetLinkedVehicle()->GetEntityId()) ownerId = pActor->GetLinkedVehicle()->GetEntityId(); SAIStimulus stim(AISTIM_BULLET_HIT, 0, ownerId, 0, pCollision->pt, ZERO, radius); gEnv->pAISystem->RegisterStimulus(stim); SAIStimulus stimSound(AISTIM_SOUND, AISOUND_COLLISION_LOUD, ownerId, 0, pCollision->pt, ZERO, soundRadius, AISTIMPROC_FILTER_LINK_WITH_PREVIOUS); gEnv->pAISystem->RegisterStimulus(stimSound); } } } } else { // Notify AI // The above case only catches entity vs. entity hits, the AI is interested in all hits. if (gEnv->pAISystem && !gEnv->bMultiplayer) { CGameRules *pGameRules = g_pGame->GetGameRules(); static int htMelee = pGameRules->GetHitTypeId("melee"); if (m_ownerId && m_hitTypeId != htMelee) { int material = pGameRules->GetHitMaterialIdFromSurfaceId(pCollision->idmat[1]); ISurfaceType *pSurfaceType = pGameRules->GetHitMaterial(material); const ISurfaceType::SSurfaceTypeAIParams* pParams = pSurfaceType ? pSurfaceType->GetAIParams() : 0; const float radius = pParams ? pParams->fImpactRadius : 2.5f; const float soundRadius = pParams ? pParams->fImpactSoundRadius : 20.0f; // Associate event with vehicle if the shooter is in a vehicle (tank cannon shot, etc) EntityId ownerId = m_ownerId; IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_ownerId); if (pActor && pActor->GetLinkedVehicle() && pActor->GetLinkedVehicle()->GetEntityId()) ownerId = pActor->GetLinkedVehicle()->GetEntityId(); SAIStimulus stim(AISTIM_BULLET_HIT, 0, ownerId, 0, pCollision->pt, ZERO, radius); gEnv->pAISystem->RegisterStimulus(stim); SAIStimulus stimSound(AISTIM_SOUND, AISOUND_COLLISION_LOUD, ownerId, 0, pCollision->pt, ZERO, soundRadius, AISTIMPROC_FILTER_LINK_WITH_PREVIOUS); gEnv->pAISystem->RegisterStimulus(stimSound); } } } if (pCollision->pEntity[0]->GetType() == PE_PARTICLE) { float bouncy, friction; uint32 pierceabilityMat; gEnv->pPhysicalWorld->GetSurfaceParameters(pCollision->idmat[1], bouncy, friction, pierceabilityMat); pierceabilityMat&=sf_pierceable_mask; pe_params_particle params; if(pCollision->pEntity[0]->GetParams(¶ms)==0) SetDefaultParticleParams(¶ms); //Under water trail Vec3 pos=pCollision->pt; if ((pCollision->idmat[1] == CBullet::m_waterMaterialId) && (pCollision->pEntity[1]!=gEnv->pPhysicalWorld->AddGlobalArea() || !gEnv->p3DEngine->GetVisAreaFromPos(pos))) { //Reduce drastically bullet velocity (to be able to see the trail effect) //pe_params_particle pparams; //if(m_pPhysicalEntity->GetParams(&pparams)==0) //SetDefaultParticleParams(&pparams); //pparams.velocity = 25.0f; //m_pPhysicalEntity->SetParams(&pparams); if(m_trailUnderWaterId<0) { //Check terrain/against water level float terrainHeight = gEnv->p3DEngine->GetTerrainElevation(pCollision->pt.x,pCollision->pt.y); float waterLevel = gEnv->p3DEngine->GetWaterLevel(&(pCollision->pt)); if(waterLevel>terrainHeight) { TrailEffect(true,true); return; } } } if (pierceabilityMat<=params.iPierceability || pCollision->idCollider==-1) //Do not destroy if collides water Destroy(); } } }