skullball/rust/src/ui/player_listing.rs

144 lines
4.6 KiB
Rust

use godot::{
classes::{GridContainer, IGridContainer, Label, OptionButton, TextEdit},
prelude::*,
};
use crate::{
game_manager::{Game, GameOptions},
net::network_manager::NetworkManager,
team_resource::TeamResource,
};
#[derive(GodotClass)]
#[class(base=GridContainer, init)]
pub struct PlayerListing {
#[export]
pub name_label: Option<Gd<Label>>,
#[export]
pub ping_label: Option<Gd<Label>>,
#[export]
pub ready_label: Option<Gd<Label>>,
#[export]
pub team_dropdown: Option<Gd<OptionButton>>,
pub player_id: Option<u16>,
base: Base<GridContainer>,
}
#[godot_api]
impl IGridContainer for PlayerListing {
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() {
self.update_game_options(&game.bind().opts, game.bind().self_id);
}
}
}
impl PlayerListing {
pub fn update_game_options(&mut self, opts: &GameOptions, self_id: Option<u16>) {
let is_host = NetworkManager::singleton().bind().is_host();
if let Some(dropdown) = &mut self.team_dropdown {
dropdown.set_disabled(!is_host && !opts.allow_any_team && 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<Gd<TeamResource>>) {
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);
}
}
}