From 7b42befcb371e229d63a992f8bd8c96ae935dc13 Mon Sep 17 00:00:00 2001 From: Marco Cawthorne Date: Sat, 18 Mar 2023 17:49:12 -0700 Subject: [PATCH] Networked versions of func_conveyor, trigger_push. Bounce pads should be much nicer. --- src/client/crosshair.h | 60 ++-- src/client/crosshair.qc | 44 +-- src/client/entities.qc | 6 + src/client/entry.qc | 2 + src/gs-entbase/server.src | 2 - src/gs-entbase/server/func_conveyor.qc | 179 ------------ src/gs-entbase/server/trigger_push.qc | 173 ----------- src/gs-entbase/shared.src | 3 + src/gs-entbase/shared/func_conveyor.qc | 390 +++++++++++++++++++++++++ src/gs-entbase/shared/info_waypoint.qc | 50 ++++ src/gs-entbase/shared/trigger_push.qc | 349 ++++++++++++++++++++++ src/menu-fn/entry.qc | 24 +- src/menu-vgui/ui_modelviewer.qc | 2 +- src/server/entry.qc | 33 ++- src/shared/NSClientPlayer.h | 1 + src/shared/NSClientPlayer.qc | 9 + src/shared/decalgroups.qc | 10 +- src/shared/entities.h | 2 + src/shared/materials.qc | 12 +- src/shared/player_pmove.qc | 13 +- src/shared/pmove_custom.qc | 12 +- src/shared/surfaceproperties.qc | 4 + 22 files changed, 927 insertions(+), 453 deletions(-) delete mode 100644 src/gs-entbase/server/func_conveyor.qc delete mode 100644 src/gs-entbase/server/trigger_push.qc create mode 100644 src/gs-entbase/shared/func_conveyor.qc create mode 100644 src/gs-entbase/shared/info_waypoint.qc create mode 100644 src/gs-entbase/shared/trigger_push.qc diff --git a/src/client/crosshair.h b/src/client/crosshair.h index 5c6c21b6..fcf4991a 100644 --- a/src/client/crosshair.h +++ b/src/client/crosshair.h @@ -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); \ No newline at end of file +@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); \ No newline at end of file diff --git a/src/client/crosshair.qc b/src/client/crosshair.qc index a5f1b7ea..db157816 100644 --- a/src/client/crosshair.qc +++ b/src/client/crosshair.qc @@ -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); } } \ No newline at end of file diff --git a/src/client/entities.qc b/src/client/entities.qc index 42d349f4..420bc08c 100644 --- a/src/client/entities.qc +++ b/src/client/entities.qc @@ -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)); } diff --git a/src/client/entry.qc b/src/client/entry.qc index 8838a217..3ee52162 100644 --- a/src/client/entry.qc +++ b/src/client/entry.qc @@ -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); diff --git a/src/gs-entbase/server.src b/src/gs-entbase/server.src index 232fe362..e4e2d679 100644 --- a/src/gs-entbase/server.src +++ b/src/gs-entbase/server.src @@ -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 diff --git a/src/gs-entbase/server/func_conveyor.qc b/src/gs-entbase/server/func_conveyor.qc deleted file mode 100644 index f5e0537d..00000000 --- a/src/gs-entbase/server/func_conveyor.qc +++ /dev/null @@ -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); - } -} diff --git a/src/gs-entbase/server/trigger_push.qc b/src/gs-entbase/server/trigger_push.qc deleted file mode 100644 index 6f4bcd95..00000000 --- a/src/gs-entbase/server/trigger_push.qc +++ /dev/null @@ -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; - } -} diff --git a/src/gs-entbase/shared.src b/src/gs-entbase/shared.src index 2ec08989..8f13b04d 100644 --- a/src/gs-entbase/shared.src +++ b/src/gs-entbase/shared.src @@ -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 diff --git a/src/gs-entbase/shared/func_conveyor.qc b/src/gs-entbase/shared/func_conveyor.qc new file mode 100644 index 00000000..cae53702 --- /dev/null +++ b/src/gs-entbase/shared/func_conveyor.qc @@ -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); +} diff --git a/src/gs-entbase/shared/info_waypoint.qc b/src/gs-entbase/shared/info_waypoint.qc new file mode 100644 index 00000000..dd7bcd6d --- /dev/null +++ b/src/gs-entbase/shared/info_waypoint.qc @@ -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__; +} \ No newline at end of file diff --git a/src/gs-entbase/shared/trigger_push.qc b/src/gs-entbase/shared/trigger_push.qc new file mode 100644 index 00000000..582a6c8a --- /dev/null +++ b/src/gs-entbase/shared/trigger_push.qc @@ -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)); + } + } + } +} \ No newline at end of file diff --git a/src/menu-fn/entry.qc b/src/menu-fn/entry.qc index 04982748..c068dd66 100644 --- a/src/menu-fn/entry.qc +++ b/src/menu-fn/entry.qc @@ -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 \ -\ -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"); diff --git a/src/menu-vgui/ui_modelviewer.qc b/src/menu-vgui/ui_modelviewer.qc index 87f16430..09f5fce2 100644 --- a/src/menu-vgui/ui_modelviewer.qc +++ b/src/menu-vgui/ui_modelviewer.qc @@ -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 ); diff --git a/src/server/entry.qc b/src/server/entry.qc index b6e82b9c..d79d70e8 100644 --- a/src/server/entry.qc +++ b/src/server/entry.qc @@ -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--; + } } } diff --git a/src/shared/NSClientPlayer.h b/src/shared/NSClientPlayer.h index 1b586bcd..07cf1ddf 100644 --- a/src/shared/NSClientPlayer.h +++ b/src/shared/NSClientPlayer.h @@ -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) diff --git a/src/shared/NSClientPlayer.qc b/src/shared/NSClientPlayer.qc index b76824c8..7bc36765 100644 --- a/src/shared/NSClientPlayer.qc +++ b/src/shared/NSClientPlayer.qc @@ -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) diff --git a/src/shared/decalgroups.qc b/src/shared/decalgroups.qc index 50a397d3..afe97e69 100644 --- a/src/shared/decalgroups.qc +++ b/src/shared/decalgroups.qc @@ -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 diff --git a/src/shared/entities.h b/src/shared/entities.h index 50f09e82..f5cee000 100644 --- a/src/shared/entities.h +++ b/src/shared/entities.h @@ -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; diff --git a/src/shared/materials.qc b/src/shared/materials.qc index 30bd84d1..82b4daa1 100644 --- a/src/shared/materials.qc +++ b/src/shared/materials.qc @@ -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)); } diff --git a/src/shared/player_pmove.qc b/src/shared/player_pmove.qc index 899d5429..5d1ff9b4 100644 --- a/src/shared/player_pmove.qc +++ b/src/shared/player_pmove.qc @@ -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; diff --git a/src/shared/pmove_custom.qc b/src/shared/pmove_custom.qc index 208b3513..a6396ec9 100644 --- a/src/shared/pmove_custom.qc +++ b/src/shared/pmove_custom.qc @@ -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); diff --git a/src/shared/surfaceproperties.qc b/src/shared/surfaceproperties.qc index 836aaf19..4516597e 100644 --- a/src/shared/surfaceproperties.qc +++ b/src/shared/surfaceproperties.qc @@ -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;