]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/mapobjects/func/ladder.qc
Make ladders use the same iterative logic as conveyors, fixes some maps with super...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / mapobjects / func / ladder.qc
index 6fb3a435aa59b7b557cf04b521f2e77a01367665..23cdf1d49f4ac454c8d6901070e9d90ab9df3199 100644 (file)
@@ -1,22 +1,45 @@
 #include "ladder.qh"
 REGISTER_NET_LINKED(ENT_CLIENT_LADDER)
 
-void func_ladder_touch(entity this, entity toucher)
+void func_ladder_think(entity this)
 {
-#ifdef SVQC
-       if (!toucher.iscreature)
-               return;
-       if(IS_VEHICLE(toucher))
-               return;
-#elif defined(CSQC)
-       if(!IS_PLAYER(toucher)) // don't allow non-player predicted entities!
-               return;
+#ifdef CSQC
+       // TODO: check if this is what is causing the glitchiness when switching between them
+       float dt = time - this.move_time;
+       this.move_time = time;
+       if(dt <= 0) { return; }
 #endif
 
-       EXACTTRIGGER_TOUCH(this, toucher);
+       // set myself as current ladders where possible
+       IL_EACH(g_ladderents, it.ladder_entity == this,
+       {
+               it.ladder_entity = NULL;
+               IL_REMOVE(g_ladderents, it);
+       });
 
-       toucher.ladder_time = time + 0.1;
-       toucher.ladder_entity = this;
+       FOREACH_ENTITY_RADIUS((this.absmin + this.absmax) * 0.5, vlen(this.absmax - this.absmin) * 0.5 + 1, !it.ladder_entity && IS_PLAYER(it) && it.move_movetype != MOVETYPE_NOCLIP && !IS_DEAD(it),
+       {
+               vector emin = it.absmin;
+               vector emax = it.absmax;
+               if(this.solid == SOLID_BSP || (IS_CSQC && this.solid == SOLID_TRIGGER)) // CSQC doesn't expand properly
+               {
+                       emin -= '1 1 1';
+                       emax += '1 1 1';
+               }
+               if(boxesoverlap(emin, emax, this.absmin, this.absmax)) // quick
+               {
+                       if(WarpZoneLib_BoxTouchesBrush(emin, emax, this, it)) // accurate
+                       {
+                               if(!it.ladder_entity)
+                                       IL_PUSH(g_ladderents, it);
+                               it.ladder_entity = this;
+                       }
+               }
+       });
+
+#ifdef SVQC
+       this.nextthink = time;
+#endif
 }
 
 #ifdef SVQC
@@ -41,9 +64,10 @@ void func_ladder_link(entity this)
 
 void func_ladder_init(entity this)
 {
-       settouch(this, func_ladder_touch);
        trigger_init(this);
        func_ladder_link(this);
+       setthink(this, func_ladder_think);
+       this.nextthink = time;
 
        if(min(this.absmax.x - this.absmin.x, this.absmax.y - this.absmin.y) > 100)
                return;
@@ -124,8 +148,15 @@ spawnfunc(func_water)
 #elif defined(CSQC)
 .float speed;
 
+void func_ladder_draw(entity this) { func_ladder_think(this); }
+
 void func_ladder_remove(entity this)
 {
+       IL_EACH(g_ladderents, it.ladder_entity == this,
+       {
+               it.ladder_entity = NULL;
+               IL_REMOVE(g_ladderents, it);
+       });
        strfree(this.classname);
 }
 
@@ -134,15 +165,22 @@ NET_HANDLE(ENT_CLIENT_LADDER, bool isnew)
        this.classname = strzone(ReadString());
        this.skin = ReadByte();
        this.speed = ReadCoord();
+       this.solid = SOLID_TRIGGER;
 
        trigger_common_read(this, false);
 
-       this.solid = SOLID_TRIGGER;
-       settouch(this, func_ladder_touch);
+       if(isnew)
+               IL_PUSH(g_drawables, this);
+       this.draw = func_ladder_draw;
        this.drawmask = MASK_NORMAL;
+
        this.move_time = time;
        this.entremove = func_ladder_remove;
 
+       // NOTE: CSQC's version of setorigin doesn't expand
+       this.absmin -= '1 1 1';
+       this.absmax += '1 1 1';
+
        return true;
 }
 #endif