void navigation_routerating(entity e, float f, float rangebias)
{
entity nwp;
+ vector o;
if (!e)
return;
+ o = (e.absmin + e.absmax) * 0.5;
//print("routerating ", etos(e), " = ", ftos(f), " - ", ftos(rangebias), "\n");
// Evaluate path using jetpack
if(g_jetpack)
if(self.items & IT_JETPACK)
if(autocvar_bot_ai_navigation_jetpack)
- if(vlen(self.origin - e.origin) > autocvar_bot_ai_navigation_jetpack_mindistance)
+ if(vlen(self.origin - o) > autocvar_bot_ai_navigation_jetpack_mindistance)
{
vector pointa, pointb;
pointa = trace_endpos - '0 0 1';
// Point B
- traceline(e.origin, e.origin + '0 0 65535', MOVE_NORMAL, e);
+ traceline(o, o + '0 0 65535', MOVE_NORMAL, e);
pointb = trace_endpos - '0 0 1';
// Can I see these two points from the sky?
{
//te_wizspike(nwp.wpnearestpoint);
// dprint(e.classname, " ", ftos(f), "/(1+", ftos((nwp.wpcost + vlen(e.origin - nwp.wpnearestpoint))), "/", ftos(rangebias), ") = ");
- f = f * rangebias / (rangebias + (nwp.wpcost + vlen(e.origin - nwp.wpnearestpoint)));
+ f = f * rangebias / (rangebias + (nwp.wpcost + vlen(o - nwp.wpnearestpoint)));
//dprint("considering ", e.classname, " (with rating ", ftos(f), ")\n");
//dprint(ftos(f));
if (navigation_bestrating < f)
return TRUE;
// if it can reach the goal there is nothing more to do
- if (tracewalk(self, startposition, PL_MIN, PL_MAX, e.origin, bot_navigation_movemode))
+ if (tracewalk(self, startposition, PL_MIN, PL_MAX, (e.absmin + e.absmax) * 0.5, bot_navigation_movemode))
return TRUE;
// see if there are waypoints describing a path to the item
void botframe_updatedangerousobjects(float maxupdate)
{
local entity head, bot_dodgelist;
- local vector m1, m2, v;
+ local vector m1, m2, v, o;
local float c, d, danger;
c = 0;
bot_dodgelist = findchainfloat(bot_dodge, TRUE);
v_x = bound(m1_x, v_x, m2_x);
v_y = bound(m1_y, v_y, m2_y);
v_z = bound(m1_z, v_z, m2_z);
- d = head.bot_dodgerating - vlen(head.origin - v);
+ o = (head.absmin + head.absmax) * 0.5;
+ d = head.bot_dodgerating - vlen(o - v);
if (d > 0)
{
- traceline(head.origin, v, TRUE, world);
+ traceline(o, v, TRUE, world);
if (trace_fraction == 1)
danger = danger + d;
}
void navigation_unstuck()
{
+ float search_radius = 1000;
+
if not(autocvar_bot_wander_enable)
return;
- if not(navigation_wander_owner)
+ if not(bot_waypoint_queue_owner)
{
- dprint(self.netname, " taking over the waypoints queue\n");
- navigation_wander_owner = self;
- navigation_wander_bestgoal = world;
- navigation_wander_bestgoalrating = 0;
+ // dprint(self.netname, " sutck, taking over the waypoints queue\n");
+ bot_waypoint_queue_owner = self;
+ bot_waypoint_queue_bestgoal = world;
+ bot_waypoint_queue_bestgoalrating = 0;
}
- if(navigation_wander_owner!=self)
+ if(bot_waypoint_queue_owner!=self)
return;
- if (navigation_wander_goal)
+ if (bot_waypoint_queue_goal)
{
// evaluate the next goal on the queue
- float d = vlen(self.origin - navigation_wander_goal.origin);
- // dprint(self.netname, " evaluating ", navigation_wander_goal.classname, " with distance ", ftos(d), "\n");
- if(tracewalk(navigation_wander_goal, self.origin, PL_MIN, PL_MAX, navigation_wander_goal.origin, bot_navigation_movemode))
+ float d = vlen(self.origin - bot_waypoint_queue_goal.origin);
+ // dprint(self.netname, " evaluating ", bot_waypoint_queue_goal.classname, " with distance ", ftos(d), "\n");
+ if(tracewalk(bot_waypoint_queue_goal, self.origin, PL_MIN, PL_MAX, bot_waypoint_queue_goal.origin, bot_navigation_movemode))
{
- if( d > navigation_wander_bestgoalrating)
+ if( d > bot_waypoint_queue_bestgoalrating)
{
- navigation_wander_bestgoalrating = d;
- navigation_wander_bestgoal = navigation_wander_goal;
+ bot_waypoint_queue_bestgoalrating = d;
+ bot_waypoint_queue_bestgoal = bot_waypoint_queue_goal;
}
}
- navigation_wander_goal = navigation_wander_goal.navigation_wander_nextgoal;
+ bot_waypoint_queue_goal = bot_waypoint_queue_goal.bot_waypoint_queue_nextgoal;
- if not(navigation_wander_goal)
+ if not(bot_waypoint_queue_goal)
{
- if (navigation_wander_bestgoal)
+ if (bot_waypoint_queue_bestgoal)
{
- navigation_routetogoal(navigation_wander_bestgoal, self.origin);
+ dprint(self.netname, " stuck, reachable waypoint found, heading to it\n");
+ navigation_routetogoal(bot_waypoint_queue_bestgoal, self.origin);
self.bot_strategytime = time + autocvar_bot_ai_strategyinterval;
self.aistatus &~= AI_STATUS_STUCK;
}
else
{
- dprint(self.netname, " got BADLY stuck, giving up.\n");
+ dprint(self.netname, " stuck, cannot walk to any waypoint at all\n");
}
- navigation_wander_owner = world;
+ bot_waypoint_queue_owner = world;
}
}
else
{
+ if(bot_strategytoken!=self)
+ return;
+
// build a new queue
- dprint(self.netname, " building a new wayoints queue\n");
+ dprint(self.netname, " stuck, scanning reachable waypoints within ", ftos(search_radius)," qu\n");
- entity first, head, prev;
- head = findradius(self.origin, 1000);
+ entity head, first;
+
+ first = world;
+ head = findradius(self.origin, search_radius);
while(head)
{
if(head.classname=="waypoint")
- if(!(head.wpflags & WAYPOINTFLAG_GENERATED))
+ // if(!(head.wpflags & WAYPOINTFLAG_GENERATED))
{
- if (first==world)
- {
- first = head;
- navigation_wander_goal = head;
- }
+ if(bot_waypoint_queue_goal)
+ bot_waypoint_queue_goal.bot_waypoint_queue_nextgoal = head;
else
- {
- prev = navigation_wander_goal;
- navigation_wander_goal = head;
- prev.navigation_wander_nextgoal = head;
- navigation_wander_goal.navigation_wander_nextgoal = world;
- }
+ first = head;
+
+ bot_waypoint_queue_goal = head;
+ bot_waypoint_queue_goal.bot_waypoint_queue_nextgoal = world;
}
head = head.chain;
}
if (first)
- navigation_wander_goal = first;
+ bot_waypoint_queue_goal = first;
else
{
- dprint(self.netname, " got BADLY stuck, giving up.\n");
+ dprint(self.netname, " stuck, cannot walk to any waypoint at all\n");
+ bot_waypoint_queue_owner = world;
}
}
}
void debuggoalstack()
{
local entity goal;
- local vector org;
+ local vector org, go;
if(self.goalcounter==0)goal=self.goalcurrent;
else if(self.goalcounter==1)goal=self.goalstack01;
org = self.lastposition;
- te_lightning2(world, org, goal.origin);
- self.lastposition = goal.origin;
+ go = ( goal.absmin + goal.absmax ) * 0.5;
+ te_lightning2(world, org, go);
+ self.lastposition = go;
self.goalcounter++;
}