]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/lib/warpzone/common.qc
Merge branch 'bones_was_here/sv_legacy_bbox_expand_4' into 'master'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / warpzone / common.qc
index 66658a3901d1dd7837e5883675a328c26e35b927..7858311bcecdb78404d6999fc56adc5e6969ba95 100644 (file)
@@ -101,17 +101,12 @@ void WarpZone_Camera_SetUp(entity e, vector my_org, vector my_ang) // we assume
 
 .entity enemy;
 
-vector WarpZoneLib_BoxTouchesBrush_mins;
-vector WarpZoneLib_BoxTouchesBrush_maxs;
-entity WarpZoneLib_BoxTouchesBrush_ent;
-entity WarpZoneLib_BoxTouchesBrush_ignore;
-float WarpZoneLib_BoxTouchesBrush_Recurse()
+float WarpZoneLib_BoxTouchesBrush_Recurse(vector mi, vector ma, entity e, entity ig)
 {
-       float s;
+       float f, s;
        entity se;
-       float f;
 
-       tracebox('0 0 0', WarpZoneLib_BoxTouchesBrush_mins, WarpZoneLib_BoxTouchesBrush_maxs, '0 0 0', MOVE_NOMONSTERS, WarpZoneLib_BoxTouchesBrush_ignore);
+       tracebox('0 0 0', mi, ma, '0 0 0', MOVE_NOMONSTERS, ig);
 #ifdef CSQC
        if (trace_networkentity)
        {
@@ -123,35 +118,52 @@ float WarpZoneLib_BoxTouchesBrush_Recurse()
 #endif
        if (!trace_ent)
                return 0;
-       if (trace_ent == WarpZoneLib_BoxTouchesBrush_ent)
+       if (trace_ent == e)
                return 1;
 
        se = trace_ent;
        s = se.solid;
        se.solid = SOLID_NOT;
-       f = WarpZoneLib_BoxTouchesBrush_Recurse();
+       setorigin(se, se.origin); // unlink
+       f = WarpZoneLib_BoxTouchesBrush_Recurse(mi, ma, e, ig);
        se.solid = s;
+       setorigin(se, se.origin); // relink
 
        return f;
 }
 
 float WarpZoneLib_BoxTouchesBrush(vector mi, vector ma, entity e, entity ig)
 {
-    float f, s;
+       // bones_was_here: TODO: when findbox() builtin is available, use it to
+       // optimise this into a single non-recursive function that only calls tracebox once
 
-    if(!e.modelindex || e.warpzone_isboxy)
-        return 1;
+       float f, s;
 
-    s = e.solid;
-    e.solid = SOLID_BSP;
-    WarpZoneLib_BoxTouchesBrush_mins = mi;
-    WarpZoneLib_BoxTouchesBrush_maxs = ma;
-    WarpZoneLib_BoxTouchesBrush_ent = e;
-    WarpZoneLib_BoxTouchesBrush_ignore = ig;
-    f = WarpZoneLib_BoxTouchesBrush_Recurse();
-    e.solid = s;
+       if(!e.modelindex || e.warpzone_isboxy)
+               return 1;
+
+       // work around trigger_hurt on geit3ctf1 not being detected by tracebox
+       // bones_was_here: FIXME: WHY do these triggers only have supercontents == 128 ?!
+       if (Q3COMPAT_COMMON && ig != world)
+               ig.dphitcontentsmask |= 128;
+
+       s = e.solid;
+       if (e.solid != SOLID_BSP)
+       {
+               e.solid = SOLID_BSP;
+               setorigin(e, e.origin); // update linking
+       }
+       f = WarpZoneLib_BoxTouchesBrush_Recurse(mi, ma, e, ig);
+       if (e.solid != s) // if we needed to change .solid temporarily
+       {
+               e.solid = s; // restore it
+               setorigin(e, e.origin); // update linking
+       }
+
+       if (Q3COMPAT_COMMON && ig != world)
+               ig.dphitcontentsmask &= ~128;
 
-    return f;
+       return f;
 }
 
 entity WarpZone_Find(vector mi, vector ma)
@@ -582,6 +594,7 @@ bool WarpZoneLib_BadEntity(entity e)
                case "weaponentity":
                case "exteriorweaponentity":
                case "sprite_waypoint":
+               case "waypoint":
                case "spawnfunc":
                case "weaponchild":
                case "chatbubbleentity":
@@ -795,14 +808,22 @@ entity WarpZone_RefSys_SpawnSameRefSys(entity me)
        return e;
 }
 
-bool WarpZoneLib_ExactTrigger_Touch(entity this, entity toucher)
+bool WarpZoneLib_ExactTrigger_Touch(entity this, entity toucher, bool touchfunc)
 {
        vector emin = toucher.absmin, emax = toucher.absmax;
-       // the engine offsets absolute bounding boxes by a single quake unit
-       // we must undo that here to allow accurate touching
-       emin += '1 1 1';
-       emax -= '1 1 1';
-       return !WarpZoneLib_BoxTouchesBrush(emin, emax, this, toucher);
+       if (!Q3COMPAT_COMMON)
+       {
+               // Xonotic and Nexuiz maps assume triggers will be activated by adjacent players
+               // prior to sv_legacy_bbox_expand 0 DP always did this for SVQC and never for CSQC
+               emin -= '1 1 1';
+               emax += '1 1 1';
+       }
+
+       // if called from a touch func, we can assume the boxes do overlap
+       if (!touchfunc && !boxesoverlap(emin, emax, this.absmin, this.absmax)) // quick
+               return false;
+
+       return WarpZoneLib_BoxTouchesBrush(emin, emax, this, toucher); // accurate
 }
 
 
@@ -820,16 +841,16 @@ void WarpZoneLib_MoveOutOfSolid_Expand(entity e, vector by)
        }
 }
 
-bool WarpZoneLib_MoveOutOfSolid(entity e)
+int WarpZoneLib_MoveOutOfSolid(entity e)
 {
        vector o = e.origin;
        traceline(o, o, MOVE_WORLDONLY, e);
        if (trace_startsolid)
-               return false;
+               return 0; // too stuck, giving up
 
        tracebox(o, e.mins, e.maxs, o, MOVE_WORLDONLY, e);
        if (!trace_startsolid)
-               return true;
+               return -1; // wasn't stuck
 
        vector m0 = e.mins;
        vector m1 = e.maxs;
@@ -847,8 +868,8 @@ bool WarpZoneLib_MoveOutOfSolid(entity e)
        if (trace_startsolid)
        {
                setorigin(e, o);
-               return false;
+               return 0; // can't fix
        }
 
-       return true;
+       return 1; // was stuck but is fixed now
 }