6.3 KiB
Stockade Rend periodic damage source audit — 2026-10-05
This adds a source-backed timing and amount descriptor for Stockade Rend spells 6547 and 16509. The active Stockade catalog uses the Ascension patch-D profile; the distinct Epoch profile is retained in the helper so imports cannot silently reuse the wrong 6547 amount.
Spell rows
| Profile | Spell | Stockade users | Duration | Tick interval/count | BasePoints / DieSides | Raw tick before core scaling | Creature-level scaling |
|---|---|---|---|---|---|---|---|
| Ascension patch-D | 6547 | Defias Inmate (1708) | 15 s | 3 s / 5 | 13 / 1 | 14 | No |
| Ascension patch-D | 16509 | Captive (1707), Prisoner (1706), Convict (1711) | 15 s | 3 s / 5 | 26 / 1 | 27 | Yes |
| Epoch client | 6547 | Separate Epoch profile | 15 s | 3 s / 5 | 9 / 1 | 10 | No |
| Epoch client | 16509 | Separate Epoch profile | 15 s | 3 s / 5 | 26 / 1 | 27 | Yes |
Each row has effect 6 (APPLY_AURA) with aura 3 (PERIODIC_DAMAGE), effect
mechanic 15 (BLEED), implicit target A 6 and no secondary target. The shared
SpellDuration row 8 is [8, 15000, 0, 15000]; the Spell.dbc rows use duration
index 8 and period 3000 ms. School mask 1 is physical, damage class 2 is melee,
and Spell.dbc StackAmount is 0 (one active stack).
EffectRealPointsPerLevel is 0 on all four rows. BasePoints is stored one
below its effective value; AzerothCore SpellEffectInfo::CalcValue adds the
1..DieSides roll, so DieSides 1 yields the raw amounts above. These are inputs
before core damage modifiers. Spell 16509 also carries
SPELL_ATTR0_SCALES_WITH_CREATURE_LEVEL in both DBC profiles, with
BaseLevel=SpellLevel=20 and MaxLevel=0. For a non-player caster whose level
differs from 20, the referenced core scales that raw amount by
CreatureBaseStats.BaseDamage[caster level][creature expansion] / CreatureBaseStats.BaseDamage[spell level 20][creature expansion], then truncates
to int32. Spell 6547 has no such attribute. No spell_bonus_data row exists
for either spell in the inspected core SQL snapshot.
The new helper resolves that 16509 ratio only when both exact class-level rows
and the creature template are present. It reads BaseDamage directly; it does
not fold in CreatureTemplate.damageModifier, attack power, weapon variance,
or swing time. A missing template or stats row returns an explicit unsupported
result; the source-tagged runtime fails closed instead of inventing a scale.
Caster damage-done modifiers are snapshotted at aura application. Target
damage-taken modifiers remain dynamic at each pulse.
Runtime contract
The source effect is periodic-only, so a cast must not create an immediate
direct-damage packet. For a fresh aura, schedule the first pulse after 3000 ms
and the fifth pulse at 15000 ms. Same-caster recasts keep at most one stack and
refresh the duration and tick count. An ordinary recast restarts the tick phase,
so its next pulse is three seconds later. The core preserves the old phase only
for casts marked TRIGGERED_NO_PERIODIC_RESET. Separate casters may retain
independent bleed auras on the same target.
Core applies DOT done/taken modifiers, then checks armor. Its
Unit::IsDamageReducedByArmor explicitly exempts periodic effects whose
mechanic mask includes BLEED; therefore the runtime needs an armor-only bypass
for these pulses. Do not use targetMitigationSnapshotted for this purpose,
because that also skips resistance. The attack remains physical/melee typed for
the sourced cast and hit table; the periodic pulses use the existing common
periodic damage resolution.
The generated catalog currently has authored attack damageMultiplier values
for the Rend cast rows. Those are not DBC periodic tick amounts. Keep any
source-level cast scalar separate from the periodic amount. The game may still
apply its outer entity mob.damageMultiplier after resolving the source tick.
Integration points
src/game/enemyPeriodicDamage.tsprovides the exact Ascension patch-D and Epoch source profiles, five-tick schedule helper, armor and stack metadata, and NPC core scaling calculation for 6547/16509.src/game/azerothCoreReference.tsexposes the pinned template/class-levelBaseDamageinput with no template multiplier. The strict helper rejects levels outside 1–80, missing templates, invalid expansion indices, and absent class-level rows.- The campaign compiler/runtime adapter should select
ascension-patch-dfor the active Stockade catalog and preserve theepoch-clientvariant only for Epoch imports. Serialize the source identity (spellIdplus profile) and let runtime resolve it through this helper. Emit no direct damage effect; carryperiodicIgnoresArmorto tick resolution. If 16509 lacks a source template or class-level base-damage row, omit that source effect instead of inventing a ratio or substituting the old attack scalar.
The runtime integration tests cover player and party NPC defenders in both WoW-compatible and native RoM stat modes, the application hit gate, five full pulses, armor bypass, refresh, independent casters and magic-dispel exclusion. The fourteen integration checks also verify caster bonus expiry/gain after application and changing target-side damage-taken modifiers. Nine pure source contract/amount checks pass separately.
Source pins
The Ascension Spell.dbc is
../LadiksMPQEditor/client-current/area-52/patch-D/DBFilesClient/Spell.dbc,
SHA-256 2f77f18b91ffbae32a19568e4bc05ec78ee384b6ba8dd2a6e05f0e97abbb2dce.
The Epoch Spell.dbc is
../HealerMan-Storage/pipeline-work/dungeons/epoch-client/DBFilesClient/Spell.dbc,
SHA-256 D5CCE1A83550DCFA9EB2F0251DBB11FD24C272534B2B1A9B230924A44D817AB3.
Neither profile has a sibling SpellDuration.dbc; both use the established
patch-S duration fallback, SHA-256
EEAE44EF0185924F3D6EC57AB2701C66566DB86E51AB0BAE017A9449126EB3A0.
Core behavior was checked in the read-only historical AzerothCore reference:
src/server/game/Spells/SpellInfo.cpp (SpellEffectInfo::CalcValue),
src/server/game/Spells/Spell.cpp (the ordinary-cast periodic-reset flag),
src/server/game/Spells/Auras/SpellAuraEffects.cpp (periodic setup, ticks, and
damage mitigation), src/server/game/Spells/Auras/SpellAuras.cpp (refresh and
stack behavior), and src/server/game/Entities/Unit/Unit.cpp
(_TryStackingOrRefreshingExistingAura and IsDamageReducedByArmor). These
files are source references, not HealerMan runtime dependencies.