Skip to main content

wowlab_engine_content/generated/specs/
fire_mage.rs

1//! @generated by codegen-cli from manifests/specs/mage/fire/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_combat::{
6    BuiltCombatSystem, AuraDefinitionDraft, LocalAuraIdx, LocalSpellIdx,
7    SpellDefinitionDraft,
8};
9use wowlab_engine_ports::{
10    DeclaredSpecMetadata, SpecDescriptor, SpecHandler, HeroTalentTreeDesc,
11};
12use wowlab_engine_gamedata::ResolvedGameData;
13pub(crate) mod SPELL {
14    ///<https://wowlab.gg/inspect/spell/133>
15    pub(crate) const FIREBALL: u32 = 133;
16    ///<https://wowlab.gg/inspect/spell/11366>
17    pub(crate) const PYROBLAST: u32 = 11366;
18    ///<https://wowlab.gg/inspect/spell/108853>
19    pub(crate) const FIRE_BLAST: u32 = 108_853;
20    ///<https://wowlab.gg/inspect/spell/2120>
21    pub(crate) const FLAMESTRIKE: u32 = 2120;
22    ///<https://wowlab.gg/inspect/spell/190319>
23    pub(crate) const COMBUSTION: u32 = 190_319;
24    ///<https://wowlab.gg/inspect/spell/153561>
25    pub(crate) const METEOR: u32 = 153_561;
26    ///<https://wowlab.gg/inspect/spell/2948>
27    pub(crate) const SCORCH: u32 = 2948;
28    ///<https://wowlab.gg/inspect/spell/431044>
29    pub(crate) const FROSTFIRE_BOLT: u32 = 431_044;
30    ///<https://wowlab.gg/inspect/spell/1459>
31    pub(crate) const ARCANE_INTELLECT: u32 = 1459;
32    ///<https://wowlab.gg/inspect/spell/12654>
33    pub(crate) const IGNITE: u32 = 12654;
34    ///<https://wowlab.gg/inspect/spell/419800>
35    pub(crate) const INTENSIFYING_FLAME: u32 = 419_800;
36    ///<https://wowlab.gg/inspect/spell/1271335>
37    pub(crate) const BURNOUT: u32 = 1_271_335;
38}
39pub(crate) mod AURA {
40    ///<https://wowlab.gg/inspect/spell/48107>
41    pub(crate) const HEATING_UP: u32 = 48107;
42    ///<https://wowlab.gg/inspect/spell/48108>
43    pub(crate) const HOT_STREAK: u32 = 48108;
44    ///<https://wowlab.gg/inspect/spell/190319>
45    pub(crate) const COMBUSTION: u32 = 190_319;
46    ///<https://wowlab.gg/inspect/spell/12654>
47    pub(crate) const IGNITE: u32 = 12654;
48    ///<https://wowlab.gg/inspect/spell/453268>
49    pub(crate) const CONTROLLED_DESTRUCTION: u32 = 453_268;
50    ///<https://wowlab.gg/inspect/spell/383874>
51    pub(crate) const HYPERTHERMIA: u32 = 383_874;
52    ///<https://wowlab.gg/inspect/spell/1242220>
53    pub(crate) const HYPERTHERMIA_DAMAGE: u32 = 1_242_220;
54    ///<https://wowlab.gg/inspect/spell/157644>
55    pub(crate) const PYROTECHNICS: u32 = 157_644;
56    ///<https://wowlab.gg/inspect/spell/269651>
57    pub(crate) const PYROCLASM: u32 = 269_651;
58    ///<https://wowlab.gg/inspect/spell/383395>
59    pub(crate) const FEEL_THE_BURN: u32 = 383_395;
60    ///<https://wowlab.gg/inspect/spell/383811>
61    pub(crate) const FEVERED_INCANTATION: u32 = 383_811;
62    ///<https://wowlab.gg/inspect/spell/1257350>
63    pub(crate) const FIRED_UP: u32 = 1_257_350;
64    ///<https://wowlab.gg/inspect/spell/458964>
65    pub(crate) const HEAT_SHIMMER: u32 = 458_964;
66    ///<https://wowlab.gg/inspect/spell/431177>
67    pub(crate) const FROSTFIRE_EMPOWERMENT: u32 = 431_177;
68    ///<https://wowlab.gg/inspect/spell/1459>
69    pub(crate) const ARCANE_INTELLECT_HIGHLIGHT: u32 = 1459;
70    ///<https://wowlab.gg/inspect/spell/448604>
71    pub(crate) const SPELLFIRE_SPHERE: u32 = 448_604;
72    ///<https://wowlab.gg/inspect/spell/383637>
73    pub(crate) const FIERY_RUSH_EFFECT: u32 = 383_637;
74}
75pub(crate) mod TALENT {
76    ///<https://wowlab.gg/inspect/spell/1271177>
77    pub(crate) const BURNOUT: u32 = 1_271_177;
78    ///<https://wowlab.gg/inspect/spell/1254512>
79    pub(crate) const BURN_IT_ALL: u32 = 1_254_512;
80    ///<https://wowlab.gg/inspect/spell/1254865>
81    pub(crate) const CINDERSTORM: u32 = 1_254_865;
82    ///<https://wowlab.gg/inspect/spell/449382>
83    pub(crate) const CODEX_OF_THE_SUNSTRIDERS: u32 = 449_382;
84    ///<https://wowlab.gg/inspect/spell/190319>
85    pub(crate) const COMBUSTION: u32 = 190_319;
86    ///<https://wowlab.gg/inspect/spell/1271171>
87    pub(crate) const CONFLAGRATION: u32 = 1_271_171;
88    ///<https://wowlab.gg/inspect/spell/383669>
89    pub(crate) const CONTROLLED_DESTRUCTION: u32 = 383_669;
90    ///<https://wowlab.gg/inspect/spell/117216>
91    pub(crate) const CRITICAL_MASS: u32 = 117_216;
92    ///<https://wowlab.gg/inspect/spell/416719>
93    pub(crate) const DEEP_IMPACT: u32 = 416_719;
94    ///<https://wowlab.gg/inspect/spell/383391>
95    pub(crate) const FEEL_THE_BURN: u32 = 383_391;
96    ///<https://wowlab.gg/inspect/spell/383810>
97    pub(crate) const FEVERED_INCANTATION: u32 = 383_810;
98    ///<https://wowlab.gg/inspect/spell/383634>
99    pub(crate) const FIERY_RUSH: u32 = 383_634;
100    ///<https://wowlab.gg/inspect/spell/1257343>
101    pub(crate) const FIRED_UP_1: u32 = 1_257_343;
102    ///<https://wowlab.gg/inspect/spell/1257349>
103    pub(crate) const FIRED_UP_2: u32 = 1_257_349;
104    ///<https://wowlab.gg/inspect/spell/1257348>
105    pub(crate) const FIRED_UP_3: u32 = 1_257_348;
106    ///<https://wowlab.gg/inspect/spell/205026>
107    pub(crate) const FIRESTARTER: u32 = 205_026;
108    ///<https://wowlab.gg/inspect/spell/450831>
109    pub(crate) const FIRES_IRE: u32 = 450_831;
110    ///<https://wowlab.gg/inspect/spell/108853>
111    pub(crate) const FIRE_BLAST: u32 = 108_853;
112    ///<https://wowlab.gg/inspect/spell/2120>
113    pub(crate) const FLAMESTRIKE: u32 = 2120;
114    ///<https://wowlab.gg/inspect/spell/205029>
115    pub(crate) const FLAME_ON: u32 = 205_029;
116    ///<https://wowlab.gg/inspect/spell/342344>
117    pub(crate) const FROM_THE_ASHES: u32 = 342_344;
118    ///<https://wowlab.gg/inspect/spell/383550>
119    pub(crate) const FUEL_THE_FIRE: u32 = 383_550;
120    ///<https://wowlab.gg/inspect/spell/457736>
121    pub(crate) const HEAT_SHIMMER: u32 = 457_736;
122    ///<https://wowlab.gg/inspect/spell/383549>
123    pub(crate) const IGNITION: u32 = 383_549;
124    ///<https://wowlab.gg/inspect/spell/417467>
125    pub(crate) const INFLAME: u32 = 417_467;
126    ///<https://wowlab.gg/inspect/spell/416714>
127    pub(crate) const INTENSIFYING_FLAME: u32 = 416_714;
128    ///<https://wowlab.gg/inspect/spell/448658>
129    pub(crate) const INVOCATION_ARCANE_PHOENIX: u32 = 448_658;
130    ///<https://wowlab.gg/inspect/spell/155148>
131    pub(crate) const KINDLING: u32 = 155_148;
132    ///<https://wowlab.gg/inspect/spell/384174>
133    pub(crate) const MASTER_OF_FLAME: u32 = 384_174;
134    ///<https://wowlab.gg/inspect/spell/449619>
135    pub(crate) const MEMORY_OF_ALAR: u32 = 449_619;
136    ///<https://wowlab.gg/inspect/spell/153561>
137    pub(crate) const METEOR: u32 = 153_561;
138    ///<https://wowlab.gg/inspect/spell/457803>
139    pub(crate) const MOLTEN_FURY: u32 = 457_803;
140    ///<https://wowlab.gg/inspect/spell/11366>
141    pub(crate) const PYROBLAST: u32 = 11366;
142    ///<https://wowlab.gg/inspect/spell/269650>
143    pub(crate) const PYROCLASM: u32 = 269_650;
144    ///<https://wowlab.gg/inspect/spell/451466>
145    pub(crate) const PYROMANIAC: u32 = 451_466;
146    ///<https://wowlab.gg/inspect/spell/449412>
147    pub(crate) const SAVOR_THE_MOMENT: u32 = 449_412;
148    ///<https://wowlab.gg/inspect/spell/450746>
149    pub(crate) const SCALD: u32 = 450_746;
150    ///<https://wowlab.gg/inspect/spell/2948>
151    pub(crate) const SCORCH: u32 = 2948;
152    ///<https://wowlab.gg/inspect/spell/383967>
153    pub(crate) const SLOW_BURN: u32 = 383_967;
154    ///<https://wowlab.gg/inspect/spell/451875>
155    pub(crate) const SPONTANEOUS_COMBUSTION: u32 = 451_875;
156    ///<https://wowlab.gg/inspect/spell/383489>
157    pub(crate) const WILDFIRE: u32 = 383_489;
158}
159pub(crate) mod SET_BONUS {
160    ///<https://wowlab.gg/inspect/spell/1264835>
161    pub(crate) const MID1_FIRE_4PC: u32 = 1_264_835;
162}
163pub(crate) mod REPORTED_SPELL {
164    ///<https://wowlab.gg/inspect/spell/450499>
165    pub(crate) const ARCANE_BARRAGE: u32 = 450_499;
166    ///<https://wowlab.gg/inspect/spell/448659>
167    pub(crate) const ARCANE_PHOENIX_CONTROLLER: u32 = 448_659;
168    ///<https://wowlab.gg/inspect/spell/453326>
169    pub(crate) const ARCANE_SURGE: u32 = 453_326;
170    ///<https://wowlab.gg/inspect/spell/450421>
171    pub(crate) const GREATER_PYROBLAST: u32 = 450_421;
172    ///<https://wowlab.gg/inspect/spell/12654>
173    pub(crate) const IGNITE: u32 = 12654;
174    ///<https://wowlab.gg/inspect/spell/449560>
175    pub(crate) const METEORITE_BUG_IMPACT: u32 = 449_560;
176    ///<https://wowlab.gg/inspect/spell/456139>
177    pub(crate) const METEORITE_IMPACT: u32 = 456_139;
178    ///<https://wowlab.gg/inspect/spell/450461>
179    pub(crate) const PHOENIX_PYROBLAST: u32 = 450_461;
180    ///<https://wowlab.gg/inspect/spell/460475>
181    pub(crate) const PYROBLAST_PYROMANIAC: u32 = 460_475;
182    ///<https://wowlab.gg/inspect/spell/451466>
183    pub(crate) const PYROMANIAC_CONTROLLER: u32 = 451_466;
184}
185pub(crate) mod HERO {
186    pub(crate) mod FROSTFIRE {
187        pub(crate) mod SPELL {
188            ///<https://wowlab.gg/inspect/spell/1236209>
189            pub(crate) const DUALITY_GLACIAL_SPIKE: u32 = 1_236_209;
190            ///<https://wowlab.gg/inspect/spell/1278079>
191            pub(crate) const FLASH_FREEZEBURN_DAMAGE: u32 = 1_278_079;
192            ///<https://wowlab.gg/inspect/spell/431044>
193            pub(crate) const FROSTFIRE_BOLT: u32 = 431_044;
194            ///<https://wowlab.gg/inspect/spell/431186>
195            pub(crate) const FROSTFIRE_EMPOWERMENT_DAMAGE: u32 = 431_186;
196            ///<https://wowlab.gg/inspect/spell/1262887>
197            pub(crate) const MOLTEN_CHILL_IGNITE: u32 = 1_262_887;
198        }
199        pub(crate) mod AURA {
200            ///<https://wowlab.gg/inspect/spell/431177>
201            pub(crate) const FROSTFIRE_EMPOWERMENT: u32 = 431_177;
202        }
203    }
204    pub(crate) mod SUNFURY {
205        pub(crate) mod SPELL {
206            ///<https://wowlab.gg/inspect/spell/449559>
207            pub(crate) const METEORITE: u32 = 449_559;
208            ///<https://wowlab.gg/inspect/spell/449569>
209            pub(crate) const METEORITE_IMPACT: u32 = 449_569;
210        }
211        pub(crate) mod AURA {
212            ///<https://wowlab.gg/inspect/spell/451073>
213            pub(crate) const GLORIOUS_INCANDESCENCE: u32 = 451_073;
214            ///<https://wowlab.gg/inspect/spell/383874>
215            pub(crate) const HYPERTHERMIA: u32 = 383_874;
216            ///<https://wowlab.gg/inspect/spell/1242220>
217            pub(crate) const HYPERTHERMIA_DAMAGE: u32 = 1_242_220;
218            ///<https://wowlab.gg/inspect/spell/1260277>
219            pub(crate) const LESSER_TIME_WARP: u32 = 1_260_277;
220            ///<https://wowlab.gg/inspect/spell/449314>
221            pub(crate) const MANA_CASCADE: u32 = 449_314;
222            ///<https://wowlab.gg/inspect/spell/448604>
223            pub(crate) const SPELLFIRE_SPHERE: u32 = 448_604;
224        }
225    }
226}
227static HERO_TREE_FROSTFIRE_SPELLS: &[(&str, u32)] = &[
228    ("DUALITY_GLACIAL_SPIKE", 1_236_209),
229    ("FLASH_FREEZEBURN_DAMAGE", 1_278_079),
230    ("FROSTFIRE_BOLT", 431_044),
231    ("FROSTFIRE_EMPOWERMENT_DAMAGE", 431_186),
232    ("MOLTEN_CHILL_IGNITE", 1_262_887),
233];
234static HERO_TREE_FROSTFIRE_AURAS: &[(&str, u32)] = &[("FROSTFIRE_EMPOWERMENT", 431_177)];
235static HERO_TREE_SUNFURY_SPELLS: &[(&str, u32)] = &[
236    ("METEORITE", 449_559),
237    ("METEORITE_IMPACT", 449_569),
238];
239static HERO_TREE_SUNFURY_AURAS: &[(&str, u32)] = &[
240    ("GLORIOUS_INCANDESCENCE", 451_073),
241    ("HYPERTHERMIA", 383_874),
242    ("HYPERTHERMIA_DAMAGE", 1_242_220),
243    ("LESSER_TIME_WARP", 1_260_277),
244    ("MANA_CASCADE", 449_314),
245    ("SPELLFIRE_SPHERE", 448_604),
246];
247pub(crate) const AURA_HEATING_UP: LocalAuraIdx = LocalAuraIdx::new(0);
248pub(crate) const AURA_HOT_STREAK: LocalAuraIdx = LocalAuraIdx::new(1);
249pub(crate) const AURA_COMBUSTION: LocalAuraIdx = LocalAuraIdx::new(2);
250pub(crate) const AURA_IGNITE: LocalAuraIdx = LocalAuraIdx::new(3);
251pub(crate) const AURA_CONTROLLED_DESTRUCTION: LocalAuraIdx = LocalAuraIdx::new(4);
252pub(crate) const AURA_HYPERTHERMIA: LocalAuraIdx = LocalAuraIdx::new(5);
253pub(crate) const AURA_HYPERTHERMIA_DAMAGE: LocalAuraIdx = LocalAuraIdx::new(6);
254pub(crate) const AURA_PYROTECHNICS: LocalAuraIdx = LocalAuraIdx::new(7);
255pub(crate) const AURA_PYROCLASM: LocalAuraIdx = LocalAuraIdx::new(8);
256pub(crate) const AURA_FEEL_THE_BURN: LocalAuraIdx = LocalAuraIdx::new(9);
257pub(crate) const AURA_FEVERED_INCANTATION: LocalAuraIdx = LocalAuraIdx::new(10);
258pub(crate) const AURA_FIRED_UP: LocalAuraIdx = LocalAuraIdx::new(11);
259pub(crate) const AURA_HEAT_SHIMMER: LocalAuraIdx = LocalAuraIdx::new(12);
260pub(crate) const AURA_FROSTFIRE_EMPOWERMENT: LocalAuraIdx = LocalAuraIdx::new(13);
261pub(crate) const AURA_ARCANE_INTELLECT_HIGHLIGHT: LocalAuraIdx = LocalAuraIdx::new(14);
262pub(crate) const AURA_SPELLFIRE_SPHERE: LocalAuraIdx = LocalAuraIdx::new(15);
263pub(crate) const AURA_FIERY_RUSH_EFFECT: LocalAuraIdx = LocalAuraIdx::new(16);
264pub(crate) const AURA_COUNT: usize = 17;
265const _: () = assert!(
266    AURA_COUNT == 17, "AURA index ABI: count changed -- update positional hook consumers"
267);
268pub(crate) const SPELL_FIREBALL: LocalSpellIdx = LocalSpellIdx::new(0);
269pub(crate) const SPELL_PYROBLAST: LocalSpellIdx = LocalSpellIdx::new(1);
270pub(crate) const SPELL_FIRE_BLAST: LocalSpellIdx = LocalSpellIdx::new(2);
271pub(crate) const SPELL_FLAMESTRIKE: LocalSpellIdx = LocalSpellIdx::new(3);
272pub(crate) const SPELL_COMBUSTION: LocalSpellIdx = LocalSpellIdx::new(4);
273pub(crate) const SPELL_METEOR: LocalSpellIdx = LocalSpellIdx::new(5);
274pub(crate) const SPELL_SCORCH: LocalSpellIdx = LocalSpellIdx::new(6);
275pub(crate) const SPELL_FROSTFIRE_BOLT: LocalSpellIdx = LocalSpellIdx::new(7);
276pub(crate) const SPELL_ARCANE_INTELLECT: LocalSpellIdx = LocalSpellIdx::new(8);
277pub(crate) const SPELL_IGNITE: LocalSpellIdx = LocalSpellIdx::new(9);
278pub(crate) const SPELL_INTENSIFYING_FLAME: LocalSpellIdx = LocalSpellIdx::new(10);
279pub(crate) const SPELL_BURNOUT: LocalSpellIdx = LocalSpellIdx::new(11);
280pub(crate) const SPELL_COUNT: usize = 12;
281const _: () = assert!(
282    SPELL_COUNT == 12,
283    "SPELL index ABI: count changed -- update positional hook consumers"
284);
285pub(crate) mod EFFECT {
286    ///<https://wowlab.gg/inspect/spell/205026>
287    pub(crate) const FIRESTARTER_THRESHOLD: (u32, u8) = (205_026, 1);
288    ///<https://wowlab.gg/inspect/spell/12846>
289    pub(crate) const IGNITE_MASTERY: (u32, u8) = (12846, 1);
290    ///<https://wowlab.gg/inspect/spell/155158>
291    pub(crate) const METEOR_BURN_DAMAGE: (u32, u8) = (155_158, 1);
292    ///<https://wowlab.gg/inspect/spell/175396>
293    pub(crate) const METEOR_BURN_DURATION: (u32, u8) = (175_396, 1);
294    ///<https://wowlab.gg/inspect/spell/177345>
295    pub(crate) const METEOR_DELAY: (u32, u8) = (177_345, 1);
296    ///<https://wowlab.gg/inspect/spell/351140>
297    pub(crate) const METEOR_IMPACT_DAMAGE: (u32, u8) = (351_140, 1);
298    ///<https://wowlab.gg/inspect/spell/449569>
299    pub(crate) const METEORITE_IMPACT_DAMAGE: (u32, u8) = (449_569, 1);
300    ///<https://wowlab.gg/inspect/spell/450499>
301    pub(crate) const PHOENIX_ARCANE_BARRAGE_DAMAGE: (u32, u8) = (450_499, 1);
302    ///<https://wowlab.gg/inspect/spell/453326>
303    pub(crate) const PHOENIX_ARCANE_SURGE_DAMAGE: (u32, u8) = (453_326, 1);
304    ///<https://wowlab.gg/inspect/spell/450421>
305    pub(crate) const PHOENIX_GREATER_PYROBLAST_DAMAGE: (u32, u8) = (450_421, 1);
306    ///<https://wowlab.gg/inspect/spell/456139>
307    pub(crate) const PHOENIX_METEORITE_DAMAGE: (u32, u8) = (456_139, 1);
308    ///<https://wowlab.gg/inspect/spell/450461>
309    pub(crate) const PHOENIX_PYROBLAST_DAMAGE: (u32, u8) = (450_461, 1);
310    ///<https://wowlab.gg/inspect/spell/460475>
311    pub(crate) const PYROBLAST_PYROMANIAC_DAMAGE: (u32, u8) = (460_475, 1);
312    ///<https://wowlab.gg/inspect/spell/1271177>
313    pub(crate) const BURNOUT_PCT: (u32, u8) = (1_271_177, 1);
314    ///<https://wowlab.gg/inspect/spell/416714>
315    pub(crate) const INTENSIFYING_FLAME_PCT: (u32, u8) = (416_714, 2);
316    ///<https://wowlab.gg/inspect/spell/1257343>
317    pub(crate) const FIRED_UP_CHANCE: (u32, u8) = (1_257_343, 1);
318    ///<https://wowlab.gg/inspect/spell/1257348>
319    pub(crate) const FIRED_UP_COMBUSTION_EXTEND_MS: (u32, u8) = (1_257_348, 2);
320    ///<https://wowlab.gg/inspect/spell/1257349>
321    pub(crate) const FIRED_UP_FIRE_BLAST_CDR_MS: (u32, u8) = (1_257_349, 1);
322    ///<https://wowlab.gg/inspect/spell/1264835>
323    pub(crate) const SET4PC_FIRE_BLAST_CDR_MS: (u32, u8) = (1_264_835, 1);
324    ///<https://wowlab.gg/inspect/spell/1254512>
325    pub(crate) const BURN_IT_ALL_BASE_PCT: (u32, u8) = (1_254_512, 2);
326    ///<https://wowlab.gg/inspect/spell/1254512>
327    pub(crate) const BURN_IT_ALL_CRIT_PCT: (u32, u8) = (1_254_512, 1);
328    ///<https://wowlab.gg/inspect/spell/449382>
329    pub(crate) const CODEX_COMBUSTION_PCT: (u32, u8) = (449_382, 2);
330    ///<https://wowlab.gg/inspect/spell/383669>
331    pub(crate) const CONTROLLED_DESTRUCTION_PCT_X100: (u32, u8) = (383_669, 2);
332    ///<https://wowlab.gg/inspect/spell/449412>
333    pub(crate) const SAVOR_CAP_MS: (u32, u8) = (449_412, 2);
334    ///<https://wowlab.gg/inspect/spell/449412>
335    pub(crate) const SAVOR_PER_SPHERE_MS: (u32, u8) = (449_412, 1);
336}
337static REPORTED_SPELLS: &[(&str, u32)] = &[
338    ("arcane_barrage", 450_499),
339    ("arcane_phoenix_controller", 448_659),
340    ("arcane_surge", 453_326),
341    ("greater_pyroblast", 450_421),
342    ("ignite", 12654),
343    ("meteorite_bug_impact", 449_560),
344    ("meteorite_impact", 456_139),
345    ("phoenix_pyroblast", 450_461),
346    ("pyroblast_pyromaniac", 460_475),
347    ("pyromaniac_controller", 451_466),
348];
349static DECLARED_SPELL_IDS: &[u32] = &[
350    133, 11366, 108_853, 2120, 190_319, 153_561, 2948, 431_044, 1459, 12654, 419_800,
351    1_271_335, 48107, 48108, 190_319, 12654, 453_268, 383_874, 1_242_220, 157_644,
352    269_651, 383_395, 383_811, 1_257_350, 458_964, 431_177, 1459, 448_604, 383_637,
353    12654, 12846, 155_158, 175_396, 177_345, 205_026, 351_140, 383_637, 383_669, 383_874,
354    416_714, 448_659, 449_382, 449_412, 449_560, 449_569, 450_421, 450_461, 450_499,
355    451_466, 453_326, 456_139, 460_475, 1_254_512, 1_257_343, 1_257_348, 1_257_349,
356    1_257_350, 1_264_835, 1_271_177, 450_499, 448_659, 453_326, 450_421, 12654, 449_560,
357    456_139, 450_461, 460_475, 451_466, 1_236_209, 1_278_079, 431_044, 431_186,
358    1_262_887, 431_177, 449_559, 449_569, 451_073, 383_874, 1_242_220, 1_260_277,
359    449_314, 448_604,
360];
361static DECLARED_AURA_IDS: &[u32] = &[
362    48107, 48108, 190_319, 12654, 453_268, 383_874, 1_242_220, 157_644, 269_651, 383_395,
363    383_811, 1_257_350, 458_964, 431_177, 1459, 448_604, 383_637, 431_177, 451_073,
364    383_874, 1_242_220, 1_260_277, 449_314, 448_604,
365];
366static TALENTS: &[(&str, u32)] = &[
367    ("BURNOUT", TALENT::BURNOUT),
368    ("BURN_IT_ALL", TALENT::BURN_IT_ALL),
369    ("CINDERSTORM", TALENT::CINDERSTORM),
370    ("CODEX_OF_THE_SUNSTRIDERS", TALENT::CODEX_OF_THE_SUNSTRIDERS),
371    ("COMBUSTION", TALENT::COMBUSTION),
372    ("CONFLAGRATION", TALENT::CONFLAGRATION),
373    ("CONTROLLED_DESTRUCTION", TALENT::CONTROLLED_DESTRUCTION),
374    ("CRITICAL_MASS", TALENT::CRITICAL_MASS),
375    ("DEEP_IMPACT", TALENT::DEEP_IMPACT),
376    ("FEEL_THE_BURN", TALENT::FEEL_THE_BURN),
377    ("FEVERED_INCANTATION", TALENT::FEVERED_INCANTATION),
378    ("FIERY_RUSH", TALENT::FIERY_RUSH),
379    ("FIRED_UP_1", TALENT::FIRED_UP_1),
380    ("FIRED_UP_2", TALENT::FIRED_UP_2),
381    ("FIRED_UP_3", TALENT::FIRED_UP_3),
382    ("FIRESTARTER", TALENT::FIRESTARTER),
383    ("FIRES_IRE", TALENT::FIRES_IRE),
384    ("FIRE_BLAST", TALENT::FIRE_BLAST),
385    ("FLAMESTRIKE", TALENT::FLAMESTRIKE),
386    ("FLAME_ON", TALENT::FLAME_ON),
387    ("FROM_THE_ASHES", TALENT::FROM_THE_ASHES),
388    ("FUEL_THE_FIRE", TALENT::FUEL_THE_FIRE),
389    ("HEAT_SHIMMER", TALENT::HEAT_SHIMMER),
390    ("IGNITION", TALENT::IGNITION),
391    ("INFLAME", TALENT::INFLAME),
392    ("INTENSIFYING_FLAME", TALENT::INTENSIFYING_FLAME),
393    ("INVOCATION_ARCANE_PHOENIX", TALENT::INVOCATION_ARCANE_PHOENIX),
394    ("KINDLING", TALENT::KINDLING),
395    ("MASTER_OF_FLAME", TALENT::MASTER_OF_FLAME),
396    ("MEMORY_OF_ALAR", TALENT::MEMORY_OF_ALAR),
397    ("METEOR", TALENT::METEOR),
398    ("MOLTEN_FURY", TALENT::MOLTEN_FURY),
399    ("PYROBLAST", TALENT::PYROBLAST),
400    ("PYROCLASM", TALENT::PYROCLASM),
401    ("PYROMANIAC", TALENT::PYROMANIAC),
402    ("SAVOR_THE_MOMENT", TALENT::SAVOR_THE_MOMENT),
403    ("SCALD", TALENT::SCALD),
404    ("SCORCH", TALENT::SCORCH),
405    ("SLOW_BURN", TALENT::SLOW_BURN),
406    ("SPONTANEOUS_COMBUSTION", TALENT::SPONTANEOUS_COMBUSTION),
407    ("WILDFIRE", TALENT::WILDFIRE),
408];
409pub(crate) mod FIRE_MAGE {
410    pub(crate) const FIREBALL_CASTS: u32 = 0;
411    pub(crate) const PYROBLAST_CASTS: u32 = 1;
412    pub(crate) const FIRE_BLAST_CASTS: u32 = 2;
413    pub(crate) const COMBUSTION_CASTS: u32 = 3;
414    pub(crate) const METEOR_CASTS: u32 = 4;
415    pub(crate) const FLAMESTRIKE_CASTS: u32 = 5;
416    pub(crate) const COMBUSTION_UPTIME_MS: u32 = 6;
417    pub(crate) const IGNITE_UPTIME_MS: u32 = 7;
418}
419fn aura_heating_up(
420    a: AuraDefinitionDraft,
421    data: &ResolvedGameData,
422) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
423    Ok(
424        a
425            .on_player()
426            .apply_base_from_data(data, 48107)?
427            .max_stacks(
428                data
429                    .require_aura_max_stacks(
430                        wowlab_types::sim::SpellIdx::from_raw(48107),
431                    )?,
432            ),
433    )
434}
435fn aura_hot_streak(
436    a: AuraDefinitionDraft,
437    data: &ResolvedGameData,
438) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
439    Ok(
440        a
441            .on_player()
442            .apply_base_from_data(data, 48108)?
443            .max_stacks(
444                data
445                    .require_aura_max_stacks(
446                        wowlab_types::sim::SpellIdx::from_raw(48108),
447                    )?,
448            ),
449    )
450}
451fn aura_combustion(
452    a: AuraDefinitionDraft,
453    data: &ResolvedGameData,
454) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
455    Ok(
456        a
457            .on_player()
458            .apply_base_from_data(data, 190_319)?
459            .max_stacks(
460                data
461                    .require_aura_max_stacks(
462                        wowlab_types::sim::SpellIdx::from_raw(190_319),
463                    )?,
464            )
465            .on_expire(crate::hooks::fire_mage::combustion_expire_hook),
466    )
467}
468fn aura_ignite(
469    a: AuraDefinitionDraft,
470    data: &ResolvedGameData,
471) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
472    a.on_target()
473        .apply_base_from_data(data, 12654)?
474        .max_stacks(
475            data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(12654))?,
476        )
477        .periodic_residual_damage(
478            wowlab_engine_combat::validated_milliseconds(
479                data.period(wowlab_types::sim::SpellIdx::from_raw(12654), 1),
480                12654,
481                "periodic_residual_damage.tick_ms",
482            )?,
483        )
484        .apply_periodic_behavior_from_data(data, 12654)
485}
486fn aura_controlled_destruction(
487    a: AuraDefinitionDraft,
488    data: &ResolvedGameData,
489) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
490    Ok(
491        a
492            .on_target()
493            .apply_base_from_data(data, 453_268)?
494            .max_stacks(
495                data
496                    .require_aura_max_stacks(
497                        wowlab_types::sim::SpellIdx::from_raw(453_268),
498                    )?,
499            ),
500    )
501}
502fn aura_hyperthermia(
503    a: AuraDefinitionDraft,
504    data: &ResolvedGameData,
505) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
506    Ok(
507        a
508            .on_player()
509            .duration_ms(
510                wowlab_engine_combat::validated_milliseconds(
511                    (f64::from(
512                        data
513                            .require_aura_duration_ms(
514                                wowlab_types::sim::SpellIdx::from_raw(383_874),
515                            )?,
516                    )) * 0.8,
517                    383_874,
518                    "aura.duration_ms",
519                )?,
520            )
521            .apply_periodic_effect_from_data(data, 383_874)?
522            .apply_duration_behavior_from_data(data, 383_874)?
523            .apply_timing_modifiers_from_data(data, 383_874)?
524            .max_stacks(
525                data
526                    .require_aura_max_stacks(
527                        wowlab_types::sim::SpellIdx::from_raw(383_874),
528                    )?,
529            )
530            .crit_chance_spells(100.0, &[11366, 2120])?
531            .apply_periodic_behavior_from_data(data, 383_874)?
532            .on_expire(crate::hooks::fire_mage::hyperthermia_expire_hook),
533    )
534}
535fn aura_hyperthermia_damage(
536    a: AuraDefinitionDraft,
537    data: &ResolvedGameData,
538) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
539    Ok(
540        a
541            .on_player()
542            .apply_base_from_data(data, 1_242_220)?
543            .max_stacks(
544                data
545                    .require_aura_max_stacks(
546                        wowlab_types::sim::SpellIdx::from_raw(1_242_220),
547                    )?,
548            ),
549    )
550}
551fn aura_pyrotechnics(
552    a: AuraDefinitionDraft,
553    data: &ResolvedGameData,
554) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
555    a.on_player()
556        .apply_base_from_data(data, 157_644)?
557        .max_stacks(
558            data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(157_644))?,
559        )
560        .crit_chance_spells(20.0, &[133])
561}
562fn aura_pyroclasm(
563    a: AuraDefinitionDraft,
564    data: &ResolvedGameData,
565) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
566    Ok(
567        a
568            .on_player()
569            .apply_base_from_data(data, 269_651)?
570            .max_stacks(
571                data
572                    .require_aura_max_stacks(
573                        wowlab_types::sim::SpellIdx::from_raw(269_651),
574                    )?,
575            ),
576    )
577}
578fn aura_feel_the_burn(
579    a: AuraDefinitionDraft,
580    data: &ResolvedGameData,
581) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
582    Ok(
583        a
584            .on_player()
585            .apply_base_from_data(data, 383_395)?
586            .max_stacks(
587                data
588                    .require_aura_max_stacks(
589                        wowlab_types::sim::SpellIdx::from_raw(383_395),
590                    )?,
591            ),
592    )
593}
594fn aura_fevered_incantation(
595    a: AuraDefinitionDraft,
596    data: &ResolvedGameData,
597) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
598    a.on_player()
599        .apply_base_from_data(data, 383_811)?
600        .max_stacks(
601            data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(383_811))?,
602        )
603        .crit_damage_spells(2.0, &[133, 11366, 108_853, 2120, 153_561, 2948, 431_044])
604}
605fn aura_fired_up(
606    a: AuraDefinitionDraft,
607    data: &ResolvedGameData,
608) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
609    Ok(
610        a
611            .on_player()
612            .apply_base_from_data(data, 1_257_350)?
613            .max_stacks(
614                data
615                    .require_aura_max_stacks(
616                        wowlab_types::sim::SpellIdx::from_raw(1_257_350),
617                    )?,
618            )
619            .damage_multiplier_stacking(
620                (data.base_points(wowlab_types::sim::SpellIdx::from_raw(1_257_350), 1))
621                    * 0.01,
622                (data.base_points(wowlab_types::sim::SpellIdx::from_raw(1_257_350), 1))
623                    * 0.01,
624            )?
625            .async_stacks(),
626    )
627}
628fn aura_heat_shimmer(
629    a: AuraDefinitionDraft,
630    data: &ResolvedGameData,
631) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
632    Ok(
633        a
634            .on_player()
635            .apply_base_from_data(data, 458_964)?
636            .max_stacks(
637                data
638                    .require_aura_max_stacks(
639                        wowlab_types::sim::SpellIdx::from_raw(458_964),
640                    )?,
641            ),
642    )
643}
644fn aura_frostfire_empowerment(
645    a: AuraDefinitionDraft,
646    data: &ResolvedGameData,
647) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
648    Ok(
649        a
650            .on_player()
651            .apply_base_from_data(data, 431_177)?
652            .max_stacks(
653                data
654                    .require_aura_max_stacks(
655                        wowlab_types::sim::SpellIdx::from_raw(431_177),
656                    )?,
657            ),
658    )
659}
660fn aura_arcane_intellect_highlight(
661    a: AuraDefinitionDraft,
662    data: &ResolvedGameData,
663) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
664    Ok(
665        a
666            .on_player()
667            .apply_base_from_data(data, 1459)?
668            .max_stacks(
669                data
670                    .require_aura_max_stacks(
671                        wowlab_types::sim::SpellIdx::from_raw(1459),
672                    )?,
673            ),
674    )
675}
676fn aura_spellfire_sphere(
677    a: AuraDefinitionDraft,
678    data: &ResolvedGameData,
679) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
680    Ok(
681        a
682            .on_player()
683            .duration_ms(
684                wowlab_engine_combat::validated_milliseconds(
685                    0.0,
686                    448_604,
687                    "aura.duration_ms",
688                )?,
689            )
690            .apply_periodic_effect_from_data(data, 448_604)?
691            .max_stacks(
692                data
693                    .require_aura_max_stacks(
694                        wowlab_types::sim::SpellIdx::from_raw(448_604),
695                    )?,
696            )
697            .apply_at_max_stacks(),
698    )
699}
700fn aura_fiery_rush_effect(
701    a: AuraDefinitionDraft,
702    data: &ResolvedGameData,
703) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
704    Ok(
705        a
706            .on_player()
707            .apply_base_from_data(data, 383_637)?
708            .max_stacks(
709                data
710                    .require_aura_max_stacks(
711                        wowlab_types::sim::SpellIdx::from_raw(383_637),
712                    )?,
713            ),
714    )
715}
716fn spell_fireball(
717    s: SpellDefinitionDraft,
718    data: &ResolvedGameData,
719) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
720    Ok(
721        s
722            .apply_base_from_data(data, 133)?
723            .travel_time(
724                wowlab_engine_combat::validated_milliseconds(
725                    200.0,
726                    133,
727                    "spell.travel_time_ms",
728                )?,
729            )
730            .apply_aoe_from_data(data)
731            .on_cast(crate::hooks::fire_mage::fireball_hook),
732    )
733}
734fn spell_pyroblast(
735    s: SpellDefinitionDraft,
736    data: &ResolvedGameData,
737) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
738    Ok(
739        s
740            .apply_base_from_data(data, 11366)?
741            .cast_time(
742                wowlab_engine_combat::validated_milliseconds(
743                    0.0,
744                    11366,
745                    "spell.cast_time_ms",
746                )?,
747            )
748            .apply_aoe_from_data(data)
749            .on_cast(crate::hooks::fire_mage::pyroblast_hook),
750    )
751}
752fn spell_fire_blast(
753    s: SpellDefinitionDraft,
754    data: &ResolvedGameData,
755) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
756    Ok(
757        s
758            .apply_base_from_data(data, 108_853)?
759            .usable_while_casting()
760            .guaranteed_crit()
761            .apply_aoe_from_data(data)
762            .on_cast(crate::hooks::fire_mage::fire_blast_hook),
763    )
764}
765fn spell_flamestrike(
766    s: SpellDefinitionDraft,
767    data: &ResolvedGameData,
768) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
769    Ok(s.apply_base_from_data(data, 2120)?.apply_aoe_from_data(data))
770}
771fn spell_combustion(
772    s: SpellDefinitionDraft,
773    data: &ResolvedGameData,
774) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
775    Ok(
776        s
777            .apply_base_from_data(data, 190_319)?
778            .applies_inferred_aura(AURA_COMBUSTION, 190_319)
779            .apply_aoe_from_data(data)
780            .on_cast(crate::hooks::fire_mage::combustion_hook),
781    )
782}
783fn spell_meteor(
784    s: SpellDefinitionDraft,
785    data: &ResolvedGameData,
786) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
787    Ok(
788        s
789            .apply_base_from_data(data, 153_561)?
790            .apply_aoe_from_data(data)
791            .on_cast(crate::hooks::fire_mage::meteor_hook),
792    )
793}
794fn spell_scorch(
795    s: SpellDefinitionDraft,
796    data: &ResolvedGameData,
797) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
798    Ok(s.apply_base_from_data(data, 2948)?.apply_aoe_from_data(data))
799}
800fn spell_frostfire_bolt(
801    s: SpellDefinitionDraft,
802    data: &ResolvedGameData,
803) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
804    Ok(s.apply_base_from_data(data, 431_044)?.apply_aoe_from_data(data))
805}
806fn spell_arcane_intellect(
807    s: SpellDefinitionDraft,
808    data: &ResolvedGameData,
809) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
810    Ok(
811        s
812            .apply_base_from_data(data, 1459)?
813            .applies_inferred_aura(AURA_ARCANE_INTELLECT_HIGHLIGHT, 1459)
814            .apply_aoe_from_data(data),
815    )
816}
817fn spell_ignite(
818    s: SpellDefinitionDraft,
819    data: &ResolvedGameData,
820) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
821    Ok(
822        s
823            .apply_base_from_data(data, 12654)?
824            .applies_inferred_aura(AURA_IGNITE, 12654)
825            .apply_aoe_from_data(data),
826    )
827}
828fn spell_intensifying_flame(
829    s: SpellDefinitionDraft,
830    data: &ResolvedGameData,
831) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
832    Ok(s.apply_base_from_data(data, 419_800)?.apply_aoe_from_data(data))
833}
834fn spell_burnout(
835    s: SpellDefinitionDraft,
836    data: &ResolvedGameData,
837) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
838    Ok(s.apply_base_from_data(data, 1_271_335)?.apply_aoe_from_data(data))
839}
840pub(crate) fn build_combat_system(
841    params: &wowlab_engine_ports::HandlerParams<'_>,
842) -> Result<BuiltCombatSystem, wowlab_engine_ports::EngineError> {
843    let builder = BuiltCombatSystem::builder(params.stats.clone())
844        .spec_id(SpecId::Fire)
845        .hero_talent_trees(DECLARED_METADATA.hero_talent_trees)
846        .mastery_spell(12846)
847        .mastery_hook(crate::hooks::fire_mage::mastery)
848        .resource(
849            "mana",
850            100_000.0,
851            params
852                .game_data
853                .power_regen_for_max(0, 100_000.0)
854                .ok_or_else(|| {
855                    wowlab_engine_ports::EngineError::spec_construction(
856                        "missing power-type power_regen_for_max for type_id 0",
857                    )
858                })?,
859        )
860        .resource_type_id(0)
861        .resource_start(100_000.0)
862        .precombat_aura(AURA_SPELLFIRE_SPHERE)
863        .aura("heating_up", AURA::HEATING_UP, |a| aura_heating_up(a, &params.game_data))
864        .aura("hot_streak", AURA::HOT_STREAK, |a| aura_hot_streak(a, &params.game_data))
865        .aura("combustion", AURA::COMBUSTION, |a| aura_combustion(a, &params.game_data))
866        .aura("ignite", AURA::IGNITE, |a| aura_ignite(a, &params.game_data))
867        .aura(
868            "controlled_destruction",
869            AURA::CONTROLLED_DESTRUCTION,
870            |a| aura_controlled_destruction(a, &params.game_data),
871        )
872        .aura(
873            "hyperthermia",
874            AURA::HYPERTHERMIA,
875            |a| aura_hyperthermia(a, &params.game_data),
876        )
877        .aura(
878            "hyperthermia_damage",
879            AURA::HYPERTHERMIA_DAMAGE,
880            |a| aura_hyperthermia_damage(a, &params.game_data),
881        )
882        .aura(
883            "pyrotechnics",
884            AURA::PYROTECHNICS,
885            |a| aura_pyrotechnics(a, &params.game_data),
886        )
887        .aura("pyroclasm", AURA::PYROCLASM, |a| aura_pyroclasm(a, &params.game_data))
888        .aura(
889            "feel_the_burn",
890            AURA::FEEL_THE_BURN,
891            |a| aura_feel_the_burn(a, &params.game_data),
892        )
893        .aura(
894            "fevered_incantation",
895            AURA::FEVERED_INCANTATION,
896            |a| aura_fevered_incantation(a, &params.game_data),
897        )
898        .aura("fired_up", AURA::FIRED_UP, |a| aura_fired_up(a, &params.game_data))
899        .aura(
900            "heat_shimmer",
901            AURA::HEAT_SHIMMER,
902            |a| aura_heat_shimmer(a, &params.game_data),
903        )
904        .aura(
905            "frostfire_empowerment",
906            AURA::FROSTFIRE_EMPOWERMENT,
907            |a| aura_frostfire_empowerment(a, &params.game_data),
908        )
909        .aura(
910            "arcane_intellect_highlight",
911            AURA::ARCANE_INTELLECT_HIGHLIGHT,
912            |a| aura_arcane_intellect_highlight(a, &params.game_data),
913        )
914        .aura(
915            "spellfire_sphere",
916            AURA::SPELLFIRE_SPHERE,
917            |a| aura_spellfire_sphere(a, &params.game_data),
918        )
919        .aura(
920            "fiery_rush_effect",
921            AURA::FIERY_RUSH_EFFECT,
922            |a| aura_fiery_rush_effect(a, &params.game_data),
923        )
924        .spell("fireball", SPELL::FIREBALL, |s| spell_fireball(s, &params.game_data))
925        .spell("pyroblast", SPELL::PYROBLAST, |s| spell_pyroblast(s, &params.game_data))
926        .spell(
927            "fire_blast",
928            SPELL::FIRE_BLAST,
929            |s| spell_fire_blast(s, &params.game_data),
930        )
931        .spell(
932            "flamestrike",
933            SPELL::FLAMESTRIKE,
934            |s| spell_flamestrike(s, &params.game_data),
935        )
936        .spell(
937            "combustion",
938            SPELL::COMBUSTION,
939            |s| spell_combustion(s, &params.game_data),
940        )
941        .spell("meteor", SPELL::METEOR, |s| spell_meteor(s, &params.game_data))
942        .spell("scorch", SPELL::SCORCH, |s| spell_scorch(s, &params.game_data))
943        .spell(
944            "frostfire_bolt",
945            SPELL::FROSTFIRE_BOLT,
946            |s| spell_frostfire_bolt(s, &params.game_data),
947        )
948        .spell(
949            "arcane_intellect",
950            SPELL::ARCANE_INTELLECT,
951            |s| spell_arcane_intellect(s, &params.game_data),
952        )
953        .spell("ignite", SPELL::IGNITE, |s| spell_ignite(s, &params.game_data))
954        .spell(
955            "intensifying_flame",
956            SPELL::INTENSIFYING_FLAME,
957            |s| spell_intensifying_flame(s, &params.game_data),
958        )
959        .spell("burnout", SPELL::BURNOUT, |s| spell_burnout(s, &params.game_data))
960        .game_data(params.game_data.clone())
961        .talent_spell_ids(TALENTS)
962        .talent_selections(params.talent_selections)
963        .talent_gated_aura_effect(TALENT::FIERY_RUSH, AURA_COMBUSTION, 383_637, 1)
964        .set_bonus_auras(params.set_bonus_auras)
965        .encounter(params.encounter.clone());
966    let builder = crate::generated::items::register_equipped(
967        builder,
968        &params.game_data,
969        params.equipped_items,
970    )?;
971
972    builder
973        .build(params.rotation)
974        .map_err(wowlab_engine_ports::EngineError::rotation_compile)
975}
976fn new_handler(
977    params: wowlab_engine_ports::HandlerParams<'_>,
978) -> Result<Box<dyn SpecHandler>, wowlab_engine_ports::EngineError> {
979    let handler = crate::composition::compose_handler(
980        build_combat_system,
981        &params,
982        |parts, params| Ok(crate::hooks::fire_mage::FireHandler::new(parts, params)),
983    )?;
984
985    Ok(Box::new(handler))
986}
987static DECLARED_METADATA: DeclaredSpecMetadata = DeclaredSpecMetadata {
988    primary_resource: ResourceType::Mana,
989    secondary_resource: None,
990    spell_ids: DECLARED_SPELL_IDS,
991    aura_ids: DECLARED_AURA_IDS,
992    server_proc_entries: &[],
993    talents: TALENTS,
994    rotation_field_schema: &[],
995    metrics_plugin_id: None,
996    hero_talent_trees: &[
997        HeroTalentTreeDesc {
998            name: "Frostfire",
999            spells: HERO_TREE_FROSTFIRE_SPELLS,
1000            auras: HERO_TREE_FROSTFIRE_AURAS,
1001        },
1002        HeroTalentTreeDesc {
1003            name: "Sunfury",
1004            spells: HERO_TREE_SUNFURY_SPELLS,
1005            auras: HERO_TREE_SUNFURY_AURAS,
1006        },
1007    ],
1008    reported_spells: REPORTED_SPELLS,
1009    masked_passive_effects: &[],
1010    passive_effect_overrides: &[],
1011};
1012pub(super) const SPEC_DESCRIPTOR: SpecDescriptor = SpecDescriptor {
1013    spec_id: SpecId::Fire,
1014    display_name: "Fire Mage",
1015    metadata: DECLARED_METADATA,
1016    handler_factory: new_handler,
1017};
1018wowlab_engine_combat::smoke_test!(build_combat_system);