Skip to content

Commit

Permalink
Multiplayer: end game on error (#623)
Browse files Browse the repository at this point in the history
  • Loading branch information
Indy2222 authored Jul 14, 2023
1 parent ed6d5c5 commit 5d5abb8
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 11 deletions.
25 changes: 22 additions & 3 deletions crates/core/src/gresult.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
use bevy::prelude::Resource;

#[derive(Resource)]
pub struct GameResult {
won: bool,
pub enum GameResult {
/// Game finished normally with the player either loosing or winning.
Finished(NormalResult),
/// The game finished due to an error.
Error(String),
}

impl GameResult {
pub fn new(won: bool) -> Self {
/// Create new normally finished game result.
pub fn finished(won: bool) -> Self {
Self::Finished(NormalResult::new(won))
}

/// Create game result from an error.
pub fn error(message: impl ToString) -> Self {
Self::Error(message.to_string())
}
}

pub struct NormalResult {
won: bool,
}

impl NormalResult {
fn new(won: bool) -> Self {
Self { won }
}

Expand Down
16 changes: 12 additions & 4 deletions crates/menu/src/aftergame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,18 @@ fn cleanup(mut commands: Commands) {
}

fn setup(mut commands: GuiCommands, menu: Res<Menu>, result: Res<GameResult>) {
let text = if result.won() {
"You have won!"
} else {
"You have lost! "
let text = match result.as_ref() {
GameResult::Finished(result) => {
if result.won() {
"You have won!".to_owned()
} else {
"You have lost!".to_owned()
}
}
GameResult::Error(message) => {
error!("Game finished with an error: {message}");
format!("Error: {message}")
}
};
let text_id = commands.spawn_label(OuterStyle::default(), text).id();
commands.entity(menu.root_node()).add_child(text_id);
Expand Down
18 changes: 16 additions & 2 deletions crates/multiplayer/src/lifecycle.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::ops::Deref;

use bevy::prelude::*;
use de_core::state::AppState;
use de_core::{gresult::GameResult, state::AppState};
use de_gui::ToastEvent;

use crate::{config::NetGameConf, NetState};
Expand All @@ -14,6 +14,11 @@ impl Plugin for LifecyclePlugin {
.add_event::<ShutdownMultiplayerEvent>()
.add_event::<FatalErrorEvent>()
.add_system(cleanup.in_schedule(OnEnter(NetState::None)))
.add_system(
finish_game
.in_schedule(OnEnter(NetState::None))
.run_if(in_state(AppState::InGame)),
)
.add_system(
game_left
.in_schedule(OnExit(AppState::InGame))
Expand All @@ -26,7 +31,9 @@ impl Plugin for LifecyclePlugin {
)
.add_system(
shutdown
.run_if(not(in_state(NetState::None)))
.run_if(not(
in_state(NetState::None).or_else(in_state(NetState::ShuttingDown))
))
.run_if(on_event::<ShutdownMultiplayerEvent>()),
)
.add_system(
Expand Down Expand Up @@ -81,6 +88,10 @@ fn cleanup(mut commands: Commands) {
commands.remove_resource::<NetGameConfRes>();
}

fn finish_game(mut next_state: ResMut<NextState<AppState>>) {
next_state.set(AppState::InMenu);
}

fn start(
mut commands: Commands,
mut next_state: ResMut<NextState<NetState>>,
Expand All @@ -99,6 +110,7 @@ fn shutdown(mut next_state: ResMut<NextState<NetState>>) {
}

fn errors(
mut commands: Commands,
mut events: EventReader<FatalErrorEvent>,
mut toasts: EventWriter<ToastEvent>,
mut shutdowns: EventWriter<ShutdownMultiplayerEvent>,
Expand All @@ -111,6 +123,8 @@ fn errors(
toasts.send(ToastEvent::new(&event.0));
shutdowns.send(ShutdownMultiplayerEvent);

commands.insert_resource(GameResult::error(&event.0));

events.clear();
}

Expand Down
4 changes: 2 additions & 2 deletions crates/spawner/src/gameend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ fn game_end_detection_system(
) {
let mut result = None;
if counter.player(conf.locals().playable()).unwrap().total() == 0 {
result = Some(GameResult::new(false));
result = Some(GameResult::finished(false));
} else if conf.players().all(|player| {
conf.locals().is_playable(player) || counter.player(player).unwrap().total() == 0
}) {
result = Some(GameResult::new(true));
result = Some(GameResult::finished(true));
}

if let Some(result) = result {
Expand Down

0 comments on commit 5d5abb8

Please sign in to comment.