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