aboutsummaryrefslogtreecommitdiff
path: root/src/actor/mod.rs
diff options
context:
space:
mode:
authorLibravatar Silas Bartha <silas@exvacuum.dev>2024-11-21 12:17:44 -0500
committerLibravatar Silas Bartha <silas@exvacuum.dev>2024-11-21 12:17:44 -0500
commit26e2eddd1efeb0a5fff8ffabebefdae48c4a65dc (patch)
tree7f0903a6c90fb4e09d2894f55cffd0acbcb51350 /src/actor/mod.rs
parent99c398cc127dbc83480f98fea8c76f7c19d4dce8 (diff)
Thu Nov 21 12:17:44 PM EST 2024
Diffstat (limited to 'src/actor/mod.rs')
-rw-r--r--src/actor/mod.rs99
1 files changed, 99 insertions, 0 deletions
diff --git a/src/actor/mod.rs b/src/actor/mod.rs
new file mode 100644
index 0000000..9d0af43
--- /dev/null
+++ b/src/actor/mod.rs
@@ -0,0 +1,99 @@
+//! NPCs containing their own individual yarnspinner contexts
+// TODO: Split off into own crate?
+
+use std::sync::{Arc, Mutex};
+
+use bevy::{prelude::*, utils::HashMap};
+use lazy_static::lazy_static;
+use resources::FunctionLibrary;
+use yarnspinner::{core::{LineId, YarnValue}, runtime::Dialogue};
+
+pub mod components;
+pub mod events;
+pub mod resources;
+mod systems;
+
+lazy_static! {
+ /// Custom yarnspinner variable storage
+ /// Stores variables as <instance>.<varname>
+ /// Global variables are stored in the "global" instance
+ pub static ref DIRWORLD_VARIABLE_STORAGE: Arc<Mutex<DirworldVariableStorage>> =
+ Arc::new(Mutex::new(DirworldVariableStorage::default()));
+}
+
+/// Plugin which controls the behavior of actors
+pub struct ActorPlugin {
+ pub custom_function_registration: Option<fn(&mut FunctionLibrary)>,
+}
+
+impl Plugin for ActorPlugin {
+ fn build(&self, app: &mut App) {
+ let mut function_library = FunctionLibrary::default();
+ function_library.add_function("get_string", get_string);
+ function_library.add_function("get_number", get_number);
+ function_library.add_function("get_bool", get_bool);
+ if let Some(custom_function_registration) = &self.custom_function_registration {
+ (custom_function_registration)(&mut function_library)
+ }
+
+ app.add_systems(
+ Update,
+ (systems::handle_dialog_initiation, systems::progress_dialog, systems::handle_variable_set_commands),
+ )
+ .insert_resource(function_library)
+ .add_event::<events::ContinueDialogueEvent>()
+ .add_event::<events::DialogueEvent>();
+ }
+}
+
+fn get_string(instance_name: &str, var_name: &str) -> String {
+ if let Some(YarnValue::String(value)) = DIRWORLD_VARIABLE_STORAGE
+ .lock()
+ .unwrap()
+ .get(instance_name, var_name)
+ {
+ value
+ } else {
+ "".into()
+ }
+}
+
+fn get_number(instance_name: &str, var_name: &str) -> f32 {
+ if let Some(YarnValue::Number(value)) = DIRWORLD_VARIABLE_STORAGE
+ .lock()
+ .unwrap()
+ .get(instance_name, var_name)
+ {
+ value
+ } else {
+ 0.0
+ }
+}
+
+fn get_bool(instance_name: &str, var_name: &str) -> bool {
+ if let Some(YarnValue::Boolean(value)) = DIRWORLD_VARIABLE_STORAGE
+ .lock()
+ .unwrap()
+ .get(instance_name, var_name)
+ {
+ value
+ } else {
+ false
+ }
+}
+
+/// Variable Storage
+#[derive(Default, Debug)]
+pub struct DirworldVariableStorage(pub HashMap<String, YarnValue>);
+
+impl DirworldVariableStorage {
+ /// Set value of instance variable (use "global" for global)
+ pub fn set(&mut self, instance_name: &str, var_name: &str, value: YarnValue) {
+ self.0.insert(format!("{instance_name}.{var_name}"), value);
+ }
+
+ /// Get value of instance variable (use "global" for global)
+ pub fn get(&self, instance_name: &str, var_name: &str) -> Option<YarnValue> {
+ self.0.get(&format!("{instance_name}.{var_name}")).cloned()
+ }
+}