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