From 668bef6a88afb9fc562e3725e0b524fb7ee0996b Mon Sep 17 00:00:00 2001 From: Rusty Striker Date: Tue, 15 Jul 2025 20:40:41 +0300 Subject: [PATCH] allow creating scenes and setting scene visibility to players --- src/api/mod.rs | 11 +++++++++++ src/game/mod.rs | 21 +++++++++++++++++++++ src/lib.rs | 31 ++++++++++++++++++++++++++----- 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/api/mod.rs b/src/api/mod.rs index a1bc175..a853d93 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -48,6 +48,17 @@ pub enum Request { amount: usize, }, // Map requests + CreateScene { + title: String, + }, + SceneSetGrid { + grid_cell_size: f32, + grid_offset: [f32; 2], + }, + SceneSetVisible { + scene: usize, + visible: bool, + }, GetScene { id: usize, }, diff --git a/src/game/mod.rs b/src/game/mod.rs index cc3d5ec..61d65db 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -25,6 +25,8 @@ pub trait GameImpl<'a, C: Character + Serialize + Deserialize<'a>, A: entry:: /// the list of available scenes fn scenes(&self) -> Vec; fn get_scene(&self, id: usize) -> Option<&Scene>; + fn create_scene(&mut self, title: String); + fn scene_visible(&mut self, scene: usize, visible: bool); fn create_token(&mut self, scene_id: usize, character: String, img_source: String, x: f32, y: f32) -> usize; fn move_token(&mut self, scene_id: usize, token_id: usize, x: f32, y: f32) -> bool; fn token_info(&self, scene: usize, token_id: usize) -> Option<&TokenInfo>; @@ -187,6 +189,25 @@ impl<'a, C: Character + Serialize + Deserialize<'a>, A: entry::GameEntry + Se fn get_scene(&self, id: usize) -> Option<&Scene> { self.scenes.get(&id) } + + fn create_scene(&mut self, title: String) { + let id = self.scenes.keys().max().map(|k| k + 1).unwrap_or(0); + self.scenes.insert( + id, + Scene { + title, + visible_to_users: false, + map: None, + characters: Vec::new(), + }, + ); + } + + fn scene_visible(&mut self, scene: usize, visible: bool) { + if let Some(scene) = self.scenes.get_mut(&scene) { + scene.visible_to_users = visible; + } + } } #[derive(Serialize, Deserialize, Default, Debug, Clone)] diff --git a/src/lib.rs b/src/lib.rs index 7e9092d..a31ad25 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -85,7 +85,6 @@ impl GameServer { println!("Got message from {}: {:?}", &id, &req); match req { - // ignore errors, should probably be blocked before they are sent here api::Request::Error => {} api::Request::Login(login) => { println!("login req from {}: {:?}", &id, &login); @@ -105,7 +104,8 @@ impl GameServer { }), )); // Send the list of scenes and chat history and such - _ = broadcast.send((Some(login.username.clone()), self.get_scene_list(&id))); + let admin = *self.users.get(&id).unwrap_or(&false); + _ = broadcast.send((Some(login.username.clone()), self.get_scene_list(admin))); _ = broadcast.send((Some(login.username.clone()), self.get_last_messages(50))); } else { _ = broadcast.send(( @@ -161,7 +161,29 @@ impl GameServer { _ = broadcast.send((Some(id), response)); } } - api::Request::GetSceneList => _ = broadcast.send((Some(id.clone()), self.get_scene_list(&id))), + api::Request::CreateScene { title } => { + if *self.users.get(&id).unwrap_or(&false) { + self.game.create_scene(title); + let admin = *self.users.get(&id).unwrap_or(&false); + let scenes = self.get_scene_list(admin); + _ = broadcast.send((Some(id), scenes)); + } + } + api::Request::SceneSetGrid { + grid_cell_size, + grid_offset, + } => todo!(), + api::Request::SceneSetVisible { scene, visible } => { + if *self.users.get(&id).unwrap_or(&false) { + self.game.scene_visible(scene, visible); + _ = broadcast.send((None, self.get_scene_list(false))); + _ = broadcast.send((Some(id), self.get_scene_list(true))); + } + } + api::Request::GetSceneList => { + let admin = *self.users.get(&id).unwrap_or(&false); + _ = broadcast.send((Some(id.clone()), self.get_scene_list(admin))); + } api::Request::SpawnToken { map_id, character, @@ -250,8 +272,7 @@ impl GameServer { self.save().await; // Save the game one last time :) } - fn get_scene_list(&self, id: &str) -> api::Response { - let admin = *self.users.get(id).unwrap_or(&false); + fn get_scene_list(&self, admin: bool) -> api::Response { let scenes = self .game .scenes()