forked from phenom/healer-man
153 lines
9.2 KiB
Markdown
153 lines
9.2 KiB
Markdown
# Ordinary enemy block aura parity — 2026-10-06
|
||
|
||
## Implemented contract
|
||
|
||
[`src/game/enemyBlockAuras.ts`](../src/game/enemyBlockAuras.ts) records the
|
||
source-backed aura inputs used by ordinary AzerothCore Creature blocking:
|
||
|
||
- Aura 51 (`SPELL_AURA_MOD_BLOCK_PERCENT`) adds its percentage-point amount to
|
||
the ordinary creature's 5% block chance.
|
||
- Aura 253 (`SPELL_AURA_MOD_BLOCK_CRIT_CHANCE`) contributes to the separate
|
||
critical-block roll after a block succeeds. The summed amount is truncated
|
||
to an integer for `roll_chance_i`; a successful critical block doubles the
|
||
block value, then the ordinary damage cap applies.
|
||
- Aura 288 (`SPELL_AURA_IGNORE_HIT_DIRECTION`) bypasses the facing check. It
|
||
does not bypass the independent eligibility gates. The hit-table full-block
|
||
spell path still honors `CU_REQ_CASTER_BEHIND_TARGET`; the post-hit direct
|
||
spell path does not add that separate attribute check.
|
||
|
||
`resolveEnemyNpcBlockAuraInputs` returns target-local active values as
|
||
`blockChanceAuraPercent`, `criticalBlockChancePercent`, and
|
||
`ignoresHitDirection`. It sums aura amounts and ignores expired or other-
|
||
target auras. `enemyNpcCriticalBlockChanceForRoll` and
|
||
`enemyNpcBlockValueAfterCritical` expose the integer roll argument and the
|
||
post-roll multiplier as pure helpers. The caller must first resolve a block,
|
||
then make the independent critical-block roll.
|
||
|
||
`supportedEnemyBlockAuraDefinition` returns an importable full-spell aura only
|
||
when every DBC effect is represented. On these source rows, only Improved
|
||
Blocking (3419) meets that rule. Critical Block (47294–47296) and Deterrence
|
||
rows retain their full source signatures and explicit unsupported-sibling
|
||
lists; `enemyBlockAuraInputDefinition` is only for a block-input fixture or a
|
||
deliberately modeled passive. It must not be treated as an imported complete
|
||
spell definition.
|
||
|
||
## Raw source rows
|
||
|
||
The three Spell.dbc files below each have 234 fields. The parser's localized
|
||
field shift applies only at 239 fields, so these rows use shift 0. Aura effects
|
||
below are effect type 6, implicit targets 1/0, mechanic 0, radius 0, and period
|
||
0 unless otherwise stated. Base points are the parsed client amount
|
||
(`basePoints` field plus one). Duration index 0 means permanent; the runtime
|
||
contract represents that as `durationMs: null`.
|
||
|
||
| Spell | Profile | Duration | Present effects (`auraType:basePoints:miscValue`) |
|
||
| --- | --- | ---: | --- |
|
||
| 3419 Improved Blocking | WoW 3.3.5a, Ascension, Epoch | 6,000 ms | `51:75:0` |
|
||
| 47294 Critical Block | WoW 3.3.5a | permanent | `253:20:0`, `107:5:7` |
|
||
| 47295 Critical Block | WoW 3.3.5a | permanent | `253:40:0`, `107:10:7` |
|
||
| 47296 Critical Block | WoW 3.3.5a | permanent | `253:60:0`, `107:15:7` |
|
||
| 47294 Critical Block | Ascension | permanent | `253:100:0`, `107:4:7`, `107:8:3` |
|
||
| 47295 Critical Block | Ascension | permanent | `253:100:0`, `107:7:7`, `107:16:3` |
|
||
| 47296 Critical Block | Ascension | permanent | `253:100:0`, `107:10:7`, `107:25:3` |
|
||
| 47294–47296 Critical Block | Epoch | permanent | Same as the corresponding WoW 3.3.5a row |
|
||
| 67801 Deterrence | WoW 3.3.5a, Epoch | 5,000 ms | `288:100:0`, `185:-100:0` |
|
||
| 67801 Deterrence | Ascension | 60,000 ms | `288:100:0`, `4:0:0`, `27:0:0` |
|
||
| 667801 Deterrence | Ascension | 5,000 ms | `288:100:0`, `185:-100:0`, `27:0:0` |
|
||
| 1167801 Deterrence | Ascension | 5,000 ms | `288:100:0`, `185:-100:0` |
|
||
|
||
This preserves an important profile difference: the stock and Epoch Critical
|
||
Block rows contain one aura-107 sibling; Ascension contains two. No effect 2
|
||
is present on the stock or Epoch rows. Aura 107 effects are preserved as
|
||
unsupported effects because this contract implements critical-block chance,
|
||
not their separate flat spell modifiers (`SPELLMOD_CRITICAL_CHANCE`, misc 7,
|
||
and Ascension `SPELLMOD_EFFECT1`, misc 3). Deterrence's effects besides aura
|
||
288 are also preserved, not silently dropped.
|
||
|
||
A bounded follow-up found that the pinned core's `ApplySpellMod` returns for
|
||
non-player targets (`SpellAuraEffects.cpp:813–816`), after aura 107 reaches the
|
||
spell-modifier path. These siblings are therefore no-ops on that ordinary
|
||
Creature self-buff path. This pass retains the complete-import gate because the
|
||
shared definition API does not enforce that actor/target restriction; a future
|
||
NPC-only importer can use an explicit ordinary-Creature self-target guard. This
|
||
is not evidence for player/party handling or external custom script overrides.
|
||
The source file SHA-256 is
|
||
`107369aa671a26d68081fc65b0066cb00b2cd80dfa2174ddf55bd5919d5db772`;
|
||
`SpellDefines.h` is
|
||
`635a025f615e16b6f10f39aa32d523f9b3d6df3959fdd0e4b49a8250da1db48f`.
|
||
|
||
The local inputs and SHA-256 pins are:
|
||
|
||
| Profile | Spell.dbc path | SHA-256 |
|
||
| --- | --- | --- |
|
||
| WoW 3.3.5a | `../wow-pvt-server-backups-2/wow335a/Data/patch-A.MPQ/DBFilesClient/Spell.dbc` | `57011d528fd66cf39f5ab6fb168e389ab9e4cc1b8050f7201a54239d489b415c` |
|
||
| Ascension | `../LadiksMPQEditor/client-current/area-52/patch-D/DBFilesClient/Spell.dbc` | `2f77f18b91ffbae32a19568e4bc05ec78ee384b6ba8dd2a6e05f0e97abbb2dce` |
|
||
| Epoch | `../HealerMan-Storage/pipeline-work/dungeons/epoch-client/DBFilesClient/Spell.dbc` | `d5cce1a83550dcfa9eb2f0251dbb11fd24c272534b2b1a9b230924a44d817ab3` |
|
||
|
||
All duration indexes use
|
||
`../LadiksMPQEditor/client-current/patch-S/DBFilesClient/SpellDuration.dbc`,
|
||
SHA-256 `eeae44ef0185924f3d6ec57ab2701c66566db86e51ab0bae017a9449126eb3a0`.
|
||
The parsed durations are index 32 = 6,000 ms, index 28 = 5,000 ms, and index
|
||
3 = 60,000 ms.
|
||
|
||
## Non-direct full-hit block boundary
|
||
|
||
One non-direct row is source-proven for a bounded WoW 3.3.5a helper:
|
||
Shield Bash (spell 72) has damage class 2, school mask 1, `attributes0=327696`,
|
||
`attributes3=8` (`COMPLETELY_BLOCKED`), and present effects 68 and 64. Neither
|
||
effect is in the pinned core's direct-damage effect list. The pinned
|
||
`creature_template_spell.sql` assigns spell 72 to creature entries 1540 and
|
||
3739 (rows 582 and 1442).
|
||
|
||
The AzerothCore checkout is pinned at commit
|
||
`e822d718322289dd036fb2daf8867ba41283bf9a`. `SpellMgr.cpp:3214–3222` derives
|
||
`CU_DIRECT_DAMAGE` from its explicit direct/heal effect list;
|
||
`SpellMgr.cpp:3440–3470` sets `CU_REQ_CASTER_BEHIND_TARGET` from an explicit
|
||
spell-ID list that does not include 72. The shipped
|
||
`data/sql/base/db_world/spell_custom_attr.sql` and the checked active world SQL
|
||
updates contain no spell-72 override. The source correction path has no
|
||
spell-72 custom-attribute correction, and no loaded module replaces the
|
||
custom-attribute hook in this checkout. These checks prove only the two
|
||
blocking-relevant bits for this exact source snapshot. The helper records a
|
||
known-bit mask and zero value for those bits; it does not claim that the full
|
||
computed `AttributesCu` word is zero.
|
||
|
||
This contract is available only for spell 72 with the `wow335` source profile.
|
||
It is not an Ascension/Epoch assertion and is not a generic inference from a
|
||
DBC row. Other non-direct candidates remain gated until their exact server
|
||
custom-attribute evidence is imported. A database or core correction outside
|
||
the pinned checkout can change this result.
|
||
|
||
`enemyNpcSourceSpellBlockMetadata(72, "wow335")` returns the metadata used by
|
||
the pure phase classifier. It proves only the two block-relevant
|
||
`AttributesCu` bits through `customAttributeEvidence.knownMask/value`; it never
|
||
fills the unknown remainder of the custom word. The helper returns no row for
|
||
other IDs or source profiles. Its phase and facing-gate behavior has focused
|
||
unit coverage, but no source NPC non-direct spell importer/application has
|
||
been wired in this pass, so this is not runtime Shield Bash coverage.
|
||
|
||
## Historical core pins
|
||
|
||
Read-only source: `../wow-pvt-server-backups-2/azerothcore-wotlk`, commit
|
||
`e822d718322289dd036fb2daf8867ba41283bf9a`.
|
||
|
||
| Source | Verified behavior |
|
||
| --- | --- |
|
||
| `src/server/game/Spells/Auras/SpellAuraDefines.h:114,316,351` | Aura IDs 51, 253, and 288. |
|
||
| `src/server/game/Entities/Unit/Unit.cpp:3276–3307` | Post-hit spell block checks front-or-aura and the critical-block roll uses `roll_chance_i(GetTotalAuraModifier(...253))`. |
|
||
| `src/server/game/Entities/Unit/Unit.cpp:1579–1590,1879–1887` | Successful block removes block value; a successful critical-block roll doubles it. The direct spell packet can already be critical. |
|
||
| `src/server/game/Entities/Unit/Unit.cpp:3364–3396` | Hit-table full block requires the blockable attribute and absence of the direct-damage custom bit; the behind-required custom bit limits the aura-facing exception. |
|
||
| `src/common/Utilities/Random.h:63–66` | `roll_chance_i` compares an integer chance with an inclusive 0–99 roll. |
|
||
| `src/server/game/Spells/SpellMgr.cpp:3214–3222,3440–3470` | Direct-damage effect derivation and the explicit caster-behind spell list. |
|
||
| `data/sql/base/db_world/creature_template_spell.sql:582,1442` | Source NPC spell assignments for Shield Bash spell 72. |
|
||
|
||
## Validation
|
||
|
||
Focused source-aura, block-helper, and `damageMob` integration tests are
|
||
`src/game/enemyBlockAuras.test.ts`, `src/game/enemyBlocking.test.ts`, and
|
||
`src/game/enemyBlockAuraRuntime.integration.test.ts`. They verify profile rows,
|
||
unsupported siblings, target-local duration behavior, behind-facing aura
|
||
input for player and party attacks, the separate critical-block result, and
|
||
the native RoM exclusion. The no-block flag is covered in the pure source gate
|
||
tests in `enemyBlocking.test.ts`.
|