use godot::{ classes::{GridContainer, IGridContainer, Label, OptionButton}, prelude::*, }; use crate::{ game_manager::{Game, GameOption, GameOptions}, net::network_manager::NetworkManager, team_resource::TeamResource, }; #[derive(GodotClass)] #[class(base=GridContainer, init)] pub struct LobbyPlayerListing { #[export] pub name_label: Option>, #[export] pub ping_label: Option>, #[export] pub ready_label: Option>, #[export] pub team_dropdown: Option>, pub player_id: Option, base: Base, } #[godot_api] impl IGridContainer for LobbyPlayerListing { fn ready(&mut self) { self.run_deferred(|s| { if let Some(game) = &mut Game::singleton() { game.bind_mut() .signals() .on_player_team_changed() .connect_other(s, |s, id, team| { if id == s.player_id.unwrap_or(0) { s.on_team_update(team); } }); } }); if let Some(team_dropdown) = self.team_dropdown.clone() { team_dropdown .signals() .item_selected() .connect_other(self, |s, selection| { s.on_team_selection_changed(selection as u8); }); } if let Some(game) = &Game::singleton() { game.signals().options_changed().connect_other(self, |s| { s.run_deferred(|s| { if let Some(game) = Game::singleton() { s.update_game_options(&game.bind().opts, game.bind().self_id); } }); }); self.update_game_options(&game.bind().opts, game.bind().self_id); } } } impl LobbyPlayerListing { pub fn update_game_options(&mut self, opts: &GameOptions, self_id: Option) { let is_host = NetworkManager::singleton().bind().is_host(); if let Some(dropdown) = &mut self.team_dropdown { dropdown.set_disabled( !is_host && !opts.is_true(GameOption::AllowAnyTeam) && self.player_id != self_id, ); } } pub fn update(&mut self) { if let Some(player_id) = &self.player_id && let Some(game) = Game::singleton() && let Some(player) = game.bind().find_player(*player_id) { if let Some(player_label) = &mut self.name_label { player_label.set_text(&format!( "{} ({})", player.data.name, player.connection_addr )); if let Some(team) = game.bind().get_team(player.data.team) { player_label.add_theme_color_override("font_color", team.bind().color); } } if let Some(ready_label) = &mut self.ready_label { if player.ready { ready_label.set_text("Ready"); } else { ready_label.set_text("Not Ready"); } } if let Some(ping_label) = &mut self.ping_label { ping_label.set_text(&format!("({}ms)", player.data.ping)); } if let Some(dropdown) = &mut self.team_dropdown { dropdown.select(player.data.team as i32); } } } pub fn update_teams(&mut self, teams: Array>) { if let Some(dropdown) = &mut self.team_dropdown { let prev_selection = dropdown.get_selected(); dropdown.clear(); for team in teams.iter_shared() { dropdown.add_item(&team.bind().name); } dropdown.select(prev_selection.min((teams.len() - 1) as i32)); } } pub fn on_team_selection_changed(&mut self, team: u8) { if let Some(mut game) = Game::singleton() { game.bind_mut() .try_set_player_team(self.player_id.unwrap_or(0), team, false); if let Some(player) = game.bind().find_player(self.player_id.unwrap_or(0)) && let Some(player_label) = &mut self.name_label && let Some(team) = game.bind().get_team(player.data.team) { godot_print!("Setting color"); player_label.add_theme_color_override("font_color", team.bind().color); } } } fn on_team_update(&mut self, team: u8) { if let Some(dropdown) = &mut self.team_dropdown { dropdown.select(team as i32); } if let Some(game) = Game::singleton() && let Some(player) = game.bind().find_player(self.player_id.unwrap_or(0)) && let Some(player_label) = &mut self.name_label && let Some(team) = game.bind().get_team(player.data.team) { godot_print!("Setting color"); player_label.add_theme_color_override("font_color", team.bind().color); } } }