From 34f63d08a51a42f5e45192e9a7460fde68db5c4e Mon Sep 17 00:00:00 2001 From: hut Date: Wed, 20 Mar 2024 20:37:35 +0100 Subject: [PATCH] implemented spawning Actors through defs.txt --- src/actor.rs | 1 + src/defs.txt | 9 ++++-- src/world.rs | 83 +++++++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 76 insertions(+), 17 deletions(-) diff --git a/src/actor.rs b/src/actor.rs index 0bda0af..0fa83c5 100644 --- a/src/actor.rs +++ b/src/actor.rs @@ -84,6 +84,7 @@ pub struct Chat { pub struct Talker { pub conv_id: String, } +impl Default for Talker { fn default() -> Self { Self { conv_id: "".to_string() } } } #[derive(Component)] pub struct LifeForm { diff --git a/src/defs.txt b/src/defs.txt index 47c9852..8af764d 100644 --- a/src/defs.txt +++ b/src/defs.txt @@ -1,12 +1,15 @@ -actor -30 0 0 "alien" +actor -50 0 0 "icarus" alive "yes" - suited "yes" name "Icarus" pronoun "it" - chatid "hialien" + chatid "hi_icarus" scale 1 chat "hialien" + name "Alien" + msg 0 "INIT" "EXIT" "Leave me alone" + +chat "hi_icarus" name "Icarus" msg 2 "INIT" "hi" "Requesting permission to communicate..." lvl "info" diff --git a/src/world.rs b/src/world.rs index 25fd1ad..4d494b2 100644 --- a/src/world.rs +++ b/src/world.rs @@ -26,6 +26,12 @@ const ASSET_ASTEROID1: &str = "models/asteroid.glb#Scene0"; const ASSET_ASTEROID2: &str = "models/asteroid2.glb#Scene0"; const ASSET_PIZZERIA: &str = "models/pizzeria.glb#Scene0"; const ASSET_JUPITER: &str = "models/jupiter.glb#Scene0"; +fn asset_name_to_path(name: &str) -> &'static str { + match name { + "astronaut" => ASSET_ASTRONAUT, + _ => ASSET_ASTRONAUT, + } +} pub struct WorldPlugin; impl Plugin for WorldPlugin { @@ -406,16 +412,66 @@ impl ParserState { } self.reset_message(); } - fn spawn_actor(&mut self, commands: &mut Commands) { + fn spawn_actor(&mut self, commands: &mut Commands, asset_server: &Res) { let component_actor = actor::Actor::default(); let component_lifeform = actor::LifeForm::default(); + let component_talker = actor::Talker { + conv_id: self.chat.clone(), + ..default() + }; let component_suit = actor::Suit::default(); - commands.spawn((component_actor, component_lifeform, component_suit)); + let component_model = SceneBundle { + transform: Transform { + translation: self.pos, + scale: Vec3::splat(self.model_scale), + rotation: Quat::from_rotation_y(-PI / 3.), + }, + scene: asset_server.load(asset_name_to_path(self.model.as_str())), + ..default() + }; + + // TODO: is there a more dynamic way to construct this...? + info!("Spawning actor {} with model {} at {}/{}/{}", + self.name, self.model, self.pos.x, self.pos.y, self.pos.z); + if self.is_alive { + if !self.chat.is_empty() { + commands.spawn(( + component_actor, + component_lifeform, + component_suit, + component_talker, + component_model, + )); + } + else { + commands.spawn(( + component_actor, + component_lifeform, + component_suit, + component_model, + )); + } + } + else { + if !self.chat.is_empty() { + commands.spawn(( + component_actor, + component_talker, + component_model, + )); + } + else { + commands.spawn(( + component_actor, + component_model, + )); + } + } self.reset(); } - fn spawn_entities(&mut self, commands: &mut Commands) { + fn spawn_entities(&mut self, commands: &mut Commands, asset_server: &Res) { match self.class { - DefClass::Actor => { self.spawn_actor(commands); } + DefClass::Actor => { self.spawn_actor(commands, asset_server); } DefClass::Chat => { self.spawn_chat(commands); } DefClass::None => {} } @@ -424,9 +480,10 @@ impl ParserState { pub fn load_defs( mut commands: Commands, + asset_server: Res, ) { let re1 = Regex::new(r"^\s*([a-z]+)\s+(.*)$").unwrap(); - let re2 = Regex::new("\"([^\"]*)\"|([0-9]+(?:\\.[0-9]+)?)").unwrap(); + let re2 = Regex::new("\"([^\"]*)\"|(-?[0-9]+(?:\\.[0-9]+)?)").unwrap(); let defs_string = include_str!("defs.txt"); let mut lines = defs_string.lines(); let mut state = ParserState::default(); @@ -472,8 +529,6 @@ pub fn load_defs( ["alive", "yes"] => { state.is_alive = true; state.is_lifeform = true; - } - ["suited", "yes"] => { state.is_suited = true; } ["pronoun", pronoun] => { @@ -495,9 +550,9 @@ pub fn load_defs( // Parsing chats ["chat", chat_name] => { debug!("Registering chat: {}", chat_name); - state.class = DefClass::Chat; - state.spawn_entities(&mut commands); + state.spawn_entities(&mut commands, &asset_server); state.reset_chat(); + state.class = DefClass::Chat; state.chat = chat_name.to_string(); } ["name", name] => { @@ -506,7 +561,7 @@ pub fn load_defs( } ["msg", sleep, text] => { debug!("Registering message (sleep={}): {}", sleep, text); - state.spawn_entities(&mut commands); + state.spawn_entities(&mut commands, &asset_server); if let Ok(sleep_float) = sleep.parse::() { state.delay = sleep_float; state.text = text.to_string(); @@ -519,7 +574,7 @@ pub fn load_defs( } ["msg", sleep, label, goto, text] => { debug!("Registering message (sleep={}): {}", sleep, text); - state.spawn_entities(&mut commands); + state.spawn_entities(&mut commands, &asset_server); if let Ok(sleep_float) = sleep.parse::() { state.delay = sleep_float; state.text = text.to_string(); @@ -534,7 +589,7 @@ pub fn load_defs( } ["choice", sleep, text] => { debug!("Registering choice (sleep={}): {}", sleep, text); - state.spawn_entities(&mut commands); + state.spawn_entities(&mut commands, &asset_server); if let Ok(sleep_float) = sleep.parse::() { state.delay = sleep_float; state.text = text.to_string(); @@ -547,7 +602,7 @@ pub fn load_defs( } ["choice", sleep, label, goto, text] => { debug!("Registering choice (sleep={}): {}", sleep, text); - state.spawn_entities(&mut commands); + state.spawn_entities(&mut commands, &asset_server); if let Ok(sleep_float) = sleep.parse::() { state.delay = sleep_float; state.text = text.to_string(); @@ -577,7 +632,7 @@ pub fn load_defs( } } } - state.spawn_entities(&mut commands); + state.spawn_entities(&mut commands, &asset_server); } //pub fn swap_world_on_ar_toggle(