67 lines
2.7 KiB
Rust
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;
|