// return true when bot isn't getting closer to the current goal
bool havocbot_checkgoaldistance(entity this, vector gco)
{
- float curr_dist = vlen(this.origin - gco);
- float curr_dist_2d = vlen(vec2(this.origin - gco));
+ float curr_dist_z = max(20, fabs(this.origin.z - gco.z));
+ float curr_dist_2d = max(20, vlen(vec2(this.origin - gco)));
float distance_time = this.goalcurrent_distance_time;
if(distance_time < 0)
distance_time = -distance_time;
- if(curr_dist > this.goalcurrent_distance && curr_dist_2d > this.goalcurrent_distance_2d)
+ if(curr_dist_z >= this.goalcurrent_distance_z && curr_dist_2d >= this.goalcurrent_distance_2d)
{
if(!distance_time)
this.goalcurrent_distance_time = time;
else
{
// reduce it a little bit so it works even with very small approaches to the goal
- this.goalcurrent_distance = max(20, curr_dist - 10);
+ this.goalcurrent_distance_z = max(20, curr_dist_z - 10);
this.goalcurrent_distance_2d = max(20, curr_dist_2d - 10);
this.goalcurrent_distance_time = 0;
}
PHYS_INPUT_BUTTON_JETPACK(this) = false;
// Jetpack navigation
- if(this.goalcurrent)
if(this.navigation_jetpack_goal)
if(this.goalcurrent==this.navigation_jetpack_goal)
if(this.ammo_fuel)
if(this.aistatus & AI_STATUS_JETPACK_LANDING)
{
// Calculate brake distance in xy
- float db, v, d;
- vector dxy;
-
- dxy = this.origin - ( ( this.goalcurrent.absmin + this.goalcurrent.absmax ) * 0.5 ); dxy.z = 0;
- d = vlen(dxy);
- v = vlen(this.velocity - this.velocity.z * '0 0 1');
- db = ((v ** 2) / (autocvar_g_jetpack_acceleration_side * 2)) + 100;
- // dprint("distance ", ftos(ceil(d)), " velocity ", ftos(ceil(v)), " brake at ", ftos(ceil(db)), "\n");
+ float d = vlen(vec2(this.origin - (this.goalcurrent.absmin + this.goalcurrent.absmax) * 0.5));
+ float v = vlen(vec2(this.velocity));
+ float db = ((v ** 2) / (autocvar_g_jetpack_acceleration_side * 2)) + 100;
+ //LOG_INFOF("distance %d, velocity %d, brake at %d ", ceil(d), ceil(v), ceil(db));
if(d < db || d < 500)
{
// Brake
- if(fabs(this.velocity.x)>maxspeed*0.3)
+ if(v > maxspeed * 0.3)
{
CS(this).movement_x = dir * v_forward * -maxspeed;
return;
}
else
{
+ if (this.goalcurrent.bot_pickup)
+ {
+ entity jumppad_wp = this.goalcurrent_prev;
+ navigation_poptouchedgoals(this);
+ if(!this.goalcurrent && jumppad_wp.wp00)
+ {
+ // head to the jumppad destination once bot reaches the goal item
+ navigation_pushroute(this, jumppad_wp.wp00);
+ }
+ }
gco = (this.goalcurrent.absmin + this.goalcurrent.absmax) * 0.5;
if (this.origin.z > gco.z && vdist(vec2(this.velocity), <, autocvar_sv_maxspeed))
this.aistatus &= ~AI_STATUS_OUT_JUMPPAD;
if (skill > 6 && !(IS_ONGROUND(this)))
{
#define ROCKETJUMP_DAMAGE() WEP_CVAR(devastator, damage) * 0.8 \
- * ((this.strength_finished < time) ? autocvar_g_balance_powerup_strength_selfdamage : 1) \
- * ((this.invincible_finished < time) ? autocvar_g_balance_powerup_invincible_takedamage : 1)
+ * ((this.strength_finished > time) ? autocvar_g_balance_powerup_strength_selfdamage : 1) \
+ * ((this.invincible_finished > time) ? autocvar_g_balance_powerup_invincible_takedamage : 1)
tracebox(this.origin, this.mins, this.maxs, this.origin + '0 0 -65536', MOVE_NOMONSTERS, this);
if(tracebox_hits_trigger_hurt(this.origin, this.mins, this.maxs, trace_endpos ))
}
if(!locked_goal)
{
- if(navigation_poptouchedgoals(this) && time > this.bot_strategytime - (IS_MOVABLE(this.goalentity) ? 3 : 2))
- navigation_goalrating_timeout_force(this);
+ // optimize path finding by anticipating goalrating when bot is near a waypoint;
+ // in this case path finding can start directly from a waypoint instead of
+ // looking for all the reachable waypoints up to a certain distance
+ if(navigation_poptouchedgoals(this) && this.goalcurrent)
+ {
+ if(navigation_goalrating_timeout_can_be_anticipated(this))
+ navigation_goalrating_timeout_force(this);
+ }
}
// if ran out of goals try to use an alternative goal or get a new strategy asap
}
// if bot for some reason doesn't get close to the current goal find another one
- if(!this.jumppadcount && !IS_PLAYER(this.goalcurrent) && !(this.goalcurrent.bot_pickup_respawning && this.goalcurrent_distance < 50))
+ if(!this.jumppadcount && !IS_PLAYER(this.goalcurrent))
+ if(!(this.goalcurrent.bot_pickup_respawning && this.goalcurrent_distance_z < 50 && this.goalcurrent_distance_2d < 50))
if(havocbot_checkgoaldistance(this, gco))
{
if(this.goalcurrent_distance_time < 0) // can't get close for the second time
// give bot only another chance to prevent bot getting stuck
// in case it thinks it can walk but actually can't
- this.goalcurrent_distance = FLOAT_MAX;
+ this.goalcurrent_distance_z = FLOAT_MAX;
this.goalcurrent_distance_2d = FLOAT_MAX;
this.goalcurrent_distance_time = -time; // mark second try
}