return;
}
- if(this.waterlevel > WATERLEVEL_WETFEET)
+ if(this.waterlevel > WATERLEVEL_WETFEET || IS_DUCKED(this))
{
this.aistatus &= ~AI_STATUS_RUNNING;
return;
if(this.aistatus & AI_STATUS_ROAMING)
if(this.goalcurrent.classname == "waypoint")
- if(!(this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL))
+ if (!(this.goalcurrent.wpflags & WAYPOINTFLAG_PERSONAL))
if(fabs(gco.z - this.origin.z) < this.maxs.z - this.mins.z)
- if(this.goalstack01 && !wasfreed(this.goalstack01))
+ if (this.goalstack01 && !wasfreed(this.goalstack01))
+ if (!(this.goalstack01.wpflags & WAYPOINTFLAG_JUMP))
{
vector gno = (this.goalstack01.absmin + this.goalstack01.absmax) * 0.5;
vector deviation = vectoangles(gno - this.origin) - vectoangles(gco - this.origin);
// return true when bot isn't getting closer to the current goal
bool havocbot_checkgoaldistance(entity this, vector gco)
{
+ if (this.bot_stop_moving_timeout > time)
+ return false;
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;
CS(this).movement = '0 0 0';
maxspeed = autocvar_sv_maxspeed;
+ if (this.goalcurrent.wpflags & WAYPOINTFLAG_CROUCH)
+ PHYS_INPUT_BUTTON_CROUCH(this) = true;
+ else
+ PHYS_INPUT_BUTTON_CROUCH(this) = false;
+
PHYS_INPUT_BUTTON_JETPACK(this) = false;
// Jetpack navigation
if(this.navigation_jetpack_goal)
return;
}
- else if(!this.jumppadcount && !this.goalcurrent.wphardwired
+ else if(!this.jumppadcount && !waypoint_is_hardwiredlink(this.goalcurrent_prev, this.goalcurrent)
+ && !(this.goalcurrent_prev && this.goalcurrent_prev.wpflags & WAYPOINTFLAG_JUMP)
&& GetResource(this, RES_HEALTH) + GetResource(this, RES_ARMOR) > ROCKETJUMP_DAMAGE())
{
if(this.velocity.z < 0)
vector flat_diff = vec2(diff);
offset = max(32, current_speed * cos(deviation.y * DEG2RAD) * 0.3) * flatdir;
vector actual_destorg = this.origin + offset;
- if (!this.goalstack01 || this.goalcurrent.wpflags & (WAYPOINTFLAG_TELEPORT | WAYPOINTFLAG_LADDER))
+ if (this.goalcurrent_prev && this.goalcurrent_prev.wpflags & WAYPOINTFLAG_JUMP)
+ {
+ if (time > this.bot_stop_moving_timeout
+ && fabs(deviation.y) > 20 && current_speed > maxspeed * 0.4
+ && vdist(vec2(this.origin - this.goalcurrent_prev.origin), <, 50))
+ {
+ this.bot_stop_moving_timeout = time + 0.1;
+ }
+ if (current_speed > autocvar_sv_maxspeed * 0.9
+ && vlen2(flat_diff) < vlen2(vec2(this.goalcurrent_prev.origin - destorg))
+ && vdist(vec2(this.origin - this.goalcurrent_prev.origin), >, 50)
+ && vdist(vec2(this.origin - this.goalcurrent_prev.origin), <, 150)
+ )
+ {
+ PHYS_INPUT_BUTTON_JUMP(this) = true;
+ // 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))
{
if (vlen2(flat_diff) < vlen2(offset))
{
turning = true;
}
- LABEL(jump_check);
+ LABEL(jumpobstacle_check);
dir = flatdir = normalize(actual_destorg - this.origin);
- if (turning || fabs(deviation.y) < 50) // don't even try to jump if deviation is too high
+ bool jump_forbidden = false;
+ if (!turning && fabs(deviation.y) > 50)
+ jump_forbidden = true;
+ else if (IS_DUCKED(this))
+ {
+ tracebox(this.origin, PL_MIN_CONST, PL_MAX_CONST, this.origin, false, this);
+ if (trace_startsolid)
+ jump_forbidden = true;
+ }
+
+ if (!jump_forbidden)
{
tracebox(this.origin, this.mins, this.maxs, actual_destorg, false, this);
if (trace_fraction < 1 && trace_plane_normal.z < 0.7)
actual_destorg = destorg;
turning = false;
this.bot_tracewalk_time = time + 0.25;
- goto jump_check;
+ goto jumpobstacle_check;
}
s = trace_fraction;
// don't artificially reduce max jump height in real-time
bool unreachable = false;
s = CONTENT_SOLID;
- if(trace_fraction == 1 && this.jumppadcount == 0 && !this.goalcurrent.wphardwired )
+ if (trace_fraction == 1 && !this.jumppadcount
+ && !waypoint_is_hardwiredlink(this.goalcurrent_prev, this.goalcurrent)
+ && !(this.goalcurrent_prev && this.goalcurrent_prev.wpflags & WAYPOINTFLAG_JUMP) )
if((IS_ONGROUND(this)) || (this.aistatus & AI_STATUS_RUNNING) || (this.aistatus & AI_STATUS_ROAMING) || PHYS_INPUT_BUTTON_JUMP(this))
{
// Look downwards
}
// slow down if bot is in the air and goal is under it
- if (!this.goalcurrent.wphardwired
+ if (!waypoint_is_hardwiredlink(this.goalcurrent_prev, this.goalcurrent)
&& vdist(flat_diff, <, 250) && this.origin.z - destorg.z > 120
&& (!IS_ONGROUND(this) || vdist(vec2(this.velocity), >, maxspeed * 0.3)))
{