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>, #[export] settings_button: Option>, #[export] exit_to_lobby: Option>, #[export] exit: Option>, #[export] settings_panel: Option>, #[export] scoreboard: Option>, #[export] chatbox: Option>, #[export] health_label: Option>, lock: bool, base: Base, } #[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) { 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); } } }