Skip to content

Commit 3f721db

Browse files
authored
Merge branch 'WoWAnalyzer:midnight' into unholy-midnight-cooldown-tracking
2 parents 243d2d7 + acabdc7 commit 3f721db

File tree

30 files changed

+539
-213
lines changed

30 files changed

+539
-213
lines changed

src/CHANGELOG.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import SpellLink from 'interface/SpellLink';
3030

3131
// prettier-ignore
3232
export default [
33+
change(date(2026, 2, 10), 'Prevent duplicate GCDs triggering for normalized channels', Vollmer),
3334
change(date(2026, 2, 1), 'Fix playwright tests for specs with partial support', Vollmer),
3435
change(date(2026, 1, 29), 'RU: improve localization on key pages (news/about/specs/premium/help-wanted) and make Panel headings fully translatable', SaltyRain),
3536
change(date(2026, 1, 27), 'Add support for Midnight gems and enchants.', Arlie),

src/analysis/classic/priest/shadow/CombatLogParser.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Base files
22
import BaseCombatLogParser from 'parser/classic/CombatLogParser';
33
// Core
4-
import GlobalCooldown from './modules/core/GlobalCooldown';
54
// Shared
65
import { Haste } from '../shared';
76
import ManaTracker from 'parser/core/healingEfficiency/ManaTracker';
@@ -19,7 +18,6 @@ import Shadowfiend from './modules/spells/Shadowfiend';
1918
class CombatLogParser extends BaseCombatLogParser {
2019
static specModules = {
2120
// Core
22-
globalCooldown: GlobalCooldown,
2321
// Shared
2422
haste: Haste,
2523
manaTracker: ManaTracker,

src/analysis/classic/priest/shadow/modules/core/GlobalCooldown.tsx

Lines changed: 0 additions & 18 deletions
This file was deleted.

src/analysis/retail/demonhunter/devourer/CHANGELOG.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import { change, date } from 'common/changelog';
22
import { Topple, Texleretour } from 'CONTRIBUTORS';
33
import SHARED_CHANGELOG from 'analysis/retail/demonhunter/shared/CHANGELOG';
4+
import SpellLink from 'interface/SpellLink';
5+
import { TALENTS_DEMON_HUNTER } from 'common/TALENTS';
46

57
// prettier-ignore
68
export default [
9+
change(date(2026, 2, 7), <>{<SpellLink spell={TALENTS_DEMON_HUNTER.VOID_METAMORPHOSIS_TALENT} />} cast analysis</>, Texleretour),
710
change(date(2026, 2, 3), 'Core analysis', Texleretour),
811
change(date(2026, 1, 30), 'Add more complete foundation', Texleretour),
912
change(date(2025, 10, 24), 'Add basic support for the spec.', Topple),

src/analysis/retail/demonhunter/devourer/CONFIG.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const CONFIG: Config = {
1111
branch: GameBranch.Retail,
1212
// The WoW client patch this spec was last updated.
1313
patchCompatibility: '12.0.0',
14-
supportLevel: SupportLevel.Foundation,
14+
supportLevel: SupportLevel.MaintainedPartial,
1515
// 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.
1616
// If this spec's analysis does not show a complete picture please mention this in the `<Warning>` component.
1717
description: (

src/analysis/retail/demonhunter/devourer/CombatLogParser.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import CoreCombatLogParser from 'parser/core/CombatLogParser';
22
import Channeling from 'parser/shared/normalizers/Channeling';
33
import ArcaneTorrent from 'parser/shared/modules/racials/bloodelf/ArcaneTorrent';
44
import { Buffs } from 'analysis/retail/demonhunter/devourer/modules/Buffs';
5-
import { GlobalCooldown } from 'analysis/retail/demonhunter/devourer/modules/core/GlobalCooldown';
65
import { AlwaysBeCasting } from 'analysis/retail/demonhunter/devourer/modules/features/AlwaysBeCasting';
76
import CooldownThroughputTracker from 'analysis/retail/demonhunter/devourer/modules/features/CooldownThroughputTracker';
87
import { FuryTracker } from 'analysis/retail/demonhunter/devourer/modules/resourcetracker/FuryTracker';
@@ -20,15 +19,15 @@ import VoidMetamorphosis from './modules/talents/VoidMetamorphosis';
2019
import Voidstep from './modules/buffs/Voidstep';
2120
import Reap from './modules/spells/Reap';
2221
import Cull from './modules/spells/Cull';
22+
import VoidRay from './modules/talents/VoidRay';
23+
import VoidRayEventLinkNormalizer from './normalizers/VoidRayEventLinkNormalizer';
2324

2425
class CombatLogParser extends CoreCombatLogParser {
2526
static specModules = {
2627
// Core Statistics
2728
channeling: Channeling,
2829
buffs: Buffs,
2930

30-
globalCooldown: GlobalCooldown,
31-
3231
// Features
3332
alwaysBeCasting: AlwaysBeCasting,
3433
abilities: Abilities,
@@ -44,6 +43,7 @@ class CombatLogParser extends CoreCombatLogParser {
4443
momentOfCraving: MomentOfCraving,
4544
massAcceleration: MassAcceleration,
4645
voidMetamorphosis: VoidMetamorphosis,
46+
voidRay: VoidRay,
4747

4848
// Buffs
4949
voidstep: Voidstep,
@@ -58,6 +58,7 @@ class CombatLogParser extends CoreCombatLogParser {
5858

5959
// Normalizers
6060
voidMetamorphosisNormalizer: VoidMetamorphosisNormalizer,
61+
voidRayEventLinkNormalizer: VoidRayEventLinkNormalizer,
6162

6263
// There's no throughput benefit from casting Arcane Torrent on cooldown
6364
arcaneTorrent: [ArcaneTorrent, { castEfficiency: null }] as const,

src/analysis/retail/demonhunter/devourer/constants.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,7 @@ export const MOMENT_OF_CRAVING_ADDITIONAL_SOUL_ABSORB_CAPACITY = 6;
1212

1313
export const VOID_METAMORPHOSIS_BASE_SOULS_COST = 50;
1414
export const VOID_METAMORPHOSIS_SOUL_GLUTTON_SOULS_COST = 35;
15+
16+
export const VOID_RAY_MAX_TICKS = 21;
17+
// Void Ray receives a cooldown during Void Metamorphosis only
18+
export const VOID_RAY_COOLDOWN_VOID_METAMORPHOSIS = (haste: number) => 16 / (1 + haste);

src/analysis/retail/demonhunter/devourer/guide/CoreSection.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import ActiveTimeGraph from 'parser/ui/ActiveTimeGraph';
55
import CombatLogParser from '../CombatLogParser';
66
import SpellLink from 'interface/SpellLink';
77
import SPELLS from 'common/SPELLS';
8+
import { TALENTS_DEMON_HUNTER } from 'common/TALENTS';
89

910
function CoreSection({ modules, info }: GuideProps<typeof CombatLogParser>) {
1011
return (
@@ -15,9 +16,10 @@ function CoreSection({ modules, info }: GuideProps<typeof CombatLogParser>) {
1516
Continuously casting throughout an encounter is the single most important thing for
1617
achieving good DPS.
1718
</b>
18-
<br />
19-
Some fights have unavoidable downtime due to phase transitions and the like, so in these
20-
cases 0% downtime will not be possible - do the best you can.
19+
<div>
20+
Some fights have unavoidable downtime due to phase transitions and the like, so in these
21+
cases 0% downtime will not be possible - do the best you can.
22+
</div>
2123
</p>
2224
<p>
2325
Remember that you always have access to either <SpellLink spell={SPELLS.CONSUME} /> or{' '}
@@ -37,6 +39,8 @@ function CoreSection({ modules, info }: GuideProps<typeof CombatLogParser>) {
3739
</SubSection>
3840

3941
{modules.reap.guideSubsection()}
42+
{info.combatant.hasTalent(TALENTS_DEMON_HUNTER.VOID_RAY_TALENT) &&
43+
modules.voidRay.guideSubsection()}
4044
</Section>
4145
);
4246
}
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
import { GuideProps, Section } from 'interface/guide';
22
import CombatLogParser from '../CombatLogParser';
3+
import { TALENTS_DEMON_HUNTER } from 'common/TALENTS';
34

4-
function ProcsAndBuffsSection({ modules }: GuideProps<typeof CombatLogParser>) {
5-
return <Section title="Procs">{modules.voidstep.guideSubsection()}</Section>;
5+
function ProcsAndBuffsSection({ modules, info }: GuideProps<typeof CombatLogParser>) {
6+
return info.combatant.hasTalent(TALENTS_DEMON_HUNTER.HUNGERING_SLASH_TALENT) ? (
7+
<Section title="Procs">{modules.voidstep.guideSubsection()}</Section>
8+
) : (
9+
<></>
10+
);
611
}
712

813
export default ProcsAndBuffsSection;

src/analysis/retail/demonhunter/devourer/modules/Abilities.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class Abilities extends SharedAbilities {
1818
},
1919
},
2020
{
21-
spell: [SPELLS.HUNGERING_SLASH_CAST.id, SPELLS.REAPERS_TOLL.id],
21+
spell: [SPELLS.HUNGERING_SLASH_CAST.id, SPELLS.REAPERS_TOLL_CAST.id],
2222
enabled: combatant.hasTalent(TALENTS_DEMON_HUNTER.HUNGERING_SLASH_TALENT),
2323
category: SPELL_CATEGORY.ROTATIONAL,
2424
gcd: {

0 commit comments

Comments
 (0)