diff --git a/crates/hedz_reloaded/Cargo.toml b/crates/hedz_reloaded/Cargo.toml index 17a0e90..078f39e 100644 --- a/crates/hedz_reloaded/Cargo.toml +++ b/crates/hedz_reloaded/Cargo.toml @@ -20,7 +20,7 @@ client = [ "bevy_replicon_renet/client", "bevy_trenchbroom/client", ] -dbg = ["avian3d/debug-plugin", "dep:bevy-inspector-egui"] +dbg = ["avian3d/debug-plugin", "bevy/debug", "dep:bevy-inspector-egui"] [dependencies] avian3d = { workspace = true } diff --git a/crates/hedz_reloaded/src/lib.rs b/crates/hedz_reloaded/src/lib.rs index fe414ca..62eb293 100644 --- a/crates/hedz_reloaded/src/lib.rs +++ b/crates/hedz_reloaded/src/lib.rs @@ -36,7 +36,7 @@ pub mod water; use crate::{ config::NetworkingConfig, heads_database::{HeadDatabaseAsset, HeadsDatabase}, - protocol::{PlayerId, messages::AssignClientPlayer}, + protocol::{PlayerIdCounter, messages::AssignClientPlayer}, tb_entities::SpawnPoint, }; use avian3d::{PhysicsPlugins, prelude::TransformInterpolation}; @@ -198,12 +198,16 @@ fn start_solo_client( query: Query<&Transform, With>, heads_db: Res, mut assign_player_id: MessageWriter, + mut ids: ResMut, ) { next.set(GameState::Playing); - player::spawn(commands, ClientId::Server, query, heads_db); + ids.reset(); + let id = ids.alloc(); - assign_player_id.write(AssignClientPlayer(PlayerId { id: 0 })); + player::spawn(commands, ClientId::Server, id, query, heads_db); + + assign_player_id.write(AssignClientPlayer(id)); } fn start_listen_server( @@ -212,12 +216,16 @@ fn start_listen_server( query: Query<&Transform, With>, heads_db: Res, mut assign_player_id: MessageWriter, + mut ids: ResMut, ) { next.set(GameState::Hosting); - player::spawn(commands, ClientId::Server, query, heads_db); + ids.reset(); + let id = ids.alloc(); - assign_player_id.write(AssignClientPlayer(PlayerId { id: 0 })); + player::spawn(commands, ClientId::Server, id, query, heads_db); + + assign_player_id.write(AssignClientPlayer(id)); } fn start_client(mut next: ResMut>) { diff --git a/crates/hedz_reloaded/src/player.rs b/crates/hedz_reloaded/src/player.rs index f4396f6..847529d 100644 --- a/crates/hedz_reloaded/src/player.rs +++ b/crates/hedz_reloaded/src/player.rs @@ -65,6 +65,7 @@ pub fn plugin(app: &mut App) { pub fn spawn( mut commands: Commands, owner: ClientId, + id: PlayerId, query: Query<&Transform, With>, heads_db: Res, ) -> Option { @@ -91,7 +92,7 @@ pub fn spawn( transform, Visibility::default(), PlayerCharacterController, - PlayerId { id: 0 }, + id, ), Backpack::default(), BackpackUiState::default(), diff --git a/crates/hedz_reloaded/src/protocol/components.rs b/crates/hedz_reloaded/src/protocol/components.rs index c108bfc..671b715 100644 --- a/crates/hedz_reloaded/src/protocol/components.rs +++ b/crates/hedz_reloaded/src/protocol/components.rs @@ -76,6 +76,23 @@ impl From for Collider { } } +#[derive(Resource, Default)] +pub struct PlayerIdCounter { + next: u8, +} + +impl PlayerIdCounter { + pub fn reset(&mut self) { + self.next = 0; + } + + pub fn alloc(&mut self) -> PlayerId { + let id = PlayerId { id: self.next }; + self.next += 1; + id + } +} + /// An ID, unique per player, inserted on the character controller. The `PlayerIdMap` maintains a mapping of ID -> controller entity /// on the server #[derive(Clone, Copy, Component, Hash, Reflect, Serialize, Deserialize, PartialEq, Eq)] diff --git a/crates/hedz_reloaded/src/protocol/mod.rs b/crates/hedz_reloaded/src/protocol/mod.rs index 5363e25..65a1a3b 100644 --- a/crates/hedz_reloaded/src/protocol/mod.rs +++ b/crates/hedz_reloaded/src/protocol/mod.rs @@ -74,6 +74,7 @@ pub fn plugin(app: &mut App) { app.register_type::(); app.register_type::(); + app.init_resource::(); app.init_resource::(); app.init_resource::(); app.init_resource::(); diff --git a/crates/hedz_reloaded/src/server.rs b/crates/hedz_reloaded/src/server.rs index 2a84480..dbdcf35 100644 --- a/crates/hedz_reloaded/src/server.rs +++ b/crates/hedz_reloaded/src/server.rs @@ -2,7 +2,7 @@ use crate::{ GameState, global_observer, heads_database::HeadsDatabase, player::ClientPlayerId, - protocol::{ClientEnteredPlaying, PlayerId, SetGameTick, messages::AssignClientPlayer}, + protocol::{ClientEnteredPlaying, PlayerIdCounter, SetGameTick, messages::AssignClientPlayer}, tb_entities::SpawnPoint, tick::GameTick, }; @@ -38,12 +38,14 @@ pub fn plugin(app: &mut App) { fn on_client_playing( trigger: On>, commands: Commands, + clients: Query<&ClientPlayerId>, query: Query<&Transform, With>, heads_db: Res, ) -> Result { info!("client has entered playing gamestate"); - crate::player::spawn(commands, trigger.client_id, query, heads_db) + let id = clients.get(trigger.client_id.entity().unwrap()).unwrap(); + crate::player::spawn(commands, trigger.client_id, id.0, query, heads_db) .ok_or("failed to spawn player")?; Ok(()) @@ -100,16 +102,17 @@ fn on_connected( game_tick: Res, mut commands: Commands, mut assign_id: MessageWriter>, + mut ids: ResMut, ) { let client = trigger.event_target(); info!("{client} connected to server!"); - let id = ClientPlayerId(PlayerId { id: 0 }); - commands.entity(client).insert(id); + let id = ids.alloc(); + commands.entity(client).insert(ClientPlayerId(id)); assign_id.write(ToClients { mode: SendMode::Direct(ClientId::Client(trigger.entity)), - message: AssignClientPlayer(id.0), + message: AssignClientPlayer(id), }); commands.server_trigger(ToClients {