diff --git a/crates/game-service/src/battle_session.rs b/crates/game-service/src/battle_session.rs index 20b83d6..99ecab5 100644 --- a/crates/game-service/src/battle_session.rs +++ b/crates/game-service/src/battle_session.rs @@ -228,6 +228,9 @@ impl BattleSession { pub fn advance_to(&mut self, tick: i32) { let tick = tick.min(self.tick + MAX_CATCH_UP_TICKS); while self.tick < tick { + if self.mode.battle.is_end_condition_matched(self.tick) { + break; + } self.tick += 1; self.mode.time.tick = self.tick; self.release_queued(self.tick); diff --git a/crates/game-service/tests/walk_to_tower.rs b/crates/game-service/tests/walk_to_tower.rs index 2ca867c..1afb13c 100644 --- a/crates/game-service/tests/walk_to_tower.rs +++ b/crates/game-service/tests/walk_to_tower.rs @@ -1,6 +1,7 @@ use std::path::Path; use std::sync::Arc; use game_service::battle::BattleBuilder; +use game_service::battle_session::MAX_CATCH_UP_TICKS; use logic::battle::{LogicVector2, BATTLE_TICKS_PER_SECOND}; use logic::data::{table, LogicDataRef, LogicDataTables}; use logic::model::LogicClientAvatar; @@ -265,3 +266,33 @@ fn both_leaders_resolve_to_a_summoner() { ); } } +#[test] +fn a_finished_battle_stops_ticking() { + let root = assets(); + if let Ok(tables) = LogicDataTables::load_from_dir(&root) { + LogicDataTables::install(Arc::new(tables)); + } + let builder = BattleBuilder::new(&root); + let mode = builder + .build( + LogicDataRef::by_name(table::LOCATIONS, "PvP_goblin"), + LogicDataRef::None, + LogicDataRef::by_name(table::ARENAS, "Arena_T"), + vec![avatar(5), avatar(0)], + [None, None], + 1, + ) + .expect("battle"); + let mut session = game_service::battle_session::BattleSession::new(mode, Vec::new()); + for _ in 0..400 { + session.advance_to(session.tick() + MAX_CATCH_UP_TICKS); + } + assert!(session.is_finished(), "the battle never reached its end"); + let settled = session.tick(); + session.advance_to(settled + 10_000); + assert_eq!( + session.tick(), + settled, + "a finished battle carried on ticking" + ); +}