diff --git a/src/g_phys.c b/src/g_phys.c index d4890e3..1c2f0fa 100644 --- a/src/g_phys.c +++ b/src/g_phys.c @@ -35,15 +35,18 @@ edict_t * SV_TestEntityPosition(edict_t *ent) { + trace_t trace; + int mask; + if (!ent) { return NULL; } - trace_t trace; - int mask; - - if (ent->clipmask) + /* dead bodies are supposed to not be solid so lets + ensure they only collide with BSP during pushmoves + */ + if (ent->clipmask && !(ent->svflags & SVF_MONSTER)) { mask = ent->clipmask; } @@ -52,12 +55,8 @@ SV_TestEntityPosition(edict_t *ent) mask = MASK_SOLID; } - trace = gi.trace(ent->s.origin, - ent->mins, - ent->maxs, - ent->s.origin, - ent, - mask); + trace = gi.trace(ent->s.origin, ent->mins, ent->maxs, + ent->s.origin, ent, mask); if (trace.startsolid) { @@ -505,6 +504,17 @@ retry: trace = gi.trace(start, ent->mins, ent->maxs, end, ent, mask); + /* startsolid treats different-content volumes + as continuous, like the bbox of a monster/player + and the floor of an elevator. So do another trace + that only collides with BSP so that we make a best + effort to keep these entities inside non-solid space + */ + if (trace.startsolid && (mask & ~MASK_SOLID)) + { + trace = gi.trace (start, ent->mins, ent->maxs, end, ent, MASK_SOLID); + } + VectorCopy(trace.endpos, ent->s.origin); gi.linkentity(ent);