]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
Move SV_NudgeOutOfSolid() into a common namespace and unit
authorbones_was_here <bones_was_here@xonotic.au>
Sat, 15 Jul 2023 12:27:09 +0000 (22:27 +1000)
committerbones_was_here <bones_was_here@xonotic.au>
Sat, 15 Jul 2023 12:27:09 +0000 (22:27 +1000)
Signed-off-by: bones_was_here <bones_was_here@xonotic.au>
cl_main.c
makefile.inc
phys.c [new file with mode: 0644]
phys.h [new file with mode: 0644]
quakedef.h
server.h
sv_phys.c
svvm_cmds.c

index c114156382440d2141c3ff6aaf4fa59442317802..fe1840aff42db97cb43db2ec931f381da739312b 100644 (file)
--- 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();
index 87b114ce50b58163acd101c018070cc25895c6fa..90e2bf86aaca8a5e9853a262f3a182c0b45a2a69 100644 (file)
@@ -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 (file)
index 0000000..6bad2bb
--- /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 (file)
index 0000000..caa554a
--- /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
index ec5c72b6efb29fbb305e5d0f0ed17bb542fd3a24..f423d5985aab35137cab98ed205e47f8c9f43a13 100644 (file)
@@ -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"
index 635eb72b29124dc199cfc0b51056ef5c7ebe8db4..5dfe2ac04aff7715a0f1ad747c1233af0f1d2b51 100644 (file)
--- 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);
index 96139467879a79e2dc211e0ced41e83ea08614f3..35bc3410cc7c7382710358a62afefad8606608a1 100644 (file)
--- 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);
index c04cd97fbe93be3561e6cd3d258a9490a887ee7f..25e8798296113768ef5c4069433b285dc1c34f59 100644 (file)
@@ -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);