From 27569f431f1adc4bde4691bde2ebcd2f1e9e646b Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Fri, 9 Feb 2024 15:42:36 +0800 Subject: [PATCH] Naxx thaddius strategy --- src/strategy/druid/HealDruidStrategy.cpp | 16 +- src/strategy/mage/GenericMageStrategy.cpp | 2 +- src/strategy/priest/HealPriestStrategy.cpp | 4 + .../raids/naxxramas/RaidNaxxActionContext.h | 12 +- .../raids/naxxramas/RaidNaxxActions.cpp | 311 ++++++------------ .../raids/naxxramas/RaidNaxxActions.h | 44 +-- .../raids/naxxramas/RaidNaxxBossHelper.h | 57 ++++ .../raids/naxxramas/RaidNaxxMultipliers.cpp | 81 +++-- .../raids/naxxramas/RaidNaxxMultipliers.h | 16 +- .../raids/naxxramas/RaidNaxxStrategy.cpp | 32 +- .../raids/naxxramas/RaidNaxxTriggerContext.h | 17 +- .../raids/naxxramas/RaidNaxxTriggers.cpp | 24 ++ .../raids/naxxramas/RaidNaxxTriggers.h | 57 ++-- src/strategy/values/TargetValue.h | 2 +- 14 files changed, 328 insertions(+), 347 deletions(-) diff --git a/src/strategy/druid/HealDruidStrategy.cpp b/src/strategy/druid/HealDruidStrategy.cpp index 5409a75e..b539d596 100644 --- a/src/strategy/druid/HealDruidStrategy.cpp +++ b/src/strategy/druid/HealDruidStrategy.cpp @@ -8,7 +8,17 @@ class HealDruidStrategyActionNodeFactory : public NamedObjectFactory { public: - HealDruidStrategyActionNodeFactory() { } + HealDruidStrategyActionNodeFactory() { + creators["nourish on party"] = &nourtish_on_party; + } + private: + static ActionNode* nourtish_on_party([[maybe_unused]] PlayerbotAI* botAI) + { + return new ActionNode ("nourish on party", + /*P*/ nullptr, + /*A*/ NextAction::array(0, new NextAction("healing touch on party"), nullptr), + /*C*/ nullptr); + } }; HealDruidStrategy::HealDruidStrategy(PlayerbotAI* botAI) : GenericDruidStrategy(botAI) @@ -34,7 +44,7 @@ void HealDruidStrategy::InitTriggers(std::vector& triggers) new NextAction("wild growth", ACTION_CRITICAL_HEAL + 3), new NextAction("regrowth on party", ACTION_CRITICAL_HEAL + 2), new NextAction("nourish on party", ACTION_CRITICAL_HEAL + 1), - new NextAction("healing touch on party", ACTION_CRITICAL_HEAL + 0), + // new NextAction("healing touch on party", ACTION_CRITICAL_HEAL + 0), NULL))); triggers.push_back(new TriggerNode( @@ -52,7 +62,7 @@ void HealDruidStrategy::InitTriggers(std::vector& triggers) new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 8), new NextAction("swiftmend on party", ACTION_MEDIUM_HEAL + 7), new NextAction("nourish on party", ACTION_MEDIUM_HEAL + 6), - new NextAction("healing touch on party", ACTION_MEDIUM_HEAL + 5), + // new NextAction("healing touch on party", ACTION_MEDIUM_HEAL + 5), NULL))); // MEDIUM diff --git a/src/strategy/mage/GenericMageStrategy.cpp b/src/strategy/mage/GenericMageStrategy.cpp index 8fc746a0..e6bff447 100644 --- a/src/strategy/mage/GenericMageStrategy.cpp +++ b/src/strategy/mage/GenericMageStrategy.cpp @@ -55,7 +55,7 @@ class GenericMageStrategyActionNodeFactory : public NamedObjectFactory& triggers) new NextAction("prayer of healing on party", ACTION_MEDIUM_HEAL + 6), NULL))); + triggers.push_back(new TriggerNode( + "medium group heal occasion", + NextAction::array(0, new NextAction("divine hymn", ACTION_CRITICAL_HEAL + 5), NULL))); + triggers.push_back(new TriggerNode( "party member critical health", NextAction::array(0, diff --git a/src/strategy/raids/naxxramas/RaidNaxxActionContext.h b/src/strategy/raids/naxxramas/RaidNaxxActionContext.h index 21539b8e..fe2c8366 100644 --- a/src/strategy/raids/naxxramas/RaidNaxxActionContext.h +++ b/src/strategy/raids/naxxramas/RaidNaxxActionContext.h @@ -19,11 +19,11 @@ class RaidNaxxActionContext : public NamedObjectContext creators["heigan dance melee"] = &RaidNaxxActionContext::heigan_dance_melee; creators["heigan dance ranged"] = &RaidNaxxActionContext::heigan_dance_ranged; - // creators["thaddius attack nearest pet"] = &RaidNaxxActionContext::thaddius_attack_nearest_pet; + creators["thaddius attack nearest pet"] = &RaidNaxxActionContext::thaddius_attack_nearest_pet; // creators["thaddius melee to place"] = &RaidNaxxActionContext::thaddius_tank_to_place; // creators["thaddius ranged to place"] = &RaidNaxxActionContext::thaddius_ranged_to_place; - // creators["thaddius move to platform"] = &RaidNaxxActionContext::thaddius_move_to_platform; - // creators["thaddius move polarity"] = &RaidNaxxActionContext::thaddius_move_polarity; + creators["thaddius move to platform"] = &RaidNaxxActionContext::thaddius_move_to_platform; + creators["thaddius move polarity"] = &RaidNaxxActionContext::thaddius_move_polarity; creators["razuvious use obedience crystal"] = &RaidNaxxActionContext::razuvious_use_obedience_crystal; creators["razuvious target"] = &RaidNaxxActionContext::razuvious_target; @@ -53,11 +53,11 @@ class RaidNaxxActionContext : public NamedObjectContext static Action* grobbulus_move_center(PlayerbotAI* ai) { return new GrobblulusMoveCenterAction(ai); } static Action* heigan_dance_melee(PlayerbotAI* ai) { return new HeiganDanceMeleeAction(ai); } static Action* heigan_dance_ranged(PlayerbotAI* ai) { return new HeiganDanceRangedAction(ai); } - // static Action* thaddius_attack_nearest_pet(PlayerbotAI* ai) { return new ThaddiusAttackNearestPetAction(ai); } + static Action* thaddius_attack_nearest_pet(PlayerbotAI* ai) { return new ThaddiusAttackNearestPetAction(ai); } // static Action* thaddius_tank_to_place(PlayerbotAI* ai) { return new ThaddiusMeleeToPlaceAction(ai); } // static Action* thaddius_ranged_to_place(PlayerbotAI* ai) { return new ThaddiusRangedToPlaceAction(ai); } - // static Action* thaddius_move_to_platform(PlayerbotAI* ai) { return new ThaddiusMoveToPlatformAction(ai); } - // static Action* thaddius_move_polarity(PlayerbotAI* ai) { return new ThaddiusMovePolarityAction(ai); } + static Action* thaddius_move_to_platform(PlayerbotAI* ai) { return new ThaddiusMoveToPlatformAction(ai); } + static Action* thaddius_move_polarity(PlayerbotAI* ai) { return new ThaddiusMovePolarityAction(ai); } static Action* razuvious_target(PlayerbotAI* ai) { return new RazuviousTargetAction(ai); } static Action* razuvious_use_obedience_crystal(PlayerbotAI* ai) { return new RazuviousUseObedienceCrystalAction(ai); } static Action* horseman_attract_alternatively(PlayerbotAI* ai) { return new HorsemanAttractAlternativelyAction(ai); } diff --git a/src/strategy/raids/naxxramas/RaidNaxxActions.cpp b/src/strategy/raids/naxxramas/RaidNaxxActions.cpp index 21a93615..ebebeb4b 100644 --- a/src/strategy/raids/naxxramas/RaidNaxxActions.cpp +++ b/src/strategy/raids/naxxramas/RaidNaxxActions.cpp @@ -8,37 +8,6 @@ #include "SharedDefines.h" #include "RaidNaxxBossHelper.h" -// bool TryToGetBossAIAction::Execute(Event event) { -// Unit* boss = AI_VALUE(Unit*, "boss target"); -// if (!boss) { -// return false; -// } -// Creature* creature = boss->ToCreature(); -// BossAI* b_ai = dynamic_cast(boss->GetAI()); -// if (!b_ai) { -// return false; -// } -// bool enabled = boss->IsAIEnabled; -// EventMap *eventMap = b_botAI->GetEvents(); -// uint8 phase_mask = eventMap->GetPhaseMask(); -// uint32 bossID = b_botAI->GetBossID(); -// bool isDungeonBoss = creature->IsDungeonBoss(); -// // bot->Yell("boss ai detected.", LANG_UNIVERSAL); -// uint32 next_event_time_1 = eventMap->GetNextEventTime(1); -// uint32 next_event_time_2 = eventMap->GetNextEventTime(2); -// uint32 next_event_time_3 = eventMap->GetNextEventTime(3); -// uint32 next_event_time_4 = eventMap->GetNextEventTime(4); -// uint32 next_event_time_5 = eventMap->GetNextEventTime(5); -// uint32 curr_timer = eventMap->GetTimer(); -// bot->Yell("boss ai detected. phase mask: " + std::to_string(phase_mask) + " ai enabled: " + std::to_string(enabled) + -// " boss id: " + std::to_string(bossID) + " name: " + boss->GetName() + " entry: " + std::to_string(boss->GetEntry()) + -// " guid: " + std::to_string(boss->GetGUID().GetRawValue()) + " isDungeonBoss: " + std::to_string(isDungeonBoss) + -// " event1: " + std::to_string(next_event_time_1) + " event2: " + std::to_string(next_event_time_2) + -// " event3: " + std::to_string(next_event_time_3) + " event4: " + std::to_string(next_event_time_4) + -// " event5: " + std::to_string(next_event_time_5) + " timer: " + std::to_string(curr_timer), LANG_UNIVERSAL); -// return true; - -// } bool GrobbulusGoBehindAction::Execute(Event event) { @@ -122,159 +91,106 @@ bool HeiganDanceRangedAction::Execute(Event event) { return MoveInside(bot->GetMapId(), waypoints[curr_safe].first, waypoints[curr_safe].second, bot->GetPositionZ(), 0); } -// bool ThaddiusAttackNearestPetAction::isUseful() -// { -// Unit* feugen = AI_VALUE2(Unit*, "find target", "feugen"); -// Unit* stalagg = AI_VALUE2(Unit*, "find target", "stalagg"); -// if (!feugen || !stalagg) { -// return false; -// } -// Unit* result = feugen; -// if (stalagg && (!result || (bot->GetDistance2d(result) > bot->GetDistance2d(stalagg)))) { -// result = stalagg; -// } -// if (AI_VALUE(Unit*, "current target") == result) { -// return false; -// } -// return true; -// } +bool ThaddiusAttackNearestPetAction::isUseful() +{ + if (!helper.UpdateBossAI()) { + return false; + } + if (!helper.IsPhasePet()) { + return false; + } + Unit* target = helper.GetNearestPet(); + if (bot->GetDistance(target) > 50.0f) { + return false; + } + return true; +} -// bool ThaddiusAttackNearestPetAction::Execute(Event event) { -// Unit* feugen = AI_VALUE2(Unit*, "find target", "feugen"); -// Unit* stalagg = AI_VALUE2(Unit*, "find target", "stalagg"); -// Unit* result = feugen; -// if (stalagg && (!result || (bot->GetDistance2d(result) > bot->GetDistance2d(stalagg)))) { -// result = stalagg; -// } -// // if (result) { -// // bot->Yell("Goona attack " + result->GetName(), LANG_UNIVERSAL); -// // } -// return Attack(result); -// } +bool ThaddiusAttackNearestPetAction::Execute(Event event) { + Unit* target = helper.GetNearestPet(); + if (!bot->IsWithinLOSInMap(target)) { + return MoveTo(target); + } + if (AI_VALUE(Unit*, "current target") != target) { + return Attack(target); + } + if (botAI->IsTank(bot) && AI_VALUE2(bool, "has aggro", "current target")) { + std::pair posForTank = helper.PetPhaseGetPosForTank(); + return MoveTo(533, posForTank.first, posForTank.second, helper.tankPosZ); + } + if (botAI->IsRanged(bot)) { + std::pair posForRanged = helper.PetPhaseGetPosForRanged(); + return MoveTo(533, posForRanged.first, posForRanged.second, helper.tankPosZ); + } + return false; +} -// bool ThaddiusMeleeToPlaceAction::isUseful() -// { -// if (botAI->IsTank(bot)) { -// Unit* target = AI_VALUE(Unit*, "current target"); -// return target && target->GetVictim() == bot; -// } else { -// return !botAI->IsRanged(bot); -// } -// } +bool ThaddiusMoveToPlatformAction::isUseful() +{ + return true; +} -// bool ThaddiusMeleeToPlaceAction::Execute(Event event) -// { -// Unit* target = AI_VALUE(Unit*, "current target"); -// Unit* feugen = AI_VALUE2(Unit*, "find target", "feugen"); -// Unit* stalagg = AI_VALUE2(Unit*, "find target", "stalagg"); -// // float high_lx = 3455.14f, high_ly = -2927.48f; -// // float high_rx = 3515.00f, high_ry = -2983.09f; -// float high_lx = 3436.14f, high_ly = -2919.98f; -// float high_rx = 3522.94f, high_ry = -3002.60f; -// float high_z = 312.61f; -// if (target == feugen) { -// return MoveTo(bot->GetMapId(), high_rx, high_ry, high_z); -// } else if (target == stalagg) { -// return MoveTo(bot->GetMapId(), high_lx, high_ly, high_z); -// } -// return false; -// } +bool ThaddiusMoveToPlatformAction::Execute(Event event) { + std::vector> position = { + // high left + {3462.99f, -2918.90f}, + // high right + {3520.65f, -2976.51f}, + // low left + {3471.36f, -2910.65f}, + // low right + {3528.80f, -2967.04f}, + // center + {3512.19f, -2928.58f}, + }; + float high_z = 312.00f, low_z = 304.02f; + bool is_left = bot->GetDistance2d(position[0].first, position[0].second) < bot->GetDistance2d(position[1].first, position[1].second); + if (bot->GetPositionZ() >= (high_z - 3.0f)) { + if (is_left) { + if (!MoveTo(bot->GetMapId(), position[0].first, position[0].second, high_z)) { + bot->TeleportTo(bot->GetMapId(), position[2].first, position[2].second, low_z, bot->GetOrientation()); + } + } else { + if (!MoveTo(bot->GetMapId(), position[1].first, position[1].second, high_z)) { + bot->TeleportTo(bot->GetMapId(), position[3].first, position[3].second, low_z, bot->GetOrientation()); + } + } + } else { + return MoveTo(bot->GetMapId(), position[4].first, position[4].second, low_z); + } + return true; +} -// bool ThaddiusRangedToPlaceAction::isUseful() -// { -// return botAI->IsRanged(bot); -// } +bool ThaddiusMovePolarityAction::isUseful() { + return !botAI->IsMainTank(bot) || AI_VALUE2(bool, "has aggro", "current target"); +} -// bool ThaddiusRangedToPlaceAction::Execute(Event event) -// { -// Unit* target = AI_VALUE(Unit*, "current target"); -// Unit* feugen = AI_VALUE2(Unit*, "find target", "feugen"); -// Unit* stalagg = AI_VALUE2(Unit*, "find target", "stalagg"); -// float high_lx = 3441.01f, high_ly = -2942.04f; -// float high_rx = 3500.45f, high_ry = -2997.92f; -// float high_z = 312.61f; -// if (target == feugen) { -// return MoveTo(bot->GetMapId(), high_rx, high_ry, high_z); -// } else if (target == stalagg) { -// return MoveTo(bot->GetMapId(), high_lx, high_ly, high_z); -// } -// return false; -// } - -// bool ThaddiusMoveToPlatformAction::isUseful() -// { -// // float high_z = 312.0f; -// // if (bot->GetPositionZ() < (high_z - 3.0f)) { -// // return false; -// // } -// return true; -// } - -// bool ThaddiusMoveToPlatformAction::Execute(Event event) { -// std::vector> position = { -// // high left -// {3462.99f, -2918.90f}, -// // high right -// {3520.65f, -2976.51f}, -// // low left -// {3471.36f, -2910.65f}, -// // low right -// {3528.80f, -2967.04f}, -// // center -// {3512.19f, -2928.58f}, -// }; -// // float high_lx = 3462.99f, high_ly = -2918.90f; -// // float high_rx = 3520.65f, high_ly = -2976.51f; -// // float low_lx = 3471.36f, low_ly = -2910.65f; -// // float low_rx = 3528.80f, low_ry = -2967.04f; -// float high_z = 312.00f, low_z = 304.02f; -// bool is_left = bot->GetDistance2d(position[0].first, position[0].second) < bot->GetDistance2d(position[1].first, position[1].second); -// if (bot->GetPositionZ() >= (high_z - 3.0f)) { -// if (is_left) { -// if (!MoveTo(bot->GetMapId(), position[0].first, position[0].second, high_z)) { -// bot->TeleportTo(bot->GetMapId(), position[2].first, position[2].second, low_z, bot->GetOrientation()); -// } -// } else { -// if (!MoveTo(bot->GetMapId(), position[1].first, position[1].second, high_z)) { -// bot->TeleportTo(bot->GetMapId(), position[3].first, position[3].second, low_z, bot->GetOrientation()); -// } -// } -// } else { -// return MoveTo(bot->GetMapId(), position[4].first, position[4].second, low_z); -// } -// return true; -// } - -// bool ThaddiusMovePolarityAction::isUseful() { -// return !botAI->IsMainTank(bot) || AI_VALUE2(bool, "has aggro", "current target"); -// } - -// bool ThaddiusMovePolarityAction::Execute(Event event) { -// std::vector> position = { -// // left melee -// {3508.29f, -2920.12f}, -// // left ranged -// {3501.72f, -2913.36f}, -// // right melee -// {3519.74f, -2931.69f}, -// // right ranged -// {3524.32f, -2936.26f}, -// // center melee -// {3512.19f, -2928.58f}, -// // center ranged -// {3504.68f, -2936.68f}, -// }; -// uint32 idx; -// if (botAI->HasAuraWithDuration("negative charge", bot)) { -// idx = 0; -// } else if (botAI->HasAuraWithDuration("positive charge", bot)) { -// idx = 1; -// } else { -// idx = 2; -// } -// idx = idx * 2 + botAI->IsRanged(bot); -// return MoveTo(bot->GetMapId(), position[idx].first, position[idx].second, bot->GetPositionZ()); -// } +bool ThaddiusMovePolarityAction::Execute(Event event) { + std::vector> position = { + // left melee + {3508.29f, -2920.12f}, + // left ranged + {3501.72f, -2913.36f}, + // right melee + {3519.74f, -2931.69f}, + // right ranged + {3524.32f, -2936.26f}, + // center melee + {3512.19f, -2928.58f}, + // center ranged + {3504.68f, -2936.68f}, + }; + uint32 idx; + if (botAI->HasAura("negative charge", bot, false, false, -1, true)) { + idx = 0; + } else if (botAI->HasAura("positive charge", bot, false, false, -1, true)) { + idx = 1; + } else { + idx = 2; + } + idx = idx * 2 + botAI->IsRanged(bot); + return MoveTo(bot->GetMapId(), position[idx].first, position[idx].second, bot->GetPositionZ()); +} bool RazuviousUseObedienceCrystalAction::Execute(Event event) { @@ -529,43 +445,6 @@ bool SapphironFlightPositionAction::MoveToNearestIcebolt() return false; } -// bool SapphironAvoidChillAction::Execute(Event event) -// { -// Aura* aura = botAI->GetAura("chill", bot); -// if (!aura) return false; -// DynamicObject* dyn_obj = aura->GetDynobjOwner(); -// if (!dyn_obj) return false; -// Unit* currentTarget = AI_VALUE(Unit*, "current target"); -// float angle = 0; -// uint32 index = botAI->GetGroupSlotIndex(bot); -// // prevent seg fault -// if (currentTarget) { -// if (botAI->IsRanged(bot)) { -// if (bot->GetExactDist2d(currentTarget) <= 45.0f) { -// angle = bot->GetAngle(dyn_obj) - M_PI + (rand_norm() - 0.5) * M_PI / 2; -// } else { -// if (index % 2 == 0) { -// angle = bot->GetAngle(currentTarget) + M_PI / 2; -// } else { -// angle = bot->GetAngle(currentTarget) - M_PI / 2; -// } -// } -// } else { -// if (index % 3 == 0) { -// angle = bot->GetAngle(currentTarget); -// } else if (index % 3 == 1) { -// angle = bot->GetAngle(currentTarget) + M_PI / 2; -// } else { -// angle = bot->GetAngle(currentTarget) - M_PI / 2; -// } -// } -// } else { -// angle = bot->GetAngle(dyn_obj) - M_PI + (rand_norm() - 0.5) * M_PI / 2; -// } -// // } -// return MoveTo(bot->GetMapId(), bot->GetPositionX() + cos(angle) * 5.0f, bot->GetPositionY() + sin(angle) * 5.0f, bot->GetPositionZ()); -// } - bool KelthuzadChooseTargetAction::Execute(Event event) { if (!helper.UpdateBossAI()) { diff --git a/src/strategy/raids/naxxramas/RaidNaxxActions.h b/src/strategy/raids/naxxramas/RaidNaxxActions.h index 6e36ffab..702d8839 100644 --- a/src/strategy/raids/naxxramas/RaidNaxxActions.h +++ b/src/strategy/raids/naxxramas/RaidNaxxActions.h @@ -87,13 +87,15 @@ protected: std::pair platform; }; -// class ThaddiusAttackNearestPetAction : public AttackAction -// { -// public: -// ThaddiusAttackNearestPetAction(PlayerbotAI* ai) : AttackAction(ai, "thaddius attack nearest pet") {} -// virtual bool Execute(Event event); -// virtual bool isUseful(); -// }; +class ThaddiusAttackNearestPetAction : public AttackAction +{ + public: + ThaddiusAttackNearestPetAction(PlayerbotAI* ai) : AttackAction(ai, "thaddius attack nearest pet"), helper(ai) {} + virtual bool Execute(Event event); + virtual bool isUseful(); + private: + ThaddiusBossHelper helper; +}; // class ThaddiusMeleeToPlaceAction : public MovementAction // { @@ -111,21 +113,21 @@ protected: // virtual bool isUseful(); // }; -// class ThaddiusMoveToPlatformAction : public MovementAction -// { -// public: -// ThaddiusMoveToPlatformAction(PlayerbotAI* ai) : MovementAction(ai, "thaddius move to platform") {} -// virtual bool Execute(Event event); -// virtual bool isUseful(); -// }; +class ThaddiusMoveToPlatformAction : public MovementAction +{ + public: + ThaddiusMoveToPlatformAction(PlayerbotAI* ai) : MovementAction(ai, "thaddius move to platform") {} + virtual bool Execute(Event event); + virtual bool isUseful(); +}; -// class ThaddiusMovePolarityAction : public MovementAction -// { -// public: -// ThaddiusMovePolarityAction(PlayerbotAI* ai) : MovementAction(ai, "thaddius move polarity") {} -// virtual bool Execute(Event event); -// virtual bool isUseful(); -// }; +class ThaddiusMovePolarityAction : public MovementAction +{ + public: + ThaddiusMovePolarityAction(PlayerbotAI* ai) : MovementAction(ai, "thaddius move polarity") {} + virtual bool Execute(Event event); + virtual bool isUseful(); +}; class RazuviousUseObedienceCrystalAction : public MovementAction { diff --git a/src/strategy/raids/naxxramas/RaidNaxxBossHelper.h b/src/strategy/raids/naxxramas/RaidNaxxBossHelper.h index 26ee973d..35b59e35 100644 --- a/src/strategy/raids/naxxramas/RaidNaxxBossHelper.h +++ b/src/strategy/raids/naxxramas/RaidNaxxBossHelper.h @@ -46,6 +46,9 @@ class GenericBossHelper : public AiObject { return false; } } + if (!_event_map) { + return false; + } _timer = _event_map->GetTimer(); return true; } @@ -294,5 +297,59 @@ class FourhorsemanBossHelper: public GenericBossHelper { + public: + const std::pair tankPosFeugen = {3522.94f, -3002.60f}; + const std::pair tankPosStalagg = {3436.14f, -2919.98f}; + const std::pair rangedPosFeugen = {3500.45f, -2997.92f}; + const std::pair rangedPosStalagg = {3441.01f, -2942.04f}; + const float tankPosZ = 312.61f; + ThaddiusBossHelper(PlayerbotAI *botAI): GenericBossHelper(botAI, "thaddius") {} + bool UpdateBossAI() override { + if (!GenericBossHelper::UpdateBossAI()) { + return false; + } + feugen = AI_VALUE2(Unit*, "find target", "feugen"); + stalagg = AI_VALUE2(Unit*, "find target", "stalagg"); + return true; + } + bool IsPhasePet() { + return (feugen && feugen->IsAlive()) || (stalagg && stalagg->IsAlive()); + } + bool IsPhaseTransition() { + if (IsPhasePet()) { + return false; + } + return _unit->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE); + } + bool IsPhaseThaddius() { + return !IsPhasePet() && !IsPhaseTransition(); + } + Unit* GetNearestPet() { + Unit* unit = nullptr; + if (feugen && feugen->IsAlive()) { + unit = feugen; + } + if (stalagg && stalagg->IsAlive() && (!feugen || bot->GetDistance(stalagg) < bot->GetDistance(feugen))) { + unit = stalagg; + } + return unit; + } + std::pair PetPhaseGetPosForTank() { + if (GetNearestPet() == feugen) { + return tankPosFeugen; + } + return tankPosStalagg; + } + std::pair PetPhaseGetPosForRanged() { + if (GetNearestPet() == feugen) { + return rangedPosFeugen; + } + return rangedPosStalagg; + } + protected: + Unit* feugen = nullptr; + Unit* stalagg = nullptr; +}; #endif diff --git a/src/strategy/raids/naxxramas/RaidNaxxMultipliers.cpp b/src/strategy/raids/naxxramas/RaidNaxxMultipliers.cpp index 2cc3c393..ff9fc212 100644 --- a/src/strategy/raids/naxxramas/RaidNaxxMultipliers.cpp +++ b/src/strategy/raids/naxxramas/RaidNaxxMultipliers.cpp @@ -80,49 +80,44 @@ float LoathebGenericMultiplier::GetValue(Action* action) return 0.0f; } -// float ThaddiusGenericMultiplier::GetValue(Action* action) -// { -// Unit* boss = AI_VALUE2(Unit*, "find target", "thaddius"); -// if (!boss) { -// return 1.0f; -// } -// BossAI* boss_ai = dynamic_cast(boss->GetAI()); -// EventMap* eventMap = boss_botAI->GetEvents(); -// uint32 curr_phase = eventMap->GetPhaseMask(); -// // pet phase -// if (curr_phase == 2 && -// ( dynamic_cast(action) || -// dynamic_cast(action) || -// dynamic_cast(action) || -// dynamic_cast(action) || -// dynamic_cast(action) )) { -// return 0.0f; -// } -// // die at the same time -// Unit* target = AI_VALUE(Unit*, "current target"); -// Unit* feugen = AI_VALUE2(Unit*, "find target", "feugen"); -// Unit* stalagg = AI_VALUE2(Unit*, "find target", "stalagg"); -// if (curr_phase == 2 && target && feugen && stalagg && -// target->GetHealthPct() <= 40 && -// (feugen->GetHealthPct() >= target->GetHealthPct() + 3 || stalagg->GetHealthPct() >= target->GetHealthPct() + 3)) { -// if (dynamic_cast(action) && !dynamic_cast(action)) { -// return 0.0f; -// } -// } -// // magnetic pull -// // uint32 curr_timer = eventMap->GetTimer(); -// // // if (curr_phase == 2 && bot->GetPositionZ() > 312.5f && dynamic_cast(action)) { -// // if (curr_phase == 2 && (curr_timer % 20000 >= 18000 || curr_timer % 20000 <= 2000) && dynamic_cast(action)) { -// // // MotionMaster *mm = bot->GetMotionMaster(); -// // // mm->Clear(); -// // return 0.0f; -// // } -// // thaddius phase -// if (curr_phase == 8 && dynamic_cast(action)) { -// return 0.0f; -// } -// return 1.0f; -// } +float ThaddiusGenericMultiplier::GetValue(Action* action) +{ + if (!helper.UpdateBossAI()) { + return 1.0f; + } + // pet phase + if (helper.IsPhasePet() && + (dynamic_cast(action) || + dynamic_cast(action) || + dynamic_cast(action) || + dynamic_cast(action) || + dynamic_cast(action))) { + return 0.0f; + } + // die at the same time + Unit* target = AI_VALUE(Unit*, "current target"); + Unit* feugen = AI_VALUE2(Unit*, "find target", "feugen"); + Unit* stalagg = AI_VALUE2(Unit*, "find target", "stalagg"); + if (helper.IsPhasePet() && target && feugen && stalagg && target->GetHealthPct() <= 40 && + (feugen->GetHealthPct() >= target->GetHealthPct() + 3 || stalagg->GetHealthPct() >= target->GetHealthPct() + 3)) { + if (dynamic_cast(action) && !dynamic_cast(action)) { + return 0.0f; + } + } + // magnetic pull + // uint32 curr_timer = eventMap->GetTimer(); + // // if (curr_phase == 2 && bot->GetPositionZ() > 312.5f && dynamic_cast(action)) { + // if (curr_phase == 2 && (curr_timer % 20000 >= 18000 || curr_timer % 20000 <= 2000) && dynamic_cast(action)) { + // // MotionMaster *mm = bot->GetMotionMaster(); + // // mm->Clear(); + // return 0.0f; + // } + // thaddius phase + // if (curr_phase == 8 && dynamic_cast(action)) { + // return 0.0f; + // } + return 1.0f; +} float SapphironGenericMultiplier::GetValue(Action* action) { diff --git a/src/strategy/raids/naxxramas/RaidNaxxMultipliers.h b/src/strategy/raids/naxxramas/RaidNaxxMultipliers.h index 82ca328d..4d80d566 100644 --- a/src/strategy/raids/naxxramas/RaidNaxxMultipliers.h +++ b/src/strategy/raids/naxxramas/RaidNaxxMultipliers.h @@ -23,14 +23,16 @@ public: virtual float GetValue(Action* action); }; -// class ThaddiusGenericMultiplier : public Multiplier -// { -// public: -// ThaddiusGenericMultiplier(PlayerbotAI* ai) : Multiplier(ai, "thaddius generic") {} +class ThaddiusGenericMultiplier : public Multiplier +{ + public: + ThaddiusGenericMultiplier(PlayerbotAI* ai) : Multiplier(ai, "thaddius generic"), helper(ai) {} -// public: -// virtual float GetValue(Action* action); -// }; + public: + virtual float GetValue(Action* action); + private: + ThaddiusBossHelper helper; +}; class SapphironGenericMultiplier : public Multiplier { diff --git a/src/strategy/raids/naxxramas/RaidNaxxStrategy.cpp b/src/strategy/raids/naxxramas/RaidNaxxStrategy.cpp index fca2a6db..c58d8b32 100644 --- a/src/strategy/raids/naxxramas/RaidNaxxStrategy.cpp +++ b/src/strategy/raids/naxxramas/RaidNaxxStrategy.cpp @@ -42,25 +42,23 @@ void RaidNaxxStrategy::InitTriggers(std::vector &triggers) nullptr))); // Thaddius - // triggers.push_back(new TriggerNode( - // "thaddius phase pet", - // NextAction::array(0, - // new NextAction("thaddius attack nearest pet", ACTION_RAID + 1), - // new NextAction("thaddius melee to place", ACTION_RAID), - // new NextAction("thaddius ranged to place", ACTION_RAID), - // nullptr))); + triggers.push_back(new TriggerNode( + "thaddius phase pet", + NextAction::array(0, + new NextAction("thaddius attack nearest pet", ACTION_RAID + 1), + nullptr))); - // triggers.push_back(new TriggerNode( - // "thaddius phase pet lose aggro", - // NextAction::array(0, new NextAction("taunt spell", ACTION_RAID + 2), nullptr))); + triggers.push_back(new TriggerNode( + "thaddius phase pet lose aggro", + NextAction::array(0, new NextAction("taunt spell", ACTION_RAID + 2), nullptr))); - // triggers.push_back(new TriggerNode( - // "thaddius phase transition", - // NextAction::array(0, new NextAction("thaddius move to platform", ACTION_RAID + 1), nullptr))); + triggers.push_back(new TriggerNode( + "thaddius phase transition", + NextAction::array(0, new NextAction("thaddius move to platform", ACTION_RAID + 1), nullptr))); - // triggers.push_back(new TriggerNode( - // "thaddius phase thaddius", - // NextAction::array(0, new NextAction("thaddius move polarity", ACTION_RAID + 1), nullptr))); + triggers.push_back(new TriggerNode( + "thaddius phase thaddius", + NextAction::array(0, new NextAction("thaddius move polarity", ACTION_RAID + 1), nullptr))); // Instructor Razuvious triggers.push_back(new TriggerNode( @@ -116,7 +114,7 @@ void RaidNaxxStrategy::InitMultipliers(std::vector &multipliers) { multipliers.push_back(new HeiganDanceMultiplier(botAI)); multipliers.push_back(new LoathebGenericMultiplier(botAI)); - // multipliers.push_back(new ThaddiusGenericMultiplier(botAI)); + multipliers.push_back(new ThaddiusGenericMultiplier(botAI)); multipliers.push_back(new SapphironGenericMultiplier(botAI)); multipliers.push_back(new InstructorRazuviousGenericMultiplier(botAI)); multipliers.push_back(new KelthuzadGenericMultiplier(botAI)); diff --git a/src/strategy/raids/naxxramas/RaidNaxxTriggerContext.h b/src/strategy/raids/naxxramas/RaidNaxxTriggerContext.h index 9a84eb49..342f58e6 100644 --- a/src/strategy/raids/naxxramas/RaidNaxxTriggerContext.h +++ b/src/strategy/raids/naxxramas/RaidNaxxTriggerContext.h @@ -20,10 +20,10 @@ class RaidNaxxTriggerContext : public NamedObjectContext creators["heigan melee"] = &RaidNaxxTriggerContext::heigan_melee; creators["heigan ranged"] = &RaidNaxxTriggerContext::heigan_ranged; - // creators["thaddius phase pet"] = &RaidNaxxTriggerContext::thaddius_phase_pet; - // creators["thaddius phase pet lose aggro"] = &RaidNaxxTriggerContext::thaddius_phase_pet_lose_aggro; - // creators["thaddius phase transition"] = &RaidNaxxTriggerContext::thaddius_phase_transition; - // creators["thaddius phase thaddius"] = &RaidNaxxTriggerContext::thaddius_phase_thaddius; + creators["thaddius phase pet"] = &RaidNaxxTriggerContext::thaddius_phase_pet; + creators["thaddius phase pet lose aggro"] = &RaidNaxxTriggerContext::thaddius_phase_pet_lose_aggro; + creators["thaddius phase transition"] = &RaidNaxxTriggerContext::thaddius_phase_transition; + creators["thaddius phase thaddius"] = &RaidNaxxTriggerContext::thaddius_phase_thaddius; creators["razuvious tank"] = &RaidNaxxTriggerContext::razuvious_tank; creators["razuvious nontank"] = &RaidNaxxTriggerContext::razuvious_nontank; @@ -49,10 +49,11 @@ class RaidNaxxTriggerContext : public NamedObjectContext static Trigger* grobbulus_cloud(PlayerbotAI* ai) { return new GrobbulusCloudTrigger(ai); } static Trigger* heigan_melee(PlayerbotAI* ai) { return new HeiganMeleeTrigger(ai); } static Trigger* heigan_ranged(PlayerbotAI* ai) { return new HeiganRangedTrigger(ai); } - // static Trigger* thaddius_phase_pet(PlayerbotAI* ai) { return new ThaddiusPhasePetTrigger(ai); } - // static Trigger* thaddius_phase_pet_lose_aggro(PlayerbotAI* ai) { return new ThaddiusPhasePetLoseAggroTrigger(ai); } - // static Trigger* thaddius_phase_transition(PlayerbotAI* ai) { return new ThaddiusPhaseTransitionTrigger(ai); } - // static Trigger* thaddius_phase_thaddius(PlayerbotAI* ai) { return new ThaddiusPhaseThaddiusTrigger(ai); } + + static Trigger* thaddius_phase_pet(PlayerbotAI* ai) { return new ThaddiusPhasePetTrigger(ai); } + static Trigger* thaddius_phase_pet_lose_aggro(PlayerbotAI* ai) { return new ThaddiusPhasePetLoseAggroTrigger(ai); } + static Trigger* thaddius_phase_transition(PlayerbotAI* ai) { return new ThaddiusPhaseTransitionTrigger(ai); } + static Trigger* thaddius_phase_thaddius(PlayerbotAI* ai) { return new ThaddiusPhaseThaddiusTrigger(ai); } static Trigger* razuvious_tank(PlayerbotAI* ai) { return new RazuviousTankTrigger(ai); } static Trigger* razuvious_nontank(PlayerbotAI* ai) { return new RazuviousNontankTrigger(ai); } diff --git a/src/strategy/raids/naxxramas/RaidNaxxTriggers.cpp b/src/strategy/raids/naxxramas/RaidNaxxTriggers.cpp index b2b5cb1d..1a815bf5 100644 --- a/src/strategy/raids/naxxramas/RaidNaxxTriggers.cpp +++ b/src/strategy/raids/naxxramas/RaidNaxxTriggers.cpp @@ -191,5 +191,29 @@ bool LoathebTrigger::IsActive() return helper.UpdateBossAI(); } +bool ThaddiusPhasePetTrigger::IsActive() +{ + if (!helper.UpdateBossAI()) { + return false; + } + return helper.IsPhasePet(); +} + +bool ThaddiusPhaseTransitionTrigger::IsActive() +{ + if (!helper.UpdateBossAI()) { + return false; + } + return helper.IsPhaseTransition(); +} + +bool ThaddiusPhaseThaddiusTrigger::IsActive() +{ + if (!helper.UpdateBossAI()) { + return false; + } + return helper.IsPhaseThaddius(); +} + template bool BossEventTrigger::IsActive(); template bool BossPhaseTrigger::IsActive(); \ No newline at end of file diff --git a/src/strategy/raids/naxxramas/RaidNaxxTriggers.h b/src/strategy/raids/naxxramas/RaidNaxxTriggers.h index 0310023b..4b07cc80 100644 --- a/src/strategy/raids/naxxramas/RaidNaxxTriggers.h +++ b/src/strategy/raids/naxxramas/RaidNaxxTriggers.h @@ -115,33 +115,42 @@ public: AnubrekhanTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "anub'rekhan", 0, "anub'rekhan trigger") {} }; -// class ThaddiusPhasePetTrigger : public BossPhaseTrigger -// { -// public: -// ThaddiusPhasePetTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "thaddius", 1 << (2 - 1), "thaddius phase pet") {} -// }; +class ThaddiusPhasePetTrigger : public Trigger +{ + public: + ThaddiusPhasePetTrigger(PlayerbotAI* ai) : Trigger(ai, "thaddius phase pet"), helper(ai) {} + bool IsActive() override; + private: + ThaddiusBossHelper helper; +}; -// class ThaddiusPhasePetLoseAggroTrigger : public ThaddiusPhasePetTrigger -// { -// public: -// ThaddiusPhasePetLoseAggroTrigger(PlayerbotAI* ai) : ThaddiusPhasePetTrigger(ai) {} -// virtual bool IsActive() { -// Unit* target = AI_VALUE(Unit*, "current target"); -// return ThaddiusPhasePetTrigger::IsActive() && ai->IsTank(bot) && target && target->GetVictim() != bot; -// } -// }; +class ThaddiusPhasePetLoseAggroTrigger : public ThaddiusPhasePetTrigger +{ +public: + ThaddiusPhasePetLoseAggroTrigger(PlayerbotAI* ai) : ThaddiusPhasePetTrigger(ai) {} + virtual bool IsActive() { + Unit* target = AI_VALUE(Unit*, "current target"); + return ThaddiusPhasePetTrigger::IsActive() && botAI->IsTank(bot) && target && target->GetVictim() != bot; + } +}; -// class ThaddiusPhaseTransitionTrigger : public BossPhaseTrigger -// { -// public: -// ThaddiusPhaseTransitionTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "thaddius", 1 << (3 - 1), "thaddius phase transition") {} -// }; +class ThaddiusPhaseTransitionTrigger : public Trigger +{ + public: + ThaddiusPhaseTransitionTrigger(PlayerbotAI* ai) : Trigger(ai, "thaddius phase transition"), helper(ai) {} + bool IsActive() override; + private: + ThaddiusBossHelper helper; +}; -// class ThaddiusPhaseThaddiusTrigger : public BossPhaseTrigger -// { -// public: -// ThaddiusPhaseThaddiusTrigger(PlayerbotAI* ai) : BossPhaseTrigger(ai, "thaddius", 1 << (4 - 1), "thaddius phase thaddius") {} -// }; +class ThaddiusPhaseThaddiusTrigger : public Trigger +{ + public: + ThaddiusPhaseThaddiusTrigger(PlayerbotAI* ai) : Trigger(ai, "thaddius phase thaddius"), helper(ai) {} + bool IsActive() override; + private: + ThaddiusBossHelper helper; +}; class HorsemanAttractorsTrigger : public Trigger { diff --git a/src/strategy/values/TargetValue.h b/src/strategy/values/TargetValue.h index b2cab18f..215977bd 100644 --- a/src/strategy/values/TargetValue.h +++ b/src/strategy/values/TargetValue.h @@ -101,7 +101,7 @@ class PullTargetValue : public ManualSetValue class FindTargetValue : public UnitCalculatedValue, public Qualified { public: - FindTargetValue(PlayerbotAI* ai) : UnitCalculatedValue(ai, "find target", 2 * 1000) {} + FindTargetValue(PlayerbotAI* ai) : UnitCalculatedValue(ai, "find target", /*2 * 1000*/1) {} public: Unit* Calculate();