forked from blasthavers/blastmud
114 lines
4.4 KiB
Rust
114 lines
4.4 KiB
Rust
use super::{get_player_item_or_fail, UResult, UserError, UserVerb, UserVerbRef, VerbContext};
|
|
use crate::{
|
|
models::item::LocationActionType,
|
|
static_content::{
|
|
possession_type::{possession_data, DamageType},
|
|
species::species_info_map,
|
|
},
|
|
};
|
|
use ansi::ansi;
|
|
use async_trait::async_trait;
|
|
use std::collections::BTreeMap;
|
|
|
|
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?;
|
|
|
|
let all_gear = ctx
|
|
.trans
|
|
.find_by_action_and_location(&player_item.refstr(), &LocationActionType::Worn)
|
|
.await?;
|
|
|
|
let mut msg = String::new();
|
|
msg.push_str(&format!(
|
|
ansi!(
|
|
"<bgblue><white><bold>| {:6} | {:25} | {:5} | {:5} | {:5} | {:5} | {:5} |<reset>\n"
|
|
),
|
|
"Part", "Clothing", "Beat", "Slash", "Prce", "Shock", "Bullt"
|
|
));
|
|
for body_part in &species_info_map()
|
|
.get(&player_item.species)
|
|
.ok_or_else(|| UserError("Species not found".to_owned()))?
|
|
.body_parts
|
|
{
|
|
let mut damage_ranges: BTreeMap<DamageType, (f64, f64)> = BTreeMap::new();
|
|
for damtyp in [
|
|
DamageType::Beat,
|
|
DamageType::Slash,
|
|
DamageType::Pierce,
|
|
DamageType::Shock,
|
|
DamageType::Bullet,
|
|
] {
|
|
damage_ranges.insert(damtyp, (0.0, 0.0));
|
|
}
|
|
let mut worn: String = String::new();
|
|
for item in &all_gear {
|
|
if let Some(wear_data) = item
|
|
.possession_type
|
|
.as_ref()
|
|
.and_then(|pt| possession_data().get(pt))
|
|
.and_then(|pd| pd.wear_data.as_ref())
|
|
{
|
|
if wear_data.covers_parts.contains(&body_part) {
|
|
if !worn.is_empty() {
|
|
worn.push_str(", ");
|
|
}
|
|
worn.push_str(&item.display);
|
|
for entry in damage_ranges.iter_mut() {
|
|
if let Some(soak_data) = wear_data.soaks.get(entry.0) {
|
|
let (old_min, old_max) = entry.1;
|
|
*entry.1 =
|
|
(*old_min + soak_data.min_soak, *old_max + soak_data.max_soak);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
worn.truncate(25);
|
|
msg.push_str(&format!(
|
|
ansi!("| <bold>{:6}<reset> | {:25} | {:2}-{:2} | {:2}-{:2} | {:2}-{:2} | {:2}-{:2} | {:2}-{:2} |\n"),
|
|
body_part.display(player_item.sex.clone()),
|
|
&worn,
|
|
damage_ranges.get(&DamageType::Beat).map(|dt| dt.0).unwrap_or(0.0),
|
|
damage_ranges.get(&DamageType::Beat).map(|dt| dt.1).unwrap_or(0.0),
|
|
damage_ranges.get(&DamageType::Slash).map(|dt| dt.0).unwrap_or(0.0),
|
|
damage_ranges.get(&DamageType::Slash).map(|dt| dt.1).unwrap_or(0.0),
|
|
damage_ranges.get(&DamageType::Pierce).map(|dt| dt.0).unwrap_or(0.0),
|
|
damage_ranges.get(&DamageType::Pierce).map(|dt| dt.1).unwrap_or(0.0),
|
|
damage_ranges.get(&DamageType::Shock).map(|dt| dt.0).unwrap_or(0.0),
|
|
damage_ranges.get(&DamageType::Shock).map(|dt| dt.1).unwrap_or(0.0),
|
|
damage_ranges.get(&DamageType::Bullet).map(|dt| dt.0).unwrap_or(0.0),
|
|
damage_ranges.get(&DamageType::Bullet).map(|dt| dt.1).unwrap_or(0.0),
|
|
));
|
|
}
|
|
let mut total_dodge: f64 = 0.0;
|
|
for item in &all_gear {
|
|
if let Some(wear_data) = item
|
|
.possession_type
|
|
.as_ref()
|
|
.and_then(|pt| possession_data().get(pt))
|
|
.and_then(|pd| pd.wear_data.as_ref())
|
|
{
|
|
total_dodge += wear_data.dodge_penalty;
|
|
}
|
|
}
|
|
msg.push_str(&format!(
|
|
"Total dodge penalty from armour: {}\n",
|
|
total_dodge
|
|
));
|
|
|
|
ctx.trans.queue_for_session(ctx.session, Some(&msg)).await?;
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
static VERB_INT: Verb = Verb;
|
|
pub static VERB: UserVerbRef = &VERB_INT as UserVerbRef;
|