Skip to main content

wowlab_engine_content/generated/specs/
elemental_shaman.rs

1//! @generated by codegen-cli from manifests/specs/shaman/elemental/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/188196>
15    pub(crate) const LIGHTNING_BOLT: u32 = 188_196;
16    ///<https://wowlab.gg/inspect/spell/188443>
17    pub(crate) const CHAIN_LIGHTNING: u32 = 188_443;
18    ///<https://wowlab.gg/inspect/spell/51505>
19    pub(crate) const LAVA_BURST: u32 = 51505;
20    ///<https://wowlab.gg/inspect/spell/8042>
21    pub(crate) const EARTH_SHOCK: u32 = 8042;
22    ///<https://wowlab.gg/inspect/spell/117014>
23    pub(crate) const ELEMENTAL_BLAST: u32 = 117_014;
24    ///<https://wowlab.gg/inspect/spell/61882>
25    pub(crate) const EARTHQUAKE: u32 = 61882;
26    ///<https://wowlab.gg/inspect/spell/188389>
27    pub(crate) const FLAME_SHOCK: u32 = 188_389;
28    ///<https://wowlab.gg/inspect/spell/196840>
29    pub(crate) const FROST_SHOCK: u32 = 196_840;
30    ///<https://wowlab.gg/inspect/spell/452201>
31    pub(crate) const TEMPEST: u32 = 452_201;
32    ///<https://wowlab.gg/inspect/spell/191634>
33    pub(crate) const STORMKEEPER: u32 = 191_634;
34    ///<https://wowlab.gg/inspect/spell/1219480>
35    pub(crate) const ASCENDANCE: u32 = 1_219_480;
36    ///<https://wowlab.gg/inspect/spell/443454>
37    pub(crate) const ANCESTRAL_SWIFTNESS: u32 = 443_454;
38    ///<https://wowlab.gg/inspect/spell/318038>
39    pub(crate) const FLAMETONGUE_WEAPON: u32 = 318_038;
40    ///<https://wowlab.gg/inspect/spell/462757>
41    pub(crate) const THUNDERSTRIKE_WARD: u32 = 462_757;
42    ///<https://wowlab.gg/inspect/spell/192106>
43    pub(crate) const LIGHTNING_SHIELD: u32 = 192_106;
44    ///<https://wowlab.gg/inspect/spell/188592>
45    pub(crate) const FIRE_ELEMENTAL: u32 = 188_592;
46    ///<https://wowlab.gg/inspect/spell/57984>
47    pub(crate) const FIRE_BLAST: u32 = 57984;
48    ///<https://wowlab.gg/inspect/spell/117588>
49    pub(crate) const METEOR: u32 = 117_588;
50    ///<https://wowlab.gg/inspect/spell/118297>
51    pub(crate) const IMMOLATE: u32 = 118_297;
52    ///<https://wowlab.gg/inspect/spell/157331>
53    pub(crate) const WIND_GUST: u32 = 157_331;
54    ///<https://wowlab.gg/inspect/spell/157348>
55    pub(crate) const CALL_LIGHTNING: u32 = 157_348;
56    ///<https://wowlab.gg/inspect/spell/269005>
57    pub(crate) const STORMFURY: u32 = 269_005;
58    ///<https://wowlab.gg/inspect/spell/45284>
59    pub(crate) const LIGHTNING_BOLT_OVERLOAD: u32 = 45284;
60    ///<https://wowlab.gg/inspect/spell/45297>
61    pub(crate) const CHAIN_LIGHTNING_OVERLOAD: u32 = 45297;
62    ///<https://wowlab.gg/inspect/spell/285466>
63    pub(crate) const LAVA_BURST_OVERLOAD: u32 = 285_466;
64    ///<https://wowlab.gg/inspect/spell/120588>
65    pub(crate) const ELEMENTAL_BLAST_OVERLOAD: u32 = 120_588;
66    ///<https://wowlab.gg/inspect/spell/463351>
67    pub(crate) const TEMPEST_OVERLOAD: u32 = 463_351;
68    ///<https://wowlab.gg/inspect/spell/1235840>
69    pub(crate) const STORMS_EYE: u32 = 1_235_840;
70    ///<https://wowlab.gg/inspect/spell/197568>
71    pub(crate) const LIGHTNING_ROD_DAMAGE: u32 = 197_568;
72    ///<https://wowlab.gg/inspect/spell/462854>
73    pub(crate) const SKYFURY: u32 = 462_854;
74}
75pub(crate) mod AURA {
76    ///<https://wowlab.gg/inspect/spell/1219480>
77    pub(crate) const ASCENDANCE: u32 = 1_219_480;
78    ///<https://wowlab.gg/inspect/spell/191634>
79    pub(crate) const STORMKEEPER: u32 = 191_634;
80    ///<https://wowlab.gg/inspect/spell/260734>
81    pub(crate) const MASTER_OF_THE_ELEMENTS: u32 = 260_734;
82    ///<https://wowlab.gg/inspect/spell/77762>
83    pub(crate) const LAVA_SURGE: u32 = 77762;
84    ///<https://wowlab.gg/inspect/spell/454015>
85    pub(crate) const TEMPEST: u32 = 454_015;
86    ///<https://wowlab.gg/inspect/spell/1272101>
87    pub(crate) const THUNDEROUS_VELOCITY: u32 = 1_272_101;
88    ///<https://wowlab.gg/inspect/spell/191877>
89    pub(crate) const POWER_OF_THE_MAELSTROM: u32 = 191_877;
90    ///<https://wowlab.gg/inspect/spell/454394>
91    pub(crate) const UNLIMITED_POWER: u32 = 454_394;
92    ///<https://wowlab.gg/inspect/spell/118522>
93    pub(crate) const ELEMENTAL_BLAST_CRIT: u32 = 118_522;
94    ///<https://wowlab.gg/inspect/spell/173183>
95    pub(crate) const ELEMENTAL_BLAST_HASTE: u32 = 173_183;
96    ///<https://wowlab.gg/inspect/spell/173184>
97    pub(crate) const ELEMENTAL_BLAST_MASTERY: u32 = 173_184;
98    ///<https://wowlab.gg/inspect/spell/443454>
99    pub(crate) const ANCESTRAL_SWIFTNESS: u32 = 443_454;
100    ///<https://wowlab.gg/inspect/spell/188389>
101    pub(crate) const FLAME_SHOCK: u32 = 188_389;
102    ///<https://wowlab.gg/inspect/spell/210689>
103    pub(crate) const LIGHTNING_ROD: u32 = 210_689;
104    ///<https://wowlab.gg/inspect/spell/1259491>
105    pub(crate) const PURGING_FLAMES: u32 = 1_259_491;
106    ///<https://wowlab.gg/inspect/spell/192106>
107    pub(crate) const LIGHTNING_SHIELD: u32 = 192_106;
108    ///<https://wowlab.gg/inspect/spell/462757>
109    pub(crate) const THUNDERSTRIKE_WARD: u32 = 462_757;
110    ///<https://wowlab.gg/inspect/spell/382027>
111    pub(crate) const IMPROVED_FLAMETONGUE_WEAPON: u32 = 382_027;
112    ///<https://wowlab.gg/inspect/spell/384088>
113    pub(crate) const ECHOES_OF_GREAT_SUNDERING: u32 = 384_088;
114    ///<https://wowlab.gg/inspect/spell/263806>
115    pub(crate) const WIND_GUST: u32 = 263_806;
116    ///<https://wowlab.gg/inspect/spell/188592>
117    pub(crate) const FIRE_ELEMENTAL: u32 = 188_592;
118    ///<https://wowlab.gg/inspect/spell/157299>
119    pub(crate) const STORM_ELEMENTAL: u32 = 157_299;
120    ///<https://wowlab.gg/inspect/spell/1239315>
121    pub(crate) const STORMS_EYE: u32 = 1_239_315;
122    ///<https://wowlab.gg/inspect/spell/462854>
123    pub(crate) const SKYFURY: u32 = 462_854;
124    ///<https://wowlab.gg/inspect/spell/462854>
125    pub(crate) const SKYFURY_HIGHLIGHT: u32 = 462_854;
126}
127pub(crate) mod TALENT {
128    ///<https://wowlab.gg/inspect/spell/273221>
129    pub(crate) const AFTERSHOCK: u32 = 273_221;
130    ///<https://wowlab.gg/inspect/spell/443454>
131    pub(crate) const ANCESTRAL_SWIFTNESS: u32 = 443_454;
132    ///<https://wowlab.gg/inspect/spell/455096>
133    pub(crate) const ARC_DISCHARGE: u32 = 455_096;
134    ///<https://wowlab.gg/inspect/spell/114050>
135    pub(crate) const ASCENDANCE: u32 = 114_050;
136    ///<https://wowlab.gg/inspect/spell/455129>
137    pub(crate) const AWAKENING_STORMS: u32 = 455_129;
138    ///<https://wowlab.gg/inspect/spell/378255>
139    pub(crate) const CALL_OF_FIRE: u32 = 378_255;
140    ///<https://wowlab.gg/inspect/spell/117014>
141    pub(crate) const ELEMENTAL_BLAST: u32 = 117_014;
142    ///<https://wowlab.gg/inspect/spell/462866>
143    pub(crate) const ELEMENTAL_UNITY: u32 = 462_866;
144    ///<https://wowlab.gg/inspect/spell/1270064>
145    pub(crate) const FEEDBACK_LOOP_3: u32 = 1_270_064;
146    ///<https://wowlab.gg/inspect/spell/188592>
147    pub(crate) const FIRE_ELEMENTAL: u32 = 188_592;
148    ///<https://wowlab.gg/inspect/spell/318038>
149    pub(crate) const FLAMETONGUE_WEAPON: u32 = 318_038;
150    ///<https://wowlab.gg/inspect/spell/191717>
151    pub(crate) const FURY_OF_THE_STORMS: u32 = 191_717;
152    ///<https://wowlab.gg/inspect/spell/462840>
153    pub(crate) const FUSION_OF_ELEMENTS: u32 = 462_840;
154    ///<https://wowlab.gg/inspect/spell/1259047>
155    pub(crate) const INFERNO_ARC: u32 = 1_259_047;
156    ///<https://wowlab.gg/inspect/spell/462862>
157    pub(crate) const LIGHTNING_CAPACITOR: u32 = 462_862;
158    ///<https://wowlab.gg/inspect/spell/210689>
159    pub(crate) const LIGHTNING_ROD: u32 = 210_689;
160    ///<https://wowlab.gg/inspect/spell/16166>
161    pub(crate) const MASTER_OF_THE_ELEMENTS: u32 = 16166;
162    ///<https://wowlab.gg/inspect/spell/381726>
163    pub(crate) const MOUNTAINS_WILL_FALL: u32 = 381_726;
164    ///<https://wowlab.gg/inspect/spell/191861>
165    pub(crate) const POWER_OF_THE_MAELSTROM: u32 = 191_861;
166    ///<https://wowlab.gg/inspect/spell/117013>
167    pub(crate) const PRIMAL_ELEMENTALIST: u32 = 117_013;
168    ///<https://wowlab.gg/inspect/spell/443448>
169    pub(crate) const PRIMORDIAL_CAPACITY: u32 = 443_448;
170    ///<https://wowlab.gg/inspect/spell/381782>
171    pub(crate) const SEARING_FLAMES: u32 = 381_782;
172    ///<https://wowlab.gg/inspect/spell/191634>
173    pub(crate) const STORMKEEPER: u32 = 191_634;
174    ///<https://wowlab.gg/inspect/spell/1264762>
175    pub(crate) const STORMWELL: u32 = 1_264_762;
176    ///<https://wowlab.gg/inspect/spell/157299>
177    pub(crate) const STORM_ELEMENTAL: u32 = 157_299;
178    ///<https://wowlab.gg/inspect/spell/455110>
179    pub(crate) const SUPERCHARGE: u32 = 455_110;
180    ///<https://wowlab.gg/inspect/spell/381707>
181    pub(crate) const SWELLING_MAELSTROM: u32 = 381_707;
182    ///<https://wowlab.gg/inspect/spell/454009>
183    pub(crate) const TEMPEST_TALENT: u32 = 454_009;
184    ///<https://wowlab.gg/inspect/spell/462757>
185    pub(crate) const THUNDERSTRIKE_WARD: u32 = 462_757;
186    ///<https://wowlab.gg/inspect/spell/454391>
187    pub(crate) const UNLIMITED_POWER: u32 = 454_391;
188    ///<https://wowlab.gg/inspect/spell/1259101>
189    pub(crate) const VOLTAIC_BLAZE: u32 = 1_259_101;
190}
191pub(crate) mod SET_BONUS {
192    ///<https://wowlab.gg/inspect/spell/1264862>
193    pub(crate) const MID1_ELEMENTAL_2PC: u32 = 1_264_862;
194    ///<https://wowlab.gg/inspect/spell/1264863>
195    pub(crate) const MID1_ELEMENTAL_4PC: u32 = 1_264_863;
196    ///<https://wowlab.gg/inspect/spell/1236408>
197    pub(crate) const TWW3_STORMBRINGER_2PC: u32 = 1_236_408;
198    ///<https://wowlab.gg/inspect/spell/1236409>
199    pub(crate) const TWW3_STORMBRINGER_4PC: u32 = 1_236_409;
200}
201pub(crate) mod HERO {
202    pub(crate) mod STORMBRINGER {
203        pub(crate) mod SPELL {
204            ///<https://wowlab.gg/inspect/spell/452201>
205            pub(crate) const TEMPEST: u32 = 452_201;
206            ///<https://wowlab.gg/inspect/spell/463351>
207            pub(crate) const TEMPEST_OVERLOAD: u32 = 463_351;
208        }
209        pub(crate) mod AURA {
210            ///<https://wowlab.gg/inspect/spell/470532>
211            pub(crate) const ARC_DISCHARGE: u32 = 470_532;
212            ///<https://wowlab.gg/inspect/spell/455129>
213            pub(crate) const AWAKENING_STORMS: u32 = 455_129;
214            ///<https://wowlab.gg/inspect/spell/455089>
215            pub(crate) const STORM_SWELL: u32 = 455_089;
216            ///<https://wowlab.gg/inspect/spell/454015>
217            pub(crate) const TEMPEST: u32 = 454_015;
218            ///<https://wowlab.gg/inspect/spell/454394>
219            pub(crate) const UNLIMITED_POWER: u32 = 454_394;
220        }
221    }
222    pub(crate) mod FARSEER {
223        pub(crate) mod SPELL {
224            ///<https://wowlab.gg/inspect/spell/443454>
225            pub(crate) const ANCESTRAL_SWIFTNESS: u32 = 443_454;
226            ///<https://wowlab.gg/inspect/spell/447244>
227            pub(crate) const CALL_OF_THE_ANCESTORS: u32 = 447_244;
228        }
229        pub(crate) mod AURA {
230            ///<https://wowlab.gg/inspect/spell/443454>
231            pub(crate) const ANCESTRAL_SWIFTNESS: u32 = 443_454;
232            ///<https://wowlab.gg/inspect/spell/447244>
233            pub(crate) const CALL_OF_THE_ANCESTORS: u32 = 447_244;
234            ///<https://wowlab.gg/inspect/spell/443448>
235            pub(crate) const PRIMORDIAL_CAPACITY: u32 = 443_448;
236        }
237    }
238    pub(crate) mod TOTEMIC {
239        pub(crate) mod SPELL {
240            ///<https://wowlab.gg/inspect/spell/1221347>
241            pub(crate) const SURGING_TOTEM: u32 = 1_221_347;
242        }
243        pub(crate) mod AURA {
244            ///<https://wowlab.gg/inspect/spell/456369>
245            pub(crate) const AMPLIFICATION_CORE: u32 = 456_369;
246            ///<https://wowlab.gg/inspect/spell/461242>
247            pub(crate) const LIVELY_TOTEMS: u32 = 461_242;
248            ///<https://wowlab.gg/inspect/spell/1221347>
249            pub(crate) const SURGING_TOTEM: u32 = 1_221_347;
250            ///<https://wowlab.gg/inspect/spell/458269>
251            pub(crate) const TOTEMIC_REBOUND: u32 = 458_269;
252        }
253    }
254}
255static HERO_TREE_STORMBRINGER_SPELLS: &[(&str, u32)] = &[
256    ("TEMPEST", 452_201),
257    ("TEMPEST_OVERLOAD", 463_351),
258];
259static HERO_TREE_STORMBRINGER_AURAS: &[(&str, u32)] = &[
260    ("ARC_DISCHARGE", 470_532),
261    ("AWAKENING_STORMS", 455_129),
262    ("STORM_SWELL", 455_089),
263    ("TEMPEST", 454_015),
264    ("UNLIMITED_POWER", 454_394),
265];
266static HERO_TREE_FARSEER_SPELLS: &[(&str, u32)] = &[
267    ("ANCESTRAL_SWIFTNESS", 443_454),
268    ("CALL_OF_THE_ANCESTORS", 447_244),
269];
270static HERO_TREE_FARSEER_AURAS: &[(&str, u32)] = &[
271    ("ANCESTRAL_SWIFTNESS", 443_454),
272    ("CALL_OF_THE_ANCESTORS", 447_244),
273    ("PRIMORDIAL_CAPACITY", 443_448),
274];
275static HERO_TREE_TOTEMIC_SPELLS: &[(&str, u32)] = &[("SURGING_TOTEM", 1_221_347)];
276static HERO_TREE_TOTEMIC_AURAS: &[(&str, u32)] = &[
277    ("AMPLIFICATION_CORE", 456_369),
278    ("LIVELY_TOTEMS", 461_242),
279    ("SURGING_TOTEM", 1_221_347),
280    ("TOTEMIC_REBOUND", 458_269),
281];
282pub(crate) const AURA_ASCENDANCE: LocalAuraIdx = LocalAuraIdx::new(0);
283pub(crate) const AURA_STORMKEEPER: LocalAuraIdx = LocalAuraIdx::new(1);
284pub(crate) const AURA_MASTER_OF_THE_ELEMENTS: LocalAuraIdx = LocalAuraIdx::new(2);
285pub(crate) const AURA_LAVA_SURGE: LocalAuraIdx = LocalAuraIdx::new(3);
286pub(crate) const AURA_TEMPEST: LocalAuraIdx = LocalAuraIdx::new(4);
287pub(crate) const AURA_THUNDEROUS_VELOCITY: LocalAuraIdx = LocalAuraIdx::new(5);
288pub(crate) const AURA_POWER_OF_THE_MAELSTROM: LocalAuraIdx = LocalAuraIdx::new(6);
289pub(crate) const AURA_UNLIMITED_POWER: LocalAuraIdx = LocalAuraIdx::new(7);
290pub(crate) const AURA_ELEMENTAL_BLAST_CRIT: LocalAuraIdx = LocalAuraIdx::new(8);
291pub(crate) const AURA_ELEMENTAL_BLAST_HASTE: LocalAuraIdx = LocalAuraIdx::new(9);
292pub(crate) const AURA_ELEMENTAL_BLAST_MASTERY: LocalAuraIdx = LocalAuraIdx::new(10);
293pub(crate) const AURA_ANCESTRAL_SWIFTNESS: LocalAuraIdx = LocalAuraIdx::new(11);
294pub(crate) const AURA_FLAME_SHOCK: LocalAuraIdx = LocalAuraIdx::new(12);
295pub(crate) const AURA_LIGHTNING_ROD: LocalAuraIdx = LocalAuraIdx::new(13);
296pub(crate) const AURA_PURGING_FLAMES: LocalAuraIdx = LocalAuraIdx::new(14);
297pub(crate) const AURA_LIGHTNING_SHIELD: LocalAuraIdx = LocalAuraIdx::new(15);
298pub(crate) const AURA_THUNDERSTRIKE_WARD: LocalAuraIdx = LocalAuraIdx::new(16);
299pub(crate) const AURA_IMPROVED_FLAMETONGUE_WEAPON: LocalAuraIdx = LocalAuraIdx::new(17);
300pub(crate) const AURA_ECHOES_OF_GREAT_SUNDERING: LocalAuraIdx = LocalAuraIdx::new(18);
301pub(crate) const AURA_WIND_GUST: LocalAuraIdx = LocalAuraIdx::new(19);
302pub(crate) const AURA_FIRE_ELEMENTAL: LocalAuraIdx = LocalAuraIdx::new(20);
303pub(crate) const AURA_STORM_ELEMENTAL: LocalAuraIdx = LocalAuraIdx::new(21);
304pub(crate) const AURA_STORMS_EYE: LocalAuraIdx = LocalAuraIdx::new(22);
305pub(crate) const AURA_SKYFURY: LocalAuraIdx = LocalAuraIdx::new(23);
306pub(crate) const AURA_SKYFURY_HIGHLIGHT: LocalAuraIdx = LocalAuraIdx::new(24);
307pub(crate) const AURA_COUNT: usize = 25;
308const _: () = assert!(
309    AURA_COUNT == 25, "AURA index ABI: count changed -- update positional hook consumers"
310);
311pub(crate) const SPELL_LIGHTNING_BOLT: LocalSpellIdx = LocalSpellIdx::new(0);
312pub(crate) const SPELL_CHAIN_LIGHTNING: LocalSpellIdx = LocalSpellIdx::new(1);
313pub(crate) const SPELL_LAVA_BURST: LocalSpellIdx = LocalSpellIdx::new(2);
314pub(crate) const SPELL_EARTH_SHOCK: LocalSpellIdx = LocalSpellIdx::new(3);
315pub(crate) const SPELL_ELEMENTAL_BLAST: LocalSpellIdx = LocalSpellIdx::new(4);
316pub(crate) const SPELL_EARTHQUAKE: LocalSpellIdx = LocalSpellIdx::new(5);
317pub(crate) const SPELL_FLAME_SHOCK: LocalSpellIdx = LocalSpellIdx::new(6);
318pub(crate) const SPELL_FROST_SHOCK: LocalSpellIdx = LocalSpellIdx::new(7);
319pub(crate) const SPELL_TEMPEST: LocalSpellIdx = LocalSpellIdx::new(8);
320pub(crate) const SPELL_STORMKEEPER: LocalSpellIdx = LocalSpellIdx::new(9);
321pub(crate) const SPELL_ASCENDANCE: LocalSpellIdx = LocalSpellIdx::new(10);
322pub(crate) const SPELL_ANCESTRAL_SWIFTNESS: LocalSpellIdx = LocalSpellIdx::new(11);
323pub(crate) const SPELL_FLAMETONGUE_WEAPON: LocalSpellIdx = LocalSpellIdx::new(12);
324pub(crate) const SPELL_THUNDERSTRIKE_WARD: LocalSpellIdx = LocalSpellIdx::new(13);
325pub(crate) const SPELL_LIGHTNING_SHIELD: LocalSpellIdx = LocalSpellIdx::new(14);
326pub(crate) const SPELL_FIRE_ELEMENTAL: LocalSpellIdx = LocalSpellIdx::new(15);
327pub(crate) const SPELL_FIRE_BLAST: LocalSpellIdx = LocalSpellIdx::new(16);
328pub(crate) const SPELL_METEOR: LocalSpellIdx = LocalSpellIdx::new(17);
329pub(crate) const SPELL_IMMOLATE: LocalSpellIdx = LocalSpellIdx::new(18);
330pub(crate) const SPELL_WIND_GUST: LocalSpellIdx = LocalSpellIdx::new(19);
331pub(crate) const SPELL_CALL_LIGHTNING: LocalSpellIdx = LocalSpellIdx::new(20);
332pub(crate) const SPELL_STORMFURY: LocalSpellIdx = LocalSpellIdx::new(21);
333pub(crate) const SPELL_LIGHTNING_BOLT_OVERLOAD: LocalSpellIdx = LocalSpellIdx::new(22);
334pub(crate) const SPELL_CHAIN_LIGHTNING_OVERLOAD: LocalSpellIdx = LocalSpellIdx::new(23);
335pub(crate) const SPELL_LAVA_BURST_OVERLOAD: LocalSpellIdx = LocalSpellIdx::new(24);
336pub(crate) const SPELL_ELEMENTAL_BLAST_OVERLOAD: LocalSpellIdx = LocalSpellIdx::new(25);
337pub(crate) const SPELL_TEMPEST_OVERLOAD: LocalSpellIdx = LocalSpellIdx::new(26);
338pub(crate) const SPELL_STORMS_EYE: LocalSpellIdx = LocalSpellIdx::new(27);
339pub(crate) const SPELL_LIGHTNING_ROD_DAMAGE: LocalSpellIdx = LocalSpellIdx::new(28);
340pub(crate) const SPELL_SKYFURY: LocalSpellIdx = LocalSpellIdx::new(29);
341pub(crate) const SPELL_COUNT: usize = 30;
342const _: () = assert!(
343    SPELL_COUNT == 30,
344    "SPELL index ABI: count changed -- update positional hook consumers"
345);
346pub(crate) mod EFFECT {
347    ///<https://wowlab.gg/inspect/spell/157348>
348    pub(crate) const CALL_LIGHTNING_DAMAGE: (u32, u8) = (157_348, 1);
349    ///<https://wowlab.gg/inspect/spell/157348>
350    pub(crate) const CALL_LIGHTNING_DAMAGE_BONUS: (u32, u8) = (157_348, 2);
351    ///<https://wowlab.gg/inspect/spell/45297>
352    pub(crate) const CHAIN_LIGHTNING_OVERLOAD: (u32, u8) = (45297, 1);
353    ///<https://wowlab.gg/inspect/spell/117014>
354    pub(crate) const ELEMENTAL_BLAST_DAMAGE: (u32, u8) = (117_014, 1);
355    ///<https://wowlab.gg/inspect/spell/120588>
356    pub(crate) const ELEMENTAL_BLAST_OVERLOAD: (u32, u8) = (120_588, 1);
357    ///<https://wowlab.gg/inspect/spell/77478>
358    pub(crate) const EARTHQUAKE_DAMAGE: (u32, u8) = (77478, 1);
359    ///<https://wowlab.gg/inspect/spell/61882>
360    pub(crate) const EARTHQUAKE_TIMING: (u32, u8) = (61882, 2);
361    ///<https://wowlab.gg/inspect/spell/1270064>
362    pub(crate) const FEEDBACK_LOOP_BONUS: (u32, u8) = (1_270_064, 1);
363    ///<https://wowlab.gg/inspect/spell/57984>
364    pub(crate) const FIRE_BLAST_DAMAGE: (u32, u8) = (57984, 1);
365    ///<https://wowlab.gg/inspect/spell/462840>
366    pub(crate) const FUSION_OF_ELEMENTS_BONUS: (u32, u8) = (462_840, 1);
367    ///<https://wowlab.gg/inspect/spell/118297>
368    pub(crate) const IMMOLATE_DAMAGE: (u32, u8) = (118_297, 1);
369    ///<https://wowlab.gg/inspect/spell/118297>
370    pub(crate) const IMMOLATE_PERIODIC_DAMAGE: (u32, u8) = (118_297, 2);
371    ///<https://wowlab.gg/inspect/spell/285466>
372    pub(crate) const LAVA_BURST_OVERLOAD: (u32, u8) = (285_466, 1);
373    ///<https://wowlab.gg/inspect/spell/45284>
374    pub(crate) const LIGHTNING_BOLT_OVERLOAD: (u32, u8) = (45284, 1);
375    ///<https://wowlab.gg/inspect/spell/168534>
376    pub(crate) const MASTERY_DIRECT_DAMAGE: (u32, u8) = (168_534, 3);
377    ///<https://wowlab.gg/inspect/spell/168534>
378    pub(crate) const MASTERY_PERIODIC_DAMAGE: (u32, u8) = (168_534, 4);
379    ///<https://wowlab.gg/inspect/spell/168534>
380    pub(crate) const MASTERY_PET_DAMAGE: (u32, u8) = (168_534, 5);
381    ///<https://wowlab.gg/inspect/spell/117588>
382    pub(crate) const METEOR_DAMAGE: (u32, u8) = (117_588, 1);
383    ///<https://wowlab.gg/inspect/spell/1264863>
384    pub(crate) const MID1_STORMKEEPER_BONUS: (u32, u8) = (1_264_863, 2);
385    ///<https://wowlab.gg/inspect/spell/381726>
386    pub(crate) const MOUNTAINS_WILL_FALL_BONUS: (u32, u8) = (381_726, 1);
387    ///<https://wowlab.gg/inspect/spell/269005>
388    pub(crate) const STORMFURY_DAMAGE: (u32, u8) = (269_005, 1);
389    ///<https://wowlab.gg/inspect/spell/1235840>
390    pub(crate) const STORMS_EYE_DAMAGE: (u32, u8) = (1_235_840, 2);
391    ///<https://wowlab.gg/inspect/spell/463351>
392    pub(crate) const TEMPEST_OVERLOAD: (u32, u8) = (463_351, 1);
393    ///<https://wowlab.gg/inspect/spell/157331>
394    pub(crate) const WIND_GUST_DAMAGE: (u32, u8) = (157_331, 1);
395    ///<https://wowlab.gg/inspect/spell/168534>
396    pub(crate) const OVERLOAD_CHANCE: (u32, u8) = (168_534, 1);
397    ///<https://wowlab.gg/inspect/spell/168534>
398    pub(crate) const OVERLOAD_PENALTY: (u32, u8) = (168_534, 2);
399    ///<https://wowlab.gg/inspect/spell/455110>
400    pub(crate) const SUPERCHARGE_CHANCE: (u32, u8) = (455_110, 1);
401    ///<https://wowlab.gg/inspect/spell/273221>
402    pub(crate) const AFTERSHOCK_CHANCE: (u32, u8) = (273_221, 1);
403    ///<https://wowlab.gg/inspect/spell/454009>
404    pub(crate) const TEMPEST_TALENT_CHANCE: (u32, u8) = (454_009, 1);
405    ///<https://wowlab.gg/inspect/spell/455129>
406    pub(crate) const AWAKENING_STORMS_CHANCE: (u32, u8) = (455_129, 3);
407    ///<https://wowlab.gg/inspect/spell/191861>
408    pub(crate) const POWER_OF_THE_MAELSTROM_CHANCE: (u32, u8) = (191_861, 1);
409    ///<https://wowlab.gg/inspect/spell/285452>
410    pub(crate) const LAVA_BURST_DAMAGE: (u32, u8) = (285_452, 1);
411    ///<https://wowlab.gg/inspect/spell/210689>
412    pub(crate) const LIGHTNING_ROD_PERCENT: (u32, u8) = (210_689, 2);
413    ///<https://wowlab.gg/inspect/spell/157375>
414    pub(crate) const STORMFURY_RAMP: (u32, u8) = (157_375, 2);
415    ///<https://wowlab.gg/inspect/spell/191634>
416    pub(crate) const STORMKEEPER_DAMAGE: (u32, u8) = (191_634, 2);
417    ///<https://wowlab.gg/inspect/spell/191634>
418    pub(crate) const STORMKEEPER_TIER_DAMAGE: (u32, u8) = (191_634, 4);
419    ///<https://wowlab.gg/inspect/spell/462866>
420    pub(crate) const ELEMENTAL_UNITY_FIRE: (u32, u8) = (462_866, 1);
421    ///<https://wowlab.gg/inspect/spell/462866>
422    pub(crate) const ELEMENTAL_UNITY_STORM: (u32, u8) = (462_866, 3);
423    ///<https://wowlab.gg/inspect/spell/188592>
424    pub(crate) const FIRE_ELEMENTAL_UNITY: (u32, u8) = (188_592, 4);
425    ///<https://wowlab.gg/inspect/spell/188592>
426    pub(crate) const FIRE_ELEMENTAL_UNITY_PERIODIC: (u32, u8) = (188_592, 5);
427    ///<https://wowlab.gg/inspect/spell/157299>
428    pub(crate) const STORM_ELEMENTAL_UNITY: (u32, u8) = (157_299, 3);
429    ///<https://wowlab.gg/inspect/spell/157299>
430    pub(crate) const STORM_ELEMENTAL_UNITY_PET: (u32, u8) = (157_299, 4);
431    ///<https://wowlab.gg/inspect/spell/462862>
432    pub(crate) const LIGHTNING_CAPACITOR_DAMAGE: (u32, u8) = (462_862, 3);
433    ///<https://wowlab.gg/inspect/spell/382028>
434    pub(crate) const IMPROVED_FLAMETONGUE_DAMAGE: (u32, u8) = (382_028, 1);
435    ///<https://wowlab.gg/inspect/spell/1264762>
436    pub(crate) const STORMWELL_SK_MAELSTROM: (u32, u8) = (1_264_762, 2);
437}
438static REPORTED_SPELLS: &[(&str, u32)] = &[];
439static DECLARED_SPELL_IDS: &[u32] = &[
440    188_196, 188_443, 51505, 8042, 117_014, 61882, 188_389, 196_840, 452_201, 191_634,
441    1_219_480, 443_454, 318_038, 462_757, 192_106, 188_592, 57984, 117_588, 118_297,
442    157_331, 157_348, 269_005, 45284, 45297, 285_466, 120_588, 463_351, 1_235_840,
443    197_568, 462_854, 1_219_480, 191_634, 260_734, 77762, 454_015, 1_272_101, 191_877,
444    454_394, 118_522, 173_183, 173_184, 443_454, 188_389, 210_689, 1_259_491, 192_106,
445    462_757, 382_027, 384_088, 263_806, 188_592, 157_299, 1_239_315, 462_854, 462_854,
446    16166, 45284, 45297, 57984, 61882, 77478, 117_014, 117_588, 118_297, 120_588,
447    157_299, 157_331, 157_348, 157_375, 168_534, 188_592, 191_634, 191_861, 192_106,
448    210_689, 269_005, 273_221, 285_452, 285_466, 381_726, 382_028, 454_009, 455_110,
449    455_129, 462_840, 462_862, 462_866, 463_351, 1_219_480, 1_235_840, 1_264_762,
450    1_264_863, 1_270_064, 452_201, 463_351, 470_532, 455_129, 455_089, 454_015, 454_394,
451    443_454, 447_244, 443_454, 447_244, 443_448, 1_221_347, 456_369, 461_242, 1_221_347,
452    458_269,
453];
454static DECLARED_AURA_IDS: &[u32] = &[
455    1_219_480, 191_634, 260_734, 77762, 454_015, 1_272_101, 191_877, 454_394, 118_522,
456    173_183, 173_184, 443_454, 188_389, 210_689, 1_259_491, 192_106, 462_757, 382_027,
457    384_088, 263_806, 188_592, 157_299, 1_239_315, 462_854, 462_854, 470_532, 455_129,
458    455_089, 454_015, 454_394, 443_454, 447_244, 443_448, 456_369, 461_242, 1_221_347,
459    458_269,
460];
461static TALENTS: &[(&str, u32)] = &[
462    ("AFTERSHOCK", TALENT::AFTERSHOCK),
463    ("ANCESTRAL_SWIFTNESS", TALENT::ANCESTRAL_SWIFTNESS),
464    ("ARC_DISCHARGE", TALENT::ARC_DISCHARGE),
465    ("ASCENDANCE", TALENT::ASCENDANCE),
466    ("AWAKENING_STORMS", TALENT::AWAKENING_STORMS),
467    ("CALL_OF_FIRE", TALENT::CALL_OF_FIRE),
468    ("ELEMENTAL_BLAST", TALENT::ELEMENTAL_BLAST),
469    ("ELEMENTAL_UNITY", TALENT::ELEMENTAL_UNITY),
470    ("FEEDBACK_LOOP_3", TALENT::FEEDBACK_LOOP_3),
471    ("FIRE_ELEMENTAL", TALENT::FIRE_ELEMENTAL),
472    ("FLAMETONGUE_WEAPON", TALENT::FLAMETONGUE_WEAPON),
473    ("FURY_OF_THE_STORMS", TALENT::FURY_OF_THE_STORMS),
474    ("FUSION_OF_ELEMENTS", TALENT::FUSION_OF_ELEMENTS),
475    ("INFERNO_ARC", TALENT::INFERNO_ARC),
476    ("LIGHTNING_CAPACITOR", TALENT::LIGHTNING_CAPACITOR),
477    ("LIGHTNING_ROD", TALENT::LIGHTNING_ROD),
478    ("MASTER_OF_THE_ELEMENTS", TALENT::MASTER_OF_THE_ELEMENTS),
479    ("MOUNTAINS_WILL_FALL", TALENT::MOUNTAINS_WILL_FALL),
480    ("POWER_OF_THE_MAELSTROM", TALENT::POWER_OF_THE_MAELSTROM),
481    ("PRIMAL_ELEMENTALIST", TALENT::PRIMAL_ELEMENTALIST),
482    ("PRIMORDIAL_CAPACITY", TALENT::PRIMORDIAL_CAPACITY),
483    ("SEARING_FLAMES", TALENT::SEARING_FLAMES),
484    ("STORMKEEPER", TALENT::STORMKEEPER),
485    ("STORMWELL", TALENT::STORMWELL),
486    ("STORM_ELEMENTAL", TALENT::STORM_ELEMENTAL),
487    ("SUPERCHARGE", TALENT::SUPERCHARGE),
488    ("SWELLING_MAELSTROM", TALENT::SWELLING_MAELSTROM),
489    ("TEMPEST_TALENT", TALENT::TEMPEST_TALENT),
490    ("THUNDERSTRIKE_WARD", TALENT::THUNDERSTRIKE_WARD),
491    ("UNLIMITED_POWER", TALENT::UNLIMITED_POWER),
492    ("VOLTAIC_BLAZE", TALENT::VOLTAIC_BLAZE),
493];
494pub(crate) mod ELEMENTAL_SHAMAN {
495    pub(crate) const LIGHTNING_BOLT_CASTS: u32 = 0;
496    pub(crate) const LAVA_BURST_CASTS: u32 = 1;
497    pub(crate) const EARTH_SHOCK_CASTS: u32 = 2;
498    pub(crate) const ELEMENTAL_BLAST_CASTS: u32 = 3;
499    pub(crate) const STORMKEEPER_CASTS: u32 = 4;
500    pub(crate) const ASCENDANCE_CASTS: u32 = 5;
501    pub(crate) const FLAME_SHOCK_UPTIME_MS: u32 = 6;
502    pub(crate) const TEMPEST_CASTS: u32 = 7;
503}
504fn aura_ascendance(
505    a: AuraDefinitionDraft,
506    data: &ResolvedGameData,
507) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
508    a.on_player()
509        .apply_base_from_data(data, 1_219_480)?
510        .max_stacks(
511            data
512                .require_aura_max_stacks(
513                    wowlab_types::sim::SpellIdx::from_raw(1_219_480),
514                )?,
515        )
516        .damage_percent_spells(
517            data.base_points(wowlab_types::sim::SpellIdx::from_raw(1_219_480), 8),
518            &[45284, 45297, 285_466, 120_588, 463_351],
519        )
520}
521fn aura_stormkeeper(
522    a: AuraDefinitionDraft,
523    data: &ResolvedGameData,
524) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
525    Ok(
526        a
527            .on_player()
528            .apply_base_from_data(data, 191_634)?
529            .max_stacks(
530                wowlab_engine_combat::validated_max_stacks(
531                    1.0,
532                    191_634,
533                    "aura.max_stacks",
534                )?,
535            ),
536    )
537}
538fn aura_master_of_the_elements(
539    a: AuraDefinitionDraft,
540    data: &ResolvedGameData,
541) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
542    a.on_player()
543        .apply_base_from_data(data, 260_734)?
544        .max_stacks(
545            data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(260_734))?,
546        )
547        .damage_multiplier(
548            ((data.base_points(wowlab_types::sim::SpellIdx::from_raw(16166), 2)) * 0.01)
549                + 1.0,
550        )
551}
552fn aura_lava_surge(
553    a: AuraDefinitionDraft,
554    data: &ResolvedGameData,
555) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
556    Ok(
557        a
558            .on_player()
559            .apply_base_from_data(data, 77762)?
560            .max_stacks(
561                data
562                    .require_aura_max_stacks(
563                        wowlab_types::sim::SpellIdx::from_raw(77762),
564                    )?,
565            ),
566    )
567}
568fn aura_tempest(
569    a: AuraDefinitionDraft,
570    data: &ResolvedGameData,
571) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
572    Ok(
573        a
574            .on_player()
575            .apply_base_from_data(data, 454_015)?
576            .max_stacks(
577                data
578                    .require_aura_max_stacks(
579                        wowlab_types::sim::SpellIdx::from_raw(454_015),
580                    )?,
581            ),
582    )
583}
584fn aura_thunderous_velocity(
585    a: AuraDefinitionDraft,
586    data: &ResolvedGameData,
587) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
588    Ok(
589        a
590            .on_player()
591            .apply_base_from_data(data, 1_272_101)?
592            .max_stacks(
593                data
594                    .require_aura_max_stacks(
595                        wowlab_types::sim::SpellIdx::from_raw(1_272_101),
596                    )?,
597            ),
598    )
599}
600fn aura_power_of_the_maelstrom(
601    a: AuraDefinitionDraft,
602    data: &ResolvedGameData,
603) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
604    Ok(
605        a
606            .on_player()
607            .apply_base_from_data(data, 191_877)?
608            .max_stacks(
609                data
610                    .require_aura_max_stacks(
611                        wowlab_types::sim::SpellIdx::from_raw(191_877),
612                    )?,
613            ),
614    )
615}
616fn aura_unlimited_power(
617    a: AuraDefinitionDraft,
618    data: &ResolvedGameData,
619) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
620    Ok(
621        a
622            .on_player()
623            .apply_base_from_data(data, 454_394)?
624            .max_stacks(
625                data
626                    .require_aura_max_stacks(
627                        wowlab_types::sim::SpellIdx::from_raw(454_394),
628                    )?,
629            ),
630    )
631}
632fn aura_elemental_blast_crit(
633    a: AuraDefinitionDraft,
634    data: &ResolvedGameData,
635) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
636    Ok(
637        a
638            .on_player()
639            .apply_base_from_data(data, 118_522)?
640            .max_stacks(
641                data
642                    .require_aura_max_stacks(
643                        wowlab_types::sim::SpellIdx::from_raw(118_522),
644                    )?,
645            ),
646    )
647}
648fn aura_elemental_blast_haste(
649    a: AuraDefinitionDraft,
650    data: &ResolvedGameData,
651) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
652    Ok(
653        a
654            .on_player()
655            .apply_base_from_data(data, 173_183)?
656            .max_stacks(
657                data
658                    .require_aura_max_stacks(
659                        wowlab_types::sim::SpellIdx::from_raw(173_183),
660                    )?,
661            ),
662    )
663}
664fn aura_elemental_blast_mastery(
665    a: AuraDefinitionDraft,
666    data: &ResolvedGameData,
667) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
668    Ok(
669        a
670            .on_player()
671            .apply_base_from_data(data, 173_184)?
672            .max_stacks(
673                data
674                    .require_aura_max_stacks(
675                        wowlab_types::sim::SpellIdx::from_raw(173_184),
676                    )?,
677            ),
678    )
679}
680fn aura_ancestral_swiftness(
681    a: AuraDefinitionDraft,
682    data: &ResolvedGameData,
683) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
684    Ok(
685        a
686            .on_player()
687            .apply_base_from_data(data, 443_454)?
688            .max_stacks(
689                data
690                    .require_aura_max_stacks(
691                        wowlab_types::sim::SpellIdx::from_raw(443_454),
692                    )?,
693            ),
694    )
695}
696fn aura_flame_shock(
697    a: AuraDefinitionDraft,
698    data: &ResolvedGameData,
699) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
700    a.on_target()
701        .apply_base_from_data(data, 188_389)?
702        .max_stacks(
703            data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(188_389))?,
704        )
705        .crit_chance_spells(100.0, &[51505, 285_466])
706}
707fn aura_lightning_rod(
708    a: AuraDefinitionDraft,
709    data: &ResolvedGameData,
710) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
711    Ok(
712        a
713            .on_target()
714            .apply_base_from_data(data, 210_689)?
715            .max_stacks(
716                data
717                    .require_aura_max_stacks(
718                        wowlab_types::sim::SpellIdx::from_raw(210_689),
719                    )?,
720            ),
721    )
722}
723fn aura_purging_flames(
724    a: AuraDefinitionDraft,
725    data: &ResolvedGameData,
726) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
727    Ok(
728        a
729            .on_player()
730            .apply_base_from_data(data, 1_259_491)?
731            .max_stacks(
732                data
733                    .require_aura_max_stacks(
734                        wowlab_types::sim::SpellIdx::from_raw(1_259_491),
735                    )?,
736            ),
737    )
738}
739fn aura_lightning_shield(
740    a: AuraDefinitionDraft,
741    data: &ResolvedGameData,
742) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
743    a.on_player()
744        .apply_base_from_data(data, 192_106)?
745        .max_stacks(
746            data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(192_106))?,
747        )
748        .primary_pct_per_stack(
749            data.base_points(wowlab_types::sim::SpellIdx::from_raw(192_106), 4),
750        )
751}
752fn aura_thunderstrike_ward(
753    a: AuraDefinitionDraft,
754    data: &ResolvedGameData,
755) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
756    Ok(
757        a
758            .on_player()
759            .apply_base_from_data(data, 462_757)?
760            .max_stacks(
761                data
762                    .require_aura_max_stacks(
763                        wowlab_types::sim::SpellIdx::from_raw(462_757),
764                    )?,
765            ),
766    )
767}
768fn aura_improved_flametongue_weapon(
769    a: AuraDefinitionDraft,
770    data: &ResolvedGameData,
771) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
772    Ok(
773        a
774            .on_player()
775            .apply_base_from_data(data, 382_027)?
776            .max_stacks(
777                data
778                    .require_aura_max_stacks(
779                        wowlab_types::sim::SpellIdx::from_raw(382_027),
780                    )?,
781            ),
782    )
783}
784fn aura_echoes_of_great_sundering(
785    a: AuraDefinitionDraft,
786    data: &ResolvedGameData,
787) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
788    Ok(
789        a
790            .on_player()
791            .apply_base_from_data(data, 384_088)?
792            .max_stacks(
793                data
794                    .require_aura_max_stacks(
795                        wowlab_types::sim::SpellIdx::from_raw(384_088),
796                    )?,
797            ),
798    )
799}
800fn aura_wind_gust(
801    a: AuraDefinitionDraft,
802    data: &ResolvedGameData,
803) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
804    Ok(
805        a
806            .on_player()
807            .apply_base_from_data(data, 263_806)?
808            .max_stacks(
809                data
810                    .require_aura_max_stacks(
811                        wowlab_types::sim::SpellIdx::from_raw(263_806),
812                    )?,
813            ),
814    )
815}
816fn aura_fire_elemental(
817    a: AuraDefinitionDraft,
818    data: &ResolvedGameData,
819) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
820    Ok(
821        a
822            .on_player()
823            .apply_base_from_data(data, 188_592)?
824            .max_stacks(
825                data
826                    .require_aura_max_stacks(
827                        wowlab_types::sim::SpellIdx::from_raw(188_592),
828                    )?,
829            ),
830    )
831}
832fn aura_storm_elemental(
833    a: AuraDefinitionDraft,
834    data: &ResolvedGameData,
835) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
836    a.on_player()
837        .duration_ms(
838            wowlab_engine_combat::validated_milliseconds(
839                (((f64::from(
840                    data
841                        .require_aura_duration_ms(
842                            wowlab_types::sim::SpellIdx::from_raw(157_299),
843                        )?,
844                )) * 1.028_571_428_571_428_5) * 1.0)
845                    .round() / 1.0,
846                157_299,
847                "aura.duration_ms",
848            )?,
849        )
850        .apply_periodic_effect_from_data(data, 157_299)?
851        .apply_duration_behavior_from_data(data, 157_299)?
852        .apply_timing_modifiers_from_data(data, 157_299)?
853        .max_stacks(
854            data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(157_299))?,
855        )
856        .apply_periodic_behavior_from_data(data, 157_299)
857}
858fn aura_storms_eye(
859    a: AuraDefinitionDraft,
860    data: &ResolvedGameData,
861) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
862    Ok(
863        a
864            .on_player()
865            .apply_base_from_data(data, 1_239_315)?
866            .max_stacks(
867                data
868                    .require_aura_max_stacks(
869                        wowlab_types::sim::SpellIdx::from_raw(1_239_315),
870                    )?,
871            ),
872    )
873}
874fn aura_skyfury(
875    a: AuraDefinitionDraft,
876    data: &ResolvedGameData,
877) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
878    Ok(
879        a
880            .on_player()
881            .apply_base_from_data(data, 462_854)?
882            .max_stacks(
883                data
884                    .require_aura_max_stacks(
885                        wowlab_types::sim::SpellIdx::from_raw(462_854),
886                    )?,
887            ),
888    )
889}
890fn aura_skyfury_highlight(
891    a: AuraDefinitionDraft,
892    data: &ResolvedGameData,
893) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
894    Ok(
895        a
896            .on_player()
897            .apply_base_from_data(data, 462_854)?
898            .max_stacks(
899                data
900                    .require_aura_max_stacks(
901                        wowlab_types::sim::SpellIdx::from_raw(462_854),
902                    )?,
903            ),
904    )
905}
906fn spell_lightning_bolt(
907    s: SpellDefinitionDraft,
908    data: &ResolvedGameData,
909) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
910    Ok(
911        s
912            .apply_base_from_data(data, 188_196)?
913            .gain(6.0)
914            .apply_aoe_from_data(data)
915            .on_cast(crate::hooks::elemental_shaman::lightning_bolt_hook),
916    )
917}
918fn spell_chain_lightning(
919    s: SpellDefinitionDraft,
920    data: &ResolvedGameData,
921) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
922    Ok(
923        s
924            .apply_base_from_data(data, 188_443)?
925            .gain(2.0)
926            .apply_aoe_from_data(data)
927            .on_cast(crate::hooks::elemental_shaman::chain_lightning_hook),
928    )
929}
930fn spell_lava_burst(
931    s: SpellDefinitionDraft,
932    data: &ResolvedGameData,
933) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
934    Ok(
935        s
936            .apply_base_from_data(data, 51505)?
937            .apply_aoe_from_data(data)
938            .on_cast(crate::hooks::elemental_shaman::lava_burst_hook),
939    )
940}
941fn spell_earth_shock(
942    s: SpellDefinitionDraft,
943    data: &ResolvedGameData,
944) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
945    Ok(s.apply_base_from_data(data, 8042)?.apply_aoe_from_data(data))
946}
947fn spell_elemental_blast(
948    s: SpellDefinitionDraft,
949    data: &ResolvedGameData,
950) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
951    Ok(
952        s
953            .apply_base_from_data(data, 117_014)?
954            .apply_aoe_from_data(data)
955            .on_cast(crate::hooks::elemental_shaman::elemental_blast_hook)
956            .cost_free_when_aura(443_454),
957    )
958}
959fn spell_earthquake(
960    s: SpellDefinitionDraft,
961    data: &ResolvedGameData,
962) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
963    Ok(
964        s
965            .apply_base_from_data(data, 61882)?
966            .apply_aoe_from_data(data)
967            .on_cast(crate::hooks::elemental_shaman::earthquake_hook),
968    )
969}
970fn spell_flame_shock(
971    s: SpellDefinitionDraft,
972    data: &ResolvedGameData,
973) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
974    Ok(
975        s
976            .apply_base_from_data(data, 188_389)?
977            .gain(3.0)
978            .applies_inferred_aura(AURA_FLAME_SHOCK, 188_389)
979            .apply_aoe_from_data(data),
980    )
981}
982fn spell_frost_shock(
983    s: SpellDefinitionDraft,
984    data: &ResolvedGameData,
985) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
986    Ok(s.apply_base_from_data(data, 196_840)?.apply_aoe_from_data(data))
987}
988fn spell_tempest(
989    s: SpellDefinitionDraft,
990    data: &ResolvedGameData,
991) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
992    Ok(
993        s
994            .apply_base_from_data(data, 452_201)?
995            .apply_aoe_from_data(data)
996            .on_cast(crate::hooks::elemental_shaman::tempest_hook),
997    )
998}
999fn spell_stormkeeper(
1000    s: SpellDefinitionDraft,
1001    data: &ResolvedGameData,
1002) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1003    Ok(
1004        s
1005            .apply_base_from_data(data, 191_634)?
1006            .cast_time(
1007                wowlab_engine_combat::validated_milliseconds(
1008                    0.0,
1009                    191_634,
1010                    "spell.cast_time_ms",
1011                )?,
1012            )
1013            .gain(10.0)
1014            .applies_inferred_aura(AURA_STORMKEEPER, 191_634)
1015            .apply_aoe_from_data(data)
1016            .on_cast(crate::hooks::elemental_shaman::stormkeeper_hook),
1017    )
1018}
1019fn spell_ascendance(
1020    s: SpellDefinitionDraft,
1021    data: &ResolvedGameData,
1022) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1023    Ok(
1024        s
1025            .apply_base_from_data(data, 1_219_480)?
1026            .applies_inferred_aura(AURA_ASCENDANCE, 1_219_480)
1027            .apply_aoe_from_data(data)
1028            .on_cast(crate::hooks::elemental_shaman::ascendance_hook),
1029    )
1030}
1031fn spell_ancestral_swiftness(
1032    s: SpellDefinitionDraft,
1033    data: &ResolvedGameData,
1034) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1035    Ok(
1036        s
1037            .apply_base_from_data(data, 443_454)?
1038            .applies_inferred_aura(AURA_ANCESTRAL_SWIFTNESS, 443_454)
1039            .apply_aoe_from_data(data),
1040    )
1041}
1042fn spell_flametongue_weapon(
1043    s: SpellDefinitionDraft,
1044    data: &ResolvedGameData,
1045) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1046    Ok(s.apply_base_from_data(data, 318_038)?.apply_aoe_from_data(data))
1047}
1048fn spell_thunderstrike_ward(
1049    s: SpellDefinitionDraft,
1050    data: &ResolvedGameData,
1051) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1052    Ok(
1053        s
1054            .apply_base_from_data(data, 462_757)?
1055            .applies_inferred_aura(AURA_THUNDERSTRIKE_WARD, 462_757)
1056            .apply_aoe_from_data(data),
1057    )
1058}
1059fn spell_lightning_shield(
1060    s: SpellDefinitionDraft,
1061    data: &ResolvedGameData,
1062) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1063    Ok(
1064        s
1065            .apply_base_from_data(data, 192_106)?
1066            .applies_inferred_aura(AURA_LIGHTNING_SHIELD, 192_106)
1067            .apply_aoe_from_data(data),
1068    )
1069}
1070fn spell_fire_elemental(
1071    s: SpellDefinitionDraft,
1072    data: &ResolvedGameData,
1073) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1074    Ok(
1075        s
1076            .apply_base_from_data(data, 188_592)?
1077            .applies_inferred_aura(AURA_FIRE_ELEMENTAL, 188_592)
1078            .apply_aoe_from_data(data),
1079    )
1080}
1081fn spell_fire_blast(
1082    s: SpellDefinitionDraft,
1083    data: &ResolvedGameData,
1084) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1085    Ok(s.apply_base_from_data(data, 57984)?.apply_aoe_from_data(data))
1086}
1087fn spell_meteor(
1088    s: SpellDefinitionDraft,
1089    data: &ResolvedGameData,
1090) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1091    Ok(s.apply_base_from_data(data, 117_588)?.apply_aoe_from_data(data))
1092}
1093fn spell_immolate(
1094    s: SpellDefinitionDraft,
1095    data: &ResolvedGameData,
1096) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1097    Ok(s.apply_base_from_data(data, 118_297)?.apply_aoe_from_data(data))
1098}
1099fn spell_wind_gust(
1100    s: SpellDefinitionDraft,
1101    data: &ResolvedGameData,
1102) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1103    Ok(s.apply_base_from_data(data, 157_331)?.apply_aoe_from_data(data))
1104}
1105fn spell_call_lightning(
1106    s: SpellDefinitionDraft,
1107    data: &ResolvedGameData,
1108) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1109    Ok(s.apply_base_from_data(data, 157_348)?.apply_aoe_from_data(data))
1110}
1111fn spell_stormfury(
1112    s: SpellDefinitionDraft,
1113    data: &ResolvedGameData,
1114) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1115    Ok(s.apply_base_from_data(data, 269_005)?.apply_aoe_from_data(data))
1116}
1117fn spell_lightning_bolt_overload(
1118    s: SpellDefinitionDraft,
1119    data: &ResolvedGameData,
1120) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1121    Ok(s.apply_base_from_data(data, 45284)?.apply_aoe_from_data(data))
1122}
1123fn spell_chain_lightning_overload(
1124    s: SpellDefinitionDraft,
1125    data: &ResolvedGameData,
1126) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1127    Ok(s.apply_base_from_data(data, 45297)?.apply_aoe_from_data(data))
1128}
1129fn spell_lava_burst_overload(
1130    s: SpellDefinitionDraft,
1131    data: &ResolvedGameData,
1132) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1133    Ok(s.apply_base_from_data(data, 285_466)?.apply_aoe_from_data(data))
1134}
1135fn spell_elemental_blast_overload(
1136    s: SpellDefinitionDraft,
1137    data: &ResolvedGameData,
1138) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1139    Ok(s.apply_base_from_data(data, 120_588)?.apply_aoe_from_data(data))
1140}
1141fn spell_tempest_overload(
1142    s: SpellDefinitionDraft,
1143    data: &ResolvedGameData,
1144) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1145    Ok(s.apply_base_from_data(data, 463_351)?.apply_aoe_from_data(data))
1146}
1147fn spell_storms_eye(
1148    s: SpellDefinitionDraft,
1149    data: &ResolvedGameData,
1150) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1151    Ok(
1152        s
1153            .apply_base_from_data(data, 1_235_840)?
1154            .applies_inferred_aura(AURA_STORMS_EYE, 1_239_315)
1155            .apply_aoe_from_data(data),
1156    )
1157}
1158fn spell_lightning_rod_damage(
1159    s: SpellDefinitionDraft,
1160    data: &ResolvedGameData,
1161) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1162    Ok(s.apply_base_from_data(data, 197_568)?.apply_aoe_from_data(data))
1163}
1164fn spell_skyfury(
1165    s: SpellDefinitionDraft,
1166    data: &ResolvedGameData,
1167) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1168    Ok(
1169        s
1170            .apply_base_from_data(data, 462_854)?
1171            .applies_inferred_aura(AURA_SKYFURY, 462_854)
1172            .apply_aoe_from_data(data),
1173    )
1174}
1175pub(crate) fn build_combat_system(
1176    params: &wowlab_engine_ports::HandlerParams<'_>,
1177) -> Result<BuiltCombatSystem, wowlab_engine_ports::EngineError> {
1178    let builder = BuiltCombatSystem::builder(params.stats.clone())
1179        .spec_id(SpecId::Elemental)
1180        .hero_talent_trees(DECLARED_METADATA.hero_talent_trees)
1181        .mastery_spell(168_534)
1182        .mastery_hook(crate::hooks::elemental_shaman::mastery)
1183        .resource(
1184            "maelstrom",
1185            params
1186                .game_data
1187                .power_max(11)
1188                .ok_or_else(|| {
1189                    wowlab_engine_ports::EngineError::spec_construction(
1190                        "missing power-type power_max for type_id 11",
1191                    )
1192                })?,
1193            params
1194                .game_data
1195                .power_regen_for_max(
1196                    11,
1197                    params
1198                        .game_data
1199                        .power_max(11)
1200                        .ok_or_else(|| {
1201                            wowlab_engine_ports::EngineError::spec_construction(
1202                                "missing power-type power_max for type_id 11",
1203                            )
1204                        })?,
1205                )
1206                .ok_or_else(|| {
1207                    wowlab_engine_ports::EngineError::spec_construction(
1208                        "missing power-type power_regen_for_max for type_id 11",
1209                    )
1210                })?,
1211        )
1212        .resource_type_id(11)
1213        .resource_start(
1214            params
1215                .game_data
1216                .power_default(11)
1217                .ok_or_else(|| {
1218                    wowlab_engine_ports::EngineError::spec_construction(
1219                        "missing power-type power_default for type_id 11",
1220                    )
1221                })?,
1222        )
1223        .aura("ascendance", AURA::ASCENDANCE, |a| aura_ascendance(a, &params.game_data))
1224        .aura(
1225            "stormkeeper",
1226            AURA::STORMKEEPER,
1227            |a| aura_stormkeeper(a, &params.game_data),
1228        )
1229        .aura(
1230            "master_of_the_elements",
1231            AURA::MASTER_OF_THE_ELEMENTS,
1232            |a| aura_master_of_the_elements(a, &params.game_data),
1233        )
1234        .aura("lava_surge", AURA::LAVA_SURGE, |a| aura_lava_surge(a, &params.game_data))
1235        .aura("tempest", AURA::TEMPEST, |a| aura_tempest(a, &params.game_data))
1236        .aura(
1237            "thunderous_velocity",
1238            AURA::THUNDEROUS_VELOCITY,
1239            |a| aura_thunderous_velocity(a, &params.game_data),
1240        )
1241        .aura(
1242            "power_of_the_maelstrom",
1243            AURA::POWER_OF_THE_MAELSTROM,
1244            |a| aura_power_of_the_maelstrom(a, &params.game_data),
1245        )
1246        .aura(
1247            "unlimited_power",
1248            AURA::UNLIMITED_POWER,
1249            |a| aura_unlimited_power(a, &params.game_data),
1250        )
1251        .aura(
1252            "elemental_blast_crit",
1253            AURA::ELEMENTAL_BLAST_CRIT,
1254            |a| aura_elemental_blast_crit(a, &params.game_data),
1255        )
1256        .aura(
1257            "elemental_blast_haste",
1258            AURA::ELEMENTAL_BLAST_HASTE,
1259            |a| aura_elemental_blast_haste(a, &params.game_data),
1260        )
1261        .aura(
1262            "elemental_blast_mastery",
1263            AURA::ELEMENTAL_BLAST_MASTERY,
1264            |a| aura_elemental_blast_mastery(a, &params.game_data),
1265        )
1266        .aura(
1267            "ancestral_swiftness",
1268            AURA::ANCESTRAL_SWIFTNESS,
1269            |a| aura_ancestral_swiftness(a, &params.game_data),
1270        )
1271        .aura(
1272            "flame_shock",
1273            AURA::FLAME_SHOCK,
1274            |a| aura_flame_shock(a, &params.game_data),
1275        )
1276        .aura(
1277            "lightning_rod",
1278            AURA::LIGHTNING_ROD,
1279            |a| aura_lightning_rod(a, &params.game_data),
1280        )
1281        .aura(
1282            "purging_flames",
1283            AURA::PURGING_FLAMES,
1284            |a| aura_purging_flames(a, &params.game_data),
1285        )
1286        .aura(
1287            "lightning_shield",
1288            AURA::LIGHTNING_SHIELD,
1289            |a| aura_lightning_shield(a, &params.game_data),
1290        )
1291        .aura(
1292            "thunderstrike_ward",
1293            AURA::THUNDERSTRIKE_WARD,
1294            |a| aura_thunderstrike_ward(a, &params.game_data),
1295        )
1296        .aura(
1297            "improved_flametongue_weapon",
1298            AURA::IMPROVED_FLAMETONGUE_WEAPON,
1299            |a| aura_improved_flametongue_weapon(a, &params.game_data),
1300        )
1301        .aura(
1302            "echoes_of_great_sundering",
1303            AURA::ECHOES_OF_GREAT_SUNDERING,
1304            |a| aura_echoes_of_great_sundering(a, &params.game_data),
1305        )
1306        .aura("wind_gust", AURA::WIND_GUST, |a| aura_wind_gust(a, &params.game_data))
1307        .aura(
1308            "fire_elemental",
1309            AURA::FIRE_ELEMENTAL,
1310            |a| aura_fire_elemental(a, &params.game_data),
1311        )
1312        .aura(
1313            "storm_elemental",
1314            AURA::STORM_ELEMENTAL,
1315            |a| aura_storm_elemental(a, &params.game_data),
1316        )
1317        .aura("storms_eye", AURA::STORMS_EYE, |a| aura_storms_eye(a, &params.game_data))
1318        .aura("skyfury", AURA::SKYFURY, |a| aura_skyfury(a, &params.game_data))
1319        .aura(
1320            "skyfury_highlight",
1321            AURA::SKYFURY_HIGHLIGHT,
1322            |a| aura_skyfury_highlight(a, &params.game_data),
1323        )
1324        .spell(
1325            "lightning_bolt",
1326            SPELL::LIGHTNING_BOLT,
1327            |s| spell_lightning_bolt(s, &params.game_data),
1328        )
1329        .spell(
1330            "chain_lightning",
1331            SPELL::CHAIN_LIGHTNING,
1332            |s| spell_chain_lightning(s, &params.game_data),
1333        )
1334        .spell(
1335            "lava_burst",
1336            SPELL::LAVA_BURST,
1337            |s| spell_lava_burst(s, &params.game_data),
1338        )
1339        .spell(
1340            "earth_shock",
1341            SPELL::EARTH_SHOCK,
1342            |s| spell_earth_shock(s, &params.game_data),
1343        )
1344        .spell(
1345            "elemental_blast",
1346            SPELL::ELEMENTAL_BLAST,
1347            |s| spell_elemental_blast(s, &params.game_data),
1348        )
1349        .spell(
1350            "earthquake",
1351            SPELL::EARTHQUAKE,
1352            |s| spell_earthquake(s, &params.game_data),
1353        )
1354        .spell(
1355            "flame_shock",
1356            SPELL::FLAME_SHOCK,
1357            |s| spell_flame_shock(s, &params.game_data),
1358        )
1359        .spell(
1360            "frost_shock",
1361            SPELL::FROST_SHOCK,
1362            |s| spell_frost_shock(s, &params.game_data),
1363        )
1364        .spell("tempest", SPELL::TEMPEST, |s| spell_tempest(s, &params.game_data))
1365        .spell(
1366            "stormkeeper",
1367            SPELL::STORMKEEPER,
1368            |s| spell_stormkeeper(s, &params.game_data),
1369        )
1370        .spell(
1371            "ascendance",
1372            SPELL::ASCENDANCE,
1373            |s| spell_ascendance(s, &params.game_data),
1374        )
1375        .spell(
1376            "ancestral_swiftness",
1377            SPELL::ANCESTRAL_SWIFTNESS,
1378            |s| spell_ancestral_swiftness(s, &params.game_data),
1379        )
1380        .spell(
1381            "flametongue_weapon",
1382            SPELL::FLAMETONGUE_WEAPON,
1383            |s| spell_flametongue_weapon(s, &params.game_data),
1384        )
1385        .spell(
1386            "thunderstrike_ward",
1387            SPELL::THUNDERSTRIKE_WARD,
1388            |s| spell_thunderstrike_ward(s, &params.game_data),
1389        )
1390        .spell(
1391            "lightning_shield",
1392            SPELL::LIGHTNING_SHIELD,
1393            |s| spell_lightning_shield(s, &params.game_data),
1394        )
1395        .spell(
1396            "fire_elemental",
1397            SPELL::FIRE_ELEMENTAL,
1398            |s| spell_fire_elemental(s, &params.game_data),
1399        )
1400        .spell(
1401            "fire_blast",
1402            SPELL::FIRE_BLAST,
1403            |s| spell_fire_blast(s, &params.game_data),
1404        )
1405        .spell("meteor", SPELL::METEOR, |s| spell_meteor(s, &params.game_data))
1406        .spell("immolate", SPELL::IMMOLATE, |s| spell_immolate(s, &params.game_data))
1407        .spell("wind_gust", SPELL::WIND_GUST, |s| spell_wind_gust(s, &params.game_data))
1408        .spell(
1409            "call_lightning",
1410            SPELL::CALL_LIGHTNING,
1411            |s| spell_call_lightning(s, &params.game_data),
1412        )
1413        .spell("stormfury", SPELL::STORMFURY, |s| spell_stormfury(s, &params.game_data))
1414        .spell(
1415            "lightning_bolt_overload",
1416            SPELL::LIGHTNING_BOLT_OVERLOAD,
1417            |s| spell_lightning_bolt_overload(s, &params.game_data),
1418        )
1419        .spell(
1420            "chain_lightning_overload",
1421            SPELL::CHAIN_LIGHTNING_OVERLOAD,
1422            |s| spell_chain_lightning_overload(s, &params.game_data),
1423        )
1424        .spell(
1425            "lava_burst_overload",
1426            SPELL::LAVA_BURST_OVERLOAD,
1427            |s| spell_lava_burst_overload(s, &params.game_data),
1428        )
1429        .spell(
1430            "elemental_blast_overload",
1431            SPELL::ELEMENTAL_BLAST_OVERLOAD,
1432            |s| spell_elemental_blast_overload(s, &params.game_data),
1433        )
1434        .spell(
1435            "tempest_overload",
1436            SPELL::TEMPEST_OVERLOAD,
1437            |s| spell_tempest_overload(s, &params.game_data),
1438        )
1439        .spell(
1440            "storms_eye",
1441            SPELL::STORMS_EYE,
1442            |s| spell_storms_eye(s, &params.game_data),
1443        )
1444        .spell(
1445            "lightning_rod_damage",
1446            SPELL::LIGHTNING_ROD_DAMAGE,
1447            |s| spell_lightning_rod_damage(s, &params.game_data),
1448        )
1449        .spell("skyfury", SPELL::SKYFURY, |s| spell_skyfury(s, &params.game_data))
1450        .game_data(params.game_data.clone())
1451        .talent_spell_ids(TALENTS)
1452        .talent_selections(params.talent_selections)
1453        .set_bonus_auras(params.set_bonus_auras)
1454        .encounter(params.encounter.clone());
1455    let builder = crate::generated::items::register_equipped(
1456        builder,
1457        &params.game_data,
1458        params.equipped_items,
1459    )?;
1460
1461    builder
1462        .build(params.rotation)
1463        .map_err(wowlab_engine_ports::EngineError::rotation_compile)
1464}
1465fn new_handler(
1466    params: wowlab_engine_ports::HandlerParams<'_>,
1467) -> Result<Box<dyn SpecHandler>, wowlab_engine_ports::EngineError> {
1468    let handler = crate::composition::compose_handler(
1469        build_combat_system,
1470        &params,
1471        |parts, params| Ok(
1472            crate::hooks::elemental_shaman::ElementalHandler::new(parts, params),
1473        ),
1474    )?;
1475
1476    Ok(Box::new(handler))
1477}
1478static DECLARED_METADATA: DeclaredSpecMetadata = DeclaredSpecMetadata {
1479    primary_resource: ResourceType::Maelstrom,
1480    secondary_resource: None,
1481    spell_ids: DECLARED_SPELL_IDS,
1482    aura_ids: DECLARED_AURA_IDS,
1483    server_proc_entries: &[],
1484    talents: TALENTS,
1485    rotation_field_schema: &[],
1486    metrics_plugin_id: None,
1487    hero_talent_trees: &[
1488        HeroTalentTreeDesc {
1489            name: "Stormbringer",
1490            spells: HERO_TREE_STORMBRINGER_SPELLS,
1491            auras: HERO_TREE_STORMBRINGER_AURAS,
1492        },
1493        HeroTalentTreeDesc {
1494            name: "Farseer",
1495            spells: HERO_TREE_FARSEER_SPELLS,
1496            auras: HERO_TREE_FARSEER_AURAS,
1497        },
1498        HeroTalentTreeDesc {
1499            name: "Totemic",
1500            spells: HERO_TREE_TOTEMIC_SPELLS,
1501            auras: HERO_TREE_TOTEMIC_AURAS,
1502        },
1503    ],
1504    reported_spells: REPORTED_SPELLS,
1505    masked_passive_effects: &[],
1506    passive_effect_overrides: &[],
1507};
1508pub(super) const SPEC_DESCRIPTOR: SpecDescriptor = SpecDescriptor {
1509    spec_id: SpecId::Elemental,
1510    display_name: "Elemental Shaman",
1511    metadata: DECLARED_METADATA,
1512    handler_factory: new_handler,
1513};
1514wowlab_engine_combat::smoke_test!(build_combat_system);