maxspeed = autocvar_sv_maxspeed;
- if(this.aistatus & AI_STATUS_DANGER_AHEAD)
+ if(this.aistatus & AI_STATUS_RUNNING && vdist(this.velocity, <, autocvar_sv_maxspeed * 0.75)
+ || this.aistatus & AI_STATUS_DANGER_AHEAD)
{
this.aistatus &= ~AI_STATUS_RUNNING;
PHYS_INPUT_BUTTON_JUMP(this) = false;
if(fabs(this.velocity.z)<50)
{
entity newgoal = NULL;
- IL_EACH(g_waypoints, vdist(it.origin - this.origin, <=, 1000),
+ if (vdist(this.origin - this.goalcurrent.origin, <, 150))
+ this.aistatus &= ~AI_STATUS_OUT_JUMPPAD;
+ else IL_EACH(g_waypoints, vdist(it.origin - this.origin, <=, 1000),
{
traceline(this.origin + this.view_ofs, ((it.absmin + it.absmax) * 0.5), true, this);
}
else
{
- if(this.velocity.z>0)
+ if(time - this.lastteleporttime > 0.3 && this.velocity.z > 0)
{
- float threshold;
vector velxy = this.velocity; velxy_z = 0;
- threshold = maxspeed * 0.2;
- if(vdist(velxy, <, threshold))
+ if(vdist(velxy, <, autocvar_sv_maxspeed * 0.2))
{
LOG_TRACE("Warning: ", this.netname, " got stuck on a jumppad (velocity in xy is ", vtos(velxy), "), trying to get out of it now");
this.aistatus |= AI_STATUS_OUT_JUMPPAD;
if (this.goalcurrent == NULL)
return;
- navigation_poptouchedgoals(this);
+
+ bool locked_goal = false;
+ if(this.goalentity && wasfreed(this.goalentity))
+ {
+ navigation_clearroute(this);
+ this.bot_strategytime = 0;
+ return;
+ }
+ else if(this.goalentity.bot_pickup)
+ {
+ if(this.goalentity.bot_pickup_respawning)
+ {
+ if(this.goalentity.solid) // item respawned
+ this.goalentity.bot_pickup_respawning = false;
+ else if(time < this.goalentity.scheduledrespawntime - 10) // item already taken (by someone else)
+ {
+ this.goalentity.bot_pickup_respawning = false;
+ navigation_clearroute(this);
+ this.bot_strategytime = 0;
+ return;
+ }
+ else if(this.goalentity == this.goalcurrent)
+ locked_goal = true; // wait for item to respawn
+ }
+ else if(!this.goalentity.solid)
+ {
+ navigation_clearroute(this);
+ this.bot_strategytime = 0;
+ return;
+ }
+ }
+ if(!locked_goal)
+ navigation_poptouchedgoals(this);
// if ran out of goals try to use an alternative goal or get a new strategy asap
if(this.goalcurrent == NULL)
evadeobstacle = '0 0 0';
evadelava = '0 0 0';
+ makevectors(this.v_angle.y * '0 1 0');
if (this.waterlevel)
{
if(this.waterlevel>WATERLEVEL_SWIMMING)
PHYS_INPUT_BUTTON_JUMP(this) = false;
}
dir = normalize(flatdir);
- makevectors(this.v_angle.y * '0 1 0');
}
else
{
float s;
+ vector offset;
if(this.aistatus & AI_STATUS_OUT_WATER)
this.aistatus &= ~AI_STATUS_OUT_WATER;
// jump if going toward an obstacle that doesn't look like stairs we
// can walk up directly
- tracebox(this.origin, this.mins, this.maxs, this.origin + this.velocity * 0.2, false, this);
+ offset = (vdist(this.velocity, >, 32) ? this.velocity * 0.2 : v_forward * 32);
+ tracebox(this.origin, this.mins, this.maxs, this.origin + offset, false, this);
if (trace_fraction < 1)
if (trace_plane_normal.z < 0.7)
{
s = trace_fraction;
- tracebox(this.origin + stepheightvec, this.mins, this.maxs, this.origin + this.velocity * 0.2 + stepheightvec, false, this);
+ tracebox(this.origin + stepheightvec, this.mins, this.maxs, this.origin + offset + stepheightvec, false, this);
if (trace_fraction < s + 0.01)
if (trace_plane_normal.z < 0.7)
{
s = trace_fraction;
- tracebox(this.origin + jumpstepheightvec, this.mins, this.maxs, this.origin + this.velocity * 0.2 + jumpstepheightvec, false, this);
+ tracebox(this.origin + jumpstepheightvec, this.mins, this.maxs, this.origin + offset + jumpstepheightvec, false, this);
if (trace_fraction > s)
PHYS_INPUT_BUTTON_JUMP(this) = true;
}
}
// avoiding dangers and obstacles
- vector dst_ahead = this.origin + this.view_ofs + this.velocity * 0.5;
+ offset = (vdist(this.velocity, >, 32) ? this.velocity * 0.5 : v_forward * 32);
+ vector dst_ahead = this.origin + this.view_ofs + offset;
vector dst_down = dst_ahead - '0 0 3000';
// Look ahead