Skip to main content

manabrew_engine/ability/effects/
choose_source_effect.rs

1use forge_foundation::ZoneType;
2
3use super::{matches_valid_cards_for_sa, EffectContext};
4use crate::ids::CardId;
5
6/// `SP$ ChooseSource` — the activating player chooses a source (permanent/spell).
7/// Stores the result for subsequent effects.
8///
9/// Mirrors Java's `ChooseSourceEffect.java`.
10/// - `Choices$` — filter for valid sources (default: Permanent on battlefield).
11///
12/// # Card script examples
13/// ```text
14/// A:SP$ ChooseSource | Choices$ Permanent
15/// ```
16/// Struct form of this effect so it can participate in the
17/// `SpellAbilityEffect` trait hierarchy — mirrors Java's
18/// `ChooseSourceEffect` class extending `SpellAbilityEffect`.
19#[manabrew_engine_macros::spell_effect(ChooseSourceEffect)]
20fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
21    let controller = sa.activating_player;
22    let choices_filter = sa
23        .ir
24        .choices
25        .clone()
26        .unwrap_or_else(|| "Permanent".to_string());
27    let choices_selector = sa.ir.choices_selector.as_ref();
28
29    let player_ids = ctx.game.player_order.clone();
30    let mut valid: Vec<CardId> = Vec::new();
31
32    for &pid in &player_ids {
33        let zone_cards = ctx.game.cards_in_zone(ZoneType::Battlefield, pid).to_vec();
34        for cid in zone_cards {
35            if matches_valid_cards_for_sa(
36                ctx.game,
37                sa,
38                ctx.game.card(cid),
39                choices_selector,
40                &choices_filter,
41            ) {
42                valid.push(cid);
43            }
44        }
45    }
46
47    if valid.is_empty() {
48        return;
49    }
50
51    let chosen = ctx.agents[controller.index()].choose_cards_for_effect(controller, &valid, 1, 1);
52
53    if let Some(&chosen_id) = chosen.first() {
54        if let Some(source_id) = sa.source {
55            ctx.game.card_mut(source_id).add_chosen_card(chosen_id);
56        }
57    }
58}