diff --git a/crates/game-service/src/battle_session.rs b/crates/game-service/src/battle_session.rs index bd31a79..e961ea3 100644 --- a/crates/game-service/src/battle_session.rs +++ b/crates/game-service/src/battle_session.rs @@ -209,6 +209,12 @@ impl BattleSession { pub fn stars(&self) -> (i32, i32) { (self.mode.battle.stars(0), self.mode.battle.stars(1)) } + pub fn towers_standing(&self) -> (usize, usize) { + ( + self.mode.battle.leader_towers[0].len(), + self.mode.battle.leader_towers[1].len(), + ) + } pub fn owner_of(&self, account: LogicLong) -> Option { self.mode .battle @@ -312,6 +318,7 @@ impl BattleRegistry { finished: session.is_finished(), stars: session.stars(), objects: session.object_count(), + towers: session.towers_standing(), }) } pub async fn play( @@ -348,4 +355,5 @@ pub struct BattleProgress { pub finished: bool, pub stars: (i32, i32), pub objects: usize, + pub towers: (usize, usize), } diff --git a/crates/game-service/src/service.rs b/crates/game-service/src/service.rs index 965ac11..7ab5dcc 100644 --- a/crates/game-service/src/service.rs +++ b/crates/game-service/src/service.rs @@ -373,6 +373,7 @@ impl GameApi for GameService { finished = progress.map(|state| state.finished), stars = ?progress.map(|state| state.stars), objects = progress.map(|state| state.objects), + towers = ?progress.map(|state| state.towers), spawned, commands = ?turn .commands diff --git a/crates/logic/src/battle/logic_simulation.rs b/crates/logic/src/battle/logic_simulation.rs index f6f72d7..00d494a 100644 --- a/crates/logic/src/battle/logic_simulation.rs +++ b/crates/logic/src/battle/logic_simulation.rs @@ -187,6 +187,24 @@ impl LogicBattle { } } } + fn default_target(&self, index: usize) -> Option { + let owner = self.objects.objects[index].owner_index(); + let from = self.objects.objects[index].position(); + let mut best: Option<(i32, usize)> = None; + for (other, entry) in self.objects.objects.iter().enumerate() { + if other == index || entry.owner_index() == owner || !entry.is_alive() { + continue; + } + if !entry.stats().is_building() { + continue; + } + let distance = distance_squared(from, entry.position()); + if best.map(|(closest, _)| distance < closest).unwrap_or(true) { + best = Some((distance, other)); + } + } + best.map(|(_, other)| other) + } fn move_objects(&mut self) { let positions: Vec<(i32, i32)> = self .objects @@ -199,11 +217,15 @@ impl LogicBattle { if stats.speed < 1 || !self.objects.objects[index].is_alive() { continue; } - let Some(target) = self.objects.objects[index] + let target = match self.objects.objects[index] .combat_mut() .and_then(|component| component.target_index) - else { - continue; + { + Some(target) => target, + None => match self.default_target(index) { + Some(target) => target, + None => continue, + }, }; let Some(goal) = positions.get(target).copied() else { continue;