From bc2b83e759da6cc69a129df603b00a0e0e0e4407 Mon Sep 17 00:00:00 2001 From: kadeshar Date: Sun, 20 Apr 2025 08:23:36 +0200 Subject: [PATCH] Resistance usage to ulduar strategy (#1212) * - Added resistance usage to ulduar strategy * - Fixed resistance strategies to affect only first required raid member --- .../raids/ulduar/RaidUlduarActionContext.h | 6 + .../raids/ulduar/RaidUlduarActions.cpp | 40 +++++ src/strategy/raids/ulduar/RaidUlduarActions.h | 27 +++ .../raids/ulduar/RaidUlduarStrategy.cpp | 15 ++ .../raids/ulduar/RaidUlduarTriggerContext.h | 6 + .../raids/ulduar/RaidUlduarTriggers.cpp | 164 +++++++++++++++++- .../raids/ulduar/RaidUlduarTriggers.h | 28 ++- 7 files changed, 284 insertions(+), 2 deletions(-) diff --git a/src/strategy/raids/ulduar/RaidUlduarActionContext.h b/src/strategy/raids/ulduar/RaidUlduarActionContext.h index 49823169..3bf822b4 100644 --- a/src/strategy/raids/ulduar/RaidUlduarActionContext.h +++ b/src/strategy/raids/ulduar/RaidUlduarActionContext.h @@ -24,6 +24,8 @@ public: creators["razorscale grounded"] = &RaidUlduarActionContext::razorscale_grounded; creators["razorscale harpoon action"] = &RaidUlduarActionContext::razorscale_harpoon_action; creators["razorscale fuse armor action"] = &RaidUlduarActionContext::razorscale_fuse_armor_action; + creators["razorscale fire resistance action"] = &RaidUlduarActionContext::razorscale_fire_resistance_action; + creators["ignis fire resistance action"] = &RaidUlduarActionContext::ignis_fire_resistance_action; creators["iron assembly lightning tendrils action"] = &RaidUlduarActionContext::iron_assembly_lightning_tendrils_action; creators["iron assembly overload action"] = &RaidUlduarActionContext::iron_assembly_overload_action; creators["kologarn mark dps target action"] = &RaidUlduarActionContext::kologarn_mark_dps_target_action; @@ -31,6 +33,7 @@ public: creators["kologarn nature resistance action"] = &RaidUlduarActionContext::kologarn_nature_resistance_action; creators["hodir move snowpacked icicle"] = &RaidUlduarActionContext::hodir_move_snowpacked_icicle; creators["hodir biting cold jump"] = &RaidUlduarActionContext::hodir_biting_cold_jump; + creators["hodir frost resistance action"] = &RaidUlduarActionContext::hodir_frost_resistance_action; creators["freya move away nature bomb"] = &RaidUlduarActionContext::freya_move_away_nature_bomb; creators["freya mark eonars gift"] = &RaidUlduarActionContext::freya_mark_eonars_gift; } @@ -45,6 +48,8 @@ private: static Action* razorscale_grounded(PlayerbotAI* ai) { return new RazorscaleGroundedAction(ai); } static Action* razorscale_harpoon_action(PlayerbotAI* ai) { return new RazorscaleHarpoonAction(ai); } static Action* razorscale_fuse_armor_action(PlayerbotAI* ai) { return new RazorscaleFuseArmorAction(ai); } + static Action* razorscale_fire_resistance_action(PlayerbotAI* ai) { return new RazorscaleFireResistanceAction(ai); } + static Action* ignis_fire_resistance_action(PlayerbotAI* ai) { return new IgnisFireResistanceAction(ai); } static Action* iron_assembly_lightning_tendrils_action(PlayerbotAI* ai) { return new IronAssemblyLightningTendrilsAction(ai); } static Action* iron_assembly_overload_action(PlayerbotAI* ai) { return new IronAssemblyOverloadAction(ai); } static Action* kologarn_mark_dps_target_action(PlayerbotAI* ai) { return new KologarnMarkDpsTargetAction(ai); } @@ -52,6 +57,7 @@ private: static Action* kologarn_nature_resistance_action(PlayerbotAI* ai) { return new KologarnNatureResistanceAction(ai); } static Action* hodir_move_snowpacked_icicle(PlayerbotAI* ai) { return new HodirMoveSnowpackedIcicleAction(ai); } static Action* hodir_biting_cold_jump(PlayerbotAI* ai) { return new HodirBitingColdJumpAction(ai); } + static Action* hodir_frost_resistance_action(PlayerbotAI* ai) { return new HodirFrostResistanceAction(ai); } static Action* freya_move_away_nature_bomb(PlayerbotAI* ai) { return new FreyaMoveAwayNatureBombAction(ai); } static Action* freya_mark_eonars_gift(PlayerbotAI* ai) { return new FreyaMarkEonarsGiftAction(ai); } }; diff --git a/src/strategy/raids/ulduar/RaidUlduarActions.cpp b/src/strategy/raids/ulduar/RaidUlduarActions.cpp index 4cb492c7..c0f61d11 100644 --- a/src/strategy/raids/ulduar/RaidUlduarActions.cpp +++ b/src/strategy/raids/ulduar/RaidUlduarActions.cpp @@ -25,6 +25,7 @@ #include "Unit.h" #include "Vehicle.h" #include +#include const std::vector availableVehicles = {NPC_VEHICLE_CHOPPER, NPC_SALVAGED_DEMOLISHER, NPC_SALVAGED_DEMOLISHER_TURRET, NPC_SALVAGED_SIEGE_ENGINE, @@ -1167,6 +1168,32 @@ bool RazorscaleFuseArmorAction::Execute(Event event) return true; } +bool RazorscaleFireResistanceAction::isUseful() +{ + RazorscaleFireResistanceTrigger razorscaleFireResistanceTrigger(botAI); + return razorscaleFireResistanceTrigger.IsActive(); +} + +bool RazorscaleFireResistanceAction::Execute(Event event) +{ + PaladinFireResistanceStrategy paladinFireResistanceStrategy(botAI); + botAI->ChangeStrategy(std::string("+") + paladinFireResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT); + return true; +} + +bool IgnisFireResistanceAction::isUseful() +{ + IgnisFireResistanceTrigger ignisFireResistanceTrigger(botAI); + return ignisFireResistanceTrigger.IsActive(); +} + +bool IgnisFireResistanceAction::Execute(Event event) +{ + PaladinFireResistanceStrategy paladinFireResistanceStrategy(botAI); + botAI->ChangeStrategy(std::string("+") + paladinFireResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT); + return true; +} + bool IronAssemblyLightningTendrilsAction::isUseful() { IronAssemblyLightningTendrilsTrigger ironAssemblyLightningTendrilsTrigger(botAI); @@ -1436,6 +1463,19 @@ bool HodirBitingColdJumpAction::Execute(Event event) // return true; } +bool HodirFrostResistanceAction::isUseful() +{ + HodirFrostResistanceTrigger hodirFrostResistanceTrigger(botAI); + return hodirFrostResistanceTrigger.IsActive(); +} + +bool HodirFrostResistanceAction::Execute(Event event) +{ + PaladinFrostResistanceStrategy paladinFrostResistanceStrategy(botAI); + botAI->ChangeStrategy(std::string("+") + paladinFrostResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT); + return true; +} + bool FreyaMoveAwayNatureBombAction::isUseful() { // Check boss and it is alive diff --git a/src/strategy/raids/ulduar/RaidUlduarActions.h b/src/strategy/raids/ulduar/RaidUlduarActions.h index afad5121..0c12585c 100644 --- a/src/strategy/raids/ulduar/RaidUlduarActions.h +++ b/src/strategy/raids/ulduar/RaidUlduarActions.h @@ -106,6 +106,25 @@ public: bool isUseful() override; }; +class RazorscaleFireResistanceAction : public Action +{ +public: + RazorscaleFireResistanceAction(PlayerbotAI* botAI) : Action(botAI, "razorscale fire resistance action") {} + bool Execute(Event event) override; + bool isUseful() override; +}; + +// +// Ignis +// +class IgnisFireResistanceAction : public Action +{ +public: + IgnisFireResistanceAction(PlayerbotAI* botAI) : Action(botAI, "ignis fire resistance action") {} + bool Execute(Event event) override; + bool isUseful() override; +}; + class HodirMoveSnowpackedIcicleAction : public MovementAction { public: @@ -114,6 +133,14 @@ public: bool isUseful() override; }; +class HodirFrostResistanceAction : public Action +{ +public: + HodirFrostResistanceAction(PlayerbotAI* botAI) : Action(botAI, "hodir frost resistance action") {} + bool Execute(Event event) override; + bool isUseful() override; +}; + class IronAssemblyLightningTendrilsAction : public MovementAction { public: diff --git a/src/strategy/raids/ulduar/RaidUlduarStrategy.cpp b/src/strategy/raids/ulduar/RaidUlduarStrategy.cpp index aedd246b..277e94b5 100644 --- a/src/strategy/raids/ulduar/RaidUlduarStrategy.cpp +++ b/src/strategy/raids/ulduar/RaidUlduarStrategy.cpp @@ -46,6 +46,17 @@ void RaidUlduarStrategy::InitTriggers(std::vector& triggers) "razorscale fuse armor trigger", NextAction::array(0, new NextAction("razorscale fuse armor action", ACTION_RAID + 2), nullptr))); + triggers.push_back(new TriggerNode( + "razorscale fire resistance trigger", + NextAction::array(0, new NextAction("razorscale fire resistance action", ACTION_RAID), nullptr))); + + // + // Ignis + // + triggers.push_back(new TriggerNode( + "ignis fire resistance trigger", + NextAction::array(0, new NextAction("ignis fire resistance action", ACTION_RAID), nullptr))); + // // Iron Assembly // @@ -83,6 +94,10 @@ void RaidUlduarStrategy::InitTriggers(std::vector& triggers) "hodir biting cold", NextAction::array(0, new NextAction("hodir biting cold jump", ACTION_RAID), nullptr))); + triggers.push_back(new TriggerNode( + "hodir frost resistance trigger", + NextAction::array(0, new NextAction("hodir frost resistance action", ACTION_RAID), nullptr))); + // // Freya // diff --git a/src/strategy/raids/ulduar/RaidUlduarTriggerContext.h b/src/strategy/raids/ulduar/RaidUlduarTriggerContext.h index 91dd1719..bd7d1b29 100644 --- a/src/strategy/raids/ulduar/RaidUlduarTriggerContext.h +++ b/src/strategy/raids/ulduar/RaidUlduarTriggerContext.h @@ -24,6 +24,8 @@ public: creators["razorscale grounded"] = &RaidUlduarTriggerContext::razorscale_grounded; creators["razorscale harpoon trigger"] = &RaidUlduarTriggerContext::razorscale_harpoon_trigger; creators["razorscale fuse armor trigger"] = &RaidUlduarTriggerContext::razorscale_fuse_armor_trigger; + creators["razorscale fire resistance trigger"] = &RaidUlduarTriggerContext::razorscale_fire_resistance_trigger; + creators["ignis fire resistance trigger"] = &RaidUlduarTriggerContext::ignis_fire_resistance_trigger; creators["iron assembly lightning tendrils trigger"] = &RaidUlduarTriggerContext::iron_assembly_lightning_tendrils_trigger; creators["iron assembly overload trigger"] = &RaidUlduarTriggerContext::iron_assembly_overload_trigger; creators["kologarn mark dps target trigger"] = &RaidUlduarTriggerContext::kologarn_mark_dps_target_trigger; @@ -31,6 +33,7 @@ public: creators["kologarn nature resistance trigger"] = &RaidUlduarTriggerContext::kologarn_nature_resistance_trigger; creators["hodir biting cold"] = &RaidUlduarTriggerContext::hodir_biting_cold; creators["hodir near snowpacked icicle"] = &RaidUlduarTriggerContext::hodir_near_snowpacked_icicle; + creators["hodir frost resistance trigger"] = &RaidUlduarTriggerContext::hodir_frost_resistance_trigger; creators["freya near nature bomb"] = &RaidUlduarTriggerContext::freya_near_nature_bomb; creators["freya tank near eonars gift"] = &RaidUlduarTriggerContext::freya_tank_near_eonars_gift; } @@ -45,6 +48,8 @@ private: static Trigger* razorscale_grounded(PlayerbotAI* ai) { return new RazorscaleGroundedTrigger(ai); } static Trigger* razorscale_harpoon_trigger(PlayerbotAI* ai) { return new RazorscaleHarpoonAvailableTrigger(ai); } static Trigger* razorscale_fuse_armor_trigger(PlayerbotAI* ai) { return new RazorscaleFuseArmorTrigger(ai); } + static Trigger* razorscale_fire_resistance_trigger(PlayerbotAI* ai) { return new RazorscaleFireResistanceTrigger(ai); } + static Trigger* ignis_fire_resistance_trigger(PlayerbotAI* ai) { return new IgnisFireResistanceTrigger(ai); } static Trigger* iron_assembly_lightning_tendrils_trigger(PlayerbotAI* ai) { return new IronAssemblyLightningTendrilsTrigger(ai); } static Trigger* iron_assembly_overload_trigger(PlayerbotAI* ai) { return new IronAssemblyOverloadTrigger(ai); } static Trigger* kologarn_mark_dps_target_trigger(PlayerbotAI* ai) { return new KologarnMarkDpsTargetTrigger(ai); } @@ -52,6 +57,7 @@ private: static Trigger* kologarn_nature_resistance_trigger(PlayerbotAI* ai) { return new KologarnNatureResistanceTrigger(ai); } static Trigger* hodir_biting_cold(PlayerbotAI* ai) { return new HodirBitingColdTrigger(ai); } static Trigger* hodir_near_snowpacked_icicle(PlayerbotAI* ai) { return new HodirNearSnowpackedIcicleTrigger(ai); } + static Trigger* hodir_frost_resistance_trigger(PlayerbotAI* ai) { return new HodirFrostResistanceTrigger(ai); } static Trigger* freya_near_nature_bomb(PlayerbotAI* ai) { return new FreyaNearNatureBombTrigger(ai); } static Trigger* freya_tank_near_eonars_gift(PlayerbotAI* ai) { return new FreyaTankNearEonarsGiftTrigger(ai); } }; diff --git a/src/strategy/raids/ulduar/RaidUlduarTriggers.cpp b/src/strategy/raids/ulduar/RaidUlduarTriggers.cpp index 1c339913..4ddaca56 100644 --- a/src/strategy/raids/ulduar/RaidUlduarTriggers.cpp +++ b/src/strategy/raids/ulduar/RaidUlduarTriggers.cpp @@ -12,6 +12,7 @@ #include "Trigger.h" #include "Vehicle.h" #include +#include const std::vector availableVehicles = {NPC_VEHICLE_CHOPPER, NPC_SALVAGED_DEMOLISHER, NPC_SALVAGED_DEMOLISHER_TURRET, NPC_SALVAGED_SIEGE_ENGINE, @@ -243,6 +244,100 @@ bool RazorscaleFuseArmorTrigger::IsActive() return false; } +bool RazorscaleFireResistanceTrigger::IsActive() +{ + // Check boss and it is alive + Unit* boss = AI_VALUE2(Unit*, "find target", "razorscale"); + if (!boss || !boss->IsAlive()) + return false; + + // Check if bot is paladin + if (bot->getClass() != CLASS_PALADIN) + return false; + + // Check if bot have fire resistance aura + if (bot->HasAura(SPELL_FIRE_RESISTANCE_AURA)) + return false; + + // Check if bot dont have already have fire resistance strategy + PaladinFireResistanceStrategy paladinFireResistanceStrategy(botAI); + if (botAI->HasStrategy(paladinFireResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT)) + return false; + + // Check that the bot actually knows the spell + if (!bot->HasActiveSpell(SPELL_FIRE_RESISTANCE_AURA)) + return false; + + // Get the group and ensure it's a raid group + Group* group = bot->GetGroup(); + if (!group || !group->isRaidGroup()) + return false; + + // Iterate through group members to find the first alive paladin + for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next()) + { + Player* member = gref->GetSource(); + if (!member || !member->IsAlive()) + continue; + + // Check if the member is a hunter + if (member->getClass() == CLASS_PALADIN) + { + // Return true only if the current bot is the first alive paladin + return member == bot; + } + } + + return false; +} + +bool IgnisFireResistanceTrigger::IsActive() +{ + // Check boss and it is alive + Unit* boss = AI_VALUE2(Unit*, "find target", "ignis the furnace master"); + if (!boss || !boss->IsAlive()) + return false; + + // Check if bot is paladin + if (bot->getClass() != CLASS_PALADIN) + return false; + + // Check if bot have fire resistance aura + if (bot->HasAura(SPELL_FIRE_RESISTANCE_AURA)) + return false; + + // Check if bot dont have already have fire resistance strategy + PaladinFireResistanceStrategy paladinFireResistanceStrategy(botAI); + if (botAI->HasStrategy(paladinFireResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT)) + return false; + + // Check that the bot actually knows the spell + if (!bot->HasActiveSpell(SPELL_FIRE_RESISTANCE_AURA)) + return false; + + // Get the group and ensure it's a raid group + Group* group = bot->GetGroup(); + if (!group || !group->isRaidGroup()) + return false; + + // Iterate through group members to find the first alive paladin + for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next()) + { + Player* member = gref->GetSource(); + if (!member || !member->IsAlive()) + continue; + + // Check if the member is a hunter + if (member->getClass() == CLASS_PALADIN) + { + // Return true only if the current bot is the first alive paladin + return member == bot; + } + } + + return false; +} + bool IronAssemblyLightningTendrilsTrigger::IsActive() { // Check boss and it is alive @@ -384,7 +479,27 @@ bool KologarnNatureResistanceTrigger::IsActive() if (!bot->HasActiveSpell(SPELL_ASPECT_OF_THE_WILD)) return false; - return true; + // Get the group and ensure it's a raid group + Group* group = bot->GetGroup(); + if (!group || !group->isRaidGroup()) + return false; + + // Iterate through group members to find the first alive hunter + for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next()) + { + Player* member = gref->GetSource(); + if (!member || !member->IsAlive()) + continue; + + // Check if the member is a hunter + if (member->getClass() == CLASS_HUNTER) + { + // Return true only if the current bot is the first alive hunter + return member == bot; + } + } + + return false; } bool HodirBitingColdTrigger::IsActive() @@ -435,6 +550,53 @@ bool HodirNearSnowpackedIcicleTrigger::IsActive() return true; } +bool HodirFrostResistanceTrigger::IsActive() +{ + // Check boss and it is alive + Unit* boss = AI_VALUE2(Unit*, "find target", "hodir"); + if (!boss || !boss->IsAlive()) + return false; + + // Check if bot is paladin + if (bot->getClass() != CLASS_PALADIN) + return false; + + // Check if bot have frost resistance aura + if (bot->HasAura(SPELL_FROST_RESISTANCE_AURA)) + return false; + + // Check if bot dont have already have frost resistance strategy + PaladinFrostResistanceStrategy paladinFrostResistanceStrategy(botAI); + if (botAI->HasStrategy(paladinFrostResistanceStrategy.getName(), BotState::BOT_STATE_COMBAT)) + return false; + + // Check that the bot actually knows the spell + if (!bot->HasActiveSpell(SPELL_FROST_RESISTANCE_AURA)) + return false; + + // Get the group and ensure it's a raid group + Group* group = bot->GetGroup(); + if (!group || !group->isRaidGroup()) + return false; + + // Iterate through group members to find the first alive paladin + for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next()) + { + Player* member = gref->GetSource(); + if (!member || !member->IsAlive()) + continue; + + // Check if the member is a hunter + if (member->getClass() == CLASS_PALADIN) + { + // Return true only if the current bot is the first alive paladin + return member == bot; + } + } + + return false; +} + bool FreyaNearNatureBombTrigger::IsActive() { // Check boss and it is alive diff --git a/src/strategy/raids/ulduar/RaidUlduarTriggers.h b/src/strategy/raids/ulduar/RaidUlduarTriggers.h index 2c097dd2..3b953c12 100644 --- a/src/strategy/raids/ulduar/RaidUlduarTriggers.h +++ b/src/strategy/raids/ulduar/RaidUlduarTriggers.h @@ -32,12 +32,14 @@ enum UlduarIDs NPC_TOASTY_FIRE = 33342, SPELL_FLASH_FREEZE = 61968, SPELL_BITING_COLD_PLAYER_AURA = 62039, - + // Freya NPC_EONARS_GIFT = 33228, GOBJECT_NATURE_BOMB = 194902, // Buffs + SPELL_FROST_RESISTANCE_AURA = 48945, + SPELL_FIRE_RESISTANCE_AURA = 48947, SPELL_ASPECT_OF_THE_WILD = 49071, }; @@ -112,6 +114,23 @@ public: bool IsActive() override; }; +class RazorscaleFireResistanceTrigger : public Trigger +{ +public: + RazorscaleFireResistanceTrigger(PlayerbotAI* ai) : Trigger(ai, "razorscale fire resistance trigger") {} + bool IsActive() override; +}; + +// +// Ignis +// +class IgnisFireResistanceTrigger : public Trigger +{ +public: + IgnisFireResistanceTrigger(PlayerbotAI* ai) : Trigger(ai, "ignis fire resistance trigger") {} + bool IsActive() override; +}; + // // Iron Assembly // @@ -170,6 +189,13 @@ public: bool IsActive() override; }; +class HodirFrostResistanceTrigger : public Trigger +{ +public: + HodirFrostResistanceTrigger(PlayerbotAI* ai) : Trigger(ai, "hodir frost resistance trigger") {} + bool IsActive() override; +}; + // // Freya //