2022-01-18 01:41:24 +00:00
|
|
|
use crate::{
|
|
|
|
combat::{
|
2022-07-15 14:00:27 +00:00
|
|
|
Attack, AttackDamage, AttackEffect, CombatBuff, CombatBuffStrength, CombatEffect,
|
2022-01-18 01:41:24 +00:00
|
|
|
CombatRequirement, Damage, DamageKind, DamageSource, GroupTarget, Knockback, KnockbackDir,
|
|
|
|
},
|
|
|
|
comp::{
|
|
|
|
buff::BuffKind,
|
|
|
|
tool::{Stats, ToolKind},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
use common_base::dev_panic;
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use specs::{Component, VecStorage};
|
|
|
|
use vek::*;
|
|
|
|
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
|
|
pub struct Melee {
|
|
|
|
pub attack: Attack,
|
|
|
|
pub range: f32,
|
|
|
|
pub max_angle: f32,
|
|
|
|
pub applied: bool,
|
|
|
|
pub hit_count: u32,
|
2022-10-09 07:17:29 +00:00
|
|
|
pub multi_target: Option<MultiTarget>,
|
2022-01-18 01:41:24 +00:00
|
|
|
pub break_block: Option<(Vec3<i32>, Option<ToolKind>)>,
|
2023-04-24 01:31:29 +00:00
|
|
|
pub simultaneous_hits: u32,
|
2022-01-18 01:41:24 +00:00
|
|
|
}
|
|
|
|
|
2022-10-09 07:17:29 +00:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
pub enum MultiTarget {
|
|
|
|
Normal,
|
2022-10-23 17:10:37 +00:00
|
|
|
/// Applies scaling to the power of the attack based on how many consecutive
|
|
|
|
/// enemies have been hit. First enemy hit will be at a power of 1.0, second
|
|
|
|
/// enemy hit will be at a power of `1.0 + scaling`, nth enemy hit will be
|
|
|
|
/// at a power of `1.0 + (n - 1) * scaling`.
|
2022-10-09 07:17:29 +00:00
|
|
|
Scaling(f32),
|
|
|
|
}
|
|
|
|
|
2022-01-18 01:41:24 +00:00
|
|
|
impl Melee {
|
|
|
|
#[must_use]
|
|
|
|
pub fn with_block_breaking(
|
|
|
|
mut self,
|
|
|
|
break_block: Option<(Vec3<i32>, Option<ToolKind>)>,
|
|
|
|
) -> Self {
|
|
|
|
self.break_block = break_block;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Component for Melee {
|
|
|
|
type Storage = VecStorage<Self>;
|
|
|
|
}
|
|
|
|
|
2023-04-24 01:31:29 +00:00
|
|
|
fn default_simultaneous_hits() -> u32 { 1 }
|
2023-05-14 22:07:45 +00:00
|
|
|
fn default_combo_gain() -> i32 { 1 }
|
2023-04-24 01:31:29 +00:00
|
|
|
|
2024-01-20 17:32:29 +00:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
pub struct Scaled {
|
|
|
|
pub kind: MeleeConstructorKind,
|
|
|
|
#[serde(default)]
|
|
|
|
pub range: f32,
|
|
|
|
#[serde(default)]
|
|
|
|
pub angle: f32,
|
|
|
|
}
|
|
|
|
|
2022-01-18 01:41:24 +00:00
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
2022-03-05 06:35:57 +00:00
|
|
|
#[serde(deny_unknown_fields)]
|
2022-01-18 01:41:24 +00:00
|
|
|
pub struct MeleeConstructor {
|
|
|
|
pub kind: MeleeConstructorKind,
|
2023-04-06 19:48:23 +00:00
|
|
|
/// This multiplied by a fraction is added to what is specified in `kind`.
|
|
|
|
///
|
|
|
|
/// Note, that this must be the same variant as what is specified in `kind`.
|
2024-01-20 17:32:29 +00:00
|
|
|
pub scaled: Option<Scaled>,
|
2022-01-18 01:41:24 +00:00
|
|
|
pub range: f32,
|
|
|
|
pub angle: f32,
|
2022-10-09 07:17:29 +00:00
|
|
|
pub multi_target: Option<MultiTarget>,
|
2022-01-18 01:41:24 +00:00
|
|
|
pub damage_effect: Option<CombatEffect>,
|
2023-04-24 01:31:29 +00:00
|
|
|
#[serde(default = "default_simultaneous_hits")]
|
|
|
|
pub simultaneous_hits: u32,
|
2023-05-14 22:07:45 +00:00
|
|
|
#[serde(default = "default_combo_gain")]
|
|
|
|
pub combo_gain: i32,
|
2022-01-18 01:41:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl MeleeConstructor {
|
2023-11-11 19:20:38 +00:00
|
|
|
pub fn create_melee(self, precision_mult: f32, tool_stats: Stats) -> Melee {
|
2022-01-18 01:41:24 +00:00
|
|
|
use MeleeConstructorKind::*;
|
|
|
|
if self.scaled.is_some() {
|
|
|
|
dev_panic!(
|
|
|
|
"Attempted to create a melee attack that had a provided scaled value without \
|
|
|
|
scaling the melee attack."
|
|
|
|
)
|
|
|
|
}
|
2022-04-18 14:41:49 +00:00
|
|
|
let instance = rand::random();
|
2022-01-18 01:41:24 +00:00
|
|
|
let attack = match self.kind {
|
|
|
|
Slash {
|
|
|
|
damage,
|
|
|
|
poise,
|
|
|
|
knockback,
|
|
|
|
energy_regen,
|
|
|
|
} => {
|
|
|
|
let energy = AttackEffect::new(None, CombatEffect::EnergyReward(energy_regen))
|
|
|
|
.with_requirement(CombatRequirement::AnyDamage);
|
|
|
|
let buff = CombatEffect::Buff(CombatBuff {
|
|
|
|
kind: BuffKind::Bleeding,
|
|
|
|
dur_secs: 10.0,
|
2023-02-14 02:43:52 +00:00
|
|
|
strength: CombatBuffStrength::DamageFraction(0.1),
|
2022-01-18 01:41:24 +00:00
|
|
|
chance: 0.1,
|
2023-02-14 02:43:52 +00:00
|
|
|
})
|
|
|
|
.adjusted_by_stats(tool_stats);
|
2022-01-18 01:41:24 +00:00
|
|
|
let mut damage = AttackDamage::new(
|
|
|
|
Damage {
|
|
|
|
source: DamageSource::Melee,
|
|
|
|
kind: DamageKind::Slashing,
|
|
|
|
value: damage,
|
|
|
|
},
|
|
|
|
Some(GroupTarget::OutOfGroup),
|
2022-04-18 14:41:49 +00:00
|
|
|
instance,
|
2022-01-18 01:41:24 +00:00
|
|
|
)
|
|
|
|
.with_effect(buff);
|
|
|
|
|
|
|
|
if let Some(damage_effect) = self.damage_effect {
|
|
|
|
damage = damage.with_effect(damage_effect);
|
|
|
|
}
|
|
|
|
|
|
|
|
let poise =
|
|
|
|
AttackEffect::new(Some(GroupTarget::OutOfGroup), CombatEffect::Poise(poise))
|
|
|
|
.with_requirement(CombatRequirement::AnyDamage);
|
|
|
|
let knockback = AttackEffect::new(
|
|
|
|
Some(GroupTarget::OutOfGroup),
|
|
|
|
CombatEffect::Knockback(Knockback {
|
|
|
|
strength: knockback,
|
|
|
|
direction: KnockbackDir::Away,
|
2023-02-14 02:43:52 +00:00
|
|
|
})
|
|
|
|
.adjusted_by_stats(tool_stats),
|
2022-01-18 01:41:24 +00:00
|
|
|
)
|
|
|
|
.with_requirement(CombatRequirement::AnyDamage);
|
|
|
|
|
|
|
|
Attack::default()
|
|
|
|
.with_damage(damage)
|
2023-11-11 19:20:38 +00:00
|
|
|
.with_precision(precision_mult)
|
2022-01-18 01:41:24 +00:00
|
|
|
.with_effect(energy)
|
|
|
|
.with_effect(poise)
|
|
|
|
.with_effect(knockback)
|
2023-05-14 22:07:45 +00:00
|
|
|
.with_combo(self.combo_gain)
|
2022-01-18 01:41:24 +00:00
|
|
|
},
|
|
|
|
Stab {
|
|
|
|
damage,
|
|
|
|
poise,
|
|
|
|
knockback,
|
|
|
|
energy_regen,
|
|
|
|
} => {
|
|
|
|
let energy = AttackEffect::new(None, CombatEffect::EnergyReward(energy_regen))
|
|
|
|
.with_requirement(CombatRequirement::AnyDamage);
|
|
|
|
let buff = CombatEffect::Buff(CombatBuff {
|
|
|
|
kind: BuffKind::Bleeding,
|
|
|
|
dur_secs: 5.0,
|
2023-02-14 02:43:52 +00:00
|
|
|
strength: CombatBuffStrength::DamageFraction(0.05),
|
2022-01-18 01:41:24 +00:00
|
|
|
chance: 0.1,
|
2023-02-14 02:43:52 +00:00
|
|
|
})
|
|
|
|
.adjusted_by_stats(tool_stats);
|
2022-01-18 01:41:24 +00:00
|
|
|
let mut damage = AttackDamage::new(
|
|
|
|
Damage {
|
|
|
|
source: DamageSource::Melee,
|
|
|
|
kind: DamageKind::Piercing,
|
|
|
|
value: damage,
|
|
|
|
},
|
|
|
|
Some(GroupTarget::OutOfGroup),
|
2022-04-18 14:41:49 +00:00
|
|
|
instance,
|
2022-01-18 01:41:24 +00:00
|
|
|
)
|
|
|
|
.with_effect(buff);
|
|
|
|
|
|
|
|
if let Some(damage_effect) = self.damage_effect {
|
|
|
|
damage = damage.with_effect(damage_effect);
|
|
|
|
}
|
|
|
|
|
|
|
|
let poise =
|
|
|
|
AttackEffect::new(Some(GroupTarget::OutOfGroup), CombatEffect::Poise(poise))
|
|
|
|
.with_requirement(CombatRequirement::AnyDamage);
|
|
|
|
let knockback = AttackEffect::new(
|
|
|
|
Some(GroupTarget::OutOfGroup),
|
|
|
|
CombatEffect::Knockback(Knockback {
|
|
|
|
strength: knockback,
|
|
|
|
direction: KnockbackDir::Away,
|
2023-02-14 02:43:52 +00:00
|
|
|
})
|
|
|
|
.adjusted_by_stats(tool_stats),
|
2022-01-18 01:41:24 +00:00
|
|
|
)
|
|
|
|
.with_requirement(CombatRequirement::AnyDamage);
|
|
|
|
|
|
|
|
Attack::default()
|
|
|
|
.with_damage(damage)
|
2023-11-11 19:20:38 +00:00
|
|
|
.with_precision(precision_mult)
|
2022-01-18 01:41:24 +00:00
|
|
|
.with_effect(energy)
|
|
|
|
.with_effect(poise)
|
|
|
|
.with_effect(knockback)
|
2023-05-14 22:07:45 +00:00
|
|
|
.with_combo(self.combo_gain)
|
2022-01-18 01:41:24 +00:00
|
|
|
},
|
|
|
|
Bash {
|
|
|
|
damage,
|
|
|
|
poise,
|
|
|
|
knockback,
|
|
|
|
energy_regen,
|
|
|
|
} => {
|
|
|
|
let energy = AttackEffect::new(None, CombatEffect::EnergyReward(energy_regen))
|
|
|
|
.with_requirement(CombatRequirement::AnyDamage);
|
|
|
|
let mut damage = AttackDamage::new(
|
|
|
|
Damage {
|
|
|
|
source: DamageSource::Melee,
|
|
|
|
kind: DamageKind::Crushing,
|
|
|
|
value: damage,
|
|
|
|
},
|
|
|
|
Some(GroupTarget::OutOfGroup),
|
2022-04-18 14:41:49 +00:00
|
|
|
instance,
|
2022-01-18 01:41:24 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
if let Some(damage_effect) = self.damage_effect {
|
|
|
|
damage = damage.with_effect(damage_effect);
|
|
|
|
}
|
|
|
|
|
|
|
|
let poise =
|
|
|
|
AttackEffect::new(Some(GroupTarget::OutOfGroup), CombatEffect::Poise(poise))
|
|
|
|
.with_requirement(CombatRequirement::AnyDamage);
|
|
|
|
let knockback = AttackEffect::new(
|
|
|
|
Some(GroupTarget::OutOfGroup),
|
|
|
|
CombatEffect::Knockback(Knockback {
|
|
|
|
strength: knockback,
|
|
|
|
direction: KnockbackDir::Away,
|
2023-02-14 02:43:52 +00:00
|
|
|
})
|
|
|
|
.adjusted_by_stats(tool_stats),
|
2022-01-18 01:41:24 +00:00
|
|
|
)
|
|
|
|
.with_requirement(CombatRequirement::AnyDamage);
|
|
|
|
|
|
|
|
Attack::default()
|
|
|
|
.with_damage(damage)
|
2023-11-11 19:20:38 +00:00
|
|
|
.with_precision(precision_mult)
|
2022-01-18 01:41:24 +00:00
|
|
|
.with_effect(energy)
|
|
|
|
.with_effect(poise)
|
|
|
|
.with_effect(knockback)
|
2023-05-14 22:07:45 +00:00
|
|
|
.with_combo(self.combo_gain)
|
2022-01-18 01:41:24 +00:00
|
|
|
},
|
2023-05-27 22:00:04 +00:00
|
|
|
Hook {
|
|
|
|
damage,
|
|
|
|
poise,
|
|
|
|
pull,
|
|
|
|
} => {
|
|
|
|
let buff = CombatEffect::Buff(CombatBuff {
|
|
|
|
kind: BuffKind::Bleeding,
|
|
|
|
dur_secs: 5.0,
|
|
|
|
strength: CombatBuffStrength::DamageFraction(0.2),
|
|
|
|
chance: 0.1,
|
|
|
|
})
|
|
|
|
.adjusted_by_stats(tool_stats);
|
|
|
|
let mut damage = AttackDamage::new(
|
|
|
|
Damage {
|
|
|
|
source: DamageSource::Melee,
|
|
|
|
kind: DamageKind::Piercing,
|
|
|
|
value: damage,
|
|
|
|
},
|
|
|
|
Some(GroupTarget::OutOfGroup),
|
|
|
|
instance,
|
|
|
|
)
|
|
|
|
.with_effect(buff);
|
|
|
|
|
|
|
|
if let Some(damage_effect) = self.damage_effect {
|
|
|
|
damage = damage.with_effect(damage_effect);
|
|
|
|
}
|
|
|
|
|
|
|
|
let poise =
|
|
|
|
AttackEffect::new(Some(GroupTarget::OutOfGroup), CombatEffect::Poise(poise))
|
|
|
|
.with_requirement(CombatRequirement::AnyDamage);
|
|
|
|
let knockback = AttackEffect::new(
|
|
|
|
Some(GroupTarget::OutOfGroup),
|
|
|
|
CombatEffect::Knockback(Knockback {
|
|
|
|
strength: pull,
|
|
|
|
direction: KnockbackDir::Towards,
|
|
|
|
})
|
|
|
|
.adjusted_by_stats(tool_stats),
|
|
|
|
)
|
|
|
|
.with_requirement(CombatRequirement::AnyDamage);
|
|
|
|
|
|
|
|
Attack::default()
|
|
|
|
.with_damage(damage)
|
2023-11-11 19:20:38 +00:00
|
|
|
.with_precision(precision_mult)
|
2023-05-27 22:00:04 +00:00
|
|
|
.with_effect(poise)
|
|
|
|
.with_effect(knockback)
|
|
|
|
.with_combo(self.combo_gain)
|
|
|
|
},
|
2022-01-18 01:41:24 +00:00
|
|
|
NecroticVortex {
|
|
|
|
damage,
|
|
|
|
pull,
|
|
|
|
lifesteal,
|
|
|
|
} => {
|
|
|
|
let lifesteal = CombatEffect::Lifesteal(lifesteal);
|
|
|
|
|
|
|
|
let mut damage = AttackDamage::new(
|
|
|
|
Damage {
|
|
|
|
source: DamageSource::Melee,
|
|
|
|
kind: DamageKind::Energy,
|
|
|
|
value: damage,
|
|
|
|
},
|
|
|
|
None,
|
2022-04-18 14:41:49 +00:00
|
|
|
instance,
|
2022-01-18 01:41:24 +00:00
|
|
|
)
|
|
|
|
.with_effect(lifesteal);
|
|
|
|
|
|
|
|
if let Some(damage_effect) = self.damage_effect {
|
|
|
|
damage = damage.with_effect(damage_effect);
|
|
|
|
}
|
|
|
|
|
|
|
|
let knockback = AttackEffect::new(
|
|
|
|
Some(GroupTarget::OutOfGroup),
|
|
|
|
CombatEffect::Knockback(Knockback {
|
|
|
|
strength: pull,
|
|
|
|
direction: KnockbackDir::Towards,
|
2023-02-14 02:43:52 +00:00
|
|
|
})
|
|
|
|
.adjusted_by_stats(tool_stats),
|
2022-01-18 01:41:24 +00:00
|
|
|
)
|
|
|
|
.with_requirement(CombatRequirement::AnyDamage);
|
|
|
|
|
|
|
|
Attack::default()
|
|
|
|
.with_damage(damage)
|
2023-11-11 19:20:38 +00:00
|
|
|
.with_precision(precision_mult)
|
2022-01-18 01:41:24 +00:00
|
|
|
.with_effect(knockback)
|
2023-05-14 22:07:45 +00:00
|
|
|
.with_combo(self.combo_gain)
|
2022-01-18 01:41:24 +00:00
|
|
|
},
|
2022-02-02 05:17:06 +00:00
|
|
|
SonicWave {
|
|
|
|
damage,
|
|
|
|
poise,
|
|
|
|
knockback,
|
|
|
|
} => {
|
|
|
|
let mut damage = AttackDamage::new(
|
|
|
|
Damage {
|
|
|
|
source: DamageSource::Melee,
|
|
|
|
kind: DamageKind::Energy,
|
|
|
|
value: damage,
|
|
|
|
},
|
|
|
|
Some(GroupTarget::OutOfGroup),
|
2022-04-18 14:41:49 +00:00
|
|
|
instance,
|
2022-02-02 05:17:06 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
if let Some(damage_effect) = self.damage_effect {
|
|
|
|
damage = damage.with_effect(damage_effect);
|
|
|
|
}
|
|
|
|
|
|
|
|
let poise =
|
|
|
|
AttackEffect::new(Some(GroupTarget::OutOfGroup), CombatEffect::Poise(poise))
|
|
|
|
.with_requirement(CombatRequirement::AnyDamage);
|
|
|
|
let knockback = AttackEffect::new(
|
|
|
|
Some(GroupTarget::OutOfGroup),
|
|
|
|
CombatEffect::Knockback(Knockback {
|
|
|
|
strength: knockback,
|
|
|
|
direction: KnockbackDir::Away,
|
2023-02-14 02:43:52 +00:00
|
|
|
})
|
|
|
|
.adjusted_by_stats(tool_stats),
|
2022-02-02 05:17:06 +00:00
|
|
|
)
|
|
|
|
.with_requirement(CombatRequirement::AnyDamage);
|
|
|
|
|
|
|
|
Attack::default()
|
|
|
|
.with_damage(damage)
|
2023-11-11 19:20:38 +00:00
|
|
|
.with_precision(precision_mult)
|
2022-02-02 05:17:06 +00:00
|
|
|
.with_effect(poise)
|
|
|
|
.with_effect(knockback)
|
2023-05-14 22:07:45 +00:00
|
|
|
.with_combo(self.combo_gain)
|
2022-02-02 05:17:06 +00:00
|
|
|
},
|
2022-01-18 01:41:24 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Melee {
|
|
|
|
attack,
|
|
|
|
range: self.range,
|
|
|
|
max_angle: self.angle.to_radians(),
|
|
|
|
applied: false,
|
|
|
|
hit_count: 0,
|
2022-02-17 18:19:17 +00:00
|
|
|
multi_target: self.multi_target,
|
2022-01-18 01:41:24 +00:00
|
|
|
break_block: None,
|
2023-04-24 01:31:29 +00:00
|
|
|
simultaneous_hits: self.simultaneous_hits,
|
2022-01-18 01:41:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[must_use]
|
|
|
|
pub fn handle_scaling(mut self, scaling: f32) -> Self {
|
|
|
|
let scale_values = |a, b| a + b * scaling;
|
|
|
|
|
|
|
|
if let Some(max_scale) = self.scaled {
|
|
|
|
use MeleeConstructorKind::*;
|
2024-01-20 17:32:29 +00:00
|
|
|
let scaled = match (self.kind, max_scale.kind) {
|
2022-01-18 01:41:24 +00:00
|
|
|
(
|
|
|
|
Slash {
|
|
|
|
damage: a_damage,
|
|
|
|
poise: a_poise,
|
|
|
|
knockback: a_knockback,
|
|
|
|
energy_regen: a_energy_regen,
|
|
|
|
},
|
|
|
|
Slash {
|
|
|
|
damage: b_damage,
|
|
|
|
poise: b_poise,
|
|
|
|
knockback: b_knockback,
|
|
|
|
energy_regen: b_energy_regen,
|
|
|
|
},
|
|
|
|
) => Slash {
|
|
|
|
damage: scale_values(a_damage, b_damage),
|
|
|
|
poise: scale_values(a_poise, b_poise),
|
|
|
|
knockback: scale_values(a_knockback, b_knockback),
|
|
|
|
energy_regen: scale_values(a_energy_regen, b_energy_regen),
|
|
|
|
},
|
|
|
|
(
|
|
|
|
Stab {
|
|
|
|
damage: a_damage,
|
|
|
|
poise: a_poise,
|
|
|
|
knockback: a_knockback,
|
|
|
|
energy_regen: a_energy_regen,
|
|
|
|
},
|
|
|
|
Stab {
|
|
|
|
damage: b_damage,
|
|
|
|
poise: b_poise,
|
|
|
|
knockback: b_knockback,
|
|
|
|
energy_regen: b_energy_regen,
|
|
|
|
},
|
|
|
|
) => Stab {
|
|
|
|
damage: scale_values(a_damage, b_damage),
|
|
|
|
poise: scale_values(a_poise, b_poise),
|
|
|
|
knockback: scale_values(a_knockback, b_knockback),
|
|
|
|
energy_regen: scale_values(a_energy_regen, b_energy_regen),
|
|
|
|
},
|
|
|
|
(
|
|
|
|
Bash {
|
|
|
|
damage: a_damage,
|
|
|
|
poise: a_poise,
|
|
|
|
knockback: a_knockback,
|
|
|
|
energy_regen: a_energy_regen,
|
|
|
|
},
|
|
|
|
Bash {
|
|
|
|
damage: b_damage,
|
|
|
|
poise: b_poise,
|
|
|
|
knockback: b_knockback,
|
|
|
|
energy_regen: b_energy_regen,
|
|
|
|
},
|
|
|
|
) => Bash {
|
|
|
|
damage: scale_values(a_damage, b_damage),
|
|
|
|
poise: scale_values(a_poise, b_poise),
|
|
|
|
knockback: scale_values(a_knockback, b_knockback),
|
|
|
|
energy_regen: scale_values(a_energy_regen, b_energy_regen),
|
|
|
|
},
|
|
|
|
(
|
|
|
|
NecroticVortex {
|
|
|
|
damage: a_damage,
|
|
|
|
pull: a_pull,
|
|
|
|
lifesteal: a_lifesteal,
|
|
|
|
},
|
|
|
|
NecroticVortex {
|
|
|
|
damage: b_damage,
|
|
|
|
pull: b_pull,
|
|
|
|
lifesteal: b_lifesteal,
|
|
|
|
},
|
|
|
|
) => NecroticVortex {
|
|
|
|
damage: scale_values(a_damage, b_damage),
|
|
|
|
pull: scale_values(a_pull, b_pull),
|
|
|
|
lifesteal: scale_values(a_lifesteal, b_lifesteal),
|
|
|
|
},
|
2023-05-27 22:00:04 +00:00
|
|
|
(
|
|
|
|
Hook {
|
|
|
|
damage: a_damage,
|
|
|
|
poise: a_poise,
|
|
|
|
pull: a_pull,
|
|
|
|
},
|
|
|
|
Hook {
|
|
|
|
damage: b_damage,
|
|
|
|
poise: b_poise,
|
|
|
|
pull: b_pull,
|
|
|
|
},
|
|
|
|
) => Hook {
|
|
|
|
damage: scale_values(a_damage, b_damage),
|
|
|
|
poise: scale_values(a_poise, b_poise),
|
|
|
|
pull: scale_values(a_pull, b_pull),
|
|
|
|
},
|
2022-02-02 05:17:06 +00:00
|
|
|
(
|
|
|
|
SonicWave {
|
|
|
|
damage: a_damage,
|
|
|
|
poise: a_poise,
|
|
|
|
knockback: a_knockback,
|
|
|
|
},
|
|
|
|
SonicWave {
|
|
|
|
damage: b_damage,
|
|
|
|
poise: b_poise,
|
|
|
|
knockback: b_knockback,
|
|
|
|
},
|
|
|
|
) => SonicWave {
|
|
|
|
damage: scale_values(a_damage, b_damage),
|
|
|
|
poise: scale_values(a_poise, b_poise),
|
|
|
|
knockback: scale_values(a_knockback, b_knockback),
|
|
|
|
},
|
2022-01-18 01:41:24 +00:00
|
|
|
_ => {
|
|
|
|
dev_panic!(
|
|
|
|
"Attempted to scale on a melee attack between two different kinds of \
|
|
|
|
melee constructors."
|
|
|
|
);
|
|
|
|
self.kind
|
|
|
|
},
|
|
|
|
};
|
|
|
|
self.kind = scaled;
|
2024-01-20 17:32:29 +00:00
|
|
|
self.range = scale_values(self.range, max_scale.range);
|
|
|
|
self.angle = scale_values(self.angle, max_scale.angle);
|
2022-01-18 01:41:24 +00:00
|
|
|
self.scaled = None;
|
|
|
|
} else {
|
|
|
|
dev_panic!("Attempted to scale on a melee attack that had no provided scaling value.")
|
|
|
|
}
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
#[must_use]
|
2022-01-23 06:39:59 +00:00
|
|
|
pub fn adjusted_by_stats(mut self, stats: Stats) -> Self {
|
2022-01-18 01:41:24 +00:00
|
|
|
self.range *= stats.range;
|
2022-01-23 06:39:59 +00:00
|
|
|
self.kind = self.kind.adjusted_by_stats(stats);
|
2022-01-18 01:41:24 +00:00
|
|
|
if let Some(ref mut scaled) = &mut self.scaled {
|
2024-01-20 17:32:29 +00:00
|
|
|
scaled.kind = scaled.kind.adjusted_by_stats(stats);
|
|
|
|
scaled.range *= stats.range;
|
2022-01-18 01:41:24 +00:00
|
|
|
}
|
2023-02-14 02:43:52 +00:00
|
|
|
self.damage_effect = self.damage_effect.map(|de| de.adjusted_by_stats(stats));
|
2022-01-18 01:41:24 +00:00
|
|
|
self
|
|
|
|
}
|
2023-05-14 22:07:45 +00:00
|
|
|
|
|
|
|
#[must_use]
|
|
|
|
pub fn with_combo(mut self, combo: i32) -> Self {
|
|
|
|
self.combo_gain = combo;
|
|
|
|
self
|
|
|
|
}
|
2022-01-18 01:41:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
// TODO: Get someone not me to name these variants
|
|
|
|
pub enum MeleeConstructorKind {
|
|
|
|
Slash {
|
|
|
|
damage: f32,
|
|
|
|
poise: f32,
|
|
|
|
knockback: f32,
|
|
|
|
energy_regen: f32,
|
|
|
|
},
|
|
|
|
Stab {
|
|
|
|
damage: f32,
|
|
|
|
poise: f32,
|
|
|
|
knockback: f32,
|
|
|
|
energy_regen: f32,
|
|
|
|
},
|
|
|
|
Bash {
|
|
|
|
damage: f32,
|
|
|
|
poise: f32,
|
|
|
|
knockback: f32,
|
|
|
|
energy_regen: f32,
|
|
|
|
},
|
2023-05-27 22:00:04 +00:00
|
|
|
Hook {
|
|
|
|
damage: f32,
|
|
|
|
poise: f32,
|
|
|
|
pull: f32,
|
|
|
|
},
|
2022-01-18 01:41:24 +00:00
|
|
|
NecroticVortex {
|
|
|
|
damage: f32,
|
|
|
|
pull: f32,
|
|
|
|
lifesteal: f32,
|
|
|
|
},
|
2022-02-02 05:17:06 +00:00
|
|
|
SonicWave {
|
|
|
|
damage: f32,
|
|
|
|
poise: f32,
|
|
|
|
knockback: f32,
|
|
|
|
},
|
2022-01-18 01:41:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl MeleeConstructorKind {
|
|
|
|
#[must_use]
|
2022-01-23 06:39:59 +00:00
|
|
|
pub fn adjusted_by_stats(mut self, stats: Stats) -> Self {
|
2022-01-18 01:41:24 +00:00
|
|
|
use MeleeConstructorKind::*;
|
|
|
|
match self {
|
|
|
|
Slash {
|
|
|
|
ref mut damage,
|
|
|
|
ref mut poise,
|
|
|
|
knockback: _,
|
2022-01-23 06:39:59 +00:00
|
|
|
energy_regen: _,
|
2022-01-18 01:41:24 +00:00
|
|
|
} => {
|
|
|
|
*damage *= stats.power;
|
|
|
|
*poise *= stats.effect_power;
|
|
|
|
},
|
|
|
|
Stab {
|
|
|
|
ref mut damage,
|
|
|
|
ref mut poise,
|
|
|
|
knockback: _,
|
2022-01-23 06:39:59 +00:00
|
|
|
energy_regen: _,
|
2022-01-18 01:41:24 +00:00
|
|
|
} => {
|
|
|
|
*damage *= stats.power;
|
|
|
|
*poise *= stats.effect_power;
|
|
|
|
},
|
|
|
|
Bash {
|
|
|
|
ref mut damage,
|
|
|
|
ref mut poise,
|
|
|
|
knockback: _,
|
2022-01-23 06:39:59 +00:00
|
|
|
energy_regen: _,
|
2022-01-18 01:41:24 +00:00
|
|
|
} => {
|
|
|
|
*damage *= stats.power;
|
|
|
|
*poise *= stats.effect_power;
|
|
|
|
},
|
2023-05-27 22:00:04 +00:00
|
|
|
Hook {
|
|
|
|
ref mut damage,
|
|
|
|
ref mut poise,
|
|
|
|
pull: _,
|
|
|
|
} => {
|
|
|
|
*damage *= stats.power;
|
|
|
|
*poise *= stats.effect_power;
|
|
|
|
},
|
2022-01-18 01:41:24 +00:00
|
|
|
NecroticVortex {
|
|
|
|
ref mut damage,
|
|
|
|
pull: _,
|
|
|
|
lifesteal: _,
|
|
|
|
} => {
|
|
|
|
*damage *= stats.power;
|
|
|
|
},
|
2022-02-02 05:17:06 +00:00
|
|
|
SonicWave {
|
|
|
|
ref mut damage,
|
|
|
|
ref mut poise,
|
|
|
|
knockback: _,
|
|
|
|
} => {
|
|
|
|
*damage *= stats.power;
|
|
|
|
*poise *= stats.effect_power;
|
|
|
|
},
|
2022-01-18 01:41:24 +00:00
|
|
|
}
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|