implement chat scripts

This commit is contained in:
yuni 2024-03-23 20:13:37 +01:00
parent 61324ffe7a
commit b22f780f73
3 changed files with 56 additions and 1 deletions

View file

@ -17,9 +17,11 @@ impl Plugin for ActorPlugin {
handle_send_messages, handle_send_messages,
handle_conversations, handle_conversations,
handle_input, handle_input,
handle_chat_scripts,
)); ));
app.add_event::<StartConversationEvent>(); app.add_event::<StartConversationEvent>();
app.add_event::<SendMessageEvent>(); app.add_event::<SendMessageEvent>();
app.add_event::<ChatScriptEvent>();
} }
} }
@ -35,6 +37,12 @@ pub struct SendMessageEvent {
pub text: String, pub text: String,
} }
#[derive(Event)]
pub struct ChatScriptEvent {
name: String,
param: String,
}
#[derive(Component)] #[derive(Component)]
pub struct Actor { pub struct Actor {
pub hp: f32, pub hp: f32,
@ -74,6 +82,8 @@ pub struct ChatBranch {
pub reply: String, pub reply: String,
pub goto: String, pub goto: String,
pub choice: String, pub choice: String,
pub script: String,
pub script_parameter: String,
} }
#[derive(Component)] #[derive(Component)]
@ -266,6 +276,7 @@ pub fn handle_send_messages(
mut commands: Commands, mut commands: Commands,
mut er_sendmsg: EventReader<SendMessageEvent>, mut er_sendmsg: EventReader<SendMessageEvent>,
mut ew_sfx: EventWriter<audio::PlaySfxEvent>, mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
mut ew_chatscript: EventWriter<ChatScriptEvent>,
mut q_conv: Query<(Entity, &mut Chat)>, mut q_conv: Query<(Entity, &mut Chat)>,
time: Res<Time>, time: Res<Time>,
chat_branches: Query<&ChatBranch>, chat_branches: Query<&ChatBranch>,
@ -324,6 +335,12 @@ pub fn handle_send_messages(
}); });
} }
} }
if !branch.script.is_empty() {
ew_chatscript.send(ChatScriptEvent {
name: branch.script.clone(),
param: branch.script_parameter.clone(),
});
}
} }
break; // let's only handle one of these per frame break; // let's only handle one of these per frame
} }
@ -334,6 +351,7 @@ pub fn handle_conversations(
mut log: ResMut<hud::Log>, mut log: ResMut<hud::Log>,
mut q_conv: Query<(Entity, &mut Chat)>, mut q_conv: Query<(Entity, &mut Chat)>,
mut ew_sfx: EventWriter<audio::PlaySfxEvent>, mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
mut ew_chatscript: EventWriter<ChatScriptEvent>,
time: Res<Time>, time: Res<Time>,
chat_branches: Query<&ChatBranch>, // TODO: use Table for faster iteration? chat_branches: Query<&ChatBranch>, // TODO: use Table for faster iteration?
) { ) {
@ -363,7 +381,7 @@ pub fn handle_conversations(
match branch.level.as_str() { match branch.level.as_str() {
"chat" => log.chat(branch.reply.clone(), branch.name.clone()), "chat" => log.chat(branch.reply.clone(), branch.name.clone()),
"info" => log.info(branch.reply.clone()), "info" => log.info(branch.reply.clone()),
"warn" => log.warning(branch.reply.clone()), "warn" => log.warning(branch.reply.clone()),
_ => (), _ => (),
} }
} }
@ -392,5 +410,30 @@ pub fn handle_conversations(
}); });
} }
} }
if !branch.script.is_empty() {
ew_chatscript.send(ChatScriptEvent {
name: branch.script.clone(),
param: branch.script_parameter.clone(),
});
}
}
}
pub fn handle_chat_scripts(
mut er_chatscript: EventReader<ChatScriptEvent>,
mut q_player: Query<(&mut Actor, &mut Suit), With<Player>>,
) {
for script in er_chatscript.read() {
match script.name.as_str() {
"refilloxygen" => if let Ok(amount) = script.param.parse::<f32>() {
for (mut _actor, mut suit) in q_player.iter_mut() {
suit.oxygen = (suit.oxygen + amount).clamp(0.0, suit.oxygen_max);
}
} else {
error!("Invalid parameter for command `{}`: `{}`", script.name, script.param);
}
_ => {}
}
} }
} }

View file

@ -133,6 +133,8 @@ actor -300 0 40 suit
msg 15 dead outcold "No life signs detected" msg 15 dead outcold "No life signs detected"
lvl info lvl info
choice 0 outcold EXIT "Damn, it's gotta be moldy in that suit. How long has it been drifting?" choice 0 outcold EXIT "Damn, it's gotta be moldy in that suit. How long has it been drifting?"
choice 0 outcold EXIT "Harvest some oxygen"
script refilloxygen 0.08
msg 0 outcold EXIT "" msg 0 outcold EXIT ""
chat error chat error

View file

@ -254,6 +254,8 @@ struct ParserState {
goto: String, goto: String,
is_choice: bool, is_choice: bool,
stores_item: bool, stores_item: bool,
script: String,
script_parameter: String,
} }
impl Default for ParserState { impl Default for ParserState {
fn default() -> Self { fn default() -> Self {
@ -286,6 +288,8 @@ impl Default for ParserState {
goto: "".to_string(), goto: "".to_string(),
is_choice: false, is_choice: false,
stores_item: false, stores_item: false,
script: "".to_string(),
script_parameter: "".to_string(),
} }
} }
} }
@ -318,6 +322,8 @@ impl ParserState {
reply: if self.is_choice { "".to_string() } else { self.text.clone() }, reply: if self.is_choice { "".to_string() } else { self.text.clone() },
choice: if self.is_choice { self.text.clone() } else { "".to_string() }, choice: if self.is_choice { self.text.clone() } else { "".to_string() },
goto: self.goto.clone(), goto: self.goto.clone(),
script: self.script.clone(),
script_parameter: self.script_parameter.clone(),
} }
} }
fn spawn_chat(&mut self, commands: &mut Commands) { fn spawn_chat(&mut self, commands: &mut Commands) {
@ -606,6 +612,10 @@ pub fn load_defs(
debug!("Registering level: {}", level); debug!("Registering level: {}", level);
state.level = level.to_string(); state.level = level.to_string();
} }
["script", scriptname, parameter] => {
state.script = scriptname.to_string();
state.script_parameter = parameter.to_string();
}
_ => { _ => {
error!("No match for [{}]", parts.join(",")); error!("No match for [{}]", parts.join(","));
} }