Skip to content

Commit e40bf47

Browse files
authored
Merge pull request WoWAnalyzer#7628 from brandrewsss/unholy-midnight-cleanup
[Unholy] Enable Unholy Death Knight Analyzer for Midnight
2 parents 1ea4aa1 + b0dd265 commit e40bf47

20 files changed

+85
-744
lines changed

eslint.config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ const ignores = tseslint.config({
3535
// REMOVE SPECS FROM HERE ONCE THEY ARE SUPPORTED
3636
'src/analysis/retail/deathknight/blood/**',
3737
'src/analysis/retail/deathknight/frost/**',
38-
'src/analysis/retail/deathknight/unholy/**',
3938
'src/analysis/retail/druid/balance/**',
4039
'src/analysis/retail/druid/feral/**',
4140
'src/analysis/retail/druid/restoration/**',
Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,6 @@
11
import { change, date } from 'common/changelog';
2-
import { Vetyst, Khazak, Brandrewsss, Arlie } from 'CONTRIBUTORS';
3-
import { SpellLink } from 'interface';
4-
import SPELLS from 'common/SPELLS';
5-
import TALENTS from 'common/TALENTS/deathknight';
2+
import { Brandrewsss } from 'CONTRIBUTORS';
63

74
export default [
8-
change(date(2025, 10, 13), <>Updated cooldown and CDR of <SpellLink spell={TALENTS.ANTI_MAGIC_ZONE_TALENT} />.</>, Arlie),
9-
change(date(2025, 10, 13), 'Added a Cooldown section to the Guide', Brandrewsss),
10-
change(date(2025, 10, 12), 'Updated Unholy Death Knight Analyzer to Guide layout and updated folder structure', Brandrewsss),
11-
change(date(2025, 6, 23), 'Update Unholy Death Knight Buffs for Patch 11.1.5', Brandrewsss),
12-
change(date(2025, 6, 8), 'Update Unholy Death Knight Abilities and Talents for Patch 11.1.5', Brandrewsss),
13-
change(date(2024, 12, 9), 'Update spec config to reflect lack of long term maintainers', Khazak),
14-
change(date(2024, 10, 7), <>Correct GCD and cooldown of <SpellLink spell={SPELLS.ANTI_MAGIC_SHELL.id} /> when paired with <SpellLink spell={TALENTS.ANTI_MAGIC_BARRIER_TALENT.id} /> and <SpellLink spell={TALENTS.UNYIELDING_WILL_TALENT.id} />.</>, Vetyst),
15-
change(date(2024, 10, 4), 'Enable Core Foundation of Unholy DK for TWW.', Vetyst),
5+
change(date(2026, 2, 5), <>Initial Update for Midnight</>, Brandrewsss)
166
];

src/analysis/retail/deathknight/unholy/CONFIG.tsx

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,24 @@
11
import GameBranch from 'game/GameBranch';
22
import SPECS from 'game/SPECS';
33
import Config, { SupportLevel } from 'parser/Config';
4-
// import CHANGELOG from './CHANGELOG';
4+
import CHANGELOG from './CHANGELOG';
55
import { Brandrewsss } from 'CONTRIBUTORS';
6-
import SpellLink from 'interface/SpellLink';
7-
import SPELLS from 'common/SPELLS/deathknight';
86

97
const config: Config = {
108
// The people that have contributed to this spec recently. People don't have to sign up to be long-time maintainers to be included in this list. If someone built a large part of the spec or contributed something recently to that spec, they can be added to the contributors list. If someone goes MIA, they may be removed after major changes or during a new expansion.
119
contributors: [Brandrewsss],
1210
branch: GameBranch.Retail,
1311
// The WoW client patch this spec was last updated.
14-
patchCompatibility: '11.2.0',
12+
patchCompatibility: '12.0.0',
1513
supportLevel: SupportLevel.MaintainedPartial,
1614
// Explain the status of this spec's analysis here. Try to mention how complete it is, and perhaps show links to places users can learn more.
1715
// If this spec's analysis does not show a complete picture please mention this in the `<Warning>` component.
1816
description: (
1917
<>
2018
<p>
2119
Unholy Death Knights are disease specialists and undead masters, they turn rot and plague
22-
into damage. The specialization focuses on spreading and bursting{' '}
23-
<SpellLink spell={SPELLS.FESTERING_WOUND} /> and maintaining{' '}
24-
<SpellLink spell={SPELLS.VIRULENT_PLAGUE} />.
20+
into damage. The specialization focuses on spreading diseases and keeping abilities on
21+
cooldown to maximize the damage from DOTs.
2522
</p>
2623
<p>
2724
Efficient resource use and cooldown alignment are key. Whether in AoE or single-target
@@ -45,18 +42,18 @@ const config: Config = {
4542
),
4643
// A recent example report to see interesting parts of the spec. Will be shown on the homepage.
4744
exampleReport:
48-
'/report/qHX2tmrGzkyB4cdL/49-Mythic+Dimensius,+the+All-Devouring+-+Kill+(9:04)/350-Vairuhdk/standard',
45+
'report/ZwajMpPgzt28C4RN/3-Mythic+Nexus-King+Salhadaar+-+Kill+(1:57)/10-Dopa/standard',
4946

5047
// Don't change anything below this line;
5148
// The current spec identifier. This is the only place (in code) that specifies which spec this parser is about.
5249
spec: SPECS.UNHOLY_DEATH_KNIGHT,
5350
// The contents of your changelog.
54-
changelog: [], // CHANGELOG,
51+
changelog: CHANGELOG,
5552
// The CombatLogParser class for your spec.
56-
// parser: () =>
57-
// import('./CombatLogParser' /* webpackChunkName: "UnholyDeathKnight" */).then(
58-
// (exports) => exports.default,
59-
// ),
53+
parser: () =>
54+
import('./CombatLogParser' /* webpackChunkName: "UnholyDeathKnight" */).then(
55+
(exports) => exports.default,
56+
),
6057
// The path to the current directory (relative form project root). This is used for generating a GitHub link directly to your spec's code.
6158
path: import.meta.url,
6259
};

src/analysis/retail/deathknight/unholy/CombatLogParser.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,11 @@ import CooldownThroughputTracker from './modules/core/CooldownThroughputTracker'
99
import UnholyRuneForgeChecker from './modules/features/RuneForgeChecker';
1010
import RuneTracker from './modules/core/RuneTracker';
1111
import SuddenDoom from './modules/talents/SuddenDoom';
12-
import WoundTracker from './modules/features/WoundTracker';
1312
import RunicPowerDetails from './modules/core/RunicPowerDetails';
1413
import RunicPowerTracker from './modules/core/RunicPowerTracker';
15-
import Apocalypse from './modules/talents/Apocalypse';
16-
import FesteringStrikeEfficiency from './modules/spells/FesteringStrikeEfficiency';
17-
import ScourgeStrikeEfficiency from './modules/spells/ScourgeStrikeEfficiency';
1814
import VirulentPlagueEfficiency from './modules/spells/VirulentPlagueEfficiency';
1915
import SoulReaper from '../shared/talents/SoulReaper';
2016
import CommanderOfTheDead from './modules/talents/CommanderOfTheDead';
21-
import SummonGargoyleBuffs from './modules/talents/SummonGargoyleBuffs';
22-
import PlagueBringer from './modules/talents/PlagueBringer';
2317
import RunicPowerGraph from './modules/core/RunicPowerGraph';
2418
import RuneGraph from './modules/core/RuneGraph';
2519
import Guide from './modules/Guide';
@@ -35,18 +29,12 @@ class CombatLogParser extends CoreCombatLogParser {
3529

3630
// Features
3731
virulentPlagueEfficiency: VirulentPlagueEfficiency,
38-
woundTracker: WoundTracker,
3932
suddenDoom: SuddenDoom,
4033
unholyRuneForge: UnholyRuneForgeChecker,
4134

4235
// Talents
43-
apocalypse: Apocalypse,
4436
soulReaper: SoulReaper,
45-
festeringStrikeEfficiency: FesteringStrikeEfficiency,
46-
scourgeStrikeEfficiency: ScourgeStrikeEfficiency,
4737
commanderOfTheDead: CommanderOfTheDead,
48-
summonGargoyleBuffs: SummonGargoyleBuffs,
49-
plagueBringer: PlagueBringer,
5038

5139
// RunicPower
5240
runicPowerTracker: RunicPowerTracker,

src/analysis/retail/deathknight/unholy/modules/Abilities.tsx

Lines changed: 23 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import TALENTS from 'common/TALENTS/deathknight';
33
import CoreAbilities, { AbilityRange } from 'parser/core/modules/Abilities';
44
import { SpellbookAbility } from 'parser/core/modules/Ability';
55
import SPELL_CATEGORY from 'parser/core/SPELL_CATEGORY';
6-
import { SpellLink } from 'interface';
76

87
class Abilities extends CoreAbilities {
98
spellbook(): SpellbookAbility[] {
@@ -20,31 +19,12 @@ class Abilities extends CoreAbilities {
2019
},
2120
{
2221
spell: TALENTS.SCOURGE_STRIKE_TALENT.id,
23-
enabled: !combatant.hasTalent(TALENTS.CLAWING_SHADOWS_TALENT),
24-
category: SPELL_CATEGORY.ROTATIONAL,
25-
gcd: {
26-
base: 1500,
27-
},
28-
range: AbilityRange.Melee,
29-
},
30-
{
31-
spell: TALENTS.CLAWING_SHADOWS_TALENT.id,
32-
enabled: combatant.hasTalent(TALENTS.CLAWING_SHADOWS_TALENT),
3322
category: SPELL_CATEGORY.ROTATIONAL,
3423
gcd: {
3524
base: 1500,
3625
},
3726
range: 30,
3827
},
39-
{
40-
spell: TALENTS.FESTERING_STRIKE_TALENT.id,
41-
enabled: combatant.hasTalent(TALENTS.FESTERING_STRIKE_TALENT),
42-
category: SPELL_CATEGORY.ROTATIONAL,
43-
gcd: {
44-
base: 1500,
45-
},
46-
range: AbilityRange.Melee,
47-
},
4828
{
4929
spell: SPELLS.FESTERING_SCYTHE.id,
5030
enabled: combatant.hasTalent(TALENTS.FESTERING_SCYTHE_TALENT),
@@ -72,21 +52,8 @@ class Abilities extends CoreAbilities {
7252
},
7353
{
7454
spell: SPELLS.DEATH_AND_DECAY.id,
75-
enabled: !combatant.hasTalent(TALENTS.DEFILE_TALENT),
7655
category: SPELL_CATEGORY.ROTATIONAL_AOE,
7756
cooldown: 30,
78-
charges: combatant.hasTalent(TALENTS.DEATHS_ECHO_TALENT) ? 2 : 1,
79-
gcd: {
80-
base: 1500,
81-
},
82-
range: 30,
83-
},
84-
{
85-
spell: TALENTS.DEFILE_TALENT.id,
86-
enabled: combatant.hasTalent(TALENTS.DEFILE_TALENT),
87-
category: SPELL_CATEGORY.ROTATIONAL_AOE,
88-
cooldown: 20,
89-
charges: 1,
9057
gcd: {
9158
base: 1500,
9259
},
@@ -102,80 +69,43 @@ class Abilities extends CoreAbilities {
10269
},
10370
range: AbilityRange.Melee,
10471
},
105-
//endregion
106-
107-
// region Cooldowns
10872
{
109-
spell: TALENTS.APOCALYPSE_TALENT.id,
110-
enabled: combatant.hasTalent(TALENTS.APOCALYPSE_TALENT),
111-
category: SPELL_CATEGORY.COOLDOWNS,
112-
cooldown: 45,
73+
spell: SPELLS.FESTERING_STRIKE.id,
74+
category: SPELL_CATEGORY.ROTATIONAL,
75+
// If Festering Scythe is talented, there is a -500ms GCD reduction
11376
gcd: {
114-
base: 1500,
77+
base: combatant.hasTalent(TALENTS.FESTERING_SCYTHE_TALENT) ? 1000 : 1500,
11578
},
11679
range: AbilityRange.Melee,
117-
castEfficiency: {
118-
suggestion: true,
119-
recommendedEfficiency: 0.9,
120-
extraSuggestion: (
121-
<span>
122-
Making sure to use <SpellLink spell={TALENTS.APOCALYPSE_TALENT} /> immediately after
123-
it's cooldown is up is important, try to plan for it's use as it is coming off
124-
cooldown.
125-
</span>
126-
),
127-
},
128-
},
129-
{
130-
spell: TALENTS.DARK_TRANSFORMATION_TALENT.id,
131-
enabled: combatant.hasTalent(TALENTS.DARK_TRANSFORMATION_TALENT),
132-
category: SPELL_CATEGORY.COOLDOWNS,
133-
cooldown: 45,
134-
gcd: {
135-
base: 1500,
136-
},
137-
range: 100,
13880
},
13981
{
140-
spell: TALENTS.UNHOLY_ASSAULT_TALENT.id,
141-
enabled: combatant.hasTalent(TALENTS.UNHOLY_ASSAULT_TALENT),
142-
category: SPELL_CATEGORY.COOLDOWNS,
143-
cooldown: 90,
82+
spell: TALENTS.PUTREFY_TALENT.id,
83+
enabled: combatant.hasTalent(TALENTS.PUTREFY_TALENT),
84+
category: SPELL_CATEGORY.ROTATIONAL,
14485
gcd: {
14586
base: 1500,
14687
},
147-
range: AbilityRange.Melee,
88+
range: 40,
14889
},
90+
91+
// region Cooldowns
14992
{
150-
spell: [TALENTS.SUMMON_GARGOYLE_TALENT.id, SPELLS.DARK_ARBITER_TALENT_GLYPH.id],
151-
enabled: combatant.hasTalent(TALENTS.SUMMON_GARGOYLE_TALENT),
93+
spell: TALENTS.DARK_TRANSFORMATION_TALENT.id,
94+
enabled: combatant.hasTalent(TALENTS.DARK_TRANSFORMATION_TALENT),
15295
category: SPELL_CATEGORY.COOLDOWNS,
153-
cooldown: 180,
96+
cooldown: 45,
15497
gcd: null,
155-
range: 30,
98+
range: 100,
15699
},
157100
{
158101
spell: TALENTS.ARMY_OF_THE_DEAD_TALENT.id,
159-
enabled:
160-
combatant.hasTalent(TALENTS.ARMY_OF_THE_DEAD_TALENT) &&
161-
!combatant.hasTalent(TALENTS.RAISE_ABOMINATION_TALENT),
162-
category: SPELL_CATEGORY.COOLDOWNS,
163-
cooldown: 180,
164-
gcd: {
165-
base: 1500,
166-
},
167-
},
168-
{
169-
spell: TALENTS.RAISE_ABOMINATION_TALENT.id,
170-
enabled: combatant.hasTalent(TALENTS.RAISE_ABOMINATION_TALENT),
102+
enabled: combatant.hasTalent(TALENTS.ARMY_OF_THE_DEAD_TALENT),
171103
category: SPELL_CATEGORY.COOLDOWNS,
172104
cooldown: 90,
173105
gcd: {
174106
base: 1500,
175107
},
176-
range: 40,
177108
},
178-
//endregion
179109

180110
// region Defensives
181111
{
@@ -187,10 +117,7 @@ class Abilities extends CoreAbilities {
187117
{
188118
spell: SPELLS.ANTI_MAGIC_SHELL.id,
189119
category: SPELL_CATEGORY.DEFENSIVE,
190-
cooldown:
191-
60 -
192-
Number(combatant.hasTalent(TALENTS.ANTI_MAGIC_BARRIER_TALENT)) * 20 +
193-
Number(combatant.hasTalent(TALENTS.UNYIELDING_WILL_TALENT)) * 20,
120+
cooldown: 60,
194121
gcd: null,
195122
},
196123
{
@@ -204,14 +131,6 @@ class Abilities extends CoreAbilities {
204131
isDefensive: true,
205132
enabled: combatant.hasTalent(TALENTS.ANTI_MAGIC_ZONE_TALENT),
206133
},
207-
{
208-
spell: TALENTS.SACRIFICIAL_PACT_TALENT.id,
209-
category: SPELL_CATEGORY.DEFENSIVE,
210-
cooldown: 120,
211-
gcd: {
212-
base: 1500,
213-
},
214-
},
215134
{
216135
spell: SPELLS.LICHBORNE.id,
217136
category: SPELL_CATEGORY.DEFENSIVE,
@@ -234,7 +153,6 @@ class Abilities extends CoreAbilities {
234153
cooldown: 120,
235154
gcd: null,
236155
},
237-
//endregion
238156

239157
// region Utility
240158
{
@@ -277,14 +195,6 @@ class Abilities extends CoreAbilities {
277195
},
278196
range: 20,
279197
},
280-
{
281-
spell: TALENTS.RAISE_DEAD_UNHOLY_TALENT.id,
282-
enabled: combatant.hasTalent(TALENTS.RAISE_DEAD_UNHOLY_TALENT),
283-
category: SPELL_CATEGORY.UTILITY,
284-
cooldown: 120,
285-
gcd: null,
286-
range: 30,
287-
},
288198
{
289199
spell: SPELLS.CHAINS_OF_ICE.id,
290200
category: SPELL_CATEGORY.UTILITY,
@@ -337,34 +247,28 @@ class Abilities extends CoreAbilities {
337247
base: 1500,
338248
},
339249
},
250+
/*
251+
Rune cooldown is base 10s reduced by haste. Runic Corruption's regeneration acceleration is handled in the RuneTracker via onApplybuff/onRemovebuff.
252+
Do not add RC logic here to avoid double-counting.
253+
*/
340254
{
341255
spell: SPELLS.RUNE_1.id,
342256
category: SPELL_CATEGORY.HIDDEN,
343-
cooldown: (haste) => {
344-
const multiplier = combatant.hasBuff(SPELLS.RUNIC_CORRUPTION.id) ? 1 : 0;
345-
return 10 / (1 + haste) / (1 + multiplier);
346-
},
257+
cooldown: (haste) => 10 / (1 + haste),
347258
charges: 2,
348259
},
349260
{
350261
spell: SPELLS.RUNE_2.id,
351262
category: SPELL_CATEGORY.HIDDEN,
352-
cooldown: (haste) => {
353-
const multiplier = combatant.hasBuff(SPELLS.RUNIC_CORRUPTION.id) ? 1 : 0;
354-
return 10 / (1 + haste) / (1 + multiplier);
355-
},
263+
cooldown: (haste) => 10 / (1 + haste),
356264
charges: 2,
357265
},
358266
{
359267
spell: SPELLS.RUNE_3.id,
360268
category: SPELL_CATEGORY.HIDDEN,
361-
cooldown: (haste) => {
362-
const multiplier = combatant.hasBuff(SPELLS.RUNIC_CORRUPTION.id) ? 1 : 0;
363-
return 10 / (1 + haste) / (1 + multiplier);
364-
},
269+
cooldown: (haste) => 10 / (1 + haste),
365270
charges: 2,
366271
},
367-
//endregion
368272
];
369273
}
370274
}

0 commit comments

Comments
 (0)