//------------------------------------------------------------------------ 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 CTacBullet::HandleEvent(const SGameObjectEvent &event) { if (m_destroying) return; CProjectile::HandleEvent(event); if (event.event == eGFE_OnCollision) { 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) { CGameRules *pGameRules = g_pGame->GetGameRules(); EntityId targetId = pTarget->GetId(); CActor *pActor = (CActor *)gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(targetId); if(pActor && pActor->CanSleep()) { if(pActor->GetLinkedVehicle() && !gEnv->bMultiplayer) { SleepTargetInVehicle(m_ownerId,pActor); } else if(IEntity* pOwnerEntity = gEnv->pEntitySystem->GetEntity(m_ownerId)) { if (pTarget->GetAI() && !pTarget->GetAI()->IsFriendly(pOwnerEntity->GetAI(), false)) { float sleepTime = 30.0f; if(m_pAmmoParams) sleepTime = m_pAmmoParams->sleepTime; SimpleHitInfo info(m_ownerId, targetId, m_weaponId, 1, sleepTime); // 0=tag,1=tac info.remote=IsRemote(); pGameRules->ClientSimpleHit(info); } } } else { Vec3 dir(0, 0, 0); if (pCollision->vloc[0].GetLengthSquared() > 1e-6f) dir = pCollision->vloc[0].GetNormalized(); 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); } } else 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); if (pierceabilityMat>params.iPierceability && pCollision->idCollider!=-1) return; } 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()); }