[Assist Dps] Healer assist dps strats

This commit is contained in:
Yunfan Li
2024-10-03 22:35:26 +08:00
parent 11ce70635d
commit 008d098eda
31 changed files with 253 additions and 68 deletions

View File

@@ -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

View File

@@ -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())

View File

@@ -3339,8 +3339,8 @@ bool PlayerbotAI::CastSpell(uint32 spellId, Unit* target, Item* itemTarget)
// }
// }
WaitForSpellCast(spell);
if (spell->GetCastTime())
// WaitForSpellCast(spell);
aiObjectContext->GetValue<LastSpellCast&>("last spell cast")
->Get()
.Set(spellId, target->GetGUID(), time(nullptr));
@@ -3473,7 +3473,7 @@ bool PlayerbotAI::CastSpell(uint32 spellId, float x, float y, float z, Item* ite
}
}
WaitForSpellCast(spell);
// WaitForSpellCast(spell);
aiObjectContext->GetValue<LastSpellCast&>("last spell cast")->Get().Set(spellId, bot->GetGUID(), time(nullptr));
aiObjectContext->GetValue<PositionMap&>("position")->Get()["random"].Reset();
@@ -3688,7 +3688,7 @@ bool PlayerbotAI::CastVehicleSpell(uint32 spellId, Unit* target)
return false;
}
WaitForSpellCast(spell);
// WaitForSpellCast(spell);
// aiObjectContext->GetValue<LastSpellCast&>("last spell cast")->Get().Set(spellId, target->GetGUID(), time(0));
// aiObjectContext->GetValue<botAI::PositionMap&>("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);
}

View File

@@ -145,9 +145,6 @@ void CasterDruidStrategy::InitTriggers(std::vector<TriggerNode*>& 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<TriggerNode*>& triggers)

View File

@@ -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<Strategy>

View File

@@ -130,6 +130,11 @@ void DruidCureStrategy::InitTriggers(std::vector<TriggerNode*>& 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<TriggerNode*>& triggers)
@@ -147,3 +152,13 @@ void DruidCcStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
triggers.push_back(new TriggerNode(
"hibernate", NextAction::array(0, new NextAction("hibernate on cc", ACTION_HIGH + 3), nullptr)));
}
void DruidAssistDpsStrategy::InitTriggers(std::vector<TriggerNode*>& 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)));
}

View File

@@ -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<TriggerNode*>& triggers) override;
std::string const getName() override { return "assist dps"; }
};
#endif

View File

@@ -10,7 +10,12 @@
class HealDruidStrategyActionNodeFactory : public NamedObjectFactory<ActionNode>
{
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"] = &regrowth_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<TriggerNode*>& 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<TriggerNode*>& 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

View File

@@ -71,3 +71,16 @@ void PaladinCcStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
triggers.push_back(
new TriggerNode("turn undead", NextAction::array(0, new NextAction("turn undead", ACTION_HIGH + 1), nullptr)));
}
void PaladinAssistDpsStrategy::InitTriggers(std::vector<TriggerNode*>& 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)));
}

View File

@@ -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<TriggerNode*>& triggers) override;
std::string const getName() override { return "assist dps"; }
};
#endif

View File

@@ -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",

View File

@@ -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<TriggerNode*>& triggers)

View File

@@ -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<Strategy>

View File

@@ -73,7 +73,7 @@ void TankPaladinStrategy::InitTriggers(std::vector<TriggerNode*>& 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),

View File

@@ -87,3 +87,23 @@ void PriestCcStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
triggers.push_back(
new TriggerNode("shackle undead", NextAction::array(0, new NextAction("shackle undead", 31.0f), nullptr)));
}
void PriestAssistDpsStrategy::InitTriggers(std::vector<TriggerNode*>& 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)));
}

View File

@@ -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<TriggerNode*>& triggers) override;
std::string const getName() override { return "assist dps"; }
};
#endif

View File

@@ -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");

View File

@@ -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<Strategy>

View File

@@ -55,7 +55,7 @@ void PriestNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& 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<TriggerNode*>& triggers)

View File

@@ -51,8 +51,8 @@ void CasterShamanStrategy::InitTriggers(std::vector<TriggerNode*>& 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)));

View File

@@ -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<TriggerNode*>& 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<TriggerNode*>& 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)));
}

View File

@@ -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<TriggerNode*>& triggers) override;
std::string const getName() override { return "assist dps"; }
};
#endif

View File

@@ -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

View File

@@ -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<Strategy>

View File

@@ -39,7 +39,7 @@ void ShamanNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& 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)));

View File

@@ -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()

View File

@@ -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
{

View File

@@ -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;
}

View File

@@ -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;
};

View File

@@ -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); }

View File

@@ -94,7 +94,7 @@ uint8 BalancePercentValue::Calculate()
level *= 3;
break;
case CREATURE_ELITE_WORLDBOSS:
level *= 30;
level *= 20;
break;
}