////////////////////////////////////////////////////////////////////////// //clear everything out before loading a checkpoint void CCheckpointSystem::ResetEngine() { //let game do initial resetting if (m_pGameHandler) { m_pGameHandler->OnPreResetEngine(); } //turn off physics gEnv->pSystem->SetThreadState(ESubsys_Physics, false); //reset engine similar to editor when leaving game mode //broken geometry and dynamics CCryAction::GetCryAction()->FlushBreakableObjects(); DeleteDynamicEntities(); CCryAction::GetCryAction()->ResetBrokenGameObjects(); //this should just reset the velocity of all moving things, but instead vehicle doors fall off ... //CXP : add this back in after CXP, Anton has to fix it //gEnv->pPhysicalWorld->ResetDynamicEntities(); //particle and post process effects gEnv->p3DEngine->ResetPostEffects(); gEnv->p3DEngine->ResetParticlesAndDecals(); REINST("notify the audio system?"); //AI System if (gEnv->pAISystem) { gEnv->pAISystem->Reset(IAISystem::RESET_EXIT_GAME); gEnv->pAISystem->Reset(IAISystem::RESET_ENTER_GAME); } //flow system //reset trackview gEnv->pMovieSystem->Reset(true, true); //entity system SEntityEvent event; event.event = ENTITY_EVENT_RESET; event.nParam[0] = 0; gEnv->pEntitySystem->SendEventToAll( event ); //Vehicle System IVehicleSystem *pVehicleSystem = CCryAction::GetCryAction()->GetIVehicleSystem(); IVehicleIteratorPtr pVehIt = pVehicleSystem->CreateVehicleIterator(); while(IVehicle *pVehicle = pVehIt->Next()) { pVehicle->Reset(true); } //make sure the scripts are clean gEnv->pScriptSystem->ForceGarbageCollection(); //turn on physics again gEnv->pSystem->SetThreadState(ESubsys_Physics, true); //let game do final resetting if (m_pGameHandler) { m_pGameHandler->OnPostResetEngine(); } }
//------------------------------------------------------------------------ void CDebugGun::Update( SEntityUpdateContext& ctx, int update) { if (!IsSelected()) return; static float drawColor[4] = {1,1,1,1}; static const int dx = 5; static const int dy = 15; static const float font = 1.2f; static const float fontLarge = 1.4f; IRenderer* pRenderer = gEnv->pRenderer; IRenderAuxGeom* pAuxGeom = pRenderer->GetIRenderAuxGeom(); pAuxGeom->SetRenderFlags(e_Def3DPublicRenderflags); pRenderer->Draw2dLabel(pRenderer->GetWidth()/5.f, pRenderer->GetHeight()-35, fontLarge, drawColor, false, "Firemode: %s (%.1f)", m_fireModes[m_fireMode].first.c_str(), m_fireModes[m_fireMode].second); ray_hit rayhit; int hits = 0; unsigned int flags = rwi_stop_at_pierceable|rwi_colltype_any; if (m_fireModes[m_fireMode].first == "pierceability") { flags = (unsigned int)m_fireModes[m_fireMode].second & rwi_pierceability_mask; } // use cam, no need for firing pos/dir CCamera& cam = GetISystem()->GetViewCamera(); if (hits = gEnv->pPhysicalWorld->RayWorldIntersection(cam.GetPosition()+cam.GetViewdir(), cam.GetViewdir()*HIT_RANGE, ent_all, flags, &rayhit, 1)) { IMaterialManager* pMatMan = gEnv->p3DEngine->GetMaterialManager(); IActorSystem* pActorSystem = g_pGame->GetIGameFramework()->GetIActorSystem(); IVehicleSystem* pVehicleSystem = g_pGame->GetIGameFramework()->GetIVehicleSystem(); int x = (int)(pRenderer->GetWidth() *0.5f) + dx; int y = (int)(pRenderer->GetHeight()*0.5f) + dx - dy; // draw normal ColorB colNormal(200,0,0,128); Vec3 end = rayhit.pt + 0.75f*rayhit.n; pAuxGeom->DrawLine(rayhit.pt, colNormal, end, colNormal); pAuxGeom->DrawCone(end, rayhit.n, 0.1f, 0.2f, colNormal); IEntity * pEntity = (IEntity*)rayhit.pCollider->GetForeignData(PHYS_FOREIGN_ID_ENTITY); if(pEntity) { pRenderer->Draw2dLabel(x, y+=dy, fontLarge, drawColor, false, pEntity->GetName()); } // material const char* matName = pMatMan->GetSurfaceType(rayhit.surface_idx)->GetName(); if (matName[0]) pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%s (%i)", matName, rayhit.surface_idx); pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%.1f m", rayhit.dist); if (pEntity) { IScriptTable* pScriptTable = pEntity->GetScriptTable(); // physics if (IPhysicalEntity* pPhysEnt = pEntity->GetPhysics()) { pe_status_dynamics status; if (pPhysEnt->GetStatus(&status)) { if (status.mass > 0.f) pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%.1f kg", status.mass); pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "pe_type: %i", pPhysEnt->GetType()); if (status.submergedFraction > 0.f) pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%.2f submerged", status.submergedFraction); if (status.v.len2() > 0.0001f) pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%.2f m/s", status.v.len()); } } if (pScriptTable) { HSCRIPTFUNCTION func = 0; if (pScriptTable->GetValue("GetFrozenAmount", func) && func) { float frozen = 0.f; Script::CallReturn(gEnv->pScriptSystem, func, pScriptTable, frozen); if (frozen > 0.f) pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "Frozen: %.2f", frozen); } } // class-specific stuff if (IActor* pActor = pActorSystem->GetActor(pEntity->GetId())) { pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%i health", pActor->GetHealth()); } else if (IVehicle* pVehicle = pVehicleSystem->GetVehicle(pEntity->GetId())) { const SVehicleStatus& status = pVehicle->GetStatus(); pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%.0f%% health", 100.f*status.health); pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%i passengers", status.passengerCount); if (pVehicle->GetMovement() && pVehicle->GetMovement()->IsPowered()) { pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "Running"); } } else { if (pScriptTable) { HSCRIPTFUNCTION func = 0; if (pScriptTable->GetValue("GetHealth", func) && func) { float health = 0.f; if (Script::CallReturn(gEnv->pScriptSystem, func, pScriptTable, health)) { pRenderer->Draw2dLabel(x, y+=dy, font, drawColor, false, "%.0f health", health); } } } } } } }
//------------------------------------------------------------------------ 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); } } }
virtual void ProcessEvent( EFlowEvent event,SActivationInfo *pActInfo ) { IVehicleSystem * pVehicleSystem = NULL; IVehicle * pVehicle = NULL; switch(event) { case eFE_Initialize: { pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, false); break; } case eFE_Activate: { if (!pActInfo->pEntity) return; pVehicleSystem = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem(); pVehicle = pVehicleSystem->GetVehicle(pActInfo->pEntity->GetId()); if (!pVehicleSystem || !pVehicle) return; string givenString = GetPortString(pActInfo, IN_PARTS); currentParam = givenString.substr(0,givenString.find_first_of(":")); currentSetting = givenString.substr(givenString.find_first_of(":")+1,(givenString.length()-givenString.find_first_of(":"))); column1 = 10.f; column2 = 100.f; if (IsPortActive(pActInfo,IN_SHOW)) pActInfo->pGraph->SetRegularlyUpdated(pActInfo->myID, true); break; } case eFE_Update: { IRenderer * pRenderer = gEnv->pRenderer; pVehicleSystem = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem(); pVehicle = pVehicleSystem->GetVehicle(pActInfo->pEntity->GetId()); if(!pVehicleSystem || !pActInfo->pEntity || !pVehicle) return; pRenderer->Draw2dLabel(column1,10,GetPortFloat(pActInfo,IN_SIZE)+2.f,Col_Cyan,false,pActInfo->pEntity->GetName()); if(currentParam=="Seats") { loops = 0; for(uint32 i=0;i<pVehicle->GetSeatCount();i++) { IVehicleSeat * currentSeat; if(currentSetting=="All") { currentSeat = pVehicle->GetSeatById(i+1); } else { currentSeat = pVehicle->GetSeatById(pVehicle->GetSeatId(currentSetting)); i = pVehicle->GetSeatCount()-1; } loops += 1; // column 1 string pMessage = ("%s:", currentSeat->GetSeatName()); if (column2<pMessage.size()*8*GetPortFloat(pActInfo, IN_SIZE)) column2=pMessage.size()*8*GetPortFloat(pActInfo, IN_SIZE); pRenderer->Draw2dLabel(column1,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),Col_Cyan,false,pMessage); // column 2 if(currentSeat->GetPassenger(true)) { pMessage = ("- %s", gEnv->pEntitySystem->GetEntity(currentSeat->GetPassenger(true))->GetName()); pRenderer->Draw2dLabel(column2,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),Col_Cyan,false,pMessage); } } } else if(currentParam=="Wheels") { pRenderer->Draw2dLabel(column1,50.f,GetPortFloat(pActInfo,IN_SIZE)+1.f,Col_Red,false,"!"); } else if(currentParam=="Weapons") { loops = 0; for(int i=0;i<pVehicle->GetWeaponCount();i++) { IItemSystem * pItemSystem = gEnv->pGame->GetIGameFramework()->GetIItemSystem(); IWeapon * currentWeapon; EntityId currentEntityId; IItem * pItem; if(currentSetting=="All") { currentEntityId = pVehicle->GetWeaponId(i+1); } else { currentEntityId = gEnv->pEntitySystem->FindEntityByName(currentSetting)->GetId(); i = pVehicle->GetWeaponCount()-1; } if(!pItemSystem->GetItem(currentEntityId)) return; pItem = pItemSystem->GetItem(currentEntityId); currentWeapon = pItem->GetIWeapon(); loops += 1; // column 1 string pMessageName = string().Format("%s", gEnv->pEntitySystem->GetEntity(currentEntityId)->GetName()); pRenderer->Draw2dLabel(column1,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),Col_Cyan,false,pMessageName); if (column2<pMessageName.size()*8*GetPortFloat(pActInfo, IN_SIZE)) column2=pMessageName.size()*8*GetPortFloat(pActInfo, IN_SIZE); // column 2 string pMessageValue = string().Format("seat: %s firemode: %i", pVehicle->GetWeaponParentSeat(currentEntityId)->GetSeatName(), currentWeapon->GetCurrentFireMode()).c_str(); pRenderer->Draw2dLabel(column2,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),Col_Cyan,false,pMessageValue); } } else if(currentParam=="Components") { loops = 0; for(int i=0;i<pVehicle->GetComponentCount();i++) { IVehicleComponent * currentComponent; if(currentSetting=="All") { currentComponent = pVehicle->GetComponent(i); } else { currentComponent = pVehicle->GetComponent(currentSetting); i = pVehicle->GetComponentCount()-1; } loops += 1; ColorF labelColor; labelColor = ColorF(currentComponent->GetDamageRatio(),(1.f-currentComponent->GetDamageRatio()),0.f); // column 1 string pMessageName = string().Format("%s", currentComponent->GetComponentName()).c_str(); pRenderer->Draw2dLabel(column1,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),labelColor,false,pMessageName); if (column2<pMessageName.size()*8*GetPortFloat(pActInfo, IN_SIZE)) column2=pMessageName.size()*8*GetPortFloat(pActInfo, IN_SIZE); // column 2 string pMessageValue = string().Format("%5.2f (%3.2f)", currentComponent->GetDamageRatio()*currentComponent->GetMaxDamage(), currentComponent->GetDamageRatio()).c_str(); pRenderer->Draw2dLabel(column2,(15*(float(loops+1))*GetPortFloat(pActInfo,IN_SIZE)),GetPortFloat(pActInfo,IN_SIZE),labelColor,false,pMessageValue); } } else { pRenderer->Draw2dLabel(column1,50.f,GetPortFloat(pActInfo,IN_SIZE)+1.f,Col_Red,false,"no component selected!"); } break; } } };
void CTornado::UpdateFlow() { IVehicleSystem* pVehicleSystem = g_pGame->GetIGameFramework()->GetIVehicleSystem(); assert(pVehicleSystem); float frameTime(gEnv->pTimer->GetFrameTime()); IPhysicalWorld *ppWorld = gEnv->pPhysicalWorld; Vec3 pos(GetEntity()->GetWorldPos()); //first, check the entities in range m_nextEntitiesCheck -= frameTime; if (m_nextEntitiesCheck<0.0f) { m_nextEntitiesCheck = 1.0f; Vec3 radiusVec(m_radius,m_radius,0); IPhysicalEntity **ppList = NULL; int numEnts = ppWorld->GetEntitiesInBox(pos-radiusVec,pos+radiusVec+Vec3(0,0,m_cloudHeight*0.5f),ppList,ent_sleeping_rigid|ent_rigid|ent_living); m_spinningEnts.clear(); for (int i=0;i<numEnts;++i) { // add check for spectating players... EntityId id = ppWorld->GetPhysicalEntityId(ppList[i]); CActor* pActor = static_cast<CActor*>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(id)); if(!pActor || !pActor->GetSpectatorMode()) { m_spinningEnts.push_back(id); } } //OutputDistance(); } //mess entities around for (size_t i=0;i<m_spinningEnts.size();++i) { IPhysicalEntity *ppEnt = ppWorld->GetPhysicalEntityById(m_spinningEnts[i]); if (ppEnt) { pe_status_pos spos; pe_status_dynamics sdyn; if (!ppEnt->GetStatus(&spos) || !ppEnt->GetStatus(&sdyn)) continue; //gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(spos.pos,2.0f,ColorB(255,0,255,255)); Vec3 delta(pos - spos.pos); delta.z = 0.0f; float dLen(delta.len()); float forceMult(max(0.0f,(m_radius-dLen)/m_radius)); if (dLen>0.001f) delta /= dLen; else delta.zero(); Vec3 upVector(0,0,1); float spinImpulse(m_spinImpulse); float attractionImpulse(m_attractionImpulse); float upImpulse(m_upImpulse); if (ppEnt->GetType() == PE_LIVING) { upImpulse *= 0.75f; attractionImpulse *= 0.35f; spinImpulse *= 1.5f; } if (IVehicle* pVehicle = pVehicleSystem->GetVehicle(m_spinningEnts[i])) { IVehicleMovement* pMovement = pVehicle->GetMovement(); if (pMovement && pMovement->GetMovementType() == IVehicleMovement::eVMT_Air) { SVehicleMovementEventParams params; params.fValue = forceMult; pMovement->OnEvent(IVehicleMovement::eVME_Turbulence, params); } } Vec3 spinForce( (delta % upVector) * spinImpulse ); Vec3 attractionForce(delta * attractionImpulse); Vec3 upForce(0,0,upImpulse); pe_action_impulse aimpulse; aimpulse.impulse = (spinForce + attractionForce + upForce) * (forceMult * sdyn.mass * frameTime); aimpulse.angImpulse = (upVector + (delta % upVector)) * (gf_PI * 0.33f * forceMult * sdyn.mass * frameTime); aimpulse.iApplyTime = 0; ppEnt->Action(&aimpulse); //gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(spos.pos,ColorB(255,0,255,255),spos.pos+aimpulse.impulse.GetNormalizedSafe(ZERO),ColorB(255,0,255,255)); } } }
//------------------------------------------------------------------------ bool CVehicleDamagesGroup::ParseDamagesGroup(const CVehicleParams& table) { if (table.haveAttr("useTemplate")) { IVehicleSystem* pVehicleSystem = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem(); CRY_ASSERT(pVehicleSystem); if (IVehicleDamagesTemplateRegistry* pDamageTemplReg = pVehicleSystem->GetDamagesTemplateRegistry()) pDamageTemplReg->UseTemplate(table.getAttr("useTemplate"), this); } if (CVehicleParams damagesSubGroupsTable = table.findChild("DamagesSubGroups")) { int i = 0; int c = damagesSubGroupsTable.getChildCount(); for (; i < c; i++) { if (CVehicleParams groupTable = damagesSubGroupsTable.getChild(i)) { m_damageSubGroups.resize(m_damageSubGroups.size() + 1); SDamagesSubGroup& subGroup = m_damageSubGroups.back(); subGroup.id = m_damageSubGroups.size() - 1; subGroup.m_isAlreadyInProcess = false; if (!groupTable.getAttr("delay", subGroup.m_delay)) subGroup.m_delay = 0.0f; if (!groupTable.getAttr("randomness", subGroup.m_randomness)) subGroup.m_randomness = 0.0f; if (CVehicleParams damageBehaviorsTable = groupTable.findChild("DamageBehaviors")) { int k = 0; int numDamageBehaviors = damageBehaviorsTable.getChildCount(); subGroup.m_damageBehaviors.reserve(c); for (; k < numDamageBehaviors; k++) { if (CVehicleParams behaviorTable = damageBehaviorsTable.getChild(k)) { if (IVehicleDamageBehavior* pDamageBehavior = ParseDamageBehavior(behaviorTable)) { subGroup.m_damageBehaviors.push_back(pDamageBehavior); CVehicleDamageBehaviorDestroy *pDamageDestroy = CAST_VEHICLEOBJECT(CVehicleDamageBehaviorDestroy, pDamageBehavior); if (pDamageDestroy) { TVehiclePartVector& parts = m_pVehicle->GetParts(); for (TVehiclePartVector::iterator ite = parts.begin(); ite != parts.end(); ++ite) { IVehiclePart* pPart = ite->second; if (CVehiclePartAnimatedJoint* pAnimJoint = CAST_VEHICLEOBJECT(CVehiclePartAnimatedJoint, pPart)) { if (pAnimJoint->IsPhysicalized() && !pAnimJoint->GetDetachBaseForce().IsZero()) { CVehicleDamageBehaviorDetachPart* pDetachBehavior = new CVehicleDamageBehaviorDetachPart; pDetachBehavior->Init(m_pVehicle, pAnimJoint->GetName(), pDamageDestroy->GetEffectName()); subGroup.m_damageBehaviors.push_back(pDetachBehavior); } } } } } } } } } } } return true; }
//------------------------------------------------------------------------ void CGameRules::ClientExplosion(const ExplosionInfo &explosionInfo) { 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))); } } if(!gEnv->bMultiplayer && g_pGameCVars->g_spRecordGameplay) { float distance = (explosion.epicenter-pClientActor->GetEntity()->GetWorldPos()).len(); m_pGameplayRecorder->Event(pClientActor->GetEntity(), GameplayEvent(eGE_Explosion, 0, distance, 0)); } // 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 CHUDTagNames::Update() { CActor *pClientActor = static_cast<CActor *>(g_pGame->GetIGameFramework()->GetClientActor()); CGameRules *pGameRules = g_pGame->GetGameRules(); if(!pClientActor || !pGameRules || !gEnv->bMultiplayer) return; int iClientTeam = pGameRules->GetTeam(pClientActor->GetEntityId()); // Skip enemies, they need to be added only when shot // (except in spectator mode when we display everyone) for(int iTeam = 0; iTeam < pGameRules->GetTeamCount() + 1; ++iTeam) { if((iTeam == iClientTeam) || (pClientActor->GetSpectatorMode() != CActor::eASM_None)) { int iTeamPlayerCount = pGameRules->GetTeamPlayerCount(iTeam); for(int iPlayer=0; iPlayer<iTeamPlayerCount; iPlayer++) { IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pGameRules->GetTeamPlayer(iTeam,iPlayer)); if(!pActor) continue; // Never display the local player if(pActor == pClientActor) continue; // never display other spectators if(static_cast<CActor*>(pActor)->GetSpectatorMode() != CActor::eASM_None) continue; // never display the name of the player we're spectating (it's shown separately with their current health) if(pClientActor->GetSpectatorMode() == CActor::eASM_Follow && pClientActor->GetSpectatorTarget() == pActor->GetEntityId()) continue; DrawTagName(pActor); } } } IVehicleSystem *pVehicleSystem = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem(); if(!pVehicleSystem) return; IVehicleIteratorPtr pVehicleIter = pVehicleSystem->CreateVehicleIterator(); while(IVehicle *pVehicle=pVehicleIter->Next()) { SVehicleStatus rVehicleStatus = pVehicle->GetStatus(); if(0 == rVehicleStatus.passengerCount) continue; // Skip enemy vehicles, they need to be added only when shot (except in spectator mode...) bool bEnemyVehicle = true; for(int iSeatId=1; iSeatId<=pVehicle->GetLastSeatId(); iSeatId++) { IVehicleSeat *pVehicleSeat = pVehicle->GetSeatById(iSeatId); if(!pVehicleSeat) continue; EntityId uiEntityId = pVehicleSeat->GetPassenger(); if(0 == iClientTeam) { if(uiEntityId && IsFriendlyToClient(uiEntityId)) { bEnemyVehicle = false; } } else if(uiEntityId && pGameRules->GetTeam(uiEntityId) == iClientTeam) { bEnemyVehicle = false; } } if(bEnemyVehicle && (pClientActor->GetSpectatorMode() == CActor::eASM_None)) // again, draw enemies in spectator mode continue; DrawTagName(pVehicle); } // don't need to do any of this if we're in spectator mode - all player names will have been drawn above. if(pClientActor->GetSpectatorMode() == CActor::eASM_None) { for(TEnemyTagNamesList::iterator iter=m_enemyTagNamesList.begin(); iter!=m_enemyTagNamesList.end(); ++iter) { SEnemyTagName *pEnemyTagName = &(*iter); if(gEnv->pTimer->GetAsyncTime().GetSeconds() >= pEnemyTagName->fSpawnTime+((float) g_pGameCVars->hud_mpNamesDuration)) { // Note: iter=my_list.erase(iter) may not be standard/safe TEnemyTagNamesList::iterator iterNext = iter; ++iterNext; m_enemyTagNamesList.erase(iter); iter = iterNext; } else { IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pEnemyTagName->uiEntityId); if(pActor) DrawTagName(pActor); IVehicle *pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(pEnemyTagName->uiEntityId); if(pVehicle) DrawTagName(pVehicle); } } } }