1 // for physics functions shared by the client and server
6 #include "cl_collision.h"
9 int PHYS_NudgeOutOfSolid(prvm_prog_t *prog, prvm_edict_t *ent)
14 vec3_t stuckmins, stuckmaxs;
18 if (prog == SVVM_prog)
20 worldmodel = sv.worldmodel;
21 separation = sv_gameplayfix_nudgeoutofsolid_separation.value;
23 else if (prog == CLVM_prog)
25 worldmodel = cl.worldmodel;
26 separation = cl_gameplayfix_nudgeoutofsolid_separation.value;
29 Sys_Abort("PHYS_NudgeOutOfSolid: cannot be called from %s VM\n", prog->name);
31 VectorCopy(PRVM_serveredictvector(ent, mins), stuckmins);
32 VectorCopy(PRVM_serveredictvector(ent, maxs), stuckmaxs);
33 if (worldmodel && worldmodel->brushq1.numclipnodes)
34 separation = 0.0f; // when using hulls, it can not be enlarged
37 stuckmins[0] -= separation;
38 stuckmins[1] -= separation;
39 stuckmins[2] -= separation;
40 stuckmaxs[0] += separation;
41 stuckmaxs[1] += separation;
42 stuckmaxs[2] += separation;
45 // first pass we try to get it out of brush entities
46 // second pass we try to get it out of world only (can't win them all)
47 for (pass = 0;pass < 2;pass++)
49 VectorCopy(PRVM_serveredictvector(ent, origin), stuckorigin);
50 for (bump = 0;bump < 10;bump++)
52 if (prog == SVVM_prog) // TODO: can we refactor to use a shared TraceBox or at least a func ptr for these cases?
53 stucktrace = SV_TraceBox(stuckorigin, stuckmins, stuckmaxs, stuckorigin, pass ? MOVE_WORLDONLY : MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value);
55 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);
57 // Separation compared here to ensure a good location will be recognised reliably.
58 if (-stucktrace.startdepth <= separation
59 || (!stucktrace.bmodelstartsolid && !stucktrace.worldstartsolid)
60 || (pass && !stucktrace.worldstartsolid))
62 // found a good location, use it
63 VectorCopy(stuckorigin, PRVM_serveredictvector(ent, origin));
64 return bump || pass ? 1 : -1; // -1 means it wasn't stuck
67 VectorMA(stuckorigin, -stucktrace.startdepth, stucktrace.startdepthnormal, stuckorigin);