nil_core/world/npc/
bot.rs1use crate::city::City;
5use crate::error::Result;
6use crate::infrastructure::Infrastructure;
7use crate::npc::bot::{Bot, BotId, BotManager};
8use crate::with_random_level;
9use crate::world::World;
10use num_traits::ToPrimitive;
11use tap::Conv;
12
13impl World {
14 #[inline]
15 pub fn bot_manager(&self) -> &BotManager {
16 &self.bot_manager
17 }
18
19 #[inline]
20 pub fn bot(&self, id: &BotId) -> Result<&Bot> {
21 self.bot_manager.bot(id)
22 }
23
24 #[inline]
25 pub(crate) fn bot_mut(&mut self, id: &BotId) -> Result<&mut Bot> {
26 self.bot_manager.bot_mut(id)
27 }
28
29 pub fn bots(&self) -> impl Iterator<Item = &Bot> {
30 self.bot_manager.bots()
31 }
32
33 pub(crate) fn spawn_bots(&mut self) -> Result<()> {
34 let size = self.continent.size();
35 let density = self.config().bot_density();
36 let amount = (f64::from(size) * density)
37 .floor()
38 .max(0.0)
39 .to_usize()
40 .unwrap_or_else(|| usize::from(size).saturating_mul(2));
41
42 let advanced_start_ratio = self
43 .config
44 .bot_advanced_start_ratio()
45 .conv::<f64>();
46
47 for name in nil_namegen::generate(amount) {
48 let infrastructure = if rand::random::<f64>() > advanced_start_ratio {
49 Infrastructure::default()
50 } else {
51 Infrastructure::builder()
52 .farm(with_random_level!(Farm, 1, 10))
53 .iron_mine(with_random_level!(IronMine, 1, 10))
54 .prefecture(with_random_level!(Prefecture, 1, 5))
55 .quarry(with_random_level!(Quarry, 1, 10))
56 .sawmill(with_random_level!(Sawmill, 1, 10))
57 .silo(with_random_level!(Silo, 10, 15))
58 .warehouse(with_random_level!(Warehouse, 10, 15))
59 .build()
60 };
61
62 self.spawn_bot(name, infrastructure)?;
63 }
64
65 Ok(())
66 }
67
68 pub(crate) fn spawn_bot(
69 &mut self,
70 id: impl Into<BotId>,
71 infrastructure: Infrastructure,
72 ) -> Result<BotId> {
73 let id: BotId = id.into();
74 self.bot_manager.manage(id.clone())?;
75
76 let (coord, field) = self.find_spawn_point()?;
77
78 *field = City::builder(coord)
79 .name(id.as_ref())
80 .owner(id.clone())
81 .infrastructure(infrastructure)
82 .build()
83 .into();
84
85 Ok(id)
86 }
87}