From 008d098eda4d475ca75c2b042ec32a7fae72ab76 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Thu, 3 Oct 2024 22:35:26 +0800 Subject: [PATCH 01/10] [Assist Dps] Healer assist dps strats --- conf/playerbots.conf.dist | 8 ++-- src/AiFactory.cpp | 11 ++--- src/PlayerbotAI.cpp | 36 +++++++---------- src/strategy/druid/CasterDruidStrategy.cpp | 3 -- src/strategy/druid/DruidAiObjectContext.cpp | 3 ++ src/strategy/druid/GenericDruidStrategy.cpp | 15 +++++++ src/strategy/druid/GenericDruidStrategy.h | 9 +++++ src/strategy/druid/HealDruidStrategy.cpp | 40 +++++++++++++++---- .../paladin/GenericPaladinStrategy.cpp | 13 ++++++ src/strategy/paladin/GenericPaladinStrategy.h | 9 +++++ .../GenericPaladinStrategyActionNodeFactory.h | 16 ++++---- src/strategy/paladin/HealPaladinStrategy.cpp | 2 +- .../paladin/PaladinAiObjectContext.cpp | 2 + src/strategy/paladin/TankPaladinStrategy.cpp | 2 +- src/strategy/priest/GenericPriestStrategy.cpp | 20 ++++++++++ src/strategy/priest/GenericPriestStrategy.h | 9 +++++ src/strategy/priest/PriestActions.h | 8 +++- src/strategy/priest/PriestAiObjectContext.cpp | 3 ++ .../priest/PriestNonCombatStrategy.cpp | 2 +- src/strategy/shaman/CasterShamanStrategy.cpp | 4 +- src/strategy/shaman/GenericShamanStrategy.cpp | 16 ++++++++ src/strategy/shaman/GenericShamanStrategy.h | 9 +++++ src/strategy/shaman/ShamanActions.h | 2 +- src/strategy/shaman/ShamanAiObjectContext.cpp | 3 ++ .../shaman/ShamanNonCombatStrategy.cpp | 2 +- src/strategy/triggers/GenericTriggers.cpp | 30 +++++++++++++- src/strategy/triggers/GenericTriggers.h | 10 +++++ src/strategy/triggers/HealthTriggers.cpp | 17 ++++++-- src/strategy/triggers/HealthTriggers.h | 5 +-- src/strategy/triggers/TriggerContext.h | 10 ++++- src/strategy/values/AttackerCountValues.cpp | 2 +- 31 files changed, 253 insertions(+), 68 deletions(-) diff --git a/conf/playerbots.conf.dist b/conf/playerbots.conf.dist index d7d02059..f158327a 100644 --- a/conf/playerbots.conf.dist +++ b/conf/playerbots.conf.dist @@ -1002,16 +1002,16 @@ AiPlayerbot.PremadeSpecLink.9.2.80 = -03310030003-05203205210331051335230351 AiPlayerbot.PremadeSpecName.11.0 = balance pve AiPlayerbot.PremadeSpecGlyph.11.0 = 40916,43331,40921,43335,44922,40919 -AiPlayerbot.PremadeSpecLink.11.0.60 = 5012203115331003213302301231 -AiPlayerbot.PremadeSpecLink.11.0.80 = 5012203125331103213305301231--205003212 +AiPlayerbot.PremadeSpecLink.11.0.60 = 5022203105331003213005301231 +AiPlayerbot.PremadeSpecLink.11.0.80 = 5032203105331303213305301231--205003012 AiPlayerbot.PremadeSpecName.11.1 = bear pve AiPlayerbot.PremadeSpecGlyph.11.1 = 40897,43331,46372,43335,43332,40899 AiPlayerbot.PremadeSpecLink.11.1.60 = -500232130322110353100301310501 AiPlayerbot.PremadeSpecLink.11.1.80 = -501232130322110353120303313511-20350001 AiPlayerbot.PremadeSpecName.11.2 = resto pve AiPlayerbot.PremadeSpecGlyph.11.2 = 40913,43331,40906,43335,44922,45602 -AiPlayerbot.PremadeSpecLink.11.2.60 = --230033312031501531050013051 -AiPlayerbot.PremadeSpecLink.11.2.80 = 05320001--230033312031512531153313051 +AiPlayerbot.PremadeSpecLink.11.2.60 = --230033312031500531050113051 +AiPlayerbot.PremadeSpecLink.11.2.80 = 05320031--230033312031501531053313051 AiPlayerbot.PremadeSpecName.11.3 = cat pve AiPlayerbot.PremadeSpecGlyph.11.3 = 40902,43331,40901,43335,44922,45604 AiPlayerbot.PremadeSpecLink.11.3.60 = -552202032322010053100030310501 diff --git a/src/AiFactory.cpp b/src/AiFactory.cpp index dadf327f..ce3fc272 100644 --- a/src/AiFactory.cpp +++ b/src/AiFactory.cpp @@ -277,10 +277,6 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa { engine->addStrategiesNoInit("racials", "chat", "default", "cast time", "duel", "boost", nullptr); } - if (sPlayerbotAIConfig->autoSaveMana) - { - engine->addStrategy("save mana", false); - } if (sPlayerbotAIConfig->autoAvoidAoe && facade->HasRealPlayerMaster()) { engine->addStrategy("avoid aoe", false); @@ -394,7 +390,12 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa if (PlayerbotAI::IsMelee(player, true) && PlayerbotAI::IsDps(player, true)) { engine->addStrategy("behind", false); } - + if (PlayerbotAI::IsHeal(player, true)) + { + if (sPlayerbotAIConfig->autoSaveMana) + engine->addStrategy("save mana", false); + engine->addStrategy("assist dps", false); + } if (facade->IsRealPlayer() || sRandomPlayerbotMgr->IsRandomBot(player)) { if (!player->GetGroup()) diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 4f79196f..7b6b9887 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -3339,11 +3339,11 @@ bool PlayerbotAI::CastSpell(uint32 spellId, Unit* target, Item* itemTarget) // } // } - WaitForSpellCast(spell); - if (spell->GetCastTime()) - aiObjectContext->GetValue("last spell cast") - ->Get() - .Set(spellId, target->GetGUID(), time(nullptr)); + // WaitForSpellCast(spell); + + aiObjectContext->GetValue("last spell cast") + ->Get() + .Set(spellId, target->GetGUID(), time(nullptr)); aiObjectContext->GetValue("position")->Get()["random"].Reset(); @@ -3473,7 +3473,7 @@ bool PlayerbotAI::CastSpell(uint32 spellId, float x, float y, float z, Item* ite } } - WaitForSpellCast(spell); + // WaitForSpellCast(spell); aiObjectContext->GetValue("last spell cast")->Get().Set(spellId, bot->GetGUID(), time(nullptr)); aiObjectContext->GetValue("position")->Get()["random"].Reset(); @@ -3688,7 +3688,7 @@ bool PlayerbotAI::CastVehicleSpell(uint32 spellId, Unit* target) return false; } - WaitForSpellCast(spell); + // WaitForSpellCast(spell); // aiObjectContext->GetValue("last spell cast")->Get().Set(spellId, target->GetGUID(), time(0)); // aiObjectContext->GetValue("position")->Get()["random"].Reset(); @@ -3745,23 +3745,15 @@ bool PlayerbotAI::IsInVehicle(bool canControl, bool canCast, bool canAttack, boo void PlayerbotAI::WaitForSpellCast(Spell* spell) { - return; SpellInfo const* spellInfo = spell->GetSpellInfo(); uint32 castTime = spell->GetCastTime(); - // float castTime = spell->GetCastTime(); - // if (spellInfo->IsChanneled()) - // { - // int32 duration = spellInfo->GetDuration(); - // bot->ApplySpellMod(spellInfo->Id, SPELLMOD_DURATION, duration); - // if (duration > 0) - // castTime += duration; - // } - - // castTime = ceil(castTime); - - // uint32 globalCooldown = CalculateGlobalCooldown(spellInfo->Id); - // if (castTime < globalCooldown) - // castTime = globalCooldown; + if (spellInfo->IsChanneled()) + { + int32 duration = spellInfo->GetDuration(); + bot->ApplySpellMod(spellInfo->Id, SPELLMOD_DURATION, duration); + if (duration > 0) + castTime += duration; + } SetNextCheckDelay(castTime + sPlayerbotAIConfig->reactDelay); } diff --git a/src/strategy/druid/CasterDruidStrategy.cpp b/src/strategy/druid/CasterDruidStrategy.cpp index 1dfeadfa..61e7ab3d 100644 --- a/src/strategy/druid/CasterDruidStrategy.cpp +++ b/src/strategy/druid/CasterDruidStrategy.cpp @@ -145,9 +145,6 @@ void CasterDruidStrategy::InitTriggers(std::vector& triggers) new TriggerNode("medium mana", NextAction::array(0, new NextAction("innervate", ACTION_HIGH + 9), NULL))); triggers.push_back(new TriggerNode("enemy too close for spell", NextAction::array(0, new NextAction("flee", ACTION_MOVE + 9), nullptr))); - triggers.push_back( - new TriggerNode("party member remove curse", - NextAction::array(0, new NextAction("remove curse on party", ACTION_DISPEL + 7), NULL))); } void CasterDruidAoeStrategy::InitTriggers(std::vector& triggers) diff --git a/src/strategy/druid/DruidAiObjectContext.cpp b/src/strategy/druid/DruidAiObjectContext.cpp index 04652487..fabd491b 100644 --- a/src/strategy/druid/DruidAiObjectContext.cpp +++ b/src/strategy/druid/DruidAiObjectContext.cpp @@ -14,6 +14,7 @@ #include "DruidShapeshiftActions.h" #include "DruidTriggers.h" #include "GenericDruidNonCombatStrategy.h" +#include "GenericDruidStrategy.h" #include "HealDruidStrategy.h" #include "MeleeDruidStrategy.h" #include "Playerbots.h" @@ -33,6 +34,7 @@ public: creators["buff"] = &DruidStrategyFactoryInternal::buff; creators["boost"] = &DruidStrategyFactoryInternal::boost; creators["cc"] = &DruidStrategyFactoryInternal::cc; + creators["assist dps"] = &DruidStrategyFactoryInternal::assist_dps; } private: @@ -45,6 +47,7 @@ private: static Strategy* buff(PlayerbotAI* botAI) { return new GenericDruidBuffStrategy(botAI); } static Strategy* boost(PlayerbotAI* botAI) { return new DruidBoostStrategy(botAI); } static Strategy* cc(PlayerbotAI* botAI) { return new DruidCcStrategy(botAI); } + static Strategy* assist_dps(PlayerbotAI* botAI) { return new DruidAssistDpsStrategy(botAI); } }; class DruidDruidStrategyFactoryInternal : public NamedObjectContext diff --git a/src/strategy/druid/GenericDruidStrategy.cpp b/src/strategy/druid/GenericDruidStrategy.cpp index c44668f7..ccd3be5e 100644 --- a/src/strategy/druid/GenericDruidStrategy.cpp +++ b/src/strategy/druid/GenericDruidStrategy.cpp @@ -130,6 +130,11 @@ void DruidCureStrategy::InitTriggers(std::vector& triggers) triggers.push_back( new TriggerNode("party member cure poison", NextAction::array(0, new NextAction("abolish poison on party", ACTION_DISPEL + 1), nullptr))); + + triggers.push_back( + new TriggerNode("party member remove curse", + NextAction::array(0, new NextAction("remove curse on party", ACTION_DISPEL + 7), NULL))); + } void DruidBoostStrategy::InitTriggers(std::vector& triggers) @@ -147,3 +152,13 @@ void DruidCcStrategy::InitTriggers(std::vector& triggers) triggers.push_back(new TriggerNode( "hibernate", NextAction::array(0, new NextAction("hibernate on cc", ACTION_HIGH + 3), nullptr))); } + +void DruidAssistDpsStrategy::InitTriggers(std::vector& triggers) +{ + triggers.push_back( + new TriggerNode("healer should attack", + NextAction::array(0, + new NextAction("moonfire", ACTION_DEFAULT + 0.2f), + new NextAction("wrath", ACTION_DEFAULT + 0.1f), + nullptr))); +} diff --git a/src/strategy/druid/GenericDruidStrategy.h b/src/strategy/druid/GenericDruidStrategy.h index db6631b2..6099527e 100644 --- a/src/strategy/druid/GenericDruidStrategy.h +++ b/src/strategy/druid/GenericDruidStrategy.h @@ -46,4 +46,13 @@ public: std::string const getName() override { return "cc"; } }; +class DruidAssistDpsStrategy : public Strategy +{ +public: + DruidAssistDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {} + + void InitTriggers(std::vector& triggers) override; + std::string const getName() override { return "assist dps"; } +}; + #endif diff --git a/src/strategy/druid/HealDruidStrategy.cpp b/src/strategy/druid/HealDruidStrategy.cpp index 0da13563..8fb17f2c 100644 --- a/src/strategy/druid/HealDruidStrategy.cpp +++ b/src/strategy/druid/HealDruidStrategy.cpp @@ -10,7 +10,12 @@ class HealDruidStrategyActionNodeFactory : public NamedObjectFactory { public: - HealDruidStrategyActionNodeFactory() { creators["nourish on party"] = &nourtish_on_party; } + HealDruidStrategyActionNodeFactory() { + creators["nourish on party"] = &nourtish_on_party; + creators["wild growth on party"] = &wild_growth_on_party; + creators["rejuvenation on party"] = &rejuvenation_on_party; + creators["regrowth on party"] = ®rowth_on_party; + } private: static ActionNode* nourtish_on_party([[maybe_unused]] PlayerbotAI* botAI) @@ -20,6 +25,27 @@ private: /*A*/ NextAction::array(0, new NextAction("healing touch on party"), nullptr), /*C*/ nullptr); } + static ActionNode* wild_growth_on_party([[maybe_unused]] PlayerbotAI* botAI) + { + return new ActionNode("wild growth on party", + /*P*/ NextAction::array(0, new NextAction("tree form"), nullptr), + /*A*/ nullptr, + /*C*/ nullptr); + } + static ActionNode* rejuvenation_on_party([[maybe_unused]] PlayerbotAI* botAI) + { + return new ActionNode("rejuvenation on party", + /*P*/ NextAction::array(0, new NextAction("tree form"), nullptr), + /*A*/ nullptr, + /*C*/ nullptr); + } + static ActionNode* regrowth_on_party([[maybe_unused]] PlayerbotAI* botAI) + { + return new ActionNode("regrowth on party", + /*P*/ NextAction::array(0, new NextAction("tree form"), nullptr), + /*A*/ nullptr, + /*C*/ nullptr); + } }; HealDruidStrategy::HealDruidStrategy(PlayerbotAI* botAI) : GenericDruidStrategy(botAI) @@ -33,19 +59,18 @@ void HealDruidStrategy::InitTriggers(std::vector& triggers) // triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell", // ACTION_NORMAL + 9), nullptr))); - triggers.push_back( - new TriggerNode("tree form", NextAction::array(0, new NextAction("tree form", ACTION_HIGH + 1), nullptr))); + // triggers.push_back( + // new TriggerNode("tree form", NextAction::array(0, new NextAction("tree form", ACTION_HIGH + 1), nullptr))); + triggers.push_back(new TriggerNode( "party member to heal out of spell range", NextAction::array(0, new NextAction("reach party member to heal", ACTION_CRITICAL_HEAL + 9), nullptr))); - triggers.push_back( - new TriggerNode("party member remove curse", - NextAction::array(0, new NextAction("remove curse on party", ACTION_DISPEL + 7), NULL))); + // CRITICAL triggers.push_back( new TriggerNode("party member critical health", NextAction::array(0, new NextAction("swiftmend on party", ACTION_CRITICAL_HEAL + 4), - new NextAction("wild growth", ACTION_CRITICAL_HEAL + 3), + new NextAction("wild growth on party", 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), @@ -66,7 +91,6 @@ 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), NULL))); // MEDIUM diff --git a/src/strategy/paladin/GenericPaladinStrategy.cpp b/src/strategy/paladin/GenericPaladinStrategy.cpp index d25a7518..791b5cff 100644 --- a/src/strategy/paladin/GenericPaladinStrategy.cpp +++ b/src/strategy/paladin/GenericPaladinStrategy.cpp @@ -71,3 +71,16 @@ void PaladinCcStrategy::InitTriggers(std::vector& triggers) triggers.push_back( new TriggerNode("turn undead", NextAction::array(0, new NextAction("turn undead", ACTION_HIGH + 1), nullptr))); } + +void PaladinAssistDpsStrategy::InitTriggers(std::vector& triggers) +{ + triggers.push_back( + new TriggerNode("healer should attack", + NextAction::array(0, + new NextAction("hammer of wrath", ACTION_DEFAULT + 0.5f), + new NextAction("holy shock", ACTION_DEFAULT + 0.4f), + new NextAction("shield of righteousness", ACTION_DEFAULT + 0.3f), + new NextAction("judgement of light", ACTION_DEFAULT + 0.2f), + new NextAction("exorcism", ACTION_DEFAULT + 0.1f), + nullptr))); +} diff --git a/src/strategy/paladin/GenericPaladinStrategy.h b/src/strategy/paladin/GenericPaladinStrategy.h index 4922a1bc..fcdef3c6 100644 --- a/src/strategy/paladin/GenericPaladinStrategy.h +++ b/src/strategy/paladin/GenericPaladinStrategy.h @@ -46,4 +46,13 @@ public: std::string const getName() override { return "cc"; } }; +class PaladinAssistDpsStrategy : public Strategy +{ +public: + PaladinAssistDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {} + + void InitTriggers(std::vector& triggers) override; + std::string const getName() override { return "assist dps"; } +}; + #endif diff --git a/src/strategy/paladin/GenericPaladinStrategyActionNodeFactory.h b/src/strategy/paladin/GenericPaladinStrategyActionNodeFactory.h index 68617eba..3503d773 100644 --- a/src/strategy/paladin/GenericPaladinStrategyActionNodeFactory.h +++ b/src/strategy/paladin/GenericPaladinStrategyActionNodeFactory.h @@ -22,7 +22,7 @@ public: creators["cleanse magic"] = &cleanse_magic; creators["cleanse poison on party"] = &cleanse_poison_on_party; creators["cleanse disease on party"] = &cleanse_disease_on_party; - // creators["seal of wisdom"] = &seal_of_wisdom; + creators["seal of wisdom"] = &seal_of_wisdom; creators["seal of justice"] = &seal_of_justice; creators["hand of reckoning"] = &hand_of_reckoning; creators["judgement"] = &judgement; @@ -147,13 +147,13 @@ private: /*A*/ NextAction::array(0, new NextAction("purify disease on party"), nullptr), /*C*/ nullptr); } - // static ActionNode* seal_of_wisdom(PlayerbotAI* ai) - // { - // return new ActionNode ("seal of wisdom", - // /*P*/ NULL, - // /*A*/ NextAction::array(0, new NextAction("seal of justice"), NULL), - // /*C*/ NULL); - // } + static ActionNode* seal_of_wisdom(PlayerbotAI* ai) + { + return new ActionNode ("seal of wisdom", + /*P*/ NULL, + /*A*/ NextAction::array(0, new NextAction("seal of righteousness"), NULL), + /*C*/ NULL); + } static ActionNode* seal_of_justice(PlayerbotAI* ai) { return new ActionNode("seal of justice", diff --git a/src/strategy/paladin/HealPaladinStrategy.cpp b/src/strategy/paladin/HealPaladinStrategy.cpp index 70c461ce..42517630 100644 --- a/src/strategy/paladin/HealPaladinStrategy.cpp +++ b/src/strategy/paladin/HealPaladinStrategy.cpp @@ -27,7 +27,7 @@ HealPaladinStrategy::HealPaladinStrategy(PlayerbotAI* botAI) : GenericPaladinStr NextAction** HealPaladinStrategy::getDefaultActions() { - return NextAction::array(0, new NextAction("judgement of light", ACTION_DEFAULT + 2), nullptr); + return NextAction::array(0, new NextAction("judgement of light", ACTION_DEFAULT), nullptr); } void HealPaladinStrategy::InitTriggers(std::vector& triggers) diff --git a/src/strategy/paladin/PaladinAiObjectContext.cpp b/src/strategy/paladin/PaladinAiObjectContext.cpp index 094e2fb7..5bc056ba 100644 --- a/src/strategy/paladin/PaladinAiObjectContext.cpp +++ b/src/strategy/paladin/PaladinAiObjectContext.cpp @@ -25,6 +25,7 @@ public: creators["boost"] = &PaladinStrategyFactoryInternal::boost; creators["cc"] = &PaladinStrategyFactoryInternal::cc; creators["bthreat"] = &PaladinStrategyFactoryInternal::bthreat; + creators["assist dps"] = &PaladinStrategyFactoryInternal::assist_dps; } private: @@ -33,6 +34,7 @@ private: static Strategy* boost(PlayerbotAI* botAI) { return new PaladinBoostStrategy(botAI); } static Strategy* cc(PlayerbotAI* botAI) { return new PaladinCcStrategy(botAI); } static Strategy* bthreat(PlayerbotAI* botAI) { return new PaladinBuffThreatStrategy(botAI); } + static Strategy* assist_dps(PlayerbotAI* botAI) { return new PaladinAssistDpsStrategy(botAI); } }; class PaladinResistanceStrategyFactoryInternal : public NamedObjectContext diff --git a/src/strategy/paladin/TankPaladinStrategy.cpp b/src/strategy/paladin/TankPaladinStrategy.cpp index 553d2a7d..1cb2c5c4 100644 --- a/src/strategy/paladin/TankPaladinStrategy.cpp +++ b/src/strategy/paladin/TankPaladinStrategy.cpp @@ -73,7 +73,7 @@ void TankPaladinStrategy::InitTriggers(std::vector& triggers) GenericPaladinStrategy::InitTriggers(triggers); triggers.push_back( - new TriggerNode("seal", NextAction::array(0, new NextAction("seal of command", ACTION_HIGH), nullptr))); + new TriggerNode("seal", NextAction::array(0, new NextAction("seal of corruption", ACTION_HIGH), nullptr))); triggers.push_back( new TriggerNode("low mana", NextAction::array(0, new NextAction("seal of wisdom", ACTION_HIGH + 9), nullptr))); // triggers.push_back(new TriggerNode("devotion aura", NextAction::array(0, new NextAction("devotion aura", 90.0f), diff --git a/src/strategy/priest/GenericPriestStrategy.cpp b/src/strategy/priest/GenericPriestStrategy.cpp index 40bae42d..42826fcd 100644 --- a/src/strategy/priest/GenericPriestStrategy.cpp +++ b/src/strategy/priest/GenericPriestStrategy.cpp @@ -87,3 +87,23 @@ void PriestCcStrategy::InitTriggers(std::vector& triggers) triggers.push_back( new TriggerNode("shackle undead", NextAction::array(0, new NextAction("shackle undead", 31.0f), nullptr))); } + +void PriestAssistDpsStrategy::InitTriggers(std::vector& triggers) +{ + triggers.push_back( + new TriggerNode("healer should attack", + NextAction::array(0, + new NextAction("shadow word: pain", ACTION_DEFAULT + 0.5f), + new NextAction("holy fire", ACTION_DEFAULT + 0.4f), + // new NextAction("mind blast", ACTION_DEFAULT + 0.3f), + new NextAction("smite", ACTION_DEFAULT + 0.1f), + new NextAction("shoot", ACTION_DEFAULT), + nullptr))); + + triggers.push_back( + new TriggerNode("medium aoe and healer should attack", + NextAction::array(0, + new NextAction("mind sear", ACTION_DEFAULT + 0.5f), + nullptr))); +} + diff --git a/src/strategy/priest/GenericPriestStrategy.h b/src/strategy/priest/GenericPriestStrategy.h index 7c6684af..f18e2b00 100644 --- a/src/strategy/priest/GenericPriestStrategy.h +++ b/src/strategy/priest/GenericPriestStrategy.h @@ -46,4 +46,13 @@ public: std::string const getName() override { return "cc"; } }; +class PriestAssistDpsStrategy : public Strategy +{ +public: + PriestAssistDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {} + + void InitTriggers(std::vector& triggers) override; + std::string const getName() override { return "assist dps"; } +}; + #endif diff --git a/src/strategy/priest/PriestActions.h b/src/strategy/priest/PriestActions.h index 468694c8..d5af0509 100644 --- a/src/strategy/priest/PriestActions.h +++ b/src/strategy/priest/PriestActions.h @@ -68,7 +68,13 @@ CURE_PARTY_ACTION(CastCureDiseaseOnPartyAction, "cure disease", DISPEL_DISEASE); CURE_ACTION(CastAbolishDiseaseAction, "abolish disease"); CURE_PARTY_ACTION(CastAbolishDiseaseOnPartyAction, "abolish disease", DISPEL_DISEASE); -DEBUFF_CHECKISOWNER_ACTION(CastHolyFireAction, "holy fire"); +// DEBUFF_CHECKISOWNER_ACTION(CastHolyFireAction, "holy fire"); +class CastHolyFireAction : public CastDebuffSpellAction +{ +public: + CastHolyFireAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "holy fire", true, 0.0f) {} +}; + // shadow 2.4.3 // BUFF_ACTION(CastShadowfiendAction, "shadowfiend"); SPELL_ACTION(CastShadowWordDeathAction, "shadow word: death"); diff --git a/src/strategy/priest/PriestAiObjectContext.cpp b/src/strategy/priest/PriestAiObjectContext.cpp index 0df50eec..caf4eb79 100644 --- a/src/strategy/priest/PriestAiObjectContext.cpp +++ b/src/strategy/priest/PriestAiObjectContext.cpp @@ -5,6 +5,7 @@ #include "PriestAiObjectContext.h" +#include "GenericPriestStrategy.h" #include "HolyPriestStrategy.h" #include "NamedObjectContext.h" #include "Playerbots.h" @@ -30,6 +31,7 @@ public: creators["boost"] = &PriestStrategyFactoryInternal::boost; creators["rshadow"] = &PriestStrategyFactoryInternal::rshadow; creators["cc"] = &PriestStrategyFactoryInternal::cc; + creators["assist dps"] = &PriestStrategyFactoryInternal::assist_dps; } private: @@ -42,6 +44,7 @@ private: static Strategy* pull(PlayerbotAI* botAI) { return new PullStrategy(botAI, "shoot"); } static Strategy* shadow_debuff(PlayerbotAI* botAI) { return new ShadowPriestDebuffStrategy(botAI); } static Strategy* cure(PlayerbotAI* botAI) { return new PriestCureStrategy(botAI); } + static Strategy* assist_dps(PlayerbotAI* botAI) { return new PriestAssistDpsStrategy(botAI); } }; class PriestCombatStrategyFactoryInternal : public NamedObjectContext diff --git a/src/strategy/priest/PriestNonCombatStrategy.cpp b/src/strategy/priest/PriestNonCombatStrategy.cpp index 161ac361..5283fb75 100644 --- a/src/strategy/priest/PriestNonCombatStrategy.cpp +++ b/src/strategy/priest/PriestNonCombatStrategy.cpp @@ -55,7 +55,7 @@ void PriestNonCombatStrategy::InitTriggers(std::vector& triggers) NextAction::array(0, new NextAction("renew on party", ACTION_LIGHT_HEAL + 3), NULL))); triggers.push_back( - new TriggerNode("medium aoe heal", NextAction::array(0, new NextAction("circle of healing", 27.0f), NULL))); + new TriggerNode("group heal occasion", NextAction::array(0, new NextAction("circle of healing", 27.0f), NULL))); } void PriestBuffStrategy::InitTriggers(std::vector& triggers) diff --git a/src/strategy/shaman/CasterShamanStrategy.cpp b/src/strategy/shaman/CasterShamanStrategy.cpp index 746abf86..c11c523d 100644 --- a/src/strategy/shaman/CasterShamanStrategy.cpp +++ b/src/strategy/shaman/CasterShamanStrategy.cpp @@ -51,8 +51,8 @@ void CasterShamanStrategy::InitTriggers(std::vector& triggers) // triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell", // ACTION_NORMAL + 9), nullptr))); triggers.push_back(new TriggerNode("shaman weapon", NextAction::array(0, new // NextAction("flametongue weapon", 23.0f), nullptr))); - // triggers.push_back(new TriggerNode( - // "enough mana", NextAction::array(0, new NextAction("chain lightning", ACTION_DEFAULT + 0.1f), nullptr))); + triggers.push_back(new TriggerNode( + "enough mana", NextAction::array(0, new NextAction("chain lightning", ACTION_DEFAULT + 0.1f), nullptr))); triggers.push_back(new TriggerNode("main hand weapon no imbue", NextAction::array(0, new NextAction("flametongue weapon", 22.0f), nullptr))); diff --git a/src/strategy/shaman/GenericShamanStrategy.cpp b/src/strategy/shaman/GenericShamanStrategy.cpp index 7110036d..d84b07a7 100644 --- a/src/strategy/shaman/GenericShamanStrategy.cpp +++ b/src/strategy/shaman/GenericShamanStrategy.cpp @@ -3,6 +3,7 @@ * and/or modify it under version 2 of the License, or (at your option), any later version. */ +#include "GenericShamanStrategy.h" #include "HealShamanStrategy.h" #include "Playerbots.h" #include "Strategy.h" @@ -162,3 +163,18 @@ void ShamanCureStrategy::InitTriggers(std::vector& triggers) new TriggerNode("party member cleanse spirit curse", NextAction::array(0, new NextAction("cleanse spirit curse on party", 23.0f), nullptr))); } + +void ShamanAssistDpsStrategy::InitTriggers(std::vector& triggers) +{ + triggers.push_back( + new TriggerNode("healer should attack", + NextAction::array(0, + new NextAction("flame shock", ACTION_DEFAULT + 0.2f), + new NextAction("lava burst", ACTION_DEFAULT + 0.1f), + new NextAction("lightning bolt", ACTION_DEFAULT), nullptr))); + + triggers.push_back( + new TriggerNode("medium aoe and healer should attack", + NextAction::array(0, + new NextAction("chain lightning", ACTION_DEFAULT + 0.3f), nullptr))); +} \ No newline at end of file diff --git a/src/strategy/shaman/GenericShamanStrategy.h b/src/strategy/shaman/GenericShamanStrategy.h index 49753e7b..d41b8c04 100644 --- a/src/strategy/shaman/GenericShamanStrategy.h +++ b/src/strategy/shaman/GenericShamanStrategy.h @@ -45,4 +45,13 @@ public: std::string const getName() override { return "cure"; } }; +class ShamanAssistDpsStrategy : public Strategy +{ +public: + ShamanAssistDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {} + + void InitTriggers(std::vector& triggers) override; + std::string const getName() override { return "assist dps"; } +}; + #endif diff --git a/src/strategy/shaman/ShamanActions.h b/src/strategy/shaman/ShamanActions.h index c4f6ce38..9d3b8b69 100644 --- a/src/strategy/shaman/ShamanActions.h +++ b/src/strategy/shaman/ShamanActions.h @@ -335,7 +335,7 @@ public: class CastFlameShockAction : public CastDebuffSpellAction { public: - CastFlameShockAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "flame shock", true) {} + CastFlameShockAction(PlayerbotAI* botAI) : CastDebuffSpellAction(botAI, "flame shock", true, 6.0f) {} }; class CastEarthShockAction : public CastSpellAction diff --git a/src/strategy/shaman/ShamanAiObjectContext.cpp b/src/strategy/shaman/ShamanAiObjectContext.cpp index e67f4230..bf9e76e3 100644 --- a/src/strategy/shaman/ShamanAiObjectContext.cpp +++ b/src/strategy/shaman/ShamanAiObjectContext.cpp @@ -6,6 +6,7 @@ #include "ShamanAiObjectContext.h" #include "CasterShamanStrategy.h" +#include "GenericShamanStrategy.h" #include "HealShamanStrategy.h" #include "MeleeShamanStrategy.h" #include "NamedObjectContext.h" @@ -25,6 +26,7 @@ public: creators["melee aoe"] = &ShamanStrategyFactoryInternal::melee_aoe; creators["caster aoe"] = &ShamanStrategyFactoryInternal::caster_aoe; creators["cure"] = &ShamanStrategyFactoryInternal::cure; + creators["assist dps"] = &ShamanStrategyFactoryInternal::assist_dps; } private: @@ -33,6 +35,7 @@ private: static Strategy* melee_aoe(PlayerbotAI* botAI) { return new MeleeAoeShamanStrategy(botAI); } static Strategy* caster_aoe(PlayerbotAI* botAI) { return new CasterAoeShamanStrategy(botAI); } static Strategy* cure(PlayerbotAI* botAI) { return new ShamanCureStrategy(botAI); } + static Strategy* assist_dps(PlayerbotAI* botAI) { return new ShamanAssistDpsStrategy(botAI); } }; class ShamanBuffStrategyFactoryInternal : public NamedObjectContext diff --git a/src/strategy/shaman/ShamanNonCombatStrategy.cpp b/src/strategy/shaman/ShamanNonCombatStrategy.cpp index 3d544419..f3380cb5 100644 --- a/src/strategy/shaman/ShamanNonCombatStrategy.cpp +++ b/src/strategy/shaman/ShamanNonCombatStrategy.cpp @@ -39,7 +39,7 @@ void ShamanNonCombatStrategy::InitTriggers(std::vector& triggers) new NextAction("lesser healing wave on party", 24.0f), NULL))); triggers.push_back( - new TriggerNode("medium aoe heal", NextAction::array(0, new NextAction("chain heal", 27.0f), NULL))); + new TriggerNode("group heal occasion", NextAction::array(0, new NextAction("chain heal", 27.0f), NULL))); triggers.push_back( new TriggerNode("cure poison", NextAction::array(0, new NextAction("cure poison", 21.0f), nullptr))); diff --git a/src/strategy/triggers/GenericTriggers.cpp b/src/strategy/triggers/GenericTriggers.cpp index f700e472..0adbc077 100644 --- a/src/strategy/triggers/GenericTriggers.cpp +++ b/src/strategy/triggers/GenericTriggers.cpp @@ -76,7 +76,7 @@ bool AlmostFullManaTrigger::IsActive() bool EnoughManaTrigger::IsActive() { - return AI_VALUE2(bool, "has mana", "self target") && AI_VALUE2(uint8, "mana", "self target") > 65; + return AI_VALUE2(bool, "has mana", "self target") && AI_VALUE2(uint8, "mana", "self target") > sPlayerbotAIConfig->highMana; } bool RageAvailable::IsActive() { return AI_VALUE2(uint8, "rage", "self target") >= amount; } @@ -366,6 +366,34 @@ bool GenericBoostTrigger::IsActive() return AI_VALUE(uint8, "balance") <= balance; } +bool HealerShouldAttackTrigger::IsActive() +{ + // nobody can help me + if (botAI->GetNearGroupMemberCount(sPlayerbotAIConfig->sightDistance) <= 1) + return true; + + bool almostFullMana = AI_VALUE2(bool, "has mana", "self target") && + AI_VALUE2(uint8, "mana", "self target") < 85; + + // high pressure + if (AI_VALUE(uint8, "balance") <= 50 && almostFullMana) + return false; + + bool highMana = AI_VALUE2(bool, "has mana", "self target") && + AI_VALUE2(uint8, "mana", "self target") < sPlayerbotAIConfig->highMana; + + if (AI_VALUE(uint8, "balance") <= 100 && highMana) + return false; + + bool mediumMana = AI_VALUE2(bool, "has mana", "self target") && + AI_VALUE2(uint8, "mana", "self target") < sPlayerbotAIConfig->mediumMana; + + if (mediumMana) + return false; + + return true; +} + bool ItemCountTrigger::IsActive() { return AI_VALUE2(uint32, "item count", item) < count; } bool InterruptSpellTrigger::IsActive() diff --git a/src/strategy/triggers/GenericTriggers.h b/src/strategy/triggers/GenericTriggers.h index e9990c3e..f93cb156 100644 --- a/src/strategy/triggers/GenericTriggers.h +++ b/src/strategy/triggers/GenericTriggers.h @@ -459,6 +459,16 @@ protected: float balance; }; +class HealerShouldAttackTrigger : public Trigger +{ +public: + HealerShouldAttackTrigger(PlayerbotAI* botAI) + : Trigger(botAI, "healer should attack", 1) + { + } + + bool IsActive() override; +}; class RandomTrigger : public Trigger { diff --git a/src/strategy/triggers/HealthTriggers.cpp b/src/strategy/triggers/HealthTriggers.cpp index d4c971ac..3bc8d4f3 100644 --- a/src/strategy/triggers/HealthTriggers.cpp +++ b/src/strategy/triggers/HealthTriggers.cpp @@ -24,7 +24,18 @@ bool AoeHealTrigger::IsActive() { return AI_VALUE2(uint8, "aoe heal", type) >= c bool AoeInGroupTrigger::IsActive() { - Group* group = bot->GetGroup(); - return group && group->GetMembersCount() >= 5 && - AI_VALUE2(uint8, "aoe heal", type) >= (group->GetMembersCount() * ratio); + int32 member = botAI->GetNearGroupMemberCount(); + if (member < 5) + return false; + int threshold = member * 0.5; + if (member <= 5) + threshold = 3; + else if (member <= 10) + threshold = std::min(threshold, 5); + else if (member <= 25) + threshold = std::min(threshold, 10); + else + threshold = std::min(threshold, 15); + + return AI_VALUE2(uint8, "aoe heal", type) >= threshold; } \ No newline at end of file diff --git a/src/strategy/triggers/HealthTriggers.h b/src/strategy/triggers/HealthTriggers.h index d9f3253c..279bc3fe 100644 --- a/src/strategy/triggers/HealthTriggers.h +++ b/src/strategy/triggers/HealthTriggers.h @@ -186,14 +186,13 @@ protected: class AoeInGroupTrigger : public Trigger { public: - AoeInGroupTrigger(PlayerbotAI* ai, std::string name, std::string type, float ratio) - : Trigger(ai, name), ratio(ratio), type(type) + AoeInGroupTrigger(PlayerbotAI* ai, std::string name, std::string type) + : Trigger(ai, name), type(type) { } bool IsActive() override; protected: - float ratio; std::string type; }; diff --git a/src/strategy/triggers/TriggerContext.h b/src/strategy/triggers/TriggerContext.h index 860ee682..4bfea1d4 100644 --- a/src/strategy/triggers/TriggerContext.h +++ b/src/strategy/triggers/TriggerContext.h @@ -48,6 +48,7 @@ public: creators["almost full mana"] = &TriggerContext::AlmostFullMana; creators["enough mana"] = &TriggerContext::EnoughMana; + creators["party member critical health"] = &TriggerContext::PartyMemberCriticalHealth; creators["party member low health"] = &TriggerContext::PartyMemberLowHealth; creators["party member medium health"] = &TriggerContext::PartyMemberMediumHealth; @@ -83,6 +84,9 @@ public: creators["medium aoe"] = &TriggerContext::MediumAoe; creators["high aoe"] = &TriggerContext::HighAoe; + creators["healer should attack"] = &TriggerContext::healer_should_attack; + creators["medium aoe and healer should attack"] = &TriggerContext::medium_aoe_and_healer_should_attack; + creators["has area debuff"] = &TriggerContext::HasAreaDebuff; creators["enemy out of melee"] = &TriggerContext::EnemyOutOfMelee; @@ -242,11 +246,11 @@ private: } static Trigger* group_heal_occasion(PlayerbotAI* ai) { - return new AoeInGroupTrigger(ai, "group heal occasion", "almost full", 0.6); + return new AoeInGroupTrigger(ai, "group heal occasion", "almost full"); } static Trigger* medium_group_heal_occasion(PlayerbotAI* ai) { - return new AoeInGroupTrigger(ai, "group heal occasion", "medium", 0.6); + return new AoeInGroupTrigger(ai, "medium group heal occasion", "medium"); } static Trigger* target_changed(PlayerbotAI* botAI) { return new TargetChangedTrigger(botAI); } static Trigger* swimming(PlayerbotAI* botAI) { return new IsSwimmingTrigger(botAI); } @@ -265,6 +269,8 @@ private: static Trigger* LightAoe(PlayerbotAI* botAI) { return new LightAoeTrigger(botAI); } static Trigger* MediumAoe(PlayerbotAI* botAI) { return new MediumAoeTrigger(botAI); } static Trigger* HighAoe(PlayerbotAI* botAI) { return new HighAoeTrigger(botAI); } + static Trigger* healer_should_attack(PlayerbotAI* botAI) { return new HealerShouldAttackTrigger(botAI); } + static Trigger* medium_aoe_and_healer_should_attack(PlayerbotAI* botAI) { return new TwoTriggers(botAI, "medium aoe", "healer should attack"); } static Trigger* HasAreaDebuff(PlayerbotAI* botAI) { return new HasAreaDebuffTrigger(botAI); } static Trigger* LoseAggro(PlayerbotAI* botAI) { return new LoseAggroTrigger(botAI); } static Trigger* HasAggro(PlayerbotAI* botAI) { return new HasAggroTrigger(botAI); } diff --git a/src/strategy/values/AttackerCountValues.cpp b/src/strategy/values/AttackerCountValues.cpp index 59de8995..17ba4562 100644 --- a/src/strategy/values/AttackerCountValues.cpp +++ b/src/strategy/values/AttackerCountValues.cpp @@ -94,7 +94,7 @@ uint8 BalancePercentValue::Calculate() level *= 3; break; case CREATURE_ELITE_WORLDBOSS: - level *= 30; + level *= 20; break; } From a0dd00bba1ef711881bffce1b03de10dd5e044ae Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Fri, 4 Oct 2024 01:49:57 +0800 Subject: [PATCH 02/10] [Spell] Handle tree of life and assist dps --- src/AiFactory.cpp | 4 +- src/strategy/druid/CasterDruidStrategy.cpp | 2 +- src/strategy/druid/DruidAiObjectContext.cpp | 2 + src/strategy/druid/DruidShapeshiftActions.cpp | 11 +++ src/strategy/druid/DruidShapeshiftActions.h | 10 +++ .../druid/GenericDruidNonCombatStrategy.cpp | 24 ++++--- src/strategy/druid/GenericDruidStrategy.cpp | 8 +++ src/strategy/druid/HealDruidStrategy.cpp | 71 ++++++++++--------- .../GenericPaladinNonCombatStrategy.cpp | 2 +- .../paladin/GenericPaladinStrategy.cpp | 11 +-- src/strategy/priest/GenericPriestStrategy.cpp | 4 +- src/strategy/triggers/GenericTriggers.cpp | 33 +++++---- .../GenericWarlockNonCombatStrategy.cpp | 2 +- 13 files changed, 117 insertions(+), 67 deletions(-) diff --git a/src/AiFactory.cpp b/src/AiFactory.cpp index ce3fc272..c03cd615 100644 --- a/src/AiFactory.cpp +++ b/src/AiFactory.cpp @@ -484,8 +484,8 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa engine->removeStrategy("threat", false); engine->addStrategy("boost", false); - if ((player->getClass() == CLASS_DRUID && tab == 2) || (player->getClass() == CLASS_SHAMAN && tab == 2)) - engine->addStrategiesNoInit("caster", "caster aoe", nullptr); + // if ((player->getClass() == CLASS_DRUID && tab == 2) || (player->getClass() == CLASS_SHAMAN && tab == 2)) + // engine->addStrategiesNoInit("caster", "caster aoe", nullptr); // if (player->getClass() == CLASS_DRUID && tab == 1) // engine->addStrategiesNoInit(/*"behind",*/ "dps", nullptr); diff --git a/src/strategy/druid/CasterDruidStrategy.cpp b/src/strategy/druid/CasterDruidStrategy.cpp index 61e7ab3d..27080efe 100644 --- a/src/strategy/druid/CasterDruidStrategy.cpp +++ b/src/strategy/druid/CasterDruidStrategy.cpp @@ -150,7 +150,7 @@ void CasterDruidStrategy::InitTriggers(std::vector& triggers) void CasterDruidAoeStrategy::InitTriggers(std::vector& triggers) { triggers.push_back( - new TriggerNode("high aoe", NextAction::array(0, new NextAction("hurricane", ACTION_HIGH + 1), nullptr))); + new TriggerNode("medium aoe", NextAction::array(0, new NextAction("hurricane", ACTION_HIGH + 1), nullptr))); triggers.push_back(new TriggerNode( "light aoe", NextAction::array(0, new NextAction("starfall", ACTION_NORMAL + 5), new NextAction("insect swarm on attacker", ACTION_NORMAL + 3), diff --git a/src/strategy/druid/DruidAiObjectContext.cpp b/src/strategy/druid/DruidAiObjectContext.cpp index fabd491b..a39fbc5b 100644 --- a/src/strategy/druid/DruidAiObjectContext.cpp +++ b/src/strategy/druid/DruidAiObjectContext.cpp @@ -164,6 +164,7 @@ public: creators["travel form"] = &DruidAiObjectContextInternal::travel_form; creators["aquatic form"] = &DruidAiObjectContextInternal::aquatic_form; creators["caster form"] = &DruidAiObjectContextInternal::caster_form; + creators["cancel tree form"] = &DruidAiObjectContextInternal::cancel_tree_form; creators["mangle (bear)"] = &DruidAiObjectContextInternal::mangle_bear; creators["maul"] = &DruidAiObjectContextInternal::maul; creators["bash"] = &DruidAiObjectContextInternal::bash; @@ -249,6 +250,7 @@ private: static Action* travel_form(PlayerbotAI* botAI) { return new CastTravelFormAction(botAI); } static Action* aquatic_form(PlayerbotAI* botAI) { return new CastAquaticFormAction(botAI); } static Action* caster_form(PlayerbotAI* botAI) { return new CastCasterFormAction(botAI); } + static Action* cancel_tree_form(PlayerbotAI* botAI) { return new CastCancelTreeFormAction(botAI); } static Action* mangle_bear(PlayerbotAI* botAI) { return new CastMangleBearAction(botAI); } static Action* maul(PlayerbotAI* botAI) { return new CastMaulAction(botAI); } static Action* bash(PlayerbotAI* botAI) { return new CastBashAction(botAI); } diff --git a/src/strategy/druid/DruidShapeshiftActions.cpp b/src/strategy/druid/DruidShapeshiftActions.cpp index 9894b1f5..4354328e 100644 --- a/src/strategy/druid/DruidShapeshiftActions.cpp +++ b/src/strategy/druid/DruidShapeshiftActions.cpp @@ -45,6 +45,17 @@ bool CastCasterFormAction::Execute(Event event) return true; } +bool CastCancelTreeFormAction::isUseful() +{ + return botAI->HasAura(33891, bot); +} + +bool CastCancelTreeFormAction::Execute(Event event) +{ + botAI->RemoveAura("tree of life"); + return true; +} + bool CastTreeFormAction::isUseful() { return GetTarget() && CastSpellAction::isUseful() && !botAI->HasAura(33891, bot); diff --git a/src/strategy/druid/DruidShapeshiftActions.h b/src/strategy/druid/DruidShapeshiftActions.h index 1f8fc082..6b24208b 100644 --- a/src/strategy/druid/DruidShapeshiftActions.h +++ b/src/strategy/druid/DruidShapeshiftActions.h @@ -70,4 +70,14 @@ public: bool Execute(Event event) override; }; +class CastCancelTreeFormAction : public CastBuffSpellAction +{ +public: + CastCancelTreeFormAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "cancel tree form") {} + + bool isUseful() override; + bool isPossible() override { return true; } + bool Execute(Event event) override; +}; + #endif diff --git a/src/strategy/druid/GenericDruidNonCombatStrategy.cpp b/src/strategy/druid/GenericDruidNonCombatStrategy.cpp index 398ba274..be5e822f 100644 --- a/src/strategy/druid/GenericDruidNonCombatStrategy.cpp +++ b/src/strategy/druid/GenericDruidNonCombatStrategy.cpp @@ -125,26 +125,34 @@ void GenericDruidNonCombatStrategy::InitTriggers(std::vector& trig triggers.push_back( new TriggerNode("party member critical health", - NextAction::array(0, new NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 5), - new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 6), NULL))); + NextAction::array(0, + new NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 7), + new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 6), + new NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 5), + nullptr))); triggers.push_back( new TriggerNode("party member low health", - NextAction::array(0, new NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 3), - new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 4), NULL))); + NextAction::array(0, + new NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 5), + new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 4), + new NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 3), + nullptr))); triggers.push_back( new TriggerNode("party member medium health", - NextAction::array(0, new NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 1), - new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 2), NULL))); + NextAction::array(0, new NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 3), + new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 2), + new NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 1), + nullptr))); triggers.push_back( new TriggerNode("party member almost full health", - NextAction::array(0, new NextAction("rejuvenation on party", ACTION_LIGHT_HEAL + 2), NULL))); + NextAction::array(0, new NextAction("wild growth on party", ACTION_LIGHT_HEAL + 3), new NextAction("rejuvenation on party", ACTION_LIGHT_HEAL + 2), NULL))); triggers.push_back( new TriggerNode("party member remove curse", - NextAction::array(0, new NextAction("remove curse on party", ACTION_DISPEL + 7), NULL))); + NextAction::array(0, new NextAction("remove curse on party", ACTION_DISPEL + 7), nullptr))); } GenericDruidBuffStrategy::GenericDruidBuffStrategy(PlayerbotAI* botAI) : NonCombatStrategy(botAI) diff --git a/src/strategy/druid/GenericDruidStrategy.cpp b/src/strategy/druid/GenericDruidStrategy.cpp index ccd3be5e..c3dacdb3 100644 --- a/src/strategy/druid/GenericDruidStrategy.cpp +++ b/src/strategy/druid/GenericDruidStrategy.cpp @@ -158,7 +158,15 @@ void DruidAssistDpsStrategy::InitTriggers(std::vector& triggers) triggers.push_back( new TriggerNode("healer should attack", NextAction::array(0, + new NextAction("cancel tree form", ACTION_DEFAULT + 0.3f), new NextAction("moonfire", ACTION_DEFAULT + 0.2f), new NextAction("wrath", ACTION_DEFAULT + 0.1f), + new NextAction("starfire", ACTION_DEFAULT), + nullptr))); + + triggers.push_back( + new TriggerNode("medium aoe and healer should attack", + NextAction::array(0, + new NextAction("hurricane", ACTION_DEFAULT + 0.7f), nullptr))); } diff --git a/src/strategy/druid/HealDruidStrategy.cpp b/src/strategy/druid/HealDruidStrategy.cpp index 8fb17f2c..b1a28c6e 100644 --- a/src/strategy/druid/HealDruidStrategy.cpp +++ b/src/strategy/druid/HealDruidStrategy.cpp @@ -12,9 +12,9 @@ class HealDruidStrategyActionNodeFactory : public NamedObjectFactory public: HealDruidStrategyActionNodeFactory() { creators["nourish on party"] = &nourtish_on_party; - creators["wild growth on party"] = &wild_growth_on_party; - creators["rejuvenation on party"] = &rejuvenation_on_party; - creators["regrowth on party"] = ®rowth_on_party; + // creators["wild growth on party"] = &wild_growth_on_party; + // creators["rejuvenation on party"] = &rejuvenation_on_party; + // creators["regrowth on party"] = ®rowth_on_party; } private: @@ -25,27 +25,27 @@ private: /*A*/ NextAction::array(0, new NextAction("healing touch on party"), nullptr), /*C*/ nullptr); } - static ActionNode* wild_growth_on_party([[maybe_unused]] PlayerbotAI* botAI) - { - return new ActionNode("wild growth on party", - /*P*/ NextAction::array(0, new NextAction("tree form"), nullptr), - /*A*/ nullptr, - /*C*/ nullptr); - } - static ActionNode* rejuvenation_on_party([[maybe_unused]] PlayerbotAI* botAI) - { - return new ActionNode("rejuvenation on party", - /*P*/ NextAction::array(0, new NextAction("tree form"), nullptr), - /*A*/ nullptr, - /*C*/ nullptr); - } - static ActionNode* regrowth_on_party([[maybe_unused]] PlayerbotAI* botAI) - { - return new ActionNode("regrowth on party", - /*P*/ NextAction::array(0, new NextAction("tree form"), nullptr), - /*A*/ nullptr, - /*C*/ nullptr); - } + // static ActionNode* wild_growth_on_party([[maybe_unused]] PlayerbotAI* botAI) + // { + // return new ActionNode("wild growth on party", + // /*P*/ NextAction::array(0, new NextAction("tree form"), nullptr), + // /*A*/ nullptr, + // /*C*/ nullptr); + // } + // static ActionNode* rejuvenation_on_party([[maybe_unused]] PlayerbotAI* botAI) + // { + // return new ActionNode("rejuvenation on party", + // /*P*/ NextAction::array(0, new NextAction("tree form"), nullptr), + // /*A*/ nullptr, + // /*C*/ nullptr); + // } + // static ActionNode* regrowth_on_party([[maybe_unused]] PlayerbotAI* botAI) + // { + // return new ActionNode("regrowth on party", + // /*P*/ NextAction::array(0, new NextAction("tree form"), nullptr), + // /*A*/ nullptr, + // /*C*/ nullptr); + // } }; HealDruidStrategy::HealDruidStrategy(PlayerbotAI* botAI) : GenericDruidStrategy(botAI) @@ -57,8 +57,6 @@ void HealDruidStrategy::InitTriggers(std::vector& triggers) { GenericDruidStrategy::InitTriggers(triggers); - // triggers.push_back(new TriggerNode("enemy out of spell", NextAction::array(0, new NextAction("reach spell", - // ACTION_NORMAL + 9), nullptr))); // triggers.push_back( // new TriggerNode("tree form", NextAction::array(0, new NextAction("tree form", ACTION_HIGH + 1), nullptr))); @@ -69,12 +67,14 @@ void HealDruidStrategy::InitTriggers(std::vector& triggers) // CRITICAL triggers.push_back( new TriggerNode("party member critical health", - NextAction::array(0, new NextAction("swiftmend on party", ACTION_CRITICAL_HEAL + 4), + NextAction::array(0, + new NextAction("tree form", ACTION_CRITICAL_HEAL + 4.1f), + new NextAction("swiftmend on party", ACTION_CRITICAL_HEAL + 4), new NextAction("wild growth on party", 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), - NULL))); + nullptr))); triggers.push_back( new TriggerNode("party member critical health", @@ -87,29 +87,32 @@ void HealDruidStrategy::InitTriggers(std::vector& triggers) // LOW triggers.push_back( new TriggerNode("party member low health", - NextAction::array(0, new NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 9), + NextAction::array(0, new NextAction("tree form", ACTION_MEDIUM_HEAL + 9.1f), + new NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 9), 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), - NULL))); + nullptr))); // MEDIUM triggers.push_back( new TriggerNode("party member medium health", - NextAction::array(0, new NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 4), + NextAction::array(0, + new NextAction("tree form", ACTION_MEDIUM_HEAL + 4.1f), + new NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 4), new NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 3), new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 2), - new NextAction("nourish on party", ACTION_MEDIUM_HEAL + 1), NULL))); + new NextAction("nourish on party", ACTION_MEDIUM_HEAL + 1), nullptr))); // almost full triggers.push_back( new TriggerNode("party member almost full health", NextAction::array(0, new NextAction("wild growth on party", ACTION_LIGHT_HEAL + 3), new NextAction("rejuvenation on party", ACTION_LIGHT_HEAL + 2), - new NextAction("regrowth on party", ACTION_LIGHT_HEAL + 1), NULL))); + new NextAction("regrowth on party", ACTION_LIGHT_HEAL + 1), nullptr))); triggers.push_back( - new TriggerNode("medium mana", NextAction::array(0, new NextAction("innervate", ACTION_HIGH + 5), NULL))); + new TriggerNode("medium mana", NextAction::array(0, new NextAction("innervate", ACTION_HIGH + 5), nullptr))); triggers.push_back(new TriggerNode("enemy too close for spell", NextAction::array(0, new NextAction("flee", ACTION_MOVE + 9), nullptr))); diff --git a/src/strategy/paladin/GenericPaladinNonCombatStrategy.cpp b/src/strategy/paladin/GenericPaladinNonCombatStrategy.cpp index 80e23cd3..d19320bd 100644 --- a/src/strategy/paladin/GenericPaladinNonCombatStrategy.cpp +++ b/src/strategy/paladin/GenericPaladinNonCombatStrategy.cpp @@ -22,7 +22,7 @@ void GenericPaladinNonCombatStrategy::InitTriggers(std::vector& tr triggers.push_back(new TriggerNode("party member almost full health", NextAction::array(0, new NextAction("flash of light on party", 25.0f), NULL))); triggers.push_back(new TriggerNode("party member medium health", - NextAction::array(0, new NextAction("holy light on party", 26.0f), NULL))); + NextAction::array(0, new NextAction("flash of light on party", 26.0f), NULL))); triggers.push_back(new TriggerNode("party member low health", NextAction::array(0, new NextAction("holy light on party", 27.0f), NULL))); triggers.push_back(new TriggerNode("party member critical health", diff --git a/src/strategy/paladin/GenericPaladinStrategy.cpp b/src/strategy/paladin/GenericPaladinStrategy.cpp index 791b5cff..09eb2074 100644 --- a/src/strategy/paladin/GenericPaladinStrategy.cpp +++ b/src/strategy/paladin/GenericPaladinStrategy.cpp @@ -77,10 +77,11 @@ void PaladinAssistDpsStrategy::InitTriggers(std::vector& triggers) triggers.push_back( new TriggerNode("healer should attack", NextAction::array(0, - new NextAction("hammer of wrath", ACTION_DEFAULT + 0.5f), - new NextAction("holy shock", ACTION_DEFAULT + 0.4f), - new NextAction("shield of righteousness", ACTION_DEFAULT + 0.3f), - new NextAction("judgement of light", ACTION_DEFAULT + 0.2f), - new NextAction("exorcism", ACTION_DEFAULT + 0.1f), + new NextAction("hammer of wrath", ACTION_DEFAULT + 0.6f), + new NextAction("holy shock", ACTION_DEFAULT + 0.5f), + new NextAction("shield of righteousness", ACTION_DEFAULT + 0.4f), + new NextAction("judgement of light", ACTION_DEFAULT + 0.3f), + new NextAction("consecration", ACTION_DEFAULT + 0.2f), + new NextAction("exorcism", ACTION_DEFAULT+ 0.1f), nullptr))); } diff --git a/src/strategy/priest/GenericPriestStrategy.cpp b/src/strategy/priest/GenericPriestStrategy.cpp index 42826fcd..fa680424 100644 --- a/src/strategy/priest/GenericPriestStrategy.cpp +++ b/src/strategy/priest/GenericPriestStrategy.cpp @@ -95,8 +95,8 @@ void PriestAssistDpsStrategy::InitTriggers(std::vector& triggers) NextAction::array(0, new NextAction("shadow word: pain", ACTION_DEFAULT + 0.5f), new NextAction("holy fire", ACTION_DEFAULT + 0.4f), - // new NextAction("mind blast", ACTION_DEFAULT + 0.3f), - new NextAction("smite", ACTION_DEFAULT + 0.1f), + new NextAction("smite", ACTION_DEFAULT + 0.3f), + new NextAction("mind blast", ACTION_DEFAULT + 0.2f), new NextAction("shoot", ACTION_DEFAULT), nullptr))); diff --git a/src/strategy/triggers/GenericTriggers.cpp b/src/strategy/triggers/GenericTriggers.cpp index 0adbc077..26572394 100644 --- a/src/strategy/triggers/GenericTriggers.cpp +++ b/src/strategy/triggers/GenericTriggers.cpp @@ -9,6 +9,8 @@ #include "BattlegroundWS.h" #include "CreatureAI.h" +#include "GameTime.h" +#include "LastSpellCastValue.h" #include "ObjectGuid.h" #include "PlayerbotAIConfig.h" #include "Playerbots.h" @@ -372,23 +374,28 @@ bool HealerShouldAttackTrigger::IsActive() if (botAI->GetNearGroupMemberCount(sPlayerbotAIConfig->sightDistance) <= 1) return true; - bool almostFullMana = AI_VALUE2(bool, "has mana", "self target") && - AI_VALUE2(uint8, "mana", "self target") < 85; - - // high pressure - if (AI_VALUE(uint8, "balance") <= 50 && almostFullMana) + if (AI_VALUE2(uint8, "health", "party member to heal") < sPlayerbotAIConfig->almostFullHealth) return false; - bool highMana = AI_VALUE2(bool, "has mana", "self target") && - AI_VALUE2(uint8, "mana", "self target") < sPlayerbotAIConfig->highMana; + // special check for resto druid (dont remove tree of life frequently) + if (bot->GetAura(33891)) + { + LastSpellCast& lastSpell = botAI->GetAiObjectContext()->GetValue("last spell cast")->Get(); + if (lastSpell.timer + 5 > time(nullptr)) + return false; + } - if (AI_VALUE(uint8, "balance") <= 100 && highMana) - return false; - - bool mediumMana = AI_VALUE2(bool, "has mana", "self target") && - AI_VALUE2(uint8, "mana", "self target") < sPlayerbotAIConfig->mediumMana; + int manaThreshold; + int balance = AI_VALUE(uint8, "balance"); + // higher threshold in higher pressure + if (balance <= 50) + manaThreshold = 85; + else if (balance <= 100) + manaThreshold = sPlayerbotAIConfig->highMana; + else + manaThreshold = sPlayerbotAIConfig->mediumMana; - if (mediumMana) + if (AI_VALUE2(bool, "has mana", "self target") && AI_VALUE2(uint8, "mana", "self target") < manaThreshold) return false; return true; diff --git a/src/strategy/warlock/GenericWarlockNonCombatStrategy.cpp b/src/strategy/warlock/GenericWarlockNonCombatStrategy.cpp index 7ed900cf..a46346fe 100644 --- a/src/strategy/warlock/GenericWarlockNonCombatStrategy.cpp +++ b/src/strategy/warlock/GenericWarlockNonCombatStrategy.cpp @@ -55,7 +55,7 @@ private: { return new ActionNode("summon felhunter", /*P*/ nullptr, - /*A*/ NextAction::array(0, new NextAction("summon voidwalker"), nullptr), + /*A*/ NextAction::array(0, new NextAction("summon succubus"), nullptr), /*C*/ nullptr); } static ActionNode* summon_felguard([[maybe_unused]] PlayerbotAI* botAI) From 55cd5ab923f737433a1bc8c9e4b954e6baacc7b1 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Fri, 4 Oct 2024 01:50:21 +0800 Subject: [PATCH 03/10] [AI] Remove reset after near teleport --- src/PlayerbotAI.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index 7b6b9887..a0a2c39b 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -703,8 +703,7 @@ void PlayerbotAI::HandleTeleportAck() p << (uint32)0; // supposed to be flags? not used currently p << (uint32)0; // time - not currently used bot->GetSession()->HandleMoveTeleportAck(p); - } - SetNextCheckDelay(urand(1000, 3000)); + }; } if (bot->IsBeingTeleportedFar()) { @@ -712,13 +711,13 @@ void PlayerbotAI::HandleTeleportAck() { bot->GetSession()->HandleMoveWorldportAck(); } - SetNextCheckDelay(urand(2000, 5000)); + // SetNextCheckDelay(urand(2000, 5000)); if (sPlayerbotAIConfig->applyInstanceStrategies) ApplyInstanceStrategies(bot->GetMapId(), true); + Reset(); } SetNextCheckDelay(sPlayerbotAIConfig->globalCoolDown); - Reset(); } void PlayerbotAI::Reset(bool full) @@ -1198,7 +1197,7 @@ void PlayerbotAI::HandleBotOutgoingPacket(WorldPacket const& packet) void PlayerbotAI::SpellInterrupted(uint32 spellid) { - for (uint8 type = CURRENT_MELEE_SPELL; type < CURRENT_CHANNELED_SPELL; type++) + for (uint8 type = CURRENT_MELEE_SPELL; type <= CURRENT_CHANNELED_SPELL; type++) { Spell* spell = bot->GetCurrentSpell((CurrentSpellTypes)type); if (!spell) @@ -1206,8 +1205,8 @@ void PlayerbotAI::SpellInterrupted(uint32 spellid) if (spell->GetSpellInfo()->Id == spellid) bot->InterruptSpell((CurrentSpellTypes)type); } - LastSpellCast& lastSpell = aiObjectContext->GetValue("last spell cast")->Get(); - lastSpell.id = 0; + // LastSpellCast& lastSpell = aiObjectContext->GetValue("last spell cast")->Get(); + // lastSpell.id = 0; } int32 PlayerbotAI::CalculateGlobalCooldown(uint32 spellid) From ff68a92fe944210e82196d571299a1f2b52954ef Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Fri, 4 Oct 2024 01:50:38 +0800 Subject: [PATCH 04/10] [Movement] Modify combat reach calculation --- src/strategy/actions/MovementActions.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/strategy/actions/MovementActions.cpp b/src/strategy/actions/MovementActions.cpp index e07fc79a..569d7fcc 100644 --- a/src/strategy/actions/MovementActions.cpp +++ b/src/strategy/actions/MovementActions.cpp @@ -827,11 +827,12 @@ bool MovementAction::ReachCombatTo(Unit* target, float distance) float shortenTo = distance; // Avoid walking too far when moving towards each other - if (bot->GetDistance(tx, ty, tz) >= 10.0f) - shortenTo = std::max(distance, bot->GetDistance(tx, ty, tz) / 2); + float disToGo = bot->GetExactDist(tx, ty, tz) - distance; + if (disToGo >= 10.0f) + shortenTo = disToGo / 2 + distance; - if (bot->GetExactDist(tx, ty, tz) <= shortenTo) - return false; + // if (bot->GetExactDist(tx, ty, tz) <= shortenTo) + // return false; path.ShortenPathUntilDist(G3D::Vector3(tx, ty, tz), shortenTo); G3D::Vector3 endPos = path.GetPath().back(); @@ -2313,7 +2314,7 @@ bool TankFaceAction::Execute(Event event) if (!bot->GetGroup()) return false; - if (!bot->IsWithinMeleeRange(target)) + if (!bot->IsWithinMeleeRange(target) || target->isMoving()) return false; if (!AI_VALUE2(bool, "has aggro", "current target")) @@ -2513,7 +2514,7 @@ bool SetBehindTargetAction::Execute(Event event) if (target->GetVictim() == bot) return false; - if (!bot->IsWithinMeleeRange(target)) + if (!bot->IsWithinMeleeRange(target) || target->isMoving()) return false; float deltaAngle = Position::NormalizeOrientation(target->GetOrientation() - target->GetAngle(bot)); From a0865cca140d5e610212bb8137a598fe9df41ca5 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Fri, 4 Oct 2024 14:14:00 +0800 Subject: [PATCH 05/10] [Spell] SpellInfo check on current spell --- src/PlayerbotAI.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PlayerbotAI.cpp b/src/PlayerbotAI.cpp index a0a2c39b..1200e050 100644 --- a/src/PlayerbotAI.cpp +++ b/src/PlayerbotAI.cpp @@ -317,13 +317,13 @@ void PlayerbotAI::UpdateAI(uint32 elapsed, bool minimal) Spell* currentSpell = bot->GetCurrentSpell(CURRENT_GENERIC_SPELL); if (!currentSpell) currentSpell = bot->GetCurrentSpell(CURRENT_CHANNELED_SPELL); - if (currentSpell && currentSpell->getState() == SPELL_STATE_PREPARING) + if (currentSpell && currentSpell->GetSpellInfo() && currentSpell->getState() == SPELL_STATE_PREPARING) { const SpellInfo* spellInfo = currentSpell->GetSpellInfo(); // interrupt if target is dead if (currentSpell->m_targets.GetUnitTarget() && !currentSpell->m_targets.GetUnitTarget()->IsAlive() && - spellInfo && !spellInfo->IsAllowingDeadTarget()) + !spellInfo->IsAllowingDeadTarget()) { InterruptSpell(); SetNextCheckDelay(sPlayerbotAIConfig->reactDelay); From 37c5c1dcdf2e759db49c02182a105917632e2fec Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Fri, 4 Oct 2024 14:38:09 +0800 Subject: [PATCH 06/10] [Spell] Fix alternative healing spell --- src/strategy/druid/HealDruidStrategy.cpp | 4 ++-- src/strategy/priest/HealPriestStrategy.cpp | 19 ++++++++----------- src/strategy/priest/HolyPriestStrategy.cpp | 16 ++++++++-------- src/strategy/priest/PriestActions.h | 9 ++++++++- src/strategy/priest/PriestAiObjectContext.cpp | 2 +- .../priest/PriestNonCombatStrategy.cpp | 2 +- ...PriestNonCombatStrategyActionNodeFactory.h | 4 ++-- src/strategy/shaman/GenericShamanStrategy.cpp | 8 ++++---- src/strategy/shaman/HealShamanStrategy.cpp | 4 ++-- src/strategy/shaman/ShamanActions.h | 4 ++-- src/strategy/shaman/ShamanAiObjectContext.cpp | 2 +- .../shaman/ShamanNonCombatStrategy.cpp | 2 +- src/strategy/triggers/TriggerContext.h | 4 ++-- 13 files changed, 42 insertions(+), 38 deletions(-) diff --git a/src/strategy/druid/HealDruidStrategy.cpp b/src/strategy/druid/HealDruidStrategy.cpp index b1a28c6e..ec33dea3 100644 --- a/src/strategy/druid/HealDruidStrategy.cpp +++ b/src/strategy/druid/HealDruidStrategy.cpp @@ -78,11 +78,11 @@ void HealDruidStrategy::InitTriggers(std::vector& triggers) triggers.push_back( new TriggerNode("party member critical health", - NextAction::array(0, new NextAction("nature's swiftness", ACTION_CRITICAL_HEAL + 4), NULL))); + NextAction::array(0, new NextAction("nature's swiftness", ACTION_CRITICAL_HEAL + 4), nullptr))); triggers.push_back( new TriggerNode("medium group heal occasion", - NextAction::array(0, new NextAction("tranquility", ACTION_CRITICAL_HEAL + 5), NULL))); + NextAction::array(0, new NextAction("tranquility", ACTION_CRITICAL_HEAL + 5), nullptr))); // LOW triggers.push_back( diff --git a/src/strategy/priest/HealPriestStrategy.cpp b/src/strategy/priest/HealPriestStrategy.cpp index 25f8e8bd..52c12df6 100644 --- a/src/strategy/priest/HealPriestStrategy.cpp +++ b/src/strategy/priest/HealPriestStrategy.cpp @@ -29,15 +29,14 @@ void HealPriestStrategy::InitTriggers(std::vector& triggers) // triggers.push_back(new TriggerNode( // "medium aoe heal", // NextAction::array(0, - // new NextAction("circle of healing", ACTION_MEDIUM_HEAL + 8), + // new NextAction("circle of healing on party", ACTION_MEDIUM_HEAL + 8), // // new NextAction("power word: shield on almost full health below", ACTION_MEDIUM_HEAL + 7), // NULL))); triggers.push_back(new TriggerNode( - "group heal occasion", - NextAction::array(0, new NextAction("circle of healing", ACTION_MEDIUM_HEAL + 8), - new NextAction("power word: shield on almost full health below", ACTION_MEDIUM_HEAL + 7), - NULL))); + "group heal setting", + NextAction::array(0, new NextAction("power word: shield on almost full health below", ACTION_MEDIUM_HEAL + 7), + nullptr))); triggers.push_back(new TriggerNode( "medium group heal occasion", @@ -49,25 +48,23 @@ void HealPriestStrategy::InitTriggers(std::vector& triggers) NextAction::array(0, new NextAction("power word: shield on party", ACTION_CRITICAL_HEAL + 6), new NextAction("penance on party", ACTION_CRITICAL_HEAL + 4), new NextAction("flash heal on party", ACTION_CRITICAL_HEAL + 3), - new NextAction("prayer of mending on party", ACTION_CRITICAL_HEAL + 2), NULL))); + new NextAction("prayer of mending on party", ACTION_CRITICAL_HEAL + 2), nullptr))); triggers.push_back( new TriggerNode("party member low health", NextAction::array(0, new NextAction("power word: shield on party", ACTION_MEDIUM_HEAL + 4), new NextAction("penance on party", ACTION_MEDIUM_HEAL + 2), - new NextAction("circle of healing", ACTION_MEDIUM_HEAL + 2), new NextAction("prayer of mending on party", ACTION_MEDIUM_HEAL + 1), - new NextAction("flash heal on party", ACTION_MEDIUM_HEAL + 0), NULL))); + new NextAction("flash heal on party", ACTION_MEDIUM_HEAL + 0), nullptr))); triggers.push_back( new TriggerNode("party member medium health", NextAction::array(0, new NextAction("power word: shield on party", ACTION_LIGHT_HEAL + 9), new NextAction("penance on party", ACTION_LIGHT_HEAL + 7), - new NextAction("circle of healing", ACTION_LIGHT_HEAL + 7), new NextAction("prayer of mending on party", ACTION_LIGHT_HEAL + 6), new NextAction("flash heal on party", ACTION_LIGHT_HEAL + 5), // new NextAction("renew on party", ACTION_LIGHT_HEAL + 8), - NULL))); + nullptr))); triggers.push_back( new TriggerNode("party member almost full health", @@ -86,7 +83,7 @@ void HealPriestStrategy::InitTriggers(std::vector& triggers) NextAction::array(0, new NextAction("reach party member to heal", ACTION_CRITICAL_HEAL + 10), nullptr))); // triggers.push_back(new TriggerNode("medium aoe heal", NextAction::array(0, new NextAction("prayer of // mending", 49.0f), nullptr))); triggers.push_back(new TriggerNode("medium aoe heal", NextAction::array(0, new - // NextAction("circle of healing", 48.0f), nullptr))); triggers.push_back(new TriggerNode("binding heal", + // NextAction("circle of healing on party", 48.0f), nullptr))); triggers.push_back(new TriggerNode("binding heal", // NextAction::array(0, new NextAction("binding heal", 52.0f), nullptr))); triggers.push_back(new TriggerNode("low // mana", NextAction::array(0, new NextAction("shadowfiend", ACTION_HIGH), nullptr))); diff --git a/src/strategy/priest/HolyPriestStrategy.cpp b/src/strategy/priest/HolyPriestStrategy.cpp index 40f34a28..de29d7ea 100644 --- a/src/strategy/priest/HolyPriestStrategy.cpp +++ b/src/strategy/priest/HolyPriestStrategy.cpp @@ -63,8 +63,8 @@ void HolyHealPriestStrategy::InitTriggers(std::vector& triggers) GenericPriestStrategy::InitTriggers(triggers); triggers.push_back( - new TriggerNode("group heal occasion", - NextAction::array(0, new NextAction("circle of healing", ACTION_MEDIUM_HEAL + 8), NULL))); + new TriggerNode("group heal setting", + NextAction::array(0, new NextAction("circle of healing on party", ACTION_MEDIUM_HEAL + 8), nullptr))); triggers.push_back(new TriggerNode( "medium group heal occasion", @@ -77,28 +77,28 @@ void HolyHealPriestStrategy::InitTriggers(std::vector& triggers) new NextAction("guardian spirit on party", ACTION_CRITICAL_HEAL + 6), new NextAction("power word: shield on party", ACTION_CRITICAL_HEAL + 5), new NextAction("flash heal on party", ACTION_CRITICAL_HEAL + 3), - new NextAction("prayer of mending on party", ACTION_CRITICAL_HEAL + 2), NULL))); + new NextAction("prayer of mending on party", ACTION_CRITICAL_HEAL + 2), nullptr))); triggers.push_back( new TriggerNode("party member low health", - NextAction::array(0, new NextAction("circle of healing", ACTION_MEDIUM_HEAL + 4), + NextAction::array(0, new NextAction("circle of healing on party", ACTION_MEDIUM_HEAL + 4), new NextAction("greater heal on party", ACTION_MEDIUM_HEAL + 3), new NextAction("prayer of mending on party", ACTION_MEDIUM_HEAL + 2), - new NextAction("flash heal on party", ACTION_MEDIUM_HEAL + 1), NULL))); + new NextAction("flash heal on party", ACTION_MEDIUM_HEAL + 1), nullptr))); triggers.push_back( new TriggerNode("party member medium health", - NextAction::array(0, new NextAction("circle of healing", ACTION_LIGHT_HEAL + 7), + NextAction::array(0, new NextAction("circle of healing on party", ACTION_LIGHT_HEAL + 7), new NextAction("prayer of mending on party", ACTION_LIGHT_HEAL + 6), new NextAction("flash heal on party", ACTION_LIGHT_HEAL + 5), // new NextAction("renew on party", ACTION_LIGHT_HEAL + 8), - NULL))); + nullptr))); triggers.push_back( new TriggerNode("party member almost full health", NextAction::array(0, new NextAction("renew on party", ACTION_LIGHT_HEAL + 2), // new NextAction("flash heal on party", ACTION_LIGHT_HEAL + 1), - NULL))); + nullptr))); triggers.push_back(new TriggerNode( "party member to heal out of spell range", diff --git a/src/strategy/priest/PriestActions.h b/src/strategy/priest/PriestActions.h index d5af0509..bffea2bc 100644 --- a/src/strategy/priest/PriestActions.h +++ b/src/strategy/priest/PriestActions.h @@ -55,7 +55,14 @@ HEAL_PARTY_ACTION(CastRenewOnPartyAction, "renew", 15.0f, HealingManaEfficiency: HEAL_PARTY_ACTION(CastPrayerOfMendingAction, "prayer of mending", 15.0f, HealingManaEfficiency::MEDIUM); HEAL_PARTY_ACTION(CastBindingHealAction, "binding heal", 15.0f, HealingManaEfficiency::MEDIUM); HEAL_PARTY_ACTION(CastPrayerOfHealingAction, "prayer of healing", 15.0f, HealingManaEfficiency::MEDIUM); -AOE_HEAL_ACTION(CastCircleOfHealingAction, "circle of healing", 15.0f, HealingManaEfficiency::HIGH); +// AOE_HEAL_ACTION(CastCircleOfHealingAction, "circle of healing", 15.0f, HealingManaEfficiency::HIGH); +class CastCircleOfHealingAction : public HealPartyMemberAction +{ +public: + CastCircleOfHealingAction(PlayerbotAI* ai) : HealPartyMemberAction(ai, "circle of healing", 15.0f, HealingManaEfficiency::HIGH) + { + } +}; AOE_HEAL_ACTION(CastLightwellAction, "lightwell", 15.0f, HealingManaEfficiency::MEDIUM); SPELL_ACTION(CastSmiteAction, "smite"); diff --git a/src/strategy/priest/PriestAiObjectContext.cpp b/src/strategy/priest/PriestAiObjectContext.cpp index caf4eb79..d6c59233 100644 --- a/src/strategy/priest/PriestAiObjectContext.cpp +++ b/src/strategy/priest/PriestAiObjectContext.cpp @@ -195,7 +195,7 @@ public: creators["fade"] = &PriestAiObjectContextInternal::fade; creators["inner fire"] = &PriestAiObjectContextInternal::inner_fire; creators["resurrection"] = &PriestAiObjectContextInternal::resurrection; - creators["circle of healing"] = &PriestAiObjectContextInternal::circle_of_healing; + creators["circle of healing on party"] = &PriestAiObjectContextInternal::circle_of_healing; creators["psychic scream"] = &PriestAiObjectContextInternal::psychic_scream; creators["vampiric touch"] = &PriestAiObjectContextInternal::vampiric_touch; creators["vampiric touch on attacker"] = &PriestAiObjectContextInternal::vampiric_touch_on_attacker; diff --git a/src/strategy/priest/PriestNonCombatStrategy.cpp b/src/strategy/priest/PriestNonCombatStrategy.cpp index 5283fb75..be596054 100644 --- a/src/strategy/priest/PriestNonCombatStrategy.cpp +++ b/src/strategy/priest/PriestNonCombatStrategy.cpp @@ -55,7 +55,7 @@ void PriestNonCombatStrategy::InitTriggers(std::vector& triggers) NextAction::array(0, new NextAction("renew on party", ACTION_LIGHT_HEAL + 3), NULL))); triggers.push_back( - new TriggerNode("group heal occasion", NextAction::array(0, new NextAction("circle of healing", 27.0f), NULL))); + new TriggerNode("group heal setting", NextAction::array(0, new NextAction("circle of healing on party", 27.0f), NULL))); } void PriestBuffStrategy::InitTriggers(std::vector& triggers) diff --git a/src/strategy/priest/PriestNonCombatStrategyActionNodeFactory.h b/src/strategy/priest/PriestNonCombatStrategyActionNodeFactory.h index 84318fcb..c1084610 100644 --- a/src/strategy/priest/PriestNonCombatStrategyActionNodeFactory.h +++ b/src/strategy/priest/PriestNonCombatStrategyActionNodeFactory.h @@ -29,7 +29,7 @@ public: creators["lesser heal on party"] = &lesser_heal_on_party; creators["flash heal"] = &flash_heal; creators["flash heal on party"] = &flash_heal_on_party; - creators["circle of healing"] = &circle_of_healing; + creators["circle of healing on party"] = &circle_of_healing; creators["prayer of fortitude on party"] = &prayer_of_fortitude_on_party; creators["prayer of spirit on party"] = &prayer_of_spirit_on_party; } @@ -128,7 +128,7 @@ private: } static ActionNode* circle_of_healing(PlayerbotAI* ai) { - return new ActionNode("circle of healing", + return new ActionNode("circle of healing on party", /*P*/ NextAction::array(0, new NextAction("remove shadowform"), NULL), // /*A*/ NextAction::array(0, new NextAction("flash heal on party"), NULL), /*A*/ NULL, diff --git a/src/strategy/shaman/GenericShamanStrategy.cpp b/src/strategy/shaman/GenericShamanStrategy.cpp index d84b07a7..430a1bdc 100644 --- a/src/strategy/shaman/GenericShamanStrategy.cpp +++ b/src/strategy/shaman/GenericShamanStrategy.cpp @@ -18,7 +18,7 @@ public: creators["windfury weapon"] = &windfury_weapon; creators["lesser healing wave"] = &lesser_healing_wave; creators["lesser healing wave on party"] = &lesser_healing_wave_on_party; - creators["chain heal"] = &chain_heal; + creators["chain heal on party"] = &chain_heal; creators["riptide"] = &riptide; creators["riptide on party"] = &riptide_on_party; creators["earth shock"] = &earth_shock; @@ -75,9 +75,9 @@ private: static ActionNode* chain_heal([[maybe_unused]] PlayerbotAI* botAI) { - return new ActionNode("chain heal", + return new ActionNode("chain heal on party", /*P*/ nullptr, - /*A*/ NextAction::array(0, new NextAction("lesser healing wave"), nullptr), + /*A*/ NextAction::array(0, new NextAction("lesser healing wave on party"), nullptr), /*C*/ nullptr); } @@ -117,7 +117,7 @@ void GenericShamanStrategy::InitTriggers(std::vector& triggers) // triggers.push_back(new TriggerNode("party member medium health", NextAction::array(0, new NextAction("lesser // healing wave on party", 25.0f), nullptr))); triggers.push_back(new TriggerNode("party member low health", // NextAction::array(0, new NextAction("riptide on party", 25.0f), nullptr))); triggers.push_back(new - // TriggerNode("medium aoe heal", NextAction::array(0, new NextAction("chain heal", 27.0f), nullptr))); + // TriggerNode("medium aoe heal", NextAction::array(0, new NextAction("chain heal on party", 27.0f), nullptr))); // triggers.push_back(new TriggerNode("medium health", NextAction::array(0, new NextAction("lesser healing // wave", 26.0f), nullptr))); triggers.push_back(new TriggerNode("low health", NextAction::array(0, new // NextAction("riptide", 26.0f), nullptr))); diff --git a/src/strategy/shaman/HealShamanStrategy.cpp b/src/strategy/shaman/HealShamanStrategy.cpp index ff305559..17d4ff44 100644 --- a/src/strategy/shaman/HealShamanStrategy.cpp +++ b/src/strategy/shaman/HealShamanStrategy.cpp @@ -49,8 +49,8 @@ void HealShamanStrategy::InitTriggers(std::vector& triggers) triggers.push_back(new TriggerNode("main hand weapon no imbue", NextAction::array(0, new NextAction("earthliving weapon", 22.0f), nullptr))); triggers.push_back(new TriggerNode( - "group heal occasion", - NextAction::array(0, new NextAction("riptide on party", 23.0f), new NextAction("chain heal", 22.0f), NULL))); + "group heal setting", + NextAction::array(0, new NextAction("riptide on party", 23.0f), new NextAction("chain heal on party", 22.0f), NULL))); triggers.push_back(new TriggerNode( "party member critical health", diff --git a/src/strategy/shaman/ShamanActions.h b/src/strategy/shaman/ShamanActions.h index 9d3b8b69..2d110e51 100644 --- a/src/strategy/shaman/ShamanActions.h +++ b/src/strategy/shaman/ShamanActions.h @@ -42,11 +42,11 @@ public: } }; -class CastChainHealAction : public CastAoeHealSpellAction +class CastChainHealAction : public HealPartyMemberAction { public: CastChainHealAction(PlayerbotAI* botAI) - : CastAoeHealSpellAction(botAI, "chain heal", 15.0f, HealingManaEfficiency::HIGH) + : HealPartyMemberAction(botAI, "chain heal", 15.0f, HealingManaEfficiency::HIGH) { } }; diff --git a/src/strategy/shaman/ShamanAiObjectContext.cpp b/src/strategy/shaman/ShamanAiObjectContext.cpp index bf9e76e3..193d292a 100644 --- a/src/strategy/shaman/ShamanAiObjectContext.cpp +++ b/src/strategy/shaman/ShamanAiObjectContext.cpp @@ -210,7 +210,7 @@ public: creators["lesser healing wave on party"] = &ShamanAiObjectContextInternal::lesser_healing_wave_on_party; creators["earth shield"] = &ShamanAiObjectContextInternal::earth_shield; creators["earth shield on party"] = &ShamanAiObjectContextInternal::earth_shield_on_party; - creators["chain heal"] = &ShamanAiObjectContextInternal::chain_heal; + creators["chain heal on party"] = &ShamanAiObjectContextInternal::chain_heal; creators["riptide"] = &ShamanAiObjectContextInternal::riptide; creators["riptide on party"] = &ShamanAiObjectContextInternal::riptide_on_party; creators["stormstrike"] = &ShamanAiObjectContextInternal::stormstrike; diff --git a/src/strategy/shaman/ShamanNonCombatStrategy.cpp b/src/strategy/shaman/ShamanNonCombatStrategy.cpp index f3380cb5..ad4dcb82 100644 --- a/src/strategy/shaman/ShamanNonCombatStrategy.cpp +++ b/src/strategy/shaman/ShamanNonCombatStrategy.cpp @@ -39,7 +39,7 @@ void ShamanNonCombatStrategy::InitTriggers(std::vector& triggers) new NextAction("lesser healing wave on party", 24.0f), NULL))); triggers.push_back( - new TriggerNode("group heal occasion", NextAction::array(0, new NextAction("chain heal", 27.0f), NULL))); + new TriggerNode("group heal setting", NextAction::array(0, new NextAction("chain heal on party", 27.0f), NULL))); triggers.push_back( new TriggerNode("cure poison", NextAction::array(0, new NextAction("cure poison", 21.0f), nullptr))); diff --git a/src/strategy/triggers/TriggerContext.h b/src/strategy/triggers/TriggerContext.h index 4bfea1d4..7baebc8d 100644 --- a/src/strategy/triggers/TriggerContext.h +++ b/src/strategy/triggers/TriggerContext.h @@ -139,7 +139,7 @@ public: creators["medium aoe heal"] = &TriggerContext::medium_aoe_heal; creators["almost full aoe heal"] = &TriggerContext::almost_full_aoe_heal; - creators["group heal occasion"] = &TriggerContext::group_heal_occasion; + creators["group heal setting"] = &TriggerContext::group_heal_occasion; creators["medium group heal occasion"] = &TriggerContext::medium_group_heal_occasion; creators["invalid target"] = &TriggerContext::invalid_target; creators["lfg proposal active"] = &TriggerContext::lfg_proposal_active; @@ -246,7 +246,7 @@ private: } static Trigger* group_heal_occasion(PlayerbotAI* ai) { - return new AoeInGroupTrigger(ai, "group heal occasion", "almost full"); + return new AoeInGroupTrigger(ai, "group heal setting", "almost full"); } static Trigger* medium_group_heal_occasion(PlayerbotAI* ai) { From db9b1115cb9de5f0cebbd8caad11ded1bd13b700 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Fri, 4 Oct 2024 18:56:44 +0800 Subject: [PATCH 07/10] [Spell] Priest prayer of mending buff owner --- src/strategy/priest/PriestActions.cpp | 35 +++++++++++++++++++++++++-- src/strategy/priest/PriestActions.h | 23 +++++++++++++++--- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/src/strategy/priest/PriestActions.cpp b/src/strategy/priest/PriestActions.cpp index 3a94dafc..2364a5e2 100644 --- a/src/strategy/priest/PriestActions.cpp +++ b/src/strategy/priest/PriestActions.cpp @@ -18,7 +18,7 @@ bool CastRemoveShadowformAction::Execute(Event event) return true; } -Unit* CastPowerWordShieldOnAlmostFullHealthBelow::GetTarget() +Unit* CastPowerWordShieldOnAlmostFullHealthBelowAction::GetTarget() { Group* group = bot->GetGroup(); for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next()) @@ -47,7 +47,7 @@ Unit* CastPowerWordShieldOnAlmostFullHealthBelow::GetTarget() return nullptr; } -bool CastPowerWordShieldOnAlmostFullHealthBelow::isUseful() +bool CastPowerWordShieldOnAlmostFullHealthBelowAction::isUseful() { Group* group = bot->GetGroup(); for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next()) @@ -74,4 +74,35 @@ bool CastPowerWordShieldOnAlmostFullHealthBelow::isUseful() return true; } return false; +} + +Unit* CastPowerWordShieldOnNotFullAction::GetTarget() +{ + Group* group = bot->GetGroup(); + MinValueCalculator calc(100); + for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next()) + { + Player* player = gref->GetSource(); + if (!player) + continue; + if (player->isDead() || player->IsFullHealth()) + { + continue; + } + if (player->GetDistance2d(bot) > sPlayerbotAIConfig->spellDistance) + { + continue; + } + if (botAI->HasAnyAuraOf(player, "weakened soul", "power word: shield", nullptr)) + { + continue; + } + calc.probe(player->GetHealthPct(), player); + } + return (Unit*)calc.param; +} + +bool CastPowerWordShieldOnNotFullAction::isUseful() +{ + return GetTarget(); } \ No newline at end of file diff --git a/src/strategy/priest/PriestActions.h b/src/strategy/priest/PriestActions.h index bffea2bc..c84bfc7d 100644 --- a/src/strategy/priest/PriestActions.h +++ b/src/strategy/priest/PriestActions.h @@ -52,7 +52,13 @@ HEAL_PARTY_ACTION(CastGreaterHealOnPartyAction, "greater heal", 50.0f, HealingMa HEAL_PARTY_ACTION(CastPowerWordShieldOnPartyAction, "power word: shield", 15.0f, HealingManaEfficiency::VERY_HIGH); HEAL_PARTY_ACTION(CastFlashHealOnPartyAction, "flash heal", 15.0f, HealingManaEfficiency::LOW); HEAL_PARTY_ACTION(CastRenewOnPartyAction, "renew", 15.0f, HealingManaEfficiency::VERY_HIGH); -HEAL_PARTY_ACTION(CastPrayerOfMendingAction, "prayer of mending", 15.0f, HealingManaEfficiency::MEDIUM); +// HEAL_PARTY_ACTION(CastPrayerOfMendingAction, "prayer of mending", 10.0f, HealingManaEfficiency::HIGH); +class CastPrayerOfMendingAction : public HealPartyMemberAction +{ +public: + CastPrayerOfMendingAction(PlayerbotAI* botAI) : HealPartyMemberAction(botAI, "prayer of mending", 10.0f, HealingManaEfficiency::HIGH, false) {} +}; + HEAL_PARTY_ACTION(CastBindingHealAction, "binding heal", 15.0f, HealingManaEfficiency::MEDIUM); HEAL_PARTY_ACTION(CastPrayerOfHealingAction, "prayer of healing", 15.0f, HealingManaEfficiency::MEDIUM); // AOE_HEAL_ACTION(CastCircleOfHealingAction, "circle of healing", 15.0f, HealingManaEfficiency::HIGH); @@ -169,10 +175,10 @@ public: virtual std::string const GetTargetName() { return "current target"; } }; -class CastPowerWordShieldOnAlmostFullHealthBelow : public HealPartyMemberAction +class CastPowerWordShieldOnAlmostFullHealthBelowAction : public HealPartyMemberAction { public: - CastPowerWordShieldOnAlmostFullHealthBelow(PlayerbotAI* ai) + CastPowerWordShieldOnAlmostFullHealthBelowAction(PlayerbotAI* ai) : HealPartyMemberAction(ai, "power word: shield", 15.0f, HealingManaEfficiency::HIGH) { } @@ -180,6 +186,17 @@ public: Unit* GetTarget() override; }; +class CastPowerWordShieldOnNotFullAction : public HealPartyMemberAction +{ +public: + CastPowerWordShieldOnNotFullAction(PlayerbotAI* ai) + : HealPartyMemberAction(ai, "power word: shield", 5.0f, HealingManaEfficiency::HIGH) + { + } + bool isUseful() override; + Unit* GetTarget() override; +}; + class CastMindSearAction : public CastSpellAction { public: From 21e17e163bba6bfd068ab4599518bafaf41c50b1 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Fri, 4 Oct 2024 20:48:29 +0800 Subject: [PATCH 08/10] [Spell] Healer spell enhancement --- src/strategy/Engine.cpp | 8 ++-- src/strategy/actions/GenericActions.cpp | 2 +- src/strategy/actions/GenericSpellActions.cpp | 4 +- src/strategy/actions/GenericSpellActions.h | 6 +-- src/strategy/druid/DruidActions.cpp | 31 +++++++++++++ src/strategy/druid/DruidActions.h | 12 +++++ src/strategy/druid/DruidAiObjectContext.cpp | 2 + src/strategy/druid/GenericDruidStrategy.cpp | 11 ++--- src/strategy/druid/HealDruidStrategy.cpp | 44 ++++++++++++------- src/strategy/paladin/HealPaladinStrategy.cpp | 2 +- src/strategy/paladin/TankPaladinStrategy.cpp | 2 +- src/strategy/priest/HealPriestStrategy.cpp | 30 ++++++++----- src/strategy/priest/HolyPriestStrategy.cpp | 30 ++++++++----- src/strategy/priest/PriestAiObjectContext.cpp | 8 +++- src/strategy/triggers/TriggerContext.h | 4 +- 15 files changed, 137 insertions(+), 59 deletions(-) diff --git a/src/strategy/Engine.cpp b/src/strategy/Engine.cpp index d298aaf5..a9569a20 100644 --- a/src/strategy/Engine.cpp +++ b/src/strategy/Engine.cpp @@ -202,9 +202,9 @@ bool Engine::DoNextAction(Unit* unit, uint32 depth, bool minimal) { LogAction("A:%s - PREREQ", action->getName().c_str()); - if (MultiplyAndPush(actionNode->getPrerequisites(), relevance + 0.02, false, event, "prereq")) + if (MultiplyAndPush(actionNode->getPrerequisites(), relevance + 0.002f, false, event, "prereq")) { - PushAgain(actionNode, relevance + 0.01, event); + PushAgain(actionNode, relevance + 0.001f, event); continue; } } @@ -226,7 +226,7 @@ bool Engine::DoNextAction(Unit* unit, uint32 depth, bool minimal) else { LogAction("A:%s - FAILED", action->getName().c_str()); - MultiplyAndPush(actionNode->getAlternatives(), relevance + 0.03, false, event, "alt"); + MultiplyAndPush(actionNode->getAlternatives(), relevance + 0.003f, false, event, "alt"); } } else @@ -246,7 +246,7 @@ bool Engine::DoNextAction(Unit* unit, uint32 depth, bool minimal) botAI->TellMasterNoFacing(out); } LogAction("A:%s - IMPOSSIBLE", action->getName().c_str()); - MultiplyAndPush(actionNode->getAlternatives(), relevance + 0.03, false, event, "alt"); + MultiplyAndPush(actionNode->getAlternatives(), relevance + 0.003f, false, event, "alt"); } } else diff --git a/src/strategy/actions/GenericActions.cpp b/src/strategy/actions/GenericActions.cpp index 9682d2ef..84997212 100644 --- a/src/strategy/actions/GenericActions.cpp +++ b/src/strategy/actions/GenericActions.cpp @@ -38,7 +38,7 @@ bool TogglePetSpellAutoCastAction::Execute(Event event) bool shouldApply = true; // imp's spell, felhunte's intelligence, cat stealth if (spellId == 4511 || spellId == 1742 || spellId == 54424 || spellId == 57564 || spellId == 57565 || - spellId == 57566 || spellId == 57567 || spellId == 24450 || spellId == 53477) + spellId == 57566 || spellId == 57567 || spellId == 24450) { shouldApply = false; } diff --git a/src/strategy/actions/GenericSpellActions.cpp b/src/strategy/actions/GenericSpellActions.cpp index 9285f20a..749bed14 100644 --- a/src/strategy/actions/GenericSpellActions.cpp +++ b/src/strategy/actions/GenericSpellActions.cpp @@ -196,8 +196,8 @@ bool CastEnchantItemAction::isPossible() } CastHealingSpellAction::CastHealingSpellAction(PlayerbotAI* botAI, std::string const spell, uint8 estAmount, - HealingManaEfficiency manaEfficiency) - : CastAuraSpellAction(botAI, spell, true), estAmount(estAmount), manaEfficiency(manaEfficiency) + HealingManaEfficiency manaEfficiency, bool isOwner) + : CastAuraSpellAction(botAI, spell, isOwner), estAmount(estAmount), manaEfficiency(manaEfficiency) { range = botAI->GetRange("heal"); } diff --git a/src/strategy/actions/GenericSpellActions.h b/src/strategy/actions/GenericSpellActions.h index 2ab49bb0..be1dc200 100644 --- a/src/strategy/actions/GenericSpellActions.h +++ b/src/strategy/actions/GenericSpellActions.h @@ -129,7 +129,7 @@ class CastHealingSpellAction : public CastAuraSpellAction { public: CastHealingSpellAction(PlayerbotAI* botAI, std::string const spell, uint8 estAmount = 15.0f, - HealingManaEfficiency manaEfficiency = HealingManaEfficiency::MEDIUM); + HealingManaEfficiency manaEfficiency = HealingManaEfficiency::MEDIUM, bool isOwner = true); std::string const GetTargetName() override { return "self target"; } bool isUseful() override; @@ -177,8 +177,8 @@ class HealPartyMemberAction : public CastHealingSpellAction, public PartyMemberA { public: HealPartyMemberAction(PlayerbotAI* botAI, std::string const spell, uint8 estAmount = 15.0f, - HealingManaEfficiency manaEfficiency = HealingManaEfficiency::MEDIUM) - : CastHealingSpellAction(botAI, spell, estAmount, manaEfficiency), PartyMemberActionNameSupport(spell) + HealingManaEfficiency manaEfficiency = HealingManaEfficiency::MEDIUM, bool isOwner = true) + : CastHealingSpellAction(botAI, spell, estAmount, manaEfficiency, isOwner), PartyMemberActionNameSupport(spell) { } diff --git a/src/strategy/druid/DruidActions.cpp b/src/strategy/druid/DruidActions.cpp index 739ac941..1743a339 100644 --- a/src/strategy/druid/DruidActions.cpp +++ b/src/strategy/druid/DruidActions.cpp @@ -47,4 +47,35 @@ bool CastRebirthAction::isUseful() { return CastSpellAction::isUseful() && AI_VALUE2(float, "distance", GetTargetName()) <= sPlayerbotAIConfig->spellDistance; +} + +Unit* CastRejuvenationOnNotFullAction::GetTarget() +{ + Group* group = bot->GetGroup(); + MinValueCalculator calc(100); + for (GroupReference* gref = group->GetFirstMember(); gref; gref = gref->next()) + { + Player* player = gref->GetSource(); + if (!player) + continue; + if (player->isDead() || player->IsFullHealth()) + { + continue; + } + if (player->GetDistance2d(bot) > sPlayerbotAIConfig->spellDistance) + { + continue; + } + if (botAI->HasAura("rejuvenation", player)) + { + continue; + } + calc.probe(player->GetHealthPct(), player); + } + return (Unit*)calc.param; +} + +bool CastRejuvenationOnNotFullAction::isUseful() +{ + return GetTarget(); } \ No newline at end of file diff --git a/src/strategy/druid/DruidActions.h b/src/strategy/druid/DruidActions.h index 749ba3ea..ee90788a 100644 --- a/src/strategy/druid/DruidActions.h +++ b/src/strategy/druid/DruidActions.h @@ -311,4 +311,16 @@ public: CastEnrageAction(PlayerbotAI* ai) : CastBuffSpellAction(ai, "enrage") {} }; + +class CastRejuvenationOnNotFullAction : public HealPartyMemberAction +{ +public: + CastRejuvenationOnNotFullAction(PlayerbotAI* ai) + : HealPartyMemberAction(ai, "rejuvenation", 5.0f, HealingManaEfficiency::VERY_HIGH) + { + } + bool isUseful() override; + Unit* GetTarget() override; +}; + #endif diff --git a/src/strategy/druid/DruidAiObjectContext.cpp b/src/strategy/druid/DruidAiObjectContext.cpp index a39fbc5b..d9882c76 100644 --- a/src/strategy/druid/DruidAiObjectContext.cpp +++ b/src/strategy/druid/DruidAiObjectContext.cpp @@ -209,6 +209,7 @@ public: creators["healing touch"] = &DruidAiObjectContextInternal::healing_touch; creators["regrowth on party"] = &DruidAiObjectContextInternal::regrowth_on_party; creators["rejuvenation on party"] = &DruidAiObjectContextInternal::rejuvenation_on_party; + creators["rejuvenation on not full"] = &DruidAiObjectContextInternal::rejuvenation_on_not_full; creators["healing touch on party"] = &DruidAiObjectContextInternal::healing_touch_on_party; creators["rebirth"] = &DruidAiObjectContextInternal::rebirth; creators["revive"] = &DruidAiObjectContextInternal::revive; @@ -295,6 +296,7 @@ private: static Action* healing_touch(PlayerbotAI* botAI) { return new CastHealingTouchAction(botAI); } static Action* regrowth_on_party(PlayerbotAI* botAI) { return new CastRegrowthOnPartyAction(botAI); } static Action* rejuvenation_on_party(PlayerbotAI* botAI) { return new CastRejuvenationOnPartyAction(botAI); } + static Action* rejuvenation_on_not_full(PlayerbotAI* botAI) { return new CastRejuvenationOnNotFullAction(botAI); } static Action* healing_touch_on_party(PlayerbotAI* botAI) { return new CastHealingTouchOnPartyAction(botAI); } static Action* rebirth(PlayerbotAI* botAI) { return new CastRebirthAction(botAI); } static Action* revive(PlayerbotAI* botAI) { return new CastReviveAction(botAI); } diff --git a/src/strategy/druid/GenericDruidStrategy.cpp b/src/strategy/druid/GenericDruidStrategy.cpp index c3dacdb3..cbe3ad7a 100644 --- a/src/strategy/druid/GenericDruidStrategy.cpp +++ b/src/strategy/druid/GenericDruidStrategy.cpp @@ -164,9 +164,10 @@ void DruidAssistDpsStrategy::InitTriggers(std::vector& triggers) new NextAction("starfire", ACTION_DEFAULT), nullptr))); - triggers.push_back( - new TriggerNode("medium aoe and healer should attack", - NextAction::array(0, - new NextAction("hurricane", ACTION_DEFAULT + 0.7f), - nullptr))); + // long cast time + // triggers.push_back( + // new TriggerNode("medium aoe and healer should attack", + // NextAction::array(0, + // new NextAction("hurricane", ACTION_DEFAULT + 0.7f), + // nullptr))); } diff --git a/src/strategy/druid/HealDruidStrategy.cpp b/src/strategy/druid/HealDruidStrategy.cpp index ec33dea3..b1e2f125 100644 --- a/src/strategy/druid/HealDruidStrategy.cpp +++ b/src/strategy/druid/HealDruidStrategy.cpp @@ -70,8 +70,8 @@ void HealDruidStrategy::InitTriggers(std::vector& triggers) NextAction::array(0, new NextAction("tree form", ACTION_CRITICAL_HEAL + 4.1f), new NextAction("swiftmend on party", ACTION_CRITICAL_HEAL + 4), - new NextAction("wild growth on party", ACTION_CRITICAL_HEAL + 3), - new NextAction("regrowth on party", ACTION_CRITICAL_HEAL + 2), + new NextAction("regrowth on party", ACTION_CRITICAL_HEAL + 3), + new NextAction("wild growth 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), nullptr))); @@ -80,36 +80,46 @@ void HealDruidStrategy::InitTriggers(std::vector& triggers) new TriggerNode("party member critical health", NextAction::array(0, new NextAction("nature's swiftness", ACTION_CRITICAL_HEAL + 4), nullptr))); + triggers.push_back(new TriggerNode( + "group heal setting", + NextAction::array(0, + new NextAction("tree form", ACTION_MEDIUM_HEAL + 2.3f), + new NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 2.2f), + new NextAction("rejuvenation on not full", ACTION_MEDIUM_HEAL + 2.1f), + nullptr))); + triggers.push_back( - new TriggerNode("medium group heal occasion", - NextAction::array(0, new NextAction("tranquility", ACTION_CRITICAL_HEAL + 5), nullptr))); + new TriggerNode("medium group heal setting", + NextAction::array(0, + new NextAction("tree form", ACTION_CRITICAL_HEAL + 0.6f), + new NextAction("tranquility", ACTION_CRITICAL_HEAL + 0.5f), nullptr))); // LOW triggers.push_back( new TriggerNode("party member low health", - NextAction::array(0, new NextAction("tree form", ACTION_MEDIUM_HEAL + 9.1f), - new NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 9), - 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), + NextAction::array(0, new NextAction("tree form", ACTION_MEDIUM_HEAL + 1.5f), + new NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 1.4f), + new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 1.3f), + new NextAction("swiftmend on party", ACTION_MEDIUM_HEAL + 1.2), + new NextAction("nourish on party", ACTION_MEDIUM_HEAL + 1.1f), nullptr))); // MEDIUM triggers.push_back( new TriggerNode("party member medium health", NextAction::array(0, - new NextAction("tree form", ACTION_MEDIUM_HEAL + 4.1f), - new NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 4), - new NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 3), - new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 2), - new NextAction("nourish on party", ACTION_MEDIUM_HEAL + 1), nullptr))); + new NextAction("tree form", ACTION_MEDIUM_HEAL + 0.5f), + new NextAction("wild growth on party", ACTION_MEDIUM_HEAL + 0.4f), + new NextAction("rejuvenation on party", ACTION_MEDIUM_HEAL + 0.3f), + new NextAction("regrowth on party", ACTION_MEDIUM_HEAL + 0.2f), + new NextAction("nourish on party", ACTION_MEDIUM_HEAL + 0.1f), nullptr))); // almost full triggers.push_back( new TriggerNode("party member almost full health", - NextAction::array(0, new NextAction("wild growth on party", ACTION_LIGHT_HEAL + 3), - new NextAction("rejuvenation on party", ACTION_LIGHT_HEAL + 2), - new NextAction("regrowth on party", ACTION_LIGHT_HEAL + 1), nullptr))); + NextAction::array(0, new NextAction("wild growth on party", ACTION_LIGHT_HEAL + 0.3f), + new NextAction("rejuvenation on party", ACTION_LIGHT_HEAL + 0.2f), + new NextAction("regrowth on party", ACTION_LIGHT_HEAL + 0.1f), nullptr))); triggers.push_back( new TriggerNode("medium mana", NextAction::array(0, new NextAction("innervate", ACTION_HIGH + 5), nullptr))); diff --git a/src/strategy/paladin/HealPaladinStrategy.cpp b/src/strategy/paladin/HealPaladinStrategy.cpp index 42517630..5f1767dd 100644 --- a/src/strategy/paladin/HealPaladinStrategy.cpp +++ b/src/strategy/paladin/HealPaladinStrategy.cpp @@ -49,7 +49,7 @@ void HealPaladinStrategy::InitTriggers(std::vector& triggers) NextAction::array(0, new NextAction("reach party member to heal", ACTION_EMERGENCY + 3), nullptr))); triggers.push_back( - new TriggerNode("medium group heal occasion", + new TriggerNode("medium group heal setting", NextAction::array(0, new NextAction("divine sacrifice", ACTION_CRITICAL_HEAL + 5), new NextAction("avenging wrath", ACTION_HIGH + 4), nullptr))); diff --git a/src/strategy/paladin/TankPaladinStrategy.cpp b/src/strategy/paladin/TankPaladinStrategy.cpp index 1cb2c5c4..25e761b7 100644 --- a/src/strategy/paladin/TankPaladinStrategy.cpp +++ b/src/strategy/paladin/TankPaladinStrategy.cpp @@ -106,7 +106,7 @@ void TankPaladinStrategy::InitTriggers(std::vector& triggers) triggers.push_back(new TriggerNode( "righteous fury", NextAction::array(0, new NextAction("righteous fury", ACTION_HIGH + 8), nullptr))); triggers.push_back( - new TriggerNode("medium group heal occasion", + new TriggerNode("medium group heal setting", NextAction::array(0, new NextAction("divine sacrifice", ACTION_HIGH + 5), nullptr))); triggers.push_back(new TriggerNode( "enough mana", NextAction::array(0, new NextAction("consecration", ACTION_HIGH + 4), nullptr))); diff --git a/src/strategy/priest/HealPriestStrategy.cpp b/src/strategy/priest/HealPriestStrategy.cpp index 52c12df6..64c747fd 100644 --- a/src/strategy/priest/HealPriestStrategy.cpp +++ b/src/strategy/priest/HealPriestStrategy.cpp @@ -35,33 +35,39 @@ void HealPriestStrategy::InitTriggers(std::vector& triggers) triggers.push_back(new TriggerNode( "group heal setting", - NextAction::array(0, new NextAction("power word: shield on almost full health below", ACTION_MEDIUM_HEAL + 7), + NextAction::array(0, + new NextAction("prayer of mending on party", ACTION_MEDIUM_HEAL + 8), + new NextAction("power word: shield on not full", ACTION_MEDIUM_HEAL + 7), nullptr))); triggers.push_back(new TriggerNode( - "medium group heal occasion", - NextAction::array(0, new NextAction("divine hymn", ACTION_CRITICAL_HEAL + 6), - new NextAction("prayer of healing on party", ACTION_CRITICAL_HEAL + 5), nullptr))); + "medium group heal setting", + NextAction::array(0, new NextAction("divine hymn", ACTION_CRITICAL_HEAL + 7), + new NextAction("prayer of mending on party", ACTION_CRITICAL_HEAL + 6), + new NextAction("power word: shield on not full", ACTION_CRITICAL_HEAL + 5), + new NextAction("prayer of healing on party", ACTION_CRITICAL_HEAL + 4), + nullptr))); triggers.push_back(new TriggerNode( "party member critical health", - NextAction::array(0, new NextAction("power word: shield on party", ACTION_CRITICAL_HEAL + 6), + NextAction::array(0, new NextAction("power word: shield on party", ACTION_CRITICAL_HEAL + 5), new NextAction("penance on party", ACTION_CRITICAL_HEAL + 4), - new NextAction("flash heal on party", ACTION_CRITICAL_HEAL + 3), - new NextAction("prayer of mending on party", ACTION_CRITICAL_HEAL + 2), nullptr))); + new NextAction("prayer of mending on party", ACTION_CRITICAL_HEAL + 3), + new NextAction("flash heal on party", ACTION_CRITICAL_HEAL + 2), + nullptr))); triggers.push_back( new TriggerNode("party member low health", NextAction::array(0, new NextAction("power word: shield on party", ACTION_MEDIUM_HEAL + 4), + new NextAction("prayer of mending on party", ACTION_MEDIUM_HEAL + 3), new NextAction("penance on party", ACTION_MEDIUM_HEAL + 2), - new NextAction("prayer of mending on party", ACTION_MEDIUM_HEAL + 1), new NextAction("flash heal on party", ACTION_MEDIUM_HEAL + 0), nullptr))); triggers.push_back( new TriggerNode("party member medium health", NextAction::array(0, new NextAction("power word: shield on party", ACTION_LIGHT_HEAL + 9), - new NextAction("penance on party", ACTION_LIGHT_HEAL + 7), - new NextAction("prayer of mending on party", ACTION_LIGHT_HEAL + 6), + new NextAction("prayer of mending on party", ACTION_LIGHT_HEAL + 7), + new NextAction("penance on party", ACTION_LIGHT_HEAL + 6), new NextAction("flash heal on party", ACTION_LIGHT_HEAL + 5), // new NextAction("renew on party", ACTION_LIGHT_HEAL + 8), nullptr))); @@ -70,7 +76,9 @@ void HealPriestStrategy::InitTriggers(std::vector& triggers) new TriggerNode("party member almost full health", NextAction::array(0, // new NextAction("penance on party", ACTION_LIGHT_HEAL + 3), - new NextAction("renew on party", ACTION_LIGHT_HEAL + 2), NULL))); + new NextAction("prayer of mending on party", ACTION_LIGHT_HEAL + 2), + new NextAction("renew on party", ACTION_LIGHT_HEAL + 1), + nullptr))); // triggers.push_back(new TriggerNode("almost full health", NextAction::array(0, new NextAction("renew", 43.f), // nullptr))); triggers.push_back(new TriggerNode("party member almost full health", NextAction::array(0, new diff --git a/src/strategy/priest/HolyPriestStrategy.cpp b/src/strategy/priest/HolyPriestStrategy.cpp index de29d7ea..7c073e05 100644 --- a/src/strategy/priest/HolyPriestStrategy.cpp +++ b/src/strategy/priest/HolyPriestStrategy.cpp @@ -64,40 +64,48 @@ void HolyHealPriestStrategy::InitTriggers(std::vector& triggers) triggers.push_back( new TriggerNode("group heal setting", - NextAction::array(0, new NextAction("circle of healing on party", ACTION_MEDIUM_HEAL + 8), nullptr))); + NextAction::array(0, + new NextAction("prayer of mending on party", ACTION_MEDIUM_HEAL + 9), + new NextAction("circle of healing on party", ACTION_MEDIUM_HEAL + 8), nullptr))); triggers.push_back(new TriggerNode( - "medium group heal occasion", - NextAction::array(0, new NextAction("divine hymn", ACTION_CRITICAL_HEAL + 6), - new NextAction("prayer of healing on party", ACTION_CRITICAL_HEAL + 5), nullptr))); + "medium group heal setting", + NextAction::array(0, new NextAction("divine hymn", ACTION_CRITICAL_HEAL + 7), + new NextAction("prayer of mending on party", ACTION_CRITICAL_HEAL + 6), + new NextAction("circle of healing on party", ACTION_CRITICAL_HEAL + 5), + new NextAction("prayer of healing on party", ACTION_CRITICAL_HEAL + 4), nullptr))); triggers.push_back(new TriggerNode( "party member critical health", NextAction::array(0, new NextAction("guardian spirit on party", ACTION_CRITICAL_HEAL + 6), new NextAction("power word: shield on party", ACTION_CRITICAL_HEAL + 5), - new NextAction("flash heal on party", ACTION_CRITICAL_HEAL + 3), - new NextAction("prayer of mending on party", ACTION_CRITICAL_HEAL + 2), nullptr))); + new NextAction("prayer of mending on party", ACTION_CRITICAL_HEAL + 3), + new NextAction("greater heal on party", ACTION_MEDIUM_HEAL + 2), + new NextAction("flash heal on party", ACTION_CRITICAL_HEAL + 1), + nullptr))); triggers.push_back( new TriggerNode("party member low health", NextAction::array(0, new NextAction("circle of healing on party", ACTION_MEDIUM_HEAL + 4), - new NextAction("greater heal on party", ACTION_MEDIUM_HEAL + 3), - new NextAction("prayer of mending on party", ACTION_MEDIUM_HEAL + 2), + new NextAction("prayer of mending on party", ACTION_MEDIUM_HEAL + 3), + new NextAction("greater heal on party", ACTION_MEDIUM_HEAL + 2), new NextAction("flash heal on party", ACTION_MEDIUM_HEAL + 1), nullptr))); triggers.push_back( new TriggerNode("party member medium health", NextAction::array(0, new NextAction("circle of healing on party", ACTION_LIGHT_HEAL + 7), new NextAction("prayer of mending on party", ACTION_LIGHT_HEAL + 6), - new NextAction("flash heal on party", ACTION_LIGHT_HEAL + 5), + new NextAction("greater heal on party", ACTION_MEDIUM_HEAL + 5), + new NextAction("flash heal on party", ACTION_LIGHT_HEAL + 4), // new NextAction("renew on party", ACTION_LIGHT_HEAL + 8), nullptr))); triggers.push_back( new TriggerNode("party member almost full health", - NextAction::array(0, new NextAction("renew on party", ACTION_LIGHT_HEAL + 2), - // new NextAction("flash heal on party", ACTION_LIGHT_HEAL + 1), + NextAction::array(0, + new NextAction("renew on party", ACTION_LIGHT_HEAL + 2), + new NextAction("prayer of mending on party", ACTION_LIGHT_HEAL + 1), nullptr))); triggers.push_back(new TriggerNode( diff --git a/src/strategy/priest/PriestAiObjectContext.cpp b/src/strategy/priest/PriestAiObjectContext.cpp index d6c59233..3f8dbacd 100644 --- a/src/strategy/priest/PriestAiObjectContext.cpp +++ b/src/strategy/priest/PriestAiObjectContext.cpp @@ -175,6 +175,8 @@ public: creators["power word: shield on party"] = &PriestAiObjectContextInternal::power_word_shield_on_party; creators["power word: shield on almost full health below"] = &PriestAiObjectContextInternal::power_word_shield_on_almost_full_health_below; + creators["power word: shield on not full"] = + &PriestAiObjectContextInternal::power_word_shield_on_not_full; creators["renew"] = &PriestAiObjectContextInternal::renew; creators["renew on party"] = &PriestAiObjectContextInternal::renew_on_party; creators["greater heal"] = &PriestAiObjectContextInternal::greater_heal; @@ -285,7 +287,11 @@ private: } static Action* power_word_shield_on_almost_full_health_below(PlayerbotAI* ai) { - return new CastPowerWordShieldOnAlmostFullHealthBelow(ai); + return new CastPowerWordShieldOnAlmostFullHealthBelowAction(ai); + } + static Action* power_word_shield_on_not_full(PlayerbotAI* ai) + { + return new CastPowerWordShieldOnNotFullAction(ai); } static Action* renew(PlayerbotAI* botAI) { return new CastRenewAction(botAI); } static Action* renew_on_party(PlayerbotAI* botAI) { return new CastRenewOnPartyAction(botAI); } diff --git a/src/strategy/triggers/TriggerContext.h b/src/strategy/triggers/TriggerContext.h index 7baebc8d..cbfeec6f 100644 --- a/src/strategy/triggers/TriggerContext.h +++ b/src/strategy/triggers/TriggerContext.h @@ -140,7 +140,7 @@ public: creators["almost full aoe heal"] = &TriggerContext::almost_full_aoe_heal; creators["group heal setting"] = &TriggerContext::group_heal_occasion; - creators["medium group heal occasion"] = &TriggerContext::medium_group_heal_occasion; + creators["medium group heal setting"] = &TriggerContext::medium_group_heal_occasion; creators["invalid target"] = &TriggerContext::invalid_target; creators["lfg proposal active"] = &TriggerContext::lfg_proposal_active; @@ -250,7 +250,7 @@ private: } static Trigger* medium_group_heal_occasion(PlayerbotAI* ai) { - return new AoeInGroupTrigger(ai, "medium group heal occasion", "medium"); + return new AoeInGroupTrigger(ai, "medium group heal setting", "medium"); } static Trigger* target_changed(PlayerbotAI* botAI) { return new TargetChangedTrigger(botAI); } static Trigger* swimming(PlayerbotAI* botAI) { return new IsSwimmingTrigger(botAI); } From 529db3e75429bfa5a85d815845b28207d906fca2 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Fri, 4 Oct 2024 21:43:38 +0800 Subject: [PATCH 09/10] [Core sync] Add DynamicObject.h --- src/strategy/AiObjectContext.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/strategy/AiObjectContext.h b/src/strategy/AiObjectContext.h index f7bd2694..07fa78a6 100644 --- a/src/strategy/AiObjectContext.h +++ b/src/strategy/AiObjectContext.h @@ -10,6 +10,7 @@ #include #include "Common.h" +#include "DynamicObject.h" #include "NamedObjectContext.h" #include "PlayerbotAIAware.h" #include "Strategy.h" From 11377436cd7281d7f0743c9acdb7ad19a9d28ec0 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Fri, 4 Oct 2024 21:44:39 +0800 Subject: [PATCH 10/10] [Strategy] Rename "assist dps" to "healer dps" --- src/AiFactory.cpp | 2 +- src/strategy/druid/DruidAiObjectContext.cpp | 4 ++-- src/strategy/druid/GenericDruidStrategy.cpp | 2 +- src/strategy/druid/GenericDruidStrategy.h | 6 +++--- src/strategy/paladin/GenericPaladinStrategy.cpp | 2 +- src/strategy/paladin/GenericPaladinStrategy.h | 6 +++--- src/strategy/paladin/PaladinAiObjectContext.cpp | 4 ++-- src/strategy/priest/GenericPriestStrategy.cpp | 2 +- src/strategy/priest/GenericPriestStrategy.h | 6 +++--- src/strategy/priest/PriestAiObjectContext.cpp | 4 ++-- src/strategy/shaman/GenericShamanStrategy.cpp | 2 +- src/strategy/shaman/GenericShamanStrategy.h | 6 +++--- src/strategy/shaman/ShamanAiObjectContext.cpp | 4 ++-- 13 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/AiFactory.cpp b/src/AiFactory.cpp index c03cd615..d3cd1ef3 100644 --- a/src/AiFactory.cpp +++ b/src/AiFactory.cpp @@ -394,7 +394,7 @@ void AiFactory::AddDefaultCombatStrategies(Player* player, PlayerbotAI* const fa { if (sPlayerbotAIConfig->autoSaveMana) engine->addStrategy("save mana", false); - engine->addStrategy("assist dps", false); + engine->addStrategy("healer dps", false); } if (facade->IsRealPlayer() || sRandomPlayerbotMgr->IsRandomBot(player)) { diff --git a/src/strategy/druid/DruidAiObjectContext.cpp b/src/strategy/druid/DruidAiObjectContext.cpp index d9882c76..e0d8c7de 100644 --- a/src/strategy/druid/DruidAiObjectContext.cpp +++ b/src/strategy/druid/DruidAiObjectContext.cpp @@ -34,7 +34,7 @@ public: creators["buff"] = &DruidStrategyFactoryInternal::buff; creators["boost"] = &DruidStrategyFactoryInternal::boost; creators["cc"] = &DruidStrategyFactoryInternal::cc; - creators["assist dps"] = &DruidStrategyFactoryInternal::assist_dps; + creators["healer dps"] = &DruidStrategyFactoryInternal::healer_dps; } private: @@ -47,7 +47,7 @@ private: static Strategy* buff(PlayerbotAI* botAI) { return new GenericDruidBuffStrategy(botAI); } static Strategy* boost(PlayerbotAI* botAI) { return new DruidBoostStrategy(botAI); } static Strategy* cc(PlayerbotAI* botAI) { return new DruidCcStrategy(botAI); } - static Strategy* assist_dps(PlayerbotAI* botAI) { return new DruidAssistDpsStrategy(botAI); } + static Strategy* healer_dps(PlayerbotAI* botAI) { return new DruidHealerDpsStrategy(botAI); } }; class DruidDruidStrategyFactoryInternal : public NamedObjectContext diff --git a/src/strategy/druid/GenericDruidStrategy.cpp b/src/strategy/druid/GenericDruidStrategy.cpp index cbe3ad7a..d06a0e56 100644 --- a/src/strategy/druid/GenericDruidStrategy.cpp +++ b/src/strategy/druid/GenericDruidStrategy.cpp @@ -153,7 +153,7 @@ void DruidCcStrategy::InitTriggers(std::vector& triggers) "hibernate", NextAction::array(0, new NextAction("hibernate on cc", ACTION_HIGH + 3), nullptr))); } -void DruidAssistDpsStrategy::InitTriggers(std::vector& triggers) +void DruidHealerDpsStrategy::InitTriggers(std::vector& triggers) { triggers.push_back( new TriggerNode("healer should attack", diff --git a/src/strategy/druid/GenericDruidStrategy.h b/src/strategy/druid/GenericDruidStrategy.h index 6099527e..547b93b0 100644 --- a/src/strategy/druid/GenericDruidStrategy.h +++ b/src/strategy/druid/GenericDruidStrategy.h @@ -46,13 +46,13 @@ public: std::string const getName() override { return "cc"; } }; -class DruidAssistDpsStrategy : public Strategy +class DruidHealerDpsStrategy : public Strategy { public: - DruidAssistDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {} + DruidHealerDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {} void InitTriggers(std::vector& triggers) override; - std::string const getName() override { return "assist dps"; } + std::string const getName() override { return "healer dps"; } }; #endif diff --git a/src/strategy/paladin/GenericPaladinStrategy.cpp b/src/strategy/paladin/GenericPaladinStrategy.cpp index 09eb2074..b5b77f58 100644 --- a/src/strategy/paladin/GenericPaladinStrategy.cpp +++ b/src/strategy/paladin/GenericPaladinStrategy.cpp @@ -72,7 +72,7 @@ void PaladinCcStrategy::InitTriggers(std::vector& triggers) new TriggerNode("turn undead", NextAction::array(0, new NextAction("turn undead", ACTION_HIGH + 1), nullptr))); } -void PaladinAssistDpsStrategy::InitTriggers(std::vector& triggers) +void PaladinHealerDpsStrategy::InitTriggers(std::vector& triggers) { triggers.push_back( new TriggerNode("healer should attack", diff --git a/src/strategy/paladin/GenericPaladinStrategy.h b/src/strategy/paladin/GenericPaladinStrategy.h index fcdef3c6..737048cc 100644 --- a/src/strategy/paladin/GenericPaladinStrategy.h +++ b/src/strategy/paladin/GenericPaladinStrategy.h @@ -46,13 +46,13 @@ public: std::string const getName() override { return "cc"; } }; -class PaladinAssistDpsStrategy : public Strategy +class PaladinHealerDpsStrategy : public Strategy { public: - PaladinAssistDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {} + PaladinHealerDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {} void InitTriggers(std::vector& triggers) override; - std::string const getName() override { return "assist dps"; } + std::string const getName() override { return "healer dps"; } }; #endif diff --git a/src/strategy/paladin/PaladinAiObjectContext.cpp b/src/strategy/paladin/PaladinAiObjectContext.cpp index 5bc056ba..42e89a8a 100644 --- a/src/strategy/paladin/PaladinAiObjectContext.cpp +++ b/src/strategy/paladin/PaladinAiObjectContext.cpp @@ -25,7 +25,7 @@ public: creators["boost"] = &PaladinStrategyFactoryInternal::boost; creators["cc"] = &PaladinStrategyFactoryInternal::cc; creators["bthreat"] = &PaladinStrategyFactoryInternal::bthreat; - creators["assist dps"] = &PaladinStrategyFactoryInternal::assist_dps; + creators["healer dps"] = &PaladinStrategyFactoryInternal::healer_dps; } private: @@ -34,7 +34,7 @@ private: static Strategy* boost(PlayerbotAI* botAI) { return new PaladinBoostStrategy(botAI); } static Strategy* cc(PlayerbotAI* botAI) { return new PaladinCcStrategy(botAI); } static Strategy* bthreat(PlayerbotAI* botAI) { return new PaladinBuffThreatStrategy(botAI); } - static Strategy* assist_dps(PlayerbotAI* botAI) { return new PaladinAssistDpsStrategy(botAI); } + static Strategy* healer_dps(PlayerbotAI* botAI) { return new PaladinHealerDpsStrategy(botAI); } }; class PaladinResistanceStrategyFactoryInternal : public NamedObjectContext diff --git a/src/strategy/priest/GenericPriestStrategy.cpp b/src/strategy/priest/GenericPriestStrategy.cpp index fa680424..82ca65e9 100644 --- a/src/strategy/priest/GenericPriestStrategy.cpp +++ b/src/strategy/priest/GenericPriestStrategy.cpp @@ -88,7 +88,7 @@ void PriestCcStrategy::InitTriggers(std::vector& triggers) new TriggerNode("shackle undead", NextAction::array(0, new NextAction("shackle undead", 31.0f), nullptr))); } -void PriestAssistDpsStrategy::InitTriggers(std::vector& triggers) +void PriestHealerDpsStrategy::InitTriggers(std::vector& triggers) { triggers.push_back( new TriggerNode("healer should attack", diff --git a/src/strategy/priest/GenericPriestStrategy.h b/src/strategy/priest/GenericPriestStrategy.h index f18e2b00..2668723e 100644 --- a/src/strategy/priest/GenericPriestStrategy.h +++ b/src/strategy/priest/GenericPriestStrategy.h @@ -46,13 +46,13 @@ public: std::string const getName() override { return "cc"; } }; -class PriestAssistDpsStrategy : public Strategy +class PriestHealerDpsStrategy : public Strategy { public: - PriestAssistDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {} + PriestHealerDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {} void InitTriggers(std::vector& triggers) override; - std::string const getName() override { return "assist dps"; } + std::string const getName() override { return "healer dps"; } }; #endif diff --git a/src/strategy/priest/PriestAiObjectContext.cpp b/src/strategy/priest/PriestAiObjectContext.cpp index 3f8dbacd..4f057718 100644 --- a/src/strategy/priest/PriestAiObjectContext.cpp +++ b/src/strategy/priest/PriestAiObjectContext.cpp @@ -31,7 +31,7 @@ public: creators["boost"] = &PriestStrategyFactoryInternal::boost; creators["rshadow"] = &PriestStrategyFactoryInternal::rshadow; creators["cc"] = &PriestStrategyFactoryInternal::cc; - creators["assist dps"] = &PriestStrategyFactoryInternal::assist_dps; + creators["healer dps"] = &PriestStrategyFactoryInternal::healer_dps; } private: @@ -44,7 +44,7 @@ private: static Strategy* pull(PlayerbotAI* botAI) { return new PullStrategy(botAI, "shoot"); } static Strategy* shadow_debuff(PlayerbotAI* botAI) { return new ShadowPriestDebuffStrategy(botAI); } static Strategy* cure(PlayerbotAI* botAI) { return new PriestCureStrategy(botAI); } - static Strategy* assist_dps(PlayerbotAI* botAI) { return new PriestAssistDpsStrategy(botAI); } + static Strategy* healer_dps(PlayerbotAI* botAI) { return new PriestHealerDpsStrategy(botAI); } }; class PriestCombatStrategyFactoryInternal : public NamedObjectContext diff --git a/src/strategy/shaman/GenericShamanStrategy.cpp b/src/strategy/shaman/GenericShamanStrategy.cpp index 430a1bdc..95ed14f2 100644 --- a/src/strategy/shaman/GenericShamanStrategy.cpp +++ b/src/strategy/shaman/GenericShamanStrategy.cpp @@ -164,7 +164,7 @@ void ShamanCureStrategy::InitTriggers(std::vector& triggers) NextAction::array(0, new NextAction("cleanse spirit curse on party", 23.0f), nullptr))); } -void ShamanAssistDpsStrategy::InitTriggers(std::vector& triggers) +void ShamanHealerDpsStrategy::InitTriggers(std::vector& triggers) { triggers.push_back( new TriggerNode("healer should attack", diff --git a/src/strategy/shaman/GenericShamanStrategy.h b/src/strategy/shaman/GenericShamanStrategy.h index d41b8c04..5fa0ff83 100644 --- a/src/strategy/shaman/GenericShamanStrategy.h +++ b/src/strategy/shaman/GenericShamanStrategy.h @@ -45,13 +45,13 @@ public: std::string const getName() override { return "cure"; } }; -class ShamanAssistDpsStrategy : public Strategy +class ShamanHealerDpsStrategy : public Strategy { public: - ShamanAssistDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {} + ShamanHealerDpsStrategy(PlayerbotAI* botAI) : Strategy(botAI) {} void InitTriggers(std::vector& triggers) override; - std::string const getName() override { return "assist dps"; } + std::string const getName() override { return "healer dps"; } }; #endif diff --git a/src/strategy/shaman/ShamanAiObjectContext.cpp b/src/strategy/shaman/ShamanAiObjectContext.cpp index 193d292a..9e79f792 100644 --- a/src/strategy/shaman/ShamanAiObjectContext.cpp +++ b/src/strategy/shaman/ShamanAiObjectContext.cpp @@ -26,7 +26,7 @@ public: creators["melee aoe"] = &ShamanStrategyFactoryInternal::melee_aoe; creators["caster aoe"] = &ShamanStrategyFactoryInternal::caster_aoe; creators["cure"] = &ShamanStrategyFactoryInternal::cure; - creators["assist dps"] = &ShamanStrategyFactoryInternal::assist_dps; + creators["healer dps"] = &ShamanStrategyFactoryInternal::healer_dps; } private: @@ -35,7 +35,7 @@ private: static Strategy* melee_aoe(PlayerbotAI* botAI) { return new MeleeAoeShamanStrategy(botAI); } static Strategy* caster_aoe(PlayerbotAI* botAI) { return new CasterAoeShamanStrategy(botAI); } static Strategy* cure(PlayerbotAI* botAI) { return new ShamanCureStrategy(botAI); } - static Strategy* assist_dps(PlayerbotAI* botAI) { return new ShamanAssistDpsStrategy(botAI); } + static Strategy* healer_dps(PlayerbotAI* botAI) { return new ShamanHealerDpsStrategy(botAI); } }; class ShamanBuffStrategyFactoryInternal : public NamedObjectContext