Add command for slow spacing of commands.

This commit is contained in:
Condorra 2025-04-21 01:24:11 +10:00
parent 6dd6cd1f71
commit 44a9b89844
3 changed files with 64 additions and 0 deletions

View File

@ -18,6 +18,7 @@
"panel_merge": "Use #panel_merge followed by the frame path to merge panels. For example, #panel_merge {} will merge the current panel with the top-level split.", "panel_merge": "Use #panel_merge followed by the frame path to merge panels. For example, #panel_merge {} will merge the current panel with the top-level split.",
"send_multiple_commands": "To send several commands in quick succession, separate them with a semicolon. For example, use 'n;e' to go north and then east.", "send_multiple_commands": "To send several commands in quick succession, separate them with a semicolon. For example, use 'n;e' to go north and then east.",
"tick": "Use #tick to set a recurring command to run at a specified time interval (in seconds).\r\nFor example, #tick 60 {#echo Cockadoodledoo!} will repeat every 60 seconds.\r\nOptionally give it a name with a third argument.\r\nUse #tick by itself to list active ticks.\r\nSee also: #untick", "tick": "Use #tick to set a recurring command to run at a specified time interval (in seconds).\r\nFor example, #tick 60 {#echo Cockadoodledoo!} will repeat every 60 seconds.\r\nOptionally give it a name with a third argument.\r\nUse #tick by itself to list active ticks.\r\nSee also: #untick",
"slow": "To send commands at a controlled rate, try #slow {command;command;command} 0.5, where 0.5 is replaced with the time between commands in seconds"
"unact": "Use #unact followed by the trigger pattern to delete a trigger. Example: #unact {^The (.*) attacks you.}.", "unact": "Use #unact followed by the trigger pattern to delete a trigger. Example: #unact {^The (.*) attacks you.}.",
"unalias": "Use #unalias followed by the alias pattern to delete it. For example, #unalias {^hi}.", "unalias": "Use #unalias followed by the alias pattern to delete it. For example, #unalias {^hi}.",
"undelay": "Use #undelay followed by the delay name to cancel it. Example: #undelay ding to cancel a delay named 'ding'.", "undelay": "Use #undelay followed by the delay name to cancel it. Example: #undelay ding to cancel a delay named 'ding'.",

View File

@ -234,6 +234,7 @@ pub fn install_lua_globals(
register_command!(panel_merge); register_command!(panel_merge);
register_command!(panel_swap); register_command!(panel_swap);
register_command!(sendmud_raw); register_command!(sendmud_raw);
register_command!(slow);
register_stateless_command!(storage); register_stateless_command!(storage);
register_command!(tick); register_command!(tick);
register_command!(tsplit); register_command!(tsplit);

View File

@ -2,6 +2,7 @@ use crate::{
echo_to_term_frame, echo_to_term_frame,
id_intern::intern_id, id_intern::intern_id,
match_table::{create_match_table, match_table_add, match_table_remove}, match_table::{create_match_table, match_table_add, match_table_remove},
parsing::parse_commands,
timer_host::TimerHostAccessContext, timer_host::TimerHostAccessContext,
FrameId, FrameViewType, GlobalLayoutCell, GlobalLayoutState, GlobalMemoCell, FrameId, FrameViewType, GlobalLayoutCell, GlobalLayoutState, GlobalMemoCell,
}; };
@ -875,6 +876,67 @@ pub(super) fn untick<'gc>(
}) })
} }
pub(super) fn slow<'gc>(
ctx: Context<'gc>,
global_memo: &GlobalMemoCell,
_global_layout: &UseStateSetter<GlobalLayoutCell>,
) -> Callback<'gc> {
let global_memo = global_memo.clone();
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
let cur_frame_id = try_unwrap_frame(
ctx,
&ctx.get_global::<Table>("info")?
.get(ctx, ctx.intern_static(b"current_frame"))?,
)?;
let cmds = piccolo::String::from_value(
ctx,
stack
.pop_front()
.ok_or_else(|| anyhow::Error::msg("Missing commands to slowly queue"))?,
)?
.to_str()?;
let delay: f64 = f64::from_value(
ctx,
stack
.pop_front()
.ok_or_else(|| anyhow::Error::msg("Missing slow delay time"))?,
)?;
if !stack.is_empty() {
Err(anyhow::Error::msg(
"Extra arguments to slow command. Try wrapping the action in {}",
))?;
}
let cmds = parse_commands(cmds).commands;
let delay_fn: Function = ctx.get_global::<Table>("commands")?.get(ctx, "delay")?;
let seq = async_sequence(&ctx, |locals, mut seq| {
let global_memo = global_memo.clone();
let delay_fn = locals.stash(&ctx, delay_fn);
async move {
for (idx, cmd) in cmds.iter().enumerate() {
if idx == 0 {
global_memo
.command_queue
.borrow_mut()
.push_front((cur_frame_id.clone(), cmd.clone()));
} else {
seq.try_enter(|ctx, _locals, _exec, mut stack| {
stack.consume::<()>(ctx)?;
stack.into_back(ctx, delay * (idx as f64));
stack.into_back(ctx, cmd.to_string());
Ok(())
})?;
seq.call(&delay_fn, 0).await?;
}
}
Ok(SequenceReturn::Return)
}
});
Ok(piccolo::CallbackReturn::Sequence(seq))
})
}
pub(super) fn editor<'gc>( pub(super) fn editor<'gc>(
ctx: Context<'gc>, ctx: Context<'gc>,
global_memo: &GlobalMemoCell, global_memo: &GlobalMemoCell,