Allow switching which player is being spectated

This commit is contained in:
Sofia 2026-07-28 23:30:39 +03:00
parent 227dea72c6
commit 8d4ee54d98
4 changed files with 84 additions and 2 deletions

View File

@ -136,6 +136,16 @@ throw_telegrenade={
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":81,"key_label":0,"unicode":113,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":81,"key_label":0,"unicode":113,"location":0,"echo":false,"script":null)
] ]
} }
next_spectator={
"deadzone": 0.2,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
]
}
prev_spectator={
"deadzone": 0.2,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":2,"canceled":false,"pressed":false,"double_click":false,"script":null)
]
}
[physics] [physics]

View File

@ -128,6 +128,18 @@ impl StandaloneReplayManager {
s.go_to_menu(); s.go_to_menu();
}); });
hud.signals().on_next_spectator().connect_other(self, |s| {
if let Some(playback) = &mut s.playback {
playback.bind_mut().next_spectator();
}
});
hud.signals().on_prev_spectator().connect_other(self, |s| {
if let Some(playback) = &mut s.playback {
playback.bind_mut().prev_spectator();
}
});
self.hud = Some(hud.clone()); self.hud = Some(hud.clone());
playback.add_child(&hud); playback.add_child(&hud);
@ -432,6 +444,42 @@ impl INode for ReplayPlayback {
} }
} }
impl ReplayPlayback {
pub fn next_spectator(&mut self) {
let mut ids = self.player_characters.keys().collect::<Vec<_>>();
ids.sort();
if let Some((current_idx, _)) = ids
.iter()
.enumerate()
.find(|(_, id)| ***id == self.spectated_player_id)
{
let idx = (current_idx + 1) % ids.len();
if let Some(id) = ids.get(idx) {
self.spectated_player_id = **id;
}
}
}
pub fn prev_spectator(&mut self) {
let mut ids = self.player_characters.keys().collect::<Vec<_>>();
ids.sort();
if let Some((current_idx, _)) = ids
.iter()
.enumerate()
.find(|(_, id)| ***id == self.spectated_player_id)
{
let mut idx = current_idx as i32 - 1;
if idx == -1 {
idx = ids.len() as i32 - 1;
}
let idx = (idx % ids.len() as i32) as usize;
if let Some(id) = ids.get(idx) {
self.spectated_player_id = **id;
}
}
}
}
#[derive(GodotClass)] #[derive(GodotClass)]
#[class(base=Node, init)] #[class(base=Node, init)]
pub struct ReplayRecorder { pub struct ReplayRecorder {

View File

@ -1,5 +1,8 @@
use godot::{ use godot::{
classes::{Button, Control, IControl, Input, InputEvent, Label, Panel, PanelContainer}, classes::{
Button, Control, IControl, Input, InputEvent, InputEventMouseButton, Label, Panel,
PanelContainer,
},
prelude::*, prelude::*,
}; };
@ -45,6 +48,11 @@ impl IControl for Hud {
} }
}); });
self.base()
.signals()
.gui_input()
.connect_other(self, |s, event| s.on_gui_input(event));
CommandLinePanel::singleton() CommandLinePanel::singleton()
.signals() .signals()
.on_open() .on_open()
@ -127,6 +135,10 @@ impl Hud {
pub fn on_exit_to_lobby(); pub fn on_exit_to_lobby();
#[signal] #[signal]
pub fn on_exit(); pub fn on_exit();
#[signal]
pub fn on_next_spectator();
#[signal]
pub fn on_prev_spectator();
pub fn update_lock(&mut self) { pub fn update_lock(&mut self) {
let paused = if let Some(panel) = &self.pause_panel { let paused = if let Some(panel) = &self.pause_panel {
@ -146,4 +158,16 @@ impl Hud {
self.signals().on_lock_changed().emit(lock); self.signals().on_lock_changed().emit(lock);
} }
} }
pub fn on_gui_input(&mut self, event: Gd<InputEvent>) {
if let Ok(button) = event.try_cast::<InputEventMouseButton>()
&& button.is_pressed()
{
if button.is_action("next_spectator") {
self.signals().on_next_spectator().emit();
} else if button.is_action("prev_spectator") {
self.signals().on_prev_spectator().emit();
}
}
}
} }

View File

@ -1,5 +1,5 @@
use godot::{ use godot::{
classes::{Control, IControl, Label, Slider}, classes::{Control, IControl, InputEvent, Label, Slider},
prelude::*, prelude::*,
}; };