Skip to content

Commit

Permalink
fix: UI for leaving online game when disconnected (#1002)
Browse files Browse the repository at this point in the history
During a game, if all other players have been disconnected, UI pop-up
will notify player providing button to return to main menu.

If one player but not all have disconnected, going to have game keep
going / figure out how to handle this separately.

Relates to #994, will not fix
anything, but if hung due to disconnect, will inform player at least.

Depends on fishfolk/bones#409, CI will fail
until merged + update bones version.
  • Loading branch information
MaxCWhitehead authored Jun 8, 2024
1 parent 6bbb037 commit 5f1f40d
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 13 deletions.
26 changes: 13 additions & 13 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions assets/locales/en-US/network-game.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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
5 changes: 5 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions src/sessions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
1 change: 1 addition & 0 deletions src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
105 changes: 105 additions & 0 deletions src/ui/notification.rs
Original file line number Diff line number Diff line change
@@ -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<GameMeta>,
ctx: Res<EguiCtx>,
mut sessions: ResMut<Sessions>,
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::<DisconnectedPlayers>()
{
// 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::<PlayerIdx>().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<GameMeta>,
meta: Root<GameMeta>,
) {
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();
}));
}
});
}

0 comments on commit 5f1f40d

Please sign in to comment.