From cf0d2f740bbdaba630d8d00b7ad2386eac0fd015 Mon Sep 17 00:00:00 2001 From: Condorra Date: Sun, 28 May 2023 21:59:09 +1000 Subject: [PATCH] Apply dodge penalty from armour. --- .../message_handler/user_commands/remove.rs | 24 +++++++++++++- .../src/message_handler/user_commands/wear.rs | 31 +++++++++++++++++-- blastmud_game/src/models/item.rs | 10 +++--- blastmud_game/src/services/combat.rs | 10 ++++-- blastmud_game/src/services/skills.rs | 4 +-- 5 files changed, 66 insertions(+), 13 deletions(-) diff --git a/blastmud_game/src/message_handler/user_commands/remove.rs b/blastmud_game/src/message_handler/user_commands/remove.rs index ff96069..26f1961 100644 --- a/blastmud_game/src/message_handler/user_commands/remove.rs +++ b/blastmud_game/src/message_handler/user_commands/remove.rs @@ -19,8 +19,9 @@ use crate::{ }, services::{ comms::broadcast_to_room, + skills::calculate_total_stats_skills_for_user, }, - models::item::{Item, LocationActionType}, + models::item::{Item, LocationActionType, BuffCause}, }; use async_trait::async_trait; use std::time; @@ -132,6 +133,27 @@ impl QueueCommandHandler for QueueHandler { let mut item_mut = (*item).clone(); item_mut.action_type = LocationActionType::Normal; item_mut.action_type_started = None; + + let poss_data = item.possession_type.as_ref() + .and_then(|pt| possession_data().get(&pt)) + .ok_or_else(|| UserError( + "That item no longer exists in the game so can't be handled. Ask staff for help.".to_owned()))?; + + let wear_data = poss_data.wear_data.as_ref().ok_or_else( + || UserError("You seem to be wearing something that isn't clothes! Ask staff for help.".to_owned()))?; + if wear_data.dodge_penalty != 0.0 { + let mut player_item_mut = (*player_item).clone(); + player_item_mut.temporary_buffs = player_item_mut.temporary_buffs.into_iter() + .filter(|buf| buf.cause != + BuffCause::ByItem { item_code: item_mut.item_code.clone(), + item_type: item_mut.item_type.clone() }) + .collect(); + if let Some(ref usr) = ctx.user_dat { + calculate_total_stats_skills_for_user(&mut player_item_mut, usr); + } + ctx.trans.save_item_model(&player_item_mut).await?; + } + ctx.trans.save_item_model(&item_mut).await?; Ok(()) } diff --git a/blastmud_game/src/message_handler/user_commands/wear.rs b/blastmud_game/src/message_handler/user_commands/wear.rs index ff67daf..0a1d9b0 100644 --- a/blastmud_game/src/message_handler/user_commands/wear.rs +++ b/blastmud_game/src/message_handler/user_commands/wear.rs @@ -19,12 +19,18 @@ use crate::{ }, services::{ comms::broadcast_to_room, + skills::calculate_total_stats_skills_for_user, + }, + models::item::{ + LocationActionType, + Buff, + BuffCause, + BuffImpact, + SkillType, }, - models::item::LocationActionType, }; use async_trait::async_trait; use chrono::Utc; -use log::info; use std::time; pub struct QueueHandler; @@ -123,7 +129,6 @@ impl QueueCommandHandler for QueueHandler { _ => tot, } ); - info!("Thickness with item: {}", thickness); if thickness > 12.0 { user_error(format!( "You're wearing too much on your {} already.", @@ -142,6 +147,26 @@ impl QueueCommandHandler for QueueHandler { let mut item_mut = (*item).clone(); item_mut.action_type = LocationActionType::Worn; item_mut.action_type_started = Some(Utc::now()); + + if wear_data.dodge_penalty != 0.0 { + let mut player_item_mut = (*player_item).clone(); + player_item_mut.temporary_buffs.push(Buff { + description: "Dodge penalty".to_owned(), + cause: BuffCause::ByItem { + item_type: item_mut.item_type.clone(), + item_code: item_mut.item_code.clone(), + }, + impacts: vec!(BuffImpact::ChangeSkill { + skill: SkillType::Dodge, + magnitude: -wear_data.dodge_penalty + }) + }); + if let Some(ref usr) = ctx.user_dat { + calculate_total_stats_skills_for_user(&mut player_item_mut, usr); + } + ctx.trans.save_item_model(&player_item_mut).await?; + } + ctx.trans.save_item_model(&item_mut).await?; Ok(()) } diff --git a/blastmud_game/src/models/item.rs b/blastmud_game/src/models/item.rs index 5090aac..c91de20 100644 --- a/blastmud_game/src/models/item.rs +++ b/blastmud_game/src/models/item.rs @@ -9,19 +9,19 @@ use crate::{ use super::session::Session; use chrono::{DateTime, Utc}; -#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, PartialOrd)] pub enum BuffCause { WaitingTask { task_code: String, task_type: String }, ByItem { item_code: String, item_type: String } } -#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, PartialOrd)] pub enum BuffImpact { - ChangeStat { stat: StatType, magnitude: i16 }, - ChangeSkill { skill: SkillType, magnitude: i16 } + ChangeStat { stat: StatType, magnitude: f64 }, + ChangeSkill { skill: SkillType, magnitude: f64 } } -#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, PartialOrd)] pub struct Buff { pub description: String, pub cause: BuffCause, diff --git a/blastmud_game/src/services/combat.rs b/blastmud_game/src/services/combat.rs index 07f85a1..a6f35b8 100644 --- a/blastmud_game/src/services/combat.rs +++ b/blastmud_game/src/services/combat.rs @@ -1,8 +1,11 @@ use crate::{ services::{ comms::broadcast_to_room, - skills::skill_check_and_grind, - skills::skill_check_only, + skills::{ + skill_check_and_grind, + skill_check_only, + calculate_total_stats_skills_for_user, + }, destroy_container, }, models::{ @@ -384,6 +387,9 @@ pub async fn handle_resurrect(trans: &DBTrans, player: &mut Item) -> DResult { target_item.total_stats.entry(stat.clone()) .and_modify(|old_value| *old_value = (*old_value + magnitude.clone() as f64).max(0.0)) - .or_insert((*magnitude).max(0) as f64); + .or_insert((*magnitude).max(0.0)); } _ => {} } @@ -153,7 +153,7 @@ pub fn calculate_total_stats_skills_for_user(target_item: &mut Item, user: &User BuffImpact::ChangeSkill { skill, magnitude } => { target_item.total_skills.entry(skill.clone()) .and_modify(|old_value| *old_value = (*old_value + magnitude.clone() as f64).max(0.0)) - .or_insert((*magnitude).max(0) as f64); + .or_insert((*magnitude).max(0.0)); } _ => {} }