manabrew_engine/replacement/
replace_add_counter.rs1use crate::card::Card;
6use crate::game::GameState;
7use crate::ids::CardId;
8
9use super::replacement_effect::ReplacementEffect;
10use super::replacement_handler::ReplacementEvent;
11use super::replacement_result::ReplacementResult;
12use super::replacement_type::ReplacementType;
13use crate::card_trait_base::CardTrait;
14
15pub fn has_any_in_counter_map(effect: &ReplacementEffect, counter_type: Option<&str>) -> bool {
23 match effect.ir.valid_counter_type_text.as_deref() {
24 None => true, Some(valid) => match counter_type {
26 None => false, Some(ct) => valid.split(',').any(|v| v.trim().eq_ignore_ascii_case(ct)),
28 },
29 }
30}
31
32pub fn mode_check(effect: &ReplacementEffect, event: &ReplacementType) -> bool {
39 match event {
40 ReplacementType::AddCounter => true,
41 ReplacementType::Moved => effect.ir.counter_map,
42 _ => false,
43 }
44}
45
46pub fn can_replace(
48 effect: &ReplacementEffect,
49 event: &ReplacementEvent,
50 game: &GameState,
51 source_card: &Card,
52) -> bool {
53 if effect.event != ReplacementType::AddCounter {
54 return false;
55 }
56 let (target, is_effect) = match event {
57 ReplacementEvent::AddCounter {
58 target, is_effect, ..
59 } => (*target, *is_effect),
60 _ => return false,
61 };
62 if effect.ir.effect_only && !is_effect {
64 return false;
65 }
66 let target_card = &game.cards[target.index()];
67 if let Some(valid) = effect.ir.valid_card_selector.as_ref() {
68 if !effect.matches_compiled_valid_card(valid, target_card, source_card) {
69 return false;
70 }
71 }
72 if let Some(valid_ct) = effect.ir.valid_counter_type_text.as_deref() {
74 let counter_type = match event {
75 ReplacementEvent::AddCounter { counter_type, .. } => counter_type,
76 _ => return false,
77 };
78 let expected = crate::ability::effects::parse_counter_type(valid_ct);
79 if *counter_type != expected {
80 return false;
81 }
82 }
83 true
84}
85
86pub fn execute(
88 effect: &ReplacementEffect,
89 event: &mut ReplacementEvent,
90 _game: &GameState,
91 _source_card_id: CardId,
92) -> ReplacementResult {
93 let count = match event {
94 ReplacementEvent::AddCounter { count, .. } => count,
95 _ => return ReplacementResult::NotReplaced,
96 };
97 if let Some(replace) = effect.replace_with() {
98 match replace {
99 "AddOneMoreCounter" | "AddOneMoreCounters" => {
100 *count += 1;
101 return ReplacementResult::Updated;
102 }
103 "AddTwiceCounters" | "DoubleCounters" => {
104 *count *= 2;
105 return ReplacementResult::Updated;
106 }
107 _ => {
108 if let Some(result) =
110 super::replacement_handler::execute_replace_with_numeric_update(
111 effect,
112 event,
113 _game,
114 _source_card_id,
115 "CounterNum",
116 )
117 {
118 return result;
119 }
120 eprintln!(
121 "[WARN] Unknown replacement mode in AddCounter event: {:?}",
122 replace
123 );
124 }
125 }
126 }
127 ReplacementResult::Replaced
128}