.float speed;
+void navigation_goalrating_timeout_set(entity this)
+{
+ if(IS_MOVABLE(this.goalentity))
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval_movingtarget;
+ else
+ this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+}
+
+void navigation_goalrating_timeout_force(entity this)
+{
+ this.bot_strategytime = 0;
+}
+
+bool navigation_goalrating_timeout(entity this)
+{
+ return this.bot_strategytime < time;
+}
+
void navigation_dynamicgoal_init(entity this, bool initially_static)
{
this.navigation_dynamicgoal = true;
IL_EACH(g_waypoints, it != ent && it != except,
{
if(boxesoverlap(pm1, pm2, it.absmin, it.absmax))
+ {
+ if(!autocvar_g_waypointeditor && walkfromwp && !ent.navigation_dynamicgoal)
+ {
+ waypoint_clearlinks(ent); // initialize wpXXmincost fields
+ navigation_item_addlink(it, ent);
+ }
return it;
+ }
});
vector org = ent.origin;
if(walkfromwp && (it.wpflags & WAYPOINTFLAG_NORELINK))
continue;
- SET_TRACEWALK_DESTCOORDS(it, org, v2, v2_height);
- if(vdist(v2 - org, <, 1050))
- if(tracewalk(ent, org, PL_MIN_CONST, PL_MAX_CONST, v2, v2_height, bot_navigation_movemode))
+ SET_TRACEWALK_DESTCOORDS(ent, it.origin, v2, v2_height);
+ if(vdist(v2 - it.origin, <, 1050))
+ if(tracewalk(ent, it.origin, PL_MIN_CONST, PL_MAX_CONST, v2, v2_height, bot_navigation_movemode))
navigation_item_addlink(it, ent);
});
}
if ((!e.nearestwaypoint || e.navigation_dynamicgoal)
&& e.nearestwaypointtimeout >= 0 && time > e.nearestwaypointtimeout)
{
- nwp = navigation_findnearestwaypoint(e, true);
- if(nwp)
- {
- e.nearestwaypoint = nwp;
-
- vector m1 = nwp.absmin, m2 = nwp.absmax;
- m1.x = nwp.origin.x; m1.y = nwp.origin.y;
- m2.x = nwp.origin.x; m2.y = nwp.origin.y;
- vector ve = (e.absmin - e.absmax) * 0.5;
- ve.x = bound(m1.x, ve.x, m2.x);
- ve.y = bound(m1.y, ve.y, m2.y);
- ve.z = bound(m1.z, ve.z, m2.z);
-
- m1 = e.absmin; m2 = e.absmax;
- m1.x = e.origin.x; m1.y = e.origin.y;
- m2.x = e.origin.x; m2.y = e.origin.y;
- vector vnwp = nwp.origin;
- vnwp.x = bound(m1.x, vnwp.x, m2.x);
- vnwp.y = bound(m1.y, vnwp.y, m2.y);
- vnwp.z = bound(m1.z, vnwp.z, m2.z);
- e.nearestwaypoint_dist = vlen(ve - vnwp);
- }
- else
+ e.nearestwaypoint = nwp = navigation_findnearestwaypoint(e, true);
+ if(!nwp)
{
LOG_DEBUG("FAILED to find a nearest waypoint to '", e.classname, "' #", etos(e));
if(nearest_wp && nearest_wp.enemy)
{
// often path can be optimized by not adding the nearest waypoint
- if (this.goalentity.nearestwaypoint_dist < 8)
- e = nearest_wp.enemy;
- else
+ if (this.goalentity.navigation_dynamicgoal || autocvar_g_waypointeditor)
{
- if (this.goalentity.navigation_dynamicgoal || autocvar_g_waypointeditor)
- {
- SET_TRACEWALK_DESTCOORDS(e, nearest_wp.enemy.origin, dest, dest_height);
- if(vdist(dest - nearest_wp.enemy.origin, <, 1050))
- if(tracewalk(this, nearest_wp.enemy.origin, STAT(PL_MIN, this), STAT(PL_MAX, this), dest, dest_height, bot_navigation_movemode))
- e = nearest_wp.enemy;
- }
- else if(navigation_item_islinked(nearest_wp.enemy, this.goalentity))
+ SET_TRACEWALK_DESTCOORDS(this.goalentity, nearest_wp.enemy.origin, dest, dest_height);
+ if(vdist(dest - nearest_wp.enemy.origin, <, 1050))
+ if(tracewalk(this, nearest_wp.enemy.origin, STAT(PL_MIN, this), STAT(PL_MAX, this), dest, dest_height, bot_navigation_movemode))
e = nearest_wp.enemy;
}
+ else if(navigation_item_islinked(nearest_wp.enemy, this.goalentity))
+ e = nearest_wp.enemy;
}
for (;;)
int navigation_poptouchedgoals(entity this)
{
int removed_goals = 0;
+
+ if(IS_PLAYER(this.goalcurrent) && IS_DEAD(this.goalcurrent) && checkpvs(this.origin + this.view_ofs, this.goalcurrent))
+ {
+ navigation_poproute(this);
+ ++removed_goals;
+ }
+
if(this.goalcurrent.wpflags & WAYPOINTFLAG_TELEPORT)
{
// make sure jumppad is really hit, don't rely on distance based checks
this.aistatus |= AI_STATUS_WAYPOINT_PERSONAL_REACHED;
}
navigation_poproute(this);
+ this.lastteleporttime = 0;
++removed_goals;
}
else
// If for some reason the bot is closer to the next goal, pop the current one
if(this.goalstack01 && !wasfreed(this.goalstack01))
- if(vlen2(this.goalcurrent.origin - this.origin) > vlen2(this.goalstack01.origin - this.origin))
+ if(vlen2(this.goalcurrent.origin - this.origin) > vlen2(this.goalstack01.origin - this.origin)
+ || vlen2(this.goalcurrent.origin - this.goalstack01.origin) > vlen2(this.goalstack01.origin - this.origin))
if(checkpvs(this.origin + this.view_ofs, this.goalstack01))
{
vector dest = '0 0 0';
{
LOG_DEBUG(this.netname, " stuck, reachable waypoint found, heading to it");
navigation_routetogoal(this, bot_waypoint_queue_bestgoal, this.origin);
- this.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
+ navigation_goalrating_timeout_set(this);
this.aistatus &= ~AI_STATUS_STUCK;
}
else