295 lines
10 KiB
Rust
295 lines
10 KiB
Rust
use godot::{
|
|
classes::{
|
|
Button, CheckBox, Control, GridContainer, IPanel, Label, OptionButton, Panel, TextEdit,
|
|
VBoxContainer,
|
|
},
|
|
prelude::*,
|
|
};
|
|
|
|
use crate::{
|
|
game_manager::{Game, GameManager, GameOption, GameOptionValue, GameOptions},
|
|
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>>,
|
|
#[export]
|
|
options_panel: Option<Gd<Panel>>,
|
|
#[export]
|
|
options_grid: Option<Gd<GridContainer>>,
|
|
|
|
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() {
|
|
game.signals().options_changed().connect_other(self, |s| {
|
|
s.run_deferred(|s| {
|
|
if let Some(game) = Game::singleton() {
|
|
s.on_game_opts_update(
|
|
&game.bind().opts,
|
|
NetworkManager::singleton().bind().is_host(),
|
|
);
|
|
}
|
|
});
|
|
});
|
|
|
|
if let Some(map_selection) = &mut self.map_selection {
|
|
for map in game.bind().maps.iter_shared() {
|
|
map_selection.add_item(&map.bind().name);
|
|
}
|
|
map_selection.select(0);
|
|
}
|
|
let is_host = if let Some(peer) = &NetworkManager::singleton().bind().peer {
|
|
peer.is_host()
|
|
} else {
|
|
false
|
|
};
|
|
self.on_game_opts_update(&game.bind().opts, is_host);
|
|
}
|
|
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();
|
|
|
|
let mut nodes = Vec::new();
|
|
if let Some(game) = Game::singleton() {
|
|
for (option, value) in &game.bind().opts.values {
|
|
let mut label = Label::new_alloc();
|
|
label.set_text(&format!("{}:", option.to_string()));
|
|
nodes.push(label.upcast());
|
|
|
|
let value_node = match value {
|
|
GameOptionValue::Boolean(value) => {
|
|
let mut checkbox = CheckBox::new_alloc();
|
|
checkbox.set_pressed(*value);
|
|
checkbox.set_disabled(!NetworkManager::singleton().bind().is_host());
|
|
|
|
let checkbox_clone = checkbox.clone();
|
|
let option = option.clone();
|
|
checkbox.signals().pressed().connect_other(self, move |s| {
|
|
s.option_changed(
|
|
option,
|
|
GameOptionValue::Boolean(checkbox_clone.is_pressed()),
|
|
);
|
|
});
|
|
|
|
checkbox.upcast::<Control>()
|
|
}
|
|
};
|
|
nodes.push(value_node);
|
|
}
|
|
}
|
|
|
|
if let Some(grid) = &mut self.options_grid {
|
|
for node in nodes {
|
|
grid.add_child(&node);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[godot_api]
|
|
impl LobbyPanel {
|
|
#[func]
|
|
fn open_options(&mut self) {
|
|
if let Some(panel) = &mut self.options_panel {
|
|
panel.set_visible(true);
|
|
}
|
|
}
|
|
|
|
#[func]
|
|
fn close_options(&mut self) {
|
|
if let Some(panel) = &mut self.options_panel {
|
|
panel.set_visible(false);
|
|
}
|
|
}
|
|
|
|
fn option_changed(&mut self, key: GameOption, value: GameOptionValue) {
|
|
if let Some(game) = &mut Game::singleton() {
|
|
game.bind_mut().change_option(key, value);
|
|
}
|
|
}
|
|
|
|
fn on_game_opts_update(&mut self, opts: &GameOptions, is_host: bool) {
|
|
if let Some(selection) = &mut self.map_selection {
|
|
selection.set_disabled(!is_host && !opts.is_true(GameOption::AllowAnyMap));
|
|
}
|
|
}
|
|
|
|
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(peer, addr) => {
|
|
if let Some(map_selection) = &mut self.map_selection {
|
|
map_selection.select(idx as i32);
|
|
self.run_deferred(|s| s.update_players(false));
|
|
peer.send_reliable(addr, Package::SelectMap(idx));
|
|
}
|
|
}
|
|
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));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|