wowlab_engine_content/hooks/outlaw_rogue/
restless_blades.rs1use wowlab_engine_combat::AuraOps as _;
2use wowlab_engine_combat::CooldownOps as _;
3use wowlab_engine_combat::ProcOps as _;
4use wowlab_engine_combat::ResourceOps as _;
5use wowlab_engine_combat::{HookCtx, LocalSpellIdx};
6use wowlab_engine_rng::proc_chance;
7
8use crate::generated::specs::outlaw_rogue::{
9 AURA_DEADLY_PURSUIT_CDR, AURA_DEADLY_PURSUIT_WAIT, SPELL_ADRENALINE_RUSH,
10 SPELL_BETWEEN_THE_EYES, SPELL_BLADE_FLURRY, SPELL_BLADE_RUSH, SPELL_KEEP_IT_ROLLING,
11 SPELL_KILLING_SPREE, SPELL_ROLL_THE_BONES,
12};
13
14use super::{config::outlaw_config, roll_the_bones::rtb_tier};
15
16const RTB_TIER_CDR_BONUS: usize = 3;
17const DEADLY_PURSUIT_THRESHOLD: u32 = 15;
18
19#[rustfmt::skip]
20const RESTLESS_BLADES_TARGETS: [LocalSpellIdx; 7] = [
21 SPELL_ADRENALINE_RUSH,
22 SPELL_BETWEEN_THE_EYES,
23 SPELL_BLADE_FLURRY,
24 SPELL_BLADE_RUSH,
25 SPELL_KEEP_IT_ROLLING,
26 SPELL_KILLING_SPREE,
27 SPELL_ROLL_THE_BONES,
28];
29
30pub(super) fn on_finisher(ctx: &mut HookCtx<'_>) {
31 let cp = ctx.last_secondary_spent();
32
33 on_finisher_with_cp(ctx, cp);
34}
35
36pub(super) fn on_finisher_with_cp(ctx: &mut HookCtx<'_>, cp: f64) {
37 let cfg = outlaw_config(ctx);
38
39 if cp <= 0.0 {
40 return;
41 }
42
43 if cfg.restless_blades_cdr_ms_per_cp > 0 {
44 let mut cdr = f64::from(cfg.restless_blades_cdr_ms_per_cp) * cp;
45
46 if rtb_tier(ctx) >= RTB_TIER_CDR_BONUS {
47 cdr *= 1.0 + cfg.restless_blades_rtb_bonus;
48 }
49
50 let cdr_ms = wowlab_types::numeric::f64_to_u32_saturating_trunc(cdr);
51
52 for target in RESTLESS_BLADES_TARGETS {
53 ctx.reduce_cooldown(target, cdr_ms);
54 }
55 }
56
57 if cfg.ruthlessness_cp_per_cp > 0.0 {
58 let expected = cfg.ruthlessness_cp_per_cp * cp;
59 let mut refund = expected.floor();
60 let remainder = expected - refund;
61
62 if remainder > 0.0 && proc_chance(ctx.rng(), remainder) {
63 refund += 1.0;
64 }
65
66 if refund > 0.0 {
67 ctx.gain_secondary_resource(refund);
68 }
69 }
70
71 if cfg.has_deadly_pursuit {
72 if ctx.is_aura_active(AURA_DEADLY_PURSUIT_CDR) {
73 ctx.consume_aura(AURA_DEADLY_PURSUIT_CDR);
74 } else if ctx.is_aura_active(AURA_DEADLY_PURSUIT_WAIT) {
75 ctx.apply_aura(AURA_DEADLY_PURSUIT_WAIT);
76 } else {
77 let combo_points = wowlab_types::numeric::f64_to_u32_saturating_trunc(cp);
78
79 if ctx.advance_proc_counter_by(
80 wowlab_engine_combat::generated_identities::proc_counter::DEADLY_PURSUIT,
81 combo_points,
82 DEADLY_PURSUIT_THRESHOLD,
83 ) {
84 ctx.apply_aura(AURA_DEADLY_PURSUIT_WAIT);
85 }
86 }
87 }
88}