From c9e98a6b4ed9e7bb5a82828500ebd1dc8de20d8b Mon Sep 17 00:00:00 2001 From: privatecore Date: Wed, 7 Jan 2026 15:24:18 +0100 Subject: [PATCH] [BUG FIX] the issue where bots on vehicles cant move (#1969) Fix the [issue #1964](https://github.com/mod-playerbots/mod-playerbots/issues/1964) where bots on vehicles cant move. Transfer the allowed movement logic to `PlayerbotAI::CanMove` -- Ulduar raid strategy also used this method for the Malady of the Mind trigger. The only remaining `IsRooted` check is in `MovementAction::UpdateMovementState`. I'm not sure if this also needs to be updated for the vehicles case, but on paper, everything should work as intended. A more complex solution to fix this issue can be found in the [comment](https://github.com/mod-playerbots/mod-playerbots/issues/1902#issuecomment-3703795779), but for now, these changes are safer. --- src/PlayerbotAI.cpp | 34 +++++++++++++++++++----- src/strategy/actions/AttackAction.cpp | 2 +- src/strategy/actions/MovementActions.cpp | 31 +-------------------- 3 files changed, 30 insertions(+), 37 deletions(-) diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 3cdf15f5..28e09294 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -5932,16 +5932,38 @@ int32 PlayerbotAI::GetNearGroupMemberCount(float dis) bool PlayerbotAI::CanMove() { - // do not allow if not vehicle driver - if (IsInVehicle() && !IsInVehicle(true)) + // Most common checks: confused, stunned, fleeing, jumping, charging. All these + // states are set when handling certain aura effects. We don't check against + // UNIT_STATE_ROOT here, because this state is used by vehicles. + if (bot->HasUnitState(UNIT_STATE_LOST_CONTROL)) return false; - if (bot->isFrozen() || bot->IsPolymorphed() || (bot->isDead() && !bot->HasPlayerFlag(PLAYER_FLAGS_GHOST)) || - bot->IsBeingTeleported() || bot->HasRootAura() || bot->HasSpiritOfRedemptionAura() || bot->HasConfuseAura() || - bot->IsCharmed() || bot->HasStunAura() || bot->IsInFlight() || bot->HasUnitState(UNIT_STATE_LOST_CONTROL)) + // Death state (w/o spirit release) and Spirit of Redemption aura (priest) + if ((bot->isDead() && !bot->HasPlayerFlag(PLAYER_FLAGS_GHOST)) || bot->HasSpiritOfRedemptionAura()) return false; - return bot->GetMotionMaster()->GetCurrentMovementGeneratorType() != FLIGHT_MOTION_TYPE; + // Common CC effects, ordered by frequency: rooted > charmed > frozen > polymorphed. + // NOTE: Can't find proper way to check if bot is rooted or charmed w/o additional + // vehicle check -- when a passenger is added, they become rooted and charmed. + if (!bot->GetVehicle() && (bot->IsRooted() || bot->IsCharmed())) + return false; + if (bot->isFrozen() || bot->IsPolymorphed()) + return false; + + // Check for the MM controlled slot types: feared, confused, fleeing, etc. + if (bot->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_CONTROLLED) != NULL_MOTION_TYPE) + return false; + + // Traveling state: taxi flight and being teleported (relatively rare) + if (bot->IsInFlight() || bot->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE || + bot->IsBeingTeleported()) + return false; + + // Vehicle state: is in the vehicle and can control it (rare, content-specific) + if ((bot->GetVehicle() && !IsInVehicle(true))) + return false; + + return true; } bool PlayerbotAI::IsInRealGuild() diff --git a/src/strategy/actions/AttackAction.cpp b/src/strategy/actions/AttackAction.cpp index d72b18c5..2b8c486f 100644 --- a/src/strategy/actions/AttackAction.cpp +++ b/src/strategy/actions/AttackAction.cpp @@ -159,7 +159,7 @@ bool AttackAction::Attack(Unit* target, bool /*with_pet*/ /*true*/) bot->StopMoving(); } - if (IsMovingAllowed() && !bot->HasInArc(CAST_ANGLE_IN_FRONT, target)) + if (botAI->CanMove() && !bot->HasInArc(CAST_ANGLE_IN_FRONT, target)) sServerFacade->SetFacingTo(bot, target); botAI->ChangeEngine(BOT_STATE_COMBAT); diff --git a/src/strategy/actions/MovementActions.cpp b/src/strategy/actions/MovementActions.cpp index ed650fbf..69e5c278 100644 --- a/src/strategy/actions/MovementActions.cpp +++ b/src/strategy/actions/MovementActions.cpp @@ -946,36 +946,7 @@ bool MovementAction::IsWaitingForLastMove(MovementPriority priority) bool MovementAction::IsMovingAllowed() { - // Most common checks: confused, stunned, fleeing, jumping, charging. All these - // states are set when handling certain aura effects. We don't check against - // UNIT_STATE_ROOT here, because this state is used by vehicles. - if (bot->HasUnitState(UNIT_STATE_LOST_CONTROL)) - return false; - - // Death state (w/o spirit release) and Spirit of Redemption aura (priest) - if ((bot->isDead() && !bot->HasPlayerFlag(PLAYER_FLAGS_GHOST)) || bot->HasSpiritOfRedemptionAura()) - return false; - - // Common CC effects, ordered by frequency: rooted > frozen > polymorphed - if (bot->IsRooted() || bot->isFrozen() || bot->IsPolymorphed()) - return false; - - // Check for the MM controlled slot types: feared, confused, fleeing, etc. - if (bot->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_CONTROLLED) != NULL_MOTION_TYPE) - return false; - - // Traveling state: taxi flight and being teleported (relatively rare) - if (bot->IsInFlight() || bot->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE || - bot->IsBeingTeleported()) - return false; - - // Vehicle state: is in the vehicle and can control it (rare, content-specific). - // We need to check charmed state AFTER vehicle one, cuz that's how it works: - // passengers are set to charmed by vehicle with CHARM_TYPE_VEHICLE. - if ((bot->GetVehicle() && !botAI->IsInVehicle(true)) || bot->IsCharmed()) - return false; - - return true; + return botAI->CanMove(); } bool MovementAction::Follow(Unit* target, float distance) { return Follow(target, distance, GetFollowAngle()); }