Skip to main content

manabrew_engine/trigger/
trigger_ir.rs

1use forge_foundation::{PhaseType, ZoneType};
2
3use crate::card::valid_filter::CardTraitRequirementsIr;
4use crate::parsing::{keys, CompiledSelector, Params};
5use crate::spellability::TriggerCondition;
6
7#[derive(Debug, Clone, Default)]
8pub struct TriggerIr {
9    pub card_trait_requirements: CardTraitRequirementsIr,
10    pub trigger_description: Option<String>,
11    pub phase_count: Option<i32>,
12    pub player_turn: bool,
13    pub not_player_turn: bool,
14    pub opponent_turn: bool,
15    pub first_upkeep: bool,
16    pub first_upkeep_this_game: bool,
17    pub first_combat: bool,
18    pub turn_count: Option<u32>,
19    pub a_player_has_more_life_than_each_other: bool,
20    pub a_player_has_most_cards_in_hand: bool,
21    pub condition: Option<TriggerCondition>,
22    pub chapter: Option<i32>,
23    pub origin_zone: Option<ZoneType>,
24    pub destination_zone: Option<ZoneType>,
25    pub origin_zones: Vec<ZoneType>,
26    pub destination_zones: Vec<ZoneType>,
27    pub excluded_origins: Vec<ZoneType>,
28    pub excluded_destinations: Vec<ZoneType>,
29    pub valid_attackers_selector: Option<CompiledSelector>,
30    pub valid_card_selector: Option<CompiledSelector>,
31    pub valid_cause_selector: Option<CompiledSelector>,
32    pub not_this_ability: bool,
33    pub fizzle: Option<bool>,
34    pub condition_you_cast_this_turn: Option<String>,
35    pub check_on_triggered_card: Option<String>,
36    pub resolved_limit: Option<u32>,
37    pub activation_limit: Option<u32>,
38    pub game_activation_limit: Option<u32>,
39    pub valid_phases: Option<Vec<PhaseType>>,
40    pub activator_this_turn_cast: Option<String>,
41}
42
43impl TriggerIr {
44    pub fn from_params(params: &Params) -> Self {
45        Self {
46            card_trait_requirements: CardTraitRequirementsIr::from_key_values(
47                params.iter(),
48                params.selector_untracked(keys::IS_PRESENT).cloned(),
49                params.selector_untracked("IsPresent2").cloned(),
50            ),
51            trigger_description: params.get(keys::TRIGGER_DESCRIPTION).map(str::to_string),
52            phase_count: params.get("PhaseCount").and_then(|v| v.parse().ok()),
53            player_turn: params.has(keys::PLAYER_TURN),
54            not_player_turn: params.has("NotPlayerTurn"),
55            opponent_turn: params.has("OpponentTurn"),
56            first_upkeep: params.has("FirstUpkeep"),
57            first_upkeep_this_game: params.has("FirstUpkeepThisGame"),
58            first_combat: params.has("FirstCombat"),
59            turn_count: params.get("TurnCount").and_then(|v| v.parse().ok()),
60            a_player_has_more_life_than_each_other: params.has("APlayerHasMoreLifeThanEachOther"),
61            a_player_has_most_cards_in_hand: params.has("APlayerHasMostCardsInHand"),
62            condition: params.get(keys::CONDITION).map(TriggerCondition::parse),
63            chapter: params.get("Chapter").and_then(|v| v.parse().ok()),
64            origin_zone: params
65                .get(keys::ORIGIN)
66                .and_then(|s| s.split(',').next())
67                .and_then(|s| ZoneType::from_str_compat(s.trim())),
68            destination_zone: params
69                .get(keys::DESTINATION)
70                .and_then(|s| s.split(',').next())
71                .and_then(|s| ZoneType::from_str_compat(s.trim())),
72            origin_zones: params
73                .get(keys::ORIGIN)
74                .map(|raw| {
75                    raw.split(',')
76                        .filter_map(|s| ZoneType::from_str_compat(s.trim()))
77                        .collect()
78                })
79                .unwrap_or_default(),
80            destination_zones: params
81                .get(keys::DESTINATION)
82                .map(|raw| {
83                    raw.split(',')
84                        .filter_map(|s| ZoneType::from_str_compat(s.trim()))
85                        .collect()
86                })
87                .unwrap_or_default(),
88            excluded_origins: params
89                .get("ExcludedOrigins")
90                .map(|raw| {
91                    raw.split(',')
92                        .filter_map(|s| ZoneType::from_str_compat(s.trim()))
93                        .collect()
94                })
95                .unwrap_or_default(),
96            excluded_destinations: params
97                .get("ExcludedDestinations")
98                .map(|raw| {
99                    raw.split(',')
100                        .filter_map(|s| ZoneType::from_str_compat(s.trim()))
101                        .collect()
102                })
103                .unwrap_or_default(),
104            valid_attackers_selector: params.selector_cloned("ValidAttackers"),
105            valid_card_selector: params.selector_cloned(keys::VALID_CARD),
106            valid_cause_selector: params.selector_cloned(keys::VALID_CAUSE),
107            not_this_ability: params.has("NotThisAbility"),
108            fizzle: params
109                .get("Fizzle")
110                .map(|value| value.eq_ignore_ascii_case("true")),
111            condition_you_cast_this_turn: params
112                .get("ConditionYouCastThisTurn")
113                .map(str::to_string),
114            check_on_triggered_card: params.get("CheckOnTriggeredCard").map(str::to_string),
115            resolved_limit: params.get("ResolvedLimit").and_then(|v| v.parse().ok()),
116            activation_limit: params.get("ActivationLimit").and_then(|v| v.parse().ok()),
117            game_activation_limit: params
118                .get(keys::GAME_ACTIVATION_LIMIT)
119                .and_then(|v| v.parse().ok()),
120            valid_phases: params.get(keys::PHASE).map(|phase_text| {
121                phase_text
122                    .split(',')
123                    .filter_map(|token| PhaseType::from_script_name(token.trim()))
124                    .collect::<Vec<_>>()
125            }),
126            activator_this_turn_cast: params
127                .get(keys::ACTIVATOR_THIS_TURN_CAST)
128                .map(str::to_string),
129        }
130    }
131}