+ if (this.goalcurrent == this.goalentity && this.goalentity_lock_timeout > time)
+ locked_goal = true;
+
+ if (navigation_shortenpath(this))
+ {
+ if (vdist(this.origin - this.goalcurrent_prev.origin, <, 50)
+ && navigation_goalrating_timeout_can_be_anticipated(this))
+ {
+ navigation_goalrating_timeout_force(this);
+ }
+ }
+
+ bool goalcurrent_can_be_removed = false;
+ if (IS_PLAYER(this.goalcurrent) || IS_MONSTER(this.goalcurrent))
+ {
+ bool freeze_state_changed = (boolean(STAT(FROZEN, this.goalentity)) != this.goalentity_shouldbefrozen);
+ if (IS_DEAD(this.goalcurrent) || (this.goalentity == this.goalcurrent && freeze_state_changed))
+ {
+ goalcurrent_can_be_removed = true;
+ // don't remove if not visible
+ if (checkpvs(this.origin + this.view_ofs, this.goalcurrent))
+ {
+ if (IS_DEAD(this.goalcurrent))
+ {
+ IL_EACH(g_items, it.enemy == this.goalcurrent && Item_IsLoot(it),
+ {
+ if (vdist(it.origin - this.goalcurrent.death_origin, <, 50))
+ {
+ navigation_clearroute(this);
+ navigation_pushroute(this, it);
+ // loot can't be immediately rated since it isn't on ground yet
+ // it will be rated after a second when on ground, meanwhile head to it
+ navigation_goalrating_timeout_expire(this, 1);
+ return;
+ }
+ });
+ }
+ if (!Item_IsLoot(this.goalcurrent))
+ {
+ navigation_goalrating_timeout_force(this);
+ return;
+ }
+ }
+ }
+ else if (!(STAT(FROZEN, this.goalentity)) && this.bot_tracewalk_time < time)
+ {
+ set_tracewalk_dest(this.goalcurrent, this.origin, true);
+ if (!(trace_ent == this || tracewalk(this, this.origin, this.mins, this.maxs,
+ tracewalk_dest, tracewalk_dest_height, bot_navigation_movemode)))
+ {
+ navigation_goalrating_timeout_force(this);
+ return;
+ }
+ this.bot_tracewalk_time = max(time, this.bot_tracewalk_time) + 0.25;
+ }
+ }
+