forked from blasthavers/blastmud
This is the start of being able to implement following in a way that works for NPCs, but it isn't finished yet. It does mean NPCs can do things like climb immediately, and will make it far simpler for NPCs to do other player-like actions in the future.
92 lines
3.0 KiB
Rust
92 lines
3.0 KiB
Rust
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;
|