From e5482975a50c76aeb83019ef62ba4d6dbbfb071d Mon Sep 17 00:00:00 2001 From: Alan Shen Date: Wed, 14 Oct 2026 10:33:37 -0600 Subject: [PATCH 1/2] Steer for the landing once a bot falls past a drop A bot that walks off a drop-down kept the top of the drop as its goal until its feet were a step above the landing, so it steered back toward the edge behind it while falling and landed moving backward, then walked back to rejoin its path. Count the drop as reached once the bot is airborne past its top, and skip the landing point too, since it lies straight below the top and is also behind a falling bot. --- .../server/NextBot/Path/NextBotPathFollow.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/game/server/NextBot/Path/NextBotPathFollow.cpp b/src/game/server/NextBot/Path/NextBotPathFollow.cpp index a8efd479dd..760ad42b5f 100644 --- a/src/game/server/NextBot/Path/NextBotPathFollow.cpp +++ b/src/game/server/NextBot/Path/NextBotPathFollow.cpp @@ -205,6 +205,15 @@ bool PathFollower::IsAtGoal( INextBot *bot ) const // reached goal return true; } + +#ifdef NEO + // a bot that walked off past the top of the drop has started its fall, + // so steer for the landing instead of back toward the edge behind it + if ( !mover->IsOnGround() && DotProduct2D( toGoal.AsVector2D(), current->forward.AsVector2D() ) < 0.0f ) + { + return true; + } +#endif } /// @todo: it is possible to fall into a bad place and get stuck - should move back onto the path @@ -573,6 +582,14 @@ bool PathFollower::CheckProgress( INextBot *bot ) // iterate to next segment of the path const Path::Segment *nextSegment = pSkipToGoal ? pSkipToGoal : NextSegment( m_goal ); +#ifdef NEO + // a drop's landing lies straight below its top, so it is behind a bot already falling past the top + if ( !pSkipToGoal && m_goal->type == DROP_DOWN && !mover->IsOnGround() && nextSegment && NextSegment( nextSegment ) ) + { + nextSegment = NextSegment( nextSegment ); + } +#endif + if ( nextSegment == NULL ) { // must be on ground to complete the path From 5b2aaf2c321a6035b23b0c494016e873c211ff22 Mon Sep 17 00:00:00 2001 From: Alan Shen Date: Wed, 14 Oct 2026 19:13:09 -0600 Subject: [PATCH 2/2] Restore the drop goal when a bot lands part way A bot that skipped a drop's landing in the air steers for the path past the landing, which on some drops (the ghostzc vent shaft) carries it onto a ledge part way down. There the goal is below it, and nothing acts until the stuck monitor fires about 5 s later. On touchdown more than a step above the landing and more than a step below the drop's top, set the goal back to the drop's top. --- src/game/server/NextBot/Path/NextBotPathFollow.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/game/server/NextBot/Path/NextBotPathFollow.cpp b/src/game/server/NextBot/Path/NextBotPathFollow.cpp index 760ad42b5f..879a2d5859 100644 --- a/src/game/server/NextBot/Path/NextBotPathFollow.cpp +++ b/src/game/server/NextBot/Path/NextBotPathFollow.cpp @@ -832,6 +832,16 @@ void PathFollower::Update( INextBot *bot ) const bool hasJustLanded = isOnGround && !m_wasOnGround; m_wasOnGround = isOnGround; + // a bot that skipped a drop's landing in the air can come down on a ledge part way down, + // so aim for the top of the drop again instead of the path past the landing it missed + const Path::Segment *landing = hasJustLanded ? PriorSegment( m_goal ) : NULL; + const Path::Segment *dropTop = landing ? PriorSegment( landing ) : NULL; + const float feetZ = mover->GetFeet().z; + if ( dropTop && dropTop->type == DROP_DOWN && feetZ > landing->pos.z + mover->GetStepHeight() && feetZ < dropTop->pos.z - mover->GetStepHeight() ) + { + m_goal = dropTop; + } + if ( hasJustLanded && HasFallenBelowPath( bot ) && IsNearNavMesh( bot ) ) { mover->GetBot()->OnMoveToFailure( this, FAIL_FELL_OFF );