//------------------------------------------------------------------------ void CDetonate::StartFire() { if (CanFire(false)) { CActor *pOwner=m_pWeapon->GetOwnerActor(); CCCPOINT(DetonateFireMode_StartFireOK); m_pWeapon->RequireUpdate(eIUS_FireMode); m_detonationTimer = 0.1f; m_pWeapon->PlayAction(GetFragmentIds().fire); m_pWeapon->RequestDetonate(); } else { #if !defined(_RELEASE) IFireMode* pFM = m_pWeapon->GetFireMode(m_pWeapon->GetCurrentFireMode()); EntityId projectileId = pFM ? pFM->GetProjectileId() : 0; IEntity * projectile = gEnv->pEntitySystem->GetEntity(projectileId); CryLog ("[Detonate] Failure to detonate %s '%s' (timer = %.4f, can detonate = %s, fire mode = '%s') projectile = %u (%s '%s')", m_pWeapon->GetEntity()->GetClass()->GetName(), m_pWeapon->GetEntity()->GetName(), m_detonationTimer, m_canDetonate ? "TRUE" : "FALSE", pFM ? pFM->GetName() : "NONE", projectileId, projectile ? projectile->GetClass()->GetName() : "NONE", projectile ? projectile->GetName() : "N/A"); #endif CCCPOINT_IF(m_detonationTimer > 0.0f, DetonateFireMode_CannotFire_TimerNotReachedZero); CCCPOINT(DetonateFireMode_CannotFire); } }
//------------------------------------------------------------------------ void CGameRulesKingOfTheHillObjective::UpdateIcon(SHoldEntityDetails * pDetails) { SKotHEntity *pKotHEntity = static_cast<SKotHEntity *>(pDetails->m_pAdditionalData); CRY_ASSERT(pKotHEntity); const char *pName = NULL; const char *pColour = NULL; EGameRulesMissionObjectives requestedIcon = GetIcon(pDetails, &pName, &pColour); if (requestedIcon != EGRMO_Unknown) { CCCPOINT(KingOfTheHillObjective_SetNewIcon); SHUDEventWrapper::OnNewObjective(pDetails->m_id, requestedIcon, 0.f, 0, pName, pColour); pKotHEntity->m_needsIconUpdate = false; if(!pKotHEntity->m_isOnRadar) { SHUDEvent hudevent(eHUDEvent_AddEntity); hudevent.AddData(SHUDEventData((int)pDetails->m_id)); CHUDEventDispatcher::CallEvent(hudevent); pKotHEntity->m_isOnRadar = true; } } else if (pKotHEntity->m_currentIcon != EGRMO_Unknown) { CCCPOINT(KingOfTheHillObjective_RemoveIcon); SHUDEventWrapper::OnRemoveObjective(pDetails->m_id, 0); } pKotHEntity->m_currentIcon = requestedIcon; }
//------------------------------------------------------------------------ void CGameRulesHoldObjectiveBase::DetermineControllingTeamId(SHoldEntityDetails *pDetails, const int team1Count, const int team2Count) { if (team1Count && !team2Count) { pDetails->m_controllingTeamId = 1; CryLog("CGameRulesHoldObjectiveBase::InsideStateChanged: entity controlled by team 1"); CCCPOINT(HoldObjective_TeamMarinesNowInProximity); } else if (!team1Count && team2Count) { pDetails->m_controllingTeamId = 2; CryLog("CGameRulesHoldObjectiveBase::InsideStateChanged: entity controlled by team 2"); CCCPOINT(HoldObjective_TeamCellNowInProximity); } else if (!team1Count && !team2Count) { pDetails->m_controllingTeamId = 0; CryLog("CGameRulesHoldObjectiveBase::InsideStateChanged: entity controlled by neither team"); CCCPOINT(HoldObjective_NeitherTeamNowInProximity); } else { pDetails->m_controllingTeamId = CONTESTED_TEAM_ID; CryLog("CGameRulesHoldObjectiveBase::InsideStateChanged: entity is contested"); CCCPOINT(HoldObjective_BothTeamsNowInProximity); } }
//--------------------------------------------------------------------- bool CWeapon::OnActionSpecial(EntityId actorId, const ActionId& actionId, int activationMode, float value) { CPlayer* pOwnerPlayer = GetOwnerPlayer(); if (pOwnerPlayer && !pOwnerPlayer->CanMelee()) return true; if(gEnv->bMultiplayer && AreAnyItemFlagsSet(eIF_Transitioning)) //Ignore the transition from attachments menu and melee immediately { ClearItemFlags( eIF_Transitioning ); } if (gEnv->bMultiplayer && !g_pGameCVars->pl_boostedMelee_allowInMP) { if (activationMode == eAAM_OnPress) { if (CanMeleeAttack()) { if (PreMeleeAttack()) MeleeAttack(); } else { CCCPOINT(Melee_PressedButMeleeNotAllowed); } } } else { if (activationMode == eAAM_OnPress) { if(CanMeleeAttack()) { if (pOwnerPlayer) { if (PreMeleeAttack()) { BoostMelee(false); MeleeAttack(); } } } else { CCCPOINT(Melee_PressedButMeleeNotAllowed); } } } return true; }
//--------------------------------- void CScreenEffects::CamShake(Vec3 rotateShake, Vec3 shiftShake, float freq, float shakeTime, float randomness, int shakeID) { if (g_pGameCVars && g_pGameCVars->g_detachCamera==0) { IViewSystem *pViewSystem = g_pGame->GetIGameFramework()->GetIViewSystem(); if (pViewSystem) { IView *pView = pViewSystem->GetActiveView(); if (pView) { const bool bClientActorView = pViewSystem->IsClientActorViewActive();; if (gEnv->pFlashUI) { gEnv->pFlashUI->SetHudElementsVisible(bClientActorView); } if (bClientActorView && shakeID == eCS_GID_Player) { CCCPOINT(Camera_DoShake); pView->SetViewShake(Ang3(rotateShake), shiftShake, shakeTime, freq, randomness, shakeID, false); } } } } }
//------------------------------------------------------------------------ int CScriptbind_GameAudio::StopEntitySignal(IFunctionHandler *pH, TAudioSignalID signalId, ScriptHandle handleEntityId ) { CCCPOINT(Audio_ScriptStopEntitySignal); EntityId entityId = (EntityId)handleEntityId.n; StopSignal_Internal( signalId, entityId ); return pH->EndFunction(); }
void execute(CItem *_this) { CShotgun *fm = (CShotgun *)pWep->GetFireMode(pWep->GetCurrentFireMode()); if(fm->m_reload_was_broken) return; IEntityClass* pAmmoType = fm->GetAmmoType(); if (pWep->IsServer()) { const int ammoCount = pWep->GetAmmoCount(pAmmoType); const int inventoryCount = pWep->GetInventoryAmmoCount(pAmmoType); const int refill = fm->m_fireParams->shotgunparams.partial_reload ? 1 : min(inventoryCount, fm->GetClipSize() - ammoCount); pWep->SetAmmoCount(pAmmoType, ammoCount + refill); pWep->SetInventoryAmmoCount(pAmmoType, pWep->GetInventoryAmmoCount(pAmmoType) - refill); } CCCPOINT(Shotgun_ReloadShell); g_pGame->GetIGameFramework()->GetIGameplayRecorder()->Event(pWep->GetOwner(), GameplayEvent(eGE_WeaponReload, pAmmoType->GetName(), 1, (void *)(EXPAND_PTR)(pWep->GetEntityId()))); if (!fm->m_break_reload) fm->ReloadShell(rzoomed); else fm->EndReload(rzoomed); }
//------------------------------------------------------------------------ bool CGameRules::OnFinalise(SHostMigrationInfo& hostMigrationInfo, uint32& state) { if (!g_pGame->GetIGameFramework()->ShouldMigrateNub(hostMigrationInfo.m_session)) { return true; } CryLogAlways("[Host Migration]: CGameRules::OnFinalise() started"); //if (m_hostMigrationClientHasRejoined) { CCCPOINT(HostMigration_OnFinalise); if (!hostMigrationInfo.IsNewHost()) { FlushPhysicsQueues(); int numEntities = m_hostMigrationCachedEntities.size(); CryLog(" removing %i entities", numEntities); for (int i = 0; i < numEntities; ++ i) { EntityId entId = m_hostMigrationCachedEntities[i]; gEnv->pEntitySystem->RemoveEntity(entId, true); TEntityTeamIdMap::iterator entityTeamsIt = m_entityteams.begin(); for (; entityTeamsIt != m_entityteams.end(); ++ entityTeamsIt) { EntityId entityId = entityTeamsIt->first; if (entityId == entId) { int teamId = entityTeamsIt->second; if (teamId) { // Remove this entity from the team lists TPlayers &playersVec = m_playerteams[teamId]; stl::find_and_erase(playersVec, entId); m_entityteams.erase(entityTeamsIt); } break; } } } } m_hostMigrationCachedEntities.clear(); HostMigrationResumeAddingPlayers(); g_pGame->PlayerIdSet(g_pGame->GetIGameFramework()->GetClientActorId()); CryLogAlways("[Host Migration]: CGameRules::OnFinalise() finished - success"); return true; } CryLogAlways("[Host Migration]: CGameRules::OnFinalise() finished - failure"); return false; }
//------------------------------------------------------------------------ bool CDetonate::Detonate(bool net) { bool detonatedAll = true; if (m_pWeapon->IsServer()) { CActor *pOwner=m_pWeapon->GetOwnerActor(); if (!pOwner) return false; if (IFireMode* pFM = m_pWeapon->GetFireMode(m_pWeapon->GetCurrentFireMode())) { std::vector<EntityId> undetonatedList; undetonatedList.clear(); while(EntityId projectileId = pFM->RemoveProjectileId()) { if (CProjectile *pProjectile = g_pGame->GetWeaponSystem()->GetProjectile(projectileId)) { if(pProjectile->Detonate()) { CCCPOINT(DetonateFireMode_ProjectileHasBeenDetonated); g_pGame->GetIGameFramework()->GetIGameplayRecorder()->Event(m_pWeapon->GetOwner(), GameplayEvent(eGE_WeaponShot, pProjectile->GetEntity()->GetClass()->GetName(), 1, (void *)(EXPAND_PTR)m_pWeapon->GetEntityId())); } else { CCCPOINT(DetonateFireMode_ProjectileFailedToDetonate); stl::push_back_unique(undetonatedList, projectileId); } } } while(!undetonatedList.empty()) { pFM->SetProjectileId(undetonatedList.back()); undetonatedList.pop_back(); detonatedAll = false; } } } return detonatedAll; }
//------------------------------------------------------------------------ void CGameRulesHoldObjectiveBase::CleanUpEntity(SHoldEntityDetails *pDetails) { CCCPOINT(HoldObjective_CleanUpActiveCaptureEntity); if (pDetails->m_localPlayerIsWithinRange) { CHUDEventDispatcher::CallEvent(SHUDEvent(eHUDEvent_OnSiteAboutToExplode)); } OnRemoveHoldEntity(pDetails); gEnv->pEntitySystem->RemoveEntityEventListener(pDetails->m_id, ENTITY_EVENT_ENTERAREA, this); gEnv->pEntitySystem->RemoveEntityEventListener(pDetails->m_id, ENTITY_EVENT_LEAVEAREA, this); if (m_spawnPOIType == eSPT_Avoid) { IGameRulesSpawningModule *pSpawningModule = g_pGame->GetGameRules()->GetSpawningModule(); if (pSpawningModule) { pSpawningModule->RemovePOI(pDetails->m_id); } } IEntity *pEntity = gEnv->pEntitySystem->GetEntity(pDetails->m_id); if (pEntity) { IScriptTable *pScript = pEntity->GetScriptTable(); if (pScript != NULL && pScript->GetValueType("DeactivateCapturePoint") == svtFunction) { IScriptSystem *pScriptSystem = gEnv->pScriptSystem; pScriptSystem->BeginCall(pScript, "DeactivateCapturePoint"); pScriptSystem->PushFuncParam(pScript); pScriptSystem->PushFuncParam(true); pScriptSystem->EndCall(); } CGameRules *pGameRules = g_pGame->GetGameRules(); EGameMode gamemode = pGameRules->GetGameMode(); if (gamemode == eGM_CrashSite) { Announce("Destruct", k_announceType_CS_Destruct); } } pDetails->Reset(); // Fade out effect m_effectData.alphaLerp.Set(1.0f,0.0f,0.0f); }
//------------------------------------------------------------------------ bool CGameRules::OnReconnectClient(SHostMigrationInfo& hostMigrationInfo, uint32& state) { if (!g_pGame->GetIGameFramework()->ShouldMigrateNub(hostMigrationInfo.m_session)) { return true; } CryLogAlways("[Host Migration]: CGameRules::OnReconnectClient() started"); if (hostMigrationInfo.IsNewHost()) { // Can't use gamerules cached version of server time since this function will be called before the Update() m_gameStartedTime.SetValue(m_gameStartedTime.GetValue() + g_pGame->GetIGameFramework()->GetServerTime().GetValue()); m_gameStartTime.SetValue(m_gameStartTime.GetValue() + g_pGame->GetIGameFramework()->GetServerTime().GetValue()); } CryLogAlways("[Host Migration]: CGameRules::OnReconnectClient() finished"); CCCPOINT(HostMigration_OnReconnectClient); return true; }
//------------------------------------------------------------------------ void CDetonate::Update(float frameTime, uint32 frameId) { BaseClass::Update(frameTime, frameId); if (m_detonationTimer>0.0f) { m_detonationTimer-=frameTime; if (m_detonationTimer<=0.0f) { m_detonationTimer=0.0f; CCCPOINT(DetonateFireMode_TimerHasReachedZero); bool detonated = Detonate(); if (detonated && m_pWeapon->GetOwnerActor() && m_pWeapon->GetOwnerActor()->IsClient()) m_pWeapon->GetScheduler()->TimerAction(uint32(m_pWeapon->GetCurrentAnimationTime(eIGS_Owner)), CSchedulerAction<ExplodeAction>::Create(this), false); } else m_pWeapon->RequireUpdate(eIUS_FireMode); } }
//------------------------------------------------------------------------ bool CGameRules::OnDemoteToClient(SHostMigrationInfo &hostMigrationInfo, uint32 &state) { if (!g_pGame->GetIGameFramework()->ShouldMigrateNub(hostMigrationInfo.m_session)) { return true; } CryLogAlways("[Host Migration]: CGameRules::OnDemoteToClient() started"); if (m_hostMigrationCachedEntities.empty()) { HostMigrationFindDynamicEntities(m_hostMigrationCachedEntities); } else { HostMigrationRemoveDuplicateDynamicEntities(); } CryLogAlways("[Host Migration]: CGameRules::OnDemoteToClient() finished"); CCCPOINT(HostMigration_OnDemoteToClient); return true; }
//------------------------------------------------------------------------ void CGameRulesKingOfTheHillObjective::ClSiteChangedOwner( SHoldEntityDetails *pDetails, int oldTeamId ) { // Site has been captured CGameRules *pGameRules = g_pGame->GetGameRules(); EntityId clientActorId = g_pGame->GetIGameFramework()->GetClientActorId(); int localTeam = pGameRules->GetTeam(clientActorId); SKotHEntity *pKotHEntity = static_cast<SKotHEntity*>(pDetails->m_pAdditionalData); CRY_ASSERT(pKotHEntity); const int ownerTeamId = pDetails->m_controllingTeamId; if (ownerTeamId > 0) { ClSiteChangedOwnerAnnouncement(pDetails, clientActorId, ownerTeamId, localTeam); if (localTeam == ownerTeamId) { CCCPOINT(KingOfTheHillObjective_SiteCapturedByFriendlyTeam); if (!m_friendlyCaptureString.empty()) { SHUDEventWrapper::GameStateNotify(m_friendlyCaptureString.c_str()); } if (!m_gameStateFriendlyString.empty()) { const char *localisedMessage = CHUDUtils::LocalizeString(m_gameStateFriendlyString.c_str()); SHUDEventWrapper::OnGameStatusUpdate(eGBNFLP_Good, localisedMessage); } } else { CCCPOINT(KingOfTheHillObjective_SiteCapturedByEnemyTeam); if (!m_enemyCaptureString.empty()) { SHUDEventWrapper::GameStateNotify(m_enemyCaptureString.c_str()); } if (!m_gameStateEnemyString.empty()) { const char *localisedMessage = CHUDUtils::LocalizeString(m_gameStateEnemyString.c_str()); SHUDEventWrapper::OnGameStatusUpdate(eGBNFLP_Bad, localisedMessage); } } } else if (oldTeamId > 0) { if (localTeam == oldTeamId) { CCCPOINT(KingOfTheHillObjective_SiteLostByFriendlyTeam); if (!m_friendlyLostString.empty()) { SHUDEventWrapper::GameStateNotify(m_friendlyLostString.c_str()); } } else { CCCPOINT(KingOfTheHillObjective_SiteLostByEnemyTeam); if (!m_enemyLostString.empty()) { SHUDEventWrapper::GameStateNotify(m_enemyLostString.c_str()); } } if (!m_gameStateNeutralString.empty()) { const char *localisedMessage = CHUDUtils::LocalizeString(m_gameStateNeutralString.c_str()); SHUDEventWrapper::OnGameStatusUpdate(eGBNFLP_Neutral, localisedMessage); } } int currActiveIndex = -1; for (int i = 0; i < HOLD_OBJECTIVE_MAX_ENTITIES; i ++) { if( !m_entities[i].m_id) { continue; } ++currActiveIndex; if( &m_entities[i] != pDetails ) { continue; } CRY_TODO( 23,03,2010, "HUD: OnSiteCaptured events are being sent multiple times from multiple places. /FH"); SHUDEvent siteIsCaptured(eHUDEvent_OnSiteCaptured); siteIsCaptured.eventIntData = currActiveIndex; siteIsCaptured.eventIntData2 = ownerTeamId; CHUDEventDispatcher::CallEvent(siteIsCaptured); } }
//------------------------------------------------------------------------ bool CGameRules::OnPromoteToServer(SHostMigrationInfo &hostMigrationInfo, uint32 &state) { if (!g_pGame->GetIGameFramework()->ShouldMigrateNub(hostMigrationInfo.m_session)) { return true; } CryLogAlways("[Host Migration]: CGameRules::OnPromoteToServer() started"); // Server time will change after we migrate (change from old server time to new server time) m_gameStartedTime.SetValue(m_gameStartedTime.GetValue() - m_cachedServerTime.GetValue()); m_gameStartTime.SetValue(m_gameStartTime.GetValue() - m_cachedServerTime.GetValue()); // If this migration has reset (we're not the original anticipated host, remove any entities from the first attempt if (!m_hostMigrationCachedEntities.empty()) { HostMigrationRemoveDuplicateDynamicEntities(); } for (uint32 i = 0; i < MAX_PLAYERS; ++ i) { m_migratedPlayerChannels[i] = 0; } IEntityItPtr it = gEnv->pEntitySystem->GetEntityIterator(); it->MoveFirst(); for (uint32 i = 0; i < m_hostMigrationItemMaxCount; ++ i) { m_pHostMigrationItemInfo[i].Reset(); } uint32 itemIndex = 0; IEntity *pEntity = NULL; // Tell entities that we're host migrating // - Currently only used by ForbiddenArea but may well be needed for other entities later // - Currently only called on the new server, add to OnDemoteToClient if we need to use this on a client IScriptTable *pScript = pEntity->GetScriptTable(); if (pScript != NULL && pScript->GetValueType("OnHostMigration") == svtFunction) { m_pScriptSystem->BeginCall(pScript, "OnHostMigration"); m_pScriptSystem->PushFuncParam(pScript); m_pScriptSystem->PushFuncParam(true); m_pScriptSystem->EndCall(); } // This needs initialising on the new server otherwise the respawn timer will be counting down // from uninitialised data. Likewise for the pre-round timer. ResetReviveCycleTime(); // the server does not listen for entity_event_done, clients do however, when we migrate // the new server needs to remove any of these events he may be listening for TEntityTeamIdMap::iterator entityTeamsIt = m_entityteams.begin(); for (; entityTeamsIt != m_entityteams.end(); ++ entityTeamsIt) { EntityId entityId = entityTeamsIt->first; RemoveEntityEventDoneListener(entityId); #if !defined(_RELEASE) IEntity *pTeamEntity = gEnv->pEntitySystem->GetEntity(entityId); CryLog("[GameRules] OnPromoteToServer RemoveEntityEventLister(%d(%s), ENTITY_EVENT_DONE, %p)", entityId, pTeamEntity ? pTeamEntity->GetName() : "null", this); #endif } ClearRemoveEntityEventListeners(); const int numRespawnParams = m_respawndata.size(); for (int i = 0; i < numRespawnParams; ++ i) { SEntityRespawnData *pData = &m_respawndata[i]; pEntity = gEnv->pEntitySystem->GetEntity(pData->m_currentEntityId); if (pEntity == NULL) { CryLog(" detected respawn entity (id=%u) is not present, scheduling for respawn", pData->m_currentEntityId); ScheduleEntityRespawn(pData->m_currentEntityId, false, g_pGameCVars->g_defaultItemRespawnTimer); } } CryLog("[Host Migration]: CGameRules::OnPromoteToServer() finished"); CCCPOINT(HostMigration_OnPromoteToServer); return true; }
void CMelee::StartAttack() { bool canAttack = CanAttack(); MeleeDebugLog ("CMelee<%p> StartAttack canAttack=%s", this, canAttack ? "true" : "false"); if (!canAttack) return; CActor* pOwner = m_pWeapon->GetOwnerActor(); CPlayer *ownerPlayer = m_pWeapon->GetOwnerPlayer(); m_attacking = true; m_slideKick = false; m_attacked = false; m_pWeapon->RequireUpdate(eIUS_FireMode); m_pWeapon->ExitZoom(); bool isClient = pOwner ? pOwner->IsClient() : false; bool doingMultiMeleeAttack = true; if (!DoSlideMeleeAttack(pOwner)) { const float use_melee_weapon_delay = m_pMeleeParams->meleeparams.use_melee_weapon_delay; if( use_melee_weapon_delay >= 0.0f ) { if( !ownerPlayer || ownerPlayer->IsSliding() || ownerPlayer->IsExitingSlide() ) { m_attacking = false; return; } if( use_melee_weapon_delay == 0.0f ) { // instant switch: don't use the weapon's melee, send the event to the WeaponMelee weapon instead! if( SwitchToMeleeWeaponAndAttack() ) { m_useMeleeWeaponDelay = -1.0f; return; } } } if( IsMeleeWeapon() ) { doingMultiMeleeAttack = false; GenerateAndQueueMeleeAction(); } else if(!gEnv->bMultiplayer || !g_pGameCVars->pl_melee.mp_melee_system || !ownerPlayer || !StartMultiAnimMeleeAttack(ownerPlayer)) { const ItemString &meleeAction = SelectMeleeAction(); FragmentID fragmentId = m_pWeapon->GetFragmentID(meleeAction.c_str()); m_pWeapon->PlayAction(fragmentId, 0, false, CItem::eIPAF_Default); doingMultiMeleeAttack = false; } m_delayTimer = GetDelay(); m_attackTime = 0.f; if (ownerPlayer) { ownerPlayer->StateMachineHandleEventMovement( PLAYER_EVENT_FORCEEXITSLIDE ); } } else { CRY_ASSERT(pOwner && (pOwner->GetActorClass() == CPlayer::GetActorClassType())); doingMultiMeleeAttack = false; m_hitTypeID = CGameRules::EHitType::Melee; // Dispatch the event and the delay timer is magically set! ownerPlayer->StateMachineHandleEventMovement( SStateEventSlideKick(this) ); m_slideKick = true; } m_pWeapon->SetBusy(true); if(!doingMultiMeleeAttack) { // Set up a timer to disable the melee attack at the end of the first-person animation... uint32 durationInMilliseconds = static_cast<uint32>(GetDuration() * 1000.f); MeleeDebugLog ("CMelee<%p> Setting a timer to trigger StopAttackingAction (duration=%u)", this, durationInMilliseconds); // How much longer we need the animation to be than the damage delay, in seconds... const float k_requireAdditionalTime = 0.1f; if (durationInMilliseconds < (m_delayTimer + k_requireAdditionalTime) * 1000.0f) { if (!gEnv->IsDedicated()) { CRY_ASSERT_MESSAGE(false, string().Format("CMelee<%p> Warning! Melee attack timeout (%f seconds) needs to be substantially longer than the damage delay (%f seconds)! Increasing...", this, durationInMilliseconds / 1000.f, m_delayTimer)); } durationInMilliseconds = (uint32) ((m_delayTimer + k_requireAdditionalTime) * 1000.0f + 0.5f); // Add 0.5f to round up when turning into a uint32 } m_pWeapon->GetScheduler()->TimerAction(durationInMilliseconds, CSchedulerAction<StopAttackingAction>::Create(this), true); } m_pWeapon->OnMelee(m_pWeapon->GetOwnerId()); m_pWeapon->RequestStartMeleeAttack((m_pWeapon->GetMelee() == this), false); if (isClient) { s_fNextAttack = GetDuration() + gEnv->pTimer->GetFrameStartTime().GetSeconds(); if(s_meleeSnapTargetId = GetNearestTarget()) { IActor* pTargetActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(s_meleeSnapTargetId); s_bMeleeSnapTargetCrouched = pTargetActor && static_cast<CPlayer*>(pTargetActor)->GetStance() == STANCE_CROUCH; } CHANGED_NETWORK_STATE(pOwner, CPlayer::ASPECT_SNAP_TARGET); if (ownerPlayer) { if (ownerPlayer->IsThirdPerson()) { CAudioSignalPlayer::JustPlay(m_pMeleeParams->meleeparams.m_3PSignalId, ownerPlayer->GetEntityId()); } else { CAudioSignalPlayer::JustPlay(m_pMeleeParams->meleeparams.m_FPSignalId, ownerPlayer->GetEntityId()); } } CCCPOINT(Melee_LocalActorMelee); } else { CCCPOINT(Melee_NonLocalActorMelee); } }
bool CShotgun::Shoot(bool resetAnimation, bool autoreload/* =true */, bool isRemote) { CCCPOINT(Shotgun_TryShoot); m_firePending = false; m_shotIndex++; IEntityClass* ammo = m_fireParams->fireparams.ammo_type_class; int ammoCount = m_pWeapon->GetAmmoCount(ammo); int clipSize = GetClipSize(); if (clipSize == 0) ammoCount = m_pWeapon->GetInventoryAmmoCount(ammo); CActor *pActor = m_pWeapon->GetOwnerActor(); bool playerIsShooter = pActor ? pActor->IsPlayer() : false; bool shooterIsClient = pActor ? pActor->IsClient() : false; if (!CanFire(true)) { if ((ammoCount <= 0) && (!m_reloading)) { m_pWeapon->PlayAction(GetFragmentIds().empty_clip); m_pWeapon->OnFireWhenOutOfAmmo(); CCCPOINT(Shotgun_TryShootWhileOutOfAmmo); } else { CCCPOINT(Shotgun_TryShootWhileCannotBeFired); } return false; } if (m_reloading) { if(m_pWeapon->IsBusy()) m_pWeapon->SetBusy(false); if(CanFire(true) && !m_break_reload) { m_break_reload = true; m_pWeapon->RequestCancelReload(); } CCCPOINT(Shotgun_TryShootWhileReloading); return false; } uint32 flags = CItem::eIPAF_Default; if (IsProceduralRecoilEnabled() && pActor) { pActor->ProceduralRecoil(m_fireParams->proceduralRecoilParams.duration, m_fireParams->proceduralRecoilParams.strength, m_fireParams->proceduralRecoilParams.kickIn, m_fireParams->proceduralRecoilParams.arms); } float speedOverride = -1.f; m_pWeapon->PlayAction(GetFragmentIds().fire, 0, false, flags, speedOverride); Vec3 hit = GetProbableHit(WEAPON_HIT_RANGE); Vec3 pos = GetFiringPos(hit); Vec3 fdir = GetFiringDir(hit, pos); Vec3 vel = GetFiringVelocity(fdir); Vec3 dir; const float hitDist = hit.GetDistance(pos); CheckNearMisses(hit, pos, fdir, WEAPON_HIT_RANGE, m_fireParams->shotgunparams.spread); CRY_ASSERT_MESSAGE(m_fireParams->fireparams.hitTypeId, string().Format("Invalid hit type '%s' in fire params for '%s'", m_fireParams->fireparams.hit_type.c_str(), m_pWeapon->GetEntity()->GetName())); CRY_ASSERT_MESSAGE(m_fireParams->fireparams.hitTypeId == g_pGame->GetGameRules()->GetHitTypeId(m_fireParams->fireparams.hit_type.c_str()), "Sanity Check Failed: Stored hit type id does not match the type string, possibly CacheResources wasn't called on this weapon type"); int quad = cry_random(0, 3); const int numPellets = m_fireParams->shotgunparams.pellets; std::vector<CProjectile*> projList; projList.reserve(numPellets); int ammoCost = (m_fireParams->fireparams.fake_fire_rate && playerIsShooter) ? m_fireParams->fireparams.fake_fire_rate : 1; ammoCost = min(ammoCost, ammoCount); EntityId firstAmmoId = 0; // SHOT HERE for (int i = 0; i < numPellets; i++) { CProjectile *pAmmo = m_pWeapon->SpawnAmmo(m_fireParams->fireparams.spawn_ammo_class, false); if (pAmmo) { if(!firstAmmoId) { firstAmmoId = pAmmo->GetEntityId(); } projList.push_back(pAmmo); dir = ApplySpread(fdir, m_fireParams->shotgunparams.spread, quad); quad = (quad+1)%4; int pelletDamage = m_fireParams->shotgunparams.pelletdamage; if (!playerIsShooter) pelletDamage += m_fireParams->shotgunparams.npc_additional_damage; const bool canOvercharge = m_pWeapon->GetSharedItemParams()->params.can_overcharge; const float overchargeModifier = pActor ? pActor->GetOverchargeDamageScale() : 1.0f; if (canOvercharge) { pelletDamage = int(pelletDamage * overchargeModifier); } CProjectile::SProjectileDesc projectileDesc( m_pWeapon->GetOwnerId(), m_pWeapon->GetHostId(), m_pWeapon->GetEntityId(), pelletDamage, m_fireParams->fireparams.damage_drop_min_distance, m_fireParams->fireparams.damage_drop_per_meter, m_fireParams->fireparams.damage_drop_min_damage, m_fireParams->fireparams.hitTypeId, m_fireParams->fireparams.bullet_pierceability_modifier, m_pWeapon->IsZoomed()); projectileDesc.pointBlankAmount = m_fireParams->fireparams.point_blank_amount; projectileDesc.pointBlankDistance = m_fireParams->fireparams.point_blank_distance; projectileDesc.pointBlankFalloffDistance = m_fireParams->fireparams.point_blank_falloff_distance; if (m_fireParams->fireparams.ignore_damage_falloff) projectileDesc.damageFallOffAmount = 0.0f; const Vec3 pelletDestination = pos + (dir * hitDist); pAmmo->SetParams(projectileDesc); pAmmo->SetDestination(m_pWeapon->GetDestination()); pAmmo->Launch(pos, dir, vel); pAmmo->CreateBulletTrail( pelletDestination ); pAmmo->SetKnocksTargetInfo( GetShared() ); if ((!m_fireParams->tracerparams.geometry.empty() || !m_fireParams->tracerparams.effect.empty()) && ((ammoCount == clipSize) || (ammoCount%m_fireParams->tracerparams.frequency==0))) { EmitTracer(pos, pelletDestination, &m_fireParams->tracerparams, pAmmo); } if(shooterIsClient) { pAmmo->RegisterLinkedProjectile(m_shotIndex); if(gEnv->bMultiplayer) { float damageCap = g_pGameCVars->pl_shotgunDamageCap; pAmmo->SetDamageCap(damageCap); } } m_projectileId = pAmmo->GetEntity()->GetId(); pAmmo->SetAmmoCost(ammoCost); } } if (m_pWeapon->IsServer()) { const char *ammoName = ammo != NULL ? ammo->GetName() : NULL; g_pGame->GetIGameFramework()->GetIGameplayRecorder()->Event(m_pWeapon->GetOwner(), GameplayEvent(eGE_WeaponShot, ammoName, m_fireParams->shotgunparams.pellets, (void *)(EXPAND_PTR)m_pWeapon->GetEntityId())); } m_muzzleEffect.Shoot(this, hit, m_barrelId); m_fired = true; SetNextShotTime(m_next_shot + m_next_shot_dt); ammoCount -= ammoCost; if (ammoCount < m_fireParams->fireparams.minimum_ammo_count) ammoCount = 0; if (clipSize != -1) { if (clipSize != 0) m_pWeapon->SetAmmoCount(ammo, ammoCount); else m_pWeapon->SetInventoryAmmoCount(ammo, ammoCount); } OnShoot(m_pWeapon->GetOwnerId(), firstAmmoId, ammo, pos, dir, vel); const SThermalVisionParams& thermalParams = m_fireParams->thermalVisionParams; m_pWeapon->AddShootHeatPulse(pActor, thermalParams.weapon_shootHeatPulse, thermalParams.weapon_shootHeatPulseTime, thermalParams.owner_shootHeatPulse, thermalParams.owner_shootHeatPulseTime); if (OutOfAmmo()) { m_pWeapon->OnOutOfAmmo(ammo); if (autoreload) { uint32 scheduleTime = max(m_pWeapon->GetCurrentAnimationTime(eIGS_Owner), (uint)(m_next_shot*1000)); m_pWeapon->GetScheduler()->TimerAction(scheduleTime, CSchedulerAction<ScheduleReload>::Create(ScheduleReload(this, m_pWeapon)), false); m_autoReloading = true; } } m_pWeapon->RequestShoot(ammo, pos, dir, vel, hit, 1.0f, 0, false); #if defined(ANTI_CHEAT) const int numProjectiles = projList.size(); uint32 shotId = m_pWeapon->GetLastShotId(); for(int i = 0; i < numProjectiles; i++) { CProjectile * pAmmo = projList[i]; pAmmo->SetShotId(shotId); shotId -= (1 << CWeapon::GetShotIdCountOffset()); } #endif CCCPOINT(Shotgun_Fired); return true; }
//------------------------------------------------------------------------- void CGameBrowser::StartSearchingForServers(CryMatchmakingSessionSearchCallback cb) { ICryLobby *lobby = gEnv->pNetwork->GetLobby(); if (lobby != NULL && lobby->GetLobbyService()) { CCCPOINT (GameLobby_StartSearchingForServers); if (CanStartSearch()) { CryLog("[UI] Delayed Searching for sessions"); m_delayedSearchType = eDST_Full; NOTIFY_UILOBBY_MP(SearchStarted()); return; } SCrySessionSearchParam param; SCrySessionSearchData data[START_SEARCHING_FOR_SERVERS_NUM_DATA]; param.m_type = REQUIRED_SESSIONS_QUERY; param.m_data = data; #if defined(XENON) || defined(PS3) param.m_numFreeSlots = max(g_pGame->GetSquadManager()->GetSquadSize(), 1); #else param.m_numFreeSlots = 0; #endif param.m_maxNumReturn = g_pGameCVars->g_maxGameBrowserResults; param.m_ranked = false; int curData = 0; #if defined(XENON) data[curData].m_operator = eCSSO_Equal; data[curData].m_data.m_id = REQUIRED_SESSIONS_SEARCH_PARAM; data[curData].m_data.m_type = eCLUDT_Int32; data[curData].m_data.m_int32 = 0; ++curData; #endif CRY_ASSERT_MESSAGE( curData < START_SEARCHING_FOR_SERVERS_NUM_DATA, "Session search data buffer overrun" ); data[curData].m_operator = eCSSO_Equal; data[curData].m_data.m_id = LID_MATCHDATA_VERSION; data[curData].m_data.m_type = eCLUDT_Int32; data[curData].m_data.m_int32 = GameLobbyData::GetVersion(); ++curData; // if you want to use this, make sure the search query in the SPA asks for this param as well if (!g_pGameCVars->g_ignoreDLCRequirements) { // Note: GetSquadCommonDLCs is actually a bit field, so it should really be doing a bitwise & to determine // if the client can join the server. However this is not supported so the less than equal operator // is used instead. This may return some false positives but never any false negatives, the false // positives will be filtered out when the results are retreived. CRY_ASSERT_MESSAGE( curData < START_SEARCHING_FOR_SERVERS_NUM_DATA, "Session search data buffer overrun" ); data[curData].m_operator = eCSSO_LessThanEqual; data[curData].m_data.m_id = LID_MATCHDATA_REQUIRED_DLCS; data[curData].m_data.m_type = eCLUDT_Int32; data[curData].m_data.m_int32 = g_pGame->GetDLCManager()->GetSquadCommonDLCs(); ++curData; } param.m_numData = curData; CRY_ASSERT_MESSAGE(m_searchingTask==CryLobbyInvalidTaskID,"CGameBrowser Trying to search for sessions when you think you are already searching."); ECryLobbyError error = StartSearchingForServers(¶m, cb, this, false); CRY_ASSERT_MESSAGE(error==eCLE_Success,"CGameBrowser searching for sessions failed."); if (error == eCLE_Success) { NOTIFY_UILOBBY_MP(SearchStarted()); CryLogAlways("CCGameBrowser::StartSearchingForServers %d", m_searchingTask); } else { NOTIFY_UILOBBY_MP(SearchCompleted()); m_searchingTask = CryLobbyInvalidTaskID; } } else { CRY_ASSERT_MESSAGE(0,"CGameBrowser Cannot search for servers : no lobby service available."); } }
//------------------------------------------------------------------------ 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()); } } } }
//------------------------------------------------------------------------ bool CGameRules::OnPromoteToServer(SHostMigrationInfo& hostMigrationInfo, uint32& state) { if (!g_pGame->GetIGameFramework()->ShouldMigrateNub(hostMigrationInfo.m_session)) { return true; } CryLogAlways("[Host Migration]: CGameRules::OnPromoteToServer() started"); // Server time will change after we migrate (change from old server time to new server time) m_gameStartedTime.SetValue(m_gameStartedTime.GetValue() - m_cachedServerTime.GetValue()); m_gameStartTime.SetValue(m_gameStartTime.GetValue() - m_cachedServerTime.GetValue()); // If this migration has reset (we're not the original anticipated host, remove any entities from the first attempt if (!m_hostMigrationCachedEntities.empty()) { HostMigrationRemoveDuplicateDynamicEntities(); } // Now we know we're the server, remove the actors for anyone we know isn't going to migrate CGameLobby *pGameLobby = g_pGame->GetGameLobby(); CRY_ASSERT(pGameLobby); if (pGameLobby) { TPlayers playersToRemove; IActorSystem *pActorSystem = g_pGame->GetIGameFramework()->GetIActorSystem(); playersToRemove.reserve(pActorSystem->GetActorCount()); IActorIteratorPtr actorIt = pActorSystem->CreateActorIterator(); IActor *pActor; while (pActor = actorIt->Next()) { if (pActor->IsPlayer()) { CRY_ASSERT(pActor->GetChannelId()); SCryMatchMakingConnectionUID conId = pGameLobby->GetConnectionUIDFromChannelID((int) pActor->GetChannelId()); if (pGameLobby->GetSessionNames().Find(conId) == SSessionNames::k_unableToFind) { CryLog(" player '%s' has not got a corresponding CGameLobby entry, removing actor", pActor->GetEntity()->GetName()); playersToRemove.push_back(pActor->GetEntityId()); } } } const int numPlayersToRemove = playersToRemove.size(); for (int i = 0; i < numPlayersToRemove; ++ i) { FakeDisconnectPlayer(playersToRemove[i]); } } for (uint32 i = 0; i < MAX_PLAYERS; ++ i) { m_migratedPlayerChannels[i] = 0; } IItemSystem *pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem(); IEntityItPtr it = gEnv->pEntitySystem->GetEntityIterator(); it->MoveFirst(); for (uint32 i = 0; i < m_hostMigrationItemMaxCount; ++ i) { m_pHostMigrationItemInfo[i].Reset(); } uint32 itemIndex = 0; IEntity *pEntity = NULL; while (pEntity = it->Next()) { IItem *pItem = pItemSystem->GetItem(pEntity->GetId()); if (pItem) { if (pItem->GetOwnerId()) { IEntity *pOwner = gEnv->pEntitySystem->GetEntity(pItem->GetOwnerId()); if (pOwner) { EntityId currentItemId = 0; IActor *pOwnerActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pOwner->GetId()); if (pOwnerActor) { IItem *pCurrentItem = pOwnerActor->GetCurrentItem(); currentItemId = pCurrentItem ? pCurrentItem->GetEntityId() : 0; } CryLog("[CG] Item '%s' is owned by '%s'", pEntity->GetName(), pOwner->GetName()); //m_pHostMigrationItemInfo[itemIndex].Set(pEntity->GetId(), pOwner->GetId(), pItem->IsUsed(), (pItem->GetEntityId() == currentItemId)); itemIndex ++; if (itemIndex >= m_hostMigrationItemMaxCount) { CRY_ASSERT(itemIndex < m_hostMigrationItemMaxCount); break; } } } } // Tell entities that we're host migrating // - Currently only used by ForbiddenArea but may well be needed for other entities later // - Currently only called on the new server, add to OnDemoteToClient if we need to use this on a client IScriptTable *pScript = pEntity->GetScriptTable(); if (pScript != NULL && pScript->GetValueType("OnHostMigration") == svtFunction) { m_pScriptSystem->BeginCall(pScript, "OnHostMigration"); m_pScriptSystem->PushFuncParam(pScript); m_pScriptSystem->PushFuncParam(true); m_pScriptSystem->EndCall(); } } // This needs initialising on the new server otherwise the respawn timer will be counting down // from uninitialised data. Likewise for the pre-round timer. ResetReviveCycleTime(); const int numRespawnParams = m_respawndata.size(); for (int i = 0; i < numRespawnParams; ++ i) { SEntityRespawnData *pData = &m_respawndata[i]; pEntity = gEnv->pEntitySystem->GetEntity(pData->m_currentEntityId); if (pEntity == NULL) { CryLog(" detected respawn entity (id=%u) is not present, scheduling for respawn", pData->m_currentEntityId); ScheduleEntityRespawn(pData->m_currentEntityId, false, g_pGameCVars->g_defaultItemRespawnTimer); } } CryLog("[Host Migration]: CGameRules::OnPromoteToServer() finished"); CCCPOINT(HostMigration_OnPromoteToServer); return true; }
//------------------------------------------------------------------------ bool CGameRules::OnInitiate(SHostMigrationInfo& hostMigrationInfo, uint32& state) { if (!g_pGame->GetIGameFramework()->ShouldMigrateNub(hostMigrationInfo.m_session)) { return true; } CryLog("[Host Migration]: CGameRules::OnInitiate() Saving character for host migration started"); m_hostMigrationClientHasRejoined = false; IEntityScriptProxy* pScriptProxy = static_cast<IEntityScriptProxy*>(GetEntity()->GetProxy(ENTITY_PROXY_SCRIPT)); if (pScriptProxy) { if (string(pScriptProxy->GetState()) == "InGame") { m_hostMigrationTimeSinceGameStarted = (m_cachedServerTime - m_gameStartedTime); } } HostMigrationStopAddingPlayers(); if (gEnv->IsClient()) { if (!m_pHostMigrationParams) { m_pHostMigrationParams = new SHostMigrationClientRequestParams(); m_pHostMigrationClientParams = new SHostMigrationClientControlledParams(); } IActor *pPlayer = g_pGame->GetIGameFramework()->GetClientActor(); if (pPlayer) { m_pHostMigrationClientParams->m_viewQuat = pPlayer->GetViewRotation(); m_pHostMigrationClientParams->m_position = pPlayer->GetEntity()->GetPos(); pe_status_living livStat; IPhysicalEntity *pPhysicalEntity = pPlayer->GetEntity()->GetPhysics(); if (pPhysicalEntity != NULL && (pPhysicalEntity->GetType() == PE_LIVING) && (pPhysicalEntity->GetStatus(&livStat) > 0)) { m_pHostMigrationClientParams->m_velocity = livStat.velUnconstrained; m_pHostMigrationClientParams->m_hasValidVelocity = true; CryLog(" velocity={%f,%f,%f}", m_pHostMigrationClientParams->m_velocity.x, m_pHostMigrationClientParams->m_velocity.y, m_pHostMigrationClientParams->m_velocity.z); } IInventory *pInventory = pPlayer->GetInventory(); m_pHostMigrationClientParams->m_numExpectedItems = 0; int numAmmoTypes = 0; m_pHostMigrationClientParams->m_pAmmoParams = new SHostMigrationClientControlledParams::SAmmoParams[numAmmoTypes]; m_pHostMigrationClientParams->m_numAmmoParams = numAmmoTypes; /*CryLog(" player has %i different ammo types", numAmmoTypes); for (int i = 0; i < numAmmoTypes; ++ i) { IEntityClass *pAmmoType = pInventory->GetAmmoType(i); int ammoCount = pInventory->GetAmmoCount(pAmmoType); m_pHostMigrationClientParams->m_pAmmoParams[i].m_pAmmoClass = pAmmoType; m_pHostMigrationClientParams->m_pAmmoParams[i].m_count = ammoCount; CryLog(" %s : %i", pAmmoType->GetName(), ammoCount); }* EntityId holseredItemId = pInventory->GetHolsteredItem(); if (holseredItemId) { IEntity *pHolsteredEntity = gEnv->pEntitySystem->GetEntity(holseredItemId); if (pHolsteredEntity) { m_pHostMigrationClientParams->m_pHolsteredItemClass = pHolsteredEntity->GetClass(); } }*/ IMovementController *pMovementController = pPlayer->GetMovementController(); if(pMovementController) { SMovementState movementState; pMovementController->GetMovementState(movementState); m_pHostMigrationClientParams->m_aimDirection = movementState.aimDirection; } /*CItem *pItem = static_cast<CItem*>(pPlayer->GetCurrentItem()); if (pItem) { m_pHostMigrationClientParams->m_pSelectedItemClass = pItem->GetEntity()->GetClass(); CryLog(" currently using item '%s", pItem->GetEntity()->GetName()); }*/ } else { CRY_ASSERT_MESSAGE(false, "Failed to find client actor when initiating a host migration"); gEnv->pNetwork->TerminateHostMigration(hostMigrationInfo.m_session); return false; } } g_pGame->SetHostMigrationState(CGame::eHMS_WaitingForPlayers); CCCPOINT(HostMigration_OnInitiate); return true; }
//------------------------------------------------------------------------ void CGameRulesHoldObjectiveBase::CheckCylinder( SHoldEntityDetails *pDetails, EntityId localPlayerId ) { IEntity *pHoldEntity = gEnv->pEntitySystem->GetEntity(pDetails->m_id); if (pHoldEntity) { pDetails->m_totalInsideBoxCount = 0; const Vec3 &holdPos = pHoldEntity->GetPos(); bool hasChanged = false; bool localPlayerWithinRange = false; for (int teamIdx = 0; teamIdx < NUM_TEAMS; ++ teamIdx) { const int previousNumEntities = pDetails->m_insideEntities[teamIdx].size(); pDetails->m_insideEntities[teamIdx].clear(); const TEntityIdVec &boxEntities = pDetails->m_insideBoxEntities[teamIdx]; const int numBoxEntities = boxEntities.size(); pDetails->m_totalInsideBoxCount += numBoxEntities; for (int entIdx = 0; entIdx < numBoxEntities; ++ entIdx) { EntityId playerId = boxEntities[entIdx]; IEntity *pPlayer = gEnv->pEntitySystem->GetEntity(playerId); if (pPlayer) { //Make sure we're not in a vehicle for C3 if(IActor * pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(playerId)) { if(pActor->GetLinkedVehicle() != NULL) continue; } const Vec3 &playerPos = pPlayer->GetPos(); const float xDist = playerPos.x - holdPos.x; const float yDist = playerPos.y - holdPos.y; const float flatDistSqr = (xDist * xDist) + (yDist * yDist); if (flatDistSqr < pDetails->m_controlRadiusSqr) { pDetails->m_insideEntities[teamIdx].push_back(playerId); if (playerId == localPlayerId) { localPlayerWithinRange = true; } } } } if (pDetails->m_insideEntities[teamIdx].size() != previousNumEntities) { hasChanged = true; } } if (hasChanged) { if (localPlayerWithinRange != pDetails->m_localPlayerIsWithinRange) { if (localPlayerWithinRange) { pDetails->m_localPlayerIsWithinRange = true; CCCPOINT(HoldObjective_LocalPlayerEnterArea); } else { pDetails->m_localPlayerIsWithinRange = false; CCCPOINT(HoldObjective_LocalPlayerLeaveArea); } OnLocalPlayerInsideStateChanged(pDetails); } if (gEnv->bServer) { InsideStateChanged(pDetails); } else { OnInsideStateChanged(pDetails); } } } }
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 CGameRulesHoldObjectiveBase::DoAddEntityId(int type, EntityId entityId, int index, bool isNewEntity) { CRY_ASSERT(index < HOLD_OBJECTIVE_MAX_ENTITIES); CryLog("CGameRulesHoldObjectiveBase::DoAddEntityId() received objective, eid=%i, index=%i", entityId, index); SHoldEntityDetails *pDetails = &m_entities[index]; pDetails->m_id = entityId; if (m_spawnPOIType == eSPT_Avoid) { IGameRulesSpawningModule *pSpawningModule = g_pGame->GetGameRules()->GetSpawningModule(); if (pSpawningModule) { pSpawningModule->AddAvoidPOI(entityId, m_spawnPOIDistance, true, AreObjectivesStatic()); } } OnNewHoldEntity(pDetails, index); CCCPOINT(HoldObjective_AddEntity); gEnv->pEntitySystem->AddEntityEventListener(entityId, ENTITY_EVENT_ENTERAREA, this); gEnv->pEntitySystem->AddEntityEventListener(entityId, ENTITY_EVENT_LEAVEAREA, this); if (gEnv->bServer) { CHANGED_NETWORK_STATE(g_pGame->GetGameRules(), HOLD_OBJECTIVE_STATE_ASPECT); } if(isNewEntity) { //Not playing for the first time because it clashes with game start Announce("Incoming", k_announceType_CS_Incoming, m_shouldPlayIncomingAudio); m_shouldPlayIncomingAudio = true; } IEntity *pEntity = gEnv->pEntitySystem->GetEntity(entityId); if (pEntity) { IScriptTable *pScript = pEntity->GetScriptTable(); CRY_TODO(11, 02, 2009, "function name from xml?"); if (pScript) { if (pScript->GetValueType("ActivateCapturePoint") == svtFunction) { if (isNewEntity) { // Set flag to say we're expecting a trackview to start - so we can set the start position in the callback m_bExpectingMovieStart = true; if (!m_bAddedMovieListener) { if (gEnv->pMovieSystem) { CryLog("CGameRulesHoldObjectiveBase::CGameRulesHoldObjectiveBase() adding movie listener"); gEnv->pMovieSystem->AddMovieListener(NULL, this); m_bAddedMovieListener = true; } } } IScriptSystem *pScriptSystem = gEnv->pScriptSystem; pScriptSystem->BeginCall(pScript, "ActivateCapturePoint"); pScriptSystem->PushFuncParam(pScript); pScriptSystem->PushFuncParam(isNewEntity); pScriptSystem->EndCall(); } SmartScriptTable propertiesTable; if (pScript->GetValue("Properties", propertiesTable)) { pDetails->m_controlRadius = 5.f; propertiesTable->GetValue("ControlRadius", pDetails->m_controlRadius); pDetails->m_controlRadiusSqr = (pDetails->m_controlRadius * pDetails->m_controlRadius); pDetails->m_controlHeight = 5.f; propertiesTable->GetValue("ControlHeight", pDetails->m_controlHeight); pDetails->m_controlOffsetZ = 0.f; propertiesTable->GetValue("ControlOffsetZ", pDetails->m_controlOffsetZ); } } const IActor *pLocalPlayer = g_pGame->GetIGameFramework()->GetClientActor(); if (pLocalPlayer != NULL && IsActorEligible(pLocalPlayer)) { CheckLocalPlayerInside(pDetails, pEntity, pLocalPlayer->GetEntity()); } } }
//------------------------------------------------------------------------- void CGameBrowser::StartSearchingForServers(CryMatchmakingSessionSearchCallback cb) { ICryLobby *lobby = gEnv->pNetwork->GetLobby(); if (lobby != NULL && lobby->GetLobbyService()) { #ifdef GAME_IS_CRYSIS2 CCCPOINT (GameLobby_StartSearchingForServers); #endif if (CanStartSearch()) { CryLog("[UI] Delayed Searching for sessions"); m_delayedSearchType = eDST_Full; #ifdef USE_C2_FRONTEND if (CMPMenuHub *pMPMenu = CMPMenuHub::GetMPMenuHub()) { pMPMenu->StartSearching(); } #endif //#ifdef USE_C2_FRONTEND return; } SCrySessionSearchParam param; SCrySessionSearchData data[START_SEARCHING_FOR_SERVERS_NUM_DATA]; param.m_type = REQUIRED_SESSIONS_QUERY; param.m_data = data; param.m_numFreeSlots = 0; param.m_maxNumReturn = g_pGameCVars->g_maxGameBrowserResults; param.m_ranked = false; int curData = 0; CRY_ASSERT_MESSAGE( curData < START_SEARCHING_FOR_SERVERS_NUM_DATA, "Session search data buffer overrun" ); data[curData].m_operator = eCSSO_Equal; data[curData].m_data.m_id = LID_MATCHDATA_VERSION; data[curData].m_data.m_type = eCLUDT_Int32; data[curData].m_data.m_int32 = GameLobbyData::GetVersion(); curData++; #ifdef GAME_IS_CRYSIS2 if (!g_pGameCVars->g_ignoreDLCRequirements) { // Note: GetSquadCommonDLCs is actually a bit field, so it should really be doing a bitwise & to determine // if the client can join the server. However this is not supported so the less than equal operator // is used instead. This may return some false positives but never any false negatives, the false // positives will be filtered out when the results are retreived. CRY_ASSERT_MESSAGE( curData < START_SEARCHING_FOR_SERVERS_NUM_DATA, "Session search data buffer overrun" ); data[curData].m_operator = eCSSO_LessThanEqual; data[curData].m_data.m_id = LID_MATCHDATA_REQUIRED_DLCS; data[curData].m_data.m_type = eCLUDT_Int32; data[curData].m_data.m_int32 = g_pGame->GetDLCManager()->GetSquadCommonDLCs(); curData++; } #endif #if USE_CRYLOBBY_GAMESPY uint32 region = eSR_All; // Game side support for region filtering needs to change this. if ( region != eSR_All ) { CRY_ASSERT_MESSAGE( curData < START_SEARCHING_FOR_SERVERS_NUM_DATA, "Session search data buffer overrun" ); data[curData].m_operator = eCSSO_BitwiseAndNotEqualZero; data[curData].m_data.m_id = LID_MATCHDATA_REGION; data[curData].m_data.m_type = eCLUDT_Int32; data[curData].m_data.m_int32 = region; curData++; } int32 favouriteID = 0; // Game side support for favourite servers needs to change this. if ( favouriteID ) { CRY_ASSERT_MESSAGE( curData < START_SEARCHING_FOR_SERVERS_NUM_DATA, "Session search data buffer overrun" ); data[curData].m_operator = eCSSO_Equal; data[curData].m_data.m_id = LID_MATCHDATA_FAVOURITE_ID; data[curData].m_data.m_type = eCLUDT_Int32; data[curData].m_data.m_int32 = favouriteID; curData++; } #endif param.m_numData = curData; CRY_ASSERT_MESSAGE(m_searchingTask==CryLobbyInvalidTaskID,"CGameBrowser Trying to search for sessions when you think you are already searching."); ECryLobbyError error = StartSearchingForServers(¶m, cb, this, false); CRY_ASSERT_MESSAGE(error==eCLE_Success,"CGameBrowser searching for sessions failed."); #ifdef USE_C2_FRONTEND CMPMenuHub *pMPMenu = CMPMenuHub::GetMPMenuHub(); if (error == eCLE_Success) { if (pMPMenu) { pMPMenu->StartSearching(); } CryLogAlways("CCGameBrowser::StartSearchingForServers %d", m_searchingTask); } else { if (pMPMenu) { pMPMenu->SearchComplete(); } m_searchingTask = CryLobbyInvalidTaskID; } #endif //#ifdef USE_C2_FRONTEND } else { CRY_ASSERT_MESSAGE(0,"CGameBrowser Cannot search for servers : no lobby service available."); } }
//------------------------------------------------------------------------- void CGameRulesStandardState::ChangeState( EGR_GameState newState ) { if (gEnv->bServer) { if (newState == EGRS_InGame) { CCCPOINT(GameRulesStandardState_EnterInGame); #if !defined(_RELEASE) || defined(PERFORMANCE_BUILD) if (m_state != EGRS_InGame) { if (g_pGameCVars->g_gameRules_startCmd[0] != '\0') { gEnv->pConsole->ExecuteString(g_pGameCVars->g_gameRules_startCmd, false, true); } } #endif // #if !defined(_RELEASE) || defined(PERFORMANCE_BUILD) m_pGameRules->ResetGameTime(); IGameRulesStatsRecording *st=m_pGameRules->GetStatsRecordingModule(); if (st) { st->OnInGameBegin(); } } else if (newState == EGRS_PostGame) { m_timeInPostGame = 0.0f; IGameRulesStatsRecording *st=m_pGameRules->GetStatsRecordingModule(); if (st) { st->OnPostGameBegin(); } #if defined(DEDICATED_SERVER) if ( gEnv->bMultiplayer ) { // Stop cvar probes. CGameRules::TPlayers players; m_pGameRules->GetPlayers(players); const int numPlayers = players.size(); for (int i = 0; i < numPlayers; ++ i) { const EntityId playerId = players[i]; IActor * pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(playerId); if ( pActor ) { IGameObject * pGameObject = NULL; INetChannel * pNetChannel = NULL; IDefenceContext * pDefenceContext = NULL; if ( (pGameObject = pActor->GetGameObject()) ) { if ( (pNetChannel = pGameObject->GetNetChannel()) ) { if ( (pDefenceContext = pNetChannel->GetDefenceContext()) ) { pDefenceContext->EndCvarRequests(); } } } } } } #endif CGameLobby *pGameLobby = g_pGame->GetGameLobby(); if (pGameLobby) { CryLog("[GameRules] GameFinished, telling clients"); pGameLobby->SvFinishedGame(0.0f); } } } const bool bIsClient = gEnv->IsClient(); if (bIsClient) { if (newState == EGRS_PostGame) { m_timeInPostGame = 0.0f; EnterPostGameState(ePGS_Starting); } else if (newState == EGRS_InGame) { CHUDEventDispatcher::CallEvent( SHUDEvent(eHUDEvent_OnGameStart) ); } else if (newState == EGRS_Reset) { m_introMessageShown = false; } ClientChangeStateFeedback(newState); } m_state = newState; OnStateEntered_NotifyListeners(); if (newState == EGRS_PostGame) { m_pGameRules->FreezeInput(true); g_pGame->GetUI()->ActivateDefaultState(); // must be after settings newState to pick endgame OnGameEnd_NotifyListeners(); } else if (newState == EGRS_InGame) { OnGameStart_NotifyListeners(); if (bIsClient && g_pGameCVars->g_gameRules_preGame_StartSpawnedFrozen) { g_pGameActions->FilterMPPreGameFreeze()->Enable(false); g_pGame->GetUI()->ActivateDefaultState(); // must be after settings newState } // Have to explicitly call the spawning module, can't use the listener since that would make the modules // dependent on the initialisation order - which comes from xml IGameRulesSpawningModule *pSpawningModule = m_pGameRules->GetSpawningModule(); if (pSpawningModule) { pSpawningModule->OnInGameBegin(); } } if (gEnv->bServer) { CHANGED_NETWORK_STATE(m_pGameRules, STANDARD_STATE_ASPECT); if (m_state == EGRS_InGame) { // Revive players - has to be done after setting m_state since we don't revive players in PreGame IGameRulesSpawningModule *pSpawningModule = m_pGameRules->GetSpawningModule(); if (pSpawningModule) { const bool bOnlyIfDead = (g_pGameCVars->g_gameRules_preGame_StartSpawnedFrozen!=0); pSpawningModule->ReviveAllPlayers(false, bOnlyIfDead); } } } }
//------------------------------------------------------------------------ void CShotgun::NetShootEx(const Vec3 &pos, const Vec3 &dir, const Vec3 &vel, const Vec3 &hit, float extra, int ph) { CCCPOINT(Shotgun_NetShoot); assert(0 == ph); IEntityClass* ammo = m_fireParams->fireparams.ammo_type_class; FragmentID action = m_fireParams->fireparams.no_cock ? GetFragmentIds().fire : GetFragmentIds().fire_cock; CActor *pActor = m_pWeapon->GetOwnerActor(); bool playerIsShooter = pActor?pActor->IsPlayer():false; int ammoCount = m_pWeapon->GetAmmoCount(ammo); int clipSize = GetClipSize(); if (clipSize == 0) ammoCount = m_pWeapon->GetInventoryAmmoCount(ammo); if (ammoCount == 1) action = GetFragmentIds().fire; if (IsProceduralRecoilEnabled() && pActor) { pActor->ProceduralRecoil(m_fireParams->proceduralRecoilParams.duration, m_fireParams->proceduralRecoilParams.strength, m_fireParams->proceduralRecoilParams.kickIn,m_fireParams->proceduralRecoilParams.arms); } m_pWeapon->PlayAction(action, 0, false, CItem::eIPAF_Default); Vec3 pdir; int quad = cry_random(0, 3); CRY_ASSERT_MESSAGE(m_fireParams->fireparams.hitTypeId, string().Format("Invalid hit type '%s' in fire params for '%s'", m_fireParams->fireparams.hit_type.c_str(), m_pWeapon->GetEntity()->GetName())); CRY_ASSERT_MESSAGE(m_fireParams->fireparams.hitTypeId == g_pGame->GetGameRules()->GetHitTypeId(m_fireParams->fireparams.hit_type.c_str()), "Sanity Check Failed: Stored hit type id does not match the type string, possibly CacheResources wasn't called on this weapon type"); int ammoCost = m_fireParams->fireparams.fake_fire_rate ? m_fireParams->fireparams.fake_fire_rate : 1; ammoCost = min(ammoCost, ammoCount); // SHOT HERE for (int i = 0; i < m_fireParams->shotgunparams.pellets; i++) { CProjectile *pAmmo = m_pWeapon->SpawnAmmo(m_fireParams->fireparams.spawn_ammo_class, true); if (pAmmo) { pdir = ApplySpread(dir, m_fireParams->shotgunparams.spread, quad); quad = (quad+1)%4; CProjectile::SProjectileDesc projectileDesc( m_pWeapon->GetOwnerId(), m_pWeapon->GetHostId(), m_pWeapon->GetEntityId(), m_fireParams->shotgunparams.pelletdamage, m_fireParams->fireparams.damage_drop_min_distance, m_fireParams->fireparams.damage_drop_min_damage, m_fireParams->fireparams.damage_drop_per_meter, m_fireParams->fireparams.hitTypeId, m_fireParams->fireparams.bullet_pierceability_modifier, m_pWeapon->IsZoomed()); projectileDesc.pointBlankAmount = m_fireParams->fireparams.point_blank_amount; projectileDesc.pointBlankDistance = m_fireParams->fireparams.point_blank_distance; projectileDesc.pointBlankFalloffDistance = m_fireParams->fireparams.point_blank_falloff_distance; if (m_fireParams->fireparams.ignore_damage_falloff) projectileDesc.damageFallOffAmount = 0.0f; pAmmo->SetParams(projectileDesc); pAmmo->SetDestination(m_pWeapon->GetDestination()); pAmmo->SetRemote(true); pAmmo->Launch(pos, pdir, vel); bool emit = false; if(m_pWeapon->GetStats().fp) emit = (!m_fireParams->tracerparams.geometryFP.empty() || !m_fireParams->tracerparams.effectFP.empty()) && ((ammoCount == clipSize) || (ammoCount%m_fireParams->tracerparams.frequency==0)); else emit = (!m_fireParams->tracerparams.geometry.empty() || !m_fireParams->tracerparams.effect.empty()) && ((ammoCount == clipSize) || (ammoCount%m_fireParams->tracerparams.frequency==0)); if (emit) { EmitTracer(pos, hit, &m_fireParams->tracerparams, pAmmo); } m_projectileId = pAmmo->GetEntity()->GetId(); pAmmo->SetAmmoCost(ammoCost); } } if (m_pWeapon->IsServer()) { const char *ammoName = ammo != NULL ? ammo->GetName() : NULL; g_pGame->GetIGameFramework()->GetIGameplayRecorder()->Event(m_pWeapon->GetOwner(), GameplayEvent(eGE_WeaponShot, ammoName, m_fireParams->shotgunparams.pellets, (void *)(EXPAND_PTR)m_pWeapon->GetEntityId())); } m_muzzleEffect.Shoot(this, hit, m_barrelId); m_fired = true; m_next_shot = 0.0f; ammoCount -= ammoCost; if (m_pWeapon->IsServer()) { if (clipSize != -1) { if (clipSize != 0) m_pWeapon->SetAmmoCount(ammo, ammoCount); else m_pWeapon->SetInventoryAmmoCount(ammo, ammoCount); } } OnShoot(m_pWeapon->GetOwnerId(), 0, ammo, pos, dir, vel); m_pWeapon->RequireUpdate(eIUS_FireMode); }
//-------------------------------------------------------------------------------------------------- // 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); } } } } }//-------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------ bool CGameRules::OnInitiate(SHostMigrationInfo &hostMigrationInfo, uint32 &state) { if (!g_pGame->GetIGameFramework()->ShouldMigrateNub(hostMigrationInfo.m_session)) { return true; } CryLog("[Host Migration]: CGameRules::OnInitiate() Saving character for host migration started"); m_hostMigrationClientHasRejoined = false; IEntityScriptProxy *pScriptProxy = static_cast<IEntityScriptProxy *>(GetEntity()->GetProxy(ENTITY_PROXY_SCRIPT)); if (pScriptProxy) { if (string(pScriptProxy->GetState()) == "InGame") { m_hostMigrationTimeSinceGameStarted = (m_cachedServerTime - m_gameStartedTime); } } HostMigrationStopAddingPlayers(); if (gEnv->IsClient()) { if (!m_pHostMigrationParams) { m_pHostMigrationParams = new SHostMigrationClientRequestParams(); m_pHostMigrationClientParams = new SHostMigrationClientControlledParams(); } CPlayer *pPlayer = static_cast<CPlayer *>(g_pGame->GetIGameFramework()->GetClientActor()); if (pPlayer) { m_pHostMigrationClientParams->m_viewQuat = pPlayer->GetViewRotation(); m_pHostMigrationClientParams->m_position = pPlayer->GetEntity()->GetPos(); pe_status_living livStat; IPhysicalEntity *pPhysicalEntity = pPlayer->GetEntity()->GetPhysics(); if (pPhysicalEntity != NULL && (pPhysicalEntity->GetType() == PE_LIVING) && (pPhysicalEntity->GetStatus(&livStat) > 0)) { m_pHostMigrationClientParams->m_velocity = livStat.velUnconstrained; m_pHostMigrationClientParams->m_hasValidVelocity = true; CryLog(" velocity={%f,%f,%f}", m_pHostMigrationClientParams->m_velocity.x, m_pHostMigrationClientParams->m_velocity.y, m_pHostMigrationClientParams->m_velocity.z); } IMovementController *pMovementController = pPlayer->GetMovementController(); SMovementState movementState; pMovementController->GetMovementState(movementState); m_pHostMigrationClientParams->m_aimDirection = movementState.aimDirection; } else { CRY_ASSERT_MESSAGE(false, "Failed to find client actor when initiating a host migration"); gEnv->pNetwork->TerminateHostMigration(hostMigrationInfo.m_session); return false; } } g_pGame->SetHostMigrationState(CGame::eHMS_WaitingForPlayers); CCCPOINT(HostMigration_OnInitiate); return true; }