129 lines
8.1 KiB
Markdown
129 lines
8.1 KiB
Markdown
# Enemy weapon debuffs source audit — 2026-10-05
|
||
|
||
This note records the source contract for enemy Disarm (6713) and Infected
|
||
Wound (17230). The active game uses the selected Ascension or Epoch `Spell.dbc`
|
||
profile; the repository compiler's source rows are in
|
||
`scripts/dungeon-pipeline/compile-campaign-catalog.mjs`, and the pure contracts
|
||
and channel predicates are in `src/game/enemyWeaponDebuffs.ts`.
|
||
Character-side Disarm checks are in `src/game/enemyDisarmRuntime.ts`.
|
||
|
||
## Pinned client rows
|
||
|
||
The Ascension source is
|
||
`../LadiksMPQEditor/client-current/area-52/patch-D/DBFilesClient/Spell.dbc`,
|
||
SHA-256 `2f77f18b91ffbae32a19568e4bc05ec78ee384b6ba8dd2a6e05f0e97abbb2dce`.
|
||
The Epoch source is
|
||
`../HealerMan-Storage/pipeline-work/dungeons/epoch-client/DBFilesClient/Spell.dbc`,
|
||
SHA-256 `d5cce1a83550dcfa9eb2f0251dbb11fd24c272534b2b1a9b230924a44d817ab3`.
|
||
The pinned duration and radius fallback tables are the shared patch-S tables
|
||
recorded in `src/game/enemySourceAuras.ts`.
|
||
|
||
Both profiles define Disarm 6713 as range index 2, physical school mask 1,
|
||
melee damage class 2, mechanic 3, duration 5 seconds, zero stacks, no dispel,
|
||
and `EquippedItemClass = -1` (no caster weapon requirement). Ascension has
|
||
Aura 67 (main-hand) and Aura 278 (ranged); Epoch has Aura 67 only. Aura 254
|
||
(off-hand) is absent from both rows. These effects disable only the named
|
||
weapon attack channels; they do not silence spell casts. The profile helper
|
||
requires the target to have at least one affected usable weapon slot before
|
||
application. For a player, an already-disarmed slot is no longer usable for
|
||
this check, so a repeated cast may fail before refreshing that slot; a creature
|
||
target is checked by the presence of its virtual item slot instead. When a cast
|
||
is accepted, the zero-stack aura refreshes its duration. The source-derived
|
||
Disarm spell itself applies only after its melee hit result lands.
|
||
|
||
Both profiles define Infected Wound 17230 as range index 2, Nature school mask
|
||
8, damage class 0, duration 300 seconds, zero stacks, Disease dispel type 3,
|
||
and no caster weapon requirement. Its single Aura 14 effect has amount +6 and
|
||
misc value 1 (physical school mask). Aura 14 adds six flat damage to matching
|
||
physical packets; it is not a six-percent modifier. The aura refreshes without
|
||
stacking and can be removed by a friendly Disease dispel. As a damage-class
|
||
NONE aura-only spell, the AzerothCore hit-result path has no miss/dodge roll
|
||
for it after its ordinary immunity/evade checks. A caller modeling it as part
|
||
of a separate landed weapon attack must use that attack result as its own gate.
|
||
|
||
## Historical core behavior
|
||
|
||
The sibling `../wow-pvt-server-backups-2/azerothcore-wotlk` tree is used only
|
||
as read-only behavior evidence:
|
||
|
||
- `src/server/game/Spells/SpellInfo.cpp` checks the target's matching weapon
|
||
channels for mechanic Disarm. Players use a usable equipped weapon; creatures
|
||
use virtual item slots. Main-hand, off-hand, and ranged channels are checked
|
||
independently.
|
||
- `src/server/game/Spells/Auras/SpellAuraEffects.cpp` maps Aura 67 to main-hand,
|
||
Aura 254 to off-hand, and Aura 278 to ranged. Applying a channel removes the
|
||
player's item-dependent aura and damage contribution, keeps the item
|
||
equipped, then sets the corresponding unit flag. Creatures with configured
|
||
equipment recalculate their physical damage. Clearing the aura reverses the
|
||
temporary weapon changes.
|
||
- `src/server/game/Entities/Unit/Unit.h` maps those flags through
|
||
`CanUseAttackType`. `Unit::AttackerStateUpdate` does not gate ordinary main-hand
|
||
swings on that flag, so the character still makes an unarmed main-hand swing.
|
||
`Player::_ApplyWeaponDamage` clears disarmed ranged weapon damage and resets
|
||
its delay; for a non-feral main hand it sets base damage to 1–2 and attack
|
||
time to 2000 ms while preserving equipped item stats. Feral forms return
|
||
before that weapon reset. `Spell.cpp` chooses
|
||
melee `m_attackType` as main-hand by default or off-hand when the spell has
|
||
`REQUIRES_OFF_HAND_WEAPON`; ranged spells use the ranged channel only when
|
||
marked as ranged-weapon spells. The source flags for strict main-hand and
|
||
off-hand requirements are Spell AttributesEx3 bits `0x00000400` and
|
||
`0x01000000`. NPC `CheckItems` rejects a damage-class melee/ranged spell when
|
||
its selected attack channel is unavailable. Player `CheckItems` checks
|
||
explicit item requirements through `GetUseableItemByPos`; class `-1` passes
|
||
without an equipment gate, while class-2 requirements scan usable matching
|
||
weapons across main-hand, off-hand, and ranged slots. A matching off-hand
|
||
weapon therefore keeps a generic class-2 requirement usable under Ascension
|
||
or Epoch Disarm. For a nonpassive aura spell, the core also preserves casting
|
||
when the matching item remains equipped but Disarm made it unusable; the
|
||
explicit strict main/off-hand attribute checks still require that slot's
|
||
weapon. `Item::IsFitToSpellRequirements` applies class, subclass, and
|
||
inventory-type masks.
|
||
- `Unit.cpp` applies Aura 14 through `MeleeDamageBonusTaken` for weapon damage,
|
||
before armor mitigation. Non-direct spell packets, including periodic packets,
|
||
reach `SpellBaseDamageBonusTaken` through `SpellDamageBonusTaken` and get the
|
||
flat amount when the aura's misc school mask overlaps. The direct spell
|
||
damage path returns before `SpellBaseDamageBonusTaken`, so this audit does not
|
||
claim a bonus for ordinary direct magic spells. This aura has no charges, so the core's special
|
||
charged-aura DoT exclusion does not apply. The bonus enters before armor
|
||
mitigation; melee/ranged spell block follows armor, and damage absorbs resolve
|
||
after the damage calculation.
|
||
- `Unit::SpellHitResult` sends Disarm's melee damage class through melee miss,
|
||
dodge, and parry resolution. Infected Wound's damage class is NONE and its
|
||
only effect is an aura, so it does not take that melee result path.
|
||
|
||
The contract deliberately does not turn Disarm into root, stun, silence, or a
|
||
general physical-action lock. Runtime callers own weapon-specific equipment
|
||
state, resolved spell hit outcomes, armor/block/absorb ordering, and aura
|
||
application/removal.
|
||
|
||
The player Disarm handler removes weapon-dependent auras and recalculates the
|
||
weapon damage contribution while the item remains equipped. It does not call
|
||
the item-stat removal routine, so the weapon's equipped STR/AP/stamina
|
||
modifiers remain. The helper `enemyDisarmInvalidatesAbilityRequirement` models
|
||
explicit spell item class and subclass gates from currently usable equipped
|
||
items; it leaves requirements with item class `-1` unblocked and only reports a
|
||
Disarm-caused failure when every matching item is in a channel this source row
|
||
disables. `enemyDisarmBlocksAbilityCast` adds the core exception for
|
||
nonpassive aura casts and the strict main/off-hand flags. Runtime attack checks
|
||
derive channels from the unexpired exact `enemy-disarm:<profile>:<slot>` tags;
|
||
they never mutate saved equipment or nonweapon stats. Ascension item-requirement
|
||
metadata uses the corrected WotLK Spell.dbc fields 68/69/70 (class, subclass
|
||
mask, inventory mask). The previous generator read 67/68, which incorrectly
|
||
exported class 0 and a subclass value from the class column; regeneration
|
||
changed only those three equipped-item fields and the generated timestamp.
|
||
WoW-ruleset main-hand auto damage uses the source unarmed 1–2 base and 2-second
|
||
delay while retaining character AP and other equipped stats; an unaffected
|
||
off-hand remains active, and feral forms keep their form profile. Ranged auto
|
||
channels named by the active source profile are suppressed. Native RoM unarmed
|
||
damage is left to its existing amount path because no bound core formula was
|
||
verified. This pass also does not claim complete removal of all weapon-dependent
|
||
item aura bonuses or generic ability formulas that derive damage from raw weapon
|
||
stats.
|
||
|
||
## Focused validation
|
||
|
||
Run `npx vitest run src/game/enemyWeaponDebuffs.test.ts src/game/enemyDisarmRuntime.test.ts src/game/enemyDisarmRuntime.integration.test.ts`
|
||
for profile signatures, target/channel eligibility, refresh/dispel, cast gates,
|
||
metadata projection, and pre-mitigation school matching. Player and companion
|
||
execution are additionally covered by their focused integration tests.
|