Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Indy2222 committed Aug 16, 2023
1 parent 757173c commit b364d72
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 13 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

18 changes: 14 additions & 4 deletions crates/core/src/gconfig.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::path::{Path, PathBuf};

use bevy::prelude::Resource;
use tinyvec::ArrayVec;
use tinyvec::{array_vec, ArrayVec};

use crate::player::{Player, PlayerRange};

Expand Down Expand Up @@ -30,6 +30,8 @@ impl GameConfig {
}
}

type PlayerVec = ArrayVec<[Player; Player::MAX_PLAYERS]>;

/// Info about players directly controlled or simulated on this computer.
///
/// "Playable" is the player directly controlled by the user of this computer.
Expand All @@ -39,7 +41,7 @@ impl GameConfig {
/// exactly one computer.
pub struct LocalPlayers {
playable: Player,
locals: ArrayVec<[Player; Player::MAX_PLAYERS]>,
locals: PlayerVec,
}

impl LocalPlayers {
Expand All @@ -48,7 +50,11 @@ impl LocalPlayers {
}

pub fn from_range(playable: Player, locals: PlayerRange) -> Self {
Self::new(playable, locals.collect())
Self::new(playable, locals.collect::<PlayerVec>())
}

pub fn from_single(playable: Player) -> Self {
Self::new(playable, array_vec!(_ => playable))
}

/// # Arguments
Expand All @@ -57,7 +63,11 @@ impl LocalPlayers {
///
/// * `locals` - other players simulated locally on this computer. It must
/// include `playable`.
pub fn new(playable: Player, locals: ArrayVec<[Player; Player::MAX_PLAYERS]>) -> Self {
pub fn new<A>(playable: Player, locals: A) -> Self
where
A: Into<PlayerVec>,
{
let locals = locals.into();
assert!((*locals).contains(&playable));
Self { playable, locals }
}
Expand Down
2 changes: 1 addition & 1 deletion crates/map/src/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ impl MapHash {
}

/// Constructs the map hash from a hexadecimal string.
pub(crate) fn from_hex(hex: &str) -> Result<Self, HexError> {
pub fn from_hex(hex: &str) -> Result<Self, HexError> {
if hex.len() != 64 {
return Err(HexError::InvalidLenError);
}
Expand Down
1 change: 1 addition & 0 deletions crates/menu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ de_gui.workspace = true
de_lobby_client.workspace = true
de_lobby_model.workspace = true
de_map.workspace = true
de_messages.workspace = true
de_multiplayer.workspace = true

# Other
Expand Down
71 changes: 68 additions & 3 deletions crates/menu/src/multiplayer/joined/state.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
use bevy::prelude::*;
use de_core::state::AppState;
use de_core::{
assets::asset_path,
gconfig::{GameConfig, LocalPlayers},
player::Player,
state::AppState,
};
use de_gui::ToastEvent;
use de_lobby_client::GetGameRequest;
use de_multiplayer::{PeerJoinedEvent, PeerLeftEvent, ShutdownMultiplayerEvent};
use de_map::hash::MapHash;
use de_messages::Readiness;
use de_multiplayer::{
GameReadinessEvent, PeerJoinedEvent, PeerLeftEvent, ShutdownMultiplayerEvent,
};

use super::ui::RefreshPlayersEvent;
use crate::multiplayer::{
Expand All @@ -29,7 +38,22 @@ impl Plugin for JoinedGameStatePlugin {
}
}

fn cleanup(state: Res<State<AppState>>, mut shutdown: EventWriter<ShutdownMultiplayerEvent>) {
#[derive(Resource)]
pub(super) struct LocalPlayerRes(Player);

impl LocalPlayerRes {
pub(super) fn new(player: Player) -> Self {
Self(player)
}
}

fn cleanup(
mut commands: Commands,
state: Res<State<AppState>>,
mut shutdown: EventWriter<ShutdownMultiplayerEvent>,
) {
commands.remove_resource::<LocalPlayerRes>();

if state.as_ref() != &AppState::InGame {
shutdown.send(ShutdownMultiplayerEvent);
}
Expand All @@ -40,6 +64,19 @@ fn refresh(game_name: Res<GameNameRes>, mut sender: Sender<GetGameRequest>) {
sender.send(GetGameRequest::new(game_name.name_owned()));
}

fn handle_readiness(
mut events: EventReader<GameReadinessEvent>,
game_name: Res<GameNameRes>,
mut sender: Sender<GetGameRequest>,
) {
if events.iter().all(|e| **e != Readiness::Ready) {
return;
}

sender.send(GetGameRequest::new(game_name.name_owned()));
// TODO marek the game as ready
}

fn handle_get_response(
mut multi_state: ResMut<NextState<MultiplayerState>>,
mut receiver: Receiver<GetGameRequest>,
Expand All @@ -58,3 +95,31 @@ fn handle_get_response(
}
}
}

fn start(
mut commands: Commands,
player: Res<LocalPlayerRes>,
mut app_state: ResMut<NextState<AppState>>,
mut multi_state: ResMut<NextState<MultiplayerState>>,
mut toasts: EventWriter<ToastEvent>,
) {
// TODO config via event

let game_conf = game.setup().config();
let map_path = match MapHash::from_hex(game_conf.map().hash()) {
Ok(hash) => hash.construct_path(asset_path("maps")),
Err(error) => {
toasts.send(ToastEvent::new(error));
multi_state.set(MultiplayerState::SignIn);
return;
}
};

commands.insert_resource(GameConfig::new(
map_path,
LocalPlayers::from_single(player.0),
));
app_state.set(AppState::InGame);
}

// TODO handle ready button event
2 changes: 2 additions & 0 deletions crates/menu/src/multiplayer/joined/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,5 @@ fn row(commands: &mut GuiCommands, player: &GamePlayer) -> Entity {

row_id
}

// TODO ready button + click event
5 changes: 5 additions & 0 deletions crates/menu/src/multiplayer/joining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use de_multiplayer::{

use super::{
current::GameNameRes,
joined::LocalPlayerRes,
requests::{Receiver, Sender},
MultiplayerState,
};
Expand All @@ -31,10 +32,12 @@ impl Plugin for JoiningGamePlugin {
}

fn cleanup(
mut commands: Commands,
state: Res<State<MultiplayerState>>,
mut shutdown: EventWriter<ShutdownMultiplayerEvent>,
) {
if state.as_ref() != &MultiplayerState::GameJoined {
commands.remove_resource::<LocalPlayerRes>();
shutdown.send(ShutdownMultiplayerEvent);
}
}
Expand Down Expand Up @@ -67,6 +70,7 @@ fn handle_get_response(
}

fn handle_joined_event(
mut commands: Commands,
game_name: Res<GameNameRes>,
mut events: EventReader<GameJoinedEvent>,
mut sender: Sender<JoinGameRequest>,
Expand All @@ -75,6 +79,7 @@ fn handle_joined_event(
return;
};

commands.insert_resource(LocalPlayerRes::new(event.player()));
sender.send(JoinGameRequest::new(
game_name.name_owned(),
GamePlayerInfo::new(event.player().to_num()),
Expand Down
39 changes: 36 additions & 3 deletions crates/menu/src/multiplayer/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ use de_gui::ToastEvent;
use de_lobby_client::CreateGameRequest;
use de_lobby_model::{GameConfig, GameSetup};
use de_multiplayer::{
ConnectionType, GameOpenedEvent, NetGameConf, ShutdownMultiplayerEvent, StartMultiplayerEvent,
ConnectionType, GameJoinedEvent, GameOpenedEvent, NetGameConf, ShutdownMultiplayerEvent,
StartMultiplayerEvent,
};

use super::{
current::GameNameRes,
joined::LocalPlayerRes,
requests::{Receiver, Sender},
MultiplayerState,
};
Expand All @@ -27,8 +29,16 @@ impl Plugin for SetupGamePlugin {
)
.add_systems(
Update,
(create_game_in_lobby, handle_lobby_response)
(
create_game_in_lobby,
handle_lobby_response,
handle_joined_event,
)
.run_if(in_state(MultiplayerState::GameSetup)),
)
.add_systems(
PostUpdate,
move_once_ready.run_if(in_state(MultiplayerState::GameSetup)),
);
}
}
Expand All @@ -52,6 +62,9 @@ impl SetupGameEvent {
#[derive(Resource)]
pub(crate) struct GameConfigRes(GameConfig);

#[derive(Resource)]
struct JoinedMarker;

fn handle_setup_event(
mut commands: Commands,
mut next_state: ResMut<NextState<MultiplayerState>>,
Expand All @@ -65,14 +78,26 @@ fn handle_setup_event(
next_state.set(MultiplayerState::GameSetup);
}

fn move_once_ready(
joined: Option<Res<JoinedMarker>>,
local_player: Option<Res<LocalPlayerRes>>,
mut next_state: ResMut<NextState<MultiplayerState>>,
) {
if joined.is_some() && local_player.is_some() {
next_state.set(MultiplayerState::GameJoined);
}
}

fn cleanup(
mut commands: Commands,
state: Res<State<MultiplayerState>>,
mut shutdown: EventWriter<ShutdownMultiplayerEvent>,
) {
commands.remove_resource::<GameConfigRes>();
commands.remove_resource::<JoinedMarker>();

if state.as_ref() != &MultiplayerState::GameJoined {
commands.remove_resource::<LocalPlayerRes>();
shutdown.send(ShutdownMultiplayerEvent);
}
}
Expand Down Expand Up @@ -109,7 +134,15 @@ fn create_game_in_lobby(
sender.send(CreateGameRequest::new(game_setup));
}

fn handle_joined_event(mut commands: Commands, mut events: EventReader<GameJoinedEvent>) {
let Some(event) = events.iter().last() else {
return;
};
commands.insert_resource(LocalPlayerRes::new(event.player()));
}

fn handle_lobby_response(
mut commands: Commands,
mut next_state: ResMut<NextState<MultiplayerState>>,
mut receiver: Receiver<CreateGameRequest>,
mut toasts: EventWriter<ToastEvent>,
Expand All @@ -118,7 +151,7 @@ fn handle_lobby_response(
match result {
Ok(_) => {
info!("Game successfully created.");
next_state.set(MultiplayerState::GameJoined);
commands.insert_resource(JoinedMarker);
}
Err(error) => {
toasts.send(ToastEvent::new(error));
Expand Down
9 changes: 8 additions & 1 deletion crates/multiplayer/src/game.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::net::SocketAddr;

use bevy::prelude::*;
use de_core::{player::Player, schedule::PreMovement};
use de_messages::{FromGame, FromServer, GameOpenError, JoinError, ToGame, ToServer};
use de_messages::{FromGame, FromServer, GameOpenError, JoinError, Readiness, ToGame, ToServer};

use crate::{
config::ConnectionType,
Expand All @@ -22,6 +22,7 @@ impl Plugin for GamePlugin {
.add_event::<GameJoinedEvent>()
.add_event::<PeerJoinedEvent>()
.add_event::<PeerLeftEvent>()
.add_event::<GameReadinessEvent>()
.add_systems(OnEnter(NetState::Connected), open_or_join)
.add_systems(
PreMovement,
Expand Down Expand Up @@ -76,6 +77,10 @@ impl PeerLeftEvent {
}
}

/// This event is sent when game readiness stage of the joined game changes.
#[derive(Event, Deref)]
pub struct GameReadinessEvent(Readiness);

fn open_or_join(
conf: Res<NetGameConfRes>,
mut main_server: EventWriter<ToMainServerEvent>,
Expand Down Expand Up @@ -140,6 +145,7 @@ fn process_from_game(
mut joined_events: EventWriter<GameJoinedEvent>,
mut peer_joined_events: EventWriter<PeerJoinedEvent>,
mut peer_left_events: EventWriter<PeerLeftEvent>,
mut readiness_events: EventWriter<GameReadinessEvent>,
mut next_state: ResMut<NextState<NetState>>,
) {
for event in inputs.iter() {
Expand Down Expand Up @@ -199,6 +205,7 @@ fn process_from_game(
}
FromGame::GameReadiness(readiness) => {
info!("Game readiness changed to: {readiness:?}");
readiness_events.send(GameReadinessEvent(*readiness));
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/multiplayer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use stats::StatsPlugin;

pub use crate::{
config::{ConnectionType, NetGameConf},
game::{GameJoinedEvent, GameOpenedEvent, PeerJoinedEvent, PeerLeftEvent},
game::{GameJoinedEvent, GameOpenedEvent, PeerJoinedEvent, PeerLeftEvent, GameReadinessEvent},
lifecycle::{MultiplayerShuttingDownEvent, ShutdownMultiplayerEvent, StartMultiplayerEvent},
netstate::NetState,
};
Expand Down

0 comments on commit b364d72

Please sign in to comment.