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