X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fbot%2Fdefault%2Fnavigation.qc;h=7b80a1a6f27cfd790fb59f325f8eda9404dfbcf9;hb=820589b53e6802eb4c5ea563bb58d48c4f4aa9e1;hp=356c04b17ba6c4ef30230f0e82ba35997419c378;hpb=f84d4c215d826d9b035e1ba79a22af077f123f55;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/bot/default/navigation.qc b/qcsrc/server/bot/default/navigation.qc index 356c04b17..7b80a1a6f 100644 --- a/qcsrc/server/bot/default/navigation.qc +++ b/qcsrc/server/bot/default/navigation.qc @@ -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");