nil_core/world/cheat/
city.rs1use crate::bail_if_cheats_are_not_allowed;
5use crate::city::City;
6use crate::city::stability::Stability;
7use crate::continent::field::Field;
8use crate::continent::index::ContinentKey;
9use crate::error::{Error, Result};
10use crate::ruler::Ruler;
11use crate::world::World;
12use itertools::Itertools;
13
14pub fn fill_world(world: &mut World, ruler: &Ruler) -> Result<()> {
15 bail_if_cheats_are_not_allowed!(world);
16
17 let size = world.continent.size();
18 let coords = world
19 .continent
20 .enumerate_fields()
21 .filter(|(_, field)| field.is_empty())
22 .filter_map(|(idx, _)| idx.to_coord(size).ok())
23 .collect_vec();
24
25 for coord in coords {
26 spawn_city_with_emit(world)
27 .ruler(ruler)
28 .key(coord)
29 .emit(false)
30 .call()?;
31
32 world.emit_public_city(coord)?;
33 }
34
35 if let Some(player) = ruler.player() {
36 world.emit_player(player.clone())?;
37 }
38
39 Ok(())
40}
41
42pub fn get_city(world: &World, key: impl ContinentKey) -> Result<&City> {
43 bail_if_cheats_are_not_allowed!(world);
44 world.continent.city(key)
45}
46
47pub fn set_stability(
48 world: &mut World,
49 key: impl ContinentKey,
50 stability: Stability,
51) -> Result<()> {
52 bail_if_cheats_are_not_allowed!(world);
53
54 let coord = key.into_coord(world.continent.size())?;
55 let city = world.city_mut(coord)?;
56 *city.stability_mut() = stability;
57
58 world.emit_city(coord)?;
59
60 Ok(())
61}
62
63pub fn spawn_city(world: &mut World, ruler: &Ruler, key: impl ContinentKey) -> Result<()> {
64 spawn_city_with_emit(world)
65 .ruler(ruler)
66 .key(key)
67 .emit(true)
68 .call()
69}
70
71#[bon::builder]
72fn spawn_city_with_emit(
73 #[builder(start_fn)] world: &mut World,
74 ruler: &Ruler,
75 key: impl ContinentKey,
76 emit: bool,
77) -> Result<()> {
78 bail_if_cheats_are_not_allowed!(world);
79
80 let coord = key.into_coord(world.continent.size())?;
81 let city = City::builder(coord)
82 .name(ruler)
83 .owner(ruler.clone())
84 .build();
85
86 let field = world.continent.field_mut(coord)?;
87 if field.is_empty() {
88 *field = Field::City { city: Box::new(city) };
89
90 if emit {
91 world.emit_public_city(coord)?;
92 if let Some(player) = ruler.player() {
93 world.emit_player(player.clone())?;
94 }
95 }
96 } else {
97 return Err(Error::FieldNotEmpty(coord));
98 }
99
100 Ok(())
101}