Skip to main content

nil_core/infrastructure/building/prefecture/
mod.rs

1// Copyright (C) Call of Nil contributors
2// SPDX-License-Identifier: AGPL-3.0-only
3
4#[cfg(test)]
5mod tests;
6
7pub mod build_catalog;
8pub mod build_queue;
9
10use crate::check_total_resource_ratio;
11use crate::infrastructure::building::{BuildingId, BuildingLevel};
12use crate::infrastructure::queue::InfrastructureQueue;
13use crate::infrastructure::requirements::InfrastructureRequirements;
14use crate::ranking::score::Score;
15use crate::resources::cost::{Cost, ResourceRatio};
16use crate::resources::maintenance::MaintenanceRatio;
17use crate::resources::workforce::Workforce;
18use build_queue::{PrefectureBuildOrder, PrefectureBuildQueue};
19use nil_core_macros::Building;
20use serde::{Deserialize, Serialize};
21use std::ops::Not;
22
23#[derive(Building, Clone, Debug, Deserialize, Serialize)]
24#[serde(rename_all = "camelCase")]
25pub struct Prefecture {
26  level: BuildingLevel,
27  enabled: bool,
28  build_queue: PrefectureBuildQueue,
29}
30
31impl Prefecture {
32  pub const ID: BuildingId = BuildingId::Prefecture;
33
34  pub const MIN_LEVEL: BuildingLevel = BuildingLevel::new(1);
35  pub const MAX_LEVEL: BuildingLevel = BuildingLevel::new(30);
36
37  pub const MIN_COST: Cost = Cost::new(1000);
38  pub const MAX_COST: Cost = Cost::new(150_000);
39
40  pub const WOOD_RATIO: ResourceRatio = ResourceRatio::new(0.3);
41  pub const STONE_RATIO: ResourceRatio = ResourceRatio::new(0.5);
42  pub const IRON_RATIO: ResourceRatio = ResourceRatio::new(0.2);
43  pub const MAINTENANCE_RATIO: MaintenanceRatio = MaintenanceRatio::new(0.005);
44
45  pub const MIN_WORKFORCE: Workforce = Workforce::new(1);
46  pub const MAX_WORKFORCE: Workforce = Workforce::new(50);
47
48  pub const MIN_SCORE: Score = Score::new(10);
49  pub const MAX_SCORE: Score = Score::new(1978);
50
51  pub const INFRASTRUCTURE_REQUIREMENTS: InfrastructureRequirements =
52    InfrastructureRequirements::none();
53
54  pub fn build_queue(&self) -> &PrefectureBuildQueue {
55    &self.build_queue
56  }
57
58  pub(crate) fn build_queue_mut(&mut self) -> &mut PrefectureBuildQueue {
59    &mut self.build_queue
60  }
61
62  #[must_use]
63  pub(crate) fn process_queue(&mut self) -> Option<Vec<PrefectureBuildOrder>> {
64    if self.enabled {
65      let orders = self.build_queue.process(self.workforce());
66      orders.is_empty().not().then_some(orders)
67    } else {
68      None
69    }
70  }
71
72  #[inline]
73  pub fn workforce(&self) -> Workforce {
74    Workforce::from(self.level)
75  }
76
77  pub fn resolve_level(&self, building: BuildingId, current_level: BuildingLevel) -> BuildingLevel {
78    self
79      .build_queue
80      .resolve_level(building, current_level)
81  }
82
83  pub fn turns_in_build_queue(&self) -> Option<f64> {
84    if self.level > 0u8 {
85      let turn = self.workforce();
86      let in_queue = self.build_queue.sum_pending_workforce();
87      Some(f64::from(in_queue) / f64::from(turn))
88    } else {
89      None
90    }
91  }
92}
93
94impl Default for Prefecture {
95  fn default() -> Self {
96    Self {
97      level: BuildingLevel::new(1),
98      enabled: true,
99      build_queue: PrefectureBuildQueue::default(),
100    }
101  }
102}
103
104check_total_resource_ratio!(
105  Prefecture::WOOD_RATIO,
106  Prefecture::STONE_RATIO,
107  Prefecture::IRON_RATIO,
108);