Skip to main content

manabrew_engine/staticability/
static_ability_block_restrict.rs

1use forge_foundation::ZoneType;
2
3use crate::card::{valid_filter, Card};
4use crate::ids::PlayerId;
5use crate::parsing::CompiledSelector;
6use crate::staticability::StaticMode;
7
8pub fn block_restrict_num(cards: &[Card], defender: PlayerId) -> i32 {
9    let mut num = i32::MAX;
10    for source in cards.iter().filter(|c| c.zone == ZoneType::Battlefield) {
11        for st_ab in source
12            .static_abilities
13            .iter()
14            .filter(|sa| sa.check_mode(&StaticMode::BlockRestrict))
15        {
16            let valid = st_ab.ir.valid_defender.as_ref();
17            if !matches_valid_player(valid, defender, source.controller) {
18                continue;
19            }
20            let n = st_ab
21                .ir
22                .max_blockers
23                .as_deref()
24                .map(|s| eval_amount(source, s))
25                .unwrap_or(1);
26            if n < num {
27                num = n;
28            }
29        }
30    }
31    num
32}
33
34fn matches_valid_player(
35    valid: Option<&CompiledSelector>,
36    player: PlayerId,
37    source_controller: PlayerId,
38) -> bool {
39    valid_filter::matches_valid_player_selector_opt(valid, player, source_controller)
40}
41
42fn eval_amount(source: &Card, expr: &str) -> i32 {
43    if let Ok(n) = expr.parse::<i32>() {
44        return n;
45    }
46    if let Some(svar) = source.svars.get(expr) {
47        if let Ok(n) = svar.parse::<i32>() {
48            return n;
49        }
50        let mut sa =
51            crate::spellability::SpellAbility::new_empty(Some(source.id), source.controller);
52        sa.kicked = false;
53        return crate::ability::effects::evaluate_svar(svar, &sa);
54    }
55    1
56}