void CGameAchievements::OnActionEvent(const SActionEvent& event) { // assuming that we don't want to detect anything in MP. if(event.m_event == eAE_inGame && !gEnv->bMultiplayer) { CGameRules* pGR = g_pGame->GetGameRules(); if(pGR) { #ifdef GAME_IS_CRYSIS2 pGR->RegisterKillListener(this); #endif m_HMGHitType = pGR->GetHitTypeId("HMG"); m_gaussBulletHitType = pGR->GetHitTypeId("gaussBullet"); } m_lastPlayerThrownObject = 0; m_lastPlayerKillBulletId = 0; m_lastPlayerKillGrenadeId = 0; m_killsWithOneGrenade = 0; } // NB: by the time the eAE_unloadlevel event is sent the game // rules is already null: can't unregister. }
//------------------------------------------------------------------------ void CVehicleDamageBehaviorBurn::Update(const float deltaTime) { m_timeCounter -= deltaTime; if(m_timeCounter <= 0.0f) { CGameRules *pGameRules = g_pGame->GetGameRules(); if(pGameRules && gEnv->bServer) { Vec3 worldPos; if(m_pHelper) worldPos = m_pHelper->GetWorldSpaceTranslation(); else worldPos = m_pVehicle->GetEntity()->GetWorldTM().GetTranslation(); SEntityProximityQuery query; query.box = AABB(worldPos-Vec3(m_radius), worldPos+Vec3(m_radius)); gEnv->pEntitySystem->QueryProximity(query); IEntity *pEntity = 0; for(int i = 0; i < query.nCount; ++i) { if((pEntity = query.pEntities[i]) && pEntity->GetPhysics()) { float damage = (pEntity->GetId() == m_pVehicle->GetEntityId()) ? m_selfDamage : m_damage; // SNH: need to check vertical distance here as the QueryProximity() call seems to work in 2d only Vec3 pos = pEntity->GetWorldPos(); if(abs(pos.z - worldPos.z) < m_radius) { if(damage > 0.f) { HitInfo hitInfo; hitInfo.damage = damage; hitInfo.pos = worldPos; hitInfo.radius = m_radius; hitInfo.targetId = pEntity->GetId(); hitInfo.shooterId = m_shooterId; hitInfo.weaponId = m_pVehicle->GetEntityId(); hitInfo.type = pGameRules->GetHitTypeId("fire"); pGameRules->ServerHit(hitInfo); } } } } if(gEnv->pAISystem) gEnv->pAISystem->RegisterDamageRegion(this, Sphere(worldPos, m_radius)); } m_timeCounter = m_interval; } m_pVehicle->NeedsUpdate(); }
void SExplosionParams::PreCacheLevelResources(CItemParticleEffectCache& particleCache) { particleCache.CacheParticle(effectName); particleCache.CacheParticle(failedEffectName); CGameRules *pGameRules = g_pGame->GetGameRules(); if (pGameRules) { hitTypeId = pGameRules->GetHitTypeId(type.c_str()); } }
SExplosionParams::SExplosionParams(const IItemParamsNode *explosion) : minRadius(2.5f) , maxRadius(5.0f) , minPhysRadius(2.5f) , maxPhysRadius(5.0f) , pressure(200.0f) , holeSize(0.0f) , terrainHoleSize(3.0f) , effectScale(1) , effectName(0) , maxblurdist(10) , hitTypeId(0) , pParticleEffect(0) { const char *effect = 0; CItemParamReader reader(explosion); reader.Read("max_radius", maxRadius); minRadius = maxRadius * 0.8f; maxPhysRadius = min(maxRadius, 5.0f); minPhysRadius = maxPhysRadius * 0.8f; reader.Read("min_radius", minRadius); reader.Read("min_phys_radius", minPhysRadius); reader.Read("max_phys_radius", maxPhysRadius); reader.Read("pressure", pressure); reader.Read("hole_size", holeSize); reader.Read("terrain_hole_size", terrainHoleSize); reader.Read("effect", effect); reader.Read("effect_scale", effectScale); reader.Read("radialblurdist", maxblurdist); reader.Read("type", type); CGameRules *pGameRules = g_pGame->GetGameRules(); if (pGameRules) { hitTypeId = pGameRules->GetHitTypeId(type.c_str()); } if (effect && effect[0] && gEnv->pParticleManager) { effectName = effect; pParticleEffect = gEnv->pParticleManager->FindEffect(effect); if (pParticleEffect) { pParticleEffect->AddRef(); } } }
//------------------------------------------------------------------------ void CRock::HandleEvent(const SGameObjectEvent &event) { 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; if (!pTarget || pTarget->GetId()==m_ownerId || pTarget->GetId()==GetEntityId()) return; Vec3 dir(0, 0, 0); if (pCollision->vloc[0].GetLengthSquared() > 1e-6f) dir = pCollision->vloc[0].GetNormalized(); CGameRules *pGameRules = g_pGame->GetGameRules(); HitInfo hitInfo(m_ownerId, pTarget?pTarget->GetId():0, m_weaponId, m_fmId, 0.0f, pGameRules->GetHitMaterialIdFromSurfaceId(pCollision->idmat[1]), pCollision->partid[1], pGameRules->GetHitTypeId("melee"), pCollision->pt, dir, pCollision->n); hitInfo.remote = IsRemote(); hitInfo.projectileId = GetEntityId(); if (!hitInfo.remote) hitInfo.seq=m_seq; hitInfo.damage = m_damage; if (m_weaponId) { CWeapon *pWeapon=GetWeapon(); if (pWeapon && pWeapon->GetForcedHitMaterial() != -1) hitInfo.material=pGameRules->GetHitMaterialIdFromSurfaceId(pWeapon->GetForcedHitMaterial()); } pGameRules->ClientHit(hitInfo); if(m_damage>10) m_damage =(int)(m_damage*0.5f); } }
void CVTOLVehicleManager::CreateExplosion(IParticleEffect *inParticleEffect, const Vec3& pos, const float inEffectScale, TAudioSignalID inAudioSignal/*=INVALID_AUDIOSIGNAL_ID*/) { #if !defined(DEDICATED_SERVER) CRY_ASSERT_MESSAGE(inParticleEffect, "CreateExplosion() passsed a NULL inParticleEffect"); #endif if (gEnv->bServer) { // server wants to create actual explosions CGameRules *pGameRules = g_pGame->GetGameRules(); ExplosionInfo explosionInfo; explosionInfo.pParticleEffect = inParticleEffect; explosionInfo.effect_name = s_explosionEffectName;// needed so the explosion can be synced to clients explosionInfo.type = pGameRules->GetHitTypeId("explosion"); explosionInfo.effect_scale = inEffectScale; // this is likely not connected up in the particle effect but should be able to be so that the effect can be adjusted dynamically explosionInfo.pos = pos; explosionInfo.dir.Set(0.0f,-1.0f,0.0f); explosionInfo.effect_scale = cry_random(0.9f,1.1f); explosionInfo.pressure = 1000.0f; explosionInfo.maxblurdistance = 10.0; explosionInfo.radius = 12.0f; explosionInfo.blindAmount = 0.0f; explosionInfo.flashbangScale = 8.0f; explosionInfo.damage = 0.0f; explosionInfo.hole_size = 0.0f; pGameRules->QueueExplosion(explosionInfo); } // the gamerules SHOULD be syncing the server queued ones above to clients! if (inAudioSignal != INVALID_AUDIOSIGNAL_ID) { CAudioSignalPlayer::JustPlay(inAudioSignal, pos); } }
//------------------------------------------------------------------------ void CProjectile::Explode(bool destroy, bool impact, const Vec3 &pos, const Vec3 &normal, const Vec3 &vel, EntityId targetId) { const SExplosionParams* pExplosionParams = m_pAmmoParams->pExplosion; if (pExplosionParams) { Vec3 dir(0,0,1); if (impact && vel.len2()>0) dir = vel.normalized(); else if (normal.len2()>0) dir = -normal; m_hitPoints = 0; // marcok: using collision pos sometimes causes explosions to have no effect. Anton advised to use entity pos Vec3 epos = pos.len2()>0 ? (pos - dir * 0.2f) : GetEntity()->GetWorldPos(); CGameRules *pGameRules = g_pGame->GetGameRules(); float minRadius = pExplosionParams->minRadius; float maxRadius = pExplosionParams->maxRadius; if (m_pAmmoParams->pFlashbang) { minRadius = m_pAmmoParams->pFlashbang->maxRadius; maxRadius = m_pAmmoParams->pFlashbang->maxRadius; } ExplosionInfo explosionInfo(m_ownerId, GetEntityId(), m_damage, epos, dir, minRadius, maxRadius, pExplosionParams->minPhysRadius, pExplosionParams->maxPhysRadius, 0.0f, pExplosionParams->pressure, pExplosionParams->holeSize, pGameRules->GetHitTypeId(pExplosionParams->type.c_str())); if(m_pAmmoParams->pFlashbang) explosionInfo.SetEffect(pExplosionParams->effectName, pExplosionParams->effectScale, pExplosionParams->maxblurdist, m_pAmmoParams->pFlashbang->blindAmount, m_pAmmoParams->pFlashbang->flashbangBaseTime); else explosionInfo.SetEffect(pExplosionParams->effectName, pExplosionParams->effectScale, pExplosionParams->maxblurdist); explosionInfo.SetEffectClass(m_pAmmoParams->pEntityClass->GetName()); if (impact) explosionInfo.SetImpact(normal, vel, targetId); if (gEnv->bServer) { pGameRules->ServerExplosion(explosionInfo); // add battle dust as well CBattleDust* pBD = pGameRules->GetBattleDust(); if(pBD) pBD->RecordEvent(eBDET_Explosion, pos, GetEntity()->GetClass()); } } if(!gEnv->bMultiplayer) { //Single player (AI related code)is processed here, CGameRules::ClientExplosion process the effect if (m_pAmmoParams->pFlashbang) FlashbangEffect(m_pAmmoParams->pFlashbang); } if (destroy) Destroy(); }
//------------------------------------------------------------------------ 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 CMelee::Hit(const Vec3 &pt, const Vec3 &dir, const Vec3 &normal, IPhysicalEntity *pCollider, int partId, int ipart, int surfaceIdx, float damageScale, bool remote) { // generate the damage IEntity *pTarget = gEnv->pEntitySystem->GetEntityFromPhysics(pCollider); // Report punch to AI system. // The AI notification must come before the game rules are // called so that the death handler in AIsystem understands that the hit // came from the player. bool ok = true; if(pTarget) { CActor *pActor = m_pWeapon->GetOwnerActor(); if(!gEnv->bMultiplayer && pActor && pActor->IsPlayer()) { if (IActor *pAITarget = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTarget->GetId())) { if (IAIObject *pAITargetObject = pTarget->GetAI()) { if (pAITargetObject->IsFriendly(pActor->GetEntity()->GetAI(), false)) { ok = false; m_noImpulse = true; } } } } if(ok) { CGameRules *pGameRules = g_pGame->GetGameRules(); HitInfo info(m_pWeapon->GetOwnerId(), pTarget->GetId(), m_pWeapon->GetEntityId(), m_pShared->meleeparams.damage * damageScale * m_meleeScale, 0.0f, pGameRules->GetHitMaterialIdFromSurfaceId(surfaceIdx), partId, pGameRules->GetHitTypeId(m_pShared->meleeparams.hit_type.c_str()), pt, dir, normal); info.remote = remote; pGameRules->ClientHit(info); } } // play effects if(ok) { if(IMaterialEffects *pMaterialEffects = gEnv->pGame->GetIGameFramework()->GetIMaterialEffects()) { TMFXEffectId effectId = pMaterialEffects->GetEffectId("melee", surfaceIdx); if (effectId != InvalidEffectId) { SMFXRunTimeEffectParams params; params.pos = pt; params.normal = -dir; params.playflags = MFX_PLAY_ALL | MFX_DISABLE_DELAY; params.soundSemantic = eSoundSemantic_Player_Foley; pMaterialEffects->ExecuteEffect(effectId, params); } } } ApplyCameraShake(true); m_pWeapon->PlayAction(m_pShared->meleeactions.hit.c_str()); }
//------------------------------------------------------------------------ void CMelee::Hit(const Vec3 &pt, const Vec3 &dir, const Vec3 &normal, IPhysicalEntity *pCollider, int partId, int ipart, int surfaceIdx, float damageScale, bool remote) { // generate the damage IEntity *pTarget = gEnv->pEntitySystem->GetEntityFromPhysics(pCollider); // Report punch to AI system. // The AI notification must come before the game rules are // called so that the death handler in AIsystem understands that the hit // came from the player. CActor *pActor = m_pWeapon->GetOwnerActor(); if (pActor && pActor->GetActorClass() == CPlayer::GetActorClassType()) { CPlayer *pPlayer = (CPlayer *)pActor; if (pPlayer && pPlayer->GetNanoSuit()) { if (pPlayer->GetEntity() && pPlayer->GetEntity()->GetAI()) { SAIEVENT AIevent; AIevent.targetId = pTarget ? pTarget->GetId() : 0; // pPlayer->GetNanoSuit()->GetMode() == NANOMODE_STRENGTH pPlayer->GetEntity()->GetAI()->Event(AIEVENT_PLAYER_STUNT_PUNCH, &AIevent); } } } bool ok = true; if(pTarget) { if(!gEnv->bMultiplayer && pActor && pActor->IsPlayer()) { IActor* pAITarget = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTarget->GetId()); if(pAITarget && pTarget->GetAI() && !pTarget->GetAI()->IsHostile(pActor->GetEntity()->GetAI(),false)) { ok = false; m_noImpulse = true; } } if(ok) { CGameRules *pGameRules = g_pGame->GetGameRules(); HitInfo info(m_pWeapon->GetOwnerId(), pTarget->GetId(), m_pWeapon->GetEntityId(), m_meleeparams.damage*damageScale*m_meleeScale, 0.0f, pGameRules->GetHitMaterialIdFromSurfaceId(surfaceIdx), partId, pGameRules->GetHitTypeId(m_meleeparams.hit_type.c_str()), pt, dir, normal); info.remote = remote; if (m_pWeapon->GetForcedHitMaterial() != -1) info.material=pGameRules->GetHitMaterialIdFromSurfaceId(m_pWeapon->GetForcedHitMaterial()); pGameRules->ClientHit(info); } } // play effects if(ok) { IMaterialEffects* pMaterialEffects = gEnv->pGame->GetIGameFramework()->GetIMaterialEffects(); TMFXEffectId effectId = pMaterialEffects->GetEffectId("melee", surfaceIdx); if (effectId != InvalidEffectId) { SMFXRunTimeEffectParams params; params.pos = pt; params.playflags = MFX_PLAY_ALL | MFX_DISABLE_DELAY; params.soundSemantic = eSoundSemantic_Player_Foley; pMaterialEffects->ExecuteEffect(effectId, params); } } ApplyCameraShake(true); m_pWeapon->PlayAction(m_meleeactions.hit.c_str()); }