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;
Cvar_RegisterVariable (&cl_maxidlefps);
Cvar_RegisterVariable (&cl_areagrid_link_SOLID_NOT);
+ Cvar_RegisterVariable (&cl_gameplayfix_nudgeoutofsolid_separation);
CL_Parse_Init();
CL_Particles_Init();
model_sprite.o \
netconn.o \
palette.o \
+ phys.o \
polygon.o \
portals.o \
protocol.o \
--- /dev/null
+// 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;
+}
--- /dev/null
+#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
#include "progs.h"
#include "progsvm.h"
#include "server.h"
+#include "phys.h"
#include "input.h"
#include "keys.h"
* 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);
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
// 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);
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);
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);