1#![allow(non_snake_case, dead_code)]
4use wowlab_types::{combat::ResourceType, game::SpecId};
5use wowlab_engine_domain::dbc::ProcAttributes;
6use wowlab_engine_combat::{
7 CombatSystemBuilder, CombatSystemDraft, AuraDefinitionDraft, LocalAuraIdx,
8 LocalSpellIdx, SpellDefinitionDraft,
9};
10use wowlab_engine_ports::{
11 DeclaredSpecMetadata, SpecDescriptor, SpecHandler, HeroTalentTreeDesc,
12 DeclaredServerProcEntry,
13};
14use wowlab_engine_gamedata::ResolvedGameData;
15pub(crate) mod SPELL {
16 pub(crate) const AIMED_SHOT: u32 = 19434;
18 pub(crate) const RAPID_FIRE: u32 = 257_044;
20 pub(crate) const ARCANE_SHOT: u32 = 185_358;
22 pub(crate) const TRUESHOT: u32 = 288_613;
24 pub(crate) const KILL_SHOT: u32 = 53351;
26 pub(crate) const MULTI_SHOT: u32 = 257_620;
28 pub(crate) const STEADY_SHOT: u32 = 56641;
30 pub(crate) const VOLLEY: u32 = 260_243;
32 pub(crate) const EXPLOSIVE_SHOT: u32 = 212_431;
34 pub(crate) const RAPID_FIRE_TICK: u32 = 257_045;
36}
37pub(crate) mod AURA {
38 pub(crate) const UNNATURAL_CAUSES: u32 = 459_529;
40 pub(crate) const TRICK_SHOTS: u32 = 257_622;
42 pub(crate) const PRECISE_SHOTS: u32 = 260_242;
44 pub(crate) const TRUESHOT: u32 = 288_613;
46 pub(crate) const HEADSHOT: u32 = 1_277_558;
48 pub(crate) const SPOTTERS_MARK: u32 = 466_872;
50 pub(crate) const MASTER_MARKSMAN: u32 = 269_576;
52 pub(crate) const EXPLOSIVE_SHOT: u32 = 212_431;
54 pub(crate) const BLACK_ARROW: u32 = 466_932;
56 pub(crate) const BLACK_ARROW_DOT: u32 = 468_572;
58 pub(crate) const DEATHBLOW: u32 = 378_770;
60 pub(crate) const WITHERING_FIRE: u32 = 466_991;
62}
63pub(crate) mod TALENT {
64 pub(crate) const BLACK_ARROW: u32 = 466_932;
66 pub(crate) const BLEAK_ARROWS: u32 = 467_749;
68 pub(crate) const BLIGHTED_QUIVER: u32 = 1_264_291;
70 pub(crate) const DEATHBLOW: u32 = 343_248;
72 pub(crate) const EXPLOSIVE_SHOT: u32 = 212_431;
74 pub(crate) const FEATHERED_FRENZY: u32 = 470_943;
76 pub(crate) const FOCUSED_AIM: u32 = 378_767;
78 pub(crate) const HEADSHOT: u32 = 471_363;
80 pub(crate) const KILL_SHOT_TALENT: u32 = 53351;
82 pub(crate) const LONE_WOLF: u32 = 155_228;
84 pub(crate) const MASTER_MARKSMAN: u32 = 260_309;
86 pub(crate) const NO_SCOPE: u32 = 473_385;
88 pub(crate) const PRECISE_SHOTS: u32 = 260_240;
90 pub(crate) const SOUL_DRINKER: u32 = 469_638;
92 pub(crate) const THROUGH_THE_EYES: u32 = 1_277_565;
94 pub(crate) const UNLOAD: u32 = 1_277_548;
96 pub(crate) const UNNATURAL_CAUSES: u32 = 459_527;
98 pub(crate) const VOLLEY: u32 = 260_243;
100 pub(crate) const WINDRUNNER_QUIVER: u32 = 473_523;
102 pub(crate) const WITHERING_FIRE: u32 = 466_990;
104}
105pub(crate) mod SET_BONUS {
106 pub(crate) const MID2_MM_2PC: u32 = 1_296_633;
108 pub(crate) const MID2_MM_4PC: u32 = 1_296_634;
110}
111pub(crate) mod REPORTED_SPELL {
112 pub(crate) const BLIGHTED_ARROW: u32 = 1_264_364;
114 pub(crate) const SHOOT: u32 = 1_264_357;
116}
117pub(crate) mod HERO {
118 pub(crate) mod DARK_RANGER {
119 pub(crate) mod SPELL {
120 pub(crate) const BLACK_ARROW: u32 = 466_930;
122 pub(crate) const BLACK_ARROW_DOT_SPELL: u32 = 468_572;
124 pub(crate) const BLACK_ARROW_TALENT: u32 = 466_932;
126 pub(crate) const BLACK_ARROW_WITHERING_FIRE: u32 = 468_037;
128 pub(crate) const BLEAK_ARROWS: u32 = 467_718;
130 pub(crate) const BLEAK_ARROWS_TALENT: u32 = 467_749;
132 pub(crate) const BLEAK_POWDER: u32 = 467_914;
134 pub(crate) const BLIGHTED_QUIVER_TALENT: u32 = 1_264_291;
136 pub(crate) const CORPSECALLER_TALENT: u32 = 1_264_289;
138 pub(crate) const DARK_MINION_SUMMON: u32 = 1_264_345;
140 pub(crate) const PACT_OF_THE_HOLLOW_TALENT: u32 = 1_264_690;
142 pub(crate) const SOUL_DRINKER_TALENT: u32 = 469_638;
144 pub(crate) const THROUGH_THE_EYES_TALENT: u32 = 1_277_565;
146 pub(crate) const WAILING_ARROW: u32 = 392_060;
148 pub(crate) const WAILING_ARROW_DAMAGE: u32 = 392_058;
150 pub(crate) const WAILING_DEAD_TALENT: u32 = 1_264_290;
152 pub(crate) const WITHERING_FIRE_TALENT: u32 = 466_990;
154 }
155 pub(crate) mod AURA {
156 pub(crate) const BLACK_ARROW_DOT: u32 = 468_572;
158 pub(crate) const DEATHBLOW: u32 = 378_770;
160 pub(crate) const PHANTOM_PAIN: u32 = 467_941;
162 pub(crate) const WAILING_ARROW_BUFF: u32 = 459_808;
164 pub(crate) const WITHERING_FIRE: u32 = 466_991;
166 }
167 }
168 pub(crate) mod SENTINEL {
169 pub(crate) mod SPELL {
170 pub(crate) const LUNAR_STORM_DAMAGE: u32 = 1_253_733;
172 pub(crate) const MOONLIGHT_CHAKRAM: u32 = 1_264_949;
174 pub(crate) const MOONLIGHT_CHAKRAM_DAMAGE: u32 = 1_266_081;
176 pub(crate) const TWILIGHT_REQUIEM_DAMAGE: u32 = 1_266_096;
178 }
179 pub(crate) mod AURA {
180 pub(crate) const MOONLIGHT_CHAKRAM_BUFF: u32 = 1_264_946;
182 pub(crate) const SANCTIFIED_ARMAMENTS_DOT: u32 = 1_253_836;
184 pub(crate) const SENTINELS_MARK: u32 = 1_253_601;
186 pub(crate) const STARGAZER: u32 = 1_253_750;
188 }
189 }
190}
191static HERO_TREE_DARK_RANGER_SPELLS: &[(&str, u32)] = &[
192 ("BLACK_ARROW", 466_930),
193 ("BLACK_ARROW_DOT_SPELL", 468_572),
194 ("BLACK_ARROW_TALENT", 466_932),
195 ("BLACK_ARROW_WITHERING_FIRE", 468_037),
196 ("BLEAK_ARROWS", 467_718),
197 ("BLEAK_ARROWS_TALENT", 467_749),
198 ("BLEAK_POWDER", 467_914),
199 ("BLIGHTED_QUIVER_TALENT", 1_264_291),
200 ("CORPSECALLER_TALENT", 1_264_289),
201 ("DARK_MINION_SUMMON", 1_264_345),
202 ("PACT_OF_THE_HOLLOW_TALENT", 1_264_690),
203 ("SOUL_DRINKER_TALENT", 469_638),
204 ("THROUGH_THE_EYES_TALENT", 1_277_565),
205 ("WAILING_ARROW", 392_060),
206 ("WAILING_ARROW_DAMAGE", 392_058),
207 ("WAILING_DEAD_TALENT", 1_264_290),
208 ("WITHERING_FIRE_TALENT", 466_990),
209];
210static HERO_TREE_DARK_RANGER_AURAS: &[(&str, u32)] = &[
211 ("BLACK_ARROW_DOT", 468_572),
212 ("DEATHBLOW", 378_770),
213 ("PHANTOM_PAIN", 467_941),
214 ("WAILING_ARROW_BUFF", 459_808),
215 ("WITHERING_FIRE", 466_991),
216];
217static HERO_TREE_SENTINEL_SPELLS: &[(&str, u32)] = &[
218 ("LUNAR_STORM_DAMAGE", 1_253_733),
219 ("MOONLIGHT_CHAKRAM", 1_264_949),
220 ("MOONLIGHT_CHAKRAM_DAMAGE", 1_266_081),
221 ("TWILIGHT_REQUIEM_DAMAGE", 1_266_096),
222];
223static HERO_TREE_SENTINEL_AURAS: &[(&str, u32)] = &[
224 ("MOONLIGHT_CHAKRAM_BUFF", 1_264_946),
225 ("SANCTIFIED_ARMAMENTS_DOT", 1_253_836),
226 ("SENTINELS_MARK", 1_253_601),
227 ("STARGAZER", 1_253_750),
228];
229pub(crate) mod DAMAGE_SPELL {
230 pub(crate) const AIMED_SHOT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_19434;
231 pub(crate) const RAPID_FIRE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_257044;
232 pub(crate) const ARCANE_SHOT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_185358;
233 pub(crate) const TRUESHOT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_288613;
234 pub(crate) const KILL_SHOT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_53351;
235 pub(crate) const MULTI_SHOT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_257620;
236 pub(crate) const STEADY_SHOT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_56641;
237 pub(crate) const VOLLEY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_260243;
238 pub(crate) const EXPLOSIVE_SHOT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_212431;
239 pub(crate) const RAPID_FIRE_TICK: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_257045;
240 pub(crate) const BLACK_ARROW: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_466930;
241 pub(crate) const BLACK_ARROW_DOT_SPELL: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_468572;
242 pub(crate) const BLACK_ARROW_TALENT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_466932;
243 pub(crate) const BLACK_ARROW_WITHERING_FIRE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_468037;
244 pub(crate) const BLEAK_ARROWS: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_467718;
245 pub(crate) const BLEAK_ARROWS_TALENT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_467749;
246 pub(crate) const BLEAK_POWDER: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_467914;
247 pub(crate) const BLIGHTED_QUIVER_TALENT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_1264291;
248 pub(crate) const CORPSECALLER_TALENT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_1264289;
249 pub(crate) const DARK_MINION_SUMMON: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_1264345;
250 pub(crate) const PACT_OF_THE_HOLLOW_TALENT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_1264690;
251 pub(crate) const SOUL_DRINKER_TALENT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_469638;
252 pub(crate) const THROUGH_THE_EYES_TALENT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_1277565;
253 pub(crate) const WAILING_ARROW: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_392060;
254 pub(crate) const WAILING_ARROW_DAMAGE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_392058;
255 pub(crate) const WAILING_DEAD_TALENT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_1264290;
256 pub(crate) const WITHERING_FIRE_TALENT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_466990;
257 pub(crate) const LUNAR_STORM_DAMAGE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_1253733;
258 pub(crate) const MOONLIGHT_CHAKRAM: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_1264949;
259 pub(crate) const MOONLIGHT_CHAKRAM_DAMAGE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_1266081;
260 pub(crate) const TWILIGHT_REQUIEM_DAMAGE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_1266096;
261}
262pub(crate) mod DAMAGE_AURA {
263 pub(crate) const UNNATURAL_CAUSES: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_459529;
264 pub(crate) const TRICK_SHOTS: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_257622;
265 pub(crate) const PRECISE_SHOTS: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_260242;
266 pub(crate) const TRUESHOT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_288613;
267 pub(crate) const HEADSHOT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_1277558;
268 pub(crate) const SPOTTERS_MARK: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_466872;
269 pub(crate) const MASTER_MARKSMAN: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_269576;
270 pub(crate) const EXPLOSIVE_SHOT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_212431;
271 pub(crate) const BLACK_ARROW: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_466932;
272 pub(crate) const BLACK_ARROW_DOT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_468572;
273 pub(crate) const DEATHBLOW: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_378770;
274 pub(crate) const WITHERING_FIRE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_466991;
275}
276pub(crate) mod DAMAGE_TALENT {
277 pub(crate) const BLACK_ARROW: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_466932;
278 pub(crate) const BLEAK_ARROWS: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_467749;
279 pub(crate) const BLIGHTED_QUIVER: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_1264291;
280 pub(crate) const DEATHBLOW: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_343248;
281 pub(crate) const EXPLOSIVE_SHOT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_212431;
282 pub(crate) const FEATHERED_FRENZY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_470943;
283 pub(crate) const FOCUSED_AIM: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_378767;
284 pub(crate) const HEADSHOT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_471363;
285 pub(crate) const KILL_SHOT_TALENT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_53351;
286 pub(crate) const LONE_WOLF: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_155228;
287 pub(crate) const MASTER_MARKSMAN: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_260309;
288 pub(crate) const NO_SCOPE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_473385;
289 pub(crate) const PRECISE_SHOTS: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_260240;
290 pub(crate) const SOUL_DRINKER: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_469638;
291 pub(crate) const THROUGH_THE_EYES: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_1277565;
292 pub(crate) const UNLOAD: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_1277548;
293 pub(crate) const UNNATURAL_CAUSES: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_459527;
294 pub(crate) const VOLLEY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_260243;
295 pub(crate) const WINDRUNNER_QUIVER: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_473523;
296 pub(crate) const WITHERING_FIRE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_466990;
297}
298pub(crate) mod DAMAGE_REPORTED {
299 pub(crate) const BLIGHTED_ARROW: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_1264364;
300 pub(crate) const SHOOT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ACTION::SPELL_1264357;
301}
302pub(crate) mod DAMAGE_EFFECT {
303 pub(crate) const MASTERY_ABILITY_DAMAGE: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_193468_EFFECT_2;
304 pub(crate) const BLACK_ARROW_DAMAGE: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_466930_EFFECT_1;
305 pub(crate) const BLACK_ARROW_LOWER_PCT: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_466930_EFFECT_2;
306 pub(crate) const BLACK_ARROW_UPPER_PCT: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_466930_EFFECT_3;
307 pub(crate) const KILL_SHOT_DAMAGE: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_53351_EFFECT_1;
308 pub(crate) const KILL_SHOT_THRESHOLD: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_53351_EFFECT_2;
309 pub(crate) const BLIGHTED_QUIVER_EXTRA: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_1264291_EFFECT_7;
310 pub(crate) const WITHERING_FIRE_ARROW: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_468037_EFFECT_1;
311 pub(crate) const WITHERING_FIRE_COUNT: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_466990_EFFECT_3;
312 pub(crate) const DEATHBLOW_AIMED_PCT: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_343248_EFFECT_1;
313 pub(crate) const DEATHBLOW_RF_PCT: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_343248_EFFECT_2;
314 pub(crate) const SOUL_DRINKER_AIMED_PCT: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_469638_EFFECT_3;
315 pub(crate) const SOUL_DRINKER_RF_PCT: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_469638_EFFECT_4;
316 pub(crate) const ARCANE_SHOT_DAMAGE: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_185358_EFFECT_1;
317 pub(crate) const DARK_MINION_BLIGHTED_ARROW_DAMAGE: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_1264364_EFFECT_1;
318 pub(crate) const DARK_MINION_SHOOT_DAMAGE: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_1264357_EFFECT_1;
319 pub(crate) const FOCUSED_AIM_CDR_MS: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_378767_EFFECT_1;
320 pub(crate) const FEATHERED_FRENZY_PCT: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_470943_EFFECT_1;
321 pub(crate) const SPOTTERS_MARK_CHANCE: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_1219616_EFFECT_1;
322 pub(crate) const SPOTTERS_MARK_PCT: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_466872_EFFECT_1;
323 pub(crate) const AIMED_SHOT_DAMAGE: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_19434_EFFECT_1;
324 pub(crate) const WINDRUNNER_QUIVER_PCT: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_473523_EFFECT_3;
325 pub(crate) const MASTER_MARKSMAN_PCT: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_260309_EFFECT_1;
326 pub(crate) const EXPLOSIVE_SHOT_CLEAVE_GEOMETRY: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_212680_EFFECT_1;
327 pub(crate) const EXPLOSIVE_SHOT_CLEAVE_PCT: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_212431_EFFECT_3;
328 pub(crate) const EXPLOSIVE_SHOT_PRIMARY_DAMAGE: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_212431_EFFECT_1;
329 pub(crate) const EXPLOSIVE_SHOT_REDUCED_TARGETS: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_212431_EFFECT_2;
330 pub(crate) const MID2_MM_2PC_DAMAGE: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_1296633_EFFECT_2;
331 pub(crate) const MID2_MM_2PC_DURATION_MS: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_1296633_EFFECT_1;
332 pub(crate) const MID2_MM_4PC_CDR_MS: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_1296634_EFFECT_2;
333 pub(crate) const MID2_MM_4PC_DAMAGE: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::EFFECT::SPELL_1296634_EFFECT_1;
334}
335pub(crate) const AURA_UNNATURAL_CAUSES: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::AURA_UNNATURAL_CAUSES
336 .bind(wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF);
337pub(crate) const AURA_TRICK_SHOTS: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::AURA_TRICK_SHOTS
338 .bind(wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF);
339pub(crate) const AURA_PRECISE_SHOTS: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::AURA_PRECISE_SHOTS
340 .bind(wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF);
341pub(crate) const AURA_TRUESHOT: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::AURA_TRUESHOT
342 .bind(wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF);
343pub(crate) const AURA_HEADSHOT: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::AURA_HEADSHOT
344 .bind(wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF);
345pub(crate) const AURA_SPOTTERS_MARK: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::AURA_SPOTTERS_MARK
346 .bind(wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF);
347pub(crate) const AURA_MASTER_MARKSMAN: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::AURA_MASTER_MARKSMAN
348 .bind(wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF);
349pub(crate) const AURA_EXPLOSIVE_SHOT: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::AURA_EXPLOSIVE_SHOT
350 .bind(wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF);
351pub(crate) const AURA_BLACK_ARROW: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::AURA_BLACK_ARROW
352 .bind(wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF);
353pub(crate) const AURA_BLACK_ARROW_DOT: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::AURA_BLACK_ARROW_DOT
354 .bind(wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF);
355pub(crate) const AURA_DEATHBLOW: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::AURA_DEATHBLOW
356 .bind(wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF);
357pub(crate) const AURA_WITHERING_FIRE: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::AURA_WITHERING_FIRE
358 .bind(wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF);
359pub(crate) const AURA_COUNT: usize = 12;
360const _: () = assert!(
361 AURA_COUNT == 12, "AURA index ABI: count changed -- update positional hook consumers"
362);
363pub(crate) const SPELL_AIMED_SHOT: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::SPELL_AIMED_SHOT
364 .bind(wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF);
365pub(crate) const SPELL_RAPID_FIRE: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::SPELL_RAPID_FIRE
366 .bind(wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF);
367pub(crate) const SPELL_ARCANE_SHOT: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::SPELL_ARCANE_SHOT
368 .bind(wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF);
369pub(crate) const SPELL_TRUESHOT: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::SPELL_TRUESHOT
370 .bind(wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF);
371pub(crate) const SPELL_KILL_SHOT: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::SPELL_KILL_SHOT
372 .bind(wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF);
373pub(crate) const SPELL_MULTI_SHOT: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::SPELL_MULTI_SHOT
374 .bind(wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF);
375pub(crate) const SPELL_STEADY_SHOT: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::SPELL_STEADY_SHOT
376 .bind(wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF);
377pub(crate) const SPELL_VOLLEY: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::SPELL_VOLLEY
378 .bind(wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF);
379pub(crate) const SPELL_EXPLOSIVE_SHOT: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::SPELL_EXPLOSIVE_SHOT
380 .bind(wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF);
381pub(crate) const SPELL_RAPID_FIRE_TICK: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::SPELL_RAPID_FIRE_TICK
382 .bind(wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF);
383pub(crate) const SPELL_COUNT: usize = 10;
384const _: () = assert!(
385 SPELL_COUNT == 10,
386 "SPELL index ABI: count changed -- update positional hook consumers"
387);
388pub(crate) mod EFFECT {
389 pub(crate) const MASTERY_ABILITY_DAMAGE: (u32, u8) = (193_468, 2);
391 pub(crate) const BLACK_ARROW_DAMAGE: (u32, u8) = (466_930, 1);
393 pub(crate) const BLACK_ARROW_LOWER_PCT: (u32, u8) = (466_930, 2);
395 pub(crate) const BLACK_ARROW_UPPER_PCT: (u32, u8) = (466_930, 3);
397 pub(crate) const KILL_SHOT_DAMAGE: (u32, u8) = (53351, 1);
399 pub(crate) const KILL_SHOT_THRESHOLD: (u32, u8) = (53351, 2);
401 pub(crate) const BLIGHTED_QUIVER_EXTRA: (u32, u8) = (1_264_291, 7);
403 pub(crate) const WITHERING_FIRE_ARROW: (u32, u8) = (468_037, 1);
405 pub(crate) const WITHERING_FIRE_COUNT: (u32, u8) = (466_990, 3);
407 pub(crate) const DEATHBLOW_AIMED_PCT: (u32, u8) = (343_248, 1);
409 pub(crate) const DEATHBLOW_RF_PCT: (u32, u8) = (343_248, 2);
411 pub(crate) const SOUL_DRINKER_AIMED_PCT: (u32, u8) = (469_638, 3);
413 pub(crate) const SOUL_DRINKER_RF_PCT: (u32, u8) = (469_638, 4);
415 pub(crate) const ARCANE_SHOT_DAMAGE: (u32, u8) = (185_358, 1);
417 pub(crate) const DARK_MINION_BLIGHTED_ARROW_DAMAGE: (u32, u8) = (1_264_364, 1);
419 pub(crate) const DARK_MINION_SHOOT_DAMAGE: (u32, u8) = (1_264_357, 1);
421 pub(crate) const FOCUSED_AIM_CDR_MS: (u32, u8) = (378_767, 1);
423 pub(crate) const FEATHERED_FRENZY_PCT: (u32, u8) = (470_943, 1);
425 pub(crate) const SPOTTERS_MARK_CHANCE: (u32, u8) = (1_219_616, 1);
427 pub(crate) const SPOTTERS_MARK_PCT: (u32, u8) = (466_872, 1);
429 pub(crate) const AIMED_SHOT_DAMAGE: (u32, u8) = (19434, 1);
431 pub(crate) const WINDRUNNER_QUIVER_PCT: (u32, u8) = (473_523, 3);
433 pub(crate) const MASTER_MARKSMAN_PCT: (u32, u8) = (260_309, 1);
435 pub(crate) const EXPLOSIVE_SHOT_CLEAVE_GEOMETRY: (u32, u8) = (212_680, 1);
437 pub(crate) const EXPLOSIVE_SHOT_CLEAVE_PCT: (u32, u8) = (212_431, 3);
439 pub(crate) const EXPLOSIVE_SHOT_PRIMARY_DAMAGE: (u32, u8) = (212_431, 1);
441 pub(crate) const EXPLOSIVE_SHOT_REDUCED_TARGETS: (u32, u8) = (212_431, 2);
443 pub(crate) const MID2_MM_2PC_DAMAGE: (u32, u8) = (1_296_633, 2);
445 pub(crate) const MID2_MM_2PC_DURATION_MS: (u32, u8) = (1_296_633, 1);
447 pub(crate) const MID2_MM_4PC_CDR_MS: (u32, u8) = (1_296_634, 2);
449 pub(crate) const MID2_MM_4PC_DAMAGE: (u32, u8) = (1_296_634, 1);
451}
452static REPORTED_SPELLS: &[(&str, u32)] = &[
453 ("blighted_arrow", 1_264_364),
454 ("shoot", 1_264_357),
455];
456static DECLARED_SPELL_IDS: &[u32] = &[
457 19434, 257_044, 185_358, 288_613, 53351, 257_620, 56641, 260_243, 212_431, 257_045,
458 459_529, 257_622, 260_242, 1_277_558, 466_872, 269_576, 466_932, 468_572, 378_770,
459 466_991, 467_749, 1_264_291, 343_248, 470_943, 378_767, 471_363, 155_228, 260_309,
460 473_385, 260_240, 469_638, 1_277_565, 1_277_548, 459_527, 473_523, 466_990, 75,
461 77443, 193_468, 212_680, 263_585, 466_930, 468_037, 1_219_616, 1_264_357, 1_264_364,
462 1_296_633, 1_296_634, 467_718, 467_914, 1_264_289, 1_264_345, 1_264_690, 392_060,
463 392_058, 1_264_290, 467_941, 459_808, 1_253_733, 1_264_949, 1_266_081, 1_266_096,
464 1_264_946, 1_253_836, 1_253_601, 1_253_750,
465];
466static DECLARED_AURA_IDS: &[u32] = &[
467 459_529, 257_622, 260_242, 288_613, 1_277_558, 466_872, 269_576, 212_431, 466_932,
468 468_572, 378_770, 466_991, 468_572, 378_770, 467_941, 459_808, 466_991, 1_264_946,
469 1_253_836, 1_253_601, 1_253_750,
470];
471static TALENTS: &[(&str, u32)] = &[
472 ("BLACK_ARROW", TALENT::BLACK_ARROW),
473 ("BLEAK_ARROWS", TALENT::BLEAK_ARROWS),
474 ("BLIGHTED_QUIVER", TALENT::BLIGHTED_QUIVER),
475 ("DEATHBLOW", TALENT::DEATHBLOW),
476 ("EXPLOSIVE_SHOT", TALENT::EXPLOSIVE_SHOT),
477 ("FEATHERED_FRENZY", TALENT::FEATHERED_FRENZY),
478 ("FOCUSED_AIM", TALENT::FOCUSED_AIM),
479 ("HEADSHOT", TALENT::HEADSHOT),
480 ("KILL_SHOT_TALENT", TALENT::KILL_SHOT_TALENT),
481 ("LONE_WOLF", TALENT::LONE_WOLF),
482 ("MASTER_MARKSMAN", TALENT::MASTER_MARKSMAN),
483 ("NO_SCOPE", TALENT::NO_SCOPE),
484 ("PRECISE_SHOTS", TALENT::PRECISE_SHOTS),
485 ("SOUL_DRINKER", TALENT::SOUL_DRINKER),
486 ("THROUGH_THE_EYES", TALENT::THROUGH_THE_EYES),
487 ("UNLOAD", TALENT::UNLOAD),
488 ("UNNATURAL_CAUSES", TALENT::UNNATURAL_CAUSES),
489 ("VOLLEY", TALENT::VOLLEY),
490 ("WINDRUNNER_QUIVER", TALENT::WINDRUNNER_QUIVER),
491 ("WITHERING_FIRE", TALENT::WITHERING_FIRE),
492];
493fn aura_unnatural_causes(
494 a: AuraDefinitionDraft,
495 data: &ResolvedGameData,
496) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
497 Ok(
498 a
499 .on_target()
500 .apply_base_from_data(data, 459_529)?
501 .max_stacks(
502 data
503 .require_aura_max_stacks(
504 wowlab_types::sim::SpellIdx::from_raw(459_529),
505 )?,
506 ),
507 )
508}
509fn aura_trick_shots(
510 a: AuraDefinitionDraft,
511 data: &ResolvedGameData,
512) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
513 Ok(
514 a
515 .on_player()
516 .apply_base_from_data(data, 257_622)?
517 .max_stacks(
518 data
519 .require_aura_max_stacks(
520 wowlab_types::sim::SpellIdx::from_raw(257_622),
521 )?,
522 ),
523 )
524}
525fn aura_precise_shots(
526 a: AuraDefinitionDraft,
527 data: &ResolvedGameData,
528) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
529 Ok(
530 a
531 .on_player()
532 .apply_base_from_data(data, 260_242)?
533 .max_stacks(
534 data
535 .require_aura_max_stacks(
536 wowlab_types::sim::SpellIdx::from_raw(260_242),
537 )?,
538 ),
539 )
540}
541fn aura_trueshot(
542 a: AuraDefinitionDraft,
543 data: &ResolvedGameData,
544) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
545 Ok(
546 a
547 .on_player()
548 .apply_base_from_data(data, 288_613)?
549 .max_stacks(
550 data
551 .require_aura_max_stacks(
552 wowlab_types::sim::SpellIdx::from_raw(288_613),
553 )?,
554 ),
555 )
556}
557fn aura_headshot(
558 a: AuraDefinitionDraft,
559 data: &ResolvedGameData,
560) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
561 Ok(
562 a
563 .on_target()
564 .apply_base_from_data(data, 1_277_558)?
565 .max_stacks(
566 data
567 .require_aura_max_stacks(
568 wowlab_types::sim::SpellIdx::from_raw(1_277_558),
569 )?,
570 ),
571 )
572}
573fn aura_spotters_mark(
574 a: AuraDefinitionDraft,
575 data: &ResolvedGameData,
576) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
577 Ok(
578 a
579 .on_target()
580 .apply_base_from_data(data, 466_872)?
581 .max_stacks(
582 data
583 .require_aura_max_stacks(
584 wowlab_types::sim::SpellIdx::from_raw(466_872),
585 )?,
586 ),
587 )
588}
589fn aura_master_marksman(
590 a: AuraDefinitionDraft,
591 data: &ResolvedGameData,
592) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
593 a.on_target()
594 .apply_base_from_data(data, 269_576)?
595 .max_stacks(
596 data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(269_576))?,
597 )
598 .no_pandemic()
599 .periodic_residual_damage(
600 wowlab_engine_combat::validated_milliseconds(
601 data.period(wowlab_types::sim::SpellIdx::from_raw(269_576), 1),
602 269_576,
603 "periodic_residual_damage.tick_ms",
604 )?,
605 )
606 .apply_periodic_behavior_from_data(data, 269_576)
607}
608fn aura_explosive_shot(
609 a: AuraDefinitionDraft,
610 data: &ResolvedGameData,
611) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
612 Ok(
613 a
614 .on_target()
615 .apply_base_from_data(data, 212_431)?
616 .max_stacks(
617 data
618 .require_aura_max_stacks(
619 wowlab_types::sim::SpellIdx::from_raw(212_431),
620 )?,
621 )
622 .periodic_damage_ap_from_data(
623 data,
624 wowlab_engine_combat::PeriodicDamageDataInput {
625 tick_ms: wowlab_engine_combat::validated_milliseconds(
626 data.period(wowlab_types::sim::SpellIdx::from_raw(212_431), 1),
627 212_431,
628 "periodic_damage.tick_ms",
629 )?,
630 spell_id: 212_431,
631 effect_index: 1,
632 multiplier: 1.0,
633 offset: 0.0,
634 round_decimals: None,
635 },
636 wowlab_engine_combat::PeriodicDamageMode::Standard,
637 )?
638 .apply_periodic_behavior_from_data(data, 212_431)?
639 .tick_hook(crate::hooks::marksmanship_hunter::explosive_shot_tick_hook),
640 )
641}
642fn aura_black_arrow(
643 a: AuraDefinitionDraft,
644 data: &ResolvedGameData,
645) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
646 Ok(
647 a
648 .on_player()
649 .apply_base_from_data(data, 466_932)?
650 .max_stacks(
651 data
652 .require_aura_max_stacks(
653 wowlab_types::sim::SpellIdx::from_raw(466_932),
654 )?,
655 ),
656 )
657}
658fn aura_black_arrow_dot(
659 a: AuraDefinitionDraft,
660 data: &ResolvedGameData,
661) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
662 Ok(
663 a
664 .on_target()
665 .apply_base_from_data(data, 468_572)?
666 .max_stacks(
667 data
668 .require_aura_max_stacks(
669 wowlab_types::sim::SpellIdx::from_raw(468_572),
670 )?,
671 )
672 .unhasted_periodic(),
673 )
674}
675fn aura_deathblow(
676 a: AuraDefinitionDraft,
677 data: &ResolvedGameData,
678) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
679 Ok(
680 a
681 .on_player()
682 .apply_base_from_data(data, 378_770)?
683 .max_stacks(
684 data
685 .require_aura_max_stacks(
686 wowlab_types::sim::SpellIdx::from_raw(378_770),
687 )?,
688 ),
689 )
690}
691fn aura_withering_fire(
692 a: AuraDefinitionDraft,
693 data: &ResolvedGameData,
694) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
695 a.on_player()
696 .duration_ms(
697 wowlab_engine_combat::validated_milliseconds(
698 f64::from(
699 data
700 .require_aura_duration_ms(
701 wowlab_types::sim::SpellIdx::from_raw(288_613),
702 )?,
703 ),
704 466_991,
705 "aura.duration_ms",
706 )?,
707 )
708 .apply_periodic_effect_from_data(data, 466_991)?
709 .apply_duration_behavior_from_data(data, 288_613)?
710 .apply_timing_modifiers_from_data(data, 466_991)?
711 .max_stacks(
712 data.require_aura_max_stacks(wowlab_types::sim::SpellIdx::from_raw(466_991))?,
713 )
714 .apply_periodic_behavior_from_data(data, 288_613)
715}
716fn spell_aimed_shot(
717 s: SpellDefinitionDraft,
718 data: &ResolvedGameData,
719) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
720 Ok(
721 s
722 .apply_base_from_data(data, 19434)?
723 .damage_flat(0.0)
724 .apply_aoe_from_data(data)
725 .on_cast(crate::hooks::marksmanship_hunter::aimed_shot_hook),
726 )
727}
728fn spell_rapid_fire(
729 s: SpellDefinitionDraft,
730 data: &ResolvedGameData,
731) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
732 Ok(
733 s
734 .apply_base_from_data(data, 257_044)?
735 .apply_aoe_from_data(data)
736 .channel(
737 wowlab_engine_combat::validated_channel_tick_count(
738 data.base_points(wowlab_types::sim::SpellIdx::from_raw(257_044), 1),
739 257_044,
740 "channel.tick_count",
741 )?,
742 )
743 .channel_tick_direct_damage()
744 .channel_tick_timing(
745 wowlab_engine_combat::validated_milliseconds(
746 data.period(wowlab_types::sim::SpellIdx::from_raw(257_044), 2),
747 257_044,
748 "channel.tick_interval_ms",
749 )?,
750 true,
751 )
752 .channel_tick_damage_ap_from_data(
753 wowlab_engine_domain::dbc::EffectLookup::new(
754 data,
755 wowlab_types::sim::EffectRef::new(
756 wowlab_types::sim::SpellIdx::from_raw(257_045),
757 1,
758 ),
759 ),
760 )?
761 .channel_tick_gain(
762 data.base_points(wowlab_types::sim::SpellIdx::from_raw(263_585), 1),
763 )
764 .on_channel_tick(crate::hooks::marksmanship_hunter::rapid_fire_tick_hook)
765 .on_cast(crate::hooks::marksmanship_hunter::rapid_fire_hook),
766 )
767}
768fn spell_arcane_shot(
769 s: SpellDefinitionDraft,
770 data: &ResolvedGameData,
771) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
772 Ok(
773 s
774 .apply_base_from_data(data, 185_358)?
775 .damage_flat(0.0)
776 .apply_aoe_from_data(data)
777 .on_cast(crate::hooks::marksmanship_hunter::arcane_shot_hook),
778 )
779}
780fn spell_trueshot(
781 s: SpellDefinitionDraft,
782 data: &ResolvedGameData,
783) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
784 Ok(
785 s
786 .apply_base_from_data(data, 288_613)?
787 .applies_inferred_aura(AURA_TRUESHOT, 288_613)
788 .apply_aoe_from_data(data)
789 .on_cast(crate::hooks::marksmanship_hunter::trueshot_hook),
790 )
791}
792fn spell_kill_shot(
793 s: SpellDefinitionDraft,
794 data: &ResolvedGameData,
795) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
796 Ok(
797 s
798 .apply_base_from_data(data, 53351)?
799 .damage_flat(0.0)
800 .apply_aoe_from_data(data)
801 .on_cast(crate::hooks::marksmanship_hunter::kill_shot_hook)
802 .cost_free_when_aura(378_770),
803 )
804}
805fn spell_multi_shot(
806 s: SpellDefinitionDraft,
807 data: &ResolvedGameData,
808) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
809 Ok(s.apply_base_from_data(data, 257_620)?.apply_aoe_from_data(data))
810}
811fn spell_steady_shot(
812 s: SpellDefinitionDraft,
813 data: &ResolvedGameData,
814) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
815 Ok(
816 s
817 .apply_base_from_data(data, 56641)?
818 .gain(data.base_points(wowlab_types::sim::SpellIdx::from_raw(77443), 1))
819 .reduces_cd(
820 SPELL_AIMED_SHOT,
821 wowlab_engine_combat::validated_milliseconds(
822 data.base_points(wowlab_types::sim::SpellIdx::from_raw(56641), 2),
823 56641,
824 "spell.reduces_cd.amount_ms",
825 )?,
826 )
827 .apply_aoe_from_data(data),
828 )
829}
830fn spell_volley(
831 s: SpellDefinitionDraft,
832 data: &ResolvedGameData,
833) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
834 Ok(s.apply_base_from_data(data, 260_243)?.apply_aoe_from_data(data))
835}
836fn spell_explosive_shot(
837 s: SpellDefinitionDraft,
838 data: &ResolvedGameData,
839) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
840 Ok(
841 s
842 .apply_base_from_data(data, 212_431)?
843 .damage_flat(0.0)
844 .applies_aura(AURA_EXPLOSIVE_SHOT)
845 .apply_aoe_from_data(data),
846 )
847}
848fn spell_rapid_fire_tick(
849 s: SpellDefinitionDraft,
850 data: &ResolvedGameData,
851) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
852 Ok(s.apply_base_from_data(data, 257_045)?.damage_flat(0.0).apply_aoe_from_data(data))
853}
854pub(crate) fn build_combat_system_draft(
855 params: &wowlab_engine_ports::HandlerParams<'_>,
856) -> Result<CombatSystemDraft, wowlab_engine_ports::EngineError> {
857 let builder = CombatSystemBuilder::new(params.stats.clone())
858 .spec_id(SpecId::Marksmanship)
859 .spec_identity(
860 wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::PROOF,
861 )
862 .hero_talent_trees(DECLARED_METADATA.hero_talent_trees)
863 .effect_identities(
864 wowlab_engine_combat::generated_identities::specs::marksmanship_hunter::damage::ALL,
865 )
866 .effect_identities(wowlab_engine_combat::generated_identities::shared::ALL)
867 .mastery_spell(193_468)
868 .mastery_hook(crate::hooks::marksmanship_hunter::mastery)
869 .resource(
870 "focus",
871 params
872 .game_data
873 .power_max(2)
874 .ok_or_else(|| {
875 wowlab_engine_ports::EngineError::spec_construction(
876 "missing power-type power_max for type_id 2",
877 )
878 })?,
879 params
880 .game_data
881 .power_regen_for_max(
882 2,
883 params
884 .game_data
885 .power_max(2)
886 .ok_or_else(|| {
887 wowlab_engine_ports::EngineError::spec_construction(
888 "missing power-type power_max for type_id 2",
889 )
890 })?,
891 )
892 .ok_or_else(|| {
893 wowlab_engine_ports::EngineError::spec_construction(
894 "missing power-type power_regen_for_max for type_id 2",
895 )
896 })?,
897 )
898 .resource_type_id(2)
899 .resource_start(
900 params
901 .game_data
902 .power_default(2)
903 .ok_or_else(|| {
904 wowlab_engine_ports::EngineError::spec_construction(
905 "missing power-type power_default for type_id 2",
906 )
907 })?,
908 )
909 .aura(
910 "unnatural_causes",
911 AURA::UNNATURAL_CAUSES,
912 |a| aura_unnatural_causes(a, ¶ms.game_data),
913 )
914 .aura(
915 "trick_shots",
916 AURA::TRICK_SHOTS,
917 |a| aura_trick_shots(a, ¶ms.game_data),
918 )
919 .aura(
920 "precise_shots",
921 AURA::PRECISE_SHOTS,
922 |a| aura_precise_shots(a, ¶ms.game_data),
923 )
924 .aura("trueshot", AURA::TRUESHOT, |a| aura_trueshot(a, ¶ms.game_data))
925 .aura("headshot", AURA::HEADSHOT, |a| aura_headshot(a, ¶ms.game_data))
926 .aura(
927 "spotters_mark",
928 AURA::SPOTTERS_MARK,
929 |a| aura_spotters_mark(a, ¶ms.game_data),
930 )
931 .aura(
932 "master_marksman",
933 AURA::MASTER_MARKSMAN,
934 |a| aura_master_marksman(a, ¶ms.game_data),
935 )
936 .aura(
937 "explosive_shot",
938 AURA::EXPLOSIVE_SHOT,
939 |a| aura_explosive_shot(a, ¶ms.game_data),
940 )
941 .aura(
942 "black_arrow",
943 AURA::BLACK_ARROW,
944 |a| aura_black_arrow(a, ¶ms.game_data),
945 )
946 .aura(
947 "black_arrow_dot",
948 AURA::BLACK_ARROW_DOT,
949 |a| aura_black_arrow_dot(a, ¶ms.game_data),
950 )
951 .aura("deathblow", AURA::DEATHBLOW, |a| aura_deathblow(a, ¶ms.game_data))
952 .aura(
953 "withering_fire",
954 AURA::WITHERING_FIRE,
955 |a| aura_withering_fire(a, ¶ms.game_data),
956 )
957 .spell(
958 "aimed_shot",
959 SPELL::AIMED_SHOT,
960 |s| spell_aimed_shot(s, ¶ms.game_data),
961 )
962 .spell(
963 "rapid_fire",
964 SPELL::RAPID_FIRE,
965 |s| spell_rapid_fire(s, ¶ms.game_data),
966 )
967 .spell(
968 "arcane_shot",
969 SPELL::ARCANE_SHOT,
970 |s| spell_arcane_shot(s, ¶ms.game_data),
971 )
972 .spell("trueshot", SPELL::TRUESHOT, |s| spell_trueshot(s, ¶ms.game_data))
973 .spell("kill_shot", SPELL::KILL_SHOT, |s| spell_kill_shot(s, ¶ms.game_data))
974 .spell(
975 "multi_shot",
976 SPELL::MULTI_SHOT,
977 |s| spell_multi_shot(s, ¶ms.game_data),
978 )
979 .spell(
980 "steady_shot",
981 SPELL::STEADY_SHOT,
982 |s| spell_steady_shot(s, ¶ms.game_data),
983 )
984 .spell("volley", SPELL::VOLLEY, |s| spell_volley(s, ¶ms.game_data))
985 .spell(
986 "explosive_shot",
987 SPELL::EXPLOSIVE_SHOT,
988 |s| spell_explosive_shot(s, ¶ms.game_data),
989 )
990 .spell(
991 "rapid_fire_tick",
992 SPELL::RAPID_FIRE_TICK,
993 |s| spell_rapid_fire_tick(s, ¶ms.game_data),
994 )
995 .auto_attack(|a| {
996 a.spell_id(75).swing_ms(3000).apply_base_from_data(¶ms.game_data)
997 })
998 .game_data(params.game_data.clone())
999 .talent_spell_ids(TALENTS)
1000 .talent_selections(params.talent_selections)
1001 .talent_companion_aura(TALENT::BLACK_ARROW, AURA_BLACK_ARROW)
1002 .talent_companion_aura(TALENT::UNNATURAL_CAUSES, AURA_UNNATURAL_CAUSES)
1003 .set_bonus_auras(params.set_bonus_auras)
1004 .encounter(params.encounter.clone());
1005 let builder = crate::generated::items::register_equipped(
1006 builder,
1007 ¶ms.game_data,
1008 params.equipped_items,
1009 )?;
1010
1011 builder.into_draft()
1012}
1013fn new_handler(
1014 params: wowlab_engine_ports::HandlerParams<'_>,
1015) -> Result<Box<dyn SpecHandler>, wowlab_engine_ports::EngineError> {
1016 let handler = crate::composition::compose_handler(
1017 build_combat_system_draft,
1018 ¶ms,
1019 crate::hooks::marksmanship_hunter::MarksmanshipHandler::try_new,
1020 )?;
1021
1022 Ok(Box::new(handler))
1023}
1024static DECLARED_METADATA: DeclaredSpecMetadata = DeclaredSpecMetadata {
1025 primary_resource: ResourceType::Focus,
1026 secondary_resource: None,
1027 spell_ids: DECLARED_SPELL_IDS,
1028 aura_ids: DECLARED_AURA_IDS,
1029 server_proc_entries: &[
1030 DeclaredServerProcEntry {
1031 spell_id: 260_242,
1032 attributes: ProcAttributes::REQUIRE_SPELL_MODIFIER.bits()
1033 | ProcAttributes::USE_STACKS_FOR_CHARGES.bits(),
1034 },
1035 ],
1036 talents: TALENTS,
1037 rotation_field_schema: &[],
1038 metrics_plugin_id: None,
1039 hero_talent_trees: &[
1040 HeroTalentTreeDesc {
1041 name: "Dark Ranger",
1042 spells: HERO_TREE_DARK_RANGER_SPELLS,
1043 auras: HERO_TREE_DARK_RANGER_AURAS,
1044 },
1045 HeroTalentTreeDesc {
1046 name: "Sentinel",
1047 spells: HERO_TREE_SENTINEL_SPELLS,
1048 auras: HERO_TREE_SENTINEL_AURAS,
1049 },
1050 ],
1051 reported_spells: REPORTED_SPELLS,
1052 masked_passive_effects: &[],
1053 passive_effect_overrides: &[],
1054};
1055pub(super) const SPEC_DESCRIPTOR: SpecDescriptor = SpecDescriptor {
1056 spec_id: SpecId::Marksmanship,
1057 display_name: "Marksmanship Hunter",
1058 metadata: DECLARED_METADATA,
1059 handler_factory: new_handler,
1060};
1061wowlab_engine_combat::smoke_test!(build_combat_system_draft);