manabrew_engine/spellability/
target_choices.rs1use std::collections::HashMap;
7
8use serde::{Deserialize, Serialize};
9
10use crate::ids::{CardId, PlayerId};
11
12#[derive(Debug, Clone, Default, Serialize, Deserialize)]
15pub struct TargetChoices {
16 pub target_player: Option<PlayerId>,
17 #[serde(default)]
18 pub additional_target_players: Vec<PlayerId>,
19 pub target_card: Option<CardId>,
20 #[serde(default)]
23 pub target_card_zone_timestamp: Option<u64>,
24 pub target_stack_entry: Option<u32>,
26 #[serde(skip)]
29 pub divided_map: HashMap<CardId, i32>,
30}
31
32impl TargetChoices {
33 pub fn all_target_players(&self) -> Vec<PlayerId> {
35 let mut players = Vec::new();
36 if let Some(player) = self.target_player {
37 players.push(player);
38 }
39 for &player in &self.additional_target_players {
40 if !players.contains(&player) {
41 players.push(player);
42 }
43 }
44 players
45 }
46
47 pub fn all_target_cards(&self) -> Vec<CardId> {
49 let mut cards = Vec::new();
50 if let Some(card) = self.target_card {
51 cards.push(card);
52 }
53 for &card in self.divided_map.keys() {
54 if !cards.contains(&card) {
55 cards.push(card);
56 }
57 }
58 cards
59 }
60
61 pub fn add(&mut self, target_card: Option<CardId>, target_player: Option<PlayerId>) {
64 if let Some(card) = target_card {
65 self.target_card = Some(card);
66 self.target_card_zone_timestamp = None;
68 }
69 if let Some(player) = target_player {
70 if self.target_player.is_none() {
71 self.target_player = Some(player);
72 } else if self.target_player != Some(player)
73 && !self.additional_target_players.contains(&player)
74 {
75 self.additional_target_players.push(player);
76 }
77 }
78 }
79
80 pub fn remove(&mut self, card: CardId) {
83 if self.target_card == Some(card) {
84 self.target_card = None;
85 self.target_card_zone_timestamp = None;
86 }
87 self.divided_map.remove(&card);
88 }
89
90 pub fn remove_all(&mut self) {
93 self.target_card = None;
94 self.target_card_zone_timestamp = None;
95 self.target_player = None;
96 self.additional_target_players.clear();
97 self.target_stack_entry = None;
98 self.divided_map.clear();
99 }
100
101 pub fn contains(&self, card: CardId) -> bool {
104 self.target_card == Some(card) || self.divided_map.contains_key(&card)
105 }
106
107 pub fn replace_target_card(&mut self, old: CardId, new: CardId) {
110 if self.target_card == Some(old) {
111 self.target_card = Some(new);
112 self.target_card_zone_timestamp = None;
113 if let Some(amount) = self.divided_map.remove(&old) {
115 self.divided_map.insert(new, amount);
116 }
117 } else if let Some(amount) = self.divided_map.remove(&old) {
118 self.divided_map.insert(new, amount);
119 }
120 }
121
122 pub fn for_each_controller_changed(&self) -> Vec<PlayerId> {
127 Vec::new()
128 }
129
130 pub fn add_divided_allocation(&mut self, card: CardId, amount: i32) {
133 self.divided_map.insert(card, amount);
134 }
135
136 pub fn copy(&self) -> Self {
139 self.clone()
140 }
141}