Skip to main content

wowlab_engine_content/generated/specs/
destruction_warlock.rs

1//! @generated by codegen-cli from manifests/specs/warlock/destruction/manifest.toml -- do not edit by hand.
2// Generated code: naming follows game data conventions
3#![allow(non_snake_case, dead_code)]
4use wowlab_types::{combat::ResourceType, game::SpecId};
5use wowlab_engine_domain::dbc::ProcAttributes;
6use wowlab_engine_combat::{
7    BuiltCombatSystem, AuraDefinitionDraft, LocalAuraIdx, LocalSpellIdx,
8    SpellDefinitionDraft,
9};
10use wowlab_engine_ports::{
11    DeclaredSpecMetadata, SpecDescriptor, SpecHandler, HeroTalentTreeDesc,
12    DeclaredServerProcEntry,
13};
14use wowlab_engine_gamedata::ResolvedGameData;
15pub(crate) mod SPELL {
16    ///<https://wowlab.gg/inspect/spell/691>
17    pub(crate) const SUMMON_FELHUNTER: u32 = 691;
18    ///<https://wowlab.gg/inspect/spell/688>
19    pub(crate) const SUMMON_IMP: u32 = 688;
20    ///<https://wowlab.gg/inspect/spell/108503>
21    pub(crate) const GRIMOIRE_OF_SACRIFICE: u32 = 108_503;
22    ///<https://wowlab.gg/inspect/spell/348>
23    pub(crate) const IMMOLATE: u32 = 348;
24    ///<https://wowlab.gg/inspect/spell/29722>
25    pub(crate) const INCINERATE: u32 = 29722;
26    ///<https://wowlab.gg/inspect/spell/17962>
27    pub(crate) const CONFLAGRATE: u32 = 17962;
28    ///<https://wowlab.gg/inspect/spell/116858>
29    pub(crate) const CHAOS_BOLT: u32 = 116_858;
30    ///<https://wowlab.gg/inspect/spell/5740>
31    pub(crate) const RAIN_OF_FIRE: u32 = 5740;
32    ///<https://wowlab.gg/inspect/spell/17877>
33    pub(crate) const SHADOWBURN: u32 = 17877;
34    ///<https://wowlab.gg/inspect/spell/6353>
35    pub(crate) const SOUL_FIRE: u32 = 6353;
36    ///<https://wowlab.gg/inspect/spell/152108>
37    pub(crate) const CATACLYSM: u32 = 152_108;
38    ///<https://wowlab.gg/inspect/spell/196447>
39    pub(crate) const CHANNEL_DEMONFIRE: u32 = 196_447;
40    ///<https://wowlab.gg/inspect/spell/196448>
41    pub(crate) const CHANNEL_DEMONFIRE_TICK: u32 = 196_448;
42    ///<https://wowlab.gg/inspect/spell/80240>
43    pub(crate) const HAVOC: u32 = 80240;
44    ///<https://wowlab.gg/inspect/spell/686>
45    pub(crate) const SHADOW_BOLT: u32 = 686;
46    ///<https://wowlab.gg/inspect/spell/172>
47    pub(crate) const CORRUPTION: u32 = 172;
48    ///<https://wowlab.gg/inspect/spell/430014>
49    pub(crate) const MALEVOLENCE: u32 = 430_014;
50    ///<https://wowlab.gg/inspect/spell/234153>
51    pub(crate) const DRAIN_LIFE: u32 = 234_153;
52    ///<https://wowlab.gg/inspect/spell/434506>
53    pub(crate) const INFERNAL_BOLT: u32 = 434_506;
54    ///<https://wowlab.gg/inspect/spell/434635>
55    pub(crate) const RUINATION: u32 = 434_635;
56    ///<https://wowlab.gg/inspect/spell/1122>
57    pub(crate) const SUMMON_INFERNAL: u32 = 1122;
58}
59pub(crate) mod AURA {
60    ///<https://wowlab.gg/inspect/spell/157736>
61    pub(crate) const IMMOLATE: u32 = 157_736;
62    ///<https://wowlab.gg/inspect/spell/117828>
63    pub(crate) const BACKDRAFT: u32 = 117_828;
64    ///<https://wowlab.gg/inspect/spell/266030>
65    pub(crate) const REVERSE_ENTROPY: u32 = 266_030;
66    ///<https://wowlab.gg/inspect/spell/205148>
67    pub(crate) const REVERSE_ENTROPY_TALENT: u32 = 205_148;
68    ///<https://wowlab.gg/inspect/spell/387109>
69    pub(crate) const CONFLAGRATION_OF_CHAOS_CONFLAG: u32 = 387_109;
70    ///<https://wowlab.gg/inspect/spell/387109>
71    pub(crate) const CONFLAGRATION_OF_CHAOS_SHADOWBURN: u32 = 387_109;
72    ///<https://wowlab.gg/inspect/spell/387263>
73    pub(crate) const FLASHPOINT: u32 = 387_263;
74    ///<https://wowlab.gg/inspect/spell/1245664>
75    pub(crate) const FIENDISH_CRUELTY: u32 = 1_245_664;
76    ///<https://wowlab.gg/inspect/spell/1245633>
77    pub(crate) const FIENDISH_CRUELTY_TALENT: u32 = 1_245_633;
78    ///<https://wowlab.gg/inspect/spell/387108>
79    pub(crate) const CONFLAGRATION_OF_CHAOS_TALENT: u32 = 387_108;
80    ///<https://wowlab.gg/inspect/spell/1244860>
81    pub(crate) const CHAOTIC_INFERNO: u32 = 1_244_860;
82    ///<https://wowlab.gg/inspect/spell/1244788>
83    pub(crate) const CHAOTIC_INFERNO_TALENT: u32 = 1_244_788;
84    ///<https://wowlab.gg/inspect/spell/80240>
85    pub(crate) const HAVOC: u32 = 80240;
86    ///<https://wowlab.gg/inspect/spell/387157>
87    pub(crate) const RITUAL_OF_RUIN: u32 = 387_157;
88    ///<https://wowlab.gg/inspect/spell/196099>
89    pub(crate) const GRIMOIRE_OF_SACRIFICE: u32 = 196_099;
90    ///<https://wowlab.gg/inspect/spell/445474>
91    pub(crate) const WITHER: u32 = 445_474;
92    ///<https://wowlab.gg/inspect/spell/442726>
93    pub(crate) const MALEVOLENCE: u32 = 442_726;
94    ///<https://wowlab.gg/inspect/spell/196447>
95    pub(crate) const CHANNEL_DEMONFIRE: u32 = 196_447;
96    ///<https://wowlab.gg/inspect/spell/1288970>
97    pub(crate) const RECENTLY_DEMON_HAS_BEEN_SUMMONED_DNT: u32 = 1_288_970;
98    ///<https://wowlab.gg/inspect/spell/462599>
99    pub(crate) const TRACK_PETS: u32 = 462_599;
100    ///<https://wowlab.gg/inspect/spell/433891>
101    pub(crate) const INFERNAL_BOLT: u32 = 433_891;
102    ///<https://wowlab.gg/inspect/spell/433885>
103    pub(crate) const RUINATION: u32 = 433_885;
104    ///<https://wowlab.gg/inspect/spell/428514>
105    pub(crate) const DIABOLIC_RITUAL_TALENT: u32 = 428_514;
106    ///<https://wowlab.gg/inspect/spell/431944>
107    pub(crate) const DIABOLIC_RITUAL_OVERLORD: u32 = 431_944;
108    ///<https://wowlab.gg/inspect/spell/432815>
109    pub(crate) const DIABOLIC_RITUAL_MOTHER: u32 = 432_815;
110    ///<https://wowlab.gg/inspect/spell/432816>
111    pub(crate) const DIABOLIC_RITUAL_PIT_LORD: u32 = 432_816;
112    ///<https://wowlab.gg/inspect/spell/428524>
113    pub(crate) const DEMONIC_ART_OVERLORD: u32 = 428_524;
114    ///<https://wowlab.gg/inspect/spell/432794>
115    pub(crate) const DEMONIC_ART_MOTHER: u32 = 432_794;
116    ///<https://wowlab.gg/inspect/spell/432795>
117    pub(crate) const DEMONIC_ART_PIT_LORD: u32 = 432_795;
118    ///<https://wowlab.gg/inspect/spell/1269643>
119    pub(crate) const DEMONIC_OCULI: u32 = 1_269_643;
120    ///<https://wowlab.gg/inspect/spell/1268709>
121    pub(crate) const DIABOLIC_OCULI_TALENT: u32 = 1_268_709;
122    ///<https://wowlab.gg/inspect/spell/1268713>
123    pub(crate) const LOOKS_THAT_KILL_TALENT: u32 = 1_268_713;
124    ///<https://wowlab.gg/inspect/spell/1268716>
125    pub(crate) const MINDS_EYES_TALENT: u32 = 1_268_716;
126    ///<https://wowlab.gg/inspect/spell/1269879>
127    pub(crate) const MINDS_EYES: u32 = 1_269_879;
128    ///<https://wowlab.gg/inspect/spell/457578>
129    pub(crate) const OVERFIEND: u32 = 457_578;
130    ///<https://wowlab.gg/inspect/spell/1245089>
131    pub(crate) const AVATAR_OF_DESTRUCTION_TALENT: u32 = 1_245_089;
132    ///<https://wowlab.gg/inspect/spell/1265770>
133    pub(crate) const EMBERS_OF_NIHILAM_1_TALENT: u32 = 1_265_770;
134    ///<https://wowlab.gg/inspect/spell/1265772>
135    pub(crate) const EMBERS_OF_NIHILAM_2_TALENT: u32 = 1_265_772;
136    ///<https://wowlab.gg/inspect/spell/1265774>
137    pub(crate) const EMBERS_OF_NIHILAM_3_TALENT: u32 = 1_265_774;
138    ///<https://wowlab.gg/inspect/spell/1265939>
139    pub(crate) const VISION_OF_NIHILAM: u32 = 1_265_939;
140    ///<https://wowlab.gg/inspect/spell/264364>
141    pub(crate) const INFERNAL_EMBERS: u32 = 264_364;
142    ///<https://wowlab.gg/inspect/spell/266087>
143    pub(crate) const RAIN_OF_CHAOS: u32 = 266_087;
144    ///<https://wowlab.gg/inspect/spell/417282>
145    pub(crate) const CRASHING_CHAOS: u32 = 417_282;
146}
147pub(crate) mod TALENT {
148    ///<https://wowlab.gg/inspect/spell/1245089>
149    pub(crate) const AVATAR_OF_DESTRUCTION: u32 = 1_245_089;
150    ///<https://wowlab.gg/inspect/spell/196406>
151    pub(crate) const BACKDRAFT: u32 = 196_406;
152    ///<https://wowlab.gg/inspect/spell/152108>
153    pub(crate) const CATACLYSM: u32 = 152_108;
154    ///<https://wowlab.gg/inspect/spell/196447>
155    pub(crate) const CHANNEL_DEMONFIRE: u32 = 196_447;
156    ///<https://wowlab.gg/inspect/spell/387275>
157    pub(crate) const CHAOS_INCARNATE: u32 = 387_275;
158    ///<https://wowlab.gg/inspect/spell/1244788>
159    pub(crate) const CHAOTIC_INFERNO: u32 = 1_244_788;
160    ///<https://wowlab.gg/inspect/spell/17962>
161    pub(crate) const CONFLAGRATE: u32 = 17962;
162    ///<https://wowlab.gg/inspect/spell/387108>
163    pub(crate) const CONFLAGRATION_OF_CHAOS: u32 = 387_108;
164    ///<https://wowlab.gg/inspect/spell/417234>
165    pub(crate) const CRASHING_CHAOS: u32 = 417_234;
166    ///<https://wowlab.gg/inspect/spell/1214442>
167    pub(crate) const DEMONFIRE_INFUSION: u32 = 1_214_442;
168    ///<https://wowlab.gg/inspect/spell/387173>
169    pub(crate) const DIABOLIC_EMBERS: u32 = 387_173;
170    ///<https://wowlab.gg/inspect/spell/1268709>
171    pub(crate) const DIABOLIC_OCULI: u32 = 1_268_709;
172    ///<https://wowlab.gg/inspect/spell/428514>
173    pub(crate) const DIABOLIC_RITUAL: u32 = 428_514;
174    ///<https://wowlab.gg/inspect/spell/454744>
175    pub(crate) const EMBERSTORM: u32 = 454_744;
176    ///<https://wowlab.gg/inspect/spell/1265770>
177    pub(crate) const EMBERS_OF_NIHILAM_1: u32 = 1_265_770;
178    ///<https://wowlab.gg/inspect/spell/1265772>
179    pub(crate) const EMBERS_OF_NIHILAM_2: u32 = 1_265_772;
180    ///<https://wowlab.gg/inspect/spell/1265774>
181    pub(crate) const EMBERS_OF_NIHILAM_3: u32 = 1_265_774;
182    ///<https://wowlab.gg/inspect/spell/1245633>
183    pub(crate) const FIENDISH_CRUELTY: u32 = 1_245_633;
184    ///<https://wowlab.gg/inspect/spell/196408>
185    pub(crate) const FIRE_AND_BRIMSTONE: u32 = 196_408;
186    ///<https://wowlab.gg/inspect/spell/387259>
187    pub(crate) const FLASHPOINT: u32 = 387_259;
188    ///<https://wowlab.gg/inspect/spell/108503>
189    pub(crate) const GRIMOIRE_OF_SACRIFICE: u32 = 108_503;
190    ///<https://wowlab.gg/inspect/spell/80240>
191    pub(crate) const HAVOC: u32 = 80240;
192    ///<https://wowlab.gg/inspect/spell/231793>
193    pub(crate) const IMPROVED_CONFLAGRATE: u32 = 231_793;
194    ///<https://wowlab.gg/inspect/spell/1280483>
195    pub(crate) const INFERNO: u32 = 1_280_483;
196    ///<https://wowlab.gg/inspect/spell/266134>
197    pub(crate) const INTERNAL_COMBUSTION: u32 = 266_134;
198    ///<https://wowlab.gg/inspect/spell/1268713>
199    pub(crate) const LOOKS_THAT_KILL: u32 = 1_268_713;
200    ///<https://wowlab.gg/inspect/spell/430014>
201    pub(crate) const MALEVOLENCE: u32 = 430_014;
202    ///<https://wowlab.gg/inspect/spell/387506>
203    pub(crate) const MAYHEM: u32 = 387_506;
204    ///<https://wowlab.gg/inspect/spell/1268716>
205    pub(crate) const MINDS_EYES: u32 = 1_268_716;
206    ///<https://wowlab.gg/inspect/spell/387166>
207    pub(crate) const RAGING_DEMONFIRE: u32 = 387_166;
208    ///<https://wowlab.gg/inspect/spell/266086>
209    pub(crate) const RAIN_OF_CHAOS: u32 = 266_086;
210    ///<https://wowlab.gg/inspect/spell/5740>
211    pub(crate) const RAIN_OF_FIRE: u32 = 5740;
212    ///<https://wowlab.gg/inspect/spell/205148>
213    pub(crate) const REVERSE_ENTROPY: u32 = 205_148;
214    ///<https://wowlab.gg/inspect/spell/1244310>
215    pub(crate) const ROARING_BLAZE: u32 = 1_244_310;
216    ///<https://wowlab.gg/inspect/spell/17877>
217    pub(crate) const SHADOWBURN: u32 = 17877;
218    ///<https://wowlab.gg/inspect/spell/6353>
219    pub(crate) const SOUL_FIRE: u32 = 6353;
220    ///<https://wowlab.gg/inspect/spell/1122>
221    pub(crate) const SUMMON_INFERNAL: u32 = 1122;
222}
223pub(crate) mod REPORTED_SPELL {
224    ///<https://wowlab.gg/inspect/spell/432596>
225    pub(crate) const CHAOS_SALVO: u32 = 432_596;
226    ///<https://wowlab.gg/inspect/spell/1269892>
227    pub(crate) const DIABOLIC_GAZE_1: u32 = 1_269_892;
228    ///<https://wowlab.gg/inspect/spell/1269886>
229    pub(crate) const DIABOLIC_GAZE_2: u32 = 1_269_886;
230    ///<https://wowlab.gg/inspect/spell/1269885>
231    pub(crate) const DIABOLIC_GAZE_3: u32 = 1_269_885;
232    ///<https://wowlab.gg/inspect/spell/1265884>
233    pub(crate) const ECHO_OF_SARGERAS: u32 = 1_265_884;
234    ///<https://wowlab.gg/inspect/spell/1277879>
235    pub(crate) const ECHO_OF_SARGERAS_CB: u32 = 1_277_879;
236    ///<https://wowlab.gg/inspect/spell/1265774>
237    pub(crate) const ECHO_OF_SARGERAS_SB: u32 = 1_265_774;
238    ///<https://wowlab.gg/inspect/spell/1269800>
239    pub(crate) const EYE_EXPLOSION: u32 = 1_269_800;
240    ///<https://wowlab.gg/inspect/spell/434404>
241    pub(crate) const FELSEEKER: u32 = 434_404;
242    ///<https://wowlab.gg/inspect/spell/20153>
243    pub(crate) const IMMOLATION: u32 = 20153;
244    ///<https://wowlab.gg/inspect/spell/111685>
245    pub(crate) const INFERNAL_MELEE: u32 = 111_685;
246    ///<https://wowlab.gg/inspect/spell/7814>
247    pub(crate) const LASH_OF_PAIN: u32 = 7814;
248    ///<https://wowlab.gg/inspect/spell/432120>
249    pub(crate) const WICKED_CLEAVE: u32 = 432_120;
250}
251pub(crate) mod HERO {
252    pub(crate) mod HELLCALLER {
253        pub(crate) mod SPELL {
254            ///<https://wowlab.gg/inspect/spell/445736>
255            pub(crate) const BLACKENED_SOUL_DAMAGE: u32 = 445_736;
256            ///<https://wowlab.gg/inspect/spell/445731>
257            pub(crate) const BLACKENED_SOUL_TRIGGER: u32 = 445_731;
258            ///<https://wowlab.gg/inspect/spell/430014>
259            pub(crate) const MALEVOLENCE: u32 = 430_014;
260            ///<https://wowlab.gg/inspect/spell/446285>
261            pub(crate) const MALEVOLENCE_DAMAGE: u32 = 446_285;
262            ///<https://wowlab.gg/inspect/spell/445465>
263            pub(crate) const WITHER: u32 = 445_465;
264            ///<https://wowlab.gg/inspect/spell/445468>
265            pub(crate) const WITHER_DIRECT: u32 = 445_468;
266        }
267        pub(crate) mod AURA {
268            ///<https://wowlab.gg/inspect/spell/445731>
269            pub(crate) const BLACKENED_SOUL: u32 = 445_731;
270            ///<https://wowlab.gg/inspect/spell/442726>
271            pub(crate) const MALEVOLENCE_BUFF: u32 = 442_726;
272            ///<https://wowlab.gg/inspect/spell/445474>
273            pub(crate) const WITHER_DOT: u32 = 445_474;
274        }
275    }
276    pub(crate) mod DIABOLIST {
277        pub(crate) mod SPELL {
278            ///<https://wowlab.gg/inspect/spell/434506>
279            pub(crate) const INFERNAL_BOLT: u32 = 434_506;
280            ///<https://wowlab.gg/inspect/spell/434635>
281            pub(crate) const RUINATION: u32 = 434_635;
282            ///<https://wowlab.gg/inspect/spell/434636>
283            pub(crate) const RUINATION_IMPACT: u32 = 434_636;
284        }
285        pub(crate) mod AURA {
286            ///<https://wowlab.gg/inspect/spell/434424>
287            pub(crate) const CLOVEN_SOUL: u32 = 434_424;
288            ///<https://wowlab.gg/inspect/spell/432794>
289            pub(crate) const DEMONIC_ART_MOTHER: u32 = 432_794;
290            ///<https://wowlab.gg/inspect/spell/428524>
291            pub(crate) const DEMONIC_ART_OVERLORD: u32 = 428_524;
292            ///<https://wowlab.gg/inspect/spell/432795>
293            pub(crate) const DEMONIC_ART_PIT_LORD: u32 = 432_795;
294            ///<https://wowlab.gg/inspect/spell/1269643>
295            pub(crate) const DEMONIC_OCULI: u32 = 1_269_643;
296            ///<https://wowlab.gg/inspect/spell/432815>
297            pub(crate) const DIABOLIC_RITUAL_MOTHER: u32 = 432_815;
298            ///<https://wowlab.gg/inspect/spell/431944>
299            pub(crate) const DIABOLIC_RITUAL_OVERLORD: u32 = 431_944;
300            ///<https://wowlab.gg/inspect/spell/432816>
301            pub(crate) const DIABOLIC_RITUAL_PIT_LORD: u32 = 432_816;
302            ///<https://wowlab.gg/inspect/spell/433891>
303            pub(crate) const INFERNAL_BOLT_BUFF: u32 = 433_891;
304            ///<https://wowlab.gg/inspect/spell/1269879>
305            pub(crate) const MINDS_EYES: u32 = 1_269_879;
306            ///<https://wowlab.gg/inspect/spell/433885>
307            pub(crate) const RUINATION_BUFF: u32 = 433_885;
308        }
309    }
310}
311static HERO_TREE_HELLCALLER_SPELLS: &[(&str, u32)] = &[
312    ("BLACKENED_SOUL_DAMAGE", 445_736),
313    ("BLACKENED_SOUL_TRIGGER", 445_731),
314    ("MALEVOLENCE", 430_014),
315    ("MALEVOLENCE_DAMAGE", 446_285),
316    ("WITHER", 445_465),
317    ("WITHER_DIRECT", 445_468),
318];
319static HERO_TREE_HELLCALLER_AURAS: &[(&str, u32)] = &[
320    ("BLACKENED_SOUL", 445_731),
321    ("MALEVOLENCE_BUFF", 442_726),
322    ("WITHER_DOT", 445_474),
323];
324static HERO_TREE_DIABOLIST_SPELLS: &[(&str, u32)] = &[
325    ("INFERNAL_BOLT", 434_506),
326    ("RUINATION", 434_635),
327    ("RUINATION_IMPACT", 434_636),
328];
329static HERO_TREE_DIABOLIST_AURAS: &[(&str, u32)] = &[
330    ("CLOVEN_SOUL", 434_424),
331    ("DEMONIC_ART_MOTHER", 432_794),
332    ("DEMONIC_ART_OVERLORD", 428_524),
333    ("DEMONIC_ART_PIT_LORD", 432_795),
334    ("DEMONIC_OCULI", 1_269_643),
335    ("DIABOLIC_RITUAL_MOTHER", 432_815),
336    ("DIABOLIC_RITUAL_OVERLORD", 431_944),
337    ("DIABOLIC_RITUAL_PIT_LORD", 432_816),
338    ("INFERNAL_BOLT_BUFF", 433_891),
339    ("MINDS_EYES", 1_269_879),
340    ("RUINATION_BUFF", 433_885),
341];
342pub(crate) const AURA_IMMOLATE: LocalAuraIdx = LocalAuraIdx::new(0);
343pub(crate) const AURA_BACKDRAFT: LocalAuraIdx = LocalAuraIdx::new(1);
344pub(crate) const AURA_REVERSE_ENTROPY: LocalAuraIdx = LocalAuraIdx::new(2);
345pub(crate) const AURA_REVERSE_ENTROPY_TALENT: LocalAuraIdx = LocalAuraIdx::new(3);
346pub(crate) const AURA_CONFLAGRATION_OF_CHAOS_CONFLAG: LocalAuraIdx = LocalAuraIdx::new(
347    4,
348);
349pub(crate) const AURA_CONFLAGRATION_OF_CHAOS_SHADOWBURN: LocalAuraIdx = LocalAuraIdx::new(
350    5,
351);
352pub(crate) const AURA_FLASHPOINT: LocalAuraIdx = LocalAuraIdx::new(6);
353pub(crate) const AURA_FIENDISH_CRUELTY: LocalAuraIdx = LocalAuraIdx::new(7);
354pub(crate) const AURA_FIENDISH_CRUELTY_TALENT: LocalAuraIdx = LocalAuraIdx::new(8);
355pub(crate) const AURA_CONFLAGRATION_OF_CHAOS_TALENT: LocalAuraIdx = LocalAuraIdx::new(9);
356pub(crate) const AURA_CHAOTIC_INFERNO: LocalAuraIdx = LocalAuraIdx::new(10);
357pub(crate) const AURA_CHAOTIC_INFERNO_TALENT: LocalAuraIdx = LocalAuraIdx::new(11);
358pub(crate) const AURA_HAVOC: LocalAuraIdx = LocalAuraIdx::new(12);
359pub(crate) const AURA_RITUAL_OF_RUIN: LocalAuraIdx = LocalAuraIdx::new(13);
360pub(crate) const AURA_GRIMOIRE_OF_SACRIFICE: LocalAuraIdx = LocalAuraIdx::new(14);
361pub(crate) const AURA_WITHER: LocalAuraIdx = LocalAuraIdx::new(15);
362pub(crate) const AURA_MALEVOLENCE: LocalAuraIdx = LocalAuraIdx::new(16);
363pub(crate) const AURA_CHANNEL_DEMONFIRE: LocalAuraIdx = LocalAuraIdx::new(17);
364pub(crate) const AURA_RECENTLY_DEMON_HAS_BEEN_SUMMONED_DNT: LocalAuraIdx = LocalAuraIdx::new(
365    18,
366);
367pub(crate) const AURA_TRACK_PETS: LocalAuraIdx = LocalAuraIdx::new(19);
368pub(crate) const AURA_INFERNAL_BOLT: LocalAuraIdx = LocalAuraIdx::new(20);
369pub(crate) const AURA_RUINATION: LocalAuraIdx = LocalAuraIdx::new(21);
370pub(crate) const AURA_DIABOLIC_RITUAL_TALENT: LocalAuraIdx = LocalAuraIdx::new(22);
371pub(crate) const AURA_DIABOLIC_RITUAL_OVERLORD: LocalAuraIdx = LocalAuraIdx::new(23);
372pub(crate) const AURA_DIABOLIC_RITUAL_MOTHER: LocalAuraIdx = LocalAuraIdx::new(24);
373pub(crate) const AURA_DIABOLIC_RITUAL_PIT_LORD: LocalAuraIdx = LocalAuraIdx::new(25);
374pub(crate) const AURA_DEMONIC_ART_OVERLORD: LocalAuraIdx = LocalAuraIdx::new(26);
375pub(crate) const AURA_DEMONIC_ART_MOTHER: LocalAuraIdx = LocalAuraIdx::new(27);
376pub(crate) const AURA_DEMONIC_ART_PIT_LORD: LocalAuraIdx = LocalAuraIdx::new(28);
377pub(crate) const AURA_DEMONIC_OCULI: LocalAuraIdx = LocalAuraIdx::new(29);
378pub(crate) const AURA_DIABOLIC_OCULI_TALENT: LocalAuraIdx = LocalAuraIdx::new(30);
379pub(crate) const AURA_LOOKS_THAT_KILL_TALENT: LocalAuraIdx = LocalAuraIdx::new(31);
380pub(crate) const AURA_MINDS_EYES_TALENT: LocalAuraIdx = LocalAuraIdx::new(32);
381pub(crate) const AURA_MINDS_EYES: LocalAuraIdx = LocalAuraIdx::new(33);
382pub(crate) const AURA_OVERFIEND: LocalAuraIdx = LocalAuraIdx::new(34);
383pub(crate) const AURA_AVATAR_OF_DESTRUCTION_TALENT: LocalAuraIdx = LocalAuraIdx::new(35);
384pub(crate) const AURA_EMBERS_OF_NIHILAM_1_TALENT: LocalAuraIdx = LocalAuraIdx::new(36);
385pub(crate) const AURA_EMBERS_OF_NIHILAM_2_TALENT: LocalAuraIdx = LocalAuraIdx::new(37);
386pub(crate) const AURA_EMBERS_OF_NIHILAM_3_TALENT: LocalAuraIdx = LocalAuraIdx::new(38);
387pub(crate) const AURA_VISION_OF_NIHILAM: LocalAuraIdx = LocalAuraIdx::new(39);
388pub(crate) const AURA_INFERNAL_EMBERS: LocalAuraIdx = LocalAuraIdx::new(40);
389pub(crate) const AURA_RAIN_OF_CHAOS: LocalAuraIdx = LocalAuraIdx::new(41);
390pub(crate) const AURA_CRASHING_CHAOS: LocalAuraIdx = LocalAuraIdx::new(42);
391pub(crate) const AURA_COUNT: usize = 43;
392const _: () = assert!(
393    AURA_COUNT == 43, "AURA index ABI: count changed -- update positional hook consumers"
394);
395pub(crate) const SPELL_SUMMON_FELHUNTER: LocalSpellIdx = LocalSpellIdx::new(0);
396pub(crate) const SPELL_SUMMON_IMP: LocalSpellIdx = LocalSpellIdx::new(1);
397pub(crate) const SPELL_GRIMOIRE_OF_SACRIFICE: LocalSpellIdx = LocalSpellIdx::new(2);
398pub(crate) const SPELL_IMMOLATE: LocalSpellIdx = LocalSpellIdx::new(3);
399pub(crate) const SPELL_INCINERATE: LocalSpellIdx = LocalSpellIdx::new(4);
400pub(crate) const SPELL_CONFLAGRATE: LocalSpellIdx = LocalSpellIdx::new(5);
401pub(crate) const SPELL_CHAOS_BOLT: LocalSpellIdx = LocalSpellIdx::new(6);
402pub(crate) const SPELL_RAIN_OF_FIRE: LocalSpellIdx = LocalSpellIdx::new(7);
403pub(crate) const SPELL_SHADOWBURN: LocalSpellIdx = LocalSpellIdx::new(8);
404pub(crate) const SPELL_SOUL_FIRE: LocalSpellIdx = LocalSpellIdx::new(9);
405pub(crate) const SPELL_CATACLYSM: LocalSpellIdx = LocalSpellIdx::new(10);
406pub(crate) const SPELL_CHANNEL_DEMONFIRE: LocalSpellIdx = LocalSpellIdx::new(11);
407pub(crate) const SPELL_CHANNEL_DEMONFIRE_TICK: LocalSpellIdx = LocalSpellIdx::new(12);
408pub(crate) const SPELL_HAVOC: LocalSpellIdx = LocalSpellIdx::new(13);
409pub(crate) const SPELL_SHADOW_BOLT: LocalSpellIdx = LocalSpellIdx::new(14);
410pub(crate) const SPELL_CORRUPTION: LocalSpellIdx = LocalSpellIdx::new(15);
411pub(crate) const SPELL_MALEVOLENCE: LocalSpellIdx = LocalSpellIdx::new(16);
412pub(crate) const SPELL_DRAIN_LIFE: LocalSpellIdx = LocalSpellIdx::new(17);
413pub(crate) const SPELL_INFERNAL_BOLT: LocalSpellIdx = LocalSpellIdx::new(18);
414pub(crate) const SPELL_RUINATION: LocalSpellIdx = LocalSpellIdx::new(19);
415pub(crate) const SPELL_SUMMON_INFERNAL: LocalSpellIdx = LocalSpellIdx::new(20);
416pub(crate) const SPELL_COUNT: usize = 21;
417const _: () = assert!(
418    SPELL_COUNT == 21,
419    "SPELL index ABI: count changed -- update positional hook consumers"
420);
421pub(crate) mod EFFECT {
422    ///<https://wowlab.gg/inspect/spell/20153>
423    pub(crate) const IMMOLATION_DAMAGE: (u32, u8) = (20153, 1);
424    ///<https://wowlab.gg/inspect/spell/116858>
425    pub(crate) const CHAOS_BOLT_DAMAGE: (u32, u8) = (116_858, 1);
426    ///<https://wowlab.gg/inspect/spell/1265884>
427    pub(crate) const ECHO_OF_SARGERAS_DAMAGE: (u32, u8) = (1_265_884, 1);
428    ///<https://wowlab.gg/inspect/spell/7814>
429    pub(crate) const LASH_OF_PAIN_DAMAGE: (u32, u8) = (7814, 1);
430    ///<https://wowlab.gg/inspect/spell/42223>
431    pub(crate) const RAIN_OF_FIRE_DAMAGE: (u32, u8) = (42223, 1);
432    ///<https://wowlab.gg/inspect/spell/5740>
433    pub(crate) const RAIN_OF_FIRE_TIMING: (u32, u8) = (5740, 3);
434    ///<https://wowlab.gg/inspect/spell/432120>
435    pub(crate) const WICKED_CLEAVE_DAMAGE: (u32, u8) = (432_120, 1);
436    ///<https://wowlab.gg/inspect/spell/432596>
437    pub(crate) const CHAOS_SALVO_DAMAGE: (u32, u8) = (432_596, 1);
438    ///<https://wowlab.gg/inspect/spell/434404>
439    pub(crate) const FELSEEKER_DAMAGE: (u32, u8) = (434_404, 1);
440    ///<https://wowlab.gg/inspect/spell/1269800>
441    pub(crate) const EYE_EXPLOSION_DAMAGE: (u32, u8) = (1_269_800, 1);
442    ///<https://wowlab.gg/inspect/spell/1269892>
443    pub(crate) const DIABOLIC_GAZE_1_DAMAGE: (u32, u8) = (1_269_892, 1);
444    ///<https://wowlab.gg/inspect/spell/1269886>
445    pub(crate) const DIABOLIC_GAZE_2_DAMAGE: (u32, u8) = (1_269_886, 1);
446    ///<https://wowlab.gg/inspect/spell/1269885>
447    pub(crate) const DIABOLIC_GAZE_3_DAMAGE: (u32, u8) = (1_269_885, 1);
448}
449static REPORTED_SPELLS: &[(&str, u32)] = &[
450    ("chaos_salvo", 432_596),
451    ("diabolic_gaze_1", 1_269_892),
452    ("diabolic_gaze_2", 1_269_886),
453    ("diabolic_gaze_3", 1_269_885),
454    ("echo_of_sargeras", 1_265_884),
455    ("echo_of_sargeras_cb", 1_277_879),
456    ("echo_of_sargeras_sb", 1_265_774),
457    ("eye_explosion", 1_269_800),
458    ("felseeker", 434_404),
459    ("immolation", 20153),
460    ("infernal_melee", 111_685),
461    ("lash_of_pain", 7814),
462    ("wicked_cleave", 432_120),
463];
464static DECLARED_SPELL_IDS: &[u32] = &[
465    691, 688, 108_503, 348, 29722, 17962, 116_858, 5740, 17877, 6353, 152_108, 196_447,
466    196_448, 80240, 686, 172, 430_014, 234_153, 434_506, 434_635, 1122, 157_736, 117_828,
467    266_030, 205_148, 387_109, 387_109, 387_263, 1_245_664, 1_245_633, 387_108,
468    1_244_860, 1_244_788, 80240, 387_157, 196_099, 445_474, 442_726, 196_447, 1_288_970,
469    462_599, 433_891, 433_885, 428_514, 431_944, 432_815, 432_816, 428_524, 432_794,
470    432_795, 1_269_643, 1_268_709, 1_268_713, 1_268_716, 1_269_879, 457_578, 1_245_089,
471    1_265_770, 1_265_772, 1_265_774, 1_265_939, 264_364, 266_087, 417_282, 1, 5740, 7814,
472    20153, 42223, 77220, 111_685, 116_858, 157_736, 196_448, 264_364, 264_365, 281_490,
473    432_120, 432_596, 434_404, 434_506, 1_265_772, 1_265_774, 1_265_884, 1_269_800,
474    1_269_879, 1_269_885, 1_269_886, 1_269_892, 1_277_879, 432_596, 1_269_892, 1_269_886,
475    1_269_885, 1_265_884, 1_277_879, 1_265_774, 1_269_800, 434_404, 20153, 111_685, 7814,
476    432_120, 445_736, 445_731, 430_014, 446_285, 445_465, 445_468, 445_731, 442_726,
477    445_474, 434_506, 434_635, 434_636, 434_424, 432_794, 428_524, 432_795, 1_269_643,
478    432_815, 431_944, 432_816, 433_891, 1_269_879, 433_885,
479];
480static DECLARED_AURA_IDS: &[u32] = &[
481    157_736, 117_828, 266_030, 205_148, 387_109, 387_109, 387_263, 1_245_664, 1_245_633,
482    387_108, 1_244_860, 1_244_788, 80240, 387_157, 196_099, 445_474, 442_726, 196_447,
483    1_288_970, 462_599, 433_891, 433_885, 428_514, 431_944, 432_815, 432_816, 428_524,
484    432_794, 432_795, 1_269_643, 1_268_709, 1_268_713, 1_268_716, 1_269_879, 457_578,
485    1_245_089, 1_265_770, 1_265_772, 1_265_774, 1_265_939, 264_364, 266_087, 417_282,
486    445_731, 442_726, 445_474, 434_424, 432_794, 428_524, 432_795, 1_269_643, 432_815,
487    431_944, 432_816, 433_891, 1_269_879, 433_885,
488];
489static TALENTS: &[(&str, u32)] = &[
490    ("AVATAR_OF_DESTRUCTION", TALENT::AVATAR_OF_DESTRUCTION),
491    ("BACKDRAFT", TALENT::BACKDRAFT),
492    ("CATACLYSM", TALENT::CATACLYSM),
493    ("CHANNEL_DEMONFIRE", TALENT::CHANNEL_DEMONFIRE),
494    ("CHAOS_INCARNATE", TALENT::CHAOS_INCARNATE),
495    ("CHAOTIC_INFERNO", TALENT::CHAOTIC_INFERNO),
496    ("CONFLAGRATE", TALENT::CONFLAGRATE),
497    ("CONFLAGRATION_OF_CHAOS", TALENT::CONFLAGRATION_OF_CHAOS),
498    ("CRASHING_CHAOS", TALENT::CRASHING_CHAOS),
499    ("DEMONFIRE_INFUSION", TALENT::DEMONFIRE_INFUSION),
500    ("DIABOLIC_EMBERS", TALENT::DIABOLIC_EMBERS),
501    ("DIABOLIC_OCULI", TALENT::DIABOLIC_OCULI),
502    ("DIABOLIC_RITUAL", TALENT::DIABOLIC_RITUAL),
503    ("EMBERSTORM", TALENT::EMBERSTORM),
504    ("EMBERS_OF_NIHILAM_1", TALENT::EMBERS_OF_NIHILAM_1),
505    ("EMBERS_OF_NIHILAM_2", TALENT::EMBERS_OF_NIHILAM_2),
506    ("EMBERS_OF_NIHILAM_3", TALENT::EMBERS_OF_NIHILAM_3),
507    ("FIENDISH_CRUELTY", TALENT::FIENDISH_CRUELTY),
508    ("FIRE_AND_BRIMSTONE", TALENT::FIRE_AND_BRIMSTONE),
509    ("FLASHPOINT", TALENT::FLASHPOINT),
510    ("GRIMOIRE_OF_SACRIFICE", TALENT::GRIMOIRE_OF_SACRIFICE),
511    ("HAVOC", TALENT::HAVOC),
512    ("IMPROVED_CONFLAGRATE", TALENT::IMPROVED_CONFLAGRATE),
513    ("INFERNO", TALENT::INFERNO),
514    ("INTERNAL_COMBUSTION", TALENT::INTERNAL_COMBUSTION),
515    ("LOOKS_THAT_KILL", TALENT::LOOKS_THAT_KILL),
516    ("MALEVOLENCE", TALENT::MALEVOLENCE),
517    ("MAYHEM", TALENT::MAYHEM),
518    ("MINDS_EYES", TALENT::MINDS_EYES),
519    ("RAGING_DEMONFIRE", TALENT::RAGING_DEMONFIRE),
520    ("RAIN_OF_CHAOS", TALENT::RAIN_OF_CHAOS),
521    ("RAIN_OF_FIRE", TALENT::RAIN_OF_FIRE),
522    ("REVERSE_ENTROPY", TALENT::REVERSE_ENTROPY),
523    ("ROARING_BLAZE", TALENT::ROARING_BLAZE),
524    ("SHADOWBURN", TALENT::SHADOWBURN),
525    ("SOUL_FIRE", TALENT::SOUL_FIRE),
526    ("SUMMON_INFERNAL", TALENT::SUMMON_INFERNAL),
527];
528pub(crate) mod DESTRUCTION_WARLOCK {
529    pub(crate) const INCINERATE_CASTS: u32 = 0;
530    pub(crate) const CHAOS_BOLT_CASTS: u32 = 1;
531    pub(crate) const CONFLAGRATE_CASTS: u32 = 2;
532    pub(crate) const SUMMON_INFERNAL_CASTS: u32 = 3;
533    pub(crate) const RAIN_OF_FIRE_CASTS: u32 = 4;
534    pub(crate) const SHADOWBURN_CASTS: u32 = 5;
535    pub(crate) const SOUL_FIRE_CASTS: u32 = 6;
536    pub(crate) const IMMOLATE_UPTIME_MS: u32 = 7;
537    pub(crate) const BACKDRAFT_UPTIME_MS: u32 = 8;
538}
539fn aura_immolate(
540    a: AuraDefinitionDraft,
541    data: &ResolvedGameData,
542) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
543    a.on_target()
544        .apply_base_from_data(data, 157_736)?
545        .max_stacks(
546            data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(157_736))?,
547        )
548        .periodic_damage_sp_from_data(
549            data,
550            wowlab_engine_combat::PeriodicDamageDataInput {
551                tick_ms: wowlab_engine_combat::validated_milliseconds(
552                    data.period(wowlab_types::sim::SpellIdx::from_raw(157_736), 1),
553                    157_736,
554                    "periodic_damage.tick_ms",
555                )?,
556                spell_id: 157_736,
557                effect_index: 1,
558                multiplier: 1.0,
559                offset: 0.0,
560                round_decimals: Some(5),
561            },
562        )?
563        .periodic_damage_resource_gain(0.1)
564        .periodic_damage_crit_resource_gain(0.5, 0.1)
565        .apply_periodic_behavior_from_data(data, 157_736)
566}
567fn aura_backdraft(
568    a: AuraDefinitionDraft,
569    data: &ResolvedGameData,
570) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
571    Ok(
572        a
573            .on_player()
574            .apply_base_from_data(data, 117_828)?
575            .max_stacks(
576                data
577                    .require_aura_max_stacks(
578                        wowlab_types::sim::SpellIdx::from_raw(117_828),
579                    )?,
580            ),
581    )
582}
583fn aura_reverse_entropy(
584    a: AuraDefinitionDraft,
585    data: &ResolvedGameData,
586) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
587    Ok(
588        a
589            .on_player()
590            .apply_base_from_data(data, 266_030)?
591            .max_stacks(
592                data
593                    .require_aura_max_stacks(
594                        wowlab_types::sim::SpellIdx::from_raw(266_030),
595                    )?,
596            ),
597    )
598}
599fn aura_reverse_entropy_talent(
600    a: AuraDefinitionDraft,
601    data: &ResolvedGameData,
602) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
603    Ok(
604        a
605            .on_player()
606            .apply_base_from_data(data, 205_148)?
607            .max_stacks(
608                data
609                    .require_aura_max_stacks(
610                        wowlab_types::sim::SpellIdx::from_raw(205_148),
611                    )?,
612            ),
613    )
614}
615fn aura_conflagration_of_chaos_conflag(
616    a: AuraDefinitionDraft,
617    data: &ResolvedGameData,
618) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
619    Ok(
620        a
621            .on_player()
622            .apply_base_from_data(data, 387_109)?
623            .max_stacks(
624                data
625                    .require_aura_max_stacks(
626                        wowlab_types::sim::SpellIdx::from_raw(387_109),
627                    )?,
628            ),
629    )
630}
631fn aura_conflagration_of_chaos_shadowburn(
632    a: AuraDefinitionDraft,
633    data: &ResolvedGameData,
634) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
635    Ok(
636        a
637            .on_player()
638            .apply_base_from_data(data, 387_109)?
639            .max_stacks(
640                data
641                    .require_aura_max_stacks(
642                        wowlab_types::sim::SpellIdx::from_raw(387_109),
643                    )?,
644            ),
645    )
646}
647fn aura_flashpoint(
648    a: AuraDefinitionDraft,
649    data: &ResolvedGameData,
650) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
651    Ok(
652        a
653            .on_player()
654            .apply_base_from_data(data, 387_263)?
655            .max_stacks(
656                data
657                    .require_aura_max_stacks(
658                        wowlab_types::sim::SpellIdx::from_raw(387_263),
659                    )?,
660            ),
661    )
662}
663fn aura_fiendish_cruelty(
664    a: AuraDefinitionDraft,
665    data: &ResolvedGameData,
666) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
667    Ok(
668        a
669            .on_player()
670            .apply_base_from_data(data, 1_245_664)?
671            .max_stacks(
672                data
673                    .require_aura_max_stacks(
674                        wowlab_types::sim::SpellIdx::from_raw(1_245_664),
675                    )?,
676            ),
677    )
678}
679fn aura_fiendish_cruelty_talent(
680    a: AuraDefinitionDraft,
681    data: &ResolvedGameData,
682) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
683    Ok(
684        a
685            .on_player()
686            .apply_base_from_data(data, 1_245_633)?
687            .max_stacks(
688                data
689                    .require_aura_max_stacks(
690                        wowlab_types::sim::SpellIdx::from_raw(1_245_633),
691                    )?,
692            ),
693    )
694}
695fn aura_conflagration_of_chaos_talent(
696    a: AuraDefinitionDraft,
697    data: &ResolvedGameData,
698) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
699    Ok(
700        a
701            .on_player()
702            .apply_base_from_data(data, 387_108)?
703            .max_stacks(
704                data
705                    .require_aura_max_stacks(
706                        wowlab_types::sim::SpellIdx::from_raw(387_108),
707                    )?,
708            ),
709    )
710}
711fn aura_chaotic_inferno(
712    a: AuraDefinitionDraft,
713    data: &ResolvedGameData,
714) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
715    Ok(
716        a
717            .on_player()
718            .apply_base_from_data(data, 1_244_860)?
719            .max_stacks(
720                data
721                    .require_aura_max_stacks(
722                        wowlab_types::sim::SpellIdx::from_raw(1_244_860),
723                    )?,
724            ),
725    )
726}
727fn aura_chaotic_inferno_talent(
728    a: AuraDefinitionDraft,
729    data: &ResolvedGameData,
730) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
731    Ok(
732        a
733            .on_player()
734            .apply_base_from_data(data, 1_244_788)?
735            .max_stacks(
736                data
737                    .require_aura_max_stacks(
738                        wowlab_types::sim::SpellIdx::from_raw(1_244_788),
739                    )?,
740            ),
741    )
742}
743fn aura_havoc(
744    a: AuraDefinitionDraft,
745    data: &ResolvedGameData,
746) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
747    Ok(
748        a
749            .on_target()
750            .apply_base_from_data(data, 80240)?
751            .max_stacks(
752                data
753                    .require_aura_max_stacks(
754                        wowlab_types::sim::SpellIdx::from_raw(80240),
755                    )?,
756            ),
757    )
758}
759fn aura_ritual_of_ruin(
760    a: AuraDefinitionDraft,
761    data: &ResolvedGameData,
762) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
763    Ok(
764        a
765            .on_player()
766            .apply_base_from_data(data, 387_157)?
767            .max_stacks(
768                data
769                    .require_aura_max_stacks(
770                        wowlab_types::sim::SpellIdx::from_raw(387_157),
771                    )?,
772            ),
773    )
774}
775fn aura_grimoire_of_sacrifice(
776    a: AuraDefinitionDraft,
777    data: &ResolvedGameData,
778) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
779    Ok(
780        a
781            .on_player()
782            .apply_base_from_data(data, 196_099)?
783            .max_stacks(
784                data
785                    .require_aura_max_stacks(
786                        wowlab_types::sim::SpellIdx::from_raw(196_099),
787                    )?,
788            ),
789    )
790}
791fn aura_wither(
792    a: AuraDefinitionDraft,
793    data: &ResolvedGameData,
794) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
795    a.on_target()
796        .apply_base_from_data(data, 445_474)?
797        .max_stacks(
798            data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(445_474))?,
799        )
800        .periodic_damage_sp(
801            wowlab_engine_combat::validated_milliseconds(
802                3000.0,
803                445_474,
804                "periodic_damage.tick_ms",
805            )?,
806            0.16,
807            wowlab_engine_combat::DamageFlags::empty(),
808        )
809        .apply_periodic_behavior_from_data(data, 445_474)
810}
811fn aura_malevolence(
812    a: AuraDefinitionDraft,
813    data: &ResolvedGameData,
814) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
815    Ok(
816        a
817            .on_player()
818            .apply_base_from_data(data, 442_726)?
819            .max_stacks(
820                data
821                    .require_aura_max_stacks(
822                        wowlab_types::sim::SpellIdx::from_raw(442_726),
823                    )?,
824            ),
825    )
826}
827fn aura_channel_demonfire(
828    a: AuraDefinitionDraft,
829    data: &ResolvedGameData,
830) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
831    Ok(
832        a
833            .on_player()
834            .apply_base_from_data(data, 196_447)?
835            .max_stacks(
836                data
837                    .require_aura_max_stacks(
838                        wowlab_types::sim::SpellIdx::from_raw(196_447),
839                    )?,
840            ),
841    )
842}
843fn aura_recently_demon_has_been_summoned_dnt(
844    a: AuraDefinitionDraft,
845    data: &ResolvedGameData,
846) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
847    Ok(
848        a
849            .on_player()
850            .apply_base_from_data(data, 1_288_970)?
851            .max_stacks(
852                data
853                    .require_aura_max_stacks(
854                        wowlab_types::sim::SpellIdx::from_raw(1_288_970),
855                    )?,
856            ),
857    )
858}
859fn aura_track_pets(
860    a: AuraDefinitionDraft,
861    data: &ResolvedGameData,
862) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
863    Ok(
864        a
865            .on_player()
866            .apply_base_from_data(data, 462_599)?
867            .max_stacks(
868                data
869                    .require_aura_max_stacks(
870                        wowlab_types::sim::SpellIdx::from_raw(462_599),
871                    )?,
872            ),
873    )
874}
875fn aura_infernal_bolt(
876    a: AuraDefinitionDraft,
877    data: &ResolvedGameData,
878) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
879    Ok(
880        a
881            .on_player()
882            .apply_base_from_data(data, 433_891)?
883            .max_stacks(
884                data
885                    .require_aura_max_stacks(
886                        wowlab_types::sim::SpellIdx::from_raw(433_891),
887                    )?,
888            ),
889    )
890}
891fn aura_ruination(
892    a: AuraDefinitionDraft,
893    data: &ResolvedGameData,
894) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
895    Ok(
896        a
897            .on_player()
898            .apply_base_from_data(data, 433_885)?
899            .max_stacks(
900                data
901                    .require_aura_max_stacks(
902                        wowlab_types::sim::SpellIdx::from_raw(433_885),
903                    )?,
904            ),
905    )
906}
907fn aura_diabolic_ritual_talent(
908    a: AuraDefinitionDraft,
909    data: &ResolvedGameData,
910) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
911    Ok(
912        a
913            .on_player()
914            .apply_base_from_data(data, 428_514)?
915            .max_stacks(
916                data
917                    .require_aura_max_stacks(
918                        wowlab_types::sim::SpellIdx::from_raw(428_514),
919                    )?,
920            ),
921    )
922}
923fn aura_diabolic_ritual_overlord(
924    a: AuraDefinitionDraft,
925    data: &ResolvedGameData,
926) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
927    Ok(
928        a
929            .on_player()
930            .apply_base_from_data(data, 431_944)?
931            .max_stacks(
932                data
933                    .require_aura_max_stacks(
934                        wowlab_types::sim::SpellIdx::from_raw(431_944),
935                    )?,
936            )
937            .on_expire(
938                crate::hooks::destruction_warlock::destruction_diabolic_ritual_overlord_expire_hook,
939            ),
940    )
941}
942fn aura_diabolic_ritual_mother(
943    a: AuraDefinitionDraft,
944    data: &ResolvedGameData,
945) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
946    Ok(
947        a
948            .on_player()
949            .apply_base_from_data(data, 432_815)?
950            .max_stacks(
951                data
952                    .require_aura_max_stacks(
953                        wowlab_types::sim::SpellIdx::from_raw(432_815),
954                    )?,
955            )
956            .on_expire(
957                crate::hooks::destruction_warlock::destruction_diabolic_ritual_mother_expire_hook,
958            ),
959    )
960}
961fn aura_diabolic_ritual_pit_lord(
962    a: AuraDefinitionDraft,
963    data: &ResolvedGameData,
964) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
965    Ok(
966        a
967            .on_player()
968            .apply_base_from_data(data, 432_816)?
969            .max_stacks(
970                data
971                    .require_aura_max_stacks(
972                        wowlab_types::sim::SpellIdx::from_raw(432_816),
973                    )?,
974            )
975            .on_expire(
976                crate::hooks::destruction_warlock::destruction_diabolic_ritual_pit_lord_expire_hook,
977            ),
978    )
979}
980fn aura_demonic_art_overlord(
981    a: AuraDefinitionDraft,
982    data: &ResolvedGameData,
983) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
984    Ok(
985        a
986            .on_player()
987            .apply_base_from_data(data, 428_524)?
988            .max_stacks(
989                data
990                    .require_aura_max_stacks(
991                        wowlab_types::sim::SpellIdx::from_raw(428_524),
992                    )?,
993            )
994            .on_expire(
995                crate::hooks::destruction_warlock::destruction_demonic_art_overlord_expire_hook,
996            ),
997    )
998}
999fn aura_demonic_art_mother(
1000    a: AuraDefinitionDraft,
1001    data: &ResolvedGameData,
1002) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
1003    Ok(
1004        a
1005            .on_player()
1006            .apply_base_from_data(data, 432_794)?
1007            .max_stacks(
1008                data
1009                    .require_aura_max_stacks(
1010                        wowlab_types::sim::SpellIdx::from_raw(432_794),
1011                    )?,
1012            )
1013            .on_expire(
1014                crate::hooks::destruction_warlock::destruction_demonic_art_mother_expire_hook,
1015            ),
1016    )
1017}
1018fn aura_demonic_art_pit_lord(
1019    a: AuraDefinitionDraft,
1020    data: &ResolvedGameData,
1021) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
1022    Ok(
1023        a
1024            .on_player()
1025            .apply_base_from_data(data, 432_795)?
1026            .max_stacks(
1027                data
1028                    .require_aura_max_stacks(
1029                        wowlab_types::sim::SpellIdx::from_raw(432_795),
1030                    )?,
1031            )
1032            .on_expire(
1033                crate::hooks::destruction_warlock::destruction_demonic_art_pit_lord_expire_hook,
1034            ),
1035    )
1036}
1037fn aura_demonic_oculi(
1038    a: AuraDefinitionDraft,
1039    data: &ResolvedGameData,
1040) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
1041    Ok(
1042        a
1043            .on_player()
1044            .apply_base_from_data(data, 1_269_643)?
1045            .max_stacks(
1046                data
1047                    .require_aura_max_stacks(
1048                        wowlab_types::sim::SpellIdx::from_raw(1_269_643),
1049                    )?,
1050            ),
1051    )
1052}
1053fn aura_diabolic_oculi_talent(
1054    a: AuraDefinitionDraft,
1055    data: &ResolvedGameData,
1056) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
1057    Ok(
1058        a
1059            .on_player()
1060            .apply_base_from_data(data, 1_268_709)?
1061            .max_stacks(
1062                data
1063                    .require_aura_max_stacks(
1064                        wowlab_types::sim::SpellIdx::from_raw(1_268_709),
1065                    )?,
1066            ),
1067    )
1068}
1069fn aura_looks_that_kill_talent(
1070    a: AuraDefinitionDraft,
1071    data: &ResolvedGameData,
1072) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
1073    Ok(
1074        a
1075            .on_player()
1076            .apply_base_from_data(data, 1_268_713)?
1077            .max_stacks(
1078                data
1079                    .require_aura_max_stacks(
1080                        wowlab_types::sim::SpellIdx::from_raw(1_268_713),
1081                    )?,
1082            ),
1083    )
1084}
1085fn aura_minds_eyes_talent(
1086    a: AuraDefinitionDraft,
1087    data: &ResolvedGameData,
1088) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
1089    Ok(
1090        a
1091            .on_player()
1092            .apply_base_from_data(data, 1_268_716)?
1093            .max_stacks(
1094                data
1095                    .require_aura_max_stacks(
1096                        wowlab_types::sim::SpellIdx::from_raw(1_268_716),
1097                    )?,
1098            ),
1099    )
1100}
1101fn aura_minds_eyes(
1102    a: AuraDefinitionDraft,
1103    data: &ResolvedGameData,
1104) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
1105    a.on_player()
1106        .apply_base_from_data(data, 1_269_879)?
1107        .max_stacks(
1108            data
1109                .require_aura_max_stacks(
1110                    wowlab_types::sim::SpellIdx::from_raw(1_269_879),
1111                )?,
1112        )
1113        .primary_pct_per_stack(
1114            data.base_points(wowlab_types::sim::SpellIdx::from_raw(1_269_879), 1),
1115        )
1116}
1117fn aura_overfiend(
1118    a: AuraDefinitionDraft,
1119    data: &ResolvedGameData,
1120) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
1121    Ok(
1122        a
1123            .on_player()
1124            .apply_base_from_data(data, 457_578)?
1125            .max_stacks(
1126                data
1127                    .require_aura_max_stacks(
1128                        wowlab_types::sim::SpellIdx::from_raw(457_578),
1129                    )?,
1130            ),
1131    )
1132}
1133fn aura_avatar_of_destruction_talent(
1134    a: AuraDefinitionDraft,
1135    data: &ResolvedGameData,
1136) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
1137    Ok(
1138        a
1139            .on_player()
1140            .apply_base_from_data(data, 1_245_089)?
1141            .max_stacks(
1142                data
1143                    .require_aura_max_stacks(
1144                        wowlab_types::sim::SpellIdx::from_raw(1_245_089),
1145                    )?,
1146            ),
1147    )
1148}
1149fn aura_embers_of_nihilam_1_talent(
1150    a: AuraDefinitionDraft,
1151    data: &ResolvedGameData,
1152) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
1153    Ok(
1154        a
1155            .on_player()
1156            .apply_base_from_data(data, 1_265_770)?
1157            .max_stacks(
1158                data
1159                    .require_aura_max_stacks(
1160                        wowlab_types::sim::SpellIdx::from_raw(1_265_770),
1161                    )?,
1162            ),
1163    )
1164}
1165fn aura_embers_of_nihilam_2_talent(
1166    a: AuraDefinitionDraft,
1167    data: &ResolvedGameData,
1168) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
1169    Ok(
1170        a
1171            .on_player()
1172            .apply_base_from_data(data, 1_265_772)?
1173            .max_stacks(
1174                data
1175                    .require_aura_max_stacks(
1176                        wowlab_types::sim::SpellIdx::from_raw(1_265_772),
1177                    )?,
1178            ),
1179    )
1180}
1181fn aura_embers_of_nihilam_3_talent(
1182    a: AuraDefinitionDraft,
1183    data: &ResolvedGameData,
1184) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
1185    Ok(
1186        a
1187            .on_player()
1188            .apply_base_from_data(data, 1_265_774)?
1189            .max_stacks(
1190                data
1191                    .require_aura_max_stacks(
1192                        wowlab_types::sim::SpellIdx::from_raw(1_265_774),
1193                    )?,
1194            ),
1195    )
1196}
1197fn aura_vision_of_nihilam(
1198    a: AuraDefinitionDraft,
1199    data: &ResolvedGameData,
1200) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
1201    a.on_player()
1202        .apply_base_from_data(data, 1_265_939)?
1203        .max_stacks(
1204            data
1205                .require_aura_max_stacks(
1206                    wowlab_types::sim::SpellIdx::from_raw(1_265_939),
1207                )?,
1208        )
1209        .haste_per_stack(
1210            (data.base_points(wowlab_types::sim::SpellIdx::from_raw(1_265_772), 1)) * 2.0,
1211        )?
1212        .crit_per_stack(
1213            (data.base_points(wowlab_types::sim::SpellIdx::from_raw(1_265_772), 1)) * 2.0,
1214        )
1215}
1216fn aura_infernal_embers(
1217    a: AuraDefinitionDraft,
1218    data: &ResolvedGameData,
1219) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
1220    Ok(
1221        a
1222            .on_player()
1223            .duration_ms(
1224                wowlab_engine_combat::validated_milliseconds(
1225                    f64::from(
1226                        data
1227                            .require_aura_duration_ms(
1228                                wowlab_types::sim::SpellIdx::from_raw(111_685),
1229                            )?,
1230                    ),
1231                    264_364,
1232                    "aura.duration_ms",
1233                )?,
1234            )
1235            .apply_periodic_effect_from_data(data, 264_364)?
1236            .apply_duration_behavior_from_data(data, 111_685)?
1237            .apply_timing_modifiers_from_data(data, 264_364)?
1238            .max_stacks(
1239                data
1240                    .require_aura_max_stacks(
1241                        wowlab_types::sim::SpellIdx::from_raw(264_364),
1242                    )?,
1243            )
1244            .periodic_resource(
1245                wowlab_engine_combat::validated_milliseconds(
1246                    data.period(wowlab_types::sim::SpellIdx::from_raw(264_364), 1),
1247                    264_364,
1248                    "periodic_resource.tick_ms",
1249                )?,
1250                (data.base_points(wowlab_types::sim::SpellIdx::from_raw(264_365), 1))
1251                    * 0.1,
1252            )
1253            .apply_periodic_behavior_from_data(data, 264_364)?
1254            .unhasted_periodic(),
1255    )
1256}
1257fn aura_rain_of_chaos(
1258    a: AuraDefinitionDraft,
1259    data: &ResolvedGameData,
1260) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
1261    Ok(
1262        a
1263            .on_player()
1264            .apply_base_from_data(data, 266_087)?
1265            .max_stacks(
1266                data
1267                    .require_aura_max_stacks(
1268                        wowlab_types::sim::SpellIdx::from_raw(266_087),
1269                    )?,
1270            ),
1271    )
1272}
1273fn aura_crashing_chaos(
1274    a: AuraDefinitionDraft,
1275    data: &ResolvedGameData,
1276) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
1277    Ok(
1278        a
1279            .on_player()
1280            .apply_base_from_data(data, 417_282)?
1281            .max_stacks(
1282                data
1283                    .require_aura_max_stacks(
1284                        wowlab_types::sim::SpellIdx::from_raw(417_282),
1285                    )?,
1286            ),
1287    )
1288}
1289fn spell_summon_felhunter(
1290    s: SpellDefinitionDraft,
1291    data: &ResolvedGameData,
1292) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1293    Ok(s.apply_base_from_data(data, 691)?.apply_aoe_from_data(data))
1294}
1295fn spell_summon_imp(
1296    s: SpellDefinitionDraft,
1297    data: &ResolvedGameData,
1298) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1299    Ok(s.apply_base_from_data(data, 688)?.apply_aoe_from_data(data))
1300}
1301fn spell_grimoire_of_sacrifice(
1302    s: SpellDefinitionDraft,
1303    data: &ResolvedGameData,
1304) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1305    Ok(
1306        s
1307            .apply_base_from_data(data, 108_503)?
1308            .applies_aura(AURA_GRIMOIRE_OF_SACRIFICE)
1309            .apply_aoe_from_data(data),
1310    )
1311}
1312fn spell_immolate(
1313    s: SpellDefinitionDraft,
1314    data: &ResolvedGameData,
1315) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1316    Ok(
1317        s
1318            .apply_base_from_data(data, 348)?
1319            .applies_aura(AURA_IMMOLATE)
1320            .apply_aoe_from_data(data),
1321    )
1322}
1323fn spell_incinerate(
1324    s: SpellDefinitionDraft,
1325    data: &ResolvedGameData,
1326) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1327    Ok(
1328        s
1329            .apply_base_from_data(data, 29722)?
1330            .gain(0.5)
1331            .apply_aoe_from_data(data)
1332            .on_cast(crate::hooks::destruction_warlock::incinerate_hook),
1333    )
1334}
1335fn spell_conflagrate(
1336    s: SpellDefinitionDraft,
1337    data: &ResolvedGameData,
1338) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1339    Ok(
1340        s
1341            .apply_base_from_data(data, 17962)?
1342            .hasted_cooldown()
1343            .gain(0.7)
1344            .apply_aoe_from_data(data)
1345            .on_cast(crate::hooks::destruction_warlock::conflagrate_hook),
1346    )
1347}
1348fn spell_chaos_bolt(
1349    s: SpellDefinitionDraft,
1350    data: &ResolvedGameData,
1351) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1352    Ok(
1353        s
1354            .apply_base_from_data(data, 116_858)?
1355            .guaranteed_crit()
1356            .apply_aoe_from_data(data)
1357            .on_cast(crate::hooks::destruction_warlock::chaos_bolt_hook),
1358    )
1359}
1360fn spell_rain_of_fire(
1361    s: SpellDefinitionDraft,
1362    data: &ResolvedGameData,
1363) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1364    Ok(
1365        s
1366            .apply_base_from_data(data, 5740)?
1367            .apply_aoe_from_data(data)
1368            .on_cast(crate::hooks::destruction_warlock::rain_of_fire_hook),
1369    )
1370}
1371fn spell_shadowburn(
1372    s: SpellDefinitionDraft,
1373    data: &ResolvedGameData,
1374) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1375    Ok(
1376        s
1377            .apply_base_from_data(data, 17877)?
1378            .apply_aoe_from_data(data)
1379            .on_cast(crate::hooks::destruction_warlock::shadowburn_hook)
1380            .cost_free_when_aura(1_245_664)
1381            .execute_below_pct(20.0),
1382    )
1383}
1384fn spell_soul_fire(
1385    s: SpellDefinitionDraft,
1386    data: &ResolvedGameData,
1387) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1388    Ok(
1389        s
1390            .apply_base_from_data(data, 6353)?
1391            .gain(
1392                (data.base_points(wowlab_types::sim::SpellIdx::from_raw(281_490), 1))
1393                    * 0.1,
1394            )
1395            .apply_aoe_from_data(data)
1396            .on_cast(crate::hooks::destruction_warlock::soul_fire_hook),
1397    )
1398}
1399fn spell_cataclysm(
1400    s: SpellDefinitionDraft,
1401    data: &ResolvedGameData,
1402) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1403    Ok(s.apply_base_from_data(data, 152_108)?.apply_aoe_from_data(data))
1404}
1405fn spell_channel_demonfire(
1406    s: SpellDefinitionDraft,
1407    data: &ResolvedGameData,
1408) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1409    s.apply_base_from_data(data, 196_447)?
1410        .applies_inferred_aura(AURA_CHANNEL_DEMONFIRE, 196_447)
1411        .apply_aoe_from_data(data)
1412        .channel(
1413            data
1414                .require_channel_tick_count(
1415                    wowlab_types::sim::SpellIdx::from_raw(196_447),
1416                )?,
1417        )
1418        .channel_tick_damage_sp_from_data(
1419            wowlab_engine_domain::dbc::EffectLookup::new(
1420                data,
1421                wowlab_types::sim::EffectRef::new(
1422                    wowlab_types::sim::SpellIdx::from_raw(196_448),
1423                    1,
1424                ),
1425            ),
1426        )
1427}
1428fn spell_channel_demonfire_tick(
1429    s: SpellDefinitionDraft,
1430    data: &ResolvedGameData,
1431) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1432    Ok(s.apply_base_from_data(data, 196_448)?.apply_aoe_from_data(data))
1433}
1434fn spell_havoc(
1435    s: SpellDefinitionDraft,
1436    data: &ResolvedGameData,
1437) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1438    Ok(
1439        s
1440            .apply_base_from_data(data, 80240)?
1441            .applies_inferred_aura(AURA_HAVOC, 80240)
1442            .apply_aoe_from_data(data),
1443    )
1444}
1445fn spell_shadow_bolt(
1446    s: SpellDefinitionDraft,
1447    data: &ResolvedGameData,
1448) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1449    Ok(s.apply_base_from_data(data, 686)?.apply_aoe_from_data(data))
1450}
1451fn spell_corruption(
1452    s: SpellDefinitionDraft,
1453    data: &ResolvedGameData,
1454) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1455    Ok(s.apply_base_from_data(data, 172)?.apply_aoe_from_data(data))
1456}
1457fn spell_malevolence(
1458    s: SpellDefinitionDraft,
1459    data: &ResolvedGameData,
1460) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1461    Ok(
1462        s
1463            .apply_base_from_data(data, 430_014)?
1464            .applies_aura(AURA_MALEVOLENCE)
1465            .apply_aoe_from_data(data),
1466    )
1467}
1468fn spell_drain_life(
1469    s: SpellDefinitionDraft,
1470    data: &ResolvedGameData,
1471) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1472    Ok(s.apply_base_from_data(data, 234_153)?.apply_aoe_from_data(data))
1473}
1474fn spell_infernal_bolt(
1475    s: SpellDefinitionDraft,
1476    data: &ResolvedGameData,
1477) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1478    Ok(
1479        s
1480            .apply_base_from_data(data, 434_506)?
1481            .gain(
1482                (data.base_points(wowlab_types::sim::SpellIdx::from_raw(434_506), 2))
1483                    * 0.1,
1484            )
1485            .apply_aoe_from_data(data)
1486            .on_cast(crate::hooks::destruction_warlock::infernal_bolt_hook)
1487            .requires_aura_at_min_stacks(433_891, 0)
1488            .consume_aura_on_cast(433_891),
1489    )
1490}
1491fn spell_ruination(
1492    s: SpellDefinitionDraft,
1493    data: &ResolvedGameData,
1494) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1495    Ok(
1496        s
1497            .apply_base_from_data(data, 434_635)?
1498            .travel_time(
1499                wowlab_engine_combat::validated_milliseconds(
1500                    1000.0,
1501                    434_635,
1502                    "spell.travel_time_ms",
1503                )?,
1504            )
1505            .apply_aoe_from_data(data)
1506            .on_cast(crate::hooks::destruction_warlock::ruination_hook)
1507            .requires_aura_at_min_stacks(433_885, 0)
1508            .consume_aura_on_cast(433_885),
1509    )
1510}
1511fn spell_summon_infernal(
1512    s: SpellDefinitionDraft,
1513    data: &ResolvedGameData,
1514) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1515    Ok(
1516        s
1517            .apply_base_from_data(data, 1122)?
1518            .apply_aoe_from_data(data)
1519            .on_cast(crate::hooks::destruction_warlock::summon_infernal_hook),
1520    )
1521}
1522pub(crate) fn build_combat_system(
1523    params: &wowlab_engine_ports::HandlerParams<'_>,
1524) -> Result<BuiltCombatSystem, wowlab_engine_ports::EngineError> {
1525    let builder = BuiltCombatSystem::builder(params.stats.clone())
1526        .spec_id(SpecId::Destruction)
1527        .hero_talent_trees(DECLARED_METADATA.hero_talent_trees)
1528        .mastery_spell(77220)
1529        .mastery_hook(crate::hooks::destruction_warlock::mastery)
1530        .resource(
1531            "soul_shards",
1532            5.0,
1533            params
1534                .game_data
1535                .power_regen_for_max(7, 5.0)
1536                .ok_or_else(|| {
1537                    wowlab_engine_ports::EngineError::spec_construction(
1538                        "missing power-type power_regen_for_max for type_id 7",
1539                    )
1540                })?,
1541        )
1542        .resource_type_id(7)
1543        .resource_start(3.0)
1544        .has_pet(true)
1545        .aura("immolate", AURA::IMMOLATE, |a| aura_immolate(a, &params.game_data))
1546        .aura("backdraft", AURA::BACKDRAFT, |a| aura_backdraft(a, &params.game_data))
1547        .aura(
1548            "reverse_entropy",
1549            AURA::REVERSE_ENTROPY,
1550            |a| aura_reverse_entropy(a, &params.game_data),
1551        )
1552        .aura(
1553            "reverse_entropy_talent",
1554            AURA::REVERSE_ENTROPY_TALENT,
1555            |a| aura_reverse_entropy_talent(a, &params.game_data),
1556        )
1557        .aura(
1558            "conflagration_of_chaos_conflag",
1559            AURA::CONFLAGRATION_OF_CHAOS_CONFLAG,
1560            |a| aura_conflagration_of_chaos_conflag(a, &params.game_data),
1561        )
1562        .aura(
1563            "conflagration_of_chaos_shadowburn",
1564            AURA::CONFLAGRATION_OF_CHAOS_SHADOWBURN,
1565            |a| aura_conflagration_of_chaos_shadowburn(a, &params.game_data),
1566        )
1567        .aura("flashpoint", AURA::FLASHPOINT, |a| aura_flashpoint(a, &params.game_data))
1568        .aura(
1569            "fiendish_cruelty",
1570            AURA::FIENDISH_CRUELTY,
1571            |a| aura_fiendish_cruelty(a, &params.game_data),
1572        )
1573        .aura(
1574            "fiendish_cruelty_talent",
1575            AURA::FIENDISH_CRUELTY_TALENT,
1576            |a| aura_fiendish_cruelty_talent(a, &params.game_data),
1577        )
1578        .aura(
1579            "conflagration_of_chaos_talent",
1580            AURA::CONFLAGRATION_OF_CHAOS_TALENT,
1581            |a| aura_conflagration_of_chaos_talent(a, &params.game_data),
1582        )
1583        .aura(
1584            "chaotic_inferno",
1585            AURA::CHAOTIC_INFERNO,
1586            |a| aura_chaotic_inferno(a, &params.game_data),
1587        )
1588        .aura(
1589            "chaotic_inferno_talent",
1590            AURA::CHAOTIC_INFERNO_TALENT,
1591            |a| aura_chaotic_inferno_talent(a, &params.game_data),
1592        )
1593        .aura("havoc", AURA::HAVOC, |a| aura_havoc(a, &params.game_data))
1594        .aura(
1595            "ritual_of_ruin",
1596            AURA::RITUAL_OF_RUIN,
1597            |a| aura_ritual_of_ruin(a, &params.game_data),
1598        )
1599        .aura(
1600            "grimoire_of_sacrifice",
1601            AURA::GRIMOIRE_OF_SACRIFICE,
1602            |a| aura_grimoire_of_sacrifice(a, &params.game_data),
1603        )
1604        .aura("wither", AURA::WITHER, |a| aura_wither(a, &params.game_data))
1605        .aura(
1606            "malevolence",
1607            AURA::MALEVOLENCE,
1608            |a| aura_malevolence(a, &params.game_data),
1609        )
1610        .aura(
1611            "channel_demonfire",
1612            AURA::CHANNEL_DEMONFIRE,
1613            |a| aura_channel_demonfire(a, &params.game_data),
1614        )
1615        .aura(
1616            "recently_demon_has_been_summoned_dnt",
1617            AURA::RECENTLY_DEMON_HAS_BEEN_SUMMONED_DNT,
1618            |a| aura_recently_demon_has_been_summoned_dnt(a, &params.game_data),
1619        )
1620        .aura("track_pets", AURA::TRACK_PETS, |a| aura_track_pets(a, &params.game_data))
1621        .aura(
1622            "infernal_bolt",
1623            AURA::INFERNAL_BOLT,
1624            |a| aura_infernal_bolt(a, &params.game_data),
1625        )
1626        .aura("ruination", AURA::RUINATION, |a| aura_ruination(a, &params.game_data))
1627        .aura(
1628            "diabolic_ritual_talent",
1629            AURA::DIABOLIC_RITUAL_TALENT,
1630            |a| aura_diabolic_ritual_talent(a, &params.game_data),
1631        )
1632        .aura(
1633            "diabolic_ritual_overlord",
1634            AURA::DIABOLIC_RITUAL_OVERLORD,
1635            |a| aura_diabolic_ritual_overlord(a, &params.game_data),
1636        )
1637        .aura(
1638            "diabolic_ritual_mother",
1639            AURA::DIABOLIC_RITUAL_MOTHER,
1640            |a| aura_diabolic_ritual_mother(a, &params.game_data),
1641        )
1642        .aura(
1643            "diabolic_ritual_pit_lord",
1644            AURA::DIABOLIC_RITUAL_PIT_LORD,
1645            |a| aura_diabolic_ritual_pit_lord(a, &params.game_data),
1646        )
1647        .aura(
1648            "demonic_art_overlord",
1649            AURA::DEMONIC_ART_OVERLORD,
1650            |a| aura_demonic_art_overlord(a, &params.game_data),
1651        )
1652        .aura(
1653            "demonic_art_mother",
1654            AURA::DEMONIC_ART_MOTHER,
1655            |a| aura_demonic_art_mother(a, &params.game_data),
1656        )
1657        .aura(
1658            "demonic_art_pit_lord",
1659            AURA::DEMONIC_ART_PIT_LORD,
1660            |a| aura_demonic_art_pit_lord(a, &params.game_data),
1661        )
1662        .aura(
1663            "demonic_oculi",
1664            AURA::DEMONIC_OCULI,
1665            |a| aura_demonic_oculi(a, &params.game_data),
1666        )
1667        .aura(
1668            "diabolic_oculi_talent",
1669            AURA::DIABOLIC_OCULI_TALENT,
1670            |a| aura_diabolic_oculi_talent(a, &params.game_data),
1671        )
1672        .aura(
1673            "looks_that_kill_talent",
1674            AURA::LOOKS_THAT_KILL_TALENT,
1675            |a| aura_looks_that_kill_talent(a, &params.game_data),
1676        )
1677        .aura(
1678            "minds_eyes_talent",
1679            AURA::MINDS_EYES_TALENT,
1680            |a| aura_minds_eyes_talent(a, &params.game_data),
1681        )
1682        .aura("minds_eyes", AURA::MINDS_EYES, |a| aura_minds_eyes(a, &params.game_data))
1683        .aura("overfiend", AURA::OVERFIEND, |a| aura_overfiend(a, &params.game_data))
1684        .aura(
1685            "avatar_of_destruction_talent",
1686            AURA::AVATAR_OF_DESTRUCTION_TALENT,
1687            |a| aura_avatar_of_destruction_talent(a, &params.game_data),
1688        )
1689        .aura(
1690            "embers_of_nihilam_1_talent",
1691            AURA::EMBERS_OF_NIHILAM_1_TALENT,
1692            |a| aura_embers_of_nihilam_1_talent(a, &params.game_data),
1693        )
1694        .aura(
1695            "embers_of_nihilam_2_talent",
1696            AURA::EMBERS_OF_NIHILAM_2_TALENT,
1697            |a| aura_embers_of_nihilam_2_talent(a, &params.game_data),
1698        )
1699        .aura(
1700            "embers_of_nihilam_3_talent",
1701            AURA::EMBERS_OF_NIHILAM_3_TALENT,
1702            |a| aura_embers_of_nihilam_3_talent(a, &params.game_data),
1703        )
1704        .aura(
1705            "vision_of_nihilam",
1706            AURA::VISION_OF_NIHILAM,
1707            |a| aura_vision_of_nihilam(a, &params.game_data),
1708        )
1709        .aura(
1710            "infernal_embers",
1711            AURA::INFERNAL_EMBERS,
1712            |a| aura_infernal_embers(a, &params.game_data),
1713        )
1714        .aura(
1715            "rain_of_chaos",
1716            AURA::RAIN_OF_CHAOS,
1717            |a| aura_rain_of_chaos(a, &params.game_data),
1718        )
1719        .aura(
1720            "crashing_chaos",
1721            AURA::CRASHING_CHAOS,
1722            |a| aura_crashing_chaos(a, &params.game_data),
1723        )
1724        .spell(
1725            "summon_felhunter",
1726            SPELL::SUMMON_FELHUNTER,
1727            |s| spell_summon_felhunter(s, &params.game_data),
1728        )
1729        .spell(
1730            "summon_imp",
1731            SPELL::SUMMON_IMP,
1732            |s| spell_summon_imp(s, &params.game_data),
1733        )
1734        .spell(
1735            "grimoire_of_sacrifice",
1736            SPELL::GRIMOIRE_OF_SACRIFICE,
1737            |s| spell_grimoire_of_sacrifice(s, &params.game_data),
1738        )
1739        .spell("immolate", SPELL::IMMOLATE, |s| spell_immolate(s, &params.game_data))
1740        .spell(
1741            "incinerate",
1742            SPELL::INCINERATE,
1743            |s| spell_incinerate(s, &params.game_data),
1744        )
1745        .spell(
1746            "conflagrate",
1747            SPELL::CONFLAGRATE,
1748            |s| spell_conflagrate(s, &params.game_data),
1749        )
1750        .spell(
1751            "chaos_bolt",
1752            SPELL::CHAOS_BOLT,
1753            |s| spell_chaos_bolt(s, &params.game_data),
1754        )
1755        .spell(
1756            "rain_of_fire",
1757            SPELL::RAIN_OF_FIRE,
1758            |s| spell_rain_of_fire(s, &params.game_data),
1759        )
1760        .spell(
1761            "shadowburn",
1762            SPELL::SHADOWBURN,
1763            |s| spell_shadowburn(s, &params.game_data),
1764        )
1765        .spell("soul_fire", SPELL::SOUL_FIRE, |s| spell_soul_fire(s, &params.game_data))
1766        .spell("cataclysm", SPELL::CATACLYSM, |s| spell_cataclysm(s, &params.game_data))
1767        .spell(
1768            "channel_demonfire",
1769            SPELL::CHANNEL_DEMONFIRE,
1770            |s| spell_channel_demonfire(s, &params.game_data),
1771        )
1772        .spell(
1773            "channel_demonfire_tick",
1774            SPELL::CHANNEL_DEMONFIRE_TICK,
1775            |s| spell_channel_demonfire_tick(s, &params.game_data),
1776        )
1777        .spell("havoc", SPELL::HAVOC, |s| spell_havoc(s, &params.game_data))
1778        .spell(
1779            "shadow_bolt",
1780            SPELL::SHADOW_BOLT,
1781            |s| spell_shadow_bolt(s, &params.game_data),
1782        )
1783        .spell(
1784            "corruption",
1785            SPELL::CORRUPTION,
1786            |s| spell_corruption(s, &params.game_data),
1787        )
1788        .spell(
1789            "malevolence",
1790            SPELL::MALEVOLENCE,
1791            |s| spell_malevolence(s, &params.game_data),
1792        )
1793        .spell(
1794            "drain_life",
1795            SPELL::DRAIN_LIFE,
1796            |s| spell_drain_life(s, &params.game_data),
1797        )
1798        .spell(
1799            "infernal_bolt",
1800            SPELL::INFERNAL_BOLT,
1801            |s| spell_infernal_bolt(s, &params.game_data),
1802        )
1803        .spell("ruination", SPELL::RUINATION, |s| spell_ruination(s, &params.game_data))
1804        .spell(
1805            "summon_infernal",
1806            SPELL::SUMMON_INFERNAL,
1807            |s| spell_summon_infernal(s, &params.game_data),
1808        )
1809        .auto_attack(|a| {
1810            a
1811                .spell_id(1)
1812                .swing_ms(3000)
1813                .apply_base_from_data(&params.game_data)
1814                .ap_coef(
1815                    wowlab_engine_domain::damage::pet_swing_power_coefficient(
1816                        0.575,
1817                        3000,
1818                        1.0,
1819                    ),
1820                )
1821                .is_pet()
1822                .uses_spell_power()
1823        })
1824        .game_data(params.game_data.clone())
1825        .talent_spell_ids(TALENTS)
1826        .talent_selections(params.talent_selections)
1827        .talent_companion_aura(
1828            TALENT::AVATAR_OF_DESTRUCTION,
1829            AURA_AVATAR_OF_DESTRUCTION_TALENT,
1830        )
1831        .talent_companion_aura(TALENT::CHAOTIC_INFERNO, AURA_CHAOTIC_INFERNO_TALENT)
1832        .talent_companion_aura(
1833            TALENT::CONFLAGRATION_OF_CHAOS,
1834            AURA_CONFLAGRATION_OF_CHAOS_TALENT,
1835        )
1836        .talent_companion_aura(TALENT::DIABOLIC_OCULI, AURA_DIABOLIC_OCULI_TALENT)
1837        .talent_companion_aura(TALENT::DIABOLIC_RITUAL, AURA_DIABOLIC_RITUAL_TALENT)
1838        .talent_companion_aura(
1839            TALENT::EMBERS_OF_NIHILAM_1,
1840            AURA_EMBERS_OF_NIHILAM_1_TALENT,
1841        )
1842        .talent_companion_aura(
1843            TALENT::EMBERS_OF_NIHILAM_2,
1844            AURA_EMBERS_OF_NIHILAM_2_TALENT,
1845        )
1846        .talent_companion_aura(
1847            TALENT::EMBERS_OF_NIHILAM_3,
1848            AURA_EMBERS_OF_NIHILAM_3_TALENT,
1849        )
1850        .talent_companion_aura(TALENT::FIENDISH_CRUELTY, AURA_FIENDISH_CRUELTY_TALENT)
1851        .talent_companion_aura(TALENT::LOOKS_THAT_KILL, AURA_LOOKS_THAT_KILL_TALENT)
1852        .talent_companion_aura(TALENT::MINDS_EYES, AURA_MINDS_EYES_TALENT)
1853        .talent_companion_aura(TALENT::REVERSE_ENTROPY, AURA_REVERSE_ENTROPY_TALENT)
1854        .set_bonus_auras(params.set_bonus_auras)
1855        .encounter(params.encounter.clone());
1856    let builder = crate::generated::items::register_equipped(
1857        builder,
1858        &params.game_data,
1859        params.equipped_items,
1860    )?;
1861
1862    builder
1863        .build(params.rotation)
1864        .map_err(wowlab_engine_ports::EngineError::rotation_compile)
1865}
1866fn new_handler(
1867    params: wowlab_engine_ports::HandlerParams<'_>,
1868) -> Result<Box<dyn SpecHandler>, wowlab_engine_ports::EngineError> {
1869    let handler = crate::composition::compose_handler(
1870        build_combat_system,
1871        &params,
1872        |parts, params| Ok(
1873            crate::hooks::destruction_warlock::DestructionHandler::new(parts, params),
1874        ),
1875    )?;
1876
1877    Ok(Box::new(handler))
1878}
1879static DECLARED_METADATA: DeclaredSpecMetadata = DeclaredSpecMetadata {
1880    primary_resource: ResourceType::SoulShards,
1881    secondary_resource: None,
1882    spell_ids: DECLARED_SPELL_IDS,
1883    aura_ids: DECLARED_AURA_IDS,
1884    server_proc_entries: &[
1885        DeclaredServerProcEntry {
1886            spell_id: 117_828,
1887            attributes: ProcAttributes::REQUIRE_SPELL_MODIFIER.bits()
1888                | ProcAttributes::USE_STACKS_FOR_CHARGES.bits(),
1889        },
1890    ],
1891    talents: TALENTS,
1892    rotation_field_schema: &[],
1893    metrics_plugin_id: None,
1894    hero_talent_trees: &[
1895        HeroTalentTreeDesc {
1896            name: "Hellcaller",
1897            spells: HERO_TREE_HELLCALLER_SPELLS,
1898            auras: HERO_TREE_HELLCALLER_AURAS,
1899        },
1900        HeroTalentTreeDesc {
1901            name: "Diabolist",
1902            spells: HERO_TREE_DIABOLIST_SPELLS,
1903            auras: HERO_TREE_DIABOLIST_AURAS,
1904        },
1905    ],
1906    reported_spells: REPORTED_SPELLS,
1907    masked_passive_effects: &[],
1908    passive_effect_overrides: &[],
1909};
1910pub(super) const SPEC_DESCRIPTOR: SpecDescriptor = SpecDescriptor {
1911    spec_id: SpecId::Destruction,
1912    display_name: "Destruction Warlock",
1913    metadata: DECLARED_METADATA,
1914    handler_factory: new_handler,
1915};
1916wowlab_engine_combat::smoke_test!(build_combat_system);