]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/bot/default/navigation.qc
Bot AI: fix bots getting stuck in oblique warpzones (in the map hyperspace there...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / bot / default / navigation.qc
index 32d5c481435c673c52ef81f9a28d39a60db7d0de..8fe72ff6377d6690480eb61c7f6121e44a5cd32d 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <common/constants.qh>
 #include <common/net_linked.qh>
+#include <common/mapobjects/func/ladder.qh>
 #include <common/mapobjects/trigger/jumppads.qh>
 
 .float speed;
@@ -78,9 +79,11 @@ void navigation_dynamicgoal_init(entity this, bool initially_static)
                this.nearestwaypointtimeout = time;
 }
 
-void navigation_dynamicgoal_set(entity this)
+void navigation_dynamicgoal_set(entity this, entity dropper)
 {
        this.nearestwaypointtimeout = time;
+       if (dropper && dropper.nearestwaypointtimeout && dropper.nearestwaypointtimeout < time + 2)
+               this.nearestwaypoint = dropper.nearestwaypoint;
        if (this.nearestwaypoint)
                this.nearestwaypointtimeout += 2;
 }
@@ -913,7 +916,7 @@ entity navigation_findnearestwaypoint_withdist_except(entity ent, float walkfrom
        vector pm2 = ent.origin + ent.maxs;
 
        // do two scans, because box test is cheaper
-       IL_EACH(g_waypoints, it != ent && it != except,
+       IL_EACH(g_waypoints, it != ent && it != except && !(it.wpflags & WAYPOINTFLAG_TELEPORT),
        {
                if(boxesoverlap(pm1, pm2, it.absmin, it.absmax))
                {
@@ -1215,11 +1218,7 @@ void navigation_markroutes_inverted(entity fixed_source_waypoint)
 // updates the best goal according to a weighted calculation of travel cost and item value of a new proposed item
 void navigation_routerating(entity this, entity e, float f, float rangebias)
 {
-       if (!e)
-               return;
-
-       if(e.blacklisted)
-               return;
+       if (!e || e.blacklisted) { return; }
 
        rangebias = waypoint_getlinearcost(rangebias);
        f = waypoint_getlinearcost(f);
@@ -1609,6 +1608,16 @@ int navigation_poptouchedgoals(entity this)
 
        if(this.goalcurrent.wpflags & WAYPOINTFLAG_TELEPORT)
        {
+               if (!this.goalcurrent.wpisbox // warpzone
+                       && vlen2(this.origin - this.goalstack01.origin) < vlen2(this.origin - this.goalcurrent.origin))
+               {
+                       navigation_poproute(this);
+                       ++removed_goals;
+                       navigation_poproute(this);
+                       ++removed_goals;
+                       return removed_goals;
+               }
+
                // make sure jumppad is really hit, don't rely on distance based checks
                // as they may report a touch even if it didn't really happen
                if(this.lastteleporttime > 0 && TELEPORT_USED(this, this.goalcurrent))
@@ -1703,8 +1712,16 @@ int navigation_poptouchedgoals(entity this)
                        gc_min = this.goalcurrent.origin - '1 1 1' * 12;
                        gc_max = this.goalcurrent.origin + '1 1 1' * 12;
                }
-               if(!boxesoverlap(this.absmin, this.absmax, gc_min, gc_max))
-                       break;
+               if (time < this.ladder_time)
+               {
+                       if (!boxesoverlap(this.absmin, this.absmax - eZ * STAT(PL_MAX, this).z, gc_min, gc_max))
+                               break;
+               }
+               else
+               {
+                       if (!boxesoverlap(this.absmin, this.absmax, gc_min, gc_max))
+                               break;
+               }
 
                // Detect personal waypoints
                if(this.aistatus & AI_STATUS_WAYPOINT_PERSONAL_GOING)