void CTacAlienBullet::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) { EntityId targetId = pTarget->GetId(); CActor* pActor = static_cast<CActor*>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTarget->GetId())); if(pActor && pActor->CanSleep()) { SimpleHitInfo info(m_ownerId, targetId, m_weaponId, 1); // 0=tag,1=tac info.remote=IsRemote(); g_pGame->GetGameRules()->ClientSimpleHit(info); } } Destroy(); } }
//------------------------------------------------------------------------ void CGameRules::ServerSimpleHit(const SimpleHitInfo &simpleHitInfo) { if (my->CallHook( "OnEntityDamage", oohh::GetEntityFromId(simpleHitInfo.targetId), oohh::GetEntityFromId(simpleHitInfo.weaponId), oohh::GetEntityFromId(simpleHitInfo.shooterId), simpleHitInfo.value, Vec3(0,0,0), Vec3(0,0,0) )) { if (true) return; } switch (simpleHitInfo.type) { case 0: // tag { if (!simpleHitInfo.targetId) return; // tagged entities are temporary in MP, not in SP. bool temp = gEnv->bMultiplayer; AddTaggedEntity(simpleHitInfo.shooterId, simpleHitInfo.targetId, temp); } break; case 1: // tac { if (!simpleHitInfo.targetId) return; CActor *pActor = (CActor *)gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(simpleHitInfo.targetId); if (pActor && pActor->CanSleep()) pActor->Fall(Vec3(0.0f,0.0f,0.0f),simpleHitInfo.value); } break; case 0xe: // freeze { if (!simpleHitInfo.targetId) return; // call OnFreeze bool allow=true; if (m_serverStateScript.GetPtr() && m_serverStateScript->GetValueType("OnFreeze")==svtFunction) { HSCRIPTFUNCTION func=0; m_serverStateScript->GetValue("OnFreeze", func); Script::CallReturn(m_serverStateScript->GetScriptSystem(), func, m_script, ScriptHandle(simpleHitInfo.targetId), ScriptHandle(simpleHitInfo.shooterId), ScriptHandle(simpleHitInfo.weaponId), simpleHitInfo.value, allow); gEnv->pScriptSystem->ReleaseFunc(func); } if (!allow) return; if (IEntity *pEntity=gEnv->pEntitySystem->GetEntity(simpleHitInfo.targetId)) { IScriptTable *pScriptTable=pEntity->GetScriptTable(); // call OnFrost if (pScriptTable && pScriptTable->GetValueType("OnFrost")==svtFunction) { HSCRIPTFUNCTION func=0; pScriptTable->GetValue("OnFrost", func); Script::Call(pScriptTable->GetScriptSystem(), func, pScriptTable, ScriptHandle(simpleHitInfo.shooterId), ScriptHandle(simpleHitInfo.weaponId), simpleHitInfo.value); gEnv->pScriptSystem->ReleaseFunc(func); } FreezeEntity(simpleHitInfo.targetId, true, true, simpleHitInfo.value>0.999f); } } break; default: assert(!"Unknown Simple Hit type!"); } }
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 CGameRules::ServerSimpleHit(const SimpleHitInfo &simpleHitInfo) { switch (simpleHitInfo.type) { case 0: // tag { if (!simpleHitInfo.targetId) return; // tagged entities are temporary in MP, not in SP. // bool temp = gEnv->bMultiplayer; //kirill: - not anymore - design says must stay on bool temp = false; AddTaggedEntity(simpleHitInfo.shooterId, simpleHitInfo.targetId, temp); } break; case 1: // tac { if (!simpleHitInfo.targetId) return; CActor *pActor = (CActor *)gEnv->pGame->GetIGameFramework()->GetIActorSystem()->GetActor(simpleHitInfo.targetId); if (pActor && pActor->CanSleep()) { pActor->Fall(Vec3(0.0f,0.0f,0.0f),false,simpleHitInfo.value); //This is only used in SP by the player, so don't need further checks CPlayer* pPlayer = static_cast<CPlayer*>(g_pGame->GetIGameFramework()->GetClientActor()); if(pPlayer) pPlayer->PlaySound(CPlayer::ESound_TacBulletFeedBack,true); } } break; case 0xe: // freeze { if (!simpleHitInfo.targetId) return; CActor *pActor=GetActorByEntityId(simpleHitInfo.targetId); if (pActor && pActor->IsPlayer() && pActor->GetActorClass()==CPlayer::GetActorClassType()) { CPlayer *pPlayer=static_cast<CPlayer *>(pActor); if (CNanoSuit *pSuit=pPlayer->GetNanoSuit()) if (pSuit->IsInvulnerable()) return; } // call OnFreeze bool allow=true; if (m_serverStateScript.GetPtr() && m_serverStateScript->GetValueType("OnFreeze")==svtFunction) { HSCRIPTFUNCTION func=0; m_serverStateScript->GetValue("OnFreeze", func); Script::CallReturn(m_serverStateScript->GetScriptSystem(), func, m_script, ScriptHandle(simpleHitInfo.targetId), ScriptHandle(simpleHitInfo.shooterId), ScriptHandle(simpleHitInfo.weaponId), simpleHitInfo.value, allow); gEnv->pScriptSystem->ReleaseFunc(func); } if (!allow) return; if (IEntity *pEntity=gEnv->pEntitySystem->GetEntity(simpleHitInfo.targetId)) { IScriptTable *pScriptTable=pEntity->GetScriptTable(); // call OnFrost if (pScriptTable && pScriptTable->GetValueType("OnFrost")==svtFunction) { HSCRIPTFUNCTION func=0; pScriptTable->GetValue("OnFrost", func); Script::Call(pScriptTable->GetScriptSystem(), func, pScriptTable, ScriptHandle(simpleHitInfo.shooterId), ScriptHandle(simpleHitInfo.weaponId), simpleHitInfo.value); gEnv->pScriptSystem->ReleaseFunc(func); } FreezeEntity(simpleHitInfo.targetId, true, true, simpleHitInfo.value>0.999f); } } break; default: assert(!"Unknown Simple Hit type!"); } }