wowlab_engine_combat/pipeline/
cdr.rs1use wowlab_types::game::{CdrCondition, CdrEffect};
2
3use crate::{
4 context::CombatCtx,
5 state::{LocalAuraIdx, LocalSpellIdx, SpellData},
6 systems::{is_aura_active, reduce_cooldown, reset_cooldown},
7};
8
9pub(super) fn process_cdr_effects(ctx: &mut CombatCtx<'_>, spell: &SpellData) {
10 for i in 0..spell.cooldown.cdr_count as usize {
11 apply_cdr_effect(ctx, spell.cooldown.cdr_effects[i]);
13 }
14}
15
16fn apply_cdr_effect(ctx: &mut CombatCtx<'_>, effect: CdrEffect) {
17 let spell_local = LocalSpellIdx::new(effect.target_spell_local);
18 let reduce = |ctx: &mut CombatCtx<'_>| {
19 reduce_cooldown(ctx.state, ctx.buf, spell_local, effect.amount_ms, ctx.now);
20 };
21
22 match effect.condition {
23 CdrCondition::Always => reduce(ctx),
24 CdrCondition::ProcChance { chance } => {
25 if (ctx.rng)() < chance {
26 reduce(ctx);
27 }
28 }
29 CdrCondition::WhileAuraActive { aura_local } => {
30 if is_aura_active(
31 &ctx.view(),
32 LocalAuraIdx::new(aura_local),
33 ctx.source,
34 Some(ctx.target),
35 ) {
36 reduce(ctx);
37 }
38 }
39 CdrCondition::ResetWhileAura { aura_local } => {
40 if is_aura_active(
41 &ctx.view(),
42 LocalAuraIdx::new(aura_local),
43 ctx.source,
44 Some(ctx.target),
45 ) {
46 reset_cooldown(ctx.state, ctx.buf, spell_local);
47 }
48 }
49 _ => unreachable!("the engine and canonical CDR condition contract must stay in sync"),
50 }
51}