diff --git a/platform/base_glsl.pk3dir/glsl/heat.glsl b/platform/base_glsl.pk3dir/glsl/heat.glsl new file mode 100644 index 00000000..568bb66e --- /dev/null +++ b/platform/base_glsl.pk3dir/glsl/heat.glsl @@ -0,0 +1,56 @@ +//======= Copyright (c) 2015-2020 Vera Visions LLC. All rights reserved. ======= +// +// Purpose: +// +// Non-lit surface that predominantly offers environment cube reflection +// modulated by the diffusemap's RGB. This is used for glass, for example. +//============================================================================== + +!!ver 110 +!!permu FOG +!!samps diffusemap=0 normalmap=1 reflect=2 + +#include "sys/defs.h" + +varying vec2 tex_c; +varying vec3 eyevector; +varying mat3 invsurface; +varying vec4 tf; + +#ifdef VERTEX_SHADER +void main () +{ + + tex_c = v_texcoord; + invsurface[0] = v_svector; + invsurface[1] = v_tvector; + invsurface[2] = v_normal; + vec3 eyeminusvertex = e_eyepos - v_position.xyz; + eyevector.x = dot( eyeminusvertex, v_svector.xyz ); + eyevector.y = dot( eyeminusvertex, v_tvector.xyz ); + eyevector.z = dot( eyeminusvertex, v_normal.xyz ); + tf = ftetransform(); + gl_Position = tf; +} +#endif + +#ifdef FRAGMENT_SHADER +#include "sys/fog.h" +void main () +{ + vec2 stc; + vec3 out_f; + vec4 diffuse_f = texture2D(s_diffusemap, tex_c); + vec3 norm_f; + + norm_f = ( texture2D( s_normalmap, tex_c + vec2( e_time * 0.01, 0.0 ) ).xyz); + norm_f += ( texture2D( s_normalmap, tex_c - vec2( 0, e_time * 0.01 ) ).xyz); + norm_f -= 1.0 - ( 4.0 / 256.0 ); + norm_f = normalize( norm_f ); + + stc = (1.0 + (tf.xy / tf.w)) * 0.5; + + diffuse_f.rgb = texture2D(s_reflect, stc + norm_f.st).rgb; + gl_FragColor = diffuse_f; +} +#endif diff --git a/platform/base_textures.pk3dir/textures/sfx/heatsteam.mat b/platform/base_textures.pk3dir/textures/sfx/heatsteam.mat new file mode 100644 index 00000000..3cb9b1a1 --- /dev/null +++ b/platform/base_textures.pk3dir/textures/sfx/heatsteam.mat @@ -0,0 +1,26 @@ +// Vera Visions Material +{ + surfaceParm trans + surfaceParm nomarks + surfaceParm nolightmap + surfaceParm nonsolid + cull none + +if $programs + { + program heat + map "textures/sfx/steam.tga" + map "textures/sfx/normwobble.tga" + map $refraction + blendFunc blend + } +else + { + clampmap "textures/sfx/steam.tga" + rgbGen vertex + alphaGen vertex + blendFunc blend + } +endif +} + diff --git a/platform/base_textures.pk3dir/textures/sfx/normwobble.tga b/platform/base_textures.pk3dir/textures/sfx/normwobble.tga new file mode 100644 index 00000000..af252595 Binary files /dev/null and b/platform/base_textures.pk3dir/textures/sfx/normwobble.tga differ diff --git a/platform/base_textures.pk3dir/textures/sfx/steam.mat b/platform/base_textures.pk3dir/textures/sfx/steam.mat new file mode 100644 index 00000000..ce389499 --- /dev/null +++ b/platform/base_textures.pk3dir/textures/sfx/steam.mat @@ -0,0 +1,16 @@ +// Vera Visions Material +{ + surfaceParm trans + surfaceParm nomarks + surfaceParm nolightmap + surfaceParm nonsolid + cull none + + { + clampmap "textures/sfx/steam.tga" + rgbGen vertex + alphaGen vertex + blendFunc blend + } +} + diff --git a/platform/base_textures.pk3dir/textures/sfx/steam.tga b/platform/base_textures.pk3dir/textures/sfx/steam.tga new file mode 100644 index 00000000..7436850f Binary files /dev/null and b/platform/base_textures.pk3dir/textures/sfx/steam.tga differ diff --git a/src/client/entities.qc b/src/client/entities.qc index 262c63ed..a076c0d4 100644 --- a/src/client/entities.qc +++ b/src/client/entities.qc @@ -123,6 +123,9 @@ Entity_EntityUpdate(float type, float new) case ENT_FOG: env_fog_readentity(new); break; + case ENT_STEAM: + env_steam_ReadEntity(new); + break; case ENT_FOGCONTROLLER: env_fog_controller_readentity(new); break; diff --git a/src/gs-entbase/client/func_dustcloud.qc b/src/gs-entbase/client/func_dustcloud.qc index b24f13b0..820c22b0 100644 --- a/src/gs-entbase/client/func_dustcloud.qc +++ b/src/gs-entbase/client/func_dustcloud.qc @@ -116,11 +116,7 @@ func_dustcloud_cloud::func_dustcloud_cloud(void) float func_dustcloud::predraw(void) { - vector vecPlayer; - - int s = (float)getproperty(VF_ACTIVESEAT); - pSeat = &g_seats[s]; - vecPlayer = pSeat->m_vecPredictedOrigin; + vector vecPlayer = g_view.GetCameraOrigin(); if (checkpvs(vecPlayer, this) == FALSE) return (PREDRAW_NEXT); diff --git a/src/gs-entbase/client/func_dustmotes.qc b/src/gs-entbase/client/func_dustmotes.qc index 60cc3808..7168eca1 100644 --- a/src/gs-entbase/client/func_dustmotes.qc +++ b/src/gs-entbase/client/func_dustmotes.qc @@ -49,11 +49,7 @@ func_dustmotes::CanSpawn(bool clientSide) float func_dustmotes::predraw(void) { - vector vecPlayer; - - int s = (float)getproperty(VF_ACTIVESEAT); - pSeat = &g_seats[s]; - vecPlayer = pSeat->m_vecPredictedOrigin; + vector vecPlayer = g_view.GetCameraOrigin(); if (checkpvs(vecPlayer, this) == FALSE) return (PREDRAW_NEXT); diff --git a/src/gs-entbase/client/func_smokevolume.qc b/src/gs-entbase/client/func_smokevolume.qc index f5349ec8..c14ba68c 100644 --- a/src/gs-entbase/client/func_smokevolume.qc +++ b/src/gs-entbase/client/func_smokevolume.qc @@ -120,11 +120,7 @@ func_smokevolume_cloud::func_smokevolume_cloud(void) float func_smokevolume::predraw(void) { - vector vecPlayer; - - int s = (float)getproperty(VF_ACTIVESEAT); - pSeat = &g_seats[s]; - vecPlayer = pSeat->m_vecPredictedOrigin; + vector vecPlayer = g_view.GetCameraOrigin(); if (checkpvs(vecPlayer, this) == FALSE) return (PREDRAW_NEXT); diff --git a/src/gs-entbase/shared.src b/src/gs-entbase/shared.src index 339424d3..885c084e 100644 --- a/src/gs-entbase/shared.src +++ b/src/gs-entbase/shared.src @@ -13,6 +13,8 @@ shared/env_laser.qc shared/env_projectedtexture.qc shared/env_fog.qc shared/env_fog_controller.qc +//shared/env_fire.qc +shared/env_steam.qc shared/light_dynamic.qc shared/func_monitor.qc shared/func_illusionary.qc diff --git a/src/gs-entbase/shared/env_steam.qc b/src/gs-entbase/shared/env_steam.qc new file mode 100644 index 00000000..fd3dd099 --- /dev/null +++ b/src/gs-entbase/shared/env_steam.qc @@ -0,0 +1,498 @@ +/* + * 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 +{ + ENVSTEAM_EMISSIVE +}; + +enumflags +{ + EVSTEAM_CHANGED_ORIGIN, + EVSTEAM_CHANGED_ANGLE, + EVSTEAM_CHANGED_STATE, + EVSTEAM_CHANGED_TYPE, + EVSTEAM_CHANGED_SPREAD, + EVSTEAM_CHANGED_SPEED, + EVSTEAM_CHANGED_MINS, + EVSTEAM_CHANGED_MAXS, + EVSTEAM_CHANGED_RATE, + EVSTEAM_CHANGED_COLOR, + EVSTEAM_CHANGED_LENGTH, + EVSTEAM_CHANGED_ALPHA, + EVSTEAM_CHANGED_ROLL +}; + +#ifdef CLIENT +class env_steam_particle +{ +public: + void env_steam_particle(void); + + virtual float predraw(void); + +private: + float m_flStartSize; + float m_flEndSize; + float lifetime; + bool m_bEmissive; + bool m_bType; + + /* attributes */ + float m_flAlpha; + vector m_vecColor; + float m_flLifeTime; +}; + +float +env_steam_particle::predraw(void) +{ + float partSize; + float lerp = (lifetime / m_flLifeTime); + float alpha = m_flAlpha * lerp; + vector color; + + if (m_bEmissive) + color = m_vecColor; + else + color = (getlight(origin) / 255); + + partSize = Math_Lerp(m_flStartSize, m_flEndSize, lerp); + + makevectors(g_view.GetCameraAngle()); + + if (m_bType) + R_BeginPolygon("textures/sfx/heatsteam", 0, 0); + else + R_BeginPolygon("textures/sfx/steam", 0, 0); + + R_PolygonVertex(origin + v_right * partSize - v_up * partSize, [1,1], m_vecColor, alpha); + R_PolygonVertex(origin - v_right * partSize - v_up * partSize, [0,1], m_vecColor, alpha); + R_PolygonVertex(origin - v_right * partSize + v_up * partSize, [0,0], m_vecColor, alpha); + R_PolygonVertex(origin + v_right * partSize + v_up * partSize, [1,0], m_vecColor, alpha); + R_EndPolygon(); + + if (lerp >= 1.0f) { + remove(this); + } + + lifetime += frametime; + + return PREDRAW_NEXT; +} + +void +env_steam_particle::env_steam_particle(void) +{ + setsize(this, [0,0,0], [0,0,0]); + drawmask = MASK_ENGINE; + lifetime = 0.0f; +} +#endif + +/*!QUAKED env_steam (1 .5 0) (-8 -8 -8) (8 8 8) EMISSIVE +# OVERVIEW +Environmental steam jet entity. + +# KEYS +- "targetname" : Name +- "InitialState" : 0 - Start off, 1 - Start on +- "type" : Particle type: 0 - Default, 1 - Heat-wave effect +- "SpreadSpeed" : Amount of spread for the individual steam particles. +- "Speed" : Particle movement speed in units per second. +- "StartSize" : Initial size of the particles. +- "EndSize" : Final size of the particles before removal. +- "Rate" : Rate of particle emission in units per second. +- "rendercolor" : Color of the steam particles. Requires EMISSIVE spawnflag. +- "JetLength" : Lifetime of each particle in units, basically the length of the steam jet. +- "renderamt" : Alpha channel value of the steam particles. +- "rollspeed" : Rotation speed of the particles. + +# SPAWNFLAGS +- EMISSIVE (1) : Smoke will be colored after the 'rendercolor' field. + +# INPUTS +- "TurnOn" : Turn emitter on. +- "TurnOff" : Turn emitter off. +- "Toggle" : Toggle emitter on/off. +- "JetLength" : Change the length of the steam jet. +- "Rate" : Change the rate of the particles in units per second. +- "Speed" : Change the speed of the particles in units per second. +- "SpreadSpeed" : Change the amount of spread for the particles. + +# TRIVIA +This entity was introduced in Half-Life 2 (2004). +*/ +class +env_steam:NSPointTrigger +{ +#ifdef SERVER + bool m_bInitialState; +#else + float m_flNexTime; +#endif + + PREDICTED_BOOL(m_bEmissive) + PREDICTED_BOOL(m_bState) + PREDICTED_BOOL(m_bType) + PREDICTED_FLOAT(m_flSpread) + PREDICTED_FLOAT(m_flSpeed) + PREDICTED_FLOAT(m_flStartSize) + PREDICTED_FLOAT(m_flEndSize) + PREDICTED_FLOAT(m_flRate) + PREDICTED_VECTOR(m_vecColor) + PREDICTED_FLOAT(m_flLength) + PREDICTED_FLOAT(m_flAlpha) + PREDICTED_FLOAT(m_flRollSpeed) + + void env_steam(void); + +#ifdef SERVER + virtual void Save(float); + virtual void Restore(string,string); + virtual void SpawnKey(string strKey, string strValue); + virtual void Respawn(void); + virtual void Input(entity, string, string); + virtual void Trigger(entity, triggermode_t); + virtual void EvaluateEntity(void); + virtual float SendEntity(entity,float); +#else + virtual void ReceiveEntity(float,float); + virtual float predraw(void); +#endif +}; + +void +env_steam::env_steam(void) +{ +#ifdef SERVER + m_bEmissive = false; + m_bInitialState = false; + m_bState = false; + m_bType = false; + m_flSpread = 15.0f; + m_flSpeed = 120.0f; + m_flStartSize = 10.0f; + m_flEndSize = 25.0f; + m_flRate = 26.0f; + m_vecColor = [1.0, 1.0, 1.0]; + m_flLength = 80.0; + m_flAlpha = 1.0f; + m_flRollSpeed = 8.0f; +#endif +} + +#ifdef SERVER +void +env_steam::Save(float handle) +{ + super::Save(handle); + SaveBool(handle, "m_bEmissive", m_bEmissive); + SaveBool(handle, "m_bInitialState", m_bInitialState); + SaveBool(handle, "m_bState", m_bState); + SaveBool(handle, "m_bType", m_bType); + SaveFloat(handle, "m_flSpread", m_flSpread); + SaveFloat(handle, "m_flSpeed", m_flSpeed); + SaveFloat(handle, "m_flStartSize", m_flStartSize); + SaveFloat(handle, "m_flEndSize", m_flEndSize); + SaveFloat(handle, "m_flRate", m_flRate); + SaveVector(handle, "m_vecColor", m_vecColor); + SaveFloat(handle, "m_flLength", m_flLength); + SaveFloat(handle, "m_flAlpha", m_flAlpha); + SaveFloat(handle, "m_flRollSpeed", m_flRollSpeed); +} + +void +env_steam::Restore(string strKey, string strValue) +{ + switch (strKey) { + case "m_bEmissive": + m_bEmissive = ReadBool(strValue); + break; + case "m_bInitialState": + m_bInitialState = ReadBool(strValue); + break; + case "m_bState": + m_bState = ReadBool(strValue); + break; + case "m_bType": + m_bType = ReadBool(strValue); + break; + case "m_flSpread": + m_flSpread = ReadFloat(strValue); + break; + case "m_flSpeed": + m_flSpeed = ReadFloat(strValue); + break; + case "m_flStartSize": + m_flStartSize = ReadFloat(strValue); + break; + case "m_flEndSize": + m_flEndSize = ReadFloat(strValue); + break; + case "m_flRate": + m_flRate = ReadFloat(strValue); + break; + case "m_vecColor": + m_vecColor = ReadVector(strValue); + break; + case "m_flLength": + m_flLength = ReadFloat(strValue); + break; + case "m_flAlpha": + m_flAlpha = ReadFloat(strValue); + break; + case "m_flRollSpeed": + m_flRollSpeed = ReadFloat(strValue); + break; + default: + super::Restore(strKey, strValue); + } +} + +void +env_steam::SpawnKey(string strKey, string strValue) +{ + switch (strKey) { + case "InitialState": + m_bInitialState = stof(strValue); + break; + case "type": + m_bType = stof(strValue); + break; + case "SpreadSpeed": + m_flSpread = stof(strValue); + break; + case "Speed": + m_flSpeed = stof(strValue); + break; + case "StartSize": + m_flStartSize = stof(strValue); + break; + case "EndSize": + m_flEndSize = stof(strValue); + break; + case "Rate": + m_flRate = stof(strValue); + break; + case "rendercolor": + m_vecColor = stov(strValue) / 255; + break; + case "JetLength": + m_flLength = stof(strValue); + break; + case "renderamt": + m_flAlpha = stof(strValue) / 255; + break; + case "rollspeed": + m_flRollSpeed = stof(strValue); + break; + default: + super::SpawnKey(strKey, strValue); + } +} + +void +env_steam::Input(entity eAct, string strInput, string strData) +{ + switch (strInput) { + case "TurnOn": + Trigger(eAct, TRIG_ON); + break; + case "TurnOff": + Trigger(eAct, TRIG_OFF); + break; + case "Toggle": + Trigger(eAct, TRIG_TOGGLE); + break; + case "JetLength": + m_flLength = stof(strData); + break; + case "Rate": + m_flRate = stof(strData); + break; + case "Speed": + m_flSpeed = stof(strData); + break; + case "SpreadSpeed": + m_flSpread = stof(strData); + break; + default: + super::Input(eAct, strInput, strData); + } +} + +void +env_steam::Trigger(entity act, triggermode_t state) +{ + switch (state) { + case TRIG_OFF: + m_bState = false; + break; + case TRIG_ON: + m_bState = true; + break; + default: + m_bState == true ? false : true; + } +} + +void +env_steam::Respawn(void) +{ + SetSize([0,0,0], [0,0,0]); + SetOrigin(GetSpawnOrigin()); + + if (m_bInitialState) + m_bState = true; + if (HasSpawnFlags(1)) + m_bEmissive = true; +} + +void +env_steam::EvaluateEntity(void) +{ + EVALUATE_VECTOR(origin, 0, EVSTEAM_CHANGED_ORIGIN) + EVALUATE_VECTOR(origin, 1, EVSTEAM_CHANGED_ORIGIN) + EVALUATE_VECTOR(origin, 2, EVSTEAM_CHANGED_ORIGIN) + EVALUATE_VECTOR(angles, 0, EVSTEAM_CHANGED_ANGLE) + EVALUATE_VECTOR(angles, 1, EVSTEAM_CHANGED_ANGLE) + EVALUATE_VECTOR(angles, 2, EVSTEAM_CHANGED_ANGLE) + EVALUATE_FIELD(m_bState, EVSTEAM_CHANGED_STATE) + EVALUATE_FIELD(m_bEmissive, EVSTEAM_CHANGED_TYPE) + EVALUATE_FIELD(m_bType, EVSTEAM_CHANGED_TYPE) + EVALUATE_FIELD(m_flSpread, EVSTEAM_CHANGED_SPREAD) + EVALUATE_FIELD(m_flSpeed, EVSTEAM_CHANGED_SPEED) + EVALUATE_FIELD(m_flStartSize, EVSTEAM_CHANGED_MINS) + EVALUATE_FIELD(m_flEndSize , EVSTEAM_CHANGED_MAXS) + EVALUATE_FIELD(m_flRate, EVSTEAM_CHANGED_RATE) + EVALUATE_VECTOR(m_vecColor, 0, EVSTEAM_CHANGED_COLOR) + EVALUATE_VECTOR(m_vecColor, 1, EVSTEAM_CHANGED_COLOR) + EVALUATE_VECTOR(m_vecColor, 2, EVSTEAM_CHANGED_COLOR) + EVALUATE_FIELD(m_flLength, EVSTEAM_CHANGED_LENGTH) + EVALUATE_FIELD(m_flAlpha, EVSTEAM_CHANGED_ALPHA) + EVALUATE_FIELD(m_flRollSpeed, EVSTEAM_CHANGED_ROLL) +} + +float +env_steam::SendEntity(entity ePEnt, float flChanged) +{ + WriteByte(MSG_ENTITY, ENT_STEAM); + WriteFloat(MSG_ENTITY, flChanged); + + SENDENTITY_COORD(origin[0], EVSTEAM_CHANGED_ORIGIN) + SENDENTITY_COORD(origin[1], EVSTEAM_CHANGED_ORIGIN) + SENDENTITY_COORD(origin[2], EVSTEAM_CHANGED_ORIGIN) + SENDENTITY_COORD(angles[0], EVSTEAM_CHANGED_ANGLE) + SENDENTITY_COORD(angles[1], EVSTEAM_CHANGED_ANGLE) + SENDENTITY_COORD(angles[2], EVSTEAM_CHANGED_ANGLE) + SENDENTITY_BYTE(m_bState, EVSTEAM_CHANGED_STATE) + SENDENTITY_BYTE(m_bEmissive, EVSTEAM_CHANGED_TYPE) + SENDENTITY_BYTE(m_bType, EVSTEAM_CHANGED_TYPE) + SENDENTITY_FLOAT(m_flSpread, EVSTEAM_CHANGED_SPREAD) + SENDENTITY_FLOAT(m_flSpeed, EVSTEAM_CHANGED_SPEED) + SENDENTITY_FLOAT(m_flStartSize, EVSTEAM_CHANGED_MINS) + SENDENTITY_FLOAT(m_flEndSize , EVSTEAM_CHANGED_MAXS) + SENDENTITY_FLOAT(m_flRate, EVSTEAM_CHANGED_RATE) + SENDENTITY_COLOR(m_vecColor[0], EVSTEAM_CHANGED_COLOR) + SENDENTITY_COLOR(m_vecColor[1], EVSTEAM_CHANGED_COLOR) + SENDENTITY_COLOR(m_vecColor[2], EVSTEAM_CHANGED_COLOR) + SENDENTITY_FLOAT(m_flLength, EVSTEAM_CHANGED_LENGTH) + SENDENTITY_FLOAT(m_flAlpha, EVSTEAM_CHANGED_ALPHA) + SENDENTITY_FLOAT(m_flRollSpeed, EVSTEAM_CHANGED_ROLL) + + //print(sprintf("S (%x): %v %v %i\n", flChanged, origin, m_vecEndPos, m_iActive)); + + return (1); +} +#else +void +env_steam::ReceiveEntity(float flNew, float flChanged) +{ + READENTITY_COORD(origin[0], EVSTEAM_CHANGED_ORIGIN) + READENTITY_COORD(origin[1], EVSTEAM_CHANGED_ORIGIN) + READENTITY_COORD(origin[2], EVSTEAM_CHANGED_ORIGIN) + READENTITY_COORD(angles[0], EVSTEAM_CHANGED_ANGLE) + READENTITY_COORD(angles[1], EVSTEAM_CHANGED_ANGLE) + READENTITY_COORD(angles[2], EVSTEAM_CHANGED_ANGLE) + READENTITY_BYTE(m_bState, EVSTEAM_CHANGED_STATE) + READENTITY_BYTE(m_bEmissive, EVSTEAM_CHANGED_TYPE) + READENTITY_BYTE(m_bType, EVSTEAM_CHANGED_TYPE) + READENTITY_FLOAT(m_flSpread, EVSTEAM_CHANGED_SPREAD) + READENTITY_FLOAT(m_flSpeed, EVSTEAM_CHANGED_SPEED) + READENTITY_FLOAT(m_flStartSize, EVSTEAM_CHANGED_MINS) + READENTITY_FLOAT(m_flEndSize , EVSTEAM_CHANGED_MAXS) + READENTITY_FLOAT(m_flRate, EVSTEAM_CHANGED_RATE) + READENTITY_COLOR(m_vecColor[0], EVSTEAM_CHANGED_COLOR) + READENTITY_COLOR(m_vecColor[1], EVSTEAM_CHANGED_COLOR) + READENTITY_COLOR(m_vecColor[2], EVSTEAM_CHANGED_COLOR) + READENTITY_FLOAT(m_flLength, EVSTEAM_CHANGED_LENGTH) + READENTITY_FLOAT(m_flAlpha, EVSTEAM_CHANGED_ALPHA) + READENTITY_FLOAT(m_flRollSpeed, EVSTEAM_CHANGED_ROLL) + + //print(sprintf("R (%x): %v %v %i\n", flChanged, origin, m_vecEndPos, m_iActive)); + + drawmask = MASK_ENGINE; + setsize(this, [0,0,0], [0,0,0]); + setorigin(this, origin); +} + +float +env_steam::predraw(void) +{ + vector vecPlayer = g_view.GetCameraOrigin(); + + if (checkpvs(vecPlayer, this) == FALSE) + return (PREDRAW_NEXT); + + if (m_flNexTime > time) + return (PREDRAW_NEXT); + + env_steam_particle cloud = spawn(env_steam_particle); + setorigin(cloud, origin); + cloud.m_bEmissive = m_bEmissive; + cloud.m_bType = m_bType; + cloud.m_vecColor = m_vecColor; + cloud.m_flAlpha = m_flAlpha; + cloud.m_flStartSize = m_flStartSize; + cloud.m_flEndSize = m_flEndSize; + cloud.m_flLifeTime = m_flLength / m_flSpeed; + cloud.movetype = MOVETYPE_FLY; + makevectors(angles); + cloud.velocity = v_forward * m_flSpeed; + cloud.velocity += v_right * ((random() - 0.5) * m_flSpread); + cloud.velocity += v_up * ((random() - 0.5) * m_flSpread); + + m_flNexTime = time + (1/m_flRate); + + addentity(self); + return (PREDRAW_NEXT); +} +#endif + +#ifdef CLIENT +void +env_steam_ReadEntity(float isnew) +{ + env_steam laser = (env_steam)self; + float changedflags = readfloat(); + + if (isnew) + spawnfunc_env_steam(); + + laser.ReceiveEntity(isnew, changedflags); +} +#endif \ No newline at end of file diff --git a/src/gs-entbase/shared/point_spotlight.qc b/src/gs-entbase/shared/point_spotlight.qc index 947260d6..381f8fc8 100644 --- a/src/gs-entbase/shared/point_spotlight.qc +++ b/src/gs-entbase/shared/point_spotlight.qc @@ -59,6 +59,7 @@ public: void point_spotlight(void); #ifdef CLIENT + vector m_vecBeamEnd; float m_flBeamTrace; float m_flBeamHalfwidth; @@ -81,6 +82,9 @@ point_spotlight::UpdateBeamLength(void) { traceline(origin, origin - [0, 0, m_flBeamLength], MOVE_NORMAL, this); m_flBeamTrace = m_flBeamLength * trace_fraction; + + makevectors(angles); + m_vecBeamEnd = origin + v_forward * m_flBeamTrace; } float @@ -103,15 +107,18 @@ point_spotlight::predraw(void) coneAlpha = 0.0f; if (coneAlpha > 0.0) { + vector flareOrg = origin; makevectors(vectoangles(origin - vecPlayer)); + flareOrg += v_forward * - 32.0f; + R_BeginPolygon("textures/sfx/spot_flare"); - R_PolygonVertex(origin + v_right * m_flBeamHalfwidth - v_up * m_flBeamHalfwidth, + R_PolygonVertex(flareOrg + v_right * m_flBeamHalfwidth - v_up * m_flBeamHalfwidth, [1,1], m_vecColor * coneAlpha, 1.0f); - R_PolygonVertex(origin - v_right * m_flBeamHalfwidth - v_up * m_flBeamHalfwidth, + R_PolygonVertex(flareOrg - v_right * m_flBeamHalfwidth - v_up * m_flBeamHalfwidth, [0,1], m_vecColor * coneAlpha, 1.0f); - R_PolygonVertex(origin - v_right * m_flBeamHalfwidth + v_up * m_flBeamHalfwidth, + R_PolygonVertex(flareOrg - v_right * m_flBeamHalfwidth + v_up * m_flBeamHalfwidth, [0,0], m_vecColor * coneAlpha, 1.0f); - R_PolygonVertex(origin + v_right * m_flBeamHalfwidth + v_up * m_flBeamHalfwidth, + R_PolygonVertex(flareOrg + v_right * m_flBeamHalfwidth + v_up * m_flBeamHalfwidth, [1,0], m_vecColor * coneAlpha, 1.0f); R_EndPolygon(); } @@ -125,18 +132,34 @@ point_spotlight::predraw(void) /* beam */ if (coneAlpha > 0.0) { - vecPlayer[2] = origin[2]; + +#if 0 + //vecPlayer[2] = origin[2]; makevectors(vectoangles(origin - vecPlayer)); R_BeginPolygon("textures/sfx/spot_cone"); - R_PolygonVertex(origin + (v_right * m_flBeamHalfwidth) - (v_up * m_flBeamTrace), + R_PolygonVertex(m_vecBeamEnd + (v_right * m_flBeamHalfwidth), [1,1], m_vecColor * coneAlpha, 1.0f); - R_PolygonVertex(origin - (v_right * m_flBeamHalfwidth) - (v_up * m_flBeamTrace), + R_PolygonVertex(m_vecBeamEnd - (v_right * m_flBeamHalfwidth), [0,1], m_vecColor * coneAlpha, 1.0f); R_PolygonVertex(origin - (v_right * m_flBeamHalfwidth), [0,0], m_vecColor * coneAlpha, 1.0f); R_PolygonVertex(origin + (v_right * m_flBeamHalfwidth), [1,0], m_vecColor * coneAlpha, 1.0f); R_EndPolygon(); +#else + makevectors(getproperty(VF_CL_VIEWANGLES)); + setproperty(VF_ORIGIN, vecPlayer); + R_BeginPolygon("textures/sfx/spot_cone"); + R_PolygonVertex(origin, [1,0], m_vecColor * coneAlpha, 1.0f); + R_PolygonVertex(m_vecBeamEnd, [1,1], m_vecColor * coneAlpha, 1.0f); + R_EndPolygonRibbon(m_flBeamWidth, [-1,0]); + + /* debug */ + /*R_BeginPolygon("", 0, 0); + R_PolygonVertex(origin, [0,1], [0,1,0], 1.0f); + R_PolygonVertex(m_vecBeamEnd, [1,1], [0,1,0], 1.0f); + R_EndPolygon();*/ +#endif } } diff --git a/src/shared/entities.h b/src/shared/entities.h index e2cd855c..20c55cc8 100644 --- a/src/shared/entities.h +++ b/src/shared/entities.h @@ -35,6 +35,7 @@ typedef enum ENT_PROJECTEDTEXTURE, /**< of type env_projectedtexture */ ENT_SPOTLIGHT, /**< of type point_spotlight */ ENT_FOG, /*<< of type env_fog */ + ENT_STEAM, ENT_FOGCONTROLLER, /**< of type env_fog_controller */ ENT_LASER, /**< of type env_laser */ ENT_PARTSYSTEM, /**< of type info_particle_system */