use super::{ get_player_item_or_fail, search_item_for_user, user_error, UResult, UserVerb, UserVerbRef, VerbContext, }; use crate::{ db::ItemSearchParams, models::{consent::ConsentType, effect::EffectType, item::ItemFlag}, services::{check_consent, combat::start_attack}, }; 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 player_item = get_player_item_or_fail(ctx).await?; if player_item.death_data.is_some() { user_error("It doesn't really seem fair, but you realise you won't be able to attack anyone while you're dead!".to_string())?; } if player_item .active_effects .iter() .any(|v| v.0 == EffectType::Stunned) { user_error("You're too stunned to attack.".to_owned())?; } let attack_whom = search_item_for_user( ctx, &ItemSearchParams { include_loc_contents: true, limit: 1, ..ItemSearchParams::base(&player_item, remaining) }, ) .await?; let (loctype, loccode) = match player_item.location.split_once("/") { None => user_error("Your current location is invalid!".to_owned())?, Some(l) => l, }; let player_loc = match ctx.trans.find_item_by_type_code(loctype, loccode).await? { None => user_error("Your current location is invalid!".to_owned())?, Some(l) => l, }; if player_loc.flags.contains(&ItemFlag::NoSeeContents) { user_error("It is too foggy to even see who is here, let alone attack!".to_owned())?; } match attack_whom.item_type.as_str() { "npc" => {} "player" => {} _ => user_error("Only characters (players / NPCs) can be attacked".to_string())?, } if attack_whom.item_code == player_item.item_code && attack_whom.item_type == player_item.item_type { user_error("That's you, silly!".to_string())? } if !check_consent( ctx.trans, "attack", &ConsentType::Fight, &player_item, &attack_whom, ) .await? { user_error(ansi!("Your wristpad vibrates and blocks you from doing that. You get a feeling that while the empire might be gone, the system to stop subjects with working wristpads from fighting each unless they have an consented is very much functional. [Try help allow]").to_string())? } if attack_whom.death_data.is_some() { user_error("There's no point attacking the dead!".to_string())? } if attack_whom.active_climb.is_some() { user_error("They are already climbing away!".to_string())? } start_attack(&ctx.trans, &player_item, &attack_whom).await } } static VERB_INT: Verb = Verb; pub static VERB: UserVerbRef = &VERB_INT as UserVerbRef;