Skip to main content

manabrew_engine/ability/effects/
counters_multiply_effect.rs

1//! CountersMultiply effect — double (or multiply) counters on a permanent.
2//!
3//! Ported from Java's `CountersMultiplyEffect.java`.
4//! Double the number of each type of counter on target permanent.
5
6use super::EffectContext;
7use forge_foundation::ZoneType;
8
9/// Struct form of this effect so it can participate in the
10/// `SpellAbilityEffect` trait hierarchy — mirrors Java's
11/// `CountersMultiplyEffect` class extending `SpellAbilityEffect`.
12#[manabrew_engine_macros::spell_effect(CountersMultiplyEffect)]
13fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
14    let multiplier = super::resolve_numeric_svar(ctx.game, sa, "Multiplier", 2).max(0);
15    let counter_type_filter = sa.ir.counter_type.clone();
16
17    let targets: Vec<crate::ids::CardId> = if sa.uses_targeting() {
18        sa.target_chosen.target_card.into_iter().collect()
19    } else {
20        sa.source.into_iter().collect()
21    };
22
23    for card_id in targets {
24        if ctx.game.card(card_id).zone != ZoneType::Battlefield {
25            continue;
26        }
27
28        if let Some(ref ct) = counter_type_filter {
29            // Multiply specific counter type
30            let current = *ctx.game.card(card_id).counters.get(ct).unwrap_or(&0);
31            let to_add = current * (multiplier - 1);
32            if to_add > 0 {
33                ctx.game.card_mut(card_id).add_counter(ct, to_add);
34            }
35        } else {
36            // Multiply ALL counter types
37            let counters: Vec<(crate::card::CounterType, i32)> = ctx
38                .game
39                .card(card_id)
40                .counters
41                .iter()
42                .map(|(k, &v)| (k.clone(), v))
43                .collect();
44            for (ct, current) in counters {
45                let to_add = current * (multiplier - 1);
46                if to_add > 0 {
47                    ctx.game.card_mut(card_id).add_counter(&ct, to_add);
48                }
49            }
50        }
51    }
52}