bool CFlashMenuObject::SaveGame(const char *fileName) { string sSaveFileName = fileName; const char *reason = ValidateName(fileName); if(reason) { ShowMenuMessage(reason); return false; } else { IActor *pActor = g_pGame->GetIGameFramework()->GetClientActor(); if(pActor && pActor->GetHealth() <= 0) { ShowMenuMessage("@ui_dead_no_save"); return false; } sSaveFileName.append(".CRYSISJMSF"); const bool bSuccess = gEnv->pGame->GetIGameFramework()->SaveGame(sSaveFileName,true, false, eSGR_QuickSave, true); if (!bSuccess) return false; UpdateSaveGames(); } return true; }
//------------------------------------------------------------------------ void CGameRules::ClientHit(const HitInfo &hitInfo) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); IEntity *pTarget = m_pEntitySystem->GetEntity(hitInfo.targetId); IEntity *pShooter = m_pEntitySystem->GetEntity(hitInfo.shooterId); IVehicle *pVehicle = g_pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(hitInfo.targetId); IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(hitInfo.targetId); bool dead = pActor?(pActor->GetHealth()<=0):false; if((pClientActor && pClientActor->GetEntity()==pShooter) && pTarget && (pVehicle || pActor) && !dead) { SAFE_HUD_FUNC(GetCrosshair()->CrosshairHit()); SAFE_HUD_FUNC(GetTagNames()->AddEnemyTagName(pActor?pActor->GetEntityId():pVehicle->GetEntityId())); } if(pActor == pClientActor) if (gEnv->pInput) gEnv->pInput->ForceFeedbackEvent( SFFOutputEvent(eDI_XI, eFF_Rumble_Basic, 0.5f * hitInfo.damage * 0.01f, hitInfo.damage * 0.02f, 0.0f)); /* if (gEnv->pAISystem && !gEnv->bMultiplayer) { static int htMelee = GetHitTypeId("melee"); if (pShooter && hitInfo.type != htMelee) { ISurfaceType *pSurfaceType = GetHitMaterial(hitInfo.material); const ISurfaceType::SSurfaceTypeAIParams* pParams = pSurfaceType ? pSurfaceType->GetAIParams() : 0; const float radius = pParams ? pParams->fImpactRadius : 5.0f; gEnv->pAISystem->BulletHitEvent(hitInfo.pos, radius, pShooter->GetAI()); } }*/ CreateScriptHitInfo(m_scriptHitInfo, hitInfo); CallScript(m_clientStateScript, "OnHit", m_scriptHitInfo); bool backface = hitInfo.dir.Dot(hitInfo.normal)>0; if (!hitInfo.remote && hitInfo.targetId && !backface) { if (!gEnv->bServer) GetGameObject()->InvokeRMI(SvRequestHit(), hitInfo, eRMI_ToServer); else ServerHit(hitInfo); } }
virtual void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo ) { switch (event) { case eFE_Activate: if (IsPortActive(pActInfo, 0)) { IActor* pActor = GetAIActor(pActInfo); if(pActor) { ActivateOutput(pActInfo, 0, pActor->GetHealth()); } else { GameWarning("CFlowActorGetHealth - No Entity or Entity not an Actor!"); } } } }
virtual void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo ) { switch (event) { case eFE_Activate: if (IsPortActive(pActInfo, 0)) { IActor* pActor = GetAIActor(pActInfo); if(pActor) { float health = pActor->GetHealth(); float minH = GetPortFloat(pActInfo, 1); float maxH = GetPortFloat(pActInfo, 2); ActivateOutput(pActInfo, 0, minH <= health && health <= maxH); } else { CryLogAlways("CFlowActorCheckHealth - No Entity or Entity not an Actor!"); } } } }
virtual void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo ) { switch (event) { case eFE_Activate: if (IsPortActive(pActInfo, 0)) { IActor* pActor = GetAIActor(pActInfo); if(pActor) { if (!pActor->IsDead()) { pActor->SetHealth( GetPortFloat(pActInfo, 1) ); ActivateOutput(pActInfo, 0, pActor->GetHealth()); // use pActor->GetHealth (might have been clamped to maxhealth] } } else { GameWarning("CFlowActorSetHealth - No Entity or Entity not an actor!"); } } } }
//------------------------------------------------------------------------ void CGameRules::ClientExplosion(const ExplosionInfo &explosionInfo) { // let 3D engine know about explosion (will create holes and remove vegetation) if (explosionInfo.hole_size > 1.0f && gEnv->p3DEngine->GetIVoxTerrain()) { gEnv->p3DEngine->OnExplosion(explosionInfo.pos, explosionInfo.hole_size, true); } TExplosionAffectedEntities affectedEntities; if (gEnv->bServer) { CullEntitiesInExplosion(explosionInfo); pe_explosion explosion; explosion.epicenter = explosionInfo.pos; explosion.rmin = explosionInfo.minRadius; explosion.rmax = explosionInfo.radius; if (explosion.rmax==0) explosion.rmax=0.0001f; explosion.r = explosion.rmin; explosion.impulsivePressureAtR = explosionInfo.pressure; explosion.epicenterImp = explosionInfo.pos; explosion.explDir = explosionInfo.dir; explosion.nGrow = 0; explosion.rminOcc = 0.07f; // we separate the calls to SimulateExplosion so that we can define different radii for AI and physics bodies explosion.holeSize = 0.0f; explosion.nOccRes = explosion.rmax>50.0f ? 0:16; gEnv->pPhysicalWorld->SimulateExplosion( &explosion, 0, 0, ent_living); CreateScriptExplosionInfo(m_scriptExplosionInfo, explosionInfo); UpdateAffectedEntitiesSet(affectedEntities, &explosion); // check vehicles IVehicleSystem *pVehicleSystem = g_pGame->GetIGameFramework()->GetIVehicleSystem(); uint32 vcount = pVehicleSystem->GetVehicleCount(); if (vcount > 0) { IVehicleIteratorPtr iter = g_pGame->GetIGameFramework()->GetIVehicleSystem()->CreateVehicleIterator(); while (IVehicle* pVehicle = iter->Next()) { if(IEntity *pEntity = pVehicle->GetEntity()) { AABB aabb; pEntity->GetWorldBounds(aabb); IPhysicalEntity* pEnt = pEntity->GetPhysics(); if (pEnt && aabb.GetDistanceSqr(explosionInfo.pos) <= explosionInfo.radius*explosionInfo.radius) { float affected = gEnv->pPhysicalWorld->CalculateExplosionExposure(&explosion, pEnt); AddOrUpdateAffectedEntity(affectedEntities, pEntity, affected); } } } } explosion.rmin = explosionInfo.minPhysRadius; explosion.rmax = explosionInfo.physRadius; if (explosion.rmax==0) explosion.rmax=0.0001f; explosion.r = explosion.rmin; explosion.holeSize = explosionInfo.hole_size; if (explosion.nOccRes>0) explosion.nOccRes = -1; // makes second call re-use occlusion info gEnv->pPhysicalWorld->SimulateExplosion( &explosion, 0, 0, ent_rigid|ent_sleeping_rigid|ent_independent|ent_static | ent_delayed_deformations); UpdateAffectedEntitiesSet(affectedEntities, &explosion); CommitAffectedEntitiesSet(m_scriptExplosionInfo, affectedEntities); float fSuitEnergyBeforeExplosion = 0.0f; float fHealthBeforeExplosion = 0.0f; IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); if(pClientActor) { fHealthBeforeExplosion = (float)pClientActor->GetHealth(); } CallScript(m_serverStateScript, "OnExplosion", m_scriptExplosionInfo); if(pClientActor) { float fDeltaHealth = fHealthBeforeExplosion - static_cast<CPlayer *>(pClientActor)->GetHealth(); if(fDeltaHealth >= 20.0f) { SAFE_GAMEAUDIO_SOUNDMOODS_FUNC(AddSoundMood(SOUNDMOOD_EXPLOSION, MIN(fDeltaHealth, 100.0f) )); } } // call hit listeners if any if (m_hitListeners.empty() == false) { for (size_t i = 0; i < m_hitListeners.size(); ) { size_t count = m_hitListeners.size(); m_hitListeners[i]->OnServerExplosion(explosionInfo); if (count == m_hitListeners.size()) i++; else continue; } } } if (gEnv->IsClient()) { if (explosionInfo.pParticleEffect) explosionInfo.pParticleEffect->Spawn(true, IParticleEffect::ParticleLoc(explosionInfo.pos, explosionInfo.dir, explosionInfo.effect_scale)); if (!gEnv->bServer) { CreateScriptExplosionInfo(m_scriptExplosionInfo, explosionInfo); } else { affectedEntities.clear(); CommitAffectedEntitiesSet(m_scriptExplosionInfo, affectedEntities); } CallScript(m_clientStateScript, "OnExplosion", m_scriptExplosionInfo); // call hit listeners if any if (m_hitListeners.empty() == false) { THitListenerVec::iterator iter = m_hitListeners.begin(); while (iter != m_hitListeners.end()) { (*iter)->OnExplosion(explosionInfo); ++iter; } } } ProcessClientExplosionScreenFX(explosionInfo); ProcessExplosionMaterialFX(explosionInfo); if (gEnv->pAISystem && !gEnv->bMultiplayer) { // Associate event with vehicle if the shooter is in a vehicle (tank cannon shot, etc) EntityId ownerId = explosionInfo.shooterId; IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(ownerId); if (pActor && pActor->GetLinkedVehicle() && pActor->GetLinkedVehicle()->GetEntityId()) ownerId = pActor->GetLinkedVehicle()->GetEntityId(); if (ownerId != 0) { SAIStimulus stim(AISTIM_EXPLOSION, 0, ownerId, 0, explosionInfo.pos, ZERO, explosionInfo.radius); gEnv->pAISystem->RegisterStimulus(stim); SAIStimulus stimSound(AISTIM_SOUND, AISOUND_EXPLOSION, ownerId, 0, explosionInfo.pos, ZERO, explosionInfo.radius * 3.0f, AISTIMPROC_FILTER_LINK_WITH_PREVIOUS); gEnv->pAISystem->RegisterStimulus(stimSound); } } }
//------------------------------------------------------------------------ void CGameRules::ClientExplosion(const ExplosionInfo &explosionInfo) { // let 3D engine know about explosion (will create holes and remove vegetation) //if (explosionInfo.hole_size > 0.0f) //{ //gEnv->p3DEngine->OnExplosion(explosionInfo.pos, explosionInfo.hole_size, true); //} TExplosionAffectedEntities affectedEntities; if (gEnv->bServer) { CullEntitiesInExplosion(explosionInfo); pe_explosion explosion; explosion.epicenter = explosionInfo.pos; explosion.rmin = explosionInfo.minRadius; explosion.rmax = explosionInfo.radius; if (explosion.rmax==0) explosion.rmax=0.0001f; explosion.r = explosion.rmin; explosion.impulsivePressureAtR = explosionInfo.pressure; explosion.epicenterImp = explosionInfo.pos; explosion.explDir = explosionInfo.dir; explosion.nGrow = 2; explosion.rminOcc = 0.07f; // we separate the calls to SimulateExplosion so that we can define different radii for AI and physics bodies explosion.holeSize = 0.0f; explosion.nOccRes = explosion.rmax>50.0f ? 0:32; gEnv->pPhysicalWorld->SimulateExplosion( &explosion, 0, 0, ent_living); CreateScriptExplosionInfo(m_scriptExplosionInfo, explosionInfo); UpdateAffectedEntitiesSet(affectedEntities, &explosion); // check vehicles IVehicleSystem *pVehicleSystem = g_pGame->GetIGameFramework()->GetIVehicleSystem(); uint32 vcount = pVehicleSystem->GetVehicleCount(); if (vcount > 0) { IVehicleIteratorPtr iter = g_pGame->GetIGameFramework()->GetIVehicleSystem()->CreateVehicleIterator(); while (IVehicle* pVehicle = iter->Next()) { if(IEntity *pEntity = pVehicle->GetEntity()) { AABB aabb; pEntity->GetWorldBounds(aabb); IPhysicalEntity* pEnt = pEntity->GetPhysics(); if (pEnt && aabb.GetDistanceSqr(explosionInfo.pos) <= explosionInfo.radius*explosionInfo.radius) { float affected = gEnv->pPhysicalWorld->CalculateExplosionExposure(&explosion, pEnt); AddOrUpdateAffectedEntity(affectedEntities, pEntity, affected); } } } } explosion.rmin = explosionInfo.minPhysRadius; explosion.rmax = explosionInfo.physRadius; if (explosion.rmax==0) explosion.rmax=0.0001f; explosion.r = explosion.rmin; explosion.holeSize = explosionInfo.hole_size; explosion.nOccRes = -1; // makes second call re-use occlusion info gEnv->pPhysicalWorld->SimulateExplosion( &explosion, 0, 0, ent_rigid|ent_sleeping_rigid|ent_independent|ent_static ); UpdateAffectedEntitiesSet(affectedEntities, &explosion); CommitAffectedEntitiesSet(m_scriptExplosionInfo, affectedEntities); float fSuitEnergyBeforeExplosion = 0.0f; float fHealthBeforeExplosion = 0.0f; IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); if(pClientActor) { fSuitEnergyBeforeExplosion = static_cast<CPlayer *>(pClientActor)->GetNanoSuit()->GetSuitEnergy(); fHealthBeforeExplosion = pClientActor->GetHealth(); } CallScript(m_serverStateScript, "OnExplosion", m_scriptExplosionInfo); if(pClientActor) { float fDeltaSuitEnergy = fSuitEnergyBeforeExplosion - static_cast<CPlayer *>(pClientActor)->GetNanoSuit()->GetSuitEnergy(); float fDeltaHealth = fHealthBeforeExplosion - pClientActor->GetHealth(); if(fDeltaSuitEnergy >= 50.0f || fDeltaHealth >= 20.0f) { SAFE_SOUNDMOODS_FUNC(AddSoundMood(SOUNDMOOD_EXPLOSION,MIN(fDeltaSuitEnergy+fDeltaHealth,100.0f))); } } // call hit listeners if any if (m_hitListeners.empty() == false) { THitListenerVec::iterator iter = m_hitListeners.begin(); while (iter != m_hitListeners.end()) { (*iter)->OnServerExplosion(explosionInfo); ++iter; } } } if (gEnv->bClient) { if (explosionInfo.pParticleEffect) explosionInfo.pParticleEffect->Spawn(true, IParticleEffect::ParticleLoc(explosionInfo.pos, explosionInfo.dir, explosionInfo.effect_scale)); if (!gEnv->bServer) { CreateScriptExplosionInfo(m_scriptExplosionInfo, explosionInfo); } else { affectedEntities.clear(); CommitAffectedEntitiesSet(m_scriptExplosionInfo, affectedEntities); } CallScript(m_clientStateScript, "OnExplosion", m_scriptExplosionInfo); // call hit listeners if any if (m_hitListeners.empty() == false) { THitListenerVec::iterator iter = m_hitListeners.begin(); while (iter != m_hitListeners.end()) { (*iter)->OnExplosion(explosionInfo); ++iter; } } } ProcessClientExplosionScreenFX(explosionInfo); ProcessExplosionMaterialFX(explosionInfo); IEntity *pShooter = m_pEntitySystem->GetEntity(explosionInfo.shooterId); if (gEnv->pAISystem && !gEnv->bMultiplayer) { IAIObject *pShooterAI(pShooter!=NULL ? pShooter->GetAI() : NULL); gEnv->pAISystem->ExplosionEvent(explosionInfo.pos,explosionInfo.radius, pShooterAI); } }
void CVehicleDamageBehaviorBlowTire::DamagePlayers() { // check for the nasty case when the player is shooting at the vehicle tires while prone // under or behind the car, In that case the player should get killed by the vehicle, // otherwise he gets stuck forever. Note that he should only get killed when the tier // is actually destroyed and not by collision resulting by the impulse added by just // shooting at the tiers. Unfortunately using physics for doing this check is not reliable // enough so we have to check it explicitly IEntityPhysicalProxy *pPhysicsProxy = (IEntityPhysicalProxy*)m_pVehicle->GetEntity()->GetProxy(ENTITY_PROXY_PHYSICS); if (!pPhysicsProxy) return; AABB bbox; pPhysicsProxy->GetWorldBounds( bbox ); IPhysicalWorld *pWorld = gEnv->pSystem->GetIPhysicalWorld(); IPhysicalEntity **ppColliders; // check entities in collision with the car int cnt = pWorld->GetEntitiesInBox( bbox.min,bbox.max, ppColliders,ent_living); for (int i = 0; i < cnt; i++) { IEntity *pEntity = gEnv->pEntitySystem->GetEntityFromPhysics( ppColliders[i] ); if (!pEntity) continue; // skip the vehicle itself if (pEntity==m_pVehicle->GetEntity()) continue; IPhysicalEntity *pPhysEnt = pEntity->GetPhysics(); if (!pPhysEnt) continue; IActor* pActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pEntity->GetId()); if(!pActor) continue; //Jan M.: the player is killed when he entered the vehicle while prone although he is still passenger! if(m_pVehicle == pActor->GetLinkedVehicle()) continue; //the player must be prone under the vehicle IAnimatedCharacter * animatedCharacter=pActor->GetAnimatedCharacter(); if (!animatedCharacter) continue; int stance = animatedCharacter->GetCurrentStance(); if (stance!=STANCE_PRONE) continue; pe_player_dimensions dim; if (!pPhysEnt->GetParams(&dim)) continue; // position returned is at entity's feet, add head position from physics Vec3 vPos1=pEntity->GetPos(); vPos1.z = vPos1.z + dim.heightHead; float fZ=bbox.GetCenter().z; if (vPos1.z>fZ) continue; // not under the vehicle // at this point we have a collision with the car moving down and the guy prone under the car, it is safe // to assume he has been squished so let's kill him. if (gEnv->bServer && pActor->GetHealth()>0) { // adding a server hit to make it working in MP IGameRules *pGameRules = gEnv->pGame->GetIGameFramework()->GetIGameRulesSystem()->GetCurrentGameRules(); if (pGameRules) { HitInfo hit; EntityId shooterId=m_pVehicle->GetEntityId(); if (m_pVehicle->GetDriver()) shooterId=m_pVehicle->GetDriver()->GetEntityId(); hit.targetId = pEntity->GetId(); hit.shooterId = shooterId; hit.weaponId = m_pVehicle->GetEntityId(); hit.damage = 1000.f; hit.type = 0; hit.pos = pActor->GetEntity()->GetWorldPos(); pGameRules->ServerHit(hit); } } } //i }
void CHUDTagNames::DrawTagName(IVehicle *pVehicle) { CRY_ASSERT(pVehicle); if(!pVehicle) return; CActor *pClientActor = static_cast<CActor *>(g_pGame->GetIGameFramework()->GetClientActor()); CGameRules *pGameRules = g_pGame->GetGameRules(); int iClientTeam = pGameRules->GetTeam(pClientActor->GetEntityId()); bool bThirdPerson = pClientActor->IsThirdPerson(); bool bDrawSeatTagNames = false; if(pClientActor->GetSpectatorMode() == CActor::eASM_Follow) { IActor *pFollowedActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pClientActor->GetSpectatorTarget()); if(pFollowedActor) bDrawSeatTagNames = (pVehicle == pFollowedActor->GetLinkedVehicle()); } else bDrawSeatTagNames = (pVehicle == pClientActor->GetLinkedVehicle()); if(bDrawSeatTagNames) { // When this is local player vehicle, we always display all passengers name above their head so that he can identify them for(int iSeatId=1; iSeatId<=pVehicle->GetLastSeatId(); iSeatId++) { IVehicleSeat *pVehicleSeat = pVehicle->GetSeatById(iSeatId); if(!pVehicleSeat) continue; IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pVehicleSeat->GetPassenger()); if(!pActor || (pActor == pClientActor && !bThirdPerson)) continue; DrawTagName(pActor,true); } return; } ColorF rgbTagName = COLOR_ENEMY; // Driver seat is always 1 IVehicleSeat *pVehicleSeat = pVehicle->GetSeatById(1); if(!pVehicleSeat) return; IVehicleHelper *pVehicleHelper = pVehicleSeat->GetSitHelper(); if(!pVehicleHelper) return; Vec3 vWorldPos = pVehicleHelper->GetWorldTM().GetTranslation(); // Add some offset to be above the driver/pilot vWorldPos.z += 1.2f; AABB box; pVehicle->GetEntity()->GetWorldBounds(box); bool bDrawOnTop = false; if(ProjectOnSphere(vWorldPos,box)) { bDrawOnTop = true; } m_tagNamesVector.resize(0); for(int iSeatId=1; iSeatId<=pVehicle->GetLastSeatId(); iSeatId++) { IVehicleSeat *pVehicleSeat = pVehicle->GetSeatById(iSeatId); if(!pVehicleSeat) continue; EntityId uiEntityId = pVehicleSeat->GetPassenger(); IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(uiEntityId); if(!pActor) continue; const char *szRank = GetPlayerRank(uiEntityId); IEntity *pEntity = pActor->GetEntity(); if(!pEntity) continue; char szText[HUD_MAX_STRING_SIZE]; if(szRank) { sprintf(szText,"%s %s",szRank,pEntity->GetName()); } else { sprintf(szText,"%s",pEntity->GetName()); } if(0 == iClientTeam) { if(uiEntityId && IsFriendlyToClient(uiEntityId)) { rgbTagName = COLOR_FRIEND; } } else if(uiEntityId && pGameRules->GetTeam(uiEntityId) == iClientTeam) { rgbTagName = COLOR_FRIEND; } if(pActor->GetHealth() <= 0) { rgbTagName = COLOR_DEAD; } m_tagNamesVector.resize(m_tagNamesVector.size()+1); STagName *pTagName = &m_tagNamesVector[m_tagNamesVector.size()-1]; pTagName->strName = szText; pTagName->vWorld = vWorldPos; pTagName->bDrawOnTop = bDrawOnTop; pTagName->rgb = rgbTagName; } DrawTagNames(); }