1#![allow(non_snake_case, dead_code)]
4use wowlab_types::{combat::ResourceType, game::SpecId};
5use wowlab_engine_combat::{
6 BuiltCombatSystem, AuraDefinitionDraft, LocalAuraIdx, LocalSpellIdx,
7 SpellDefinitionDraft,
8};
9use wowlab_engine_ports::{
10 DeclaredSpecMetadata, SpecDescriptor, SpecHandler, HeroTalentTreeDesc,
11};
12use wowlab_engine_gamedata::ResolvedGameData;
13pub(crate) mod SPELL {
14 pub(crate) const CRUSADER_STRIKE: u32 = 35395;
16 pub(crate) const JUDGMENT: u32 = 20271;
18 pub(crate) const BLADE_OF_JUSTICE: u32 = 184_575;
20 pub(crate) const TEMPLARS_VERDICT: u32 = 85256;
22 pub(crate) const DIVINE_STORM: u32 = 53385;
24 pub(crate) const WAKE_OF_ASHES: u32 = 255_937;
26 pub(crate) const AVENGING_WRATH: u32 = 31884;
28 pub(crate) const FINAL_VERDICT: u32 = 383_328;
30 pub(crate) const CRUSADING_STRIKE: u32 = 408_385;
32 pub(crate) const LIGHT_WITHIN_BOJ: u32 = 1_261_160;
34 pub(crate) const HIGHLORDS_JUDGMENT: u32 = 383_921;
36 pub(crate) const JUDGMENT_DIVINE_TOLL: u32 = 406_957;
38 pub(crate) const HAMMER_OF_WRATH_DIVINE_TOLL: u32 = 1_279_408;
40 pub(crate) const DIVINE_TOLL: u32 = 375_576;
42 pub(crate) const HAMMER_OF_WRATH: u32 = 24275;
44 pub(crate) const EXECUTION_SENTENCE: u32 = 343_527;
46 pub(crate) const HAMMER_OF_LIGHT: u32 = 427_453;
48 pub(crate) const EMPYREAN_HAMMER: u32 = 431_398;
50}
51pub(crate) mod AURA {
52 pub(crate) const AVENGING_WRATH: u32 = 31884;
54 pub(crate) const EMPYREAN_POWER: u32 = 326_733;
56 pub(crate) const EMPYREAN_LEGACY: u32 = 387_178;
58 pub(crate) const DIVINE_PURPOSE: u32 = 408_458;
60 pub(crate) const ART_OF_WAR: u32 = 406_086;
62 pub(crate) const RIGHTEOUS_CAUSE: u32 = 402_916;
64 pub(crate) const HAMMER_OF_WRATH: u32 = 1_277_026;
66 pub(crate) const JUDGMENT_DEBUFF: u32 = 197_277;
68 pub(crate) const SANCTIFY: u32 = 382_538;
70 pub(crate) const EXPURGATION: u32 = 383_346;
72 pub(crate) const TRUTHS_WAKE: u32 = 403_695;
74 pub(crate) const CRUSADING_STRIKES: u32 = 404_542;
76 pub(crate) const ZEALOTS_FERVOR: u32 = 403_509;
78 pub(crate) const CONSECRATED_BLADE_LOCKOUT: u32 = 407_475;
80 pub(crate) const SANCTIFICATION: u32 = 433_671;
82 pub(crate) const RUSH_OF_LIGHT: u32 = 407_065;
84 pub(crate) const EXECUTION_SENTENCE: u32 = 343_527;
86 pub(crate) const EXECUTION_SENTENCE_GATHER: u32 = 1_260_251;
88 pub(crate) const EXECUTION_SENTENCE_TRACKER: u32 = 1_234_189;
90 pub(crate) const HAMMER_OF_LIGHT: u32 = 427_441;
92 pub(crate) const HAMMER_OF_LIGHT_FREE: u32 = 433_732;
94 pub(crate) const SHAKE_THE_HEAVENS: u32 = 431_536;
96 pub(crate) const LIGHTS_DELIVERANCE: u32 = 433_674;
98 pub(crate) const UNDISPUTED_RULING: u32 = 432_629;
100 pub(crate) const DIVINE_HAMMER: u32 = 198_034;
102}
103pub(crate) mod TALENT {
104 pub(crate) const ART_OF_WAR: u32 = 406_064;
106 pub(crate) const BLADE_OF_JUSTICE: u32 = 184_575;
108 pub(crate) const BLADE_OF_VENGEANCE: u32 = 404_358;
110 pub(crate) const BLESSED_CHAMPION: u32 = 403_010;
112 pub(crate) const BURN_TO_ASH: u32 = 446_663;
114 pub(crate) const CONSECRATED_BLADE: u32 = 404_834;
116 pub(crate) const CRUSADE: u32 = 1_253_598;
118 pub(crate) const CRUSADING_STRIKES: u32 = 404_542;
120 pub(crate) const DIVINE_PURPOSE: u32 = 408_459;
122 pub(crate) const DIVINE_STORM: u32 = 53385;
124 pub(crate) const DIVINE_TOLL: u32 = 375_576;
126 pub(crate) const EMPYREAN_LEGACY: u32 = 387_170;
128 pub(crate) const EMPYREAN_POWER: u32 = 326_732;
130 pub(crate) const EXECUTION_SENTENCE: u32 = 343_527;
132 pub(crate) const EXPURGATION: u32 = 383_344;
134 pub(crate) const FINAL_VERDICT: u32 = 383_328;
136 pub(crate) const GREATER_JUDGMENT: u32 = 231_663;
138 pub(crate) const HAMMER_OF_WRATH_TALENT: u32 = 1_241_288;
140 pub(crate) const HEART_OF_THE_CRUSADER: u32 = 406_154;
142 pub(crate) const HIGHLORDS_WRATH: u32 = 404_512;
144 pub(crate) const HOLY_BLADE: u32 = 383_342;
146 pub(crate) const IMPROVED_JUDGMENT: u32 = 405_461;
148 pub(crate) const JUDGE_JURY_AND_EXECUTIONER: u32 = 453_433;
150 pub(crate) const LIGHT_OF_JUSTICE: u32 = 404_436;
152 pub(crate) const LIGHT_WITHIN: u32 = 1_261_113;
154 pub(crate) const LIGHT_WITHIN_VERDICT: u32 = 1_261_111;
156 pub(crate) const LIGHT_WITHIN_WAVE: u32 = 1_261_159;
158 pub(crate) const QUICKENED_INVOCATION: u32 = 379_391;
160 pub(crate) const RADIANT_GLORY: u32 = 458_359;
162 pub(crate) const RIGHTEOUS_CAUSE: u32 = 402_912;
164 pub(crate) const RUSH_OF_LIGHT: u32 = 407_067;
166 pub(crate) const SANCTIFY: u32 = 382_536;
168 pub(crate) const SEETHING_FLAMES: u32 = 405_355;
170 pub(crate) const TEMPEST_OF_THE_LIGHTBRINGER: u32 = 383_396;
172 pub(crate) const TEMPLAR_STRIKES: u32 = 406_646;
174 pub(crate) const VENGEFUL_WRATH: u32 = 1_241_958;
176 pub(crate) const WAKE_OF_ASHES: u32 = 255_937;
178 pub(crate) const ZEALOTS_FERVOR: u32 = 403_509;
180}
181pub(crate) mod SET_BONUS {
182 pub(crate) const MID1_RETRIBUTION_4PC: u32 = 1_264_849;
184}
185pub(crate) mod REPORTED_SPELL {
186 pub(crate) const BLADE_OF_VENGEANCE: u32 = 404_358;
188 pub(crate) const EXECUTION_SENTENCE: u32 = 387_113;
190 pub(crate) const EXECUTION_SENTENCE_INIT: u32 = 1_260_251;
192 pub(crate) const EXPURGATION: u32 = 383_346;
194}
195pub(crate) mod HERO {
196 pub(crate) mod TEMPLAR {
197 pub(crate) mod SPELL {
198 pub(crate) const DIVINE_EXACTION: u32 = 1_260_429;
200 pub(crate) const DIVINE_HAMMER: u32 = 198_034;
202 pub(crate) const DIVINE_HAMMER_TALENT: u32 = 432_929;
204 pub(crate) const DIVINE_HAMMER_TICK: u32 = 198_137;
206 pub(crate) const EMPYREAN_HAMMER: u32 = 431_398;
208 pub(crate) const EMPYREAN_HAMMER_WD: u32 = 431_625;
210 pub(crate) const HAMMERFALL: u32 = 432_463;
212 pub(crate) const HAMMER_OF_LIGHT: u32 = 427_453;
214 pub(crate) const HIGHER_CALLING: u32 = 431_687;
216 pub(crate) const LIGHTS_DELIVERANCE_TALENT: u32 = 425_518;
218 pub(crate) const LIGHTS_GUIDANCE: u32 = 427_445;
220 pub(crate) const LIGHTS_JUDICATOR: u32 = 1_261_525;
222 pub(crate) const SANCTIFICATION_TALENT: u32 = 432_977;
224 pub(crate) const SHAKE_THE_HEAVENS_TALENT: u32 = 431_533;
226 pub(crate) const UNDISPUTED_RULING_TALENT: u32 = 432_626;
228 pub(crate) const ZEALOUS_VINDICATION: u32 = 431_463;
230 }
231 pub(crate) mod AURA {
232 pub(crate) const HAMMER_OF_LIGHT_READY: u32 = 427_441;
234 pub(crate) const LIGHTS_DELIVERANCE: u32 = 433_674;
236 pub(crate) const SANCTIFICATION: u32 = 433_671;
238 pub(crate) const SHAKE_THE_HEAVENS: u32 = 431_536;
240 pub(crate) const TEMPLAR_STRIKES: u32 = 406_648;
242 pub(crate) const UNDISPUTED_RULING: u32 = 432_629;
244 }
245 }
246 pub(crate) mod HERALD_OF_THE_SUN {
247 pub(crate) mod SPELL {
248 pub(crate) const SECOND_SUNRISE: u32 = 431_474;
250 pub(crate) const SUN_SEAR: u32 = 431_414;
252 }
253 pub(crate) mod AURA {
254 pub(crate) const BLESSING_OF_ANSHE: u32 = 445_206;
256 pub(crate) const BORN_IN_SUNLIGHT: u32 = 1_264_050;
258 pub(crate) const DAWNLIGHT: u32 = 431_522;
260 pub(crate) const MORNING_STAR: u32 = 431_539;
262 pub(crate) const SOLAR_GRACE: u32 = 431_404;
264 }
265 }
266}
267static HERO_TREE_TEMPLAR_SPELLS: &[(&str, u32)] = &[
268 ("DIVINE_EXACTION", 1_260_429),
269 ("DIVINE_HAMMER", 198_034),
270 ("DIVINE_HAMMER_TALENT", 432_929),
271 ("DIVINE_HAMMER_TICK", 198_137),
272 ("EMPYREAN_HAMMER", 431_398),
273 ("EMPYREAN_HAMMER_WD", 431_625),
274 ("HAMMERFALL", 432_463),
275 ("HAMMER_OF_LIGHT", 427_453),
276 ("HIGHER_CALLING", 431_687),
277 ("LIGHTS_DELIVERANCE_TALENT", 425_518),
278 ("LIGHTS_GUIDANCE", 427_445),
279 ("LIGHTS_JUDICATOR", 1_261_525),
280 ("SANCTIFICATION_TALENT", 432_977),
281 ("SHAKE_THE_HEAVENS_TALENT", 431_533),
282 ("UNDISPUTED_RULING_TALENT", 432_626),
283 ("ZEALOUS_VINDICATION", 431_463),
284];
285static HERO_TREE_TEMPLAR_AURAS: &[(&str, u32)] = &[
286 ("HAMMER_OF_LIGHT_READY", 427_441),
287 ("LIGHTS_DELIVERANCE", 433_674),
288 ("SANCTIFICATION", 433_671),
289 ("SHAKE_THE_HEAVENS", 431_536),
290 ("TEMPLAR_STRIKES", 406_648),
291 ("UNDISPUTED_RULING", 432_629),
292];
293static HERO_TREE_HERALD_OF_THE_SUN_SPELLS: &[(&str, u32)] = &[
294 ("SECOND_SUNRISE", 431_474),
295 ("SUN_SEAR", 431_414),
296];
297static HERO_TREE_HERALD_OF_THE_SUN_AURAS: &[(&str, u32)] = &[
298 ("BLESSING_OF_ANSHE", 445_206),
299 ("BORN_IN_SUNLIGHT", 1_264_050),
300 ("DAWNLIGHT", 431_522),
301 ("MORNING_STAR", 431_539),
302 ("SOLAR_GRACE", 431_404),
303];
304pub(crate) const AURA_AVENGING_WRATH: LocalAuraIdx = LocalAuraIdx::new(0);
305pub(crate) const AURA_EMPYREAN_POWER: LocalAuraIdx = LocalAuraIdx::new(1);
306pub(crate) const AURA_EMPYREAN_LEGACY: LocalAuraIdx = LocalAuraIdx::new(2);
307pub(crate) const AURA_DIVINE_PURPOSE: LocalAuraIdx = LocalAuraIdx::new(3);
308pub(crate) const AURA_ART_OF_WAR: LocalAuraIdx = LocalAuraIdx::new(4);
309pub(crate) const AURA_RIGHTEOUS_CAUSE: LocalAuraIdx = LocalAuraIdx::new(5);
310pub(crate) const AURA_HAMMER_OF_WRATH: LocalAuraIdx = LocalAuraIdx::new(6);
311pub(crate) const AURA_JUDGMENT_DEBUFF: LocalAuraIdx = LocalAuraIdx::new(7);
312pub(crate) const AURA_SANCTIFY: LocalAuraIdx = LocalAuraIdx::new(8);
313pub(crate) const AURA_EXPURGATION: LocalAuraIdx = LocalAuraIdx::new(9);
314pub(crate) const AURA_TRUTHS_WAKE: LocalAuraIdx = LocalAuraIdx::new(10);
315pub(crate) const AURA_CRUSADING_STRIKES: LocalAuraIdx = LocalAuraIdx::new(11);
316pub(crate) const AURA_ZEALOTS_FERVOR: LocalAuraIdx = LocalAuraIdx::new(12);
317pub(crate) const AURA_CONSECRATED_BLADE_LOCKOUT: LocalAuraIdx = LocalAuraIdx::new(13);
318pub(crate) const AURA_SANCTIFICATION: LocalAuraIdx = LocalAuraIdx::new(14);
319pub(crate) const AURA_RUSH_OF_LIGHT: LocalAuraIdx = LocalAuraIdx::new(15);
320pub(crate) const AURA_EXECUTION_SENTENCE: LocalAuraIdx = LocalAuraIdx::new(16);
321pub(crate) const AURA_EXECUTION_SENTENCE_GATHER: LocalAuraIdx = LocalAuraIdx::new(17);
322pub(crate) const AURA_EXECUTION_SENTENCE_TRACKER: LocalAuraIdx = LocalAuraIdx::new(18);
323pub(crate) const AURA_HAMMER_OF_LIGHT: LocalAuraIdx = LocalAuraIdx::new(19);
324pub(crate) const AURA_HAMMER_OF_LIGHT_FREE: LocalAuraIdx = LocalAuraIdx::new(20);
325pub(crate) const AURA_SHAKE_THE_HEAVENS: LocalAuraIdx = LocalAuraIdx::new(21);
326pub(crate) const AURA_LIGHTS_DELIVERANCE: LocalAuraIdx = LocalAuraIdx::new(22);
327pub(crate) const AURA_UNDISPUTED_RULING: LocalAuraIdx = LocalAuraIdx::new(23);
328pub(crate) const AURA_DIVINE_HAMMER: LocalAuraIdx = LocalAuraIdx::new(24);
329pub(crate) const AURA_COUNT: usize = 25;
330const _: () = assert!(
331 AURA_COUNT == 25, "AURA index ABI: count changed -- update positional hook consumers"
332);
333pub(crate) const SPELL_CRUSADER_STRIKE: LocalSpellIdx = LocalSpellIdx::new(0);
334pub(crate) const SPELL_JUDGMENT: LocalSpellIdx = LocalSpellIdx::new(1);
335pub(crate) const SPELL_BLADE_OF_JUSTICE: LocalSpellIdx = LocalSpellIdx::new(2);
336pub(crate) const SPELL_TEMPLARS_VERDICT: LocalSpellIdx = LocalSpellIdx::new(3);
337pub(crate) const SPELL_DIVINE_STORM: LocalSpellIdx = LocalSpellIdx::new(4);
338pub(crate) const SPELL_WAKE_OF_ASHES: LocalSpellIdx = LocalSpellIdx::new(5);
339pub(crate) const SPELL_AVENGING_WRATH: LocalSpellIdx = LocalSpellIdx::new(6);
340pub(crate) const SPELL_FINAL_VERDICT: LocalSpellIdx = LocalSpellIdx::new(7);
341pub(crate) const SPELL_CRUSADING_STRIKE: LocalSpellIdx = LocalSpellIdx::new(8);
342pub(crate) const SPELL_LIGHT_WITHIN_BOJ: LocalSpellIdx = LocalSpellIdx::new(9);
343pub(crate) const SPELL_HIGHLORDS_JUDGMENT: LocalSpellIdx = LocalSpellIdx::new(10);
344pub(crate) const SPELL_JUDGMENT_DIVINE_TOLL: LocalSpellIdx = LocalSpellIdx::new(11);
345pub(crate) const SPELL_HAMMER_OF_WRATH_DIVINE_TOLL: LocalSpellIdx = LocalSpellIdx::new(
346 12,
347);
348pub(crate) const SPELL_DIVINE_TOLL: LocalSpellIdx = LocalSpellIdx::new(13);
349pub(crate) const SPELL_HAMMER_OF_WRATH: LocalSpellIdx = LocalSpellIdx::new(14);
350pub(crate) const SPELL_EXECUTION_SENTENCE: LocalSpellIdx = LocalSpellIdx::new(15);
351pub(crate) const SPELL_HAMMER_OF_LIGHT: LocalSpellIdx = LocalSpellIdx::new(16);
352pub(crate) const SPELL_EMPYREAN_HAMMER: LocalSpellIdx = LocalSpellIdx::new(17);
353pub(crate) const SPELL_COUNT: usize = 18;
354const _: () = assert!(
355 SPELL_COUNT == 18,
356 "SPELL index ABI: count changed -- update positional hook consumers"
357);
358pub(crate) mod EFFECT {
359 pub(crate) const BURN_TO_ASH_EXTEND: (u32, u8) = (446_663, 1);
361 pub(crate) const CONSECRATION_TIMING: (u32, u8) = (26573, 1);
363 pub(crate) const CONSECRATION_GEOMETRY: (u32, u8) = (26573, 3);
365 pub(crate) const CONSECRATION_DAMAGE: (u32, u8) = (81297, 1);
367 pub(crate) const EXECUTION_SENTENCE_ACCUM_PCT: (u32, u8) = (343_527, 2);
369 pub(crate) const EXECUTION_SENTENCE_INIT: (u32, u8) = (1_260_251, 1);
371 pub(crate) const HIGHLORDS_MASTERY_DAMAGE: (u32, u8) = (267_316, 1);
373 pub(crate) const HIGHLORDS_MASTERY_FACTOR: (u32, u8) = (267_316, 4);
375 pub(crate) const HIGHLORDS_WRATH_DIVISOR: (u32, u8) = (404_512, 2);
377 pub(crate) const MID1_4PC_DIVINE_STORM: (u32, u8) = (1_264_849, 2);
379 pub(crate) const MID1_4PC_FINAL_VERDICT: (u32, u8) = (1_264_849, 1);
381 pub(crate) const HIGHLORDS_JUDGMENT: (u32, u8) = (383_921, 1);
383 pub(crate) const HIGHLORDS_WRATH: (u32, u8) = (404_512, 3);
385 pub(crate) const ART_OF_WAR_CHANCE: (u32, u8) = (406_064, 1);
387 pub(crate) const ART_OF_WAR_CRIT_BONUS: (u32, u8) = (406_064, 2);
389 pub(crate) const LIGHT_WITHIN: (u32, u8) = (1_261_160, 1);
391 pub(crate) const LIGHT_WITHIN_VERDICT_BONUS: (u32, u8) = (1_261_111, 1);
393 pub(crate) const LIGHT_WITHIN_WAVE_BONUS: (u32, u8) = (1_261_159, 1);
395 pub(crate) const RIGHTEOUS_CAUSE_CHANCE: (u32, u8) = (402_912, 1);
397 pub(crate) const CRUSADING_STRIKES_HP: (u32, u8) = (406_834, 1);
399 pub(crate) const EMPYREAN_POWER_CHANCE: (u32, u8) = (326_732, 2);
401 pub(crate) const DIVINE_PURPOSE_CHANCE: (u32, u8) = (408_459, 1);
403 pub(crate) const DIVINE_STORM_DAMAGE: (u32, u8) = (53385, 1);
405 pub(crate) const EMPYREAN_LEGACY_EFFECTIVENESS: (u32, u8) = (387_170, 2);
407 pub(crate) const EMPYREAN_HAMMER_DAMAGE: (u32, u8) = (431_398, 1);
409 pub(crate) const HAMMER_OF_LIGHT_DAMAGE: (u32, u8) = (427_453, 1);
411 pub(crate) const LIGHTS_GUIDANCE_COUNT: (u32, u8) = (427_445, 2);
413 pub(crate) const LIGHTS_GUIDANCE_DELAY: (u32, u8) = (427_445, 4);
415 pub(crate) const LIGHTS_GUIDANCE_STAGGER: (u32, u8) = (427_445, 3);
417 pub(crate) const ZEALOUS_VINDICATION_COUNT: (u32, u8) = (431_463, 1);
419 pub(crate) const HIGHER_CALLING_EXTEND: (u32, u8) = (431_687, 1);
421 pub(crate) const DIVINE_TOLL_HOW: (u32, u8) = (1_279_408, 1);
423 pub(crate) const DIVINE_TOLL_JUDGMENT: (u32, u8) = (406_957, 1);
425 pub(crate) const HAMMER_OF_WRATH_DAMAGE: (u32, u8) = (24275, 1);
427 pub(crate) const VENGEFUL_WRATH_MAX_BONUS: (u32, u8) = (1_241_958, 1);
429 pub(crate) const DIVINE_TOLL_ECHO_MULT: (u32, u8) = (375_576, 6);
431 pub(crate) const DIVINE_EXACTION_COUNT: (u32, u8) = (1_260_429, 1);
433 pub(crate) const DIVINE_EXACTION_MULT: (u32, u8) = (1_260_429, 2);
435 pub(crate) const JUDGMENT_DEBUFF_BONUS: (u32, u8) = (197_277, 1);
437 pub(crate) const HOLY_BLADE_ENERGIZE: (u32, u8) = (383_342, 1);
439 pub(crate) const CRUSADE_HASTE_PER_STACK: (u32, u8) = (1_253_598, 1);
441 pub(crate) const CRUSADE_HASTE_CAP: (u32, u8) = (1_253_598, 2);
443 pub(crate) const AVENGING_WRATH_CRIT: (u32, u8) = (31884, 3);
445 pub(crate) const AVENGING_WRATH_PERIODIC_DAMAGE: (u32, u8) = (31884, 2);
447 pub(crate) const TRUTHS_WAKE_BURN_EFFECT_4: (u32, u8) = (403_695, 4);
449}
450static REPORTED_SPELLS: &[(&str, u32)] = &[
451 ("blade_of_vengeance", 404_358),
452 ("execution_sentence", 387_113),
453 ("execution_sentence_init", 1_260_251),
454 ("expurgation", 383_346),
455];
456static DECLARED_SPELL_IDS: &[u32] = &[
457 35395, 20271, 184_575, 85256, 53385, 255_937, 31884, 383_328, 408_385, 1_261_160,
458 383_921, 406_957, 1_279_408, 375_576, 24275, 343_527, 427_453, 431_398, 31884,
459 326_733, 387_178, 408_458, 406_086, 402_916, 1_277_026, 197_277, 382_538, 383_346,
460 403_695, 404_542, 403_509, 407_475, 433_671, 407_065, 343_527, 1_260_251, 1_234_189,
461 427_441, 433_732, 431_536, 433_674, 432_629, 198_034, 6603, 24275, 26573, 31884,
462 53385, 81297, 197_277, 198_034, 267_316, 326_732, 343_527, 375_576, 383_342, 383_346,
463 383_921, 387_113, 387_170, 402_912, 403_695, 404_358, 404_512, 406_064, 406_834,
464 406_957, 408_459, 427_445, 427_453, 431_398, 431_463, 431_536, 431_687, 433_671,
465 446_663, 1_241_958, 1_253_598, 1_260_251, 1_260_429, 1_261_111, 1_261_159, 1_261_160,
466 1_264_849, 1_279_408, 404_358, 387_113, 1_260_251, 383_346, 1_260_429, 198_034,
467 432_929, 198_137, 431_398, 431_625, 432_463, 427_453, 431_687, 425_518, 427_445,
468 1_261_525, 432_977, 431_533, 432_626, 431_463, 427_441, 433_674, 433_671, 431_536,
469 406_648, 432_629, 431_474, 431_414, 445_206, 1_264_050, 431_522, 431_539, 431_404,
470];
471static DECLARED_AURA_IDS: &[u32] = &[
472 31884, 326_733, 387_178, 408_458, 406_086, 402_916, 1_277_026, 197_277, 382_538,
473 383_346, 403_695, 404_542, 403_509, 407_475, 433_671, 407_065, 343_527, 1_260_251,
474 1_234_189, 427_441, 433_732, 431_536, 433_674, 432_629, 198_034, 427_441, 433_674,
475 433_671, 431_536, 406_648, 432_629, 445_206, 1_264_050, 431_522, 431_539, 431_404,
476];
477static TALENTS: &[(&str, u32)] = &[
478 ("ART_OF_WAR", TALENT::ART_OF_WAR),
479 ("BLADE_OF_JUSTICE", TALENT::BLADE_OF_JUSTICE),
480 ("BLADE_OF_VENGEANCE", TALENT::BLADE_OF_VENGEANCE),
481 ("BLESSED_CHAMPION", TALENT::BLESSED_CHAMPION),
482 ("BURN_TO_ASH", TALENT::BURN_TO_ASH),
483 ("CONSECRATED_BLADE", TALENT::CONSECRATED_BLADE),
484 ("CRUSADE", TALENT::CRUSADE),
485 ("CRUSADING_STRIKES", TALENT::CRUSADING_STRIKES),
486 ("DIVINE_PURPOSE", TALENT::DIVINE_PURPOSE),
487 ("DIVINE_STORM", TALENT::DIVINE_STORM),
488 ("DIVINE_TOLL", TALENT::DIVINE_TOLL),
489 ("EMPYREAN_LEGACY", TALENT::EMPYREAN_LEGACY),
490 ("EMPYREAN_POWER", TALENT::EMPYREAN_POWER),
491 ("EXECUTION_SENTENCE", TALENT::EXECUTION_SENTENCE),
492 ("EXPURGATION", TALENT::EXPURGATION),
493 ("FINAL_VERDICT", TALENT::FINAL_VERDICT),
494 ("GREATER_JUDGMENT", TALENT::GREATER_JUDGMENT),
495 ("HAMMER_OF_WRATH_TALENT", TALENT::HAMMER_OF_WRATH_TALENT),
496 ("HEART_OF_THE_CRUSADER", TALENT::HEART_OF_THE_CRUSADER),
497 ("HIGHLORDS_WRATH", TALENT::HIGHLORDS_WRATH),
498 ("HOLY_BLADE", TALENT::HOLY_BLADE),
499 ("IMPROVED_JUDGMENT", TALENT::IMPROVED_JUDGMENT),
500 ("JUDGE_JURY_AND_EXECUTIONER", TALENT::JUDGE_JURY_AND_EXECUTIONER),
501 ("LIGHT_OF_JUSTICE", TALENT::LIGHT_OF_JUSTICE),
502 ("LIGHT_WITHIN", TALENT::LIGHT_WITHIN),
503 ("LIGHT_WITHIN_VERDICT", TALENT::LIGHT_WITHIN_VERDICT),
504 ("LIGHT_WITHIN_WAVE", TALENT::LIGHT_WITHIN_WAVE),
505 ("QUICKENED_INVOCATION", TALENT::QUICKENED_INVOCATION),
506 ("RADIANT_GLORY", TALENT::RADIANT_GLORY),
507 ("RIGHTEOUS_CAUSE", TALENT::RIGHTEOUS_CAUSE),
508 ("RUSH_OF_LIGHT", TALENT::RUSH_OF_LIGHT),
509 ("SANCTIFY", TALENT::SANCTIFY),
510 ("SEETHING_FLAMES", TALENT::SEETHING_FLAMES),
511 ("TEMPEST_OF_THE_LIGHTBRINGER", TALENT::TEMPEST_OF_THE_LIGHTBRINGER),
512 ("TEMPLAR_STRIKES", TALENT::TEMPLAR_STRIKES),
513 ("VENGEFUL_WRATH", TALENT::VENGEFUL_WRATH),
514 ("WAKE_OF_ASHES", TALENT::WAKE_OF_ASHES),
515 ("ZEALOTS_FERVOR", TALENT::ZEALOTS_FERVOR),
516];
517pub(crate) mod RETRIBUTION_PALADIN {
518 pub(crate) const CRUSADER_STRIKE_CASTS: u32 = 0;
519 pub(crate) const JUDGMENT_CASTS: u32 = 1;
520 pub(crate) const BLADE_OF_JUSTICE_CASTS: u32 = 2;
521 pub(crate) const TEMPLARS_VERDICT_CASTS: u32 = 3;
522 pub(crate) const DIVINE_STORM_CASTS: u32 = 4;
523 pub(crate) const WAKE_OF_ASHES_CASTS: u32 = 5;
524 pub(crate) const AVENGING_WRATH_CASTS: u32 = 6;
525 pub(crate) const AVENGING_WRATH_UPTIME_MS: u32 = 7;
526}
527fn aura_avenging_wrath(
528 a: AuraDefinitionDraft,
529 data: &ResolvedGameData,
530) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
531 Ok(
532 a
533 .on_player()
534 .apply_base_from_data(data, 31884)?
535 .max_stacks(
536 data
537 .require_aura_max_stacks(
538 wowlab_types::sim::SpellIdx::from_raw(31884),
539 )?,
540 )
541 .on_expire(crate::hooks::retribution_paladin::avenging_wrath_expire_hook),
542 )
543}
544fn aura_empyrean_power(
545 a: AuraDefinitionDraft,
546 data: &ResolvedGameData,
547) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
548 Ok(
549 a
550 .on_player()
551 .apply_base_from_data(data, 326_733)?
552 .max_stacks(
553 data
554 .require_aura_max_stacks(
555 wowlab_types::sim::SpellIdx::from_raw(326_733),
556 )?,
557 ),
558 )
559}
560fn aura_empyrean_legacy(
561 a: AuraDefinitionDraft,
562 data: &ResolvedGameData,
563) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
564 Ok(
565 a
566 .on_player()
567 .apply_base_from_data(data, 387_178)?
568 .max_stacks(
569 data
570 .require_aura_max_stacks(
571 wowlab_types::sim::SpellIdx::from_raw(387_178),
572 )?,
573 ),
574 )
575}
576fn aura_divine_purpose(
577 a: AuraDefinitionDraft,
578 data: &ResolvedGameData,
579) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
580 Ok(
581 a
582 .on_player()
583 .apply_base_from_data(data, 408_458)?
584 .max_stacks(
585 data
586 .require_aura_max_stacks(
587 wowlab_types::sim::SpellIdx::from_raw(408_458),
588 )?,
589 ),
590 )
591}
592fn aura_art_of_war(
593 a: AuraDefinitionDraft,
594 data: &ResolvedGameData,
595) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
596 Ok(
597 a
598 .on_player()
599 .apply_base_from_data(data, 406_086)?
600 .max_stacks(
601 data
602 .require_aura_max_stacks(
603 wowlab_types::sim::SpellIdx::from_raw(406_086),
604 )?,
605 ),
606 )
607}
608fn aura_righteous_cause(
609 a: AuraDefinitionDraft,
610 data: &ResolvedGameData,
611) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
612 Ok(
613 a
614 .on_player()
615 .apply_base_from_data(data, 402_916)?
616 .max_stacks(
617 data
618 .require_aura_max_stacks(
619 wowlab_types::sim::SpellIdx::from_raw(402_916),
620 )?,
621 ),
622 )
623}
624fn aura_hammer_of_wrath(
625 a: AuraDefinitionDraft,
626 data: &ResolvedGameData,
627) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
628 Ok(
629 a
630 .on_player()
631 .apply_base_from_data(data, 1_277_026)?
632 .max_stacks(
633 data
634 .require_aura_max_stacks(
635 wowlab_types::sim::SpellIdx::from_raw(1_277_026),
636 )?,
637 ),
638 )
639}
640fn aura_judgment_debuff(
641 a: AuraDefinitionDraft,
642 data: &ResolvedGameData,
643) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
644 Ok(
645 a
646 .on_target()
647 .apply_base_from_data(data, 197_277)?
648 .max_stacks(
649 data
650 .require_aura_max_stacks(
651 wowlab_types::sim::SpellIdx::from_raw(197_277),
652 )?,
653 ),
654 )
655}
656fn aura_sanctify(
657 a: AuraDefinitionDraft,
658 data: &ResolvedGameData,
659) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
660 Ok(
661 a
662 .on_target()
663 .apply_base_from_data(data, 382_538)?
664 .max_stacks(
665 data
666 .require_aura_max_stacks(
667 wowlab_types::sim::SpellIdx::from_raw(382_538),
668 )?,
669 ),
670 )
671}
672fn aura_expurgation(
673 a: AuraDefinitionDraft,
674 data: &ResolvedGameData,
675) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
676 Ok(
677 a
678 .on_target()
679 .apply_base_from_data(data, 383_346)?
680 .max_stacks(
681 data
682 .require_aura_max_stacks(
683 wowlab_types::sim::SpellIdx::from_raw(383_346),
684 )?,
685 )
686 .snapshot(),
687 )
688}
689fn aura_truths_wake(
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, 403_695)?
697 .max_stacks(
698 data
699 .require_aura_max_stacks(
700 wowlab_types::sim::SpellIdx::from_raw(403_695),
701 )?,
702 )
703 .snapshot()
704 .hasted_periodic(),
705 )
706}
707fn aura_crusading_strikes(
708 a: AuraDefinitionDraft,
709 data: &ResolvedGameData,
710) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
711 Ok(
712 a
713 .on_player()
714 .apply_base_from_data(data, 404_542)?
715 .max_stacks(
716 data
717 .require_aura_max_stacks(
718 wowlab_types::sim::SpellIdx::from_raw(404_542),
719 )?,
720 ),
721 )
722}
723fn aura_zealots_fervor(
724 a: AuraDefinitionDraft,
725 data: &ResolvedGameData,
726) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
727 Ok(
728 a
729 .on_player()
730 .apply_base_from_data(data, 403_509)?
731 .max_stacks(
732 data
733 .require_aura_max_stacks(
734 wowlab_types::sim::SpellIdx::from_raw(403_509),
735 )?,
736 ),
737 )
738}
739fn aura_consecrated_blade_lockout(
740 a: AuraDefinitionDraft,
741 data: &ResolvedGameData,
742) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
743 Ok(
744 a
745 .on_player()
746 .apply_base_from_data(data, 407_475)?
747 .max_stacks(
748 data
749 .require_aura_max_stacks(
750 wowlab_types::sim::SpellIdx::from_raw(407_475),
751 )?,
752 ),
753 )
754}
755fn aura_sanctification(
756 a: AuraDefinitionDraft,
757 data: &ResolvedGameData,
758) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
759 a.on_player()
760 .duration_ms(
761 wowlab_engine_combat::validated_milliseconds(
762 (f64::from(
763 data
764 .require_aura_duration_ms(
765 wowlab_types::sim::SpellIdx::from_raw(433_671),
766 )?,
767 )) * 0.833_333_333_333_333_4,
768 433_671,
769 "aura.duration_ms",
770 )?,
771 )
772 .apply_periodic_effect_from_data(data, 433_671)?
773 .apply_duration_behavior_from_data(data, 433_671)?
774 .apply_timing_modifiers_from_data(data, 433_671)?
775 .max_stacks(
776 data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(433_671))?,
777 )
778 .async_stacks()
779 .damage_percent_spells_linear(
780 data.base_points(wowlab_types::sim::SpellIdx::from_raw(433_671), 1),
781 &[431_398],
782 )?
783 .apply_periodic_behavior_from_data(data, 433_671)
784}
785fn aura_rush_of_light(
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, 407_065)?
793 .max_stacks(
794 data
795 .require_aura_max_stacks(
796 wowlab_types::sim::SpellIdx::from_raw(407_065),
797 )?,
798 ),
799 )
800}
801fn aura_execution_sentence(
802 a: AuraDefinitionDraft,
803 data: &ResolvedGameData,
804) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
805 Ok(
806 a
807 .on_target()
808 .apply_base_from_data(data, 343_527)?
809 .max_stacks(
810 data
811 .require_aura_max_stacks(
812 wowlab_types::sim::SpellIdx::from_raw(343_527),
813 )?,
814 )
815 .no_pandemic()
816 .on_expire(crate::hooks::retribution_paladin::execution_sentence_expire_hook),
817 )
818}
819fn aura_execution_sentence_gather(
820 a: AuraDefinitionDraft,
821 data: &ResolvedGameData,
822) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
823 Ok(
824 a
825 .on_target()
826 .apply_base_from_data(data, 1_260_251)?
827 .max_stacks(
828 data
829 .require_aura_max_stacks(
830 wowlab_types::sim::SpellIdx::from_raw(1_260_251),
831 )?,
832 )
833 .no_pandemic(),
834 )
835}
836fn aura_execution_sentence_tracker(
837 a: AuraDefinitionDraft,
838 data: &ResolvedGameData,
839) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
840 Ok(
841 a
842 .on_player()
843 .apply_base_from_data(data, 1_234_189)?
844 .max_stacks(
845 data
846 .require_aura_max_stacks(
847 wowlab_types::sim::SpellIdx::from_raw(1_234_189),
848 )?,
849 ),
850 )
851}
852fn aura_hammer_of_light(
853 a: AuraDefinitionDraft,
854 data: &ResolvedGameData,
855) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
856 Ok(
857 a
858 .on_player()
859 .apply_base_from_data(data, 427_441)?
860 .max_stacks(
861 data
862 .require_aura_max_stacks(
863 wowlab_types::sim::SpellIdx::from_raw(427_441),
864 )?,
865 )
866 .on_expire(crate::hooks::retribution_paladin::lights_deliverance_check_hook),
867 )
868}
869fn aura_hammer_of_light_free(
870 a: AuraDefinitionDraft,
871 data: &ResolvedGameData,
872) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
873 Ok(
874 a
875 .on_player()
876 .apply_base_from_data(data, 433_732)?
877 .max_stacks(
878 data
879 .require_aura_max_stacks(
880 wowlab_types::sim::SpellIdx::from_raw(433_732),
881 )?,
882 ),
883 )
884}
885fn aura_shake_the_heavens(
886 a: AuraDefinitionDraft,
887 data: &ResolvedGameData,
888) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
889 Ok(
890 a
891 .on_player()
892 .apply_base_from_data(data, 431_536)?
893 .max_stacks(
894 data
895 .require_aura_max_stacks(
896 wowlab_types::sim::SpellIdx::from_raw(431_536),
897 )?,
898 )
899 .periodic_hook(
900 wowlab_engine_combat::validated_milliseconds(
901 data.period(wowlab_types::sim::SpellIdx::from_raw(431_536), 1),
902 431_536,
903 "periodic_hook.tick_ms",
904 )?,
905 )
906 .apply_periodic_behavior_from_data(data, 431_536)?
907 .partial_tick()
908 .tick_hook(crate::hooks::retribution_paladin::sth_pulse_hook),
909 )
910}
911fn aura_lights_deliverance(
912 a: AuraDefinitionDraft,
913 data: &ResolvedGameData,
914) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
915 Ok(
916 a
917 .on_player()
918 .apply_base_from_data(data, 433_674)?
919 .max_stacks(
920 data
921 .require_aura_max_stacks(
922 wowlab_types::sim::SpellIdx::from_raw(433_674),
923 )?,
924 ),
925 )
926}
927fn aura_undisputed_ruling(
928 a: AuraDefinitionDraft,
929 data: &ResolvedGameData,
930) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
931 Ok(
932 a
933 .on_player()
934 .apply_base_from_data(data, 432_629)?
935 .max_stacks(
936 data
937 .require_aura_max_stacks(
938 wowlab_types::sim::SpellIdx::from_raw(432_629),
939 )?,
940 ),
941 )
942}
943fn aura_divine_hammer(
944 a: AuraDefinitionDraft,
945 data: &ResolvedGameData,
946) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
947 Ok(
948 a
949 .on_player()
950 .apply_base_from_data(data, 198_034)?
951 .max_stacks(
952 data
953 .require_aura_max_stacks(
954 wowlab_types::sim::SpellIdx::from_raw(198_034),
955 )?,
956 )
957 .periodic_hook(
958 wowlab_engine_combat::validated_milliseconds(
959 data.period(wowlab_types::sim::SpellIdx::from_raw(198_034), 1),
960 198_034,
961 "periodic_hook.tick_ms",
962 )?,
963 )
964 .apply_periodic_behavior_from_data(data, 198_034)?
965 .partial_tick()
966 .tick_hook(crate::hooks::retribution_paladin::divine_hammer_pulse_hook),
967 )
968}
969fn spell_crusader_strike(
970 s: SpellDefinitionDraft,
971 data: &ResolvedGameData,
972) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
973 Ok(s.apply_base_from_data(data, 35395)?.apply_aoe_from_data(data))
974}
975fn spell_judgment(
976 s: SpellDefinitionDraft,
977 data: &ResolvedGameData,
978) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
979 Ok(
980 s
981 .apply_base_from_data(data, 20271)?
982 .gain(1.0)
983 .apply_aoe_from_data(data)
984 .on_cast(crate::hooks::retribution_paladin::judgment_hook),
985 )
986}
987fn spell_blade_of_justice(
988 s: SpellDefinitionDraft,
989 data: &ResolvedGameData,
990) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
991 Ok(
992 s
993 .apply_base_from_data(data, 184_575)?
994 .trigger_program_predicate(
995 3,
996 crate::hooks::retribution_paladin::blade_of_vengeance_trigger_disabled,
997 )
998 .apply_aoe_from_data(data)
999 .on_cast(crate::hooks::retribution_paladin::blade_of_justice_hook),
1000 )
1001}
1002fn spell_templars_verdict(
1003 s: SpellDefinitionDraft,
1004 data: &ResolvedGameData,
1005) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1006 Ok(
1007 s
1008 .apply_base_from_data(data, 85256)?
1009 .apply_aoe_from_data(data)
1010 .on_cast(crate::hooks::retribution_paladin::templars_verdict_hook),
1011 )
1012}
1013fn spell_divine_storm(
1014 s: SpellDefinitionDraft,
1015 data: &ResolvedGameData,
1016) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1017 Ok(
1018 s
1019 .apply_base_from_data(data, 53385)?
1020 .apply_aoe_from_data(data)
1021 .on_cast(crate::hooks::retribution_paladin::divine_storm_hook),
1022 )
1023}
1024fn spell_wake_of_ashes(
1025 s: SpellDefinitionDraft,
1026 data: &ResolvedGameData,
1027) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1028 Ok(
1029 s
1030 .apply_base_from_data(data, 255_937)?
1031 .apply_aoe_from_data(data)
1032 .on_cast(crate::hooks::retribution_paladin::wake_of_ashes_hook),
1033 )
1034}
1035fn spell_avenging_wrath(
1036 s: SpellDefinitionDraft,
1037 data: &ResolvedGameData,
1038) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1039 Ok(
1040 s
1041 .apply_base_from_data(data, 31884)?
1042 .applies_inferred_aura(AURA_AVENGING_WRATH, 31884)
1043 .apply_aoe_from_data(data)
1044 .on_cast(crate::hooks::retribution_paladin::avenging_wrath_hook),
1045 )
1046}
1047fn spell_final_verdict(
1048 s: SpellDefinitionDraft,
1049 data: &ResolvedGameData,
1050) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1051 Ok(
1052 s
1053 .apply_base_from_data(data, 383_328)?
1054 .apply_aoe_from_data(data)
1055 .on_cast(crate::hooks::retribution_paladin::templars_verdict_hook),
1056 )
1057}
1058fn spell_crusading_strike(
1059 s: SpellDefinitionDraft,
1060 data: &ResolvedGameData,
1061) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1062 Ok(s.apply_base_from_data(data, 408_385)?.apply_aoe_from_data(data))
1063}
1064fn spell_light_within_boj(
1065 s: SpellDefinitionDraft,
1066 data: &ResolvedGameData,
1067) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1068 Ok(
1069 s
1070 .apply_base_from_data(data, 1_261_160)?
1071 .damage_flat(0.0)
1072 .apply_aoe_from_data(data),
1073 )
1074}
1075fn spell_highlords_judgment(
1076 s: SpellDefinitionDraft,
1077 data: &ResolvedGameData,
1078) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1079 Ok(s.apply_base_from_data(data, 383_921)?.damage_flat(0.0).apply_aoe_from_data(data))
1080}
1081fn spell_judgment_divine_toll(
1082 s: SpellDefinitionDraft,
1083 data: &ResolvedGameData,
1084) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1085 Ok(s.apply_base_from_data(data, 406_957)?.damage_flat(0.0).apply_aoe_from_data(data))
1086}
1087fn spell_hammer_of_wrath_divine_toll(
1088 s: SpellDefinitionDraft,
1089 data: &ResolvedGameData,
1090) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1091 Ok(
1092 s
1093 .apply_base_from_data(data, 1_279_408)?
1094 .damage_flat(0.0)
1095 .apply_aoe_from_data(data),
1096 )
1097}
1098fn spell_divine_toll(
1099 s: SpellDefinitionDraft,
1100 data: &ResolvedGameData,
1101) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1102 Ok(
1103 s
1104 .apply_base_from_data(data, 375_576)?
1105 .apply_aoe_from_data(data)
1106 .on_cast(crate::hooks::retribution_paladin::divine_toll_hook),
1107 )
1108}
1109fn spell_hammer_of_wrath(
1110 s: SpellDefinitionDraft,
1111 data: &ResolvedGameData,
1112) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1113 Ok(
1114 s
1115 .apply_base_from_data(data, 24275)?
1116 .damage_flat(0.0)
1117 .applies_inferred_aura(AURA_HAMMER_OF_WRATH, 1_277_026)
1118 .apply_aoe_from_data(data)
1119 .on_cast(crate::hooks::retribution_paladin::hammer_of_wrath_hook),
1120 )
1121}
1122fn spell_execution_sentence(
1123 s: SpellDefinitionDraft,
1124 data: &ResolvedGameData,
1125) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1126 Ok(
1127 s
1128 .apply_base_from_data(data, 343_527)?
1129 .without_primary_data_damage()
1130 .apply_aoe_from_data(data)
1131 .on_cast(crate::hooks::retribution_paladin::execution_sentence_hook),
1132 )
1133}
1134fn spell_hammer_of_light(
1135 s: SpellDefinitionDraft,
1136 data: &ResolvedGameData,
1137) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1138 Ok(
1139 s
1140 .apply_base_from_data(data, 427_453)?
1141 .cost(
1142 wowlab_engine_combat::validated_nonnegative(5.0, 427_453, "spell.cost")?,
1143 )
1144 .damage_flat(0.0)
1145 .applies_inferred_aura(AURA_HAMMER_OF_LIGHT, 427_441)
1146 .apply_aoe_from_data(data)
1147 .on_cast(crate::hooks::retribution_paladin::hammer_of_light_hook)
1148 .requires_aura_at_min_stacks(427_441, 0)
1149 .cost_free_when_aura(433_732),
1150 )
1151}
1152fn spell_empyrean_hammer(
1153 s: SpellDefinitionDraft,
1154 data: &ResolvedGameData,
1155) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1156 Ok(s.apply_base_from_data(data, 431_398)?.damage_flat(0.0).apply_aoe_from_data(data))
1157}
1158pub(crate) fn build_combat_system(
1159 params: &wowlab_engine_ports::HandlerParams<'_>,
1160) -> Result<BuiltCombatSystem, wowlab_engine_ports::EngineError> {
1161 let builder = BuiltCombatSystem::builder(params.stats.clone())
1162 .spec_id(SpecId::Retribution)
1163 .hero_talent_trees(DECLARED_METADATA.hero_talent_trees)
1164 .mastery_spell(267_316)
1165 .mastery_hook(crate::hooks::retribution_paladin::mastery)
1166 .resource(
1167 "holy_power",
1168 5.0,
1169 params
1170 .game_data
1171 .power_regen_for_max(9, 5.0)
1172 .ok_or_else(|| {
1173 wowlab_engine_ports::EngineError::spec_construction(
1174 "missing power-type power_regen_for_max for type_id 9",
1175 )
1176 })?,
1177 )
1178 .resource_type_id(9)
1179 .resource_start(
1180 params
1181 .game_data
1182 .power_default(9)
1183 .ok_or_else(|| {
1184 wowlab_engine_ports::EngineError::spec_construction(
1185 "missing power-type power_default for type_id 9",
1186 )
1187 })?,
1188 )
1189 .aura(
1190 "avenging_wrath",
1191 AURA::AVENGING_WRATH,
1192 |a| aura_avenging_wrath(a, ¶ms.game_data),
1193 )
1194 .aura(
1195 "empyrean_power",
1196 AURA::EMPYREAN_POWER,
1197 |a| aura_empyrean_power(a, ¶ms.game_data),
1198 )
1199 .aura(
1200 "empyrean_legacy",
1201 AURA::EMPYREAN_LEGACY,
1202 |a| aura_empyrean_legacy(a, ¶ms.game_data),
1203 )
1204 .aura(
1205 "divine_purpose",
1206 AURA::DIVINE_PURPOSE,
1207 |a| aura_divine_purpose(a, ¶ms.game_data),
1208 )
1209 .aura("art_of_war", AURA::ART_OF_WAR, |a| aura_art_of_war(a, ¶ms.game_data))
1210 .aura(
1211 "righteous_cause",
1212 AURA::RIGHTEOUS_CAUSE,
1213 |a| aura_righteous_cause(a, ¶ms.game_data),
1214 )
1215 .aura(
1216 "hammer_of_wrath",
1217 AURA::HAMMER_OF_WRATH,
1218 |a| aura_hammer_of_wrath(a, ¶ms.game_data),
1219 )
1220 .aura(
1221 "judgment_debuff",
1222 AURA::JUDGMENT_DEBUFF,
1223 |a| aura_judgment_debuff(a, ¶ms.game_data),
1224 )
1225 .aura("sanctify", AURA::SANCTIFY, |a| aura_sanctify(a, ¶ms.game_data))
1226 .aura(
1227 "expurgation",
1228 AURA::EXPURGATION,
1229 |a| aura_expurgation(a, ¶ms.game_data),
1230 )
1231 .aura(
1232 "truths_wake",
1233 AURA::TRUTHS_WAKE,
1234 |a| aura_truths_wake(a, ¶ms.game_data),
1235 )
1236 .aura(
1237 "crusading_strikes",
1238 AURA::CRUSADING_STRIKES,
1239 |a| aura_crusading_strikes(a, ¶ms.game_data),
1240 )
1241 .aura(
1242 "zealots_fervor",
1243 AURA::ZEALOTS_FERVOR,
1244 |a| aura_zealots_fervor(a, ¶ms.game_data),
1245 )
1246 .aura(
1247 "consecrated_blade_lockout",
1248 AURA::CONSECRATED_BLADE_LOCKOUT,
1249 |a| aura_consecrated_blade_lockout(a, ¶ms.game_data),
1250 )
1251 .aura(
1252 "sanctification",
1253 AURA::SANCTIFICATION,
1254 |a| aura_sanctification(a, ¶ms.game_data),
1255 )
1256 .aura(
1257 "rush_of_light",
1258 AURA::RUSH_OF_LIGHT,
1259 |a| aura_rush_of_light(a, ¶ms.game_data),
1260 )
1261 .aura(
1262 "execution_sentence",
1263 AURA::EXECUTION_SENTENCE,
1264 |a| aura_execution_sentence(a, ¶ms.game_data),
1265 )
1266 .aura(
1267 "execution_sentence_gather",
1268 AURA::EXECUTION_SENTENCE_GATHER,
1269 |a| aura_execution_sentence_gather(a, ¶ms.game_data),
1270 )
1271 .aura(
1272 "execution_sentence_tracker",
1273 AURA::EXECUTION_SENTENCE_TRACKER,
1274 |a| aura_execution_sentence_tracker(a, ¶ms.game_data),
1275 )
1276 .aura(
1277 "hammer_of_light",
1278 AURA::HAMMER_OF_LIGHT,
1279 |a| aura_hammer_of_light(a, ¶ms.game_data),
1280 )
1281 .aura(
1282 "hammer_of_light_free",
1283 AURA::HAMMER_OF_LIGHT_FREE,
1284 |a| aura_hammer_of_light_free(a, ¶ms.game_data),
1285 )
1286 .aura(
1287 "shake_the_heavens",
1288 AURA::SHAKE_THE_HEAVENS,
1289 |a| aura_shake_the_heavens(a, ¶ms.game_data),
1290 )
1291 .aura(
1292 "lights_deliverance",
1293 AURA::LIGHTS_DELIVERANCE,
1294 |a| aura_lights_deliverance(a, ¶ms.game_data),
1295 )
1296 .aura(
1297 "undisputed_ruling",
1298 AURA::UNDISPUTED_RULING,
1299 |a| aura_undisputed_ruling(a, ¶ms.game_data),
1300 )
1301 .aura(
1302 "divine_hammer",
1303 AURA::DIVINE_HAMMER,
1304 |a| aura_divine_hammer(a, ¶ms.game_data),
1305 )
1306 .spell(
1307 "crusader_strike",
1308 SPELL::CRUSADER_STRIKE,
1309 |s| spell_crusader_strike(s, ¶ms.game_data),
1310 )
1311 .spell("judgment", SPELL::JUDGMENT, |s| spell_judgment(s, ¶ms.game_data))
1312 .spell(
1313 "blade_of_justice",
1314 SPELL::BLADE_OF_JUSTICE,
1315 |s| spell_blade_of_justice(s, ¶ms.game_data),
1316 )
1317 .spell(
1318 "templars_verdict",
1319 SPELL::TEMPLARS_VERDICT,
1320 |s| spell_templars_verdict(s, ¶ms.game_data),
1321 )
1322 .spell(
1323 "divine_storm",
1324 SPELL::DIVINE_STORM,
1325 |s| spell_divine_storm(s, ¶ms.game_data),
1326 )
1327 .spell(
1328 "wake_of_ashes",
1329 SPELL::WAKE_OF_ASHES,
1330 |s| spell_wake_of_ashes(s, ¶ms.game_data),
1331 )
1332 .spell(
1333 "avenging_wrath",
1334 SPELL::AVENGING_WRATH,
1335 |s| spell_avenging_wrath(s, ¶ms.game_data),
1336 )
1337 .spell(
1338 "final_verdict",
1339 SPELL::FINAL_VERDICT,
1340 |s| spell_final_verdict(s, ¶ms.game_data),
1341 )
1342 .spell(
1343 "crusading_strike",
1344 SPELL::CRUSADING_STRIKE,
1345 |s| spell_crusading_strike(s, ¶ms.game_data),
1346 )
1347 .spell(
1348 "light_within_boj",
1349 SPELL::LIGHT_WITHIN_BOJ,
1350 |s| spell_light_within_boj(s, ¶ms.game_data),
1351 )
1352 .spell(
1353 "highlords_judgment",
1354 SPELL::HIGHLORDS_JUDGMENT,
1355 |s| spell_highlords_judgment(s, ¶ms.game_data),
1356 )
1357 .spell(
1358 "judgment_divine_toll",
1359 SPELL::JUDGMENT_DIVINE_TOLL,
1360 |s| spell_judgment_divine_toll(s, ¶ms.game_data),
1361 )
1362 .spell(
1363 "hammer_of_wrath_divine_toll",
1364 SPELL::HAMMER_OF_WRATH_DIVINE_TOLL,
1365 |s| spell_hammer_of_wrath_divine_toll(s, ¶ms.game_data),
1366 )
1367 .spell(
1368 "divine_toll",
1369 SPELL::DIVINE_TOLL,
1370 |s| spell_divine_toll(s, ¶ms.game_data),
1371 )
1372 .spell(
1373 "hammer_of_wrath",
1374 SPELL::HAMMER_OF_WRATH,
1375 |s| spell_hammer_of_wrath(s, ¶ms.game_data),
1376 )
1377 .spell(
1378 "execution_sentence",
1379 SPELL::EXECUTION_SENTENCE,
1380 |s| spell_execution_sentence(s, ¶ms.game_data),
1381 )
1382 .spell(
1383 "hammer_of_light",
1384 SPELL::HAMMER_OF_LIGHT,
1385 |s| spell_hammer_of_light(s, ¶ms.game_data),
1386 )
1387 .spell(
1388 "empyrean_hammer",
1389 SPELL::EMPYREAN_HAMMER,
1390 |s| spell_empyrean_hammer(s, ¶ms.game_data),
1391 )
1392 .auto_attack(|a| {
1393 a
1394 .spell_id(6603)
1395 .swing_ms(3600)
1396 .apply_base_from_data(¶ms.game_data)
1397 .on_swing(crate::hooks::retribution_paladin::swing_hook)
1398 })
1399 .game_data(params.game_data.clone())
1400 .talent_spell_ids(TALENTS)
1401 .talent_selections(params.talent_selections)
1402 .talent_gated_aura_effect(TALENT::CRUSADE, AURA_AVENGING_WRATH, 31884, 11)
1403 .talent_gated_aura_effect(TALENT::BURN_TO_ASH, AURA_TRUTHS_WAKE, 403_695, 4)
1404 .talent_gated_aura_effect(TALENT::BURN_TO_ASH, AURA_TRUTHS_WAKE, 403_695, 5)
1405 .talent_gated_aura_effect(TALENT::BURN_TO_ASH, AURA_TRUTHS_WAKE, 403_695, 6)
1406 .set_bonus_auras(params.set_bonus_auras)
1407 .encounter(params.encounter.clone());
1408 let builder = crate::generated::items::register_equipped(
1409 builder,
1410 ¶ms.game_data,
1411 params.equipped_items,
1412 )?;
1413
1414 builder
1415 .build(params.rotation)
1416 .map_err(wowlab_engine_ports::EngineError::rotation_compile)
1417}
1418fn new_handler(
1419 params: wowlab_engine_ports::HandlerParams<'_>,
1420) -> Result<Box<dyn SpecHandler>, wowlab_engine_ports::EngineError> {
1421 let handler = crate::composition::compose_handler(
1422 build_combat_system,
1423 ¶ms,
1424 |parts, params| Ok(
1425 crate::hooks::retribution_paladin::RetributionHandler::new(parts, params),
1426 ),
1427 )?;
1428
1429 Ok(Box::new(handler))
1430}
1431static DECLARED_METADATA: DeclaredSpecMetadata = DeclaredSpecMetadata {
1432 primary_resource: ResourceType::HolyPower,
1433 secondary_resource: None,
1434 spell_ids: DECLARED_SPELL_IDS,
1435 aura_ids: DECLARED_AURA_IDS,
1436 server_proc_entries: &[],
1437 talents: TALENTS,
1438 rotation_field_schema: &[],
1439 metrics_plugin_id: None,
1440 hero_talent_trees: &[
1441 HeroTalentTreeDesc {
1442 name: "Templar",
1443 spells: HERO_TREE_TEMPLAR_SPELLS,
1444 auras: HERO_TREE_TEMPLAR_AURAS,
1445 },
1446 HeroTalentTreeDesc {
1447 name: "Herald Of The Sun",
1448 spells: HERO_TREE_HERALD_OF_THE_SUN_SPELLS,
1449 auras: HERO_TREE_HERALD_OF_THE_SUN_AURAS,
1450 },
1451 ],
1452 reported_spells: REPORTED_SPELLS,
1453 masked_passive_effects: &[],
1454 passive_effect_overrides: &[],
1455};
1456pub(super) const SPEC_DESCRIPTOR: SpecDescriptor = SpecDescriptor {
1457 spec_id: SpecId::Retribution,
1458 display_name: "Retribution Paladin",
1459 metadata: DECLARED_METADATA,
1460 handler_factory: new_handler,
1461};
1462wowlab_engine_combat::smoke_test!(build_combat_system);