manabrew_engine/spellability/
spell_ability_condition.rs1use forge_foundation::ZoneType;
7use serde::{Deserialize, Serialize};
8
9use crate::game::GameState;
10use crate::parsing::{Params, ParsedParams};
11use crate::spellability::SpellAbility;
12
13use super::spell_ability_variables::SpellAbilityVariables;
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct SpellAbilityCondition {
20 pub variables: SpellAbilityVariables,
21}
22
23impl Default for SpellAbilityCondition {
24 fn default() -> Self {
25 Self {
26 variables: SpellAbilityVariables::new(),
27 }
28 }
29}
30
31impl SpellAbilityCondition {
32 pub fn new() -> Self {
34 Self::default()
35 }
36
37 pub fn set_conditions(&mut self, params: &Params) {
40 self.set_conditions_from(|key| params.get(key));
41 }
42
43 pub fn set_conditions_parsed(&mut self, params: &ParsedParams<'_>) {
44 self.set_conditions_from(|key| params.get(key));
45 }
46
47 fn set_conditions_from<'a, F>(&mut self, get: F)
48 where
49 F: Fn(&str) -> Option<&'a str>,
50 {
51 let is_true = |key| get(key).is_some_and(|value| value.eq_ignore_ascii_case("True"));
52
53 if let Some(phases_str) = get("ConditionPhases") {
55 for phase_name in phases_str.split(',') {
56 if let Some(phase) =
57 forge_foundation::PhaseType::from_script_name(phase_name.trim())
58 {
59 self.variables.add_phase(phase);
60 }
61 }
62 }
63
64 if is_true("ConditionPlayerTurn") {
66 self.variables.set_player_turn(true);
67 }
68 if is_true("ConditionOpponentTurn") {
69 self.variables.set_opponent_turn(true);
70 }
71
72 if is_true("ConditionThreshold") {
74 self.variables.set_threshold(true);
75 }
76 if is_true("ConditionMetalcraft") {
77 self.variables.set_metalcraft(true);
78 }
79 if is_true("ConditionDelirium") {
80 self.variables.set_delirium(true);
81 }
82 if is_true("ConditionHellbent") {
83 self.variables.set_hellbent(true);
84 }
85 if is_true("ConditionRevolt") {
86 self.variables.set_revolt(true);
87 }
88 if is_true("ConditionDesert") {
89 self.variables.set_desert(true);
90 }
91 if is_true("ConditionBlessing") {
92 self.variables.set_blessing(true);
93 }
94 if is_true("ConditionSolved") {
95 self.variables.set_solved(true);
96 }
97
98 if let Some(present) = get("ConditionPresent") {
100 self.variables.set_is_present(Some(present.to_string()));
101 }
102 if let Some(compare) = get("ConditionCompare") {
103 self.variables
104 .set_present_compare(Some(compare.to_string()));
105 }
106 if let Some(zone_str) = get("ConditionPresentZone") {
107 match zone_str.to_lowercase().as_str() {
108 "battlefield" => self.variables.set_present_zone(ZoneType::Battlefield),
109 "graveyard" => self.variables.set_present_zone(ZoneType::Graveyard),
110 "hand" => self.variables.set_present_zone(ZoneType::Hand),
111 "exile" => self.variables.set_present_zone(ZoneType::Exile),
112 "library" => self.variables.set_present_zone(ZoneType::Library),
113 _ => {}
114 }
115 }
116 if let Some(defined) = get("ConditionDefined") {
117 self.variables
118 .set_present_defined(Some(defined.to_string()));
119 }
120 }
121
122 pub fn are_met(&self, game: &GameState, sa: &SpellAbility) -> bool {
125 let player = sa.activating_player;
126
127 let phases = self.variables.phases();
129 if !phases.is_empty() && !phases.contains(&game.turn.phase) {
130 return false;
131 }
132
133 let is_players_turn = game.turn.active_player == player;
135 if self.variables.player_turn() && !is_players_turn {
136 return false;
137 }
138 if self.variables.opponent_turn() && is_players_turn {
139 return false;
140 }
141
142 if self.variables.hellbent() && !game.player_has_hellbent(player) {
144 return false;
145 }
146
147 if self.variables.threshold() && !game.player_has_threshold(player) {
149 return false;
150 }
151
152 if self.variables.metalcraft() && !game.player_has_metalcraft(player) {
154 return false;
155 }
156
157 if self.variables.delirium() && !game.player_has_delirium(player) {
159 return false;
160 }
161
162 if self.variables.revolt() && !game.player_has_revolt(player) {
163 return false;
164 }
165
166 if self.variables.desert() && !game.player_has_desert(player) {
167 return false;
168 }
169
170 if self.variables.blessing() && !game.player_has_blessing(player) {
171 return false;
172 }
173
174 if let Some(ref _present_expr) = self.variables.is_present().map(|s| s.to_string()) {
176 let _zone = self.variables.present_zone();
180 let _compare = self.variables.present_compare().map(|s| s.to_string());
181 }
184
185 true
186 }
187}