env_steam: initial implementation of this Half-Life 2 entity.

This commit is contained in:
Marco Cawthorne 2023-09-13 00:29:31 -07:00
parent 5f070fa8c9
commit b77ec906f6
Signed by: eukara
GPG Key ID: CE2032F0A2882A22
13 changed files with 635 additions and 22 deletions

View File

@ -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

View File

@ -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
}

View File

@ -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
}
}

Binary file not shown.

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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
}
}

View File

@ -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 */