Files
healer-man/docs/ENEMY_TRIGGERED_SHOUTS_2026-10-06.md
2026-10-06 22:25:34 -04:00

122 lines
6.9 KiB
Markdown

# Enemy triggered shout audit — 2026-10-06
This report covers only separate-victim child spells from Intimidating Shout
5246 and Frightening Shout 19134. It preserves the existing caster-centered
fear source contract and keeps unsupported source effects explicit.
## Pinned client evidence
The Ascension input is
`../LadiksMPQEditor/client-current/area-52/patch-D/DBFilesClient/Spell.dbc`,
SHA-256
`2f77f18b91ffbae32a19568e4bc05ec78ee384b6ba8dd2a6e05f0e97abbb2dce`. The
Epoch input is
`../HealerMan-Storage/pipeline-work/dungeons/epoch-client/DBFilesClient/Spell.dbc`,
SHA-256
`d5cce1a83550dcfa9eb2f0251dbb11fd24c272534b2b1a9b230924a44d817ab3`. Both
use the existing shared patch-S `SpellDuration.dbc` and `SpellRadius.dbc`
fallbacks; Epoch is not represented as carrying untouched sibling support
tables. The matching source pins also live in `enemySourceAuras.ts`.
Direct reads from both `WDBC` inputs confirm raw Spell.dbc field 212 is
`MaxAffectedTargets` (5246 = 5; 19134 = 0) and field 2 is `Dispel` (0 for
both parents and both children). `DamageClass` is field 213; `Attributes2` is
field 6 and is zero on all four rows. The profile signatures below are kept
separate, including Epoch 5246's Attributes1 value 136.
| Parent cast | Explicit child spell | Parent range | Parent area | Area target cap | Parent fear duration: Asc / Epoch | Child control duration: Asc / Epoch |
| --- | --- | ---: | --- | ---: | ---: | ---: |
| 5246 Intimidating Shout | 20511 Intimidating Shout | 8 yd | Caster-centered hostile radius 8 yd | 5 | 5 s / 8 s | Stun 5 s / 8 s |
| 19134 Frightening Shout | 29544 Frightening Shout | 10 yd | Caster-centered hostile radius 8 yd | 0 (unlimited) | 4 s / 6 s | Fear 3 s / 6 s |
Each parent has effect 0 `TRIGGER_SPELL` (effect type 64), target A 6
(`TARGET_UNIT_TARGET_ENEMY`), and the exact child ID shown above. Each child
has target A 6, target B 0. Parent effects 1 and 2 use target A 22
(`TARGET_SRC_CASTER`) plus target B 15 (`TARGET_UNIT_SRC_AREA_ENEMY`) at
radius index 14 (8 yd). The first area aura is fear, aura 7. Effect 2 is aura
31 (`MOD_INCREASE_SPEED`, +25%) and remains unsupported.
Child 20511 is stun aura 12 on both profiles. Ascension also has aura 87
(`MOD_DAMAGE_PERCENT_TAKEN`) for +15% physical damage taken over 5 seconds;
it has no direct damage effect. Epoch 20511 contains only the 8-second stun.
Child 29544 is fear aura 7 only: 3 seconds in Ascension and 6 seconds in
Epoch. It likewise has no direct damage effect. Battle Shout 9128 and
Demoralizing Shouts 16244/13730 have no DBC trigger ID in either selected
profile, so their names do not qualify them for this triggered-child path.
The existing direct aura baseline remains owned by `enemySourceAuras.ts` and
its existing attack-catalog contract. This report does not replace those rows
with the triggered-shout child contracts or claim full implementation of
parent effect 2.
## Targeting and core behavior
The read-only historical source used for the targeting audit is under
`../wow-pvt-server-backups-2/azerothcore-wotlk/src/server/game/Spells/`.
`SpellEffects.cpp` `Spell::EffectTriggerSpell` supplies the parent effect's
`unitTarget` to the child when `NeedsToBeTriggeredByCaster` is true;
`SpellInfo.cpp` returns true when the child requires an explicit unit target.
That establishes one child victim: the parent's explicit hostile victim.
The runtime helper therefore accepts that victim only if the caller's
hostile/range/LOS recheck still considers it eligible. It never chooses a
different secondary target for the child.
The same source's `Spell::SelectEffectImplicitTargets` combines area effects
whose target A/B, implicit conditions and calculated radius match. Here
effects 1 and 2 share the same pair and radius, so one caster-centered area
recipient selection receives their effect mask. `SelectImplicitAreaTargets`
limits that set using `MaxAffectedTargets` when nonzero, then
`AddUnitTarget` merges effect masks when a target GUID already exists. There
is no exclusion of the explicit cast victim from the area result: if it is
also a valid hostile within 8 yards, it can receive both the child and the
parent area aura. Accordingly `planEnemyTriggeredShoutTargets` returns the
eligible explicit child victim separately and preserves the area list
unchanged.
`WorldObjectSpellAreaTargetCheck` applies 3D radius and the base spell target
check; `WorldObjectSpellTargetCheck` applies hostile eligibility. These area
checks do not add a per-recipient line-of-sight test. The parent explicit
victim still follows ordinary explicit-cast checks. Spell.dbc has no
`Attributes2` ignore-LOS flag for these parents. The caller remains
responsible for game-specific visibility/LOS eligibility when forming each
input list; the pure targeting helper does not perform spatial queries.
The area cap applies to the parent area recipients only: 5 for 5246 and no
cap for 19134. The child is a separate triggered cast with one explicit unit
target. No extra max-target cap is applied to the parent's area list, and no
synthetic damage packet is introduced for either child.
## Overlap and lifecycle contract
Parent and child control remain separate named timed auras so control-removal
paths, expiry and caster refresh can retain each sourced timer. The shared utility tag is
`enemy-control-source:<fear|stun>`. Effective shout control is resolved from
currently active tagged auras on the requested target: the aura with the
latest expiry supplies the runtime mechanic/timer, with stun winning an exact
expiry tie. Thus an Ascension 19134 overlap resolves to parent fear through
4 seconds after its child fear expires at 3 seconds; a 5246 child stun wins
when its expiry ties the parent fear. Epoch 19134 ties are both fear, while
Epoch 5246 ties resolve to stun.
All four DBC rows have Dispel 0, so the source does not mark these control
auras as dispellable. The source children have stack amount zero and no
`AURA_UNIQUE` bit in either profile. The project aura policy refreshes an existing same-caster copy and
preserves a different caster's active same-spell application. Removal of a
shout caster retains these four timed control aura IDs on other targets:
`enemy-control:source-spell-20511`, `enemy-control:source-spell-29544`,
`enemy-control:source-spell-5246`, and `enemy-control:source-spell-19134`.
Removing the recipient still removes its auras.
## Boundaries
This source pass does not model parent aura 31's +25% movement speed, immune
target exceptions, creature-specific AoE immunity, random selection ordering
when 5246 has more than five area recipients, or every server/database script
override. Historical SmartAI rows establish source NPC casts but do not change
the DBC target geometry. The runtime's incoming eligible target snapshots
remain authoritative. A client/core difference or changed source pin must
fail the exact signature check rather than broaden behavior by spell name.
Focused verification: `npx vitest run src/game/enemyTriggeredShouts.test.ts
src/game/enemySourceAuras.test.ts`.