Skip to main content

wowlab_engine_content/hooks/outlaw_rogue/
restless_blades.rs

1use 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}