Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/game/server/basecombatcharacter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3466,6 +3466,21 @@ float CBaseCombatCharacter::GetFogObscuredRatio( CBaseEntity *target ) const
//-----------------------------------------------------------------------------
float CBaseCombatCharacter::GetFogObscuredRatio( float range ) const
{
#ifdef NEO // Generic solution for NPCs
auto controller = FogSystem()->GetMasterFogController();

if ( controller )
{
const fogparams_t &fog = controller->m_fog;

if ( !fog.enable )
return 0.0f;

float ratio = RemapValClamped( range, fog.start, fog.end, 0.0f, 1.0f );
ratio = MIN( ratio, fog.maxdensity );
return ratio;
}
#endif
/* TODO: Get global fog from map somehow since nav mesh fog is gone
fogparams_t fog;
GetFogParams( &fog );
Expand Down
69 changes: 53 additions & 16 deletions src/game/server/neo/neo_player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1332,12 +1332,56 @@ bool CNEO_Player::IsHiddenByFog(CBaseEntity* target) const
}
}

//-----------------------------------------------------------------------------
// Purpose: return 0-1 ratio where zero is not obscured, and 1 is completely obscured
// Including cloak for players
//-----------------------------------------------------------------------------
float CNEO_Player::GetFogObscuredRatio( CBaseEntity *target ) const
{
if ( !target )
return 0.0f;

const float range = CBaseCombatCharacter::EyePosition().DistTo( target->WorldSpaceCenter() );
const float flFogRatio = GetFogObscuredRatio( range );

auto targetPlayer = ToNEOPlayer( target );
if ( targetPlayer )
{
const float flCloakRatio = GetCloakObscuredRatio( targetPlayer );
return 1.0f - ( 1.0f - flFogRatio ) * ( 1.0f - flCloakRatio );
}

return flFogRatio;
}

//-----------------------------------------------------------------------------
// Purpose: return 0-1 ratio where zero is not obscured, and 1 is completely obscured
//-----------------------------------------------------------------------------
float CNEO_Player::GetFogObscuredRatio( float range ) const
{
auto controller = m_Local.m_PlayerFog.m_hCtrl.Get();

if ( controller )
{
const fogparams_t &fog = controller->m_fog;

if ( !fog.enable )
return 0.0f;

float ratio = RemapValClamped( range, fog.start, fog.end, 0.0f, 1.0f );
ratio = MIN( ratio, fog.maxdensity );
return ratio;
}

return 0.0f;
}

//-----------------------------------------------------------------------------
// Purpose: return 0-1 ratio where zero is not obscured, and 1 is completely obscured
// NEO JANK: If this function is too expensive,
// players may report that the game gets laggy when in line of sight bots.
//-----------------------------------------------------------------------------
float CNEO_Player::GetFogObscuredRatio(CBaseEntity* target) const
float CNEO_Player::GetCloakObscuredRatio(CNEO_Player* target) const
{
VPROF_BUDGET(__FUNCTION__, "NextBotExpensive");

Expand All @@ -1346,35 +1390,28 @@ float CNEO_Player::GetFogObscuredRatio(CBaseEntity* target) const
return 0.0f;
}

auto targetPlayer = ToNEOPlayer(target);
if (targetPlayer == nullptr)
{
// If it's not a player, this cloaking logic doesn't apply, so it is not obscured
return 0.0f;
}

if ( NEORules()->IsTeamplay()
&& (GetTeamNumber() == targetPlayer->GetTeamNumber()) )
&& (GetTeamNumber() == target->GetTeamNumber()) )
{
// Teammates are always labeled with IFF markers, unless in free-for-all game modes
return 0.0f;
}

// If target is not cloaked, it's not obscured.
if (!targetPlayer->GetInThermOpticCamo() && !sv_neo_bot_cloak_debug_perceive_always_on.GetBool())
if (!target->GetInThermOpticCamo() && !sv_neo_bot_cloak_debug_perceive_always_on.GetBool())
{
return 0.0f; // Not obscured
}

if (targetPlayer->IsCarryingGhost())
if (target->IsCarryingGhost())
{
return 0.0f;
}

// From this point on, assume we are counting bonus points towards observer detection
float flDetectionBonus = 0.0f; // # of factors that are helping the observer detect the target

if (targetPlayer->GetBotCloakStateDisrupted())
if (target->GetBotCloakStateDisrupted())
{
flDetectionBonus += sv_neo_bot_cloak_detection_bonus_disruption_effect.GetFloat();
}
Expand All @@ -1388,8 +1425,8 @@ float CNEO_Player::GetFogObscuredRatio(CBaseEntity* target) const
return player->GetAbsVelocity().LengthSqr() > (runSpeedThreshold * runSpeedThreshold);
};

bool targetIsRunning = isRunning(targetPlayer);
bool targetIsMoving = targetIsRunning || isMoving(targetPlayer);
bool targetIsRunning = isRunning(target);
bool targetIsMoving = targetIsRunning || isMoving(target);

// Class Impact:
// Assault class motion vision
Expand Down Expand Up @@ -1431,7 +1468,7 @@ float CNEO_Player::GetFogObscuredRatio(CBaseEntity* target) const
flDetectionBonus += sv_neo_bot_cloak_detection_bonus_target_moving.GetFloat();
}

if (!targetPlayer->IsDucking()) // is standing, and NOT ducking
if (!target->IsDucking()) // is standing, and NOT ducking
{
// target is more obvious when standing at full height
flDetectionBonus += sv_neo_bot_cloak_detection_bonus_target_standing.GetFloat();
Expand Down Expand Up @@ -1460,7 +1497,7 @@ float CNEO_Player::GetFogObscuredRatio(CBaseEntity* target) const
}

// Injured Target Impact
flDetectionBonus += (float)targetPlayer->GetBotDetectableBleedingInjuryEvents() * sv_neo_bot_cloak_detection_bonus_per_injury.GetFloat();
flDetectionBonus += (float)target->GetBotDetectableBleedingInjuryEvents() * sv_neo_bot_cloak_detection_bonus_per_injury.GetFloat();

// Lighting Impact
// NEO JANK: See "FIXMEL4DTOMAINMERGE" for why this doesn't have any effect yet.
Expand Down
2 changes: 2 additions & 0 deletions src/game/server/neo/neo_player.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ class CNEO_Player : public CHL2MP_Player
// -----------------------
virtual bool IsHiddenByFog(CBaseEntity* target) const OVERRIDE; ///< return true if given target cant be seen because of "fog"
virtual float GetFogObscuredRatio(CBaseEntity* target) const OVERRIDE; ///< return 0-1 ratio where zero is not obscured, and 1 is completely obscured
virtual float GetFogObscuredRatio(float range) const OVERRIDE; ///< return 0-1 ratio where zero is not obscured, and 1 is completely obscured
float GetCloakObscuredRatio(CNEO_Player* target) const; ///< return 0-1 ratio where zero is not obscured, and 1 is completely obscured

void AddNeoFlag(int flags)
{
Expand Down
Loading