diff --git a/kubi/src/chat.rs b/kubi/src/chat.rs index b0e452f..d6c9e0f 100644 --- a/kubi/src/chat.rs +++ b/kubi/src/chat.rs @@ -1,14 +1,18 @@ +use kubi_shared::networking::client::ClientId; use shipyard::{AllStoragesView, Unique, UniqueViewMut}; pub enum ChatMessage { PlayerMessage { + id: ClientId, username: String, message: String, }, PlayerJoin { + id: ClientId, username: String, }, PlayerLeave { + id: ClientId, username: String, }, System(String), @@ -24,16 +28,16 @@ impl ChatManager { self.messages.push(message); } - pub fn add_chat_message(&mut self, username: String, message: String,) { - self.messages.push(ChatMessage::PlayerMessage { username, message }); + pub fn add_chat_message(&mut self, id: ClientId, username: String, message: String,) { + self.messages.push(ChatMessage::PlayerMessage { id, username, message }); } - pub fn add_player_join(&mut self, username: String) { - self.messages.push(ChatMessage::PlayerJoin { username }); + pub fn add_player_join(&mut self, id: ClientId, username: String) { + self.messages.push(ChatMessage::PlayerJoin { id, username }); } - pub fn add_player_leave(&mut self, username: String) { - self.messages.push(ChatMessage::PlayerLeave { username }); + pub fn add_player_leave(&mut self, id: ClientId, username: String) { + self.messages.push(ChatMessage::PlayerLeave { id, username }); } pub fn add_system_message(&mut self, message: String) { diff --git a/kubi/src/cursor_lock.rs b/kubi/src/cursor_lock.rs index 02aaf65..a595f01 100644 --- a/kubi/src/cursor_lock.rs +++ b/kubi/src/cursor_lock.rs @@ -1,6 +1,10 @@ -use shipyard::{AllStoragesView, Unique, NonSendSync, UniqueView, UniqueViewMut}; -use crate::rendering::Renderer; -use winit::window::CursorGrabMode; +use shipyard::{AllStoragesView, IntoIter, NonSendSync, Unique, UniqueView, UniqueViewMut, View}; +use crate::{events::InputDeviceEvent, rendering::Renderer}; +use winit::{ + event::{DeviceEvent, ElementState, RawKeyEvent}, + keyboard::{KeyCode, PhysicalKey}, + window::CursorGrabMode +}; #[derive(Unique)] pub struct CursorLock(pub bool); @@ -34,3 +38,18 @@ pub fn lock_cursor_now( ) { lock.0 = true } + +/// XXX: this is a huge hack +pub fn debug_toggle_lock( + mut lock: UniqueViewMut, + device_events: View, +) { + for evt in device_events.iter() { + if let DeviceEvent::Key(RawKeyEvent { + physical_key: PhysicalKey::Code(KeyCode::F3), + state: ElementState::Pressed, + }) = evt.event { + lock.0 = !lock.0; + } + } +} diff --git a/kubi/src/lib.rs b/kubi/src/lib.rs index f86f6b3..f70e889 100644 --- a/kubi/src/lib.rs +++ b/kubi/src/lib.rs @@ -78,7 +78,7 @@ use rendering::{ }; use block_placement::update_block_placement; use delta_time::{DeltaTime, init_delta_time}; -use cursor_lock::{insert_lock_state, update_cursor_lock_state, lock_cursor_now}; +use cursor_lock::{debug_toggle_lock, insert_lock_state, lock_cursor_now, update_cursor_lock_state}; use control_flow::{exit_on_esc, insert_control_flow_unique, RequestExit}; use state::{is_ingame, is_ingame_or_loading, is_loading, init_state, update_state, is_connecting}; use networking::{update_networking, update_networking_late, is_multiplayer, disconnect_on_exit, is_singleplayer}; @@ -121,6 +121,7 @@ fn startup() -> Workload { fn update() -> Workload { ( + debug_toggle_lock, update_window_size, update_cursor_lock_state, process_inputs, diff --git a/kubi/src/networking/player.rs b/kubi/src/networking/player.rs index 78ad66f..300b0e8 100644 --- a/kubi/src/networking/player.rs +++ b/kubi/src/networking/player.rs @@ -4,12 +4,13 @@ use uflow::{SendMode, client::Event as ClientEvent}; use kubi_shared::{ transform::Transform, networking::{ - messages::{ClientToServerMessage, ServerToClientMessage, ServerToClientMessageType}, channels::Channel, - client::ClientIdMap, + client::{ClientIdMap, Username}, + messages::{ClientToServerMessage, ServerToClientMessage, ServerToClientMessageType}, }, }; use crate::{ + chat::ChatManager, events::player_actions::PlayerActionEvent, player::spawn_remote_player_multiplayer, }; @@ -96,6 +97,9 @@ pub fn receive_player_connect_events( for message in messages { let ServerToClientMessage::PlayerConnected { init } = message else { unreachable!() }; log::info!("player connected: {} (id {})", init.username, init.client_id); + let mut chat = storages.borrow::>().unwrap(); + chat.add_player_join(init.client_id, init.username.clone()); + drop(chat); spawn_remote_player_multiplayer(&mut storages, init); } } @@ -120,12 +124,21 @@ pub fn receive_player_disconnect_events( for message in messages { let ServerToClientMessage::PlayerDisconnected { id } = message else { unreachable!() }; log::info!("player disconnected: {}", id); + let mut id_map = storages.borrow::>().unwrap(); let Some(ent_id) = id_map.0.remove(&id) else { log::warn!("Disconnected player entity not found in client-id map"); continue }; + + let username = storages.get::<&Username>(ent_id).unwrap(); + let mut chat = storages.borrow::>().unwrap(); + chat.add_player_leave(id, username.0.to_string()); + + drop(chat); drop(id_map); + drop(username); + if !storages.delete_entity(ent_id) { log::warn!("Disconnected player entity not found in storage"); } diff --git a/kubi/src/ui/chat_ui.rs b/kubi/src/ui/chat_ui.rs index 9bc1b79..c461df3 100644 --- a/kubi/src/ui/chat_ui.rs +++ b/kubi/src/ui/chat_ui.rs @@ -1,4 +1,4 @@ -use hui::{element::{container::Container, text::Text, UiElementExt}, layout::Alignment, size}; +use hui::{color, element::{container::Container, text::Text, UiElementExt}, layout::Alignment, size}; use shipyard::{NonSendSync, UniqueView, UniqueViewMut}; use crate::{chat::{ChatManager, ChatMessage}, hui_integration::UiState, rendering::WindowSize}; @@ -14,23 +14,26 @@ pub fn render_chat( .with_align((Alignment::Begin, Alignment::End)) .with_children(|ui| { for message in messages.iter().rev().take(10).rev() { - let text = match message { - ChatMessage::PlayerMessage { username, message } => { - format!("{}: {}", username, message) + let (text, color) = match message { + ChatMessage::PlayerMessage { username, id, message } => { + (format!("{username} ({id}): {message}"), color::CYAN) } - ChatMessage::PlayerJoin { username } => { - format!("{} joined the game", username) + ChatMessage::PlayerJoin { username, id } => { + (format!("{username} ({id}) joined the game"), color::YELLOW) } - ChatMessage::PlayerLeave { username } => { - format!("{} left the game", username) + ChatMessage::PlayerLeave { username, id } => { + (format!("{username} ({id}) left the game"), color::YELLOW) + } + ChatMessage::System(message) => { + (message.clone(), color::WHITE) } - ChatMessage::System(message) => message.clone(), }; Container::default() .with_background((0., 0., 0., 0.5)) .with_padding((5., 2.)) .with_children(|ui| { Text::new(text) + .with_color(color) .add_child(ui) }) .add_child(ui);