Split adjusted_by_skills by toolkind

This commit is contained in:
juliancoffee 2021-08-16 12:16:20 +03:00
parent a2e0426d45
commit 81bbc8c31f
2 changed files with 520 additions and 513 deletions

View File

@ -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
}
}

View File

@ -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) {