From 50cc36e3d531b803bee8992de841cf3785360f49 Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Thu, 25 Apr 2024 13:39:23 +0200 Subject: [PATCH] add chat --- kubi/src/camera/matrices.rs | 97 +++++++++++++++++++------------------ kubi/src/chat.rs | 54 +++++++++++++++++++++ kubi/src/lib.rs | 8 ++- kubi/src/ui/chat_ui.rs | 39 +++++++++++++++ 4 files changed, 149 insertions(+), 49 deletions(-) create mode 100644 kubi/src/chat.rs create mode 100644 kubi/src/ui/chat_ui.rs diff --git a/kubi/src/camera/matrices.rs b/kubi/src/camera/matrices.rs index 847be29..44c359f 100644 --- a/kubi/src/camera/matrices.rs +++ b/kubi/src/camera/matrices.rs @@ -1,48 +1,49 @@ -use glam::{Vec3, Mat4}; -use shipyard::{ViewMut, View, IntoIter, Workload, IntoWorkload, track, UniqueView, SystemModificator}; -use crate::{transform::Transform, rendering::WindowSize, events::WindowResizedEvent}; -use super::Camera; - -//maybe parallelize these two? - -fn update_view_matrix( - mut vm_camera: ViewMut, - v_transform: View -) { - for (mut camera, transform) in (&mut vm_camera, v_transform.inserted_or_modified()).iter() { - let (_, rotation, translation) = transform.0.to_scale_rotation_translation(); - let direction = (rotation.normalize() * Vec3::NEG_Z).normalize(); - camera.view_matrix = Mat4::look_to_rh(translation, direction, camera.up); - } -} - -fn update_perspective_matrix( - mut vm_camera: ViewMut, - size: UniqueView, -) { - for mut camera in (&mut vm_camera).iter() { - camera.perspective_matrix = Mat4::perspective_rh_gl( - camera.fov, - size.0.x as f32 / size.0.y as f32, - camera.z_near, - camera.z_far, - ) - } -} - -fn need_perspective_calc( - v_camera: View, - resize_event: View, -) -> bool { - (resize_event.len() > 0) || - (v_camera.iter().any(|camera| { - camera.perspective_matrix == Mat4::default() - })) -} - -pub fn update_matrices() -> Workload { - ( - update_view_matrix, - update_perspective_matrix.run_if(need_perspective_calc), - ).into_sequential_workload() -} +use glam::{Vec3, Mat4}; +use shipyard::{ViewMut, View, IntoIter, Workload, IntoWorkload, track, UniqueView, SystemModificator}; +use crate::{transform::Transform, rendering::WindowSize, events::WindowResizedEvent}; +use super::Camera; + +//maybe parallelize these two? + +fn update_view_matrix( + mut vm_camera: ViewMut, + v_transform: View +) { + for (mut camera, transform) in (&mut vm_camera, v_transform.inserted_or_modified()).iter() { + let (_, rotation, translation) = transform.0.to_scale_rotation_translation(); + let direction = (rotation.normalize() * Vec3::NEG_Z).normalize(); + camera.view_matrix = Mat4::look_to_rh(translation, direction, camera.up); + } +} + +fn update_perspective_matrix( + mut vm_camera: ViewMut, + size: UniqueView, +) { + for mut camera in (&mut vm_camera).iter() { + camera.perspective_matrix = Mat4::perspective_rh_gl( + camera.fov, + size.0.x as f32 / size.0.y as f32, + camera.z_near, + camera.z_far, + ) + } +} + +fn need_perspective_calc( + v_camera: View, + resize_event: View, +) -> bool { + (resize_event.len() > 0) || + (v_camera.iter().any(|camera| { + camera.perspective_matrix == Mat4::default() + })) +} + +pub fn update_matrices() -> Workload { + ( + update_view_matrix, + //update_perspective_matrix, + update_perspective_matrix.run_if(need_perspective_calc), + ).into_sequential_workload() +} diff --git a/kubi/src/chat.rs b/kubi/src/chat.rs new file mode 100644 index 0000000..e67635b --- /dev/null +++ b/kubi/src/chat.rs @@ -0,0 +1,54 @@ +use shipyard::{AllStoragesView, Unique, UniqueViewMut}; + +pub enum ChatMessage { + PlayerMessage { + username: String, + message: String, + }, + PlayerJoin { + username: String, + }, + PlayerLeave { + username: String, + }, + System(String), +} + +#[derive(Unique, Default)] +pub struct ChatManager { + pub messages: Vec, +} + +impl ChatManager { + pub fn add_message(&mut self, message: ChatMessage) { + 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_player_join(&mut self, username: String) { + self.messages.push(ChatMessage::PlayerJoin { username }); + } + + pub fn add_player_leave(&mut self, username: String) { + self.messages.push(ChatMessage::PlayerLeave { username }); + } + + pub fn add_system_message(&mut self, message: String) { + self.messages.push(ChatMessage::System(message)); + } + + pub fn get_messages(&self) -> &[ChatMessage] { + &self.messages[..] + } +} + +pub fn init_chat_manager( + storages: AllStoragesView, +) { + let mut chat_manager = ChatManager::default(); + chat_manager.add_system_message("Welcome to Kubi!".to_string()); + storages.add_unique(chat_manager); +} diff --git a/kubi/src/lib.rs b/kubi/src/lib.rs index 054199f..f86f6b3 100644 --- a/kubi/src/lib.rs +++ b/kubi/src/lib.rs @@ -18,8 +18,9 @@ pub(crate) use kubi_shared::transform; mod ui { pub(crate) mod loading_screen; pub(crate) mod connecting_screen; + pub(crate) mod chat_ui; } -pub(crate) use ui::{loading_screen, connecting_screen}; +pub(crate) use ui::{loading_screen, connecting_screen, chat_ui}; pub(crate) mod rendering; pub(crate) mod world; @@ -42,6 +43,7 @@ pub(crate) mod color; pub(crate) mod fixed_timestamp; pub(crate) mod filesystem; pub(crate) mod client_physics; +pub(crate) mod chat; use world::{ init_game_world, @@ -87,6 +89,8 @@ use connecting_screen::update_connecting_screen; use fixed_timestamp::init_fixed_timestamp_storage; use filesystem::AssetManager; use client_physics::{init_client_physics, update_client_physics_late}; +use chat_ui::render_chat; +use chat::init_chat_manager; /// stuff required to init the renderer and other basic systems fn pre_startup() -> Workload { @@ -111,6 +115,7 @@ fn startup() -> Workload { insert_control_flow_unique, init_delta_time, init_client_physics, + init_chat_manager, ).into_sequential_workload() } @@ -144,6 +149,7 @@ fn update() -> Workload { update_raycasts, update_block_placement, apply_queued_blocks, + render_chat, ).into_sequential_workload().run_if(is_ingame), update_networking_late.run_if(is_multiplayer), compute_cameras, diff --git a/kubi/src/ui/chat_ui.rs b/kubi/src/ui/chat_ui.rs new file mode 100644 index 0000000..2a0c199 --- /dev/null +++ b/kubi/src/ui/chat_ui.rs @@ -0,0 +1,39 @@ +use hui::{element::{container::Container, text::Text, UiElementExt}, layout::Alignment, size}; +use shipyard::{NonSendSync, UniqueView, UniqueViewMut}; +use crate::{chat::{ChatManager, ChatMessage}, hui_integration::UiState, rendering::WindowSize}; + +pub fn render_chat( + mut hui: NonSendSync>, + size: UniqueView, + chat: UniqueView, +) { + let messages = chat.get_messages(); + if messages.is_empty() { return } + Container::default() + .with_size(size!(100%, 100%)) + .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) + } + ChatMessage::PlayerJoin { username } => { + format!("{} joined the game", username) + } + ChatMessage::PlayerLeave { username } => { + format!("{} left the game", username) + } + ChatMessage::System(message) => message.clone(), + }; + Container::default() + .with_background((0., 0., 0., 0.5)) + .with_children(|ui| { + Text::new(text) + .add_child(ui) + }) + .add_child(ui); + } + }) + .add_root(&mut hui.hui, size.0.as_vec2()); +}