]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/bot/default/navigation.qc
Merge branch 'master' into Lyberta/StandaloneOverkillWeapons
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / bot / default / navigation.qc
index 356c04b17ba6c4ef30230f0e82ba35997419c378..7b80a1a6f27cfd790fb59f325f8eda9404dfbcf9 100644 (file)
@@ -1474,16 +1474,20 @@ bool navigation_routetogoal(entity this, entity e, vector startposition)
                // often path can be optimized by not adding the nearest waypoint
                if (this.goalentity.navigation_dynamicgoal || autocvar_g_waypointeditor)
                {
-                       if (nearest_wp.enemy.wpcost < autocvar_bot_ai_strategyinterval_movingtarget
-                               && vdist(vec2(this.goalentity.origin - nearest_wp.origin), >, 16))
+                       if (nearest_wp.enemy.wpcost < autocvar_bot_ai_strategyinterval_movingtarget)
                        {
-                               set_tracewalk_dest(this.goalentity, nearest_wp.enemy.origin, true);
-                               if (trace_ent == this || (vdist(tracewalk_dest - nearest_wp.enemy.origin, <, 1050)
-                                       && vlen2(tracewalk_dest - nearest_wp.enemy.origin) < vlen2(nearest_wp.origin - nearest_wp.enemy.origin)
-                                       && tracewalk(this, nearest_wp.enemy.origin, STAT(PL_MIN, this), STAT(PL_MAX, this),
-                                       tracewalk_dest, tracewalk_dest_height, bot_navigation_movemode)))
-                               {
+                               if (vdist(vec2(this.goalentity.origin - nearest_wp.origin), <, 32))
                                        e = nearest_wp.enemy;
+                               else
+                               {
+                                       set_tracewalk_dest(this.goalentity, nearest_wp.enemy.origin, true);
+                                       if (trace_ent == this || (vdist(tracewalk_dest - nearest_wp.enemy.origin, <, 1050)
+                                               && vlen2(tracewalk_dest - nearest_wp.enemy.origin) < vlen2(nearest_wp.origin - nearest_wp.enemy.origin)
+                                               && tracewalk(this, nearest_wp.enemy.origin, STAT(PL_MIN, this), STAT(PL_MAX, this),
+                                               tracewalk_dest, tracewalk_dest_height, bot_navigation_movemode)))
+                                       {
+                                               e = nearest_wp.enemy;
+                                       }
                                }
                        }
                }
@@ -1588,8 +1592,7 @@ int navigation_poptouchedgoals(entity this)
        {
                // 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
-                       && time - this.lastteleporttime < ((this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL) ? 2 : 0.15))
+               if(this.lastteleporttime > 0 && TELEPORT_USED(this, this.goalcurrent))
                {
                        if(this.aistatus & AI_STATUS_WAYPOINT_PERSONAL_GOING)
                        if(this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL && this.goalcurrent.owner==this)
@@ -1604,6 +1607,37 @@ int navigation_poptouchedgoals(entity this)
                else
                        return removed_goals;
        }
+       else if (this.lastteleporttime > 0)
+       {
+               // sometimes bot is pushed so hard (by a jumppad or a shot) that ends up touching the next
+               // teleport / jumppad / warpzone present in its path skipping check of one or more goals
+               // if so immediately fix bot path by removing skipped goals
+               entity tele_ent = NULL;
+               if (this.goalstack01 && (this.goalstack01.wpflags & WAYPOINTFLAG_TELEPORT))
+                       tele_ent = this.goalstack01;
+               else if (this.goalstack02 && (this.goalstack02.wpflags & WAYPOINTFLAG_TELEPORT))
+                       tele_ent = this.goalstack02;
+               else if (this.goalstack03 && (this.goalstack03.wpflags & WAYPOINTFLAG_TELEPORT))
+                       tele_ent = this.goalstack03;
+               if (tele_ent && TELEPORT_USED(this, tele_ent))
+               {
+                       if (this.aistatus & AI_STATUS_WAYPOINT_PERSONAL_GOING)
+                       if (tele_ent.wpflags & WAYPOINTFLAG_PERSONAL && tele_ent.owner == this)
+                       {
+                               this.aistatus &= ~AI_STATUS_WAYPOINT_PERSONAL_GOING;
+                               this.aistatus |= AI_STATUS_WAYPOINT_PERSONAL_REACHED;
+                       }
+                       while (this.goalcurrent != tele_ent)
+                       {
+                               navigation_poproute(this);
+                               ++removed_goals;
+                       }
+                       navigation_poproute(this);
+                       this.lastteleporttime = 0;
+                       ++removed_goals;
+                       return removed_goals;
+               }
+       }
 
        // Loose goal touching check when running
        if(this.aistatus & AI_STATUS_RUNNING)
@@ -1662,10 +1696,16 @@ int navigation_poptouchedgoals(entity this)
 entity navigation_get_really_close_waypoint(entity this)
 {
        entity wp = this.goalcurrent;
-       if(!wp || vdist(wp.origin - this.origin, >, 50))
+       if(!wp)
                wp = this.goalcurrent_prev;
        if(!wp)
                return NULL;
+       if(wp != this.goalcurrent_prev && vdist(wp.origin - this.origin, >, 50))
+       {
+               wp = this.goalcurrent_prev;
+               if(!wp)
+                       return NULL;
+       }
        if(wp.classname != "waypoint")
        {
                wp = wp.nearestwaypoint;
@@ -1674,6 +1714,7 @@ entity navigation_get_really_close_waypoint(entity this)
        }
        if(vdist(wp.origin - this.origin, >, 50))
        {
+               wp = NULL;
                IL_EACH(g_waypoints, !(it.wpflags & WAYPOINTFLAG_TELEPORT),
                {
                        if(vdist(it.origin - this.origin, <, 50))
@@ -1682,6 +1723,8 @@ entity navigation_get_really_close_waypoint(entity this)
                                break;
                        }
                });
+               if(!wp)
+                       return NULL;
        }
        if(wp.wpflags & WAYPOINTFLAG_TELEPORT)
                return NULL;
@@ -1765,11 +1808,20 @@ void botframe_updatedangerousobjects(float maxupdate)
 
 void navigation_unstuck(entity this)
 {
-       float search_radius = 1000;
-
        if (!autocvar_bot_wander_enable)
                return;
 
+       bool has_user_waypoints = false;
+       IL_EACH(g_waypoints, !(it.wpflags & WAYPOINTFLAG_GENERATED),
+       {
+               has_user_waypoints = true;
+               break;
+       });
+       if (!has_user_waypoints)
+               return;
+
+       float search_radius = 1000;
+
        if (!bot_waypoint_queue_owner)
        {
                LOG_DEBUG(this.netname, " stuck, taking over the waypoints queue");