Skip to main content

nil_core/
ruler.rs

1// Copyright (C) Call of Nil contributors
2// SPDX-License-Identifier: AGPL-3.0-only
3
4use 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::{fmt, 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 fmt::Display for Ruler {
63  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64    match self {
65      Self::Bot { id } => id.fmt(f),
66      Self::Player { id } => id.fmt(f),
67      Self::Precursor { id } => id.fmt(f),
68    }
69  }
70}
71
72impl From<&Bot> for Ruler {
73  fn from(bot: &Bot) -> Self {
74    Self::Bot { id: bot.id() }
75  }
76}
77
78impl From<BotId> for Ruler {
79  fn from(id: BotId) -> Self {
80    Self::Bot { id }
81  }
82}
83
84impl From<&BotId> for Ruler {
85  fn from(id: &BotId) -> Self {
86    Self::Bot { id: id.clone() }
87  }
88}
89
90impl From<&Player> for Ruler {
91  fn from(player: &Player) -> Self {
92    Self::Player { id: player.id() }
93  }
94}
95
96impl From<PlayerId> for Ruler {
97  fn from(id: PlayerId) -> Self {
98    Self::Player { id }
99  }
100}
101
102impl From<&PlayerId> for Ruler {
103  fn from(id: &PlayerId) -> Self {
104    Self::Player { id: id.clone() }
105  }
106}
107
108impl From<&dyn Precursor> for Ruler {
109  fn from(precursor: &dyn Precursor) -> Self {
110    Self::Precursor { id: precursor.id() }
111  }
112}
113
114impl<T: Precursor> From<&T> for Ruler {
115  fn from(precursor: &T) -> Self {
116    Self::Precursor { id: precursor.id() }
117  }
118}
119
120impl From<PrecursorId> for Ruler {
121  fn from(id: PrecursorId) -> Self {
122    Self::Precursor { id }
123  }
124}
125
126impl From<RulerRef<'_>> for Ruler {
127  fn from(ruler: RulerRef<'_>) -> Self {
128    match ruler {
129      RulerRef::Bot(bot) => Self::Bot { id: bot.id() },
130      RulerRef::Player(player) => Self::Player { id: player.id() },
131      RulerRef::Precursor(precursor) => Self::Precursor { id: precursor.id() },
132    }
133  }
134}
135
136impl From<RulerRefMut<'_>> for Ruler {
137  fn from(ruler: RulerRefMut<'_>) -> Self {
138    match ruler {
139      RulerRefMut::Bot(bot) => Self::Bot { id: bot.id() },
140      RulerRefMut::Player(player) => Self::Player { id: player.id() },
141      RulerRefMut::Precursor(precursor) => Self::Precursor { id: precursor.id() },
142    }
143  }
144}
145
146#[derive(EnumIs, TryUnwrap, Unwrap)]
147#[try_unwrap(ref)]
148#[unwrap(ref)]
149pub enum RulerRef<'a> {
150  Bot(&'a Bot),
151  Player(&'a Player),
152  Precursor(&'a dyn Precursor),
153}
154
155impl<'a> RulerRef<'a> {
156  pub fn ethics(&self) -> Option<&'a Ethics> {
157    match self {
158      Self::Bot(bot) => Some(bot.ethics()),
159      Self::Player(..) => None,
160      Self::Precursor(precursor) => Some(precursor.ethics()),
161    }
162  }
163
164  pub fn resources(&'a self) -> &'a Resources {
165    match self {
166      Self::Bot(bot) => bot.resources(),
167      Self::Player(player) => player.resources(),
168      Self::Precursor(precursor) => precursor.resources(),
169    }
170  }
171
172  #[inline]
173  pub fn has_resources(&self, resources: &Resources) -> bool {
174    self
175      .resources()
176      .checked_sub(resources)
177      .is_some()
178  }
179
180  pub fn influence(&self) -> Influence {
181    match self {
182      Self::Bot(bot) => bot.influence(),
183      Self::Player(player) => player.influence(),
184      Self::Precursor(precursor) => precursor.influence(),
185    }
186  }
187}
188
189impl<'a> From<&'a Bot> for RulerRef<'a> {
190  fn from(bot: &'a Bot) -> Self {
191    Self::Bot(bot)
192  }
193}
194
195impl<'a> From<&'a Player> for RulerRef<'a> {
196  fn from(player: &'a Player) -> Self {
197    Self::Player(player)
198  }
199}
200
201impl<'a> From<&'a dyn Precursor> for RulerRef<'a> {
202  fn from(precursor: &'a dyn Precursor) -> Self {
203    Self::Precursor(precursor)
204  }
205}
206
207#[derive(EnumIs, TryUnwrap, Unwrap)]
208#[try_unwrap(ref)]
209#[unwrap(ref)]
210pub enum RulerRefMut<'a> {
211  Bot(&'a mut Bot),
212  Player(&'a mut Player),
213  Precursor(&'a mut dyn Precursor),
214}
215
216impl<'a> RulerRefMut<'a> {
217  pub fn resources_mut(&'a mut self) -> &'a mut Resources {
218    match self {
219      Self::Bot(bot) => bot.resources_mut(),
220      Self::Player(player) => player.resources_mut(),
221      Self::Precursor(precursor) => precursor.resources_mut(),
222    }
223  }
224
225  pub fn take_resources(&mut self) -> Resources {
226    match self {
227      Self::Bot(bot) => mem::take(bot.resources_mut()),
228      Self::Player(player) => mem::take(player.resources_mut()),
229      Self::Precursor(precursor) => mem::take(precursor.resources_mut()),
230    }
231  }
232}
233
234impl<'a> From<&'a mut Bot> for RulerRefMut<'a> {
235  fn from(bot: &'a mut Bot) -> Self {
236    Self::Bot(bot)
237  }
238}
239
240impl<'a> From<&'a mut Player> for RulerRefMut<'a> {
241  fn from(player: &'a mut Player) -> Self {
242    Self::Player(player)
243  }
244}
245
246impl<'a> From<&'a mut dyn Precursor> for RulerRefMut<'a> {
247  fn from(precursor: &'a mut dyn Precursor) -> Self {
248    Self::Precursor(precursor)
249  }
250}