Skip to main content

nil_core/world/cheat/
infrastructure.rs

1// Copyright (C) Call of Nil contributors
2// SPDX-License-Identifier: AGPL-3.0-only
3
4use crate::bail_if_cheats_are_not_allowed;
5use crate::continent::coord::Coord;
6use crate::continent::index::ContinentKey;
7use crate::error::Result;
8use crate::infrastructure::Infrastructure;
9use crate::infrastructure::building::BuildingId;
10use crate::infrastructure::building::r#impl::academy::recruit_queue::AcademyRecruitQueue;
11use crate::infrastructure::building::r#impl::prefecture::build_queue::PrefectureBuildQueue;
12use crate::infrastructure::building::r#impl::stable::recruit_queue::StableRecruitQueue;
13use crate::infrastructure::building::level::BuildingLevel;
14use crate::infrastructure::queue::InfrastructureQueue;
15use crate::infrastructure::storage::OverallStorageCapacity;
16use crate::ruler::Ruler;
17use crate::world::World;
18use itertools::Itertools;
19use strum::IntoEnumIterator;
20use tap::Pipe;
21
22pub fn get_academy_recruit_queue(
23  world: &World,
24  key: impl ContinentKey,
25) -> Result<AcademyRecruitQueue> {
26  bail_if_cheats_are_not_allowed!(world);
27  world
28    .city(key)?
29    .infrastructure()
30    .academy()
31    .recruit_queue()
32    .clone()
33    .pipe(Ok)
34}
35
36pub fn get_academy_recruit_queues(
37  world: &World,
38  coords: &[Coord],
39  filter_empty: bool,
40) -> Result<Vec<(Coord, AcademyRecruitQueue)>> {
41  bail_if_cheats_are_not_allowed!(world);
42  coords
43    .iter()
44    .copied()
45    .map(|coord| Ok((coord, get_academy_recruit_queue(world, coord)?)))
46    .filter_ok(|(_, queue)| !filter_empty || !queue.is_empty())
47    .try_collect()
48}
49
50pub fn get_all_academy_recruit_queues(
51  world: &World,
52  filter_empty: bool,
53) -> Result<Vec<(Coord, AcademyRecruitQueue)>> {
54  bail_if_cheats_are_not_allowed!(world);
55  world
56    .continent
57    .city_coords()
58    .map(|coord| Ok((coord, get_academy_recruit_queue(world, coord)?)))
59    .filter_ok(|(_, queue)| !filter_empty || !queue.is_empty())
60    .try_collect()
61}
62
63pub fn get_all_prefecture_build_queues(
64  world: &World,
65  filter_empty: bool,
66) -> Result<Vec<(Coord, PrefectureBuildQueue)>> {
67  bail_if_cheats_are_not_allowed!(world);
68  world
69    .continent
70    .city_coords()
71    .map(|coord| Ok((coord, get_prefecture_build_queue(world, coord)?)))
72    .filter_ok(|(_, queue)| !filter_empty || !queue.is_empty())
73    .try_collect()
74}
75
76pub fn get_all_stable_recruit_queues(
77  world: &World,
78  filter_empty: bool,
79) -> Result<Vec<(Coord, StableRecruitQueue)>> {
80  bail_if_cheats_are_not_allowed!(world);
81  world
82    .continent
83    .city_coords()
84    .map(|coord| Ok((coord, get_stable_recruit_queue(world, coord)?)))
85    .filter_ok(|(_, queue)| !filter_empty || !queue.is_empty())
86    .try_collect()
87}
88
89pub fn get_infrastructure(world: &World, key: impl ContinentKey) -> Result<Infrastructure> {
90  bail_if_cheats_are_not_allowed!(world);
91  world
92    .city(key)?
93    .infrastructure()
94    .clone()
95    .pipe(Ok)
96}
97
98pub fn get_prefecture_build_queue(
99  world: &World,
100  key: impl ContinentKey,
101) -> Result<PrefectureBuildQueue> {
102  bail_if_cheats_are_not_allowed!(world);
103  world
104    .city(key)?
105    .infrastructure()
106    .prefecture()
107    .build_queue()
108    .clone()
109    .pipe(Ok)
110}
111
112pub fn get_prefecture_build_queues(
113  world: &World,
114  coords: &[Coord],
115  filter_empty: bool,
116) -> Result<Vec<(Coord, PrefectureBuildQueue)>> {
117  bail_if_cheats_are_not_allowed!(world);
118  coords
119    .iter()
120    .copied()
121    .map(|coord| Ok((coord, get_prefecture_build_queue(world, coord)?)))
122    .filter_ok(|(_, queue)| !filter_empty || !queue.is_empty())
123    .try_collect()
124}
125
126pub fn get_stable_recruit_queue(
127  world: &World,
128  key: impl ContinentKey,
129) -> Result<StableRecruitQueue> {
130  bail_if_cheats_are_not_allowed!(world);
131  world
132    .city(key)?
133    .infrastructure()
134    .stable()
135    .recruit_queue()
136    .clone()
137    .pipe(Ok)
138}
139
140pub fn get_stable_recruit_queues(
141  world: &World,
142  coords: &[Coord],
143  filter_empty: bool,
144) -> Result<Vec<(Coord, StableRecruitQueue)>> {
145  bail_if_cheats_are_not_allowed!(world);
146  coords
147    .iter()
148    .copied()
149    .map(|coord| Ok((coord, get_stable_recruit_queue(world, coord)?)))
150    .filter_ok(|(_, queue)| !filter_empty || !queue.is_empty())
151    .try_collect()
152}
153
154pub fn get_storage_capacity(world: &World, ruler: Ruler) -> Result<OverallStorageCapacity> {
155  bail_if_cheats_are_not_allowed!(world);
156  world.get_storage_capacity(ruler)
157}
158
159pub fn set_building_level(
160  world: &mut World,
161  key: impl ContinentKey,
162  id: BuildingId,
163  level: BuildingLevel,
164) -> Result<()> {
165  bail_if_cheats_are_not_allowed!(world);
166  let coord = key.into_coord(world.continent.size())?;
167  world.set_building_level(coord, id, level)?;
168  world.emit_city(coord)?;
169  Ok(())
170}
171
172pub fn set_max_infrastructure(world: &mut World, key: impl ContinentKey) -> Result<()> {
173  bail_if_cheats_are_not_allowed!(world);
174
175  let coord = key.into_coord(world.continent.size())?;
176  let infrastructure = world.city_mut(coord)?.infrastructure_mut();
177
178  for id in BuildingId::iter() {
179    let building = infrastructure.building_mut(id);
180    building.set_level(building.max_level());
181  }
182
183  world.emit_city(coord)?;
184
185  Ok(())
186}