nil_core/world/military/
mod.rs1#[cfg(test)]
5mod tests;
6
7use crate::error::{Error, Result};
8use crate::military::army::{Army, ArmyState};
9use crate::military::maneuver::{Maneuver, ManeuverId, ManeuverRequest};
10use crate::ruler::Ruler;
11use crate::world::World;
12
13impl World {
14 pub fn cancel_maneuver(&mut self, id: ManeuverId) -> Result<()> {
15 self.military.cancel_maneuver(id)?;
16 self.emit_military_to_maneuver_players(id)?;
17 Ok(())
18 }
19
20 #[inline]
21 pub fn collapse_armies(&mut self) {
22 self.military.collapse_armies();
23 }
24
25 pub fn is_maneuver_army_owned_by<R>(&self, id: ManeuverId, ruler: R) -> Result<bool>
26 where
27 R: Into<Ruler>,
28 {
29 let ruler: Ruler = ruler.into();
30 let army_id = self.military.maneuver(id)?.army();
31 let army_owner = self.military.army(army_id)?.owner();
32 Ok(ruler == *army_owner)
33 }
34
35 #[inline]
36 pub fn request_maneuver(&mut self, request: ManeuverRequest) -> Result<ManeuverId> {
37 self.request_maneuver_with_emit(request, true)
38 }
39
40 pub(crate) fn request_maneuver_with_emit(
41 &mut self,
42 request: ManeuverRequest,
43 emit: bool,
44 ) -> Result<ManeuverId> {
45 self
46 .military
47 .collapse_armies_in(request.origin);
48
49 let origin_ruler = self.city(request.origin)?.owner().clone();
50 let Some(army) = self
51 .military
52 .armies_mut_at(request.origin)
53 .iter_mut()
54 .find(|army| army.is_idle_and_owned_by(&origin_ruler))
55 .filter(|army| army.has_enough_personnel(&request.personnel))
56 else {
57 return Err(Error::InsufficientUnits);
58 };
59
60 let Some(remaining) = army
61 .personnel()
62 .checked_sub(&request.personnel)
63 else {
64 return Err(Error::InsufficientUnits);
65 };
66
67 let army_id = army.id();
68 let army_owner = army.owner().clone();
69 *army.personnel_mut() = request.personnel;
70
71 let army_speed = army.speed(&self.config);
75
76 let (id, maneuver) = Maneuver::builder()
77 .army(army_id)
78 .kind(request.kind)
79 .origin(request.origin)
80 .destination(request.destination)
81 .speed(army_speed)
82 .build()?;
83
84 self.military.insert_maneuver(maneuver);
85
86 let army = self.military.army_mut(army_id)?;
87 *army.state_mut() = ArmyState::with_maneuver(id);
88
89 if !remaining.is_empty() {
92 Army::builder()
93 .owner(army_owner)
94 .personnel(remaining)
95 .build()
96 .spawn(&mut self.military, request.origin);
97 }
98
99 if emit {
100 self.emit_military_to_maneuver_players(id)?;
101 }
102
103 Ok(id)
104 }
105}