nil_core/world/npc/
precursor.rs1use crate::city::City;
5use crate::error::Result;
6use crate::infrastructure::Infrastructure;
7use crate::npc::precursor::{self, Precursor, PrecursorId, PrecursorManager};
8use crate::world::World;
9use nil_num::roman::ToRoman;
10use rand::seq::IndexedRandom;
11
12impl World {
13 #[inline]
14 pub fn precursor_manager(&self) -> &PrecursorManager {
15 &self.precursor_manager
16 }
17
18 #[inline]
19 pub fn precursor(&self, id: PrecursorId) -> &dyn Precursor {
20 self.precursor_manager.precursor(id)
21 }
22
23 #[inline]
24 pub(crate) fn precursor_mut(&mut self, id: PrecursorId) -> &mut dyn Precursor {
25 self.precursor_manager.precursor_mut(id)
26 }
27
28 pub fn precursors(&self) -> impl Iterator<Item = &dyn Precursor> {
29 self.precursor_manager.precursors()
30 }
31
32 pub(crate) fn spawn_precursors(&mut self) -> Result<()> {
33 self.spawn_precursor_cities(PrecursorId::A)?;
34 self.spawn_precursor_cities(PrecursorId::B)?;
35 Ok(())
36 }
37
38 fn spawn_precursor_cities(&mut self, id: PrecursorId) -> Result<()> {
39 let size = self.continent.size();
40 let radius = precursor::initial_territory_radius(size);
41 let amount = precursor::initial_city_amount(size);
42 let mut coords = self
43 .precursor_manager
44 .precursor(id)
45 .origin()
46 .within_distance_inclusive(radius);
47
48 coords.retain(|coord| coord.is_within_continent(size));
49
50 for (idx, coord) in coords
51 .sample(&mut rand::rng(), amount.into())
52 .copied()
53 .enumerate()
54 {
55 let field = self.continent.field_mut(coord)?;
56 debug_assert!(field.is_empty());
57
58 let Some(ridx) = idx.saturating_add(1).to_roman() else { continue };
61
62 *field = City::builder(coord)
63 .name(format!("Precursor {id} {ridx}"))
64 .owner(id)
65 .infrastructure(Infrastructure::with_max_level())
66 .build()
67 .into();
68
69 let personnel = if idx.is_multiple_of(3) {
70 precursor::initial_offensive_personnel()
71 } else {
72 precursor::initial_defensive_personnel()
73 };
74
75 self.military.spawn(coord, id, personnel);
76 }
77
78 Ok(())
79 }
80}