if (trace_fraction < 1)
{
// check if we can walk over this obstacle, possibly by jumpstepping
- tracebox(org + jumpstepheightvec, m1, m2, move + jumpstepheightvec, movemode, e);
+ tracebox(org + stepheightvec, m1, m2, move + jumpstepheightvec, movemode, e);
if (trace_fraction < 1 || trace_startsolid)
{
- if(autocvar_bot_debug_tracewalk)
- debugnodestatus(trace_endpos, DEBUG_NODE_WARNING);
-
- // check for doors
- traceline( org, move, movemode, e);
- if ( trace_ent.classname == "door_rotating" || trace_ent.classname == "door")
+ tracebox(org + jumpstepheightvec, m1, m2, move + jumpstepheightvec, movemode, e);
+ if (trace_fraction < 1 || trace_startsolid)
{
- local vector nextmove;
- move = trace_endpos;
- while(trace_ent.classname == "door_rotating" || trace_ent.classname == "door")
+ if(autocvar_bot_debug_tracewalk)
+ debugnodestatus(trace_endpos, DEBUG_NODE_WARNING);
+
+ // check for doors
+ traceline( org, move, movemode, e);
+ if ( trace_ent.classname == "door_rotating" || trace_ent.classname == "door")
{
- nextmove = move + (dir * stepdist);
- traceline( move, nextmove, movemode, e);
- move = nextmove;
+ local vector nextmove;
+ move = trace_endpos;
+ while(trace_ent.classname == "door_rotating" || trace_ent.classname == "door")
+ {
+ nextmove = move + (dir * stepdist);
+ traceline( move, nextmove, movemode, e);
+ move = nextmove;
+ }
}
- }
- else
- {
- if(autocvar_bot_debug_tracewalk)
- debugnodestatus(trace_endpos, DEBUG_NODE_FAIL);
+ else
+ {
+ if(autocvar_bot_debug_tracewalk)
+ debugnodestatus(trace_endpos, DEBUG_NODE_FAIL);
- //print("tracewalk: ", vtos(start), " hit something when trying to reach ", vtos(end), "\n");
- //te_explosion(trace_endpos);
- //print(ftos(e.dphitcontentsmask), "\n");
- return FALSE; // failed
+ //print("tracewalk: ", vtos(start), " hit something when trying to reach ", vtos(end), "\n");
+ //te_explosion(trace_endpos);
+ //print(ftos(e.dphitcontentsmask), "\n");
+ return FALSE; // failed
+ }
}
+ else
+ move = trace_endpos;
}
else
move = trace_endpos;
if (!e)
return;
+ if(e.blacklisted)
+ return;
+
o = (e.absmin + e.absmax) * 0.5;
+
//print("routerating ", etos(e), " = ", ftos(f), " - ", ftos(rangebias), "\n");
// Evaluate path using jetpack
}
else
{
+ float search;
+
+ search = TRUE;
+
+ if(e.flags & FL_ITEM)
+ {
+ if not(e.flags & FL_WEAPON)
+ if(e.nearestwaypoint)
+ search = FALSE;
+ }
+ else if (e.flags & FL_WEAPON)
+ {
+ if(e.classname != "droppedweapon")
+ if(e.nearestwaypoint)
+ search = FALSE;
+ }
+
+ if(search)
if (time > e.nearestwaypointtimeout)
{
nwp = navigation_findnearestwaypoint(e, TRUE);
if(nwp)
e.nearestwaypoint = nwp;
else
+ {
dprint("FAILED to find a nearest waypoint to '", e.classname, "' #", etos(e), "\n");
+ if(e.flags & FL_ITEM)
+ e.blacklisted = TRUE;
+ else if (e.flags & FL_WEAPON)
+ {
+ if(e.classname != "droppedweapon")
+ e.blacklisted = TRUE;
+ }
+
+ if(e.blacklisted)
+ {
+ dprint("The entity '", e.classname, "' is going to be excluded from path finding during this match\n");
+ return;
+ }
+ }
+
// TODO: Cleaner solution, probably handling this timeout from ctf.qc
if(e.classname=="item_flag_team")
e.nearestwaypointtimeout = time + 2;
}
}
+ // If for some reason the bot is closer to the next goal, pop the current one
+ if(self.goalstack01)
+ if(vlen(self.goalcurrent.origin - self.origin) > vlen(self.goalstack01.origin - self.origin))
+ if(checkpvs(self.origin + self.view_ofs, self.goalstack01))
+ if(tracewalk(self, self.origin, self.mins, self.maxs, (self.goalstack01.absmin + self.goalstack01.absmax) * 0.5, bot_navigation_movemode))
+ {
+ /// dprint("path optimized for ", self.netname, ", removed a goal from the queue\n");
+ navigation_poproute();
+ // TODO this may also be a nice idea to do "early" (e.g. by
+ // manipulating the vlen() comparisons) to shorten paths in
+ // general - this would make bots walk more "on rails" than
+ // "zigzagging" which they currently do with sufficiently
+ // random-like waypoints, and thus can make a nice bot
+ // personality property
+ }
+
+ // HACK: remove players/bots as goals, they can lead a bot to unexpected places (cliffs, lava, etc)
+ // TODO: rate waypoints near the targetted player at that moment, instead of the player itself
+ if(self.goalcurrent.classname=="player")
+ navigation_poproute();
+
+ // aid for detecting jump pads better (distance based check fails sometimes)
+ if(self.goalcurrent.wpflags & WAYPOINTFLAG_TELEPORT && self.jumppadcount > 0 )
+ navigation_poproute();
+
// Loose goal touching check when running
if(self.aistatus & AI_STATUS_RUNNING)
+ if(self.speed >= autocvar_sv_maxspeed) // if -really- running
if(self.goalcurrent.classname=="waypoint")
{
if(vlen(self.origin - self.goalcurrent.origin)<150)