Skip to content

Commit 9d3fc9c

Browse files
authored
feat: remove dead defender units after battle (#283)
* feat: remove dead defender units after battle * fix: floor `f64` mul
1 parent d046545 commit 9d3fc9c

File tree

17 files changed

+249
-104
lines changed

17 files changed

+249
-104
lines changed

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/nil-core/src/battle/mod.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
// Copyright (C) Call of Nil contributors
22
// SPDX-License-Identifier: AGPL-3.0-only
33

4-
mod luck;
4+
pub mod luck;
55

66
#[cfg(test)]
77
mod tests;
88

99
use crate::infrastructure::building::wall::WallStats;
1010
use crate::infrastructure::prelude::BuildingLevel;
1111
use crate::military::army::personnel::ArmyPersonnel;
12-
use crate::military::squad::{Squad, SquadSize};
12+
use crate::military::squad::Squad;
13+
use crate::military::squad::size::SquadSize;
1314
use crate::military::unit::UnitKind;
1415
use bon::Builder;
16+
use luck::Luck;
1517
use serde::{Deserialize, Serialize};
1618

17-
pub use luck::Luck;
18-
1919
#[derive(Builder)]
2020
pub struct Battle<'a> {
2121
#[builder(default)]
@@ -125,6 +125,22 @@ impl BattleResult {
125125
pub fn defender_surviving_personnel(&self) -> &ArmyPersonnel {
126126
&self.defender_surviving_personnel
127127
}
128+
129+
pub fn defender_surviving_personnel_ratio(&self) -> f64 {
130+
let total = self
131+
.defender_personnel
132+
.iter()
133+
.map(|squad| f64::from(squad.size()))
134+
.sum::<f64>();
135+
136+
let surviving = self
137+
.defender_surviving_personnel
138+
.iter()
139+
.map(|squad| f64::from(squad.size()))
140+
.sum::<f64>();
141+
142+
if total > 0.0 { surviving / total } else { 0.0 }
143+
}
128144
}
129145

130146
#[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)]

crates/nil-core/src/battle/tests.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ use crate::battle::{Battle, BattleWinner, DefensivePower, OffensivePower};
66
use crate::infrastructure::building::BuildingLevel;
77
use crate::infrastructure::stats::InfrastructureStats;
88
use crate::military::army::personnel::ArmyPersonnel;
9-
use crate::military::squad::{Squad, SquadSize};
9+
use crate::military::squad::Squad;
10+
use crate::military::squad::size::SquadSize;
1011
use crate::military::unit::UnitId;
1112
use crate::military::unit::UnitId::*;
1213
use std::assert_matches;

crates/nil-core/src/infrastructure/building/academy/recruit_queue.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use crate::continent::Coord;
55
use crate::decl_recruit_queue;
66
use crate::error::{Error, Result};
77
use crate::infrastructure::queue::{InfrastructureQueue, InfrastructureQueueOrder};
8-
use crate::military::squad::{Squad, SquadSize};
8+
use crate::military::squad::Squad;
9+
use crate::military::squad::size::SquadSize;
910
use crate::military::unit::{AcademyUnitId, UnitBox};
1011
use crate::resources::Resources;
1112
use crate::resources::workforce::Workforce;

crates/nil-core/src/infrastructure/building/stable/recruit_queue.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use crate::continent::Coord;
55
use crate::decl_recruit_queue;
66
use crate::error::{Error, Result};
77
use crate::infrastructure::queue::{InfrastructureQueue, InfrastructureQueueOrder};
8-
use crate::military::squad::{Squad, SquadSize};
8+
use crate::military::squad::Squad;
9+
use crate::military::squad::size::SquadSize;
910
use crate::military::unit::{StableUnitId, UnitBox};
1011
use crate::resources::Resources;
1112
use crate::resources::workforce::Workforce;

crates/nil-core/src/infrastructure/building/workshop/recruit_queue.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use crate::continent::Coord;
55
use crate::decl_recruit_queue;
66
use crate::error::{Error, Result};
77
use crate::infrastructure::queue::{InfrastructureQueue, InfrastructureQueueOrder};
8-
use crate::military::squad::{Squad, SquadSize};
8+
use crate::military::squad::Squad;
9+
use crate::military::squad::size::SquadSize;
910
use crate::military::unit::{UnitBox, WorkshopUnitId};
1011
use crate::resources::Resources;
1112
use crate::resources::workforce::Workforce;

crates/nil-core/src/military/army/mod.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ use derive_more::Display;
1818
use personnel::ArmyPersonnel;
1919
use serde::{Deserialize, Serialize};
2020
use std::mem;
21-
use strum::EnumIs;
21+
use std::ops::{Mul, MulAssign};
22+
use strum::{EnumIs, IntoEnumIterator};
2223
use uuid::Uuid;
2324

2425
#[derive(Builder, Clone, Debug, Deserialize, Serialize)]
@@ -53,6 +54,15 @@ impl Army {
5354
&mut self.personnel
5455
}
5556

57+
#[inline]
58+
pub fn squad(&self, id: UnitId) -> &Squad {
59+
self.personnel.squad(id)
60+
}
61+
62+
fn squad_mut(&mut self, id: UnitId) -> &mut Squad {
63+
self.personnel.squad_mut(id)
64+
}
65+
5666
#[inline]
5767
pub fn owner(&self) -> &Ruler {
5868
&self.owner
@@ -136,16 +146,27 @@ impl From<Army> for ArmyPersonnel {
136146
}
137147
}
138148

149+
impl Mul<f64> for Army {
150+
type Output = Army;
151+
152+
fn mul(mut self, rhs: f64) -> Self::Output {
153+
self *= rhs;
154+
self
155+
}
156+
}
157+
158+
impl MulAssign<f64> for Army {
159+
fn mul_assign(&mut self, rhs: f64) {
160+
for id in UnitId::iter() {
161+
*self.squad_mut(id) *= rhs;
162+
}
163+
}
164+
}
165+
139166
macro_rules! impl_army {
140167
($($unit:ident),+) => {
141168
paste::paste! {
142169
impl Army {
143-
pub fn squad(&self, id: UnitId) -> &Squad {
144-
match id {
145-
$(UnitId::$unit => &self.personnel.[<$unit:snake>](),)+
146-
}
147-
}
148-
149170
$(
150171
#[inline]
151172
pub fn [<$unit:snake>](&self) -> &Squad {

crates/nil-core/src/military/army/personnel.rs

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
// Copyright (C) Call of Nil contributors
22
// SPDX-License-Identifier: AGPL-3.0-only
33

4-
use crate::military::squad::{Squad, SquadSize};
4+
use crate::military::squad::Squad;
5+
use crate::military::squad::size::SquadSize;
56
use crate::military::unit::stats::haul::Haul;
67
use crate::military::unit::stats::speed::Speed;
78
use crate::military::unit::{UnitId, UnitIdIter};
89
use crate::ranking::Score;
910
use crate::resources::maintenance::Maintenance;
1011
use serde::{Deserialize, Serialize};
11-
use std::ops::{Add, AddAssign, Sub, SubAssign};
12+
use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign};
1213
use strum::IntoEnumIterator;
1314
use tap::Pipe;
1415

@@ -127,7 +128,7 @@ macro_rules! impl_army_personnel {
127128
}
128129
}
129130

130-
fn squad_mut(&mut self, id: UnitId) -> &mut Squad {
131+
pub(super) fn squad_mut(&mut self, id: UnitId) -> &mut Squad {
131132
match id {
132133
$(UnitId::$unit => &mut self.[<$unit:snake>],)+
133134
}
@@ -274,21 +275,39 @@ impl SubAssign<Squad> for ArmyPersonnel {
274275
}
275276
}
276277

278+
impl Mul<f64> for ArmyPersonnel {
279+
type Output = ArmyPersonnel;
280+
281+
fn mul(mut self, rhs: f64) -> Self::Output {
282+
self *= rhs;
283+
self
284+
}
285+
}
286+
287+
impl MulAssign<f64> for ArmyPersonnel {
288+
fn mul_assign(&mut self, rhs: f64) {
289+
for id in UnitId::iter() {
290+
*self.squad_mut(id) *= rhs;
291+
}
292+
}
293+
}
294+
277295
pub struct ArmyPersonnelIter<'a> {
278296
personnel: &'a ArmyPersonnel,
279-
iter: UnitIdIter,
297+
units: UnitIdIter,
280298
}
281299

282300
impl<'a> ArmyPersonnelIter<'a> {
283301
pub fn new(personnel: &'a ArmyPersonnel) -> Self {
284-
Self { personnel, iter: UnitId::iter() }
302+
Self { personnel, units: UnitId::iter() }
285303
}
286304
}
287305

288306
impl<'a> Iterator for ArmyPersonnelIter<'a> {
289307
type Item = &'a Squad;
290308

291309
fn next(&mut self) -> Option<Self::Item> {
292-
Some(self.personnel.squad(self.iter.next()?))
310+
let id = self.units.next()?;
311+
Some(self.personnel.squad(id))
293312
}
294313
}

crates/nil-core/src/military/mod.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,16 @@ impl Military {
121121
Ok(curr_vec.swap_remove(pos))
122122
}
123123

124+
pub(crate) fn remove_armies<I>(&mut self, armies: I) -> Result<Vec<Army>>
125+
where
126+
I: IntoIterator<Item = ArmyId>,
127+
{
128+
armies
129+
.into_iter()
130+
.map(|id| self.remove_army(id))
131+
.try_collect()
132+
}
133+
124134
pub(crate) fn relocate_army<K>(&mut self, id: ArmyId, new_key: K) -> Result<()>
125135
where
126136
K: ContinentKey,
@@ -206,6 +216,16 @@ impl Military {
206216
.filter(|army| army.is_idle())
207217
}
208218

219+
pub(crate) fn idle_armies_mut_at<K>(&mut self, key: K) -> impl Iterator<Item = &mut Army>
220+
where
221+
K: ContinentKey,
222+
{
223+
self
224+
.armies_mut_at(key)
225+
.iter_mut()
226+
.filter(|army| army.is_idle())
227+
}
228+
209229
pub fn armies_of<R>(&self, owner: R) -> impl Iterator<Item = &Army>
210230
where
211231
R: Into<Ruler>,

crates/nil-core/src/military/squad/mod.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (C) Call of Nil contributors
22
// SPDX-License-Identifier: AGPL-3.0-only
33

4-
mod size;
4+
pub mod size;
55

66
use crate::error::{Error, Result};
77
use crate::military::unit::stats::haul::Haul;
@@ -11,9 +11,8 @@ use crate::ranking::Score;
1111
use crate::resources::maintenance::Maintenance;
1212
use derive_more::{Deref, Into};
1313
use serde::{Deserialize, Serialize};
14-
use std::ops::{Add, AddAssign, Sub, SubAssign};
15-
16-
pub use size::SquadSize;
14+
use size::SquadSize;
15+
use std::ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign};
1716

1817
/// A group of units of the same type.
1918
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
@@ -162,6 +161,21 @@ impl SubAssign<SquadSize> for Squad {
162161
}
163162
}
164163

164+
impl Mul<f64> for Squad {
165+
type Output = Squad;
166+
167+
fn mul(mut self, rhs: f64) -> Self::Output {
168+
self *= rhs;
169+
self
170+
}
171+
}
172+
173+
impl MulAssign<f64> for Squad {
174+
fn mul_assign(&mut self, rhs: f64) {
175+
self.size *= rhs;
176+
}
177+
}
178+
165179
impl From<UnitId> for Squad {
166180
fn from(id: UnitId) -> Self {
167181
Squad::new(id, SquadSize::new(0))

0 commit comments

Comments
 (0)