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

94 lines
3.1 KiB
Rust

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!("<blue>Your wristpad vibrates and blocks you from doing that.<reset> 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 <bold>help allow<reset>]").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;