diff --git a/src/game/server/NextBot/Player/NextBotPlayer.h b/src/game/server/NextBot/Player/NextBotPlayer.h index 092bdb266c..4bff7aba55 100644 --- a/src/game/server/NextBot/Player/NextBotPlayer.h +++ b/src/game/server/NextBot/Player/NextBotPlayer.h @@ -153,6 +153,10 @@ class INextBotPlayerInput #endif // NEO virtual void SetButtonScale( float forward, float right ) = 0; +#ifdef NEO + // Move in this world direction until the next bot update, whichever way the bot turns meanwhile + virtual void SetMoveDirection( const Vector2D &direction ) = 0; +#endif // NEO }; @@ -273,6 +277,9 @@ class NextBotPlayer : public PlayerType, public INextBot, public INextBotPlayerI #endif // NEO virtual void SetButtonScale( float forward, float right ); +#ifdef NEO + virtual void SetMoveDirection( const Vector2D &direction ); +#endif // NEO //------------------------------------------------------------------------ // Event hooks into NextBot system @@ -324,6 +331,10 @@ class NextBotPlayer : public PlayerType, public INextBot, public INextBotPlayerI IntervalTimer m_burningTimer; // how long since we were last burning float m_forwardScale; float m_rightScale; +#ifdef NEO + Vector2D m_moveDirection; + int m_moveDirectionTick; // the bot update that set m_moveDirection +#endif // NEO CHandle< CBaseEntity > m_spawnPointEntity; }; @@ -688,6 +699,15 @@ inline void NextBotPlayer< PlayerType >::SetButtonScale( float forward, float ri m_buttonScaleTimer.Start( 0.01 ); } +#ifdef NEO +template < typename PlayerType > +inline void NextBotPlayer< PlayerType >::SetMoveDirection( const Vector2D &direction ) +{ + m_moveDirection = direction; + m_moveDirectionTick = GetTickLastUpdate(); +} +#endif // NEO + //----------------------------------------------------------------------------------------------------- @@ -698,6 +718,10 @@ inline NextBotPlayer< PlayerType >::NextBotPlayer( void ) m_inputButtons = 0; m_burningTimer.Invalidate(); m_spawnPointEntity = NULL; +#ifdef NEO + m_moveDirection.Init(); + m_moveDirectionTick = -1; +#endif // NEO } @@ -738,6 +762,7 @@ inline void NextBotPlayer< PlayerType >::Spawn( void ) m_thermopticButtonTimer.Invalidate(); m_leanLeftButtonTimer.Invalidate(); m_leanRightButtonTimer.Invalidate(); + m_moveDirectionTick = -1; #endif // NEO // reset first, because Spawn() may access various interfaces @@ -996,6 +1021,19 @@ inline void NextBotPlayer< PlayerType >::PhysicsSimulate( void ) strafeSpeed = mover->GetRunSpeed() * m_rightScale; } +#ifdef NEO + // Held on every tick until the next update, taken against this tick's view so a bot turning to aim keeps its line + if ( m_moveDirectionTick == GetTickLastUpdate() ) + { + const float yaw = DEG2RAD( this->EyeAngles()[ YAW ] ); + const Vector2D forward( cosf( yaw ), sinf( yaw ) ); + const Vector2D right( forward.y, -forward.x ); + + forwardSpeed = mover->GetRunSpeed() * m_moveDirection.Dot( forward ); + strafeSpeed = mover->GetRunSpeed() * m_moveDirection.Dot( right ); + } +#endif // NEO + if ( !NextBotPlayerMove.GetBool() ) { inputButtons &= ~(IN_FORWARD | IN_BACK | IN_MOVELEFT | IN_MOVERIGHT | IN_JUMP ); diff --git a/src/game/server/NextBot/Player/NextBotPlayerLocomotion.cpp b/src/game/server/NextBot/Player/NextBotPlayerLocomotion.cpp index 012a7afdbc..ed83abb3af 100644 --- a/src/game/server/NextBot/Player/NextBotPlayerLocomotion.cpp +++ b/src/game/server/NextBot/Player/NextBotPlayerLocomotion.cpp @@ -536,6 +536,26 @@ void PlayerLocomotion::Approach( const Vector &pos, float goalWeight ) } } +#ifdef NEO + // The move keys below give the nearest of eight directions, which can drift the bot off the path + // and over a ledge, so on precise and cliff areas move straight at the goal instead. + const CNavArea *pArea = m_player->GetLastKnownArea(); + if ( goalDistance > epsilon && pArea && pArea->HasAttributes( NAV_MESH_PRECISE | NAV_MESH_CLIFF ) ) + { + Vector2D moveDirection = to; + + // In the air, input only adds speed along the move direction, + // so steer the velocity onto the goal line before a jump's sideways speed carries the bot past a narrow ledge + if ( !IsOnGround() ) + { + moveDirection = GetRunSpeed() * to - m_player->GetAbsVelocity().AsVector2D(); + moveDirection.NormalizeInPlace(); + } + + playerButtons->SetMoveDirection( moveDirection ); + } +#endif + if ( ahead > epsilon ) { playerButtons->PressForwardButton();