diff --git a/Cargo.lock b/Cargo.lock index 2cacdac3b..f92c317ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1246,7 +1246,7 @@ dependencies = [ [[package]] name = "bones_asset" version = "0.3.0" -source = "git+https://github.com/fishfolk/bones#3cb6a880284514c8367ededa62d45e90f48c60b6" +source = "git+https://github.com/fishfolk/bones#8a9492b4af9d111c672c654badbc9872e4c05fde" dependencies = [ "anyhow", "append-only-vec", @@ -1277,7 +1277,7 @@ dependencies = [ [[package]] name = "bones_bevy_renderer" version = "0.3.0" -source = "git+https://github.com/fishfolk/bones#3cb6a880284514c8367ededa62d45e90f48c60b6" +source = "git+https://github.com/fishfolk/bones#8a9492b4af9d111c672c654badbc9872e4c05fde" dependencies = [ "anyhow", "bevy", @@ -1294,7 +1294,7 @@ dependencies = [ [[package]] name = "bones_ecs" version = "0.3.0" -source = "git+https://github.com/fishfolk/bones#3cb6a880284514c8367ededa62d45e90f48c60b6" +source = "git+https://github.com/fishfolk/bones#8a9492b4af9d111c672c654badbc9872e4c05fde" dependencies = [ "anyhow", "atomicell", @@ -1311,7 +1311,7 @@ dependencies = [ [[package]] name = "bones_ecs_macros" version = "0.3.0" -source = "git+https://github.com/fishfolk/bones#3cb6a880284514c8367ededa62d45e90f48c60b6" +source = "git+https://github.com/fishfolk/bones#8a9492b4af9d111c672c654badbc9872e4c05fde" dependencies = [ "bones_ecs_macros_core", "proc-macro2", @@ -1320,7 +1320,7 @@ dependencies = [ [[package]] name = "bones_ecs_macros_core" version = "0.3.0" -source = "git+https://github.com/fishfolk/bones#3cb6a880284514c8367ededa62d45e90f48c60b6" +source = "git+https://github.com/fishfolk/bones#8a9492b4af9d111c672c654badbc9872e4c05fde" dependencies = [ "proc-macro2", "quote", @@ -1330,7 +1330,7 @@ dependencies = [ [[package]] name = "bones_framework" version = "0.3.0" -source = "git+https://github.com/fishfolk/bones#3cb6a880284514c8367ededa62d45e90f48c60b6" +source = "git+https://github.com/fishfolk/bones#8a9492b4af9d111c672c654badbc9872e4c05fde" dependencies = [ "anyhow", "async-channel", @@ -1379,7 +1379,7 @@ dependencies = [ [[package]] name = "bones_lib" version = "0.3.0" -source = "git+https://github.com/fishfolk/bones#3cb6a880284514c8367ededa62d45e90f48c60b6" +source = "git+https://github.com/fishfolk/bones#8a9492b4af9d111c672c654badbc9872e4c05fde" dependencies = [ "bones_ecs", "instant", @@ -1388,7 +1388,7 @@ dependencies = [ [[package]] name = "bones_matchmaker_proto" version = "0.2.0" -source = "git+https://github.com/fishfolk/bones#3cb6a880284514c8367ededa62d45e90f48c60b6" +source = "git+https://github.com/fishfolk/bones#8a9492b4af9d111c672c654badbc9872e4c05fde" dependencies = [ "iroh-net", "serde", @@ -1397,7 +1397,7 @@ dependencies = [ [[package]] name = "bones_schema" version = "0.3.0" -source = "git+https://github.com/fishfolk/bones#3cb6a880284514c8367ededa62d45e90f48c60b6" +source = "git+https://github.com/fishfolk/bones#8a9492b4af9d111c672c654badbc9872e4c05fde" dependencies = [ "append-only-vec", "bones_schema_macros", @@ -1415,7 +1415,7 @@ dependencies = [ [[package]] name = "bones_schema_macros" version = "0.3.0" -source = "git+https://github.com/fishfolk/bones#3cb6a880284514c8367ededa62d45e90f48c60b6" +source = "git+https://github.com/fishfolk/bones#8a9492b4af9d111c672c654badbc9872e4c05fde" dependencies = [ "proc-macro2", "quote", @@ -1425,7 +1425,7 @@ dependencies = [ [[package]] name = "bones_scripting" version = "0.3.0" -source = "git+https://github.com/fishfolk/bones#3cb6a880284514c8367ededa62d45e90f48c60b6" +source = "git+https://github.com/fishfolk/bones#8a9492b4af9d111c672c654badbc9872e4c05fde" dependencies = [ "async-channel", "bevy_tasks", @@ -1442,7 +1442,7 @@ dependencies = [ [[package]] name = "bones_utils" version = "0.3.0" -source = "git+https://github.com/fishfolk/bones#3cb6a880284514c8367ededa62d45e90f48c60b6" +source = "git+https://github.com/fishfolk/bones#8a9492b4af9d111c672c654badbc9872e4c05fde" dependencies = [ "bones_utils_macros", "branches", @@ -1463,7 +1463,7 @@ dependencies = [ [[package]] name = "bones_utils_macros" version = "0.3.0" -source = "git+https://github.com/fishfolk/bones#3cb6a880284514c8367ededa62d45e90f48c60b6" +source = "git+https://github.com/fishfolk/bones#8a9492b4af9d111c672c654badbc9872e4c05fde" dependencies = [ "quote", "venial", diff --git a/assets/locales/en-US/network-game.ftl b/assets/locales/en-US/network-game.ftl index 1b7292ebc..d28048bd1 100644 --- a/assets/locales/en-US/network-game.ftl +++ b/assets/locales/en-US/network-game.ftl @@ -20,3 +20,8 @@ connected-and-querying = Connected waiting-for-players = Waiting for Players: { $current } / { $total } match-ready = Match Ready! error = Error + +# Pop-ups +disconnected = Disconnected +disconnected-from-all = Disconnected from all other players. +exit-match = Exit Match diff --git a/src/main.rs b/src/main.rs index 2b07d4efe..070382d21 100644 --- a/src/main.rs +++ b/src/main.rs @@ -185,6 +185,11 @@ fn main() { .create(SessionNames::SCORING) .install_plugin(ui::scoring::session_plugin); + // session for pop-ups / nofication UI + game.sessions + .create(SessionNames::NOTIFICATION) + .install_plugin(ui::notification::session_plugin); + // Create a bevy renderer for the bones game and run it. BonesBevyRenderer { game, diff --git a/src/sessions.rs b/src/sessions.rs index 4bca4f5e0..6a5621c18 100644 --- a/src/sessions.rs +++ b/src/sessions.rs @@ -9,6 +9,7 @@ impl SessionNames { pub const PAUSE_MENU: &'static str = "pause_menu"; pub const PROFILER: &'static str = "profiler"; pub const SCORING: &'static str = "scoring"; + pub const NOTIFICATION: &'static str = "notification"; } pub trait SessionExt { diff --git a/src/ui.rs b/src/ui.rs index 79a825a4a..e55e92ce0 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -2,6 +2,7 @@ use crate::prelude::*; pub mod main_menu; pub mod map_select; +pub mod notification; pub mod pause_menu; pub mod player_image; pub mod scoring; diff --git a/src/ui/notification.rs b/src/ui/notification.rs new file mode 100644 index 000000000..8e4213198 --- /dev/null +++ b/src/ui/notification.rs @@ -0,0 +1,105 @@ +use std::borrow::BorrowMut; + +use crate::prelude::*; + +#[allow(unused_variables)] +pub fn session_plugin(session: &mut Session) { + #[cfg(not(target_arch = "wasm32"))] + session.add_system_to_stage(Update, network_disconnect_notify); +} + +pub fn network_disconnect_notify( + meta: Root, + ctx: Res, + mut sessions: ResMut, + world: &World, +) { + let sessions = sessions.borrow_mut(); + #[allow(unused_assignments, unused_mut)] + let mut all_players_disconnected = false; + + #[cfg(not(target_arch = "wasm32"))] + { + all_players_disconnected = if let Some(game_session) = sessions.get(SessionNames::GAME) { + if let Some(disconnected_players) = + game_session.world.resources.get::() + { + // Determine if all remote players have been disconnected + // (Disconnected players should be player count - 1, can not have local player) + let player_indices = game_session.world.components.get::().borrow(); + + !disconnected_players.disconnected_players.is_empty() + && player_indices.bitset().bit_count() - 1 + == disconnected_players.disconnected_players.len() + } else { + false + } + } else { + false + }; + } + + if all_players_disconnected { + egui::CentralPanel::default() + .frame(egui::Frame::none()) + .show(&ctx, |ui| { + ui.vertical_centered(|ui| { + // Calculate a margin + let screen_rect = ui.max_rect(); + let outer_margin = screen_rect.size() * 0.10; + let outer_margin = egui::Margin { + left: outer_margin.x, + right: outer_margin.x, + top: outer_margin.y * 3.0, + bottom: outer_margin.y, + }; + + BorderedFrame::new(&meta.theme.panel.border) + .margin(outer_margin) + .padding(meta.theme.panel.padding) + .show(ui, |ui| { + world.run_system( + network_disconnect_notify_ui, + (ui, sessions.borrow_mut()), + ) + }); + }); + }); + } +} + +fn network_disconnect_notify_ui( + mut param: In<(&mut egui::Ui, &mut Sessions)>, + localization: Localization, + meta: Root, +) { + let (ui, sessions) = &mut *param; + ui.vertical_centered(|ui| { + ui.label( + meta.theme + .font_styles + .heading + .rich(localization.get("disconnected")), + ); + + ui.add_space(meta.theme.font_styles.normal.size); + ui.label( + meta.theme + .font_styles + .normal + .rich(localization.get("disconnected-from-all")), + ); + ui.add_space(meta.theme.font_styles.normal.size); + + if BorderedButton::themed(&meta.theme.buttons.normal, localization.get("exit-match")) + .show(ui) + .focus_by_default(ui) + .clicked() + { + sessions.add_command(Box::new(move |sessions: &mut Sessions| { + sessions.end_game(); + sessions.start_menu(); + })); + } + }); +}