return min(max(v.x, -v.x), max(v.y, -v.y));
}
-ERASEABLE
-float dist_point_line(vector p, vector l0, vector ldir)
-{
- ldir = normalize(ldir);
-
- // remove the component in line direction
- p = p - (p * ldir) * ldir;
-
- // vlen of the remaining vector
- return vlen(p);
-}
-
/** requires that m2>m1 in all coordinates, and that m4>m3 */
ERASEABLE
float boxesoverlap(vector m1, vector m2, vector m3, vector m4) { return m2_x >= m3_x && m1_x <= m4_x && m2_y >= m3_y && m1_y <= m4_y && m2_z >= m3_z && m1_z <= m4_z; }
noref vector _yinvert;
#define yinvert(v) (_yinvert = (v), _yinvert.y = 1 - _yinvert.y, _yinvert)
+/// \param[in] p point
+/// \param[in] l0 starting point of ldir
+/// \param[in] ldir line
+/// \return Vector starting from p perpendicular to ldir
+ERASEABLE
+vector point_line_vec(vector p, vector l0, vector ldir)
+{
+ ldir = normalize(ldir);
+ p = l0 - p;
+ // remove the component in line direction from p
+ return p - ((p * ldir) * ldir);
+}
+
/**
* @param dir the directional vector
* @param norm the normalized normal
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)
{
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))