#ifndef _PLAYERBOT_RAIDULDUARBOSSHELPER_H #define _PLAYERBOT_RAIDULDUARBOSSHELPER_H #include #include #include #include #include #include #include "AiObject.h" #include "AiObjectContext.h" #include "EventMap.h" #include "Log.h" #include "ObjectGuid.h" #include "Player.h" #include "PlayerbotAI.h" #include "Playerbots.h" #include "ScriptedCreature.h" #include "SharedDefines.h" const uint32 ULDUAR_MAP_ID = 603; class RazorscaleBossHelper : public AiObject { public: // Enums and constants specific to Razorscale enum RazorscaleUnits : uint32 { UNIT_RAZORSCALE = 33186, UNIT_DARK_RUNE_SENTINEL = 33846, UNIT_DARK_RUNE_WATCHER = 33453, UNIT_DARK_RUNE_GUARDIAN = 33388, UNIT_DEVOURING_FLAME = 34188, }; enum RazorscaleGameObjects : uint32 { GO_RAZORSCALE_HARPOON_1 = 194519, GO_RAZORSCALE_HARPOON_2 = 194541, GO_RAZORSCALE_HARPOON_3 = 194542, GO_RAZORSCALE_HARPOON_4 = 194543, }; enum RazorscaleSpells : uint32 { SPELL_CHAIN_1 = 49679, SPELL_CHAIN_2 = 49682, SPELL_CHAIN_3 = 49683, SPELL_CHAIN_4 = 49684, SPELL_SENTINEL_WHIRLWIND = 63806, SPELL_STUN_AURA = 62794, SPELL_FUSEARMOR = 64771 }; static constexpr uint32 FUSEARMOR_THRESHOLD = 2; // Constants for arena parameters static constexpr float RAZORSCALE_FLYING_Z_THRESHOLD = 440.0f; static constexpr float RAZORSCALE_ARENA_CENTER_X = 587.54f; static constexpr float RAZORSCALE_ARENA_CENTER_Y = -175.04f; static constexpr float RAZORSCALE_ARENA_RADIUS = 30.0f; // Harpoon cooldown (seconds) static constexpr time_t HARPOON_COOLDOWN_DURATION = 5; // Structure for harpoon data struct HarpoonData { uint32 gameObjectEntry; uint32 chainSpellId; }; explicit RazorscaleBossHelper(PlayerbotAI* botAI) : AiObject(botAI), _boss(nullptr), _lastRoleSwapTime(0), _roleSwapCooldown(10) {} bool UpdateBossAI(); Unit* GetBoss() const; bool IsGroundPhase() const; bool IsFlyingPhase() const; bool IsHarpoonFired(uint32 chainSpellId) const; static bool IsHarpoonReady(GameObject* harpoonGO); static void SetHarpoonOnCooldown(GameObject* harpoonGO); GameObject* FindNearestHarpoon(float x, float y, float z) const; static const std::vector& GetHarpoonData(); void AssignRolesBasedOnHealth(); bool AreRolesAssigned() const; bool CanSwapRoles() const; private: Unit* _boss; std::time_t _lastRoleSwapTime; const std::time_t _roleSwapCooldown; static std::unordered_map _harpoonCooldowns; }; // template // class GenericBossHelper : public AiObject // { // public: // GenericBossHelper(PlayerbotAI* botAI, std::string name) : AiObject(botAI), _name(name) {} // virtual bool UpdateBossAI() // { // if (!bot->IsInCombat()) // { // _unit = nullptr; // } // if (_unit && (!_unit->IsInWorld() || !_unit->IsAlive())) // { // _unit = nullptr; // } // if (!_unit) // { // _unit = AI_VALUE2(Unit*, "find target", _name); // if (!_unit) // { // return false; // } // _target = _unit->ToCreature(); // if (!_target) // { // return false; // } // _ai = dynamic_cast(_target->GetAI()); // if (!_ai) // { // return false; // } // _event_map = &_ai->events; // if (!_event_map) // { // return false; // } // } // if (!_event_map) // { // return false; // } // _timer = _event_map->GetTimer(); // return true; // } // virtual void Reset() // { // _unit = nullptr; // _target = nullptr; // _ai = nullptr; // _event_map = nullptr; // _timer = 0; // } // protected: // std::string _name; // Unit* _unit = nullptr; // Creature* _target = nullptr; // BossAiType* _ai = nullptr; // EventMap* _event_map = nullptr; // uint32 _timer = 0; // }; #endif