Add Unending Breath to Warlock NonCombat Strat (#2074)

# Pull Request

Adds actions and triggers for Warlock class to cast Unending Breath when
swimming, following the existing implementation for Shaman Water
Breathing.

---

## Feature Evaluation

Add triggers for Warlock noncombat strategy for Unending Breath on self
and party.
Triggers should only be active while swimming.
Minimal runtime cost on Warlock bots trigger processing.

---

## How to Test the Changes

- Bring a Warlock bot into water
- It should cast Unending Breath on itself and anyone in the party

## Complexity & Impact

- Does this change add new decision branches?
    - [ ] No
    - [x] Yes (**explain below**)
It adds triggers to Warlock to decide when to cast Unending Breath on
self or party members.

- Does this change increase per-bot or per-tick processing?
    - [ ] No
    - [x] Yes (**describe and justify impact**)
Minimal additional processing for Warlock triggers, same as already
existing triggers for Shaman.

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

- [ ] 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?
    - [ ] No
    - [x] Yes (**explain below**)

Claude was used to explore the codebase to find similar implementations
that already existed.

---

## 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: bashermens <31279994+hermensbas@users.noreply.github.com>
This commit is contained in:
dillyns
2026-02-08 12:36:27 -05:00
committed by GitHub
parent cfb2ed4bf3
commit c9c936d5c1
5 changed files with 46 additions and 0 deletions

View File

@@ -143,6 +143,8 @@ public:
creators["shadow trance"] = &WarlockTriggerFactoryInternal::shadow_trance;
creators["demon armor"] = &WarlockTriggerFactoryInternal::demon_armor;
creators["soul link"] = &WarlockTriggerFactoryInternal::soul_link;
creators["unending breath"] = &WarlockTriggerFactoryInternal::unending_breath;
creators["unending breath on party"] = &WarlockTriggerFactoryInternal::unending_breath_on_party;
creators["no soul shard"] = &WarlockTriggerFactoryInternal::no_soul_shard;
creators["too many soul shards"] = &WarlockTriggerFactoryInternal::too_many_soul_shards;
creators["no healthstone"] = &WarlockTriggerFactoryInternal::HasHealthstone;
@@ -189,6 +191,8 @@ private:
static Trigger* shadow_trance(PlayerbotAI* botAI) { return new ShadowTranceTrigger(botAI); }
static Trigger* demon_armor(PlayerbotAI* botAI) { return new DemonArmorTrigger(botAI); }
static Trigger* soul_link(PlayerbotAI* botAI) { return new SoulLinkTrigger(botAI); }
static Trigger* unending_breath(PlayerbotAI* botAI) { return new UnendingBreathTrigger(botAI); }
static Trigger* unending_breath_on_party(PlayerbotAI* botAI) { return new UnendingBreathOnPartyTrigger(botAI); }
static Trigger* no_soul_shard(PlayerbotAI* botAI) { return new OutOfSoulShardsTrigger(botAI); }
static Trigger* too_many_soul_shards(PlayerbotAI* botAI) { return new TooManySoulShardsTrigger(botAI); }
static Trigger* HasHealthstone(PlayerbotAI* botAI) { return new HasHealthstoneTrigger(botAI); }
@@ -240,6 +244,8 @@ public:
creators["demon armor"] = &WarlockAiObjectContextInternal::demon_armor;
creators["demon skin"] = &WarlockAiObjectContextInternal::demon_skin;
creators["soul link"] = &WarlockAiObjectContextInternal::soul_link;
creators["unending breath"] = &WarlockAiObjectContextInternal::unending_breath;
creators["unending breath on party"] = &WarlockAiObjectContextInternal::unending_breath_on_party;
creators["create soul shard"] = &WarlockAiObjectContextInternal::create_soul_shard;
creators["destroy soul shard"] = &WarlockAiObjectContextInternal::destroy_soul_shard;
creators["create healthstone"] = &WarlockAiObjectContextInternal::create_healthstone;
@@ -313,6 +319,8 @@ private:
static Action* demon_armor(PlayerbotAI* botAI) { return new CastDemonArmorAction(botAI); }
static Action* demon_skin(PlayerbotAI* botAI) { return new CastDemonSkinAction(botAI); }
static Action* soul_link(PlayerbotAI* botAI) { return new CastSoulLinkAction(botAI); }
static Action* unending_breath(PlayerbotAI* botAI) { return new CastUnendingBreathAction(botAI); }
static Action* unending_breath_on_party(PlayerbotAI* botAI) { return new CastUnendingBreathOnPartyAction(botAI); }
static Action* create_soul_shard(PlayerbotAI* botAI) { return new CreateSoulShardAction(botAI); }
static Action* destroy_soul_shard(PlayerbotAI* botAI) { return new DestroySoulShardAction(botAI); }
static Action* create_healthstone(PlayerbotAI* botAI) { return new CastCreateHealthstoneAction(botAI); }