Skip to content

Commit

Permalink
NudgeOutOfSolid: fix moving entities out of the world in complex cases
Browse files Browse the repository at this point in the history
Renames a var for clarity.

Signed-off-by: bones_was_here <[email protected]>
  • Loading branch information
bones-was-here committed Mar 11, 2024
1 parent ef7ce27 commit ea65ac4
Showing 1 changed file with 15 additions and 6 deletions.
21 changes: 15 additions & 6 deletions phys.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ int PHYS_NudgeOutOfSolid(prvm_prog_t *prog, prvm_edict_t *ent)
{
int bump, pass;
trace_t stucktrace;
vec3_t stuckorigin;
vec3_t testorigin, targetorigin;
vec3_t stuckmins, stuckmaxs;
vec_t separation;
model_t *worldmodel;
Expand Down Expand Up @@ -46,25 +46,34 @@ int PHYS_NudgeOutOfSolid(prvm_prog_t *prog, prvm_edict_t *ent)
// 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);
VectorCopy(PRVM_serveredictvector(ent, origin), testorigin);
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);
stucktrace = SV_TraceBox(testorigin, stuckmins, stuckmaxs, testorigin, 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);
stucktrace = CL_TraceBox(testorigin, stuckmins, stuckmaxs, testorigin, pass ? MOVE_WORLDONLY : MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value, pass ? false : true, false, NULL, false);

// Separation compared here to ensure a good location will be recognised reliably.
if (-stucktrace.startdepth <= separation
|| (!stucktrace.bmodelstartsolid && !stucktrace.worldstartsolid)
|| (pass && !stucktrace.worldstartsolid))
{
// found a good location, use it
VectorCopy(stuckorigin, PRVM_serveredictvector(ent, origin));
VectorCopy(testorigin, PRVM_serveredictvector(ent, origin));
return bump || pass ? 1 : -1; // -1 means it wasn't stuck
}

VectorMA(stuckorigin, -stucktrace.startdepth, stucktrace.startdepthnormal, stuckorigin);
VectorMA(testorigin, -stucktrace.startdepth, stucktrace.startdepthnormal, targetorigin);
// Trace to targetorigin so we don't set it out of the world in complex cases.
if (prog == SVVM_prog)
stucktrace = SV_TraceBox(testorigin, stuckmins, stuckmaxs, targetorigin, pass ? MOVE_WORLDONLY : MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value);
else
stucktrace = CL_TraceBox(testorigin, stuckmins, stuckmaxs, targetorigin, pass ? MOVE_WORLDONLY : MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value, pass ? false : true, false, NULL, false);
if (stucktrace.fraction)
VectorCopy(stucktrace.endpos, testorigin);
else
break; // Can't move it so no point doing more iterations on this pass.
}
}
return 0;
Expand Down

0 comments on commit ea65ac4

Please sign in to comment.