Skip to main content

wowlab_engine_content/generated/specs/
enhancement_shaman.rs

1//! @generated by codegen-cli from manifests/specs/shaman/enhancement/manifest.toml -- do not edit by hand.
2// Generated code: naming follows game data conventions
3#![allow(non_snake_case, dead_code)]
4use wowlab_types::{combat::ResourceType, game::SpecId};
5use wowlab_engine_domain::dbc::ProcAttributes;
6use wowlab_engine_combat::{
7    BuiltCombatSystem, AuraDefinitionDraft, LocalAuraIdx, LocalSpellIdx,
8    SpellDefinitionDraft,
9};
10use wowlab_engine_ports::{
11    DeclaredSpecMetadata, SpecDescriptor, SpecHandler, HeroTalentTreeDesc,
12    DeclaredServerProcEntry,
13};
14use wowlab_engine_gamedata::ResolvedGameData;
15pub(crate) mod SPELL {
16    ///<https://wowlab.gg/inspect/spell/17364>
17    pub(crate) const STORMSTRIKE: u32 = 17364;
18    ///<https://wowlab.gg/inspect/spell/60103>
19    pub(crate) const LAVA_LASH: u32 = 60103;
20    ///<https://wowlab.gg/inspect/spell/187874>
21    pub(crate) const CRASH_LIGHTNING: u32 = 187_874;
22    ///<https://wowlab.gg/inspect/spell/188196>
23    pub(crate) const LIGHTNING_BOLT: u32 = 188_196;
24    ///<https://wowlab.gg/inspect/spell/188443>
25    pub(crate) const CHAIN_LIGHTNING: u32 = 188_443;
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/197214>
31    pub(crate) const SUNDERING: u32 = 197_214;
32    ///<https://wowlab.gg/inspect/spell/384352>
33    pub(crate) const DOOM_WINDS: u32 = 384_352;
34    ///<https://wowlab.gg/inspect/spell/114051>
35    pub(crate) const ASCENDANCE: u32 = 114_051;
36    ///<https://wowlab.gg/inspect/spell/452201>
37    pub(crate) const TEMPEST: u32 = 452_201;
38    ///<https://wowlab.gg/inspect/spell/375982>
39    pub(crate) const PRIMORDIAL_WAVE: u32 = 375_982;
40    ///<https://wowlab.gg/inspect/spell/470057>
41    pub(crate) const VOLTAIC_BLAZE: u32 = 470_057;
42    ///<https://wowlab.gg/inspect/spell/462854>
43    pub(crate) const SKYFURY: u32 = 462_854;
44    ///<https://wowlab.gg/inspect/spell/192106>
45    pub(crate) const LIGHTNING_SHIELD: u32 = 192_106;
46    ///<https://wowlab.gg/inspect/spell/32175>
47    pub(crate) const STORMSTRIKE_MH: u32 = 32175;
48    ///<https://wowlab.gg/inspect/spell/32176>
49    pub(crate) const STORMSTRIKE_OFFHAND: u32 = 32176;
50    ///<https://wowlab.gg/inspect/spell/467283>
51    pub(crate) const SUNDERING_SPLITSTREAM: u32 = 467_283;
52    ///<https://wowlab.gg/inspect/spell/390287>
53    pub(crate) const STORMBLAST: u32 = 390_287;
54    ///<https://wowlab.gg/inspect/spell/1252431>
55    pub(crate) const CRASH_LIGHTNING_UNLEASHED: u32 = 1_252_431;
56    ///<https://wowlab.gg/inspect/spell/1218090>
57    pub(crate) const PRIMORDIAL_STORM: u32 = 1_218_090;
58    ///<https://wowlab.gg/inspect/spell/1218113>
59    pub(crate) const PRIMORDIAL_FIRE: u32 = 1_218_113;
60    ///<https://wowlab.gg/inspect/spell/1218116>
61    pub(crate) const PRIMORDIAL_FROST: u32 = 1_218_116;
62    ///<https://wowlab.gg/inspect/spell/1218118>
63    pub(crate) const PRIMORDIAL_LIGHTNING: u32 = 1_218_118;
64    ///<https://wowlab.gg/inspect/spell/444995>
65    pub(crate) const SURGING_TOTEM: u32 = 444_995;
66    ///<https://wowlab.gg/inspect/spell/455622>
67    pub(crate) const TREMOR: u32 = 455_622;
68    ///<https://wowlab.gg/inspect/spell/458267>
69    pub(crate) const SURGING_BOLT: u32 = 458_267;
70    ///<https://wowlab.gg/inspect/spell/3606>
71    pub(crate) const SEARING_BOLT: u32 = 3606;
72    ///<https://wowlab.gg/inspect/spell/458147>
73    pub(crate) const SEARING_VOLLEY: u32 = 458_147;
74    ///<https://wowlab.gg/inspect/spell/33757>
75    pub(crate) const WINDFURY_WEAPON: u32 = 33757;
76    ///<https://wowlab.gg/inspect/spell/318038>
77    pub(crate) const FLAMETONGUE_WEAPON: u32 = 318_038;
78    ///<https://wowlab.gg/inspect/spell/25504>
79    pub(crate) const WINDFURY_ATTACK: u32 = 25504;
80    ///<https://wowlab.gg/inspect/spell/10444>
81    pub(crate) const FLAMETONGUE_ATTACK: u32 = 10444;
82    ///<https://wowlab.gg/inspect/spell/467386>
83    pub(crate) const FLAMETONGUE_ATTACK_IMBUEMENT_MASTERY: u32 = 467_386;
84    ///<https://wowlab.gg/inspect/spell/187880>
85    pub(crate) const MAELSTROM_WEAPON_DRIVER: u32 = 187_880;
86    ///<https://wowlab.gg/inspect/spell/201900>
87    pub(crate) const HOT_HAND_DRIVER: u32 = 201_900;
88    ///<https://wowlab.gg/inspect/spell/201845>
89    pub(crate) const STORMSURGE_DRIVER: u32 = 201_845;
90}
91pub(crate) mod AURA {
92    ///<https://wowlab.gg/inspect/spell/114051>
93    pub(crate) const ASCENDANCE: u32 = 114_051;
94    ///<https://wowlab.gg/inspect/spell/466772>
95    pub(crate) const DOOM_WINDS: u32 = 466_772;
96    ///<https://wowlab.gg/inspect/spell/1262830>
97    pub(crate) const STORM_UNLEASHED: u32 = 1_262_830;
98    ///<https://wowlab.gg/inspect/spell/1252415>
99    pub(crate) const CRASH_LIGHTNING: u32 = 1_252_415;
100    ///<https://wowlab.gg/inspect/spell/198300>
101    pub(crate) const CONVERGING_STORMS: u32 = 198_300;
102    ///<https://wowlab.gg/inspect/spell/224125>
103    pub(crate) const MOLTEN_WEAPON: u32 = 224_125;
104    ///<https://wowlab.gg/inspect/spell/224127>
105    pub(crate) const CRACKLING_SURGE: u32 = 224_127;
106    ///<https://wowlab.gg/inspect/spell/454015>
107    pub(crate) const TEMPEST: u32 = 454_015;
108    ///<https://wowlab.gg/inspect/spell/454394>
109    pub(crate) const UNLIMITED_POWER: u32 = 454_394;
110    ///<https://wowlab.gg/inspect/spell/188389>
111    pub(crate) const FLAME_SHOCK: u32 = 188_389;
112    ///<https://wowlab.gg/inspect/spell/192106>
113    pub(crate) const LIGHTNING_SHIELD: u32 = 192_106;
114    ///<https://wowlab.gg/inspect/spell/1218125>
115    pub(crate) const PRIMORDIAL_STORM: u32 = 1_218_125;
116    ///<https://wowlab.gg/inspect/spell/384143>
117    pub(crate) const OVERFLOWING_MAELSTROM: u32 = 384_143;
118    ///<https://wowlab.gg/inspect/spell/334168>
119    pub(crate) const LASHING_FLAMES: u32 = 334_168;
120    ///<https://wowlab.gg/inspect/spell/462854>
121    pub(crate) const SKYFURY: u32 = 462_854;
122    ///<https://wowlab.gg/inspect/spell/462854>
123    pub(crate) const SKYFURY_HIGHLIGHT: u32 = 462_854;
124    ///<https://wowlab.gg/inspect/spell/384444>
125    pub(crate) const THORIM_S_INVOCATION: u32 = 384_444;
126    ///<https://wowlab.gg/inspect/spell/461242>
127    pub(crate) const LIVELY_TOTEMS: u32 = 461_242;
128    ///<https://wowlab.gg/inspect/spell/456369>
129    pub(crate) const AMPLIFICATION_CORE: u32 = 456_369;
130    ///<https://wowlab.gg/inspect/spell/1221347>
131    pub(crate) const SURGING_TOTEM: u32 = 1_221_347;
132    ///<https://wowlab.gg/inspect/spell/453405>
133    pub(crate) const WHIRLING_FIRE: u32 = 453_405;
134    ///<https://wowlab.gg/inspect/spell/453406>
135    pub(crate) const WHIRLING_EARTH: u32 = 453_406;
136    ///<https://wowlab.gg/inspect/spell/453409>
137    pub(crate) const WHIRLING_AIR: u32 = 453_409;
138    ///<https://wowlab.gg/inspect/spell/458269>
139    pub(crate) const TOTEMIC_REBOUND: u32 = 458_269;
140    ///<https://wowlab.gg/inspect/spell/344179>
141    pub(crate) const MAELSTROM_WEAPON: u32 = 344_179;
142    ///<https://wowlab.gg/inspect/spell/215785>
143    pub(crate) const HOT_HAND: u32 = 215_785;
144    ///<https://wowlab.gg/inspect/spell/201846>
145    pub(crate) const STORMSURGE: u32 = 201_846;
146}
147pub(crate) mod TALENT {
148    ///<https://wowlab.gg/inspect/spell/114051>
149    pub(crate) const ASCENDANCE: u32 = 114_051;
150    ///<https://wowlab.gg/inspect/spell/390370>
151    pub(crate) const ASHEN_CATALYST: u32 = 390_370;
152    ///<https://wowlab.gg/inspect/spell/187874>
153    pub(crate) const CRASH_LIGHTNING: u32 = 187_874;
154    ///<https://wowlab.gg/inspect/spell/378270>
155    pub(crate) const DEEPLY_ROOTED_ELEMENTS: u32 = 378_270;
156    ///<https://wowlab.gg/inspect/spell/384352>
157    pub(crate) const DOOM_WINDS: u32 = 384_352;
158    ///<https://wowlab.gg/inspect/spell/210853>
159    pub(crate) const ELEMENTAL_ASSAULT: u32 = 210_853;
160    ///<https://wowlab.gg/inspect/spell/117014>
161    pub(crate) const ELEMENTAL_BLAST: u32 = 117_014;
162    ///<https://wowlab.gg/inspect/spell/1250364>
163    pub(crate) const ELEMENTAL_TEMPO: u32 = 1_250_364;
164    ///<https://wowlab.gg/inspect/spell/384355>
165    pub(crate) const ELEMENTAL_WEAPONS: u32 = 384_355;
166    ///<https://wowlab.gg/inspect/spell/469314>
167    pub(crate) const FERAL_SPIRIT: u32 = 469_314;
168    ///<https://wowlab.gg/inspect/spell/318038>
169    pub(crate) const FLAMETONGUE_WEAPON: u32 = 318_038;
170    ///<https://wowlab.gg/inspect/spell/262647>
171    pub(crate) const FORCEFUL_WINDS: u32 = 262_647;
172    ///<https://wowlab.gg/inspect/spell/201900>
173    pub(crate) const HOT_HAND: u32 = 201_900;
174    ///<https://wowlab.gg/inspect/spell/445028>
175    pub(crate) const IMBUEMENT_MASTERY: u32 = 445_028;
176    ///<https://wowlab.gg/inspect/spell/60103>
177    pub(crate) const LAVA_LASH: u32 = 60103;
178    ///<https://wowlab.gg/inspect/spell/445034>
179    pub(crate) const LIVELY_TOTEMS: u32 = 445_034;
180    ///<https://wowlab.gg/inspect/spell/187880>
181    pub(crate) const MAELSTROM_WEAPON: u32 = 187_880;
182    ///<https://wowlab.gg/inspect/spell/384143>
183    pub(crate) const OVERFLOWING_MAELSTROM: u32 = 384_143;
184    ///<https://wowlab.gg/inspect/spell/1218047>
185    pub(crate) const PRIMORDIAL_STORM: u32 = 1_218_047;
186    ///<https://wowlab.gg/inspect/spell/384149>
187    pub(crate) const RAGING_MAELSTROM: u32 = 384_149;
188    ///<https://wowlab.gg/inspect/spell/445035>
189    pub(crate) const SPLITSTREAM: u32 = 445_035;
190    ///<https://wowlab.gg/inspect/spell/319930>
191    pub(crate) const STORMBLAST: u32 = 319_930;
192    ///<https://wowlab.gg/inspect/spell/344357>
193    pub(crate) const STORMFLURRY: u32 = 344_357;
194    ///<https://wowlab.gg/inspect/spell/392352>
195    pub(crate) const STORMS_WRATH: u32 = 392_352;
196    ///<https://wowlab.gg/inspect/spell/1262713>
197    pub(crate) const STORM_UNLEASHED: u32 = 1_262_713;
198    ///<https://wowlab.gg/inspect/spell/1252373>
199    pub(crate) const STORM_UNLEASHED_REPEATS: u32 = 1_252_373;
200    ///<https://wowlab.gg/inspect/spell/197214>
201    pub(crate) const SUNDERING: u32 = 197_214;
202    ///<https://wowlab.gg/inspect/spell/384444>
203    pub(crate) const THORIMS_INVOCATION: u32 = 384_444;
204    ///<https://wowlab.gg/inspect/spell/1260644>
205    pub(crate) const TOTEMIC_MOMENTUM: u32 = 1_260_644;
206    ///<https://wowlab.gg/inspect/spell/390288>
207    pub(crate) const UNRULY_WINDS: u32 = 390_288;
208    ///<https://wowlab.gg/inspect/spell/470057>
209    pub(crate) const VOLTAIC_BLAZE: u32 = 470_057;
210    ///<https://wowlab.gg/inspect/spell/33757>
211    pub(crate) const WINDFURY_WEAPON: u32 = 33757;
212}
213pub(crate) mod REPORTED_SPELL {
214    ///<https://wowlab.gg/inspect/spell/195592>
215    pub(crate) const CRASH_LIGHTNING_PROC: u32 = 195_592;
216    ///<https://wowlab.gg/inspect/spell/1252431>
217    pub(crate) const CRASH_LIGHTNING_UNLEASHED: u32 = 1_252_431;
218    ///<https://wowlab.gg/inspect/spell/469270>
219    pub(crate) const DOOM_WINDS_DAMAGE: u32 = 469_270;
220    ///<https://wowlab.gg/inspect/spell/408390>
221    pub(crate) const ELEMENTAL_WEAPONS_MODIFIER: u32 = 408_390;
222    ///<https://wowlab.gg/inspect/spell/467386>
223    pub(crate) const FLAMETONGUE_ATTACK_IMBUEMENT_MASTERY: u32 = 467_386;
224    ///<https://wowlab.gg/inspect/spell/1218113>
225    pub(crate) const PRIMORDIAL_FIRE: u32 = 1_218_113;
226    ///<https://wowlab.gg/inspect/spell/1218116>
227    pub(crate) const PRIMORDIAL_FROST: u32 = 1_218_116;
228    ///<https://wowlab.gg/inspect/spell/1218118>
229    pub(crate) const PRIMORDIAL_LIGHTNING: u32 = 1_218_118;
230    ///<https://wowlab.gg/inspect/spell/458147>
231    pub(crate) const SEARING_VOLLEY: u32 = 458_147;
232    ///<https://wowlab.gg/inspect/spell/390287>
233    pub(crate) const STORMBLAST: u32 = 390_287;
234    ///<https://wowlab.gg/inspect/spell/467283>
235    pub(crate) const SUNDERING_SPLITSTREAM: u32 = 467_283;
236    ///<https://wowlab.gg/inspect/spell/1259101>
237    pub(crate) const VOLTAIC_BLAZE_DAMAGE: u32 = 1_259_101;
238}
239pub(crate) mod HERO {
240    pub(crate) mod STORMBRINGER {
241        pub(crate) mod SPELL {
242            ///<https://wowlab.gg/inspect/spell/452201>
243            pub(crate) const TEMPEST: u32 = 452_201;
244        }
245        pub(crate) mod AURA {
246            ///<https://wowlab.gg/inspect/spell/470532>
247            pub(crate) const ARC_DISCHARGE: u32 = 470_532;
248            ///<https://wowlab.gg/inspect/spell/455129>
249            pub(crate) const AWAKENING_STORMS: u32 = 455_129;
250            ///<https://wowlab.gg/inspect/spell/455089>
251            pub(crate) const STORM_SWELL: u32 = 455_089;
252            ///<https://wowlab.gg/inspect/spell/454015>
253            pub(crate) const TEMPEST: u32 = 454_015;
254            ///<https://wowlab.gg/inspect/spell/454394>
255            pub(crate) const UNLIMITED_POWER: u32 = 454_394;
256        }
257    }
258    pub(crate) mod TOTEMIC {
259        pub(crate) mod SPELL {
260            ///<https://wowlab.gg/inspect/spell/444995>
261            pub(crate) const SURGING_TOTEM: u32 = 444_995;
262        }
263        pub(crate) mod AURA {
264            ///<https://wowlab.gg/inspect/spell/456369>
265            pub(crate) const AMPLIFICATION_CORE: u32 = 456_369;
266            ///<https://wowlab.gg/inspect/spell/461242>
267            pub(crate) const LIVELY_TOTEMS: u32 = 461_242;
268            ///<https://wowlab.gg/inspect/spell/1221347>
269            pub(crate) const SURGING_TOTEM: u32 = 1_221_347;
270            ///<https://wowlab.gg/inspect/spell/458269>
271            pub(crate) const TOTEMIC_REBOUND: u32 = 458_269;
272            ///<https://wowlab.gg/inspect/spell/453409>
273            pub(crate) const WHIRLING_AIR: u32 = 453_409;
274            ///<https://wowlab.gg/inspect/spell/453406>
275            pub(crate) const WHIRLING_EARTH: u32 = 453_406;
276            ///<https://wowlab.gg/inspect/spell/453405>
277            pub(crate) const WHIRLING_FIRE: u32 = 453_405;
278        }
279    }
280}
281static HERO_TREE_STORMBRINGER_SPELLS: &[(&str, u32)] = &[("TEMPEST", 452_201)];
282static HERO_TREE_STORMBRINGER_AURAS: &[(&str, u32)] = &[
283    ("ARC_DISCHARGE", 470_532),
284    ("AWAKENING_STORMS", 455_129),
285    ("STORM_SWELL", 455_089),
286    ("TEMPEST", 454_015),
287    ("UNLIMITED_POWER", 454_394),
288];
289static HERO_TREE_TOTEMIC_SPELLS: &[(&str, u32)] = &[("SURGING_TOTEM", 444_995)];
290static HERO_TREE_TOTEMIC_AURAS: &[(&str, u32)] = &[
291    ("AMPLIFICATION_CORE", 456_369),
292    ("LIVELY_TOTEMS", 461_242),
293    ("SURGING_TOTEM", 1_221_347),
294    ("TOTEMIC_REBOUND", 458_269),
295    ("WHIRLING_AIR", 453_409),
296    ("WHIRLING_EARTH", 453_406),
297    ("WHIRLING_FIRE", 453_405),
298];
299pub(crate) const AURA_ASCENDANCE: LocalAuraIdx = LocalAuraIdx::new(0);
300pub(crate) const AURA_DOOM_WINDS: LocalAuraIdx = LocalAuraIdx::new(1);
301pub(crate) const AURA_STORM_UNLEASHED: LocalAuraIdx = LocalAuraIdx::new(2);
302pub(crate) const AURA_CRASH_LIGHTNING: LocalAuraIdx = LocalAuraIdx::new(3);
303pub(crate) const AURA_CONVERGING_STORMS: LocalAuraIdx = LocalAuraIdx::new(4);
304pub(crate) const AURA_MOLTEN_WEAPON: LocalAuraIdx = LocalAuraIdx::new(5);
305pub(crate) const AURA_CRACKLING_SURGE: LocalAuraIdx = LocalAuraIdx::new(6);
306pub(crate) const AURA_TEMPEST: LocalAuraIdx = LocalAuraIdx::new(7);
307pub(crate) const AURA_UNLIMITED_POWER: LocalAuraIdx = LocalAuraIdx::new(8);
308pub(crate) const AURA_FLAME_SHOCK: LocalAuraIdx = LocalAuraIdx::new(9);
309pub(crate) const AURA_LIGHTNING_SHIELD: LocalAuraIdx = LocalAuraIdx::new(10);
310pub(crate) const AURA_PRIMORDIAL_STORM: LocalAuraIdx = LocalAuraIdx::new(11);
311pub(crate) const AURA_OVERFLOWING_MAELSTROM: LocalAuraIdx = LocalAuraIdx::new(12);
312pub(crate) const AURA_LASHING_FLAMES: LocalAuraIdx = LocalAuraIdx::new(13);
313pub(crate) const AURA_SKYFURY: LocalAuraIdx = LocalAuraIdx::new(14);
314pub(crate) const AURA_SKYFURY_HIGHLIGHT: LocalAuraIdx = LocalAuraIdx::new(15);
315pub(crate) const AURA_THORIM_S_INVOCATION: LocalAuraIdx = LocalAuraIdx::new(16);
316pub(crate) const AURA_LIVELY_TOTEMS: LocalAuraIdx = LocalAuraIdx::new(17);
317pub(crate) const AURA_AMPLIFICATION_CORE: LocalAuraIdx = LocalAuraIdx::new(18);
318pub(crate) const AURA_SURGING_TOTEM: LocalAuraIdx = LocalAuraIdx::new(19);
319pub(crate) const AURA_WHIRLING_FIRE: LocalAuraIdx = LocalAuraIdx::new(20);
320pub(crate) const AURA_WHIRLING_EARTH: LocalAuraIdx = LocalAuraIdx::new(21);
321pub(crate) const AURA_WHIRLING_AIR: LocalAuraIdx = LocalAuraIdx::new(22);
322pub(crate) const AURA_TOTEMIC_REBOUND: LocalAuraIdx = LocalAuraIdx::new(23);
323pub(crate) const AURA_MAELSTROM_WEAPON: LocalAuraIdx = LocalAuraIdx::new(24);
324pub(crate) const AURA_HOT_HAND: LocalAuraIdx = LocalAuraIdx::new(25);
325pub(crate) const AURA_STORMSURGE: LocalAuraIdx = LocalAuraIdx::new(26);
326pub(crate) const AURA_COUNT: usize = 27;
327const _: () = assert!(
328    AURA_COUNT == 27, "AURA index ABI: count changed -- update positional hook consumers"
329);
330pub(crate) const SPELL_STORMSTRIKE: LocalSpellIdx = LocalSpellIdx::new(0);
331pub(crate) const SPELL_LAVA_LASH: LocalSpellIdx = LocalSpellIdx::new(1);
332pub(crate) const SPELL_CRASH_LIGHTNING: LocalSpellIdx = LocalSpellIdx::new(2);
333pub(crate) const SPELL_LIGHTNING_BOLT: LocalSpellIdx = LocalSpellIdx::new(3);
334pub(crate) const SPELL_CHAIN_LIGHTNING: LocalSpellIdx = LocalSpellIdx::new(4);
335pub(crate) const SPELL_FLAME_SHOCK: LocalSpellIdx = LocalSpellIdx::new(5);
336pub(crate) const SPELL_FROST_SHOCK: LocalSpellIdx = LocalSpellIdx::new(6);
337pub(crate) const SPELL_SUNDERING: LocalSpellIdx = LocalSpellIdx::new(7);
338pub(crate) const SPELL_DOOM_WINDS: LocalSpellIdx = LocalSpellIdx::new(8);
339pub(crate) const SPELL_ASCENDANCE: LocalSpellIdx = LocalSpellIdx::new(9);
340pub(crate) const SPELL_TEMPEST: LocalSpellIdx = LocalSpellIdx::new(10);
341pub(crate) const SPELL_PRIMORDIAL_WAVE: LocalSpellIdx = LocalSpellIdx::new(11);
342pub(crate) const SPELL_VOLTAIC_BLAZE: LocalSpellIdx = LocalSpellIdx::new(12);
343pub(crate) const SPELL_SKYFURY: LocalSpellIdx = LocalSpellIdx::new(13);
344pub(crate) const SPELL_LIGHTNING_SHIELD: LocalSpellIdx = LocalSpellIdx::new(14);
345pub(crate) const SPELL_STORMSTRIKE_MH: LocalSpellIdx = LocalSpellIdx::new(15);
346pub(crate) const SPELL_STORMSTRIKE_OFFHAND: LocalSpellIdx = LocalSpellIdx::new(16);
347pub(crate) const SPELL_SUNDERING_SPLITSTREAM: LocalSpellIdx = LocalSpellIdx::new(17);
348pub(crate) const SPELL_STORMBLAST: LocalSpellIdx = LocalSpellIdx::new(18);
349pub(crate) const SPELL_CRASH_LIGHTNING_UNLEASHED: LocalSpellIdx = LocalSpellIdx::new(19);
350pub(crate) const SPELL_PRIMORDIAL_STORM: LocalSpellIdx = LocalSpellIdx::new(20);
351pub(crate) const SPELL_PRIMORDIAL_FIRE: LocalSpellIdx = LocalSpellIdx::new(21);
352pub(crate) const SPELL_PRIMORDIAL_FROST: LocalSpellIdx = LocalSpellIdx::new(22);
353pub(crate) const SPELL_PRIMORDIAL_LIGHTNING: LocalSpellIdx = LocalSpellIdx::new(23);
354pub(crate) const SPELL_SURGING_TOTEM: LocalSpellIdx = LocalSpellIdx::new(24);
355pub(crate) const SPELL_TREMOR: LocalSpellIdx = LocalSpellIdx::new(25);
356pub(crate) const SPELL_SURGING_BOLT: LocalSpellIdx = LocalSpellIdx::new(26);
357pub(crate) const SPELL_SEARING_BOLT: LocalSpellIdx = LocalSpellIdx::new(27);
358pub(crate) const SPELL_SEARING_VOLLEY: LocalSpellIdx = LocalSpellIdx::new(28);
359pub(crate) const SPELL_WINDFURY_WEAPON: LocalSpellIdx = LocalSpellIdx::new(29);
360pub(crate) const SPELL_FLAMETONGUE_WEAPON: LocalSpellIdx = LocalSpellIdx::new(30);
361pub(crate) const SPELL_WINDFURY_ATTACK: LocalSpellIdx = LocalSpellIdx::new(31);
362pub(crate) const SPELL_FLAMETONGUE_ATTACK: LocalSpellIdx = LocalSpellIdx::new(32);
363pub(crate) const SPELL_FLAMETONGUE_ATTACK_IMBUEMENT_MASTERY: LocalSpellIdx = LocalSpellIdx::new(
364    33,
365);
366pub(crate) const SPELL_MAELSTROM_WEAPON_DRIVER: LocalSpellIdx = LocalSpellIdx::new(34);
367pub(crate) const SPELL_HOT_HAND_DRIVER: LocalSpellIdx = LocalSpellIdx::new(35);
368pub(crate) const SPELL_STORMSURGE_DRIVER: LocalSpellIdx = LocalSpellIdx::new(36);
369pub(crate) const SPELL_COUNT: usize = 37;
370const _: () = assert!(
371    SPELL_COUNT == 37,
372    "SPELL index ABI: count changed -- update positional hook consumers"
373);
374pub(crate) mod EFFECT {
375    ///<https://wowlab.gg/inspect/spell/390370>
376    pub(crate) const ASHEN_CATALYST_CDR: (u32, u8) = (390_370, 1);
377    ///<https://wowlab.gg/inspect/spell/188443>
378    pub(crate) const CHAIN_LIGHTNING_DAMAGE: (u32, u8) = (188_443, 1);
379    ///<https://wowlab.gg/inspect/spell/1252415>
380    pub(crate) const CRASH_LIGHTNING_DAMAGE: (u32, u8) = (1_252_415, 1);
381    ///<https://wowlab.gg/inspect/spell/1252431>
382    pub(crate) const CRASH_LIGHTNING_UNLEASHED_DAMAGE: (u32, u8) = (1_252_431, 1);
383    ///<https://wowlab.gg/inspect/spell/1250364>
384    pub(crate) const ELEMENTAL_TEMPO_CDR: (u32, u8) = (1_250_364, 3);
385    ///<https://wowlab.gg/inspect/spell/384355>
386    pub(crate) const ELEMENTAL_WEAPONS_BONUS: (u32, u8) = (384_355, 1);
387    ///<https://wowlab.gg/inspect/spell/408390>
388    pub(crate) const ELEMENTAL_WEAPONS_DIRECT: (u32, u8) = (408_390, 1);
389    ///<https://wowlab.gg/inspect/spell/408390>
390    pub(crate) const ELEMENTAL_WEAPONS_PERIODIC: (u32, u8) = (408_390, 2);
391    ///<https://wowlab.gg/inspect/spell/10444>
392    pub(crate) const FLAMETONGUE_ATTACK_DAMAGE: (u32, u8) = (10444, 1);
393    ///<https://wowlab.gg/inspect/spell/60103>
394    pub(crate) const LAVA_LASH_DAMAGE: (u32, u8) = (60103, 1);
395    ///<https://wowlab.gg/inspect/spell/188196>
396    pub(crate) const LIGHTNING_BOLT_DAMAGE: (u32, u8) = (188_196, 1);
397    ///<https://wowlab.gg/inspect/spell/1218113>
398    pub(crate) const PRIMORDIAL_FIRE_DAMAGE: (u32, u8) = (1_218_113, 1);
399    ///<https://wowlab.gg/inspect/spell/1218116>
400    pub(crate) const PRIMORDIAL_FROST_DAMAGE: (u32, u8) = (1_218_116, 1);
401    ///<https://wowlab.gg/inspect/spell/1218118>
402    pub(crate) const PRIMORDIAL_LIGHTNING_DAMAGE: (u32, u8) = (1_218_118, 1);
403    ///<https://wowlab.gg/inspect/spell/3606>
404    pub(crate) const SEARING_BOLT_DAMAGE: (u32, u8) = (3606, 1);
405    ///<https://wowlab.gg/inspect/spell/458147>
406    pub(crate) const SEARING_VOLLEY_DAMAGE: (u32, u8) = (458_147, 1);
407    ///<https://wowlab.gg/inspect/spell/445035>
408    pub(crate) const SPLITSTREAM_DAMAGE: (u32, u8) = (445_035, 1);
409    ///<https://wowlab.gg/inspect/spell/319930>
410    pub(crate) const STORMBLAST_BONUS: (u32, u8) = (319_930, 1);
411    ///<https://wowlab.gg/inspect/spell/32175>
412    pub(crate) const STORMSTRIKE_MH_DAMAGE: (u32, u8) = (32175, 1);
413    ///<https://wowlab.gg/inspect/spell/32176>
414    pub(crate) const STORMSTRIKE_OH_DAMAGE: (u32, u8) = (32176, 1);
415    ///<https://wowlab.gg/inspect/spell/77223>
416    pub(crate) const STORMSURGE_MASTERY: (u32, u8) = (77223, 3);
417    ///<https://wowlab.gg/inspect/spell/1262713>
418    pub(crate) const STORM_UNLEASHED_CHANCE: (u32, u8) = (1_262_713, 1);
419    ///<https://wowlab.gg/inspect/spell/467283>
420    pub(crate) const SUNDERING_SPLITSTREAM_DAMAGE: (u32, u8) = (467_283, 1);
421    ///<https://wowlab.gg/inspect/spell/458267>
422    pub(crate) const SURGING_BOLT_DAMAGE: (u32, u8) = (458_267, 1);
423    ///<https://wowlab.gg/inspect/spell/1260644>
424    pub(crate) const TOTEMIC_MOMENTUM_BONUS: (u32, u8) = (1_260_644, 1);
425    ///<https://wowlab.gg/inspect/spell/455622>
426    pub(crate) const TREMOR_DAMAGE: (u32, u8) = (455_622, 1);
427    ///<https://wowlab.gg/inspect/spell/470057>
428    pub(crate) const VOLTAIC_BLAZE_MAELSTROM_STACKS: (u32, u8) = (470_057, 2);
429    ///<https://wowlab.gg/inspect/spell/25504>
430    pub(crate) const WINDFURY_ATTACK_DAMAGE: (u32, u8) = (25504, 1);
431    ///<https://wowlab.gg/inspect/spell/77223>
432    pub(crate) const WINDFURY_MASTERY: (u32, u8) = (77223, 4);
433    ///<https://wowlab.gg/inspect/spell/319773>
434    pub(crate) const WINDFURY_PROC: (u32, u8) = (319_773, 1);
435    ///<https://wowlab.gg/inspect/spell/445025>
436    pub(crate) const TOTEMIC_REBOUND_RPPM_DRIVER: (u32, u8) = (445_025, 1);
437}
438static REPORTED_SPELLS: &[(&str, u32)] = &[
439    ("crash_lightning_proc", 195_592),
440    ("crash_lightning_unleashed", 1_252_431),
441    ("doom_winds_damage", 469_270),
442    ("elemental_weapons_modifier", 408_390),
443    ("flametongue_attack_imbuement_mastery", 467_386),
444    ("primordial_fire", 1_218_113),
445    ("primordial_frost", 1_218_116),
446    ("primordial_lightning", 1_218_118),
447    ("searing_volley", 458_147),
448    ("stormblast", 390_287),
449    ("sundering_splitstream", 467_283),
450    ("voltaic_blaze_damage", 1_259_101),
451];
452static DECLARED_SPELL_IDS: &[u32] = &[
453    17364, 60103, 187_874, 188_196, 188_443, 188_389, 196_840, 197_214, 384_352, 114_051,
454    452_201, 375_982, 470_057, 462_854, 192_106, 32175, 32176, 467_283, 390_287,
455    1_252_431, 1_218_090, 1_218_113, 1_218_116, 1_218_118, 444_995, 455_622, 458_267,
456    3606, 458_147, 33757, 318_038, 25504, 10444, 467_386, 187_880, 201_900, 201_845,
457    114_051, 466_772, 1_262_830, 1_252_415, 198_300, 224_125, 224_127, 454_015, 454_394,
458    188_389, 192_106, 1_218_125, 384_143, 334_168, 462_854, 462_854, 384_444, 461_242,
459    456_369, 1_221_347, 453_405, 453_406, 453_409, 458_269, 344_179, 215_785, 201_846,
460    6603, 6603, 3606, 10444, 25504, 32175, 32176, 60103, 77223, 188_196, 188_389,
461    188_443, 195_592, 197_214, 319_773, 319_930, 384_355, 390_287, 390_370, 408_390,
462    445_025, 445_035, 454_394, 455_593, 455_622, 458_147, 458_267, 466_772, 467_283,
463    467_386, 469_270, 470_057, 1_218_113, 1_218_116, 1_218_118, 1_250_364, 1_252_415,
464    1_252_431, 1_259_101, 1_260_644, 1_262_713, 195_592, 1_252_431, 469_270, 408_390,
465    467_386, 1_218_113, 1_218_116, 1_218_118, 458_147, 390_287, 467_283, 1_259_101,
466    452_201, 470_532, 455_129, 455_089, 454_015, 454_394, 444_995, 456_369, 461_242,
467    1_221_347, 458_269, 453_409, 453_406, 453_405,
468];
469static DECLARED_AURA_IDS: &[u32] = &[
470    114_051, 466_772, 1_262_830, 1_252_415, 198_300, 224_125, 224_127, 454_015, 454_394,
471    188_389, 192_106, 1_218_125, 384_143, 334_168, 462_854, 462_854, 384_444, 461_242,
472    456_369, 1_221_347, 453_405, 453_406, 453_409, 458_269, 344_179, 215_785, 201_846,
473    470_532, 455_129, 455_089, 454_015, 454_394, 456_369, 461_242, 1_221_347, 458_269,
474    453_409, 453_406, 453_405,
475];
476static TALENTS: &[(&str, u32)] = &[
477    ("ASCENDANCE", TALENT::ASCENDANCE),
478    ("ASHEN_CATALYST", TALENT::ASHEN_CATALYST),
479    ("CRASH_LIGHTNING", TALENT::CRASH_LIGHTNING),
480    ("DEEPLY_ROOTED_ELEMENTS", TALENT::DEEPLY_ROOTED_ELEMENTS),
481    ("DOOM_WINDS", TALENT::DOOM_WINDS),
482    ("ELEMENTAL_ASSAULT", TALENT::ELEMENTAL_ASSAULT),
483    ("ELEMENTAL_BLAST", TALENT::ELEMENTAL_BLAST),
484    ("ELEMENTAL_TEMPO", TALENT::ELEMENTAL_TEMPO),
485    ("ELEMENTAL_WEAPONS", TALENT::ELEMENTAL_WEAPONS),
486    ("FERAL_SPIRIT", TALENT::FERAL_SPIRIT),
487    ("FLAMETONGUE_WEAPON", TALENT::FLAMETONGUE_WEAPON),
488    ("FORCEFUL_WINDS", TALENT::FORCEFUL_WINDS),
489    ("HOT_HAND", TALENT::HOT_HAND),
490    ("IMBUEMENT_MASTERY", TALENT::IMBUEMENT_MASTERY),
491    ("LAVA_LASH", TALENT::LAVA_LASH),
492    ("LIVELY_TOTEMS", TALENT::LIVELY_TOTEMS),
493    ("MAELSTROM_WEAPON", TALENT::MAELSTROM_WEAPON),
494    ("OVERFLOWING_MAELSTROM", TALENT::OVERFLOWING_MAELSTROM),
495    ("PRIMORDIAL_STORM", TALENT::PRIMORDIAL_STORM),
496    ("RAGING_MAELSTROM", TALENT::RAGING_MAELSTROM),
497    ("SPLITSTREAM", TALENT::SPLITSTREAM),
498    ("STORMBLAST", TALENT::STORMBLAST),
499    ("STORMFLURRY", TALENT::STORMFLURRY),
500    ("STORMS_WRATH", TALENT::STORMS_WRATH),
501    ("STORM_UNLEASHED", TALENT::STORM_UNLEASHED),
502    ("STORM_UNLEASHED_REPEATS", TALENT::STORM_UNLEASHED_REPEATS),
503    ("SUNDERING", TALENT::SUNDERING),
504    ("THORIMS_INVOCATION", TALENT::THORIMS_INVOCATION),
505    ("TOTEMIC_MOMENTUM", TALENT::TOTEMIC_MOMENTUM),
506    ("UNRULY_WINDS", TALENT::UNRULY_WINDS),
507    ("VOLTAIC_BLAZE", TALENT::VOLTAIC_BLAZE),
508    ("WINDFURY_WEAPON", TALENT::WINDFURY_WEAPON),
509];
510pub(crate) mod ENHANCEMENT_SHAMAN {
511    pub(crate) const STORMSTRIKE_CASTS: u32 = 0;
512    pub(crate) const LAVA_LASH_CASTS: u32 = 1;
513    pub(crate) const CRASH_LIGHTNING_CASTS: u32 = 2;
514    pub(crate) const LIGHTNING_BOLT_CASTS: u32 = 3;
515    pub(crate) const DOOM_WINDS_CASTS: u32 = 4;
516    pub(crate) const ASCENDANCE_CASTS: u32 = 5;
517    pub(crate) const TEMPEST_CASTS: u32 = 6;
518    pub(crate) const MAELSTROM_WEAPON_CONSUMED: u32 = 7;
519}
520fn aura_ascendance(
521    a: AuraDefinitionDraft,
522    data: &ResolvedGameData,
523) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
524    a.on_player()
525        .apply_base_from_data(data, 114_051)?
526        .max_stacks(
527            data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(114_051))?,
528        )
529        .damage_multiplier(1.2)
530}
531fn aura_doom_winds(
532    a: AuraDefinitionDraft,
533    data: &ResolvedGameData,
534) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
535    a.on_player()
536        .apply_base_from_data(data, 466_772)?
537        .max_stacks(
538            data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(466_772))?,
539        )
540        .periodic_damage_from_spell(
541            wowlab_engine_combat::validated_milliseconds(
542                data.period(wowlab_types::sim::SpellIdx::from_raw(466_772), 3),
543                466_772,
544                "periodic_damage.tick_ms",
545            )?,
546            wowlab_engine_combat::DamagePayload::new(
547                469_270,
548                ((data.ap_coef(wowlab_types::sim::SpellIdx::from_raw(469_270), 1))
549                    * 10.0)
550                    .round() / 10.0,
551                wowlab_engine_combat::DamageFlags::empty(),
552            ),
553        )
554        .apply_periodic_behavior_from_data(data, 466_772)
555}
556fn aura_storm_unleashed(
557    a: AuraDefinitionDraft,
558    data: &ResolvedGameData,
559) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
560    Ok(
561        a
562            .on_player()
563            .apply_base_from_data(data, 1_262_830)?
564            .max_stacks(
565                data
566                    .require_aura_max_stacks(
567                        wowlab_types::sim::SpellIdx::from_raw(1_262_830),
568                    )?,
569            ),
570    )
571}
572fn aura_crash_lightning(
573    a: AuraDefinitionDraft,
574    data: &ResolvedGameData,
575) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
576    Ok(
577        a
578            .on_player()
579            .apply_base_from_data(data, 1_252_415)?
580            .max_stacks(
581                data
582                    .require_aura_max_stacks(
583                        wowlab_types::sim::SpellIdx::from_raw(1_252_415),
584                    )?,
585            )
586            .async_stacks(),
587    )
588}
589fn aura_converging_storms(
590    a: AuraDefinitionDraft,
591    data: &ResolvedGameData,
592) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
593    Ok(
594        a
595            .on_player()
596            .apply_base_from_data(data, 198_300)?
597            .max_stacks(
598                data
599                    .require_aura_max_stacks(
600                        wowlab_types::sim::SpellIdx::from_raw(198_300),
601                    )?,
602            ),
603    )
604}
605fn aura_molten_weapon(
606    a: AuraDefinitionDraft,
607    data: &ResolvedGameData,
608) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
609    Ok(
610        a
611            .on_player()
612            .apply_base_from_data(data, 224_125)?
613            .max_stacks(
614                data
615                    .require_aura_max_stacks(
616                        wowlab_types::sim::SpellIdx::from_raw(224_125),
617                    )?,
618            ),
619    )
620}
621fn aura_crackling_surge(
622    a: AuraDefinitionDraft,
623    data: &ResolvedGameData,
624) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
625    Ok(
626        a
627            .on_player()
628            .apply_base_from_data(data, 224_127)?
629            .max_stacks(
630                data
631                    .require_aura_max_stacks(
632                        wowlab_types::sim::SpellIdx::from_raw(224_127),
633                    )?,
634            ),
635    )
636}
637fn aura_tempest(
638    a: AuraDefinitionDraft,
639    data: &ResolvedGameData,
640) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
641    Ok(
642        a
643            .on_player()
644            .apply_base_from_data(data, 454_015)?
645            .max_stacks(
646                data
647                    .require_aura_max_stacks(
648                        wowlab_types::sim::SpellIdx::from_raw(454_015),
649                    )?,
650            ),
651    )
652}
653fn aura_unlimited_power(
654    a: AuraDefinitionDraft,
655    data: &ResolvedGameData,
656) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
657    a.on_player()
658        .apply_base_from_data(data, 454_394)?
659        .max_stacks(
660            data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(454_394))?,
661        )
662        .haste_per_stack(
663            (data.base_points(wowlab_types::sim::SpellIdx::from_raw(454_394), 1)) * 2.0,
664        )
665}
666fn aura_flame_shock(
667    a: AuraDefinitionDraft,
668    data: &ResolvedGameData,
669) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
670    a.on_target()
671        .apply_base_from_data(data, 188_389)?
672        .max_stacks(
673            data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(188_389))?,
674        )
675        .periodic_damage(
676            wowlab_engine_combat::validated_milliseconds(
677                data.period(wowlab_types::sim::SpellIdx::from_raw(188_389), 2),
678                188_389,
679                "periodic_damage.tick_ms",
680            )?,
681            ((data.sp_coef(wowlab_types::sim::SpellIdx::from_raw(188_389), 2)) * 10000.0)
682                .round() / 10000.0,
683            wowlab_engine_combat::DamageFlags::empty(),
684        )
685        .apply_periodic_behavior_from_data(data, 188_389)
686}
687fn aura_lightning_shield(
688    a: AuraDefinitionDraft,
689    data: &ResolvedGameData,
690) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
691    Ok(
692        a
693            .on_player()
694            .apply_base_from_data(data, 192_106)?
695            .max_stacks(
696                data
697                    .require_aura_max_stacks(
698                        wowlab_types::sim::SpellIdx::from_raw(192_106),
699                    )?,
700            ),
701    )
702}
703fn aura_primordial_storm(
704    a: AuraDefinitionDraft,
705    data: &ResolvedGameData,
706) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
707    Ok(
708        a
709            .on_player()
710            .apply_base_from_data(data, 1_218_125)?
711            .max_stacks(
712                data
713                    .require_aura_max_stacks(
714                        wowlab_types::sim::SpellIdx::from_raw(1_218_125),
715                    )?,
716            ),
717    )
718}
719fn aura_overflowing_maelstrom(
720    a: AuraDefinitionDraft,
721    data: &ResolvedGameData,
722) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
723    Ok(
724        a
725            .on_player()
726            .apply_base_from_data(data, 384_143)?
727            .max_stacks(
728                data
729                    .require_aura_max_stacks(
730                        wowlab_types::sim::SpellIdx::from_raw(384_143),
731                    )?,
732            ),
733    )
734}
735fn aura_lashing_flames(
736    a: AuraDefinitionDraft,
737    data: &ResolvedGameData,
738) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
739    Ok(
740        a
741            .on_target()
742            .apply_base_from_data(data, 334_168)?
743            .max_stacks(
744                data
745                    .require_aura_max_stacks(
746                        wowlab_types::sim::SpellIdx::from_raw(334_168),
747                    )?,
748            ),
749    )
750}
751fn aura_skyfury(
752    a: AuraDefinitionDraft,
753    data: &ResolvedGameData,
754) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
755    Ok(
756        a
757            .on_player()
758            .apply_base_from_data(data, 462_854)?
759            .max_stacks(
760                data
761                    .require_aura_max_stacks(
762                        wowlab_types::sim::SpellIdx::from_raw(462_854),
763                    )?,
764            ),
765    )
766}
767fn aura_skyfury_highlight(
768    a: AuraDefinitionDraft,
769    data: &ResolvedGameData,
770) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
771    Ok(
772        a
773            .on_player()
774            .apply_base_from_data(data, 462_854)?
775            .max_stacks(
776                data
777                    .require_aura_max_stacks(
778                        wowlab_types::sim::SpellIdx::from_raw(462_854),
779                    )?,
780            ),
781    )
782}
783fn aura_thorim_s_invocation(
784    a: AuraDefinitionDraft,
785    data: &ResolvedGameData,
786) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
787    Ok(
788        a
789            .on_player()
790            .apply_base_from_data(data, 384_444)?
791            .max_stacks(
792                data
793                    .require_aura_max_stacks(
794                        wowlab_types::sim::SpellIdx::from_raw(384_444),
795                    )?,
796            ),
797    )
798}
799fn aura_lively_totems(
800    a: AuraDefinitionDraft,
801    data: &ResolvedGameData,
802) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
803    Ok(
804        a
805            .on_player()
806            .apply_base_from_data(data, 461_242)?
807            .max_stacks(
808                data
809                    .require_aura_max_stacks(
810                        wowlab_types::sim::SpellIdx::from_raw(461_242),
811                    )?,
812            ),
813    )
814}
815fn aura_amplification_core(
816    a: AuraDefinitionDraft,
817    data: &ResolvedGameData,
818) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
819    Ok(
820        a
821            .on_player()
822            .apply_base_from_data(data, 456_369)?
823            .max_stacks(
824                data
825                    .require_aura_max_stacks(
826                        wowlab_types::sim::SpellIdx::from_raw(456_369),
827                    )?,
828            ),
829    )
830}
831fn aura_surging_totem(
832    a: AuraDefinitionDraft,
833    data: &ResolvedGameData,
834) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
835    Ok(
836        a
837            .on_player()
838            .apply_base_from_data(data, 1_221_347)?
839            .max_stacks(
840                data
841                    .require_aura_max_stacks(
842                        wowlab_types::sim::SpellIdx::from_raw(1_221_347),
843                    )?,
844            )
845            .periodic_hook(
846                wowlab_engine_combat::validated_milliseconds(
847                    data.period(wowlab_types::sim::SpellIdx::from_raw(455_593), 1),
848                    1_221_347,
849                    "periodic_hook.tick_ms",
850                )?,
851            )
852            .apply_periodic_behavior_from_data(data, 455_593)?
853            .hasted_periodic()
854            .tick_hook(crate::hooks::enhancement_shaman::surging_totem_pulse_hook),
855    )
856}
857fn aura_whirling_fire(
858    a: AuraDefinitionDraft,
859    data: &ResolvedGameData,
860) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
861    Ok(
862        a
863            .on_player()
864            .apply_base_from_data(data, 453_405)?
865            .max_stacks(
866                data
867                    .require_aura_max_stacks(
868                        wowlab_types::sim::SpellIdx::from_raw(453_405),
869                    )?,
870            ),
871    )
872}
873fn aura_whirling_earth(
874    a: AuraDefinitionDraft,
875    data: &ResolvedGameData,
876) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
877    Ok(
878        a
879            .on_player()
880            .apply_base_from_data(data, 453_406)?
881            .max_stacks(
882                data
883                    .require_aura_max_stacks(
884                        wowlab_types::sim::SpellIdx::from_raw(453_406),
885                    )?,
886            ),
887    )
888}
889fn aura_whirling_air(
890    a: AuraDefinitionDraft,
891    data: &ResolvedGameData,
892) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
893    Ok(
894        a
895            .on_player()
896            .apply_base_from_data(data, 453_409)?
897            .max_stacks(
898                data
899                    .require_aura_max_stacks(
900                        wowlab_types::sim::SpellIdx::from_raw(453_409),
901                    )?,
902            ),
903    )
904}
905fn aura_totemic_rebound(
906    a: AuraDefinitionDraft,
907    data: &ResolvedGameData,
908) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
909    Ok(
910        a
911            .on_player()
912            .apply_base_from_data(data, 458_269)?
913            .max_stacks(
914                data
915                    .require_aura_max_stacks(
916                        wowlab_types::sim::SpellIdx::from_raw(458_269),
917                    )?,
918            ),
919    )
920}
921fn aura_maelstrom_weapon(
922    a: AuraDefinitionDraft,
923    data: &ResolvedGameData,
924) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
925    Ok(
926        a
927            .on_player()
928            .apply_base_from_data(data, 344_179)?
929            .max_stacks(
930                data
931                    .require_aura_max_stacks(
932                        wowlab_types::sim::SpellIdx::from_raw(344_179),
933                    )?,
934            ),
935    )
936}
937fn aura_hot_hand(
938    a: AuraDefinitionDraft,
939    data: &ResolvedGameData,
940) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
941    Ok(
942        a
943            .on_player()
944            .apply_base_from_data(data, 215_785)?
945            .max_stacks(
946                data
947                    .require_aura_max_stacks(
948                        wowlab_types::sim::SpellIdx::from_raw(215_785),
949                    )?,
950            ),
951    )
952}
953fn aura_stormsurge(
954    a: AuraDefinitionDraft,
955    data: &ResolvedGameData,
956) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
957    Ok(
958        a
959            .on_player()
960            .apply_base_from_data(data, 201_846)?
961            .max_stacks(
962                data
963                    .require_aura_max_stacks(
964                        wowlab_types::sim::SpellIdx::from_raw(201_846),
965                    )?,
966            ),
967    )
968}
969fn spell_stormstrike(
970    s: SpellDefinitionDraft,
971    data: &ResolvedGameData,
972) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
973    Ok(
974        s
975            .apply_base_from_data(data, 17364)?
976            .without_primary_data_damage()
977            .trigger_program_predicate(
978                1,
979                crate::hooks::enhancement_shaman::hook_owned_damage_trigger_disabled,
980            )
981            .trigger_program_predicate(
982                2,
983                crate::hooks::enhancement_shaman::hook_owned_damage_trigger_disabled,
984            )
985            .apply_aoe_from_data(data)
986            .on_cast(crate::hooks::enhancement_shaman::stormstrike_hook),
987    )
988}
989fn spell_lava_lash(
990    s: SpellDefinitionDraft,
991    data: &ResolvedGameData,
992) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
993    Ok(
994        s
995            .apply_base_from_data(data, 60103)?
996            .apply_aoe_from_data(data)
997            .on_cast(crate::hooks::enhancement_shaman::lava_lash_hook),
998    )
999}
1000fn spell_crash_lightning(
1001    s: SpellDefinitionDraft,
1002    data: &ResolvedGameData,
1003) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1004    Ok(
1005        s
1006            .apply_base_from_data(data, 187_874)?
1007            .applies_aura(AURA_CRASH_LIGHTNING)
1008            .apply_aoe_from_data(data)
1009            .on_cast(crate::hooks::enhancement_shaman::crash_lightning_hook)
1010            .cooldown_bypass_when_aura(AURA::STORM_UNLEASHED),
1011    )
1012}
1013fn spell_lightning_bolt(
1014    s: SpellDefinitionDraft,
1015    data: &ResolvedGameData,
1016) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1017    Ok(
1018        s
1019            .apply_base_from_data(data, 188_196)?
1020            .cast_time(
1021                wowlab_engine_combat::validated_milliseconds(
1022                    0.0,
1023                    188_196,
1024                    "spell.cast_time_ms",
1025                )?,
1026            )
1027            .apply_aoe_from_data(data)
1028            .on_cast(crate::hooks::enhancement_shaman::lightning_bolt_hook),
1029    )
1030}
1031fn spell_chain_lightning(
1032    s: SpellDefinitionDraft,
1033    data: &ResolvedGameData,
1034) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1035    Ok(
1036        s
1037            .apply_base_from_data(data, 188_443)?
1038            .apply_aoe_from_data(data)
1039            .on_cast(crate::hooks::enhancement_shaman::chain_lightning_hook),
1040    )
1041}
1042fn spell_flame_shock(
1043    s: SpellDefinitionDraft,
1044    data: &ResolvedGameData,
1045) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1046    Ok(
1047        s
1048            .apply_base_from_data(data, 188_389)?
1049            .applies_inferred_aura(AURA_FLAME_SHOCK, 188_389)
1050            .apply_aoe_from_data(data),
1051    )
1052}
1053fn spell_frost_shock(
1054    s: SpellDefinitionDraft,
1055    data: &ResolvedGameData,
1056) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1057    Ok(s.apply_base_from_data(data, 196_840)?.apply_aoe_from_data(data))
1058}
1059fn spell_sundering(
1060    s: SpellDefinitionDraft,
1061    data: &ResolvedGameData,
1062) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1063    Ok(
1064        s
1065            .apply_base_from_data(data, 197_214)?
1066            .damage_ap(
1067                data.ap_coef(wowlab_types::sim::SpellIdx::from_raw(197_214), 1),
1068                wowlab_engine_combat::DamageFlags::empty(),
1069            )
1070            .applies_aura(AURA_PRIMORDIAL_STORM)
1071            .apply_aoe_from_data(data)
1072            .on_cast(crate::hooks::enhancement_shaman::sundering_hook),
1073    )
1074}
1075fn spell_doom_winds(
1076    s: SpellDefinitionDraft,
1077    data: &ResolvedGameData,
1078) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1079    Ok(
1080        s
1081            .apply_base_from_data(data, 384_352)?
1082            .without_primary_data_damage()
1083            .apply_aoe_from_data(data)
1084            .on_cast(crate::hooks::enhancement_shaman::doom_winds_hook),
1085    )
1086}
1087fn spell_ascendance(
1088    s: SpellDefinitionDraft,
1089    data: &ResolvedGameData,
1090) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1091    Ok(
1092        s
1093            .apply_base_from_data(data, 114_051)?
1094            .applies_inferred_aura(AURA_ASCENDANCE, 114_051)
1095            .apply_aoe_from_data(data)
1096            .on_cast(crate::hooks::enhancement_shaman::ascendance_hook),
1097    )
1098}
1099fn spell_tempest(
1100    s: SpellDefinitionDraft,
1101    data: &ResolvedGameData,
1102) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1103    Ok(
1104        s
1105            .apply_base_from_data(data, 452_201)?
1106            .applies_aura(AURA_TEMPEST)
1107            .apply_aoe_from_data(data),
1108    )
1109}
1110fn spell_primordial_wave(
1111    s: SpellDefinitionDraft,
1112    data: &ResolvedGameData,
1113) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1114    Ok(s.apply_base_from_data(data, 375_982)?.apply_aoe_from_data(data))
1115}
1116fn spell_voltaic_blaze(
1117    s: SpellDefinitionDraft,
1118    data: &ResolvedGameData,
1119) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1120    Ok(
1121        s
1122            .apply_base_from_data(data, 470_057)?
1123            .damage_sp_from_data(
1124                wowlab_engine_domain::dbc::EffectLookup::new(
1125                    data,
1126                    wowlab_types::sim::EffectRef::new(
1127                        wowlab_types::sim::SpellIdx::from_raw(1_259_101),
1128                        1,
1129                    ),
1130                ),
1131            )?
1132            .applies_aura(AURA_FLAME_SHOCK)
1133            .guaranteed_crit()
1134            .apply_aoe_from_data(data)
1135            .on_cast(crate::hooks::enhancement_shaman::voltaic_blaze_hook),
1136    )
1137}
1138fn spell_skyfury(
1139    s: SpellDefinitionDraft,
1140    data: &ResolvedGameData,
1141) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1142    Ok(
1143        s
1144            .apply_base_from_data(data, 462_854)?
1145            .applies_inferred_aura(AURA_SKYFURY, 462_854)
1146            .apply_aoe_from_data(data),
1147    )
1148}
1149fn spell_lightning_shield(
1150    s: SpellDefinitionDraft,
1151    data: &ResolvedGameData,
1152) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1153    Ok(
1154        s
1155            .apply_base_from_data(data, 192_106)?
1156            .applies_inferred_aura(AURA_LIGHTNING_SHIELD, 192_106)
1157            .apply_aoe_from_data(data),
1158    )
1159}
1160fn spell_stormstrike_mh(
1161    s: SpellDefinitionDraft,
1162    data: &ResolvedGameData,
1163) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1164    Ok(s.apply_base_from_data(data, 32175)?.apply_aoe_from_data(data))
1165}
1166fn spell_stormstrike_offhand(
1167    s: SpellDefinitionDraft,
1168    data: &ResolvedGameData,
1169) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1170    Ok(s.apply_base_from_data(data, 32176)?.apply_aoe_from_data(data))
1171}
1172fn spell_sundering_splitstream(
1173    s: SpellDefinitionDraft,
1174    data: &ResolvedGameData,
1175) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1176    Ok(s.apply_base_from_data(data, 467_283)?.apply_aoe_from_data(data))
1177}
1178fn spell_stormblast(
1179    s: SpellDefinitionDraft,
1180    data: &ResolvedGameData,
1181) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1182    Ok(s.apply_base_from_data(data, 390_287)?.apply_aoe_from_data(data))
1183}
1184fn spell_crash_lightning_unleashed(
1185    s: SpellDefinitionDraft,
1186    data: &ResolvedGameData,
1187) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1188    Ok(s.apply_base_from_data(data, 1_252_431)?.apply_aoe_from_data(data))
1189}
1190fn spell_primordial_storm(
1191    s: SpellDefinitionDraft,
1192    data: &ResolvedGameData,
1193) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1194    Ok(
1195        s
1196            .apply_base_from_data(data, 1_218_090)?
1197            .without_primary_data_damage()
1198            .trigger_program_predicate(
1199                1,
1200                crate::hooks::enhancement_shaman::hook_owned_damage_trigger_disabled,
1201            )
1202            .trigger_program_predicate(
1203                2,
1204                crate::hooks::enhancement_shaman::hook_owned_damage_trigger_disabled,
1205            )
1206            .trigger_program_predicate(
1207                3,
1208                crate::hooks::enhancement_shaman::hook_owned_damage_trigger_disabled,
1209            )
1210            .applies_inferred_aura(AURA_PRIMORDIAL_STORM, 1_218_125)
1211            .apply_aoe_from_data(data)
1212            .on_cast(crate::hooks::enhancement_shaman::primordial_storm_hook),
1213    )
1214}
1215fn spell_primordial_fire(
1216    s: SpellDefinitionDraft,
1217    data: &ResolvedGameData,
1218) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1219    Ok(s.apply_base_from_data(data, 1_218_113)?.apply_aoe_from_data(data))
1220}
1221fn spell_primordial_frost(
1222    s: SpellDefinitionDraft,
1223    data: &ResolvedGameData,
1224) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1225    Ok(s.apply_base_from_data(data, 1_218_116)?.apply_aoe_from_data(data))
1226}
1227fn spell_primordial_lightning(
1228    s: SpellDefinitionDraft,
1229    data: &ResolvedGameData,
1230) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1231    Ok(s.apply_base_from_data(data, 1_218_118)?.apply_aoe_from_data(data))
1232}
1233fn spell_surging_totem(
1234    s: SpellDefinitionDraft,
1235    data: &ResolvedGameData,
1236) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1237    Ok(
1238        s
1239            .apply_base_from_data(data, 444_995)?
1240            .applies_aura(AURA_SURGING_TOTEM)
1241            .apply_aoe_from_data(data)
1242            .on_cast(crate::hooks::enhancement_shaman::surging_totem_hook),
1243    )
1244}
1245fn spell_tremor(
1246    s: SpellDefinitionDraft,
1247    data: &ResolvedGameData,
1248) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1249    Ok(s.apply_base_from_data(data, 455_622)?.apply_aoe_from_data(data))
1250}
1251fn spell_surging_bolt(
1252    s: SpellDefinitionDraft,
1253    data: &ResolvedGameData,
1254) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1255    Ok(s.apply_base_from_data(data, 458_267)?.apply_aoe_from_data(data))
1256}
1257fn spell_searing_bolt(
1258    s: SpellDefinitionDraft,
1259    data: &ResolvedGameData,
1260) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1261    Ok(s.apply_base_from_data(data, 3606)?.apply_aoe_from_data(data))
1262}
1263fn spell_searing_volley(
1264    s: SpellDefinitionDraft,
1265    data: &ResolvedGameData,
1266) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1267    Ok(s.apply_base_from_data(data, 458_147)?.apply_aoe_from_data(data))
1268}
1269fn spell_windfury_weapon(
1270    s: SpellDefinitionDraft,
1271    data: &ResolvedGameData,
1272) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1273    Ok(s.apply_base_from_data(data, 33757)?.apply_aoe_from_data(data))
1274}
1275fn spell_flametongue_weapon(
1276    s: SpellDefinitionDraft,
1277    data: &ResolvedGameData,
1278) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1279    Ok(s.apply_base_from_data(data, 318_038)?.apply_aoe_from_data(data))
1280}
1281fn spell_windfury_attack(
1282    s: SpellDefinitionDraft,
1283    data: &ResolvedGameData,
1284) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1285    Ok(s.apply_base_from_data(data, 25504)?.apply_aoe_from_data(data))
1286}
1287fn spell_flametongue_attack(
1288    s: SpellDefinitionDraft,
1289    data: &ResolvedGameData,
1290) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1291    Ok(s.apply_base_from_data(data, 10444)?.apply_aoe_from_data(data))
1292}
1293fn spell_flametongue_attack_imbuement_mastery(
1294    s: SpellDefinitionDraft,
1295    data: &ResolvedGameData,
1296) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1297    Ok(s.apply_base_from_data(data, 467_386)?.apply_aoe_from_data(data))
1298}
1299fn spell_maelstrom_weapon_driver(
1300    s: SpellDefinitionDraft,
1301    data: &ResolvedGameData,
1302) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1303    Ok(s.apply_base_from_data(data, 187_880)?.apply_aoe_from_data(data))
1304}
1305fn spell_hot_hand_driver(
1306    s: SpellDefinitionDraft,
1307    data: &ResolvedGameData,
1308) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1309    Ok(s.apply_base_from_data(data, 201_900)?.apply_aoe_from_data(data))
1310}
1311fn spell_stormsurge_driver(
1312    s: SpellDefinitionDraft,
1313    data: &ResolvedGameData,
1314) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1315    Ok(s.apply_base_from_data(data, 201_845)?.apply_aoe_from_data(data))
1316}
1317pub(crate) fn build_combat_system(
1318    params: &wowlab_engine_ports::HandlerParams<'_>,
1319) -> Result<BuiltCombatSystem, wowlab_engine_ports::EngineError> {
1320    let builder = BuiltCombatSystem::builder(params.stats.clone())
1321        .spec_id(SpecId::Enhancement)
1322        .hero_talent_trees(DECLARED_METADATA.hero_talent_trees)
1323        .mastery_spell(77223)
1324        .mastery_hook(crate::hooks::enhancement_shaman::mastery)
1325        .resource(
1326            "maelstrom",
1327            150.0,
1328            params
1329                .game_data
1330                .power_regen_for_max(11, 150.0)
1331                .ok_or_else(|| {
1332                    wowlab_engine_ports::EngineError::spec_construction(
1333                        "missing power-type power_regen_for_max for type_id 11",
1334                    )
1335                })?,
1336        )
1337        .resource_type_id(11)
1338        .resource_start(
1339            params
1340                .game_data
1341                .power_default(11)
1342                .ok_or_else(|| {
1343                    wowlab_engine_ports::EngineError::spec_construction(
1344                        "missing power-type power_default for type_id 11",
1345                    )
1346                })?,
1347        )
1348        .aura("ascendance", AURA::ASCENDANCE, |a| aura_ascendance(a, &params.game_data))
1349        .aura("doom_winds", AURA::DOOM_WINDS, |a| aura_doom_winds(a, &params.game_data))
1350        .aura(
1351            "storm_unleashed",
1352            AURA::STORM_UNLEASHED,
1353            |a| aura_storm_unleashed(a, &params.game_data),
1354        )
1355        .aura(
1356            "crash_lightning",
1357            AURA::CRASH_LIGHTNING,
1358            |a| aura_crash_lightning(a, &params.game_data),
1359        )
1360        .aura(
1361            "converging_storms",
1362            AURA::CONVERGING_STORMS,
1363            |a| aura_converging_storms(a, &params.game_data),
1364        )
1365        .aura(
1366            "molten_weapon",
1367            AURA::MOLTEN_WEAPON,
1368            |a| aura_molten_weapon(a, &params.game_data),
1369        )
1370        .aura(
1371            "crackling_surge",
1372            AURA::CRACKLING_SURGE,
1373            |a| aura_crackling_surge(a, &params.game_data),
1374        )
1375        .aura("tempest", AURA::TEMPEST, |a| aura_tempest(a, &params.game_data))
1376        .aura(
1377            "unlimited_power",
1378            AURA::UNLIMITED_POWER,
1379            |a| aura_unlimited_power(a, &params.game_data),
1380        )
1381        .aura(
1382            "flame_shock",
1383            AURA::FLAME_SHOCK,
1384            |a| aura_flame_shock(a, &params.game_data),
1385        )
1386        .aura(
1387            "lightning_shield",
1388            AURA::LIGHTNING_SHIELD,
1389            |a| aura_lightning_shield(a, &params.game_data),
1390        )
1391        .aura(
1392            "primordial_storm",
1393            AURA::PRIMORDIAL_STORM,
1394            |a| aura_primordial_storm(a, &params.game_data),
1395        )
1396        .aura(
1397            "overflowing_maelstrom",
1398            AURA::OVERFLOWING_MAELSTROM,
1399            |a| aura_overflowing_maelstrom(a, &params.game_data),
1400        )
1401        .aura(
1402            "lashing_flames",
1403            AURA::LASHING_FLAMES,
1404            |a| aura_lashing_flames(a, &params.game_data),
1405        )
1406        .aura("skyfury", AURA::SKYFURY, |a| aura_skyfury(a, &params.game_data))
1407        .aura(
1408            "skyfury_highlight",
1409            AURA::SKYFURY_HIGHLIGHT,
1410            |a| aura_skyfury_highlight(a, &params.game_data),
1411        )
1412        .aura(
1413            "thorims_invocation",
1414            AURA::THORIM_S_INVOCATION,
1415            |a| aura_thorim_s_invocation(a, &params.game_data),
1416        )
1417        .aura(
1418            "lively_totems",
1419            AURA::LIVELY_TOTEMS,
1420            |a| aura_lively_totems(a, &params.game_data),
1421        )
1422        .aura(
1423            "amplification_core",
1424            AURA::AMPLIFICATION_CORE,
1425            |a| aura_amplification_core(a, &params.game_data),
1426        )
1427        .aura(
1428            "surging_totem",
1429            AURA::SURGING_TOTEM,
1430            |a| aura_surging_totem(a, &params.game_data),
1431        )
1432        .aura(
1433            "whirling_fire",
1434            AURA::WHIRLING_FIRE,
1435            |a| aura_whirling_fire(a, &params.game_data),
1436        )
1437        .aura(
1438            "whirling_earth",
1439            AURA::WHIRLING_EARTH,
1440            |a| aura_whirling_earth(a, &params.game_data),
1441        )
1442        .aura(
1443            "whirling_air",
1444            AURA::WHIRLING_AIR,
1445            |a| aura_whirling_air(a, &params.game_data),
1446        )
1447        .aura(
1448            "totemic_rebound",
1449            AURA::TOTEMIC_REBOUND,
1450            |a| aura_totemic_rebound(a, &params.game_data),
1451        )
1452        .aura(
1453            "maelstrom_weapon",
1454            AURA::MAELSTROM_WEAPON,
1455            |a| aura_maelstrom_weapon(a, &params.game_data),
1456        )
1457        .aura("hot_hand", AURA::HOT_HAND, |a| aura_hot_hand(a, &params.game_data))
1458        .aura("stormsurge", AURA::STORMSURGE, |a| aura_stormsurge(a, &params.game_data))
1459        .spell(
1460            "stormstrike",
1461            SPELL::STORMSTRIKE,
1462            |s| spell_stormstrike(s, &params.game_data),
1463        )
1464        .spell("lava_lash", SPELL::LAVA_LASH, |s| spell_lava_lash(s, &params.game_data))
1465        .spell(
1466            "crash_lightning",
1467            SPELL::CRASH_LIGHTNING,
1468            |s| spell_crash_lightning(s, &params.game_data),
1469        )
1470        .spell(
1471            "lightning_bolt",
1472            SPELL::LIGHTNING_BOLT,
1473            |s| spell_lightning_bolt(s, &params.game_data),
1474        )
1475        .spell(
1476            "chain_lightning",
1477            SPELL::CHAIN_LIGHTNING,
1478            |s| spell_chain_lightning(s, &params.game_data),
1479        )
1480        .spell(
1481            "flame_shock",
1482            SPELL::FLAME_SHOCK,
1483            |s| spell_flame_shock(s, &params.game_data),
1484        )
1485        .spell(
1486            "frost_shock",
1487            SPELL::FROST_SHOCK,
1488            |s| spell_frost_shock(s, &params.game_data),
1489        )
1490        .spell("sundering", SPELL::SUNDERING, |s| spell_sundering(s, &params.game_data))
1491        .spell(
1492            "doom_winds",
1493            SPELL::DOOM_WINDS,
1494            |s| spell_doom_winds(s, &params.game_data),
1495        )
1496        .spell(
1497            "ascendance",
1498            SPELL::ASCENDANCE,
1499            |s| spell_ascendance(s, &params.game_data),
1500        )
1501        .spell("tempest", SPELL::TEMPEST, |s| spell_tempest(s, &params.game_data))
1502        .spell(
1503            "primordial_wave",
1504            SPELL::PRIMORDIAL_WAVE,
1505            |s| spell_primordial_wave(s, &params.game_data),
1506        )
1507        .spell(
1508            "voltaic_blaze",
1509            SPELL::VOLTAIC_BLAZE,
1510            |s| spell_voltaic_blaze(s, &params.game_data),
1511        )
1512        .spell("skyfury", SPELL::SKYFURY, |s| spell_skyfury(s, &params.game_data))
1513        .spell(
1514            "lightning_shield",
1515            SPELL::LIGHTNING_SHIELD,
1516            |s| spell_lightning_shield(s, &params.game_data),
1517        )
1518        .spell(
1519            "stormstrike_mh",
1520            SPELL::STORMSTRIKE_MH,
1521            |s| spell_stormstrike_mh(s, &params.game_data),
1522        )
1523        .spell(
1524            "stormstrike_offhand",
1525            SPELL::STORMSTRIKE_OFFHAND,
1526            |s| spell_stormstrike_offhand(s, &params.game_data),
1527        )
1528        .spell(
1529            "sundering_splitstream",
1530            SPELL::SUNDERING_SPLITSTREAM,
1531            |s| spell_sundering_splitstream(s, &params.game_data),
1532        )
1533        .spell(
1534            "stormblast",
1535            SPELL::STORMBLAST,
1536            |s| spell_stormblast(s, &params.game_data),
1537        )
1538        .spell(
1539            "crash_lightning_unleashed",
1540            SPELL::CRASH_LIGHTNING_UNLEASHED,
1541            |s| spell_crash_lightning_unleashed(s, &params.game_data),
1542        )
1543        .spell(
1544            "primordial_storm",
1545            SPELL::PRIMORDIAL_STORM,
1546            |s| spell_primordial_storm(s, &params.game_data),
1547        )
1548        .spell(
1549            "primordial_fire",
1550            SPELL::PRIMORDIAL_FIRE,
1551            |s| spell_primordial_fire(s, &params.game_data),
1552        )
1553        .spell(
1554            "primordial_frost",
1555            SPELL::PRIMORDIAL_FROST,
1556            |s| spell_primordial_frost(s, &params.game_data),
1557        )
1558        .spell(
1559            "primordial_lightning",
1560            SPELL::PRIMORDIAL_LIGHTNING,
1561            |s| spell_primordial_lightning(s, &params.game_data),
1562        )
1563        .spell(
1564            "surging_totem",
1565            SPELL::SURGING_TOTEM,
1566            |s| spell_surging_totem(s, &params.game_data),
1567        )
1568        .spell("tremor", SPELL::TREMOR, |s| spell_tremor(s, &params.game_data))
1569        .spell(
1570            "surging_bolt",
1571            SPELL::SURGING_BOLT,
1572            |s| spell_surging_bolt(s, &params.game_data),
1573        )
1574        .spell(
1575            "searing_bolt",
1576            SPELL::SEARING_BOLT,
1577            |s| spell_searing_bolt(s, &params.game_data),
1578        )
1579        .spell(
1580            "searing_volley",
1581            SPELL::SEARING_VOLLEY,
1582            |s| spell_searing_volley(s, &params.game_data),
1583        )
1584        .spell(
1585            "windfury_weapon",
1586            SPELL::WINDFURY_WEAPON,
1587            |s| spell_windfury_weapon(s, &params.game_data),
1588        )
1589        .spell(
1590            "flametongue_weapon",
1591            SPELL::FLAMETONGUE_WEAPON,
1592            |s| spell_flametongue_weapon(s, &params.game_data),
1593        )
1594        .spell(
1595            "windfury_attack",
1596            SPELL::WINDFURY_ATTACK,
1597            |s| spell_windfury_attack(s, &params.game_data),
1598        )
1599        .spell(
1600            "flametongue_attack",
1601            SPELL::FLAMETONGUE_ATTACK,
1602            |s| spell_flametongue_attack(s, &params.game_data),
1603        )
1604        .spell(
1605            "flametongue_attack_imbuement_mastery",
1606            SPELL::FLAMETONGUE_ATTACK_IMBUEMENT_MASTERY,
1607            |s| spell_flametongue_attack_imbuement_mastery(s, &params.game_data),
1608        )
1609        .spell(
1610            "maelstrom_weapon_driver",
1611            SPELL::MAELSTROM_WEAPON_DRIVER,
1612            |s| spell_maelstrom_weapon_driver(s, &params.game_data),
1613        )
1614        .spell(
1615            "hot_hand_driver",
1616            SPELL::HOT_HAND_DRIVER,
1617            |s| spell_hot_hand_driver(s, &params.game_data),
1618        )
1619        .spell(
1620            "stormsurge_driver",
1621            SPELL::STORMSURGE_DRIVER,
1622            |s| spell_stormsurge_driver(s, &params.game_data),
1623        )
1624        .auto_attack(|a| {
1625            a
1626                .spell_id(6603)
1627                .swing_ms(2600)
1628                .apply_base_from_data(&params.game_data)
1629                .on_swing(crate::hooks::enhancement_shaman::swing_hook)
1630        })
1631        .auto_attack(|a| {
1632            a
1633                .spell_id(6603)
1634                .swing_ms(2600)
1635                .apply_base_from_data(&params.game_data)
1636                .on_swing(crate::hooks::enhancement_shaman::swing_hook)
1637        })
1638        .game_data(params.game_data.clone())
1639        .talent_spell_ids(TALENTS)
1640        .talent_selections(params.talent_selections)
1641        .set_bonus_auras(params.set_bonus_auras)
1642        .encounter(params.encounter.clone());
1643    let builder = crate::generated::items::register_equipped(
1644        builder,
1645        &params.game_data,
1646        params.equipped_items,
1647    )?;
1648
1649    builder
1650        .build(params.rotation)
1651        .map_err(wowlab_engine_ports::EngineError::rotation_compile)
1652}
1653fn new_handler(
1654    params: wowlab_engine_ports::HandlerParams<'_>,
1655) -> Result<Box<dyn SpecHandler>, wowlab_engine_ports::EngineError> {
1656    let handler = crate::composition::compose_handler(
1657        build_combat_system,
1658        &params,
1659        crate::hooks::enhancement_shaman::EnhancementHandler::try_new,
1660    )?;
1661
1662    Ok(Box::new(handler))
1663}
1664static DECLARED_METADATA: DeclaredSpecMetadata = DeclaredSpecMetadata {
1665    primary_resource: ResourceType::Maelstrom,
1666    secondary_resource: None,
1667    spell_ids: DECLARED_SPELL_IDS,
1668    aura_ids: DECLARED_AURA_IDS,
1669    server_proc_entries: &[
1670        DeclaredServerProcEntry {
1671            spell_id: 198_300,
1672            attributes: ProcAttributes::USE_STACKS_FOR_CHARGES.bits(),
1673        },
1674    ],
1675    talents: TALENTS,
1676    rotation_field_schema: &[],
1677    metrics_plugin_id: None,
1678    hero_talent_trees: &[
1679        HeroTalentTreeDesc {
1680            name: "Stormbringer",
1681            spells: HERO_TREE_STORMBRINGER_SPELLS,
1682            auras: HERO_TREE_STORMBRINGER_AURAS,
1683        },
1684        HeroTalentTreeDesc {
1685            name: "Totemic",
1686            spells: HERO_TREE_TOTEMIC_SPELLS,
1687            auras: HERO_TREE_TOTEMIC_AURAS,
1688        },
1689    ],
1690    reported_spells: REPORTED_SPELLS,
1691    masked_passive_effects: &[],
1692    passive_effect_overrides: &[
1693        wowlab_engine_ports::DeclaredPassiveEffectOverride {
1694            spell_id: 1_251_026,
1695            effect: 2,
1696            source: Some((1_251_026, 2)),
1697            value: 0.0,
1698            multiplier: 0.5,
1699        },
1700    ],
1701};
1702pub(super) const SPEC_DESCRIPTOR: SpecDescriptor = SpecDescriptor {
1703    spec_id: SpecId::Enhancement,
1704    display_name: "Enhancement Shaman",
1705    metadata: DECLARED_METADATA,
1706    handler_factory: new_handler,
1707};
1708wowlab_engine_combat::smoke_test!(build_combat_system);