From 0c5c714b79d0d9df35be17889e5f8099aaca057e Mon Sep 17 00:00:00 2001 From: Marco Cawthorne Date: Fri, 14 Apr 2023 10:21:07 -0700 Subject: [PATCH] GS-Entbase: Implementation of CS/DMC's env_fog entity. --- src/client/entities.qc | 3 + src/gs-entbase/shared.src | 1 + src/gs-entbase/shared/env_fog.qc | 232 ++++++++++++++++++++ src/gs-entbase/shared/env_fog_controller.qc | 78 +++---- src/shared/entities.h | 1 + 5 files changed, 276 insertions(+), 39 deletions(-) create mode 100644 src/gs-entbase/shared/env_fog.qc diff --git a/src/client/entities.qc b/src/client/entities.qc index a13e3737..1d7f877e 100644 --- a/src/client/entities.qc +++ b/src/client/entities.qc @@ -114,6 +114,9 @@ Entity_EntityUpdate(float type, float new) } ept.ReceiveEntity(new, readfloat()); break; + case ENT_FOG: + env_fog_readentity(new); + break; case ENT_FOGCONTROLLER: env_fog_controller_readentity(new); break; diff --git a/src/gs-entbase/shared.src b/src/gs-entbase/shared.src index 8f13b04d..feb358f4 100644 --- a/src/gs-entbase/shared.src +++ b/src/gs-entbase/shared.src @@ -11,6 +11,7 @@ shared/env_sprite.qc shared/env_bubbles.qc shared/env_laser.qc shared/env_projectedtexture.qc +shared/env_fog.qc shared/env_fog_controller.qc shared/light_dynamic.qc shared/func_monitor.qc diff --git a/src/gs-entbase/shared/env_fog.qc b/src/gs-entbase/shared/env_fog.qc new file mode 100644 index 00000000..a4569e91 --- /dev/null +++ b/src/gs-entbase/shared/env_fog.qc @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2023 Vera Visions LLC. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +enumflags +{ + ENVFOG_CHANGED_ACTIVE, + ENVFOG_CHANGED_STARTDIST, + ENVFOG_CHANGED_ENDDIST, + ENVFOG_CHANGED_DENSITY, + ENVFOG_CHANGED_COLOR +}; + +/*!QUAKED env_fog (1 .5 0) (-8 -8 -8) (8 8 8) +# OVERVIEW +Covers the map in fog. + +# KEYS +- "targetname" : Name +- "target" : Target when triggered. +- "killtarget" : Target to kill when triggered. +- "startdist" : Distance between the player and the fog. +- "enddist" : Distance between the player and the end of the fog. +- "density" : Strength of the fog. +- "rendercolor" : Color of the fog. + +# TRIVIA +This entity was introduced in Counter-Strike (1998). +*/ +class +env_fog:NSPointTrigger +{ +public: + void env_fog(void); + +#ifdef CLIENT + virtual void ReceiveEntity(float,float); + nonvirtual void FogUpdate(void); +#endif + +#ifdef SERVER + virtual float SendEntity(entity,float); + virtual void EvaluateEntity(void); + virtual void Save(float); + virtual void Restore(string,string); + virtual void SpawnKey(string,string); + virtual void Spawned(void); + virtual void Respawn(void); + virtual void Trigger(entity, triggermode_t); +#endif + +private: + PREDICTED_FLOAT(m_flStartDist) + PREDICTED_FLOAT(m_flEndDist) + PREDICTED_FLOAT(m_flDensity) + PREDICTED_VECTOR(m_vecColor) + PREDICTED_BOOL(m_bEnabled) +}; + +void +env_fog::env_fog(void) +{ + m_flStartDist = 0; + m_flEndDist = 512; + m_flDensity = 1.0f; + m_vecColor = [1, 1, 1]; + m_bEnabled = true; +} + +#ifdef CLIENT +void +env_fog::FogUpdate(void) +{ + if (!m_bEnabled) + return; + + localcmd(sprintf("fog %f %f %f %f %f %f\n", \ + m_flDensity * 100, /* winging this */ + m_vecColor[0] / 255, + m_vecColor[1] / 255, + m_vecColor[2] / 255, + 1.0f, + m_flStartDist / 10)); /* rough conversion from units */ +} + +void +env_fog::ReceiveEntity(float flNew, float flChanged) +{ + READENTITY_FLOAT(m_flStartDist, ENVFOG_CHANGED_STARTDIST) + READENTITY_FLOAT(m_flEndDist, ENVFOG_CHANGED_ENDDIST) + READENTITY_FLOAT(m_flDensity, ENVFOG_CHANGED_DENSITY) + READENTITY_BYTE(m_vecColor[0], ENVFOG_CHANGED_COLOR) + READENTITY_BYTE(m_vecColor[1], ENVFOG_CHANGED_COLOR) + READENTITY_BYTE(m_vecColor[2], ENVFOG_CHANGED_COLOR) + READENTITY_BYTE(m_bEnabled, ENVFOG_CHANGED_ACTIVE) + FogUpdate(); +} +#endif + +#ifdef SERVER +float +env_fog::SendEntity(entity ePVEnt, float flChanged) +{ + WriteByte(MSG_ENTITY, ENT_FOG); + WriteFloat(MSG_ENTITY, flChanged); + SENDENTITY_FLOAT(m_flStartDist, ENVFOG_CHANGED_STARTDIST) + SENDENTITY_FLOAT(m_flEndDist, ENVFOG_CHANGED_ENDDIST) + SENDENTITY_FLOAT(m_flDensity, ENVFOG_CHANGED_DENSITY) + SENDENTITY_BYTE(m_vecColor[0], ENVFOG_CHANGED_COLOR) + SENDENTITY_BYTE(m_vecColor[1], ENVFOG_CHANGED_COLOR) + SENDENTITY_BYTE(m_vecColor[2], ENVFOG_CHANGED_COLOR) + SENDENTITY_BYTE(m_bEnabled, ENVFOG_CHANGED_ACTIVE) + return (1); +} + +void +env_fog::EvaluateEntity(void) +{ + EVALUATE_FIELD(m_flStartDist, ENVFOG_CHANGED_STARTDIST) + EVALUATE_FIELD(m_flEndDist, ENVFOG_CHANGED_ENDDIST) + EVALUATE_FIELD(m_flDensity, ENVFOG_CHANGED_DENSITY) + EVALUATE_VECTOR(m_vecColor, 0, ENVFOG_CHANGED_COLOR) + EVALUATE_VECTOR(m_vecColor, 1, ENVFOG_CHANGED_COLOR) + EVALUATE_VECTOR(m_vecColor, 2, ENVFOG_CHANGED_COLOR) + EVALUATE_FIELD(m_bEnabled, ENVFOG_CHANGED_ACTIVE) +} + +void +env_fog::Save(float handle) +{ + super::Save(handle); + SaveFloat(handle, "m_flStartDist", m_flStartDist); + SaveFloat(handle, "m_flEndDist", m_flEndDist); + SaveFloat(handle, "m_flDensity", m_flDensity); + SaveVector(handle, "m_vecColor", m_vecColor); +} + +void +env_fog::Restore(string strKey, string strValue) +{ + switch (strKey) { + case "m_flStartDist": + m_flStartDist = ReadFloat(strValue); + break; + case "m_flEndDist": + m_flEndDist = ReadFloat(strValue); + break; + case "m_flDensity": + m_flDensity = ReadFloat(strValue); + break; + case "m_vecColor": + m_vecColor = ReadVector(strValue); + break; + default: + super::Restore(strKey, strValue); + } +} + +void +env_fog::SpawnKey(string strKey, string strValue) +{ + switch (strKey) { + case "startdist": + m_flStartDist = stof(strValue); + break; + case "enddist": + m_flEndDist = stof(strValue); + break; + case "density": + m_flDensity = stof(strValue); + break; + case "rendercolor": + m_vecColor = stov(strValue); + break; + default: + super::SpawnKey(strKey, strValue); + } +} + +void +env_fog::Spawned(void) +{ + super::Spawned(); +} + +void +env_fog::Respawn(void) +{ + pvsflags = PVSF_IGNOREPVS; +} + +void +env_fog::Trigger(entity act, triggermode_t state) +{ + switch (state) { + case TRIG_OFF: + m_bEnabled = false; + break; + case TRIG_ON: + m_bEnabled = true; + break; + default: + m_bEnabled = (m_bEnabled) ? false : true; + } +} +#endif + +#ifdef CLIENT +void +env_fog_readentity(float isnew) +{ + env_fog fog = (env_fog)self; + float flags = readfloat(); + + if (isnew) + spawnfunc_env_fog(); + + fog.ReceiveEntity(isnew, flags); +} +#endif \ No newline at end of file diff --git a/src/gs-entbase/shared/env_fog_controller.qc b/src/gs-entbase/shared/env_fog_controller.qc index 42863253..81a9678e 100644 --- a/src/gs-entbase/shared/env_fog_controller.qc +++ b/src/gs-entbase/shared/env_fog_controller.qc @@ -16,21 +16,20 @@ enumflags { - ENVFOG_CHANGED_ACTIVE, - ENVFOG_CHANGED_BLEND, - ENVFOG_CHANGED_START, - ENVFOG_CHANGED_END, - ENVFOG_CHANGED_MAXDENSITY, - ENVFOG_CHANGED_FARZ, - ENVFOG_CHANGED_COLOR, - ENVFOG_CHANGED_COLOR2, - ENVFOG_CHANGED_DIR + ENVFOGCTRL_CHANGED_ACTIVE, + ENVFOGCTRL_CHANGED_BLEND, + ENVFOGCTRL_CHANGED_START, + ENVFOGCTRL_CHANGED_END, + ENVFOGCTRL_CHANGED_MAXDENSITY, + ENVFOGCTRL_CHANGED_FARZ, + ENVFOGCTRL_CHANGED_COLOR, + ENVFOGCTRL_CHANGED_COLOR2, + ENVFOGCTRL_CHANGED_DIR }; /*!QUAKED env_fog_controller (1 .5 0) (-8 -8 -8) (8 8 8) EVFOGCTL_MASTER # OVERVIEW -Textured light projected. This is the type of lighting that's used for -flashlights, lamp spotlights and so on. +Controls fog that affects the entire map. # KEYS - "targetname" : Name @@ -105,8 +104,9 @@ public: virtual void FogUpdate(void); virtual void RendererRestarted(void); virtual void ReceiveEntity(float,float); +#endif -#else +#ifdef SERVER virtual float SendEntity(entity,float); virtual void EvaluateEntity(void); virtual void Trigger(entity, triggermode_t); @@ -206,29 +206,29 @@ env_fog_controller::RendererRestarted(void) void env_fog_controller::ReceiveEntity(float flSendFlags, float flNew) { - if (flSendFlags & ENVFOG_CHANGED_ACTIVE) + if (flSendFlags & ENVFOGCTRL_CHANGED_ACTIVE) m_iFogActive = readbyte(); - if (flSendFlags & ENVFOG_CHANGED_BLEND) + if (flSendFlags & ENVFOGCTRL_CHANGED_BLEND) m_iFogBlend = readbyte(); - if (flSendFlags & ENVFOG_CHANGED_START) + if (flSendFlags & ENVFOGCTRL_CHANGED_START) m_flFogStart = readfloat(); - if (flSendFlags & ENVFOG_CHANGED_END) + if (flSendFlags & ENVFOGCTRL_CHANGED_END) m_flFogEnd = readfloat(); - if (flSendFlags & ENVFOG_CHANGED_MAXDENSITY) + if (flSendFlags & ENVFOGCTRL_CHANGED_MAXDENSITY) m_flFogMaxDensity = readfloat(); - if (flSendFlags & ENVFOG_CHANGED_FARZ) + if (flSendFlags & ENVFOGCTRL_CHANGED_FARZ) m_flFogFarZ = readfloat(); - if (flSendFlags & ENVFOG_CHANGED_COLOR) { + if (flSendFlags & ENVFOGCTRL_CHANGED_COLOR) { m_vecFogColor[0] = readfloat(); m_vecFogColor[1] = readfloat(); m_vecFogColor[2] = readfloat(); } - if (flSendFlags & ENVFOG_CHANGED_COLOR2) { + if (flSendFlags & ENVFOGCTRL_CHANGED_COLOR2) { m_vecFogColor2[0] = readfloat(); m_vecFogColor2[1] = readfloat(); m_vecFogColor2[2] = readfloat(); } - if (flSendFlags & ENVFOG_CHANGED_DIR) { + if (flSendFlags & ENVFOGCTRL_CHANGED_DIR) { m_vecFogDir[0] = readfloat(); m_vecFogDir[1] = readfloat(); m_vecFogDir[2] = readfloat(); @@ -250,29 +250,29 @@ env_fog_controller::SendEntity(entity ePVEnt, float flSendFlags) WriteByte(MSG_ENTITY, ENT_FOGCONTROLLER); WriteFloat(MSG_ENTITY, flSendFlags); - if (flSendFlags & ENVFOG_CHANGED_ACTIVE) + if (flSendFlags & ENVFOGCTRL_CHANGED_ACTIVE) WriteByte(MSG_ENTITY, m_iFogActive); - if (flSendFlags & ENVFOG_CHANGED_BLEND) + if (flSendFlags & ENVFOGCTRL_CHANGED_BLEND) WriteByte(MSG_ENTITY, m_iFogBlend); - if (flSendFlags & ENVFOG_CHANGED_START) + if (flSendFlags & ENVFOGCTRL_CHANGED_START) WriteFloat(MSG_ENTITY, m_flFogStart); - if (flSendFlags & ENVFOG_CHANGED_END) + if (flSendFlags & ENVFOGCTRL_CHANGED_END) WriteFloat(MSG_ENTITY, m_flFogEnd); - if (flSendFlags & ENVFOG_CHANGED_MAXDENSITY) + if (flSendFlags & ENVFOGCTRL_CHANGED_MAXDENSITY) WriteFloat(MSG_ENTITY, m_flFogMaxDensity); - if (flSendFlags & ENVFOG_CHANGED_FARZ) + if (flSendFlags & ENVFOGCTRL_CHANGED_FARZ) WriteFloat(MSG_ENTITY, m_flFogFarZ); - if (flSendFlags & ENVFOG_CHANGED_COLOR) { + if (flSendFlags & ENVFOGCTRL_CHANGED_COLOR) { WriteFloat(MSG_ENTITY, m_vecFogColor[0]); WriteFloat(MSG_ENTITY, m_vecFogColor[1]); WriteFloat(MSG_ENTITY, m_vecFogColor[2]); } - if (flSendFlags & ENVFOG_CHANGED_COLOR2) { + if (flSendFlags & ENVFOGCTRL_CHANGED_COLOR2) { WriteFloat(MSG_ENTITY, m_vecFogColor2[0]); WriteFloat(MSG_ENTITY, m_vecFogColor2[1]); WriteFloat(MSG_ENTITY, m_vecFogColor2[2]); } - if (flSendFlags & ENVFOG_CHANGED_DIR) { + if (flSendFlags & ENVFOGCTRL_CHANGED_DIR) { WriteFloat(MSG_ENTITY, m_vecFogDir[0]); WriteFloat(MSG_ENTITY, m_vecFogDir[1]); WriteFloat(MSG_ENTITY, m_vecFogDir[2]); @@ -285,23 +285,23 @@ void env_fog_controller::EvaluateEntity(void) { if (ATTR_CHANGED(m_iFogActive)) - SetSendFlags(ENVFOG_CHANGED_ACTIVE); + SetSendFlags(ENVFOGCTRL_CHANGED_ACTIVE); if (ATTR_CHANGED(m_iFogBlend)) - SetSendFlags(ENVFOG_CHANGED_BLEND); + SetSendFlags(ENVFOGCTRL_CHANGED_BLEND); if (ATTR_CHANGED(m_flFogStart)) - SetSendFlags(ENVFOG_CHANGED_START); + SetSendFlags(ENVFOGCTRL_CHANGED_START); if (ATTR_CHANGED(m_flFogEnd)) - SetSendFlags(ENVFOG_CHANGED_END); + SetSendFlags(ENVFOGCTRL_CHANGED_END); if (ATTR_CHANGED(m_flFogMaxDensity)) - SetSendFlags(ENVFOG_CHANGED_MAXDENSITY); + SetSendFlags(ENVFOGCTRL_CHANGED_MAXDENSITY); if (ATTR_CHANGED(m_flFogFarZ)) - SetSendFlags(ENVFOG_CHANGED_FARZ); + SetSendFlags(ENVFOGCTRL_CHANGED_FARZ); if (ATTR_CHANGED(m_vecFogColor)) - SetSendFlags(ENVFOG_CHANGED_COLOR); + SetSendFlags(ENVFOGCTRL_CHANGED_COLOR); if (ATTR_CHANGED(m_vecFogColor2)) - SetSendFlags(ENVFOG_CHANGED_COLOR2); + SetSendFlags(ENVFOGCTRL_CHANGED_COLOR2); if (ATTR_CHANGED(m_vecFogDir)) - SetSendFlags(ENVFOG_CHANGED_DIR); + SetSendFlags(ENVFOGCTRL_CHANGED_DIR); SAVE_STATE(m_iFogActive) SAVE_STATE(m_iFogBlend) diff --git a/src/shared/entities.h b/src/shared/entities.h index 3914b7f9..c7b3ede2 100644 --- a/src/shared/entities.h +++ b/src/shared/entities.h @@ -31,6 +31,7 @@ typedef enum ENT_BEAM, /**< of type env_beam */ ENT_DLIGHT, /**< of type light_dynamic */ ENT_PROJECTEDTEXTURE, /**< of type env_projectedtexture */ + ENT_FOG, /*<< of type env_fog */ ENT_FOGCONTROLLER, /**< of type env_fog_controller */ ENT_LASER, /**< of type env_laser */ ENT_PARTSYSTEM, /**< of type info_particle_system */