implement "set" token for chats
This commit is contained in:
parent
07be89162c
commit
5df3f66ea6
32
src/chat.rs
32
src/chat.rs
|
@ -78,7 +78,7 @@ type ChatPos = Vec<usize>;
|
|||
|
||||
#[derive(Component)]
|
||||
pub struct Chat {
|
||||
pub id: usize,
|
||||
pub internal_id: usize,
|
||||
pub position: ChatPos,
|
||||
pub timer: f64,
|
||||
pub talker: Talker,
|
||||
|
@ -94,7 +94,8 @@ pub struct Choice {
|
|||
#[derive(Component)]
|
||||
#[derive(Clone)]
|
||||
pub struct Talker {
|
||||
pub conv_id: String,
|
||||
pub chat_name: String,
|
||||
pub actor_id: String,
|
||||
pub name: Option<String>,
|
||||
pub pronoun: Option<String>,
|
||||
pub talking_speed: f32,
|
||||
|
@ -116,6 +117,7 @@ pub enum ChatEvent {
|
|||
SpawnChoice(String, usize, ChatPos, bool),
|
||||
RunScript(String),
|
||||
SleepSeconds(f64),
|
||||
SetVariable(String),
|
||||
}
|
||||
|
||||
// This is the only place where any YAML interaction should be happening.
|
||||
|
@ -297,7 +299,7 @@ impl ChatDB {
|
|||
let mut popped = false;
|
||||
let mut seek_past_dialog_choices = false;
|
||||
while chat.position.len() > 0 {
|
||||
match self.at(chat.id, &chat.position) {
|
||||
match self.at(chat.internal_id, &chat.position) {
|
||||
None => {
|
||||
chat.position.pop();
|
||||
popped = true;
|
||||
|
@ -380,7 +382,7 @@ impl ChatDB {
|
|||
// This includes flow control tokens like "goto", no-op tokens like "label",
|
||||
// but not something with a side effect like "script", and especially not "if".
|
||||
fn is_skippable(&self, chat: &mut Chat) -> bool {
|
||||
let current_item = self.at(chat.id, &chat.position);
|
||||
let current_item = self.at(chat.internal_id, &chat.position);
|
||||
if current_item.is_none() {
|
||||
return false;
|
||||
}
|
||||
|
@ -406,7 +408,7 @@ impl ChatDB {
|
|||
chat: &mut Chat,
|
||||
event: &mut EventWriter<ChatEvent>,
|
||||
) -> bool {
|
||||
let current_item = self.at(chat.id, &chat.position);
|
||||
let current_item = self.at(chat.internal_id, &chat.position);
|
||||
let mut processed_a_choice = false;
|
||||
match current_item {
|
||||
Some(Value::String(message)) => {
|
||||
|
@ -452,7 +454,9 @@ impl ChatDB {
|
|||
event.send(ChatEvent::SpawnMessage(
|
||||
message.to_string(), hud::LogLevel::Warning, sound.clone()));
|
||||
}
|
||||
(Some(TOKEN_SET), _) => {} // TODO
|
||||
(Some(TOKEN_SET), Value::String(instructions)) => {
|
||||
event.send(ChatEvent::SetVariable(instructions.to_string()));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
@ -467,7 +471,7 @@ impl ChatDB {
|
|||
}
|
||||
}
|
||||
(Some(TOKEN_GOTO), Value::String(label)) => {
|
||||
match self.search_label(chat.id, &label) {
|
||||
match self.search_label(chat.internal_id, &label) {
|
||||
Some(pos) => {
|
||||
chat.position = pos;
|
||||
}
|
||||
|
@ -519,7 +523,7 @@ impl ChatDB {
|
|||
let mut key: usize = 0;
|
||||
let mut reached_end_of_branch = false;
|
||||
while let Some((choice, _, nowait)) =
|
||||
self.search_choice(self.at(chat.id, &chat.position).as_ref()) {
|
||||
self.search_choice(self.at(chat.internal_id, &chat.position).as_ref()) {
|
||||
if reached_end_of_branch {
|
||||
break;
|
||||
}
|
||||
|
@ -556,10 +560,10 @@ pub fn handle_new_conversations(
|
|||
ew_sfx.send(audio::PlaySfxEvent(audio::Sfx::Ping));
|
||||
return;
|
||||
}
|
||||
match (*chatdb).get_chat_by_id(&event.talker.conv_id) {
|
||||
match (*chatdb).get_chat_by_id(&event.talker.chat_name) {
|
||||
Ok(chat_id) => {
|
||||
let mut chat = Chat {
|
||||
id: chat_id,
|
||||
internal_id: chat_id,
|
||||
position: vec![0],
|
||||
timer: time.elapsed_seconds_f64(),
|
||||
talker: event.talker.clone(),
|
||||
|
@ -597,6 +601,7 @@ pub fn handle_chat_events(
|
|||
mut ew_chatscript: EventWriter<ChatScriptEvent>,
|
||||
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
|
||||
mut log: ResMut<hud::Log>,
|
||||
mut vars: ResMut<var::GameVars>,
|
||||
q_choices: Query<Entity, With<Choice>>,
|
||||
mut q_chats: Query<(Entity, &mut Chat)>,
|
||||
time: Res<Time>,
|
||||
|
@ -655,6 +660,13 @@ pub fn handle_chat_events(
|
|||
ChatEvent::SleepSeconds(sleep_duration) => {
|
||||
chat.timer = now + sleep_duration;
|
||||
}
|
||||
ChatEvent::SetVariable(string) => {
|
||||
if let Some((key, value)) = string.split_once(" ") {
|
||||
vars.set_in_scope(&chat.talker.actor_id, key, value.into());
|
||||
} else {
|
||||
vars.set_in_scope(&chat.talker.actor_id, string, "".into());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
- chat: Icarus
|
||||
- Oh hey, you're awake!
|
||||
- set: talked_before
|
||||
- I found you drifting out cold, and thought, I better watch over you.
|
||||
- Took us here behind that moonlet, to shield you from the micros.
|
||||
- Thank you!:
|
||||
|
|
|
@ -692,7 +692,8 @@ fn spawn_entities(
|
|||
}
|
||||
if !state.chat.is_empty() {
|
||||
actor.insert(chat::Talker {
|
||||
conv_id: state.chat.clone(),
|
||||
actor_id: state.id.clone(),
|
||||
chat_name: state.chat.clone(),
|
||||
name: state.name.clone(),
|
||||
pronoun: Some(state.pronoun.clone()),
|
||||
talking_speed: 1.0,
|
||||
|
|
|
@ -199,6 +199,7 @@ actor -3300 10 0 pizzeria
|
|||
actor 60 -15 -40 suit
|
||||
relativeto player
|
||||
name Icarus
|
||||
id Icarus
|
||||
chatid Icarus
|
||||
alive yes
|
||||
scale 2
|
||||
|
|
|
@ -48,6 +48,7 @@ impl Plugin for OutFlyPlugin {
|
|||
app.add_systems(Startup, setup);
|
||||
app.add_systems(Update, handle_input);
|
||||
app.insert_resource(var::Settings::default());
|
||||
app.insert_resource(var::GameVars::default());
|
||||
app.add_plugins((
|
||||
DefaultPlugins,//.set(ImagePlugin::default_nearest()),
|
||||
FrameTimeDiagnosticsPlugin,
|
||||
|
|
33
src/var.rs
33
src/var.rs
|
@ -2,6 +2,8 @@ use bevy::prelude::*;
|
|||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
|
||||
pub const SCOPE_SEPARATOR: &str = "$";
|
||||
|
||||
pub const DEFAULT_CHAT_SPEED: f32 = 10.0;
|
||||
|
||||
#[derive(Resource)]
|
||||
|
@ -191,13 +193,21 @@ impl Settings {
|
|||
}
|
||||
|
||||
#[derive(Resource)]
|
||||
struct GameVars {
|
||||
pub struct GameVars {
|
||||
pub db: HashMap<String, String>,
|
||||
}
|
||||
|
||||
impl Default for GameVars {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
db: HashMap::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GameVars {
|
||||
#[allow(dead_code)]
|
||||
fn get(&self, key: &str) -> Option<String> {
|
||||
pub fn get(&self, key: &str) -> Option<String> {
|
||||
if let Some(value) = self.db.get(key) {
|
||||
return Some(value.clone());
|
||||
}
|
||||
|
@ -205,7 +215,7 @@ impl GameVars {
|
|||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn getf(&self, key: &str) -> Option<f64> {
|
||||
pub fn getf(&self, key: &str) -> Option<f64> {
|
||||
if let Some(value) = self.db.get(key) {
|
||||
if let Ok(float) = value.parse::<f64>() {
|
||||
return Some(float);
|
||||
|
@ -215,7 +225,7 @@ impl GameVars {
|
|||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn getb(&self, key: &str) -> bool {
|
||||
pub fn getb(&self, key: &str) -> bool {
|
||||
if let Some(value) = self.db.get(key) {
|
||||
return value != "0";
|
||||
}
|
||||
|
@ -223,7 +233,18 @@ impl GameVars {
|
|||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn set(&mut self, key: &str, value: String) {
|
||||
self.db.insert(key.to_string(), value);
|
||||
pub fn set(&mut self, key: &str, value: String) {
|
||||
self.db.insert(key.to_lowercase(), value);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn set_in_scope(&mut self, scope: &str, key: &str, value: String) {
|
||||
let key: String = if key.contains(SCOPE_SEPARATOR) {
|
||||
key.to_string()
|
||||
} else {
|
||||
scope.to_string() + SCOPE_SEPARATOR + key
|
||||
};
|
||||
let key = key.to_lowercase();
|
||||
self.db.insert(key, value);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue