From b23e83279133e296436c99d4e2e82a5bd2e39e03 Mon Sep 17 00:00:00 2001 From: Mario Date: Sun, 8 Mar 2020 05:55:17 +1000 Subject: [PATCH] Change unsticking to match the engine even more closely, fixes some cases where entities can be stuck with QC physics --- qcsrc/common/physics/movetypes/movetypes.qc | 56 +++++++++++++++++---- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/qcsrc/common/physics/movetypes/movetypes.qc b/qcsrc/common/physics/movetypes/movetypes.qc index 68d4c3660..63aa3dd95 100644 --- a/qcsrc/common/physics/movetypes/movetypes.qc +++ b/qcsrc/common/physics/movetypes/movetypes.qc @@ -413,6 +413,30 @@ void _Movetype_LinkEdict(entity this, bool touch_triggers) // SV_LinkEdict _Movetype_LinkEdict_TouchAreaGrid(this); } +int _Movetype_ContentsMask(entity this) // SV_GenericHitSuperContentsMask +{ + if(this) + { + if(this.dphitcontentsmask) + return this.dphitcontentsmask; + else if(this.solid == SOLID_SLIDEBOX) + { + if(this.flags & 32) // TODO: FL_MONSTER + return DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_MONSTERCLIP; + else + return DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP; + } + else if(this.solid == SOLID_CORPSE) + return DPCONTENTS_SOLID | DPCONTENTS_BODY; + else if(this.solid == SOLID_TRIGGER) + return DPCONTENTS_SOLID | DPCONTENTS_BODY; + else + return DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE; + } + else + return DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_CORPSE; +} + entity _Movetype_TestEntityPosition_ent; bool _Movetype_TestEntityPosition(vector ofs) // SV_TestEntityPosition { @@ -421,13 +445,12 @@ bool _Movetype_TestEntityPosition(vector ofs) // SV_TestEntityPosition //int cont = this.dphitcontentsmask; //this.dphitcontentsmask = DPCONTENTS_SOLID; - tracebox(org, this.mins, this.maxs, org, ((this.move_movetype == MOVETYPE_FLY_WORLDONLY) ? MOVE_WORLDONLY : MOVE_NOMONSTERS), this); + tracebox(org, this.mins, this.maxs, this.origin, ((this.move_movetype == MOVETYPE_FLY_WORLDONLY) ? MOVE_WORLDONLY : MOVE_NOMONSTERS), this); //this.dphitcontentsmask = cont; - - if(trace_startsolid) + if(trace_dpstartcontents & _Movetype_ContentsMask(this)) return true; - if(vdist(trace_endpos - this.origin, >, 0.0001)) + if(vlen2(trace_endpos - this.origin) >= 0.0001) { tracebox(trace_endpos, this.mins, this.maxs, trace_endpos, MOVE_NOMONSTERS, this); if(!trace_startsolid) @@ -436,6 +459,23 @@ bool _Movetype_TestEntityPosition(vector ofs) // SV_TestEntityPosition return false; } +bool _Movetype_TestEntityPosition_Offset(int offset) +{ + // NOTE: expects _Movetype_TestEntityPosition_ent to be set to the correct entity + // returns true if stuck + + // start at 2, since the first position has already been checked + for(int j = 2; j <= offset; ++j) + { + if(!_Movetype_TestEntityPosition('0 0 -1' * j)) + return false; + if(!_Movetype_TestEntityPosition('0 0 1' * j)) + return false; + } + + return true; +} + int _Movetype_UnstickEntity(entity this) // SV_UnstickEntity { _Movetype_TestEntityPosition_ent = this; @@ -450,13 +490,7 @@ int _Movetype_UnstickEntity(entity this) // SV_UnstickEntity X('-1 1 0') X(' 1 1 0') #undef X { - #define X(i) \ - if (_Movetype_TestEntityPosition('0 0 -1' * i)) \ - if (_Movetype_TestEntityPosition('0 0 1' * i)) - X(2) X(3) X(4) X(5) X(6) X(7) X(8) - X(9) X(10) X(11) X(12) X(13) X(14) X(15) X(16) - X(17) - #undef X + if(_Movetype_TestEntityPosition_Offset(rint((this.maxs.z - this.mins.z) * 0.36))) { LOG_DEBUGF("Can't unstick an entity (edict: %d, classname: %s, origin: %s)", etof(this), this.classname, vtos(this.origin)); -- 2.39.2