Skip to main content

nil_core/world/resources/
mod.rs

1// Copyright (C) Call of Nil contributors
2// SPDX-License-Identifier: AGPL-3.0-only
3
4#[cfg(test)]
5mod tests;
6
7use crate::continent::ContinentKey;
8use crate::error::Result;
9use crate::resources::maintenance::MaintenanceBalance;
10use crate::resources::prelude::Maintenance;
11use crate::resources::{Food, Resources};
12use crate::ruler::Ruler;
13use crate::world::World;
14use nil_num::ops::MulCeil;
15
16impl World {
17  pub(crate) fn get_maintenance<R>(&self, ruler: R) -> Result<Maintenance>
18  where
19    R: Into<Ruler>,
20  {
21    let ruler: Ruler = ruler.into();
22    let stats = self.stats().infrastructure();
23    let mut maintenance = self.military().maintenance_of(ruler.clone());
24
25    for city in self.continent().cities_of(ruler) {
26      maintenance += city.maintenance(&stats)?;
27    }
28
29    Ok(maintenance)
30  }
31
32  pub(crate) fn get_maintenance_balance<R>(&self, ruler: R) -> Result<MaintenanceBalance>
33  where
34    R: Into<Ruler>,
35  {
36    let ruler: Ruler = ruler.into();
37    let stats = self.stats().infrastructure();
38
39    let mut production = Food::new(0);
40    let mut maintenance = self.military().maintenance_of(ruler.clone());
41
42    for city in self.continent().cities_of(ruler) {
43      maintenance += city.maintenance(&stats)?;
44      production += city.round_production(&stats)?.food;
45    }
46
47    Ok(MaintenanceBalance { maintenance, production })
48  }
49
50  pub fn get_weighted_resources<K>(&self, key: K) -> Result<Resources>
51  where
52    K: ContinentKey,
53  {
54    let city = key
55      .into_coord(self.continent.size())
56      .and_then(|coord| self.city(coord))?;
57
58    let capacity_weight = self.get_storage_capacity_weight(city.coord())?;
59    let mut resources = self.ruler(city.owner())?.resources().clone();
60
61    macro_rules! apply {
62      ($res:ident, $storage:ident) => {
63        let weight = f64::from(capacity_weight.$storage);
64        resources.$res = resources.$res.mul_ceil(weight).into();
65      };
66    }
67
68    apply!(food, silo);
69    apply!(iron, warehouse);
70    apply!(stone, warehouse);
71    apply!(wood, warehouse);
72
73    Ok(resources)
74  }
75
76  pub(crate) fn take_resources_of<R>(&mut self, ruler: R, resources: &mut Resources) -> Result<()>
77  where
78    R: Into<Ruler>,
79  {
80    let mut ruler = self.ruler_mut(&ruler.into())?;
81    let current_resources = ruler.take_resources();
82    if let Some(res) = current_resources.checked_sub(resources) {
83      *ruler.resources_mut() = res;
84    } else {
85      *resources = current_resources;
86    }
87
88    Ok(())
89  }
90}