mirror of
https://github.com/liyunfan1223/mod-playerbots.git
synced 2026-06-20 15:39:25 +02:00
Add Sense Undead for Paladins (#2200)
# Pull Request This PR adds the sense undead ability for Paladins, which they will keep active at all times. This is mildly useful because the associated minor glyph provides a 1% damage increase against undead while the ability is active. Sense undead is also added to InitClassSpells(). I understand that it is a trainer spell so would normally be covered by InitAvailableSpells(), but those playing with mod-individual-progression will not receive the spell through InitAvailableSpells() because it is removed from trainers by the mod (in TBC, a quest was required to obtain the spell). Finally, the minor glyph of sense undead is now added to the config as a default glyph for all PvE specs. It is not added for PvP specs because Forsaken do not count as undead so the glyph is useless in PvP. I also made some other tweaks to Paladin default minor glyphs that are not worth spending any time talking about. Edit: I also did some minor reformatting of code and replaced some numbers with existing constants. --- ## Design Philosophy We prioritize **stability, performance, and predictability** over behavioral realism. Complex player-mimicking logic is intentionally limited due to its negative impact on scalability, maintainability, and long-term robustness. Excessive processing overhead can lead to server hiccups, increased CPU usage, and degraded performance for all participants. Because every action and decision tree is executed **per bot and per trigger**, even small increases in logic complexity can scale poorly and negatively affect both players and world (random) bots. Bots are not expected to behave perfectly, and perfect simulation of human decision-making is not a project goal. Increased behavioral realism often introduces disproportionate cost, reduced predictability, and significantly higher maintenance overhead. Every additional branch of logic increases long-term responsibility. All decision paths must be tested, validated, and maintained continuously as the system evolves. If advanced or AI-intensive behavior is introduced, the **default configuration must remain the lightweight decision model**. More complex behavior should only be available as an **explicit opt-in option**, clearly documented as having a measurable performance cost. Principles: - **Stability before intelligence** A stable system is always preferred over a smarter one. - **Performance is a shared resource** Any increase in bot cost affects all players and all bots. - **Simple logic scales better than smart logic** Predictable behavior under load is more valuable than perfect decisions. - **Complexity must justify itself** If a feature cannot clearly explain its cost, it should not exist. - **Defaults must be cheap** Expensive behavior must always be optional and clearly communicated. - **Bots should look reasonable, not perfect** The goal is believable behavior, not human simulation. Before submitting, confirm that this change aligns with those principles. --- ## Feature Evaluation Please answer the following: - Describe the **minimum logic** required to achieve the intended behavior? - Describe the **cheapest implementation** that produces an acceptable result? - Describe the **runtime cost** when this logic executes across many bots? The implementation just checks if a Paladin has the sense undead aura, and if not, the Paladin will activate sense undead. It is simple and cheap. --- ## How to Test the Changes - Step-by-step instructions to test the change - Any required setup (e.g. multiple players, bots, specific configuration) - Expected behavior and how to verify it ## Complexity & Impact Does this change add new decision branches? - - [x] No - - [ ] Yes (**explain below**) Does this change increase per-bot or per-tick processing? - - [ ] No - - [x] Yes (**describe and justify impact**) Infinitesimally Could this logic scale poorly under load? - - [x] No - - [ ] Yes (**explain why**) ## Defaults & Configuration Does this change modify default bot behavior? - - [ ] No - - [x] Yes (**explain why**) Paladin bots will by default have sense undead enabled. There is no disadvantage to this. If this introduces more advanced or AI-heavy logic: - - [x] Lightweight mode remains the default - - [ ] More complex behavior is optional and thereby configurable --- ## AI Assistance Was AI assistance (e.g. ChatGPT or similar tools) used while working on this change? - - [x] No - - [ ] Yes (**explain below**) If yes, please specify: - AI tool or model used (e.g. ChatGPT, GPT-4, Claude, etc.) - Purpose of usage (e.g. brainstorming, refactoring, documentation, code generation) - Which parts of the change were influenced or generated - Whether the result was manually reviewed and adapted AI assistance is allowed, but all submitted code must be fully understood, reviewed, and owned by the contributor. Any AI-influenced changes must be verified against existing CORE and PB logic. We expect contributors to be honest about what they do and do not understand. --- ## Final Checklist - - [x] Stability is not compromised - - [x] Performance impact is understood, tested, and acceptable - - [x] Added logic complexity is justified and explained - - [x] Documentation updated if needed --- ## Notes for Reviewers Anything that significantly improves realism at the cost of stability or performance should be carefully discussed before merging. --------- Co-authored-by: Keleborn <22352763+Celandriel@users.noreply.github.com> Co-authored-by: bash <hermensb@gmail.com> Co-authored-by: Revision <tkn963@gmail.com> Co-authored-by: kadeshar <kadeshar@gmail.com>
This commit is contained in:
parent
473b2ab5c6
commit
35a0282ca6
@ -1406,28 +1406,28 @@ AiPlayerbot.PremadeSpecLink.1.5.80 = 0502300123-3-250031220223012521332113321
|
||||
#
|
||||
|
||||
AiPlayerbot.PremadeSpecName.2.0 = holy pve
|
||||
AiPlayerbot.PremadeSpecGlyph.2.0 = 41106,43367,45741,43369,43365,41109
|
||||
AiPlayerbot.PremadeSpecGlyph.2.0 = 41106,43367,45741,43368,43365,41109
|
||||
AiPlayerbot.PremadeSpecLink.2.0.60 = 50350151020013053100515221
|
||||
AiPlayerbot.PremadeSpecLink.2.0.80 = 50350152220013053100515221-503201312
|
||||
AiPlayerbot.PremadeSpecName.2.1 = prot pve
|
||||
AiPlayerbot.PremadeSpecGlyph.2.1 = 41099,43367,43869,43369,43365,45745
|
||||
AiPlayerbot.PremadeSpecGlyph.2.1 = 41099,43367,43869,43368,43369,45745
|
||||
AiPlayerbot.PremadeSpecLink.2.1.60 = -05005135203102311333112321
|
||||
AiPlayerbot.PremadeSpecLink.2.1.80 = -05005135203102311333312321-502302012003
|
||||
AiPlayerbot.PremadeSpecName.2.2 = ret pve
|
||||
AiPlayerbot.PremadeSpecGlyph.2.2 = 41092,43367,41099,43369,43365,43869
|
||||
AiPlayerbot.PremadeSpecGlyph.2.2 = 41092,43367,41099,43368,43369,43869
|
||||
AiPlayerbot.PremadeSpecLink.2.2.60 = --05230051203331302133231131
|
||||
AiPlayerbot.PremadeSpecLink.2.2.65 = -05-05230051203331302133231131
|
||||
AiPlayerbot.PremadeSpecLink.2.2.80 = 050501-05-05232051203331302133231331
|
||||
AiPlayerbot.PremadeSpecName.2.3 = holy pvp
|
||||
AiPlayerbot.PremadeSpecGlyph.2.3 = 41110,43367,45746,43366,43365,45747
|
||||
AiPlayerbot.PremadeSpecGlyph.2.3 = 41110,43367,45746,43369,43365,45747
|
||||
AiPlayerbot.PremadeSpecLink.2.3.60 = 50332150300013050133215221
|
||||
AiPlayerbot.PremadeSpecLink.2.3.80 = 50332150300013050133315221-5032013122
|
||||
AiPlayerbot.PremadeSpecName.2.4 = prot pvp
|
||||
AiPlayerbot.PremadeSpecGlyph.2.4 = 41092,43369,41101,43368,43365,45745
|
||||
AiPlayerbot.PremadeSpecGlyph.2.4 = 41092,43367,41101,43369,43365,45745
|
||||
AiPlayerbot.PremadeSpecLink.2.4.60 = -15320130223122311323311321
|
||||
AiPlayerbot.PremadeSpecLink.2.4.80 = -15320130223122321333312321-052300502
|
||||
AiPlayerbot.PremadeSpecName.2.5 = ret pvp
|
||||
AiPlayerbot.PremadeSpecGlyph.2.5 = 41095,43369,41102,43368,43365,45747
|
||||
AiPlayerbot.PremadeSpecGlyph.2.5 = 41095,43367,41102,43369,43365,45747
|
||||
AiPlayerbot.PremadeSpecLink.2.5.60 = --05230250203331222133201321
|
||||
AiPlayerbot.PremadeSpecLink.2.5.80 = -1532013022-05230250203331322133201321
|
||||
|
||||
|
||||
@ -472,9 +472,8 @@ Unit* CastRighteousDefenseAction::GetTarget()
|
||||
{
|
||||
Unit* current_target = AI_VALUE(Unit*, "current target");
|
||||
if (!current_target)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
return current_target->GetVictim();
|
||||
}
|
||||
|
||||
|
||||
@ -91,9 +91,8 @@ public:
|
||||
class CastBlessingOnPartyAction : public BuffOnPartyAction
|
||||
{
|
||||
public:
|
||||
CastBlessingOnPartyAction(PlayerbotAI* botAI, std::string const name) : BuffOnPartyAction(botAI, name), name(name)
|
||||
{
|
||||
}
|
||||
CastBlessingOnPartyAction(PlayerbotAI* botAI, std::string const name)
|
||||
: BuffOnPartyAction(botAI, name), name(name) {}
|
||||
|
||||
Value<Unit*>* GetTargetValue() override;
|
||||
|
||||
@ -154,9 +153,7 @@ public:
|
||||
class CastBlessingOfSanctuaryOnPartyAction : public BuffOnPartyAction
|
||||
{
|
||||
public:
|
||||
CastBlessingOfSanctuaryOnPartyAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "blessing of sanctuary")
|
||||
{
|
||||
}
|
||||
CastBlessingOfSanctuaryOnPartyAction(PlayerbotAI* botAI) : BuffOnPartyAction(botAI, "blessing of sanctuary") {}
|
||||
|
||||
std::string const getName() override { return "blessing of sanctuary on party"; }
|
||||
Value<Unit*>* GetTargetValue() override;
|
||||
@ -173,18 +170,14 @@ class CastHolyShockOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastHolyShockOnPartyAction(PlayerbotAI* botAI)
|
||||
: HealPartyMemberAction(botAI, "holy shock", 25.0f, HealingManaEfficiency::LOW)
|
||||
{
|
||||
}
|
||||
: HealPartyMemberAction(botAI, "holy shock", 25.0f, HealingManaEfficiency::LOW) {}
|
||||
};
|
||||
|
||||
class CastHolyLightOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastHolyLightOnPartyAction(PlayerbotAI* botAI)
|
||||
: HealPartyMemberAction(botAI, "holy light", 50.0f, HealingManaEfficiency::MEDIUM)
|
||||
{
|
||||
}
|
||||
: HealPartyMemberAction(botAI, "holy light", 50.0f, HealingManaEfficiency::MEDIUM) {}
|
||||
};
|
||||
|
||||
class CastFlashOfLightAction : public CastHealingSpellAction
|
||||
@ -197,9 +190,7 @@ class CastFlashOfLightOnPartyAction : public HealPartyMemberAction
|
||||
{
|
||||
public:
|
||||
CastFlashOfLightOnPartyAction(PlayerbotAI* botAI)
|
||||
: HealPartyMemberAction(botAI, "flash of light", 15.0f, HealingManaEfficiency::HIGH)
|
||||
{
|
||||
}
|
||||
: HealPartyMemberAction(botAI, "flash of light", 15.0f, HealingManaEfficiency::HIGH) {}
|
||||
};
|
||||
|
||||
class CastLayOnHandsAction : public CastHealingSpellAction
|
||||
@ -357,9 +348,7 @@ class CastHammerOfJusticeOnEnemyHealerAction : public CastSpellOnEnemyHealerActi
|
||||
{
|
||||
public:
|
||||
CastHammerOfJusticeOnEnemyHealerAction(PlayerbotAI* botAI)
|
||||
: CastSpellOnEnemyHealerAction(botAI, "hammer of justice")
|
||||
{
|
||||
}
|
||||
: CastSpellOnEnemyHealerAction(botAI, "hammer of justice") {}
|
||||
};
|
||||
|
||||
class CastHammerOfJusticeSnareAction : public CastSnareSpellAction
|
||||
@ -368,6 +357,12 @@ public:
|
||||
CastHammerOfJusticeSnareAction(PlayerbotAI* botAI) : CastSnareSpellAction(botAI, "hammer of justice") {}
|
||||
};
|
||||
|
||||
class CastSenseUndeadAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastSenseUndeadAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "sense undead") {}
|
||||
};
|
||||
|
||||
class CastTurnUndeadAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
@ -381,25 +376,25 @@ PROTECT_ACTION(CastBlessingOfProtectionProtectAction, "blessing of protection");
|
||||
class CastDivinePleaAction : public CastBuffSpellAction
|
||||
{
|
||||
public:
|
||||
CastDivinePleaAction(PlayerbotAI* ai) : CastBuffSpellAction(ai, "divine plea") {}
|
||||
CastDivinePleaAction(PlayerbotAI* botAI) : CastBuffSpellAction(botAI, "divine plea") {}
|
||||
};
|
||||
|
||||
class ShieldOfRighteousnessAction : public CastMeleeSpellAction
|
||||
{
|
||||
public:
|
||||
ShieldOfRighteousnessAction(PlayerbotAI* ai) : CastMeleeSpellAction(ai, "shield of righteousness") {}
|
||||
ShieldOfRighteousnessAction(PlayerbotAI* botAI) : CastMeleeSpellAction(botAI, "shield of righteousness") {}
|
||||
};
|
||||
|
||||
class CastBeaconOfLightOnMainTankAction : public BuffOnMainTankAction
|
||||
{
|
||||
public:
|
||||
CastBeaconOfLightOnMainTankAction(PlayerbotAI* ai) : BuffOnMainTankAction(ai, "beacon of light", true) {}
|
||||
CastBeaconOfLightOnMainTankAction(PlayerbotAI* botAI) : BuffOnMainTankAction(botAI, "beacon of light", true) {}
|
||||
};
|
||||
|
||||
class CastSacredShieldOnMainTankAction : public BuffOnMainTankAction
|
||||
{
|
||||
public:
|
||||
CastSacredShieldOnMainTankAction(PlayerbotAI* ai) : BuffOnMainTankAction(ai, "sacred shield", false) {}
|
||||
CastSacredShieldOnMainTankAction(PlayerbotAI* botAI) : BuffOnMainTankAction(botAI, "sacred shield", false) {}
|
||||
};
|
||||
|
||||
class CastAvengingWrathAction : public CastBuffSpellAction
|
||||
@ -428,4 +423,5 @@ public:
|
||||
bool Execute(Event event) override;
|
||||
bool isUseful() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -132,6 +132,7 @@ public:
|
||||
&PaladinTriggerFactoryInternal::hammer_of_justice_on_enemy_target;
|
||||
creators["hammer of justice on snare target"] =
|
||||
&PaladinTriggerFactoryInternal::hammer_of_justice_on_snare_target;
|
||||
creators["not sensing undead"] = &PaladinTriggerFactoryInternal::not_sensing_undead;
|
||||
creators["divine favor"] = &PaladinTriggerFactoryInternal::divine_favor;
|
||||
creators["turn undead"] = &PaladinTriggerFactoryInternal::turn_undead;
|
||||
creators["avenger's shield"] = &PaladinTriggerFactoryInternal::avenger_shield;
|
||||
@ -151,6 +152,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
static Trigger* not_sensing_undead(PlayerbotAI* botAI) { return new NotSensingUndeadTrigger(botAI); }
|
||||
static Trigger* turn_undead(PlayerbotAI* botAI) { return new TurnUndeadTrigger(botAI); }
|
||||
static Trigger* divine_favor(PlayerbotAI* botAI) { return new DivineFavorTrigger(botAI); }
|
||||
static Trigger* holy_shield(PlayerbotAI* botAI) { return new HolyShieldTrigger(botAI); }
|
||||
@ -288,6 +290,7 @@ public:
|
||||
creators["hammer of justice on snare target"] =
|
||||
&PaladinAiObjectContextInternal::hammer_of_justice_on_snare_target;
|
||||
creators["divine favor"] = &PaladinAiObjectContextInternal::divine_favor;
|
||||
creators["sense undead"] = &PaladinAiObjectContextInternal::sense_undead;
|
||||
creators["turn undead"] = &PaladinAiObjectContextInternal::turn_undead;
|
||||
creators["blessing of protection on party"] = &PaladinAiObjectContextInternal::blessing_of_protection_on_party;
|
||||
creators["righteous defense"] = &PaladinAiObjectContextInternal::righteous_defense;
|
||||
@ -312,6 +315,7 @@ private:
|
||||
{
|
||||
return new CastBlessingOfProtectionProtectAction(botAI);
|
||||
}
|
||||
static Action* sense_undead(PlayerbotAI* botAI) { return new CastSenseUndeadAction(botAI); }
|
||||
static Action* turn_undead(PlayerbotAI* botAI) { return new CastTurnUndeadAction(botAI); }
|
||||
static Action* divine_favor(PlayerbotAI* botAI) { return new CastDivineFavorAction(botAI); }
|
||||
static Action* righteous_fury(PlayerbotAI* botAI) { return new CastRighteousFuryAction(botAI); }
|
||||
|
||||
@ -19,14 +19,15 @@ void GenericPaladinNonCombatStrategy::InitTriggers(std::vector<TriggerNode*>& tr
|
||||
NonCombatStrategy::InitTriggers(triggers);
|
||||
|
||||
triggers.push_back(new TriggerNode("party member dead", { NextAction("redemption", ACTION_CRITICAL_HEAL + 10) }));
|
||||
triggers.push_back(new TriggerNode("party member almost full health", { NextAction("flash of light on party", 25.0f) }));
|
||||
triggers.push_back(new TriggerNode("party member medium health", { NextAction("flash of light on party", 26.0f) }));
|
||||
triggers.push_back(new TriggerNode("party member low health", { NextAction("holy light on party", 27.0f) }));
|
||||
triggers.push_back(new TriggerNode("party member critical health", { NextAction("holy light on party", 28.0f) }));
|
||||
triggers.push_back(new TriggerNode("party member almost full health", { NextAction("flash of light on party", ACTION_MEDIUM_HEAL + 5.0f) }));
|
||||
triggers.push_back(new TriggerNode("party member medium health", { NextAction("flash of light on party", ACTION_MEDIUM_HEAL + 6.0f) }));
|
||||
triggers.push_back(new TriggerNode("party member low health", { NextAction("holy light on party", ACTION_MEDIUM_HEAL + 7.0f) }));
|
||||
triggers.push_back(new TriggerNode("party member critical health", { NextAction("holy light on party", ACTION_MEDIUM_HEAL + 8.0f) }));
|
||||
triggers.push_back(new TriggerNode("not sensing undead", { NextAction("sense undead", ACTION_IDLE + 1.0f) }));
|
||||
|
||||
int specTab = AiFactory::GetPlayerSpecTab(botAI->GetBot());
|
||||
if (specTab == 0 || specTab == 1) // Holy or Protection
|
||||
triggers.push_back(new TriggerNode("often", { NextAction("apply oil", 1.0f) }));
|
||||
if (specTab == 2) // Retribution
|
||||
triggers.push_back(new TriggerNode("often", { NextAction("apply stone", 1.0f) }));
|
||||
if (specTab == PALADIN_TAB_HOLY || specTab == PALADIN_TAB_PROTECTION)
|
||||
triggers.push_back(new TriggerNode("often", { NextAction("apply oil", ACTION_IDLE + 1.0f) }));
|
||||
if (specTab == PALADIN_TAB_RETRIBUTION)
|
||||
triggers.push_back(new TriggerNode("often", { NextAction("apply stone", ACTION_IDLE + 1.0f) }));
|
||||
}
|
||||
|
||||
@ -30,3 +30,8 @@ bool BlessingTrigger::IsActive()
|
||||
return SpellTrigger::IsActive() && !botAI->HasAnyAuraOf(target, "blessing of might", "blessing of wisdom",
|
||||
"blessing of kings", "blessing of sanctuary", nullptr);
|
||||
}
|
||||
|
||||
bool NotSensingUndeadTrigger::IsActive()
|
||||
{
|
||||
return !botAI->HasAura("sense undead", bot);
|
||||
}
|
||||
|
||||
@ -77,9 +77,7 @@ class BlessingOnPartyTrigger : public BuffOnPartyTrigger
|
||||
{
|
||||
public:
|
||||
BlessingOnPartyTrigger(PlayerbotAI* botAI)
|
||||
: BuffOnPartyTrigger(botAI, "blessing of kings,blessing of might,blessing of wisdom", 2 * 2000)
|
||||
{
|
||||
}
|
||||
: BuffOnPartyTrigger(botAI, "blessing of kings,blessing of might,blessing of wisdom", 2 * 2000) {}
|
||||
};
|
||||
|
||||
class BlessingTrigger : public BuffTrigger
|
||||
@ -93,7 +91,8 @@ public:
|
||||
class HammerOfJusticeInterruptSpellTrigger : public InterruptSpellTrigger
|
||||
{
|
||||
public:
|
||||
HammerOfJusticeInterruptSpellTrigger(PlayerbotAI* botAI) : InterruptSpellTrigger(botAI, "hammer of justice") {}
|
||||
HammerOfJusticeInterruptSpellTrigger(PlayerbotAI* botAI)
|
||||
: InterruptSpellTrigger(botAI, "hammer of justice") {}
|
||||
};
|
||||
|
||||
class HammerOfJusticeSnareTrigger : public SnareTargetTrigger
|
||||
@ -144,9 +143,7 @@ class CleanseCurePartyMemberDiseaseTrigger : public PartyMemberNeedCureTrigger
|
||||
{
|
||||
public:
|
||||
CleanseCurePartyMemberDiseaseTrigger(PlayerbotAI* botAI)
|
||||
: PartyMemberNeedCureTrigger(botAI, "cleanse", DISPEL_DISEASE)
|
||||
{
|
||||
}
|
||||
: PartyMemberNeedCureTrigger(botAI, "cleanse", DISPEL_DISEASE) {}
|
||||
};
|
||||
|
||||
class CleanseCurePoisonTrigger : public NeedCureTrigger
|
||||
@ -159,9 +156,7 @@ class CleanseCurePartyMemberPoisonTrigger : public PartyMemberNeedCureTrigger
|
||||
{
|
||||
public:
|
||||
CleanseCurePartyMemberPoisonTrigger(PlayerbotAI* botAI)
|
||||
: PartyMemberNeedCureTrigger(botAI, "cleanse", DISPEL_POISON)
|
||||
{
|
||||
}
|
||||
: PartyMemberNeedCureTrigger(botAI, "cleanse", DISPEL_POISON) {}
|
||||
};
|
||||
|
||||
class CleanseCureMagicTrigger : public NeedCureTrigger
|
||||
@ -173,15 +168,15 @@ public:
|
||||
class CleanseCurePartyMemberMagicTrigger : public PartyMemberNeedCureTrigger
|
||||
{
|
||||
public:
|
||||
CleanseCurePartyMemberMagicTrigger(PlayerbotAI* botAI) : PartyMemberNeedCureTrigger(botAI, "cleanse", DISPEL_MAGIC)
|
||||
{
|
||||
}
|
||||
CleanseCurePartyMemberMagicTrigger(PlayerbotAI* botAI)
|
||||
: PartyMemberNeedCureTrigger(botAI, "cleanse", DISPEL_MAGIC) {}
|
||||
};
|
||||
|
||||
class HammerOfJusticeEnemyHealerTrigger : public InterruptEnemyHealerTrigger
|
||||
{
|
||||
public:
|
||||
HammerOfJusticeEnemyHealerTrigger(PlayerbotAI* botAI) : InterruptEnemyHealerTrigger(botAI, "hammer of justice") {}
|
||||
HammerOfJusticeEnemyHealerTrigger(PlayerbotAI* botAI)
|
||||
: InterruptEnemyHealerTrigger(botAI, "hammer of justice") {}
|
||||
};
|
||||
|
||||
class DivineFavorTrigger : public BuffTrigger
|
||||
@ -190,6 +185,14 @@ public:
|
||||
DivineFavorTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "divine favor") {}
|
||||
};
|
||||
|
||||
class NotSensingUndeadTrigger : public BuffTrigger
|
||||
{
|
||||
public:
|
||||
NotSensingUndeadTrigger(PlayerbotAI* botAI) : BuffTrigger(botAI, "not sensing undead") {}
|
||||
|
||||
bool IsActive() override;
|
||||
};
|
||||
|
||||
class TurnUndeadTrigger : public HasCcTargetTrigger
|
||||
{
|
||||
public:
|
||||
@ -201,7 +204,8 @@ DEBUFF_TRIGGER(AvengerShieldTrigger, "avenger's shield");
|
||||
class BeaconOfLightOnMainTankTrigger : public BuffOnMainTankTrigger
|
||||
{
|
||||
public:
|
||||
BeaconOfLightOnMainTankTrigger(PlayerbotAI* ai) : BuffOnMainTankTrigger(ai, "beacon of light", true) {}
|
||||
BeaconOfLightOnMainTankTrigger(PlayerbotAI* ai)
|
||||
: BuffOnMainTankTrigger(ai, "beacon of light", true) {}
|
||||
};
|
||||
|
||||
class SacredShieldOnMainTankTrigger : public BuffOnMainTankTrigger
|
||||
@ -213,34 +217,29 @@ public:
|
||||
class BlessingOfKingsOnPartyTrigger : public BuffOnPartyTrigger
|
||||
{
|
||||
public:
|
||||
BlessingOfKingsOnPartyTrigger(PlayerbotAI* botAI) : BuffOnPartyTrigger(botAI, "blessing of kings", 2 * 2000) {}
|
||||
BlessingOfKingsOnPartyTrigger(PlayerbotAI* botAI)
|
||||
: BuffOnPartyTrigger(botAI, "blessing of kings", 2 * 2000) {}
|
||||
};
|
||||
|
||||
class BlessingOfWisdomOnPartyTrigger : public BuffOnPartyTrigger
|
||||
{
|
||||
public:
|
||||
BlessingOfWisdomOnPartyTrigger(PlayerbotAI* botAI)
|
||||
: BuffOnPartyTrigger(botAI, "blessing of might,blessing of wisdom", 2 * 2000)
|
||||
{
|
||||
}
|
||||
: BuffOnPartyTrigger(botAI, "blessing of might,blessing of wisdom", 2 * 2000) {}
|
||||
};
|
||||
|
||||
class BlessingOfMightOnPartyTrigger : public BuffOnPartyTrigger
|
||||
{
|
||||
public:
|
||||
BlessingOfMightOnPartyTrigger(PlayerbotAI* botAI)
|
||||
: BuffOnPartyTrigger(botAI, "blessing of might,blessing of wisdom", 2 * 2000)
|
||||
{
|
||||
}
|
||||
: BuffOnPartyTrigger(botAI, "blessing of might,blessing of wisdom", 2 * 2000) {}
|
||||
};
|
||||
|
||||
class BlessingOfSanctuaryOnPartyTrigger : public BuffOnPartyTrigger
|
||||
{
|
||||
public:
|
||||
BlessingOfSanctuaryOnPartyTrigger(PlayerbotAI* botAI)
|
||||
: BuffOnPartyTrigger(botAI, "blessing of sanctuary", 2 * 2000)
|
||||
{
|
||||
}
|
||||
: BuffOnPartyTrigger(botAI, "blessing of sanctuary", 2 * 2000) {}
|
||||
};
|
||||
|
||||
class AvengingWrathTrigger : public BoostTrigger
|
||||
@ -248,4 +247,5 @@ class AvengingWrathTrigger : public BoostTrigger
|
||||
public:
|
||||
AvengingWrathTrigger(PlayerbotAI* botAI) : BoostTrigger(botAI, "avenging wrath") {}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -2553,17 +2553,15 @@ void PlayerbotFactory::InitClassSpells()
|
||||
bot->learnSpell(7386, false); // Sunder Armor
|
||||
}
|
||||
if (level >= 30)
|
||||
{
|
||||
bot->learnSpell(2458, false); // Berserker Stance
|
||||
}
|
||||
break;
|
||||
case CLASS_PALADIN:
|
||||
bot->learnSpell(21084, true);
|
||||
bot->learnSpell(635, true);
|
||||
if (level >= 12)
|
||||
{
|
||||
bot->learnSpell(7328, false); // Redemption
|
||||
}
|
||||
if (level >= 20)
|
||||
bot->learnSpell(5502, false); // Sense Undead
|
||||
break;
|
||||
case CLASS_ROGUE:
|
||||
bot->learnSpell(1752, true);
|
||||
@ -2605,17 +2603,11 @@ void PlayerbotFactory::InitClassSpells()
|
||||
bot->learnSpell(686, true);
|
||||
bot->learnSpell(688, false); // summon imp
|
||||
if (level >= 10)
|
||||
{
|
||||
bot->learnSpell(697, false); // summon voidwalker
|
||||
}
|
||||
if (level >= 20)
|
||||
{
|
||||
bot->learnSpell(712, false); // summon succubus
|
||||
}
|
||||
if (level >= 30)
|
||||
{
|
||||
bot->learnSpell(691, false); // summon felhunter
|
||||
}
|
||||
break;
|
||||
case CLASS_DRUID:
|
||||
bot->learnSpell(5176, true);
|
||||
@ -2632,17 +2624,11 @@ void PlayerbotFactory::InitClassSpells()
|
||||
bot->learnSpell(331, true);
|
||||
// bot->learnSpell(66747, true); // Totem of the Earthen Ring
|
||||
if (level >= 4)
|
||||
{
|
||||
bot->learnSpell(8071, false); // stoneskin totem
|
||||
}
|
||||
if (level >= 10)
|
||||
{
|
||||
bot->learnSpell(3599, false); // searing totem
|
||||
}
|
||||
if (level >= 20)
|
||||
{
|
||||
bot->learnSpell(5394, false); // healing stream totem
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user