]> de.git.xonotic.org Git - xonotic/darkplaces.git/blob - phys.c
Move SV_NudgeOutOfSolid() into a common namespace and unit
[xonotic/darkplaces.git] / phys.c
1 // for physics functions shared by the client and server
2
3 #include "phys.h"
4
5 #include "quakedef.h"
6 #include "cl_collision.h"
7
8
9 qbool PHYS_NudgeOutOfSolid(prvm_prog_t *prog, prvm_edict_t *ent)
10 {
11         int bump, pass;
12         trace_t stucktrace;
13         vec3_t stuckorigin;
14         vec3_t stuckmins, stuckmaxs;
15         vec_t nudge;
16         vec_t separation;
17         model_t *worldmodel;
18
19         if (prog == SVVM_prog)
20         {
21                 worldmodel = sv.worldmodel;
22                 separation = sv_gameplayfix_nudgeoutofsolid_separation.value;
23         }
24         else if (prog == CLVM_prog)
25         {
26                 worldmodel = cl.worldmodel;
27                 separation = cl_gameplayfix_nudgeoutofsolid_separation.value;
28         }
29         else
30                 Sys_Error("PHYS_NudgeOutOfSolid: cannot be called from %s VM\n", prog->name);
31
32         VectorCopy(PRVM_serveredictvector(ent, mins), stuckmins);
33         VectorCopy(PRVM_serveredictvector(ent, maxs), stuckmaxs);
34         if (worldmodel && worldmodel->brushq1.numclipnodes)
35                 separation = 0.0f; // when using hulls, it can not be enlarged
36         else
37         {
38                 stuckmins[0] -= separation;
39                 stuckmins[1] -= separation;
40                 stuckmins[2] -= separation;
41                 stuckmaxs[0] += separation;
42                 stuckmaxs[1] += separation;
43                 stuckmaxs[2] += separation;
44         }
45
46         // first pass we try to get it out of brush entities
47         // second pass we try to get it out of world only (can't win them all)
48         for (pass = 0;pass < 2;pass++)
49         {
50                 VectorCopy(PRVM_serveredictvector(ent, origin), stuckorigin);
51                 for (bump = 0;bump < 10;bump++)
52                 {
53                         if (prog == SVVM_prog) // TODO: can we refactor to use a shared TraceBox or at least a func ptr for these cases?
54                                 stucktrace = SV_TraceBox(stuckorigin, stuckmins, stuckmaxs, stuckorigin, pass ? MOVE_WORLDONLY : MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value);
55                         else
56                                 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
58                         if (!stucktrace.bmodelstartsolid || stucktrace.startdepth >= 0)
59                         {
60                                 // found a good location, use it
61                                 VectorCopy(stuckorigin, PRVM_serveredictvector(ent, origin));
62                                 return true;
63                         }
64                         nudge = -stucktrace.startdepth;
65                         VectorMA(stuckorigin, nudge, stucktrace.startdepthnormal, stuckorigin);
66                 }
67         }
68         return false;
69 }