Skip to main content

manabrew_engine/trigger/
trigger_attacker_blocked_once.rs

1use serde::{Deserialize, Serialize};
2
3use crate::{
4    ability::AbilityKey,
5    card_trait_base::{CardTrait, MatchValidTarget},
6    event::RunParams,
7    game::GameState,
8    parsing::{keys, Params},
9    spellability::SpellAbility,
10    trigger::TriggerType,
11};
12
13use super::trigger::TriggerBehavior;
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct TriggerAttackerBlockedOnce {
17    pub valid_card: Option<crate::parsing::CompiledSelector>,
18}
19
20impl TriggerAttackerBlockedOnce {
21    pub fn parse(params: &Params) -> Box<dyn TriggerBehavior> {
22        Box::new(Self {
23            valid_card: params.selector_cloned(keys::VALID_CARD),
24        })
25    }
26}
27
28#[typetag::serde]
29impl TriggerBehavior for TriggerAttackerBlockedOnce {
30    fn trigger_type(&self) -> TriggerType {
31        TriggerType::AttackerBlockedOnce
32    }
33
34    fn perform_test(
35        &self,
36        trigger: &super::trigger::Trigger,
37        params: &RunParams,
38        game: &GameState,
39    ) -> bool {
40        let Some(attacker_ids) = params.attacker_ids.as_ref() else {
41            return false;
42        };
43
44        let attackers: Vec<_> = attacker_ids
45            .iter()
46            .map(|&attacker_id| MatchValidTarget::Card(game.card(attacker_id)))
47            .collect();
48
49        self.valid_card.as_ref().is_none_or(|selector| {
50            trigger.matches_compiled_valid(
51                &MatchValidTarget::Iter(&attackers),
52                selector,
53                Some(trigger.base.card_trait_base.host_card(game)),
54            )
55        })
56    }
57
58    fn set_triggering_objects(
59        &self,
60        _trigger: &super::trigger::Trigger,
61        sa: &mut SpellAbility,
62        params: &RunParams,
63        _game: &GameState,
64    ) {
65        if let Some(attackers) = params.attacker_ids.as_ref() {
66            sa.set_triggering_object(AbilityKey::Attackers, attackers.clone());
67        }
68    }
69
70    fn get_important_stack_objects(
71        &self,
72        _trigger: &super::trigger::Trigger,
73        sa: &SpellAbility,
74    ) -> String {
75        format!(
76            "Attackers: {}",
77            sa.get_triggering_object(AbilityKey::Attackers)
78                .unwrap_or("")
79        )
80    }
81}