mod behavior;
mod maneuver;
use crate::error::Result;
use crate::player::{Player, PlayerId};
use crate::resources::prelude::*;
use crate::round::Round;
use crate::ruler::Ruler;
use crate::world::World;
use std::collections::HashMap;
impl World {
#[inline]
pub fn round(&self) -> &Round {
&self.round
}
pub fn start_round(&mut self) -> Result<()> {
let ids = self
.player_manager
.active_players()
.map(Player::id);
self.round.start(ids)?;
self.emit_round_updated()?;
Ok(())
}
pub fn set_player_ready(&mut self, player: &PlayerId, is_ready: bool) -> Result<()> {
self.round.set_ready(player, is_ready);
if self.round.is_done() {
self.next_round(true)?;
} else {
self.emit_round_updated()?;
}
Ok(())
}
pub fn dangerously_end_round(&mut self, emit: bool) -> Result<()> {
self.round.dangerously_set_done();
self.next_round(emit)?;
Ok(())
}
pub(super) fn next_round(&mut self, emit: bool) -> Result<()> {
let ids = self
.player_manager
.active_players()
.map(Player::id);
self.round.next(ids)?;
self.prepare_next_round()?;
self.consume_pending_save()?;
if emit {
self.emit_round_updated()?;
}
if let Some(on_next_round) = self.on_next_round.clone() {
on_next_round.call(self);
}
Ok(())
}
fn prepare_next_round(&mut self) -> Result<()> {
self.update_resources()?;
self.process_city_queues();
self.collapse_armies();
self.process_maneuvers()?;
self.update_ranking()?;
self.process_npc_behavior()?;
self.report_manager.prune();
Ok(())
}
fn update_resources(&mut self) -> Result<()> {
let stats = self.stats.infrastructure.as_ref();
let mut diff: HashMap<Ruler, ResourcesDiff> = HashMap::new();
for city in self.continent.cities() {
let owner = city.owner().clone();
let resources = diff.entry(owner).or_default();
*resources += city.round_production(stats)?;
resources.food -= city.maintenance(stats)?;
}
for (ruler, mut resources) in diff {
resources.food -= self.military.maintenance_of(ruler.clone());
let capacity = self.get_storage_capacity(ruler.clone())?;
self
.ruler_mut(&ruler)?
.resources_mut()
.add_within_capacity(&resources, &capacity);
}
Ok(())
}
fn process_city_queues(&mut self) {
let config = self.config();
for city in self.continent.cities_mut() {
let coord = city.coord();
let owner = city.owner().clone();
let infrastructure = city.infrastructure_mut();
infrastructure.process_prefecture_build_queue(&config);
macro_rules! process_recruit_queue {
($building:ident) => {
paste::paste! {
if let Some(personnel) = infrastructure.[<process_ $building:snake _recruit_queue>](&config) {
self.military.spawn(coord, owner.clone(), personnel);
}
}
};
}
process_recruit_queue!(Academy);
process_recruit_queue!(Stable);
process_recruit_queue!(Workshop);
}
}
}