manabrew_engine/trigger/
trigger_ir.rs1use 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}