use bevy::prelude::*;
#[derive(Message, Debug, Clone)]
pub enum MortarEvent {
StartNode {
path: String,
node: String,
target: Option<Entity>,
},
NextText {
target: Option<Entity>,
},
SelectChoice {
index: usize,
target: Option<Entity>,
},
ConfirmChoice {
target: Option<Entity>,
},
StopDialogue {
target: Option<Entity>,
},
}
impl MortarEvent {
pub fn start_node(path: impl Into<String>, node: impl Into<String>) -> Self {
Self::StartNode {
path: path.into(),
node: node.into(),
target: None,
}
}
pub fn start_node_for(
entity: Entity,
path: impl Into<String>,
node: impl Into<String>,
) -> Self {
Self::StartNode {
path: path.into(),
node: node.into(),
target: Some(entity),
}
}
pub fn next_text() -> Self {
Self::NextText { target: None }
}
pub fn next_text_for(entity: Entity) -> Self {
Self::NextText {
target: Some(entity),
}
}
pub fn stop_dialogue() -> Self {
Self::StopDialogue { target: None }
}
pub fn stop_dialogue_for(entity: Entity) -> Self {
Self::StopDialogue {
target: Some(entity),
}
}
}
#[derive(Message, Debug, Clone)]
pub struct MortarDialogueFinished {
pub entity: Option<Entity>,
pub mortar_path: String,
pub node: String,
}
fn fire_events(
events: &[mortar_compiler::Event],
fired_events: &mut Vec<usize>,
current_index: f64,
functions: &crate::MortarFunctionRegistry,
) -> Vec<MortarEventAction> {
let mut actions_to_process = Vec::new();
for (event_idx, event) in events.iter().enumerate() {
if current_index < event.index || fired_events.contains(&event_idx) {
continue;
}
fired_events.push(event_idx);
debug!(
"Mortar event triggered at index {}: {:?}",
event.index, event.actions
);
for action in &event.actions {
let args: Vec<crate::MortarValue> = action
.args
.iter()
.map(|arg| crate::MortarValue::parse(arg))
.collect();
if let Some(result) = functions.call(&action.action_type, &args) {
debug!(
"Event function '{}' returned: {:?}",
action.action_type, result
);
} else {
warn!("Event function '{}' not found", action.action_type);
}
actions_to_process.push(MortarEventAction {
action_name: action.action_type.clone(),
args: action.args.clone(),
});
}
}
actions_to_process
}
#[derive(Component, Debug, Clone)]
pub struct MortarEventTracker {
events: Vec<mortar_compiler::Event>,
fired_events: Vec<usize>,
}
impl MortarEventTracker {
pub fn new(events: Vec<mortar_compiler::Event>) -> Self {
Self {
events,
fired_events: Vec::new(),
}
}
pub fn trigger_at_index(
&mut self,
current_index: f32,
runtime: &crate::MortarRuntime,
) -> Vec<MortarEventAction> {
fire_events(
&self.events,
&mut self.fired_events,
current_index as f64,
&runtime.functions,
)
}
pub fn reset(&mut self) {
self.fired_events.clear();
}
pub fn event_count(&self) -> usize {
self.events.len()
}
pub fn fired_count(&self) -> usize {
self.fired_events.len()
}
}
#[derive(Debug, Clone)]
pub struct MortarEventAction {
pub action_name: String,
pub args: Vec<String>,
}