diff --git a/src/game/g_phys.c b/src/game/g_phys.c index 70f6fdb4..d729bf41 100644 --- a/src/game/g_phys.c +++ b/src/game/g_phys.c @@ -54,15 +54,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_DEADMONSTER)) { mask = ent->clipmask; } @@ -76,11 +79,6 @@ SV_TestEntityPosition(edict_t *ent) if (trace.startsolid) { - if ((ent->svflags & SVF_DEADMONSTER) && (trace.ent->client || (trace.ent->svflags & SVF_MONSTER))) - { - return NULL; - } - return g_edicts; } @@ -526,10 +524,15 @@ retry: trace = gi.trace(start, ent->mins, ent->maxs, end, ent, mask); - if (trace.startsolid || trace.allsolid) + /* 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)) { - mask ^= CONTENTS_DEADMONSTER; - trace = gi.trace (start, ent->mins, ent->maxs, end, ent, mask); + trace = gi.trace (start, ent->mins, ent->maxs, end, ent, MASK_SOLID); } VectorCopy(trace.endpos, ent->s.origin);