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 CONSUME: u32 = 473_662;
18 pub(crate) const DEVOUR: u32 = 1_217_610;
20 pub(crate) const VOIDBLADE: u32 = 1_245_412;
22 pub(crate) const VOID_RAY: u32 = 473_728;
24 pub(crate) const VOID_RAY_TICK: u32 = 1_213_649;
26 pub(crate) const VOID_RAY_TICK_META: u32 = 1_214_595;
28 pub(crate) const REAP: u32 = 1_226_019;
30 pub(crate) const VOID_METAMORPHOSIS: u32 = 1_217_607;
32 pub(crate) const IMMOLATION_AURA: u32 = 258_920;
34 pub(crate) const THE_HUNT: u32 = 370_965;
36 pub(crate) const CULL: u32 = 1_245_453;
38 pub(crate) const ERADICATE: u32 = 1_225_826;
40 pub(crate) const COLLAPSING_STAR_SPELL: u32 = 1_221_150;
42 pub(crate) const SOUL_IMMOLATION_SPELL: u32 = 1_241_937;
44 pub(crate) const HUNGERING_SLASH: u32 = 1_239_123;
46 pub(crate) const PREDATORS_WAKE: u32 = 1_246_160;
48 pub(crate) const PIERCE_THE_VEIL: u32 = 1_246_158;
50 pub(crate) const STUN: u32 = 179_057;
52}
53pub(crate) mod AURA {
54 pub(crate) const VOID_METAMORPHOSIS: u32 = 1_217_607;
56 pub(crate) const VOID_METAMORPHOSIS_STACK: u32 = 1_225_789;
58 pub(crate) const COLLAPSING_STAR: u32 = 1_221_171;
60 pub(crate) const MOMENT_OF_CRAVING: u32 = 1_238_495;
62 pub(crate) const SOULBURST: u32 = 1_297_433;
64 pub(crate) const SOUL_IMMOLATION: u32 = 1_241_937;
66 pub(crate) const SPONTANEOUS_IMMOLATION: u32 = 1_246_556;
68 pub(crate) const ENTROPY_TICKER: u32 = 1_261_684;
70 pub(crate) const SOUL_FRAGMENTS: u32 = 1_245_577;
72 pub(crate) const FEAST_OF_SOULS: u32 = 1_232_310;
74 pub(crate) const FOCUSED_RAY: u32 = 1_240_203;
76 pub(crate) const VOID_RAY: u32 = 473_728;
78 pub(crate) const VOIDFALL_BUILDING: u32 = 1_256_301;
80 pub(crate) const VOIDFALL_SPENDING: u32 = 1_256_302;
82 pub(crate) const VOIDFALL_FINAL_HOUR: u32 = 1_256_322;
84 pub(crate) const CATASTROPHE: u32 = 1_256_676;
86}
87pub(crate) mod TALENT {
88 pub(crate) const COLLAPSING_STAR: u32 = 1_221_150;
90 pub(crate) const FEAST_OF_SOULS: u32 = 1_237_270;
92 pub(crate) const SOULSHAPER: u32 = 1_238_739;
94 pub(crate) const THE_HUNT: u32 = 370_965;
96 pub(crate) const VOID_RAY: u32 = 473_728;
98}
99pub(crate) mod SET_BONUS {
100 pub(crate) const MID2_DEVOURER_2PC: u32 = 1_296_615;
102 pub(crate) const MID2_DEVOURER_4PC: u32 = 1_296_616;
104}
105pub(crate) mod REPORTED_SPELL {
106 pub(crate) const REAP_DAMAGE: u32 = 1_225_823;
108 pub(crate) const SOULBURST: u32 = 1_297_432;
110 pub(crate) const VOIDBLADE_DAMAGE: u32 = 1_245_414;
112}
113pub(crate) mod HERO {
114 pub(crate) mod ANNIHILATOR {
115 pub(crate) mod SPELL {
116 pub(crate) const CATASTROPHE: u32 = 1_253_769;
118 pub(crate) const HARNESS_THE_COSMOS: u32 = 1_279_247;
120 pub(crate) const MASS_ACCELERATION: u32 = 1_256_295;
122 pub(crate) const METEORIC_FALL: u32 = 1_253_391;
124 pub(crate) const METEORIC_RISE: u32 = 1_253_377;
126 pub(crate) const OTHERWORLDLY_FOCUS: u32 = 1_253_817;
128 pub(crate) const VOIDFALL: u32 = 1_253_304;
130 pub(crate) const VOIDFALL_METEOR_DAMAGE: u32 = 1_256_305;
132 pub(crate) const WORLD_KILLER: u32 = 1_256_353;
134 pub(crate) const WORLD_KILLER_DAMAGE: u32 = 1_256_619;
136 }
137 pub(crate) mod AURA {
138 pub(crate) const VOIDFALL_BUILDING: u32 = 1_256_301;
140 pub(crate) const VOIDFALL_FINAL_HOUR: u32 = 1_256_322;
142 pub(crate) const VOIDFALL_SPENDING: u32 = 1_256_302;
144 }
145 }
146}
147static HERO_TREE_ANNIHILATOR_SPELLS: &[(&str, u32)] = &[
148 ("CATASTROPHE", 1_253_769),
149 ("HARNESS_THE_COSMOS", 1_279_247),
150 ("MASS_ACCELERATION", 1_256_295),
151 ("METEORIC_FALL", 1_253_391),
152 ("METEORIC_RISE", 1_253_377),
153 ("OTHERWORLDLY_FOCUS", 1_253_817),
154 ("VOIDFALL", 1_253_304),
155 ("VOIDFALL_METEOR_DAMAGE", 1_256_305),
156 ("WORLD_KILLER", 1_256_353),
157 ("WORLD_KILLER_DAMAGE", 1_256_619),
158];
159static HERO_TREE_ANNIHILATOR_AURAS: &[(&str, u32)] = &[
160 ("VOIDFALL_BUILDING", 1_256_301),
161 ("VOIDFALL_FINAL_HOUR", 1_256_322),
162 ("VOIDFALL_SPENDING", 1_256_302),
163];
164pub(crate) mod DAMAGE_SPELL {
165 pub(crate) const CONSUME: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_473662;
166 pub(crate) const DEVOUR: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1217610;
167 pub(crate) const VOIDBLADE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1245412;
168 pub(crate) const VOID_RAY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_473728;
169 pub(crate) const VOID_RAY_TICK: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1213649;
170 pub(crate) const VOID_RAY_TICK_META: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1214595;
171 pub(crate) const REAP: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1226019;
172 pub(crate) const VOID_METAMORPHOSIS: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1217607;
173 pub(crate) const IMMOLATION_AURA: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_258920;
174 pub(crate) const THE_HUNT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_370965;
175 pub(crate) const CULL: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1245453;
176 pub(crate) const ERADICATE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1225826;
177 pub(crate) const COLLAPSING_STAR_SPELL: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1221150;
178 pub(crate) const SOUL_IMMOLATION_SPELL: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1241937;
179 pub(crate) const HUNGERING_SLASH: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1239123;
180 pub(crate) const PREDATORS_WAKE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1246160;
181 pub(crate) const PIERCE_THE_VEIL: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1246158;
182 pub(crate) const STUN: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_179057;
183 pub(crate) const CATASTROPHE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1253769;
184 pub(crate) const HARNESS_THE_COSMOS: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1279247;
185 pub(crate) const MASS_ACCELERATION: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1256295;
186 pub(crate) const METEORIC_FALL: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1253391;
187 pub(crate) const METEORIC_RISE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1253377;
188 pub(crate) const OTHERWORLDLY_FOCUS: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1253817;
189 pub(crate) const VOIDFALL: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1253304;
190 pub(crate) const VOIDFALL_METEOR_DAMAGE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1256305;
191 pub(crate) const WORLD_KILLER: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1256353;
192 pub(crate) const WORLD_KILLER_DAMAGE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1256619;
193}
194pub(crate) mod DAMAGE_AURA {
195 pub(crate) const VOID_METAMORPHOSIS: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1217607;
196 pub(crate) const VOID_METAMORPHOSIS_STACK: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1225789;
197 pub(crate) const COLLAPSING_STAR: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1221171;
198 pub(crate) const MOMENT_OF_CRAVING: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1238495;
199 pub(crate) const SOULBURST: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1297433;
200 pub(crate) const SOUL_IMMOLATION: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1241937;
201 pub(crate) const SPONTANEOUS_IMMOLATION: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1246556;
202 pub(crate) const ENTROPY_TICKER: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1261684;
203 pub(crate) const SOUL_FRAGMENTS: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1245577;
204 pub(crate) const FEAST_OF_SOULS: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1232310;
205 pub(crate) const FOCUSED_RAY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1240203;
206 pub(crate) const VOID_RAY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_473728;
207 pub(crate) const VOIDFALL_BUILDING: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1256301;
208 pub(crate) const VOIDFALL_SPENDING: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1256302;
209 pub(crate) const VOIDFALL_FINAL_HOUR: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1256322;
210 pub(crate) const CATASTROPHE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1256676;
211}
212pub(crate) mod DAMAGE_TALENT {
213 pub(crate) const COLLAPSING_STAR: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1221150;
214 pub(crate) const FEAST_OF_SOULS: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1237270;
215 pub(crate) const SOULSHAPER: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1238739;
216 pub(crate) const THE_HUNT: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_370965;
217 pub(crate) const VOID_RAY: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_473728;
218}
219pub(crate) mod DAMAGE_REPORTED {
220 pub(crate) const REAP_DAMAGE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1225823;
221 pub(crate) const SOULBURST: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1297432;
222 pub(crate) const VOIDBLADE_DAMAGE: wowlab_engine_combat::DamageActionId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ACTION::SPELL_1245414;
223}
224pub(crate) mod DAMAGE_EFFECT {
225 pub(crate) const ENTROPY_STARTING_SOULS: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::EFFECT::SPELL_1261684_EFFECT_2;
226 pub(crate) const MONSTER_WITHIN_DIRECT: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::EFFECT::SPELL_1238855_EFFECT_1;
227 pub(crate) const MONSTER_WITHIN_PERIODIC: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::EFFECT::SPELL_1238855_EFFECT_2;
228 pub(crate) const MOMENT_OF_CRAVING_EXTRA_SOULS: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::EFFECT::SPELL_1238495_EFFECT_1;
229 pub(crate) const MID2_2PC_FRAGMENT_THRESHOLD: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::EFFECT::SPELL_1296615_EFFECT_1;
230 pub(crate) const MID2_2PC_PROC_CHANCE: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::EFFECT::SPELL_1296615_EFFECT_2;
231 pub(crate) const MID2_4PC_FRAGMENTS: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::EFFECT::SPELL_1296616_EFFECT_1;
232 pub(crate) const REAP_DAMAGE: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::EFFECT::SPELL_1225823_EFFECT_1;
233 pub(crate) const REAP_SOUL_LIMIT: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::EFFECT::SPELL_1227619_EFFECT_2;
234 pub(crate) const SHATTERED_SOULS_CHANCE: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::EFFECT::SPELL_1227619_EFFECT_1;
235 pub(crate) const SOULSHAPER_PER_FRAGMENT: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::EFFECT::SPELL_1238739_EFFECT_1;
236 pub(crate) const SOUL_SPLITTER_CHANCE: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::EFFECT::SPELL_1266330_EFFECT_1;
237 pub(crate) const SOULBURST_DAMAGE: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::EFFECT::SPELL_1297432_EFFECT_1;
238 pub(crate) const CATASTROPHE_PCT: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::EFFECT::SPELL_1253769_EFFECT_1;
239 pub(crate) const HARNESS_THE_COSMOS_PCT: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::EFFECT::SPELL_1279247_EFFECT_1;
240 pub(crate) const MASS_ACCELERATION_STACKS: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::EFFECT::SPELL_1256295_EFFECT_1;
241 pub(crate) const OTHERWORLDLY_FOCUS_PCT: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::EFFECT::SPELL_1253817_EFFECT_1;
242 pub(crate) const VOIDFALL_CHANCE: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::EFFECT::SPELL_1253304_EFFECT_3;
243 pub(crate) const VOIDFALL_METEOR_COEF: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::EFFECT::SPELL_1256305_EFFECT_1;
244 pub(crate) const VOIDFALL_STACKS: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::EFFECT::SPELL_1253304_EFFECT_1;
245 pub(crate) const WORLD_KILLER_COEF: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::EFFECT::SPELL_1256619_EFFECT_1;
246 pub(crate) const WORLD_KILLER_SOULS: wowlab_engine_combat::DamageEffectId = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::EFFECT::SPELL_1256353_EFFECT_4;
247}
248pub(crate) const AURA_VOID_METAMORPHOSIS: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::AURA_VOID_METAMORPHOSIS
249 .bind(
250 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
251 );
252pub(crate) const AURA_VOID_METAMORPHOSIS_STACK: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::AURA_VOID_METAMORPHOSIS_STACK
253 .bind(
254 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
255 );
256pub(crate) const AURA_COLLAPSING_STAR: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::AURA_COLLAPSING_STAR
257 .bind(
258 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
259 );
260pub(crate) const AURA_MOMENT_OF_CRAVING: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::AURA_MOMENT_OF_CRAVING
261 .bind(
262 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
263 );
264pub(crate) const AURA_SOULBURST: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::AURA_SOULBURST
265 .bind(
266 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
267 );
268pub(crate) const AURA_SOUL_IMMOLATION: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::AURA_SOUL_IMMOLATION
269 .bind(
270 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
271 );
272pub(crate) const AURA_SPONTANEOUS_IMMOLATION: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::AURA_SPONTANEOUS_IMMOLATION
273 .bind(
274 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
275 );
276pub(crate) const AURA_ENTROPY_TICKER: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::AURA_ENTROPY_TICKER
277 .bind(
278 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
279 );
280pub(crate) const AURA_SOUL_FRAGMENTS: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::AURA_SOUL_FRAGMENTS
281 .bind(
282 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
283 );
284pub(crate) const AURA_FEAST_OF_SOULS: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::AURA_FEAST_OF_SOULS
285 .bind(
286 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
287 );
288pub(crate) const AURA_FOCUSED_RAY: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::AURA_FOCUSED_RAY
289 .bind(
290 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
291 );
292pub(crate) const AURA_VOID_RAY: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::AURA_VOID_RAY
293 .bind(
294 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
295 );
296pub(crate) const AURA_VOIDFALL_BUILDING: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::AURA_VOIDFALL_BUILDING
297 .bind(
298 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
299 );
300pub(crate) const AURA_VOIDFALL_SPENDING: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::AURA_VOIDFALL_SPENDING
301 .bind(
302 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
303 );
304pub(crate) const AURA_VOIDFALL_FINAL_HOUR: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::AURA_VOIDFALL_FINAL_HOUR
305 .bind(
306 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
307 );
308pub(crate) const AURA_CATASTROPHE: LocalAuraIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::AURA_CATASTROPHE
309 .bind(
310 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
311 );
312pub(crate) const AURA_COUNT: usize = 16;
313const _: () = assert!(
314 AURA_COUNT == 16, "AURA index ABI: count changed -- update positional hook consumers"
315);
316pub(crate) const SPELL_CONSUME: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::SPELL_CONSUME
317 .bind(
318 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
319 );
320pub(crate) const SPELL_DEVOUR: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::SPELL_DEVOUR
321 .bind(
322 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
323 );
324pub(crate) const SPELL_VOIDBLADE: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::SPELL_VOIDBLADE
325 .bind(
326 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
327 );
328pub(crate) const SPELL_VOID_RAY: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::SPELL_VOID_RAY
329 .bind(
330 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
331 );
332pub(crate) const SPELL_VOID_RAY_TICK: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::SPELL_VOID_RAY_TICK
333 .bind(
334 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
335 );
336pub(crate) const SPELL_VOID_RAY_TICK_META: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::SPELL_VOID_RAY_TICK_META
337 .bind(
338 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
339 );
340pub(crate) const SPELL_REAP: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::SPELL_REAP
341 .bind(
342 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
343 );
344pub(crate) const SPELL_VOID_METAMORPHOSIS: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::SPELL_VOID_METAMORPHOSIS
345 .bind(
346 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
347 );
348pub(crate) const SPELL_IMMOLATION_AURA: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::SPELL_IMMOLATION_AURA
349 .bind(
350 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
351 );
352pub(crate) const SPELL_THE_HUNT: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::SPELL_THE_HUNT
353 .bind(
354 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
355 );
356pub(crate) const SPELL_CULL: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::SPELL_CULL
357 .bind(
358 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
359 );
360pub(crate) const SPELL_ERADICATE: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::SPELL_ERADICATE
361 .bind(
362 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
363 );
364pub(crate) const SPELL_COLLAPSING_STAR_SPELL: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::SPELL_COLLAPSING_STAR_SPELL
365 .bind(
366 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
367 );
368pub(crate) const SPELL_SOUL_IMMOLATION_SPELL: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::SPELL_SOUL_IMMOLATION_SPELL
369 .bind(
370 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
371 );
372pub(crate) const SPELL_HUNGERING_SLASH: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::SPELL_HUNGERING_SLASH
373 .bind(
374 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
375 );
376pub(crate) const SPELL_PREDATORS_WAKE: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::SPELL_PREDATORS_WAKE
377 .bind(
378 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
379 );
380pub(crate) const SPELL_PIERCE_THE_VEIL: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::SPELL_PIERCE_THE_VEIL
381 .bind(
382 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
383 );
384pub(crate) const SPELL_STUN: LocalSpellIdx = wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::SPELL_STUN
385 .bind(
386 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
387 );
388pub(crate) const SPELL_COUNT: usize = 18;
389const _: () = assert!(
390 SPELL_COUNT == 18,
391 "SPELL index ABI: count changed -- update positional hook consumers"
392);
393pub(crate) mod EFFECT {
394 pub(crate) const ENTROPY_STARTING_SOULS: (u32, u8) = (1_261_684, 2);
396 pub(crate) const MONSTER_WITHIN_DIRECT: (u32, u8) = (1_238_855, 1);
398 pub(crate) const MONSTER_WITHIN_PERIODIC: (u32, u8) = (1_238_855, 2);
400 pub(crate) const MOMENT_OF_CRAVING_EXTRA_SOULS: (u32, u8) = (1_238_495, 1);
402 pub(crate) const MID2_2PC_FRAGMENT_THRESHOLD: (u32, u8) = (1_296_615, 1);
404 pub(crate) const MID2_2PC_PROC_CHANCE: (u32, u8) = (1_296_615, 2);
406 pub(crate) const MID2_4PC_FRAGMENTS: (u32, u8) = (1_296_616, 1);
408 pub(crate) const REAP_DAMAGE: (u32, u8) = (1_225_823, 1);
410 pub(crate) const REAP_SOUL_LIMIT: (u32, u8) = (1_227_619, 2);
412 pub(crate) const SHATTERED_SOULS_CHANCE: (u32, u8) = (1_227_619, 1);
414 pub(crate) const SOULSHAPER_PER_FRAGMENT: (u32, u8) = (1_238_739, 1);
416 pub(crate) const SOUL_SPLITTER_CHANCE: (u32, u8) = (1_266_330, 1);
418 pub(crate) const SOULBURST_DAMAGE: (u32, u8) = (1_297_432, 1);
420 pub(crate) const CATASTROPHE_PCT: (u32, u8) = (1_253_769, 1);
422 pub(crate) const HARNESS_THE_COSMOS_PCT: (u32, u8) = (1_279_247, 1);
424 pub(crate) const MASS_ACCELERATION_STACKS: (u32, u8) = (1_256_295, 1);
426 pub(crate) const OTHERWORLDLY_FOCUS_PCT: (u32, u8) = (1_253_817, 1);
428 pub(crate) const VOIDFALL_CHANCE: (u32, u8) = (1_253_304, 3);
430 pub(crate) const VOIDFALL_METEOR_COEF: (u32, u8) = (1_256_305, 1);
432 pub(crate) const VOIDFALL_STACKS: (u32, u8) = (1_253_304, 1);
434 pub(crate) const WORLD_KILLER_COEF: (u32, u8) = (1_256_619, 1);
436 pub(crate) const WORLD_KILLER_SOULS: (u32, u8) = (1_256_353, 4);
438}
439static REPORTED_SPELLS: &[(&str, u32)] = &[
440 ("reap_damage", 1_225_823),
441 ("soulburst", 1_297_432),
442 ("voidblade_damage", 1_245_414),
443];
444static DECLARED_SPELL_IDS: &[u32] = &[
445 473_662, 1_217_610, 1_245_412, 473_728, 1_213_649, 1_214_595, 1_226_019, 1_217_607,
446 258_920, 370_965, 1_245_453, 1_225_826, 1_221_150, 1_241_937, 1_239_123, 1_246_160,
447 1_246_158, 179_057, 1_225_789, 1_221_171, 1_238_495, 1_297_433, 1_246_556, 1_261_684,
448 1_245_577, 1_232_310, 1_240_203, 1_256_301, 1_256_302, 1_256_322, 1_256_676,
449 1_237_270, 1_238_739, 1_225_823, 1_227_619, 1_238_855, 1_245_414, 1_253_304,
450 1_253_769, 1_253_817, 1_256_295, 1_256_305, 1_256_353, 1_256_619, 1_266_330,
451 1_279_247, 1_296_615, 1_296_616, 1_297_432, 1_253_391, 1_253_377,
452];
453static DECLARED_AURA_IDS: &[u32] = &[
454 1_217_607, 1_225_789, 1_221_171, 1_238_495, 1_297_433, 1_241_937, 1_246_556,
455 1_261_684, 1_245_577, 1_232_310, 1_240_203, 473_728, 1_256_301, 1_256_302, 1_256_322,
456 1_256_676, 1_256_301, 1_256_322, 1_256_302,
457];
458static TALENTS: &[(&str, u32)] = &[
459 ("COLLAPSING_STAR", TALENT::COLLAPSING_STAR),
460 ("FEAST_OF_SOULS", TALENT::FEAST_OF_SOULS),
461 ("SOULSHAPER", TALENT::SOULSHAPER),
462 ("THE_HUNT", TALENT::THE_HUNT),
463 ("VOID_RAY", TALENT::VOID_RAY),
464];
465fn aura_void_metamorphosis(
466 a: AuraDefinitionDraft,
467 data: &ResolvedGameData,
468) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
469 a.on_player()
470 .apply_base_from_data(data, 1_217_607)?
471 .max_stacks(
472 data
473 .require_aura_max_stacks(
474 wowlab_types::sim::SpellIdx::from_raw(1_217_607),
475 )?,
476 )
477 .periodic_resource_drain(
478 wowlab_engine_combat::validated_milliseconds(
479 2000.0,
480 1_217_607,
481 "periodic_resource_drain.tick_ms",
482 )?,
483 30.0,
484 )
485 .apply_periodic_behavior_from_data(data, 1_217_607)
486}
487fn aura_void_metamorphosis_stack(
488 a: AuraDefinitionDraft,
489 data: &ResolvedGameData,
490) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
491 Ok(
492 a
493 .on_player()
494 .apply_base_from_data(data, 1_225_789)?
495 .max_stacks(
496 data
497 .require_aura_max_stacks(
498 wowlab_types::sim::SpellIdx::from_raw(1_225_789),
499 )?,
500 ),
501 )
502}
503fn aura_collapsing_star(
504 a: AuraDefinitionDraft,
505 data: &ResolvedGameData,
506) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
507 Ok(
508 a
509 .on_player()
510 .apply_base_from_data(data, 1_221_171)?
511 .max_stacks(
512 data
513 .require_aura_max_stacks(
514 wowlab_types::sim::SpellIdx::from_raw(1_221_171),
515 )?,
516 ),
517 )
518}
519fn aura_moment_of_craving(
520 a: AuraDefinitionDraft,
521 data: &ResolvedGameData,
522) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
523 Ok(
524 a
525 .on_player()
526 .apply_base_from_data(data, 1_238_495)?
527 .max_stacks(
528 data
529 .require_aura_max_stacks(
530 wowlab_types::sim::SpellIdx::from_raw(1_238_495),
531 )?,
532 ),
533 )
534}
535fn aura_soulburst(
536 a: AuraDefinitionDraft,
537 data: &ResolvedGameData,
538) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
539 Ok(
540 a
541 .on_player()
542 .apply_base_from_data(data, 1_297_433)?
543 .max_stacks(
544 data
545 .require_aura_max_stacks(
546 wowlab_types::sim::SpellIdx::from_raw(1_297_433),
547 )?,
548 ),
549 )
550}
551fn aura_soul_immolation(
552 a: AuraDefinitionDraft,
553 data: &ResolvedGameData,
554) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
555 a.on_player()
556 .apply_base_from_data(data, 1_241_937)?
557 .max_stacks(
558 data
559 .require_aura_max_stacks(
560 wowlab_types::sim::SpellIdx::from_raw(1_241_937),
561 )?,
562 )
563 .periodic_damage(
564 wowlab_engine_combat::validated_milliseconds(
565 1000.0,
566 1_241_937,
567 "periodic_damage.tick_ms",
568 )?,
569 0.0,
570 wowlab_engine_combat::DamageFlags::empty(),
571 )
572 .apply_periodic_behavior_from_data(data, 1_241_937)
573}
574fn aura_spontaneous_immolation(
575 a: AuraDefinitionDraft,
576 data: &ResolvedGameData,
577) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
578 Ok(
579 a
580 .on_player()
581 .apply_base_from_data(data, 1_246_556)?
582 .max_stacks(
583 data
584 .require_aura_max_stacks(
585 wowlab_types::sim::SpellIdx::from_raw(1_246_556),
586 )?,
587 ),
588 )
589}
590fn aura_entropy_ticker(
591 a: AuraDefinitionDraft,
592 data: &ResolvedGameData,
593) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
594 a.on_player()
595 .apply_base_from_data(data, 1_261_684)?
596 .max_stacks(
597 data
598 .require_aura_max_stacks(
599 wowlab_types::sim::SpellIdx::from_raw(1_261_684),
600 )?,
601 )
602 .periodic_apply_aura(
603 wowlab_engine_combat::validated_milliseconds(
604 data.period(wowlab_types::sim::SpellIdx::from_raw(1_261_684), 1),
605 1_261_684,
606 "periodic_apply_aura.tick_ms",
607 )?,
608 1,
609 )
610 .apply_periodic_behavior_from_data(data, 1_261_684)
611}
612fn aura_soul_fragments(
613 a: AuraDefinitionDraft,
614 data: &ResolvedGameData,
615) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
616 Ok(
617 a
618 .on_player()
619 .apply_base_from_data(data, 1_245_577)?
620 .max_stacks(
621 data
622 .require_aura_max_stacks(
623 wowlab_types::sim::SpellIdx::from_raw(1_245_577),
624 )?,
625 ),
626 )
627}
628fn aura_feast_of_souls(
629 a: AuraDefinitionDraft,
630 data: &ResolvedGameData,
631) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
632 Ok(
633 a
634 .on_player()
635 .apply_base_from_data(data, 1_232_310)?
636 .max_stacks(
637 data
638 .require_aura_max_stacks(
639 wowlab_types::sim::SpellIdx::from_raw(1_232_310),
640 )?,
641 )
642 .async_stacks(),
643 )
644}
645fn aura_focused_ray(
646 a: AuraDefinitionDraft,
647 data: &ResolvedGameData,
648) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
649 a.on_player()
650 .apply_base_from_data(data, 1_240_203)?
651 .max_stacks(
652 data
653 .require_aura_max_stacks(
654 wowlab_types::sim::SpellIdx::from_raw(1_240_203),
655 )?,
656 )
657 .damage_percent_spells(
658 data.base_points(wowlab_types::sim::SpellIdx::from_raw(1_240_203), 1),
659 &[473_728],
660 )
661}
662fn aura_void_ray(
663 a: AuraDefinitionDraft,
664 data: &ResolvedGameData,
665) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
666 Ok(
667 a
668 .on_player()
669 .apply_base_from_data(data, 473_728)?
670 .max_stacks(
671 data
672 .require_aura_max_stacks(
673 wowlab_types::sim::SpellIdx::from_raw(473_728),
674 )?,
675 ),
676 )
677}
678fn aura_voidfall_building(
679 a: AuraDefinitionDraft,
680 data: &ResolvedGameData,
681) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
682 Ok(
683 a
684 .on_player()
685 .apply_base_from_data(data, 1_256_301)?
686 .max_stacks(
687 data
688 .require_aura_max_stacks(
689 wowlab_types::sim::SpellIdx::from_raw(1_256_301),
690 )?,
691 ),
692 )
693}
694fn aura_voidfall_spending(
695 a: AuraDefinitionDraft,
696 data: &ResolvedGameData,
697) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
698 Ok(
699 a
700 .on_player()
701 .apply_base_from_data(data, 1_256_302)?
702 .max_stacks(
703 data
704 .require_aura_max_stacks(
705 wowlab_types::sim::SpellIdx::from_raw(1_256_302),
706 )?,
707 ),
708 )
709}
710fn aura_voidfall_final_hour(
711 a: AuraDefinitionDraft,
712 data: &ResolvedGameData,
713) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
714 Ok(
715 a
716 .on_player()
717 .apply_base_from_data(data, 1_256_322)?
718 .max_stacks(
719 data
720 .require_aura_max_stacks(
721 wowlab_types::sim::SpellIdx::from_raw(1_256_322),
722 )?,
723 ),
724 )
725}
726fn aura_catastrophe(
727 a: AuraDefinitionDraft,
728 data: &ResolvedGameData,
729) -> Result<AuraDefinitionDraft, wowlab_engine_combat::BuilderError> {
730 a.on_target()
731 .apply_base_from_data(data, 1_256_676)?
732 .max_stacks(
733 data
734 .require_aura_max_stacks(
735 wowlab_types::sim::SpellIdx::from_raw(1_256_676),
736 )?,
737 )
738 .periodic_residual_damage(
739 wowlab_engine_combat::validated_milliseconds(
740 data.period(wowlab_types::sim::SpellIdx::from_raw(1_256_676), 1),
741 1_256_676,
742 "periodic_residual_damage.tick_ms",
743 )?,
744 )
745 .apply_periodic_behavior_from_data(data, 1_256_676)
746}
747fn spell_consume(
748 s: SpellDefinitionDraft,
749 data: &ResolvedGameData,
750) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
751 Ok(
752 s
753 .apply_base_from_data(data, 473_662)?
754 .gain(8.0)
755 .apply_aoe_from_data(data)
756 .on_cast(crate::hooks::devourer_demon_hunter::consume_hook),
757 )
758}
759fn spell_devour(
760 s: SpellDefinitionDraft,
761 data: &ResolvedGameData,
762) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
763 Ok(
764 s
765 .apply_base_from_data(data, 1_217_610)?
766 .gain(40.0)
767 .apply_aoe_from_data(data)
768 .on_cast(crate::hooks::devourer_demon_hunter::consume_hook),
769 )
770}
771fn spell_voidblade(
772 s: SpellDefinitionDraft,
773 data: &ResolvedGameData,
774) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
775 Ok(
776 s
777 .apply_base_from_data(data, 1_245_412)?
778 .gain(20.0)
779 .damage_sp_from_data(
780 wowlab_engine_domain::dbc::EffectLookup::new(
781 data,
782 wowlab_types::sim::EffectRef::new(
783 wowlab_types::sim::SpellIdx::from_raw(1_245_414),
784 2,
785 ),
786 ),
787 )?
788 .apply_aoe_from_data(data),
789 )
790}
791fn spell_void_ray(
792 s: SpellDefinitionDraft,
793 data: &ResolvedGameData,
794) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
795 Ok(
796 s
797 .apply_base_from_data(data, 473_728)?
798 .applies_inferred_aura(AURA_VOID_RAY, 473_728)
799 .apply_aoe_from_data(data)
800 .channel(
801 wowlab_engine_combat::validated_channel_tick_count(
802 20.0,
803 473_728,
804 "channel.tick_count",
805 )?,
806 )
807 .channel_tick_direct_damage()
808 .channel_tick_damage_sp_from_data(
809 wowlab_engine_domain::dbc::EffectLookup::new(
810 data,
811 wowlab_types::sim::EffectRef::new(
812 wowlab_types::sim::SpellIdx::from_raw(1_213_649),
813 1,
814 ),
815 ),
816 )?
817 .channel_tick_damage_alt_sp_from_data(
818 wowlab_engine_domain::dbc::EffectLookup::new(
819 data,
820 wowlab_types::sim::EffectRef::new(
821 wowlab_types::sim::SpellIdx::from_raw(1_214_595),
822 1,
823 ),
824 ),
825 AURA::VOID_METAMORPHOSIS,
826 )?
827 .channel_tick_cost(
828 data.require_cost(wowlab_types::sim::SpellIdx::from_raw(1_213_649))?,
829 )
830 .channel_tick_cost_alt(
831 data.require_cost(wowlab_types::sim::SpellIdx::from_raw(1_214_595))?,
832 AURA::VOID_METAMORPHOSIS,
833 )
834 .on_cast(crate::hooks::devourer_demon_hunter::void_ray_hook)
835 .cost_free_when_aura(1_217_607),
836 )
837}
838fn spell_void_ray_tick(
839 s: SpellDefinitionDraft,
840 data: &ResolvedGameData,
841) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
842 Ok(s.apply_base_from_data(data, 1_213_649)?.apply_aoe_from_data(data))
843}
844fn spell_void_ray_tick_meta(
845 s: SpellDefinitionDraft,
846 data: &ResolvedGameData,
847) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
848 Ok(s.apply_base_from_data(data, 1_214_595)?.apply_aoe_from_data(data))
849}
850fn spell_reap(
851 s: SpellDefinitionDraft,
852 data: &ResolvedGameData,
853) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
854 Ok(
855 s
856 .apply_base_from_data(data, 1_226_019)?
857 .apply_aoe_from_data(data)
858 .on_cast(crate::hooks::devourer_demon_hunter::reap_hook),
859 )
860}
861fn spell_void_metamorphosis(
862 s: SpellDefinitionDraft,
863 data: &ResolvedGameData,
864) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
865 Ok(
866 s
867 .apply_base_from_data(data, 1_217_607)?
868 .gain(200.0)
869 .applies_inferred_aura(AURA_VOID_METAMORPHOSIS, 1_217_607)
870 .apply_aoe_from_data(data)
871 .on_cast(crate::hooks::devourer_demon_hunter::void_metamorphosis_hook)
872 .requires_aura_at_min_stacks(1_225_789, 50),
873 )
874}
875fn spell_immolation_aura(
876 s: SpellDefinitionDraft,
877 data: &ResolvedGameData,
878) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
879 Ok(s.apply_base_from_data(data, 258_920)?.apply_aoe_from_data(data))
880}
881fn spell_the_hunt(
882 s: SpellDefinitionDraft,
883 data: &ResolvedGameData,
884) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
885 Ok(s.apply_base_from_data(data, 370_965)?.apply_aoe_from_data(data))
886}
887fn spell_cull(
888 s: SpellDefinitionDraft,
889 data: &ResolvedGameData,
890) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
891 Ok(s.apply_base_from_data(data, 1_245_453)?.apply_aoe_from_data(data))
892}
893fn spell_eradicate(
894 s: SpellDefinitionDraft,
895 data: &ResolvedGameData,
896) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
897 Ok(
898 s
899 .apply_base_from_data(data, 1_225_826)?
900 .apply_aoe_from_data(data)
901 .on_cast(crate::hooks::devourer_demon_hunter::eradicate_hook),
902 )
903}
904fn spell_collapsing_star_spell(
905 s: SpellDefinitionDraft,
906 data: &ResolvedGameData,
907) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
908 Ok(s.apply_base_from_data(data, 1_221_150)?.apply_aoe_from_data(data))
909}
910fn spell_soul_immolation_spell(
911 s: SpellDefinitionDraft,
912 data: &ResolvedGameData,
913) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
914 Ok(
915 s
916 .apply_base_from_data(data, 1_241_937)?
917 .applies_inferred_aura(AURA_SOUL_IMMOLATION, 1_241_937)
918 .apply_aoe_from_data(data),
919 )
920}
921fn spell_hungering_slash(
922 s: SpellDefinitionDraft,
923 data: &ResolvedGameData,
924) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
925 Ok(s.apply_base_from_data(data, 1_239_123)?.apply_aoe_from_data(data))
926}
927fn spell_predators_wake(
928 s: SpellDefinitionDraft,
929 data: &ResolvedGameData,
930) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
931 Ok(s.apply_base_from_data(data, 1_246_160)?.apply_aoe_from_data(data))
932}
933fn spell_pierce_the_veil(
934 s: SpellDefinitionDraft,
935 data: &ResolvedGameData,
936) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
937 Ok(s.apply_base_from_data(data, 1_246_158)?.apply_aoe_from_data(data))
938}
939fn spell_stun(
940 s: SpellDefinitionDraft,
941 data: &ResolvedGameData,
942) -> Result<SpellDefinitionDraft, wowlab_engine_combat::BuilderError> {
943 Ok(s.apply_base_from_data(data, 179_057)?.apply_aoe_from_data(data))
944}
945pub(crate) fn build_combat_system_draft(
946 params: &wowlab_engine_ports::HandlerParams<'_>,
947) -> Result<CombatSystemDraft, wowlab_engine_ports::EngineError> {
948 let builder = CombatSystemBuilder::new(params.stats.clone())
949 .spec_id(SpecId::Devourer)
950 .spec_identity(
951 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::PROOF,
952 )
953 .hero_talent_trees(DECLARED_METADATA.hero_talent_trees)
954 .effect_identities(
955 wowlab_engine_combat::generated_identities::specs::devourer_demon_hunter::damage::ALL,
956 )
957 .effect_identities(wowlab_engine_combat::generated_identities::shared::ALL)
958 .mastery_spell(1_238_855)
959 .mastery_hook(crate::hooks::devourer_demon_hunter::mastery)
960 .resource(
961 "fury",
962 120.0,
963 params
964 .game_data
965 .power_regen_for_max(17, 120.0)
966 .ok_or_else(|| {
967 wowlab_engine_ports::EngineError::spec_construction(
968 "missing power-type power_regen_for_max for type_id 17",
969 )
970 })?,
971 )
972 .resource_type_id(17)
973 .resource_start(
974 params
975 .game_data
976 .power_default(17)
977 .ok_or_else(|| {
978 wowlab_engine_ports::EngineError::spec_construction(
979 "missing power-type power_default for type_id 17",
980 )
981 })?,
982 )
983 .aura(
984 "void_metamorphosis",
985 AURA::VOID_METAMORPHOSIS,
986 |a| aura_void_metamorphosis(a, ¶ms.game_data),
987 )
988 .aura(
989 "void_metamorphosis_stack",
990 AURA::VOID_METAMORPHOSIS_STACK,
991 |a| aura_void_metamorphosis_stack(a, ¶ms.game_data),
992 )
993 .aura(
994 "collapsing_star",
995 AURA::COLLAPSING_STAR,
996 |a| aura_collapsing_star(a, ¶ms.game_data),
997 )
998 .aura(
999 "moment_of_craving",
1000 AURA::MOMENT_OF_CRAVING,
1001 |a| aura_moment_of_craving(a, ¶ms.game_data),
1002 )
1003 .aura("soulburst", AURA::SOULBURST, |a| aura_soulburst(a, ¶ms.game_data))
1004 .aura(
1005 "soul_immolation",
1006 AURA::SOUL_IMMOLATION,
1007 |a| aura_soul_immolation(a, ¶ms.game_data),
1008 )
1009 .aura(
1010 "spontaneous_immolation",
1011 AURA::SPONTANEOUS_IMMOLATION,
1012 |a| aura_spontaneous_immolation(a, ¶ms.game_data),
1013 )
1014 .aura(
1015 "entropy_ticker",
1016 AURA::ENTROPY_TICKER,
1017 |a| aura_entropy_ticker(a, ¶ms.game_data),
1018 )
1019 .aura(
1020 "soul_fragments",
1021 AURA::SOUL_FRAGMENTS,
1022 |a| aura_soul_fragments(a, ¶ms.game_data),
1023 )
1024 .aura(
1025 "feast_of_souls",
1026 AURA::FEAST_OF_SOULS,
1027 |a| aura_feast_of_souls(a, ¶ms.game_data),
1028 )
1029 .aura(
1030 "focused_ray",
1031 AURA::FOCUSED_RAY,
1032 |a| aura_focused_ray(a, ¶ms.game_data),
1033 )
1034 .aura("void_ray", AURA::VOID_RAY, |a| aura_void_ray(a, ¶ms.game_data))
1035 .aura(
1036 "voidfall_building",
1037 AURA::VOIDFALL_BUILDING,
1038 |a| aura_voidfall_building(a, ¶ms.game_data),
1039 )
1040 .aura(
1041 "voidfall_spending",
1042 AURA::VOIDFALL_SPENDING,
1043 |a| aura_voidfall_spending(a, ¶ms.game_data),
1044 )
1045 .aura(
1046 "voidfall_final_hour",
1047 AURA::VOIDFALL_FINAL_HOUR,
1048 |a| aura_voidfall_final_hour(a, ¶ms.game_data),
1049 )
1050 .aura(
1051 "catastrophe",
1052 AURA::CATASTROPHE,
1053 |a| aura_catastrophe(a, ¶ms.game_data),
1054 )
1055 .spell("consume", SPELL::CONSUME, |s| spell_consume(s, ¶ms.game_data))
1056 .spell("devour", SPELL::DEVOUR, |s| spell_devour(s, ¶ms.game_data))
1057 .spell("voidblade", SPELL::VOIDBLADE, |s| spell_voidblade(s, ¶ms.game_data))
1058 .spell("void_ray", SPELL::VOID_RAY, |s| spell_void_ray(s, ¶ms.game_data))
1059 .spell(
1060 "void_ray_tick",
1061 SPELL::VOID_RAY_TICK,
1062 |s| spell_void_ray_tick(s, ¶ms.game_data),
1063 )
1064 .spell(
1065 "void_ray_tick_meta",
1066 SPELL::VOID_RAY_TICK_META,
1067 |s| spell_void_ray_tick_meta(s, ¶ms.game_data),
1068 )
1069 .spell("reap", SPELL::REAP, |s| spell_reap(s, ¶ms.game_data))
1070 .spell(
1071 "void_metamorphosis",
1072 SPELL::VOID_METAMORPHOSIS,
1073 |s| spell_void_metamorphosis(s, ¶ms.game_data),
1074 )
1075 .spell(
1076 "immolation_aura",
1077 SPELL::IMMOLATION_AURA,
1078 |s| spell_immolation_aura(s, ¶ms.game_data),
1079 )
1080 .spell("the_hunt", SPELL::THE_HUNT, |s| spell_the_hunt(s, ¶ms.game_data))
1081 .spell("cull", SPELL::CULL, |s| spell_cull(s, ¶ms.game_data))
1082 .spell("eradicate", SPELL::ERADICATE, |s| spell_eradicate(s, ¶ms.game_data))
1083 .spell(
1084 "collapsing_star_spell",
1085 SPELL::COLLAPSING_STAR_SPELL,
1086 |s| spell_collapsing_star_spell(s, ¶ms.game_data),
1087 )
1088 .spell(
1089 "soul_immolation_spell",
1090 SPELL::SOUL_IMMOLATION_SPELL,
1091 |s| spell_soul_immolation_spell(s, ¶ms.game_data),
1092 )
1093 .spell(
1094 "hungering_slash",
1095 SPELL::HUNGERING_SLASH,
1096 |s| spell_hungering_slash(s, ¶ms.game_data),
1097 )
1098 .spell(
1099 "predators_wake",
1100 SPELL::PREDATORS_WAKE,
1101 |s| spell_predators_wake(s, ¶ms.game_data),
1102 )
1103 .spell(
1104 "pierce_the_veil",
1105 SPELL::PIERCE_THE_VEIL,
1106 |s| spell_pierce_the_veil(s, ¶ms.game_data),
1107 )
1108 .spell("stun", SPELL::STUN, |s| spell_stun(s, ¶ms.game_data))
1109 .game_data(params.game_data.clone())
1110 .talent_spell_ids(TALENTS)
1111 .talent_selections(params.talent_selections)
1112 .set_bonus_auras(params.set_bonus_auras)
1113 .encounter(params.encounter.clone());
1114 let builder = crate::generated::items::register_equipped(
1115 builder,
1116 ¶ms.game_data,
1117 params.equipped_items,
1118 )?;
1119
1120 builder.into_draft()
1121}
1122fn new_handler(
1123 params: wowlab_engine_ports::HandlerParams<'_>,
1124) -> Result<Box<dyn SpecHandler>, wowlab_engine_ports::EngineError> {
1125 let handler = crate::composition::compose_handler(
1126 build_combat_system_draft,
1127 ¶ms,
1128 crate::hooks::devourer_demon_hunter::DevourerHandler::try_new,
1129 )?;
1130
1131 Ok(Box::new(handler))
1132}
1133static DECLARED_METADATA: DeclaredSpecMetadata = DeclaredSpecMetadata {
1134 primary_resource: ResourceType::Fury,
1135 secondary_resource: None,
1136 spell_ids: DECLARED_SPELL_IDS,
1137 aura_ids: DECLARED_AURA_IDS,
1138 server_proc_entries: &[
1139 DeclaredServerProcEntry {
1140 spell_id: 1_238_495,
1141 attributes: ProcAttributes::TRIGGERED_CAN_PROC.bits()
1142 | ProcAttributes::USE_STACKS_FOR_CHARGES.bits(),
1143 },
1144 ],
1145 talents: TALENTS,
1146 rotation_field_schema: &[],
1147 metrics_plugin_id: None,
1148 hero_talent_trees: &[
1149 HeroTalentTreeDesc {
1150 name: "Annihilator",
1151 spells: HERO_TREE_ANNIHILATOR_SPELLS,
1152 auras: HERO_TREE_ANNIHILATOR_AURAS,
1153 },
1154 ],
1155 reported_spells: REPORTED_SPELLS,
1156 masked_passive_effects: &[],
1157 passive_effect_overrides: &[],
1158};
1159pub(super) const SPEC_DESCRIPTOR: SpecDescriptor = SpecDescriptor {
1160 spec_id: SpecId::Devourer,
1161 display_name: "Devourer Demon Hunter",
1162 metadata: DECLARED_METADATA,
1163 handler_factory: new_handler,
1164};
1165wowlab_engine_combat::smoke_test!(build_combat_system_draft);