Skip to main content

wowlab_engine_content/generated/specs/
arcane_mage.rs

1//! @generated by codegen-cli from manifests/specs/mage/arcane/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/30451>
15    pub(crate) const ARCANE_BLAST: u32 = 30451;
16    ///<https://wowlab.gg/inspect/spell/44425>
17    pub(crate) const ARCANE_BARRAGE: u32 = 44425;
18    ///<https://wowlab.gg/inspect/spell/5143>
19    pub(crate) const ARCANE_MISSILES: u32 = 5143;
20    ///<https://wowlab.gg/inspect/spell/7268>
21    pub(crate) const ARCANE_MISSILES_DAMAGE: u32 = 7268;
22    ///<https://wowlab.gg/inspect/spell/365350>
23    pub(crate) const ARCANE_SURGE: u32 = 365_350;
24    ///<https://wowlab.gg/inspect/spell/153626>
25    pub(crate) const ARCANE_ORB: u32 = 153_626;
26    ///<https://wowlab.gg/inspect/spell/153640>
27    pub(crate) const ARCANE_ORB_BOLT: u32 = 153_640;
28    ///<https://wowlab.gg/inspect/spell/443763>
29    pub(crate) const ARCANE_SPLINTER: u32 = 443_763;
30    ///<https://wowlab.gg/inspect/spell/321507>
31    pub(crate) const TOUCH_OF_THE_MAGI: u32 = 321_507;
32    ///<https://wowlab.gg/inspect/spell/210833>
33    pub(crate) const TOUCH_OF_THE_MAGI_EXPLOSION: u32 = 210_833;
34    ///<https://wowlab.gg/inspect/spell/1258134>
35    pub(crate) const TOUCH_OF_THE_ARCHMAGE: u32 = 1_258_134;
36    ///<https://wowlab.gg/inspect/spell/12051>
37    pub(crate) const EVOCATION: u32 = 12051;
38    ///<https://wowlab.gg/inspect/spell/205025>
39    pub(crate) const PRESENCE_OF_MIND: u32 = 205_025;
40    ///<https://wowlab.gg/inspect/spell/1449>
41    pub(crate) const ARCANE_EXPLOSION: u32 = 1449;
42    ///<https://wowlab.gg/inspect/spell/1459>
43    pub(crate) const ARCANE_INTELLECT: u32 = 1459;
44    ///<https://wowlab.gg/inspect/spell/225119>
45    pub(crate) const ARCANE_ASSAULT: u32 = 225_119;
46}
47pub(crate) mod AURA {
48    ///<https://wowlab.gg/inspect/spell/36032>
49    pub(crate) const ARCANE_CHARGE: u32 = 36032;
50    ///<https://wowlab.gg/inspect/spell/365362>
51    pub(crate) const ARCANE_SURGE: u32 = 365_362;
52    ///<https://wowlab.gg/inspect/spell/263725>
53    pub(crate) const CLEARCASTING: u32 = 263_725;
54    ///<https://wowlab.gg/inspect/spell/1217242>
55    pub(crate) const ENLIGHTENED: u32 = 1_217_242;
56    ///<https://wowlab.gg/inspect/spell/1242974>
57    pub(crate) const ARCANE_SALVO: u32 = 1_242_974;
58    ///<https://wowlab.gg/inspect/spell/1223797>
59    pub(crate) const INTUITION: u32 = 1_223_797;
60    ///<https://wowlab.gg/inspect/spell/205025>
61    pub(crate) const PRESENCE_OF_MIND: u32 = 205_025;
62    ///<https://wowlab.gg/inspect/spell/12051>
63    pub(crate) const EVOCATION: u32 = 12051;
64    ///<https://wowlab.gg/inspect/spell/210824>
65    pub(crate) const TOUCH_OF_THE_MAGI: u32 = 210_824;
66    ///<https://wowlab.gg/inspect/spell/383783>
67    pub(crate) const NETHER_PRECISION: u32 = 383_783;
68    ///<https://wowlab.gg/inspect/spell/1277009>
69    pub(crate) const OVERPOWERED_MISSILES: u32 = 1_277_009;
70    ///<https://wowlab.gg/inspect/spell/1459>
71    pub(crate) const ARCANE_INTELLECT_HIGHLIGHT: u32 = 1459;
72    ///<https://wowlab.gg/inspect/spell/461524>
73    pub(crate) const HIGH_VOLTAGE: u32 = 461_524;
74    ///<https://wowlab.gg/inspect/spell/236628>
75    pub(crate) const AMPLIFICATION: u32 = 236_628;
76    ///<https://wowlab.gg/inspect/spell/449322>
77    pub(crate) const SPELLFIRE_SALVO: u32 = 449_322;
78}
79pub(crate) mod TALENT {
80    ///<https://wowlab.gg/inspect/spell/1243507>
81    pub(crate) const AEGWYNNS_TECHNIQUE: u32 = 1_243_507;
82    ///<https://wowlab.gg/inspect/spell/236628>
83    pub(crate) const AMPLIFICATION: u32 = 236_628;
84    ///<https://wowlab.gg/inspect/spell/342231>
85    pub(crate) const ARCANE_ECHO: u32 = 342_231;
86    ///<https://wowlab.gg/inspect/spell/205022>
87    pub(crate) const ARCANE_FAMILIAR: u32 = 205_022;
88    ///<https://wowlab.gg/inspect/spell/5143>
89    pub(crate) const ARCANE_MISSILES: u32 = 5143;
90    ///<https://wowlab.gg/inspect/spell/153626>
91    pub(crate) const ARCANE_ORB: u32 = 153_626;
92    ///<https://wowlab.gg/inspect/spell/381006>
93    pub(crate) const ARCANE_PULSE: u32 = 381_006;
94    ///<https://wowlab.gg/inspect/spell/1242974>
95    pub(crate) const ARCANE_SALVO: u32 = 1_242_974;
96    ///<https://wowlab.gg/inspect/spell/384452>
97    pub(crate) const ARCANE_SALVO_DRIVER: u32 = 384_452;
98    ///<https://wowlab.gg/inspect/spell/365350>
99    pub(crate) const ARCANE_SURGE: u32 = 365_350;
100    ///<https://wowlab.gg/inspect/spell/231564>
101    pub(crate) const ARCING_CLEAVE: u32 = 231_564;
102    ///<https://wowlab.gg/inspect/spell/1261106>
103    pub(crate) const ATTUNED_FAMILIAR: u32 = 1_261_106;
104    ///<https://wowlab.gg/inspect/spell/1280165>
105    pub(crate) const AUGURY_ABOUNDS: u32 = 1_280_165;
106    ///<https://wowlab.gg/inspect/spell/461251>
107    pub(crate) const CHARGED_MISSILES: u32 = 461_251;
108    ///<https://wowlab.gg/inspect/spell/384651>
109    pub(crate) const CHARGED_ORB: u32 = 384_651;
110    ///<https://wowlab.gg/inspect/spell/452997>
111    pub(crate) const ENERGIZED_FAMILIAR: u32 = 452_997;
112    ///<https://wowlab.gg/inspect/spell/321387>
113    pub(crate) const ENLIGHTENED: u32 = 321_387;
114    ///<https://wowlab.gg/inspect/spell/452198>
115    pub(crate) const EUREKA: u32 = 452_198;
116    ///<https://wowlab.gg/inspect/spell/12051>
117    pub(crate) const EVOCATION: u32 = 12051;
118    ///<https://wowlab.gg/inspect/spell/451548>
119    pub(crate) const EXPANDED_MIND: u32 = 451_548;
120    ///<https://wowlab.gg/inspect/spell/1243557>
121    pub(crate) const EXPANDED_MIND_DRIVER: u32 = 1_243_557;
122    ///<https://wowlab.gg/inspect/spell/452143>
123    pub(crate) const FOCUSING_CRYSTAL: u32 = 452_143;
124    ///<https://wowlab.gg/inspect/spell/444719>
125    pub(crate) const FORCE_OF_WILL_DRIVER: u32 = 444_719;
126    ///<https://wowlab.gg/inspect/spell/461248>
127    pub(crate) const HIGH_VOLTAGE: u32 = 461_248;
128    ///<https://wowlab.gg/inspect/spell/384060>
129    pub(crate) const ILLUMINATED_THOUGHTS: u32 = 384_060;
130    ///<https://wowlab.gg/inspect/spell/321420>
131    pub(crate) const IMPROVED_CLEARCASTING: u32 = 321_420;
132    ///<https://wowlab.gg/inspect/spell/1261080>
133    pub(crate) const INFUSED_SPLINTERS: u32 = 1_261_080;
134    ///<https://wowlab.gg/inspect/spell/1223798>
135    pub(crate) const INTUITION: u32 = 1_223_798;
136    ///<https://wowlab.gg/inspect/spell/321526>
137    pub(crate) const MANA_ADEPT: u32 = 321_526;
138    ///<https://wowlab.gg/inspect/spell/449906>
139    pub(crate) const MANA_BOMB: u32 = 449_906;
140    ///<https://wowlab.gg/inspect/spell/457521>
141    pub(crate) const MANA_BOMB_DRIVER: u32 = 457_521;
142    ///<https://wowlab.gg/inspect/spell/384858>
143    pub(crate) const ORB_BARRAGE: u32 = 384_858;
144    ///<https://wowlab.gg/inspect/spell/452197>
145    pub(crate) const ORB_MASTERY: u32 = 452_197;
146    ///<https://wowlab.gg/inspect/spell/1243435>
147    pub(crate) const ORB_MASTERY_DRIVER: u32 = 1_243_435;
148    ///<https://wowlab.gg/inspect/spell/451728>
149    pub(crate) const OVERPOWERED_MISSILES: u32 = 451_728;
150    ///<https://wowlab.gg/inspect/spell/1244329>
151    pub(crate) const OVERPOWERED_MISSILES_DRIVER: u32 = 1_244_329;
152    ///<https://wowlab.gg/inspect/spell/205025>
153    pub(crate) const PRESENCE_OF_MIND: u32 = 205_025;
154    ///<https://wowlab.gg/inspect/spell/384612>
155    pub(crate) const PRODIGIOUS_SAVANT: u32 = 384_612;
156    ///<https://wowlab.gg/inspect/spell/205028>
157    pub(crate) const RESONANCE: u32 = 205_028;
158    ///<https://wowlab.gg/inspect/spell/281482>
159    pub(crate) const REVERBERATE: u32 = 281_482;
160    ///<https://wowlab.gg/inspect/spell/236457>
161    pub(crate) const SLIPSTREAM: u32 = 236_457;
162    ///<https://wowlab.gg/inspect/spell/444986>
163    pub(crate) const SPELLFROST_TEACHINGS: u32 = 444_986;
164    ///<https://wowlab.gg/inspect/spell/444256>
165    pub(crate) const SPLINTERING_ORBS: u32 = 444_256;
166    ///<https://wowlab.gg/inspect/spell/443739>
167    pub(crate) const SPLINTERING_SORCERY: u32 = 443_739;
168    ///<https://wowlab.gg/inspect/spell/443783>
169    pub(crate) const SPLINTERSTORM: u32 = 443_783;
170    ///<https://wowlab.gg/inspect/spell/1257950>
171    pub(crate) const TOUCH_OF_THE_ARCHMAGE: u32 = 1_257_950;
172    ///<https://wowlab.gg/inspect/spell/321507>
173    pub(crate) const TOUCH_OF_THE_MAGI: u32 = 321_507;
174}
175pub(crate) mod REPORTED_SPELL {
176    ///<https://wowlab.gg/inspect/spell/210126>
177    pub(crate) const ARCANE_FAMILIAR: u32 = 210_126;
178    ///<https://wowlab.gg/inspect/spell/7268>
179    pub(crate) const ARCANE_MISSILES: u32 = 7268;
180}
181pub(crate) mod HERO {
182    pub(crate) mod SPELLSLINGER {
183        pub(crate) mod SPELL {
184            ///<https://wowlab.gg/inspect/spell/444720>
185            pub(crate) const CONTROLLED_INSTINCTS: u32 = 444_720;
186            ///<https://wowlab.gg/inspect/spell/443763>
187            pub(crate) const SPLINTER: u32 = 443_763;
188        }
189        pub(crate) mod AURA {
190            ///<https://wowlab.gg/inspect/spell/443783>
191            pub(crate) const SPLINTERSTORM: u32 = 443_783;
192        }
193    }
194    pub(crate) mod SUNFURY {
195        pub(crate) mod SPELL {
196            ///<https://wowlab.gg/inspect/spell/449559>
197            pub(crate) const METEORITE: u32 = 449_559;
198            ///<https://wowlab.gg/inspect/spell/449569>
199            pub(crate) const METEORITE_IMPACT: u32 = 449_569;
200        }
201        pub(crate) mod AURA {
202            ///<https://wowlab.gg/inspect/spell/451038>
203            pub(crate) const ARCANE_SOUL: u32 = 451_038;
204            ///<https://wowlab.gg/inspect/spell/1260277>
205            pub(crate) const LESSER_TIME_WARP: u32 = 1_260_277;
206            ///<https://wowlab.gg/inspect/spell/449322>
207            pub(crate) const MANA_CASCADE: u32 = 449_322;
208            ///<https://wowlab.gg/inspect/spell/448604>
209            pub(crate) const SPELLFIRE_SPHERE: u32 = 448_604;
210        }
211    }
212}
213static HERO_TREE_SPELLSLINGER_SPELLS: &[(&str, u32)] = &[
214    ("CONTROLLED_INSTINCTS", 444_720),
215    ("SPLINTER", 443_763),
216];
217static HERO_TREE_SPELLSLINGER_AURAS: &[(&str, u32)] = &[("SPLINTERSTORM", 443_783)];
218static HERO_TREE_SUNFURY_SPELLS: &[(&str, u32)] = &[
219    ("METEORITE", 449_559),
220    ("METEORITE_IMPACT", 449_569),
221];
222static HERO_TREE_SUNFURY_AURAS: &[(&str, u32)] = &[
223    ("ARCANE_SOUL", 451_038),
224    ("LESSER_TIME_WARP", 1_260_277),
225    ("MANA_CASCADE", 449_322),
226    ("SPELLFIRE_SPHERE", 448_604),
227];
228pub(crate) const AURA_ARCANE_CHARGE: LocalAuraIdx = LocalAuraIdx::new(0);
229pub(crate) const AURA_ARCANE_SURGE: LocalAuraIdx = LocalAuraIdx::new(1);
230pub(crate) const AURA_CLEARCASTING: LocalAuraIdx = LocalAuraIdx::new(2);
231pub(crate) const AURA_ENLIGHTENED: LocalAuraIdx = LocalAuraIdx::new(3);
232pub(crate) const AURA_ARCANE_SALVO: LocalAuraIdx = LocalAuraIdx::new(4);
233pub(crate) const AURA_INTUITION: LocalAuraIdx = LocalAuraIdx::new(5);
234pub(crate) const AURA_PRESENCE_OF_MIND: LocalAuraIdx = LocalAuraIdx::new(6);
235pub(crate) const AURA_EVOCATION: LocalAuraIdx = LocalAuraIdx::new(7);
236pub(crate) const AURA_TOUCH_OF_THE_MAGI: LocalAuraIdx = LocalAuraIdx::new(8);
237pub(crate) const AURA_NETHER_PRECISION: LocalAuraIdx = LocalAuraIdx::new(9);
238pub(crate) const AURA_OVERPOWERED_MISSILES: LocalAuraIdx = LocalAuraIdx::new(10);
239pub(crate) const AURA_ARCANE_INTELLECT_HIGHLIGHT: LocalAuraIdx = LocalAuraIdx::new(11);
240pub(crate) const AURA_HIGH_VOLTAGE: LocalAuraIdx = LocalAuraIdx::new(12);
241pub(crate) const AURA_AMPLIFICATION: LocalAuraIdx = LocalAuraIdx::new(13);
242pub(crate) const AURA_SPELLFIRE_SALVO: LocalAuraIdx = LocalAuraIdx::new(14);
243pub(crate) const AURA_COUNT: usize = 15;
244const _: () = assert!(
245    AURA_COUNT == 15, "AURA index ABI: count changed -- update positional hook consumers"
246);
247pub(crate) const SPELL_ARCANE_BLAST: LocalSpellIdx = LocalSpellIdx::new(0);
248pub(crate) const SPELL_ARCANE_BARRAGE: LocalSpellIdx = LocalSpellIdx::new(1);
249pub(crate) const SPELL_ARCANE_MISSILES: LocalSpellIdx = LocalSpellIdx::new(2);
250pub(crate) const SPELL_ARCANE_MISSILES_DAMAGE: LocalSpellIdx = LocalSpellIdx::new(3);
251pub(crate) const SPELL_ARCANE_SURGE: LocalSpellIdx = LocalSpellIdx::new(4);
252pub(crate) const SPELL_ARCANE_ORB: LocalSpellIdx = LocalSpellIdx::new(5);
253pub(crate) const SPELL_ARCANE_ORB_BOLT: LocalSpellIdx = LocalSpellIdx::new(6);
254pub(crate) const SPELL_ARCANE_SPLINTER: LocalSpellIdx = LocalSpellIdx::new(7);
255pub(crate) const SPELL_TOUCH_OF_THE_MAGI: LocalSpellIdx = LocalSpellIdx::new(8);
256pub(crate) const SPELL_TOUCH_OF_THE_MAGI_EXPLOSION: LocalSpellIdx = LocalSpellIdx::new(
257    9,
258);
259pub(crate) const SPELL_TOUCH_OF_THE_ARCHMAGE: LocalSpellIdx = LocalSpellIdx::new(10);
260pub(crate) const SPELL_EVOCATION: LocalSpellIdx = LocalSpellIdx::new(11);
261pub(crate) const SPELL_PRESENCE_OF_MIND: LocalSpellIdx = LocalSpellIdx::new(12);
262pub(crate) const SPELL_ARCANE_EXPLOSION: LocalSpellIdx = LocalSpellIdx::new(13);
263pub(crate) const SPELL_ARCANE_INTELLECT: LocalSpellIdx = LocalSpellIdx::new(14);
264pub(crate) const SPELL_ARCANE_ASSAULT: LocalSpellIdx = LocalSpellIdx::new(15);
265pub(crate) const SPELL_COUNT: usize = 16;
266const _: () = assert!(
267    SPELL_COUNT == 16,
268    "SPELL index ABI: count changed -- update positional hook consumers"
269);
270pub(crate) mod EFFECT {
271    ///<https://wowlab.gg/inspect/spell/236628>
272    pub(crate) const AMPLIFICATION_WAVES: (u32, u8) = (236_628, 2);
273    ///<https://wowlab.gg/inspect/spell/225119>
274    pub(crate) const ARCANE_ASSAULT_DAMAGE: (u32, u8) = (225_119, 1);
275    ///<https://wowlab.gg/inspect/spell/44425>
276    pub(crate) const ARCANE_BARRAGE_DAMAGE: (u32, u8) = (44425, 1);
277    ///<https://wowlab.gg/inspect/spell/30451>
278    pub(crate) const ARCANE_BLAST_DAMAGE: (u32, u8) = (30451, 1);
279    ///<https://wowlab.gg/inspect/spell/36032>
280    pub(crate) const ARCANE_CHARGE_BARRAGE: (u32, u8) = (36032, 2);
281    ///<https://wowlab.gg/inspect/spell/36032>
282    pub(crate) const ARCANE_CHARGE_BLAST: (u32, u8) = (36032, 1);
283    ///<https://wowlab.gg/inspect/spell/210126>
284    pub(crate) const ARCANE_FAMILIAR_BONUS: (u32, u8) = (210_126, 1);
285    ///<https://wowlab.gg/inspect/spell/7268>
286    pub(crate) const ARCANE_MISSILES_DAMAGE: (u32, u8) = (7268, 1);
287    ///<https://wowlab.gg/inspect/spell/153640>
288    pub(crate) const ARCANE_ORB_BOLT_DAMAGE: (u32, u8) = (153_640, 1);
289    ///<https://wowlab.gg/inspect/spell/153626>
290    pub(crate) const ARCANE_ORB_TARGETS: (u32, u8) = (153_626, 1);
291    ///<https://wowlab.gg/inspect/spell/1242974>
292    pub(crate) const ARCANE_SALVO_DAMAGE: (u32, u8) = (1_242_974, 1);
293    ///<https://wowlab.gg/inspect/spell/443763>
294    pub(crate) const ARCANE_SPLINTER_DAMAGE: (u32, u8) = (443_763, 1);
295    ///<https://wowlab.gg/inspect/spell/365350>
296    pub(crate) const ARCANE_SURGE_DAMAGE: (u32, u8) = (365_350, 1);
297    ///<https://wowlab.gg/inspect/spell/1261106>
298    pub(crate) const ATTUNED_FAMILIAR_CHANCE: (u32, u8) = (1_261_106, 1);
299    ///<https://wowlab.gg/inspect/spell/461251>
300    pub(crate) const CHARGED_MISSILES_DAMAGE: (u32, u8) = (461_251, 1);
301    ///<https://wowlab.gg/inspect/spell/79684>
302    pub(crate) const CLEARCASTING_PROC: (u32, u8) = (79684, 2);
303    ///<https://wowlab.gg/inspect/spell/452997>
304    pub(crate) const ENERGIZED_FAMILIAR_ASSAULTS: (u32, u8) = (452_997, 1);
305    ///<https://wowlab.gg/inspect/spell/452997>
306    pub(crate) const ENERGIZED_FAMILIAR_CHANCE: (u32, u8) = (452_997, 2);
307    ///<https://wowlab.gg/inspect/spell/454020>
308    pub(crate) const ENERGIZED_FAMILIAR_GAIN: (u32, u8) = (454_020, 1);
309    ///<https://wowlab.gg/inspect/spell/321387>
310    pub(crate) const ENLIGHTENED_DAMAGE: (u32, u8) = (321_387, 2);
311    ///<https://wowlab.gg/inspect/spell/321387>
312    pub(crate) const ENLIGHTENED_REGEN: (u32, u8) = (321_387, 3);
313    ///<https://wowlab.gg/inspect/spell/444719>
314    pub(crate) const FORCE_OF_WILL_BARRAGE_DIVISOR: (u32, u8) = (444_719, 1);
315    ///<https://wowlab.gg/inspect/spell/384060>
316    pub(crate) const ILLUMINATED_THOUGHTS_CHANCE: (u32, u8) = (384_060, 1);
317    ///<https://wowlab.gg/inspect/spell/1223797>
318    pub(crate) const INTUITION_DAMAGE: (u32, u8) = (1_223_797, 1);
319    ///<https://wowlab.gg/inspect/spell/321526>
320    pub(crate) const MANA_ADEPT_BONUS: (u32, u8) = (321_526, 1);
321    ///<https://wowlab.gg/inspect/spell/1243435>
322    pub(crate) const ORB_MASTERY_COUNT: (u32, u8) = (1_243_435, 1);
323    ///<https://wowlab.gg/inspect/spell/1243435>
324    pub(crate) const ORB_MASTERY_DAMAGE: (u32, u8) = (1_243_435, 2);
325    ///<https://wowlab.gg/inspect/spell/190740>
326    pub(crate) const SAVANT_BARRAGE: (u32, u8) = (190_740, 3);
327    ///<https://wowlab.gg/inspect/spell/190740>
328    pub(crate) const SAVANT_BASE: (u32, u8) = (190_740, 1);
329    ///<https://wowlab.gg/inspect/spell/190740>
330    pub(crate) const SAVANT_BLAST: (u32, u8) = (190_740, 2);
331    ///<https://wowlab.gg/inspect/spell/190740>
332    pub(crate) const SAVANT_MASTERY_DAMAGE: (u32, u8) = (190_740, 5);
333    ///<https://wowlab.gg/inspect/spell/190740>
334    pub(crate) const SAVANT_SPLINTER_DAMAGE: (u32, u8) = (190_740, 6);
335}
336static REPORTED_SPELLS: &[(&str, u32)] = &[
337    ("arcane_familiar", 210_126),
338    ("arcane_missiles", 7268),
339];
340static DECLARED_SPELL_IDS: &[u32] = &[
341    30451, 44425, 5143, 7268, 365_350, 153_626, 153_640, 443_763, 321_507, 210_833,
342    1_258_134, 12051, 205_025, 1449, 1459, 225_119, 36032, 365_362, 263_725, 1_217_242,
343    1_242_974, 1_223_797, 205_025, 12051, 210_824, 383_783, 1_277_009, 1459, 461_524,
344    236_628, 449_322, 7268, 30451, 36032, 44425, 79684, 153_626, 153_640, 190_740,
345    210_126, 225_119, 236_628, 321_387, 321_526, 365_350, 384_060, 443_763, 444_719,
346    452_997, 454_020, 461_251, 1_223_797, 1_242_974, 1_243_435, 1_261_106, 210_126, 7268,
347    444_720, 443_763, 443_783, 449_559, 449_569, 451_038, 1_260_277, 449_322, 448_604,
348];
349static DECLARED_AURA_IDS: &[u32] = &[
350    36032, 365_362, 263_725, 1_217_242, 1_242_974, 1_223_797, 205_025, 12051, 210_824,
351    383_783, 1_277_009, 1459, 461_524, 236_628, 449_322, 443_783, 451_038, 1_260_277,
352    449_322, 448_604,
353];
354static TALENTS: &[(&str, u32)] = &[
355    ("AEGWYNNS_TECHNIQUE", TALENT::AEGWYNNS_TECHNIQUE),
356    ("AMPLIFICATION", TALENT::AMPLIFICATION),
357    ("ARCANE_ECHO", TALENT::ARCANE_ECHO),
358    ("ARCANE_FAMILIAR", TALENT::ARCANE_FAMILIAR),
359    ("ARCANE_MISSILES", TALENT::ARCANE_MISSILES),
360    ("ARCANE_ORB", TALENT::ARCANE_ORB),
361    ("ARCANE_PULSE", TALENT::ARCANE_PULSE),
362    ("ARCANE_SALVO", TALENT::ARCANE_SALVO),
363    ("ARCANE_SALVO_DRIVER", TALENT::ARCANE_SALVO_DRIVER),
364    ("ARCANE_SURGE", TALENT::ARCANE_SURGE),
365    ("ARCING_CLEAVE", TALENT::ARCING_CLEAVE),
366    ("ATTUNED_FAMILIAR", TALENT::ATTUNED_FAMILIAR),
367    ("AUGURY_ABOUNDS", TALENT::AUGURY_ABOUNDS),
368    ("CHARGED_MISSILES", TALENT::CHARGED_MISSILES),
369    ("CHARGED_ORB", TALENT::CHARGED_ORB),
370    ("ENERGIZED_FAMILIAR", TALENT::ENERGIZED_FAMILIAR),
371    ("ENLIGHTENED", TALENT::ENLIGHTENED),
372    ("EUREKA", TALENT::EUREKA),
373    ("EVOCATION", TALENT::EVOCATION),
374    ("EXPANDED_MIND", TALENT::EXPANDED_MIND),
375    ("EXPANDED_MIND_DRIVER", TALENT::EXPANDED_MIND_DRIVER),
376    ("FOCUSING_CRYSTAL", TALENT::FOCUSING_CRYSTAL),
377    ("FORCE_OF_WILL_DRIVER", TALENT::FORCE_OF_WILL_DRIVER),
378    ("HIGH_VOLTAGE", TALENT::HIGH_VOLTAGE),
379    ("ILLUMINATED_THOUGHTS", TALENT::ILLUMINATED_THOUGHTS),
380    ("IMPROVED_CLEARCASTING", TALENT::IMPROVED_CLEARCASTING),
381    ("INFUSED_SPLINTERS", TALENT::INFUSED_SPLINTERS),
382    ("INTUITION", TALENT::INTUITION),
383    ("MANA_ADEPT", TALENT::MANA_ADEPT),
384    ("MANA_BOMB", TALENT::MANA_BOMB),
385    ("MANA_BOMB_DRIVER", TALENT::MANA_BOMB_DRIVER),
386    ("ORB_BARRAGE", TALENT::ORB_BARRAGE),
387    ("ORB_MASTERY", TALENT::ORB_MASTERY),
388    ("ORB_MASTERY_DRIVER", TALENT::ORB_MASTERY_DRIVER),
389    ("OVERPOWERED_MISSILES", TALENT::OVERPOWERED_MISSILES),
390    ("OVERPOWERED_MISSILES_DRIVER", TALENT::OVERPOWERED_MISSILES_DRIVER),
391    ("PRESENCE_OF_MIND", TALENT::PRESENCE_OF_MIND),
392    ("PRODIGIOUS_SAVANT", TALENT::PRODIGIOUS_SAVANT),
393    ("RESONANCE", TALENT::RESONANCE),
394    ("REVERBERATE", TALENT::REVERBERATE),
395    ("SLIPSTREAM", TALENT::SLIPSTREAM),
396    ("SPELLFROST_TEACHINGS", TALENT::SPELLFROST_TEACHINGS),
397    ("SPLINTERING_ORBS", TALENT::SPLINTERING_ORBS),
398    ("SPLINTERING_SORCERY", TALENT::SPLINTERING_SORCERY),
399    ("SPLINTERSTORM", TALENT::SPLINTERSTORM),
400    ("TOUCH_OF_THE_ARCHMAGE", TALENT::TOUCH_OF_THE_ARCHMAGE),
401    ("TOUCH_OF_THE_MAGI", TALENT::TOUCH_OF_THE_MAGI),
402];
403pub(crate) mod ARCANE_MAGE {
404    pub(crate) const ARCANE_BLAST_CASTS: u32 = 0;
405    pub(crate) const ARCANE_BARRAGE_CASTS: u32 = 1;
406    pub(crate) const ARCANE_MISSILES_CASTS: u32 = 2;
407    pub(crate) const ARCANE_SURGE_CASTS: u32 = 3;
408    pub(crate) const ARCANE_ORB_CASTS: u32 = 4;
409    pub(crate) const TOUCH_OF_THE_MAGI_CASTS: u32 = 5;
410    pub(crate) const ARCANE_SURGE_UPTIME_MS: u32 = 6;
411    pub(crate) const TOUCH_OF_THE_MAGI_UPTIME_MS: u32 = 7;
412}
413fn aura_arcane_charge(
414    a: AuraDefinitionDraft,
415    data: &ResolvedGameData,
416) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
417    Ok(
418        a
419            .on_player()
420            .apply_base_from_data(data, 36032)?
421            .max_stacks(
422                data
423                    .require_aura_max_stacks(
424                        wowlab_types::sim::SpellIdx::from_raw(36032),
425                    )?,
426            ),
427    )
428}
429fn aura_arcane_surge(
430    a: AuraDefinitionDraft,
431    data: &ResolvedGameData,
432) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
433    Ok(
434        a
435            .on_player()
436            .apply_base_from_data(data, 365_362)?
437            .max_stacks(
438                data
439                    .require_aura_max_stacks(
440                        wowlab_types::sim::SpellIdx::from_raw(365_362),
441                    )?,
442            ),
443    )
444}
445fn aura_clearcasting(
446    a: AuraDefinitionDraft,
447    data: &ResolvedGameData,
448) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
449    Ok(
450        a
451            .on_player()
452            .apply_base_from_data(data, 263_725)?
453            .max_stacks(
454                data
455                    .require_aura_max_stacks(
456                        wowlab_types::sim::SpellIdx::from_raw(263_725),
457                    )?,
458            ),
459    )
460}
461fn aura_enlightened(
462    a: AuraDefinitionDraft,
463    data: &ResolvedGameData,
464) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
465    Ok(
466        a
467            .on_player()
468            .apply_base_from_data(data, 1_217_242)?
469            .max_stacks(
470                data
471                    .require_aura_max_stacks(
472                        wowlab_types::sim::SpellIdx::from_raw(1_217_242),
473                    )?,
474            ),
475    )
476}
477fn aura_arcane_salvo(
478    a: AuraDefinitionDraft,
479    data: &ResolvedGameData,
480) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
481    Ok(
482        a
483            .on_player()
484            .apply_base_from_data(data, 1_242_974)?
485            .max_stacks(
486                data
487                    .require_aura_max_stacks(
488                        wowlab_types::sim::SpellIdx::from_raw(1_242_974),
489                    )?,
490            ),
491    )
492}
493fn aura_intuition(
494    a: AuraDefinitionDraft,
495    data: &ResolvedGameData,
496) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
497    Ok(
498        a
499            .on_player()
500            .apply_base_from_data(data, 1_223_797)?
501            .max_stacks(
502                data
503                    .require_aura_max_stacks(
504                        wowlab_types::sim::SpellIdx::from_raw(1_223_797),
505                    )?,
506            ),
507    )
508}
509fn aura_presence_of_mind(
510    a: AuraDefinitionDraft,
511    data: &ResolvedGameData,
512) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
513    Ok(
514        a
515            .on_player()
516            .apply_base_from_data(data, 205_025)?
517            .max_stacks(
518                data
519                    .require_aura_max_stacks(
520                        wowlab_types::sim::SpellIdx::from_raw(205_025),
521                    )?,
522            ),
523    )
524}
525fn aura_evocation(
526    a: AuraDefinitionDraft,
527    data: &ResolvedGameData,
528) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
529    Ok(
530        a
531            .on_player()
532            .apply_base_from_data(data, 12051)?
533            .max_stacks(
534                data
535                    .require_aura_max_stacks(
536                        wowlab_types::sim::SpellIdx::from_raw(12051),
537                    )?,
538            ),
539    )
540}
541fn aura_touch_of_the_magi(
542    a: AuraDefinitionDraft,
543    data: &ResolvedGameData,
544) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
545    Ok(
546        a
547            .on_target()
548            .apply_base_from_data(data, 210_824)?
549            .max_stacks(
550                data
551                    .require_aura_max_stacks(
552                        wowlab_types::sim::SpellIdx::from_raw(210_824),
553                    )?,
554            )
555            .on_expire(crate::hooks::arcane_mage::touch_of_the_magi_expire_hook),
556    )
557}
558fn aura_nether_precision(
559    a: AuraDefinitionDraft,
560    data: &ResolvedGameData,
561) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
562    Ok(
563        a
564            .on_player()
565            .apply_base_from_data(data, 383_783)?
566            .max_stacks(
567                data
568                    .require_aura_max_stacks(
569                        wowlab_types::sim::SpellIdx::from_raw(383_783),
570                    )?,
571            ),
572    )
573}
574fn aura_overpowered_missiles(
575    a: AuraDefinitionDraft,
576    data: &ResolvedGameData,
577) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
578    Ok(
579        a
580            .on_player()
581            .apply_base_from_data(data, 1_277_009)?
582            .max_stacks(
583                data
584                    .require_aura_max_stacks(
585                        wowlab_types::sim::SpellIdx::from_raw(1_277_009),
586                    )?,
587            ),
588    )
589}
590fn aura_arcane_intellect_highlight(
591    a: AuraDefinitionDraft,
592    data: &ResolvedGameData,
593) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
594    Ok(
595        a
596            .on_player()
597            .apply_base_from_data(data, 1459)?
598            .max_stacks(
599                data
600                    .require_aura_max_stacks(
601                        wowlab_types::sim::SpellIdx::from_raw(1459),
602                    )?,
603            ),
604    )
605}
606fn aura_high_voltage(
607    a: AuraDefinitionDraft,
608    data: &ResolvedGameData,
609) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
610    Ok(
611        a
612            .on_player()
613            .apply_base_from_data(data, 461_524)?
614            .max_stacks(
615                data
616                    .require_aura_max_stacks(
617                        wowlab_types::sim::SpellIdx::from_raw(461_524),
618                    )?,
619            ),
620    )
621}
622fn aura_amplification(
623    a: AuraDefinitionDraft,
624    data: &ResolvedGameData,
625) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
626    Ok(
627        a
628            .on_player()
629            .apply_base_from_data(data, 236_628)?
630            .max_stacks(
631                data
632                    .require_aura_max_stacks(
633                        wowlab_types::sim::SpellIdx::from_raw(236_628),
634                    )?,
635            ),
636    )
637}
638fn aura_spellfire_salvo(
639    a: AuraDefinitionDraft,
640    data: &ResolvedGameData,
641) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
642    Ok(
643        a
644            .on_player()
645            .apply_base_from_data(data, 449_322)?
646            .max_stacks(
647                data
648                    .require_aura_max_stacks(
649                        wowlab_types::sim::SpellIdx::from_raw(449_322),
650                    )?,
651            ),
652    )
653}
654fn spell_arcane_blast(
655    s: SpellDefinitionDraft,
656    data: &ResolvedGameData,
657) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
658    Ok(
659        s
660            .apply_base_from_data(data, 30451)?
661            .apply_aoe_from_data(data)
662            .on_cast(crate::hooks::arcane_mage::arcane_blast_hook),
663    )
664}
665fn spell_arcane_barrage(
666    s: SpellDefinitionDraft,
667    data: &ResolvedGameData,
668) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
669    Ok(
670        s
671            .apply_base_from_data(data, 44425)?
672            .apply_aoe_from_data(data)
673            .on_cast(crate::hooks::arcane_mage::arcane_barrage_hook),
674    )
675}
676fn spell_arcane_missiles(
677    s: SpellDefinitionDraft,
678    data: &ResolvedGameData,
679) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
680    Ok(
681        s
682            .apply_base_from_data(data, 5143)?
683            .apply_aoe_from_data(data)
684            .on_cast(crate::hooks::arcane_mage::arcane_missiles_hook),
685    )
686}
687fn spell_arcane_missiles_damage(
688    s: SpellDefinitionDraft,
689    data: &ResolvedGameData,
690) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
691    Ok(s.apply_base_from_data(data, 7268)?.apply_aoe_from_data(data))
692}
693fn spell_arcane_surge(
694    s: SpellDefinitionDraft,
695    data: &ResolvedGameData,
696) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
697    Ok(
698        s
699            .apply_base_from_data(data, 365_350)?
700            .applies_aura(AURA_ARCANE_SURGE)
701            .apply_aoe_from_data(data)
702            .on_cast(crate::hooks::arcane_mage::arcane_surge_hook),
703    )
704}
705fn spell_arcane_orb(
706    s: SpellDefinitionDraft,
707    data: &ResolvedGameData,
708) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
709    Ok(
710        s
711            .apply_base_from_data(data, 153_626)?
712            .apply_aoe_from_data(data)
713            .on_cast(crate::hooks::arcane_mage::arcane_orb_hook),
714    )
715}
716fn spell_arcane_orb_bolt(
717    s: SpellDefinitionDraft,
718    data: &ResolvedGameData,
719) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
720    Ok(s.apply_base_from_data(data, 153_640)?.apply_aoe_from_data(data))
721}
722fn spell_arcane_splinter(
723    s: SpellDefinitionDraft,
724    data: &ResolvedGameData,
725) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
726    Ok(s.apply_base_from_data(data, 443_763)?.apply_aoe_from_data(data))
727}
728fn spell_touch_of_the_magi(
729    s: SpellDefinitionDraft,
730    data: &ResolvedGameData,
731) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
732    Ok(
733        s
734            .apply_base_from_data(data, 321_507)?
735            .applies_aura(AURA_TOUCH_OF_THE_MAGI)
736            .apply_aoe_from_data(data)
737            .on_cast(crate::hooks::arcane_mage::touch_of_the_magi_hook),
738    )
739}
740fn spell_touch_of_the_magi_explosion(
741    s: SpellDefinitionDraft,
742    data: &ResolvedGameData,
743) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
744    Ok(s.apply_base_from_data(data, 210_833)?.apply_aoe_from_data(data))
745}
746fn spell_touch_of_the_archmage(
747    s: SpellDefinitionDraft,
748    data: &ResolvedGameData,
749) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
750    Ok(s.apply_base_from_data(data, 1_258_134)?.apply_aoe_from_data(data))
751}
752fn spell_evocation(
753    s: SpellDefinitionDraft,
754    data: &ResolvedGameData,
755) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
756    Ok(
757        s
758            .apply_base_from_data(data, 12051)?
759            .applies_inferred_aura(AURA_EVOCATION, 12051)
760            .apply_aoe_from_data(data),
761    )
762}
763fn spell_presence_of_mind(
764    s: SpellDefinitionDraft,
765    data: &ResolvedGameData,
766) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
767    Ok(
768        s
769            .apply_base_from_data(data, 205_025)?
770            .applies_inferred_aura(AURA_PRESENCE_OF_MIND, 205_025)
771            .apply_aoe_from_data(data),
772    )
773}
774fn spell_arcane_explosion(
775    s: SpellDefinitionDraft,
776    data: &ResolvedGameData,
777) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
778    Ok(s.apply_base_from_data(data, 1449)?.apply_aoe_from_data(data))
779}
780fn spell_arcane_intellect(
781    s: SpellDefinitionDraft,
782    data: &ResolvedGameData,
783) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
784    Ok(
785        s
786            .apply_base_from_data(data, 1459)?
787            .applies_inferred_aura(AURA_ARCANE_INTELLECT_HIGHLIGHT, 1459)
788            .apply_aoe_from_data(data),
789    )
790}
791fn spell_arcane_assault(
792    s: SpellDefinitionDraft,
793    data: &ResolvedGameData,
794) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
795    Ok(s.apply_base_from_data(data, 225_119)?.apply_aoe_from_data(data))
796}
797pub(crate) fn build_combat_system(
798    params: &wowlab_engine_ports::HandlerParams<'_>,
799) -> Result<BuiltCombatSystem, wowlab_engine_ports::EngineError> {
800    let builder = BuiltCombatSystem::builder(params.stats.clone())
801        .spec_id(SpecId::Arcane)
802        .hero_talent_trees(DECLARED_METADATA.hero_talent_trees)
803        .mastery_spell(190_740)
804        .mastery_hook(crate::hooks::arcane_mage::mastery)
805        .resource(
806            "mana",
807            100_000.0,
808            params
809                .game_data
810                .power_regen_for_max(0, 100_000.0)
811                .ok_or_else(|| {
812                    wowlab_engine_ports::EngineError::spec_construction(
813                        "missing power-type power_regen_for_max for type_id 0",
814                    )
815                })?,
816        )
817        .resource_type_id(0)
818        .resource_start(100_000.0)
819        .secondary_resource(
820            "arcane_charges",
821            params
822                .game_data
823                .power_max(16)
824                .ok_or_else(|| {
825                    wowlab_engine_ports::EngineError::spec_construction(
826                        "missing power-type power_max for type_id 16",
827                    )
828                })?,
829        )
830        .secondary_resource_type_id(16)
831        .aura(
832            "arcane_charge",
833            AURA::ARCANE_CHARGE,
834            |a| aura_arcane_charge(a, &params.game_data),
835        )
836        .aura(
837            "arcane_surge",
838            AURA::ARCANE_SURGE,
839            |a| aura_arcane_surge(a, &params.game_data),
840        )
841        .aura(
842            "clearcasting",
843            AURA::CLEARCASTING,
844            |a| aura_clearcasting(a, &params.game_data),
845        )
846        .aura(
847            "enlightened",
848            AURA::ENLIGHTENED,
849            |a| aura_enlightened(a, &params.game_data),
850        )
851        .aura(
852            "arcane_salvo",
853            AURA::ARCANE_SALVO,
854            |a| aura_arcane_salvo(a, &params.game_data),
855        )
856        .aura("intuition", AURA::INTUITION, |a| aura_intuition(a, &params.game_data))
857        .aura(
858            "presence_of_mind",
859            AURA::PRESENCE_OF_MIND,
860            |a| aura_presence_of_mind(a, &params.game_data),
861        )
862        .aura("evocation", AURA::EVOCATION, |a| aura_evocation(a, &params.game_data))
863        .aura(
864            "touch_of_the_magi",
865            AURA::TOUCH_OF_THE_MAGI,
866            |a| aura_touch_of_the_magi(a, &params.game_data),
867        )
868        .aura(
869            "nether_precision",
870            AURA::NETHER_PRECISION,
871            |a| aura_nether_precision(a, &params.game_data),
872        )
873        .aura(
874            "overpowered_missiles",
875            AURA::OVERPOWERED_MISSILES,
876            |a| aura_overpowered_missiles(a, &params.game_data),
877        )
878        .aura(
879            "arcane_intellect_highlight",
880            AURA::ARCANE_INTELLECT_HIGHLIGHT,
881            |a| aura_arcane_intellect_highlight(a, &params.game_data),
882        )
883        .aura(
884            "high_voltage",
885            AURA::HIGH_VOLTAGE,
886            |a| aura_high_voltage(a, &params.game_data),
887        )
888        .aura(
889            "amplification",
890            AURA::AMPLIFICATION,
891            |a| aura_amplification(a, &params.game_data),
892        )
893        .aura(
894            "spellfire_salvo",
895            AURA::SPELLFIRE_SALVO,
896            |a| aura_spellfire_salvo(a, &params.game_data),
897        )
898        .spell(
899            "arcane_blast",
900            SPELL::ARCANE_BLAST,
901            |s| spell_arcane_blast(s, &params.game_data),
902        )
903        .spell(
904            "arcane_barrage",
905            SPELL::ARCANE_BARRAGE,
906            |s| spell_arcane_barrage(s, &params.game_data),
907        )
908        .spell(
909            "arcane_missiles",
910            SPELL::ARCANE_MISSILES,
911            |s| spell_arcane_missiles(s, &params.game_data),
912        )
913        .spell(
914            "arcane_missiles_damage",
915            SPELL::ARCANE_MISSILES_DAMAGE,
916            |s| spell_arcane_missiles_damage(s, &params.game_data),
917        )
918        .spell(
919            "arcane_surge",
920            SPELL::ARCANE_SURGE,
921            |s| spell_arcane_surge(s, &params.game_data),
922        )
923        .spell(
924            "arcane_orb",
925            SPELL::ARCANE_ORB,
926            |s| spell_arcane_orb(s, &params.game_data),
927        )
928        .spell(
929            "arcane_orb_bolt",
930            SPELL::ARCANE_ORB_BOLT,
931            |s| spell_arcane_orb_bolt(s, &params.game_data),
932        )
933        .spell(
934            "arcane_splinter",
935            SPELL::ARCANE_SPLINTER,
936            |s| spell_arcane_splinter(s, &params.game_data),
937        )
938        .spell(
939            "touch_of_the_magi",
940            SPELL::TOUCH_OF_THE_MAGI,
941            |s| spell_touch_of_the_magi(s, &params.game_data),
942        )
943        .spell(
944            "touch_of_the_magi_explosion",
945            SPELL::TOUCH_OF_THE_MAGI_EXPLOSION,
946            |s| spell_touch_of_the_magi_explosion(s, &params.game_data),
947        )
948        .spell(
949            "touch_of_the_archmage",
950            SPELL::TOUCH_OF_THE_ARCHMAGE,
951            |s| spell_touch_of_the_archmage(s, &params.game_data),
952        )
953        .spell("evocation", SPELL::EVOCATION, |s| spell_evocation(s, &params.game_data))
954        .spell(
955            "presence_of_mind",
956            SPELL::PRESENCE_OF_MIND,
957            |s| spell_presence_of_mind(s, &params.game_data),
958        )
959        .spell(
960            "arcane_explosion",
961            SPELL::ARCANE_EXPLOSION,
962            |s| spell_arcane_explosion(s, &params.game_data),
963        )
964        .spell(
965            "arcane_intellect",
966            SPELL::ARCANE_INTELLECT,
967            |s| spell_arcane_intellect(s, &params.game_data),
968        )
969        .spell(
970            "arcane_assault",
971            SPELL::ARCANE_ASSAULT,
972            |s| spell_arcane_assault(s, &params.game_data),
973        )
974        .game_data(params.game_data.clone())
975        .talent_spell_ids(TALENTS)
976        .talent_selections(params.talent_selections)
977        .talent_companion_aura(TALENT::ENLIGHTENED, AURA_ENLIGHTENED)
978        .set_bonus_auras(params.set_bonus_auras)
979        .encounter(params.encounter.clone());
980    let builder = crate::generated::items::register_equipped(
981        builder,
982        &params.game_data,
983        params.equipped_items,
984    )?;
985
986    builder
987        .build(params.rotation)
988        .map_err(wowlab_engine_ports::EngineError::rotation_compile)
989}
990fn new_handler(
991    params: wowlab_engine_ports::HandlerParams<'_>,
992) -> Result<Box<dyn SpecHandler>, wowlab_engine_ports::EngineError> {
993    let handler = crate::composition::compose_handler(
994        build_combat_system,
995        &params,
996        |parts, params| Ok(crate::hooks::arcane_mage::ArcaneHandler::new(parts, params)),
997    )?;
998
999    Ok(Box::new(handler))
1000}
1001static DECLARED_METADATA: DeclaredSpecMetadata = DeclaredSpecMetadata {
1002    primary_resource: ResourceType::Mana,
1003    secondary_resource: Some(ResourceType::ArcaneCharges),
1004    spell_ids: DECLARED_SPELL_IDS,
1005    aura_ids: DECLARED_AURA_IDS,
1006    server_proc_entries: &[],
1007    talents: TALENTS,
1008    rotation_field_schema: &[],
1009    metrics_plugin_id: None,
1010    hero_talent_trees: &[
1011        HeroTalentTreeDesc {
1012            name: "Spellslinger",
1013            spells: HERO_TREE_SPELLSLINGER_SPELLS,
1014            auras: HERO_TREE_SPELLSLINGER_AURAS,
1015        },
1016        HeroTalentTreeDesc {
1017            name: "Sunfury",
1018            spells: HERO_TREE_SUNFURY_SPELLS,
1019            auras: HERO_TREE_SUNFURY_AURAS,
1020        },
1021    ],
1022    reported_spells: REPORTED_SPELLS,
1023    masked_passive_effects: &[],
1024    passive_effect_overrides: &[],
1025};
1026pub(super) const SPEC_DESCRIPTOR: SpecDescriptor = SpecDescriptor {
1027    spec_id: SpecId::Arcane,
1028    display_name: "Arcane Mage",
1029    metadata: DECLARED_METADATA,
1030    handler_factory: new_handler,
1031};
1032wowlab_engine_combat::smoke_test!(build_combat_system);