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

98 lines
3.1 KiB
Rust

use super::{
get_player_item_or_fail, search_item_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 (install_what_raw, what_dir_raw) = match remaining.rsplit_once(" on door to ") {
None => user_error(ansi!("Install where? Try <bold>install<reset> <lt>lock> <bold>on 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 installer.\
So discriminatory!"
.to_owned(),
)?;
}
let item = search_item_for_user(
ctx,
&ItemSearchParams {
include_contents: true,
..ItemSearchParams::base(&player_item, install_what_raw.trim())
},
)
.await?;
if item.item_type != "possession" {
user_error("You can't install 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 install that!".to_owned())?,
Some(h) => h,
};
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 install things while standing in a private room you own. \
If you are outside, try installing from the inside."
.to_owned(),
)?;
}
let dir = Direction::parse(what_dir_raw.trim())
.ok_or_else(|| UserError("Invalid direction.".to_owned()))?;
loc_item
.door_states
.as_ref()
.and_then(|ds| ds.get(&dir))
.ok_or_else(|| {
UserError(
"No door to that direction in this room - are you on the wrong side?"
.to_owned(),
)
})?;
handler
.install_cmd(ctx, &player_item, &item, &loc_item, &dir)
.await?;
Ok(())
}
}
static VERB_INT: Verb = Verb;
pub static VERB: UserVerbRef = &VERB_INT as UserVerbRef;