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::world::World;
11
12impl World {
13 pub fn request_maneuver(&mut self, request: ManeuverRequest) -> Result<ManeuverId> {
14 self
15 .military
16 .collapse_armies_in(request.origin);
17
18 let origin_ruler = self.city(request.origin)?.owner().clone();
19 let Some(army) = self
20 .military
21 .armies_mut_at(request.origin)
22 .iter_mut()
23 .find(|army| army.is_idle_and_owned_by(&origin_ruler))
24 .filter(|army| army.has_enough_personnel(&request.personnel))
25 else {
26 return Err(Error::InsufficientUnits);
27 };
28
29 let Some(remaining) = army
30 .personnel()
31 .checked_sub(&request.personnel)
32 else {
33 return Err(Error::InsufficientUnits);
34 };
35
36 let army_id = army.id();
37 let army_owner = army.owner().clone();
38 *army.personnel_mut() = request.personnel;
39
40 let army_speed = army.speed();
44
45 let (id, maneuver) = Maneuver::builder()
46 .army(army_id)
47 .kind(request.kind)
48 .origin(request.origin)
49 .destination(request.destination)
50 .speed(army_speed)
51 .build()?;
52
53 self.military.insert_maneuver(maneuver);
54
55 let army = self.military.army_mut(army_id)?;
56 *army.state_mut() = ArmyState::with_maneuver(id);
57
58 if !remaining.is_empty() {
61 Army::builder()
62 .owner(army_owner)
63 .personnel(remaining)
64 .build()
65 .spawn(&mut self.military, request.origin);
66 }
67
68 let sender_player = origin_ruler.player();
69 let target_player = self.city(request.destination)?.player();
70
71 if let Some(sender_player) = sender_player {
72 self.emit_military_updated(sender_player.clone());
73 }
74
75 if let Some(target_player) = target_player
76 && sender_player.is_none_or(|it| it != &target_player)
77 {
78 self.emit_military_updated(target_player);
79 }
80
81 Ok(id)
82 }
83
84 #[inline]
85 pub fn collapse_armies(&mut self) {
86 self.military.collapse_armies();
87 }
88}