Skip to main content

manabrew_engine/staticability/
static_ability_tap_power_value.rs

1use crate::card::{valid_filter, Card};
2use crate::spellability::{matches_valid_sa, SpellAbility};
3use crate::staticability::StaticMode;
4
5/// Check if a card should use toughness as its tap power value.
6pub fn with_toughness(cards: &[Card], card: &Card, sa: Option<&SpellAbility>) -> bool {
7    for source in cards.iter().filter(|c| c.zone.is_static_ability_source()) {
8        for st_ab in source
9            .static_abilities
10            .iter()
11            .filter(|s| s.check_mode(&StaticMode::TapPowerValue) && s.zones_check(source.zone))
12        {
13            match st_ab.ir.value_text.as_deref() {
14                Some(val) if val.eq_ignore_ascii_case("Toughness") => {}
15                _ => continue,
16            }
17
18            // ValidCard$
19            if !valid_filter::matches_valid_card_selector_opt(
20                st_ab.ir.valid_card.as_ref(),
21                card,
22                source,
23            ) {
24                continue;
25            }
26
27            if let Some(valid_sa) = st_ab.ir.valid_sa.as_deref() {
28                let Some(sa) = sa else {
29                    continue;
30                };
31                if !matches_valid_sa(valid_sa, sa, source, ability_host(cards, sa)) {
32                    continue;
33                }
34            }
35
36            return true;
37        }
38    }
39    false
40}
41
42/// Get the modifier for tap power value.
43pub fn get_mod(cards: &[Card], card: &Card, sa: Option<&SpellAbility>) -> i32 {
44    let mut total = 0;
45    for source in cards.iter().filter(|c| c.zone.is_static_ability_source()) {
46        for st_ab in source
47            .static_abilities
48            .iter()
49            .filter(|s| s.check_mode(&StaticMode::TapPowerValue) && s.zones_check(source.zone))
50        {
51            // ValidCard$
52            if !valid_filter::matches_valid_card_selector_opt(
53                st_ab.ir.valid_card.as_ref(),
54                card,
55                source,
56            ) {
57                continue;
58            }
59
60            if let Some(valid_sa) = st_ab.ir.valid_sa.as_deref() {
61                let Some(sa) = sa else {
62                    continue;
63                };
64                if !matches_valid_sa(valid_sa, sa, source, ability_host(cards, sa)) {
65                    continue;
66                }
67            }
68
69            if let Some(val) = st_ab.ir.value_text.as_deref() {
70                total += val.parse::<i32>().unwrap_or(0);
71            }
72        }
73    }
74    total
75}
76
77fn ability_host<'a>(cards: &'a [Card], sa: &SpellAbility) -> Option<&'a Card> {
78    let source = sa.source?;
79    cards.get(source.index())
80}