From 540acd33401d3d6dd53cd38c1f68b1a345477ed2 Mon Sep 17 00:00:00 2001 From: bones_was_here Date: Sat, 15 Jul 2023 22:27:09 +1000 Subject: [PATCH] Move SV_NudgeOutOfSolid() into a common namespace and unit Signed-off-by: bones_was_here --- cl_main.c | 3 +++ makefile.inc | 1 + phys.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++ phys.h | 14 +++++++++++ quakedef.h | 1 + server.h | 4 --- sv_phys.c | 42 +------------------------------- svvm_cmds.c | 4 +-- 8 files changed, 91 insertions(+), 47 deletions(-) create mode 100644 phys.c create mode 100644 phys.h diff --git a/cl_main.c b/cl_main.c index c1141563..fe1840af 100644 --- a/cl_main.c +++ b/cl_main.c @@ -108,6 +108,8 @@ cvar_t cl_maxfps_alwayssleep = {CF_CLIENT | CF_ARCHIVE, "cl_maxfps_alwayssleep", cvar_t cl_maxidlefps = {CF_CLIENT | CF_ARCHIVE, "cl_maxidlefps", "20", "maximum fps cap when the game is not the active window (makes cpu time available to other programs"}; cvar_t cl_areagrid_link_SOLID_NOT = {CF_CLIENT, "cl_areagrid_link_SOLID_NOT", "1", "set to 0 to prevent SOLID_NOT entities from being linked to the area grid, and unlink any that are already linked (in the code paths that would otherwise link them), for better performance"}; +cvar_t cl_gameplayfix_nudgeoutofsolid_separation = {CF_CLIENT, "cl_gameplayfix_nudgeoutofsolid_separation", "0.03125", "keep objects this distance apart to prevent collision issues on seams"}; + client_static_t cls; client_state_t cl; @@ -3137,6 +3139,7 @@ void CL_Init (void) Cvar_RegisterVariable (&cl_maxidlefps); Cvar_RegisterVariable (&cl_areagrid_link_SOLID_NOT); + Cvar_RegisterVariable (&cl_gameplayfix_nudgeoutofsolid_separation); CL_Parse_Init(); CL_Particles_Init(); diff --git a/makefile.inc b/makefile.inc index 87b114ce..90e2bf86 100644 --- a/makefile.inc +++ b/makefile.inc @@ -116,6 +116,7 @@ OBJ_COMMON= \ model_sprite.o \ netconn.o \ palette.o \ + phys.o \ polygon.o \ portals.o \ protocol.o \ diff --git a/phys.c b/phys.c new file mode 100644 index 00000000..6bad2bbc --- /dev/null +++ b/phys.c @@ -0,0 +1,69 @@ +// for physics functions shared by the client and server + +#include "phys.h" + +#include "quakedef.h" +#include "cl_collision.h" + + +qbool PHYS_NudgeOutOfSolid(prvm_prog_t *prog, prvm_edict_t *ent) +{ + int bump, pass; + trace_t stucktrace; + vec3_t stuckorigin; + vec3_t stuckmins, stuckmaxs; + vec_t nudge; + vec_t separation; + model_t *worldmodel; + + if (prog == SVVM_prog) + { + worldmodel = sv.worldmodel; + separation = sv_gameplayfix_nudgeoutofsolid_separation.value; + } + else if (prog == CLVM_prog) + { + worldmodel = cl.worldmodel; + separation = cl_gameplayfix_nudgeoutofsolid_separation.value; + } + else + Sys_Error("PHYS_NudgeOutOfSolid: cannot be called from %s VM\n", prog->name); + + VectorCopy(PRVM_serveredictvector(ent, mins), stuckmins); + VectorCopy(PRVM_serveredictvector(ent, maxs), stuckmaxs); + if (worldmodel && worldmodel->brushq1.numclipnodes) + separation = 0.0f; // when using hulls, it can not be enlarged + else + { + stuckmins[0] -= separation; + stuckmins[1] -= separation; + stuckmins[2] -= separation; + stuckmaxs[0] += separation; + stuckmaxs[1] += separation; + stuckmaxs[2] += separation; + } + + // first pass we try to get it out of brush entities + // second pass we try to get it out of world only (can't win them all) + for (pass = 0;pass < 2;pass++) + { + VectorCopy(PRVM_serveredictvector(ent, origin), stuckorigin); + for (bump = 0;bump < 10;bump++) + { + if (prog == SVVM_prog) // TODO: can we refactor to use a shared TraceBox or at least a func ptr for these cases? + stucktrace = SV_TraceBox(stuckorigin, stuckmins, stuckmaxs, stuckorigin, pass ? MOVE_WORLDONLY : MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value); + else + stucktrace = CL_TraceBox(stuckorigin, stuckmins, stuckmaxs, stuckorigin, pass ? MOVE_WORLDONLY : MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value, pass ? false : true, false, NULL, false); + + if (!stucktrace.bmodelstartsolid || stucktrace.startdepth >= 0) + { + // found a good location, use it + VectorCopy(stuckorigin, PRVM_serveredictvector(ent, origin)); + return true; + } + nudge = -stucktrace.startdepth; + VectorMA(stuckorigin, nudge, stucktrace.startdepthnormal, stuckorigin); + } + } + return false; +} diff --git a/phys.h b/phys.h new file mode 100644 index 00000000..caa554a9 --- /dev/null +++ b/phys.h @@ -0,0 +1,14 @@ +#ifndef PHYS_H +#define PHYS_H + +#include "quakedef.h" + + +/*! move an entity that is stuck out of the surface it is stuck in (can move large amounts) + * returns true if it found a better place + */ +qbool PHYS_NudgeOutOfSolid(prvm_prog_t *prog, prvm_edict_t *ent); +extern cvar_t cl_gameplayfix_nudgeoutofsolid_separation; + + +#endif // PHYS_H guard diff --git a/quakedef.h b/quakedef.h index ec5c72b6..f423d598 100644 --- a/quakedef.h +++ b/quakedef.h @@ -140,6 +140,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "progs.h" #include "progsvm.h" #include "server.h" +#include "phys.h" #include "input.h" #include "keys.h" diff --git a/server.h b/server.h index 635eb72b..5dfe2ac0 100644 --- a/server.h +++ b/server.h @@ -568,10 +568,6 @@ void SV_LinkEdict_TouchAreaGrid_Call(prvm_edict_t *touch, prvm_edict_t *ent); // * returns true if it found a better place */ qbool SV_UnstickEntity (prvm_edict_t *ent); -/*! move an entity that is stuck out of the surface it is stuck in (can move large amounts) - * returns true if it found a better place - */ -qbool SV_NudgeOutOfSolid(prvm_edict_t *ent); /// calculates hitsupercontentsmask for a generic qc entity int SV_GenericHitSuperContentsMask(const prvm_edict_t *edict); diff --git a/sv_phys.c b/sv_phys.c index 96139467..35bc3410 100644 --- a/sv_phys.c +++ b/sv_phys.c @@ -1543,46 +1543,6 @@ static qbool SV_NudgeOutOfSolid_PivotIsKnownGood(prvm_edict_t *ent, vec3_t pivot return true; } -qbool SV_NudgeOutOfSolid(prvm_edict_t *ent) -{ - prvm_prog_t *prog = SVVM_prog; - int bump, pass; - trace_t stucktrace; - vec3_t stuckorigin; - vec3_t stuckmins, stuckmaxs; - vec_t nudge; - vec_t separation = sv_gameplayfix_nudgeoutofsolid_separation.value; - if (sv.worldmodel && sv.worldmodel->brushq1.numclipnodes) - separation = 0.0f; // when using hulls, it can not be enlarged - VectorCopy(PRVM_serveredictvector(ent, mins), stuckmins); - VectorCopy(PRVM_serveredictvector(ent, maxs), stuckmaxs); - stuckmins[0] -= separation; - stuckmins[1] -= separation; - stuckmins[2] -= separation; - stuckmaxs[0] += separation; - stuckmaxs[1] += separation; - stuckmaxs[2] += separation; - // first pass we try to get it out of brush entities - // second pass we try to get it out of world only (can't win them all) - for (pass = 0;pass < 2;pass++) - { - VectorCopy(PRVM_serveredictvector(ent, origin), stuckorigin); - for (bump = 0;bump < 10;bump++) - { - stucktrace = SV_TraceBox(stuckorigin, stuckmins, stuckmaxs, stuckorigin, pass ? MOVE_WORLDONLY : MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value); - if (!stucktrace.bmodelstartsolid || stucktrace.startdepth >= 0) - { - // found a good location, use it - VectorCopy(stuckorigin, PRVM_serveredictvector(ent, origin)); - return true; - } - nudge = -stucktrace.startdepth; - VectorMA(stuckorigin, nudge, stucktrace.startdepthnormal, stuckorigin); - } - } - return false; -} - /* ============ SV_PushEntity @@ -1610,7 +1570,7 @@ static qbool SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, qboo // move start position out of solids if (sv_gameplayfix_nudgeoutofsolid.integer && sv_gameplayfix_nudgeoutofsolid_separation.value >= 0) { - SV_NudgeOutOfSolid(ent); + PHYS_NudgeOutOfSolid(prog, ent); } VectorCopy(PRVM_serveredictvector(ent, origin), start); diff --git a/svvm_cmds.c b/svvm_cmds.c index c04cd97f..25e87982 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -1211,7 +1211,7 @@ static void VM_SV_droptofloor(prvm_prog_t *prog) end[2] -= 256; // Quake, QuakeWorld if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer) - SV_NudgeOutOfSolid(ent); + PHYS_NudgeOutOfSolid(prog, ent); VectorCopy(PRVM_serveredictvector(ent, origin), entorigin); VectorCopy(PRVM_serveredictvector(ent, mins), entmins); @@ -1237,7 +1237,7 @@ static void VM_SV_droptofloor(prvm_prog_t *prog) Con_DPrintf("droptofloor at %f %f %f - FIXED BADLY PLACED ENTITY\n", PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]); VectorCopy (trace.endpos, PRVM_serveredictvector(ent, origin)); if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer) - SV_NudgeOutOfSolid(ent); + PHYS_NudgeOutOfSolid(prog, ent); SV_LinkEdict(ent); PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) | FL_ONGROUND; PRVM_serveredictedict(ent, groundentity) = PRVM_EDICT_TO_PROG(trace.ent); -- 2.39.2