Add pickup visibility for replays

This commit is contained in:
Sofia 2026-07-27 19:46:12 +03:00
parent f92ddf567d
commit e6793fde61
5 changed files with 55 additions and 7 deletions

View File

@ -196,8 +196,6 @@ impl Map {
}
pub fn register_pickup(&mut self, pickup: DynGd<Node3D, dyn Pickup>) -> u8 {
godot_print!("Registered {:?}", pickup);
let id = self.pickup_counter;
self.pickup_counter += 1;
self.pickups.insert(id, pickup);

View File

@ -14,6 +14,14 @@ pub enum PickupKind {
Health,
}
#[derive(Debug, Default)]
pub enum ReplayVisibility {
#[default]
NoReplay,
Hidden,
Visible,
}
#[derive(GodotClass)]
#[class(base=Node3D, init, tool)]
pub struct HealthPickup {
@ -23,6 +31,7 @@ pub struct HealthPickup {
time_elapsed: f64,
pickup_id: Option<u8>,
respawn: f64,
replay_visibility: ReplayVisibility,
base: Base<Node3D>,
}
@ -52,8 +61,14 @@ impl INode3D for HealthPickup {
self.time_elapsed += delta;
self.respawn -= delta;
self.update_common(self.time_elapsed);
if let Some(area) = &mut self.pickup_area {
area.set_visible(self.respawn <= 0.);
if let Some(mut area) = self.pickup_area.clone() {
match self.replay_visibility {
ReplayVisibility::NoReplay => {
area.set_visible(self.is_active());
}
ReplayVisibility::Hidden => area.set_visible(false),
ReplayVisibility::Visible => area.set_visible(true),
}
}
}
}
@ -84,7 +99,15 @@ impl Pickup for HealthPickup {
}
fn on_pickup(&mut self) {
self.respawn = 10.;
self.respawn = 30.;
}
fn is_active(&self) -> bool {
self.respawn <= 0.
}
fn set_replay(&mut self, visible: ReplayVisibility) {
self.replay_visibility = visible;
}
}
@ -93,6 +116,8 @@ pub trait Pickup {
fn kind(&self) -> PickupKind;
fn id(&self) -> Option<u8>;
fn on_pickup(&mut self);
fn is_active(&self) -> bool;
fn set_replay(&mut self, visibility: ReplayVisibility);
}
pub trait PickupCommon {

View File

@ -309,7 +309,6 @@ impl IPlayer for LocalPlayer {
}
fn on_pickup(&mut self, kind: PickupKind) {
godot_print!("picked up");
match kind {
PickupKind::Health => self.heal(100),
}

View File

@ -15,6 +15,7 @@ use crate::{
game_manager::{Game, GameManager, Player},
map::Map,
net::{network_manager::BallSync, util::NetVector3},
pickup::ReplayVisibility,
player::{
DamageSource, IPlayer, NetTransform, ball::Ball, remote_player::RemotePlayer,
weapon::WeaponType,
@ -196,6 +197,17 @@ impl INode for ReplayPlayback {
self.player_data = frame.player_data.clone();
self.running_goals = frame.goals.clone();
if let Some(map) = &mut self.current_map {
for (id, visible) in frame.pickups_visible {
if let Some(pickup) = map.bind_mut().pickups.get_mut(&id) {
pickup.dyn_bind_mut().set_replay(match visible {
true => ReplayVisibility::Visible,
false => ReplayVisibility::Hidden,
});
}
}
}
if let ReplayBall::World(ball_state) = &frame.ball_data {
if let Some(ball) = &mut self.ball {
ball.bind_mut().apply_sync(BallSync {
@ -325,6 +337,11 @@ impl INode for ReplayPlayback {
}
fn exit_tree(&mut self) {
if let Some(map) = &mut self.current_map {
for (_, pickup) in &mut map.bind_mut().pickups {
pickup.dyn_bind_mut().set_replay(ReplayVisibility::NoReplay);
}
}
for (_, character) in &mut self.player_characters {
character.queue_free();
}
@ -424,6 +441,8 @@ impl ReplayRecorder {
let mut goals = HashMap::new();
let mut pickups_visible = HashMap::new();
if let Some(game) = Game::singleton() {
for player in &game.bind().players {
if let Some(state) = player.get_state(player.clone()) {
@ -443,6 +462,12 @@ impl ReplayRecorder {
ReplayBall::Held
};
if let Some(map) = &game.bind().current_map {
for (id, pickup) in &map.bind().pickups {
pickups_visible.insert(*id, pickup.dyn_bind().is_active());
}
}
goals = game.bind().goals.clone();
}
@ -451,6 +476,7 @@ impl ReplayRecorder {
ReplayFrame {
time: self.time_elapsed,
goals,
pickups_visible,
player_data,
ball_data,
events: Vec::new(),
@ -530,6 +556,7 @@ pub struct ReplayFrame {
time: f64,
player_data: HashMap<u16, ReplayPlayerState>,
ball_data: ReplayBall,
pickups_visible: HashMap<u8, bool>,
events: Vec<ReplayEvent>,
goals: HashMap<u8, u16>,
}

View File

@ -63,7 +63,6 @@ impl IHBoxContainer for PlayerListing {
impl PlayerListing {
pub fn update(&mut self) {
godot_print!("update");
if let Some(player_id) = self.player_id {
if let Some(game) = Game::singleton() {
if let Some(player) = game.bind().find_player(player_id) {