Paladin Seal of wisdom fallback fix for Ret/Prot Paladins (#2147)

# Pull Request

This PR removes the fallback for Seal of Wisdom action from generic
Paladin strategy and moves it to Holy Paladin only. This is necessary
because a paladin who does not have Seal of Wisdom yet who goes low mana
and triggers the seal of wisdom action will end up falling back to Seal
of Righteousness, even though a better seal may be available, such as
Seal of Command.
The fallback is added to Holy Paladin so that low level holy paladins
still use Righteousness until they get Wisdom

---

## Feature Evaluation

Please answer the following:

- Describe the **minimum logic** required to achieve the intended
behavior?
Ret paladin without Seal of Wisdom shouldn't change seals on low mana.
- Describe the **cheapest implementation** that produces an acceptable
result?
Cheapest implementation is to remove seal of wisdom fallback for
non-holy paladins.
- Describe the **runtime cost** when this logic executes across many
bots?
No difference in cost compared to existing logic.
---

## How to Test the Changes

Use a ret paladin bot who has Seal of Command but who does not have Seal
of Wisdom. A paladin under level 38 will do.
Order them to attack something, like a test dummy, until they eventually
run low on mana.

Before this change: The paladin will switch to Seal of Righteousness
when they get low mana.
After this change: The paladin leaves Seal of Command on when they get
low mana.

## Complexity & Impact

Does this change add new decision branches?
- - [x] No
- - [ ] Yes (**explain below**)

Does this change increase per-bot or per-tick processing?
- - [x] No
- - [ ] Yes (**describe and justify impact**)

Could this logic scale poorly under load?
- - [x] No
- - [ ] Yes (**explain why**)
---

## Defaults & Configuration

Does this change modify default bot behavior?
- - [x] No
- - [ ] Yes (**explain why**)

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.
This commit is contained in:
dillyns 2026-03-21 18:19:22 -04:00 committed by GitHub
parent 2b273f6a2c
commit 32af1b95de
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 27 additions and 44 deletions

View File

@ -15,9 +15,6 @@ public:
{
creators["sanctity aura"] = &sanctity_aura;
creators["retribution aura"] = &retribution_aura;
creators["seal of corruption"] = &seal_of_corruption;
creators["seal of vengeance"] = &seal_of_vengeance;
creators["seal of command"] = &seal_of_command;
creators["blessing of might"] = &blessing_of_might;
creators["crusader strike"] = &crusader_strike;
creators["repentance"] = &repentance;
@ -27,36 +24,6 @@ public:
}
private:
static ActionNode* seal_of_corruption([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode(
"seal of corruption",
/*P*/ {},
/*A*/ { NextAction("seal of vengeance") },
/*C*/ {}
);
}
static ActionNode* seal_of_vengeance([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode(
"seal of vengeance",
/*P*/ {},
/*A*/ { NextAction("seal of command") },
/*C*/ {}
);
}
static ActionNode* seal_of_command([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode(
"seal of command",
/*P*/ {},
/*A*/ { NextAction("seal of righteousness") },
/*C*/ {}
);
}
static ActionNode* blessing_of_might([[maybe_unused]] PlayerbotAI* botAI)
{
return new ActionNode(

View File

@ -22,6 +22,9 @@ 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 corruption"] = &seal_of_corruption;
creators["seal of vengeance"] = &seal_of_vengeance;
creators["seal of command"] = &seal_of_command;
creators["seal of wisdom"] = &seal_of_wisdom;
creators["seal of justice"] = &seal_of_justice;
creators["hand of reckoning"] = &hand_of_reckoning;
@ -41,7 +44,6 @@ public:
creators["blessing of wisdom on party"] = &blessing_of_wisdom_on_party;
creators["blessing of sanctuary on party"] = &blessing_of_sanctuary_on_party;
creators["blessing of sanctuary"] = &blessing_of_sanctuary;
creators["seal of command"] = &seal_of_command;
creators["taunt spell"] = &hand_of_reckoning;
creators["righteous defense"] = &righteous_defense;
creators["avenger's shield"] = &avengers_shield;
@ -155,18 +157,39 @@ private:
/*A*/ { NextAction("purify disease on party") },
/*C*/ {});
}
static ActionNode* seal_of_corruption(PlayerbotAI* /* ai */)
{
return new ActionNode("seal of corruption",
/*P*/ {},
/*A*/ { NextAction("seal of vengeance") },
/*C*/ {});
}
static ActionNode* seal_of_vengeance(PlayerbotAI* /* ai */)
{
return new ActionNode("seal of vengeance",
/*P*/ {},
/*A*/ { NextAction("seal of command") },
/*C*/ {});
}
static ActionNode* seal_of_command(PlayerbotAI* /* ai */)
{
return new ActionNode("seal of command",
/*P*/ {},
/*A*/ { NextAction("seal of righteousness") },
/*C*/ {});
}
static ActionNode* seal_of_wisdom(PlayerbotAI* /* ai */)
{
return new ActionNode ("seal of wisdom",
/*P*/ {},
/*A*/ { NextAction("seal of righteousness") },
/*A*/ { NextAction("seal of corruption") },
/*C*/ {});
}
static ActionNode* seal_of_justice(PlayerbotAI* /* ai */)
{
return new ActionNode("seal of justice",
/*P*/ {},
/*A*/ { NextAction("seal of righteousness") },
/*A*/ { NextAction("seal of corruption") },
/*C*/ {});
}
static ActionNode* hand_of_reckoning(PlayerbotAI* /* ai */)
@ -246,13 +269,6 @@ private:
/*A*/ {},
/*C*/ {});
}
static ActionNode* seal_of_command(PlayerbotAI* /* ai */)
{
return new ActionNode("seal of command",
/*P*/ {},
/*A*/ { NextAction("seal of righteousness") },
/*C*/ {});
}
};
#endif

View File

@ -30,7 +30,7 @@ void HealPaladinStrategy::InitTriggers(std::vector<TriggerNode*>& triggers)
new TriggerNode(
"seal",
{
NextAction("seal of wisdom", ACTION_HIGH)
NextAction("seal of wisdom", ACTION_HIGH),
}
)
);