Skip to main content

wowlab_engine_content/generated/specs/
balance_druid.rs

1//! @generated by codegen-cli from manifests/specs/druid/balance/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/24858>
17    pub(crate) const MOONKIN_FORM: u32 = 24858;
18    ///<https://wowlab.gg/inspect/spell/1126>
19    pub(crate) const MARK_OF_THE_WILD: u32 = 1126;
20    ///<https://wowlab.gg/inspect/spell/190984>
21    pub(crate) const WRATH: u32 = 190_984;
22    ///<https://wowlab.gg/inspect/spell/194153>
23    pub(crate) const STARFIRE: u32 = 194_153;
24    ///<https://wowlab.gg/inspect/spell/1233346>
25    pub(crate) const SOLAR_ECLIPSE: u32 = 1_233_346;
26    ///<https://wowlab.gg/inspect/spell/194223>
27    pub(crate) const CELESTIAL_ALIGNMENT: u32 = 194_223;
28    ///<https://wowlab.gg/inspect/spell/102560>
29    pub(crate) const INCARNATION_CHOSEN_OF_ELUNE: u32 = 102_560;
30    ///<https://wowlab.gg/inspect/spell/8921>
31    pub(crate) const MOONFIRE: u32 = 8921;
32    ///<https://wowlab.gg/inspect/spell/93402>
33    pub(crate) const SUNFIRE: u32 = 93402;
34    ///<https://wowlab.gg/inspect/spell/78674>
35    pub(crate) const STARSURGE: u32 = 78674;
36    ///<https://wowlab.gg/inspect/spell/191034>
37    pub(crate) const STARFALL: u32 = 191_034;
38    ///<https://wowlab.gg/inspect/spell/274281>
39    pub(crate) const NEW_MOON: u32 = 274_281;
40    ///<https://wowlab.gg/inspect/spell/202770>
41    pub(crate) const FURY_OF_ELUNE: u32 = 202_770;
42    ///<https://wowlab.gg/inspect/spell/205636>
43    pub(crate) const FORCE_OF_NATURE: u32 = 205_636;
44    ///<https://wowlab.gg/inspect/spell/391528>
45    pub(crate) const CONVOKE_THE_SPIRITS: u32 = 391_528;
46    ///<https://wowlab.gg/inspect/spell/88747>
47    pub(crate) const WILD_MUSHROOM: u32 = 88747;
48}
49pub(crate) mod AURA {
50    ///<https://wowlab.gg/inspect/spell/24858>
51    pub(crate) const MOONKIN_FORM: u32 = 24858;
52    ///<https://wowlab.gg/inspect/spell/1126>
53    pub(crate) const MARK_OF_THE_WILD_HIGHLIGHT: u32 = 1126;
54    ///<https://wowlab.gg/inspect/spell/428737>
55    pub(crate) const HARMONY_OF_THE_GROVE: u32 = 428_737;
56    ///<https://wowlab.gg/inspect/spell/433831>
57    pub(crate) const DREAM_SURGE: u32 = 433_831;
58    ///<https://wowlab.gg/inspect/spell/430589>
59    pub(crate) const ATMOSPHERIC_EXPOSURE: u32 = 430_589;
60    ///<https://wowlab.gg/inspect/spell/48517>
61    pub(crate) const ECLIPSE_SOLAR: u32 = 48517;
62    ///<https://wowlab.gg/inspect/spell/48518>
63    pub(crate) const ECLIPSE_LUNAR: u32 = 48518;
64    ///<https://wowlab.gg/inspect/spell/194223>
65    pub(crate) const CELESTIAL_ALIGNMENT: u32 = 194_223;
66    ///<https://wowlab.gg/inspect/spell/102560>
67    pub(crate) const INCARNATION_CHOSEN_OF_ELUNE: u32 = 102_560;
68    ///<https://wowlab.gg/inspect/spell/1233353>
69    pub(crate) const LUNAR_ECLIPSE_OVERRIDE: u32 = 1_233_353;
70    ///<https://wowlab.gg/inspect/spell/1239669>
71    pub(crate) const ECLIPSE: u32 = 1_239_669;
72    ///<https://wowlab.gg/inspect/spell/429523>
73    pub(crate) const LUNAR_CALLING: u32 = 429_523;
74    ///<https://wowlab.gg/inspect/spell/450346>
75    pub(crate) const DREAMSTATE: u32 = 450_346;
76    ///<https://wowlab.gg/inspect/spell/164812>
77    pub(crate) const MOONFIRE: u32 = 164_812;
78    ///<https://wowlab.gg/inspect/spell/164815>
79    pub(crate) const SUNFIRE: u32 = 164_815;
80    ///<https://wowlab.gg/inspect/spell/191034>
81    pub(crate) const STARFALL: u32 = 191_034;
82    ///<https://wowlab.gg/inspect/spell/279709>
83    pub(crate) const STARLORD: u32 = 279_709;
84    ///<https://wowlab.gg/inspect/spell/393942>
85    pub(crate) const STARWEAVER_S_WARP: u32 = 393_942;
86    ///<https://wowlab.gg/inspect/spell/393944>
87    pub(crate) const STARWEAVER_S_WEFT: u32 = 393_944;
88    ///<https://wowlab.gg/inspect/spell/450360>
89    pub(crate) const TOUCH_THE_COSMOS: u32 = 450_360;
90    ///<https://wowlab.gg/inspect/spell/343648>
91    pub(crate) const SOLSTICE: u32 = 343_648;
92    ///<https://wowlab.gg/inspect/spell/450214>
93    pub(crate) const STELLAR_AMPLIFICATION: u32 = 450_214;
94    ///<https://wowlab.gg/inspect/spell/394050>
95    pub(crate) const BOAT_ARCANE: u32 = 394_050;
96    ///<https://wowlab.gg/inspect/spell/394049>
97    pub(crate) const BOAT_NATURE: u32 = 394_049;
98    ///<https://wowlab.gg/inspect/spell/81281>
99    pub(crate) const FUNGAL_GROWTH: u32 = 81281;
100    ///<https://wowlab.gg/inspect/spell/202430>
101    pub(crate) const NATURES_BALANCE: u32 = 202_430;
102    ///<https://wowlab.gg/inspect/spell/202770>
103    pub(crate) const FURY_OF_ELUNE_ENERGIZE: u32 = 202_770;
104    ///<https://wowlab.gg/inspect/spell/211545>
105    pub(crate) const FURY_OF_ELUNE_BEAM: u32 = 211_545;
106    ///<https://wowlab.gg/inspect/spell/394108>
107    pub(crate) const SUNDERED_FIRMAMENT_ENERGIZE: u32 = 394_108;
108    ///<https://wowlab.gg/inspect/spell/394111>
109    pub(crate) const SUNDERED_FIRMAMENT_BEAM: u32 = 394_111;
110    ///<https://wowlab.gg/inspect/spell/468938>
111    pub(crate) const SUNSEEKER_MUSHROOM_DRIVER: u32 = 468_938;
112}
113pub(crate) mod TALENT {
114    ///<https://wowlab.gg/inspect/spell/1261565>
115    pub(crate) const ASCENDANT_ECLIPSES_2: u32 = 1_261_565;
116    ///<https://wowlab.gg/inspect/spell/429532>
117    pub(crate) const ATMOSPHERIC_EXPOSURE: u32 = 429_532;
118    ///<https://wowlab.gg/inspect/spell/394048>
119    pub(crate) const BALANCE_OF_ALL_THINGS: u32 = 394_048;
120    ///<https://wowlab.gg/inspect/spell/391528>
121    pub(crate) const CONVOKE_THE_SPIRITS: u32 = 391_528;
122    ///<https://wowlab.gg/inspect/spell/1239669>
123    pub(crate) const ECLIPSE: u32 = 1_239_669;
124    ///<https://wowlab.gg/inspect/spell/205636>
125    pub(crate) const FORCE_OF_NATURE: u32 = 205_636;
126    ///<https://wowlab.gg/inspect/spell/202770>
127    pub(crate) const FURY_OF_ELUNE: u32 = 202_770;
128    ///<https://wowlab.gg/inspect/spell/469004>
129    pub(crate) const HAIL_OF_STARS: u32 = 469_004;
130    ///<https://wowlab.gg/inspect/spell/1240906>
131    pub(crate) const IMPROVED_ECLIPSE: u32 = 1_240_906;
132    ///<https://wowlab.gg/inspect/spell/102560>
133    pub(crate) const INCARNATION_CHOSEN_OF_ELUNE: u32 = 102_560;
134    ///<https://wowlab.gg/inspect/spell/429523>
135    pub(crate) const LUNAR_CALLING: u32 = 429_523;
136    ///<https://wowlab.gg/inspect/spell/429520>
137    pub(crate) const MOON_GUARDIAN: u32 = 429_520;
138    ///<https://wowlab.gg/inspect/spell/202430>
139    pub(crate) const NATURE_S_BALANCE: u32 = 202_430;
140    ///<https://wowlab.gg/inspect/spell/274281>
141    pub(crate) const NEW_MOON: u32 = 274_281;
142    ///<https://wowlab.gg/inspect/spell/394046>
143    pub(crate) const POWER_OF_GOLDRINN: u32 = 394_046;
144    ///<https://wowlab.gg/inspect/spell/393954>
145    pub(crate) const RATTLE_THE_STARS: u32 = 393_954;
146    ///<https://wowlab.gg/inspect/spell/202342>
147    pub(crate) const SHOOTING_STARS: u32 = 202_342;
148    ///<https://wowlab.gg/inspect/spell/343647>
149    pub(crate) const SOLSTICE: u32 = 343_647;
150    ///<https://wowlab.gg/inspect/spell/202345>
151    pub(crate) const STARLORD: u32 = 202_345;
152    ///<https://wowlab.gg/inspect/spell/393940>
153    pub(crate) const STARWEAVER: u32 = 393_940;
154    ///<https://wowlab.gg/inspect/spell/1271206>
155    pub(crate) const STAR_CASCADE: u32 = 1_271_206;
156    ///<https://wowlab.gg/inspect/spell/450212>
157    pub(crate) const STELLAR_AMPLIFICATION: u32 = 450_212;
158    ///<https://wowlab.gg/inspect/spell/394094>
159    pub(crate) const SUNDERED_FIRMAMENT: u32 = 394_094;
160    ///<https://wowlab.gg/inspect/spell/468936>
161    pub(crate) const SUNSEEKER_MUSHROOM: u32 = 468_936;
162    ///<https://wowlab.gg/inspect/spell/450356>
163    pub(crate) const TOUCH_THE_COSMOS: u32 = 450_356;
164    ///<https://wowlab.gg/inspect/spell/393760>
165    pub(crate) const UMBRAL_EMBRACE: u32 = 393_760;
166    ///<https://wowlab.gg/inspect/spell/468743>
167    pub(crate) const WHIRLING_STARS: u32 = 468_743;
168    ///<https://wowlab.gg/inspect/spell/88747>
169    pub(crate) const WILD_MUSHROOM: u32 = 88747;
170    ///<https://wowlab.gg/inspect/spell/406890>
171    pub(crate) const WILD_SURGES: u32 = 406_890;
172}
173pub(crate) mod SET_BONUS {
174    ///<https://wowlab.gg/inspect/spell/1264810>
175    pub(crate) const MID1_BALANCE_2PC: u32 = 1_264_810;
176    ///<https://wowlab.gg/inspect/spell/1264811>
177    pub(crate) const MID1_BALANCE_4PC: u32 = 1_264_811;
178}
179pub(crate) mod REPORTED_SPELL {
180    ///<https://wowlab.gg/inspect/spell/1263250>
181    pub(crate) const ASTRAL_SMOLDER: u32 = 1_263_250;
182    ///<https://wowlab.gg/inspect/spell/1272339>
183    pub(crate) const EXPLODING_STAR: u32 = 1_272_339;
184    ///<https://wowlab.gg/inspect/spell/1280213>
185    pub(crate) const FUNGAL_GROWTH: u32 = 1_280_213;
186    ///<https://wowlab.gg/inspect/spell/394047>
187    pub(crate) const GOLDRINN: u32 = 394_047;
188    ///<https://wowlab.gg/inspect/spell/164812>
189    pub(crate) const MOONFIRE_PERIODIC: u32 = 164_812;
190    ///<https://wowlab.gg/inspect/spell/202497>
191    pub(crate) const SHOOTING_STARS: u32 = 202_497;
192    ///<https://wowlab.gg/inspect/spell/1271222>
193    pub(crate) const STARSURGE_CASCADE: u32 = 1_271_222;
194    ///<https://wowlab.gg/inspect/spell/164815>
195    pub(crate) const SUNFIRE_PERIODIC: u32 = 164_815;
196    ///<https://wowlab.gg/inspect/spell/1280212>
197    pub(crate) const SUNSEEKER_MUSHROOM: u32 = 1_280_212;
198    ///<https://wowlab.gg/inspect/spell/88751>
199    pub(crate) const WILD_MUSHROOM: u32 = 88751;
200}
201pub(crate) mod HERO {
202    pub(crate) mod KEEPER_OF_THE_GROVE {
203        pub(crate) mod SPELL {
204            ///<https://wowlab.gg/inspect/spell/433850>
205            pub(crate) const DREAM_BURST: u32 = 433_850;
206            ///<https://wowlab.gg/inspect/spell/205636>
207            pub(crate) const FORCE_OF_NATURE: u32 = 205_636;
208        }
209        pub(crate) mod AURA {
210            ///<https://wowlab.gg/inspect/spell/429433>
211            pub(crate) const BLOOMING_INFUSION: u32 = 429_433;
212            ///<https://wowlab.gg/inspect/spell/455801>
213            pub(crate) const CENARIUS_MIGHT: u32 = 455_801;
214            ///<https://wowlab.gg/inspect/spell/433831>
215            pub(crate) const DREAM_SURGE: u32 = 433_831;
216            ///<https://wowlab.gg/inspect/spell/428737>
217            pub(crate) const HARMONY_OF_THE_GROVE: u32 = 428_737;
218        }
219    }
220    pub(crate) mod ELUNES_CHOSEN {
221        pub(crate) mod SPELL {
222            ///<https://wowlab.gg/inspect/spell/1261700>
223            pub(crate) const LUNAR_BOLT: u32 = 1_261_700;
224            ///<https://wowlab.gg/inspect/spell/361237>
225            pub(crate) const ORBITAL_STRIKE: u32 = 361_237;
226            ///<https://wowlab.gg/inspect/spell/1261573>
227            pub(crate) const SOLAR_BOLT: u32 = 1_261_573;
228        }
229        pub(crate) mod AURA {
230            ///<https://wowlab.gg/inspect/spell/1263363>
231            pub(crate) const ASCENDANT_FIRES: u32 = 1_263_363;
232            ///<https://wowlab.gg/inspect/spell/1263382>
233            pub(crate) const ASCENDANT_STARS: u32 = 1_263_382;
234            ///<https://wowlab.gg/inspect/spell/430589>
235            pub(crate) const ATMOSPHERIC_EXPOSURE: u32 = 430_589;
236            ///<https://wowlab.gg/inspect/spell/429523>
237            pub(crate) const LUNAR_CALLING: u32 = 429_523;
238            ///<https://wowlab.gg/inspect/spell/395110>
239            pub(crate) const PARTING_SKIES: u32 = 395_110;
240        }
241    }
242}
243static HERO_TREE_KEEPER_OF_THE_GROVE_SPELLS: &[(&str, u32)] = &[
244    ("DREAM_BURST", 433_850),
245    ("FORCE_OF_NATURE", 205_636),
246];
247static HERO_TREE_KEEPER_OF_THE_GROVE_AURAS: &[(&str, u32)] = &[
248    ("BLOOMING_INFUSION", 429_433),
249    ("CENARIUS_MIGHT", 455_801),
250    ("DREAM_SURGE", 433_831),
251    ("HARMONY_OF_THE_GROVE", 428_737),
252];
253static HERO_TREE_ELUNES_CHOSEN_SPELLS: &[(&str, u32)] = &[
254    ("LUNAR_BOLT", 1_261_700),
255    ("ORBITAL_STRIKE", 361_237),
256    ("SOLAR_BOLT", 1_261_573),
257];
258static HERO_TREE_ELUNES_CHOSEN_AURAS: &[(&str, u32)] = &[
259    ("ASCENDANT_FIRES", 1_263_363),
260    ("ASCENDANT_STARS", 1_263_382),
261    ("ATMOSPHERIC_EXPOSURE", 430_589),
262    ("LUNAR_CALLING", 429_523),
263    ("PARTING_SKIES", 395_110),
264];
265pub(crate) const AURA_MOONKIN_FORM: LocalAuraIdx = LocalAuraIdx::new(0);
266pub(crate) const AURA_MARK_OF_THE_WILD_HIGHLIGHT: LocalAuraIdx = LocalAuraIdx::new(1);
267pub(crate) const AURA_HARMONY_OF_THE_GROVE: LocalAuraIdx = LocalAuraIdx::new(2);
268pub(crate) const AURA_DREAM_SURGE: LocalAuraIdx = LocalAuraIdx::new(3);
269pub(crate) const AURA_ATMOSPHERIC_EXPOSURE: LocalAuraIdx = LocalAuraIdx::new(4);
270pub(crate) const AURA_ECLIPSE_SOLAR: LocalAuraIdx = LocalAuraIdx::new(5);
271pub(crate) const AURA_ECLIPSE_LUNAR: LocalAuraIdx = LocalAuraIdx::new(6);
272pub(crate) const AURA_CELESTIAL_ALIGNMENT: LocalAuraIdx = LocalAuraIdx::new(7);
273pub(crate) const AURA_INCARNATION_CHOSEN_OF_ELUNE: LocalAuraIdx = LocalAuraIdx::new(8);
274pub(crate) const AURA_LUNAR_ECLIPSE_OVERRIDE: LocalAuraIdx = LocalAuraIdx::new(9);
275pub(crate) const AURA_ECLIPSE: LocalAuraIdx = LocalAuraIdx::new(10);
276pub(crate) const AURA_LUNAR_CALLING: LocalAuraIdx = LocalAuraIdx::new(11);
277pub(crate) const AURA_DREAMSTATE: LocalAuraIdx = LocalAuraIdx::new(12);
278pub(crate) const AURA_MOONFIRE: LocalAuraIdx = LocalAuraIdx::new(13);
279pub(crate) const AURA_SUNFIRE: LocalAuraIdx = LocalAuraIdx::new(14);
280pub(crate) const AURA_STARFALL: LocalAuraIdx = LocalAuraIdx::new(15);
281pub(crate) const AURA_STARLORD: LocalAuraIdx = LocalAuraIdx::new(16);
282pub(crate) const AURA_STARWEAVER_S_WARP: LocalAuraIdx = LocalAuraIdx::new(17);
283pub(crate) const AURA_STARWEAVER_S_WEFT: LocalAuraIdx = LocalAuraIdx::new(18);
284pub(crate) const AURA_TOUCH_THE_COSMOS: LocalAuraIdx = LocalAuraIdx::new(19);
285pub(crate) const AURA_SOLSTICE: LocalAuraIdx = LocalAuraIdx::new(20);
286pub(crate) const AURA_STELLAR_AMPLIFICATION: LocalAuraIdx = LocalAuraIdx::new(21);
287pub(crate) const AURA_BOAT_ARCANE: LocalAuraIdx = LocalAuraIdx::new(22);
288pub(crate) const AURA_BOAT_NATURE: LocalAuraIdx = LocalAuraIdx::new(23);
289pub(crate) const AURA_FUNGAL_GROWTH: LocalAuraIdx = LocalAuraIdx::new(24);
290pub(crate) const AURA_NATURES_BALANCE: LocalAuraIdx = LocalAuraIdx::new(25);
291pub(crate) const AURA_FURY_OF_ELUNE_ENERGIZE: LocalAuraIdx = LocalAuraIdx::new(26);
292pub(crate) const AURA_FURY_OF_ELUNE_BEAM: LocalAuraIdx = LocalAuraIdx::new(27);
293pub(crate) const AURA_SUNDERED_FIRMAMENT_ENERGIZE: LocalAuraIdx = LocalAuraIdx::new(28);
294pub(crate) const AURA_SUNDERED_FIRMAMENT_BEAM: LocalAuraIdx = LocalAuraIdx::new(29);
295pub(crate) const AURA_SUNSEEKER_MUSHROOM_DRIVER: LocalAuraIdx = LocalAuraIdx::new(30);
296pub(crate) const AURA_COUNT: usize = 31;
297const _: () = assert!(
298    AURA_COUNT == 31, "AURA index ABI: count changed -- update positional hook consumers"
299);
300pub(crate) const SPELL_MOONKIN_FORM: LocalSpellIdx = LocalSpellIdx::new(0);
301pub(crate) const SPELL_MARK_OF_THE_WILD: LocalSpellIdx = LocalSpellIdx::new(1);
302pub(crate) const SPELL_WRATH: LocalSpellIdx = LocalSpellIdx::new(2);
303pub(crate) const SPELL_STARFIRE: LocalSpellIdx = LocalSpellIdx::new(3);
304pub(crate) const SPELL_SOLAR_ECLIPSE: LocalSpellIdx = LocalSpellIdx::new(4);
305pub(crate) const SPELL_CELESTIAL_ALIGNMENT: LocalSpellIdx = LocalSpellIdx::new(5);
306pub(crate) const SPELL_INCARNATION_CHOSEN_OF_ELUNE: LocalSpellIdx = LocalSpellIdx::new(
307    6,
308);
309pub(crate) const SPELL_MOONFIRE: LocalSpellIdx = LocalSpellIdx::new(7);
310pub(crate) const SPELL_SUNFIRE: LocalSpellIdx = LocalSpellIdx::new(8);
311pub(crate) const SPELL_STARSURGE: LocalSpellIdx = LocalSpellIdx::new(9);
312pub(crate) const SPELL_STARFALL: LocalSpellIdx = LocalSpellIdx::new(10);
313pub(crate) const SPELL_NEW_MOON: LocalSpellIdx = LocalSpellIdx::new(11);
314pub(crate) const SPELL_FURY_OF_ELUNE: LocalSpellIdx = LocalSpellIdx::new(12);
315pub(crate) const SPELL_FORCE_OF_NATURE: LocalSpellIdx = LocalSpellIdx::new(13);
316pub(crate) const SPELL_CONVOKE_THE_SPIRITS: LocalSpellIdx = LocalSpellIdx::new(14);
317pub(crate) const SPELL_WILD_MUSHROOM: LocalSpellIdx = LocalSpellIdx::new(15);
318pub(crate) const SPELL_COUNT: usize = 16;
319const _: () = assert!(
320    SPELL_COUNT == 16,
321    "SPELL index ABI: count changed -- update positional hook consumers"
322);
323pub(crate) mod EFFECT {
324    ///<https://wowlab.gg/inspect/spell/393014>
325    pub(crate) const ASTRAL_INVOCATION_ARCANE_DIRECT: (u32, u8) = (393_014, 1);
326    ///<https://wowlab.gg/inspect/spell/393014>
327    pub(crate) const ASTRAL_INVOCATION_ARCANE_PERIODIC: (u32, u8) = (393_014, 2);
328    ///<https://wowlab.gg/inspect/spell/393014>
329    pub(crate) const ASTRAL_INVOCATION_NATURE_DIRECT: (u32, u8) = (393_014, 3);
330    ///<https://wowlab.gg/inspect/spell/393014>
331    pub(crate) const ASTRAL_INVOCATION_NATURE_PERIODIC: (u32, u8) = (393_014, 4);
332    ///<https://wowlab.gg/inspect/spell/197911>
333    pub(crate) const ASTRAL_POWER_WRATH_AP: (u32, u8) = (197_911, 2);
334    ///<https://wowlab.gg/inspect/spell/1261565>
335    pub(crate) const ASTRAL_SMOLDER_PCT: (u32, u8) = (1_261_565, 1);
336    ///<https://wowlab.gg/inspect/spell/1272339>
337    pub(crate) const EXPLODING_STAR_AP: (u32, u8) = (1_272_339, 2);
338    ///<https://wowlab.gg/inspect/spell/1272339>
339    pub(crate) const EXPLODING_STAR_DMG: (u32, u8) = (1_272_339, 1);
340    ///<https://wowlab.gg/inspect/spell/1280213>
341    pub(crate) const FUNGAL_GROWTH_SUNSEEKER: (u32, u8) = (1_280_213, 1);
342    ///<https://wowlab.gg/inspect/spell/394047>
343    pub(crate) const GOLDRINN_DMG: (u32, u8) = (394_047, 1);
344    ///<https://wowlab.gg/inspect/spell/469004>
345    pub(crate) const HAIL_OF_STARS_MS: (u32, u8) = (469_004, 1);
346    ///<https://wowlab.gg/inspect/spell/1264810>
347    pub(crate) const MID1_2PC_AP: (u32, u8) = (1_264_810, 2);
348    ///<https://wowlab.gg/inspect/spell/1264811>
349    pub(crate) const MID1_4PC_EXPLODING_CHANCE: (u32, u8) = (1_264_811, 2);
350    ///<https://wowlab.gg/inspect/spell/429520>
351    pub(crate) const MOON_GUARDIAN_AP: (u32, u8) = (429_520, 1);
352    ///<https://wowlab.gg/inspect/spell/202430>
353    pub(crate) const NATURES_BALANCE_START: (u32, u8) = (202_430, 2);
354    ///<https://wowlab.gg/inspect/spell/393954>
355    pub(crate) const RATTLE_COST_PCT: (u32, u8) = (393_954, 2);
356    ///<https://wowlab.gg/inspect/spell/202497>
357    pub(crate) const SHOOTING_STARS_AP: (u32, u8) = (202_497, 2);
358    ///<https://wowlab.gg/inspect/spell/202342>
359    pub(crate) const SHOOTING_STARS_CHANCE: (u32, u8) = (202_342, 1);
360    ///<https://wowlab.gg/inspect/spell/202497>
361    pub(crate) const SHOOTING_STARS_DMG: (u32, u8) = (202_497, 1);
362    ///<https://wowlab.gg/inspect/spell/191037>
363    pub(crate) const STARFALL_DAMAGE: (u32, u8) = (191_037, 1);
364    ///<https://wowlab.gg/inspect/spell/50286>
365    pub(crate) const STARFALL_GEOMETRY: (u32, u8) = (50286, 1);
366    ///<https://wowlab.gg/inspect/spell/343647>
367    pub(crate) const SOLSTICE_RATE: (u32, u8) = (343_647, 1);
368    ///<https://wowlab.gg/inspect/spell/1271222>
369    pub(crate) const STARSURGE_CASCADE_DMG: (u32, u8) = (1_271_222, 1);
370    ///<https://wowlab.gg/inspect/spell/1271206>
371    pub(crate) const STAR_CASCADE_CHANCE: (u32, u8) = (1_271_206, 1);
372    ///<https://wowlab.gg/inspect/spell/1271206>
373    pub(crate) const STAR_CASCADE_EFFECTIVENESS: (u32, u8) = (1_271_206, 3);
374    ///<https://wowlab.gg/inspect/spell/450212>
375    pub(crate) const STELLAR_AMP_CAP: (u32, u8) = (450_212, 1);
376    ///<https://wowlab.gg/inspect/spell/450356>
377    pub(crate) const TTC_CHANCE_STARFIRE: (u32, u8) = (450_356, 2);
378    ///<https://wowlab.gg/inspect/spell/450356>
379    pub(crate) const TTC_CHANCE_WRATH: (u32, u8) = (450_356, 1);
380    ///<https://wowlab.gg/inspect/spell/468743>
381    pub(crate) const WHIRLING_STARS_CDR: (u32, u8) = (468_743, 3);
382    ///<https://wowlab.gg/inspect/spell/88751>
383    pub(crate) const WILD_MUSHROOM_AP_CAP: (u32, u8) = (88751, 2);
384    ///<https://wowlab.gg/inspect/spell/1280212>
385    pub(crate) const SUNSEEKER_MUSHROOM_AP_CAP: (u32, u8) = (1_280_212, 2);
386    ///<https://wowlab.gg/inspect/spell/406890>
387    pub(crate) const WILD_SURGES_AP: (u32, u8) = (406_890, 2);
388}
389static REPORTED_SPELLS: &[(&str, u32)] = &[
390    ("astral_smolder", 1_263_250),
391    ("exploding_star", 1_272_339),
392    ("fungal_growth", 1_280_213),
393    ("goldrinn", 394_047),
394    ("moonfire_periodic", 164_812),
395    ("shooting_stars", 202_497),
396    ("starsurge_cascade", 1_271_222),
397    ("sunfire_periodic", 164_815),
398    ("sunseeker_mushroom", 1_280_212),
399    ("wild_mushroom", 88751),
400];
401static DECLARED_SPELL_IDS: &[u32] = &[
402    24858, 1126, 190_984, 194_153, 1_233_346, 194_223, 102_560, 8921, 93402, 78674,
403    191_034, 274_281, 202_770, 205_636, 391_528, 88747, 24858, 1126, 428_737, 433_831,
404    430_589, 48517, 48518, 194_223, 102_560, 1_233_353, 1_239_669, 429_523, 450_346,
405    164_812, 164_815, 191_034, 279_709, 393_942, 393_944, 450_360, 343_648, 450_214,
406    394_050, 394_049, 81281, 202_430, 202_770, 211_545, 394_108, 394_111, 468_938, 50286,
407    88751, 164_812, 164_815, 191_034, 191_037, 197_911, 202_342, 202_430, 202_497,
408    202_770, 211_545, 343_647, 393_014, 393_954, 394_047, 394_048, 394_049, 394_050,
409    394_106, 394_111, 406_890, 429_520, 450_212, 450_356, 468_743, 469_004, 1_261_565,
410    1_263_250, 1_264_810, 1_264_811, 1_271_206, 1_271_222, 1_272_339, 1_280_212,
411    1_280_213, 1_263_250, 1_272_339, 1_280_213, 394_047, 164_812, 202_497, 1_271_222,
412    164_815, 1_280_212, 88751, 433_850, 205_636, 429_433, 455_801, 433_831, 428_737,
413    1_261_700, 361_237, 1_261_573, 1_263_363, 1_263_382, 430_589, 429_523, 395_110,
414];
415static DECLARED_AURA_IDS: &[u32] = &[
416    24858, 1126, 428_737, 433_831, 430_589, 48517, 48518, 194_223, 102_560, 1_233_353,
417    1_239_669, 429_523, 450_346, 164_812, 164_815, 191_034, 279_709, 393_942, 393_944,
418    450_360, 343_648, 450_214, 394_050, 394_049, 81281, 202_430, 202_770, 211_545,
419    394_108, 394_111, 468_938, 429_433, 455_801, 433_831, 428_737, 1_263_363, 1_263_382,
420    430_589, 429_523, 395_110,
421];
422static TALENTS: &[(&str, u32)] = &[
423    ("ASCENDANT_ECLIPSES_2", TALENT::ASCENDANT_ECLIPSES_2),
424    ("ATMOSPHERIC_EXPOSURE", TALENT::ATMOSPHERIC_EXPOSURE),
425    ("BALANCE_OF_ALL_THINGS", TALENT::BALANCE_OF_ALL_THINGS),
426    ("CONVOKE_THE_SPIRITS", TALENT::CONVOKE_THE_SPIRITS),
427    ("ECLIPSE", TALENT::ECLIPSE),
428    ("FORCE_OF_NATURE", TALENT::FORCE_OF_NATURE),
429    ("FURY_OF_ELUNE", TALENT::FURY_OF_ELUNE),
430    ("HAIL_OF_STARS", TALENT::HAIL_OF_STARS),
431    ("IMPROVED_ECLIPSE", TALENT::IMPROVED_ECLIPSE),
432    ("INCARNATION_CHOSEN_OF_ELUNE", TALENT::INCARNATION_CHOSEN_OF_ELUNE),
433    ("LUNAR_CALLING", TALENT::LUNAR_CALLING),
434    ("MOON_GUARDIAN", TALENT::MOON_GUARDIAN),
435    ("NATURE_S_BALANCE", TALENT::NATURE_S_BALANCE),
436    ("NEW_MOON", TALENT::NEW_MOON),
437    ("POWER_OF_GOLDRINN", TALENT::POWER_OF_GOLDRINN),
438    ("RATTLE_THE_STARS", TALENT::RATTLE_THE_STARS),
439    ("SHOOTING_STARS", TALENT::SHOOTING_STARS),
440    ("SOLSTICE", TALENT::SOLSTICE),
441    ("STARLORD", TALENT::STARLORD),
442    ("STARWEAVER", TALENT::STARWEAVER),
443    ("STAR_CASCADE", TALENT::STAR_CASCADE),
444    ("STELLAR_AMPLIFICATION", TALENT::STELLAR_AMPLIFICATION),
445    ("SUNDERED_FIRMAMENT", TALENT::SUNDERED_FIRMAMENT),
446    ("SUNSEEKER_MUSHROOM", TALENT::SUNSEEKER_MUSHROOM),
447    ("TOUCH_THE_COSMOS", TALENT::TOUCH_THE_COSMOS),
448    ("UMBRAL_EMBRACE", TALENT::UMBRAL_EMBRACE),
449    ("WHIRLING_STARS", TALENT::WHIRLING_STARS),
450    ("WILD_MUSHROOM", TALENT::WILD_MUSHROOM),
451    ("WILD_SURGES", TALENT::WILD_SURGES),
452];
453pub(crate) mod BALANCE_DRUID {
454    pub(crate) const WRATH_CASTS: u32 = 0;
455    pub(crate) const STARFIRE_CASTS: u32 = 1;
456    pub(crate) const STARSURGE_CASTS: u32 = 2;
457    pub(crate) const STARFALL_CASTS: u32 = 3;
458    pub(crate) const MOONFIRE_CASTS: u32 = 4;
459    pub(crate) const SUNFIRE_CASTS: u32 = 5;
460    pub(crate) const CELESTIAL_ALIGNMENT_CASTS: u32 = 6;
461    pub(crate) const ECLIPSE_SOLAR_UPTIME_MS: u32 = 7;
462    pub(crate) const ECLIPSE_LUNAR_UPTIME_MS: u32 = 8;
463    pub(crate) const STARLORD_UPTIME_MS: u32 = 9;
464}
465fn aura_moonkin_form(
466    a: AuraDefinitionDraft,
467    data: &ResolvedGameData,
468) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
469    Ok(
470        a
471            .on_player()
472            .apply_base_from_data(data, 24858)?
473            .max_stacks(
474                data
475                    .require_aura_max_stacks(
476                        wowlab_types::sim::SpellIdx::from_raw(24858),
477                    )?,
478            ),
479    )
480}
481fn aura_mark_of_the_wild_highlight(
482    a: AuraDefinitionDraft,
483    data: &ResolvedGameData,
484) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
485    Ok(
486        a
487            .on_player()
488            .apply_base_from_data(data, 1126)?
489            .max_stacks(
490                data
491                    .require_aura_max_stacks(
492                        wowlab_types::sim::SpellIdx::from_raw(1126),
493                    )?,
494            ),
495    )
496}
497fn aura_harmony_of_the_grove(
498    a: AuraDefinitionDraft,
499    data: &ResolvedGameData,
500) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
501    Ok(
502        a
503            .on_player()
504            .apply_base_from_data(data, 428_737)?
505            .max_stacks(
506                data
507                    .require_aura_max_stacks(
508                        wowlab_types::sim::SpellIdx::from_raw(428_737),
509                    )?,
510            ),
511    )
512}
513fn aura_dream_surge(
514    a: AuraDefinitionDraft,
515    data: &ResolvedGameData,
516) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
517    Ok(
518        a
519            .on_target()
520            .apply_base_from_data(data, 433_831)?
521            .max_stacks(
522                data
523                    .require_aura_max_stacks(
524                        wowlab_types::sim::SpellIdx::from_raw(433_831),
525                    )?,
526            ),
527    )
528}
529fn aura_atmospheric_exposure(
530    a: AuraDefinitionDraft,
531    data: &ResolvedGameData,
532) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
533    Ok(
534        a
535            .on_target()
536            .apply_base_from_data(data, 430_589)?
537            .max_stacks(
538                data
539                    .require_aura_max_stacks(
540                        wowlab_types::sim::SpellIdx::from_raw(430_589),
541                    )?,
542            ),
543    )
544}
545fn aura_eclipse_solar(
546    a: AuraDefinitionDraft,
547    data: &ResolvedGameData,
548) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
549    Ok(
550        a
551            .on_player()
552            .apply_base_from_data(data, 48517)?
553            .max_stacks(
554                data
555                    .require_aura_max_stacks(
556                        wowlab_types::sim::SpellIdx::from_raw(48517),
557                    )?,
558            ),
559    )
560}
561fn aura_eclipse_lunar(
562    a: AuraDefinitionDraft,
563    data: &ResolvedGameData,
564) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
565    Ok(
566        a
567            .on_player()
568            .apply_base_from_data(data, 48518)?
569            .max_stacks(
570                data
571                    .require_aura_max_stacks(
572                        wowlab_types::sim::SpellIdx::from_raw(48518),
573                    )?,
574            ),
575    )
576}
577fn aura_celestial_alignment(
578    a: AuraDefinitionDraft,
579    data: &ResolvedGameData,
580) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
581    Ok(
582        a
583            .on_player()
584            .apply_base_from_data(data, 194_223)?
585            .max_stacks(
586                data
587                    .require_aura_max_stacks(
588                        wowlab_types::sim::SpellIdx::from_raw(194_223),
589                    )?,
590            ),
591    )
592}
593fn aura_incarnation_chosen_of_elune(
594    a: AuraDefinitionDraft,
595    data: &ResolvedGameData,
596) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
597    Ok(
598        a
599            .on_player()
600            .apply_base_from_data(data, 102_560)?
601            .max_stacks(
602                data
603                    .require_aura_max_stacks(
604                        wowlab_types::sim::SpellIdx::from_raw(102_560),
605                    )?,
606            ),
607    )
608}
609fn aura_lunar_eclipse_override(
610    a: AuraDefinitionDraft,
611    data: &ResolvedGameData,
612) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
613    Ok(
614        a
615            .on_player()
616            .apply_base_from_data(data, 1_233_353)?
617            .max_stacks(
618                data
619                    .require_aura_max_stacks(
620                        wowlab_types::sim::SpellIdx::from_raw(1_233_353),
621                    )?,
622            ),
623    )
624}
625fn aura_eclipse(
626    a: AuraDefinitionDraft,
627    data: &ResolvedGameData,
628) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
629    Ok(
630        a
631            .on_player()
632            .apply_base_from_data(data, 1_239_669)?
633            .max_stacks(
634                data
635                    .require_aura_max_stacks(
636                        wowlab_types::sim::SpellIdx::from_raw(1_239_669),
637                    )?,
638            ),
639    )
640}
641fn aura_lunar_calling(
642    a: AuraDefinitionDraft,
643    data: &ResolvedGameData,
644) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
645    Ok(
646        a
647            .on_player()
648            .apply_base_from_data(data, 429_523)?
649            .max_stacks(
650                data
651                    .require_aura_max_stacks(
652                        wowlab_types::sim::SpellIdx::from_raw(429_523),
653                    )?,
654            ),
655    )
656}
657fn aura_dreamstate(
658    a: AuraDefinitionDraft,
659    data: &ResolvedGameData,
660) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
661    Ok(
662        a
663            .on_player()
664            .apply_base_from_data(data, 450_346)?
665            .max_stacks(
666                data
667                    .require_aura_max_stacks(
668                        wowlab_types::sim::SpellIdx::from_raw(450_346),
669                    )?,
670            ),
671    )
672}
673fn aura_moonfire(
674    a: AuraDefinitionDraft,
675    data: &ResolvedGameData,
676) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
677    Ok(
678        a
679            .on_target()
680            .apply_base_from_data(data, 164_812)?
681            .max_stacks(
682                data
683                    .require_aura_max_stacks(
684                        wowlab_types::sim::SpellIdx::from_raw(164_812),
685                    )?,
686            ),
687    )
688}
689fn aura_sunfire(
690    a: AuraDefinitionDraft,
691    data: &ResolvedGameData,
692) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
693    Ok(
694        a
695            .on_target()
696            .apply_base_from_data(data, 164_815)?
697            .max_stacks(
698                data
699                    .require_aura_max_stacks(
700                        wowlab_types::sim::SpellIdx::from_raw(164_815),
701                    )?,
702            ),
703    )
704}
705fn aura_starfall(
706    a: AuraDefinitionDraft,
707    data: &ResolvedGameData,
708) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
709    Ok(
710        a
711            .on_player()
712            .apply_base_from_data(data, 191_034)?
713            .max_stacks(
714                data
715                    .require_aura_max_stacks(
716                        wowlab_types::sim::SpellIdx::from_raw(191_034),
717                    )?,
718            )
719            .periodic_hook(
720                wowlab_engine_combat::validated_milliseconds(
721                    data.period(wowlab_types::sim::SpellIdx::from_raw(191_034), 3),
722                    191_034,
723                    "periodic_hook.tick_ms",
724                )?,
725            )
726            .apply_periodic_behavior_from_data(data, 191_034)?
727            .tick_hook(crate::hooks::balance_druid::starfall_tick_hook),
728    )
729}
730fn aura_starlord(
731    a: AuraDefinitionDraft,
732    data: &ResolvedGameData,
733) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
734    Ok(
735        a
736            .on_player()
737            .apply_base_from_data(data, 279_709)?
738            .max_stacks(
739                data
740                    .require_aura_max_stacks(
741                        wowlab_types::sim::SpellIdx::from_raw(279_709),
742                    )?,
743            ),
744    )
745}
746fn aura_starweaver_s_warp(
747    a: AuraDefinitionDraft,
748    data: &ResolvedGameData,
749) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
750    Ok(
751        a
752            .on_player()
753            .apply_base_from_data(data, 393_942)?
754            .max_stacks(
755                data
756                    .require_aura_max_stacks(
757                        wowlab_types::sim::SpellIdx::from_raw(393_942),
758                    )?,
759            ),
760    )
761}
762fn aura_starweaver_s_weft(
763    a: AuraDefinitionDraft,
764    data: &ResolvedGameData,
765) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
766    Ok(
767        a
768            .on_player()
769            .apply_base_from_data(data, 393_944)?
770            .max_stacks(
771                data
772                    .require_aura_max_stacks(
773                        wowlab_types::sim::SpellIdx::from_raw(393_944),
774                    )?,
775            ),
776    )
777}
778fn aura_touch_the_cosmos(
779    a: AuraDefinitionDraft,
780    data: &ResolvedGameData,
781) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
782    Ok(
783        a
784            .on_player()
785            .apply_base_from_data(data, 450_360)?
786            .max_stacks(
787                data
788                    .require_aura_max_stacks(
789                        wowlab_types::sim::SpellIdx::from_raw(450_360),
790                    )?,
791            ),
792    )
793}
794fn aura_solstice(
795    a: AuraDefinitionDraft,
796    data: &ResolvedGameData,
797) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
798    Ok(
799        a
800            .on_player()
801            .apply_base_from_data(data, 343_648)?
802            .max_stacks(
803                data
804                    .require_aura_max_stacks(
805                        wowlab_types::sim::SpellIdx::from_raw(343_648),
806                    )?,
807            ),
808    )
809}
810fn aura_stellar_amplification(
811    a: AuraDefinitionDraft,
812    data: &ResolvedGameData,
813) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
814    Ok(
815        a
816            .on_target()
817            .apply_base_from_data(data, 450_214)?
818            .max_stacks(
819                data
820                    .require_aura_max_stacks(
821                        wowlab_types::sim::SpellIdx::from_raw(450_214),
822                    )?,
823            ),
824    )
825}
826fn aura_boat_arcane(
827    a: AuraDefinitionDraft,
828    data: &ResolvedGameData,
829) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
830    Ok(
831        a
832            .on_player()
833            .apply_base_from_data(data, 394_050)?
834            .max_stacks(
835                data
836                    .require_aura_max_stacks(
837                        wowlab_types::sim::SpellIdx::from_raw(394_050),
838                    )?,
839            )
840            .crit_per_stack(
841                data.base_points(wowlab_types::sim::SpellIdx::from_raw(394_048), 1),
842            )?
843            .reverse()
844            .periodic_stack_tick(
845                wowlab_engine_combat::validated_milliseconds(
846                    data.period(wowlab_types::sim::SpellIdx::from_raw(394_049), 2),
847                    394_050,
848                    "aura.stack_tick_ms",
849                )?,
850            )
851            .clip_tick_behavior(1),
852    )
853}
854fn aura_boat_nature(
855    a: AuraDefinitionDraft,
856    data: &ResolvedGameData,
857) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
858    Ok(
859        a
860            .on_player()
861            .apply_base_from_data(data, 394_049)?
862            .max_stacks(
863                data
864                    .require_aura_max_stacks(
865                        wowlab_types::sim::SpellIdx::from_raw(394_049),
866                    )?,
867            )
868            .crit_per_stack(
869                data.base_points(wowlab_types::sim::SpellIdx::from_raw(394_048), 1),
870            )?
871            .reverse()
872            .periodic_stack_tick(
873                wowlab_engine_combat::validated_milliseconds(
874                    data.period(wowlab_types::sim::SpellIdx::from_raw(394_050), 2),
875                    394_049,
876                    "aura.stack_tick_ms",
877                )?,
878            )
879            .clip_tick_behavior(1),
880    )
881}
882fn aura_fungal_growth(
883    a: AuraDefinitionDraft,
884    data: &ResolvedGameData,
885) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
886    Ok(
887        a
888            .on_target()
889            .apply_base_from_data(data, 81281)?
890            .max_stacks(
891                data
892                    .require_aura_max_stacks(
893                        wowlab_types::sim::SpellIdx::from_raw(81281),
894                    )?,
895            ),
896    )
897}
898fn aura_natures_balance(
899    a: AuraDefinitionDraft,
900    data: &ResolvedGameData,
901) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
902    Ok(
903        a
904            .on_player()
905            .apply_base_from_data(data, 202_430)?
906            .max_stacks(
907                data
908                    .require_aura_max_stacks(
909                        wowlab_types::sim::SpellIdx::from_raw(202_430),
910                    )?,
911            ),
912    )
913}
914fn aura_fury_of_elune_energize(
915    a: AuraDefinitionDraft,
916    data: &ResolvedGameData,
917) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
918    Ok(
919        a
920            .on_player()
921            .apply_base_from_data(data, 202_770)?
922            .max_stacks(
923                data
924                    .require_aura_max_stacks(
925                        wowlab_types::sim::SpellIdx::from_raw(202_770),
926                    )?,
927            ),
928    )
929}
930fn aura_fury_of_elune_beam(
931    a: AuraDefinitionDraft,
932    data: &ResolvedGameData,
933) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
934    a.on_target()
935        .duration_ms(
936            wowlab_engine_combat::validated_milliseconds(
937                f64::from(
938                    data
939                        .require_aura_duration_ms(
940                            wowlab_types::sim::SpellIdx::from_raw(202_770),
941                        )?,
942                ),
943                211_545,
944                "aura.duration_ms",
945            )?,
946        )
947        .apply_periodic_effect_from_data(data, 211_545)?
948        .apply_duration_behavior_from_data(data, 202_770)?
949        .apply_timing_modifiers_from_data(data, 211_545)?
950        .max_stacks(
951            data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(211_545))?,
952        )
953        .periodic_damage_sp(
954            wowlab_engine_combat::validated_milliseconds(
955                500.0,
956                211_545,
957                "periodic_damage.tick_ms",
958            )?,
959            ((data.sp_coef(wowlab_types::sim::SpellIdx::from_raw(211_545), 1)) * 10000.0)
960                .round() / 10000.0,
961            wowlab_engine_combat::DamageFlags::empty(),
962        )
963        .apply_periodic_behavior_from_data(data, 202_770)
964}
965fn aura_sundered_firmament_energize(
966    a: AuraDefinitionDraft,
967    data: &ResolvedGameData,
968) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
969    Ok(
970        a
971            .on_player()
972            .apply_base_from_data(data, 394_108)?
973            .max_stacks(
974                data
975                    .require_aura_max_stacks(
976                        wowlab_types::sim::SpellIdx::from_raw(394_108),
977                    )?,
978            ),
979    )
980}
981fn aura_sundered_firmament_beam(
982    a: AuraDefinitionDraft,
983    data: &ResolvedGameData,
984) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
985    a.on_target()
986        .duration_ms(
987            wowlab_engine_combat::validated_milliseconds(
988                f64::from(
989                    data
990                        .require_aura_duration_ms(
991                            wowlab_types::sim::SpellIdx::from_raw(394_106),
992                        )?,
993                ),
994                394_111,
995                "aura.duration_ms",
996            )?,
997        )
998        .apply_periodic_effect_from_data(data, 394_111)?
999        .apply_duration_behavior_from_data(data, 394_106)?
1000        .apply_timing_modifiers_from_data(data, 394_111)?
1001        .max_stacks(
1002            data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(394_111))?,
1003        )
1004        .periodic_damage_sp(
1005            wowlab_engine_combat::validated_milliseconds(
1006                500.0,
1007                394_111,
1008                "periodic_damage.tick_ms",
1009            )?,
1010            (((data.sp_coef(wowlab_types::sim::SpellIdx::from_raw(394_111), 1)) * 0.25)
1011                * 1000.0)
1012                .round() / 1000.0,
1013            wowlab_engine_combat::DamageFlags::empty(),
1014        )
1015        .apply_periodic_behavior_from_data(data, 394_106)
1016}
1017fn aura_sunseeker_mushroom_driver(
1018    a: AuraDefinitionDraft,
1019    data: &ResolvedGameData,
1020) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
1021    Ok(
1022        a
1023            .on_player()
1024            .apply_base_from_data(data, 468_938)?
1025            .max_stacks(
1026                data
1027                    .require_aura_max_stacks(
1028                        wowlab_types::sim::SpellIdx::from_raw(468_938),
1029                    )?,
1030            ),
1031    )
1032}
1033fn spell_moonkin_form(
1034    s: SpellDefinitionDraft,
1035    data: &ResolvedGameData,
1036) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1037    Ok(
1038        s
1039            .apply_base_from_data(data, 24858)?
1040            .applies_inferred_aura(AURA_MOONKIN_FORM, 24858)
1041            .apply_aoe_from_data(data),
1042    )
1043}
1044fn spell_mark_of_the_wild(
1045    s: SpellDefinitionDraft,
1046    data: &ResolvedGameData,
1047) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1048    Ok(
1049        s
1050            .apply_base_from_data(data, 1126)?
1051            .applies_inferred_aura(AURA_MARK_OF_THE_WILD_HIGHLIGHT, 1126)
1052            .apply_aoe_from_data(data),
1053    )
1054}
1055fn spell_wrath(
1056    s: SpellDefinitionDraft,
1057    data: &ResolvedGameData,
1058) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1059    Ok(
1060        s
1061            .apply_base_from_data(data, 190_984)?
1062            .apply_aoe_from_data(data)
1063            .on_cast(crate::hooks::balance_druid::wrath_hook),
1064    )
1065}
1066fn spell_starfire(
1067    s: SpellDefinitionDraft,
1068    data: &ResolvedGameData,
1069) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1070    Ok(
1071        s
1072            .apply_base_from_data(data, 194_153)?
1073            .apply_aoe_from_data(data)
1074            .on_cast(crate::hooks::balance_druid::starfire_hook),
1075    )
1076}
1077fn spell_solar_eclipse(
1078    s: SpellDefinitionDraft,
1079    data: &ResolvedGameData,
1080) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1081    Ok(
1082        s
1083            .apply_base_from_data(data, 1_233_346)?
1084            .applies_aura(AURA_ECLIPSE_SOLAR)
1085            .apply_aoe_from_data(data)
1086            .on_cast(crate::hooks::balance_druid::eclipse_hook),
1087    )
1088}
1089fn spell_celestial_alignment(
1090    s: SpellDefinitionDraft,
1091    data: &ResolvedGameData,
1092) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1093    Ok(
1094        s
1095            .apply_base_from_data(data, 194_223)?
1096            .applies_aura(AURA_ECLIPSE_SOLAR)
1097            .applies_aura(AURA_ECLIPSE_LUNAR)
1098            .apply_aoe_from_data(data)
1099            .on_cast(crate::hooks::balance_druid::celestial_alignment_hook),
1100    )
1101}
1102fn spell_incarnation_chosen_of_elune(
1103    s: SpellDefinitionDraft,
1104    data: &ResolvedGameData,
1105) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1106    Ok(
1107        s
1108            .apply_base_from_data(data, 102_560)?
1109            .applies_aura(AURA_ECLIPSE_SOLAR)
1110            .applies_aura(AURA_ECLIPSE_LUNAR)
1111            .apply_aoe_from_data(data),
1112    )
1113}
1114fn spell_moonfire(
1115    s: SpellDefinitionDraft,
1116    data: &ResolvedGameData,
1117) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1118    Ok(
1119        s
1120            .apply_base_from_data(data, 8921)?
1121            .gain(
1122                (data.base_points(wowlab_types::sim::SpellIdx::from_raw(197_911), 3))
1123                    * 0.1,
1124            )
1125            .damage_sp_from_data(
1126                wowlab_engine_domain::dbc::EffectLookup::new(
1127                    data,
1128                    wowlab_types::sim::EffectRef::new(
1129                        wowlab_types::sim::SpellIdx::from_raw(164_812),
1130                        1,
1131                    ),
1132                ),
1133            )?
1134            .applies_aura(AURA_MOONFIRE)
1135            .apply_aoe_from_data(data),
1136    )
1137}
1138fn spell_sunfire(
1139    s: SpellDefinitionDraft,
1140    data: &ResolvedGameData,
1141) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1142    Ok(
1143        s
1144            .apply_base_from_data(data, 93402)?
1145            .gain(
1146                (data.base_points(wowlab_types::sim::SpellIdx::from_raw(197_911), 3))
1147                    * 0.1,
1148            )
1149            .damage_sp_from_data(
1150                wowlab_engine_domain::dbc::EffectLookup::new(
1151                    data,
1152                    wowlab_types::sim::EffectRef::new(
1153                        wowlab_types::sim::SpellIdx::from_raw(164_815),
1154                        1,
1155                    ),
1156                ),
1157            )?
1158            .applies_aura(AURA_SUNFIRE)
1159            .apply_aoe_from_data(data),
1160    )
1161}
1162fn spell_starsurge(
1163    s: SpellDefinitionDraft,
1164    data: &ResolvedGameData,
1165) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1166    Ok(
1167        s
1168            .apply_base_from_data(data, 78674)?
1169            .applies_aura(AURA_STARLORD)
1170            .apply_aoe_from_data(data)
1171            .on_cast(crate::hooks::balance_druid::starsurge_hook)
1172            .cost_free_when_aura(450_360),
1173    )
1174}
1175fn spell_starfall(
1176    s: SpellDefinitionDraft,
1177    data: &ResolvedGameData,
1178) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1179    Ok(
1180        s
1181            .apply_base_from_data(data, 191_034)?
1182            .applies_aura(AURA_STARLORD)
1183            .apply_aoe_from_data(data),
1184    )
1185}
1186fn spell_new_moon(
1187    s: SpellDefinitionDraft,
1188    data: &ResolvedGameData,
1189) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1190    Ok(s.apply_base_from_data(data, 274_281)?.apply_aoe_from_data(data))
1191}
1192fn spell_fury_of_elune(
1193    s: SpellDefinitionDraft,
1194    data: &ResolvedGameData,
1195) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1196    Ok(
1197        s
1198            .apply_base_from_data(data, 202_770)?
1199            .applies_aura(AURA_FURY_OF_ELUNE_BEAM)
1200            .apply_aoe_from_data(data),
1201    )
1202}
1203fn spell_force_of_nature(
1204    s: SpellDefinitionDraft,
1205    data: &ResolvedGameData,
1206) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1207    Ok(s.apply_base_from_data(data, 205_636)?.apply_aoe_from_data(data))
1208}
1209fn spell_convoke_the_spirits(
1210    s: SpellDefinitionDraft,
1211    data: &ResolvedGameData,
1212) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1213    Ok(s.apply_base_from_data(data, 391_528)?.apply_aoe_from_data(data))
1214}
1215fn spell_wild_mushroom(
1216    s: SpellDefinitionDraft,
1217    data: &ResolvedGameData,
1218) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1219    Ok(
1220        s
1221            .apply_base_from_data(data, 88747)?
1222            .without_primary_data_damage()
1223            .apply_aoe_from_data(data),
1224    )
1225}
1226pub(crate) fn build_combat_system(
1227    params: &wowlab_engine_ports::HandlerParams<'_>,
1228) -> Result<BuiltCombatSystem, wowlab_engine_ports::EngineError> {
1229    let builder = BuiltCombatSystem::builder(params.stats.clone())
1230        .spec_id(SpecId::Balance)
1231        .hero_talent_trees(DECLARED_METADATA.hero_talent_trees)
1232        .mastery_spell(393_014)
1233        .mastery_hook(crate::hooks::balance_druid::mastery)
1234        .resource(
1235            "astral_power",
1236            100.0,
1237            params
1238                .game_data
1239                .power_regen_for_max(8, 100.0)
1240                .ok_or_else(|| {
1241                    wowlab_engine_ports::EngineError::spec_construction(
1242                        "missing power-type power_regen_for_max for type_id 8",
1243                    )
1244                })?,
1245        )
1246        .resource_type_id(8)
1247        .resource_start(
1248            params
1249                .game_data
1250                .power_default(8)
1251                .ok_or_else(|| {
1252                    wowlab_engine_ports::EngineError::spec_construction(
1253                        "missing power-type power_default for type_id 8",
1254                    )
1255                })?,
1256        )
1257        .aura(
1258            "moonkin_form",
1259            AURA::MOONKIN_FORM,
1260            |a| aura_moonkin_form(a, &params.game_data),
1261        )
1262        .aura(
1263            "mark_of_the_wild_highlight",
1264            AURA::MARK_OF_THE_WILD_HIGHLIGHT,
1265            |a| aura_mark_of_the_wild_highlight(a, &params.game_data),
1266        )
1267        .aura(
1268            "harmony_of_the_grove",
1269            AURA::HARMONY_OF_THE_GROVE,
1270            |a| aura_harmony_of_the_grove(a, &params.game_data),
1271        )
1272        .aura(
1273            "dream_surge",
1274            AURA::DREAM_SURGE,
1275            |a| aura_dream_surge(a, &params.game_data),
1276        )
1277        .aura(
1278            "atmospheric_exposure",
1279            AURA::ATMOSPHERIC_EXPOSURE,
1280            |a| aura_atmospheric_exposure(a, &params.game_data),
1281        )
1282        .aura(
1283            "eclipse_solar",
1284            AURA::ECLIPSE_SOLAR,
1285            |a| aura_eclipse_solar(a, &params.game_data),
1286        )
1287        .aura(
1288            "eclipse_lunar",
1289            AURA::ECLIPSE_LUNAR,
1290            |a| aura_eclipse_lunar(a, &params.game_data),
1291        )
1292        .aura(
1293            "celestial_alignment",
1294            AURA::CELESTIAL_ALIGNMENT,
1295            |a| aura_celestial_alignment(a, &params.game_data),
1296        )
1297        .aura(
1298            "incarnation_chosen_of_elune",
1299            AURA::INCARNATION_CHOSEN_OF_ELUNE,
1300            |a| aura_incarnation_chosen_of_elune(a, &params.game_data),
1301        )
1302        .aura(
1303            "lunar_eclipse_override",
1304            AURA::LUNAR_ECLIPSE_OVERRIDE,
1305            |a| aura_lunar_eclipse_override(a, &params.game_data),
1306        )
1307        .aura("eclipse", AURA::ECLIPSE, |a| aura_eclipse(a, &params.game_data))
1308        .aura(
1309            "lunar_calling",
1310            AURA::LUNAR_CALLING,
1311            |a| aura_lunar_calling(a, &params.game_data),
1312        )
1313        .aura("dreamstate", AURA::DREAMSTATE, |a| aura_dreamstate(a, &params.game_data))
1314        .aura("moonfire", AURA::MOONFIRE, |a| aura_moonfire(a, &params.game_data))
1315        .aura("sunfire", AURA::SUNFIRE, |a| aura_sunfire(a, &params.game_data))
1316        .aura("starfall", AURA::STARFALL, |a| aura_starfall(a, &params.game_data))
1317        .aura("starlord", AURA::STARLORD, |a| aura_starlord(a, &params.game_data))
1318        .aura(
1319            "starweavers_warp",
1320            AURA::STARWEAVER_S_WARP,
1321            |a| aura_starweaver_s_warp(a, &params.game_data),
1322        )
1323        .aura(
1324            "starweavers_weft",
1325            AURA::STARWEAVER_S_WEFT,
1326            |a| aura_starweaver_s_weft(a, &params.game_data),
1327        )
1328        .aura(
1329            "touch_the_cosmos",
1330            AURA::TOUCH_THE_COSMOS,
1331            |a| aura_touch_the_cosmos(a, &params.game_data),
1332        )
1333        .aura("solstice", AURA::SOLSTICE, |a| aura_solstice(a, &params.game_data))
1334        .aura(
1335            "stellar_amplification",
1336            AURA::STELLAR_AMPLIFICATION,
1337            |a| aura_stellar_amplification(a, &params.game_data),
1338        )
1339        .aura(
1340            "boat_arcane",
1341            AURA::BOAT_ARCANE,
1342            |a| aura_boat_arcane(a, &params.game_data),
1343        )
1344        .aura(
1345            "boat_nature",
1346            AURA::BOAT_NATURE,
1347            |a| aura_boat_nature(a, &params.game_data),
1348        )
1349        .aura(
1350            "fungal_growth",
1351            AURA::FUNGAL_GROWTH,
1352            |a| aura_fungal_growth(a, &params.game_data),
1353        )
1354        .aura(
1355            "natures_balance",
1356            AURA::NATURES_BALANCE,
1357            |a| aura_natures_balance(a, &params.game_data),
1358        )
1359        .aura(
1360            "fury_of_elune_energize",
1361            AURA::FURY_OF_ELUNE_ENERGIZE,
1362            |a| aura_fury_of_elune_energize(a, &params.game_data),
1363        )
1364        .aura(
1365            "fury_of_elune_beam",
1366            AURA::FURY_OF_ELUNE_BEAM,
1367            |a| aura_fury_of_elune_beam(a, &params.game_data),
1368        )
1369        .aura(
1370            "sundered_firmament_energize",
1371            AURA::SUNDERED_FIRMAMENT_ENERGIZE,
1372            |a| aura_sundered_firmament_energize(a, &params.game_data),
1373        )
1374        .aura(
1375            "sundered_firmament_beam",
1376            AURA::SUNDERED_FIRMAMENT_BEAM,
1377            |a| aura_sundered_firmament_beam(a, &params.game_data),
1378        )
1379        .aura(
1380            "sunseeker_mushroom_driver",
1381            AURA::SUNSEEKER_MUSHROOM_DRIVER,
1382            |a| aura_sunseeker_mushroom_driver(a, &params.game_data),
1383        )
1384        .spell(
1385            "moonkin_form",
1386            SPELL::MOONKIN_FORM,
1387            |s| spell_moonkin_form(s, &params.game_data),
1388        )
1389        .spell(
1390            "mark_of_the_wild",
1391            SPELL::MARK_OF_THE_WILD,
1392            |s| spell_mark_of_the_wild(s, &params.game_data),
1393        )
1394        .spell("wrath", SPELL::WRATH, |s| spell_wrath(s, &params.game_data))
1395        .spell("starfire", SPELL::STARFIRE, |s| spell_starfire(s, &params.game_data))
1396        .spell(
1397            "solar_eclipse",
1398            SPELL::SOLAR_ECLIPSE,
1399            |s| spell_solar_eclipse(s, &params.game_data),
1400        )
1401        .spell(
1402            "celestial_alignment",
1403            SPELL::CELESTIAL_ALIGNMENT,
1404            |s| spell_celestial_alignment(s, &params.game_data),
1405        )
1406        .spell(
1407            "incarnation_chosen_of_elune",
1408            SPELL::INCARNATION_CHOSEN_OF_ELUNE,
1409            |s| spell_incarnation_chosen_of_elune(s, &params.game_data),
1410        )
1411        .spell("moonfire", SPELL::MOONFIRE, |s| spell_moonfire(s, &params.game_data))
1412        .spell("sunfire", SPELL::SUNFIRE, |s| spell_sunfire(s, &params.game_data))
1413        .spell("starsurge", SPELL::STARSURGE, |s| spell_starsurge(s, &params.game_data))
1414        .spell("starfall", SPELL::STARFALL, |s| spell_starfall(s, &params.game_data))
1415        .spell("new_moon", SPELL::NEW_MOON, |s| spell_new_moon(s, &params.game_data))
1416        .spell(
1417            "fury_of_elune",
1418            SPELL::FURY_OF_ELUNE,
1419            |s| spell_fury_of_elune(s, &params.game_data),
1420        )
1421        .spell(
1422            "force_of_nature",
1423            SPELL::FORCE_OF_NATURE,
1424            |s| spell_force_of_nature(s, &params.game_data),
1425        )
1426        .spell(
1427            "convoke_the_spirits",
1428            SPELL::CONVOKE_THE_SPIRITS,
1429            |s| spell_convoke_the_spirits(s, &params.game_data),
1430        )
1431        .spell(
1432            "wild_mushroom",
1433            SPELL::WILD_MUSHROOM,
1434            |s| spell_wild_mushroom(s, &params.game_data),
1435        )
1436        .game_data(params.game_data.clone())
1437        .talent_spell_ids(TALENTS)
1438        .talent_selections(params.talent_selections)
1439        .talent_companion_aura(TALENT::LUNAR_CALLING, AURA_LUNAR_ECLIPSE_OVERRIDE)
1440        .talent_companion_aura(TALENT::NATURE_S_BALANCE, AURA_NATURES_BALANCE)
1441        .set_bonus_auras(params.set_bonus_auras)
1442        .encounter(params.encounter.clone());
1443    let builder = crate::generated::items::register_equipped(
1444        builder,
1445        &params.game_data,
1446        params.equipped_items,
1447    )?;
1448
1449    builder
1450        .build(params.rotation)
1451        .map_err(wowlab_engine_ports::EngineError::rotation_compile)
1452}
1453fn new_handler(
1454    params: wowlab_engine_ports::HandlerParams<'_>,
1455) -> Result<Box<dyn SpecHandler>, wowlab_engine_ports::EngineError> {
1456    let handler = crate::composition::compose_handler(
1457        build_combat_system,
1458        &params,
1459        |parts, params| Ok(
1460            crate::hooks::balance_druid::BalanceHandler::new(parts, params),
1461        ),
1462    )?;
1463
1464    Ok(Box::new(handler))
1465}
1466static DECLARED_METADATA: DeclaredSpecMetadata = DeclaredSpecMetadata {
1467    primary_resource: ResourceType::LunarPower,
1468    secondary_resource: None,
1469    spell_ids: DECLARED_SPELL_IDS,
1470    aura_ids: DECLARED_AURA_IDS,
1471    server_proc_entries: &[
1472        DeclaredServerProcEntry {
1473            spell_id: 450_346,
1474            attributes: ProcAttributes::REQUIRE_SPELL_MODIFIER.bits()
1475                | ProcAttributes::USE_STACKS_FOR_CHARGES.bits(),
1476        },
1477    ],
1478    talents: TALENTS,
1479    rotation_field_schema: &[],
1480    metrics_plugin_id: None,
1481    hero_talent_trees: &[
1482        HeroTalentTreeDesc {
1483            name: "Keeper Of The Grove",
1484            spells: HERO_TREE_KEEPER_OF_THE_GROVE_SPELLS,
1485            auras: HERO_TREE_KEEPER_OF_THE_GROVE_AURAS,
1486        },
1487        HeroTalentTreeDesc {
1488            name: "Elunes Chosen",
1489            spells: HERO_TREE_ELUNES_CHOSEN_SPELLS,
1490            auras: HERO_TREE_ELUNES_CHOSEN_AURAS,
1491        },
1492    ],
1493    reported_spells: REPORTED_SPELLS,
1494    masked_passive_effects: &[],
1495    passive_effect_overrides: &[],
1496};
1497pub(super) const SPEC_DESCRIPTOR: SpecDescriptor = SpecDescriptor {
1498    spec_id: SpecId::Balance,
1499    display_name: "Balance Druid",
1500    metadata: DECLARED_METADATA,
1501    handler_factory: new_handler,
1502};
1503wowlab_engine_combat::smoke_test!(build_combat_system);