}
else
{
- if (!this.jumppadcount && !STAT(FROZEN, this))
+ if (!this.jumppadcount && !STAT(FROZEN, this)
+ && !(this.goalcurrent_prev && (this.goalcurrent_prev.wpflags & WAYPOINTFLAG_JUMP)))
+ {
+ // find a new goal
this.havocbot_role(this); // little too far down the rabbit hole
+ }
}
// if we don't have a goal and we're under water look for a waypoint near the "shore" and push it
{
if (this.goalcurrent)
navigation_clearroute(this);
+ this.enemy = NULL;
+ this.bot_aimtarg = NULL;
return;
}
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) \
+ * ((STAT(STRENGTH_FINISHED, this) > time) ? autocvar_g_balance_powerup_strength_selfdamage : 1) \
* ((this.invincible_finished > time) ? autocvar_g_balance_powerup_invincible_takedamage : 1)
// save some CPU cycles by checking trigger_hurt after checking
dir = normalize(diff);
flatdir = (diff.z == 0) ? dir : normalize(vec2(diff));
- vector evadedanger = '0 0 0';
+ bool danger_detected = false;
+ vector do_break = '0 0 0';
//if (this.bot_dodgevector_time < time)
{
{
PHYS_INPUT_BUTTON_JUMP(this) = true;
this.bot_jump_time = time;
- // avoid changing route while bot is jumping a gap
- navigation_goalrating_timeout_extend_if_needed(this, 1.5);
}
}
else if (!this.goalstack01 || (this.goalcurrent.wpflags & (WAYPOINTFLAG_TELEPORT | WAYPOINTFLAG_LADDER)))
bool unreachable = false;
s = CONTENT_SOLID;
- bool danger_detected = false;
if (trace_fraction == 1 && !this.jumppadcount
&& !waypoint_is_hardwiredlink(this.goalcurrent_prev, this.goalcurrent)
&& !(this.goalcurrent_prev && (this.goalcurrent_prev.wpflags & WAYPOINTFLAG_JUMP)))
{
if (trace_dphitq3surfaceflags & Q3SURFACEFLAG_SKY)
danger_detected = true;
+ else if (trace_endpos.z < min(this.origin.z + this.mins.z, this.goalcurrent.origin.z) - 100)
+ danger_detected = true;
else
{
s = pointcontents(trace_endpos + '0 0 1');
}
}
}
- if (danger_detected && fabs(deviation.y) < 80
- && (fabs(deviation.y) > 5 || vdist(vec2(this.velocity), >, maxspeed * 1.5)))
- {
- evadedanger = normalize(this.velocity) * -1;
- evadedanger.z = 0;
- }
dir = flatdir;
makevectors(this.v_angle.y * '0 1 0');
// tracebox wouldn't work when bot is still on the ledge
traceline(this.origin, this.origin - '0 0 200', true, this);
if (this.origin.z - trace_endpos.z > 120)
- evadedanger = normalize(this.velocity) * -1;
+ do_break = normalize(this.velocity) * -1;
}
if(unreachable)
dodge = havocbot_dodge(this);
if (dodge)
dodge *= bound(0, 0.5 + (skill + this.bot_dodgeskill) * 0.1, 1);
- evadedanger *= bound(1, 3 - (skill + this.bot_dodgeskill), 3); // Noobs fear dangers a lot and take more distance from them
if (this.enemy)
{
traceline(this.origin, (this.enemy.absmin + this.enemy.absmax) * 0.5, true, NULL);
bot_aimdir(this, dir, 0);
}
+ vector evadedanger = '0 0 0';
if (!ladder_zdir)
{
dir *= dodge_enemy_factor;
- dir = normalize(dir + dodge + evadedanger);
+ if (danger_detected && vdist(this.velocity, >, maxspeed * 0.8) && this.goalcurrent_prev
+ && this.goalcurrent.classname == "waypoint")
+ {
+ vector p = this.origin + this.velocity * 0.2;
+ vector evadedanger = point_line_vec(p, vec2(this.goalcurrent_prev.origin) + eZ * p.z,
+ vec2(destorg - this.goalcurrent_prev.origin));
+ if (vdist(evadedanger, >, 20))
+ {
+ if (vdist(evadedanger, >, 40))
+ do_break = normalize(this.velocity) * -1;
+ evadedanger = normalize(evadedanger);
+ evadedanger *= bound(1, 3 - (skill + this.bot_dodgeskill), 3); // Noobs fear dangers a lot and take more distance from them
+ }
+ else
+ evadedanger = '0 0 0';
+ }
+ dir = normalize(dir + dodge + do_break + evadedanger);
}
makevectors(this.v_angle);
havocbot_keyboard_movement(this, destorg);
// Bunnyhop!
- if (!bunnyhop_forbidden && skill + this.bot_moveskill >= autocvar_bot_ai_bunnyhop_skilloffset)
+ if (!bunnyhop_forbidden && !evadedanger && !do_break && skill + this.bot_moveskill >= autocvar_bot_ai_bunnyhop_skilloffset)
havocbot_bunnyhop(this, dir);
if (dir * v_up >= autocvar_sv_jumpvelocity * 0.5 && IS_ONGROUND(this))