Skip to main content

manabrew_engine/trigger/
trigger_phase.rs

1use serde::{Deserialize, Serialize};
2
3use crate::event::RunParams;
4use crate::game::GameState;
5use crate::parsing::{keys, Params};
6use crate::spellability::SpellAbility;
7use crate::trigger::TriggerType;
8
9use super::trigger::TriggerBehavior;
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct TriggerPhase {
13    pub phases: Vec<forge_foundation::PhaseType>,
14    pub valid_player: Option<crate::parsing::CompiledSelector>,
15}
16
17impl TriggerPhase {
18    pub fn parse(params: &Params) -> Box<dyn TriggerBehavior> {
19        let phases = params
20            .get(keys::PHASE)
21            .map(forge_foundation::PhaseType::parse_range)
22            .unwrap_or_default();
23        let valid_player = params.selector_cloned(keys::VALID_PLAYER);
24        Box::new(Self {
25            phases,
26            valid_player,
27        })
28    }
29}
30
31#[typetag::serde]
32impl TriggerBehavior for TriggerPhase {
33    fn trigger_type(&self) -> TriggerType {
34        TriggerType::Phase
35    }
36
37    fn perform_test(
38        &self,
39        trigger: &super::trigger::Trigger,
40        params: &RunParams,
41        game: &GameState,
42    ) -> bool {
43        let _host_controller = trigger.base.card_trait_base.host_controller(game);
44        if !self.phases.is_empty() {
45            let matches = params
46                .phase
47                .is_some_and(|phase| self.phases.contains(&phase));
48            if !matches {
49                return false;
50            }
51        }
52        trigger.matches_optional_valid_player_filter(&self.valid_player, params.player, game)
53    }
54
55    fn set_triggering_objects(
56        &self,
57        _trigger: &super::trigger::Trigger,
58        sa: &mut SpellAbility,
59        params: &RunParams,
60        _game: &GameState,
61    ) {
62        if let Some(p) = params.player {
63            sa.set_triggering_object(crate::ability::AbilityKey::Player, p.0.to_string());
64            sa.set_triggering_object(crate::ability::AbilityKey::TriggeredPlayer, p);
65        }
66    }
67
68    fn get_important_stack_objects(
69        &self,
70        _trigger: &super::trigger::Trigger,
71        sa: &SpellAbility,
72    ) -> String {
73        format!(
74            "Phase: {}",
75            sa.trigger_objects
76                .get(&crate::ability::AbilityKey::Player)
77                .map(|s| s.as_str())
78                .unwrap_or("")
79        )
80    }
81}