1#![allow(non_snake_case, dead_code)]
4use wowlab_types::{combat::ResourceType, game::SpecId};
5use wowlab_engine_combat::{
6 CombatSystemBuilder, CombatSystemDraft, AuraDefinitionDraft, LocalAuraIdx,
7 LocalSpellIdx, SpellDefinitionDraft,
8};
9use wowlab_engine_ports::{
10 DeclaredSpecMetadata, SpecDescriptor, SpecHandler, HeroTalentTreeDesc,
11};
12use wowlab_engine_gamedata::ResolvedGameData;
13pub(crate) mod SPELL {
14 pub(crate) const SHRED: u32 = 5221;
16 pub(crate) const SWIPE: u32 = 106_785;
18 pub(crate) const MOONFIRE: u32 = 155_625;
20 pub(crate) const CAT_FORM: u32 = 768;
22 pub(crate) const MARK_OF_THE_WILD: u32 = 1126;
24 pub(crate) const WAITING_FOR_ENERGY: u32 = 1_249_752;
26 pub(crate) const RAKE: u32 = 1822;
28 pub(crate) const RIP: u32 = 1079;
30 pub(crate) const FEROCIOUS_BITE: u32 = 22568;
32 pub(crate) const PRIMAL_WRATH: u32 = 285_381;
34 pub(crate) const FERAL_FRENZY: u32 = 274_837;
36 pub(crate) const FRANTIC_FRENZY: u32 = 1_243_807;
38 pub(crate) const TIGERS_FURY: u32 = 5217;
40 pub(crate) const BERSERK: u32 = 106_951;
42 pub(crate) const INCARNATION_AVATAR_OF_ASHAMANE: u32 = 102_543;
44 pub(crate) const CONVOKE_THE_SPIRITS: u32 = 391_528;
46 pub(crate) const WRATH: u32 = 5176;
48 pub(crate) const CHOMP: u32 = 1_244_292;
50}
51pub(crate) mod AURA {
52 pub(crate) const MOONFIRE: u32 = 155_625;
54 pub(crate) const CLEARCASTING: u32 = 135_700;
56 pub(crate) const PROWL: u32 = 5215;
58 pub(crate) const CAT_FORM: u32 = 768;
60 pub(crate) const MARK_OF_THE_WILD_HIGHLIGHT: u32 = 1126;
62 pub(crate) const LUNAR_INSPIRATION: u32 = 155_580;
64 pub(crate) const RIP: u32 = 1079;
66 pub(crate) const RAKE: u32 = 155_722;
68 pub(crate) const SABERTOOTH: u32 = 391_722;
70 pub(crate) const UNSEEN_SLASH: u32 = 1_271_863;
72 pub(crate) const FERAL_FRENZY: u32 = 274_838;
74 pub(crate) const TIGERS_FURY: u32 = 5217;
76 pub(crate) const BERSERK: u32 = 106_951;
78 pub(crate) const INCARNATION_AVATAR_OF_ASHAMANE: u32 = 102_543;
80 pub(crate) const APEX_PREDATORS_CRAVING: u32 = 391_882;
82 pub(crate) const SAVAGE_FURY: u32 = 449_646;
84 pub(crate) const CHOMP_ENABLER: u32 = 1_244_292;
86 pub(crate) const OVERFLOWING_POWER: u32 = 405_189;
88 pub(crate) const TIGERS_TENACITY: u32 = 391_873;
90 pub(crate) const SUDDEN_AMBUSH: u32 = 1_244_483;
92 pub(crate) const STRATEGIC_INFUSION: u32 = 439_891;
94 pub(crate) const LYCARAS_TEACHINGS_CRIT: u32 = 378_990;
96 pub(crate) const HALAZZIS_FURY: u32 = 1_301_600;
98 pub(crate) const UNSEEN_PREDATORS_CRAVING: u32 = 1_263_939;
100 pub(crate) const STALKING_PREDATOR: u32 = 1_263_962;
102 pub(crate) const BLOODSEEKER_VINES: u32 = 439_531;
104}
105pub(crate) mod TALENT {
106 pub(crate) const APEX_PREDATORS_CRAVING: u32 = 391_881;
108 pub(crate) const ASHAMANES_GUIDANCE: u32 = 391_548;
110 pub(crate) const BERSERK: u32 = 343_223;
112 pub(crate) const CARNIVOROUS_INSTINCT: u32 = 390_902;
114 pub(crate) const CHOMP: u32 = 1_244_292;
116 pub(crate) const CONVOKE_THE_SPIRITS: u32 = 391_528;
118 pub(crate) const FERAL_FRENZY: u32 = 274_837;
120 pub(crate) const FRANTIC_FRENZY: u32 = 1_243_807;
122 pub(crate) const INCARNATION_AVATAR_OF_ASHAMANE: u32 = 102_543;
124 pub(crate) const LUNAR_INSPIRATION: u32 = 155_580;
126 pub(crate) const LYCARAS_TEACHINGS: u32 = 378_988;
128 pub(crate) const MOMENT_OF_CLARITY: u32 = 236_068;
130 pub(crate) const OMEN_OF_CLARITY: u32 = 16864;
132 pub(crate) const PANTHERS_GUILE: u32 = 1_280_316;
134 pub(crate) const PRIMAL_FURY: u32 = 159_286;
136 pub(crate) const PRIMAL_WRATH: u32 = 285_381;
138 pub(crate) const RAMPANT_FEROCITY: u32 = 391_709;
140 pub(crate) const SABERTOOTH: u32 = 202_031;
142 pub(crate) const SOUL_OF_THE_FOREST: u32 = 158_476;
144 pub(crate) const STRATEGIC_INFUSION: u32 = 439_890;
146 pub(crate) const SUDDEN_AMBUSH: u32 = 384_667;
148 pub(crate) const TASTE_FOR_BLOOD: u32 = 384_665;
150 pub(crate) const THRIVING_GROWTH: u32 = 439_528;
152 pub(crate) const TIGERS_TENACITY: u32 = 391_872;
154 pub(crate) const UNSEEN_PREDATOR: u32 = 1_263_658;
156}
157pub(crate) mod SET_BONUS {
158 pub(crate) const MID2_FERAL_2PC: u32 = 1_296_605;
160 pub(crate) const MID2_FERAL_4PC: u32 = 1_296_606;
162}
163pub(crate) mod REPORTED_SPELL {
164 pub(crate) const UNSEEN_SLASH: u32 = 1_263_890;
166}
167pub(crate) mod HERO {
168 pub(crate) mod DRUID_OF_THE_CLAW {
169 pub(crate) mod SPELL {
170 pub(crate) const RAVAGE: u32 = 441_591;
172 pub(crate) const TWIN_CLAW: u32 = 1_271_635;
174 }
175 pub(crate) mod AURA {
176 pub(crate) const DREADFUL_WOUND: u32 = 441_812;
178 pub(crate) const KILLING_STRIKES: u32 = 441_825;
180 pub(crate) const KILLING_STRIKES_COMBAT: u32 = 441_827;
182 pub(crate) const RAVAGE_FB: u32 = 441_585;
184 pub(crate) const RUTHLESS_AGGRESSION: u32 = 441_814;
186 }
187 }
188 pub(crate) mod WILDSTALKER {
189 pub(crate) mod SPELL {
190 pub(crate) const BURSTING_GROWTH: u32 = 440_122;
192 }
193 pub(crate) mod AURA {
194 pub(crate) const BLOODSEEKER_VINES: u32 = 439_531;
196 pub(crate) const IMPLANT: u32 = 455_496;
198 pub(crate) const ROOT_NETWORK: u32 = 439_887;
200 pub(crate) const STRATEGIC_INFUSION: u32 = 439_891;
202 }
203 }
204}
205static HERO_TREE_DRUID_OF_THE_CLAW_SPELLS: &[(&str, u32)] = &[
206 ("RAVAGE", 441_591),
207 ("TWIN_CLAW", 1_271_635),
208];
209static HERO_TREE_DRUID_OF_THE_CLAW_AURAS: &[(&str, u32)] = &[
210 ("DREADFUL_WOUND", 441_812),
211 ("KILLING_STRIKES", 441_825),
212 ("KILLING_STRIKES_COMBAT", 441_827),
213 ("RAVAGE_FB", 441_585),
214 ("RUTHLESS_AGGRESSION", 441_814),
215];
216static HERO_TREE_WILDSTALKER_SPELLS: &[(&str, u32)] = &[("BURSTING_GROWTH", 440_122)];
217static HERO_TREE_WILDSTALKER_AURAS: &[(&str, u32)] = &[
218 ("BLOODSEEKER_VINES", 439_531),
219 ("IMPLANT", 455_496),
220 ("ROOT_NETWORK", 439_887),
221 ("STRATEGIC_INFUSION", 439_891),
222];
223pub(crate) mod DAMAGE_SPELL {
224 pub(crate) const SHRED: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_5221;
225 pub(crate) const SWIPE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_106785;
226 pub(crate) const MOONFIRE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_155625;
227 pub(crate) const CAT_FORM: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_768;
228 pub(crate) const MARK_OF_THE_WILD: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_1126;
229 pub(crate) const WAITING_FOR_ENERGY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_1249752;
230 pub(crate) const RAKE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_1822;
231 pub(crate) const RIP: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_1079;
232 pub(crate) const FEROCIOUS_BITE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_22568;
233 pub(crate) const PRIMAL_WRATH: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_285381;
234 pub(crate) const FERAL_FRENZY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_274837;
235 pub(crate) const FRANTIC_FRENZY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_1243807;
236 pub(crate) const TIGERS_FURY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_5217;
237 pub(crate) const BERSERK: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_106951;
238 pub(crate) const INCARNATION_AVATAR_OF_ASHAMANE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_102543;
239 pub(crate) const CONVOKE_THE_SPIRITS: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_391528;
240 pub(crate) const WRATH: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_5176;
241 pub(crate) const CHOMP: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_1244292;
242 pub(crate) const RAVAGE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_441591;
243 pub(crate) const TWIN_CLAW: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_1271635;
244 pub(crate) const BURSTING_GROWTH: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_440122;
245}
246pub(crate) mod DAMAGE_AURA {
247 pub(crate) const MOONFIRE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_155625;
248 pub(crate) const CLEARCASTING: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_135700;
249 pub(crate) const PROWL: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_5215;
250 pub(crate) const CAT_FORM: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_768;
251 pub(crate) const MARK_OF_THE_WILD_HIGHLIGHT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_1126;
252 pub(crate) const LUNAR_INSPIRATION: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_155580;
253 pub(crate) const RIP: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_1079;
254 pub(crate) const RAKE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_155722;
255 pub(crate) const SABERTOOTH: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_391722;
256 pub(crate) const UNSEEN_SLASH: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_1271863;
257 pub(crate) const FERAL_FRENZY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_274838;
258 pub(crate) const TIGERS_FURY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_5217;
259 pub(crate) const BERSERK: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_106951;
260 pub(crate) const INCARNATION_AVATAR_OF_ASHAMANE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_102543;
261 pub(crate) const APEX_PREDATORS_CRAVING: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_391882;
262 pub(crate) const SAVAGE_FURY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_449646;
263 pub(crate) const CHOMP_ENABLER: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_1244292;
264 pub(crate) const OVERFLOWING_POWER: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_405189;
265 pub(crate) const TIGERS_TENACITY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_391873;
266 pub(crate) const SUDDEN_AMBUSH: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_1244483;
267 pub(crate) const STRATEGIC_INFUSION: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_439891;
268 pub(crate) const LYCARAS_TEACHINGS_CRIT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_378990;
269 pub(crate) const HALAZZIS_FURY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_1301600;
270 pub(crate) const UNSEEN_PREDATORS_CRAVING: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_1263939;
271 pub(crate) const STALKING_PREDATOR: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_1263962;
272 pub(crate) const BLOODSEEKER_VINES: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_439531;
273}
274pub(crate) mod DAMAGE_TALENT {
275 pub(crate) const APEX_PREDATORS_CRAVING: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_391881;
276 pub(crate) const ASHAMANES_GUIDANCE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_391548;
277 pub(crate) const BERSERK: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_343223;
278 pub(crate) const CARNIVOROUS_INSTINCT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_390902;
279 pub(crate) const CHOMP: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_1244292;
280 pub(crate) const CONVOKE_THE_SPIRITS: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_391528;
281 pub(crate) const FERAL_FRENZY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_274837;
282 pub(crate) const FRANTIC_FRENZY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_1243807;
283 pub(crate) const INCARNATION_AVATAR_OF_ASHAMANE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_102543;
284 pub(crate) const LUNAR_INSPIRATION: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_155580;
285 pub(crate) const LYCARAS_TEACHINGS: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_378988;
286 pub(crate) const MOMENT_OF_CLARITY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_236068;
287 pub(crate) const OMEN_OF_CLARITY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_16864;
288 pub(crate) const PANTHERS_GUILE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_1280316;
289 pub(crate) const PRIMAL_FURY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_159286;
290 pub(crate) const PRIMAL_WRATH: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_285381;
291 pub(crate) const RAMPANT_FEROCITY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_391709;
292 pub(crate) const SABERTOOTH: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_202031;
293 pub(crate) const SOUL_OF_THE_FOREST: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_158476;
294 pub(crate) const STRATEGIC_INFUSION: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_439890;
295 pub(crate) const SUDDEN_AMBUSH: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_384667;
296 pub(crate) const TASTE_FOR_BLOOD: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_384665;
297 pub(crate) const THRIVING_GROWTH: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_439528;
298 pub(crate) const TIGERS_TENACITY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_391872;
299 pub(crate) const UNSEEN_PREDATOR: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_1263658;
300}
301pub(crate) mod DAMAGE_REPORTED {
302 pub(crate) const UNSEEN_SLASH: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ACTION::SPELL_1263890;
303}
304pub(crate) mod DAMAGE_EFFECT {
305 pub(crate) const APEX_PREDATOR_CHANCE: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::EFFECT::SPELL_391881_EFFECT_1;
306 pub(crate) const FERAL_FRENZY_HIT: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::EFFECT::SPELL_274838_EFFECT_1;
307 pub(crate) const FEROCIOUS_BITE_DMG: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::EFFECT::SPELL_22568_EFFECT_1;
308 pub(crate) const HALAZZIS_FURY_GUIDED_MS_PER_CP: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::EFFECT::SPELL_1296605_EFFECT_2;
309 pub(crate) const HALAZZIS_FURY_MS_PER_CP: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::EFFECT::SPELL_1296605_EFFECT_1;
310 pub(crate) const MOMENT_OF_CLARITY_PROC_BONUS: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::EFFECT::SPELL_236068_EFFECT_2;
311 pub(crate) const RAZOR_CLAWS_BLOODSEEKER_PERIODIC: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::EFFECT::SPELL_77493_EFFECT_6;
312 pub(crate) const RAZOR_CLAWS_DAMAGE: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::EFFECT::SPELL_77493_EFFECT_1;
313 pub(crate) const RAZOR_CLAWS_DREADFUL_WOUND_PERIODIC: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::EFFECT::SPELL_77493_EFFECT_7;
314 pub(crate) const RAZOR_CLAWS_PERIODIC: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::EFFECT::SPELL_77493_EFFECT_2;
315 pub(crate) const RAZOR_CLAWS_RAMPANT_DIRECT: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::EFFECT::SPELL_77493_EFFECT_5;
316 pub(crate) const RAZOR_CLAWS_RAMPANT_PERIODIC: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::EFFECT::SPELL_77493_EFFECT_4;
317 pub(crate) const RAZOR_CLAWS_UNSEEN_SLASH_PERIODIC: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::EFFECT::SPELL_77493_EFFECT_8;
318 pub(crate) const SUDDEN_AMBUSH_CHANCE: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::EFFECT::SPELL_384667_EFFECT_1;
319 pub(crate) const THRIVING_GROWTH_RAKE: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::EFFECT::SPELL_439528_EFFECT_2;
320 pub(crate) const THRIVING_GROWTH_RIP: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::EFFECT::SPELL_439528_EFFECT_1;
321 pub(crate) const UNSEEN_SLASH_DMG: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::feral_druid::damage::EFFECT::SPELL_1263890_EFFECT_1;
322}
323pub(crate) const AURA_MOONFIRE: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_MOONFIRE
324 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
325pub(crate) const AURA_CLEARCASTING: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_CLEARCASTING
326 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
327pub(crate) const AURA_PROWL: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_PROWL
328 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
329pub(crate) const AURA_CAT_FORM: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_CAT_FORM
330 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
331pub(crate) const AURA_MARK_OF_THE_WILD_HIGHLIGHT: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_MARK_OF_THE_WILD_HIGHLIGHT
332 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
333pub(crate) const AURA_LUNAR_INSPIRATION: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_LUNAR_INSPIRATION
334 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
335pub(crate) const AURA_RIP: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_RIP
336 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
337pub(crate) const AURA_RAKE: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_RAKE
338 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
339pub(crate) const AURA_SABERTOOTH: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_SABERTOOTH
340 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
341pub(crate) const AURA_UNSEEN_SLASH: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_UNSEEN_SLASH
342 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
343pub(crate) const AURA_FERAL_FRENZY: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_FERAL_FRENZY
344 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
345pub(crate) const AURA_TIGERS_FURY: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_TIGERS_FURY
346 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
347pub(crate) const AURA_BERSERK: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_BERSERK
348 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
349pub(crate) const AURA_INCARNATION_AVATAR_OF_ASHAMANE: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_INCARNATION_AVATAR_OF_ASHAMANE
350 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
351pub(crate) const AURA_APEX_PREDATORS_CRAVING: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_APEX_PREDATORS_CRAVING
352 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
353pub(crate) const AURA_SAVAGE_FURY: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_SAVAGE_FURY
354 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
355pub(crate) const AURA_CHOMP_ENABLER: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_CHOMP_ENABLER
356 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
357pub(crate) const AURA_OVERFLOWING_POWER: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_OVERFLOWING_POWER
358 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
359pub(crate) const AURA_TIGERS_TENACITY: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_TIGERS_TENACITY
360 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
361pub(crate) const AURA_SUDDEN_AMBUSH: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_SUDDEN_AMBUSH
362 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
363pub(crate) const AURA_STRATEGIC_INFUSION: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_STRATEGIC_INFUSION
364 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
365pub(crate) const AURA_LYCARAS_TEACHINGS_CRIT: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_LYCARAS_TEACHINGS_CRIT
366 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
367pub(crate) const AURA_HALAZZIS_FURY: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_HALAZZIS_FURY
368 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
369pub(crate) const AURA_UNSEEN_PREDATORS_CRAVING: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_UNSEEN_PREDATORS_CRAVING
370 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
371pub(crate) const AURA_STALKING_PREDATOR: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_STALKING_PREDATOR
372 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
373pub(crate) const AURA_BLOODSEEKER_VINES: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::AURA_BLOODSEEKER_VINES
374 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
375pub(crate) const AURA_COUNT: usize = 26;
376const _: () = assert!(
377 AURA_COUNT == 26, "AURA index ABI: count changed -- update positional hook consumers"
378);
379pub(crate) const SPELL_SHRED: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::SPELL_SHRED
380 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
381pub(crate) const SPELL_SWIPE: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::SPELL_SWIPE
382 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
383pub(crate) const SPELL_MOONFIRE: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::SPELL_MOONFIRE
384 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
385pub(crate) const SPELL_CAT_FORM: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::SPELL_CAT_FORM
386 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
387pub(crate) const SPELL_MARK_OF_THE_WILD: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::SPELL_MARK_OF_THE_WILD
388 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
389pub(crate) const SPELL_WAITING_FOR_ENERGY: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::SPELL_WAITING_FOR_ENERGY
390 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
391pub(crate) const SPELL_RAKE: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::SPELL_RAKE
392 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
393pub(crate) const SPELL_RIP: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::SPELL_RIP
394 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
395pub(crate) const SPELL_FEROCIOUS_BITE: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::SPELL_FEROCIOUS_BITE
396 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
397pub(crate) const SPELL_PRIMAL_WRATH: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::SPELL_PRIMAL_WRATH
398 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
399pub(crate) const SPELL_FERAL_FRENZY: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::SPELL_FERAL_FRENZY
400 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
401pub(crate) const SPELL_FRANTIC_FRENZY: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::SPELL_FRANTIC_FRENZY
402 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
403pub(crate) const SPELL_TIGERS_FURY: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::SPELL_TIGERS_FURY
404 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
405pub(crate) const SPELL_BERSERK: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::SPELL_BERSERK
406 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
407pub(crate) const SPELL_INCARNATION_AVATAR_OF_ASHAMANE: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::SPELL_INCARNATION_AVATAR_OF_ASHAMANE
408 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
409pub(crate) const SPELL_CONVOKE_THE_SPIRITS: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::SPELL_CONVOKE_THE_SPIRITS
410 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
411pub(crate) const SPELL_WRATH: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::SPELL_WRATH
412 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
413pub(crate) const SPELL_CHOMP: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::feral_druid::SPELL_CHOMP
414 .bind(wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF);
415pub(crate) const SPELL_COUNT: usize = 18;
416const _: () = assert!(
417 SPELL_COUNT == 18,
418 "SPELL index ABI: count changed -- update positional hook consumers"
419);
420pub(crate) mod EFFECT {
421 pub(crate) const APEX_PREDATOR_CHANCE: (u32, u8) = (391_881, 1);
423 pub(crate) const FERAL_FRENZY_HIT: (u32, u8) = (274_838, 1);
425 pub(crate) const FEROCIOUS_BITE_DMG: (u32, u8) = (22568, 1);
427 pub(crate) const HALAZZIS_FURY_GUIDED_MS_PER_CP: (u32, u8) = (1_296_605, 2);
429 pub(crate) const HALAZZIS_FURY_MS_PER_CP: (u32, u8) = (1_296_605, 1);
431 pub(crate) const MOMENT_OF_CLARITY_PROC_BONUS: (u32, u8) = (236_068, 2);
433 pub(crate) const RAZOR_CLAWS_BLOODSEEKER_PERIODIC: (u32, u8) = (77493, 6);
435 pub(crate) const RAZOR_CLAWS_DAMAGE: (u32, u8) = (77493, 1);
437 pub(crate) const RAZOR_CLAWS_DREADFUL_WOUND_PERIODIC: (u32, u8) = (77493, 7);
439 pub(crate) const RAZOR_CLAWS_PERIODIC: (u32, u8) = (77493, 2);
441 pub(crate) const RAZOR_CLAWS_RAMPANT_DIRECT: (u32, u8) = (77493, 5);
443 pub(crate) const RAZOR_CLAWS_RAMPANT_PERIODIC: (u32, u8) = (77493, 4);
445 pub(crate) const RAZOR_CLAWS_UNSEEN_SLASH_PERIODIC: (u32, u8) = (77493, 8);
447 pub(crate) const SUDDEN_AMBUSH_CHANCE: (u32, u8) = (384_667, 1);
449 pub(crate) const THRIVING_GROWTH_RAKE: (u32, u8) = (439_528, 2);
451 pub(crate) const THRIVING_GROWTH_RIP: (u32, u8) = (439_528, 1);
453 pub(crate) const UNSEEN_SLASH_DMG: (u32, u8) = (1_263_890, 1);
455}
456static REPORTED_SPELLS: &[(&str, u32)] = &[("unseen_slash", 1_263_890)];
457static DECLARED_SPELL_IDS: &[u32] = &[
458 5221, 106_785, 155_625, 768, 1126, 1_249_752, 1822, 1079, 22568, 285_381, 274_837,
459 1_243_807, 5217, 106_951, 102_543, 391_528, 5176, 1_244_292, 135_700, 5215, 155_580,
460 155_722, 391_722, 1_271_863, 274_838, 391_882, 449_646, 405_189, 391_873, 1_244_483,
461 439_891, 378_990, 1_301_600, 1_263_939, 1_263_962, 439_531, 391_881, 391_548,
462 343_223, 390_902, 378_988, 236_068, 16864, 1_280_316, 159_286, 391_709, 202_031,
463 158_476, 439_890, 384_667, 384_665, 439_528, 391_872, 1_263_658, 6603, 77493,
464 1_263_890, 1_296_605, 441_591, 1_271_635, 441_812, 441_825, 441_827, 441_585,
465 441_814, 440_122, 455_496, 439_887,
466];
467static DECLARED_AURA_IDS: &[u32] = &[
468 155_625, 135_700, 5215, 768, 1126, 155_580, 1079, 155_722, 391_722, 1_271_863,
469 274_838, 5217, 106_951, 102_543, 391_882, 449_646, 1_244_292, 405_189, 391_873,
470 1_244_483, 439_891, 378_990, 1_301_600, 1_263_939, 1_263_962, 439_531, 441_812,
471 441_825, 441_827, 441_585, 441_814, 439_531, 455_496, 439_887, 439_891,
472];
473static TALENTS: &[(&str, u32)] = &[
474 ("APEX_PREDATORS_CRAVING", TALENT::APEX_PREDATORS_CRAVING),
475 ("ASHAMANES_GUIDANCE", TALENT::ASHAMANES_GUIDANCE),
476 ("BERSERK", TALENT::BERSERK),
477 ("CARNIVOROUS_INSTINCT", TALENT::CARNIVOROUS_INSTINCT),
478 ("CHOMP", TALENT::CHOMP),
479 ("CONVOKE_THE_SPIRITS", TALENT::CONVOKE_THE_SPIRITS),
480 ("FERAL_FRENZY", TALENT::FERAL_FRENZY),
481 ("FRANTIC_FRENZY", TALENT::FRANTIC_FRENZY),
482 ("INCARNATION_AVATAR_OF_ASHAMANE", TALENT::INCARNATION_AVATAR_OF_ASHAMANE),
483 ("LUNAR_INSPIRATION", TALENT::LUNAR_INSPIRATION),
484 ("LYCARAS_TEACHINGS", TALENT::LYCARAS_TEACHINGS),
485 ("MOMENT_OF_CLARITY", TALENT::MOMENT_OF_CLARITY),
486 ("OMEN_OF_CLARITY", TALENT::OMEN_OF_CLARITY),
487 ("PANTHERS_GUILE", TALENT::PANTHERS_GUILE),
488 ("PRIMAL_FURY", TALENT::PRIMAL_FURY),
489 ("PRIMAL_WRATH", TALENT::PRIMAL_WRATH),
490 ("RAMPANT_FEROCITY", TALENT::RAMPANT_FEROCITY),
491 ("SABERTOOTH", TALENT::SABERTOOTH),
492 ("SOUL_OF_THE_FOREST", TALENT::SOUL_OF_THE_FOREST),
493 ("STRATEGIC_INFUSION", TALENT::STRATEGIC_INFUSION),
494 ("SUDDEN_AMBUSH", TALENT::SUDDEN_AMBUSH),
495 ("TASTE_FOR_BLOOD", TALENT::TASTE_FOR_BLOOD),
496 ("THRIVING_GROWTH", TALENT::THRIVING_GROWTH),
497 ("TIGERS_TENACITY", TALENT::TIGERS_TENACITY),
498 ("UNSEEN_PREDATOR", TALENT::UNSEEN_PREDATOR),
499];
500pub(crate) mod FERAL_DRUID {
501 pub(crate) const SHRED_CASTS: u32 = 0;
502 pub(crate) const RAKE_CASTS: u32 = 1;
503 pub(crate) const RIP_CASTS: u32 = 2;
504 pub(crate) const FEROCIOUS_BITE_CASTS: u32 = 3;
505 pub(crate) const TIGERS_FURY_CASTS: u32 = 4;
506 pub(crate) const BERSERK_CASTS: u32 = 5;
507 pub(crate) const FERAL_FRENZY_CASTS: u32 = 6;
508 pub(crate) const TIGERS_FURY_UPTIME_MS: u32 = 7;
509 pub(crate) const BERSERK_UPTIME_MS: u32 = 8;
510 pub(crate) const RIP_UPTIME_MS: u32 = 9;
511 pub(crate) const RAKE_UPTIME_MS: u32 = 10;
512}
513fn aura_moonfire(
514 a: AuraDefinitionDraft,
515 data: &ResolvedGameData,
516) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
517 a.on_target()
518 .apply_base_from_data(data, 155_625)?
519 .max_stacks(
520 data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(155_625))?,
521 )
522 .periodic_damage(
523 wowlab_engine_combat::validated_milliseconds(
524 (data.period(wowlab_types::sim::SpellIdx::from_raw(155_625), 1)) * 0.8,
525 155_625,
526 "periodic_damage.tick_ms",
527 )?,
528 ((data.ap_coef(wowlab_types::sim::SpellIdx::from_raw(155_625), 1)) * 100.0)
529 .round() / 100.0,
530 wowlab_engine_combat::DamageFlags::empty(),
531 )
532 .apply_periodic_behavior_from_data(data, 155_625)
533}
534fn aura_clearcasting(
535 a: AuraDefinitionDraft,
536 data: &ResolvedGameData,
537) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
538 Ok(
539 a
540 .on_player()
541 .apply_base_from_data(data, 135_700)?
542 .max_stacks(
543 data
544 .require_aura_max_stacks(
545 wowlab_types::sim::SpellIdx::from_raw(135_700),
546 )?,
547 ),
548 )
549}
550fn aura_prowl(
551 a: AuraDefinitionDraft,
552 data: &ResolvedGameData,
553) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
554 Ok(
555 a
556 .on_player()
557 .apply_base_from_data(data, 5215)?
558 .max_stacks(
559 data
560 .require_aura_max_stacks(
561 wowlab_types::sim::SpellIdx::from_raw(5215),
562 )?,
563 ),
564 )
565}
566fn aura_cat_form(
567 a: AuraDefinitionDraft,
568 data: &ResolvedGameData,
569) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
570 Ok(
571 a
572 .on_player()
573 .apply_base_from_data(data, 768)?
574 .max_stacks(
575 data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(768))?,
576 ),
577 )
578}
579fn aura_mark_of_the_wild_highlight(
580 a: AuraDefinitionDraft,
581 data: &ResolvedGameData,
582) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
583 Ok(
584 a
585 .on_player()
586 .apply_base_from_data(data, 1126)?
587 .max_stacks(
588 data
589 .require_aura_max_stacks(
590 wowlab_types::sim::SpellIdx::from_raw(1126),
591 )?,
592 ),
593 )
594}
595fn aura_lunar_inspiration(
596 a: AuraDefinitionDraft,
597 data: &ResolvedGameData,
598) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
599 Ok(
600 a
601 .on_player()
602 .apply_base_from_data(data, 155_580)?
603 .max_stacks(
604 data
605 .require_aura_max_stacks(
606 wowlab_types::sim::SpellIdx::from_raw(155_580),
607 )?,
608 ),
609 )
610}
611fn aura_rip(
612 a: AuraDefinitionDraft,
613 data: &ResolvedGameData,
614) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
615 a.on_target()
616 .apply_base_from_data(data, 1079)?
617 .max_stacks(
618 data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(1079))?,
619 )
620 .snapshot()
621 .periodic_damage(
622 wowlab_engine_combat::validated_milliseconds(
623 (data.period(wowlab_types::sim::SpellIdx::from_raw(1079), 1)) * 0.8,
624 1079,
625 "periodic_damage.tick_ms",
626 )?,
627 (((data.ap_coef(wowlab_types::sim::SpellIdx::from_raw(1079), 1)) * 1.3)
628 * 100_000.0)
629 .round() / 100_000.0,
630 wowlab_engine_combat::DamageFlags::PHYSICAL,
631 )
632 .apply_periodic_behavior_from_data(data, 1079)
633}
634fn aura_rake(
635 a: AuraDefinitionDraft,
636 data: &ResolvedGameData,
637) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
638 a.on_target()
639 .apply_base_from_data(data, 155_722)?
640 .max_stacks(
641 data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(155_722))?,
642 )
643 .snapshot()
644 .periodic_damage(
645 wowlab_engine_combat::validated_milliseconds(
646 (data.period(wowlab_types::sim::SpellIdx::from_raw(155_722), 1)) * 0.8,
647 155_722,
648 "periodic_damage.tick_ms",
649 )?,
650 0.18,
651 wowlab_engine_combat::DamageFlags::PHYSICAL,
652 )
653 .apply_periodic_behavior_from_data(data, 155_722)
654}
655fn aura_sabertooth(
656 a: AuraDefinitionDraft,
657 data: &ResolvedGameData,
658) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
659 a.on_target()
660 .apply_base_from_data(data, 391_722)?
661 .no_pandemic()
662 .max_stacks(
663 wowlab_engine_combat::validated_max_stacks(5.0, 391_722, "aura.max_stacks")?,
664 )
665 .damage_taken_from_caster_spells(
666 data,
667 data.base_points(wowlab_types::sim::SpellIdx::from_raw(202_031), 2),
668 )
669}
670fn aura_unseen_slash(
671 a: AuraDefinitionDraft,
672 data: &ResolvedGameData,
673) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
674 a.on_target()
675 .apply_base_from_data(data, 1_271_863)?
676 .max_stacks(
677 data
678 .require_aura_max_stacks(
679 wowlab_types::sim::SpellIdx::from_raw(1_271_863),
680 )?,
681 )
682 .snapshot()
683 .periodic_damage(
684 wowlab_engine_combat::validated_milliseconds(
685 (data.period(wowlab_types::sim::SpellIdx::from_raw(1_271_863), 1)) * 0.8,
686 1_271_863,
687 "periodic_damage.tick_ms",
688 )?,
689 (((data.ap_coef(wowlab_types::sim::SpellIdx::from_raw(1_271_863), 1)) * 1.3)
690 * 1000.0)
691 .round() / 1000.0,
692 wowlab_engine_combat::DamageFlags::PHYSICAL,
693 )
694 .apply_periodic_behavior_from_data(data, 1_271_863)
695}
696fn aura_feral_frenzy(
697 a: AuraDefinitionDraft,
698 data: &ResolvedGameData,
699) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
700 a.on_target()
701 .apply_base_from_data(data, 274_838)?
702 .max_stacks(
703 data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(274_838))?,
704 )
705 .snapshot()
706 .periodic_damage(
707 wowlab_engine_combat::validated_milliseconds(
708 (data.period(wowlab_types::sim::SpellIdx::from_raw(274_838), 2)) * 0.8,
709 274_838,
710 "periodic_damage.tick_ms",
711 )?,
712 (((data.ap_coef(wowlab_types::sim::SpellIdx::from_raw(274_838), 2)) * 5.0)
713 * 10000.0)
714 .round() / 10000.0,
715 wowlab_engine_combat::DamageFlags::PHYSICAL,
716 )
717 .apply_periodic_behavior_from_data(data, 274_838)
718}
719fn aura_tigers_fury(
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, 5217)?
727 .max_stacks(
728 data
729 .require_aura_max_stacks(
730 wowlab_types::sim::SpellIdx::from_raw(5217),
731 )?,
732 ),
733 )
734}
735fn aura_berserk(
736 a: AuraDefinitionDraft,
737 data: &ResolvedGameData,
738) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
739 Ok(
740 a
741 .on_player()
742 .apply_base_from_data(data, 106_951)?
743 .max_stacks(
744 data
745 .require_aura_max_stacks(
746 wowlab_types::sim::SpellIdx::from_raw(106_951),
747 )?,
748 )
749 .on_expire(crate::hooks::feral_druid::halazzis_fury_expire_hook),
750 )
751}
752fn aura_incarnation_avatar_of_ashamane(
753 a: AuraDefinitionDraft,
754 data: &ResolvedGameData,
755) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
756 Ok(
757 a
758 .on_player()
759 .apply_base_from_data(data, 102_543)?
760 .max_stacks(
761 data
762 .require_aura_max_stacks(
763 wowlab_types::sim::SpellIdx::from_raw(102_543),
764 )?,
765 )
766 .on_expire(crate::hooks::feral_druid::halazzis_fury_expire_hook),
767 )
768}
769fn aura_apex_predators_craving(
770 a: AuraDefinitionDraft,
771 data: &ResolvedGameData,
772) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
773 Ok(
774 a
775 .on_player()
776 .apply_base_from_data(data, 391_882)?
777 .max_stacks(
778 data
779 .require_aura_max_stacks(
780 wowlab_types::sim::SpellIdx::from_raw(391_882),
781 )?,
782 ),
783 )
784}
785fn aura_savage_fury(
786 a: AuraDefinitionDraft,
787 data: &ResolvedGameData,
788) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
789 Ok(
790 a
791 .on_player()
792 .apply_base_from_data(data, 449_646)?
793 .max_stacks(
794 data
795 .require_aura_max_stacks(
796 wowlab_types::sim::SpellIdx::from_raw(449_646),
797 )?,
798 ),
799 )
800}
801fn aura_chomp_enabler(
802 a: AuraDefinitionDraft,
803 data: &ResolvedGameData,
804) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
805 Ok(
806 a
807 .on_player()
808 .apply_base_from_data(data, 1_244_292)?
809 .max_stacks(
810 data
811 .require_aura_max_stacks(
812 wowlab_types::sim::SpellIdx::from_raw(1_244_292),
813 )?,
814 ),
815 )
816}
817fn aura_overflowing_power(
818 a: AuraDefinitionDraft,
819 data: &ResolvedGameData,
820) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
821 Ok(
822 a
823 .on_player()
824 .apply_base_from_data(data, 405_189)?
825 .max_stacks(
826 data
827 .require_aura_max_stacks(
828 wowlab_types::sim::SpellIdx::from_raw(405_189),
829 )?,
830 ),
831 )
832}
833fn aura_tigers_tenacity(
834 a: AuraDefinitionDraft,
835 data: &ResolvedGameData,
836) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
837 Ok(
838 a
839 .on_player()
840 .apply_base_from_data(data, 391_873)?
841 .max_stacks(
842 wowlab_engine_combat::validated_max_stacks(
843 3.0,
844 391_873,
845 "aura.max_stacks",
846 )?,
847 ),
848 )
849}
850fn aura_sudden_ambush(
851 a: AuraDefinitionDraft,
852 data: &ResolvedGameData,
853) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
854 Ok(
855 a
856 .on_player()
857 .apply_base_from_data(data, 1_244_483)?
858 .max_stacks(
859 data
860 .require_aura_max_stacks(
861 wowlab_types::sim::SpellIdx::from_raw(1_244_483),
862 )?,
863 ),
864 )
865}
866fn aura_strategic_infusion(
867 a: AuraDefinitionDraft,
868 data: &ResolvedGameData,
869) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
870 Ok(
871 a
872 .on_player()
873 .apply_base_from_data(data, 439_891)?
874 .max_stacks(
875 data
876 .require_aura_max_stacks(
877 wowlab_types::sim::SpellIdx::from_raw(439_891),
878 )?,
879 ),
880 )
881}
882fn aura_lycaras_teachings_crit(
883 a: AuraDefinitionDraft,
884 data: &ResolvedGameData,
885) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
886 a.on_player()
887 .apply_base_from_data(data, 378_990)?
888 .max_stacks(
889 data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(378_990))?,
890 )
891 .crit_per_stack(
892 data.base_points(wowlab_types::sim::SpellIdx::from_raw(378_988), 1),
893 )
894}
895fn aura_halazzis_fury(
896 a: AuraDefinitionDraft,
897 data: &ResolvedGameData,
898) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
899 Ok(
900 a
901 .on_player()
902 .apply_base_from_data(data, 1_301_600)?
903 .max_stacks(
904 data
905 .require_aura_max_stacks(
906 wowlab_types::sim::SpellIdx::from_raw(1_301_600),
907 )?,
908 ),
909 )
910}
911fn aura_unseen_predators_craving(
912 a: AuraDefinitionDraft,
913 data: &ResolvedGameData,
914) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
915 a.on_player()
916 .apply_base_from_data(data, 1_263_939)?
917 .max_stacks(
918 data
919 .require_aura_max_stacks(
920 wowlab_types::sim::SpellIdx::from_raw(1_263_939),
921 )?,
922 )
923 .no_pandemic()
924 .forwarded_effect_value(
925 data,
926 data.base_points(wowlab_types::sim::SpellIdx::from_raw(1_263_658), 1),
927 )
928}
929fn aura_stalking_predator(
930 a: AuraDefinitionDraft,
931 data: &ResolvedGameData,
932) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
933 Ok(
934 a
935 .on_player()
936 .apply_base_from_data(data, 1_263_962)?
937 .max_stacks(
938 data
939 .require_aura_max_stacks(
940 wowlab_types::sim::SpellIdx::from_raw(1_263_962),
941 )?,
942 ),
943 )
944}
945fn aura_bloodseeker_vines(
946 a: AuraDefinitionDraft,
947 data: &ResolvedGameData,
948) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
949 Ok(
950 a
951 .on_target()
952 .apply_base_from_data(data, 439_531)?
953 .max_stacks(
954 data
955 .require_aura_max_stacks(
956 wowlab_types::sim::SpellIdx::from_raw(439_531),
957 )?,
958 )
959 .snapshot()
960 .async_stacks()
961 .periodic_damage_scales_with_stacks(),
962 )
963}
964fn spell_shred(
965 s: SpellDefinitionDraft,
966 data: &ResolvedGameData,
967) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
968 Ok(
969 s
970 .apply_base_from_data(data, 5221)?
971 .apply_aoe_from_data(data)
972 .on_cast(crate::hooks::feral_druid::shred_hook)
973 .cost_free_when_aura(135_700)
974 .consume_aura_on_cast(1_244_483),
975 )
976}
977fn spell_swipe(
978 s: SpellDefinitionDraft,
979 data: &ResolvedGameData,
980) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
981 Ok(
982 s
983 .apply_base_from_data(data, 106_785)?
984 .apply_aoe_from_data(data)
985 .on_cast(crate::hooks::feral_druid::builder_hook)
986 .consume_aura_on_cast(1_244_483),
987 )
988}
989fn spell_moonfire(
990 s: SpellDefinitionDraft,
991 data: &ResolvedGameData,
992) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
993 Ok(
994 s
995 .apply_base_from_data(data, 155_625)?
996 .applies_inferred_aura(AURA_MOONFIRE, 155_625)
997 .apply_aoe_from_data(data)
998 .on_cast(crate::hooks::feral_druid::moonfire_hook),
999 )
1000}
1001fn spell_cat_form(
1002 s: SpellDefinitionDraft,
1003 data: &ResolvedGameData,
1004) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1005 Ok(
1006 s
1007 .apply_base_from_data(data, 768)?
1008 .applies_inferred_aura(AURA_CAT_FORM, 768)
1009 .apply_aoe_from_data(data)
1010 .on_cast(crate::hooks::feral_druid::cat_form_hook),
1011 )
1012}
1013fn spell_mark_of_the_wild(
1014 s: SpellDefinitionDraft,
1015 data: &ResolvedGameData,
1016) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1017 Ok(
1018 s
1019 .apply_base_from_data(data, 1126)?
1020 .applies_inferred_aura(AURA_MARK_OF_THE_WILD_HIGHLIGHT, 1126)
1021 .apply_aoe_from_data(data),
1022 )
1023}
1024fn spell_waiting_for_energy(
1025 s: SpellDefinitionDraft,
1026 data: &ResolvedGameData,
1027) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1028 Ok(s.apply_base_from_data(data, 1_249_752)?.apply_aoe_from_data(data))
1029}
1030fn spell_rake(
1031 s: SpellDefinitionDraft,
1032 data: &ResolvedGameData,
1033) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1034 Ok(
1035 s
1036 .apply_base_from_data(data, 1822)?
1037 .applies_aura(AURA_RAKE)
1038 .apply_aoe_from_data(data)
1039 .on_cast(crate::hooks::feral_druid::rake_hook)
1040 .consume_aura_on_cast(1_244_483),
1041 )
1042}
1043fn spell_rip(
1044 s: SpellDefinitionDraft,
1045 data: &ResolvedGameData,
1046) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1047 Ok(
1048 s
1049 .apply_base_from_data(data, 1079)?
1050 .applies_inferred_aura(AURA_RIP, 1079)
1051 .apply_aoe_from_data(data)
1052 .on_cast(crate::hooks::feral_druid::rip_hook),
1053 )
1054}
1055fn spell_ferocious_bite(
1056 s: SpellDefinitionDraft,
1057 data: &ResolvedGameData,
1058) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1059 Ok(
1060 s
1061 .apply_base_from_data(data, 22568)?
1062 .damage_flat(0.0)
1063 .apply_aoe_from_data(data)
1064 .on_cast(crate::hooks::feral_druid::ferocious_bite_hook),
1065 )
1066}
1067fn spell_primal_wrath(
1068 s: SpellDefinitionDraft,
1069 data: &ResolvedGameData,
1070) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1071 Ok(s.apply_base_from_data(data, 285_381)?.apply_aoe_from_data(data))
1072}
1073fn spell_feral_frenzy(
1074 s: SpellDefinitionDraft,
1075 data: &ResolvedGameData,
1076) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1077 Ok(
1078 s
1079 .apply_base_from_data(data, 274_837)?
1080 .applies_aura(AURA_FERAL_FRENZY)
1081 .apply_aoe_from_data(data)
1082 .on_cast(crate::hooks::feral_druid::feral_frenzy_hook),
1083 )
1084}
1085fn spell_frantic_frenzy(
1086 s: SpellDefinitionDraft,
1087 data: &ResolvedGameData,
1088) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1089 Ok(s.apply_base_from_data(data, 1_243_807)?.apply_aoe_from_data(data))
1090}
1091fn spell_tigers_fury(
1092 s: SpellDefinitionDraft,
1093 data: &ResolvedGameData,
1094) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1095 Ok(
1096 s
1097 .apply_base_from_data(data, 5217)?
1098 .applies_inferred_aura(AURA_TIGERS_FURY, 5217)
1099 .apply_aoe_from_data(data)
1100 .on_cast(crate::hooks::feral_druid::tigers_fury_hook),
1101 )
1102}
1103fn spell_berserk(
1104 s: SpellDefinitionDraft,
1105 data: &ResolvedGameData,
1106) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1107 Ok(
1108 s
1109 .apply_base_from_data(data, 106_951)?
1110 .applies_inferred_aura(AURA_BERSERK, 106_951)
1111 .apply_aoe_from_data(data),
1112 )
1113}
1114fn spell_incarnation_avatar_of_ashamane(
1115 s: SpellDefinitionDraft,
1116 data: &ResolvedGameData,
1117) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1118 Ok(
1119 s
1120 .apply_base_from_data(data, 102_543)?
1121 .applies_inferred_aura(AURA_INCARNATION_AVATAR_OF_ASHAMANE, 102_543)
1122 .apply_aoe_from_data(data),
1123 )
1124}
1125fn spell_convoke_the_spirits(
1126 s: SpellDefinitionDraft,
1127 data: &ResolvedGameData,
1128) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1129 Ok(
1130 s
1131 .apply_base_from_data(data, 391_528)?
1132 .apply_aoe_from_data(data)
1133 .channel(
1134 data
1135 .require_channel_tick_count(
1136 wowlab_types::sim::SpellIdx::from_raw(391_528),
1137 )?,
1138 )
1139 .on_channel_tick(crate::hooks::feral_druid::convoke_tick_hook)
1140 .on_cast(crate::hooks::feral_druid::convoke_cast_hook),
1141 )
1142}
1143fn spell_wrath(
1144 s: SpellDefinitionDraft,
1145 data: &ResolvedGameData,
1146) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1147 Ok(s.apply_base_from_data(data, 5176)?.apply_aoe_from_data(data))
1148}
1149fn spell_chomp(
1150 s: SpellDefinitionDraft,
1151 data: &ResolvedGameData,
1152) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1153 Ok(
1154 s
1155 .apply_base_from_data(data, 1_244_292)?
1156 .applies_inferred_aura(AURA_CHOMP_ENABLER, 1_244_292)
1157 .apply_aoe_from_data(data),
1158 )
1159}
1160pub(crate) fn build_combat_system_draft(
1161 params: &wowlab_engine_ports::HandlerParams<'_>,
1162) -> Result<CombatSystemDraft, wowlab_engine_ports::EngineError> {
1163 let builder = CombatSystemBuilder::new(params.stats.clone())
1164 .spec_id(SpecId::Feral)
1165 .spec_identity(
1166 wowlab_engine_combat::generated_identities::specs::feral_druid::PROOF,
1167 )
1168 .hero_talent_trees(DECLARED_METADATA.hero_talent_trees)
1169 .effect_identities(
1170 wowlab_engine_combat::generated_identities::specs::feral_druid::damage::ALL,
1171 )
1172 .effect_identities(wowlab_engine_combat::generated_identities::shared::ALL)
1173 .mastery_spell(77493)
1174 .mastery_hook(crate::hooks::feral_druid::mastery)
1175 .resource(
1176 "energy",
1177 params
1178 .game_data
1179 .power_max(3)
1180 .ok_or_else(|| {
1181 wowlab_engine_ports::EngineError::spec_construction(
1182 "missing power-type power_max for type_id 3",
1183 )
1184 })?,
1185 12.65,
1186 )
1187 .resource_type_id(3)
1188 .resource_start(
1189 params
1190 .game_data
1191 .power_default(3)
1192 .ok_or_else(|| {
1193 wowlab_engine_ports::EngineError::spec_construction(
1194 "missing power-type power_default for type_id 3",
1195 )
1196 })?,
1197 )
1198 .secondary_resource(
1199 "combo_points",
1200 params
1201 .game_data
1202 .power_max(4)
1203 .ok_or_else(|| {
1204 wowlab_engine_ports::EngineError::spec_construction(
1205 "missing power-type power_max for type_id 4",
1206 )
1207 })?,
1208 )
1209 .secondary_resource_type_id(4)
1210 .aura("moonfire", AURA::MOONFIRE, |a| aura_moonfire(a, ¶ms.game_data))
1211 .aura(
1212 "clearcasting",
1213 AURA::CLEARCASTING,
1214 |a| aura_clearcasting(a, ¶ms.game_data),
1215 )
1216 .aura("prowl", AURA::PROWL, |a| aura_prowl(a, ¶ms.game_data))
1217 .aura("cat_form", AURA::CAT_FORM, |a| aura_cat_form(a, ¶ms.game_data))
1218 .aura(
1219 "mark_of_the_wild_highlight",
1220 AURA::MARK_OF_THE_WILD_HIGHLIGHT,
1221 |a| aura_mark_of_the_wild_highlight(a, ¶ms.game_data),
1222 )
1223 .aura(
1224 "lunar_inspiration",
1225 AURA::LUNAR_INSPIRATION,
1226 |a| aura_lunar_inspiration(a, ¶ms.game_data),
1227 )
1228 .aura("rip", AURA::RIP, |a| aura_rip(a, ¶ms.game_data))
1229 .aura("rake", AURA::RAKE, |a| aura_rake(a, ¶ms.game_data))
1230 .aura("sabertooth", AURA::SABERTOOTH, |a| aura_sabertooth(a, ¶ms.game_data))
1231 .aura(
1232 "unseen_slash",
1233 AURA::UNSEEN_SLASH,
1234 |a| aura_unseen_slash(a, ¶ms.game_data),
1235 )
1236 .aura(
1237 "feral_frenzy",
1238 AURA::FERAL_FRENZY,
1239 |a| aura_feral_frenzy(a, ¶ms.game_data),
1240 )
1241 .aura(
1242 "tigers_fury",
1243 AURA::TIGERS_FURY,
1244 |a| aura_tigers_fury(a, ¶ms.game_data),
1245 )
1246 .aura("berserk", AURA::BERSERK, |a| aura_berserk(a, ¶ms.game_data))
1247 .aura(
1248 "incarnation_avatar_of_ashamane",
1249 AURA::INCARNATION_AVATAR_OF_ASHAMANE,
1250 |a| aura_incarnation_avatar_of_ashamane(a, ¶ms.game_data),
1251 )
1252 .aura(
1253 "apex_predators_craving",
1254 AURA::APEX_PREDATORS_CRAVING,
1255 |a| aura_apex_predators_craving(a, ¶ms.game_data),
1256 )
1257 .aura(
1258 "savage_fury",
1259 AURA::SAVAGE_FURY,
1260 |a| aura_savage_fury(a, ¶ms.game_data),
1261 )
1262 .aura(
1263 "chomp_enabler",
1264 AURA::CHOMP_ENABLER,
1265 |a| aura_chomp_enabler(a, ¶ms.game_data),
1266 )
1267 .aura(
1268 "overflowing_power",
1269 AURA::OVERFLOWING_POWER,
1270 |a| aura_overflowing_power(a, ¶ms.game_data),
1271 )
1272 .aura(
1273 "tigers_tenacity",
1274 AURA::TIGERS_TENACITY,
1275 |a| aura_tigers_tenacity(a, ¶ms.game_data),
1276 )
1277 .aura(
1278 "sudden_ambush",
1279 AURA::SUDDEN_AMBUSH,
1280 |a| aura_sudden_ambush(a, ¶ms.game_data),
1281 )
1282 .aura(
1283 "strategic_infusion",
1284 AURA::STRATEGIC_INFUSION,
1285 |a| aura_strategic_infusion(a, ¶ms.game_data),
1286 )
1287 .aura(
1288 "lycaras_teachings_crit",
1289 AURA::LYCARAS_TEACHINGS_CRIT,
1290 |a| aura_lycaras_teachings_crit(a, ¶ms.game_data),
1291 )
1292 .aura(
1293 "halazzis_fury",
1294 AURA::HALAZZIS_FURY,
1295 |a| aura_halazzis_fury(a, ¶ms.game_data),
1296 )
1297 .aura(
1298 "unseen_predators_craving",
1299 AURA::UNSEEN_PREDATORS_CRAVING,
1300 |a| aura_unseen_predators_craving(a, ¶ms.game_data),
1301 )
1302 .aura(
1303 "stalking_predator",
1304 AURA::STALKING_PREDATOR,
1305 |a| aura_stalking_predator(a, ¶ms.game_data),
1306 )
1307 .aura(
1308 "bloodseeker_vines",
1309 AURA::BLOODSEEKER_VINES,
1310 |a| aura_bloodseeker_vines(a, ¶ms.game_data),
1311 )
1312 .spell("shred", SPELL::SHRED, |s| spell_shred(s, ¶ms.game_data))
1313 .spell("swipe", SPELL::SWIPE, |s| spell_swipe(s, ¶ms.game_data))
1314 .spell("moonfire", SPELL::MOONFIRE, |s| spell_moonfire(s, ¶ms.game_data))
1315 .spell("cat_form", SPELL::CAT_FORM, |s| spell_cat_form(s, ¶ms.game_data))
1316 .spell(
1317 "mark_of_the_wild",
1318 SPELL::MARK_OF_THE_WILD,
1319 |s| spell_mark_of_the_wild(s, ¶ms.game_data),
1320 )
1321 .spell(
1322 "waiting_for_energy",
1323 SPELL::WAITING_FOR_ENERGY,
1324 |s| spell_waiting_for_energy(s, ¶ms.game_data),
1325 )
1326 .spell("rake", SPELL::RAKE, |s| spell_rake(s, ¶ms.game_data))
1327 .spell("rip", SPELL::RIP, |s| spell_rip(s, ¶ms.game_data))
1328 .spell(
1329 "ferocious_bite",
1330 SPELL::FEROCIOUS_BITE,
1331 |s| spell_ferocious_bite(s, ¶ms.game_data),
1332 )
1333 .spell(
1334 "primal_wrath",
1335 SPELL::PRIMAL_WRATH,
1336 |s| spell_primal_wrath(s, ¶ms.game_data),
1337 )
1338 .spell(
1339 "feral_frenzy",
1340 SPELL::FERAL_FRENZY,
1341 |s| spell_feral_frenzy(s, ¶ms.game_data),
1342 )
1343 .spell(
1344 "frantic_frenzy",
1345 SPELL::FRANTIC_FRENZY,
1346 |s| spell_frantic_frenzy(s, ¶ms.game_data),
1347 )
1348 .spell(
1349 "tigers_fury",
1350 SPELL::TIGERS_FURY,
1351 |s| spell_tigers_fury(s, ¶ms.game_data),
1352 )
1353 .spell("berserk", SPELL::BERSERK, |s| spell_berserk(s, ¶ms.game_data))
1354 .spell(
1355 "incarnation_avatar_of_ashamane",
1356 SPELL::INCARNATION_AVATAR_OF_ASHAMANE,
1357 |s| spell_incarnation_avatar_of_ashamane(s, ¶ms.game_data),
1358 )
1359 .spell(
1360 "convoke_the_spirits",
1361 SPELL::CONVOKE_THE_SPIRITS,
1362 |s| spell_convoke_the_spirits(s, ¶ms.game_data),
1363 )
1364 .spell("wrath", SPELL::WRATH, |s| spell_wrath(s, ¶ms.game_data))
1365 .spell("chomp", SPELL::CHOMP, |s| spell_chomp(s, ¶ms.game_data))
1366 .auto_attack(|a| {
1367 a
1368 .spell_id(6603)
1369 .swing_ms(1000)
1370 .apply_base_from_data(¶ms.game_data)
1371 .on_swing(crate::hooks::feral_druid::swing_hook)
1372 })
1373 .game_data(params.game_data.clone())
1374 .talent_spell_ids(TALENTS)
1375 .talent_selections(params.talent_selections)
1376 .set_bonus_auras(params.set_bonus_auras)
1377 .encounter(params.encounter.clone());
1378 let builder = crate::generated::items::register_equipped(
1379 builder,
1380 ¶ms.game_data,
1381 params.equipped_items,
1382 )?;
1383
1384 builder.into_draft()
1385}
1386fn new_handler(
1387 params: wowlab_engine_ports::HandlerParams<'_>,
1388) -> Result<Box<dyn SpecHandler>, wowlab_engine_ports::EngineError> {
1389 let handler = crate::composition::compose_handler(
1390 build_combat_system_draft,
1391 ¶ms,
1392 crate::hooks::feral_druid::FeralHandler::new,
1393 )?;
1394
1395 Ok(Box::new(handler))
1396}
1397static DECLARED_METADATA: DeclaredSpecMetadata = DeclaredSpecMetadata {
1398 primary_resource: ResourceType::Energy,
1399 secondary_resource: Some(ResourceType::ComboPoints),
1400 spell_ids: DECLARED_SPELL_IDS,
1401 aura_ids: DECLARED_AURA_IDS,
1402 server_proc_entries: &[],
1403 talents: TALENTS,
1404 rotation_field_schema: &[],
1405 metrics_plugin_id: None,
1406 hero_talent_trees: &[
1407 HeroTalentTreeDesc {
1408 name: "Druid Of The Claw",
1409 spells: HERO_TREE_DRUID_OF_THE_CLAW_SPELLS,
1410 auras: HERO_TREE_DRUID_OF_THE_CLAW_AURAS,
1411 },
1412 HeroTalentTreeDesc {
1413 name: "Wildstalker",
1414 spells: HERO_TREE_WILDSTALKER_SPELLS,
1415 auras: HERO_TREE_WILDSTALKER_AURAS,
1416 },
1417 ],
1418 reported_spells: REPORTED_SPELLS,
1419 masked_passive_effects: &[(474_530, 3), (474_530, 4)],
1420 passive_effect_overrides: &[],
1421};
1422pub(super) const SPEC_DESCRIPTOR: SpecDescriptor = SpecDescriptor {
1423 spec_id: SpecId::Feral,
1424 display_name: "Feral Druid",
1425 metadata: DECLARED_METADATA,
1426 handler_factory: new_handler,
1427};
1428wowlab_engine_combat::smoke_test!(build_combat_system_draft);