From d9c5398a17f2b9d00afc538db6e704f63ab653fc Mon Sep 17 00:00:00 2001 From: hut Date: Wed, 20 Mar 2024 20:04:06 +0100 Subject: [PATCH] WIP implementing spawning Actors through defs.txt --- src/defs.txt | 8 ++++ src/world.rs | 120 ++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 104 insertions(+), 24 deletions(-) diff --git a/src/defs.txt b/src/defs.txt index 7022db5..47c9852 100644 --- a/src/defs.txt +++ b/src/defs.txt @@ -1,3 +1,11 @@ +actor -30 0 0 "alien" + alive "yes" + suited "yes" + name "Icarus" + pronoun "it" + chatid "hialien" + scale 1 + chat "hialien" name "Icarus" msg 2 "INIT" "hi" "Requesting permission to communicate..." diff --git a/src/world.rs b/src/world.rs index bfd96a6..25fd1ad 100644 --- a/src/world.rs +++ b/src/world.rs @@ -310,10 +310,31 @@ pub fn setup( }); } +#[derive(Debug)] +enum DefClass { + Actor, + Chat, + None, +} + #[derive(Debug)] struct ParserState { - chat: String, + class: DefClass, + + // Generic fields name: String, + chat: String, + + // Actor fields + pos: Vec3, + model: String, + model_scale: f32, + pronoun: String, + is_lifeform: bool, + is_alive: bool, + is_suited: bool, + + // Chat fields delay: f64, text: String, level: String, @@ -325,8 +346,18 @@ struct ParserState { impl Default for ParserState { fn default() -> Self { Self { - chat: "".to_string(), + class: DefClass::None, name: "".to_string(), + chat: "".to_string(), + + pos: Vec3::new(0.0, 0.0, 0.0), + model: "".to_string(), + model_scale: 1.0, + pronoun: "they/them".to_string(), + is_lifeform: false, + is_alive: false, + is_suited: false, + delay: 0.0, text: "".to_string(), level: "chat".to_string(), @@ -337,21 +368,6 @@ impl Default for ParserState { } } } -impl std::fmt::Display for ParserState { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("ParserState") - .field("chat", &self.chat) - .field("name", &self.name) - .field("delay", &self.delay) - .field("text", &self.text) - .field("level", &self.level) - .field("label", &self.label) - .field("goto", &self.goto) - .field("is_choice", &self.is_choice) - .field("stores_item", &self.stores_item) - .finish() - } -} impl ParserState { fn reset_message(&mut self) { let default = ParserState::default(); @@ -367,6 +383,9 @@ impl ParserState { self.reset_message(); self.stores_item = default.stores_item; } + fn reset(&mut self) { + *self = Self::default(); + } fn as_chatbranch(&self) -> actor::ChatBranch { return actor::ChatBranch { id: self.chat.clone(), @@ -380,13 +399,27 @@ impl ParserState { goto: self.goto.clone(), } } - fn spawn_chatbranch(&mut self, commands: &mut Commands) { + fn spawn_chat(&mut self, commands: &mut Commands) { if self.stores_item { debug!("{:#?}", self.as_chatbranch()); commands.spawn(self.as_chatbranch()); } self.reset_message(); } + fn spawn_actor(&mut self, commands: &mut Commands) { + let component_actor = actor::Actor::default(); + let component_lifeform = actor::LifeForm::default(); + let component_suit = actor::Suit::default(); + commands.spawn((component_actor, component_lifeform, component_suit)); + self.reset(); + } + fn spawn_entities(&mut self, commands: &mut Commands) { + match self.class { + DefClass::Actor => { self.spawn_actor(commands); } + DefClass::Chat => { self.spawn_chat(commands); } + DefClass::None => {} + } + } } pub fn load_defs( @@ -422,9 +455,48 @@ pub fn load_defs( } match parts.as_slice() { + // Parsing actors + ["actor", x, y, z, model] => { + state.class = DefClass::Actor; + state.model = model.to_string(); + if let (Ok(x_float), Ok(y_float), Ok(z_float)) = + (x.parse::(), y.parse::(), z.parse::()) { + state.pos = Vec3::new(x_float, y_float, z_float); + } + else { + error!("Can't parse coordinates as floats in def: {line}"); + state.reset(); + continue; + } + } + ["alive", "yes"] => { + state.is_alive = true; + state.is_lifeform = true; + } + ["suited", "yes"] => { + state.is_suited = true; + } + ["pronoun", pronoun] => { + state.pronoun = pronoun.to_string(); + } + ["chatid", chat] => { + state.chat = chat.to_string(); + } + ["scale", scale] => { + if let Ok(scale_float) = scale.parse::() { + state.model_scale = scale_float; + } + else { + error!("Can't parse float: {line}"); + continue; + } + } + + // Parsing chats ["chat", chat_name] => { debug!("Registering chat: {}", chat_name); - state.spawn_chatbranch(&mut commands); + state.class = DefClass::Chat; + state.spawn_entities(&mut commands); state.reset_chat(); state.chat = chat_name.to_string(); } @@ -434,7 +506,7 @@ pub fn load_defs( } ["msg", sleep, text] => { debug!("Registering message (sleep={}): {}", sleep, text); - state.spawn_chatbranch(&mut commands); + state.spawn_entities(&mut commands); if let Ok(sleep_float) = sleep.parse::() { state.delay = sleep_float; state.text = text.to_string(); @@ -447,7 +519,7 @@ pub fn load_defs( } ["msg", sleep, label, goto, text] => { debug!("Registering message (sleep={}): {}", sleep, text); - state.spawn_chatbranch(&mut commands); + state.spawn_entities(&mut commands); if let Ok(sleep_float) = sleep.parse::() { state.delay = sleep_float; state.text = text.to_string(); @@ -462,7 +534,7 @@ pub fn load_defs( } ["choice", sleep, text] => { debug!("Registering choice (sleep={}): {}", sleep, text); - state.spawn_chatbranch(&mut commands); + state.spawn_entities(&mut commands); if let Ok(sleep_float) = sleep.parse::() { state.delay = sleep_float; state.text = text.to_string(); @@ -475,7 +547,7 @@ pub fn load_defs( } ["choice", sleep, label, goto, text] => { debug!("Registering choice (sleep={}): {}", sleep, text); - state.spawn_chatbranch(&mut commands); + state.spawn_entities(&mut commands); if let Ok(sleep_float) = sleep.parse::() { state.delay = sleep_float; state.text = text.to_string(); @@ -505,7 +577,7 @@ pub fn load_defs( } } } - state.spawn_chatbranch(&mut commands); + state.spawn_entities(&mut commands); } //pub fn swap_world_on_ar_toggle(