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_conversations,
handle_input,
handle_chat_scripts,
));
app.add_event::<StartConversationEvent>();
app.add_event::<SendMessageEvent>();
app.add_event::<ChatScriptEvent>();
}
}
@ -35,6 +37,12 @@ pub struct SendMessageEvent {
pub text: String,
}
#[derive(Event)]
pub struct ChatScriptEvent {
name: String,
param: String,
}
#[derive(Component)]
pub struct Actor {
pub hp: f32,
@ -74,6 +82,8 @@ pub struct ChatBranch {
pub reply: String,
pub goto: String,
pub choice: String,
pub script: String,
pub script_parameter: String,
}
#[derive(Component)]
@ -266,6 +276,7 @@ pub fn handle_send_messages(
mut commands: Commands,
mut er_sendmsg: EventReader<SendMessageEvent>,
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
mut ew_chatscript: EventWriter<ChatScriptEvent>,
mut q_conv: Query<(Entity, &mut Chat)>,
time: Res<Time>,
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
}
@ -334,6 +351,7 @@ pub fn handle_conversations(
mut log: ResMut<hud::Log>,
mut q_conv: Query<(Entity, &mut Chat)>,
mut ew_sfx: EventWriter<audio::PlaySfxEvent>,
mut ew_chatscript: EventWriter<ChatScriptEvent>,
time: Res<Time>,
chat_branches: Query<&ChatBranch>, // TODO: use Table for faster iteration?
) {
@ -363,7 +381,7 @@ pub fn handle_conversations(
match branch.level.as_str() {
"chat" => log.chat(branch.reply.clone(), branch.name.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"
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 "Harvest some oxygen"
script refilloxygen 0.08
msg 0 outcold EXIT ""
chat error

View file

@ -254,6 +254,8 @@ struct ParserState {
goto: String,
is_choice: bool,
stores_item: bool,
script: String,
script_parameter: String,
}
impl Default for ParserState {
fn default() -> Self {
@ -286,6 +288,8 @@ impl Default for ParserState {
goto: "".to_string(),
is_choice: 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() },
choice: if self.is_choice { self.text.clone() } else { "".to_string() },
goto: self.goto.clone(),
script: self.script.clone(),
script_parameter: self.script_parameter.clone(),
}
}
fn spawn_chat(&mut self, commands: &mut Commands) {
@ -606,6 +612,10 @@ pub fn load_defs(
debug!("Registering level: {}", level);
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(","));
}