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 install lock> on door to 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;