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

67 lines
2.7 KiB
Rust

use super::{VerbContext, UserVerb, UserVerbRef, UResult,
UserError,
user_error, get_player_item_or_fail, search_item_for_user};
use crate::{
db::ItemSearchParams,
static_content::{
possession_type::possession_data,
room::Direction,
},
models::item::ItemFlag,
};
use async_trait::async_trait;
use ansi::ansi;
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.is_dead {
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;