Add stop command that reverses current action.

This commit is contained in:
Condorra 2023-10-23 22:12:59 +11:00
parent 76b2874077
commit 706825be20
3 changed files with 108 additions and 0 deletions

View File

@ -73,6 +73,7 @@ pub mod sit;
mod staff_show; mod staff_show;
pub mod stand; pub mod stand;
mod status; mod status;
mod stop;
mod uninstall; mod uninstall;
pub mod use_cmd; pub mod use_cmd;
mod vacate; mod vacate;
@ -250,6 +251,7 @@ static REGISTERED_COMMANDS: UserVerbRegistry = phf_map! {
"stats" => status::VERB, "stats" => status::VERB,
"status" => status::VERB, "status" => status::VERB,
"stop" => stop::VERB,
"uninstall" => uninstall::VERB, "uninstall" => uninstall::VERB,
"use" => use_cmd::VERB, "use" => use_cmd::VERB,
"vacate" => vacate::VERB, "vacate" => vacate::VERB,

View File

@ -339,6 +339,52 @@ pub async fn handle_fall(trans: &DBTrans, faller: &mut Item, fall_dist: u64) ->
Ok(descriptor.to_owned()) Ok(descriptor.to_owned())
} }
pub async fn reverse_climb(
player: &mut Item,
trans: &DBTrans,
command: &mut QueueCommand,
) -> UResult<String> {
let command_orig = command.clone();
match command {
QueueCommand::Movement {
direction: ref mut d,
..
} => {
let loc = player.location.clone();
let mut tmp_ctx = QueuedCommandContext {
trans,
command: &command_orig,
item: player,
};
let (new_loc, _item, climb_opt) = move_to_where(&loc, d, &mut tmp_ctx).await?;
if let Some(climb) = climb_opt {
if let Some(rev_d) = (*d).reverse() {
*d = rev_d;
player.location = new_loc;
if climb.height > 0 {
player
.active_climb
.as_mut()
.map(|ac| ac.height = climb.height as u64 - ac.height);
Ok("You start climbing back down.\n".to_owned())
} else {
player
.active_climb
.as_mut()
.map(|ac| ac.height = (-climb.height) as u64 - ac.height);
Ok("You start climbing back up.\n".to_owned())
}
} else {
user_error("You can't figure out how to climb back.".to_owned())?
}
} else {
user_error("You can't figure out how to climb back.".to_owned())?
}
}
_ => user_error("You can't seem to stop climbing for some reason.".to_owned())?,
}
}
// Returns true if the move is either complete or still in progress. // Returns true if the move is either complete or still in progress.
// Returns false if the move failed. // Returns false if the move failed.
async fn attempt_move_immediate( async fn attempt_move_immediate(

View File

@ -0,0 +1,60 @@
use super::{
get_player_item_or_fail, movement::reverse_climb, user_error, UResult, UserVerb, UserVerbRef,
VerbContext,
};
use async_trait::async_trait;
pub struct Verb;
#[async_trait]
impl UserVerb for Verb {
async fn handle(
self: &Self,
ctx: &mut VerbContext,
_verb: &str,
_remaining: &str,
) -> UResult<()> {
let player_item = get_player_item_or_fail(ctx).await?;
if player_item.death_data.is_some() {
user_error("You're dead. If you wanted to just stop being dead, I'm afraid it doesn't work like that (although you can try going up to resurrect into a new body). If you wanted to stop doing whatever you were doing when you died, then the good news is that your death already put a stop to it.".to_owned())?;
}
let mut player_item_mut = (*player_item).clone();
let mut queue_head = player_item_mut.queue.pop_front();
if player_item.active_combat.is_some() {
// Otherwise, we assume they wanted to stop escaping etc...
if queue_head.is_none() {
user_error("You can't just stop fighting - either fight to the death or try moving to another room.".to_owned())?;
}
}
let mut msg = String::new();
if let Some(_active_climb) = player_item_mut.active_climb.as_mut() {
if let Some(ref mut queue_head_v) = queue_head {
msg.push_str(&reverse_climb(&mut player_item_mut, &ctx.trans, queue_head_v).await?);
}
}
let qlen = player_item_mut.queue.len();
if qlen > 0 {
msg.push_str(&format!(
"You cancel your plans to take {} action{}.\n",
qlen,
if qlen > 1 { "s" } else { "" },
));
} else if msg == "" {
user_error("You weren't doing anything that could be stopped.".to_owned())?;
}
player_item_mut.queue = queue_head.clone().into_iter().collect();
ctx.trans.save_item_model(&player_item_mut).await?;
ctx.trans
.queue_for_session(&ctx.session, Some(&msg))
.await?;
Ok(())
}
}
static VERB_INT: Verb = Verb;
pub static VERB: UserVerbRef = &VERB_INT as UserVerbRef;