]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/warpzonelib/common.qc
Merge remote branch 'origin/sev/newpanelhudskin' into fruitiex/fruitbalance
[xonotic/xonotic-data.pk3dir.git] / qcsrc / warpzonelib / common.qc
index 3f6bb10a2ebe872b77bc88e45f44558beced4bb1..1c3835afa35235a51d9a88e47ef5d7b749038c0a 100644 (file)
@@ -1,3 +1,6 @@
+float trace_dphitcontents;
+.float dphitcontents;
+
 void WarpZone_Accumulator_Clear(entity acc)
 {
        acc.warpzone_transform = '0 0 0';
@@ -55,6 +58,21 @@ void WarpZone_SetUp(entity e, vector my_org, vector my_ang, vector other_org, ve
        e.camera_transform = WarpZone_camera_transform;
 }
 
+vector WarpZone_Camera_camera_transform(vector org, vector ang)
+{
+       // a fixed camera view
+       trace_endpos = self.warpzone_origin;
+       makevectors(self.warpzone_angles);
+       return self.warpzone_origin;
+}
+
+void WarpZone_Camera_SetUp(entity e, vector my_org, vector my_ang) // we assume that e.oldorigin and e.avelocity point to view origin and direction
+{
+       e.warpzone_origin = my_org;
+       e.warpzone_angles = my_ang;
+       e.camera_transform = WarpZone_Camera_camera_transform;
+}
+
 .entity enemy;
 
 vector WarpZoneLib_BoxTouchesBrush_mins;
@@ -150,7 +168,9 @@ void WarpZone_Trace_AddTransform(entity wz)
 
 void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end, float nomonsters, entity forent, entity zone, WarpZone_trace_callback_t cb)
 {
+       float nomonsters_adjusted;
        float frac, sol, i;
+       float contentshack;
        vector o0, e0;
        entity wz;
        vector vf, vr, vu;
@@ -159,6 +179,20 @@ void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end,
        vu = v_up;
        o0 = org;
        e0 = end;
+
+       switch(nomonsters)
+       {
+               case MOVE_WORLDONLY:
+               case MOVE_NOTHING:
+                       nomonsters_adjusted = MOVE_NOMONSTERS;
+                       break;
+               default:
+                       nomonsters_adjusted = nomonsters;
+                       break;
+       }
+       if((contentshack = (forent.dphitcontentsmask && !(forent.dphitcontentsmask & DPCONTENTS_SOLID))))
+               forent.dphitcontentsmask |= DPCONTENTS_SOLID;
+
        WarpZone_Trace_InitTransform();
        // if starting in warpzone, first transform
        wz = WarpZone_Find(org + mi, org + ma);
@@ -185,9 +219,10 @@ void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end,
                if(--i < 1)
                {
                        dprint("Too many warpzones in sequence, aborting trace.\n");
+                       trace_ent = world;
                        break;
                }
-               tracebox(org, mi, ma, end, nomonsters, forent);
+               tracebox(org, mi, ma, end, nomonsters_adjusted, forent);
                if(cb)
                        cb(org, trace_endpos, end);
                if(sol < 0)
@@ -197,10 +232,21 @@ void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end,
                if(trace_fraction >= 1)
                        break;
                if(trace_ent.classname != "trigger_warpzone")
+               {
+                       if((nomonsters == MOVE_NOTHING) || ((nomonsters == MOVE_WORLDONLY) && trace_ent) || (contentshack && (trace_dphitcontents & forent.dphitcontentsmask) == DPCONTENTS_SOLID))
+                       {
+                               // continue the trace, ignoring this hit (we only care for warpzones)
+                               org = trace_endpos + normalize(end - org);
+                               continue;
+                               // we cannot do an inverted trace here, as we do care for further warpzones inside that "solid" to be found
+                               // otherwise, players could block entrances that way
+                       }
                        break;
+               }
                if(trace_ent == wz)
                {
                        dprint("I transformed into the same zone again, wtf, aborting the trace\n");
+                       trace_ent = world;
                        break;
                }
                wz = trace_ent;
@@ -213,6 +259,8 @@ void WarpZone_TraceBox_ThroughZone(vector org, vector mi, vector ma, vector end,
        }
        WarpZone_MakeAllOther();
 :fail
+       if(contentshack)
+               forent.dphitcontentsmask &~= DPCONTENTS_SOLID;
        trace_startsolid = sol;
        v_forward = vf;
        v_right = vr;
@@ -240,6 +288,7 @@ void WarpZone_TraceToss_ThroughZone(entity e, entity forent, entity zone, WarpZo
        vu = v_up;
        o0 = e.origin;
        v0 = e.velocity;
+
        WarpZone_Trace_InitTransform();
        // if starting in warpzone, first transform
        wz = WarpZone_Find(e.origin + e.mins, e.origin + e.maxs);
@@ -266,6 +315,7 @@ void WarpZone_TraceToss_ThroughZone(entity e, entity forent, entity zone, WarpZo
                if(--i < 1)
                {
                        dprint("Too many warpzones in sequence, aborting trace.\n");
+                       trace_ent = world;
                        break;
                }
                tracetoss(e, forent);
@@ -282,6 +332,7 @@ void WarpZone_TraceToss_ThroughZone(entity e, entity forent, entity zone, WarpZo
                if(trace_ent == wz)
                {
                        dprint("I transformed into the same zone again, wtf, aborting the trace\n");
+                       trace_ent = world;
                        break;
                }
                wz = trace_ent;