forked from blasthavers/blastmud
94 lines
3.1 KiB
Rust
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;
|