use super::{get_player_item_or_fail, user_error, UResult, UserVerb, UserVerbRef, VerbContext}; #[double] use crate::db::DBTrans; use crate::{ models::item::{Item, LocationActionType}, regular_tasks::queued_command::{ queue_command_and_save, QueueCommand, QueueCommandHandler, QueuedCommandContext, }, services::{comms::broadcast_to_room, urges::recalculate_urge_growth}, }; use async_trait::async_trait; use mockall_double::double; use std::time; pub async fn stand_if_needed(trans: &DBTrans, who: &mut Item) -> UResult<()> { match who.action_type { LocationActionType::Sitting { .. } | LocationActionType::Reclining { .. } => {} _ => return Ok(()), } let msg_exp = format!("{} stands up.\n", &who.display_for_sentence(true, 1, true),); let msg_nonexp = format!("{} stands up.\n", &who.display_for_sentence(false, 1, true),); broadcast_to_room(trans, &who.location, None, &msg_exp, Some(&msg_nonexp)).await?; who.action_type = LocationActionType::Normal; recalculate_urge_growth(trans, who).await?; Ok(()) } pub struct QueueHandler; #[async_trait] impl QueueCommandHandler for QueueHandler { async fn start_command(&self, ctx: &mut QueuedCommandContext<'_>) -> UResult { if ctx.item.death_data.is_some() { user_error( "You try to stand, but it turns out the dead can't even do that!".to_owned(), )?; } match ctx.command { QueueCommand::Stand => {} _ => user_error("Unexpected command".to_owned())?, }; match ctx.item.action_type { LocationActionType::Sitting { .. } | LocationActionType::Reclining { .. } => {} _ => user_error("You're already standing.".to_owned())?, } Ok(time::Duration::from_secs(1)) } #[allow(unreachable_patterns)] async fn finish_command(&self, ctx: &mut QueuedCommandContext<'_>) -> UResult<()> { if ctx.item.death_data.is_some() { user_error( "You try to stand, but it turns out the dead can't even do that!".to_owned(), )?; } match ctx.command { QueueCommand::Stand => {} _ => user_error("Unexpected command".to_owned())?, }; match ctx.item.action_type { LocationActionType::Sitting { .. } | LocationActionType::Reclining { .. } => {} _ => user_error("You're already standing.".to_owned())?, } stand_if_needed(&ctx.trans, &mut ctx.item).await?; Ok(()) } } 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 try to stand, but it turns out the dead can't even do that!".to_owned(), )?; } queue_command_and_save(ctx, &player_item, &QueueCommand::Stand).await?; Ok(()) } } static VERB_INT: Verb = Verb; pub static VERB: UserVerbRef = &VERB_INT as UserVerbRef;