use super::{ cut::ensure_has_butcher_tool, get_player_item_or_fail, search_item_for_user, user_error, UResult, UserError, UserVerb, UserVerbRef, VerbContext, }; use crate::{ db::ItemSearchParams, models::item::DeathData, regular_tasks::queued_command::{queue_command, QueueCommand}, services::combat::corpsify_item, static_content::possession_type::possession_data, }; use async_trait::async_trait; use std::sync::Arc; 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 butcher things while they are dead, not while YOU are dead!".to_owned(), )? } let possible_corpse = search_item_for_user( ctx, &ItemSearchParams { include_loc_contents: true, dead_first: true, ..ItemSearchParams::base(&player_item, remaining.trim()) }, ) .await?; let possession_types = match possible_corpse.death_data.as_ref() { None => user_error(format!( "You can't do that while {} is still alive!", possible_corpse.pronouns.subject ))?, Some(DeathData { parts_remaining, .. }) => parts_remaining, } .clone(); let corpse = if possible_corpse.item_type == "corpse" { possible_corpse } else if possible_corpse.item_type == "npc" || possible_corpse.item_type == "player" { let mut possible_corpse_mut = (*possible_corpse).clone(); possible_corpse_mut.location = if possible_corpse.item_type == "npc" { "room/valhalla" } else { "room/repro_xv_respawn" } .to_owned(); Arc::new(corpsify_item(&ctx.trans, &possible_corpse).await?) } else { user_error("You can't butcher that!".to_owned())? }; ensure_has_butcher_tool(&ctx.trans, &player_item).await?; let mut player_item_mut = (*player_item).clone(); for possession_type in possession_types { let possession_data = possession_data() .get(&possession_type) .ok_or_else(|| UserError("That part doesn't exist anymore".to_owned()))?; queue_command( ctx, &mut player_item_mut, &QueueCommand::Cut { from_corpse: corpse.item_code.clone(), what_part: possession_data.display.to_owned(), }, ) .await?; } ctx.trans.save_item_model(&player_item_mut).await?; Ok(()) } } static VERB_INT: Verb = Verb; pub static VERB: UserVerbRef = &VERB_INT as UserVerbRef;