Skip to main content

nil_core/npc/bot/
mod.rs

1// Copyright (C) Call of Nil contributors
2// SPDX-License-Identifier: AGPL-3.0-only
3
4use crate::error::{Error, Result};
5use crate::ethic::Ethics;
6use crate::resources::Resources;
7use derive_more::{Display, From, Into};
8use serde::{Deserialize, Serialize};
9use std::borrow::{Borrow, Cow};
10use std::collections::HashMap;
11use std::ops::Deref;
12use std::sync::Arc;
13
14#[derive(Clone, Debug, Default, Deserialize, Serialize)]
15#[serde(rename_all = "camelCase")]
16pub struct BotManager(HashMap<BotId, Bot>);
17
18impl BotManager {
19  pub(crate) fn manage(&mut self, id: BotId) -> Result<()> {
20    if self.0.contains_key(&id) {
21      return Err(Error::BotAlreadySpawned(id));
22    }
23
24    self.0.insert(id.clone(), Bot::new(id));
25
26    Ok(())
27  }
28
29  pub fn bot(&self, id: &BotId) -> Result<&Bot> {
30    self
31      .0
32      .get(id)
33      .ok_or_else(|| Error::BotNotFound(id.clone()))
34  }
35
36  pub(crate) fn bot_mut(&mut self, id: &BotId) -> Result<&mut Bot> {
37    self
38      .0
39      .get_mut(id)
40      .ok_or_else(|| Error::BotNotFound(id.clone()))
41  }
42
43  pub fn bots(&self) -> impl Iterator<Item = &Bot> {
44    self.0.values()
45  }
46}
47
48#[derive(Clone, Debug, Deserialize, Serialize)]
49#[serde(rename_all = "camelCase")]
50pub struct Bot {
51  id: BotId,
52  ethics: Ethics,
53  resources: Resources,
54}
55
56impl Bot {
57  pub(crate) fn new(id: BotId) -> Self {
58    Self {
59      id,
60      ethics: Ethics::random(),
61      resources: Resources::BOT.clone(),
62    }
63  }
64
65  #[inline]
66  pub fn id(&self) -> BotId {
67    self.id.clone()
68  }
69
70  #[inline]
71  pub fn ethics(&self) -> &Ethics {
72    &self.ethics
73  }
74
75  #[inline]
76  pub(crate) fn ethics_mut(&mut self) -> &mut Ethics {
77    &mut self.ethics
78  }
79
80  #[inline]
81  pub fn resources(&self) -> &Resources {
82    &self.resources
83  }
84
85  pub(crate) fn resources_mut(&mut self) -> &mut Resources {
86    &mut self.resources
87  }
88}
89
90#[derive(Debug, Display, PartialEq, Eq, Hash, From, Into, Deserialize, Serialize)]
91#[from(String, &str, Arc<str>, Box<str>, Cow<'_, str>)]
92pub struct BotId(Arc<str>);
93
94impl Clone for BotId {
95  fn clone(&self) -> Self {
96    Self(Arc::clone(&self.0))
97  }
98}
99
100impl AsRef<str> for BotId {
101  fn as_ref(&self) -> &str {
102    self.0.as_str()
103  }
104}
105
106impl Deref for BotId {
107  type Target = str;
108
109  fn deref(&self) -> &Self::Target {
110    self.0.as_str()
111  }
112}
113
114impl Borrow<str> for BotId {
115  fn borrow(&self) -> &str {
116    self.0.as_str()
117  }
118}
119
120impl From<BotId> for String {
121  fn from(value: BotId) -> Self {
122    String::from(value.0.as_ref())
123  }
124}
125
126#[derive(Clone, Debug, Deserialize, Serialize)]
127#[serde(rename_all = "camelCase")]
128pub struct PublicBot {
129  id: BotId,
130}
131
132impl From<&Bot> for PublicBot {
133  fn from(bot: &Bot) -> Self {
134    Self { id: bot.id.clone() }
135  }
136}