Networked versions of func_conveyor, trigger_push. Bounce pads should be much nicer.

This commit is contained in:
Marco Cawthorne 2023-03-18 17:49:12 -07:00
parent c1a098b493
commit 7b42befcb3
Signed by: eukara
GPG Key ID: CE2032F0A2882A22
22 changed files with 927 additions and 453 deletions

View File

@ -25,50 +25,50 @@
/** Draws a crosshair on the screen with the desired material and size.
@param strMat is the material to use.
@param vecSize is the size in pixels it is meant to take up on screen. */
void Cross_Draw(string strMat, vector vecSize);
@param materialPath is the material to use.
@param sizeXY is the size in pixels it is meant to take up on screen. */
void Cross_Draw(string materialPath, vector sizeXY);
/** Draw a given crosshair on the screen, with variable color.
@param strMat is the material to use.
@param vecSize is the size in pixels it is meant to take up on screen.
@param vecColor is the normalized color values to tint the surface with.*/
void Cross_DrawRGB(string strMat, vector vecSize, vector vecColor);
@param materialPath is the material to use.
@param sizeXY is the size in pixels it is meant to take up on screen.
@param colorRGB is the normalized color values to tint the surface with.*/
void Cross_DrawRGB(string materialPath, vector sizeXY, vector colorRGB);
/** Draw a given crosshair on the screen, with variable color and alpha.
@param strMat is the material to use.
@param vecSize is the size in pixels it is meant to take up on screen.
@param vecColor is the normalized color values to tint the surface with.
@param flAlpha is the alpha values to use on the whole surface.*/
void Cross_DrawRGBA(string strMat, vector vecSize, vector vecColor, float flAlpha);
@param materialPath is the material to use.
@param sizeXY is the size in pixels it is meant to take up on screen.
@param colorRGB is the normalized color values to tint the surface with.
@param alphaValue is the alpha values to use on the whole surface.*/
void Cross_DrawRGBA(string materialPath, vector sizeXY, vector colorRGB, float alphaValue);
/** Draw a given crosshair on the screen, of only a section from a material.
@param strMat is the material to use.
@param vecSize is the size in pixels it is meant to take up on screen.
@param vecSrcPos is a normalized starting position within the material from which we should start drawing from.
@param vecSrcSize is the normalized size within the material from which we should draw from.*/
void Cross_DrawSub(string strMat, vector vecSize, vector vecSrcPos, vector vecSrcSize);
@param materialPath is the material to use.
@param sizeXY is the size in pixels it is meant to take up on screen.
@param sourcePosXY is a normalized starting position within the material from which we should start drawing from.
@param sourceSizeXY is the normalized size within the material from which we should draw from.*/
void Cross_DrawSub(string materialPath, vector sizeXY, vector sourcePosXY, vector sourceSizeXY);
/** Draw a given crosshair on the screen, of only a section from a material, with variable color.
@param strMat is the material to use.
@param vecSize is the size in pixels it is meant to take up on screen.
@param vecSrcPos is a normalized starting position within the material from which we should start drawing from.
@param vecSrcSize is the normalized size within the material from which we should draw from.
@param vecColor is the normalized color values to tint the surface with.*/
void Cross_DrawSubRGB(string strMat, vector vecSize, vector vecSrcPos, vector vecSrcSize, vector vecColor);
@param materialPath is the material to use.
@param sizeXY is the size in pixels it is meant to take up on screen.
@param sourcePosXY is a normalized starting position within the material from which we should start drawing from.
@param sourceSizeXY is the normalized size within the material from which we should draw from.
@param colorRGB is the normalized color values to tint the surface with.*/
void Cross_DrawSubRGB(string materialPath, vector sizeXY, vector sourcePosXY, vector sourceSizeXY, vector colorRGB);
/** Draw a given crosshair on the screen, of only a section from a material, with variable color/alpha.
@param strMat is the material to use.
@param vecSize is the size in pixels it is meant to take up on screen.
@param vecSrcPos is a normalized starting position within the material from which we should start drawing from.
@param vecSrcSize is the normalized size within the material from which we should draw from.
@param vecColor is the normalized color values to tint the surface with.
@param flAlpha is the alpha values to use on the whole surface.*/
void Cross_DrawSubRGBA(string strMat, vector vecSize, vector vecSrcPos, vector vecSrcSize, vector vecColor, float flAlpha);
@param materialPath is the material to use.
@param sizeXY is the size in pixels it is meant to take up on screen.
@param sourcePosXY is a normalized starting position within the material from which we should start drawing from.
@param sourceSizeXY is the normalized size within the material from which we should draw from.
@param colorRGB is the normalized color values to tint the surface with.
@param alphaValue is the alpha values to use on the whole surface.*/
void Cross_DrawSubRGBA(string materialPath, vector sizeXY, vector sourcePosXY, vector sourceSizeXY, vector colorRGB, float alphaValue);

View File

@ -15,52 +15,52 @@
*/
void
Cross_Draw(string strMat, vector vecSize)
Cross_Draw(string materialPath, vector sizeXY)
{
Cross_DrawSubRGBA(strMat, vecSize, [0,0], [1,1], [1.0f, 1.0f, 1.0f], 1.0f);
Cross_DrawSubRGBA(materialPath, sizeXY, [0,0], [1,1], [1.0f, 1.0f, 1.0f], 1.0f);
}
void
Cross_DrawRGB(string strMat, vector vecSize, vector vecColor)
Cross_DrawRGB(string materialPath, vector sizeXY, vector colorRGB)
{
Cross_DrawSubRGBA(strMat, vecSize, [0,0], [1,1], vecColor, 1.0f);
Cross_DrawSubRGBA(materialPath, sizeXY, [0,0], [1,1], colorRGB, 1.0f);
}
void
Cross_DrawRGBA(string strMat, vector vecSize, vector vecColor, float flAlpha)
Cross_DrawRGBA(string materialPath, vector sizeXY, vector colorRGB, float alphaValue)
{
Cross_DrawSubRGBA(strMat, vecSize, [0,0], [1,1], vecColor, flAlpha);
Cross_DrawSubRGBA(materialPath, sizeXY, [0,0], [1,1], colorRGB, alphaValue);
}
void
Cross_DrawSub(string strMat, vector vecSize, vector vecSrcPos, vector vecSrcSize)
Cross_DrawSub(string materialPath, vector sizeXY, vector sourcePosXY, vector sourceSizeXY)
{
Cross_DrawSubRGBA(strMat, vecSize, vecSrcPos, vecSrcSize, [1.0f, 1.0f, 1.0f], 1.0f);
Cross_DrawSubRGBA(materialPath, sizeXY, sourcePosXY, sourceSizeXY, [1.0f, 1.0f, 1.0f], 1.0f);
}
void
Cross_DrawSubRGB(string strMat, vector vecSize, vector vecSrcPos, vector vecSrcSize, vector vecColor)
Cross_DrawSubRGB(string materialPath, vector sizeXY, vector sourcePosXY, vector sourceSizeXY, vector colorRGB)
{
Cross_DrawSubRGBA(strMat, vecSize, vecSrcPos, vecSrcSize, vecColor, 1.0f);
Cross_DrawSubRGBA(materialPath, sizeXY, sourcePosXY, sourceSizeXY, colorRGB, 1.0f);
}
void
Cross_DrawSubRGBA(string strMat, vector vecSize, vector vecSrcPos, vector vecSrcSize, vector vecColor, float flAlpha)
Cross_DrawSubRGBA(string materialPath, vector sizeXY, vector sourcePosXY, vector sourceSizeXY, vector colorRGB, float alphaValue)
{
static vector cross_pos;
static vector crossPos;
if (cvar("pm_thirdPerson") < 1) {
cross_pos = g_hudmins + (g_hudres / 2) + [-(vecSize[0]/2),-(vecSize[1]/2)];
cross_pos[0] = rint(cross_pos[0]);
cross_pos[1] = rint(cross_pos[1]);
crossPos = g_hudmins + (g_hudres / 2) + [-(sizeXY[0]/2),-(sizeXY[1]/2)];
crossPos[0] = rint(crossPos[0]);
crossPos[1] = rint(crossPos[1]);
/* terrible hack to deal with engine's bad autoscale positioning */
if (cvar("vid_conautoscale") > 1) {
cross_pos[0] -= 0.25f;
cross_pos[1] -= 0.25f;
crossPos[0] -= 0.25f;
crossPos[1] -= 0.25f;
}
drawsubpic(cross_pos, vecSize, strMat, vecSrcPos, vecSrcSize, vecColor, flAlpha, DRAWFLAG_NORMAL);
drawsubpic(crossPos, sizeXY, materialPath, sourcePosXY, sourceSizeXY, colorRGB, alphaValue, DRAWFLAG_NORMAL);
} else {
vector vecSrc;
vector vecDst;
@ -70,9 +70,9 @@ Cross_DrawSubRGBA(string strMat, vector vecSize, vector vecSrcPos, vector vecSrc
makevectors(view_angles);
vecDst = (vecSrc + v_forward * 4096);
traceline(vecSrc, vecDst, MOVE_NORMAL, pSeat->m_ePlayer);
cross_pos = project(trace_endpos) + [-(vecSize[0]/2),-(vecSize[1]/2)];
cross_pos[0] = rint(cross_pos[0]);
cross_pos[1] = rint(cross_pos[1]);
drawsubpic(cross_pos, vecSize, strMat, vecSrcPos, vecSrcSize, vecColor, flAlpha, DRAWFLAG_NORMAL);
crossPos = project(trace_endpos) + [-(sizeXY[0]/2),-(sizeXY[1]/2)];
crossPos[0] = rint(crossPos[0]);
crossPos[1] = rint(crossPos[1]);
drawsubpic(crossPos, sizeXY, materialPath, sourcePosXY, sourceSizeXY, colorRGB, alphaValue, DRAWFLAG_NORMAL);
}
}

View File

@ -130,6 +130,12 @@ Entity_EntityUpdate(float type, float new)
case ENT_BUBBLES:
env_bubbles_ReadEntity(new);
break;
case ENT_CONVEYOR:
func_conveyor_ReadEntity(new);
break;
case ENT_PUSH:
trigger_push_ReadEntity(new);
break;
default:
//error(sprintf("Unknown entity type update received. (%d)\n", t));
}

View File

@ -36,6 +36,8 @@ void
CSQC_Init(float apilevel, string enginename, float engineversion)
{
print("--------- Initializing Client Game ----------\n");
print("Built: " __DATE__ " " __TIME__"\n");
print("QCC: " __QCCVER__ "\n");
for (int i = 0; i < 4; i++) {
g_viewSeats[i] = spawn(NSView);

View File

@ -43,7 +43,6 @@ server/func_tank.qc
server/func_tankcontrols.qc
server/func_pushable.qc
server/func_wall_toggle.qc
server/func_conveyor.qc
server/func_rotating.qc
server/func_rot_button.qc
server/func_physbox.qc
@ -75,7 +74,6 @@ server/trigger_changetarget.qc
server/trigger_look.qc
server/trigger_once.qc
server/trigger_multiple.qc
server/trigger_push.qc
server/trigger_teleport.qc
server/trigger_transition.qc
server/trigger_playerfreeze.qc

View File

@ -1,179 +0,0 @@
/*
* 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.
*/
#define SF_CONVEYOR_VISUAL 1
#define SF_CONVEYOR_NOTSOLID 2
/*!QUAKED func_conveyor (0 .5 .8) ? SF_CONVEYOR_VISUAL SF_CONVEYOR_NOTSOLID
# OVERVIEW
A conveyor belt entity. Texture will move along in the direction and speed of the conveyor.
# KEYS
- "targetname" : Name
- "target" : Target when triggered.
- "killtarget" : Target to kill when triggered.
# SPAWNFLAGS
- SF_CONVEYOR_VISUAL (1) : This conveyor does not affect entities physically.
- SF_CONVEYOR_NOTSOLID (2) : This conveyor is non-solid.
# TRIVIA
This entity was introduced in Quake II (1997).
*/
class
func_conveyor:NSRenderableEntity
{
float m_flSpeed;
vector m_vecMoveDir;
public:
void(void) func_conveyor;
virtual void Save(float);
virtual void Restore(string,string);
virtual void Respawn(void);
virtual void Trigger(entity, triggermode_t);
virtual void Touch(entity);
virtual void SetMovementDirection(void);
virtual void Input(entity, string, string);
virtual void SpawnKey(string,string);
};
void
func_conveyor::func_conveyor(void)
{
m_flSpeed = 0.0f;
m_vecMoveDir = [0.0f, 0.0f, 0.0f];
}
void
func_conveyor::Save(float handle)
{
super::Save(handle);
SaveFloat(handle, "m_flSpeed", m_flSpeed);
SaveVector(handle, "m_vecMoveDir", m_vecMoveDir);
}
void
func_conveyor::Restore(string strKey, string strValue)
{
switch (strKey) {
case "m_flSpeed":
m_flSpeed = ReadFloat(strValue);
break;
case "m_vecMoveDir":
m_vecMoveDir = ReadVector(strValue);
break;
default:
super::Restore(strKey, strValue);
}
}
void
func_conveyor::SpawnKey(string strKey, string strValue)
{
switch (strKey) {
case "speed":
m_flSpeed = stof(strValue);
break;
default:
super::SpawnKey(strKey, strValue);
break;
}
}
void
func_conveyor::Respawn(void)
{
if (!m_flSpeed)
m_flSpeed = 100;
RestoreAngles();
SetMovementDirection();
ClearAngles();
SetMovetype(MOVETYPE_NONE);
SetSolid(SOLID_BSP);
SetModel(GetSpawnModel());
Trigger(this, TRIG_ON);
if (HasSpawnFlags(SF_CONVEYOR_NOTSOLID)) {
SetSolid(SOLID_NOT);
SetSkin(0);
}
}
void
func_conveyor::SetMovementDirection(void)
{
if (angles == [0,-1,0]) {
m_vecMoveDir = [0,0,1];
} else if (angles == [0,-2,0]) {
m_vecMoveDir = [0,0,-1];
} else {
makevectors(angles);
m_vecMoveDir = v_forward;
}
}
void
func_conveyor::Touch(entity eToucher)
{
if (HasSpawnFlags(SF_CONVEYOR_VISUAL))
return;
eToucher.basevelocity = m_vecMoveDir * (m_flSpeed);
print("touchy\n");
print(sprintf("want basevel: %v\n", eToucher.basevelocity));
}
void
func_conveyor::Trigger(entity act, triggermode_t state)
{
switch (state) {
case TRIG_ON:
m_flSpeed = fabs(m_flSpeed);
break;
case TRIG_OFF:
m_flSpeed = -fabs(m_flSpeed);
break;
default:
m_flSpeed = -m_flSpeed;
break;
}
/* changes direction */
glowmod[1] = 0.5;
glowmod[2] = m_flSpeed / 1024;
SetSendFlags(RDENT_CHANGED_RENDERCOLOR);
}
void
func_conveyor::Input(entity eAct, string strInput, string strData)
{
switch (strInput) {
case "ToggleDirection":
Trigger(eAct, TRIG_TOGGLE);
break;
case "SetSpeed":
m_flSpeed = stof(strData);
break;
default:
super::Input(eAct, strInput, strData);
}
}

View File

@ -1,173 +0,0 @@
/*
* 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.
*/
enumflags
{
TP_ONCE,
TP_STARTOFF
};
/*!QUAKED trigger_push (.5 .5 .5) ? TP_ONCE TP_STARTOFF
# OVERVIEW
Pushes anything in its volume into a direction of your choosing.
# KEYS
- "targetname" : Name
- "speed" : The speed (units per second) it'll apply to touchers.
- "angles" : Sets the direction of the push.
# SPAWNFLAGS
- TP_ONCE (1) : Only emit a single push once before disabling itself.
- TP_STARTOFF (2) : Needs to be triggered first in order to function.
# TRIVIA
This entity was introduced in Quake (1996).
*/
class
trigger_push:NSBrushTrigger
{
public:
void trigger_push(void);
virtual void Save(float);
virtual void Restore(string,string);
virtual void SpawnKey(string,string);
virtual void Respawn(void);
virtual void Trigger(entity,triggermode_t);
virtual void Touch(entity);
virtual void SetMovementDirection(void);
private:
vector m_vecMoveDir;
float m_flSpeed;
};
void
trigger_push::trigger_push(void)
{
m_vecMoveDir = [0,0,0];
m_flSpeed = 100;
}
void
trigger_push::Save(float handle)
{
super::Save(handle);
SaveVector(handle, "m_vecMoveDir", m_vecMoveDir);
SaveFloat(handle, "m_flSpeed", m_flSpeed);
}
void
trigger_push::Restore(string strKey, string strValue)
{
switch (strKey) {
case "m_vecMoveDir":
m_vecMoveDir = ReadVector(strValue);
break;
case "m_flSpeed":
m_flSpeed = ReadFloat(strValue);
break;
default:
super::Restore(strKey, strValue);
}
}
void
trigger_push::SpawnKey(string strKey, string strValue)
{
switch (strKey) {
case "speed":
m_flSpeed = stof(strValue);
break;
default:
super::SpawnKey(strKey, strValue);
}
}
void
trigger_push::Respawn(void)
{
InitBrushTrigger();
RestoreAngles();
SetMovementDirection();
ClearAngles();
if (HasSpawnFlags(TP_STARTOFF)) {
SetSolid(SOLID_NOT);
}
}
void
trigger_push::Trigger(entity act, triggermode_t state)
{
switch (state) {
case TRIG_OFF:
SetSolid(SOLID_NOT);
break;
case TRIG_ON:
SetSolid(SOLID_TRIGGER);
break;
default:
SetSolid(solid == SOLID_NOT ? SOLID_TRIGGER : SOLID_NOT);
}
}
void
trigger_push::Touch(entity eToucher)
{
eActivator = eToucher;
switch(eToucher.movetype) {
case MOVETYPE_NONE:
case MOVETYPE_PUSH:
case MOVETYPE_NOCLIP:
case MOVETYPE_FOLLOW:
return;
}
/* trigger_push is not supposed to work underwater */
if (eToucher.waterlevel > 1)
return;
if (eToucher.solid != SOLID_NOT && eToucher.solid != SOLID_BSP) {
vector vecPush;
vecPush = (m_flSpeed * m_vecMoveDir);
if (HasSpawnFlags(TP_ONCE)) {
eToucher.velocity += vecPush;
if (eToucher.velocity[2] > 0) {
eToucher.flags &= ~FL_ONGROUND;
}
SetSolid(SOLID_NOT);
} else {
eToucher.basevelocity += vecPush;
}
}
}
void
trigger_push::SetMovementDirection(void)
{
if (GetSpawnAngles() == [0,-1,0]) {
m_vecMoveDir = [0,0,1];
} else if (angles == [0,-2,0]) {
m_vecMoveDir = [0,0,-1];
} else {
makevectors(GetSpawnAngles());
m_vecMoveDir = v_forward;
}
}

View File

@ -22,8 +22,11 @@ shared/func_tankmortar.qc
shared/trigger_camera.qc
shared/trigger_gravity.qc
shared/info_particle_system.qc
shared/info_waypoint.qc
shared/prop_physics_multiplayer.qc
shared/prop_vehicle_driveable.qc
shared/trigger_push.qc
shared/func_conveyor.qc
shared/prop_rope.qc
shared/worldspawn.qc
#endlist

View File

@ -0,0 +1,390 @@
/*
* 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.
*/
typedef enumflags
{
CONVEYOR_CHANGED_ORIGIN_X,
CONVEYOR_CHANGED_ORIGIN_Y,
CONVEYOR_CHANGED_ORIGIN_Z,
CONVEYOR_CHANGED_ANGLES_X,
CONVEYOR_CHANGED_ANGLES_Y,
CONVEYOR_CHANGED_ANGLES_Z,
CONVEYOR_CHANGED_MODELINDEX,
CONVEYOR_CHANGED_SIZE,
CONVEYOR_CHANGED_FRAME,
CONVEYOR_CHANGED_SPAWNFLAGS,
CONVEYOR_CHANGED_SOLIDMOVETYPE,
CONVEYOR_CHANGED_VELOCITY,
CONVEYOR_CHANGED_ANGULARVELOCITY,
CONVEYOR_CHANGED_RENDERCOLOR,
CONVEYOR_CHANGED_RENDERAMT,
CONVEYOR_CHANGED_RENDERMODE,
CONVEYOR_CHANGED_SPEED,
CONVEYOR_CHANGED_MOVEDIR
} func_conveyor_changed_t;
#define SF_CONVEYOR_VISUAL 1
#define SF_CONVEYOR_NOTSOLID 2
/*!QUAKED func_conveyor (0 .5 .8) ? SF_CONVEYOR_VISUAL SF_CONVEYOR_NOTSOLID
# OVERVIEW
A conveyor belt entity. Texture will move along in the direction and speed of the conveyor.
# KEYS
- "targetname" : Name
- "target" : Target when triggered.
- "killtarget" : Target to kill when triggered.
# SPAWNFLAGS
- SF_CONVEYOR_VISUAL (1) : This conveyor does not affect entities physically.
- SF_CONVEYOR_NOTSOLID (2) : This conveyor is non-solid.
# TRIVIA
This entity was introduced in Quake II (1997).
*/
class
func_conveyor:NSRenderableEntity
{
PREDICTED_FLOAT(m_flSpeed)
PREDICTED_VECTOR(m_vecMoveDir)
PREDICTED_FLOAT_N(spawnflags)
public:
void(void) func_conveyor;
virtual void Touch(entity);
#ifdef SERVER
virtual void Save(float);
virtual void Restore(string,string);
virtual void Respawn(void);
virtual void Trigger(entity, triggermode_t);
virtual float SendEntity(entity,float);
virtual void SetMovementDirection(void);
virtual void Input(entity, string, string);
virtual void SpawnKey(string,string);
virtual void EvaluateEntity(void);
#endif
#ifdef CLIENT
virtual void ReceiveEntity(float, float);
#endif
};
void
func_conveyor::func_conveyor(void)
{
m_flSpeed = 0.0f;
m_vecMoveDir = [0.0f, 0.0f, 0.0f];
}
#ifdef SERVER
void
func_conveyor::Save(float handle)
{
super::Save(handle);
SaveFloat(handle, "m_flSpeed", m_flSpeed);
SaveVector(handle, "m_vecMoveDir", m_vecMoveDir);
}
void
func_conveyor::Restore(string strKey, string strValue)
{
switch (strKey) {
case "m_flSpeed":
m_flSpeed = ReadFloat(strValue);
break;
case "m_vecMoveDir":
m_vecMoveDir = ReadVector(strValue);
break;
default:
super::Restore(strKey, strValue);
}
}
void
func_conveyor::SpawnKey(string strKey, string strValue)
{
switch (strKey) {
case "speed":
m_flSpeed = stof(strValue);
break;
default:
super::SpawnKey(strKey, strValue);
break;
}
}
void
func_conveyor::Respawn(void)
{
if (!m_flSpeed)
m_flSpeed = 100;
RestoreAngles();
SetMovementDirection();
ClearAngles();
SetMovetype(MOVETYPE_NONE);
SetSolid(SOLID_BSP);
SetModel(GetSpawnModel());
Trigger(this, TRIG_ON);
if (HasSpawnFlags(SF_CONVEYOR_NOTSOLID)) {
SetSolid(SOLID_NOT);
SetSkin(0);
}
}
void
func_conveyor::SetMovementDirection(void)
{
if (angles == [0,-1,0]) {
m_vecMoveDir = [0,0,1];
} else if (angles == [0,-2,0]) {
m_vecMoveDir = [0,0,-1];
} else {
makevectors(angles);
m_vecMoveDir = v_forward;
}
}
void
func_conveyor::Trigger(entity act, triggermode_t state)
{
switch (state) {
case TRIG_ON:
m_flSpeed = fabs(m_flSpeed);
break;
case TRIG_OFF:
m_flSpeed = -fabs(m_flSpeed);
break;
default:
m_flSpeed = -m_flSpeed;
break;
}
/* changes direction */
glowmod[1] = 0.5;
glowmod[2] = m_flSpeed / 1024;
SetSendFlags(CONVEYOR_CHANGED_RENDERCOLOR);
}
void
func_conveyor::Input(entity eAct, string strInput, string strData)
{
switch (strInput) {
case "ToggleDirection":
Trigger(eAct, TRIG_TOGGLE);
break;
case "SetSpeed":
m_flSpeed = stof(strData);
break;
default:
super::Input(eAct, strInput, strData);
}
}
void
func_conveyor::EvaluateEntity(void)
{
EVALUATE_VECTOR(origin, 0, CONVEYOR_CHANGED_ORIGIN_X)
EVALUATE_VECTOR(origin, 1, CONVEYOR_CHANGED_ORIGIN_Y)
EVALUATE_VECTOR(origin, 2, CONVEYOR_CHANGED_ORIGIN_Z)
EVALUATE_VECTOR(angles, 0, CONVEYOR_CHANGED_ANGLES_X)
EVALUATE_VECTOR(angles, 1, CONVEYOR_CHANGED_ANGLES_Y)
EVALUATE_VECTOR(angles, 2, CONVEYOR_CHANGED_ANGLES_Z)
EVALUATE_FIELD(modelindex, CONVEYOR_CHANGED_MODELINDEX)
EVALUATE_FIELD(colormap, CONVEYOR_CHANGED_MODELINDEX)
EVALUATE_FIELD(solid, CONVEYOR_CHANGED_SOLIDMOVETYPE)
EVALUATE_FIELD(movetype, CONVEYOR_CHANGED_SOLIDMOVETYPE)
EVALUATE_VECTOR(mins, 0, CONVEYOR_CHANGED_SIZE)
EVALUATE_VECTOR(mins, 1, CONVEYOR_CHANGED_SIZE)
EVALUATE_VECTOR(mins, 2, CONVEYOR_CHANGED_SIZE)
EVALUATE_VECTOR(maxs, 0, CONVEYOR_CHANGED_SIZE)
EVALUATE_VECTOR(maxs, 1, CONVEYOR_CHANGED_SIZE)
EVALUATE_VECTOR(maxs, 2, CONVEYOR_CHANGED_SIZE)
EVALUATE_FIELD(frame, CONVEYOR_CHANGED_FRAME)
EVALUATE_FIELD(spawnflags, CONVEYOR_CHANGED_SPAWNFLAGS)
EVALUATE_VECTOR(velocity, 0, CONVEYOR_CHANGED_VELOCITY)
EVALUATE_VECTOR(velocity, 1, CONVEYOR_CHANGED_VELOCITY)
EVALUATE_VECTOR(velocity, 2, CONVEYOR_CHANGED_VELOCITY)
EVALUATE_VECTOR(avelocity, 0, CONVEYOR_CHANGED_ANGULARVELOCITY)
EVALUATE_VECTOR(avelocity, 1, CONVEYOR_CHANGED_ANGULARVELOCITY)
EVALUATE_VECTOR(avelocity, 2, CONVEYOR_CHANGED_ANGULARVELOCITY)
EVALUATE_FIELD(m_iRenderMode, CONVEYOR_CHANGED_RENDERMODE)
EVALUATE_FIELD(m_iRenderFX, CONVEYOR_CHANGED_RENDERMODE)
EVALUATE_VECTOR(m_vecRenderColor, 0, CONVEYOR_CHANGED_RENDERCOLOR)
EVALUATE_VECTOR(m_vecRenderColor, 1, CONVEYOR_CHANGED_RENDERCOLOR)
EVALUATE_VECTOR(m_vecRenderColor, 2, CONVEYOR_CHANGED_RENDERCOLOR)
EVALUATE_VECTOR(glowmod, 0, CONVEYOR_CHANGED_RENDERCOLOR)
EVALUATE_VECTOR(glowmod, 1, CONVEYOR_CHANGED_RENDERCOLOR)
EVALUATE_VECTOR(glowmod, 2, CONVEYOR_CHANGED_RENDERCOLOR)
EVALUATE_FIELD(m_flRenderAmt, CONVEYOR_CHANGED_RENDERAMT)
EVALUATE_FIELD(m_flSpeed, CONVEYOR_CHANGED_SPEED)
EVALUATE_VECTOR(m_vecMoveDir, 0, CONVEYOR_CHANGED_MOVEDIR)
EVALUATE_VECTOR(m_vecMoveDir, 1, CONVEYOR_CHANGED_MOVEDIR)
EVALUATE_VECTOR(m_vecMoveDir, 2, CONVEYOR_CHANGED_MOVEDIR)
}
float
func_conveyor::SendEntity(entity ePEnt, float flChanged)
{
if (!modelindex)
return (0);
if (clienttype(ePEnt) != CLIENTTYPE_REAL)
return (0);
WriteByte(MSG_ENTITY, ENT_CONVEYOR);
/* optimisation */
{
/* we'll never network these if we aren't moving. */
if (movetype == MOVETYPE_NONE) {
flChanged &= ~CONVEYOR_CHANGED_VELOCITY;
flChanged &= ~CONVEYOR_CHANGED_ANGULARVELOCITY;
}
/* no rendermode means no extra fields */
if (m_iRenderMode == RM_NORMAL && m_iRenderFX == RFX_NORMAL) {
flChanged &= ~CONVEYOR_CHANGED_RENDERMODE;
//flChanged &= ~CONVEYOR_CHANGED_RENDERCOLOR; /* glowmod needs this */
flChanged &= ~CONVEYOR_CHANGED_RENDERAMT;
}
}
/* broadcast how much data is expected to be read */
WriteFloat(MSG_ENTITY, flChanged);
SENDENTITY_COORD(origin[0], CONVEYOR_CHANGED_ORIGIN_X)
SENDENTITY_COORD(origin[1], CONVEYOR_CHANGED_ORIGIN_Y)
SENDENTITY_COORD(origin[2], CONVEYOR_CHANGED_ORIGIN_Z)
SENDENTITY_ANGLE(angles[0], CONVEYOR_CHANGED_ANGLES_X)
SENDENTITY_ANGLE(angles[1], CONVEYOR_CHANGED_ANGLES_Y)
SENDENTITY_ANGLE(angles[2], CONVEYOR_CHANGED_ANGLES_Z)
SENDENTITY_SHORT(modelindex, CONVEYOR_CHANGED_MODELINDEX)
SENDENTITY_BYTE(colormap, CONVEYOR_CHANGED_MODELINDEX)
SENDENTITY_BYTE(solid, CONVEYOR_CHANGED_SOLIDMOVETYPE)
SENDENTITY_BYTE(movetype, CONVEYOR_CHANGED_SOLIDMOVETYPE)
SENDENTITY_COORD(mins[0], CONVEYOR_CHANGED_SIZE)
SENDENTITY_COORD(mins[1], CONVEYOR_CHANGED_SIZE)
SENDENTITY_COORD(mins[2], CONVEYOR_CHANGED_SIZE)
SENDENTITY_COORD(maxs[0], CONVEYOR_CHANGED_SIZE)
SENDENTITY_COORD(maxs[1], CONVEYOR_CHANGED_SIZE)
SENDENTITY_COORD(maxs[2], CONVEYOR_CHANGED_SIZE)
SENDENTITY_BYTE(frame, CONVEYOR_CHANGED_FRAME)
SENDENTITY_BYTE(spawnflags, CONVEYOR_CHANGED_SPAWNFLAGS)
SENDENTITY_COORD(velocity[0], CONVEYOR_CHANGED_VELOCITY)
SENDENTITY_COORD(velocity[1], CONVEYOR_CHANGED_VELOCITY)
SENDENTITY_COORD(velocity[2], CONVEYOR_CHANGED_VELOCITY)
SENDENTITY_COORD(avelocity[0], CONVEYOR_CHANGED_ANGULARVELOCITY)
SENDENTITY_COORD(avelocity[1], CONVEYOR_CHANGED_ANGULARVELOCITY)
SENDENTITY_COORD(avelocity[2], CONVEYOR_CHANGED_ANGULARVELOCITY)
SENDENTITY_BYTE(m_iRenderMode, CONVEYOR_CHANGED_RENDERMODE)
SENDENTITY_BYTE(m_iRenderFX, CONVEYOR_CHANGED_RENDERMODE)
SENDENTITY_ANGLE(m_vecRenderColor[0], CONVEYOR_CHANGED_RENDERCOLOR)
SENDENTITY_ANGLE(m_vecRenderColor[1], CONVEYOR_CHANGED_RENDERCOLOR)
SENDENTITY_ANGLE(m_vecRenderColor[2], CONVEYOR_CHANGED_RENDERCOLOR)
/* these need more precision for shader hacks... */
SENDENTITY_FLOAT(glowmod[0], CONVEYOR_CHANGED_RENDERCOLOR)
SENDENTITY_FLOAT(glowmod[1], CONVEYOR_CHANGED_RENDERCOLOR)
SENDENTITY_FLOAT(glowmod[2], CONVEYOR_CHANGED_RENDERCOLOR)
SENDENTITY_FLOAT(m_flRenderAmt, CONVEYOR_CHANGED_RENDERAMT)
SENDENTITY_FLOAT(m_flSpeed, CONVEYOR_CHANGED_SPEED)
SENDENTITY_FLOAT(m_vecMoveDir[0], CONVEYOR_CHANGED_MOVEDIR)
SENDENTITY_FLOAT(m_vecMoveDir[1], CONVEYOR_CHANGED_MOVEDIR)
SENDENTITY_FLOAT(m_vecMoveDir[2], CONVEYOR_CHANGED_MOVEDIR)
return true;
}
#endif
#ifdef CLIENT
void
func_conveyor::ReceiveEntity(float flNew, float flChanged)
{
READENTITY_COORD(origin[0], CONVEYOR_CHANGED_ORIGIN_X)
READENTITY_COORD(origin[1], CONVEYOR_CHANGED_ORIGIN_Y)
READENTITY_COORD(origin[2], CONVEYOR_CHANGED_ORIGIN_Z)
READENTITY_ANGLE(angles[0], CONVEYOR_CHANGED_ANGLES_X)
READENTITY_ANGLE(angles[1], CONVEYOR_CHANGED_ANGLES_Y)
READENTITY_ANGLE(angles[2], CONVEYOR_CHANGED_ANGLES_Z)
READENTITY_SHORT(modelindex, CONVEYOR_CHANGED_MODELINDEX)
READENTITY_BYTE(colormap, CONVEYOR_CHANGED_MODELINDEX)
READENTITY_BYTE(solid, CONVEYOR_CHANGED_SOLIDMOVETYPE)
READENTITY_BYTE(movetype, CONVEYOR_CHANGED_SOLIDMOVETYPE)
READENTITY_COORD(mins[0], CONVEYOR_CHANGED_SIZE)
READENTITY_COORD(mins[1], CONVEYOR_CHANGED_SIZE)
READENTITY_COORD(mins[2], CONVEYOR_CHANGED_SIZE)
READENTITY_COORD(maxs[0], CONVEYOR_CHANGED_SIZE)
READENTITY_COORD(maxs[1], CONVEYOR_CHANGED_SIZE)
READENTITY_COORD(maxs[2], CONVEYOR_CHANGED_SIZE)
READENTITY_BYTE(frame, CONVEYOR_CHANGED_FRAME)
READENTITY_BYTE(spawnflags, CONVEYOR_CHANGED_SPAWNFLAGS)
READENTITY_COORD(velocity[0], CONVEYOR_CHANGED_VELOCITY)
READENTITY_COORD(velocity[1], CONVEYOR_CHANGED_VELOCITY)
READENTITY_COORD(velocity[2], CONVEYOR_CHANGED_VELOCITY)
READENTITY_COORD(avelocity[0], CONVEYOR_CHANGED_ANGULARVELOCITY)
READENTITY_COORD(avelocity[1], CONVEYOR_CHANGED_ANGULARVELOCITY)
READENTITY_COORD(avelocity[2], CONVEYOR_CHANGED_ANGULARVELOCITY)
READENTITY_BYTE(m_iRenderMode, CONVEYOR_CHANGED_RENDERMODE)
READENTITY_BYTE(m_iRenderFX, CONVEYOR_CHANGED_RENDERMODE)
READENTITY_ANGLE(m_vecRenderColor[0], CONVEYOR_CHANGED_RENDERCOLOR)
READENTITY_ANGLE(m_vecRenderColor[1], CONVEYOR_CHANGED_RENDERCOLOR)
READENTITY_ANGLE(m_vecRenderColor[2], CONVEYOR_CHANGED_RENDERCOLOR)
/* these need more precision for shader hacks... */
READENTITY_FLOAT(glowmod[0], CONVEYOR_CHANGED_RENDERCOLOR)
READENTITY_FLOAT(glowmod[1], CONVEYOR_CHANGED_RENDERCOLOR)
READENTITY_FLOAT(glowmod[2], CONVEYOR_CHANGED_RENDERCOLOR)
READENTITY_FLOAT(m_flRenderAmt, CONVEYOR_CHANGED_RENDERAMT)
READENTITY_FLOAT(m_flSpeed, CONVEYOR_CHANGED_SPEED)
READENTITY_FLOAT(m_vecMoveDir[0], CONVEYOR_CHANGED_MOVEDIR)
READENTITY_FLOAT(m_vecMoveDir[1], CONVEYOR_CHANGED_MOVEDIR)
READENTITY_FLOAT(m_vecMoveDir[2], CONVEYOR_CHANGED_MOVEDIR)
if (flChanged & CONVEYOR_CHANGED_SIZE)
setsize(this, mins, maxs);
setorigin(this, origin);
}
void
func_conveyor_ReadEntity(bool new)
{
float fl;
func_conveyor rend = (func_conveyor)self;
if (new) {
spawnfunc_func_conveyor();
}
fl = readfloat();
rend.ReceiveEntity(new, fl);
}
#endif
void
func_conveyor::Touch(entity eToucher)
{
if (HasSpawnFlags(SF_CONVEYOR_VISUAL))
return;
eToucher.basevelocity = m_vecMoveDir * (m_flSpeed);
}

View File

@ -0,0 +1,50 @@
/*
* 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.
*/
/*!QUAKED info_waypoint (0 1 0) (-8 -8 -8) (8 8 8)
# OVERVIEW
When active, will display an icon and text at its position that can be seen
by players.
# KEYS
- "targetname" : Name
- "Image" : Path of the material that the game will use for the icon.
- "Text" : A localised string to display next to it.
# INPUTS
- "Enable" : Enables the entity.
- "Disable" : Disables the entity.
# TRIVIA
This entity was introduced in Obsidian Conflict (2006).
*/
class
info_waypoint
{
public:
void info_waypoint(void);
private:
string m_strIcon;
string m_strText;
};
void
info_waypoint::info_waypoint(void)
{
m_strIcon =
m_strText = __NULL__;
}

View File

@ -0,0 +1,349 @@
/*
* 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.
*/
typedef enumflags
{
PUSH_CHANGED_ORIGIN_X,
PUSH_CHANGED_ORIGIN_Y,
PUSH_CHANGED_ORIGIN_Z,
PUSH_CHANGED_ANGLES_X,
PUSH_CHANGED_ANGLES_Y,
PUSH_CHANGED_ANGLES_Z,
PUSH_CHANGED_MODELINDEX,
PUSH_CHANGED_SIZE,
PUSH_CHANGED_FRAME,
PUSH_CHANGED_SPAWNFLAGS,
PUSH_CHANGED_SOLIDMOVETYPE,
PUSH_CHANGED_VELOCITY,
PUSH_CHANGED_ANGULARVELOCITY,
PUSH_CHANGED_RENDERCOLOR,
PUSH_CHANGED_RENDERAMT,
PUSH_CHANGED_RENDERMODE,
PUSH_CHANGED_SPEED,
PUSH_CHANGED_MOVEDIR
} trigger_push_changed_t;
enumflags
{
TP_ONCE,
TP_STARTOFF
};
/*!QUAKED trigger_push (.5 .5 .5) ? TP_ONCE TP_STARTOFF
# OVERVIEW
Pushes anything in its volume into a direction of your choosing.
# KEYS
- "targetname" : Name
- "speed" : The speed (units per second) it'll apply to touchers.
- "angles" : Sets the direction of the push.
# SPAWNFLAGS
- TP_ONCE (1) : Only emit a single push once before disabling itself.
- TP_STARTOFF (2) : Needs to be triggered first in order to function.
# TRIVIA
This entity was introduced in Quake (1996).
*/
class
trigger_push:NSBrushTrigger
{
public:
void trigger_push(void);
virtual void Touch(entity);
#ifdef SERVER
virtual void Save(float);
virtual void Restore(string,string);
virtual void SpawnKey(string,string);
virtual void Respawn(void);
virtual void Trigger(entity,triggermode_t);
virtual void SetMovementDirection(void);
virtual float SendEntity(entity,float);
virtual void EvaluateEntity(void);
#endif
#ifdef CLIENT
virtual void ReceiveEntity(float, float);
#endif
private:
PREDICTED_FLOAT(m_flSpeed)
PREDICTED_VECTOR(m_vecMoveDir)
};
void
trigger_push::trigger_push(void)
{
m_vecMoveDir = [0,0,0];
m_flSpeed = 100;
}
#ifdef SERVER
void
trigger_push::Save(float handle)
{
super::Save(handle);
SaveVector(handle, "m_vecMoveDir", m_vecMoveDir);
SaveFloat(handle, "m_flSpeed", m_flSpeed);
}
void
trigger_push::Restore(string strKey, string strValue)
{
switch (strKey) {
case "m_vecMoveDir":
m_vecMoveDir = ReadVector(strValue);
break;
case "m_flSpeed":
m_flSpeed = ReadFloat(strValue);
break;
default:
super::Restore(strKey, strValue);
}
}
void
trigger_push::SpawnKey(string strKey, string strValue)
{
switch (strKey) {
case "speed":
m_flSpeed = stof(strValue);
break;
default:
super::SpawnKey(strKey, strValue);
}
}
void
trigger_push::Respawn(void)
{
InitBrushTrigger();
RestoreAngles();
SetMovementDirection();
ClearAngles();
if (HasSpawnFlags(TP_STARTOFF)) {
SetSolid(SOLID_NOT);
}
}
void
trigger_push::Trigger(entity act, triggermode_t state)
{
switch (state) {
case TRIG_OFF:
SetSolid(SOLID_NOT);
break;
case TRIG_ON:
SetSolid(SOLID_TRIGGER);
break;
default:
SetSolid(solid == SOLID_NOT ? SOLID_TRIGGER : SOLID_NOT);
}
}
void
trigger_push::SetMovementDirection(void)
{
if (GetSpawnAngles() == [0,-1,0]) {
m_vecMoveDir = [0,0,1];
} else if (angles == [0,-2,0]) {
m_vecMoveDir = [0,0,-1];
} else {
makevectors(GetSpawnAngles());
m_vecMoveDir = v_forward;
}
}
void
trigger_push::EvaluateEntity(void)
{
EVALUATE_VECTOR(origin, 0, PUSH_CHANGED_ORIGIN_X)
EVALUATE_VECTOR(origin, 1, PUSH_CHANGED_ORIGIN_Y)
EVALUATE_VECTOR(origin, 2, PUSH_CHANGED_ORIGIN_Z)
EVALUATE_VECTOR(angles, 0, PUSH_CHANGED_ANGLES_X)
EVALUATE_VECTOR(angles, 1, PUSH_CHANGED_ANGLES_Y)
EVALUATE_VECTOR(angles, 2, PUSH_CHANGED_ANGLES_Z)
EVALUATE_FIELD(modelindex, PUSH_CHANGED_MODELINDEX)
EVALUATE_FIELD(solid, PUSH_CHANGED_SOLIDMOVETYPE)
EVALUATE_FIELD(movetype, PUSH_CHANGED_SOLIDMOVETYPE)
EVALUATE_VECTOR(mins, 0, PUSH_CHANGED_SIZE)
EVALUATE_VECTOR(mins, 1, PUSH_CHANGED_SIZE)
EVALUATE_VECTOR(mins, 2, PUSH_CHANGED_SIZE)
EVALUATE_VECTOR(maxs, 0, PUSH_CHANGED_SIZE)
EVALUATE_VECTOR(maxs, 1, PUSH_CHANGED_SIZE)
EVALUATE_VECTOR(maxs, 2, PUSH_CHANGED_SIZE)
EVALUATE_FIELD(frame, PUSH_CHANGED_FRAME)
EVALUATE_VECTOR(velocity, 0, PUSH_CHANGED_VELOCITY)
EVALUATE_VECTOR(velocity, 1, PUSH_CHANGED_VELOCITY)
EVALUATE_VECTOR(velocity, 2, PUSH_CHANGED_VELOCITY)
EVALUATE_VECTOR(avelocity, 0, PUSH_CHANGED_ANGULARVELOCITY)
EVALUATE_VECTOR(avelocity, 1, PUSH_CHANGED_ANGULARVELOCITY)
EVALUATE_VECTOR(avelocity, 2, PUSH_CHANGED_ANGULARVELOCITY)
EVALUATE_FIELD(m_flSpeed, PUSH_CHANGED_SPEED)
EVALUATE_VECTOR(m_vecMoveDir, 0, PUSH_CHANGED_MOVEDIR)
EVALUATE_VECTOR(m_vecMoveDir, 1, PUSH_CHANGED_MOVEDIR)
EVALUATE_VECTOR(m_vecMoveDir, 2, PUSH_CHANGED_MOVEDIR)
}
float
trigger_push::SendEntity(entity ePEnt, float flChanged)
{
if (!modelindex)
return (0);
if (clienttype(ePEnt) != CLIENTTYPE_REAL)
return (0);
WriteByte(MSG_ENTITY, ENT_PUSH);
/* optimisation */
{
/* we'll never network these if we aren't moving. */
if (movetype == MOVETYPE_NONE) {
flChanged &= ~PUSH_CHANGED_VELOCITY;
flChanged &= ~PUSH_CHANGED_ANGULARVELOCITY;
}
}
/* broadcast how much data is expected to be read */
WriteFloat(MSG_ENTITY, flChanged);
SENDENTITY_COORD(origin[0], PUSH_CHANGED_ORIGIN_X)
SENDENTITY_COORD(origin[1], PUSH_CHANGED_ORIGIN_Y)
SENDENTITY_COORD(origin[2], PUSH_CHANGED_ORIGIN_Z)
SENDENTITY_ANGLE(angles[0], PUSH_CHANGED_ANGLES_X)
SENDENTITY_ANGLE(angles[1], PUSH_CHANGED_ANGLES_Y)
SENDENTITY_ANGLE(angles[2], PUSH_CHANGED_ANGLES_Z)
SENDENTITY_SHORT(modelindex, PUSH_CHANGED_MODELINDEX)
SENDENTITY_BYTE(solid, PUSH_CHANGED_SOLIDMOVETYPE)
SENDENTITY_BYTE(movetype, PUSH_CHANGED_SOLIDMOVETYPE)
SENDENTITY_COORD(mins[0], PUSH_CHANGED_SIZE)
SENDENTITY_COORD(mins[1], PUSH_CHANGED_SIZE)
SENDENTITY_COORD(mins[2], PUSH_CHANGED_SIZE)
SENDENTITY_COORD(maxs[0], PUSH_CHANGED_SIZE)
SENDENTITY_COORD(maxs[1], PUSH_CHANGED_SIZE)
SENDENTITY_COORD(maxs[2], PUSH_CHANGED_SIZE)
SENDENTITY_BYTE(frame, PUSH_CHANGED_FRAME)
SENDENTITY_COORD(velocity[0], PUSH_CHANGED_VELOCITY)
SENDENTITY_COORD(velocity[1], PUSH_CHANGED_VELOCITY)
SENDENTITY_COORD(velocity[2], PUSH_CHANGED_VELOCITY)
SENDENTITY_COORD(avelocity[0], PUSH_CHANGED_ANGULARVELOCITY)
SENDENTITY_COORD(avelocity[1], PUSH_CHANGED_ANGULARVELOCITY)
SENDENTITY_COORD(avelocity[2], PUSH_CHANGED_ANGULARVELOCITY)
SENDENTITY_FLOAT(m_flSpeed, PUSH_CHANGED_SPEED)
SENDENTITY_FLOAT(m_vecMoveDir[0], PUSH_CHANGED_MOVEDIR)
SENDENTITY_FLOAT(m_vecMoveDir[1], PUSH_CHANGED_MOVEDIR)
SENDENTITY_FLOAT(m_vecMoveDir[2], PUSH_CHANGED_MOVEDIR)
return true;
}
#endif
#ifdef CLIENT
void
trigger_push::ReceiveEntity(float flNew, float flChanged)
{
READENTITY_COORD(origin[0], PUSH_CHANGED_ORIGIN_X)
READENTITY_COORD(origin[1], PUSH_CHANGED_ORIGIN_Y)
READENTITY_COORD(origin[2], PUSH_CHANGED_ORIGIN_Z)
READENTITY_ANGLE(angles[0], PUSH_CHANGED_ANGLES_X)
READENTITY_ANGLE(angles[1], PUSH_CHANGED_ANGLES_Y)
READENTITY_ANGLE(angles[2], PUSH_CHANGED_ANGLES_Z)
READENTITY_SHORT(modelindex, PUSH_CHANGED_MODELINDEX)
READENTITY_BYTE(solid, PUSH_CHANGED_SOLIDMOVETYPE)
READENTITY_BYTE(movetype, PUSH_CHANGED_SOLIDMOVETYPE)
READENTITY_COORD(mins[0], PUSH_CHANGED_SIZE)
READENTITY_COORD(mins[1], PUSH_CHANGED_SIZE)
READENTITY_COORD(mins[2], PUSH_CHANGED_SIZE)
READENTITY_COORD(maxs[0], PUSH_CHANGED_SIZE)
READENTITY_COORD(maxs[1], PUSH_CHANGED_SIZE)
READENTITY_COORD(maxs[2], PUSH_CHANGED_SIZE)
READENTITY_BYTE(frame, PUSH_CHANGED_FRAME)
READENTITY_COORD(velocity[0], PUSH_CHANGED_VELOCITY)
READENTITY_COORD(velocity[1], PUSH_CHANGED_VELOCITY)
READENTITY_COORD(velocity[2], PUSH_CHANGED_VELOCITY)
READENTITY_COORD(avelocity[0], PUSH_CHANGED_ANGULARVELOCITY)
READENTITY_COORD(avelocity[1], PUSH_CHANGED_ANGULARVELOCITY)
READENTITY_COORD(avelocity[2], PUSH_CHANGED_ANGULARVELOCITY)
READENTITY_FLOAT(m_flSpeed, PUSH_CHANGED_SPEED)
READENTITY_FLOAT(m_vecMoveDir[0], PUSH_CHANGED_MOVEDIR)
READENTITY_FLOAT(m_vecMoveDir[1], PUSH_CHANGED_MOVEDIR)
READENTITY_FLOAT(m_vecMoveDir[2], PUSH_CHANGED_MOVEDIR)
if (flChanged & PUSH_CHANGED_SIZE)
setsize(this, mins, maxs);
setorigin(this, origin);
}
void
trigger_push_ReadEntity(bool new)
{
float fl;
trigger_push rend = (trigger_push)self;
if (new) {
spawnfunc_trigger_push();
}
fl = readfloat();
rend.ReceiveEntity(new, fl);
}
#endif
void
trigger_push::Touch(entity eToucher)
{
#ifdef SERVER
eActivator = eToucher;
#endif
switch(eToucher.movetype) {
case MOVETYPE_NONE:
case MOVETYPE_PUSH:
case MOVETYPE_NOCLIP:
case MOVETYPE_FOLLOW:
return;
}
/* trigger_push is not supposed to work underwater */
if (eToucher.waterlevel > 1)
return;
if (eToucher.solid != SOLID_NOT && eToucher.solid != SOLID_BSP) {
vector vecPush;
vecPush = (m_flSpeed * m_vecMoveDir);
if (HasSpawnFlags(TP_ONCE)) {
//crossprint(sprintf("one push %v (%v)\n", eToucher.basevelocity, eToucher.velocity));
eToucher.velocity += vecPush;
if (eToucher.velocity[2] > 0) {
eToucher.flags &= ~FL_ONGROUND;
}
SetSolid(SOLID_NOT);
} else {
if (eToucher.flags & FL_ONGROUND) {
eToucher.basevelocity = vecPush * 0.25;
//crossprint(sprintf("basevel push %v (%v)\n", eToucher.basevelocity, eToucher.velocity));
}
}
}
}

View File

@ -19,23 +19,6 @@ var bool g_input_received = false;
#define FN_UPDATE_PKGLIST "http://www.frag-net.com/dl/%s_packages"
const string LICENSE_TEXT = "\
==============================================================================\
Copyright (c) 2016-2022 Marco Cawthorne <marco@vera-visions.com>\
\
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.\
==============================================================================";
/* r_autoscale forces vid_conautoscale to be one of 4 integer values.
* this is due to vid_conautoscale 0 scaling with in floating point... which
* in turns results in skipped rows/columns and shimmering. */
@ -86,6 +69,10 @@ m_init(void)
{
vector g_btnsize;
print("--------- Initializing Menu ----------\n");
print("Built: " __DATE__ " " __TIME__"\n");
print("QCC: " __QCCVER__ "\n");
/* things that should really be default. platform_default.cfg is supposed to set
* them the first time - however FTE doesn't do that when switching manifests
* for unknown reasons. It'll be fixed */
@ -108,9 +95,6 @@ m_init(void)
cvar_set("r_imageextensions", "tga bmp pcx png jpg");
cvar_set("cl_cursor_scale", "1");
print(LICENSE_TEXT);
print("\n\n");
registercommand("menu_updates");
registercommand("menu_customgame");
registercommand("map_background");

View File

@ -294,7 +294,7 @@ void UI_ModelViewer_Show ( void )
btnSeqPrev.SetTitle( "<<" );
btnSeqPrev.SetFunc( UI_ModelViewer_SetFrameM );
searchhandle shModels = search_begin( "models/*.mdl:models/*.vvm", SEARCH_NAMESORT | SEARCH_MULTISEARCH, TRUE );
searchhandle shModels = search_begin( "models/*.mdl:models/*.vvm:models/*/*.mdl:models/*/*.vvm:models/*/*/*.mdl:models/*/*/*.vvm:models/*/*/*/*.mdl:models/*/*/*/*.vvm", SEARCH_NAMESORT | SEARCH_MULTISEARCH, TRUE );
lstModels = spawn( CUIList );
lstModels.SetItemCount( search_getsize( shModels ) );
lstModels.CallOnScroll( ModelViewer_ScrollUpdate );

View File

@ -14,6 +14,8 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
static int g_ent_spawned;
/** Called once every single tic on the server. */
void
StartFrame(void)
@ -329,7 +331,10 @@ So avoid calling spawn() related functions here. */
void
init(float prevprogs)
{
print("--------- Initializing Server-Module ----------\n");
print("--------- Initializing Server Game ----------\n");
print("Built: " __DATE__ " " __TIME__"\n");
print("QCC: " __QCCVER__ "\n");
Plugin_Init();
Sound_Init();
@ -344,18 +349,18 @@ method called at the beginning of them having spawned.
void
init_respawn(void)
{
print("--------- Respawning Server Entities ----------\n");
int endspawn = 0;
if (g_ents_initialized)
g_grMode.InitPostEnts();
#if 0
for (entity a = world; (a = findfloat(a, ::identity, 1));) {
NSEntity ent = (NSEntity)a;
ent.Respawn();
/* of all the map entities that we wanted to spawn, how many are left? */
for (entity a = world; (a = findfloat(a, ::_mapspawned, true));) {
endspawn++;
}
print(sprintf("...%i entities spawned (%i inhibited)\n", g_ent_spawned, g_ent_spawned - endspawn));
remove(self);
#endif
}
entity g_respawntimer;
@ -367,8 +372,6 @@ Before this, we are not able to spawn, touch or allocate any entity slots.
void
initents(void)
{
print("--------- Initializing Server Entities ----------\n");
/* sound shader init */
Materials_Init();
PMove_Init();
@ -460,7 +463,10 @@ as they do not exist yet.
void
worldspawn(void)
{
print("--------- Initializing World ----------\n");
print("--------- Map Initialization --------- \n");
print(sprintf("Map: %s \n", mapname));
print("----------- Game Map Init ------------ \n");
lightstyle(0, "m");
lightstyle(1, "mmnmmommommnonmmonqnmmo");
lightstyle(2, "abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba");
@ -493,6 +499,8 @@ worldspawn(void)
}
forceinfokey(world, "skyname", self.skyname);
}
print("Spawning entities\n");
}
/** Any command executed on the server (either tty, rcon or `sv`) gets
@ -753,6 +761,7 @@ CheckSpawn(void() spawnfunc)
if (spawnfunc) {
spawnfunc();
self._mapspawned = true;
g_ent_spawned++;
} else {
print(sprintf("^1Cannot find entity class ^7%s\n", self.classname));
remove(self);
@ -762,7 +771,9 @@ CheckSpawn(void() spawnfunc)
if (self.identity) {
NSEntity ent = (NSEntity)self;
if (ent.CanSpawn(false) == false)
if (ent.CanSpawn(false) == false) {
ent.Destroy();
g_ent_spawned--;
}
}
}

View File

@ -116,6 +116,7 @@ private:
PREDICTED_FLOAT_N(gflags)
PREDICTED_FLOAT(viewzoom)
PREDICTED_VECTOR_N(view_ofs)
PREDICTED_VECTOR_N(basevelocity)
PREDICTED_VECTOR(v_angle)
PREDICTED_FLOAT_N(pmove_flags)

View File

@ -503,6 +503,9 @@ NSClientPlayer::ReceiveEntity(float new, float flChanged)
READENTITY_COORD(velocity[0], PLAYER_VELOCITY)
READENTITY_COORD(velocity[1], PLAYER_VELOCITY)
READENTITY_COORD(velocity[2], PLAYER_VELOCITY)
READENTITY_COORD(basevelocity[0], PLAYER_VELOCITY)
READENTITY_COORD(basevelocity[1], PLAYER_VELOCITY)
READENTITY_COORD(basevelocity[2], PLAYER_VELOCITY)
READENTITY_INT(flags, PLAYER_FLAGS)
READENTITY_INT(gflags, PLAYER_FLAGS)
READENTITY_INT(pmove_flags, PLAYER_FLAGS)
@ -893,6 +896,9 @@ NSClientPlayer::EvaluateEntity(void)
EVALUATE_VECTOR(velocity, 0, PLAYER_VELOCITY)
EVALUATE_VECTOR(velocity, 1, PLAYER_VELOCITY)
EVALUATE_VECTOR(velocity, 2, PLAYER_VELOCITY)
EVALUATE_VECTOR(basevelocity, 0, PLAYER_VELOCITY)
EVALUATE_VECTOR(basevelocity, 1, PLAYER_VELOCITY)
EVALUATE_VECTOR(basevelocity, 2, PLAYER_VELOCITY)
EVALUATE_FIELD(flags, PLAYER_FLAGS)
EVALUATE_FIELD(gflags, PLAYER_FLAGS)
EVALUATE_FIELD(pmove_flags, PLAYER_FLAGS)
@ -950,6 +956,9 @@ NSClientPlayer::SendEntity(entity ePEnt, float flChanged)
SENDENTITY_COORD(velocity[0], PLAYER_VELOCITY)
SENDENTITY_COORD(velocity[1], PLAYER_VELOCITY)
SENDENTITY_COORD(velocity[2], PLAYER_VELOCITY)
SENDENTITY_COORD(basevelocity[0], PLAYER_VELOCITY)
SENDENTITY_COORD(basevelocity[1], PLAYER_VELOCITY)
SENDENTITY_COORD(basevelocity[2], PLAYER_VELOCITY)
SENDENTITY_INT(flags, PLAYER_FLAGS)
SENDENTITY_INT(gflags, PLAYER_FLAGS)
SENDENTITY_INT(pmove_flags, PLAYER_FLAGS)

View File

@ -8,9 +8,9 @@ typedef struct
} decalGroup_t;
decalGroup_t *g_decalgroup;
int g_decalgroup_count;
#endif
static int g_decalgroup_count;
var hashtable g_hashdecalgroup;
#ifdef CLIENT
@ -87,6 +87,7 @@ DecalGroups_Parse(string line)
} else if (braced == 0) {
t_name = strtolower(line);
hash_add(g_hashdecalgroup, t_name, (int)i);
g_decalgroup_count++;
}
}
}
@ -97,6 +98,8 @@ DecalGroups_Init(void)
filestream fh;
string line;
print("--------- Initializing Decal Groups ----------\n");
/* create the hash-table if it doesn't exist */
if (!g_hashdecalgroup) {
g_hashdecalgroup = hash_createtab(2, EV_STRING | HASH_REPLACE);
@ -124,6 +127,7 @@ DecalGroups_Init(void)
}
#endif
g_decalgroup_count = 0;
fseek(fh, 0);
while ((line = fgets(fh))) {
@ -133,11 +137,15 @@ DecalGroups_Init(void)
fclose(fh);
#if 0
#ifdef CLIENT
for (int i = 0; i < g_decalgroup_count; i++) {
print(sprintf("%i (members: %i) %s\n", i, g_decalgroup[i].members, g_decalgroup[i].materials));
}
#endif
#endif
print(sprintf("decal groups initialized with %i entries.\n", g_decalgroup_count));
}
#ifdef CLIENT

View File

@ -45,6 +45,8 @@ typedef enum
ENT_VEH_4WHEEL, /**< of type prop_vehicle_driveable */
ENT_PROPROPE, /**< of type prop_rope */
ENT_BUBBLES, /**< of type env_bubbles */
ENT_CONVEYOR,
ENT_PUSH,
ENT_SEPARATOR, /**< This is a separator. This separator is used by you to add game-specific networked entities. When declaring your own entity-update types, you want the first value to equal ENT_SEPARATOR at all times to ensure you'll not be overriding existing slots. */
} entupdate_t;

View File

@ -14,6 +14,7 @@
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
static int g_mat_total;
/* general purpose functions to interact with the material system */
static void
@ -67,7 +68,8 @@ Materials_LoadFromMat(string filename)
if (command == "surfaceprop") {
hash_add(g_hashMaterials, materialname, parameters, EV_STRING);
print(sprintf("added Material %S type %S\n", materialname, parameters));
g_mat_total++;
//print(sprintf("added Material %S type %S\n", materialname, parameters));
break;
}
}
@ -171,6 +173,7 @@ Materials_LoadFromLegacyText(string filename)
hash_add(g_hashMaterials, tex_name, mat_type, EV_STRING);
///print(sprintf("hlmaterial: %S %S\n", tex_name, mat_type));
g_hlmaterial_entries++;
g_mat_total++;
}
}
fclose(fileMaterial);
@ -183,6 +186,9 @@ Materials_LoadFromLegacyText(string filename)
void
Materials_Init(void)
{
print("--------- Initializing Material Data ----------\n");
g_mat_total = 0i;
g_hashMaterials = __NULL__;
g_hashMaterials = hash_createtab(2, EV_STRING | HASH_REPLACE);
@ -238,9 +244,11 @@ Materials_Init(void)
searchhandle mdlsearch = search_begin("models/*/*/*/*.mat:models/*/*/*.mat:models/*/*.mat:models/*.mat", SEARCH_MULTISEARCH | SEARCH_NAMESORT, TRUE);
for (int i = 0; i < search_getsize(mdlsearch); i++) {
string mdlmat = search_getfilename(mdlsearch, i);
printf("model: %S\n", mdlmat);
//printf("model: %S\n", mdlmat);
Materials_LoadFromMat(mdlmat);
}
search_end(mdlsearch);
}
print(sprintf("material data initialized with %i entries.\n", g_mat_total));
}

View File

@ -374,6 +374,8 @@ void
NSClientPlayer::Physics_Run(void)
{
float flFallVel = (flags & FL_ONGROUND) ? 0 : -velocity[2];
float flBaseVel = basevelocity[2];
bool onGround = (flags & FL_ONGROUND) ? true : false;
saved_input_movevalues = input_movevalues;
saved_input_buttons = input_buttons;
@ -413,12 +415,11 @@ NSClientPlayer::Physics_Run(void)
Physics_CheckJump(FALSE);
if (waterlevel != 0) {
flFallVel = 0;
}
if ((flags & FL_ONGROUND) && movetype == MOVETYPE_WALK) {
Physics_Fall(flFallVel);
if (onGround == false && (flags & FL_ONGROUND)) {
if (waterlevel != 0) {
flFallVel = 0;
}
Physics_Fall(flFallVel - flBaseVel);
}
input_movevalues = saved_input_movevalues;

View File

@ -493,7 +493,7 @@ PMoveCustom_Move(void)
/* no friction for the deceased */
if (self.movetype == MOVETYPE_NOCLIP) {
self.origin = self.origin + self.velocity * input_timelength;
self.origin += self.velocity * input_timelength;
return;
}
@ -502,6 +502,7 @@ PMoveCustom_Move(void)
for (i = 3, move_time = input_timelength; move_time > 0 && i; i--) {
dest = self.origin + (self.velocity * move_time);
dest += (self.basevelocity * move_time);
//print(sprintf("basevel: %v\n", self.basevelocity));
tracebox(self.origin, self.mins, self.maxs, dest, MOVE_NORMAL, self);
@ -545,6 +546,9 @@ PMoveCustom_Move(void)
dest += (self.basevelocity * move_time);
dest[2] = trace_endpos[2]; /*only horizontally*/
/* clear base-velocity */
self.basevelocity = [0,0,0];
/* move forwards */
tracebox(trace_endpos, self.mins, self.maxs, dest, MOVE_NORMAL, self);
@ -577,7 +581,7 @@ PMoveCustom_Move(void)
/* stepping failed, just bounce off */
PMoveCustom_Rebound(saved_plane);
PMoveCustom_DoTouch(trace_ent);
PMoveCustom_DoTouch(trace_ent); /* this is where basevelocity might get set */
}
/* touch whatever is below */
@ -613,7 +617,6 @@ PMoveCustom_RunPlayerPhysics(entity target)
if (self.maxspeed <= 0)
self.maxspeed = 240;
/* call accelerate before and after the actual move,
* with half the move each time. this reduces framerate dependence.
* and makes controlling jumps slightly easier */
@ -625,9 +628,6 @@ PMoveCustom_RunPlayerPhysics(entity target)
self.angles = input_angles;
self.angles[0] *= -0.333;
/* clear base-velocity and ground-entity */
self.basevelocity = [0,0,0];
/* activate any SOLID_TRIGGER entities */
touchtriggers();
setorigin(self, self.origin);

View File

@ -269,6 +269,8 @@ SurfData_Init(void)
string line;
int index;
print("--------- Initializing Surface Data ----------\n");
/* remove old data */
SurfData_Shutdown();
@ -331,6 +333,8 @@ SurfData_Init(void)
Sound_Precache(g_surfdata[i].m_sndStepRight);
Sound_Precache(g_surfdata[i].m_sndBulletImpact);
}
print(sprintf("surface data initialized with %i entries.\n", g_surfdata_count));
}
static string g_curSurfData;