void CProjectile::FlashbangEffect(const SFlashbangParams *flashbang) { if(!flashbang) return; const float radius = flashbang->maxRadius; if(!gEnv->pAISystem) return; // Associate event with vehicle if the shooter is in a vehicle (tank cannon shot, etc) EntityId ownerId = m_ownerId; IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(ownerId); if(pActor && pActor->GetLinkedVehicle() && pActor->GetLinkedVehicle()->GetEntityId()) ownerId = pActor->GetLinkedVehicle()->GetEntityId(); SAIStimulus stim(AISTIM_GRENADE, AIGRENADE_FLASH_BANG, ownerId, GetEntityId(), GetEntity()->GetWorldPos(), ZERO, radius); gEnv->pAISystem->RegisterStimulus(stim); SAIStimulus stimSound(AISTIM_SOUND, AISOUND_WEAPON, ownerId, 0, GetEntity()->GetWorldPos(), ZERO, radius * 3.0f); gEnv->pAISystem->RegisterStimulus(stimSound); }
void CSmokeManager::CreateNewSmokeInstance(EntityId grenadeId, EntityId grenadeOwnerId, float fMaxRadius) { IEntity * pGrenade = gEnv->pEntitySystem->GetEntity(grenadeId); int iNewSmokeInstanceIndex = m_numActiveSmokeInstances; //If all of the smoke instances are used up, get the index of the next one to be deleted // and re-use that instance if(iNewSmokeInstanceIndex >= MAX_SMOKE_INSTANCES) { float fLeastLifeLeft = kSmokeLingerTime; iNewSmokeInstanceIndex = 0; for(int i = 0; i < iNewSmokeInstanceIndex; i++) { SSmokeInstance& smokeInstance = m_smokeInstances[i]; if(smokeInstance.fTimer < fLeastLifeLeft) { iNewSmokeInstanceIndex = i; fLeastLifeLeft=smokeInstance.fTimer; } } } else { m_numActiveSmokeInstances++; } //Fill out the smoke instance with the new data SSmokeInstance& newSmokeInstance = m_smokeInstances[iNewSmokeInstanceIndex]; newSmokeInstance.state = eSIS_Active_PhysicsAwake; newSmokeInstance.vPositon = pGrenade->GetPos(); newSmokeInstance.grenadeId = grenadeId; newSmokeInstance.fMaxRadius = fMaxRadius; newSmokeInstance.fCurrentRadius = 0.1f; newSmokeInstance.fTimer = 0.0f; if (!gEnv->bMultiplayer) { CreateSmokeObstructionObject(newSmokeInstance); if (gEnv->pAISystem) { // Associate event with vehicle if the shooter is in a vehicle (tank cannon shot, etc) EntityId ownerId = grenadeId; IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(ownerId); IVehicle* pVehicle = pActor ? pActor->GetLinkedVehicle() : NULL; if (pVehicle) { ownerId = pVehicle->GetEntityId(); } SAIStimulus stim(AISTIM_GRENADE, AIGRENADE_SMOKE, ownerId, grenadeId, newSmokeInstance.vPositon, ZERO, kMaxSmokeRadius*1.5f); gEnv->pAISystem->RegisterStimulus(stim); } } }
void CClaymore::ProcessEvent(SEntityEvent &event) { if (m_frozen) return; switch(event.event) { case ENTITY_EVENT_ENTERAREA: { IEntity * pEntity = gEnv->pEntitySystem->GetEntity(event.nParam[0]); IVehicle* pVehicle = NULL; IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(event.nParam[0]); // only detonate for actors... if(!pActor) pVehicle = g_pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(event.nParam[0]); // ...or vehicles // ignore actors in vehicles (we detect the vehicle instead) if(pActor && pActor->GetLinkedVehicle()) pActor = NULL; // ignore spectators if(pActor && static_cast<CActor*>(pActor)->GetSpectatorMode() != CActor::eASM_None) pActor = NULL; if(pEntity && (pActor || pVehicle)) { if(g_pGameCVars->g_debugMines != 0) CryLog("Claymore detected entity: %d, type %s", pEntity->GetId(), pActor == NULL ? "Vehicle" : "Actor"); m_targetList.push_back(pEntity->GetId()); } break; } case ENTITY_EVENT_LEAVEAREA: { IEntity * pEntity = gEnv->pEntitySystem->GetEntity(event.nParam[0]); if(pEntity) { std::list<EntityId>::iterator it = std::find(m_targetList.begin(), m_targetList.end(), pEntity->GetId()); if(it != m_targetList.end()) m_targetList.erase(it); } break; } default: break; } return CProjectile::ProcessEvent(event); }
//------------------------------------------------------------------------ void CFlowVehiclePassenger::ProcessEvent(EFlowEvent flowEvent, SActivationInfo* pActivationInfo) { CFlowVehicleBase::ProcessEvent(flowEvent, pActivationInfo); if (flowEvent == eFE_Activate) { m_actorId = GetPortEntityId(pActivationInfo, IN_ACTORID); m_seatId = GetPortInt(pActivationInfo, IN_SEATID); if (IVehicle* pVehicle = GetVehicle()) { if (IsPortActive(pActivationInfo, IN_TRIGGERPASSENGERIN)) { if (m_actorId && m_seatId > 0) { IActor* pActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_actorId); if (pActor) { IVehicle* pCurrent = pActor->GetLinkedVehicle(); if (pCurrent && pCurrent != pVehicle) { if (IVehicleSeat* pSeat = pCurrent->GetSeatForPassenger(m_actorId)) pSeat->Exit(false, true); } if (pCurrent == pVehicle && pCurrent->GetSeatForPassenger(m_actorId)) { ((CVehicle*)pVehicle)->ChangeSeat(m_actorId, 0, m_seatId); } else { if (IVehicleSeat* pSeat = pVehicle->GetSeatById(m_seatId)) pSeat->Enter(m_actorId); } } } } if (IsPortActive(pActivationInfo, IN_TRIGGERPASSENGEROUT)) { if (m_actorId) { if (IVehicleSeat* pSeat = pVehicle->GetSeatForPassenger(m_actorId)) pSeat->Exit(true); } } } } }
//----------------------------------------------------------------------- void CVehiclePartLight::UpdateLight(const float frameTime) { if (m_slot == -1) return; // move to vehicle event change view? if (m_diffuseMult[0] != m_diffuseMult[1]) { SEntitySlotInfo info; if (m_pVehicle->GetEntity()->GetSlotInfo(m_slot, info) && info.pLight) { CDLight& light = info.pLight->GetLightProperties(); IActor* pActor = CCryAction::GetCryAction()->GetClientActor(); bool localPlayer = (pActor != NULL) && (pActor->GetLinkedVehicle() == m_pVehicle); IVehicleSeat* pSeat = pActor ? m_pVehicle->GetSeatForPassenger(pActor->GetEntityId()) : NULL; IVehicleView* pView = pSeat? pSeat->GetView(pSeat->GetCurrentView()) : NULL; bool isThirdPersonView = pView? pView->IsThirdPerson() : true; if (localPlayer && !isThirdPersonView) light.SetLightColor(ColorF(m_diffuseCol * m_diffuseMult[0], 1.f)); else light.SetLightColor(ColorF(m_diffuseCol * m_diffuseMult[1], 1.f)); } } if (m_pHelper) { const static Matrix33 rot(Matrix33::CreateRotationXYZ(Ang3(0.f, 0.f, DEG2RAD(90.f)))); Matrix34 helperTM; m_pHelper->GetVehicleTM(helperTM); Matrix34 localTM = Matrix33(helperTM) * rot; localTM.SetTranslation(helperTM.GetTranslation()); GetEntity()->SetSlotLocalTM(m_slot, localTM); } }
//---------------------------------------------------------------------- IView* GetView( SActivationInfo* pActInfo ) { SInputParams inputParams; ReadCurrentInputParams( pActInfo, inputParams ); IGameFramework* pGF = gEnv->pGame->GetIGameFramework(); IView* pView = 0; IView* pActiveView = pGF->GetIViewSystem()->GetActiveView(); eViewType viewType = inputParams.view; if (viewType == VT_FirstPerson) // use player's view { IActor* pActor = pGF->GetClientActor(); if (pActor == 0) return NULL; eRestriction restriction = inputParams.restriction; if (restriction != ER_None) { IVehicle* pVehicle = pActor->GetLinkedVehicle(); if (restriction == ER_InVehicle && pVehicle == 0) return NULL; if (restriction == ER_NoVehicle && pVehicle != 0 /* && pVehicle->GetSeatForPassenger(entityId) != 0 */) return NULL; } EntityId entityId = pActor->GetEntityId(); pView = pGF->GetIViewSystem()->GetViewByEntityId(entityId); } else // active view { pView = pActiveView; } if (pView != pActiveView) return NULL; return pView; }
//------------------------------------------------------------------------ void CProjectile::Launch(const Vec3 &pos, const Vec3 &dir, const Vec3 &velocity, float speedScale) { m_destroying = false; GetGameObject()->EnablePhysicsEvent(true, eEPE_OnCollisionLogged); // Only for bullets m_hitPoints = m_pAmmoParams->hitPoints; m_hitListener = false; if(m_hitPoints>0) { //Only projectiles with hit points are hit listeners g_pGame->GetGameRules()->AddHitListener(this); m_hitListener = true; m_noBulletHits = m_pAmmoParams->noBulletHits; } Matrix34 worldTM=Matrix34(Matrix33::CreateRotationVDir(dir.GetNormalizedSafe())); worldTM.SetTranslation(pos); GetEntity()->SetWorldTM(worldTM); //Must set velocity after position, if not velocity could be reseted for PE_RIGID SetVelocity(pos, dir, velocity, speedScale); m_initial_pos = pos; m_initial_dir = dir; m_initial_vel = velocity; m_last = pos; // Attach effect when fired (not first update) if(m_trailEffectId<0) TrailEffect(true); IAIObject *pAI = 0; if((pAI = GetEntity()->GetAI()) != NULL && pAI->GetAIType() == AIOBJECT_GRENADE) { IEntity *pOwnerEntity = gEnv->pEntitySystem->GetEntity(m_ownerId); pe_status_dynamics dyn; pe_status_dynamics dynProj; if(pOwnerEntity->GetPhysics() && pOwnerEntity->GetPhysics()->GetStatus(&dyn) && GetEntity()->GetPhysics()->GetStatus(&dynProj)) { // Vec3 ownerVel(dyn.v); Vec3 grenadeDir(dynProj.v.GetNormalizedSafe()); // Trigger the signal at the predicted landing position. Vec3 predictedPos = pos; float dummySpeed; if(GetWeapon()) GetWeapon()->PredictProjectileHit(pOwnerEntity->GetPhysics(), pos, dir, velocity, speedScale * m_pAmmoParams->speed, predictedPos, dummySpeed); // Associate event with vehicle if the shooter is in a vehicle (tank cannon shot, etc) EntityId ownerId = pOwnerEntity->GetId(); IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(ownerId); if(pActor && pActor->GetLinkedVehicle() && pActor->GetLinkedVehicle()->GetEntityId()) ownerId = pActor->GetLinkedVehicle()->GetEntityId(); SAIStimulus stim(AISTIM_GRENADE, AIGRENADE_THROWN, ownerId, GetEntityId(), predictedPos, ZERO, 20.0f); gEnv->pAISystem->RegisterStimulus(stim); } } }
//------------------------------------------------------------------------ void CProjectile::HandleEvent(const SGameObjectEvent &event) { if(m_destroying) return; FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); if(event.event == eGFE_OnCollision) { EventPhysCollision *pCollision = (EventPhysCollision *)event.ptr; if(pCollision == NULL) return; const SCollisionParams *pCollisionParams = m_pAmmoParams->pCollision; if(pCollisionParams) { if(pCollisionParams->pParticleEffect) pCollisionParams->pParticleEffect->Spawn(true, IParticleEffect::ParticleLoc(pCollision->pt, pCollision->n, pCollisionParams->scale)); if(pCollisionParams->sound) { _smart_ptr<ISound> pSound = gEnv->pSoundSystem->CreateSound(pCollisionParams->sound, FLAG_SOUND_DEFAULT_3D); if(pSound) { pSound->SetSemantic(eSoundSemantic_Projectile); pSound->SetPosition(pCollision->pt); pSound->Play(); } } } // add battledust for bulletimpact if(gEnv->bServer && g_pGame->GetGameRules()) { if(CBattleDust *pBD = g_pGame->GetGameRules()->GetBattleDust()) { pBD->RecordEvent(eBDET_ShotImpact, pCollision->pt, GetEntity()->GetClass()); } } Ricochet(pCollision); //Update damage if((m_damageDropPerMeter>0.0001f)&& (((pCollision->pt-m_initial_pos).len2()>m_damageDropMinDisSqr)||m_firstDropApplied)) { if(!m_firstDropApplied) { m_firstDropApplied = true; m_initial_pos = m_initial_pos + (m_initial_dir*(sqrt_fast_tpl(m_damageDropMinDisSqr))); } Vec3 vDiff = pCollision->pt - m_initial_pos; float dis = vDiff.len(); m_damage -= (int)(floor_tpl(m_damageDropPerMeter * dis)); //Check m_damage is positive if(m_damage<MIN_DAMAGE) m_damage=MIN_DAMAGE; //Also modify initial position (the projectile could not be destroyed, cause of pirceability) m_initial_pos = pCollision->pt; } // Notify AI system about grenades. if(gEnv->pAISystem) { IAIObject *pAI = 0; if((pAI = GetEntity()->GetAI()) != NULL && pAI->GetAIType() == AIOBJECT_GRENADE) { // Associate event with vehicle if the shooter is in a vehicle (tank cannon shot, etc) EntityId ownerId = m_ownerId; IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(ownerId); if(pActor && pActor->GetLinkedVehicle() && pActor->GetLinkedVehicle()->GetEntityId()) ownerId = pActor->GetLinkedVehicle()->GetEntityId(); SAIStimulus stim(AISTIM_GRENADE, AIGRENADE_COLLISION, ownerId, GetEntityId(), GetEntity()->GetWorldPos(), ZERO, 12.0f); gEnv->pAISystem->RegisterStimulus(stim); } } } }
//------------------------------------------------------------------------ void CProjectile::ScaledEffect(const SScaledEffectParams *pScaledEffect) { if(!pScaledEffect) return; float lifetime = m_pAmmoParams->lifetime; IActor *local = gEnv->pGame->GetIGameFramework()->GetClientActor(); if(local) { float dist = (GetEntity()->GetWorldPos() - local->GetEntity()->GetWorldPos()).len(); if(m_totalLifetime < pScaledEffect->delay || pScaledEffect->radius == 0.0f) return; float fadeInAmt = 1.0f; float fadeOutAmt = 1.0f; if(pScaledEffect->fadeInTime > 0.0f) { fadeInAmt = (m_totalLifetime - pScaledEffect->delay) / pScaledEffect->fadeInTime; fadeInAmt = min(fadeInAmt, 1.0f); fadeOutAmt = 1.0f - (m_totalLifetime - (lifetime - pScaledEffect->fadeOutTime)) / pScaledEffect->fadeOutTime; fadeOutAmt = max(fadeOutAmt, 0.0f); } if(!m_obstructObject && pScaledEffect->aiObstructionRadius != 0.0f) { pe_params_pos pos; pos.scale = 0.1f; pos.pos = GetEntity()->GetWorldPos() + Vec3(0,0,pScaledEffect->aiObstructionRadius/4 * pos.scale); m_obstructObject = gEnv->pPhysicalWorld->CreatePhysicalEntity(PE_STATIC, &pos); if(m_obstructObject) { primitives::sphere sphere; sphere.center = Vec3(0,0,0); sphere.r = pScaledEffect->aiObstructionRadius; int obstructID = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceTypeIdByName("mat_obstruct"); IGeometry *pGeom = gEnv->pPhysicalWorld->GetGeomManager()->CreatePrimitive(primitives::sphere::type, &sphere); phys_geometry *geometry = gEnv->pPhysicalWorld->GetGeomManager()->RegisterGeometry(pGeom, obstructID); pe_geomparams params; params.flags = geom_colltype14; geometry->nRefCount = 0; // automatically delete geometry m_obstructObject->AddGeometry(geometry, ¶ms); } } else { pe_params_pos pos; pos.scale = 0.1f + min(fadeInAmt, fadeOutAmt) * 0.9f; pos.pos = GetEntity()->GetWorldPos() + Vec3(0,0, pScaledEffect->aiObstructionRadius/4.0f * pos.scale); m_obstructObject->SetParams(&pos); // Signal the AI if(gEnv->pAISystem && !m_scaledEffectSignaled && m_totalLifetime > (pScaledEffect->delay + pScaledEffect->fadeInTime)) { m_scaledEffectSignaled = true; // Associate event with vehicle if the shooter is in a vehicle (tank cannon shot, etc) EntityId ownerId = m_ownerId; IActor *pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(ownerId); if(pActor && pActor->GetLinkedVehicle() && pActor->GetLinkedVehicle()->GetEntityId()) ownerId = pActor->GetLinkedVehicle()->GetEntityId(); SAIStimulus stim(AISTIM_GRENADE, AIGRENADE_SMOKE, ownerId, GetEntityId(), pos.pos, ZERO, pScaledEffect->aiObstructionRadius*1.5f); gEnv->pAISystem->RegisterStimulus(stim); } } if(dist > pScaledEffect->radius) { gEnv->p3DEngine->SetPostEffectParam(pScaledEffect->ppname, 0.0f); return; } float effectAmt = 1.0f - (dist / pScaledEffect->radius); effectAmt = max(effectAmt, 0.0f); float effectVal = effectAmt * pScaledEffect->maxValue; effectVal *= fadeInAmt; m_scaledEffectval = effectVal; gEnv->p3DEngine->SetPostEffectParam(pScaledEffect->ppname, effectVal); } }
//------------------------------------------ void CC4Projectile::HandleEvent(const SGameObjectEvent &event) { if (CheckAnyProjectileFlags(ePFlag_destroying)) return; CProjectile::HandleEvent(event); if (event.event == eGFE_OnCollision) { EventPhysCollision *pCollision = (EventPhysCollision *)event.ptr; if(pCollision && pCollision->pEntity[0]->GetType()==PE_PARTICLE) { float bouncy, friction; uint32 pierceabilityMat; gEnv->pPhysicalWorld->GetSurfaceParameters(pCollision->idmat[1], bouncy, friction, pierceabilityMat); pierceabilityMat &= sf_pierceable_mask; uint32 pierceabilityProj = GetAmmoParams().pParticleParams ? GetAmmoParams().pParticleParams->iPierceability : 13; if (pierceabilityMat > pierceabilityProj) return; if(gEnv->bMultiplayer) { // Don't stick to weapons. if(pCollision->iForeignData[1]==PHYS_FOREIGN_ID_ENTITY) { if(IEntity* pEntity = (IEntity*)pCollision->pForeignData[1]) { if(IItem* pItem = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(pEntity->GetId())) { if(pItem->GetIWeapon()) { return; } } } } } // Notify AI system about the C4. if (gEnv->pAISystem) { // Associate event with vehicle if the shooter is in a vehicle (tank cannon shot, etc) EntityId ownerId = m_ownerId; IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(ownerId); if (pActor && pActor->GetLinkedVehicle() && pActor->GetLinkedVehicle()->GetEntityId()) ownerId = pActor->GetLinkedVehicle()->GetEntityId(); SAIStimulus stim(AISTIM_EXPLOSION, 0, ownerId, GetEntityId(), GetEntity()->GetWorldPos(), ZERO, 12.0f, AISTIMPROC_ONLY_IF_VISIBLE); gEnv->pAISystem->RegisterStimulus(stim); SAIStimulus soundStim(AISTIM_SOUND, AISOUND_COLLISION, ownerId, GetEntityId(), GetEntity()->GetWorldPos(), ZERO, 8.0f); gEnv->pAISystem->RegisterStimulus(soundStim); } } if (gEnv->bServer && !m_stickyProjectile.IsStuck()) m_stickyProjectile.Stick( CStickyProjectile::SStickParams(this, pCollision, CStickyProjectile::eO_AlignToSurface)); } }
void CHUDCrosshair::UpdateCrosshair() { IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); if(!pClientActor) return; int iNewFriendly = 0; if(pClientActor->GetLinkedVehicle()) { // JanM/MichaelR: // Get status from the VehicleWeapon, which raycasts considering the necessary SkipEntities (in contrast to WorldQuery) // Julien: this is now done in MP as well iNewFriendly = g_pHUD->GetVehicleInterface()->GetFriendlyFire(); } else { if(!gEnv->bMultiplayer) { CWeapon *pWeapon = g_pHUD->GetCurrentWeapon(); if(pWeapon) { iNewFriendly = pWeapon->IsWeaponLowered() && pWeapon->IsPendingFireRequest(); if(iNewFriendly && pWeapon->GetEntity()->GetClass() == CItem::sTACGunFleetClass) iNewFriendly = 0; } else{ //Two handed pickups need the red X as well CPlayer *pPlayer= static_cast<CPlayer*>(pClientActor); if(CWeapon *pOffHand = static_cast<CWeapon*>(pPlayer->GetItemByClass(CItem::sOffHandClass))) iNewFriendly = pOffHand->IsWeaponLowered(); } } else { EntityId uiCenterId = pClientActor->GetGameObject()->GetWorldQuery()->GetLookAtEntityId(); if(uiCenterId) { iNewFriendly = IsFriendlyEntity(gEnv->pEntitySystem->GetEntity(uiCenterId)); } } } // SNH: if player is carrying a claymore or mine, ask the weapon whether it is possible to place it currently // (takes into account player speed / stance / aim direction). // So 'friendly' is a bit of a misnomer here, but we want the "don't/can't fire" crosshair... if(iNewFriendly != 1 && g_pHUD) { CWeapon *pWeapon = g_pHUD->GetCurrentWeapon(); if(pWeapon) { static IEntityClass* pClaymoreClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("Claymore"); static IEntityClass* pAVMineClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("AVMine"); IEntityClass* pClass = pWeapon->GetEntity()->GetClass(); if(pClass == pClaymoreClass || pClass == pAVMineClass) { if(IFireMode* pfm = pWeapon->GetFireMode(pWeapon->GetCurrentFireMode())) { if(!pfm->IsFiring()) iNewFriendly = pWeapon->CanFire() ? 0 : 1; } } } } if(iNewFriendly != m_iFriendlyTarget) { m_iFriendlyTarget = iNewFriendly; //m_animCrossHair.Invoke("setFriendly", m_iFriendlyTarget); if(iNewFriendly) m_animFriendCross.SetVisible(true); else m_animFriendCross.SetVisible(false); } if(m_animInterActiveIcons.GetVisible()) { m_bHideUseIconTemp = false; CItem *pItem = static_cast<CItem*>(pClientActor->GetCurrentItem()); if(pItem) { IWeapon *pWeapon = pItem->GetIWeapon(); if(pWeapon) { CItem::SStats stats = pItem->GetStats(); if(stats.mounted && stats.used) m_bHideUseIconTemp = true; } } if(!m_bHideUseIconTemp) { EntityId offHandId = pClientActor->GetInventory()->GetItemByClass(CItem::sOffHandClass); IItem *pOffHandItem = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(offHandId); if(pOffHandItem) { COffHand *pOffHand = static_cast<COffHand*>(pOffHandItem); uint32 offHandState = pOffHand->GetOffHandState(); if(offHandState == eOHS_HOLDING_OBJECT || offHandState == eOHS_THROWING_OBJECT || offHandState == eOHS_HOLDING_NPC || offHandState == eOHS_THROWING_NPC) m_bHideUseIconTemp = true; } } } }
//------------------------------------------------------------------------ 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 CBullet::HandleEvent(const SGameObjectEvent &event) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); CProjectile::HandleEvent(event); if (event.event == eGFE_OnCollision) { if (m_destroying) return; EventPhysCollision *pCollision = reinterpret_cast<EventPhysCollision *>(event.ptr); if (!pCollision) return; IEntity *pTarget = pCollision->iForeignData[1]==PHYS_FOREIGN_ID_ENTITY ? (IEntity*)pCollision->pForeignData[1]:0; //Only process hits that have a target if(pTarget) { Vec3 dir(0, 0, 0); if (pCollision->vloc[0].GetLengthSquared() > 1e-6f) dir = pCollision->vloc[0].GetNormalized(); CGameRules *pGameRules = g_pGame->GetGameRules(); IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_ownerId); bool ok = true; if(!gEnv->bMultiplayer && pActor && pActor->IsPlayer()) { IActor* pAITarget = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTarget->GetId()); if(pAITarget && pTarget->GetAI() && pTarget->GetAI()->IsFriendly(pActor->GetEntity()->GetAI(), false)) { pGameRules->SetEntityToIgnore(pTarget->GetId()); ok = false; } } if(ok) { HitInfo hitInfo(m_ownerId, pTarget->GetId(), m_weaponId, (float)m_damage, 0.0f, pGameRules->GetHitMaterialIdFromSurfaceId(pCollision->idmat[1]), pCollision->partid[1], m_hitTypeId, pCollision->pt, dir, pCollision->n); hitInfo.remote = IsRemote(); hitInfo.projectileId = GetEntityId(); hitInfo.bulletType = m_pAmmoParams->bulletType; pGameRules->ClientHit(hitInfo); // Notify AI if (gEnv->pAISystem && !gEnv->bMultiplayer) { static int htMelee = pGameRules->GetHitTypeId("melee"); if (m_ownerId && m_hitTypeId != htMelee) { ISurfaceType *pSurfaceType = pGameRules->GetHitMaterial(hitInfo.material); const ISurfaceType::SSurfaceTypeAIParams* pParams = pSurfaceType ? pSurfaceType->GetAIParams() : 0; const float radius = pParams ? pParams->fImpactRadius : 2.5f; const float soundRadius = pParams ? pParams->fImpactSoundRadius : 20.0f; // Associate event with vehicle if the shooter is in a vehicle (tank cannon shot, etc) EntityId ownerId = m_ownerId; if (pActor && pActor->GetLinkedVehicle() && pActor->GetLinkedVehicle()->GetEntityId()) ownerId = pActor->GetLinkedVehicle()->GetEntityId(); SAIStimulus stim(AISTIM_BULLET_HIT, 0, ownerId, 0, pCollision->pt, ZERO, radius); gEnv->pAISystem->RegisterStimulus(stim); SAIStimulus stimSound(AISTIM_SOUND, AISOUND_COLLISION_LOUD, ownerId, 0, pCollision->pt, ZERO, soundRadius, AISTIMPROC_FILTER_LINK_WITH_PREVIOUS); gEnv->pAISystem->RegisterStimulus(stimSound); } } } } else { // Notify AI // The above case only catches entity vs. entity hits, the AI is interested in all hits. if (gEnv->pAISystem && !gEnv->bMultiplayer) { CGameRules *pGameRules = g_pGame->GetGameRules(); static int htMelee = pGameRules->GetHitTypeId("melee"); if (m_ownerId && m_hitTypeId != htMelee) { int material = pGameRules->GetHitMaterialIdFromSurfaceId(pCollision->idmat[1]); ISurfaceType *pSurfaceType = pGameRules->GetHitMaterial(material); const ISurfaceType::SSurfaceTypeAIParams* pParams = pSurfaceType ? pSurfaceType->GetAIParams() : 0; const float radius = pParams ? pParams->fImpactRadius : 2.5f; const float soundRadius = pParams ? pParams->fImpactSoundRadius : 20.0f; // Associate event with vehicle if the shooter is in a vehicle (tank cannon shot, etc) EntityId ownerId = m_ownerId; IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_ownerId); if (pActor && pActor->GetLinkedVehicle() && pActor->GetLinkedVehicle()->GetEntityId()) ownerId = pActor->GetLinkedVehicle()->GetEntityId(); SAIStimulus stim(AISTIM_BULLET_HIT, 0, ownerId, 0, pCollision->pt, ZERO, radius); gEnv->pAISystem->RegisterStimulus(stim); SAIStimulus stimSound(AISTIM_SOUND, AISOUND_COLLISION_LOUD, ownerId, 0, pCollision->pt, ZERO, soundRadius, AISTIMPROC_FILTER_LINK_WITH_PREVIOUS); gEnv->pAISystem->RegisterStimulus(stimSound); } } } if (pCollision->pEntity[0]->GetType() == PE_PARTICLE) { float bouncy, friction; uint32 pierceabilityMat; gEnv->pPhysicalWorld->GetSurfaceParameters(pCollision->idmat[1], bouncy, friction, pierceabilityMat); pierceabilityMat&=sf_pierceable_mask; pe_params_particle params; if(pCollision->pEntity[0]->GetParams(¶ms)==0) SetDefaultParticleParams(¶ms); //Under water trail Vec3 pos=pCollision->pt; if ((pCollision->idmat[1] == CBullet::m_waterMaterialId) && (pCollision->pEntity[1]!=gEnv->pPhysicalWorld->AddGlobalArea() || !gEnv->p3DEngine->GetVisAreaFromPos(pos))) { //Reduce drastically bullet velocity (to be able to see the trail effect) //pe_params_particle pparams; //if(m_pPhysicalEntity->GetParams(&pparams)==0) //SetDefaultParticleParams(&pparams); //pparams.velocity = 25.0f; //m_pPhysicalEntity->SetParams(&pparams); if(m_trailUnderWaterId<0) { //Check terrain/against water level float terrainHeight = gEnv->p3DEngine->GetTerrainElevation(pCollision->pt.x,pCollision->pt.y); float waterLevel = gEnv->p3DEngine->GetWaterLevel(&(pCollision->pt)); if(waterLevel>terrainHeight) { TrailEffect(true,true); return; } } } if (pierceabilityMat<=params.iPierceability || pCollision->idCollider==-1) //Do not destroy if collides water Destroy(); } } }
void CFlowNode_AISequenceAction_VehicleRotateTurret::HandleSequenceEvent(AIActionSequence::SequenceEvent sequenceEvent) { switch(sequenceEvent) { case AIActionSequence::StartAction: { if (!m_actInfo.pEntity) { // the entity has gone for some reason, at least make sure the action gets finished properly and the FG continues CancelSequenceAndActivateOutputPort(OutputPort_Done); return; } assert(gEnv && gEnv->pGame && gEnv->pGame->GetIGameFramework() && gEnv->pGame->GetIGameFramework()->GetIActorSystem()); IActor* pActor = gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_actInfo.pEntity->GetId()); // ensure the FG entity is an IActor if (!pActor) { CRY_ASSERT_MESSAGE(0, "no compatible entity was provided"); CryWarning(VALIDATOR_MODULE_AI, VALIDATOR_WARNING, "Actor %s failed to enter vehicle (no compatible entity was provided)", m_actInfo.pEntity->GetName()); CancelSequenceAndActivateOutputPort(OutputPort_Done); return; } // get the vehicle the actor is linked to IVehicle* pVehicle = pActor->GetLinkedVehicle(); if (!pVehicle) { CRY_ASSERT_MESSAGE(0, "agent is not linked to a vehicle"); CryWarning(VALIDATOR_MODULE_AI, VALIDATOR_WARNING, "Actor %s is not linked to a vehicle", m_actInfo.pEntity->GetName()); CancelSequenceAndActivateOutputPort(OutputPort_Done); return; } // get the seat the actor is sitting on CVehicleSeat* pSeat = static_cast<CVehicleSeat*>(pVehicle->GetSeatForPassenger(m_actInfo.pEntity->GetId())); if (!pSeat) { CRY_ASSERT_MESSAGE(0, "agent is not sitting in the vehicle it is linked to"); CryWarning(VALIDATOR_MODULE_AI, VALIDATOR_WARNING, "Actor %s is not sitting in the vehicle it is linked to", m_actInfo.pEntity->GetName()); CancelSequenceAndActivateOutputPort(OutputPort_Done); return; } // scan for the seat-action that allows rotating the turret TVehicleSeatActionVector& seatActions = pSeat->GetSeatActions(); for (TVehicleSeatActionVector::iterator it = seatActions.begin(); it != seatActions.end(); ++it) { IVehicleSeatAction* pSeatAction = it->pSeatAction; if ((m_pActionRotateTurret = CAST_VEHICLEOBJECT(CVehicleSeatActionRotateTurret, pSeatAction))) { break; } } // ensure the vehicle-seat provided the correct action if (!m_pActionRotateTurret) { CRY_ASSERT_MESSAGE(0, "a CVehicleSeatActionRotateTurret is not provided by the vehicle or someone else in the vehicle has reserved that action already."); CryWarning(VALIDATOR_MODULE_AI, VALIDATOR_WARNING, "Actor %s could not find a CVehicleSeatActionRotateTurret or that action is already reserved by someone else", m_actInfo.pEntity->GetName()); CancelSequenceAndActivateOutputPort(OutputPort_Done); return; } m_pitchThreshold = GetPortFloat(&m_actInfo, InputPort_ThresholdPitch); m_yawThreshold = GetPortFloat(&m_actInfo, InputPort_ThresholdYaw); Vec3 aimPos = GetPortVec3(&m_actInfo, InputPort_AimPos); m_pActionRotateTurret->SetAimGoal(aimPos); } break; case AIActionSequence::SequenceStopped: { if (m_pActionRotateTurret) { // cancel the rotation action m_pActionRotateTurret->SetAimGoal(Vec3Constants<float>::fVec3_Zero); m_pActionRotateTurret = NULL; } } break; } }
virtual void ProcessEvent( EFlowEvent event,SActivationInfo* pActInfo ) { if (event != eFE_Activate) return; if (!InputEntityIsLocalPlayer( pActInfo )) return; const bool bTriggered = IsPortActive(pActInfo, EIP_Trigger); const bool bFreqTriggered = IsPortActive(pActInfo, EIP_Frequency); if (bTriggered == false && bFreqTriggered == false) return; IGameFramework* pGF = gEnv->pGame->GetIGameFramework(); IView* pView = 0; IView* pActiveView = pGF->GetIViewSystem()->GetActiveView(); int viewType = GetPortInt(pActInfo, EIP_ViewType); if (viewType == VT_FirstPerson) // use player's view { IActor* pActor = pGF->GetClientActor(); if (pActor == 0) return; const int restriction = GetPortInt(pActInfo, EIP_Restriction); if (restriction != ER_None) { IVehicle* pVehicle = pActor->GetLinkedVehicle(); if (restriction == ER_InVehicle && pVehicle == 0) return; if (restriction == ER_NoVehicle && pVehicle != 0 /* && pVehicle->GetSeatForPassenger(entityId) != 0 */) return; } EntityId entityId = pActor->GetEntityId(); pView = pGF->GetIViewSystem()->GetViewByEntityId(entityId); } else // active view { pView = pActiveView; } if (pView == 0 || pView != pActiveView) return; const bool bGroundOnly = GetPortBool(pActInfo, EIP_GroundOnly); Ang3 angles = Ang3(DEG2RAD(GetPortVec3(pActInfo, EIP_Angle))); Vec3 shift = GetPortVec3(pActInfo, EIP_Shift); const float duration = GetPortFloat(pActInfo, EIP_Duration); float freq = GetPortFloat(pActInfo, EIP_Frequency); if (iszero(freq) == false) freq = 1.0f / freq; const float randomness = GetPortFloat(pActInfo, EIP_Randomness); static const bool bFlip = true; // GetPortBool(pActInfo, EIP_Flip); const bool bUpdateOnly = !bTriggered && bFreqTriggered; // it's an update if and only if Frequency has been changed const float distance = GetPortFloat(pActInfo, EIP_Distance); const float rangeMin = GetPortFloat(pActInfo, EIP_RangeMin); const float rangeMax = GetPortFloat(pActInfo, EIP_RangeMax); float amount = min(1.f, max(0.f, (rangeMax - distance) / (rangeMax - rangeMin))); angles *= amount; shift *= amount; pView->SetViewShake(angles, shift, duration, freq, randomness, FLOWGRAPH_SHAKE_ID, bFlip, bUpdateOnly, bGroundOnly); }
void CHUDCrosshair::Update(float fDeltaTime) { if(m_bBroken) return; IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); IItemSystem *pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem(); if(!pClientActor || !pItemSystem) return; IInventory *pInventory = pClientActor->GetInventory(); if(!pInventory) return; IItem *pItem = pItemSystem->GetItem(pInventory->GetCurrentItem()); IWeapon *pWeapon = NULL; IWeapon *pSlaveWeapon = NULL; const float fAlternateIronSight = 0.03f; if(pItem) { pWeapon = pItem->GetIWeapon(); if(pItem->IsDualWieldMaster()) { if(IItem *pSlave=pItem->GetDualWieldSlave()) pSlaveWeapon = pSlave->GetIWeapon(); } } else if(IVehicle *pVehicle=pClientActor->GetLinkedVehicle()) { pItem = pItemSystem->GetItem(pVehicle->GetCurrentWeaponId(pClientActor->GetEntityId())); if(pItem) pWeapon = pItem->GetIWeapon(); } if(pWeapon) { float fMinSpread = 0.0f; float fMaxSpread = 0.0f; m_spread = 0.0f; if(IFireMode *pFireMode=pWeapon->GetFireMode(pWeapon->GetCurrentFireMode())) { fMinSpread = pFireMode->GetMinSpread(); fMaxSpread = pFireMode->GetMaxSpread(); m_spread = pFireMode->GetSpread(); } if(pSlaveWeapon) { if(IFireMode *pSlaveFireMode=pSlaveWeapon->GetFireMode(pSlaveWeapon->GetCurrentFireMode())) { fMinSpread += pSlaveFireMode->GetMinSpread(); fMaxSpread += pSlaveFireMode->GetMaxSpread(); m_spread += pSlaveFireMode->GetSpread(); } } CPlayer *pPlayer = static_cast<CPlayer*>(pClientActor); if(pPlayer && pPlayer->GetNanoSuit() && pPlayer->GetNanoSuit()->GetMode() == NANOMODE_STRENGTH) m_spread *=0.5; if(g_pGameCVars->hud_iAlternateCrosshairSpread) { if(m_spread < fMinSpread) m_spread = min(m_spread,g_pGameCVars->hud_fAlternateCrosshairSpreadCrouch) / g_pGameCVars->hud_fAlternateCrosshairSpreadCrouch; else m_spread = min(m_spread,g_pGameCVars->hud_fAlternateCrosshairSpreadNeutral) / g_pGameCVars->hud_fAlternateCrosshairSpreadNeutral; } else { m_spread = min((m_spread-fMinSpread),15.0f) / 15.0f; IZoomMode *pZoomMode = pWeapon->GetZoomMode(pWeapon->GetCurrentZoomMode()); if(pZoomMode && !pZoomMode->IsToggle() && (pZoomMode->IsZoomed() || pZoomMode->IsZooming())) { m_spread -= fAlternateIronSight; } else { m_spread = min(m_spread,1.0f); m_spread = max(m_spread,0.0f); } } } if(m_animCrossHair.GetVisible() && !g_pHUD->InSpectatorMode()) { //also disables the damage indicator if(/*g_pGameCVars->hud_crosshair>0 && m_iCrosshair > 0 &&*/ (g_pGameCVars->g_difficultyLevel<4 || gEnv->bMultiplayer)) { m_animCrossHair.GetFlashPlayer()->Advance(fDeltaTime); m_animCrossHair.GetFlashPlayer()->Render(); } if(m_animInterActiveIcons.GetVisible()) //if the crosshair is invisible, the use icon should be too { if(!m_bHideUseIconTemp) //hides the icon, when something is already grabbed/being used { m_animInterActiveIcons.GetFlashPlayer()->Advance(fDeltaTime); m_animInterActiveIcons.GetFlashPlayer()->Render(); } } } if(m_animFriendCross.GetVisible()) { m_animFriendCross.GetFlashPlayer()->Advance(fDeltaTime); m_animFriendCross.GetFlashPlayer()->Render(); } if(!g_pGameCVars->hud_iAlternateCrosshairSpread) { m_spread = max(m_spread,-fAlternateIronSight); m_spread = min(m_spread,1.0f); } if (m_smoothSpread != m_spread) { Interpolate(m_smoothSpread, m_spread, 20.0f, fDeltaTime); m_animCrossHair.Invoke("setRecoil", m_smoothSpread); } UpdateCrosshair(); }
void CMPTutorial::Update() { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); if(!m_enabled && g_pGameCVars->g_PSTutorial_Enabled) EnableTutorialMode(true); else if(m_enabled && !g_pGameCVars->g_PSTutorial_Enabled) EnableTutorialMode(false); m_currentEvent.m_msgDisplayTime -= gEnv->pTimer->GetFrameTime(); if(!m_enabled) { if(m_currentEvent.m_msgDisplayTime < 0.0f && m_currentEvent.m_msgRemovalCondition != eMRC_None) { m_currentEvent.m_msgRemovalCondition = eMRC_None; SAFE_HUD_FUNC(ShowTutorialText(NULL,1)); } } // update the text... must be done even if not enabled, to ensure the 'you may reenable...' // message is shown correctly. if(m_currentEvent.m_numChunks > 0) { // calculate how far through the current sound we are CTimeValue now = gEnv->pTimer->GetFrameStartTime(); float soundTimer = now.GetMilliSeconds() - m_currentEvent.m_soundStartTime; assert(soundTimer >= 0); float soundPercent = 1.0f; if(m_currentEvent.m_soundLength == 0.0f && m_currentEvent.m_pCurrentSound.get()) { m_currentEvent.m_soundLength = m_currentEvent.m_pCurrentSound->GetLengthMs(); } if(m_currentEvent.m_soundLength > 0.0f) { soundPercent = soundTimer / m_currentEvent.m_soundLength; } for(int i=m_currentEvent.m_numChunks-1; i > m_currentEvent.m_currentChunk; --i) { if(m_currentEvent.m_chunks[i].m_startPercent <= soundPercent) { m_currentEvent.m_currentChunk = i; int pos = 2; // 2=bottom, 1=middle IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); if(pClientActor && pClientActor->GetLinkedVehicle()) { pos = 1; } SAFE_HUD_FUNC(ShowTutorialText(m_currentEvent.m_chunks[i].m_text, pos)); break; } } } if(!m_enabled) return; CPlayer* pPlayer = static_cast<CPlayer*>(g_pGame->GetIGameFramework()->GetClientActor()); if(!pPlayer) return; // don't start until game begins if(pPlayer->GetSpectatorMode() != 0 || g_pGame->GetGameRules()->GetCurrentStateId() != 3) return; if(!m_initialised) { m_initialised = true; if(g_pGame->GetHUD()) { // register as a HUD listener g_pGame->GetHUD()->RegisterListener(this); } // go through entity list and pull out the factories. IEntityItPtr pIt = gEnv->pEntitySystem->GetEntityIterator(); while (!pIt->IsEnd()) { if (IEntity * pEnt = pIt->Next()) { if(pEnt->GetClass() == m_pHQClass) { m_baseList.push_back(pEnt->GetId()); //CryLog("Adding HQ %d to list: %d", pEnt->GetId(), m_baseList.size()); } else if(pEnt->GetClass() == m_pAlienEnergyPointClass) { m_alienEnergyPointList.push_back(pEnt->GetId()); //CryLog("Adding AEP %d to list: %d", pEnt->GetId(), m_alienEnergyPointList.size()); } else if(pEnt->GetClass() == m_pSpawnGroupClass) { m_spawnGroupList.push_back(pEnt->GetId()); //CryLog("Adding spawngroup %d to list: %d", pEnt->GetId(), m_spawnGroupList.size()); } else if(pEnt->GetClass() == m_pFactoryClass) { m_factoryList.push_back(pEnt->GetId()); //CryLog("Adding Factory %d to list: %d", pEnt->GetId(), m_factoryList.size()); } } } } // first the briefing events. These are shown in order. bool showPrompt = CheckBriefingEvents(pPlayer); // player has been killed if(pPlayer->GetHealth() <= 0) { showPrompt = TriggerEvent(eTE_Killed); } else if(!showPrompt) { // check each event type here. Which might take a while. // entering a neutral factory // enter prototype factory // enter hostile factory // find alien crash m_entityCheckTimer -= gEnv->pTimer->GetFrameTime(); if(m_entityCheckTimer < 0.0f) { CheckNearbyEntities(pPlayer); m_entityCheckTimer = ENTITY_CHECK_TIME; } // board vehicle and vehicle tutorials CheckVehicles(pPlayer); // player has been wounded if(pPlayer->GetHealth() < pPlayer->GetMaxHealth()) TriggerEvent(eTE_Wounded); // bases m_baseCheckTimer -= gEnv->pTimer->GetFrameTime(); if(m_baseCheckTimer < 0.0f) { CheckBases(pPlayer); m_baseCheckTimer = ENTITY_CHECK_TIME; } } bool promptShown = false; for(int i=0; i<eTE_NumEvents; ++i) { if(m_events[i].m_status == eMS_Waiting) { if(m_currentEvent.m_msgDisplayTime < -MESSAGE_GAP_TIME) { ShowMessage(m_events[i]); } promptShown = true; break; } } if(!promptShown && (m_currentEvent.m_msgRemovalCondition == eMRC_Time) && (m_currentEvent.m_msgDisplayTime < 0.0f)) { HideMessage(); } }
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 }
//-------------------------------------------------------------------------------------------------- // Name: SpawnScreenExplosionEffect // Desc: Spawns screen explosion effect //-------------------------------------------------------------------------------------------------- void CExplosionGameEffect::SpawnScreenExplosionEffect(const SExplosionContainer &explosionContainer) { // Disclaimer: this code was originally from GameRulesClientServer::ProcessClientExplosionScreenFX() const ExplosionInfo& explosionInfo = explosionContainer.m_explosionInfo; if(explosionInfo.pressure < 1.0f) return; IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor(); if(pClientActor != NULL && !pClientActor->IsDead()) { CPlayer* pPlayer = static_cast<CPlayer*>(pClientActor); bool hasFlashBangEffect = explosionInfo.blindAmount > 0.0f; // Flashbang friends and self?... if(hasFlashBangEffect) { bool flashBangSelf = true; bool flashBangFriends = false; #ifndef _RELEASE flashBangSelf = g_pGameCVars->g_flashBangSelf != 0; flashBangFriends = g_pGameCVars->g_flashBangFriends != 0; #endif bool ownFlashBang = pPlayer->GetEntityId() == explosionInfo.shooterId; if((!flashBangSelf && ownFlashBang) || // FlashBang self? ((g_pGame->GetGameRules()->GetFriendlyFireRatio()<=0.0f) && (!flashBangFriends) && (!ownFlashBang) && pPlayer->IsFriendlyEntity(explosionInfo.shooterId))) // FlashBang friends? { return; } } // Distance float dist = (pClientActor->GetEntity()->GetWorldPos() - explosionInfo.pos).len(); // Is the explosion in Player's FOV (let's suppose the FOV a bit higher, like 80) SMovementState state; if(IMovementController *pMV = pClientActor->GetMovementController()) { pMV->GetMovementState(state); } Vec3 eyeToExplosion = explosionInfo.pos - state.eyePosition; Vec3 eyeDir = pClientActor->GetLinkedVehicle() ? pPlayer->GetVehicleViewDir() : state.eyeDirection; eyeToExplosion.Normalize(); float eyeDirectionDP = eyeDir.Dot(eyeToExplosion); bool inFOV = (eyeDirectionDP > 0.68f); // All explosions have radial blur (default 30m radius) const float maxBlurDistance = (explosionInfo.maxblurdistance >0.0f) ? explosionInfo.maxblurdistance : 30.0f; if((maxBlurDistance > 0.0f) && (g_pGameCVars->g_radialBlur > 0.0f) && (explosionInfo.radius > 0.5f)) { if (inFOV && (dist < maxBlurDistance)) { const int intersectionObjTypes = ent_static | ent_terrain; const unsigned int intersectionFlags = rwi_stop_at_pierceable|rwi_colltype_any; m_deferredScreenEffects.RequestRayCast(CDeferredExplosionEffect::eDET_RadialBlur, explosionInfo.pos, -eyeToExplosion, dist, maxBlurDistance, intersectionObjTypes, intersectionFlags, NULL, 0); } } // Flashbang effect if(hasFlashBangEffect && ((dist < (explosionInfo.radius*g_pGameCVars->g_flashBangNotInFOVRadiusFraction)) || (inFOV && (dist < explosionInfo.radius)))) { ray_hit hit; const int intersectionObjTypes = ent_static | ent_terrain; const unsigned int intersectionFlags = rwi_stop_at_pierceable|rwi_colltype_any; const int intersectionMaxHits = 1; int collision = gEnv->pPhysicalWorld->RayWorldIntersection( explosionInfo.pos, -eyeToExplosion*dist, intersectionObjTypes, intersectionFlags, &hit, intersectionMaxHits); // If there was no obstacle between flashbang grenade and player if(!collision) { bool enabled = true; if(enabled) { CCCPOINT (FlashBang_Explode_BlindLocalPlayer); float timeScale = max(0.0f, 1 - (dist/explosionInfo.radius)); float lookingAt = max(g_pGameCVars->g_flashBangMinFOVMultiplier, (eyeDirectionDP + 1)*0.5f); float time = explosionInfo.flashbangScale * timeScale *lookingAt; // time is determined by distance to explosion CRY_ASSERT_MESSAGE(pClientActor->IsPlayer(),"Effect shouldn't be spawned if not a player"); SPlayerStats* pStats = static_cast<SPlayerStats*>(pPlayer->GetActorStats()); NET_BATTLECHATTER(BC_Blinded, pPlayer); if(pClientActor->GetEntityId() == explosionInfo.shooterId) { g_pGame->GetPersistantStats()->IncrementClientStats(EIPS_BlindSelf); } else { g_pGame->GetGameRules()->SuccessfulFlashBang(explosionInfo, time); } pPlayer->StartFlashbangEffects(time, explosionInfo.shooterId); gEnv->p3DEngine->SetPostEffectParam("Flashbang_Time", time); gEnv->p3DEngine->SetPostEffectParam("FlashBang_BlindAmount", explosionInfo.blindAmount); gEnv->p3DEngine->SetPostEffectParam("Flashbang_DifractionAmount", time); gEnv->p3DEngine->SetPostEffectParam("Flashbang_Active", 1.0f); CRecordingSystem *pRecordingSystem = g_pGame->GetRecordingSystem(); if (pRecordingSystem) { pRecordingSystem->OnPlayerFlashed(time, explosionInfo.blindAmount); } } } else { CCCPOINT (FlashBang_Explode_NearbyButBlockedByGeometry); } } else if(inFOV && (dist < explosionInfo.radius)) { if(explosionInfo.damage>10.0f || explosionInfo.pressure>100.0f) { // Add some angular impulse to the client actor depending on distance, direction... float dt = (1.0f - dist/explosionInfo.radius); dt = dt * dt; float angleZ = gf_PI*0.15f*dt; float angleX = gf_PI*0.15f*dt; if (pClientActor) { static_cast<CActor*>(pClientActor)->AddAngularImpulse(Ang3(cry_random(-angleX*0.5f,angleX),0.0f,cry_random(-angleZ,angleZ)),0.0f,dt*2.0f); } } } } }//-------------------------------------------------------------------------------------------------
void 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(); }