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