Skip to main content

nil_core/world/infrastructure/
storage.rs

1// Copyright (C) Call of Nil contributors
2// SPDX-License-Identifier: AGPL-3.0-only
3
4use crate::continent::index::ContinentKey;
5use crate::error::Result;
6use crate::infrastructure::storage::{
7  OverallStorageCapacity,
8  OverallStorageCapacityWeight,
9  StorageCapacity,
10  StorageCapacityWeight,
11};
12use crate::resources::ResourceId;
13use crate::ruler::Ruler;
14use crate::world::World;
15
16impl World {
17  pub fn get_storage_capacity<R>(&self, ruler: R) -> Result<OverallStorageCapacity>
18  where
19    R: Into<Ruler>,
20  {
21    let stats = &self.stats.infrastructure;
22    self
23      .continent
24      .cities_of(ruler)
25      .try_fold(OverallStorageCapacity::default(), |mut acc, city| {
26        acc += city.storage_capacity(stats)?;
27        Ok(acc)
28      })
29  }
30
31  pub fn get_storage_capacity_for<R>(
32    &self,
33    ruler: R,
34    resource: ResourceId,
35  ) -> Result<StorageCapacity>
36  where
37    R: Into<Ruler>,
38  {
39    let capacity = self.get_storage_capacity(ruler)?;
40    match resource {
41      ResourceId::Food => Ok(capacity.silo),
42      ResourceId::Iron | ResourceId::Stone | ResourceId::Wood => Ok(capacity.warehouse),
43    }
44  }
45
46  pub fn get_storage_capacity_weight<K>(&self, key: K) -> Result<OverallStorageCapacityWeight>
47  where
48    K: ContinentKey,
49  {
50    let stats = &self.stats.infrastructure;
51    let city = key
52      .into_coord(self.continent.size())
53      .and_then(|coord| self.city(coord))?;
54
55    let capacity = city.storage_capacity(stats)?;
56    let total = self.get_storage_capacity(city.owner().clone())?;
57
58    let mut weight = OverallStorageCapacityWeight::new(city.coord());
59
60    macro_rules! set_weight {
61      ($($storage:ident),+ $(,)?) => {
62        $(
63          if *total.$storage > 0u32 {
64            let value = f64::from(capacity.$storage) / f64::from(total.$storage);
65            weight.$storage = StorageCapacityWeight::from(value);
66            debug_assert!(value.is_normal());
67          }
68        )+
69      };
70    }
71
72    set_weight!(silo, warehouse);
73
74    Ok(weight)
75  }
76}