skullball/rust/src/ui/hud.rs
2026-07-27 02:11:54 +03:00

150 lines
4.3 KiB
Rust

use godot::{
classes::{Button, Control, IControl, Input, InputEvent, Label, Panel, PanelContainer},
prelude::*,
};
use crate::{
game_manager::Game,
net::network_manager::NetworkManager,
ui::{chatbox::ChatBox, cli::CommandLinePanel, settings::SettingsPanel},
};
#[derive(GodotClass)]
#[class(base=Control, init)]
pub struct Hud {
pub player_id: u16,
#[export]
pause_panel: Option<Gd<Panel>>,
#[export]
settings_button: Option<Gd<Button>>,
#[export]
exit_to_lobby: Option<Gd<Button>>,
#[export]
exit: Option<Gd<Button>>,
#[export]
settings_panel: Option<Gd<SettingsPanel>>,
#[export]
scoreboard: Option<Gd<PanelContainer>>,
#[export]
chatbox: Option<Gd<ChatBox>>,
#[export]
health_label: Option<Gd<Label>>,
lock: bool,
base: Base<Control>,
}
#[godot_api]
impl IControl for Hud {
fn ready(&mut self) {
self.run_deferred(|s| {
if let Some(exit_to_lobby) = &mut s.exit_to_lobby {
exit_to_lobby.set_visible(NetworkManager::singleton().bind().is_host());
}
});
CommandLinePanel::singleton()
.signals()
.on_open()
.connect_other(self, |s| s.update_lock());
CommandLinePanel::singleton()
.signals()
.on_close()
.connect_other(self, |s| {
s.update_lock();
});
if let Some(chatbox) = self.chatbox.clone() {
chatbox
.signals()
.on_opened()
.connect_other(self, |s| s.update_lock());
chatbox
.signals()
.on_closed()
.connect_other(self, |s| s.update_lock());
}
if let Some(exit_to_lobby) = &self.exit_to_lobby {
exit_to_lobby
.signals()
.pressed()
.connect_other(self, |s| s.signals().on_exit_to_lobby().emit());
}
if let Some(exit) = &self.exit {
exit.signals()
.pressed()
.connect_other(self, |s| s.signals().on_exit().emit());
}
if let Some(settings_btn) = &self.settings_button {
settings_btn.signals().pressed().connect_other(self, |s| {
if let Some(settings) = &mut s.settings_panel {
settings.set_visible(true);
}
});
}
self.update_lock();
}
fn process(&mut self, _: f64) {
if let Some(scoreboard) = &mut self.scoreboard {
scoreboard.set_visible(Input::singleton().is_action_pressed("scoreboard"));
}
if let Some(game) = Game::singleton()
&& let Some(player) = game.bind().find_player(self.player_id)
&& let Some(character) = &player.character
&& let Some(health_label) = &mut self.health_label
{
health_label.set_text(&character.dyn_bind().get_health().to_string());
}
}
fn input(&mut self, event: Gd<InputEvent>) {
if event.is_action_pressed("pause") {
if let Some(pause_panel) = &mut self.pause_panel {
let is_visible = pause_panel.is_visible();
pause_panel.set_visible(!is_visible);
if !pause_panel.is_visible() {
if let Some(settings_panel) = &mut self.settings_panel {
settings_panel.set_visible(false);
}
}
self.update_lock();
}
}
}
}
#[godot_api]
impl Hud {
#[signal]
pub fn on_lock_changed(lock: bool);
#[signal]
pub fn on_exit_to_lobby();
#[signal]
pub fn on_exit();
pub fn update_lock(&mut self) {
let paused = if let Some(panel) = &self.pause_panel {
panel.is_visible()
} else {
false
};
let chat_visible = if let Some(chat) = &self.chatbox {
chat.bind().is_editing()
} else {
false
};
let prev_lock = self.lock;
self.lock = !CommandLinePanel::singleton().bind().opened && !paused && !chat_visible;
if prev_lock != self.lock {
let lock = self.lock;
self.signals().on_lock_changed().emit(lock);
}
}
}