From 01453e46f8ef76d93b8aed069837e758a810c8a9 Mon Sep 17 00:00:00 2001 From: hut Date: Sun, 14 Apr 2024 03:21:48 +0200 Subject: [PATCH] implement "include" token for chats --- src/chat.rs | 56 +++++++++++++++++++++++++++++++++++++++- src/chats/startrans.yaml | 11 ++++---- 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/src/chat.rs b/src/chat.rs index 5901498..67526fe 100644 --- a/src/chat.rs +++ b/src/chat.rs @@ -1,9 +1,10 @@ +use crate::{actor, audio, hud, settings, world, effects}; use bevy::prelude::*; use bevy::math::DVec3; use bevy_xpbd_3d::prelude::*; use serde_yaml::Value; use serde::Deserialize; -use crate::{actor, audio, hud, settings, world, effects}; +use std::collections::HashMap; pub const CHATS: &[&str] = &[ include_str!("chats/serenity.yaml"), @@ -22,6 +23,8 @@ pub const TOKEN_LABEL: &str = "label"; pub const TOKEN_SCRIPT: &str = "script"; pub const TOKEN_SOUND: &str = "sound"; pub const TOKEN_NOWAIT: &str = "nowait"; + +pub const TOKEN_INCLUDE: &str = "include"; pub const TOKEN_GOTO_EXIT: &str = "EXIT"; pub const DEFAULT_SOUND: &str = "chat"; @@ -142,6 +145,56 @@ impl ChatDB { return Ok(()); } + pub fn preprocess_includes(&mut self) { + let mut include_db: HashMap> = HashMap::new(); + for sequence in &self.0 { + if let Some(vector) = sequence.as_sequence() { + if let Some(first_item) = vector.get(0) { + if let Some(map) = first_item.as_mapping() { + for (key, value) in map { + if let (Some(key), Some(value)) = (key.as_str(), value.as_str()) { + if key == TOKEN_CHAT { + include_db.insert(value.to_string(), vector.clone()); + } + } + } + } + } + } + } + for mut sequence in self.0.iter_mut() { + ChatDB::preprocess_includes_recursively(&mut sequence, &include_db); + } + } + + fn preprocess_includes_recursively(sequence: &mut Value, include_db: &HashMap>) { + let mut changes: Vec<(usize, String)> = Vec::new(); + if let Some(vector) = sequence.as_sequence_mut() { + for (index, item) in vector.iter_mut().enumerate() { + match item { + Value::Mapping(map) => { + for (key, value) in map.iter_mut() { + if let (Some(key), Some(value)) = (key.as_str(), value.as_str()) { + if key == TOKEN_INCLUDE { + changes.push((index, value.to_string())); + } + } + else if value.is_sequence() { + ChatDB::preprocess_includes_recursively(value, include_db); + } + } + } + _ => {} + } + } + for (index, label) in changes { + vector.remove(index); + vector.splice(index..index, include_db[&label].iter().cloned()); + } + } + return; + } + pub fn get_chat_by_id(&self, id: &String) -> Result { let mut found: Option = None; for (index, object_yaml) in self.0.iter().enumerate() { @@ -483,6 +536,7 @@ pub fn load_chats(mut chatdb: ResMut) { error!("Could not load chat definitions. Validate files in `src/chats/` path."); } } + chatdb.preprocess_includes(); } pub fn handle_new_conversations( diff --git a/src/chats/startrans.yaml b/src/chats/startrans.yaml index accd0ae..d660135 100644 --- a/src/chats/startrans.yaml +++ b/src/chats/startrans.yaml @@ -11,7 +11,7 @@ - "Ready for a trip? Available bus stops: Oscillation Station, Metis Prime Station" - set: busstop serenity - label: startransbusstop -- goto: EXIT +- include: BusStops - label: interesting - Serenity Station is famous for the best pizza across the Jovian Rings. - Look for the neon sign of the pizzeria nearby. @@ -25,7 +25,7 @@ - "Ready for a trip? Available bus stops: Oscillation Station, Serenity Station" - set: busstop metis - label: startransbusstop -- goto: EXIT +- include: BusStops - label: interesting - This area is an industrial paradise for asteroid miners. - Though it has been recently abandoned due to the excessive particle radiation. @@ -40,7 +40,7 @@ - "Ready for a trip? Available bus stops: Serenity Station, Metis Prime Station" - set: busstop oscillation - label: startransbusstop -- goto: EXIT +- include: BusStops - label: interesting - The main attraction around here is the gorgeous view onto Jupiter from far up ahead. @@ -48,7 +48,7 @@ --- -- addon: startransbusstop +- chat: BusStops - Bus stop?! How does this work?: - StarTrans Cargo Services is the most convenient way to travel the vast distances of space. - Just activate your suit's built-in cryostasis. A StarTrans carrier will pick you up and you will wake up at your destination in the blink of an eye. @@ -56,7 +56,7 @@ - goto: startransbusstop - Can I take a spacecraft with me?: - Absolutely. - - goto startransbusstop + - goto: startransbusstop - if: busstop != "oscillation" Take me to Oscillation Station, please.: - StarTrans wishes you a pleasant journey. @@ -85,3 +85,4 @@ - goto: interesting - No, thank you.: - Feel free to come back any time. +- goto: EXIT