#[cfg(test)]
mod tests;
pub mod build_catalog;
pub mod build_queue;
use crate::check_total_resource_ratio;
use crate::infrastructure::building::{BuildingId, BuildingLevel};
use crate::infrastructure::queue::InfrastructureQueue;
use crate::infrastructure::requirements::InfrastructureRequirements;
use crate::ranking::score::Score;
use crate::resources::cost::{Cost, ResourceRatio};
use crate::resources::maintenance::MaintenanceRatio;
use crate::resources::workforce::{Workforce, WorkforceSource};
use crate::world::config::WorldConfig;
use build_queue::{PrefectureBuildOrder, PrefectureBuildQueue};
use nil_core_macros::Building;
use serde::{Deserialize, Serialize};
#[derive(Building, Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
pub struct Prefecture {
level: BuildingLevel,
enabled: bool,
build_queue: PrefectureBuildQueue,
}
impl Prefecture {
pub const ID: BuildingId = BuildingId::Prefecture;
pub const MIN_LEVEL: BuildingLevel = BuildingLevel::new(1);
pub const MAX_LEVEL: BuildingLevel = BuildingLevel::new(30);
pub const MIN_COST: Cost = Cost::new(1_000);
pub const MAX_COST: Cost = Cost::new(150_000);
pub const FOOD_RATIO: ResourceRatio = ResourceRatio::new(0.0);
pub const IRON_RATIO: ResourceRatio = ResourceRatio::new(0.2);
pub const STONE_RATIO: ResourceRatio = ResourceRatio::new(0.5);
pub const WOOD_RATIO: ResourceRatio = ResourceRatio::new(0.3);
pub const MAINTENANCE_RATIO: MaintenanceRatio = MaintenanceRatio::new(0.005);
pub const MIN_WORKFORCE: Workforce = Workforce::new(1);
pub const MAX_WORKFORCE: Workforce = Workforce::new(50);
pub const MIN_SCORE: Score = Score::new(10);
pub const MAX_SCORE: Score = Score::new(1_978);
pub const INFRASTRUCTURE_REQUIREMENTS: InfrastructureRequirements =
InfrastructureRequirements::none();
pub fn build_queue(&self) -> &PrefectureBuildQueue {
&self.build_queue
}
pub(crate) fn build_queue_mut(&mut self) -> &mut PrefectureBuildQueue {
&mut self.build_queue
}
#[must_use]
pub(crate) fn process_queue(
&mut self,
config: &WorldConfig,
) -> Option<Vec<PrefectureBuildOrder>> {
if self.enabled {
let workforce = self.workforce(config);
let orders = self.build_queue.process(workforce);
(!orders.is_empty()).then_some(orders)
} else {
None
}
}
pub fn resolve_level(&self, building: BuildingId, current_level: BuildingLevel) -> BuildingLevel {
self
.build_queue
.resolve_level(building, current_level)
}
pub(crate) fn turns_in_build_queue(&self, config: &WorldConfig) -> Option<f64> {
if self.level > 0u8 {
let turn = self.workforce(config);
let in_queue = self.build_queue.sum_pending_workforce();
Some(f64::from(in_queue) / f64::from(turn))
} else {
None
}
}
}
impl WorkforceSource for Prefecture {}
impl Default for Prefecture {
fn default() -> Self {
Self {
level: BuildingLevel::new(1),
enabled: true,
build_queue: PrefectureBuildQueue::default(),
}
}
}
check_total_resource_ratio!(
Prefecture::FOOD_RATIO,
Prefecture::IRON_RATIO,
Prefecture::STONE_RATIO,
Prefecture::WOOD_RATIO
);