Add replay ball

This commit is contained in:
Sofia 2026-07-26 20:34:40 +03:00
parent 6badb845b5
commit 8552aeb55d

View File

@ -5,9 +5,10 @@ use godot::prelude::*;
use crate::{
game_manager::{Game, Player},
map::Map,
net::util::NetVector3,
net::{network_manager::BallSync, util::NetVector3},
player::{
DamageSource, IPlayer, NetTransform, remote_player::RemotePlayer, weapon::WeaponType,
DamageSource, IPlayer, NetTransform, ball::Ball, remote_player::RemotePlayer,
weapon::WeaponType,
},
};
@ -18,6 +19,7 @@ pub struct ReplayPlayback {
pub current_map: Option<Gd<Map>>,
current_frame_idx: usize,
player_characters: HashMap<u16, Gd<RemotePlayer>>,
ball: Option<Gd<Ball>>,
pub current_time: f64,
@ -48,6 +50,27 @@ impl INode for ReplayPlayback {
while let Some(frame) = self.replay.frames.get(self.current_frame_idx)
&& frame.time <= self.current_time
{
if let ReplayBall::World(ball_state) = &frame.ball_data {
if let Some(ball) = &mut self.ball {
ball.bind_mut().apply_sync(BallSync {
transform: ball_state.transform,
velocity: ball_state.velocity,
});
} else if let Some(map) = &mut self.current_map {
if let Some(ball) = map.bind_mut().spawn_ball(
ball_state.transform.into(),
ball_state.velocity.into(),
None,
) {
self.ball = Some(ball);
}
}
} else {
if let Some(mut ball) = self.ball.take() {
ball.queue_free();
}
}
if !self.fast_forwarding {
if let Some(map) = &mut self.current_map {
for (id, data) in &frame.player_data {
@ -128,6 +151,9 @@ impl INode for ReplayPlayback {
character.queue_free();
}
self.player_characters.clear();
if let Some(mut ball) = self.ball.take() {
ball.queue_free();
}
}
}
@ -180,17 +206,28 @@ impl ReplayRecorder {
fn record_frame(&mut self) -> ReplayFrame {
let mut player_data = HashMap::new();
let mut ball_data = ReplayBall::Held;
if let Some(game) = Game::singleton() {
for player in &game.bind().players {
if let Some(state) = player.get_state() {
player_data.insert(player.id(), state);
}
}
ball_data = if let Some(ball) = &game.bind().world_ball {
ReplayBall::World(ReplayBallData {
transform: ball.bind().get_transform(),
velocity: ball.bind().get_velocity(),
})
} else {
ReplayBall::Held
};
}
ReplayFrame {
time: self.time_elapsed,
player_data,
ball_data,
events: Vec::new(),
}
}
@ -221,6 +258,7 @@ pub struct ReplayPlayer {
pub struct ReplayFrame {
time: f64,
player_data: HashMap<u16, ReplayPlayerState>,
ball_data: ReplayBall,
events: Vec<ReplayEvent>,
}
@ -231,9 +269,10 @@ pub enum ReplayEvent {
Respawn(u16, ReplayPlayerState),
}
#[derive(Debug)]
#[derive(Debug, Clone, Default)]
pub enum ReplayBall {
World(ReplayBallData),
#[default]
Held,
}
@ -266,7 +305,7 @@ impl Player {
}
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct ReplayBallData {
transform: NetTransform,
velocity: NetVector3,