mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Split adjusted_by_skills by toolkind
This commit is contained in:
parent
a2e0426d45
commit
81bbc8c31f
@ -15,7 +15,7 @@ use crate::{
|
||||
terrain::SpriteKind,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
use std::{convert::TryFrom, time::Duration};
|
||||
|
||||
#[derive(Copy, Clone, Hash, Eq, PartialEq, Debug, Serialize, Deserialize)]
|
||||
pub enum CharacterAbilityType {
|
||||
@ -886,18 +886,72 @@ impl CharacterAbility {
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use = "method returns new ability and doesn't mutate the original value"]
|
||||
#[warn(clippy::pedantic)]
|
||||
pub fn adjusted_by_skills(
|
||||
mut self,
|
||||
skillset: &skills::SkillSet,
|
||||
tool: Option<ToolKind>,
|
||||
) -> Self {
|
||||
use skills::Skill::{self, *};
|
||||
use CharacterAbility::*;
|
||||
use skills::Skill;
|
||||
match tool {
|
||||
Some(ToolKind::Sword) => {
|
||||
use skills::SwordSkill::*;
|
||||
Some(ToolKind::Sword) => self.adjusted_by_sword_skills(skillset),
|
||||
Some(ToolKind::Axe) => self.adjusted_by_axe_skills(skillset),
|
||||
Some(ToolKind::Hammer) => self.adjusted_by_hammer_skills(skillset),
|
||||
Some(ToolKind::Bow) => self.adjusted_by_bow_skills(skillset),
|
||||
Some(ToolKind::Staff) => self.adjusted_by_staff_skills(skillset),
|
||||
Some(ToolKind::Sceptre) => self.adjusted_by_sceptre_skills(skillset),
|
||||
Some(ToolKind::Pick) => {
|
||||
use skills::MiningSkill::Speed;
|
||||
|
||||
if let CharacterAbility::BasicMelee {
|
||||
ref mut buildup_duration,
|
||||
ref mut swing_duration,
|
||||
ref mut recover_duration,
|
||||
..
|
||||
} = self
|
||||
{
|
||||
if let Ok(Some(level)) = skillset.skill_level(Skill::Pick(Speed)) {
|
||||
let speed = 1.1_f32.powi(level.into());
|
||||
*buildup_duration /= speed;
|
||||
*swing_duration /= speed;
|
||||
*recover_duration /= speed;
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {
|
||||
if let CharacterAbility::Roll {
|
||||
ref mut energy_cost,
|
||||
ref mut roll_strength,
|
||||
ref mut movement_duration,
|
||||
..
|
||||
} = self
|
||||
{
|
||||
use skills::RollSkill::{Cost, Duration, Strength};
|
||||
|
||||
if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Cost)) {
|
||||
*energy_cost *= 0.9_f32.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Strength)) {
|
||||
*roll_strength *= 1.1_f32.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Duration)) {
|
||||
*movement_duration *= 1.1_f32.powi(level.into());
|
||||
}
|
||||
}
|
||||
},
|
||||
Some(_) => {},
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
#[warn(clippy::pedantic)]
|
||||
fn adjusted_by_sword_skills(&mut self, skillset: &skills::SkillSet) {
|
||||
#![allow(clippy::enum_glob_use)]
|
||||
use skills::{Skill::Sword, SwordSkill::*};
|
||||
|
||||
match self {
|
||||
ComboMelee {
|
||||
CharacterAbility::ComboMelee {
|
||||
ref mut is_interruptible,
|
||||
ref mut speed_increase,
|
||||
ref mut max_speed_increase,
|
||||
@ -907,36 +961,30 @@ impl CharacterAbility {
|
||||
..
|
||||
} => {
|
||||
*is_interruptible = skillset.has_skill(Sword(InterruptingAttacks));
|
||||
let speed_segments = Sword(TsSpeed).max_level().map_or(1, |l| l + 1) as f32;
|
||||
let speed_level = if skillset.has_skill(Sword(TsCombo)) {
|
||||
skillset
|
||||
.skill_level(Sword(TsSpeed))
|
||||
.unwrap_or(None)
|
||||
.map_or(1, |l| l + 1) as f32
|
||||
|
||||
if skillset.has_skill(Sword(TsCombo)) {
|
||||
let speed_segments = Sword(TsSpeed)
|
||||
.max_level()
|
||||
.map_or(1.0, |l| f32::from(l) + 1.0);
|
||||
let speed_level = f32::from(skillset.skill_level_or(Sword(TsSpeed), 0));
|
||||
*speed_increase = (speed_level + 1.0) / speed_segments;
|
||||
*max_speed_increase = (speed_level + 1.0) / speed_segments;
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
{
|
||||
*speed_increase *= speed_level / speed_segments;
|
||||
*max_speed_increase *= speed_level / speed_segments;
|
||||
*speed_increase = 0.0;
|
||||
*max_speed_increase = 0.0;
|
||||
}
|
||||
let energy_level =
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sword(TsRegen)) {
|
||||
level
|
||||
} else {
|
||||
0
|
||||
};
|
||||
*max_energy_gain = *max_energy_gain
|
||||
* ((energy_level + 1) * stage_data.len() as u16 - 1) as f32
|
||||
/ (Sword(TsRegen).max_level().unwrap() + 1) as f32
|
||||
* (stage_data.len() - 1) as f32;
|
||||
*scales_from_combo = skillset
|
||||
.skill_level(Sword(TsDamage))
|
||||
.unwrap_or(None)
|
||||
.unwrap_or(0)
|
||||
.into();
|
||||
|
||||
let energy_level = skillset.skill_level_or(Sword(TsRegen), 0);
|
||||
|
||||
let stages = u16::try_from(stage_data.len())
|
||||
.expect("number of stages can't be more than u16");
|
||||
|
||||
*max_energy_gain *= f32::from((energy_level + 1) * stages - 1)
|
||||
* f32::from(stages - 1)
|
||||
/ f32::from(Sword(TsRegen).max_level().unwrap() + 1);
|
||||
*scales_from_combo = skillset.skill_level_or(Sword(TsDamage), 0).into();
|
||||
},
|
||||
DashMelee {
|
||||
CharacterAbility::DashMelee {
|
||||
ref mut is_interruptible,
|
||||
ref mut energy_cost,
|
||||
ref mut energy_drain,
|
||||
@ -964,7 +1012,7 @@ impl CharacterAbility {
|
||||
}
|
||||
*charge_through = skillset.has_skill(Sword(DInfinite));
|
||||
},
|
||||
SpinMelee {
|
||||
CharacterAbility::SpinMelee {
|
||||
ref mut is_interruptible,
|
||||
ref mut base_damage,
|
||||
ref mut swing_duration,
|
||||
@ -982,19 +1030,20 @@ impl CharacterAbility {
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sword(SCost)) {
|
||||
*energy_cost *= 0.75_f32.powi(level.into());
|
||||
}
|
||||
*num_spins = skillset
|
||||
.skill_level(Sword(SSpins))
|
||||
.unwrap_or(None)
|
||||
.unwrap_or(0) as u32
|
||||
+ 1;
|
||||
let spin_level = skillset.skill_level_or(Sword(SSpins), 0);
|
||||
*num_spins = u32::from(spin_level) + 1;
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
},
|
||||
Some(ToolKind::Axe) => {
|
||||
use skills::AxeSkill::*;
|
||||
}
|
||||
|
||||
#[warn(clippy::pedantic)]
|
||||
fn adjusted_by_axe_skills(&mut self, skillset: &skills::SkillSet) {
|
||||
#![allow(clippy::enum_glob_use)]
|
||||
use skills::{AxeSkill::*, Skill::Axe};
|
||||
|
||||
match self {
|
||||
ComboMelee {
|
||||
CharacterAbility::ComboMelee {
|
||||
ref mut speed_increase,
|
||||
ref mut max_speed_increase,
|
||||
ref mut stage_data,
|
||||
@ -1005,32 +1054,22 @@ impl CharacterAbility {
|
||||
if !skillset.has_skill(Axe(DsCombo)) {
|
||||
stage_data.pop();
|
||||
}
|
||||
let speed_segments = Axe(DsSpeed).max_level().unwrap_or(1) as f32;
|
||||
let speed_level = skillset
|
||||
.skill_level(Axe(DsSpeed))
|
||||
.unwrap_or(None)
|
||||
.unwrap_or(0) as f32;
|
||||
{
|
||||
let speed_segments = f32::from(Axe(DsSpeed).max_level().unwrap_or(1));
|
||||
let speed_level = f32::from(skillset.skill_level_or(Axe(DsSpeed), 0));
|
||||
*speed_increase *= speed_level / speed_segments;
|
||||
*max_speed_increase *= speed_level / speed_segments;
|
||||
}
|
||||
let energy_level =
|
||||
if let Ok(Some(level)) = skillset.skill_level(Axe(DsRegen)) {
|
||||
level
|
||||
} else {
|
||||
0
|
||||
};
|
||||
*max_energy_gain = *max_energy_gain
|
||||
* ((energy_level + 1) * stage_data.len() as u16 - 1).max(1) as f32
|
||||
/ (Axe(DsRegen).max_level().unwrap() + 1) as f32
|
||||
* (stage_data.len() - 1).max(1) as f32;
|
||||
*scales_from_combo = skillset
|
||||
.skill_level(Axe(DsDamage))
|
||||
.unwrap_or(None)
|
||||
.unwrap_or(0)
|
||||
.into();
|
||||
|
||||
let energy_level = skillset.skill_level_or(Axe(DsRegen), 0);
|
||||
|
||||
let stages = u16::try_from(stage_data.len())
|
||||
.expect("number of stages can't be more than u16");
|
||||
|
||||
*max_energy_gain *= f32::from((energy_level + 1) * stages - 1).max(1.0)
|
||||
* f32::from(stages - 1).max(1.0)
|
||||
/ f32::from(Axe(DsRegen).max_level().unwrap() + 1);
|
||||
*scales_from_combo = skillset.skill_level_or(Axe(DsDamage), 0).into();
|
||||
},
|
||||
SpinMelee {
|
||||
CharacterAbility::SpinMelee {
|
||||
ref mut base_damage,
|
||||
ref mut swing_duration,
|
||||
ref mut energy_cost,
|
||||
@ -1054,7 +1093,7 @@ impl CharacterAbility {
|
||||
*energy_cost *= 0.75_f32.powi(level.into());
|
||||
}
|
||||
},
|
||||
LeapMelee {
|
||||
CharacterAbility::LeapMelee {
|
||||
ref mut base_damage,
|
||||
ref mut knockback,
|
||||
ref mut energy_cost,
|
||||
@ -1078,11 +1117,14 @@ impl CharacterAbility {
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
},
|
||||
Some(ToolKind::Hammer) => {
|
||||
use skills::HammerSkill::*;
|
||||
}
|
||||
|
||||
#[warn(clippy::pedantic)]
|
||||
fn adjusted_by_hammer_skills(&mut self, skillset: &skills::SkillSet) {
|
||||
#![allow(clippy::enum_glob_use)]
|
||||
use skills::{HammerSkill::*, Skill::Hammer};
|
||||
match self {
|
||||
ComboMelee {
|
||||
CharacterAbility::ComboMelee {
|
||||
ref mut speed_increase,
|
||||
ref mut max_speed_increase,
|
||||
ref mut stage_data,
|
||||
@ -1094,34 +1136,24 @@ impl CharacterAbility {
|
||||
*stage_data = (*stage_data)
|
||||
.iter()
|
||||
.map(|s| s.modify_strike(1.5_f32.powi(level.into())))
|
||||
.collect::<Vec<combo_melee::Stage<f32>>>();
|
||||
.collect::<Vec<_>>();
|
||||
}
|
||||
let speed_segments = Hammer(SsSpeed).max_level().unwrap_or(1) as f32;
|
||||
let speed_level = skillset
|
||||
.skill_level(Hammer(SsSpeed))
|
||||
.unwrap_or(None)
|
||||
.unwrap_or(0) as f32;
|
||||
{
|
||||
let speed_segments = f32::from(Hammer(SsSpeed).max_level().unwrap_or(1));
|
||||
let speed_level = f32::from(skillset.skill_level_or(Hammer(SsSpeed), 0));
|
||||
*speed_increase *= speed_level / speed_segments;
|
||||
*max_speed_increase *= speed_level / speed_segments;
|
||||
}
|
||||
let energy_level =
|
||||
if let Ok(Some(level)) = skillset.skill_level(Hammer(SsRegen)) {
|
||||
level
|
||||
} else {
|
||||
0
|
||||
};
|
||||
*max_energy_gain = *max_energy_gain
|
||||
* ((energy_level + 1) * stage_data.len() as u16) as f32
|
||||
/ ((Hammer(SsRegen).max_level().unwrap() + 1) * stage_data.len() as u16)
|
||||
as f32;
|
||||
*scales_from_combo = skillset
|
||||
.skill_level(Hammer(SsDamage))
|
||||
.unwrap_or(None)
|
||||
.unwrap_or(0)
|
||||
.into();
|
||||
|
||||
let energy_level = skillset.skill_level_or(Hammer(SsRegen), 0);
|
||||
|
||||
let stages = u16::try_from(stage_data.len())
|
||||
.expect("number of stages can't be more than u16");
|
||||
|
||||
*max_energy_gain *= f32::from((energy_level + 1) * stages)
|
||||
/ f32::from((Hammer(SsRegen).max_level().unwrap() + 1) * stages);
|
||||
|
||||
*scales_from_combo = skillset.skill_level_or(Hammer(SsDamage), 0).into();
|
||||
},
|
||||
ChargedMelee {
|
||||
CharacterAbility::ChargedMelee {
|
||||
ref mut scaled_damage,
|
||||
ref mut scaled_knockback,
|
||||
ref mut energy_drain,
|
||||
@ -1141,7 +1173,7 @@ impl CharacterAbility {
|
||||
*charge_duration /= 1.25_f32.powi(level.into());
|
||||
}
|
||||
},
|
||||
LeapMelee {
|
||||
CharacterAbility::LeapMelee {
|
||||
ref mut base_damage,
|
||||
ref mut knockback,
|
||||
ref mut energy_cost,
|
||||
@ -1164,16 +1196,20 @@ impl CharacterAbility {
|
||||
*vertical_leap_strength *= 1.25_f32.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Hammer(LRange)) {
|
||||
*range += 1.0 * level as f32;
|
||||
*range += 1.0 * f32::from(level);
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
},
|
||||
Some(ToolKind::Bow) => {
|
||||
use skills::BowSkill::*;
|
||||
}
|
||||
|
||||
#[warn(clippy::pedantic)]
|
||||
fn adjusted_by_bow_skills(&mut self, skillset: &skills::SkillSet) {
|
||||
#![allow(clippy::enum_glob_use)]
|
||||
use skills::{BowSkill::*, Skill::Bow};
|
||||
|
||||
match self {
|
||||
ChargedRanged {
|
||||
CharacterAbility::ChargedRanged {
|
||||
ref mut initial_damage,
|
||||
ref mut scaled_damage,
|
||||
ref mut initial_regen,
|
||||
@ -1213,7 +1249,7 @@ impl CharacterAbility {
|
||||
*move_speed *= 1.1_f32.powi(level.into());
|
||||
}
|
||||
},
|
||||
RepeaterRanged {
|
||||
CharacterAbility::RepeaterRanged {
|
||||
ref mut energy_cost,
|
||||
ref mut projectile,
|
||||
ref mut max_speed,
|
||||
@ -1234,7 +1270,7 @@ impl CharacterAbility {
|
||||
*max_speed *= 1.2_f32.powi(level.into());
|
||||
}
|
||||
},
|
||||
BasicRanged {
|
||||
CharacterAbility::BasicRanged {
|
||||
ref mut projectile,
|
||||
ref mut energy_cost,
|
||||
ref mut num_projectiles,
|
||||
@ -1253,7 +1289,7 @@ impl CharacterAbility {
|
||||
*energy_cost *= 0.8_f32.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Bow(SArrows)) {
|
||||
*num_projectiles += level as u32;
|
||||
*num_projectiles += u32::from(level);
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Bow(SSpread)) {
|
||||
*projectile_spread *= 0.8_f32.powi(level.into());
|
||||
@ -1261,31 +1297,26 @@ impl CharacterAbility {
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
},
|
||||
Some(ToolKind::Staff) => {
|
||||
use skills::StaffSkill::*;
|
||||
}
|
||||
|
||||
#[warn(clippy::pedantic)]
|
||||
fn adjusted_by_staff_skills(&mut self, skillset: &skills::SkillSet) {
|
||||
#![allow(clippy::enum_glob_use)]
|
||||
use skills::{Skill::Staff, StaffSkill::*};
|
||||
|
||||
match self {
|
||||
BasicRanged {
|
||||
CharacterAbility::BasicRanged {
|
||||
ref mut projectile, ..
|
||||
} => {
|
||||
let damage_level = skillset
|
||||
.skill_level(Staff(BDamage))
|
||||
.unwrap_or(None)
|
||||
.unwrap_or(0);
|
||||
let regen_level = skillset
|
||||
.skill_level(Staff(BRegen))
|
||||
.unwrap_or(None)
|
||||
.unwrap_or(0);
|
||||
let range_level = skillset
|
||||
.skill_level(Staff(BRadius))
|
||||
.unwrap_or(None)
|
||||
.unwrap_or(0);
|
||||
let damage_level = skillset.skill_level_or(Staff(BDamage), 0);
|
||||
let regen_level = skillset.skill_level_or(Staff(BRegen), 0);
|
||||
let range_level = skillset.skill_level_or(Staff(BRadius), 0);
|
||||
let power = 1.2_f32.powi(damage_level.into());
|
||||
let regen = 1.2_f32.powi(regen_level.into());
|
||||
let range = 1.15_f32.powi(range_level.into());
|
||||
*projectile = projectile.modified_projectile(power, regen, range);
|
||||
},
|
||||
BasicBeam {
|
||||
CharacterAbility::BasicBeam {
|
||||
ref mut damage,
|
||||
ref mut range,
|
||||
ref mut energy_drain,
|
||||
@ -1310,7 +1341,7 @@ impl CharacterAbility {
|
||||
*beam_duration *= duration_mod;
|
||||
}
|
||||
},
|
||||
Shockwave {
|
||||
CharacterAbility::Shockwave {
|
||||
ref mut damage,
|
||||
ref mut knockback,
|
||||
ref mut shockwave_duration,
|
||||
@ -1332,11 +1363,14 @@ impl CharacterAbility {
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
},
|
||||
Some(ToolKind::Sceptre) => {
|
||||
use skills::SceptreSkill::*;
|
||||
}
|
||||
|
||||
#[warn(clippy::pedantic)]
|
||||
fn adjusted_by_sceptre_skills(&mut self, skillset: &skills::SkillSet) {
|
||||
#![allow(clippy::enum_glob_use)]
|
||||
use skills::{SceptreSkill::*, Skill::Sceptre};
|
||||
match self {
|
||||
BasicBeam {
|
||||
CharacterAbility::BasicBeam {
|
||||
ref mut damage,
|
||||
ref mut range,
|
||||
ref mut beam_duration,
|
||||
@ -1362,14 +1396,13 @@ impl CharacterAbility {
|
||||
*lifesteal *= 1.15_f32.powi(level.into());
|
||||
}
|
||||
},
|
||||
BasicAura {
|
||||
CharacterAbility::BasicAura {
|
||||
ref mut aura,
|
||||
ref mut range,
|
||||
ref mut energy_cost,
|
||||
ref specifier,
|
||||
specifier: aura::Specifier::WardingAura,
|
||||
..
|
||||
} => {
|
||||
if matches!(*specifier, aura::Specifier::WardingAura) {
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sceptre(AStrength)) {
|
||||
aura.strength *= 1.15_f32.powi(level.into());
|
||||
}
|
||||
@ -1382,7 +1415,14 @@ impl CharacterAbility {
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sceptre(ACost)) {
|
||||
*energy_cost *= 0.85_f32.powi(level.into());
|
||||
}
|
||||
} else if matches!(*specifier, aura::Specifier::HealingAura) {
|
||||
},
|
||||
CharacterAbility::BasicAura {
|
||||
ref mut aura,
|
||||
ref mut range,
|
||||
ref mut energy_cost,
|
||||
specifier: aura::Specifier::HealingAura,
|
||||
..
|
||||
} => {
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sceptre(HHeal)) {
|
||||
aura.strength *= 1.15_f32.powi(level.into());
|
||||
}
|
||||
@ -1395,51 +1435,9 @@ impl CharacterAbility {
|
||||
if let Ok(Some(level)) = skillset.skill_level(Sceptre(HCost)) {
|
||||
*energy_cost *= 0.85_f32.powi(level.into());
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
},
|
||||
Some(ToolKind::Pick) => {
|
||||
use skills::MiningSkill::*;
|
||||
if let BasicMelee {
|
||||
ref mut buildup_duration,
|
||||
ref mut swing_duration,
|
||||
ref mut recover_duration,
|
||||
..
|
||||
} = self
|
||||
{
|
||||
if let Ok(Some(level)) = skillset.skill_level(Pick(Speed)) {
|
||||
let speed = 1.1_f32.powi(level.into());
|
||||
*buildup_duration /= speed;
|
||||
*swing_duration /= speed;
|
||||
*recover_duration /= speed;
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {
|
||||
if let CharacterAbility::Roll {
|
||||
ref mut energy_cost,
|
||||
ref mut roll_strength,
|
||||
ref mut movement_duration,
|
||||
..
|
||||
} = self
|
||||
{
|
||||
use skills::RollSkill::*;
|
||||
if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Cost)) {
|
||||
*energy_cost *= 0.9_f32.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Strength)) {
|
||||
*roll_strength *= 1.1_f32.powi(level.into());
|
||||
}
|
||||
if let Ok(Some(level)) = skillset.skill_level(Skill::Roll(Duration)) {
|
||||
*movement_duration *= 1.1_f32.powi(level.into());
|
||||
}
|
||||
}
|
||||
},
|
||||
Some(_) => {},
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -956,6 +956,15 @@ impl SkillSet {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the level of the skill or passed value as default
|
||||
pub fn skill_level_or(&self, skill: Skill, default: u16) -> u16 {
|
||||
if let Ok(Some(level)) = self.skill_level(skill) {
|
||||
level
|
||||
} else {
|
||||
default
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks the next level of a skill
|
||||
fn next_skill_level(&self, skill: Skill) -> Option<u16> {
|
||||
if let Ok(level) = self.skill_level(skill) {
|
||||
|
Loading…
Reference in New Issue
Block a user