manabrew_engine/game_loop/
trigger_replacement_base.rs1use std::collections::HashMap;
2
3use forge_foundation::ZoneType;
4
5use crate::card::card_state::CardState;
6use crate::card_trait_base::CardTraitBase;
7use crate::core::Identifiable;
8use crate::game::GameState;
9use crate::ids::CardId;
10use crate::keyword::keyword_interface::KeywordInterface;
11use crate::spellability::SpellAbility;
12use serde::{Deserialize, Serialize};
13
14#[derive(Debug, Clone, Default, Serialize, Deserialize)]
19pub struct TriggerReplacementBase {
20 pub card_trait_base: CardTraitBase,
21 pub valid_host_zones: Option<Vec<ZoneType>>,
22 pub overriding_ability: Option<SpellAbility>,
23}
24
25impl Identifiable for TriggerReplacementBase {
26 fn id(&self) -> i32 {
27 self.card_trait_base.id()
28 }
29}
30
31impl TriggerReplacementBase {
32 pub fn set_host_card_id(&mut self, id: CardId) {
33 self.card_trait_base.set_host_card_id(id);
34 if let Some(overriding_ability) = self.overriding_ability.as_mut() {
35 overriding_ability.set_host_card_id(id);
36 }
37 }
38
39 pub fn set_keyword(&mut self, kw: KeywordInterface) {
40 self.card_trait_base.set_keyword(kw.clone());
41 if let Some(overriding_ability) = self.overriding_ability.as_mut() {
42 overriding_ability.set_keyword(kw);
43 }
44 }
45
46 pub fn set_card_state(&mut self, state: CardState) {
47 self.card_trait_base.set_card_state(&state);
48 if let Some(overriding_ability) = self.overriding_ability.as_mut() {
49 overriding_ability.set_card_state(&state);
50 }
51 }
52
53 pub fn get_active_zone(&self) -> Option<&[ZoneType]> {
54 self.valid_host_zones.as_deref()
55 }
56
57 pub fn set_active_zone(&mut self, zones: Vec<ZoneType>) {
58 self.valid_host_zones = Some(zones);
59 }
60
61 pub fn zones_check(&self, game: &GameState, host_card_zone: Option<ZoneType>) -> bool {
62 !self.card_trait_base.host_card(game).phased_out
63 && (self.valid_host_zones.is_none()
64 || self
65 .valid_host_zones
66 .as_ref()
67 .is_some_and(|zones| zones.is_empty())
68 || (host_card_zone.is_some()
69 && self
70 .valid_host_zones
71 .as_ref()
72 .is_some_and(|zones| zones.contains(&host_card_zone.unwrap()))))
73 }
74
75 pub fn get_overriding_ability(&self) -> Option<&SpellAbility> {
76 self.overriding_ability.as_ref()
77 }
78
79 pub fn set_overriding_ability(&mut self, overriding_ability: SpellAbility) {
80 self.overriding_ability = Some(overriding_ability);
81 if let Some(ability) = self.overriding_ability.as_mut() {
82 if let Some(host_card_id) = self.card_trait_base.get_host_card_id() {
83 ability.set_host_card_id(host_card_id);
84 }
85 if let Some(keyword) = self.card_trait_base.get_keyword().cloned() {
86 ability.set_keyword(keyword);
87 }
88 ability.set_intrinsic(self.card_trait_base.is_intrinsic());
89 }
90 }
91
92 pub fn ensure_ability(&mut self) -> Option<&mut SpellAbility> {
99 self.overriding_ability.as_mut()
100 }
101
102 pub fn change_text(&mut self) {
103 if !self.card_trait_base.is_intrinsic() {
104 return;
105 }
106 self.card_trait_base.change_text();
107
108 let changed_text_pairs = self.card_trait_base.changed_text_pairs();
109 if let Some(sa) = self.ensure_ability() {
110 sa.apply_text_changes(&changed_text_pairs);
111 }
112 }
113
114 pub fn change_text_intrinsic(
115 &mut self,
116 color_map: HashMap<String, String>,
117 type_map: HashMap<String, String>,
118 ) {
119 self.card_trait_base
120 .change_text_intrinsic(color_map.clone(), type_map.clone());
121
122 if let Some(sa) = self.ensure_ability() {
123 sa.apply_text_changes_intrinsic(&color_map, &type_map);
124 }
125 }
126}