Skip to main content

manabrew_engine/trigger/
trigger_counter_added_once.rs

1use serde::{Deserialize, Serialize};
2
3use crate::event::RunParams;
4use crate::game::GameState;
5use crate::spellability::SpellAbility;
6use crate::trigger::TriggerType;
7
8use super::trigger::TriggerBehavior;
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct TriggerCounterAddedOnce {
12    pub valid_card: Option<crate::parsing::CompiledSelector>,
13    pub counter_type: Option<String>,
14    pub valid_source: Option<crate::parsing::CompiledSelector>,
15}
16
17impl TriggerCounterAddedOnce {
18    pub fn parse(
19        valid_card: Option<crate::parsing::CompiledSelector>,
20        counter_type: Option<String>,
21        valid_source: Option<crate::parsing::CompiledSelector>,
22    ) -> Box<dyn TriggerBehavior> {
23        Box::new(Self {
24            valid_card,
25            counter_type,
26            valid_source,
27        })
28    }
29}
30
31#[typetag::serde]
32impl TriggerBehavior for TriggerCounterAddedOnce {
33    fn trigger_type(&self) -> TriggerType {
34        TriggerType::CounterAddedOnce
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 !trigger.matches_optional_valid_card_filter(&self.valid_card, params.card, game) {
45            return false;
46        }
47        if !super::trigger::Trigger::matches_counter_type_filter(
48            &self.counter_type,
49            &params.counter_type,
50        ) {
51            return false;
52        }
53        if let Some(filter) = &self.valid_source {
54            if filter.is_any_of(["You"]) {
55                return params.cause_player == Some(host_controller);
56            }
57        }
58        true
59    }
60
61    fn set_triggering_objects(
62        &self,
63        _trigger: &super::trigger::Trigger,
64        sa: &mut SpellAbility,
65        params: &RunParams,
66        _game: &GameState,
67    ) {
68        if let Some(card) = params.card {
69            sa.set_triggering_object(crate::ability::AbilityKey::Card, card.0.to_string());
70        }
71        if let Some(p) = params.player {
72            sa.set_triggering_object(crate::ability::AbilityKey::Player, p.0.to_string());
73        }
74        if let Some(amount) = params.counter_amount {
75            sa.set_triggering_object(crate::ability::AbilityKey::Amount, amount.to_string());
76        }
77    }
78
79    fn get_important_stack_objects(
80        &self,
81        _trigger: &super::trigger::Trigger,
82        sa: &SpellAbility,
83    ) -> String {
84        let target = sa
85            .trigger_objects
86            .get(&crate::ability::AbilityKey::Card)
87            .or(sa.trigger_objects.get(&crate::ability::AbilityKey::Player));
88        format!(
89            "AddedOnce: {}, Amount: {}",
90            target.cloned().unwrap_or_default(),
91            sa.trigger_objects
92                .get(&crate::ability::AbilityKey::Amount)
93                .cloned()
94                .unwrap_or_default()
95        )
96    }
97}