manabrew_engine/trigger/
trigger_counter_player_added_all.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 TriggerCounterPlayerAddedAll {
12 pub valid_source: Option<crate::parsing::CompiledSelector>,
13 pub valid_object: Option<crate::parsing::CompiledSelector>,
14 pub valid_object_to_source: Option<crate::parsing::CompiledSelector>,
15}
16
17impl TriggerCounterPlayerAddedAll {
18 pub fn parse(
19 valid_source: Option<crate::parsing::CompiledSelector>,
20 valid_object: Option<crate::parsing::CompiledSelector>,
21 valid_object_to_source: Option<crate::parsing::CompiledSelector>,
22 ) -> Box<dyn TriggerBehavior> {
23 Box::new(Self {
24 valid_source,
25 valid_object,
26 valid_object_to_source,
27 })
28 }
29}
30
31#[typetag::serde]
32impl TriggerBehavior for TriggerCounterPlayerAddedAll {
33 fn trigger_type(&self) -> TriggerType {
34 TriggerType::CounterPlayerAddedAll
35 }
36
37 fn perform_test(
38 &self,
39 trigger: &super::trigger::Trigger,
40 params: &RunParams,
41 game: &GameState,
42 ) -> bool {
43 if let Some(filter) = &self.valid_source {
44 let source_ok = if let Some(cid) = params.source_card.or(params.card) {
45 trigger.matches_valid_card_filter(filter, cid, game)
46 } else if let Some(pid) = params.source_player {
47 trigger.matches_valid_player_filter(filter, pid, game)
48 } else {
49 false
50 };
51 if !source_ok {
52 return false;
53 }
54 }
55
56 if let Some(filter) = &self.valid_object {
57 let object_ok = if let Some(cid) = params.object_card {
58 trigger.matches_valid_card_filter(filter, cid, game)
59 } else if let Some(pid) = params.object_player {
60 trigger.matches_valid_player_filter(filter, pid, game)
61 } else {
62 false
63 };
64 if !object_ok {
65 return false;
66 }
67 }
68
69 if let Some(filter) = &self.valid_object_to_source {
70 let Some(source_player) = params.source_player else {
71 return false;
72 };
73 let object_ok = if let Some(pid) = params.object_player {
74 trigger.matches_valid_player_filter_with_controller(filter, pid, source_player)
75 } else if let Some(cid) = params.object_card {
76 let card_controller = game.card(cid).controller;
77 let raw_filter = filter.as_raw();
78 if raw_filter.contains("YouCtrl") {
79 card_controller == source_player
80 } else if raw_filter.contains("OppCtrl") {
81 card_controller != source_player
82 } else {
83 trigger.matches_valid_card_filter(filter, cid, game)
84 }
85 } else {
86 false
87 };
88 if !object_ok {
89 return false;
90 }
91 }
92
93 true
94 }
95
96 fn set_triggering_objects(
97 &self,
98 _trigger: &super::trigger::Trigger,
99 sa: &mut SpellAbility,
100 params: &RunParams,
101 _game: &GameState,
102 ) {
103 if let Some(source) = params.source_player {
106 sa.set_triggering_value(crate::ability::AbilityKey::Source, source);
107 } else if let Some(source) = params.source_card {
108 sa.set_triggering_value(crate::ability::AbilityKey::Source, source);
109 }
110 if let Some(obj) = params.object_card {
111 sa.set_triggering_value(crate::ability::AbilityKey::Object, obj);
112 } else if let Some(p) = params.object_player {
113 sa.set_triggering_value(crate::ability::AbilityKey::Object, p);
114 }
115 if let Some(counter_map) = params.counter_map.as_ref() {
116 sa.set_triggering_value(crate::ability::AbilityKey::CounterMap, counter_map.clone());
117 let amount: i32 = counter_map.values().sum();
118 sa.set_triggering_object(crate::ability::AbilityKey::Amount, amount.to_string());
119 }
120 }
121
122 fn get_important_stack_objects(
123 &self,
124 _trigger: &super::trigger::Trigger,
125 sa: &SpellAbility,
126 ) -> String {
127 format!(
128 "AddedOnce: {}: {}",
129 sa.trigger_objects
130 .get(&crate::ability::AbilityKey::Source)
131 .cloned()
132 .unwrap_or_default(),
133 sa.trigger_objects
134 .get(&crate::ability::AbilityKey::Object)
135 .cloned()
136 .unwrap_or_default()
137 )
138 }
139}