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 crate::agent::GameEntity;
8use crate::game_entity_counter_table::GameEntityCounterTable;
9use forge_foundation::ZoneType;
10
11/// Struct form of this effect so it can participate in the
12/// `SpellAbilityEffect` trait hierarchy — mirrors Java's
13/// `CountersMultiplyEffect` class extending `SpellAbilityEffect`.
14#[manabrew_engine_macros::spell_effect(CountersMultiplyEffect)]
15fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
16    let multiplier = super::resolve_numeric_svar(ctx.game, sa, "Multiplier", 2).max(0);
17    let counter_type_filter = sa.ir.counter_type.clone();
18
19    let targets: Vec<crate::ids::CardId> = if sa.uses_targeting() {
20        sa.target_chosen.target_card.into_iter().collect()
21    } else {
22        sa.source.into_iter().collect()
23    };
24
25    let mut table = GameEntityCounterTable::default();
26    for card_id in targets {
27        if ctx.game.card(card_id).zone != ZoneType::Battlefield {
28            continue;
29        }
30
31        if let Some(ref ct) = counter_type_filter {
32            // Multiply specific counter type
33            let current = *ctx.game.card(card_id).counters.get(ct).unwrap_or(&0);
34            let to_add = current * (multiplier - 1);
35            if to_add > 0 {
36                table.put(
37                    Some(sa.activating_player),
38                    GameEntity::Card(card_id),
39                    ct.clone(),
40                    to_add,
41                );
42            }
43        } else {
44            // Multiply ALL counter types
45            let counters: Vec<(crate::card::CounterType, i32)> = ctx
46                .game
47                .card(card_id)
48                .counters
49                .iter()
50                .map(|(k, &v)| (k.clone(), v))
51                .collect();
52            for (ct, current) in counters {
53                let to_add = current * (multiplier - 1);
54                if to_add > 0 {
55                    table.put(
56                        Some(sa.activating_player),
57                        GameEntity::Card(card_id),
58                        ct,
59                        to_add,
60                    );
61                }
62            }
63        }
64    }
65    table.replace_counter_effect(
66        ctx.game,
67        Some(ctx.trigger_handler),
68        Some(ctx.agents),
69        Some(sa),
70        true,
71        Default::default(),
72    );
73}