1use crate::ethic::Ethics;
5use crate::npc::bot::{Bot, BotId};
6use crate::npc::precursor::{Precursor, PrecursorId};
7use crate::player::{Player, PlayerId};
8use crate::resources::Resources;
9use crate::resources::influence::Influence;
10use serde::{Deserialize, Serialize};
11use std::mem;
12use strum::EnumIs;
13
14#[derive(Clone, Debug, PartialEq, Eq, Hash, Deserialize, Serialize, EnumIs)]
15#[serde(tag = "kind", rename_all = "kebab-case")]
16#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
17pub enum Ruler {
18 Bot { id: BotId },
19 Player { id: PlayerId },
20 Precursor { id: PrecursorId },
21}
22
23impl Ruler {
24 #[inline]
25 pub fn bot(&self) -> Option<&BotId> {
26 if let Self::Bot { id } = self { Some(id) } else { None }
27 }
28
29 #[inline]
30 pub fn player(&self) -> Option<&PlayerId> {
31 if let Self::Player { id } = self { Some(id) } else { None }
32 }
33
34 #[inline]
35 pub fn precursor(&self) -> Option<PrecursorId> {
36 if let Self::Precursor { id } = self { Some(*id) } else { None }
37 }
38
39 pub fn is_bot_and<F>(&self, f: F) -> bool
40 where
41 F: FnOnce(&BotId) -> bool,
42 {
43 self.bot().is_some_and(f)
44 }
45
46 pub fn is_player_and<F>(&self, f: F) -> bool
47 where
48 F: FnOnce(&PlayerId) -> bool,
49 {
50 self.player().is_some_and(f)
51 }
52
53 pub fn is_precursor_and<F>(&self, f: F) -> bool
54 where
55 F: FnOnce(PrecursorId) -> bool,
56 {
57 self.precursor().is_some_and(f)
58 }
59}
60
61impl From<&Bot> for Ruler {
62 fn from(bot: &Bot) -> Self {
63 Self::Bot { id: bot.id() }
64 }
65}
66
67impl From<BotId> for Ruler {
68 fn from(id: BotId) -> Self {
69 Self::Bot { id }
70 }
71}
72
73impl From<&BotId> for Ruler {
74 fn from(id: &BotId) -> Self {
75 Self::Bot { id: id.clone() }
76 }
77}
78
79impl From<&Player> for Ruler {
80 fn from(player: &Player) -> Self {
81 Self::Player { id: player.id() }
82 }
83}
84
85impl From<PlayerId> for Ruler {
86 fn from(id: PlayerId) -> Self {
87 Self::Player { id }
88 }
89}
90
91impl From<&PlayerId> for Ruler {
92 fn from(id: &PlayerId) -> Self {
93 Self::Player { id: id.clone() }
94 }
95}
96
97impl From<&dyn Precursor> for Ruler {
98 fn from(precursor: &dyn Precursor) -> Self {
99 Self::Precursor { id: precursor.id() }
100 }
101}
102
103impl<T: Precursor> From<&T> for Ruler {
104 fn from(precursor: &T) -> Self {
105 Self::Precursor { id: precursor.id() }
106 }
107}
108
109impl From<PrecursorId> for Ruler {
110 fn from(id: PrecursorId) -> Self {
111 Self::Precursor { id }
112 }
113}
114
115impl From<RulerRef<'_>> for Ruler {
116 fn from(ruler: RulerRef<'_>) -> Self {
117 match ruler {
118 RulerRef::Bot(bot) => Self::Bot { id: bot.id() },
119 RulerRef::Player(player) => Self::Player { id: player.id() },
120 RulerRef::Precursor(precursor) => Self::Precursor { id: precursor.id() },
121 }
122 }
123}
124
125impl From<RulerRefMut<'_>> for Ruler {
126 fn from(ruler: RulerRefMut<'_>) -> Self {
127 match ruler {
128 RulerRefMut::Bot(bot) => Self::Bot { id: bot.id() },
129 RulerRefMut::Player(player) => Self::Player { id: player.id() },
130 RulerRefMut::Precursor(precursor) => Self::Precursor { id: precursor.id() },
131 }
132 }
133}
134
135pub enum RulerRef<'a> {
136 Bot(&'a Bot),
137 Player(&'a Player),
138 Precursor(&'a dyn Precursor),
139}
140
141impl<'a> RulerRef<'a> {
142 pub fn ethics(&self) -> Option<&'a Ethics> {
143 match self {
144 Self::Bot(bot) => Some(bot.ethics()),
145 Self::Player(..) => None,
146 Self::Precursor(precursor) => Some(precursor.ethics()),
147 }
148 }
149
150 pub fn resources(&'a self) -> &'a Resources {
151 match self {
152 Self::Bot(bot) => bot.resources(),
153 Self::Player(player) => player.resources(),
154 Self::Precursor(precursor) => precursor.resources(),
155 }
156 }
157
158 #[inline]
159 pub fn has_resources(&self, resources: &Resources) -> bool {
160 self
161 .resources()
162 .checked_sub(resources)
163 .is_some()
164 }
165
166 pub fn influence(&self) -> Influence {
167 match self {
168 Self::Bot(bot) => bot.influence(),
169 Self::Player(player) => player.influence(),
170 Self::Precursor(precursor) => precursor.influence(),
171 }
172 }
173}
174
175impl<'a> From<&'a Bot> for RulerRef<'a> {
176 fn from(bot: &'a Bot) -> Self {
177 Self::Bot(bot)
178 }
179}
180
181impl<'a> From<&'a Player> for RulerRef<'a> {
182 fn from(player: &'a Player) -> Self {
183 Self::Player(player)
184 }
185}
186
187impl<'a> From<&'a dyn Precursor> for RulerRef<'a> {
188 fn from(precursor: &'a dyn Precursor) -> Self {
189 Self::Precursor(precursor)
190 }
191}
192
193pub enum RulerRefMut<'a> {
194 Bot(&'a mut Bot),
195 Player(&'a mut Player),
196 Precursor(&'a mut dyn Precursor),
197}
198
199impl<'a> RulerRefMut<'a> {
200 pub fn resources_mut(&'a mut self) -> &'a mut Resources {
201 match self {
202 Self::Bot(bot) => bot.resources_mut(),
203 Self::Player(player) => player.resources_mut(),
204 Self::Precursor(precursor) => precursor.resources_mut(),
205 }
206 }
207
208 pub fn take_resources(&mut self) -> Resources {
209 match self {
210 Self::Bot(bot) => mem::take(bot.resources_mut()),
211 Self::Player(player) => mem::take(player.resources_mut()),
212 Self::Precursor(precursor) => mem::take(precursor.resources_mut()),
213 }
214 }
215}
216
217impl<'a> From<&'a mut Bot> for RulerRefMut<'a> {
218 fn from(bot: &'a mut Bot) -> Self {
219 Self::Bot(bot)
220 }
221}
222
223impl<'a> From<&'a mut Player> for RulerRefMut<'a> {
224 fn from(player: &'a mut Player) -> Self {
225 Self::Player(player)
226 }
227}
228
229impl<'a> From<&'a mut dyn Precursor> for RulerRefMut<'a> {
230 fn from(precursor: &'a mut dyn Precursor) -> Self {
231 Self::Precursor(precursor)
232 }
233}