Skip to main content

wowlab_engine_content/generated/specs/
outlaw_rogue.rs

1//! @generated by codegen-cli from manifests/specs/rogue/outlaw/manifest.toml -- do not edit by hand.
2// Generated code: naming follows game data conventions
3#![allow(non_snake_case, dead_code)]
4use wowlab_types::{combat::ResourceType, game::SpecId};
5use wowlab_engine_combat::{
6    BuiltCombatSystem, AuraDefinitionDraft, LocalAuraIdx, LocalSpellIdx,
7    SpellDefinitionDraft,
8};
9use wowlab_engine_ports::{
10    DeclaredSpecMetadata, SpecDescriptor, SpecHandler, HeroTalentTreeDesc,
11};
12use wowlab_engine_gamedata::ResolvedGameData;
13pub(crate) mod SPELL {
14    ///<https://wowlab.gg/inspect/spell/381623>
15    pub(crate) const THISTLE_TEA: u32 = 381_623;
16    ///<https://wowlab.gg/inspect/spell/1856>
17    pub(crate) const VANISH: u32 = 1856;
18    ///<https://wowlab.gg/inspect/spell/193315>
19    pub(crate) const SINISTER_STRIKE: u32 = 193_315;
20    ///<https://wowlab.gg/inspect/spell/197834>
21    pub(crate) const SINISTER_STRIKE_EXTRA_ATTACK: u32 = 197_834;
22    ///<https://wowlab.gg/inspect/spell/185763>
23    pub(crate) const PISTOL_SHOT: u32 = 185_763;
24    ///<https://wowlab.gg/inspect/spell/8676>
25    pub(crate) const AMBUSH: u32 = 8676;
26    ///<https://wowlab.gg/inspect/spell/2098>
27    pub(crate) const DISPATCH: u32 = 2098;
28    ///<https://wowlab.gg/inspect/spell/315341>
29    pub(crate) const BETWEEN_THE_EYES: u32 = 315_341;
30    ///<https://wowlab.gg/inspect/spell/196819>
31    pub(crate) const EVISCERATE: u32 = 196_819;
32    ///<https://wowlab.gg/inspect/spell/315496>
33    pub(crate) const SLICE_AND_DICE: u32 = 315_496;
34    ///<https://wowlab.gg/inspect/spell/315584>
35    pub(crate) const INSTANT_POISON: u32 = 315_584;
36    ///<https://wowlab.gg/inspect/spell/8679>
37    pub(crate) const WOUND_POISON: u32 = 8679;
38    ///<https://wowlab.gg/inspect/spell/381637>
39    pub(crate) const ATROPHIC_POISON: u32 = 381_637;
40    ///<https://wowlab.gg/inspect/spell/5761>
41    pub(crate) const NUMBING_POISON: u32 = 5761;
42    ///<https://wowlab.gg/inspect/spell/3408>
43    pub(crate) const CRIPPLING_POISON: u32 = 3408;
44    ///<https://wowlab.gg/inspect/spell/86392>
45    pub(crate) const MAIN_GAUCHE: u32 = 86392;
46    ///<https://wowlab.gg/inspect/spell/1265918>
47    pub(crate) const SCOUNDREL_STRIKE: u32 = 1_265_918;
48    ///<https://wowlab.gg/inspect/spell/315585>
49    pub(crate) const INSTANT_POISON_DAMAGE: u32 = 315_585;
50    ///<https://wowlab.gg/inspect/spell/1766>
51    pub(crate) const KICK: u32 = 1766;
52    ///<https://wowlab.gg/inspect/spell/315508>
53    pub(crate) const ROLL_THE_BONES: u32 = 315_508;
54    ///<https://wowlab.gg/inspect/spell/13750>
55    pub(crate) const ADRENALINE_RUSH: u32 = 13750;
56    ///<https://wowlab.gg/inspect/spell/13877>
57    pub(crate) const BLADE_FLURRY: u32 = 13877;
58    ///<https://wowlab.gg/inspect/spell/429951>
59    pub(crate) const BLADE_FLURRY_INSTANT_ATTACK: u32 = 429_951;
60    ///<https://wowlab.gg/inspect/spell/271877>
61    pub(crate) const BLADE_RUSH: u32 = 271_877;
62    ///<https://wowlab.gg/inspect/spell/51690>
63    pub(crate) const KILLING_SPREE: u32 = 51690;
64    ///<https://wowlab.gg/inspect/spell/381989>
65    pub(crate) const KEEP_IT_ROLLING: u32 = 381_989;
66    ///<https://wowlab.gg/inspect/spell/1277933>
67    pub(crate) const PREPARATION: u32 = 1_277_933;
68    ///<https://wowlab.gg/inspect/spell/271881>
69    pub(crate) const BLADE_RUSH_ATTACK: u32 = 271_881;
70}
71pub(crate) mod AURA {
72    ///<https://wowlab.gg/inspect/spell/315496>
73    pub(crate) const SLICE_AND_DICE: u32 = 315_496;
74    ///<https://wowlab.gg/inspect/spell/195627>
75    pub(crate) const OPPORTUNITY: u32 = 195_627;
76    ///<https://wowlab.gg/inspect/spell/386270>
77    pub(crate) const AUDACITY: u32 = 386_270;
78    ///<https://wowlab.gg/inspect/spell/315341>
79    pub(crate) const BETWEEN_THE_EYES: u32 = 315_341;
80    ///<https://wowlab.gg/inspect/spell/1784>
81    pub(crate) const STEALTH: u32 = 1784;
82    ///<https://wowlab.gg/inspect/spell/1856>
83    pub(crate) const VANISH: u32 = 1856;
84    ///<https://wowlab.gg/inspect/spell/115192>
85    pub(crate) const SUBTERFUGE: u32 = 115_192;
86    ///<https://wowlab.gg/inspect/spell/383281>
87    pub(crate) const HIDDEN_OPPORTUNITY: u32 = 383_281;
88    ///<https://wowlab.gg/inspect/spell/381878>
89    pub(crate) const DEFT_MANEUVERS: u32 = 381_878;
90    ///<https://wowlab.gg/inspect/spell/14983>
91    pub(crate) const VIGOR: u32 = 14983;
92    ///<https://wowlab.gg/inspect/spell/1214933>
93    pub(crate) const ONE_OF_A_KIND: u32 = 1_214_933;
94    ///<https://wowlab.gg/inspect/spell/1214934>
95    pub(crate) const DOUBLE_TROUBLE: u32 = 1_214_934;
96    ///<https://wowlab.gg/inspect/spell/1214935>
97    pub(crate) const TRIPLE_THREAT: u32 = 1_214_935;
98    ///<https://wowlab.gg/inspect/spell/1214937>
99    pub(crate) const JACKPOT: u32 = 1_214_937;
100    ///<https://wowlab.gg/inspect/spell/256171>
101    pub(crate) const LOADED_DICE: u32 = 256_171;
102    ///<https://wowlab.gg/inspect/spell/13750>
103    pub(crate) const ADRENALINE_RUSH: u32 = 13750;
104    ///<https://wowlab.gg/inspect/spell/13877>
105    pub(crate) const BLADE_FLURRY: u32 = 13877;
106    ///<https://wowlab.gg/inspect/spell/315584>
107    pub(crate) const INSTANT_POISON: u32 = 315_584;
108    ///<https://wowlab.gg/inspect/spell/8679>
109    pub(crate) const WOUND_POISON: u32 = 8679;
110    ///<https://wowlab.gg/inspect/spell/381637>
111    pub(crate) const ATROPHIC_POISON: u32 = 381_637;
112    ///<https://wowlab.gg/inspect/spell/5761>
113    pub(crate) const NUMBING_POISON: u32 = 5761;
114    ///<https://wowlab.gg/inspect/spell/3408>
115    pub(crate) const CRIPPLING_POISON: u32 = 3408;
116    ///<https://wowlab.gg/inspect/spell/395422>
117    pub(crate) const IMPROVED_ADRENALINE_RUSH: u32 = 395_422;
118    ///<https://wowlab.gg/inspect/spell/271896>
119    pub(crate) const BLADE_RUSH_ENERGIZE: u32 = 271_896;
120    ///<https://wowlab.gg/inspect/spell/1265931>
121    pub(crate) const PALMED_BULLETS: u32 = 1_265_931;
122    ///<https://wowlab.gg/inspect/spell/1265935>
123    pub(crate) const GRAVEDIGGER: u32 = 1_265_935;
124    ///<https://wowlab.gg/inspect/spell/1259613>
125    pub(crate) const DEADLY_PURSUIT_WAIT: u32 = 1_259_613;
126    ///<https://wowlab.gg/inspect/spell/1259614>
127    pub(crate) const DEADLY_PURSUIT_CDR: u32 = 1_259_614;
128    ///<https://wowlab.gg/inspect/spell/134735>
129    pub(crate) const PVP_RULES_ENABLED_HARDCODED: u32 = 134_735;
130    ///<https://wowlab.gg/inspect/spell/452923>
131    pub(crate) const FATEBOUND_COIN_HEADS: u32 = 452_923;
132    ///<https://wowlab.gg/inspect/spell/452917>
133    pub(crate) const FATEBOUND_COIN_TAILS: u32 = 452_917;
134    ///<https://wowlab.gg/inspect/spell/1248971>
135    pub(crate) const FATEBOUND_LUCKY_COIN: u32 = 1_248_971;
136    ///<https://wowlab.gg/inspect/spell/1249093>
137    pub(crate) const LUCKY_COIN_COUNTER: u32 = 1_249_093;
138}
139pub(crate) mod TALENT {
140    ///<https://wowlab.gg/inspect/spell/381828>
141    pub(crate) const ACE_UP_YOUR_SLEEVE: u32 = 381_828;
142    ///<https://wowlab.gg/inspect/spell/13750>
143    pub(crate) const ADRENALINE_RUSH: u32 = 13750;
144    ///<https://wowlab.gg/inspect/spell/386270>
145    pub(crate) const AUDACITY: u32 = 386_270;
146    ///<https://wowlab.gg/inspect/spell/13877>
147    pub(crate) const BLADE_FLURRY: u32 = 13877;
148    ///<https://wowlab.gg/inspect/spell/271877>
149    pub(crate) const BLADE_RUSH: u32 = 271_877;
150    ///<https://wowlab.gg/inspect/spell/1259612>
151    pub(crate) const DEADLY_PURSUIT: u32 = 1_259_612;
152    ///<https://wowlab.gg/inspect/spell/381878>
153    pub(crate) const DEFT_MANEUVERS: u32 = 381_878;
154    ///<https://wowlab.gg/inspect/spell/394321>
155    pub(crate) const DEVIOUS_STRATAGEM: u32 = 394_321;
156    ///<https://wowlab.gg/inspect/spell/381846>
157    pub(crate) const FAN_THE_HAMMER: u32 = 381_846;
158    ///<https://wowlab.gg/inspect/spell/35551>
159    pub(crate) const FATAL_FLOURISH: u32 = 35551;
160    ///<https://wowlab.gg/inspect/spell/1265861>
161    pub(crate) const GRAVEDIGGER_1: u32 = 1_265_861;
162    ///<https://wowlab.gg/inspect/spell/1265862>
163    pub(crate) const GRAVEDIGGER_2: u32 = 1_265_862;
164    ///<https://wowlab.gg/inspect/spell/1265863>
165    pub(crate) const GRAVEDIGGER_3: u32 = 1_265_863;
166    ///<https://wowlab.gg/inspect/spell/383281>
167    pub(crate) const HIDDEN_OPPORTUNITY: u32 = 383_281;
168    ///<https://wowlab.gg/inspect/spell/395422>
169    pub(crate) const IMPROVED_ADRENALINE_RUSH: u32 = 395_422;
170    ///<https://wowlab.gg/inspect/spell/381989>
171    pub(crate) const KEEP_IT_ROLLING: u32 = 381_989;
172    ///<https://wowlab.gg/inspect/spell/51690>
173    pub(crate) const KILLING_SPREE: u32 = 51690;
174    ///<https://wowlab.gg/inspect/spell/256170>
175    pub(crate) const LOADED_DICE: u32 = 256_170;
176    ///<https://wowlab.gg/inspect/spell/1256630>
177    pub(crate) const MENACING_RUSH: u32 = 1_256_630;
178    ///<https://wowlab.gg/inspect/spell/279876>
179    pub(crate) const OPPORTUNITY: u32 = 279_876;
180    ///<https://wowlab.gg/inspect/spell/1277933>
181    pub(crate) const PREPARATION: u32 = 1_277_933;
182    ///<https://wowlab.gg/inspect/spell/196938>
183    pub(crate) const QUICK_DRAW: u32 = 196_938;
184    ///<https://wowlab.gg/inspect/spell/79096>
185    pub(crate) const RESTLESS_BLADES: u32 = 79096;
186    ///<https://wowlab.gg/inspect/spell/14161>
187    pub(crate) const RUTHLESSNESS: u32 = 14161;
188    ///<https://wowlab.gg/inspect/spell/381839>
189    pub(crate) const SLEIGHT_OF_HAND: u32 = 381_839;
190    ///<https://wowlab.gg/inspect/spell/381990>
191    pub(crate) const SUMMARILY_DISPATCHED: u32 = 381_990;
192    ///<https://wowlab.gg/inspect/spell/469779>
193    pub(crate) const THISTLE_TEA: u32 = 469_779;
194    ///<https://wowlab.gg/inspect/spell/1259485>
195    pub(crate) const ZERO_IN: u32 = 1_259_485;
196}
197pub(crate) mod REPORTED_SPELL {
198    ///<https://wowlab.gg/inspect/spell/271881>
199    pub(crate) const BLADE_RUSH_ATTACK: u32 = 271_881;
200    ///<https://wowlab.gg/inspect/spell/452538>
201    pub(crate) const FATEBOUND_COIN_TAILS: u32 = 452_538;
202    ///<https://wowlab.gg/inspect/spell/315585>
203    pub(crate) const INSTANT_POISON_DAMAGE: u32 = 315_585;
204    ///<https://wowlab.gg/inspect/spell/57841>
205    pub(crate) const KILLING_SPREE_MH: u32 = 57841;
206    ///<https://wowlab.gg/inspect/spell/57842>
207    pub(crate) const KILLING_SPREE_OH: u32 = 57842;
208    ///<https://wowlab.gg/inspect/spell/86392>
209    pub(crate) const MAIN_GAUCHE: u32 = 86392;
210    ///<https://wowlab.gg/inspect/spell/1265918>
211    pub(crate) const SCOUNDREL_STRIKE: u32 = 1_265_918;
212    ///<https://wowlab.gg/inspect/spell/197834>
213    pub(crate) const SINISTER_STRIKE_EXTRA_ATTACK: u32 = 197_834;
214}
215pub(crate) mod HERO {
216    pub(crate) mod FATEBOUND {
217        pub(crate) mod SPELL {
218            ///<https://wowlab.gg/inspect/spell/1276816>
219            pub(crate) const CONTROLLED_CHAOS: u32 = 1_276_816;
220            ///<https://wowlab.gg/inspect/spell/454419>
221            pub(crate) const DEAL_FATE: u32 = 454_419;
222            ///<https://wowlab.gg/inspect/spell/1249194>
223            pub(crate) const DELIVERED_DOOM: u32 = 1_249_194;
224            ///<https://wowlab.gg/inspect/spell/454435>
225            pub(crate) const DESTINY_DEFINED: u32 = 454_435;
226            ///<https://wowlab.gg/inspect/spell/453457>
227            pub(crate) const EDGE_CASE: u32 = 453_457;
228            ///<https://wowlab.gg/inspect/spell/452538>
229            pub(crate) const FATEBOUND_COIN_TAILS: u32 = 452_538;
230            ///<https://wowlab.gg/inspect/spell/452536>
231            pub(crate) const HAND_OF_FATE: u32 = 452_536;
232            ///<https://wowlab.gg/inspect/spell/1248970>
233            pub(crate) const LUCKY_COIN: u32 = 1_248_970;
234            ///<https://wowlab.gg/inspect/spell/453428>
235            pub(crate) const MEAN_STREAK: u32 = 453_428;
236            ///<https://wowlab.gg/inspect/spell/1276809>
237            pub(crate) const RAVENHOLDT_MINT: u32 = 1_276_809;
238            ///<https://wowlab.gg/inspect/spell/1249204>
239            pub(crate) const RUSH_TO_THE_INEVITABLE: u32 = 1_249_204;
240        }
241        pub(crate) mod AURA {
242            ///<https://wowlab.gg/inspect/spell/452923>
243            pub(crate) const FATEBOUND_COIN_HEADS: u32 = 452_923;
244            ///<https://wowlab.gg/inspect/spell/452917>
245            pub(crate) const FATEBOUND_COIN_TAILS: u32 = 452_917;
246            ///<https://wowlab.gg/inspect/spell/1248971>
247            pub(crate) const FATEBOUND_LUCKY_COIN: u32 = 1_248_971;
248        }
249    }
250    pub(crate) mod TRICKSTER {
251        pub(crate) mod SPELL {
252            ///<https://wowlab.gg/inspect/spell/441519>
253            pub(crate) const COUP_DE_GRACE: u32 = 441_519;
254            ///<https://wowlab.gg/inspect/spell/462127>
255            pub(crate) const COUP_DE_GRACE_DAMAGE_1: u32 = 462_127;
256            ///<https://wowlab.gg/inspect/spell/462128>
257            pub(crate) const COUP_DE_GRACE_DAMAGE_2: u32 = 462_128;
258            ///<https://wowlab.gg/inspect/spell/462129>
259            pub(crate) const COUP_DE_GRACE_DAMAGE_3: u32 = 462_129;
260            ///<https://wowlab.gg/inspect/spell/459485>
261            pub(crate) const UNSEEN_BLADE: u32 = 459_485;
262        }
263        pub(crate) mod AURA {
264            ///<https://wowlab.gg/inspect/spell/441274>
265            pub(crate) const DISORIENTING_STRIKES: u32 = 441_274;
266            ///<https://wowlab.gg/inspect/spell/441786>
267            pub(crate) const ESCALATING_BLADE: u32 = 441_786;
268            ///<https://wowlab.gg/inspect/spell/441224>
269            pub(crate) const FAZED: u32 = 441_224;
270            ///<https://wowlab.gg/inspect/spell/441326>
271            pub(crate) const FLAWLESS_FORM: u32 = 441_326;
272            ///<https://wowlab.gg/inspect/spell/459485>
273            pub(crate) const UNSEEN_BLADE_CD: u32 = 459_485;
274        }
275    }
276}
277static HERO_TREE_FATEBOUND_SPELLS: &[(&str, u32)] = &[
278    ("CONTROLLED_CHAOS", 1_276_816),
279    ("DEAL_FATE", 454_419),
280    ("DELIVERED_DOOM", 1_249_194),
281    ("DESTINY_DEFINED", 454_435),
282    ("EDGE_CASE", 453_457),
283    ("FATEBOUND_COIN_TAILS", 452_538),
284    ("HAND_OF_FATE", 452_536),
285    ("LUCKY_COIN", 1_248_970),
286    ("MEAN_STREAK", 453_428),
287    ("RAVENHOLDT_MINT", 1_276_809),
288    ("RUSH_TO_THE_INEVITABLE", 1_249_204),
289];
290static HERO_TREE_FATEBOUND_AURAS: &[(&str, u32)] = &[
291    ("FATEBOUND_COIN_HEADS", 452_923),
292    ("FATEBOUND_COIN_TAILS", 452_917),
293    ("FATEBOUND_LUCKY_COIN", 1_248_971),
294];
295static HERO_TREE_TRICKSTER_SPELLS: &[(&str, u32)] = &[
296    ("COUP_DE_GRACE", 441_519),
297    ("COUP_DE_GRACE_DAMAGE_1", 462_127),
298    ("COUP_DE_GRACE_DAMAGE_2", 462_128),
299    ("COUP_DE_GRACE_DAMAGE_3", 462_129),
300    ("UNSEEN_BLADE", 459_485),
301];
302static HERO_TREE_TRICKSTER_AURAS: &[(&str, u32)] = &[
303    ("DISORIENTING_STRIKES", 441_274),
304    ("ESCALATING_BLADE", 441_786),
305    ("FAZED", 441_224),
306    ("FLAWLESS_FORM", 441_326),
307    ("UNSEEN_BLADE_CD", 459_485),
308];
309pub(crate) const AURA_SLICE_AND_DICE: LocalAuraIdx = LocalAuraIdx::new(0);
310pub(crate) const AURA_OPPORTUNITY: LocalAuraIdx = LocalAuraIdx::new(1);
311pub(crate) const AURA_AUDACITY: LocalAuraIdx = LocalAuraIdx::new(2);
312pub(crate) const AURA_BETWEEN_THE_EYES: LocalAuraIdx = LocalAuraIdx::new(3);
313pub(crate) const AURA_STEALTH: LocalAuraIdx = LocalAuraIdx::new(4);
314pub(crate) const AURA_VANISH: LocalAuraIdx = LocalAuraIdx::new(5);
315pub(crate) const AURA_SUBTERFUGE: LocalAuraIdx = LocalAuraIdx::new(6);
316pub(crate) const AURA_HIDDEN_OPPORTUNITY: LocalAuraIdx = LocalAuraIdx::new(7);
317pub(crate) const AURA_DEFT_MANEUVERS: LocalAuraIdx = LocalAuraIdx::new(8);
318pub(crate) const AURA_VIGOR: LocalAuraIdx = LocalAuraIdx::new(9);
319pub(crate) const AURA_ONE_OF_A_KIND: LocalAuraIdx = LocalAuraIdx::new(10);
320pub(crate) const AURA_DOUBLE_TROUBLE: LocalAuraIdx = LocalAuraIdx::new(11);
321pub(crate) const AURA_TRIPLE_THREAT: LocalAuraIdx = LocalAuraIdx::new(12);
322pub(crate) const AURA_JACKPOT: LocalAuraIdx = LocalAuraIdx::new(13);
323pub(crate) const AURA_LOADED_DICE: LocalAuraIdx = LocalAuraIdx::new(14);
324pub(crate) const AURA_ADRENALINE_RUSH: LocalAuraIdx = LocalAuraIdx::new(15);
325pub(crate) const AURA_BLADE_FLURRY: LocalAuraIdx = LocalAuraIdx::new(16);
326pub(crate) const AURA_INSTANT_POISON: LocalAuraIdx = LocalAuraIdx::new(17);
327pub(crate) const AURA_WOUND_POISON: LocalAuraIdx = LocalAuraIdx::new(18);
328pub(crate) const AURA_ATROPHIC_POISON: LocalAuraIdx = LocalAuraIdx::new(19);
329pub(crate) const AURA_NUMBING_POISON: LocalAuraIdx = LocalAuraIdx::new(20);
330pub(crate) const AURA_CRIPPLING_POISON: LocalAuraIdx = LocalAuraIdx::new(21);
331pub(crate) const AURA_IMPROVED_ADRENALINE_RUSH: LocalAuraIdx = LocalAuraIdx::new(22);
332pub(crate) const AURA_BLADE_RUSH_ENERGIZE: LocalAuraIdx = LocalAuraIdx::new(23);
333pub(crate) const AURA_PALMED_BULLETS: LocalAuraIdx = LocalAuraIdx::new(24);
334pub(crate) const AURA_GRAVEDIGGER: LocalAuraIdx = LocalAuraIdx::new(25);
335pub(crate) const AURA_DEADLY_PURSUIT_WAIT: LocalAuraIdx = LocalAuraIdx::new(26);
336pub(crate) const AURA_DEADLY_PURSUIT_CDR: LocalAuraIdx = LocalAuraIdx::new(27);
337pub(crate) const AURA_PVP_RULES_ENABLED_HARDCODED: LocalAuraIdx = LocalAuraIdx::new(28);
338pub(crate) const AURA_FATEBOUND_COIN_HEADS: LocalAuraIdx = LocalAuraIdx::new(29);
339pub(crate) const AURA_FATEBOUND_COIN_TAILS: LocalAuraIdx = LocalAuraIdx::new(30);
340pub(crate) const AURA_FATEBOUND_LUCKY_COIN: LocalAuraIdx = LocalAuraIdx::new(31);
341pub(crate) const AURA_LUCKY_COIN_COUNTER: LocalAuraIdx = LocalAuraIdx::new(32);
342pub(crate) const AURA_COUNT: usize = 33;
343const _: () = assert!(
344    AURA_COUNT == 33, "AURA index ABI: count changed -- update positional hook consumers"
345);
346pub(crate) const SPELL_THISTLE_TEA: LocalSpellIdx = LocalSpellIdx::new(0);
347pub(crate) const SPELL_VANISH: LocalSpellIdx = LocalSpellIdx::new(1);
348pub(crate) const SPELL_SINISTER_STRIKE: LocalSpellIdx = LocalSpellIdx::new(2);
349pub(crate) const SPELL_SINISTER_STRIKE_EXTRA_ATTACK: LocalSpellIdx = LocalSpellIdx::new(
350    3,
351);
352pub(crate) const SPELL_PISTOL_SHOT: LocalSpellIdx = LocalSpellIdx::new(4);
353pub(crate) const SPELL_AMBUSH: LocalSpellIdx = LocalSpellIdx::new(5);
354pub(crate) const SPELL_DISPATCH: LocalSpellIdx = LocalSpellIdx::new(6);
355pub(crate) const SPELL_BETWEEN_THE_EYES: LocalSpellIdx = LocalSpellIdx::new(7);
356pub(crate) const SPELL_EVISCERATE: LocalSpellIdx = LocalSpellIdx::new(8);
357pub(crate) const SPELL_SLICE_AND_DICE: LocalSpellIdx = LocalSpellIdx::new(9);
358pub(crate) const SPELL_INSTANT_POISON: LocalSpellIdx = LocalSpellIdx::new(10);
359pub(crate) const SPELL_WOUND_POISON: LocalSpellIdx = LocalSpellIdx::new(11);
360pub(crate) const SPELL_ATROPHIC_POISON: LocalSpellIdx = LocalSpellIdx::new(12);
361pub(crate) const SPELL_NUMBING_POISON: LocalSpellIdx = LocalSpellIdx::new(13);
362pub(crate) const SPELL_CRIPPLING_POISON: LocalSpellIdx = LocalSpellIdx::new(14);
363pub(crate) const SPELL_MAIN_GAUCHE: LocalSpellIdx = LocalSpellIdx::new(15);
364pub(crate) const SPELL_SCOUNDREL_STRIKE: LocalSpellIdx = LocalSpellIdx::new(16);
365pub(crate) const SPELL_INSTANT_POISON_DAMAGE: LocalSpellIdx = LocalSpellIdx::new(17);
366pub(crate) const SPELL_KICK: LocalSpellIdx = LocalSpellIdx::new(18);
367pub(crate) const SPELL_ROLL_THE_BONES: LocalSpellIdx = LocalSpellIdx::new(19);
368pub(crate) const SPELL_ADRENALINE_RUSH: LocalSpellIdx = LocalSpellIdx::new(20);
369pub(crate) const SPELL_BLADE_FLURRY: LocalSpellIdx = LocalSpellIdx::new(21);
370pub(crate) const SPELL_BLADE_FLURRY_INSTANT_ATTACK: LocalSpellIdx = LocalSpellIdx::new(
371    22,
372);
373pub(crate) const SPELL_BLADE_RUSH: LocalSpellIdx = LocalSpellIdx::new(23);
374pub(crate) const SPELL_KILLING_SPREE: LocalSpellIdx = LocalSpellIdx::new(24);
375pub(crate) const SPELL_KEEP_IT_ROLLING: LocalSpellIdx = LocalSpellIdx::new(25);
376pub(crate) const SPELL_PREPARATION: LocalSpellIdx = LocalSpellIdx::new(26);
377pub(crate) const SPELL_BLADE_RUSH_ATTACK: LocalSpellIdx = LocalSpellIdx::new(27);
378pub(crate) const SPELL_COUNT: usize = 28;
379const _: () = assert!(
380    SPELL_COUNT == 28,
381    "SPELL index ABI: count changed -- update positional hook consumers"
382);
383pub(crate) mod EFFECT {
384    ///<https://wowlab.gg/inspect/spell/381828>
385    pub(crate) const ACE_UP_CHANCE: (u32, u8) = (381_828, 1);
386    ///<https://wowlab.gg/inspect/spell/394120>
387    pub(crate) const ACE_UP_ENERGIZE: (u32, u8) = (394_120, 1);
388    ///<https://wowlab.gg/inspect/spell/13877>
389    pub(crate) const BLADE_FLURRY_CLEAVE: (u32, u8) = (13877, 2);
390    ///<https://wowlab.gg/inspect/spell/22482>
391    pub(crate) const BLADE_FLURRY_DAMAGE: (u32, u8) = (22482, 1);
392    ///<https://wowlab.gg/inspect/spell/13877>
393    pub(crate) const BLADE_FLURRY_TARGETS: (u32, u8) = (13877, 3);
394    ///<https://wowlab.gg/inspect/spell/271881>
395    pub(crate) const BLADE_RUSH_ATTACK_DAMAGE: (u32, u8) = (271_881, 1);
396    ///<https://wowlab.gg/inspect/spell/452923>
397    pub(crate) const COIN_HEADS_INITIAL: (u32, u8) = (452_923, 4);
398    ///<https://wowlab.gg/inspect/spell/315341>
399    pub(crate) const BETWEEN_THE_EYES_SUMMARILY_DISPATCHED: (u32, u8) = (315_341, 4);
400    ///<https://wowlab.gg/inspect/spell/452923>
401    pub(crate) const COIN_HEADS_PER_STACK: (u32, u8) = (452_923, 1);
402    ///<https://wowlab.gg/inspect/spell/452923>
403    pub(crate) const COIN_HEADS_PER_STACK_PERIODIC: (u32, u8) = (452_923, 2);
404    ///<https://wowlab.gg/inspect/spell/454419>
405    pub(crate) const DEAL_FATE_CP: (u32, u8) = (454_419, 1);
406    ///<https://wowlab.gg/inspect/spell/1249194>
407    pub(crate) const DELIVERED_DOOM_DMG: (u32, u8) = (1_249_194, 1);
408    ///<https://wowlab.gg/inspect/spell/1249194>
409    pub(crate) const DELIVERED_DOOM_CP: (u32, u8) = (1_249_194, 2);
410    ///<https://wowlab.gg/inspect/spell/454435>
411    pub(crate) const DESTINY_DEFINED_ODDS: (u32, u8) = (454_435, 3);
412    ///<https://wowlab.gg/inspect/spell/381846>
413    pub(crate) const FAN_THE_HAMMER_EXTRA: (u32, u8) = (381_846, 1);
414    ///<https://wowlab.gg/inspect/spell/381846>
415    pub(crate) const FAN_THE_HAMMER_REDUCTION: (u32, u8) = (381_846, 3);
416    ///<https://wowlab.gg/inspect/spell/452538>
417    pub(crate) const FATEBOUND_COIN_TAILS_DAMAGE: (u32, u8) = (452_538, 1);
418    ///<https://wowlab.gg/inspect/spell/1279356>
419    pub(crate) const GRAVEDIGGER_ENERGIZE: (u32, u8) = (1_279_356, 1);
420    ///<https://wowlab.gg/inspect/spell/452536>
421    pub(crate) const HAND_OF_FATE_CP: (u32, u8) = (452_536, 1);
422    ///<https://wowlab.gg/inspect/spell/383281>
423    pub(crate) const HIDDEN_OPPORTUNITY_DAMAGE: (u32, u8) = (383_281, 1);
424    ///<https://wowlab.gg/inspect/spell/315585>
425    pub(crate) const INSTANT_POISON_DAMAGE: (u32, u8) = (315_585, 1);
426    ///<https://wowlab.gg/inspect/spell/1214937>
427    pub(crate) const JACKPOT_RB: (u32, u8) = (1_214_937, 4);
428    ///<https://wowlab.gg/inspect/spell/57841>
429    pub(crate) const KILLING_SPREE_MH_DAMAGE: (u32, u8) = (57841, 1);
430    ///<https://wowlab.gg/inspect/spell/57842>
431    pub(crate) const KILLING_SPREE_OH_DAMAGE: (u32, u8) = (57842, 1);
432    ///<https://wowlab.gg/inspect/spell/1248970>
433    pub(crate) const LUCKY_COIN_FLIPS: (u32, u8) = (1_248_970, 1);
434    ///<https://wowlab.gg/inspect/spell/1248971>
435    pub(crate) const LUCKY_COIN_ODDS: (u32, u8) = (1_248_971, 5);
436    ///<https://wowlab.gg/inspect/spell/86392>
437    pub(crate) const MAIN_GAUCHE_DAMAGE: (u32, u8) = (86392, 1);
438    ///<https://wowlab.gg/inspect/spell/76806>
439    pub(crate) const MAIN_GAUCHE_MASTERY_COEF: (u32, u8) = (76806, 2);
440    ///<https://wowlab.gg/inspect/spell/453428>
441    pub(crate) const MEAN_STREAK_ODDS: (u32, u8) = (453_428, 1);
442    ///<https://wowlab.gg/inspect/spell/1265863>
443    pub(crate) const PALMED_BULLETS_CHANCE: (u32, u8) = (1_265_863, 1);
444    ///<https://wowlab.gg/inspect/spell/185763>
445    pub(crate) const PISTOL_SHOT_DAMAGE: (u32, u8) = (185_763, 1);
446    ///<https://wowlab.gg/inspect/spell/1254567>
447    pub(crate) const QUICK_DRAW_ENERGIZE: (u32, u8) = (1_254_567, 1);
448    ///<https://wowlab.gg/inspect/spell/1276809>
449    pub(crate) const RAVENHOLDT_MINT_HEADS: (u32, u8) = (1_276_809, 1);
450    ///<https://wowlab.gg/inspect/spell/79096>
451    pub(crate) const RESTLESS_BLADES_CDR: (u32, u8) = (79096, 1);
452    ///<https://wowlab.gg/inspect/spell/14161>
453    pub(crate) const RUTHLESSNESS_CP: (u32, u8) = (14161, 1);
454    ///<https://wowlab.gg/inspect/spell/381990>
455    pub(crate) const SUMMARILY_DISPATCHED_DMG: (u32, u8) = (381_990, 2);
456    ///<https://wowlab.gg/inspect/spell/1265862>
457    pub(crate) const SCOUNDREL_CP_THRESHOLD: (u32, u8) = (1_265_862, 1);
458    ///<https://wowlab.gg/inspect/spell/1265918>
459    pub(crate) const SCOUNDREL_STRIKE_DAMAGE: (u32, u8) = (1_265_918, 1);
460    ///<https://wowlab.gg/inspect/spell/197834>
461    pub(crate) const SINISTER_STRIKE_EXTRA_ATTACK_DAMAGE: (u32, u8) = (197_834, 1);
462    ///<https://wowlab.gg/inspect/spell/381839>
463    pub(crate) const SLEIGHT_OF_HAND_CHANCE: (u32, u8) = (381_839, 1);
464    ///<https://wowlab.gg/inspect/spell/271881>
465    pub(crate) const BLADE_RUSH_PRIMARY_MULT: (u32, u8) = (271_881, 2);
466    ///<https://wowlab.gg/inspect/spell/1276816>
467    pub(crate) const CONTROLLED_CHAOS_STREAK: (u32, u8) = (1_276_816, 1);
468    ///<https://wowlab.gg/inspect/spell/1249204>
469    pub(crate) const RUSH_ENERGY: (u32, u8) = (1_249_204, 2);
470    ///<https://wowlab.gg/inspect/spell/1249204>
471    pub(crate) const RUSH_ENERGY_EDGE: (u32, u8) = (1_249_204, 4);
472    ///<https://wowlab.gg/inspect/spell/429951>
473    pub(crate) const BLADE_FLURRY_INSTANT_ATTACK_DAMAGE: (u32, u8) = (429_951, 1);
474}
475static REPORTED_SPELLS: &[(&str, u32)] = &[
476    ("blade_rush_attack", 271_881),
477    ("fatebound_coin_tails", 452_538),
478    ("instant_poison_damage", 315_585),
479    ("killing_spree_mh", 57841),
480    ("killing_spree_oh", 57842),
481    ("main_gauche", 86392),
482    ("scoundrel_strike", 1_265_918),
483    ("sinister_strike_extra_attack", 197_834),
484];
485static DECLARED_SPELL_IDS: &[u32] = &[
486    381_623, 1856, 193_315, 197_834, 185_763, 8676, 2098, 315_341, 196_819, 315_496,
487    315_584, 8679, 381_637, 5761, 3408, 86392, 1_265_918, 315_585, 1766, 315_508, 13750,
488    13877, 429_951, 271_877, 51690, 381_989, 1_277_933, 271_881, 315_496, 195_627,
489    386_270, 315_341, 1784, 1856, 115_192, 383_281, 381_878, 14983, 1_214_933, 1_214_934,
490    1_214_935, 1_214_937, 256_171, 13750, 13877, 315_584, 8679, 381_637, 5761, 3408,
491    395_422, 271_896, 1_265_931, 1_265_935, 1_259_613, 1_259_614, 134_735, 452_923,
492    452_917, 1_248_971, 1_249_093, 6603, 13750, 13877, 14161, 22482, 35546, 35551, 57841,
493    57842, 76806, 79096, 86392, 185_763, 197_834, 271_881, 315_341, 315_585, 381_828,
494    381_839, 381_846, 381_990, 383_281, 394_120, 429_951, 452_536, 452_538, 452_923,
495    453_428, 454_419, 454_435, 1_214_937, 1_248_970, 1_248_971, 1_249_194, 1_249_204,
496    1_254_567, 1_265_862, 1_265_863, 1_265_918, 1_276_809, 1_276_816, 1_279_356, 271_881,
497    452_538, 315_585, 57841, 57842, 86392, 1_265_918, 197_834, 1_276_816, 454_419,
498    1_249_194, 454_435, 453_457, 452_538, 452_536, 1_248_970, 453_428, 1_276_809,
499    1_249_204, 452_923, 452_917, 1_248_971, 441_519, 462_127, 462_128, 462_129, 459_485,
500    441_274, 441_786, 441_224, 441_326, 459_485,
501];
502static DECLARED_AURA_IDS: &[u32] = &[
503    315_496, 195_627, 386_270, 315_341, 1784, 1856, 115_192, 383_281, 381_878, 14983,
504    1_214_933, 1_214_934, 1_214_935, 1_214_937, 256_171, 13750, 13877, 315_584, 8679,
505    381_637, 5761, 3408, 395_422, 271_896, 1_265_931, 1_265_935, 1_259_613, 1_259_614,
506    134_735, 452_923, 452_917, 1_248_971, 1_249_093, 452_923, 452_917, 1_248_971,
507    441_274, 441_786, 441_224, 441_326, 459_485,
508];
509static TALENTS: &[(&str, u32)] = &[
510    ("ACE_UP_YOUR_SLEEVE", TALENT::ACE_UP_YOUR_SLEEVE),
511    ("ADRENALINE_RUSH", TALENT::ADRENALINE_RUSH),
512    ("AUDACITY", TALENT::AUDACITY),
513    ("BLADE_FLURRY", TALENT::BLADE_FLURRY),
514    ("BLADE_RUSH", TALENT::BLADE_RUSH),
515    ("DEADLY_PURSUIT", TALENT::DEADLY_PURSUIT),
516    ("DEFT_MANEUVERS", TALENT::DEFT_MANEUVERS),
517    ("DEVIOUS_STRATAGEM", TALENT::DEVIOUS_STRATAGEM),
518    ("FAN_THE_HAMMER", TALENT::FAN_THE_HAMMER),
519    ("FATAL_FLOURISH", TALENT::FATAL_FLOURISH),
520    ("GRAVEDIGGER_1", TALENT::GRAVEDIGGER_1),
521    ("GRAVEDIGGER_2", TALENT::GRAVEDIGGER_2),
522    ("GRAVEDIGGER_3", TALENT::GRAVEDIGGER_3),
523    ("HIDDEN_OPPORTUNITY", TALENT::HIDDEN_OPPORTUNITY),
524    ("IMPROVED_ADRENALINE_RUSH", TALENT::IMPROVED_ADRENALINE_RUSH),
525    ("KEEP_IT_ROLLING", TALENT::KEEP_IT_ROLLING),
526    ("KILLING_SPREE", TALENT::KILLING_SPREE),
527    ("LOADED_DICE", TALENT::LOADED_DICE),
528    ("MENACING_RUSH", TALENT::MENACING_RUSH),
529    ("OPPORTUNITY", TALENT::OPPORTUNITY),
530    ("PREPARATION", TALENT::PREPARATION),
531    ("QUICK_DRAW", TALENT::QUICK_DRAW),
532    ("RESTLESS_BLADES", TALENT::RESTLESS_BLADES),
533    ("RUTHLESSNESS", TALENT::RUTHLESSNESS),
534    ("SLEIGHT_OF_HAND", TALENT::SLEIGHT_OF_HAND),
535    ("SUMMARILY_DISPATCHED", TALENT::SUMMARILY_DISPATCHED),
536    ("THISTLE_TEA", TALENT::THISTLE_TEA),
537    ("ZERO_IN", TALENT::ZERO_IN),
538];
539pub(crate) mod OUTLAW_ROGUE {
540    pub(crate) const SINISTER_STRIKE_CASTS: u32 = 0;
541    pub(crate) const PISTOL_SHOT_CASTS: u32 = 1;
542    pub(crate) const AMBUSH_CASTS: u32 = 2;
543    pub(crate) const DISPATCH_CASTS: u32 = 3;
544    pub(crate) const BETWEEN_THE_EYES_CASTS: u32 = 4;
545    pub(crate) const ROLL_THE_BONES_CASTS: u32 = 5;
546    pub(crate) const ADRENALINE_RUSH_CASTS: u32 = 6;
547    pub(crate) const BLADE_FLURRY_CASTS: u32 = 7;
548    pub(crate) const BLADE_RUSH_CASTS: u32 = 8;
549    pub(crate) const KILLING_SPREE_CASTS: u32 = 9;
550    pub(crate) const ADRENALINE_RUSH_UPTIME_MS: u32 = 10;
551    pub(crate) const BLADE_FLURRY_UPTIME_MS: u32 = 11;
552}
553fn aura_slice_and_dice(
554    a: AuraDefinitionDraft,
555    data: &ResolvedGameData,
556) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
557    Ok(
558        a
559            .on_player()
560            .apply_base_from_data(data, 315_496)?
561            .max_stacks(
562                data
563                    .require_aura_max_stacks(
564                        wowlab_types::sim::SpellIdx::from_raw(315_496),
565                    )?,
566            ),
567    )
568}
569fn aura_opportunity(
570    a: AuraDefinitionDraft,
571    data: &ResolvedGameData,
572) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
573    Ok(
574        a
575            .on_player()
576            .apply_base_from_data(data, 195_627)?
577            .max_stacks(
578                data
579                    .require_aura_max_stacks(
580                        wowlab_types::sim::SpellIdx::from_raw(195_627),
581                    )?,
582            ),
583    )
584}
585fn aura_audacity(
586    a: AuraDefinitionDraft,
587    data: &ResolvedGameData,
588) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
589    Ok(
590        a
591            .on_player()
592            .apply_base_from_data(data, 386_270)?
593            .max_stacks(
594                data
595                    .require_aura_max_stacks(
596                        wowlab_types::sim::SpellIdx::from_raw(386_270),
597                    )?,
598            ),
599    )
600}
601fn aura_between_the_eyes(
602    a: AuraDefinitionDraft,
603    data: &ResolvedGameData,
604) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
605    Ok(
606        a
607            .on_player()
608            .apply_base_from_data(data, 315_341)?
609            .max_stacks(
610                data
611                    .require_aura_max_stacks(
612                        wowlab_types::sim::SpellIdx::from_raw(315_341),
613                    )?,
614            )
615            .async_stacks(),
616    )
617}
618fn aura_stealth(
619    a: AuraDefinitionDraft,
620    data: &ResolvedGameData,
621) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
622    Ok(
623        a
624            .on_player()
625            .apply_base_from_data(data, 1784)?
626            .max_stacks(
627                data
628                    .require_aura_max_stacks(
629                        wowlab_types::sim::SpellIdx::from_raw(1784),
630                    )?,
631            ),
632    )
633}
634fn aura_vanish(
635    a: AuraDefinitionDraft,
636    data: &ResolvedGameData,
637) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
638    Ok(
639        a
640            .on_player()
641            .apply_base_from_data(data, 1856)?
642            .max_stacks(
643                data
644                    .require_aura_max_stacks(
645                        wowlab_types::sim::SpellIdx::from_raw(1856),
646                    )?,
647            ),
648    )
649}
650fn aura_subterfuge(
651    a: AuraDefinitionDraft,
652    data: &ResolvedGameData,
653) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
654    Ok(
655        a
656            .on_player()
657            .apply_base_from_data(data, 115_192)?
658            .max_stacks(
659                data
660                    .require_aura_max_stacks(
661                        wowlab_types::sim::SpellIdx::from_raw(115_192),
662                    )?,
663            ),
664    )
665}
666fn aura_hidden_opportunity(
667    a: AuraDefinitionDraft,
668    data: &ResolvedGameData,
669) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
670    Ok(
671        a
672            .on_player()
673            .apply_base_from_data(data, 383_281)?
674            .max_stacks(
675                data
676                    .require_aura_max_stacks(
677                        wowlab_types::sim::SpellIdx::from_raw(383_281),
678                    )?,
679            ),
680    )
681}
682fn aura_deft_maneuvers(
683    a: AuraDefinitionDraft,
684    data: &ResolvedGameData,
685) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
686    Ok(
687        a
688            .on_player()
689            .apply_base_from_data(data, 381_878)?
690            .max_stacks(
691                data
692                    .require_aura_max_stacks(
693                        wowlab_types::sim::SpellIdx::from_raw(381_878),
694                    )?,
695            ),
696    )
697}
698fn aura_vigor(
699    a: AuraDefinitionDraft,
700    data: &ResolvedGameData,
701) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
702    Ok(
703        a
704            .on_player()
705            .apply_base_from_data(data, 14983)?
706            .max_stacks(
707                data
708                    .require_aura_max_stacks(
709                        wowlab_types::sim::SpellIdx::from_raw(14983),
710                    )?,
711            ),
712    )
713}
714fn aura_one_of_a_kind(
715    a: AuraDefinitionDraft,
716    data: &ResolvedGameData,
717) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
718    Ok(
719        a
720            .on_player()
721            .apply_base_from_data(data, 1_214_933)?
722            .max_stacks(
723                data
724                    .require_aura_max_stacks(
725                        wowlab_types::sim::SpellIdx::from_raw(1_214_933),
726                    )?,
727            ),
728    )
729}
730fn aura_double_trouble(
731    a: AuraDefinitionDraft,
732    data: &ResolvedGameData,
733) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
734    Ok(
735        a
736            .on_player()
737            .apply_base_from_data(data, 1_214_934)?
738            .max_stacks(
739                data
740                    .require_aura_max_stacks(
741                        wowlab_types::sim::SpellIdx::from_raw(1_214_934),
742                    )?,
743            ),
744    )
745}
746fn aura_triple_threat(
747    a: AuraDefinitionDraft,
748    data: &ResolvedGameData,
749) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
750    Ok(
751        a
752            .on_player()
753            .apply_base_from_data(data, 1_214_935)?
754            .max_stacks(
755                data
756                    .require_aura_max_stacks(
757                        wowlab_types::sim::SpellIdx::from_raw(1_214_935),
758                    )?,
759            ),
760    )
761}
762fn aura_jackpot(
763    a: AuraDefinitionDraft,
764    data: &ResolvedGameData,
765) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
766    Ok(
767        a
768            .on_player()
769            .apply_base_from_data(data, 1_214_937)?
770            .max_stacks(
771                data
772                    .require_aura_max_stacks(
773                        wowlab_types::sim::SpellIdx::from_raw(1_214_937),
774                    )?,
775            ),
776    )
777}
778fn aura_loaded_dice(
779    a: AuraDefinitionDraft,
780    data: &ResolvedGameData,
781) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
782    Ok(
783        a
784            .on_player()
785            .apply_base_from_data(data, 256_171)?
786            .max_stacks(
787                data
788                    .require_aura_max_stacks(
789                        wowlab_types::sim::SpellIdx::from_raw(256_171),
790                    )?,
791            ),
792    )
793}
794fn aura_adrenaline_rush(
795    a: AuraDefinitionDraft,
796    data: &ResolvedGameData,
797) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
798    a.on_player()
799        .apply_base_from_data(data, 13750)?
800        .max_stacks(
801            data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(13750))?,
802        )
803        .max_resource_per_stack(
804            data.base_points(wowlab_types::sim::SpellIdx::from_raw(13750), 6),
805        )
806}
807fn aura_blade_flurry(
808    a: AuraDefinitionDraft,
809    data: &ResolvedGameData,
810) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
811    Ok(
812        a
813            .on_player()
814            .apply_base_from_data(data, 13877)?
815            .max_stacks(
816                data
817                    .require_aura_max_stacks(
818                        wowlab_types::sim::SpellIdx::from_raw(13877),
819                    )?,
820            ),
821    )
822}
823fn aura_instant_poison(
824    a: AuraDefinitionDraft,
825    data: &ResolvedGameData,
826) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
827    Ok(
828        a
829            .on_player()
830            .apply_base_from_data(data, 315_584)?
831            .max_stacks(
832                data
833                    .require_aura_max_stacks(
834                        wowlab_types::sim::SpellIdx::from_raw(315_584),
835                    )?,
836            )
837            .spell_group(0, wowlab_types::combat::SpellGroupRule::Exclusive),
838    )
839}
840fn aura_wound_poison(
841    a: AuraDefinitionDraft,
842    data: &ResolvedGameData,
843) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
844    Ok(
845        a
846            .on_player()
847            .apply_base_from_data(data, 8679)?
848            .max_stacks(
849                data
850                    .require_aura_max_stacks(
851                        wowlab_types::sim::SpellIdx::from_raw(8679),
852                    )?,
853            )
854            .spell_group(0, wowlab_types::combat::SpellGroupRule::Exclusive),
855    )
856}
857fn aura_atrophic_poison(
858    a: AuraDefinitionDraft,
859    data: &ResolvedGameData,
860) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
861    Ok(
862        a
863            .on_player()
864            .apply_base_from_data(data, 381_637)?
865            .max_stacks(
866                data
867                    .require_aura_max_stacks(
868                        wowlab_types::sim::SpellIdx::from_raw(381_637),
869                    )?,
870            )
871            .spell_group(1, wowlab_types::combat::SpellGroupRule::Exclusive),
872    )
873}
874fn aura_numbing_poison(
875    a: AuraDefinitionDraft,
876    data: &ResolvedGameData,
877) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
878    Ok(
879        a
880            .on_player()
881            .apply_base_from_data(data, 5761)?
882            .max_stacks(
883                data
884                    .require_aura_max_stacks(
885                        wowlab_types::sim::SpellIdx::from_raw(5761),
886                    )?,
887            )
888            .spell_group(1, wowlab_types::combat::SpellGroupRule::Exclusive),
889    )
890}
891fn aura_crippling_poison(
892    a: AuraDefinitionDraft,
893    data: &ResolvedGameData,
894) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
895    Ok(
896        a
897            .on_player()
898            .apply_base_from_data(data, 3408)?
899            .max_stacks(
900                data
901                    .require_aura_max_stacks(
902                        wowlab_types::sim::SpellIdx::from_raw(3408),
903                    )?,
904            )
905            .spell_group(1, wowlab_types::combat::SpellGroupRule::Exclusive),
906    )
907}
908fn aura_improved_adrenaline_rush(
909    a: AuraDefinitionDraft,
910    data: &ResolvedGameData,
911) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
912    Ok(
913        a
914            .on_player()
915            .apply_base_from_data(data, 395_422)?
916            .max_stacks(
917                data
918                    .require_aura_max_stacks(
919                        wowlab_types::sim::SpellIdx::from_raw(395_422),
920                    )?,
921            ),
922    )
923}
924fn aura_blade_rush_energize(
925    a: AuraDefinitionDraft,
926    data: &ResolvedGameData,
927) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
928    Ok(
929        a
930            .on_player()
931            .apply_base_from_data(data, 271_896)?
932            .max_stacks(
933                data
934                    .require_aura_max_stacks(
935                        wowlab_types::sim::SpellIdx::from_raw(271_896),
936                    )?,
937            ),
938    )
939}
940fn aura_palmed_bullets(
941    a: AuraDefinitionDraft,
942    data: &ResolvedGameData,
943) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
944    Ok(
945        a
946            .on_player()
947            .apply_base_from_data(data, 1_265_931)?
948            .max_stacks(
949                data
950                    .require_aura_max_stacks(
951                        wowlab_types::sim::SpellIdx::from_raw(1_265_931),
952                    )?,
953            ),
954    )
955}
956fn aura_gravedigger(
957    a: AuraDefinitionDraft,
958    data: &ResolvedGameData,
959) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
960    Ok(
961        a
962            .on_player()
963            .apply_base_from_data(data, 1_265_935)?
964            .max_stacks(
965                data
966                    .require_aura_max_stacks(
967                        wowlab_types::sim::SpellIdx::from_raw(1_265_935),
968                    )?,
969            ),
970    )
971}
972fn aura_deadly_pursuit_wait(
973    a: AuraDefinitionDraft,
974    data: &ResolvedGameData,
975) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
976    Ok(
977        a
978            .on_player()
979            .apply_base_from_data(data, 1_259_613)?
980            .max_stacks(
981                data
982                    .require_aura_max_stacks(
983                        wowlab_types::sim::SpellIdx::from_raw(1_259_613),
984                    )?,
985            )
986            .on_expire(crate::hooks::outlaw_rogue::deadly_pursuit_wait_expire_hook),
987    )
988}
989fn aura_deadly_pursuit_cdr(
990    a: AuraDefinitionDraft,
991    data: &ResolvedGameData,
992) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
993    Ok(
994        a
995            .on_player()
996            .apply_base_from_data(data, 1_259_614)?
997            .max_stacks(
998                data
999                    .require_aura_max_stacks(
1000                        wowlab_types::sim::SpellIdx::from_raw(1_259_614),
1001                    )?,
1002            ),
1003    )
1004}
1005fn aura_pvp_rules_enabled_hardcoded(
1006    a: AuraDefinitionDraft,
1007    data: &ResolvedGameData,
1008) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
1009    Ok(
1010        a
1011            .on_player()
1012            .apply_base_from_data(data, 134_735)?
1013            .max_stacks(
1014                data
1015                    .require_aura_max_stacks(
1016                        wowlab_types::sim::SpellIdx::from_raw(134_735),
1017                    )?,
1018            ),
1019    )
1020}
1021fn aura_fatebound_coin_heads(
1022    a: AuraDefinitionDraft,
1023    data: &ResolvedGameData,
1024) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
1025    Ok(
1026        a
1027            .on_player()
1028            .apply_base_from_data(data, 452_923)?
1029            .max_stacks(
1030                data
1031                    .require_aura_max_stacks(
1032                        wowlab_types::sim::SpellIdx::from_raw(452_923),
1033                    )?,
1034            ),
1035    )
1036}
1037fn aura_fatebound_coin_tails(
1038    a: AuraDefinitionDraft,
1039    data: &ResolvedGameData,
1040) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
1041    Ok(
1042        a
1043            .on_player()
1044            .apply_base_from_data(data, 452_917)?
1045            .max_stacks(
1046                data
1047                    .require_aura_max_stacks(
1048                        wowlab_types::sim::SpellIdx::from_raw(452_917),
1049                    )?,
1050            ),
1051    )
1052}
1053fn aura_fatebound_lucky_coin(
1054    a: AuraDefinitionDraft,
1055    data: &ResolvedGameData,
1056) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
1057    a.on_player()
1058        .apply_base_from_data(data, 1_248_971)?
1059        .max_stacks(
1060            data
1061                .require_aura_max_stacks(
1062                    wowlab_types::sim::SpellIdx::from_raw(1_248_971),
1063                )?,
1064        )
1065        .primary_pct_per_stack(
1066            data.base_points(wowlab_types::sim::SpellIdx::from_raw(1_248_971), 1),
1067        )
1068}
1069fn aura_lucky_coin_counter(
1070    a: AuraDefinitionDraft,
1071    data: &ResolvedGameData,
1072) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
1073    Ok(
1074        a
1075            .on_player()
1076            .apply_base_from_data(data, 1_249_093)?
1077            .max_stacks(
1078                data
1079                    .require_aura_max_stacks(
1080                        wowlab_types::sim::SpellIdx::from_raw(1_249_093),
1081                    )?,
1082            ),
1083    )
1084}
1085fn spell_thistle_tea(
1086    s: SpellDefinitionDraft,
1087    data: &ResolvedGameData,
1088) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1089    Ok(
1090        s
1091            .apply_base_from_data(data, 381_623)?
1092            .no_stealth_break()
1093            .apply_aoe_from_data(data),
1094    )
1095}
1096fn spell_vanish(
1097    s: SpellDefinitionDraft,
1098    data: &ResolvedGameData,
1099) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1100    Ok(
1101        s
1102            .apply_base_from_data(data, 1856)?
1103            .applies_aura(AURA_STEALTH)
1104            .no_stealth_break()
1105            .apply_aoe_from_data(data),
1106    )
1107}
1108fn spell_sinister_strike(
1109    s: SpellDefinitionDraft,
1110    data: &ResolvedGameData,
1111) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1112    Ok(
1113        s
1114            .apply_base_from_data(data, 193_315)?
1115            .apply_aoe_from_data(data)
1116            .on_cast(crate::hooks::outlaw_rogue::sinister_strike_hook),
1117    )
1118}
1119fn spell_sinister_strike_extra_attack(
1120    s: SpellDefinitionDraft,
1121    data: &ResolvedGameData,
1122) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1123    Ok(s.apply_base_from_data(data, 197_834)?.apply_aoe_from_data(data))
1124}
1125fn spell_pistol_shot(
1126    s: SpellDefinitionDraft,
1127    data: &ResolvedGameData,
1128) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1129    Ok(
1130        s
1131            .apply_base_from_data(data, 185_763)?
1132            .damage_ap_from_data_typed(
1133                wowlab_engine_domain::dbc::EffectLookup::new(
1134                    data,
1135                    wowlab_types::sim::EffectRef::new(
1136                        wowlab_types::sim::SpellIdx::from_raw(185_763),
1137                        1,
1138                    ),
1139                ),
1140                wowlab_engine_combat::WeaponApType::Both,
1141            )?
1142            .apply_aoe_from_data(data)
1143            .on_cast(crate::hooks::outlaw_rogue::pistol_shot_hook),
1144    )
1145}
1146fn spell_ambush(
1147    s: SpellDefinitionDraft,
1148    data: &ResolvedGameData,
1149) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1150    Ok(
1151        s
1152            .apply_base_from_data(data, 8676)?
1153            .no_stealth_break()
1154            .apply_aoe_from_data(data)
1155            .on_cast(crate::hooks::outlaw_rogue::ambush_hook),
1156    )
1157}
1158fn spell_dispatch(
1159    s: SpellDefinitionDraft,
1160    data: &ResolvedGameData,
1161) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1162    Ok(
1163        s
1164            .apply_base_from_data(data, 2098)?
1165            .apply_aoe_from_data(data)
1166            .on_cast(crate::hooks::outlaw_rogue::dispatch_hook),
1167    )
1168}
1169fn spell_between_the_eyes(
1170    s: SpellDefinitionDraft,
1171    data: &ResolvedGameData,
1172) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1173    Ok(
1174        s
1175            .apply_base_from_data(data, 315_341)?
1176            .damage_ap_from_data_typed(
1177                wowlab_engine_domain::dbc::EffectLookup::new(
1178                    data,
1179                    wowlab_types::sim::EffectRef::new(
1180                        wowlab_types::sim::SpellIdx::from_raw(315_341),
1181                        1,
1182                    ),
1183                ),
1184                wowlab_engine_combat::WeaponApType::Both,
1185            )?
1186            .applies_inferred_aura(AURA_BETWEEN_THE_EYES, 315_341)
1187            .apply_aoe_from_data(data)
1188            .on_cast(crate::hooks::outlaw_rogue::between_the_eyes_hook),
1189    )
1190}
1191fn spell_eviscerate(
1192    s: SpellDefinitionDraft,
1193    data: &ResolvedGameData,
1194) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1195    Ok(s.apply_base_from_data(data, 196_819)?.apply_aoe_from_data(data))
1196}
1197fn spell_slice_and_dice(
1198    s: SpellDefinitionDraft,
1199    data: &ResolvedGameData,
1200) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1201    Ok(
1202        s
1203            .apply_base_from_data(data, 315_496)?
1204            .applies_inferred_aura(AURA_SLICE_AND_DICE, 315_496)
1205            .apply_aoe_from_data(data)
1206            .on_cast(crate::hooks::outlaw_rogue::slice_and_dice_hook),
1207    )
1208}
1209fn spell_instant_poison(
1210    s: SpellDefinitionDraft,
1211    data: &ResolvedGameData,
1212) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1213    Ok(
1214        s
1215            .apply_base_from_data(data, 315_584)?
1216            .applies_inferred_aura(AURA_INSTANT_POISON, 315_584)
1217            .apply_aoe_from_data(data),
1218    )
1219}
1220fn spell_wound_poison(
1221    s: SpellDefinitionDraft,
1222    data: &ResolvedGameData,
1223) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1224    Ok(
1225        s
1226            .apply_base_from_data(data, 8679)?
1227            .applies_inferred_aura(AURA_WOUND_POISON, 8679)
1228            .apply_aoe_from_data(data),
1229    )
1230}
1231fn spell_atrophic_poison(
1232    s: SpellDefinitionDraft,
1233    data: &ResolvedGameData,
1234) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1235    Ok(
1236        s
1237            .apply_base_from_data(data, 381_637)?
1238            .applies_inferred_aura(AURA_ATROPHIC_POISON, 381_637)
1239            .apply_aoe_from_data(data),
1240    )
1241}
1242fn spell_numbing_poison(
1243    s: SpellDefinitionDraft,
1244    data: &ResolvedGameData,
1245) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1246    Ok(
1247        s
1248            .apply_base_from_data(data, 5761)?
1249            .applies_inferred_aura(AURA_NUMBING_POISON, 5761)
1250            .apply_aoe_from_data(data),
1251    )
1252}
1253fn spell_crippling_poison(
1254    s: SpellDefinitionDraft,
1255    data: &ResolvedGameData,
1256) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1257    Ok(
1258        s
1259            .apply_base_from_data(data, 3408)?
1260            .applies_inferred_aura(AURA_CRIPPLING_POISON, 3408)
1261            .apply_aoe_from_data(data),
1262    )
1263}
1264fn spell_main_gauche(
1265    s: SpellDefinitionDraft,
1266    data: &ResolvedGameData,
1267) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1268    Ok(s.apply_base_from_data(data, 86392)?.apply_aoe_from_data(data))
1269}
1270fn spell_scoundrel_strike(
1271    s: SpellDefinitionDraft,
1272    data: &ResolvedGameData,
1273) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1274    Ok(s.apply_base_from_data(data, 1_265_918)?.apply_aoe_from_data(data))
1275}
1276fn spell_instant_poison_damage(
1277    s: SpellDefinitionDraft,
1278    data: &ResolvedGameData,
1279) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1280    Ok(s.apply_base_from_data(data, 315_585)?.apply_aoe_from_data(data))
1281}
1282fn spell_kick(
1283    s: SpellDefinitionDraft,
1284    data: &ResolvedGameData,
1285) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1286    Ok(s.apply_base_from_data(data, 1766)?.apply_aoe_from_data(data))
1287}
1288fn spell_roll_the_bones(
1289    s: SpellDefinitionDraft,
1290    data: &ResolvedGameData,
1291) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1292    Ok(
1293        s
1294            .apply_base_from_data(data, 315_508)?
1295            .no_stealth_break()
1296            .apply_aoe_from_data(data)
1297            .on_cast(crate::hooks::outlaw_rogue::roll_the_bones_hook),
1298    )
1299}
1300fn spell_adrenaline_rush(
1301    s: SpellDefinitionDraft,
1302    data: &ResolvedGameData,
1303) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1304    Ok(
1305        s
1306            .apply_base_from_data(data, 13750)?
1307            .applies_inferred_aura(AURA_ADRENALINE_RUSH, 13750)
1308            .apply_aoe_from_data(data)
1309            .on_cast(crate::hooks::outlaw_rogue::adrenaline_rush_hook),
1310    )
1311}
1312fn spell_blade_flurry(
1313    s: SpellDefinitionDraft,
1314    data: &ResolvedGameData,
1315) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1316    Ok(
1317        s
1318            .apply_base_from_data(data, 13877)?
1319            .applies_inferred_aura(AURA_BLADE_FLURRY, 13877)
1320            .apply_aoe_from_data(data)
1321            .on_cast(crate::hooks::outlaw_rogue::blade_flurry_hook),
1322    )
1323}
1324fn spell_blade_flurry_instant_attack(
1325    s: SpellDefinitionDraft,
1326    data: &ResolvedGameData,
1327) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1328    Ok(s.apply_base_from_data(data, 429_951)?.apply_aoe_from_data(data))
1329}
1330fn spell_blade_rush(
1331    s: SpellDefinitionDraft,
1332    data: &ResolvedGameData,
1333) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1334    Ok(
1335        s
1336            .apply_base_from_data(data, 271_877)?
1337            .applies_aura(AURA_BLADE_RUSH_ENERGIZE)
1338            .apply_aoe_from_data(data)
1339            .on_cast(crate::hooks::outlaw_rogue::blade_rush_hook),
1340    )
1341}
1342fn spell_killing_spree(
1343    s: SpellDefinitionDraft,
1344    data: &ResolvedGameData,
1345) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1346    Ok(
1347        s
1348            .apply_base_from_data(data, 51690)?
1349            .apply_aoe_from_data(data)
1350            .on_cast(crate::hooks::outlaw_rogue::killing_spree_hook),
1351    )
1352}
1353fn spell_keep_it_rolling(
1354    s: SpellDefinitionDraft,
1355    data: &ResolvedGameData,
1356) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1357    Ok(
1358        s
1359            .apply_base_from_data(data, 381_989)?
1360            .apply_aoe_from_data(data)
1361            .on_cast(crate::hooks::outlaw_rogue::keep_it_rolling_hook),
1362    )
1363}
1364fn spell_preparation(
1365    s: SpellDefinitionDraft,
1366    data: &ResolvedGameData,
1367) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1368    Ok(
1369        s
1370            .apply_base_from_data(data, 1_277_933)?
1371            .apply_aoe_from_data(data)
1372            .on_cast(crate::hooks::outlaw_rogue::preparation_hook),
1373    )
1374}
1375fn spell_blade_rush_attack(
1376    s: SpellDefinitionDraft,
1377    data: &ResolvedGameData,
1378) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
1379    Ok(s.apply_base_from_data(data, 271_881)?.apply_aoe_from_data(data))
1380}
1381pub(crate) fn build_combat_system(
1382    params: &wowlab_engine_ports::HandlerParams<'_>,
1383) -> Result<BuiltCombatSystem, wowlab_engine_ports::EngineError> {
1384    let builder = BuiltCombatSystem::builder(params.stats.clone())
1385        .spec_id(SpecId::Outlaw)
1386        .hero_talent_trees(DECLARED_METADATA.hero_talent_trees)
1387        .mastery_spell(76806)
1388        .mastery_hook(crate::hooks::outlaw_rogue::mastery)
1389        .resource(
1390            "energy",
1391            params
1392                .game_data
1393                .power_max(3)
1394                .ok_or_else(|| {
1395                    wowlab_engine_ports::EngineError::spec_construction(
1396                        "missing power-type power_max for type_id 3",
1397                    )
1398                })?,
1399            params
1400                .game_data
1401                .power_regen_for_max(
1402                    3,
1403                    params
1404                        .game_data
1405                        .power_max(3)
1406                        .ok_or_else(|| {
1407                            wowlab_engine_ports::EngineError::spec_construction(
1408                                "missing power-type power_max for type_id 3",
1409                            )
1410                        })?,
1411                )
1412                .ok_or_else(|| {
1413                    wowlab_engine_ports::EngineError::spec_construction(
1414                        "missing power-type power_regen_for_max for type_id 3",
1415                    )
1416                })?,
1417        )
1418        .resource_type_id(3)
1419        .resource_start(
1420            params
1421                .game_data
1422                .power_default(3)
1423                .ok_or_else(|| {
1424                    wowlab_engine_ports::EngineError::spec_construction(
1425                        "missing power-type power_default for type_id 3",
1426                    )
1427                })?,
1428        )
1429        .secondary_resource(
1430            "combo_points",
1431            params
1432                .game_data
1433                .power_max(4)
1434                .ok_or_else(|| {
1435                    wowlab_engine_ports::EngineError::spec_construction(
1436                        "missing power-type power_max for type_id 4",
1437                    )
1438                })?,
1439        )
1440        .secondary_resource_type_id(4)
1441        .precombat_aura(AURA_STEALTH)
1442        .precombat_aura(AURA_INSTANT_POISON)
1443        .precombat_aura(AURA_ATROPHIC_POISON)
1444        .stealth_aura(AURA::STEALTH)
1445        .aura(
1446            "slice_and_dice",
1447            AURA::SLICE_AND_DICE,
1448            |a| aura_slice_and_dice(a, &params.game_data),
1449        )
1450        .aura(
1451            "opportunity",
1452            AURA::OPPORTUNITY,
1453            |a| aura_opportunity(a, &params.game_data),
1454        )
1455        .aura("audacity", AURA::AUDACITY, |a| aura_audacity(a, &params.game_data))
1456        .aura(
1457            "between_the_eyes",
1458            AURA::BETWEEN_THE_EYES,
1459            |a| aura_between_the_eyes(a, &params.game_data),
1460        )
1461        .aura("stealth", AURA::STEALTH, |a| aura_stealth(a, &params.game_data))
1462        .aura("vanish", AURA::VANISH, |a| aura_vanish(a, &params.game_data))
1463        .aura("subterfuge", AURA::SUBTERFUGE, |a| aura_subterfuge(a, &params.game_data))
1464        .aura(
1465            "hidden_opportunity",
1466            AURA::HIDDEN_OPPORTUNITY,
1467            |a| aura_hidden_opportunity(a, &params.game_data),
1468        )
1469        .aura(
1470            "deft_maneuvers",
1471            AURA::DEFT_MANEUVERS,
1472            |a| aura_deft_maneuvers(a, &params.game_data),
1473        )
1474        .aura("vigor", AURA::VIGOR, |a| aura_vigor(a, &params.game_data))
1475        .aura(
1476            "one_of_a_kind",
1477            AURA::ONE_OF_A_KIND,
1478            |a| aura_one_of_a_kind(a, &params.game_data),
1479        )
1480        .aura(
1481            "double_trouble",
1482            AURA::DOUBLE_TROUBLE,
1483            |a| aura_double_trouble(a, &params.game_data),
1484        )
1485        .aura(
1486            "triple_threat",
1487            AURA::TRIPLE_THREAT,
1488            |a| aura_triple_threat(a, &params.game_data),
1489        )
1490        .aura("jackpot", AURA::JACKPOT, |a| aura_jackpot(a, &params.game_data))
1491        .aura(
1492            "loaded_dice",
1493            AURA::LOADED_DICE,
1494            |a| aura_loaded_dice(a, &params.game_data),
1495        )
1496        .aura(
1497            "adrenaline_rush",
1498            AURA::ADRENALINE_RUSH,
1499            |a| aura_adrenaline_rush(a, &params.game_data),
1500        )
1501        .aura(
1502            "blade_flurry",
1503            AURA::BLADE_FLURRY,
1504            |a| aura_blade_flurry(a, &params.game_data),
1505        )
1506        .aura(
1507            "instant_poison",
1508            AURA::INSTANT_POISON,
1509            |a| aura_instant_poison(a, &params.game_data),
1510        )
1511        .aura(
1512            "wound_poison",
1513            AURA::WOUND_POISON,
1514            |a| aura_wound_poison(a, &params.game_data),
1515        )
1516        .aura(
1517            "atrophic_poison",
1518            AURA::ATROPHIC_POISON,
1519            |a| aura_atrophic_poison(a, &params.game_data),
1520        )
1521        .aura(
1522            "numbing_poison",
1523            AURA::NUMBING_POISON,
1524            |a| aura_numbing_poison(a, &params.game_data),
1525        )
1526        .aura(
1527            "crippling_poison",
1528            AURA::CRIPPLING_POISON,
1529            |a| aura_crippling_poison(a, &params.game_data),
1530        )
1531        .aura(
1532            "improved_adrenaline_rush",
1533            AURA::IMPROVED_ADRENALINE_RUSH,
1534            |a| aura_improved_adrenaline_rush(a, &params.game_data),
1535        )
1536        .aura(
1537            "blade_rush_energize",
1538            AURA::BLADE_RUSH_ENERGIZE,
1539            |a| aura_blade_rush_energize(a, &params.game_data),
1540        )
1541        .aura(
1542            "palmed_bullets",
1543            AURA::PALMED_BULLETS,
1544            |a| aura_palmed_bullets(a, &params.game_data),
1545        )
1546        .aura(
1547            "gravedigger",
1548            AURA::GRAVEDIGGER,
1549            |a| aura_gravedigger(a, &params.game_data),
1550        )
1551        .aura(
1552            "deadly_pursuit_wait",
1553            AURA::DEADLY_PURSUIT_WAIT,
1554            |a| aura_deadly_pursuit_wait(a, &params.game_data),
1555        )
1556        .aura(
1557            "deadly_pursuit_cdr",
1558            AURA::DEADLY_PURSUIT_CDR,
1559            |a| aura_deadly_pursuit_cdr(a, &params.game_data),
1560        )
1561        .aura(
1562            "pvp_rules_enabled_hardcoded",
1563            AURA::PVP_RULES_ENABLED_HARDCODED,
1564            |a| aura_pvp_rules_enabled_hardcoded(a, &params.game_data),
1565        )
1566        .aura(
1567            "fatebound_coin_heads",
1568            AURA::FATEBOUND_COIN_HEADS,
1569            |a| aura_fatebound_coin_heads(a, &params.game_data),
1570        )
1571        .aura(
1572            "fatebound_coin_tails",
1573            AURA::FATEBOUND_COIN_TAILS,
1574            |a| aura_fatebound_coin_tails(a, &params.game_data),
1575        )
1576        .aura(
1577            "fatebound_lucky_coin",
1578            AURA::FATEBOUND_LUCKY_COIN,
1579            |a| aura_fatebound_lucky_coin(a, &params.game_data),
1580        )
1581        .aura(
1582            "lucky_coin_counter",
1583            AURA::LUCKY_COIN_COUNTER,
1584            |a| aura_lucky_coin_counter(a, &params.game_data),
1585        )
1586        .spell(
1587            "thistle_tea",
1588            SPELL::THISTLE_TEA,
1589            |s| spell_thistle_tea(s, &params.game_data),
1590        )
1591        .spell("vanish", SPELL::VANISH, |s| spell_vanish(s, &params.game_data))
1592        .spell(
1593            "sinister_strike",
1594            SPELL::SINISTER_STRIKE,
1595            |s| spell_sinister_strike(s, &params.game_data),
1596        )
1597        .spell(
1598            "sinister_strike_extra_attack",
1599            SPELL::SINISTER_STRIKE_EXTRA_ATTACK,
1600            |s| spell_sinister_strike_extra_attack(s, &params.game_data),
1601        )
1602        .spell(
1603            "pistol_shot",
1604            SPELL::PISTOL_SHOT,
1605            |s| spell_pistol_shot(s, &params.game_data),
1606        )
1607        .spell("ambush", SPELL::AMBUSH, |s| spell_ambush(s, &params.game_data))
1608        .spell("dispatch", SPELL::DISPATCH, |s| spell_dispatch(s, &params.game_data))
1609        .spell(
1610            "between_the_eyes",
1611            SPELL::BETWEEN_THE_EYES,
1612            |s| spell_between_the_eyes(s, &params.game_data),
1613        )
1614        .spell(
1615            "eviscerate",
1616            SPELL::EVISCERATE,
1617            |s| spell_eviscerate(s, &params.game_data),
1618        )
1619        .spell(
1620            "slice_and_dice",
1621            SPELL::SLICE_AND_DICE,
1622            |s| spell_slice_and_dice(s, &params.game_data),
1623        )
1624        .spell(
1625            "instant_poison",
1626            SPELL::INSTANT_POISON,
1627            |s| spell_instant_poison(s, &params.game_data),
1628        )
1629        .spell(
1630            "wound_poison",
1631            SPELL::WOUND_POISON,
1632            |s| spell_wound_poison(s, &params.game_data),
1633        )
1634        .spell(
1635            "atrophic_poison",
1636            SPELL::ATROPHIC_POISON,
1637            |s| spell_atrophic_poison(s, &params.game_data),
1638        )
1639        .spell(
1640            "numbing_poison",
1641            SPELL::NUMBING_POISON,
1642            |s| spell_numbing_poison(s, &params.game_data),
1643        )
1644        .spell(
1645            "crippling_poison",
1646            SPELL::CRIPPLING_POISON,
1647            |s| spell_crippling_poison(s, &params.game_data),
1648        )
1649        .spell(
1650            "main_gauche",
1651            SPELL::MAIN_GAUCHE,
1652            |s| spell_main_gauche(s, &params.game_data),
1653        )
1654        .spell(
1655            "scoundrel_strike",
1656            SPELL::SCOUNDREL_STRIKE,
1657            |s| spell_scoundrel_strike(s, &params.game_data),
1658        )
1659        .spell(
1660            "instant_poison_damage",
1661            SPELL::INSTANT_POISON_DAMAGE,
1662            |s| spell_instant_poison_damage(s, &params.game_data),
1663        )
1664        .spell("kick", SPELL::KICK, |s| spell_kick(s, &params.game_data))
1665        .spell(
1666            "roll_the_bones",
1667            SPELL::ROLL_THE_BONES,
1668            |s| spell_roll_the_bones(s, &params.game_data),
1669        )
1670        .spell(
1671            "adrenaline_rush",
1672            SPELL::ADRENALINE_RUSH,
1673            |s| spell_adrenaline_rush(s, &params.game_data),
1674        )
1675        .spell(
1676            "blade_flurry",
1677            SPELL::BLADE_FLURRY,
1678            |s| spell_blade_flurry(s, &params.game_data),
1679        )
1680        .spell(
1681            "blade_flurry_instant_attack",
1682            SPELL::BLADE_FLURRY_INSTANT_ATTACK,
1683            |s| spell_blade_flurry_instant_attack(s, &params.game_data),
1684        )
1685        .spell(
1686            "blade_rush",
1687            SPELL::BLADE_RUSH,
1688            |s| spell_blade_rush(s, &params.game_data),
1689        )
1690        .spell(
1691            "killing_spree",
1692            SPELL::KILLING_SPREE,
1693            |s| spell_killing_spree(s, &params.game_data),
1694        )
1695        .spell(
1696            "keep_it_rolling",
1697            SPELL::KEEP_IT_ROLLING,
1698            |s| spell_keep_it_rolling(s, &params.game_data),
1699        )
1700        .spell(
1701            "preparation",
1702            SPELL::PREPARATION,
1703            |s| spell_preparation(s, &params.game_data),
1704        )
1705        .spell(
1706            "blade_rush_attack",
1707            SPELL::BLADE_RUSH_ATTACK,
1708            |s| spell_blade_rush_attack(s, &params.game_data),
1709        )
1710        .auto_attack(|a| {
1711            a
1712                .spell_id(6603)
1713                .swing_ms(2600)
1714                .apply_base_from_data(&params.game_data)
1715                .on_swing(crate::hooks::outlaw_rogue::swing_hook)
1716        })
1717        .game_data(params.game_data.clone())
1718        .talent_spell_ids(TALENTS)
1719        .talent_selections(params.talent_selections)
1720        .register_impact_effect_proc_if_talent(
1721            TALENT::FATAL_FLOURISH,
1722            wowlab_engine_combat::ImpactEffectProcDefinition::new(
1723                    wowlab_engine_combat::ImpactSource::AutoAttack(
1724                        wowlab_engine_combat::SwingHand::OffHand,
1725                    ),
1726                )
1727                .chance(
1728                    (params
1729                        .game_data
1730                        .base_points(wowlab_types::sim::SpellIdx::from_raw(35551), 1))
1731                        / 100.0,
1732                )
1733                .weapon_speed_scaled(2600)
1734                .gain(
1735                    params
1736                        .game_data
1737                        .base_points(wowlab_types::sim::SpellIdx::from_raw(35546), 1),
1738                ),
1739        )
1740        .register_impact_effect_proc_if_talent(
1741            TALENT::FATAL_FLOURISH,
1742            wowlab_engine_combat::ImpactEffectProcDefinition::new(
1743                    wowlab_engine_combat::ImpactSource::Spell(SPELL::MAIN_GAUCHE),
1744                )
1745                .chance(
1746                    (params
1747                        .game_data
1748                        .base_points(wowlab_types::sim::SpellIdx::from_raw(35551), 1))
1749                        / 100.0,
1750                )
1751                .gain(
1752                    params
1753                        .game_data
1754                        .base_points(wowlab_types::sim::SpellIdx::from_raw(35546), 1),
1755                ),
1756        )
1757        .register_impact_effect_proc_if_talent(
1758            TALENT::FATAL_FLOURISH,
1759            wowlab_engine_combat::ImpactEffectProcDefinition::new(
1760                    wowlab_engine_combat::ImpactSource::Spell(SPELL::PISTOL_SHOT),
1761                )
1762                .chance(
1763                    (params
1764                        .game_data
1765                        .base_points(wowlab_types::sim::SpellIdx::from_raw(35551), 1))
1766                        / 100.0,
1767                )
1768                .gain(
1769                    params
1770                        .game_data
1771                        .base_points(wowlab_types::sim::SpellIdx::from_raw(35546), 1),
1772                ),
1773        )
1774        .set_bonus_auras(params.set_bonus_auras)
1775        .encounter(params.encounter.clone());
1776    let builder = crate::generated::items::register_equipped(
1777        builder,
1778        &params.game_data,
1779        params.equipped_items,
1780    )?;
1781
1782    builder
1783        .build(params.rotation)
1784        .map_err(wowlab_engine_ports::EngineError::rotation_compile)
1785}
1786fn new_handler(
1787    params: wowlab_engine_ports::HandlerParams<'_>,
1788) -> Result<Box<dyn SpecHandler>, wowlab_engine_ports::EngineError> {
1789    let handler = crate::composition::compose_handler(
1790        build_combat_system,
1791        &params,
1792        crate::hooks::outlaw_rogue::OutlawHandler::try_new,
1793    )?;
1794
1795    Ok(Box::new(handler))
1796}
1797static DECLARED_METADATA: DeclaredSpecMetadata = DeclaredSpecMetadata {
1798    primary_resource: ResourceType::Energy,
1799    secondary_resource: Some(ResourceType::ComboPoints),
1800    spell_ids: DECLARED_SPELL_IDS,
1801    aura_ids: DECLARED_AURA_IDS,
1802    server_proc_entries: &[],
1803    talents: TALENTS,
1804    rotation_field_schema: &[],
1805    metrics_plugin_id: None,
1806    hero_talent_trees: &[
1807        HeroTalentTreeDesc {
1808            name: "Fatebound",
1809            spells: HERO_TREE_FATEBOUND_SPELLS,
1810            auras: HERO_TREE_FATEBOUND_AURAS,
1811        },
1812        HeroTalentTreeDesc {
1813            name: "Trickster",
1814            spells: HERO_TREE_TRICKSTER_SPELLS,
1815            auras: HERO_TREE_TRICKSTER_AURAS,
1816        },
1817    ],
1818    reported_spells: REPORTED_SPELLS,
1819    masked_passive_effects: &[(452_536, 5), (381_990, 2)],
1820    passive_effect_overrides: &[],
1821};
1822pub(super) const SPEC_DESCRIPTOR: SpecDescriptor = SpecDescriptor {
1823    spec_id: SpecId::Outlaw,
1824    display_name: "Outlaw Rogue",
1825    metadata: DECLARED_METADATA,
1826    handler_factory: new_handler,
1827};
1828wowlab_engine_combat::smoke_test!(build_combat_system);