# Phase 2.2: Create CombatMovementStrategy **Duration**: 1 week (2025-01-20 to 2025-01-27) **Status**: ⏳ PENDING **Owner**: Development Team --- ## Objectives Create a comprehensive combat movement system that positions bots based on their role during combat: 1. Role detection (Tank, Healer, Melee DPS, Ranged DPS) 2. Dynamic position calculation per role 3. Mechanic avoidance (fire, poison, void zones) 4. Integration with existing movement systems --- ## Background ### Current Problem - Bots use only LeaderFollowBehavior for movement (social following) - No role-based combat positioning - Melee bots stand at range, ranged bots run into melee - No mechanic avoidance during combat - Combat effectiveness severely reduced ### Solution - Dedicated CombatMovementStrategy for combat-specific positioning - Separate from LeaderFollowBehavior (which handles out-of-combat following) - Role-based positioning logic - Higher priority than social movement during combat - Lightweight (<0.5ms per update) --- ## Technical Requirements ### Performance Constraints - Position calculation: <0.3ms per bot per frame - Path validation: <0.2ms per bot per frame - Total combat movement overhead: <0.5ms per bot - Must work efficiently with 5000+ bots ### Role Definitions **Tank**: - Position: Melee range (5 yards) - Facing: Front of target - Responsibility: Hold aggro, face boss away from group **Melee DPS**: - Position: Melee range (5 yards) - Facing: Behind target when possible - Responsibility: Maximize DPS, avoid frontal cleaves **Ranged DPS**: - Position: 20-30 yards from target - Facing: Any - Responsibility: Maximize DPS, maintain safe distance **Healer**: - Position: 15-20 yards (casting range) - Facing: Group center - Responsibility: Stay in range of all group members ### Integration Points - Must coexist with LeaderFollowBehavior (different priorities) - Must use MotionMaster API for movement - Must respect existing path validation - Must not conflict with other strategies --- ## Deliverables ### 1. CombatMovementStrategy.h Location: `src/modules/Playerbot/AI/Strategy/CombatMovementStrategy.h` **Content**: ```cpp #pragma once #include "Strategy.h" namespace Playerbot { enum class FormationRole { TANK, // Front line, melee range, face boss MELEE_DPS, // Behind boss, melee range RANGED_DPS, // 20-30 yards, any position HEALER // 15-20 yards, central position }; /** * CombatMovementStrategy - Role-based combat positioning * * Handles all combat movement based on bot's role: * - Tanks maintain frontal position * - Melee DPS attack from behind * - Ranged DPS maintain 20-30 yard distance * - Healers stay central for group coverage * * This strategy has higher priority than LeaderFollowBehavior * and only activates during combat. */ class TC_GAME_API CombatMovementStrategy : public Strategy { public: CombatMovementStrategy(); ~CombatMovementStrategy() override = default; // Strategy interface void InitializeActions() override; void InitializeTriggers() override; void InitializeValues() override; // Activation - only during combat void OnActivate(BotAI* ai) override; void OnDeactivate(BotAI* ai) override; bool IsActive(BotAI* ai) const override; // Main update loop void UpdateBehavior(BotAI* ai, uint32 diff) override; private: // Role detection FormationRole DetermineRole(Player* bot) const; // Position calculations Position CalculateTankPosition(Player* bot, Unit* target) const; Position CalculateMeleePosition(Player* bot, Unit* target) const; Position CalculateRangedPosition(Player* bot, Unit* target) const; Position CalculateHealerPosition(Player* bot, Unit* target) const; // Movement execution void MoveToPosition(Player* bot, Position const& pos); bool IsInCorrectPosition(Player* bot, Position const& targetPos, float tolerance) const; // Mechanic avoidance bool IsStandingInDanger(Player* bot) const; Position FindSafePosition(Player* bot, Unit* target) const; // State FormationRole _currentRole = FormationRole::MELEE_DPS; uint32 _lastPositionUpdate = 0; uint32 _positionUpdateInterval = 100; // Update every 100ms }; } // namespace Playerbot ``` ### 2. CombatMovementStrategy.cpp Location: `src/modules/Playerbot/AI/Strategy/CombatMovementStrategy.cpp` **Implementation Requirements**: - Complete role detection based on class/spec - Full position calculation algorithms - TrinityCore MotionMaster API integration - Mechanic detection (AreaTriggers, DynamicObjects) - Safe position pathfinding ### 3. Integration with BotAI Location: `src/modules/Playerbot/AI/BotAI.cpp` **Changes Required**: ```cpp void BotAI::InitializeStrategies() { // Combat movement (higher priority than follow) _combatMovementStrategy = std::make_unique(); _combatMovementStrategy->SetPriority(80); // Higher than follow (60) // Social follow (lower priority) _leaderFollowBehavior = std::make_unique(); _leaderFollowBehavior->SetPriority(60); // Idle behavior (lowest priority) _idleStrategy = std::make_unique(); _idleStrategy->SetPriority(50); } void BotAI::UpdateStrategies(uint32 diff) { // Priority sorting ensures combat movement overrides follow during combat SortStrategiesByPriority(); for (auto& strategy : _activeStrategies) { if (strategy->IsActive(this)) strategy->UpdateBehavior(this, diff); } } ``` ### 4. Unit Tests Location: `tests/unit/AI/Strategy/CombatMovementStrategyTest.cpp` **Test Coverage**: - Role detection for all 13 classes - Position calculations for each role - Priority override during combat - Deactivation when leaving combat - Mechanic avoidance detection - Safe position calculation ### 5. Integration Tests Location: `tests/integration/CombatMovementIntegrationTest.cpp` **Test Scenarios**: - Solo bot attacking training dummy (correct positioning) - Group of 5 bots in dungeon (all roles position correctly) - Tank holds boss facing away from group - Melee DPS attack from behind - Ranged DPS maintain 25 yard distance - Healer stays within healing range of all members - Bots move out of fire/poison - Transition from follow → combat → follow ### 6. Documentation Location: `docs/COMBAT_MOVEMENT_GUIDE.md` **Content**: - Role detection algorithm explanation - Position calculation formulas - Priority system explanation - Mechanic avoidance implementation - Troubleshooting guide - Performance tuning tips --- ## Implementation Steps ### Step 1: Create Strategy Framework (2 days) 1. Write CombatMovementStrategy.h with full documentation 2. Create skeleton .cpp with method stubs 3. Add to CMakeLists.txt 4. Verify compilation ### Step 2: Implement Role Detection (1 day) ```cpp FormationRole CombatMovementStrategy::DetermineRole(Player* bot) const { uint32 spec = bot->GetPrimaryTalentTree(bot->GetActiveSpec()); uint8 playerClass = bot->getClass(); // Tank specs if ((playerClass == CLASS_WARRIOR && spec == TALENT_TREE_WARRIOR_PROTECTION) || (playerClass == CLASS_PALADIN && spec == TALENT_TREE_PALADIN_PROTECTION) || (playerClass == CLASS_DEATH_KNIGHT && spec == TALENT_TREE_DEATH_KNIGHT_BLOOD) || (playerClass == CLASS_DRUID && spec == TALENT_TREE_DRUID_FERAL_COMBAT && bot->HasAura(9634))) // Bear Form { return FormationRole::TANK; } // Healer specs if ((playerClass == CLASS_PRIEST && (spec == TALENT_TREE_PRIEST_DISCIPLINE || spec == TALENT_TREE_PRIEST_HOLY)) || (playerClass == CLASS_PALADIN && spec == TALENT_TREE_PALADIN_HOLY) || (playerClass == CLASS_SHAMAN && spec == TALENT_TREE_SHAMAN_RESTORATION) || (playerClass == CLASS_DRUID && spec == TALENT_TREE_DRUID_RESTORATION)) { return FormationRole::HEALER; } // Ranged DPS specs if (playerClass == CLASS_HUNTER || playerClass == CLASS_MAGE || playerClass == CLASS_WARLOCK || (playerClass == CLASS_PRIEST && spec == TALENT_TREE_PRIEST_SHADOW) || (playerClass == CLASS_SHAMAN && spec == TALENT_TREE_SHAMAN_ELEMENTAL) || (playerClass == CLASS_DRUID && spec == TALENT_TREE_DRUID_BALANCE)) { return FormationRole::RANGED_DPS; } // Melee DPS (default for remaining classes) return FormationRole::MELEE_DPS; } ``` ### Step 3: Implement Position Calculations (2 days) 1. Tank position - 5 yards in front 2. Melee DPS position - 5 yards behind (180° from front) 3. Ranged DPS position - 25 yards, optimal angle 4. Healer position - 18 yards, central to group 5. Path validation using TrinityCore APIs 6. Test each role independently ### Step 4: Implement Movement Execution (1 day) ```cpp void CombatMovementStrategy::MoveToPosition(Player* bot, Position const& pos) { if (!bot || !bot->IsInWorld()) return; // Check if already in position (avoid unnecessary movement) if (IsInCorrectPosition(bot, pos, 2.0f)) return; // Use MotionMaster to move bot->GetMotionMaster()->MovePoint(0, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()); } bool CombatMovementStrategy::IsInCorrectPosition(Player* bot, Position const& targetPos, float tolerance) const { if (!bot) return false; float dist = bot->GetDistance2d(targetPos.GetPositionX(), targetPos.GetPositionY()); return dist <= tolerance; } ``` ### Step 5: Implement Mechanic Avoidance (1 day) ```cpp bool CombatMovementStrategy::IsStandingInDanger(Player* bot) const { if (!bot) return false; // Check for dangerous AreaTriggers (fire, poison, etc.) std::list triggers; bot->GetAreaTriggersWithEntryInRange(triggers, 0, bot->GetPositionX(), bot->GetPositionY(), bot->GetPositionZ(), 5.0f); for (AreaTrigger* trigger : triggers) { if (trigger->IsUnitAffected(bot) && trigger->GetTemplate()->HasFlag(AREATRIGGER_FLAG_HOSTILE)) return true; } // Check for DynamicObjects (AoE effects) std::list dynObjects; bot->GetDynamicObjectsInRange(dynObjects, 5.0f); for (DynamicObject* obj : dynObjects) { if (obj->GetCasterGUID() != bot->GetGUID() && obj->IsHostileTo(bot)) return true; } return false; } ``` ### Step 6: Write Tests (1 day) 1. Unit tests for role detection (all classes) 2. Unit tests for position calculations 3. Integration test with dummy target 4. Integration test with group composition ### Step 7: Integration with BotAI (1 day) 1. Add CombatMovementStrategy to BotAI 2. Set priority (80 - higher than follow) 3. Test priority system works 4. Test activation/deactivation during combat transitions --- ## Success Criteria ### Functional - ✅ All 13 classes correctly detect their role - ✅ Tanks position in front of target - ✅ Melee DPS attack from behind - ✅ Ranged DPS maintain 20-30 yard distance - ✅ Healers stay within healing range of group - ✅ Bots move out of dangerous ground effects - ✅ Strategy activates on combat start - ✅ Strategy deactivates on combat end - ✅ Combat movement overrides follow behavior ### Performance - ✅ Position calculation <0.3ms per bot - ✅ Movement execution <0.2ms per bot - ✅ Total overhead <0.5ms per bot per frame - ✅ No performance degradation with 100+ bots in combat - ✅ No memory leaks after 1000 combat cycles ### Code Quality - ✅ Full documentation in header - ✅ All public methods documented - ✅ Follows TrinityCore coding conventions - ✅ No compiler warnings - ✅ 100% test coverage for role detection - ✅ 90%+ test coverage for position calculations --- ## Dependencies ### Requires - Phase 2.1 complete (BehaviorManager base class) - Existing LeaderFollowBehavior (for priority comparison) - TrinityCore MotionMaster API - TrinityCore AreaTrigger/DynamicObject APIs ### Blocks - Phase 2.6 (Integration testing needs combat movement) - Full combat effectiveness testing --- ## Risk Mitigation ### Risk: Bots get stuck in terrain **Mitigation**: Use TrinityCore's pathfinding validation before moving ### Risk: Movement conflicts with other systems **Mitigation**: Priority-based strategy execution, combat movement has highest priority ### Risk: Performance degradation with many bots **Mitigation**: Throttle position updates to 100ms intervals, profile with 500+ bots ### Risk: Role detection fails for hybrid classes **Mitigation**: Comprehensive unit tests for all class/spec combinations --- ## Next Phase After completion, proceed to **Phase 2.3: Fix Combat Activation (Universal ClassAI)** --- **Last Updated**: 2025-01-13 **Next Review**: 2025-01-27