Add the ability to pause singleplayer matches (#68)
Reviewed-on: #68 Co-authored-by: Álex Román Núñez <eirexe@eirteam.moe>
This commit was merged in pull request #68.
This commit is contained in:
+59
-3
@@ -1,9 +1,14 @@
|
||||
//! Rollback-simulated state for an active match.
|
||||
|
||||
use bevy::input::InputSystems;
|
||||
use bevy::prelude::*;
|
||||
use bevy_ggrs::prelude::*;
|
||||
use bevy_ggrs::{RunGgrsSystems, prelude::*};
|
||||
|
||||
use crate::match_loading::{MatchConfig, MatchRules};
|
||||
use crate::{
|
||||
AppState,
|
||||
match_loading::{MatchConfig, MatchRules},
|
||||
netcode::session::SessionConfig,
|
||||
};
|
||||
|
||||
#[derive(Resource, Clone, Debug, Hash, PartialEq, Eq)]
|
||||
pub struct MatchState {
|
||||
@@ -19,6 +24,11 @@ pub struct PlayerMatchState {
|
||||
pub deaths: u32,
|
||||
}
|
||||
|
||||
#[derive(Resource, Debug, Default, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct PauseState {
|
||||
pub paused: bool,
|
||||
}
|
||||
|
||||
impl MatchState {
|
||||
pub fn from_config(config: &MatchConfig) -> Self {
|
||||
let stocks_remaining = match &config.rules {
|
||||
@@ -46,10 +56,56 @@ pub struct MatchRuntimePlugin;
|
||||
impl Plugin for MatchRuntimePlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.rollback_resource_with_clone::<MatchState>()
|
||||
.checksum_resource_with_hash::<MatchState>();
|
||||
.checksum_resource_with_hash::<MatchState>()
|
||||
.init_resource::<PauseState>()
|
||||
.configure_sets(PreUpdate, RunGgrsSystems.run_if(ggrs_should_run))
|
||||
.add_systems(OnEnter(AppState::InMatch), reset_pause)
|
||||
.add_systems(OnExit(AppState::InMatch), reset_pause)
|
||||
.add_systems(
|
||||
PreUpdate,
|
||||
toggle_pause
|
||||
.after(InputSystems)
|
||||
.before(RunGgrsSystems)
|
||||
.run_if(in_state(AppState::InMatch)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ggrs_should_run(pause: Option<Res<PauseState>>) -> bool {
|
||||
!pause.is_some_and(|pause| pause.paused)
|
||||
}
|
||||
|
||||
fn toggle_pause(
|
||||
key: Res<ButtonInput<KeyCode>>,
|
||||
gamepads: Query<&Gamepad>,
|
||||
session: Res<SessionConfig>,
|
||||
mut pause: ResMut<PauseState>,
|
||||
mut virtual_time: ResMut<Time<Virtual>>,
|
||||
) {
|
||||
if session.is_multiplayer() {
|
||||
return;
|
||||
}
|
||||
|
||||
let pressed = key.just_pressed(KeyCode::Escape)
|
||||
|| gamepads
|
||||
.iter()
|
||||
.any(|gamepad| gamepad.just_pressed(GamepadButton::Start));
|
||||
if !pressed {
|
||||
return;
|
||||
}
|
||||
|
||||
pause.paused = !pause.paused;
|
||||
virtual_time.toggle();
|
||||
}
|
||||
|
||||
fn reset_pause(
|
||||
mut pause: ResMut<PauseState>,
|
||||
mut virtual_time: ResMut<Time<Virtual>>,
|
||||
) {
|
||||
pause.paused = false;
|
||||
virtual_time.unpause();
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user