forked from blasthavers/blastmud
Support wielding weapons.
This commit is contained in:
parent
dc38d87beb
commit
2850b66bee
@ -12,7 +12,10 @@ use crate::message_handler::user_commands::parsing::parse_offset;
|
|||||||
use crate::models::{
|
use crate::models::{
|
||||||
session::Session,
|
session::Session,
|
||||||
user::User,
|
user::User,
|
||||||
item::Item,
|
item::{
|
||||||
|
Item,
|
||||||
|
LocationActionType,
|
||||||
|
},
|
||||||
task::{Task, TaskParse}
|
task::{Task, TaskParse}
|
||||||
};
|
};
|
||||||
use tokio_postgres::types::ToSql;
|
use tokio_postgres::types::ToSql;
|
||||||
@ -630,11 +633,46 @@ impl DBTrans {
|
|||||||
|
|
||||||
pub async fn get_location_stats(&self, location: &str) -> DResult<LocationStats> {
|
pub async fn get_location_stats(&self, location: &str) -> DResult<LocationStats> {
|
||||||
Ok(serde_json::from_value(self.pg_trans()?.query_one(
|
Ok(serde_json::from_value(self.pg_trans()?.query_one(
|
||||||
"SELECT COUNT(*) AS total_count, SUM(details->>'weight') AS total_weight \
|
"SELECT JSON_BUILD_OBJECT('total_count', COUNT(*), 'total_weight', COALESCE(SUM(CAST(details->>'weight' AS NUMERIC)), 0)) \
|
||||||
FROM items WHERE location = $1", &[&location]
|
FROM items WHERE details->>'location' = $1", &[&location]
|
||||||
).await?.get(0))?)
|
).await?.get(0))?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn set_exclusive_action_type_to(&self, item: &Item,
|
||||||
|
new_action_type: &LocationActionType,
|
||||||
|
other_item_action_type: &LocationActionType) -> DResult<()> {
|
||||||
|
self.pg_trans()?.execute("UPDATE items SET details=\
|
||||||
|
JSONB_SET(details, '{action_type}', $1) \
|
||||||
|
WHERE details->>'location' = $2 AND \
|
||||||
|
details->>'action_type' = $3",
|
||||||
|
&[&serde_json::to_value(other_item_action_type)?,
|
||||||
|
&item.location,
|
||||||
|
&serde_json::to_value(new_action_type)?
|
||||||
|
.as_str().unwrap()
|
||||||
|
]).await?;
|
||||||
|
self.pg_trans()?.execute("UPDATE items SET details=\
|
||||||
|
JSONB_SET(details, '{action_type}', $1) \
|
||||||
|
WHERE details->>'item_type' = $2 AND \
|
||||||
|
details->>'item_code' = $3",
|
||||||
|
&[&serde_json::to_value(new_action_type)?,
|
||||||
|
&item.item_type,
|
||||||
|
&item.item_code
|
||||||
|
]).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn find_by_action_and_location(&self, location: &str, action_type: &LocationActionType) -> DResult<Option<Arc<Item>>> {
|
||||||
|
if let Some(item) = self.pg_trans()?.query_opt(
|
||||||
|
"SELECT details FROM items WHERE \
|
||||||
|
details->>'location' = $1 AND \
|
||||||
|
details->>'action_type' = $2",
|
||||||
|
&[&location,
|
||||||
|
&serde_json::to_value(action_type)?.as_str().unwrap()]).await? {
|
||||||
|
return Ok(Some(Arc::new(serde_json::from_value::<Item>(item.get("details"))?)));
|
||||||
|
}
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn commit(mut self: Self) -> DResult<()> {
|
pub async fn commit(mut self: Self) -> DResult<()> {
|
||||||
let trans_opt = self.with_trans_mut(|t| std::mem::replace(t, None));
|
let trans_opt = self.with_trans_mut(|t| std::mem::replace(t, None));
|
||||||
if let Some(trans) = trans_opt {
|
if let Some(trans) = trans_opt {
|
||||||
|
@ -28,6 +28,7 @@ mod register;
|
|||||||
pub mod say;
|
pub mod say;
|
||||||
mod whisper;
|
mod whisper;
|
||||||
mod who;
|
mod who;
|
||||||
|
pub mod wield;
|
||||||
|
|
||||||
pub struct VerbContext<'l> {
|
pub struct VerbContext<'l> {
|
||||||
pub session: &'l ListenerSession,
|
pub session: &'l ListenerSession,
|
||||||
@ -125,6 +126,7 @@ static REGISTERED_COMMANDS: UserVerbRegistry = phf_map! {
|
|||||||
"whisper" => whisper::VERB,
|
"whisper" => whisper::VERB,
|
||||||
"tell" => whisper::VERB,
|
"tell" => whisper::VERB,
|
||||||
|
|
||||||
|
"wield" => wield::VERB,
|
||||||
"who" => who::VERB,
|
"who" => who::VERB,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
140
blastmud_game/src/message_handler/user_commands/wield.rs
Normal file
140
blastmud_game/src/message_handler/user_commands/wield.rs
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
use super::{
|
||||||
|
VerbContext,
|
||||||
|
UserVerb,
|
||||||
|
UserVerbRef,
|
||||||
|
UResult,
|
||||||
|
ItemSearchParams,
|
||||||
|
user_error,
|
||||||
|
get_player_item_or_fail,
|
||||||
|
search_item_for_user,
|
||||||
|
};
|
||||||
|
use crate::{
|
||||||
|
static_content::possession_type::possession_data,
|
||||||
|
regular_tasks::queued_command::{
|
||||||
|
QueueCommandHandler,
|
||||||
|
QueueCommand,
|
||||||
|
queue_command
|
||||||
|
},
|
||||||
|
models::item::{
|
||||||
|
LocationActionType,
|
||||||
|
SkillType,
|
||||||
|
},
|
||||||
|
services::{
|
||||||
|
broadcast_to_room,
|
||||||
|
skills::skill_check_and_grind,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use std::time;
|
||||||
|
|
||||||
|
pub struct QueueHandler;
|
||||||
|
#[async_trait]
|
||||||
|
impl QueueCommandHandler for QueueHandler {
|
||||||
|
async fn start_command(&self, ctx: &mut VerbContext<'_>, command: &QueueCommand)
|
||||||
|
-> UResult<time::Duration> {
|
||||||
|
let player_item = get_player_item_or_fail(ctx).await?;
|
||||||
|
if player_item.is_dead {
|
||||||
|
user_error("You try to wield it, but your ghostly hands slip through it uselessly".to_owned())?;
|
||||||
|
}
|
||||||
|
let item_id = match command {
|
||||||
|
QueueCommand::Wield { possession_id } => possession_id,
|
||||||
|
_ => user_error("Unexpected command".to_owned())?
|
||||||
|
};
|
||||||
|
let item = match ctx.trans.find_item_by_type_code("possession", &item_id).await? {
|
||||||
|
None => user_error("Item not found".to_owned())?,
|
||||||
|
Some(it) => it
|
||||||
|
};
|
||||||
|
if item.location != format!("player/{}", player_item.item_code) {
|
||||||
|
user_error("You try to wield it but realise you no longer have it".to_owned())?
|
||||||
|
}
|
||||||
|
let msg_exp = format!("{} fumbles around with {} {}\n",
|
||||||
|
&player_item.display_for_sentence(true, 1, true),
|
||||||
|
&player_item.pronouns.possessive,
|
||||||
|
&item.display_for_sentence(true, 1, false));
|
||||||
|
let msg_nonexp = format!("{} fumbles around with {} {}\n",
|
||||||
|
&player_item.display_for_sentence(false, 1, true),
|
||||||
|
&player_item.pronouns.possessive,
|
||||||
|
&item.display_for_sentence(false, 1, false));
|
||||||
|
broadcast_to_room(ctx.trans, &player_item.location, None, &msg_exp, Some(&msg_nonexp)).await?;
|
||||||
|
let mut draw_level: f64 = *player_item.total_skills.get(&SkillType::Quickdraw).to_owned().unwrap_or(&8.0);
|
||||||
|
let mut player_item_mut = (*player_item).clone();
|
||||||
|
|
||||||
|
let skill_result =
|
||||||
|
skill_check_and_grind(ctx.trans, &mut player_item_mut, &SkillType::Quickdraw, draw_level).await?;
|
||||||
|
if skill_result < -0.5 {
|
||||||
|
draw_level -= 2.0;
|
||||||
|
} else if skill_result < -0.25 {
|
||||||
|
draw_level -= 1.0;
|
||||||
|
} else if skill_result > 0.5 {
|
||||||
|
draw_level += 2.0;
|
||||||
|
} else if skill_result > 0.25 {
|
||||||
|
draw_level += 1.0;
|
||||||
|
}
|
||||||
|
ctx.trans.save_item_model(&player_item_mut).await?;
|
||||||
|
|
||||||
|
let wait_ticks = (12.0 - (draw_level / 2.0)).min(8.0).max(1.0);
|
||||||
|
Ok(time::Duration::from_millis((wait_ticks * 500.0).round() as u64))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(unreachable_patterns)]
|
||||||
|
async fn finish_command(&self, ctx: &mut VerbContext<'_>, command: &QueueCommand)
|
||||||
|
-> UResult<()> {
|
||||||
|
let player_item = get_player_item_or_fail(ctx).await?;
|
||||||
|
if player_item.is_dead {
|
||||||
|
user_error("You try to wield it, but your ghostly hands slip through it uselessly".to_owned())?;
|
||||||
|
}
|
||||||
|
let item_id = match command {
|
||||||
|
QueueCommand::Wield { possession_id } => possession_id,
|
||||||
|
_ => user_error("Unexpected command".to_owned())?
|
||||||
|
};
|
||||||
|
let item = match ctx.trans.find_item_by_type_code("possession", &item_id).await? {
|
||||||
|
None => user_error("Item not found".to_owned())?,
|
||||||
|
Some(it) => it
|
||||||
|
};
|
||||||
|
if item.location != format!("player/{}", player_item.item_code) {
|
||||||
|
user_error("You try to wield it but realise you no longer have it".to_owned())?
|
||||||
|
}
|
||||||
|
let msg_exp = format!("{} wields {} {}\n",
|
||||||
|
&player_item.display_for_sentence(true, 1, true),
|
||||||
|
&player_item.pronouns.possessive,
|
||||||
|
&item.display_for_sentence(true, 1, false));
|
||||||
|
let msg_nonexp = format!("{} wields {} {}\n",
|
||||||
|
&player_item.display_for_sentence(false, 1, true),
|
||||||
|
&player_item.pronouns.possessive,
|
||||||
|
&item.display_for_sentence(false, 1, false));
|
||||||
|
broadcast_to_room(ctx.trans, &player_item.location, None, &msg_exp, Some(&msg_nonexp)).await?;
|
||||||
|
ctx.trans.set_exclusive_action_type_to(&item,
|
||||||
|
&LocationActionType::Wielded,
|
||||||
|
&LocationActionType::Normal).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 weapon = search_item_for_user(ctx, &ItemSearchParams {
|
||||||
|
include_contents: true,
|
||||||
|
..ItemSearchParams::base(&player_item, &remaining)
|
||||||
|
}).await?;
|
||||||
|
if player_item.is_dead {
|
||||||
|
user_error("You try to wield it, but your ghostly hands slip through it uselessly".to_owned())?;
|
||||||
|
}
|
||||||
|
if weapon.action_type == LocationActionType::Wielded {
|
||||||
|
user_error("You're actually already wielding it.".to_owned())?;
|
||||||
|
}
|
||||||
|
if weapon.item_type != "possession" ||
|
||||||
|
weapon.possession_type.as_ref()
|
||||||
|
.and_then(|poss_type| possession_data().get(&poss_type))
|
||||||
|
.and_then(|poss_data| poss_data.weapon_data.as_ref())
|
||||||
|
.is_none() {
|
||||||
|
user_error("You can't wield that!".to_owned())?;
|
||||||
|
}
|
||||||
|
queue_command(ctx, &QueueCommand::Wield { possession_id: weapon.item_code.clone() }).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static VERB_INT: Verb = Verb;
|
||||||
|
pub static VERB: UserVerbRef = &VERB_INT as UserVerbRef;
|
@ -15,6 +15,7 @@ use crate::message_handler::user_commands::{
|
|||||||
CommandHandlingError,
|
CommandHandlingError,
|
||||||
UResult,
|
UResult,
|
||||||
movement,
|
movement,
|
||||||
|
wield,
|
||||||
user_error,
|
user_error,
|
||||||
get_user_or_fail
|
get_user_or_fail
|
||||||
};
|
};
|
||||||
@ -24,12 +25,14 @@ use once_cell::sync::OnceCell;
|
|||||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub enum QueueCommand {
|
pub enum QueueCommand {
|
||||||
Movement { direction: Direction },
|
Movement { direction: Direction },
|
||||||
|
Wield { possession_id: String }
|
||||||
}
|
}
|
||||||
impl QueueCommand {
|
impl QueueCommand {
|
||||||
pub fn name(&self) -> &'static str {
|
pub fn name(&self) -> &'static str {
|
||||||
use QueueCommand::*;
|
use QueueCommand::*;
|
||||||
match self {
|
match self {
|
||||||
Movement {..} => "Movement"
|
Movement {..} => "Movement",
|
||||||
|
Wield {..} => "Wield",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -44,7 +47,8 @@ fn queue_command_registry() -> &'static BTreeMap<&'static str, &'static (dyn Que
|
|||||||
static REGISTRY: OnceCell<BTreeMap<&'static str, &'static (dyn QueueCommandHandler + Sync + Send)>> =
|
static REGISTRY: OnceCell<BTreeMap<&'static str, &'static (dyn QueueCommandHandler + Sync + Send)>> =
|
||||||
OnceCell::new();
|
OnceCell::new();
|
||||||
REGISTRY.get_or_init(|| vec!(
|
REGISTRY.get_or_init(|| vec!(
|
||||||
("Movement", &movement::QueueHandler as &(dyn QueueCommandHandler + Sync + Send))
|
("Movement", &movement::QueueHandler as &(dyn QueueCommandHandler + Sync + Send)),
|
||||||
|
("Wield", &wield::QueueHandler as &(dyn QueueCommandHandler + Sync + Send))
|
||||||
).into_iter().collect())
|
).into_iter().collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,7 +291,16 @@ pub async fn stop_attacking(trans: &DBTrans, by_whom: &Item, to_whom: &Item) ->
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn what_wielded(_trans: &DBTrans, who: &Item) -> DResult<&'static WeaponData> {
|
async fn what_wielded(trans: &DBTrans, who: &Item) -> DResult<&'static WeaponData> {
|
||||||
|
if let Some(item) = trans.find_by_action_and_location(
|
||||||
|
&format!("{}/{}", &who.item_type, &who.item_code), &LocationActionType::Wielded).await? {
|
||||||
|
if let Some(dat) = item.possession_type.as_ref()
|
||||||
|
.and_then(|pt| possession_data().get(&pt))
|
||||||
|
.and_then(|pd| pd.weapon_data.as_ref()) {
|
||||||
|
return Ok(dat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Search inventory for wielded item first.
|
// TODO: Search inventory for wielded item first.
|
||||||
if who.item_type == "npc" {
|
if who.item_type == "npc" {
|
||||||
if let Some(intrinsic) = npc_by_code().get(who.item_code.as_str())
|
if let Some(intrinsic) = npc_by_code().get(who.item_code.as_str())
|
||||||
|
@ -46,105 +46,105 @@ pub fn calculate_total_stats_skills_for_user(target_item: &mut Item, user: &User
|
|||||||
target_item.total_skills.entry(SkillType::Appraise)
|
target_item.total_skills.entry(SkillType::Appraise)
|
||||||
.and_modify(|sk| *sk += brn * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += brn * 0.5).or_insert(brn * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Appraise)
|
target_item.total_skills.entry(SkillType::Appraise)
|
||||||
.and_modify(|sk| *sk += sen * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += sen * 0.5).or_insert(sen * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Blades)
|
target_item.total_skills.entry(SkillType::Blades)
|
||||||
.and_modify(|sk| *sk += refl * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += refl * 0.5).or_insert(refl * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Blades)
|
target_item.total_skills.entry(SkillType::Blades)
|
||||||
.and_modify(|sk| *sk += col * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += col * 0.5).or_insert(col * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Bombs)
|
target_item.total_skills.entry(SkillType::Bombs)
|
||||||
.and_modify(|sk| *sk += brn * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += brn * 0.5).or_insert(brn * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Bombs)
|
target_item.total_skills.entry(SkillType::Bombs)
|
||||||
.and_modify(|sk| *sk += col * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += col * 0.5).or_insert(col * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Chemistry)
|
target_item.total_skills.entry(SkillType::Chemistry)
|
||||||
.and_modify(|sk| *sk += brn).or_insert(brn);
|
.and_modify(|sk| *sk += brn).or_insert(brn);
|
||||||
target_item.total_skills.entry(SkillType::Climb)
|
target_item.total_skills.entry(SkillType::Climb)
|
||||||
.and_modify(|sk| *sk += refl * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += refl * 0.5).or_insert(refl * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Climb)
|
target_item.total_skills.entry(SkillType::Climb)
|
||||||
.and_modify(|sk| *sk += end * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += end * 0.5).or_insert(end * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Clubs)
|
target_item.total_skills.entry(SkillType::Clubs)
|
||||||
.and_modify(|sk| *sk += brw * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += brw * 0.5).or_insert(brw * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Clubs)
|
target_item.total_skills.entry(SkillType::Clubs)
|
||||||
.and_modify(|sk| *sk += refl * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += refl * 0.5).or_insert(refl * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Craft)
|
target_item.total_skills.entry(SkillType::Craft)
|
||||||
.and_modify(|sk| *sk += brn).or_insert(brn);
|
.and_modify(|sk| *sk += brn).or_insert(brn);
|
||||||
target_item.total_skills.entry(SkillType::Dodge)
|
target_item.total_skills.entry(SkillType::Dodge)
|
||||||
.and_modify(|sk| *sk += sen * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += sen * 0.5).or_insert(sen * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Dodge)
|
target_item.total_skills.entry(SkillType::Dodge)
|
||||||
.and_modify(|sk| *sk += refl * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += refl * 0.5).or_insert(refl * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Fish)
|
target_item.total_skills.entry(SkillType::Fish)
|
||||||
.and_modify(|sk| *sk += end * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += end * 0.5).or_insert(end * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Fish)
|
target_item.total_skills.entry(SkillType::Fish)
|
||||||
.and_modify(|sk| *sk += col * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += col * 0.5).or_insert(col * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Fists)
|
target_item.total_skills.entry(SkillType::Fists)
|
||||||
.and_modify(|sk| *sk += brw * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += brw * 0.5).or_insert(brw * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Fists)
|
target_item.total_skills.entry(SkillType::Fists)
|
||||||
.and_modify(|sk| *sk += end * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += end * 0.5).or_insert(end * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Focus)
|
target_item.total_skills.entry(SkillType::Focus)
|
||||||
.and_modify(|sk| *sk += sen * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += sen * 0.5).or_insert(sen * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Focus)
|
target_item.total_skills.entry(SkillType::Focus)
|
||||||
.and_modify(|sk| *sk += end * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += end * 0.5).or_insert(end * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Fuck)
|
target_item.total_skills.entry(SkillType::Fuck)
|
||||||
.and_modify(|sk| *sk += sen * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += sen * 0.5).or_insert(sen * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Fuck)
|
target_item.total_skills.entry(SkillType::Fuck)
|
||||||
.and_modify(|sk| *sk += end * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += end * 0.5).or_insert(end * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Hack)
|
target_item.total_skills.entry(SkillType::Hack)
|
||||||
.and_modify(|sk| *sk += brn).or_insert(brn);
|
.and_modify(|sk| *sk += brn).or_insert(brn);
|
||||||
target_item.total_skills.entry(SkillType::Locksmith)
|
target_item.total_skills.entry(SkillType::Locksmith)
|
||||||
.and_modify(|sk| *sk += brn * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += brn * 0.5).or_insert(brn * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Locksmith)
|
target_item.total_skills.entry(SkillType::Locksmith)
|
||||||
.and_modify(|sk| *sk += refl * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += refl * 0.5).or_insert(refl * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Medic)
|
target_item.total_skills.entry(SkillType::Medic)
|
||||||
.and_modify(|sk| *sk += brn).or_insert(brn);
|
.and_modify(|sk| *sk += brn).or_insert(brn);
|
||||||
target_item.total_skills.entry(SkillType::Persuade)
|
target_item.total_skills.entry(SkillType::Persuade)
|
||||||
.and_modify(|sk| *sk += brn * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += brn * 0.5).or_insert(brn * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Persuade)
|
target_item.total_skills.entry(SkillType::Persuade)
|
||||||
.and_modify(|sk| *sk += col * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += col * 0.5).or_insert(col * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Pilot)
|
target_item.total_skills.entry(SkillType::Pilot)
|
||||||
.and_modify(|sk| *sk += brn * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += brn * 0.5).or_insert(brn * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Pilot)
|
target_item.total_skills.entry(SkillType::Pilot)
|
||||||
.and_modify(|sk| *sk += refl * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += refl * 0.5).or_insert(refl * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Pistols)
|
target_item.total_skills.entry(SkillType::Pistols)
|
||||||
.and_modify(|sk| *sk += refl * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += refl * 0.5).or_insert(refl * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Pistols)
|
target_item.total_skills.entry(SkillType::Pistols)
|
||||||
.and_modify(|sk| *sk += col * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += col * 0.5).or_insert(col * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Quickdraw)
|
target_item.total_skills.entry(SkillType::Quickdraw)
|
||||||
.and_modify(|sk| *sk += refl * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += refl * 0.5).or_insert(refl * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Quickdraw)
|
target_item.total_skills.entry(SkillType::Quickdraw)
|
||||||
.and_modify(|sk| *sk += col * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += col * 0.5).or_insert(col * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Repair)
|
target_item.total_skills.entry(SkillType::Repair)
|
||||||
.and_modify(|sk| *sk += brn).or_insert(brn);
|
.and_modify(|sk| *sk += brn).or_insert(brn);
|
||||||
target_item.total_skills.entry(SkillType::Rifles)
|
target_item.total_skills.entry(SkillType::Rifles)
|
||||||
.and_modify(|sk| *sk += refl * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += refl * 0.5).or_insert(refl * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Rifles)
|
target_item.total_skills.entry(SkillType::Rifles)
|
||||||
.and_modify(|sk| *sk += col * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += col * 0.5).or_insert(col * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Scavenge)
|
target_item.total_skills.entry(SkillType::Scavenge)
|
||||||
.and_modify(|sk| *sk += sen * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += sen * 0.5).or_insert(sen * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Scavenge)
|
target_item.total_skills.entry(SkillType::Scavenge)
|
||||||
.and_modify(|sk| *sk += end * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += end * 0.5).or_insert(end * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Science)
|
target_item.total_skills.entry(SkillType::Science)
|
||||||
.and_modify(|sk| *sk += brn).or_insert(brn);
|
.and_modify(|sk| *sk += brn).or_insert(brn);
|
||||||
target_item.total_skills.entry(SkillType::Sneak)
|
target_item.total_skills.entry(SkillType::Sneak)
|
||||||
.and_modify(|sk| *sk += sen * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += sen * 0.5).or_insert(sen * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Sneak)
|
target_item.total_skills.entry(SkillType::Sneak)
|
||||||
.and_modify(|sk| *sk += col * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += col * 0.5).or_insert(col * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Spears)
|
target_item.total_skills.entry(SkillType::Spears)
|
||||||
.and_modify(|sk| *sk += refl * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += refl * 0.5).or_insert(refl * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Spears)
|
target_item.total_skills.entry(SkillType::Spears)
|
||||||
.and_modify(|sk| *sk += end * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += end * 0.5).or_insert(end * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Swim)
|
target_item.total_skills.entry(SkillType::Swim)
|
||||||
.and_modify(|sk| *sk += end).or_insert(brn);
|
.and_modify(|sk| *sk += end).or_insert(brn);
|
||||||
target_item.total_skills.entry(SkillType::Teach)
|
target_item.total_skills.entry(SkillType::Teach)
|
||||||
.and_modify(|sk| *sk += brn).or_insert(brn);
|
.and_modify(|sk| *sk += brn).or_insert(brn);
|
||||||
target_item.total_skills.entry(SkillType::Throw)
|
target_item.total_skills.entry(SkillType::Throw)
|
||||||
.and_modify(|sk| *sk += sen * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += sen * 0.5).or_insert(sen * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Throw)
|
target_item.total_skills.entry(SkillType::Throw)
|
||||||
.and_modify(|sk| *sk += brw * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += brw * 0.5).or_insert(brw * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Track)
|
target_item.total_skills.entry(SkillType::Track)
|
||||||
.and_modify(|sk| *sk += sen).or_insert(brn);
|
.and_modify(|sk| *sk += sen).or_insert(brn);
|
||||||
target_item.total_skills.entry(SkillType::Whips)
|
target_item.total_skills.entry(SkillType::Whips)
|
||||||
.and_modify(|sk| *sk += sen * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += sen * 0.5).or_insert(sen * 0.5);
|
||||||
target_item.total_skills.entry(SkillType::Whips)
|
target_item.total_skills.entry(SkillType::Whips)
|
||||||
.and_modify(|sk| *sk += refl * 0.5).or_insert(brn * 0.5);
|
.and_modify(|sk| *sk += refl * 0.5).or_insert(refl * 0.5);
|
||||||
// 5: Apply skill (de)buffs...
|
// 5: Apply skill (de)buffs...
|
||||||
for buff in &target_item.temporary_buffs {
|
for buff in &target_item.temporary_buffs {
|
||||||
for impact in &buff.impacts {
|
for impact in &buff.impacts {
|
||||||
|
Loading…
Reference in New Issue
Block a user