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(
20 ctx.program,
21 ctx.instance,
22 spell_local,
23 effect.amount_ms,
24 ctx.now,
25 );
26 };
27
28 match effect.condition {
29 CdrCondition::Always => reduce(ctx),
30 CdrCondition::ProcChance { chance } => {
31 if (ctx.rng)() < chance {
32 reduce(ctx);
33 }
34 }
35 CdrCondition::WhileAuraActive { aura_local } => {
36 if is_aura_active(
37 &ctx.view(),
38 LocalAuraIdx::new(aura_local),
39 ctx.source,
40 Some(ctx.target),
41 ) {
42 reduce(ctx);
43 }
44 }
45 CdrCondition::ResetWhileAura { aura_local } => {
46 if is_aura_active(
47 &ctx.view(),
48 LocalAuraIdx::new(aura_local),
49 ctx.source,
50 Some(ctx.target),
51 ) {
52 reset_cooldown(ctx.program, ctx.instance, spell_local, ctx.now);
53 }
54 }
55 _ => unreachable!("the engine and canonical CDR condition contract must stay in sync"),
56 }
57}