quakeball-rust/rust/src/ui/lobby.rs

214 lines
7.3 KiB
Rust

use godot::{
classes::{Button, IPanel, OptionButton, Panel, TextEdit, VBoxContainer},
prelude::*,
};
use crate::{
game_manager::{Game, GameManager},
net::network_manager::{NetworkManager, Package, PeerKind},
ui::player_listing::PlayerListing,
};
#[derive(GodotClass)]
#[class(base=Panel, init)]
pub struct LobbyPanel {
#[export]
players_list: Option<Gd<VBoxContainer>>,
#[export]
name_field: Option<Gd<TextEdit>>,
#[export]
player_listing_prefab: Option<Gd<PackedScene>>,
#[export]
ready_button: Option<Gd<Button>>,
#[export]
map_selection: Option<Gd<OptionButton>>,
is_ready: bool,
base: Base<Panel>,
}
#[godot_api]
impl IPanel for LobbyPanel {
fn ready(&mut self) {
GameManager::singleton()
.signals()
.on_new_player()
.connect_other(self, |s, _| s.update_players(true));
GameManager::singleton()
.signals()
.on_player_disconnected()
.connect_other(self, |s, _| s.update_players(true));
GameManager::singleton()
.signals()
.on_players_updated()
.connect_other(self, |s| s.update_players(false));
GameManager::singleton()
.signals()
.on_map_changed()
.connect_other(self, |s, id| s.update_map_selection(id));
if let Some(ready_button) = &self.ready_button {
ready_button
.signals()
.pressed()
.connect_other(self, |s| s.on_ready());
}
if let Some(map_selection) = &self.map_selection {
map_selection
.signals()
.item_selected()
.connect_other(self, |s, id| {
s.update_map_selection(id as u8);
});
}
if let Some(game) = Game::singleton() {
if let Some(map_selection) = &mut self.map_selection {
for map in game.bind().maps.iter_shared() {
map_selection.add_item(&map.bind().name);
}
let is_host = if let Some(peer) = &NetworkManager::singleton().bind().peer {
peer.is_host()
} else {
false
};
map_selection.set_disabled(!is_host);
map_selection.select(0);
}
}
self.update_map_selection(0);
if let Some(name_field) = &self.name_field {
name_field
.signals()
.text_changed()
.connect_other(self, |s| {
if let Some(name_field) = &s.name_field {
if let Some(game) = &mut Game::singleton() {
let player_id = game.bind().self_id;
if let Some(player_id) = player_id {
game.bind_mut().update_player_nick(
player_id,
name_field.get_text().to_string(),
);
}
}
NetworkManager::singleton()
.bind_mut()
.update_nick(name_field.get_text().to_string());
}
});
}
self.update_players(true);
if let Some(peer) = &NetworkManager::singleton().bind().peer
&& peer.is_host()
{
if let Some(button) = &mut self.ready_button {
button.set_text("Start Game");
button.set_disabled(true);
}
}
self.update_ready_button();
}
}
impl LobbyPanel {
fn update_ready_button(&mut self) {
if let Some(game) = Game::singleton()
&& let Some(peer) = &NetworkManager::singleton().bind().peer
{
if let PeerKind::Server(_, _) = peer
&& let Some(button) = &mut self.ready_button
{
let all_ready = game.bind().players.iter().all(|p| p.ready);
button.set_disabled(!all_ready);
}
}
}
pub fn update_players(&mut self, replace: bool) {
self.update_ready_button();
if let Some(list) = &mut self.players_list {
if replace {
for child in list.get_children().iter_shared() {
list.remove_child(&child);
}
if let Some(game) = &Game::singleton() {
if let Some(prefab) = &self.player_listing_prefab {
for player in &game.bind().players {
if let Some(node) = prefab.instantiate() {
let mut listing = node.cast::<PlayerListing>();
listing.bind_mut().player_id = Some(player.id());
listing.bind_mut().update_teams(game.bind().get_teams());
listing.bind_mut().update();
list.add_child(&listing);
}
}
}
}
} else {
for child in list.get_children().iter_shared() {
let mut listing = child.cast::<PlayerListing>();
if let Some(game) = Game::singleton() {
listing.bind_mut().update_teams(game.bind().get_teams());
}
listing.bind_mut().update();
}
}
}
}
pub fn on_ready(&mut self) {
let is_host = if let Some(peer) = &NetworkManager::singleton().bind().peer {
peer.is_host()
} else {
false
};
if !is_host {
self.is_ready = !self.is_ready;
if let Some(button) = &mut self.ready_button {
if self.is_ready {
button.set_text("Ready");
} else {
button.set_text("Not Ready");
}
}
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer {
if let PeerKind::Client(peer, socket_addr) = peer {
peer.send_reliable(&socket_addr, Package::SetReady(0, self.is_ready));
}
}
} else {
if let Some(game) = &mut Game::singleton() {
game.bind_mut().start_game();
}
}
}
pub fn update_map_selection(&mut self, idx: u8) {
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer {
match peer {
PeerKind::Client(..) => {
if let Some(map_selection) = &mut self.map_selection {
map_selection.select(idx as i32);
self.run_deferred(|s| s.update_players(false));
}
}
PeerKind::Server(peer, _) => {
if let Some(game) = &mut Game::singleton() {
game.bind_mut().change_map_selection(idx, false);
}
self.run_deferred(|s| s.update_players(false));
peer.broadcast_reliable(Package::SelectMap(idx));
}
}
}
}
}