diff --git a/crates/border-wars/src/lib.rs b/crates/border-wars/src/lib.rs index c988c19..02fd172 100644 --- a/crates/border-wars/src/lib.rs +++ b/crates/border-wars/src/lib.rs @@ -21,6 +21,6 @@ pub enum CurrentScene { /// When we play this wonderful game. Game, - /// When we are in the waiting menu. - WaitingMenu, + /// TODO. + AdminLobby, } diff --git a/crates/border-wars/src/scenes/admin_lobby.rs b/crates/border-wars/src/scenes/admin_lobby.rs new file mode 100644 index 0000000..ff3f61c --- /dev/null +++ b/crates/border-wars/src/scenes/admin_lobby.rs @@ -0,0 +1,110 @@ +//! The lobby of the game. + +use bevnet::{Connection, Receive, SendTo, Uuid}; +use bevy::prelude::*; +use bevy_egui::{egui, EguiContexts}; + +use super::handle_new_players; +use crate::connection::{AddPlayer, AllPlayers, RemovePlayer, RequestConnection}; +use crate::CurrentScene; + +/// The plugin for the lobby. +pub struct LobbyPlugin; + +impl Plugin for LobbyPlugin { + fn build(&self, app: &mut App) { + app.add_systems( + Update, + (lobby_ui, handle_request, admin_panel, handle_new_players) + .run_if(in_state(CurrentScene::AdminLobby)), + ); + } +} + +/// Display the UI of the lobby. +fn lobby_ui(mut ctx: EguiContexts, connection: Res) { + egui::CentralPanel::default().show(ctx.ctx_mut(), |ui| { + ui.heading("Border Wars"); + + ui.separator(); + + ui.label("Game created"); + ui.horizontal(|ui| { + ui.label("Game ID: "); + ui.text_edit_singleline( + &mut connection + .identifier() + .unwrap_or_else(Uuid::nil) + .to_string(), + ); + }); + }); +} + +/// TODO +fn admin_panel( + mut ctx: EguiContexts, + connection: Res, + all_players: Res, + mut event: EventWriter>, + mut next_scene: ResMut>, +) { + egui::Window::new("Admin").show(ctx.ctx_mut(), |ui| { + for player in all_players.0.iter() { + ui.separator(); + ui.label(player.1.to_string()); + if Some(*player.0) == connection.identifier() { + ui.label("The most beautiful admin (You)"); + continue; + } + let button = ui.button(format!("Kick {}", player.1)); + if button.clicked() { + for target_player in all_players.0.iter() { + event.send(SendTo(*target_player.0, RemovePlayer { uuid: *player.0 })); + } + } + } + + ui.separator(); + if ui.button("Run the game").clicked() { + next_scene.set(CurrentScene::Game); + } + }); +} + +/// TODO +fn handle_request( + mut events: EventReader>, + all_players: Res, + mut new_players: EventWriter>, +) { + for event in events.read() { + for player in all_players.0.iter() { + let player1 = (event.0, event.1.name.clone()); + let player2 = (*player.0, player.1.clone()); + link_two_players(player1, player2, &mut new_players); + } + } +} + +/// TODO +fn link_two_players( + player1: (Uuid, String), + player2: (Uuid, String), + event: &mut EventWriter>, +) { + event.send(SendTo( + player1.0, + AddPlayer { + uuid: player2.0, + name: player2.1.clone(), + }, + )); + event.send(SendTo( + player2.0, + AddPlayer { + uuid: player1.0, + name: player1.1, + }, + )) +} diff --git a/crates/border-wars/src/scenes/lobby.rs b/crates/border-wars/src/scenes/lobby.rs index c5ff7cb..3d60ad1 100644 --- a/crates/border-wars/src/scenes/lobby.rs +++ b/crates/border-wars/src/scenes/lobby.rs @@ -1,90 +1,33 @@ -//! The lobby of the game. +//! The file containing the lobby scene where players can wait. -use bevnet::{Connection, Receive, SendTo}; use bevy::prelude::*; use bevy_egui::{egui, EguiContexts}; -use crate::connection::{AddPlayer, AllPlayers, RemovePlayer, RequestConnection}; +use super::handle_new_players; +use crate::connection::AllPlayers; use crate::CurrentScene; /// The plugin for the lobby. -pub struct LobbyPlugin; +pub struct WaitingMenuPlugin; -impl Plugin for LobbyPlugin { +impl Plugin for WaitingMenuPlugin { fn build(&self, app: &mut App) { app.add_systems( Update, - (lobby_ui, handle_request).run_if(in_state(CurrentScene::Lobby)), + (ui, handle_new_players).run_if(in_state(CurrentScene::Lobby)), ); } } -/// Display the UI of the lobby. -fn lobby_ui( - mut ctx: EguiContexts, - mut next_scene: ResMut>, - connection: Res, - mut all_players: ResMut, - mut event: EventWriter>, -) { +/// TODO +fn ui(all_players: Res, mut ctx: EguiContexts) { egui::CentralPanel::default().show(ctx.ctx_mut(), |ui| { ui.heading("Border Wars"); ui.separator(); - ui.label("Game created"); - ui.horizontal(|ui| { - ui.label("Game ID: "); - // TODO : get the game ID and display it. - ui.text_edit_singleline(&mut connection.identifier().unwrap().to_string()); - }); - - ui.separator(); - - if ui.button("Run the game").clicked() { - next_scene.set(CurrentScene::Game); - // TODO: run the game - } - }); - egui::Window::new("Admin").show(ctx.ctx_mut(), |ui| { - for player in all_players.0.iter() { - ui.label(format!("{}", player.1)); - ui.separator(); - if player.0 == &connection.identifier().unwrap() { - continue; - } - let button = ui.button(format!("Kick {}", player.1)); - if button.clicked() { - for target_player in all_players.0.iter() { - event.send(SendTo(*target_player.0, RemovePlayer { uuid: *player.0 })); - } - } + for (uuid, name) in all_players.0.iter() { + ui.label(format!("{}: {}", uuid, name)); } }); } - -fn handle_request( - mut events: EventReader>, - mut all_players: ResMut, - mut new_players: EventWriter>, -) { - for event in events.iter() { - all_players.0.insert(event.0, event.1.name.clone()); - for player in all_players.0.iter() { - new_players.send(SendTo( - *player.0, - AddPlayer { - uuid: event.0, - name: event.1.name.clone(), - }, - )); - new_players.send(SendTo( - event.0, - AddPlayer { - uuid: *player.0, - name: player.1.clone(), - }, - )) - } - } -} diff --git a/crates/border-wars/src/scenes/menu.rs b/crates/border-wars/src/scenes/menu.rs index d9a6c87..0dd631b 100644 --- a/crates/border-wars/src/scenes/menu.rs +++ b/crates/border-wars/src/scenes/menu.rs @@ -23,10 +23,18 @@ fn menu_ui( mut ctx: EguiContexts, mut connection_string: Local, mut next_scene: ResMut>, - mut all_players: ResMut, - mut connection: Res, + all_players: Res, + connection: Res, mut request_join_event: EventWriter>, ) { + let Some(connection_id) = connection.identifier() else { + return; + }; + + let Ok(target_uuid) = Uuid::parse_str(&connection_string) else { + return; + }; + egui::CentralPanel::default().show(ctx.ctx_mut(), |ui| { ui.heading("Border Wars"); @@ -38,14 +46,14 @@ fn menu_ui( ui.text_edit_singleline(&mut *connection_string); if ui.button("Join").clicked() { - next_scene.set(CurrentScene::WaitingMenu); + next_scene.set(CurrentScene::Lobby); request_join_event.send(SendTo( - Uuid::parse_str(&connection_string).unwrap(), + target_uuid, RequestConnection { name: all_players .0 - .get(&connection.identifier().unwrap()) - .unwrap() + .get(&connection_id) + .unwrap_or(&"Unknown".to_string()) .clone(), }, )); @@ -55,25 +63,26 @@ fn menu_ui( ui.separator(); if ui.button("Create new game").clicked() { - next_scene.set(CurrentScene::Lobby); + next_scene.set(CurrentScene::AdminLobby); } }); } +/// TODO fn name_settings( mut ctx: EguiContexts, mut all_players: ResMut, mut local_name: Local, - mut connection: Res, + connection: Res, ) { + let Some(connection_id) = connection.identifier() else { + return; + }; egui::Window::new("Name settings").show(ctx.ctx_mut(), |ui| { ui.label("Enter your name:"); ui.horizontal(|ui| { - let text = ui.text_edit_singleline(&mut *local_name); - if text.changed() { - all_players - .0 - .insert(connection.identifier().unwrap(), local_name.to_string()); + if ui.text_edit_singleline(&mut *local_name).changed() { + all_players.0.insert(connection_id, local_name.to_string()); } }); }); diff --git a/crates/border-wars/src/scenes/mod.rs b/crates/border-wars/src/scenes/mod.rs index 3874fe2..7285aed 100644 --- a/crates/border-wars/src/scenes/mod.rs +++ b/crates/border-wars/src/scenes/mod.rs @@ -1,13 +1,15 @@ //! The file containing all scenes programs. +use bevnet::{Connection, Receive}; use bevy::prelude::*; use bevy_egui::EguiPlugin; +use crate::connection::{AddPlayer, AllPlayers, RemovePlayer}; use crate::{responsive_scale, CurrentScene}; +pub mod admin_lobby; pub mod lobby; pub mod menu; -pub mod waiting_menu; /// The plugin for all scenes. pub struct ScenesPlugin; @@ -17,8 +19,30 @@ impl Plugin for ScenesPlugin { app.add_plugins(EguiPlugin) .add_state::() .add_plugins(menu::MenuPlugin) - .add_plugins(lobby::LobbyPlugin) - .add_plugins(waiting_menu::WaitingMenuPlugin) + .add_plugins(admin_lobby::LobbyPlugin) + .add_plugins(lobby::WaitingMenuPlugin) .add_plugins(responsive_scale::ResponsiveScalingPlugin); } } + +/// TODO +pub fn handle_new_players( + mut all_players: ResMut, + mut new_players: EventReader>, + mut remove_players: EventReader>, + self_uuid: Res, + mut next_scene: ResMut>, +) { + for new_player in new_players.read() { + all_players + .0 + .insert(new_player.1.uuid, new_player.1.name.clone()); + } + + for remove_player in remove_players.read() { + if remove_player.1.uuid == self_uuid.identifier().unwrap_or_default() { + next_scene.set(CurrentScene::Menu); + } + all_players.0.remove(&remove_player.1.uuid); + } +} diff --git a/crates/border-wars/src/scenes/waiting_menu.rs b/crates/border-wars/src/scenes/waiting_menu.rs deleted file mode 100644 index 1e5c6cc..0000000 --- a/crates/border-wars/src/scenes/waiting_menu.rs +++ /dev/null @@ -1,52 +0,0 @@ -//! TODO - -use bevnet::{Connection, Receive}; -use bevy::prelude::*; -use bevy_egui::{egui, EguiContexts}; - -use crate::connection::{AddPlayer, AllPlayers, RemovePlayer, RequestConnection}; -use crate::CurrentScene; - -/// The plugin for the lobby. -pub struct WaitingMenuPlugin; - -impl Plugin for WaitingMenuPlugin { - fn build(&self, app: &mut App) { - app.add_systems( - Update, - (ui, handle_new_players).run_if(in_state(CurrentScene::WaitingMenu)), - ); - } -} - -fn ui(all_players: Res, mut ctx: EguiContexts) { - egui::CentralPanel::default().show(ctx.ctx_mut(), |ui| { - ui.heading("Border Wars"); - - ui.separator(); - - for (uuid, name) in all_players.0.iter() { - ui.label(format!("{}: {}", uuid, name)); - } - }); -} - -fn handle_new_players( - mut all_players: ResMut, - mut new_players: EventReader>, - mut remove_players: EventReader>, - self_uuid: Res, -) { - for new_player in new_players.iter() { - all_players - .0 - .insert(new_player.1.uuid, new_player.1.name.clone()); - } - - for remove_player in remove_players.iter() { - if remove_player.1.uuid == self_uuid.identifier().unwrap() { - todo!("end the game"); - } - all_players.0.remove(&remove_player.1.uuid); - } -}