Skip to main content

nil_core/world/infrastructure/building/
mod.rs

1// Copyright (C) Call of Nil contributors
2// SPDX-License-Identifier: AGPL-3.0-only
3
4mod academy;
5mod prefecture;
6mod stable;
7mod workshop;
8
9#[cfg(test)]
10mod tests;
11
12use crate::continent::coord::Coord;
13use crate::continent::index::ContinentKey;
14use crate::error::Result;
15use crate::infrastructure::prelude::{BuildingId, BuildingLevel};
16use crate::world::World;
17
18impl World {
19  /// Sets the level of a building.
20  ///
21  /// Does **NOT** emit any events.
22  pub(crate) fn set_building_level(
23    &mut self,
24    key: impl ContinentKey,
25    id: BuildingId,
26    level: BuildingLevel,
27  ) -> Result<()> {
28    self
29      .city_mut(key)?
30      .infrastructure_mut()
31      .building_mut(id)
32      .set_level(level);
33
34    Ok(())
35  }
36
37  pub fn toggle_building(&mut self, coord: Coord, id: BuildingId, enabled: bool) -> Result<()> {
38    self
39      .continent
40      .city_mut(coord)?
41      .infrastructure_mut()
42      .building_mut(id)
43      .toggle(enabled);
44
45    self.emit_city(coord)?;
46
47    Ok(())
48  }
49}
50
51#[doc(hidden)]
52#[macro_export]
53macro_rules! decl_world_recruit_order_fn {
54  ($building:ident) => {
55    paste::paste! {
56      impl World {
57        pub fn [<add_ $building:snake _recruit_order>](
58          &mut self,
59          req: &[<$building RecruitOrderRequest>]
60        ) -> Result<()> {
61          let ruler = self.city(req.coord)?.owner().clone();
62          let available_resources = self.ruler(&ruler)?.resources();
63
64          let order = self
65            .city_mut(req.coord)?
66            .infrastructure_mut()
67            .[<add_ $building:snake _recruit_order>](req, available_resources)?
68            .clone();
69
70          let mut ruler_ref = self.ruler_mut(&ruler)?;
71          let resources = ruler_ref.resources_mut();
72          *resources = resources
73            .checked_sub(order.resources())
74            .ok_or(Error::InsufficientResources)?;
75
76          self.emit_ruler(&ruler)?;
77          self.emit_city(req.coord)?;
78
79          Ok(())
80        }
81
82        pub fn [<cancel_ $building:snake _recruit_order>](
83          &mut self,
84          coord: Coord,
85          id: [<$building RecruitOrderId>]
86        ) -> Result<()> {
87          let city = self.city_mut(coord)?;
88          let order = city
89            .infrastructure_mut()
90            .[<cancel_ $building:snake _recruit_order>](id);
91
92          if let Some(order) = order {
93            let ruler = city.owner().clone();
94            let mut ruler_ref = self.ruler_mut(&ruler)?;
95            let resources = ruler_ref.resources_mut();
96            *resources += order.resources();
97
98            self.emit_ruler(&ruler)?;
99            self.emit_city(coord)?;
100          }
101
102          Ok(())
103        }
104      }
105    }
106  };
107}