Skip to main content

manabrew_engine/ability/effects/
counters_proliferate_effect.rs

1use forge_foundation::ZoneType;
2
3use super::EffectContext;
4use crate::agent::GameEntity;
5use crate::game_entity_counter_table::GameEntityCounterTable;
6use crate::replacement::replacement_handler::{apply_replacements_with_agents, ReplacementEvent};
7use crate::replacement::ReplacementResult;
8use crate::trigger::TriggerType;
9
10#[manabrew_engine_macros::spell_effect(CountersProliferateEffect)]
11fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
12    let controller = sa.activating_player;
13    let mut event = ReplacementEvent::Proliferate {
14        player: controller,
15        count: super::resolve_numeric_svar(ctx.game, sa, "Amount", 1),
16    };
17    let result = apply_replacements_with_agents(ctx.game, ctx.agents, &mut event);
18    if !matches!(
19        result,
20        ReplacementResult::NotReplaced | ReplacementResult::Updated
21    ) {
22        return;
23    }
24    let ReplacementEvent::Proliferate { count, .. } = event else {
25        return;
26    };
27
28    for _ in 0..count {
29        let mut candidates = Vec::new();
30        for &player in &ctx.game.player_order {
31            let entity = GameEntity::Player(player);
32            if !GameEntityCounterTable::counters(ctx.game, entity).is_empty() {
33                candidates.push(entity);
34            }
35        }
36        for card in ctx.game.cards_in_all_zones(ZoneType::Battlefield) {
37            let entity = GameEntity::Card(card);
38            if !GameEntityCounterTable::counters(ctx.game, entity).is_empty() {
39                candidates.push(entity);
40            }
41        }
42
43        let chosen = ctx.agents[controller.index()].choose_entities_for_effect(
44            controller,
45            &candidates,
46            0,
47            candidates.len(),
48        );
49        let mut table = GameEntityCounterTable::default();
50        for entity in chosen {
51            for (counter_type, _) in GameEntityCounterTable::counters(ctx.game, entity) {
52                table.put(Some(controller), entity, counter_type, 1);
53            }
54        }
55        table.replace_counter_effect(
56            ctx.game,
57            Some(ctx.trigger_handler),
58            Some(ctx.agents),
59            Some(sa),
60            true,
61            Default::default(),
62        );
63        ctx.trigger_handler.run_trigger(
64            TriggerType::Proliferate,
65            crate::event::RunParams {
66                player: Some(controller),
67                ..Default::default()
68            },
69            false,
70        );
71    }
72}