401 lines
9.2 KiB
Plaintext
401 lines
9.2 KiB
Plaintext
/*
|
|
* Copyright (c) 2016-2022 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.
|
|
*/
|
|
|
|
/*QUAKED env_sprite (1 0 0) (-8 -8 -8) (8 8 8) ENVS_STARTON ENVS_PLAYONCE
|
|
A sprite entity manager with fancy overrides.
|
|
|
|
-------- KEYS --------
|
|
"targetname" : Name
|
|
"target" : Target when triggered.
|
|
"killtarget" : Target to kill when triggered.
|
|
"angles" : Sets the pitch, yaw and roll angles of the sprite.
|
|
"model" : Path to the sprite in question.
|
|
"rendercolor" : Color modifier of the sprite.
|
|
"renderamt" : Alpha modifier of the sprite.
|
|
"rendermode" : Render mode of the sprite.
|
|
"framerate" : Rate between frames in seconds.
|
|
"scale" : Scale modifier of the sprite.
|
|
|
|
-------- SPAWNFLAGS --------
|
|
ENVS_STARTON : Start visible.
|
|
ENVS_PLAYONCE : Play once from start to finish, then make invisible.
|
|
|
|
-------- NOTES --------
|
|
Only used with an external sprite format, like SPR, SPRHL and SPR32.
|
|
|
|
-------- TRIVIA --------
|
|
This entity was introduced in Half-Life (1998).
|
|
*/
|
|
|
|
enumflags
|
|
{
|
|
SPRITE_CHANGED_ORIGIN,
|
|
SPRITE_CHANGED_MODELINDEX,
|
|
SPRITE_CHANGED_FRAMERATE,
|
|
SPRITE_CHANGED_SCALE,
|
|
SPRITE_CHANGED_RENDERMODE,
|
|
SPRITE_CHANGED_RENDERFX,
|
|
SPRITE_CHANGED_RENDERCOLOR,
|
|
SPRITE_CHANGED_RENDERAMT,
|
|
SPRITE_CHANGED_MATERIAL,
|
|
};
|
|
|
|
enumflags
|
|
{
|
|
ENVS_STARTON,
|
|
ENVS_PLAYONCE
|
|
};
|
|
|
|
class env_sprite:NSRenderableEntity
|
|
{
|
|
bool m_iIsShader;
|
|
int m_iToggled;
|
|
float m_flEffects;
|
|
|
|
PREDICTED_STRING(m_strMaterial)
|
|
PREDICTED_FLOAT(m_flFramerate)
|
|
|
|
#ifdef CLIENT
|
|
int m_iMaxFrame;
|
|
bool m_bLoops;
|
|
#endif
|
|
|
|
void(void) env_sprite;
|
|
|
|
virtual void(bool) SetFramerate;
|
|
|
|
#ifdef SERVER
|
|
virtual void Spawned(void);
|
|
virtual void Trigger(entity,int);
|
|
virtual void EvaluateEntity(void);
|
|
virtual float SendEntity(entity,float);
|
|
virtual void SpawnKey(string,string);
|
|
virtual void NetworkOnce(void);
|
|
#else
|
|
virtual float(void) predraw;
|
|
virtual void(void) think;
|
|
virtual void(float, float) ReceiveEntity;
|
|
virtual void(int) SetMaxFrame;
|
|
virtual void(bool) SetLoopFlag;
|
|
#endif
|
|
};
|
|
|
|
#ifdef SERVER
|
|
void
|
|
env_sprite::EvaluateEntity(void)
|
|
{
|
|
if (ATTR_CHANGED(origin)) {
|
|
SetSendFlags(SPRITE_CHANGED_ORIGIN);
|
|
}
|
|
if (ATTR_CHANGED(modelindex)) {
|
|
SetSendFlags(SPRITE_CHANGED_MODELINDEX);
|
|
}
|
|
if (ATTR_CHANGED(m_flFramerate)) {
|
|
SetSendFlags(SPRITE_CHANGED_FRAMERATE);
|
|
}
|
|
if (ATTR_CHANGED(scale)) {
|
|
SetSendFlags(SPRITE_CHANGED_SCALE);
|
|
}
|
|
if (ATTR_CHANGED(m_iRenderMode)) {
|
|
SetSendFlags(SPRITE_CHANGED_RENDERMODE);
|
|
}
|
|
if (ATTR_CHANGED(m_vecRenderColor)) {
|
|
SetSendFlags(SPRITE_CHANGED_RENDERCOLOR);
|
|
}
|
|
if (ATTR_CHANGED(m_flRenderAmt)) {
|
|
SetSendFlags(SPRITE_CHANGED_RENDERAMT);
|
|
}
|
|
if (ATTR_CHANGED(m_strMaterial)) {
|
|
SetSendFlags(SPRITE_CHANGED_MATERIAL);
|
|
}
|
|
|
|
SAVE_STATE(origin);
|
|
SAVE_STATE(modelindex);
|
|
SAVE_STATE(m_flFramerate);
|
|
SAVE_STATE(scale);
|
|
SAVE_STATE(m_iRenderMode);
|
|
SAVE_STATE(m_iRenderFX);
|
|
SAVE_STATE(m_vecRenderColor);
|
|
SAVE_STATE(m_flRenderAmt);
|
|
SAVE_STATE(m_strMaterial);
|
|
}
|
|
|
|
float
|
|
env_sprite::SendEntity(entity ePEnt, float flFlags)
|
|
{
|
|
if (clienttype(ePEnt) != CLIENTTYPE_REAL)
|
|
return (0);
|
|
|
|
if (HasSpawnFlags(ENVS_PLAYONCE))
|
|
return (0);
|
|
|
|
/* Delete it on the client. */
|
|
if (m_iToggled == FALSE)
|
|
return (0);
|
|
|
|
WriteByte(MSG_ENTITY, ENT_SPRITE);
|
|
WriteFloat(MSG_ENTITY, flFlags);
|
|
|
|
if (flFlags & SPRITE_CHANGED_ORIGIN) {
|
|
WriteCoord(MSG_ENTITY, origin[0]);
|
|
WriteCoord(MSG_ENTITY, origin[1]);
|
|
WriteCoord(MSG_ENTITY, origin[2]);
|
|
}
|
|
|
|
if (flFlags & SPRITE_CHANGED_MODELINDEX) {
|
|
WriteFloat(MSG_ENTITY, modelindex);
|
|
}
|
|
if (flFlags & SPRITE_CHANGED_FRAMERATE) {
|
|
WriteFloat(MSG_ENTITY, m_flFramerate);
|
|
}
|
|
if (flFlags & SPRITE_CHANGED_SCALE) {
|
|
WriteFloat(MSG_ENTITY, scale);
|
|
}
|
|
if (flFlags & SPRITE_CHANGED_RENDERMODE) {
|
|
WriteByte(MSG_ENTITY, m_iRenderMode);
|
|
}
|
|
if (flFlags & SPRITE_CHANGED_RENDERFX) {
|
|
WriteByte(MSG_ENTITY, m_iRenderFX);
|
|
}
|
|
if (flFlags & SPRITE_CHANGED_RENDERCOLOR) {
|
|
WriteFloat(MSG_ENTITY, m_vecRenderColor[0]);
|
|
WriteFloat(MSG_ENTITY, m_vecRenderColor[1]);
|
|
WriteFloat(MSG_ENTITY, m_vecRenderColor[2]);
|
|
}
|
|
if (flFlags & SPRITE_CHANGED_RENDERAMT) {
|
|
WriteFloat(MSG_ENTITY, m_flRenderAmt);
|
|
}
|
|
if (flFlags & SPRITE_CHANGED_MATERIAL) {
|
|
WriteString(MSG_ENTITY, m_strMaterial);
|
|
}
|
|
|
|
return (1);
|
|
}
|
|
|
|
void
|
|
env_sprite::NetworkOnce(void)
|
|
{
|
|
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
|
WriteByte(MSG_MULTICAST, EV_SPRITE);
|
|
WriteCoord(MSG_MULTICAST, origin[0]);
|
|
WriteCoord(MSG_MULTICAST, origin[1]);
|
|
WriteCoord(MSG_MULTICAST, origin[2]);
|
|
WriteFloat(MSG_MULTICAST, modelindex);
|
|
WriteFloat(MSG_MULTICAST, m_flFramerate);
|
|
WriteFloat(MSG_MULTICAST, scale);
|
|
WriteByte(MSG_MULTICAST, m_iRenderMode);
|
|
WriteByte(MSG_MULTICAST, m_iRenderFX);
|
|
WriteFloat(MSG_MULTICAST, m_vecRenderColor[0]);
|
|
WriteFloat(MSG_MULTICAST, m_vecRenderColor[1]);
|
|
WriteFloat(MSG_MULTICAST, m_vecRenderColor[2]);
|
|
WriteFloat(MSG_MULTICAST, m_flRenderAmt);
|
|
WriteString(MSG_MULTICAST, m_strMaterial);
|
|
|
|
msg_entity = this;
|
|
multicast(origin, MULTICAST_PVS);
|
|
}
|
|
|
|
/* TODO: Implement state */
|
|
void
|
|
env_sprite::Trigger(entity act, int state)
|
|
{
|
|
if (HasSpawnFlags(ENVS_PLAYONCE)) {
|
|
NetworkOnce();
|
|
} else {
|
|
m_iToggled = 1 - m_iToggled;
|
|
SendFlags = 1;
|
|
}
|
|
}
|
|
|
|
void
|
|
env_sprite::SpawnKey(string strKey, string strValue)
|
|
{
|
|
switch (strKey) {
|
|
case "shader":
|
|
case "material":
|
|
m_strMaterial = strValue;
|
|
break;
|
|
case "framerate":
|
|
m_flFramerate = stof(strValue);
|
|
break;
|
|
default:
|
|
super::SpawnKey(strKey, strValue);
|
|
}
|
|
}
|
|
|
|
void
|
|
env_sprite::Spawned(void)
|
|
{
|
|
super::Spawned();
|
|
|
|
m_iToggled = (HasSpawnFlags(ENVS_STARTON) > 0) ? TRUE : FALSE;
|
|
|
|
/* how pointless this would be otherwise. */
|
|
if (!targetname)
|
|
m_iToggled = TRUE;
|
|
}
|
|
#else
|
|
float
|
|
env_sprite::predraw(void)
|
|
{
|
|
if (m_strMaterial == __NULL__) {
|
|
return super::predraw();
|
|
}
|
|
|
|
int s = (float)getproperty(VF_ACTIVESEAT);
|
|
pSeat = &g_seats[s];
|
|
vector vecPlayer = pSeat->m_vecPredictedOrigin;
|
|
makevectors(view_angles);
|
|
makevectors(vectoangles(origin - vecPlayer));
|
|
vector forg = origin + (v_forward * -16);
|
|
vector fsize = [64,64];
|
|
|
|
traceline(origin, vecPlayer, MOVE_WORLDONLY, this);
|
|
|
|
if (trace_fraction < 1.0)
|
|
return (PREDRAW_NEXT);
|
|
|
|
R_BeginPolygon(m_strMaterial, 1, 0);
|
|
R_PolygonVertex(forg + v_right * fsize[0] - v_up * fsize[1],
|
|
[1,1], m_vecRenderColor, 1.0);
|
|
R_PolygonVertex(forg - v_right * fsize[0] - v_up * fsize[1],
|
|
[0,1], m_vecRenderColor, 1.0);
|
|
R_PolygonVertex(forg - v_right * fsize[0] + v_up * fsize[1],
|
|
[0,0], m_vecRenderColor, 1.0);
|
|
R_PolygonVertex(forg + v_right * fsize[0] + v_up * fsize[1],
|
|
[1,0], m_vecRenderColor, 1.0);
|
|
R_EndPolygon();
|
|
|
|
addentity(this);
|
|
|
|
return (PREDRAW_NEXT);
|
|
}
|
|
|
|
void
|
|
env_sprite::think(void)
|
|
{
|
|
if (frame >= (m_iMaxFrame-1)) {
|
|
if (m_bLoops == 0) {
|
|
Destroy();
|
|
return;
|
|
} else {
|
|
frame = 0;
|
|
}
|
|
} else {
|
|
frame += 1;
|
|
}
|
|
|
|
nextthink = time + (1 / m_flFramerate);
|
|
}
|
|
|
|
void
|
|
env_sprite::ReceiveEntity(float flNew, float flFlags)
|
|
{
|
|
if (flFlags & SPRITE_CHANGED_ORIGIN) {
|
|
origin[0] = readcoord();
|
|
origin[1] = readcoord();
|
|
origin[2] = readcoord();
|
|
}
|
|
if (flFlags & SPRITE_CHANGED_MODELINDEX) {
|
|
modelindex = readfloat();
|
|
}
|
|
if (flFlags & SPRITE_CHANGED_FRAMERATE) {
|
|
m_flFramerate = readfloat();
|
|
}
|
|
if (flFlags & SPRITE_CHANGED_SCALE) {
|
|
scale = readfloat();
|
|
}
|
|
if (flFlags & SPRITE_CHANGED_RENDERMODE) {
|
|
m_iRenderMode = readbyte();
|
|
}
|
|
if (flFlags & SPRITE_CHANGED_RENDERFX) {
|
|
m_iRenderFX = readbyte();
|
|
}
|
|
if (flFlags & SPRITE_CHANGED_RENDERCOLOR) {
|
|
m_vecRenderColor[0] = readfloat();
|
|
m_vecRenderColor[1] = readfloat();
|
|
m_vecRenderColor[2] = readfloat();
|
|
}
|
|
if (flFlags & SPRITE_CHANGED_RENDERAMT) {
|
|
m_flRenderAmt = readfloat();
|
|
}
|
|
if (flFlags & SPRITE_CHANGED_MATERIAL) {
|
|
m_strMaterial = readstring();
|
|
}
|
|
|
|
drawmask = MASK_ENGINE;
|
|
nextthink = time + (1 / m_flFramerate);
|
|
m_iMaxFrame = modelframecount(modelindex);
|
|
m_bLoops = 1; /* repeats */
|
|
setorigin(this, origin);
|
|
}
|
|
|
|
void
|
|
env_sprite::SetMaxFrame(int fr)
|
|
{
|
|
m_iMaxFrame = fr;
|
|
}
|
|
|
|
void
|
|
env_sprite::SetLoopFlag(bool loops)
|
|
{
|
|
m_bLoops = loops;
|
|
}
|
|
#endif
|
|
|
|
|
|
void
|
|
env_sprite::SetFramerate(bool flag)
|
|
{
|
|
|
|
}
|
|
|
|
void
|
|
env_sprite::env_sprite(void)
|
|
{
|
|
m_iIsShader = false;
|
|
m_flFramerate = 10;
|
|
m_strMaterial = __NULL__;
|
|
scale = 1.0f;
|
|
}
|
|
|
|
#ifdef CLIENT
|
|
void
|
|
EnvSprite_ParseEvent(void)
|
|
{
|
|
env_sprite spr = spawn(env_sprite);
|
|
spr.origin[0] = readcoord();
|
|
spr.origin[1] = readcoord();
|
|
spr.origin[2] = readcoord();
|
|
spr.modelindex = readfloat();
|
|
spr.m_flFramerate = readfloat();
|
|
spr.scale = readfloat();
|
|
spr.m_iRenderMode = readbyte();
|
|
spr.m_iRenderFX = readbyte();
|
|
spr.m_vecRenderColor[0] = readfloat();
|
|
spr.m_vecRenderColor[1] = readfloat();
|
|
spr.m_vecRenderColor[2] = readfloat();
|
|
spr.m_flRenderAmt = readfloat();
|
|
spr.m_strMaterial = readstring();
|
|
|
|
spr.drawmask = MASK_ENGINE;
|
|
spr.nextthink = time + (1 / spr.m_flFramerate);
|
|
spr.m_iMaxFrame = modelframecount(spr.modelindex);
|
|
spr.m_bLoops = 0; /* does not repeat */
|
|
setorigin(spr, spr.origin);
|
|
}
|
|
#endif
|