146 lines
7.9 KiB
Markdown
146 lines
7.9 KiB
Markdown
# Enemy Defensive and Battle Stance audit — 2026-10-05
|
|
|
|
This audit covers the Stockade enemy stance casts Defensive Stance 7164 and
|
|
Battle Stance 7165. Their form auras are state, not direct damage. The reviewed
|
|
profile-specific rows and the ActiveAura-supported subset are in
|
|
[`src/game/enemyStances.ts`](../src/game/enemyStances.ts).
|
|
|
|
## Pinned client rows
|
|
|
|
The Ascension source is the recipe compiler's pinned 3.3.5a patch-D table:
|
|
|
|
`../LadiksMPQEditor/client-current/area-52/patch-D/DBFilesClient/Spell.dbc`
|
|
|
|
SHA-256: `2f77f18b91ffbae32a19568e4bc05ec78ee384b6ba8dd2a6e05f0e97abbb2dce`.
|
|
|
|
Epoch uses the compiler's pinned table:
|
|
|
|
`../HealerMan-Storage/pipeline-work/dungeons/epoch-client/DBFilesClient/Spell.dbc`
|
|
|
|
SHA-256: `d5cce1a83550dcfa9eb2f0251dbb11fd24c272534b2b1a9b230924a44d817ab3`.
|
|
Both profiles use the compiler's shared patch-S `SpellDuration.dbc` fallback
|
|
for duration indices because neither client folder contains that table. Its
|
|
SHA-256 is `eeae44ef0185924f3d6ec57ab2701c66566db86e51ab0bae017a9449126eb3a0`.
|
|
|
|
The two NPC casts have the same Spell.dbc behavior in both profiles:
|
|
|
|
| Spell | Effect row (`effect/aura/base/misc/trigger`) | Duration | Stance masks |
|
|
| --- | --- | --- | --- |
|
|
| 7164 Defensive Stance | `6/36/0/18/0` | 180,000 ms | required `0/0`, excluded `0/0` |
|
|
| 7165 Battle Stance | `6/36/0/17/0` | permanent (`-1`) | required `0/0`, excluded `0/0` |
|
|
|
|
Both have range index 1, school mask 1, damage class 0 for 7164 and 2 for
|
|
7165, dispel 0, stack amount 0, and Attribute0 327696. Their equipped-item
|
|
class is -1 with subclass and inventory masks 0. The direct effects target self
|
|
(`targetA=1`, `targetB=0`), use radius index/value 0, mechanic 0, and period 0.
|
|
That attribute value does not include AzerothCore's `SPELL_ATTR0_NOT_SHAPESHIFT`
|
|
bit (`0x00010000`). The casts themselves therefore have no source stance mask
|
|
or “not while shapeshifted” restriction in these rows. This statement applies
|
|
to 7164 and 7165 only; it does not infer restrictions for unrelated abilities.
|
|
|
|
## Server-linked passive rows
|
|
|
|
The historical AzerothCore form handler links the forms to passive spells in
|
|
`src/server/game/Spells/Auras/SpellAuraEffects.cpp`:
|
|
|
|
- form 18 → Defensive Stance Passive 7376;
|
|
- form 17 → Battle Stance Passive 21156.
|
|
|
|
This is a server-side mapping. Neither stance cast has a nonzero
|
|
`EffectTriggerSpell` in either profile. Both child rows have Attribute0 327888,
|
|
the passive flag, and zero required/excluded stance masks. Their actual effect
|
|
rows differ by client profile:
|
|
|
|
| Child passive | Ascension patch-D | Epoch client |
|
|
| --- | --- | --- |
|
|
| 7376 Defensive Stance Passive | `6/87/-10/127/0`, `6/79/-5/127/0`, `6/4/+42/127/0` | `6/87/-10/127/0`, `6/79/-5/127/0`, `6/10/+45/127/0` |
|
|
| 21156 Battle Stance Passive | `6/10/0/127/0`, `6/280/0/0/0` | `6/10/-20/127/0` |
|
|
|
|
Rows use `effect/aura/base points/misc/trigger`. The final value in each row is
|
|
zero: these passive rows also have no triggered child spell. A separate player
|
|
stance spell such as 2457 is not a substitute for these NPC rows; its own
|
|
profile rows contain additional effects and are not the source cast IDs here.
|
|
|
|
The passive scalar fields are identical in both profiles: dispel 0, duration
|
|
index 0, range index 1, school mask 1, damage class 0, stack amount 0,
|
|
equipped-item class -1 with subclass and inventory masks 0, and required and
|
|
excluded stance masks 0/0. Each active effect is type 6, targets self
|
|
(`targetA=1`, `targetB=0`), has mechanic 0, radius index/value 0, period 0, and
|
|
trigger spell 0. The helper pins these scalar fields alongside each profile's
|
|
effect rows so the campaign compiler can compare the complete child source.
|
|
|
|
For compiler drift checks, the WDBC scalar field indices are: `Dispel=2`,
|
|
`Attribute0=4`, `ShapeshiftMask=12..13`, `ShapeshiftExclude=14..15`,
|
|
`DurationIndex=40`, `RangeIndex=46`, `StackAmount=49`,
|
|
`EquippedItemClass=68`, `EquippedItemSubclassMask=69`,
|
|
`EquippedItemInventoryMask=70`, `DamageClass=213`, and `SchoolMask=225`.
|
|
The three per-effect `EffectTriggerSpell` fields are `116..118`; active effect
|
|
rows also use `Effect=71+j`, `BasePoints=80+j`, `Mechanic=83+j`,
|
|
`ImplicitTargetA=86+j`, `ImplicitTargetB=89+j`, `RadiusIndex=92+j`,
|
|
`Aura=95+j`, `Period=98+j`, and `MiscValue=110+j`. In the campaign compiler,
|
|
array fields at index 77 or greater shift by six only when a Spell.dbc has at
|
|
least 239 fields. Both pinned client tables have 234 fields, so none of these
|
|
indices shift for the current Ascension or Epoch data; stance and equipped-item
|
|
fields are below 77 and never use that localized-string adjustment.
|
|
|
|
Aura 79 is percent damage done, aura 87 is percent damage taken, and aura 10
|
|
modifies threat. Their `miscValue` 127 covers all schools. The runtime can
|
|
therefore apply Defensive Stance's shared `-10%` damage taken and `-5%` damage
|
|
dealt in both profiles. Epoch's passive rows additionally supply `+45%` threat
|
|
in Defensive Stance and `-20%` threat in Battle Stance. HealerMan already has a
|
|
generic `stat: "threat"` resolver used by party and summon threat generation,
|
|
so these profile-specific scalars are retained in the helper. Current combat
|
|
threat tables record party and summon threat against hostile mobs; hostile NPCs
|
|
have no outgoing-threat consumer in the current combat runtime. The two threat
|
|
modifiers therefore do not change direct enemy hits, party threat, or the
|
|
current threat tables.
|
|
|
|
Ascension's aura 4 row on 7376 is `DUMMY` with base points +42. No
|
|
spell-specific `HandleAuraDummy` case, server script registration, linked spell,
|
|
or triggered child was found for 7376, so its meaning is not guessed. Aura 280
|
|
on Ascension's 21156 row has base points 0; it has no numerical delta and is
|
|
kept as source metadata without an unsupported-effect warning. Aura 10 with
|
|
base points 0 on that same row is also a sourced zero. No defensive or battle
|
|
stance row is treated as an NPC direct hit.
|
|
|
|
## Apply, replacement, expiry, and removal
|
|
|
|
In `SpellAuraEffects.cpp`, applying a new shapeshift removes an existing
|
|
shapeshift aura before setting the new form. The form boost handler applies the
|
|
mapped passive only when the form changes and removes that owned passive when
|
|
the stance aura is removed. The two stances are therefore mutually exclusive;
|
|
the helper uses the `enemy-warrior-stance` exclusive group to preserve that
|
|
state. Reapplying 7164 refreshes its timed form aura; 7165 remains until another
|
|
form replaces it or it is explicitly removed.
|
|
|
|
When a warrior stance aura is removed, AzerothCore caps Rage to its computed
|
|
stance removal value. Player-only spellbook bonuses contribute to that value;
|
|
an ordinary NPC has no player spellbook contribution, so the default cap is
|
|
zero. On expiry or removal with no replacement stance, the server also clears
|
|
the form. The current enemy helper records the sourced form and duration; it
|
|
does not invent a creature Rage baseline or treat the passive DUMMY row as
|
|
resource regeneration. Its aura uses the shared `enemy-source-spell-<id>` ID
|
|
format and carries utility tags for the form and linked passive ID, allowing
|
|
existing source-aura cleanup and telemetry to identify it.
|
|
|
|
## Historical source checked
|
|
|
|
Read-only reference: `../wow-pvt-server-backups-2/azerothcore-wotlk`.
|
|
|
|
- `src/server/game/Spells/Auras/SpellAuraEffects.cpp`: form-to-passive mapping,
|
|
child aura cleanup, replacement of existing shapeshift auras, and stance Rage
|
|
reset on removal.
|
|
- `src/server/game/Spells/SpellInfo.cpp`: `CheckShapeshift` reads
|
|
`ShapeshiftMask`, `ShapeshiftExclude`, and `NOT_SHAPESHIFT`.
|
|
- `src/server/game/Spells/Auras/SpellAuraDefines.h`: aura IDs 4, 10, 79, 87,
|
|
and 280.
|
|
- `src/server/game/Combat/ThreatManager.cpp`: aura 10 is consumed as a
|
|
multiplicative threat modifier by school mask.
|
|
- `src/server/game/Spells/Auras/SpellAuraEffects.cpp` and the server scripts
|
|
plus SQL update tree: no 7376-specific dummy effect or linked-spell consumer
|
|
was found.
|
|
|
|
The targeted helper tests check both profile rows, exclusivity, supported
|
|
damage/threat modifiers, and the permanent versus timed duration. No full test
|
|
suite, build, or live combat run is part of this source audit.
|