float CGameRulesRSSpawning::GetScoreFromProximityToFriendlies( SUsefulSpawnData& spawnData, TPositionList& FriendlyPlayerPositions, TMultiplierList& FriendlyScoreMultipliers, const Vec3& potentialSpawnPosition ) { SpawnLogAlways("[SPAWN] > GetScoreFromProximityToFriendlies()"); float fScoreFromFriendlies = 0.0f; if(spawnData.numActiveFriendlyPlayers > 0) { const float fIdealMax = 30.0f; const float fIdealMin = 15.0f; const float fCloseFriendlyScoreMultiplier = 500.0f; const float fFarFriendlyScoreMultiplier = 2.0f; float fClosestFriendlySq = FLT_MAX; int index = 0; for(int i = FriendlyPlayerPositions.size() - 1; i >= 0; i--) { Vec3 diff = (FriendlyPlayerPositions[i] - potentialSpawnPosition); //This will bias against using spawn positions near in X/Y but on a different level in Z float fZBiasDistanceFromFriendlySq = (diff.x * diff.x) + (diff.y * diff.y) + fabsf(diff.z * diff.z * diff.z); if(fZBiasDistanceFromFriendlySq < fClosestFriendlySq) { fClosestFriendlySq = fZBiasDistanceFromFriendlySq; index = i; } } float fClosestFriendly = sqrt_fast_tpl(fClosestFriendlySq); if(fClosestFriendly < fIdealMin) { const float fAbortDist = 0.7f; //If the sapwn is within this distance of a friendly, we're going to be intersecting - abort const float fDiff = (fIdealMin - fClosestFriendly); const float fDistanceScore = (float)__fsel(fDiff - fAbortDist, fDiff, sqr(fDiff) * 10.0f); fScoreFromFriendlies = fDiff * fCloseFriendlyScoreMultiplier * FriendlyScoreMultipliers[index]; } else { const float fIdealSub = (fIdealMin + fIdealMax) * 0.5f; const float fIdealRadius = fabsf(fIdealMax - fIdealSub); fScoreFromFriendlies = max(fabsf(fClosestFriendly - fIdealSub) - fIdealRadius, 0.0f) * fFarFriendlyScoreMultiplier; } SpawnLogAlways("[SPAWN] >> Total Score from Friendlies: %.6f, closest was at %.2f, spawn time modifier %s", fScoreFromFriendlies, fClosestFriendly, FriendlyScoreMultipliers[index] < 1.0f ? "APPLIED" : "NOT APPLIED"); } return fScoreFromFriendlies; }
//------------------------------------------------------------------------ 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); } } } }