feat(movement): Task 3 COMPLETE - Final 3 Dungeon files migrated to BotMovementController
This completes Task 3 (Movement Generator Replacement) at 100% - all 33 files migrated from legacy MotionMaster to validated BotMovementController. Final migration details: DungeonAutonomyManager.cpp (3 MovePoint → MoveTo migrations): - Line 739: Pack navigation movement - Line 765: Healer positioning behind tank - Line 790: DPS positioning behind tank - Kept MoveChase at line 429 as legacy (combat engagement) DungeonBehavior.cpp (5 MovePoint → MoveTo migrations): - Lines 663-664: Tank optimal position - Lines 703-704: Healer safe position - Lines 748-749: DPS optimal position - Lines 880-881: Player optimal position - Lines 983-984: Safe spot avoidance EncounterStrategy.cpp (7 MovePoint → MoveTo migrations): - Lines 440-441: AoE avoidance - Lines 580-581: Optimal positioning - Lines 665-666: Danger zone avoidance - Line 1421: General positioning - Lines 1577-1578: Target positioning - Line 1742: Movement positioning - Lines 1805-1806: Stack on tank positioning All migrations follow enterprise pattern: - BotAI::MoveTo() with ground/collision/liquid validation - Fallback to legacy MotionMaster if validation fails - Safe bot AI retrieval via GetBotAI() helper - Added PlayerBotHelpers.h includes where needed TASK 3 STATISTICS: - Files migrated: 33/33 (100%) - Total usages: 70 (69 migrated + 1 legacy MoveChase) - HIGH PRIORITY: 13 files (combat systems) ✓ - MEDIUM PRIORITY: 9 files (ClassAI/Actions) ✓ - LOW PRIORITY: 11 files (dungeon/travel/behavior tree) ✓ Build: Successful (RelWithDebInfo, worldserver.exe created) Test: Ready for production testing Co-Authored-By: Claude Opus 4.5 <[email protected]> Signed-off-by: luis <[email protected]>
This commit is contained in:
committed by
luis
co-authored by
Claude Opus 4.5
parent
2af8c650a7
commit
5ceb60ffeb
@@ -23,6 +23,7 @@
|
||||
#include "MotionMaster.h"
|
||||
#include "MovementGenerator.h"
|
||||
#include "DBCEnums.h" // For ChrSpecialization enum
|
||||
#include "Core/PlayerBotHelpers.h"
|
||||
|
||||
namespace Playerbot
|
||||
{
|
||||
@@ -735,8 +736,21 @@ bool DungeonAutonomyManager::UpdateTankAI(Player* tank, BotAI* ai, Group* group,
|
||||
TrashPack* pack = coordinator->GetCurrentPullTarget();
|
||||
if (pack)
|
||||
{
|
||||
// Move toward next pack
|
||||
tank->GetMotionMaster()->MovePoint(0, pack->x, pack->y, pack->z);
|
||||
// Use validated pathfinding for pack navigation
|
||||
Position dest(pack->x, pack->y, pack->z, 0.0f);
|
||||
if (BotAI* ai = GetBotAI(tank))
|
||||
{
|
||||
if (!ai->MoveTo(dest, true))
|
||||
{
|
||||
// Fallback to legacy if validation fails
|
||||
tank->GetMotionMaster()->MovePoint(0, pack->x, pack->y, pack->z);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-bot player - use standard movement
|
||||
tank->GetMotionMaster()->MovePoint(0, pack->x, pack->y, pack->z);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -762,7 +776,20 @@ bool DungeonAutonomyManager::UpdateHealerAI(Player* healer, BotAI* ai, Group* gr
|
||||
followPos.m_positionY = tank->GetPositionY() + 15.0f * sin(angle);
|
||||
followPos.m_positionZ = tank->GetPositionZ();
|
||||
|
||||
healer->GetMotionMaster()->MovePoint(0, followPos);
|
||||
// Use validated pathfinding for healer positioning
|
||||
if (BotAI* ai = GetBotAI(healer))
|
||||
{
|
||||
if (!ai->MoveTo(followPos, true))
|
||||
{
|
||||
// Fallback to legacy if validation fails
|
||||
healer->GetMotionMaster()->MovePoint(0, followPos);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-bot player - use standard movement
|
||||
healer->GetMotionMaster()->MovePoint(0, followPos);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -787,7 +814,20 @@ bool DungeonAutonomyManager::UpdateDpsAI(Player* dps, BotAI* ai, Group* group, D
|
||||
followPos.m_positionY = tank->GetPositionY() + 20.0f * sin(angle);
|
||||
followPos.m_positionZ = tank->GetPositionZ();
|
||||
|
||||
dps->GetMotionMaster()->MovePoint(0, followPos);
|
||||
// Use validated pathfinding for DPS positioning
|
||||
if (BotAI* ai = GetBotAI(dps))
|
||||
{
|
||||
if (!ai->MoveTo(followPos, true))
|
||||
{
|
||||
// Fallback to legacy if validation fails
|
||||
dps->GetMotionMaster()->MovePoint(0, followPos);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-bot player - use standard movement
|
||||
dps->GetMotionMaster()->MovePoint(0, followPos);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -659,9 +659,22 @@ void DungeonBehavior::CoordinateTankBehavior(Player* tank, const DungeonEncounte
|
||||
}
|
||||
else
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if arbiter not available
|
||||
tank->GetMotionMaster()->MovePoint(0, optimalPos.GetPositionX(),
|
||||
optimalPos.GetPositionY(), optimalPos.GetPositionZ());
|
||||
// Use validated pathfinding for tank positioning
|
||||
if (BotAI* ai = GetBotAI(tank))
|
||||
{
|
||||
if (!ai->MoveTo(optimalPos, true))
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if validation fails
|
||||
tank->GetMotionMaster()->MovePoint(0, optimalPos.GetPositionX(),
|
||||
optimalPos.GetPositionY(), optimalPos.GetPositionZ());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-bot player - use standard movement
|
||||
tank->GetMotionMaster()->MovePoint(0, optimalPos.GetPositionX(),
|
||||
optimalPos.GetPositionY(), optimalPos.GetPositionZ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -699,9 +712,22 @@ void DungeonBehavior::CoordinateHealerBehavior(Player* healer, const DungeonEnco
|
||||
}
|
||||
else
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if arbiter not available
|
||||
healer->GetMotionMaster()->MovePoint(0, safePos.GetPositionX(),
|
||||
safePos.GetPositionY(), safePos.GetPositionZ());
|
||||
// Use validated pathfinding for healer positioning
|
||||
if (BotAI* ai = GetBotAI(healer))
|
||||
{
|
||||
if (!ai->MoveTo(safePos, true))
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if validation fails
|
||||
healer->GetMotionMaster()->MovePoint(0, safePos.GetPositionX(),
|
||||
safePos.GetPositionY(), safePos.GetPositionZ());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-bot player - use standard movement
|
||||
healer->GetMotionMaster()->MovePoint(0, safePos.GetPositionX(),
|
||||
safePos.GetPositionY(), safePos.GetPositionZ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -744,9 +770,22 @@ void DungeonBehavior::CoordinateDpsBehavior(Player* dps, const DungeonEncounter&
|
||||
}
|
||||
else
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if arbiter not available
|
||||
dps->GetMotionMaster()->MovePoint(0, optimalPos.GetPositionX(),
|
||||
optimalPos.GetPositionY(), optimalPos.GetPositionZ());
|
||||
// Use validated pathfinding for DPS positioning
|
||||
if (BotAI* ai = GetBotAI(dps))
|
||||
{
|
||||
if (!ai->MoveTo(optimalPos, true))
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if validation fails
|
||||
dps->GetMotionMaster()->MovePoint(0, optimalPos.GetPositionX(),
|
||||
optimalPos.GetPositionY(), optimalPos.GetPositionZ());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-bot player - use standard movement
|
||||
dps->GetMotionMaster()->MovePoint(0, optimalPos.GetPositionX(),
|
||||
optimalPos.GetPositionY(), optimalPos.GetPositionZ());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -876,9 +915,22 @@ void DungeonBehavior::UpdateGroupPositioning(Group* group, const DungeonEncounte
|
||||
}
|
||||
else
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if arbiter not available
|
||||
player->GetMotionMaster()->MovePoint(0, optimalPos.GetPositionX(),
|
||||
optimalPos.GetPositionY(), optimalPos.GetPositionZ());
|
||||
// Use validated pathfinding for player positioning
|
||||
if (BotAI* ai = GetBotAI(player))
|
||||
{
|
||||
if (!ai->MoveTo(optimalPos, true))
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if validation fails
|
||||
player->GetMotionMaster()->MovePoint(0, optimalPos.GetPositionX(),
|
||||
optimalPos.GetPositionY(), optimalPos.GetPositionZ());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-bot player - use standard movement
|
||||
player->GetMotionMaster()->MovePoint(0, optimalPos.GetPositionX(),
|
||||
optimalPos.GetPositionY(), optimalPos.GetPositionZ());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -979,9 +1031,22 @@ void DungeonBehavior::AvoidDangerousAreas(Player* player, const ::std::vector<Po
|
||||
}
|
||||
else
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if arbiter not available
|
||||
player->GetMotionMaster()->MovePoint(0, nearestSafeSpot.GetPositionX(),
|
||||
nearestSafeSpot.GetPositionY(), nearestSafeSpot.GetPositionZ());
|
||||
// Use validated pathfinding for safe spot movement
|
||||
if (BotAI* ai = GetBotAI(player))
|
||||
{
|
||||
if (!ai->MoveTo(nearestSafeSpot, true))
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if validation fails
|
||||
player->GetMotionMaster()->MovePoint(0, nearestSafeSpot.GetPositionX(),
|
||||
nearestSafeSpot.GetPositionY(), nearestSafeSpot.GetPositionZ());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-bot player - use standard movement
|
||||
player->GetMotionMaster()->MovePoint(0, nearestSafeSpot.GetPositionX(),
|
||||
nearestSafeSpot.GetPositionY(), nearestSafeSpot.GetPositionZ());
|
||||
}
|
||||
}
|
||||
|
||||
TC_LOG_DEBUG("module.playerbot", "Player {} moving to avoid dangerous area", player->GetName());
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "../Movement/Arbiter/MovementPriorityMapper.h"
|
||||
#include "../AI/BotAI.h"
|
||||
#include "UnitAI.h"
|
||||
#include "../Core/PlayerBotHelpers.h"
|
||||
|
||||
namespace Playerbot
|
||||
{
|
||||
@@ -436,9 +437,22 @@ void EncounterStrategy::HandleAoEDamageMechanic(Group* group, const Position& da
|
||||
}
|
||||
else
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if arbiter not available
|
||||
player->GetMotionMaster()->MovePoint(0, safePos.GetPositionX(),
|
||||
safePos.GetPositionY(), safePos.GetPositionZ());
|
||||
// Use validated pathfinding for AoE avoidance
|
||||
if (BotAI* ai = GetBotAI(player))
|
||||
{
|
||||
if (!ai->MoveTo(safePos, true))
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if validation fails
|
||||
player->GetMotionMaster()->MovePoint(0, safePos.GetPositionX(),
|
||||
safePos.GetPositionY(), safePos.GetPositionZ());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-bot player - use standard movement
|
||||
player->GetMotionMaster()->MovePoint(0, safePos.GetPositionX(),
|
||||
safePos.GetPositionY(), safePos.GetPositionZ());
|
||||
}
|
||||
TC_LOG_TRACE("module.playerbot", "Player {} moving to avoid AoE", player->GetName());
|
||||
}
|
||||
}
|
||||
@@ -576,9 +590,22 @@ void EncounterStrategy::UpdateEncounterPositioning(Group* group, uint32 encounte
|
||||
}
|
||||
else
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if arbiter not available
|
||||
player->GetMotionMaster()->MovePoint(0, optimalPos.GetPositionX(),
|
||||
optimalPos.GetPositionY(), optimalPos.GetPositionZ());
|
||||
// Use validated pathfinding for optimal positioning
|
||||
if (BotAI* ai = GetBotAI(player))
|
||||
{
|
||||
if (!ai->MoveTo(optimalPos, true))
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if validation fails
|
||||
player->GetMotionMaster()->MovePoint(0, optimalPos.GetPositionX(),
|
||||
optimalPos.GetPositionY(), optimalPos.GetPositionZ());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-bot player - use standard movement
|
||||
player->GetMotionMaster()->MovePoint(0, optimalPos.GetPositionX(),
|
||||
optimalPos.GetPositionY(), optimalPos.GetPositionZ());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -661,9 +688,22 @@ void EncounterStrategy::AvoidMechanicAreas(Group* group, const ::std::vector<Pos
|
||||
}
|
||||
else
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if arbiter not available
|
||||
player->GetMotionMaster()->MovePoint(0, safePos.GetPositionX(),
|
||||
safePos.GetPositionY(), safePos.GetPositionZ());
|
||||
// Use validated pathfinding for danger zone avoidance
|
||||
if (BotAI* ai = GetBotAI(player))
|
||||
{
|
||||
if (!ai->MoveTo(safePos, true))
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if validation fails
|
||||
player->GetMotionMaster()->MovePoint(0, safePos.GetPositionX(),
|
||||
safePos.GetPositionY(), safePos.GetPositionZ());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-bot player - use standard movement
|
||||
player->GetMotionMaster()->MovePoint(0, safePos.GetPositionX(),
|
||||
safePos.GetPositionY(), safePos.GetPositionZ());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1417,8 +1457,21 @@ void EncounterStrategy::HandleGenericGroundAvoidance(::Player* player, ::Creatur
|
||||
}
|
||||
else
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if arbiter not available
|
||||
player->GetMotionMaster()->MovePoint(0, x, y, z);
|
||||
// Use validated pathfinding for positioning
|
||||
Position dest(x, y, z, 0.0f);
|
||||
if (BotAI* ai = GetBotAI(player))
|
||||
{
|
||||
if (!ai->MoveTo(dest, true))
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if validation fails
|
||||
player->GetMotionMaster()->MovePoint(0, x, y, z);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-bot player - use standard movement
|
||||
player->GetMotionMaster()->MovePoint(0, x, y, z);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1573,9 +1626,22 @@ void EncounterStrategy::HandleGenericPositioning(::Player* player, ::Creature* b
|
||||
}
|
||||
else
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if arbiter not available
|
||||
player->GetMotionMaster()->MovePoint(0, targetPos.GetPositionX(),
|
||||
targetPos.GetPositionY(), targetPos.GetPositionZ());
|
||||
// Use validated pathfinding for target positioning
|
||||
if (BotAI* ai = GetBotAI(player))
|
||||
{
|
||||
if (!ai->MoveTo(targetPos, true))
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if validation fails
|
||||
player->GetMotionMaster()->MovePoint(0, targetPos.GetPositionX(),
|
||||
targetPos.GetPositionY(), targetPos.GetPositionZ());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-bot player - use standard movement
|
||||
player->GetMotionMaster()->MovePoint(0, targetPos.GetPositionX(),
|
||||
targetPos.GetPositionY(), targetPos.GetPositionZ());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1738,8 +1804,21 @@ void EncounterStrategy::HandleGenericSpread(::Player* player, ::Creature* boss,
|
||||
}
|
||||
else
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if arbiter not available
|
||||
player->GetMotionMaster()->MovePoint(0, x, y, z);
|
||||
// Use validated pathfinding for positioning
|
||||
Position dest(x, y, z, 0.0f);
|
||||
if (BotAI* ai = GetBotAI(player))
|
||||
{
|
||||
if (!ai->MoveTo(dest, true))
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if validation fails
|
||||
player->GetMotionMaster()->MovePoint(0, x, y, z);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-bot player - use standard movement
|
||||
player->GetMotionMaster()->MovePoint(0, x, y, z);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -1801,9 +1880,23 @@ void EncounterStrategy::HandleGenericStack(::Player* player, ::Creature* boss)
|
||||
}
|
||||
else
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if arbiter not available
|
||||
player->GetMotionMaster()->MovePoint(0, tank->GetPositionX(),
|
||||
tank->GetPositionY(), tank->GetPositionZ());
|
||||
// Use validated pathfinding for stacking on tank
|
||||
Position dest(tank->GetPositionX(), tank->GetPositionY(), tank->GetPositionZ(), 0.0f);
|
||||
if (BotAI* ai = GetBotAI(player))
|
||||
{
|
||||
if (!ai->MoveTo(dest, true))
|
||||
{
|
||||
// FALLBACK: Direct MotionMaster if validation fails
|
||||
player->GetMotionMaster()->MovePoint(0, tank->GetPositionX(),
|
||||
tank->GetPositionY(), tank->GetPositionZ());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Non-bot player - use standard movement
|
||||
player->GetMotionMaster()->MovePoint(0, tank->GetPositionX(),
|
||||
tank->GetPositionY(), tank->GetPositionZ());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user