diff --git a/regamedll/dlls/player.cpp b/regamedll/dlls/player.cpp index 469eb4d6..9723f112 100644 --- a/regamedll/dlls/player.cpp +++ b/regamedll/dlls/player.cpp @@ -7858,6 +7858,22 @@ void CBasePlayer::UpdateStatusBar() CBaseEntity *pEntity = CBaseEntity::Instance(tr.pHit); bool isVisiblePlayer = ((TheBots == nullptr || !TheBots->IsLineBlockedBySmoke(&pev->origin, &pEntity->pev->origin)) && pEntity->Classify() == CLASS_PLAYER); +#ifdef REGAMEDLL_FIXES + if (g_FogParameters.density > 0) + { + // Estimation of the max distance to which an entity is visible, + // taking into account the fog density and the visibility factor + const float flVisibilityFogFactor = 2.0f; + float flDistance = (pev->origin - pEntity->pev->origin).Length(); + float flMaxVisibleDistance = flVisibilityFogFactor / g_FogParameters.density; + + // Check if the distance between the player's position and the entity + // exceeds the max visible distance. If so, the entity is not visible + if (flDistance > flMaxVisibleDistance) + isVisiblePlayer = false; + } +#endif + if (gpGlobals->time >= m_blindUntilTime && isVisiblePlayer) { CBasePlayer *pTarget = (CBasePlayer *)pEntity; diff --git a/regamedll/dlls/triggers.cpp b/regamedll/dlls/triggers.cpp index f454806c..d9de0e0f 100644 --- a/regamedll/dlls/triggers.cpp +++ b/regamedll/dlls/triggers.cpp @@ -2469,6 +2469,8 @@ void CWeather::Spawn() InitTrigger(); } +FogParameters g_FogParameters; + void CClientFog::KeyValue(KeyValueData *pkvd) { #if 0 @@ -2505,6 +2507,28 @@ void CClientFog::Spawn() pev->solid = SOLID_NOT; // Remove model & collisions pev->renderamt = 0; // The engine won't draw this model if this is set to 0 and blending is on pev->rendermode = kRenderTransTexture; + + g_FogParameters.density = m_fDensity; + g_FogParameters.r = clamp(int(pev->rendercolor[0]), 0, 255); + g_FogParameters.g = clamp(int(pev->rendercolor[1]), 0, 255); + g_FogParameters.b = clamp(int(pev->rendercolor[2]), 0, 255); +} + +void CClientFog::OnDestroy() +{ + g_FogParameters.density = 0; + +#ifdef REGAMEDLL_FIXES + if (!g_bServerActive) + return; // server isn't active or changes map + + MESSAGE_BEGIN(MSG_ALL, gmsgFog); + WRITE_BYTE(0); + WRITE_BYTE(0); + WRITE_BYTE(0); + WRITE_LONG(0); // a fog density of 0 suggests fog is disabled + MESSAGE_END(); +#endif } LINK_ENTITY_TO_CLASS(env_fog, CClientFog, CCSClientFog) diff --git a/regamedll/dlls/triggers.h b/regamedll/dlls/triggers.h index c16f969c..4082e8d0 100644 --- a/regamedll/dlls/triggers.h +++ b/regamedll/dlls/triggers.h @@ -538,6 +538,7 @@ class CClientFog: public CBaseEntity public: virtual void Spawn(); virtual void KeyValue(KeyValueData *pkvd); + virtual void OnDestroy(); public: int m_iStartDist; @@ -545,6 +546,25 @@ public: float m_fDensity; }; +struct FogParameters +{ + FogParameters() : + r(0), g(0), b(0), density(0) + { + } + + void Clear() + { + r = g = b = 0; + density = 0; + } + + int r, g, b; + float density; +}; + +extern FogParameters g_FogParameters; + void PlayCDTrack(edict_t *pClient, int iTrack); int BuildChangeList(LEVELLIST *pLevelList, int maxList); void NextLevel(); diff --git a/regamedll/dlls/world.cpp b/regamedll/dlls/world.cpp index 55147af0..33908fc2 100644 --- a/regamedll/dlls/world.cpp +++ b/regamedll/dlls/world.cpp @@ -279,6 +279,7 @@ void CWorld::Precache() g_pLastSpawn = nullptr; g_pLastCTSpawn = nullptr; g_pLastTerroristSpawn = nullptr; + g_FogParameters.Clear(); CVAR_SET_STRING("sv_gravity", "800"); CVAR_SET_STRING("sv_maxspeed", "900");