197 lines
12 KiB
Markdown
197 lines
12 KiB
Markdown
# Stockade enemy buff and debuff audit — 2026-10-05
|
||
|
||
Later continuation: NPC stance and ordinary-creature blocking omissions in this
|
||
original investigation are superseded by
|
||
[the stance/blocking implementation](ENEMY_STANCES_BLOCKING_2026-10-05.md).
|
||
The dated investigation below remains source history.
|
||
|
||
This pass records source-backed aura behavior for Enrage 8599, Defensive Stance
|
||
7164, Battle Stance 7165, Demoralizing Shout 16244 and 13730, Battle Shout
|
||
9128, and Improved Blocking 3419. The purpose is to keep these effects from
|
||
becoming direct damage and to expose only the modifiers the current ActiveAura
|
||
runtime can apply without inventing baselines. The profile-specific contracts
|
||
and the supported ActiveAura subset are in
|
||
[`src/game/enemySourceAuras.ts`](../src/game/enemySourceAuras.ts).
|
||
|
||
## Source pins and interpretation
|
||
|
||
Ascension uses the recipe compiler's pinned 3.3.5a patch-D source:
|
||
|
||
`../LadiksMPQEditor/client-current/area-52/patch-D/DBFilesClient/Spell.dbc`
|
||
|
||
SHA-256: `2f77f18b91ffbae32a19568e4bc05ec78ee384b6ba8dd2a6e05f0e97abbb2dce`.
|
||
|
||
Epoch uses the compiler's pinned
|
||
`../HealerMan-Storage/pipeline-work/dungeons/epoch-client/DBFilesClient/Spell.dbc`
|
||
(SHA-256 `d5cce1a83550dcfa9eb2f0251dbb11fd24c272534b2b1a9b230924a44d817ab3`).
|
||
Neither client directory has `SpellDuration.dbc` or `SpellRadius.dbc`, so both
|
||
duration and radius lookups use the shared patch-S fallbacks in the
|
||
compiler: `SpellDuration.dbc` SHA-256
|
||
`eeae44ef0185924f3d6ec57ab2701c66566db86e51ab0bae017a9449126eb3a0`, and
|
||
`SpellRadius.dbc` SHA-256
|
||
`dba6ed2f165f75c84dda5f32ae46b1a01fe562efd88fa51fd19365705c3e6a44`. These
|
||
are compiler support inputs, not claims that Epoch shipped those support
|
||
tables.
|
||
|
||
The six already pinned signatures (7164, 7165, 16244, 13730, 9128, and 3419)
|
||
match the compiler's profile-specific `PINNED_SOURCE_SPELLS` entries in
|
||
`scripts/dungeon-pipeline/compile-campaign-catalog.mjs`. Enrage 8599 was read
|
||
directly from both pinned DBCs because it did not have an entry in that pin map.
|
||
In the table below, every spell has range index 1 and school mask 1; the damage
|
||
class and effect rows are shown where the profiles or target type matter.
|
||
Effect rows use `effect/aura/base/A/B/radius/misc`, with the DBC's base-points
|
||
value (`raw base points + 1`). The inspected `EffectTriggerSpell` fields are
|
||
zero for every row.
|
||
|
||
| Spell | Ascension patch-D signature; duration | Epoch DBC signature; duration |
|
||
| --- | --- | --- |
|
||
| 8599 Enrage | damage class 0; `6/79/+30/1/0/0/1`, `6/138/+30/1/0/0/0`; 120,000 ms | damage class 0; `6/79/+10/1/0/0/1`, `6/138/+30/1/0/0/0`; 120,000 ms |
|
||
| 7164 Defensive Stance | damage class 0; `6/36/0/1/0/0/18`; 180,000 ms | same; 180,000 ms |
|
||
| 7165 Battle Stance | damage class 2; `6/36/0/1/0/0/17`; permanent (`-1`) | same; permanent (`-1`) |
|
||
| 16244 Demoralizing Shout | damage class 1; `6/79/-10/22/15/10/1`; 15,000 ms | damage class 1; `6/99/-20/22/15/10/0`; 30,000 ms |
|
||
| 13730 Demoralizing Shout | damage class 1; `6/166/-15/22/15/10/0`; 30,000 ms | damage class 1; `6/99/-10/22/15/10/0`; 30,000 ms |
|
||
| 9128 Battle Shout | damage class 1; `6/79/+15/20/0/20/1`; 120,000 ms | damage class 1; `6/99/+4/20/0/20/0`; 120,000 ms |
|
||
| 3419 Improved Blocking | damage class 0; `6/51/+75/1/0/0/0`; 6,000 ms | same; 6,000 ms |
|
||
|
||
The numeric target IDs are confirmed against the historical AzerothCore target
|
||
table in `src/server/game/Spells/SpellInfo.cpp`: 1 is caster, 15 is source-area
|
||
enemy, 20 is caster-area party, and 22 is caster source. Therefore 16244 and
|
||
13730 are centered on the caster and select enemies within radius 10; 9128
|
||
selects the caster's party within radius 20; 8599, 7164, 7165, and 3419 target
|
||
the caster. The applicable profile radius is sourced from its DBC or the
|
||
compiler's pinned Epoch fallback.
|
||
|
||
The DBC `Dispel` field is 9 (Enrage) for 8599 and 0 (no dispel category) for the
|
||
other six spells. The DBC `stackAmount` field is 0 for all seven, so no
|
||
multi-stack count is imported. That field does not describe cross-spell
|
||
exclusivity. In historical AzerothCore, `Aura::CanStackWith` rejects another
|
||
copy in the same spell-rank chain, including a copy from a different caster.
|
||
For an already-affected area-aura recipient, a second caster's non-stackable
|
||
application is skipped and does not refresh the first aura; a caster applying
|
||
to itself removes its prior non-stackable copy before adding the new one. The
|
||
runtime uses that same-spell-only rule: repeated casts by the same source
|
||
refresh, another caster cannot refresh an existing recipient, and an owner may
|
||
replace its own application. It adds no exclusivity across 16244 and 13730 just
|
||
because both are named Demoralizing Shout. AzerothCore's shapeshift aura handler
|
||
removes an existing shapeshift aura when a new shapeshift applies, so stance
|
||
form exclusivity is verified; the stance mechanics themselves remain outside
|
||
the current supported subset.
|
||
|
||
No child spell IDs appear in these effect rows. The historical AzerothCore
|
||
`spell_linked_spell.sql`, `spell_proc.sql`, and `spell_script_names.sql` base
|
||
tables also have no rows keyed by these seven IDs. Enrage's second DBC effect
|
||
is melee haste, not a triggered spell.
|
||
|
||
## Exact behavior and runtime boundary
|
||
|
||
Aura types map through AzerothCore's `SpellAuraDefines.h`: 36 is shapeshift,
|
||
51 block chance, 79 damage percent done, 99 flat attack power, 138 melee haste,
|
||
and 166 attack-power percent. Its damage calculation filters aura 79 using
|
||
the aura's school mask; the three aura-79 effects here have `miscValue=1`, so
|
||
they affect physical damage. The descriptor helper maps this mask only when it
|
||
is exactly 1 and returns unsupported for other masks; it does not treat every
|
||
damage-percent aura as physical. AzerothCore resolves aura-99 and aura-166 in
|
||
attack-power recalculation, while aura-51 contributes to block chance. Its
|
||
shapeshift handler owns form replacement.
|
||
|
||
The source-backed modifiers that fit existing ActiveAura stat and damage
|
||
modifiers are:
|
||
|
||
| Spell/profile | Recipient and duration | Modifier |
|
||
| --- | --- | --- |
|
||
| 8599, Ascension | caster, 120 s, Enrage dispel | +30% physical damage dealt; +30 melee-haste percentage points |
|
||
| 8599, Epoch | caster, 120 s, Enrage dispel | +10% physical damage dealt; +30 melee-haste percentage points |
|
||
| 16244, Ascension | caster-area enemies, 10 yd, 15 s | -10% physical damage dealt |
|
||
| 16244, Epoch | caster-area enemies, 10 yd, 30 s | -20 flat attack power |
|
||
| 13730, Ascension | caster-area enemies, 10 yd, 30 s | -15% attack power |
|
||
| 13730, Epoch | caster-area enemies, 10 yd, 30 s | -10 flat attack power |
|
||
| 9128, Ascension | caster-area party, 20 yd, 120 s | +15% physical damage dealt |
|
||
| 9128, Epoch | caster-area party, 20 yd, 120 s | +4 flat attack power |
|
||
|
||
Enrage's melee-haste modifier is in the contract so the combat owner can apply
|
||
it to the source's basic-attack cadence. Spell casts and other ability
|
||
cooldowns must remain unchanged. For Battle Shout, the supported area must
|
||
include the caster and nearby friendly NPCs from the caster's party; applying
|
||
it only to the caster would be an incomplete representation. Debuffs from
|
||
16244 and 13730 apply to each eligible party actor inside the sourced enemy
|
||
area. Effects attach to the resulting aura targets, so `damage dealt` modifiers
|
||
reduce the debuffed actor's outgoing physical damage and stat modifiers adjust
|
||
that actor's attack power.
|
||
|
||
The following are deliberately not materialized as ActiveAura modifiers yet:
|
||
|
||
- 7164 and 7165 select form 18 and 17. They have no direct damage effect or
|
||
child spell; their stance-specific consequences are not encoded by the
|
||
current modifier runtime.
|
||
- 3419 supplies +75 block percentage points, but `npcCombatDefender` currently
|
||
sets NPC `blockPercent` and `blockValue` to zero and the source rows do not
|
||
establish a target block value. Applying the chance alone could report blocks
|
||
without reducing damage, so it is not enabled.
|
||
- Enrage's aura 138 changes melee speed. The current enemy cooldown path does
|
||
not apply haste; only the basic-auto cadence may use this modifier, as stated
|
||
above.
|
||
|
||
The old generated Enrage 8599 effect in Stockade uses a 12,000 ms duration and
|
||
`magnitude: 0.25`. Both conflict with the pinned profile rows: the duration is
|
||
120,000 ms, and its physical damage modifier is +30% in Ascension or +10% in
|
||
Epoch, alongside +30% melee haste. Integrations must take duration and
|
||
modifiers from `enemySourceAuraContract(spellId, profile)`, not preserve those
|
||
legacy approximations. The imported campaign now contains five source-tagged
|
||
Stockade casts (8599 ×1, 16244 ×1, 13730 ×1, 9128 ×2) and one Epoch Enrage cast
|
||
in the Nexus. The remaining verified non-damage rows are no longer represented
|
||
as false direct-hit attacks.
|
||
|
||
## Runtime integration and stacking
|
||
|
||
The current integration routes the supported source modifiers through
|
||
`ActiveAura`. Enrage adjusts only the basic auto-attack cadence, scaling the
|
||
remaining swing phase when it starts or expires; spell and other ability
|
||
cooldowns keep their scheduled times. The Ascension and Epoch profiles stay
|
||
distinct in their damage modifiers. Battle Shout's area includes its caster
|
||
and eligible friendly mobs within 20 yards and line of sight; Demoralizing
|
||
Shout's enemy area includes only eligible player/party actors within 10 yards
|
||
and line of sight. Auras attach to each recipient, so source damage and attack
|
||
power modifiers apply through the recipient's shared actor stats. These
|
||
source-tagged area spells do not create a direct damage packet.
|
||
|
||
Historical AzerothCore's `Unit::GetTotalAuraMultiplier` starts at 1 and applies
|
||
each aura 79 percentage with `AddPct`, multiplying distinct effects. For
|
||
example, Enrage +30% and Battle Shout +15% resolve as `1.30 × 1.15 = 1.495`
|
||
(100 physical damage becomes 149.5 before later rounding), not as a single
|
||
additive +45% bonus. Source-backed percentage modifiers opt into this
|
||
multiplicative behavior; ordinary ActiveAura percentages retain their existing
|
||
summed behavior. Aura 79 is also filtered by the source school mask, which is
|
||
physical-only for these imported rows.
|
||
|
||
The focused runtime and contract checks passed: `npx vitest run
|
||
src/game/enemySourceAuras.integration.test.ts src/game/enemySourceAuras.test.ts`
|
||
(10 tests after the parent added the home-leash boundary regression). The integration cases verify both Enrage profiles, basic-auto phase
|
||
preservation on haste application and expiry, untouched spell cooldowns,
|
||
navigation reset and clean re-engagement, physical-only damage, the two target
|
||
geometries, source-aura non-stacking across Battle Shout casters, and the
|
||
Ascension attack-power reduction on the shared player stat resolver. No full
|
||
suite, build, or live-combat run was part of this audit.
|
||
|
||
## Historical AzerothCore behavior consulted
|
||
|
||
The read-only historical reference is
|
||
`../wow-pvt-server-backups-2/azerothcore-wotlk`:
|
||
|
||
- `src/server/game/Spells/SpellInfo.cpp` defines implicit target reference,
|
||
party/enemy check, and area-selection behavior for IDs 1, 15, 20, and 22.
|
||
- `src/server/game/Spells/Auras/SpellAuraDefines.h` names the aura opcodes;
|
||
`src/server/game/Entities/Unit/Unit.cpp` applies aura 79 to damage and aura
|
||
51 to block chance; `src/server/game/Entities/Unit/StatSystem.cpp` recalculates
|
||
attack power and block chance.
|
||
- `src/server/game/Spells/Auras/SpellAuraEffects.cpp` applies aura 36 and
|
||
removes the old shapeshift form when another form is added.
|
||
- The SQL lookup found no linked-spell, proc, or script-name rows for these
|
||
IDs. The imported Stockade Enrage row is Targorr the Dread (entry 1696). Its
|
||
former generated `durationMs: 12000` and `magnitude: 0.25` values were
|
||
replaced by the source contract and supported modifiers above.
|
||
|
||
No creature baseline, AP value, block value, or unknown stance modifier was
|
||
filled from a guess. The imported supported subset is routed through
|
||
`ActiveAura`; stance and blocking effects remain absent until their required
|
||
runtime behavior and baselines are available.
|