save
Some checks failed
Rust Checks / checks (push) Failing after 5m59s

This commit is contained in:
CoCo_Sol 2024-03-16 22:50:26 +01:00
parent 64280ab3ff
commit 7acbc42adc
7 changed files with 181 additions and 11 deletions

10
Cargo.lock generated
View file

@ -1314,10 +1314,12 @@ dependencies = [
name = "border-wars" name = "border-wars"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bevnet",
"bevy", "bevy",
"bevy_egui", "bevy_egui",
"noise", "noise",
"paste", "paste",
"serde",
] ]
[[package]] [[package]]
@ -3805,18 +3807,18 @@ dependencies = [
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.196" version = "1.0.197"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.196" version = "1.0.197"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",

View file

@ -15,3 +15,5 @@ bevy = "0.12.1"
bevy_egui = "0.24.0" bevy_egui = "0.24.0"
noise = "0.8.2" noise = "0.8.2"
paste = "1.0.14" paste = "1.0.14"
bevnet = { path = "../bevnet" }
serde = "1.0.197"

View file

@ -0,0 +1,43 @@
//! All the code related to the connection to an host.
use std::collections::HashMap;
use bevnet::{NetworkAppExt, Uuid};
use bevy::prelude::*;
use serde::{Deserialize, Serialize};
/// The plugin that manages the connection to the host.
pub struct ConnectionPlugin;
impl Plugin for ConnectionPlugin {
fn build(&self, app: &mut App) {
app.add_network_event::<RequestConnection>()
.add_network_event::<AddPlayer>()
.add_network_event::<RemovePlayer>()
.init_resource::<AllPlayers>();
}
}
/// All the players in the game.
#[derive(Resource, Default, Deserialize, Serialize)]
pub struct AllPlayers(pub HashMap<Uuid, String>);
/// The message sent by the client to the server to request a connection.
#[derive(Event, Deserialize, Serialize)]
pub struct RequestConnection {
/// The name of the player.
pub name: String,
}
/// The message sent in order to update the list of players.
#[derive(Deserialize, Serialize, Event)]
pub struct AddPlayer {
pub uuid: Uuid,
pub name: String,
}
/// The packet sent when a player is removed.
#[derive(Event, Deserialize, Serialize)]
pub struct RemovePlayer {
pub uuid: String,
}

View file

@ -3,6 +3,7 @@
use bevy::prelude::*; use bevy::prelude::*;
pub mod camera; pub mod camera;
pub mod connection;
pub mod map; pub mod map;
pub mod responsive_scale; pub mod responsive_scale;
pub mod scenes; pub mod scenes;
@ -19,4 +20,7 @@ pub enum CurrentScene {
/// When we play this wonderful game. /// When we play this wonderful game.
Game, Game,
/// When we are in the waiting menu.
WaitingMenu,
} }

View file

@ -1,8 +1,10 @@
//! The lobby of the game. //! The lobby of the game.
use bevnet::{Connection, Receive, SendTo};
use bevy::prelude::*; use bevy::prelude::*;
use bevy_egui::{egui, EguiContexts}; use bevy_egui::{egui, EguiContexts};
use crate::connection::{AddPlayer, AllPlayers, RequestConnection};
use crate::CurrentScene; use crate::CurrentScene;
/// The plugin for the lobby. /// The plugin for the lobby.
@ -10,12 +12,19 @@ pub struct LobbyPlugin;
impl Plugin for LobbyPlugin { impl Plugin for LobbyPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_systems(Update, lobby_ui.run_if(in_state(CurrentScene::Lobby))); app.add_systems(
Update,
(lobby_ui, handle_request).run_if(in_state(CurrentScene::Lobby)),
);
} }
} }
/// Display the UI of the lobby. /// Display the UI of the lobby.
fn lobby_ui(mut ctx: EguiContexts, mut next_scene: ResMut<NextState<CurrentScene>>) { fn lobby_ui(
mut ctx: EguiContexts,
mut next_scene: ResMut<NextState<CurrentScene>>,
connection: Res<Connection>,
) {
egui::CentralPanel::default().show(ctx.ctx_mut(), |ui| { egui::CentralPanel::default().show(ctx.ctx_mut(), |ui| {
ui.heading("Border Wars"); ui.heading("Border Wars");
@ -25,7 +34,7 @@ fn lobby_ui(mut ctx: EguiContexts, mut next_scene: ResMut<NextState<CurrentScene
ui.horizontal(|ui| { ui.horizontal(|ui| {
ui.label("Game ID: "); ui.label("Game ID: ");
// TODO : get the game ID and display it. // TODO : get the game ID and display it.
ui.label("connection_string"); ui.text_edit_singleline(&mut connection.identifier().unwrap().to_string());
}); });
ui.separator(); ui.separator();
@ -36,3 +45,29 @@ fn lobby_ui(mut ctx: EguiContexts, mut next_scene: ResMut<NextState<CurrentScene
} }
}); });
} }
fn handle_request(
mut events: EventReader<Receive<RequestConnection>>,
mut all_players: ResMut<AllPlayers>,
mut new_players: EventWriter<SendTo<AddPlayer>>,
) {
for event in events.iter() {
all_players.0.insert(event.0, event.1.name.clone());
for player in all_players.0.iter() {
new_players.send(SendTo(
*player.0,
AddPlayer {
uuid: event.0,
name: event.1.name.clone(),
},
));
new_players.send(SendTo(
event.0,
AddPlayer {
uuid: *player.0,
name: player.1.clone(),
},
))
}
}
}

View file

@ -1,8 +1,10 @@
//! The main menu of the game. //! The main menu of the game.
use bevnet::{Connection, SendTo, Uuid};
use bevy::prelude::*; use bevy::prelude::*;
use bevy_egui::{egui, EguiContexts}; use bevy_egui::{egui, EguiContexts};
use crate::connection::{AllPlayers, RequestConnection};
use crate::CurrentScene; use crate::CurrentScene;
/// The plugin for the menu. /// The plugin for the menu.
@ -10,7 +12,10 @@ pub struct MenuPlugin;
impl Plugin for MenuPlugin { impl Plugin for MenuPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_systems(Update, menu_ui.run_if(in_state(CurrentScene::Menu))); app.add_systems(
Update,
(menu_ui, name_settings).run_if(in_state(CurrentScene::Menu)),
);
} }
} }
/// Display the UI of the menu to host a game or join one. /// Display the UI of the menu to host a game or join one.
@ -18,6 +23,9 @@ fn menu_ui(
mut ctx: EguiContexts, mut ctx: EguiContexts,
mut connection_string: Local<String>, mut connection_string: Local<String>,
mut next_scene: ResMut<NextState<CurrentScene>>, mut next_scene: ResMut<NextState<CurrentScene>>,
mut all_players: ResMut<AllPlayers>,
mut connection: Res<Connection>,
mut request_join_event: EventWriter<SendTo<RequestConnection>>,
) { ) {
egui::CentralPanel::default().show(ctx.ctx_mut(), |ui| { egui::CentralPanel::default().show(ctx.ctx_mut(), |ui| {
ui.heading("Border Wars"); ui.heading("Border Wars");
@ -30,8 +38,17 @@ fn menu_ui(
ui.text_edit_singleline(&mut *connection_string); ui.text_edit_singleline(&mut *connection_string);
if ui.button("Join").clicked() { if ui.button("Join").clicked() {
next_scene.set(CurrentScene::Game); next_scene.set(CurrentScene::WaitingMenu);
// TODO: connect to the game request_join_event.send(SendTo(
Uuid::parse_str(&connection_string).unwrap(),
RequestConnection {
name: all_players
.0
.get(&connection.identifier().unwrap())
.unwrap()
.clone(),
},
));
} }
}); });
@ -39,7 +56,25 @@ fn menu_ui(
if ui.button("Create new game").clicked() { if ui.button("Create new game").clicked() {
next_scene.set(CurrentScene::Lobby); next_scene.set(CurrentScene::Lobby);
// TODO: create a new game
} }
}); });
} }
fn name_settings(
mut ctx: EguiContexts,
mut all_players: ResMut<AllPlayers>,
mut local_name: Local<String>,
mut connection: Res<Connection>,
) {
egui::CentralPanel::default().show(ctx.ctx_mut(), |ui| {
ui.label("Enter your name:");
ui.horizontal(|ui| {
let text = ui.text_edit_singleline(&mut *local_name);
if text.changed() {
all_players
.0
.insert(connection.identifier().unwrap(), local_name.to_string());
}
});
});
}

View file

@ -0,0 +1,49 @@
//! TODO
use bevy::prelude::*;
use bevy_egui::{egui, EguiContexts};
use crate::connection::{AllPlayers, RequestConnection};
use crate::CurrentScene;
/// The plugin for the lobby.
pub struct WaitingMenuPlugin;
impl Plugin for WaitingMenuPlugin {
fn build(&self, app: &mut App) {
app.add_systems(
Update,
(ui, handle_new_players).run_if(in_state(CurrentScene::WaitingMenu)),
);
}
}
fn ui(all_players: Res<AllPlayers>, mut ctx: EguiContexts) {
egui::CentralPanel::default().show(ctx.ctx_mut(), |ui| {
ui.heading("Border Wars");
ui.separator();
for (uuid, name) in all_players.iter() {
ui.label(format!("{}: {}", uuid, name));
}
})
}
fn handle_new_players(
mut all_players: ResMut<AllPlayers>,
mut new_players: EventReader<AddPlayer>,
mut remove_players: EventReader<RemovePlayer>,
self_uuid: Res<Connection>,
) {
for new_player in new_players.iter() {
all_players.insert(new_player.uuid, new_player.name.clone());
}
for remove_player in remove_players.iter() {
if remove_player.uuid == self_uuid.identifier().unwrap() {
todo!("end the game");
}
all_players.remove(&remove_player.uuid);
}
}