From 008d098eda4d475ca75c2b042ec32a7fae72ab76 Mon Sep 17 00:00:00 2001 From: Yunfan Li Date: Thu, 3 Oct 2024 22:35:26 +0800 Subject: [PATCH] [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; }