give every object a new id once the client is live
the client never asks for the state, so the objects it decoded before the battle screen installed its listener were stuck without models for the whole battle - and every later snapshot matched them by global id and reused them, so the "newly created" flag the visual depends on was never set again. the first sector command is the client telling us it is up. at that point every object is handed a fresh id: nothing matches, so the client builds them all from scratch and they get models. the leaders and the tower lists are remapped with them and the column is re-sorted, since the client binary searches it. the battle itself is complete as of this run: a princess tower fell and the first crown was scored, towers (2, 1) and stars (1, 0) in the log.
This commit is contained in:
parent
8699a6884d
commit
eb0e59f6f4
2 changed files with 53 additions and 1 deletions
|
|
@ -4,7 +4,8 @@ pub const SNAPSHOT_INTERVAL_TICKS: i32 = 4;
|
|||
pub const MAX_CATCH_UP_TICKS: i32 = 40;
|
||||
use std::time::Instant;
|
||||
use logic::battle::{
|
||||
LogicGameMode, LogicGameObjectEntry, LogicVector2, BATTLE_TICKS_PER_SECOND, BATTLE_TYPE_PVP,
|
||||
LogicGameMode, LogicGameObjectEntry, LogicGameObjectRef, LogicVector2,
|
||||
BATTLE_TICKS_PER_SECOND, BATTLE_TYPE_PVP, CHARACTER_OBJECT_TYPE,
|
||||
};
|
||||
use logic::battle::{verify_snapshot, LogicBattleEvent};
|
||||
use logic::SectorStateMessage;
|
||||
|
|
@ -25,6 +26,7 @@ pub struct BattleSession {
|
|||
next_bot_play: i32,
|
||||
pub pushed_snapshots: u32,
|
||||
next_instance: i32,
|
||||
announced: bool,
|
||||
pending_bot_play: Option<(LogicDataRef, LogicVector2, i32)>,
|
||||
}
|
||||
impl BattleSession {
|
||||
|
|
@ -53,9 +55,43 @@ impl BattleSession {
|
|||
next_bot_play: crate::bot::BOT_OPENING_DELAY_SECONDS * BATTLE_TICKS_PER_SECOND,
|
||||
pushed_snapshots: 0,
|
||||
next_instance: first_instance,
|
||||
announced: false,
|
||||
pending_bot_play: None,
|
||||
}
|
||||
}
|
||||
pub fn reannounce(&mut self) {
|
||||
let mut remap: Vec<(LogicGameObjectRef, LogicGameObjectRef)> = Vec::new();
|
||||
for entry in self.mode.battle.objects.objects.iter_mut() {
|
||||
let fresh = LogicGameObjectRef::of(CHARACTER_OBJECT_TYPE + 1, self.next_instance);
|
||||
self.next_instance += 1;
|
||||
remap.push((entry.global_id, fresh));
|
||||
entry.global_id = fresh;
|
||||
}
|
||||
let translate = |old: &LogicGameObjectRef| -> Option<LogicGameObjectRef> {
|
||||
remap
|
||||
.iter()
|
||||
.find(|(was, _)| was == old)
|
||||
.map(|(_, now)| *now)
|
||||
};
|
||||
for leader in self.mode.battle.leaders.iter_mut() {
|
||||
if let Some(now) = translate(leader) {
|
||||
*leader = now;
|
||||
}
|
||||
}
|
||||
for towers in self.mode.battle.leader_towers.iter_mut() {
|
||||
for tower in towers.iter_mut() {
|
||||
if let Some(now) = translate(tower) {
|
||||
*tower = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.mode
|
||||
.battle
|
||||
.objects
|
||||
.objects
|
||||
.sort_by_key(|entry| entry.global_id.0.map(|id| (id.class_id, id.instance_id)));
|
||||
self.next_snapshot = self.tick;
|
||||
}
|
||||
pub fn take_bot_play(&mut self) -> Option<(LogicDataRef, LogicVector2, i32)> {
|
||||
self.pending_bot_play.take()
|
||||
}
|
||||
|
|
@ -347,8 +383,21 @@ impl BattleRegistry {
|
|||
pub async fn resend(&self, account: AccountRef) -> Option<WireMessage> {
|
||||
let handle = self.session(account).await?;
|
||||
let mut session = handle.lock().await;
|
||||
session.reannounce();
|
||||
session.snapshot_message()
|
||||
}
|
||||
pub async fn announce_once(&self, account: AccountRef) -> bool {
|
||||
let Some(handle) = self.session(account).await else {
|
||||
return false;
|
||||
};
|
||||
let mut session = handle.lock().await;
|
||||
if session.announced {
|
||||
return false;
|
||||
}
|
||||
session.announced = true;
|
||||
session.reannounce();
|
||||
true
|
||||
}
|
||||
pub async fn send(&self, account: AccountRef, message: WireMessage) {
|
||||
if let Some(handle) = self.session(account).await {
|
||||
handle.lock().await.push_outbound(message);
|
||||
|
|
|
|||
|
|
@ -488,6 +488,9 @@ impl GameApi for GameService {
|
|||
let Ok(sector) = SectorCommandMessage::from_bytes(&payload) else {
|
||||
return Ok(());
|
||||
};
|
||||
if self.running_battles.announce_once(account).await {
|
||||
tracing::info!(%account, "client is live, announcing the objects again");
|
||||
}
|
||||
let progress = self
|
||||
.running_battles
|
||||
.advance(account, sector.client_tick)
|
||||
|
|
|
|||
Loading…
Reference in a new issue