53 lines
7.6 KiB
Markdown
53 lines
7.6 KiB
Markdown
# WoW Death Knight Blood Gorged
|
||
|
||
## Source precedence and confirmed values
|
||
|
||
The local generated talent node `talent-2034` is the primary source. It has five ranks, using spell IDs `61154`–`61158`, and each rank links two child spells. The generated rank tooltip says: “When you are above 75% health, you deal N% more damage. In addition, your attacks ignore up to N% of your opponent's armor at all times.” The values for N are 2%, 4%, 6%, 8%, and 10% at ranks 1–5.
|
||
|
||
The child links are `50096`, `50108`–`50111` for the damage bonus and `61274`–`61278` for armor penetration. Both local `Spell.dbc` copies checked (the patch-D DBC used by the talent-generation command and the original patch-A DBC) agree on these payloads:
|
||
|
||
- Damage children use aura type `79`, school mask `127`, and base values 2/4/6/8/10. Their descriptions retain the “above 75% health” gate.
|
||
- Armor children use aura type `280` and base values 2/4/6/8/10. The generated tooltip says this part applies “at all times.”
|
||
- Both child auras use Death Knight spell family `15` and the effect family mask `[0x01400001, 0, 0]`.
|
||
|
||
The numeric payloads come from local generated rows and client DBC data; WotLKDB was not needed. The local historical AzerothCore reference labels aura type `79` as percent damage done and aura type `280` as percent armor penetration. Those names corroborate the local numeric effects; they do not replace the project DBC values.
|
||
|
||
## Trigger and family-mask behavior
|
||
|
||
Blood Gorged is a passive rank effect, not a random proc. The generated ranks have no proc cooldown, charges, or duration. The simulator helper reads the rank values and child IDs from the generated talent row. It treats “above 75%” as a strict comparison at outgoing-hit resolution: exactly 75% health receives no damage bonus. The armor penetration component is independent of current health.
|
||
|
||
The client DBC class mask is narrower than the prose tooltip. In local Death Knight spell family 15 data, its first word intersects Plague Strike (`0x1`), Blood Strike (`0x400000`), and Heart Strike (`0x1000000`). A spell must match family 15 and have at least one bit intersect the mask. The helper preserves this gate for both child effects; it does not turn the tooltip into an unconditional bonus for every Death Knight ability. Aura type 280 only affects the physical armor calculation, while the aura’s class mask remains the same.
|
||
|
||
The historical AzerothCore reference has a fork-specific `SpellInfoCorrections.cpp` override for armor child spells `61274`–`61278`. Its comment says it adds Death Strike and Rune Strike to the armor-penetration class mask. The local patch-A and patch-D DBCs do not contain those added bits, so this preparation follows the local client DBC mask and does not import the fork override. The discrepancy is recorded here because it changes which attacks receive armor penetration.
|
||
|
||
## Runtime integration boundary and limits
|
||
|
||
Player and generated-companion hits now share Blood Gorged handling in `combatStore.ts`. `resolveAndDamageMobInWork` looks up the selected raw `dbcSpellId`, obtains the source actor's talent rank and current health, then applies the damage bonus once to the outgoing amount only when health is strictly above 75%. `resolvePlayerDamageResult` adds the unconditional armor-penetration percentage to the attacker's existing armor-penetration stat; the normal physical armor calculation then consumes it. The damage rider never changes the armor input or applies itself again after the roll.
|
||
|
||
Player casts already use the rolled-hit resolver. `partyRuntime.ts` now selects it for a non-periodic direct damage effect only when a companion Death Knight has Blood Gorged ranks and the actual selected spell ID matches the local family mask. It passes that rank's `dbcSpellId` in the roll context; this matters because a party action ID alone does not preserve the chosen spell rank. The three eligible actions are physical strikes, so this routed event uses the melee attack table. Other companion actions and auto-attacks remain on their existing path. Periodic events do not receive Blood Gorged, and unlisted IDs or known nonmatching IDs such as Death Strike remain ineligible. This keeps the raw `damageMobInWork` route from receiving a second application.
|
||
|
||
The generated tooltip and DBC establish the percentage values and mask, not fractional-damage rounding; the simulator keeps the existing damage rounding in its normal hit resolver. The DBC mask itself does not enumerate names; the exact eligible local rows are listed above. No Death Strike or Rune Strike correction from a non-stock fork is added.
|
||
|
||
## Local DBC family mapping and catalog cross-check
|
||
|
||
The generated ability JSON contains 77 Death Knight raw spell-rank rows, but omits `SpellFamilyName` and `SpellFamilyFlags`. The ID-keyed map in `src/game/wow335DeathKnightBloodGorgedSpellFamily.ts` supplies those fields from the same local patch-D `Spell.dbc` used by the talent generator. It keeps all 77 generated raw rows for source auditing; the selectable generated ability catalog filters out the two rank-0 Death Coil variants `47632` and `47633`, leaving 75 rank IDs that can reach the runtime cast/action definitions. No name-based inference is used. Spell IDs outside this known generated set (for example Rune Strike `56815`) return `null` and do not match.
|
||
|
||
The local mask `[0x01400001, 0, 0]` matches eight generated rows. All are actual selectable direct-hit actions:
|
||
|
||
| Modeled action | Raw DBC spell IDs matching the mask | ID selected at level 80 |
|
||
| --- | --- | --- |
|
||
| Plague Strike | `45462`, `49917`, `49918`, `49919`, `49920`, `49921` | `49921` (rank 6) |
|
||
| Blood Strike | `45902` | `45902` (rank 1) |
|
||
| Heart Strike | `55050` | `55050` (rank 1; requires learned `talent-1957`) |
|
||
|
||
The mapping tests cross-check each generated source row against the explicit ID table, confirm the 75 selectable catalog ranks, and pass the level-80 player selection and the party AI's `learnedAbilityForBuild` selection for these attacks through the same mask lookup. In particular, Plague Strike resolves to rank-6 spell ID `49921` in both selections; the companion Heart Strike selection requires `talent-1957` rank 1. Among the generated raw rows, the other 69 IDs do not intersect the mask: `42650`, `43265`, `45463`, `45477`, `45524`, `45529`, `46584`, `47476`, `47528`, `47541`, `47568`, `47632`, `47633`, `48263`, `48265`, `48266`, `48707`, `48721`, `48743`, `48778`, `48792`, `48982`, `49005`, `49016`, `49020`, `49028`, `49039`, `49143`, `49146`, `49158`, `49184`, `49189`, `49203`, `49206`, `49222`, `49576`, `49796`, `49892`, `49893`, `49894`, `49895`, `49896`, `49903`, `49904`, `49909`, `49923`, `49924`, `49936`, `49937`, `49938`, `49939`, `49940`, `49941`, `49998`, `49999`, `50149`, `50150`, `50842`, `51052`, `51267`, `51271`, `55090`, `55233`, `61154`, `61155`, `61156`, `61157`, `61158`, `63560`. The two Death Coil IDs in this source-level exclusion list are the rank-0 variants noted above, not selectable runtime ranks.
|
||
|
||
## Files and validation
|
||
|
||
- Local talent node and ranks: `src/game/wow335Talents.generated.ts` (`talent-2034`).
|
||
- Isolated profile and eligibility helper: `src/game/wow335DeathKnightBloodGorgedRuntime.ts`.
|
||
- Focused helper test: `src/game/wow335DeathKnightBloodGorgedRuntime.test.ts`.
|
||
- Local Spell.dbc family map and rank-selection test: `src/game/wow335DeathKnightBloodGorgedSpellFamily.ts`, `src/game/wow335DeathKnightBloodGorgedSpellFamily.test.ts`.
|
||
- Player/companion integration tests: `src/game/wow335DeathKnightBloodGorged.integration.test.ts`.
|
||
- Focused tests: `npx vitest run src/game/wow335DeathKnightBloodGorgedRuntime.test.ts src/game/wow335DeathKnightBloodGorgedSpellFamily.test.ts src/game/wow335DeathKnightBloodGorged.integration.test.ts`.
|