manabrew_engine/trigger/
trigger_countered.rs1use 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 TriggerCountered {
12 pub valid_card: Option<crate::parsing::CompiledSelector>,
13 pub valid_cause: Option<crate::parsing::CompiledSelector>,
14 pub valid_sa: Option<String>,
15}
16
17impl TriggerCountered {
18 pub fn parse(
19 valid_card: Option<crate::parsing::CompiledSelector>,
20 valid_cause: Option<crate::parsing::CompiledSelector>,
21 valid_sa: Option<String>,
22 ) -> Box<dyn TriggerBehavior> {
23 Box::new(Self {
24 valid_card,
25 valid_cause,
26 valid_sa,
27 })
28 }
29}
30
31#[typetag::serde]
32impl TriggerBehavior for TriggerCountered {
33 fn trigger_type(&self) -> TriggerType {
34 TriggerType::Countered
35 }
36
37 fn perform_test(
38 &self,
39 trigger: &super::trigger::Trigger,
40 params: &RunParams,
41 game: &GameState,
42 ) -> bool {
43 if !trigger.matches_optional_valid_card_filter(&self.valid_card, params.card, game) {
44 return false;
45 }
46 if let Some(filter) = &self.valid_cause {
47 if let Some(cause) = params.cause.as_ref() {
48 let Some(cause_card) = cause.source else {
49 return false;
50 };
51 if !trigger.matches_valid_card_filter(filter, cause_card, game) {
52 return false;
53 }
54 } else {
55 return false;
56 }
57 }
58 if let Some(filter) = &self.valid_sa {
59 if let Some(countered_sa) = params.spell_ability.as_ref() {
60 if !trigger.matches_valid_sa_filter(filter, countered_sa) {
61 return false;
62 }
63 } else {
64 return false;
65 }
66 }
67 true
68 }
69
70 fn set_triggering_objects(
71 &self,
72 _trigger: &super::trigger::Trigger,
73 sa: &mut SpellAbility,
74 params: &RunParams,
75 _game: &GameState,
76 ) {
77 if let Some(card) = params.card {
79 sa.set_triggering_object(crate::ability::AbilityKey::Card, card.0.to_string());
80 }
81 }
84
85 fn get_important_stack_objects(
86 &self,
87 _trigger: &super::trigger::Trigger,
88 sa: &SpellAbility,
89 ) -> String {
90 format!(
92 "Countered: {}, Cause: {}",
93 sa.get_triggering_object(crate::ability::AbilityKey::Card)
94 .unwrap_or(""),
95 sa.get_triggering_object(crate::ability::AbilityKey::Cause)
96 .unwrap_or("")
97 )
98 }
99}