From 706825be20c347b0f4aa9ee17544bbd6519cd9b3 Mon Sep 17 00:00:00 2001 From: Condorra Date: Mon, 23 Oct 2023 22:12:59 +1100 Subject: [PATCH] Add stop command that reverses current action. --- .../src/message_handler/user_commands.rs | 2 + .../message_handler/user_commands/movement.rs | 46 ++++++++++++++ .../src/message_handler/user_commands/stop.rs | 60 +++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 blastmud_game/src/message_handler/user_commands/stop.rs diff --git a/blastmud_game/src/message_handler/user_commands.rs b/blastmud_game/src/message_handler/user_commands.rs index 3f39b3a..0a07ca5 100644 --- a/blastmud_game/src/message_handler/user_commands.rs +++ b/blastmud_game/src/message_handler/user_commands.rs @@ -73,6 +73,7 @@ pub mod sit; mod staff_show; pub mod stand; mod status; +mod stop; mod uninstall; pub mod use_cmd; mod vacate; @@ -250,6 +251,7 @@ static REGISTERED_COMMANDS: UserVerbRegistry = phf_map! { "stats" => status::VERB, "status" => status::VERB, + "stop" => stop::VERB, "uninstall" => uninstall::VERB, "use" => use_cmd::VERB, "vacate" => vacate::VERB, diff --git a/blastmud_game/src/message_handler/user_commands/movement.rs b/blastmud_game/src/message_handler/user_commands/movement.rs index f653d4b..b347d5d 100644 --- a/blastmud_game/src/message_handler/user_commands/movement.rs +++ b/blastmud_game/src/message_handler/user_commands/movement.rs @@ -339,6 +339,52 @@ pub async fn handle_fall(trans: &DBTrans, faller: &mut Item, fall_dist: u64) -> Ok(descriptor.to_owned()) } +pub async fn reverse_climb( + player: &mut Item, + trans: &DBTrans, + command: &mut QueueCommand, +) -> UResult { + 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 false if the move failed. async fn attempt_move_immediate( diff --git a/blastmud_game/src/message_handler/user_commands/stop.rs b/blastmud_game/src/message_handler/user_commands/stop.rs new file mode 100644 index 0000000..83935a8 --- /dev/null +++ b/blastmud_game/src/message_handler/user_commands/stop.rs @@ -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;