blastmud/blastmud_game/src/message_handler/user_commands/uninstall.rs

96 lines
3.2 KiB
Rust

use super::{
get_player_item_or_fail, search_items_for_user, user_error, UResult, UserError, UserVerb,
UserVerbRef, VerbContext,
};
use crate::{
db::ItemSearchParams,
models::item::ItemFlag,
static_content::{possession_type::possession_data, room::Direction},
};
use ansi::ansi;
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 (uninstall_what_raw, what_dir_raw) = match remaining.rsplit_once(" from door to ") {
None => user_error(ansi!("Uninstall from where? Try <bold>uninstall<reset> <lt>lock> <bold>from door to<reset> <lt>direction>").to_owned())?,
Some(v) => v
};
let player_item = get_player_item_or_fail(ctx).await?;
if player_item.death_data.is_some() {
user_error(
"Apparently, you have to be alive to work as an uninstaller. \
So discriminatory!"
.to_owned(),
)?;
}
let (loc_t, loc_c) = player_item
.location
.split_once("/")
.ok_or_else(|| UserError("Invalid current location".to_owned()))?;
let loc_item = ctx
.trans
.find_item_by_type_code(loc_t, loc_c)
.await?
.ok_or_else(|| UserError("Can't find your location".to_owned()))?;
if loc_item.owner.as_ref() != Some(&player_item.refstr())
|| !loc_item.flags.contains(&ItemFlag::PrivatePlace)
{
user_error(
"You can only uninstall things while standing in a private room you own. \
If you are outside, try uninstalling from the inside."
.to_owned(),
)?;
}
let dir = Direction::parse(what_dir_raw.trim())
.ok_or_else(|| UserError("Invalid direction.".to_owned()))?;
let cand_items = search_items_for_user(
ctx,
&ItemSearchParams {
include_loc_contents: true,
..ItemSearchParams::base(&player_item, uninstall_what_raw.trim())
},
)
.await?;
let item = cand_items
.iter()
.find(|it| it.action_type.is_in_direction(&dir))
.ok_or_else(|| {
UserError(
"Sorry, I couldn't find anything matching installed on that door.".to_owned(),
)
})?;
if item.item_type != "possession" {
user_error("You can't uninstall that!".to_owned())?;
}
let handler = match item
.possession_type
.as_ref()
.and_then(|pt| possession_data().get(pt))
.and_then(|pd| pd.install_handler)
{
None => user_error("You can't uninstall that!".to_owned())?,
Some(h) => h,
};
handler
.uninstall_cmd(ctx, &player_item, &item, &loc_item, &dir)
.await?;
Ok(())
}
}
static VERB_INT: Verb = Verb;
pub static VERB: UserVerbRef = &VERB_INT as UserVerbRef;