Implement concept of fast forwarding

This commit is contained in:
Sofia 2026-07-26 20:10:41 +03:00
parent f67843cc59
commit 91f76b3836
2 changed files with 57 additions and 19 deletions

View File

@ -352,6 +352,7 @@ impl Game {
playback.bind_mut().replay = recorder.bind().replay.clone();
playback.bind_mut().current_map = self.current_map.clone();
playback.bind_mut().current_time = recorder.bind().time_elapsed + time_delta;
playback.bind_mut().fast_forwarding = true;
self.current_replay_playback = Some(playback.clone());
self.base_mut().add_child(&playback);
}
@ -789,11 +790,19 @@ impl Game {
self.stop_playback();
}
if let Some(player) = self.find_player_mut(id)
&& let Some(character) = &mut player.character
if let Some(player) = self.find_player(id)
&& let Some(mut character) = player.character.clone()
{
// This is a respawn, remove old character
character.queue_free();
if let Some(mut recorder) = self.replay_recorder.clone()
&& let Some(state) = player.get_state()
{
recorder
.bind_mut()
.record_event(ReplayEvent::Respawn(id, state));
}
}
if let Some(mut map) = self.current_map.clone() {
@ -867,6 +876,14 @@ impl Game {
if let Some(character) = &mut player.character {
// This is a respawn, delete old character
character.queue_free();
if let Some(mut recorder) = self.replay_recorder.clone()
&& let Some(state) = player.get_state()
{
recorder
.bind_mut()
.record_event(ReplayEvent::Respawn(id, state));
}
}
let mut character = map.bind_mut().spawn_player(

View File

@ -23,6 +23,8 @@ pub struct ReplayPlayback {
pub spectated_player_id: u16,
pub fast_forwarding: bool,
base: Base<Node>,
}
@ -46,27 +48,43 @@ impl INode for ReplayPlayback {
while let Some(frame) = self.replay.frames.get(self.current_frame_idx)
&& frame.time <= self.current_time
{
if let Some(map) = &mut self.current_map {
for (id, data) in &frame.player_data {
if !self.player_characters.contains_key(id) {
if let Some(player) = map.bind_mut().spawn_replay_player(*id, data.clone())
{
self.player_characters.insert(*id, player);
if !self.fast_forwarding {
if let Some(map) = &mut self.current_map {
for (id, data) in &frame.player_data {
if !self.player_characters.contains_key(id) {
if let Some(player) =
map.bind_mut().spawn_replay_player(*id, data.clone())
{
self.player_characters.insert(*id, player);
}
}
}
}
}
for event in &frame.events {
match event {
ReplayEvent::Death(damage_source, player_id) => {
if let Some(character) = self.player_characters.get_mut(player_id) {
character.bind_mut().kill(*damage_source);
for event in &frame.events {
match event {
ReplayEvent::Death(damage_source, player_id) => {
if let Some(character) = self.player_characters.get_mut(player_id) {
character.bind_mut().kill(*damage_source);
}
}
}
ReplayEvent::Shoot(player_id, to) => {
if let Some(character) = self.player_characters.get_mut(player_id) {
character.bind_mut().try_shoot(*to, false);
ReplayEvent::Shoot(player_id, to) => {
if let Some(character) = self.player_characters.get_mut(player_id) {
character.bind_mut().try_shoot(*to, false);
}
}
ReplayEvent::Respawn(player_id, data) => {
if let Some(mut character) = self.player_characters.remove(player_id) {
character.queue_free();
}
if let Some(map) = &mut self.current_map {
if let Some(player) =
map.bind_mut().spawn_replay_player(*player_id, data.clone())
{
self.player_characters.insert(*player_id, player);
}
}
}
}
}
@ -90,6 +108,8 @@ impl INode for ReplayPlayback {
self.current_frame_idx += 1;
}
self.fast_forwarding = false;
if self.current_frame_idx >= self.replay.frames.len() {
for (id, mut character) in self.player_characters.clone() {
character.queue_free();
@ -203,6 +223,7 @@ pub struct ReplayFrame {
pub enum ReplayEvent {
Death(DamageSource, u16),
Shoot(u16, Vector3),
Respawn(u16, ReplayPlayerState),
}
#[derive(Debug)]
@ -220,7 +241,7 @@ pub struct ReplayPlayerState {
}
impl Player {
fn get_state(&self) -> Option<ReplayPlayerState> {
pub fn get_state(&self) -> Option<ReplayPlayerState> {
if let Some(character) = &self.character {
Some(ReplayPlayerState {
transform: character.dyn_bind().get_transform(),