Merge branch 'aweinstock/damage-types' into 'master'

Add `DamageKind`, and make piercing damage partially ignore damage resistence.

See merge request veloren/veloren!2262
This commit is contained in:
Samuel Keiffer 2021-05-06 22:22:49 +00:00
commit a2999ce96f
84 changed files with 232 additions and 37 deletions

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.075,
base_recover_duration: 0.35,
forward_movement: 0.5,
damage_kind: Slashing,
),
(
stage: 2,
@ -27,6 +28,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.35,
forward_movement: 0.25,
damage_kind: Slashing,
),
],
initial_energy_gain: 25,

View File

@ -11,4 +11,5 @@ LeapMelee(
max_angle: 30.0,
forward_leap_strength: 20.0,
vertical_leap_strength: 8.0,
damage_kind: Slashing,
)

View File

@ -15,4 +15,5 @@ SpinMelee(
num_spins: 1,
specifier: None,
target: Some(OutOfGroup),
damage_kind: Slashing,
)

View File

@ -16,4 +16,5 @@ DashMelee(
recover_duration: 1.2,
charge_through: true,
is_interruptible: true,
damage_kind: Slashing,
)

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.12,
base_recover_duration: 0.6,
forward_movement: 3.5,
damage_kind: Slashing,
),
(
stage: 2,
@ -27,6 +28,7 @@ ComboMelee(
base_swing_duration: 0.15,
base_recover_duration: 1.2,
forward_movement: 4.5,
damage_kind: Slashing,
),
],
initial_energy_gain: 0,

View File

@ -1,9 +1,9 @@
BasicRanged(
energy_cost: 0,
buildup_duration: 0.5,
buildup_duration: 0.4,
recover_duration: 0.3,
projectile: Arrow(
damage: 70.0,
damage: 90.0,
knockback: 5.0,
energy_regen: 40,
),

View File

@ -14,4 +14,5 @@ ChargedRanged(
initial_projectile_speed: 120.0,
scaled_projectile_speed: 160.0,
move_speed: 0.3,
damage_kind: Piercing,
)

View File

@ -9,4 +9,5 @@ BasicMelee(
range: 5.0,
max_angle: 120.0,
damage_effect: None,
damage_kind: Slashing,
)

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.3,
forward_movement: 2.0,
damage_kind: Slashing,
),
(
stage: 2,
@ -27,6 +28,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.3,
forward_movement: 1.5,
damage_kind: Slashing,
),
(
stage: 3,
@ -41,6 +43,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.3,
forward_movement: 1.5,
damage_kind: Slashing,
),
],
initial_energy_gain: 0,

View File

@ -12,4 +12,5 @@ Shockwave(
shockwave_duration: 0.5,
requires_ground: false,
move_efficiency: 0.1,
damage_kind: Energy,
)

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.3,
forward_movement: 2.0,
damage_kind: Slashing,
),
(
stage: 2,
@ -27,6 +28,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.3,
forward_movement: 1.5,
damage_kind: Slashing,
),
(
stage: 3,
@ -41,6 +43,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.3,
forward_movement: 1.5,
damage_kind: Slashing,
),
],
initial_energy_gain: 0,

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.07,
base_recover_duration: 0.25,
forward_movement: 0.5,
damage_kind: Crushing,
),
],
initial_energy_gain: 0,

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.07,
base_recover_duration: 0.2,
forward_movement: 1.0,
damage_kind: Crushing,
),
(
stage: 2,
@ -27,6 +28,7 @@ ComboMelee(
base_swing_duration: 0.07,
base_recover_duration: 0.2,
forward_movement: 0.0,
damage_kind: Crushing,
),
(
stage: 3,
@ -41,6 +43,7 @@ ComboMelee(
base_swing_duration: 0.07,
base_recover_duration: 0.2,
forward_movement: 1.0,
damage_kind: Crushing,
),
],
initial_energy_gain: 0,

View File

@ -15,4 +15,5 @@ SpinMelee(
num_spins: 1,
specifier: Some(CultistVortex),
target: None,
damage_kind: Energy,
)

View File

@ -16,4 +16,5 @@ DashMelee(
recover_duration: 0.5,
charge_through: false,
is_interruptible: false,
damage_kind: Piercing,
)

View File

@ -15,4 +15,5 @@ ChargedMelee(
hit_timing: 0.8,
recover_duration: 0.5,
specifier: Some(GroundCleave),
damage_kind: Slashing,
)

View File

@ -14,4 +14,5 @@ BasicMelee(
strength: Value(0.5),
chance: 1.0,
))),
damage_kind: Slashing,
)

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.07,
base_recover_duration: 0.4,
forward_movement: 3.0,
damage_kind: Crushing,
),
],
initial_energy_gain: 0,

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.07,
base_recover_duration: 0.3,
forward_movement: 2.0,
damage_kind: Crushing,
),
(
stage: 2,
@ -27,6 +28,7 @@ ComboMelee(
base_swing_duration: 0.07,
base_recover_duration: 0.3,
forward_movement: 1.5,
damage_kind: Crushing,
),
(
stage: 3,
@ -41,6 +43,7 @@ ComboMelee(
base_swing_duration: 0.07,
base_recover_duration: 0.3,
forward_movement: 1.5,
damage_kind: Crushing,
),
],
initial_energy_gain: 0,

View File

@ -16,4 +16,5 @@ DashMelee(
recover_duration: 0.8,
charge_through: true,
is_interruptible: false,
damage_kind: Crushing,
)

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.3,
forward_movement: 2.0,
damage_kind: Crushing,
),
(
stage: 2,
@ -27,6 +28,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.3,
forward_movement: 1.5,
damage_kind: Crushing,
),
(
stage: 3,
@ -41,6 +43,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.3,
forward_movement: 1.5,
damage_kind: Crushing,
),
],
initial_energy_gain: 0,

View File

@ -16,4 +16,5 @@ DashMelee(
recover_duration: 0.5,
charge_through: true,
is_interruptible: false,
damage_kind: Crushing,
)

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.1,
forward_movement: 1.5,
damage_kind: Crushing,
),
(
stage: 2,
@ -27,6 +28,7 @@ ComboMelee(
base_swing_duration: 0.07,
base_recover_duration: 0.1,
forward_movement: 0.8,
damage_kind: Crushing,
),
(
stage: 3,
@ -41,6 +43,7 @@ ComboMelee(
base_swing_duration: 0.07,
base_recover_duration: 0.1,
forward_movement: 0.8,
damage_kind: Crushing,
),
(
stage: 4,
@ -55,6 +58,7 @@ ComboMelee(
base_swing_duration: 0.07,
base_recover_duration: 0.1,
forward_movement: 0.8,
damage_kind: Crushing,
),
],
initial_energy_gain: 0,

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.4,
forward_movement: 3.0,
damage_kind: Crushing,
),
],
initial_energy_gain: 0,

View File

@ -14,4 +14,5 @@ ChargedMelee(
swing_duration: 0.7,
hit_timing: 0.9,
recover_duration: 1.2,
damage_kind: Crushing,
)

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.2,
forward_movement: 2.0,
damage_kind: Crushing,
),
(
stage: 2,
@ -27,6 +28,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.2,
forward_movement: 1.0,
damage_kind: Crushing,
),
(
stage: 3,
@ -41,6 +43,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.2,
forward_movement: 1.0,
damage_kind: Crushing,
),
],
initial_energy_gain: 0,

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.4,
forward_movement: 1.0,
damage_kind: Crushing,
),
],
initial_energy_gain: 0,

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.07,
base_recover_duration: 0.2,
forward_movement: 1.0,
damage_kind: Crushing,
),
(
stage: 2,
@ -27,6 +28,7 @@ ComboMelee(
base_swing_duration: 0.07,
base_recover_duration: 0.2,
forward_movement: 0.0,
damage_kind: Crushing,
),
(
stage: 3,
@ -41,6 +43,7 @@ ComboMelee(
base_swing_duration: 0.07,
base_recover_duration: 0.2,
forward_movement: 1.0,
damage_kind: Crushing,
),
],
initial_energy_gain: 0,

View File

@ -16,4 +16,5 @@ DashMelee(
recover_duration: 1.1,
charge_through: true,
is_interruptible: false,
damage_kind: Crushing,
)

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.3,
forward_movement: 1.0,
damage_kind: Crushing,
),
(
stage: 2,
@ -27,6 +28,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.3,
forward_movement: 0.5,
damage_kind: Crushing,
),
],
initial_energy_gain: 0,

View File

@ -9,4 +9,5 @@ BasicMelee(
range: 1.2,
max_angle: 50.0,
damage_effect: None,
damage_kind: Crushing,
)

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.3,
forward_movement: 1.0,
damage_kind: Crushing,
),
(
stage: 2,
@ -27,6 +28,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.3,
forward_movement: 1.5,
damage_kind: Crushing,
),
],
initial_energy_gain: 0,

View File

@ -11,4 +11,5 @@ LeapMelee(
max_angle: 180.0,
forward_leap_strength: 40.0,
vertical_leap_strength: 10.0,
damage_kind: Crushing,
)

View File

@ -11,4 +11,5 @@ LeapMelee(
max_angle: 180.0,
forward_leap_strength: 20.0,
vertical_leap_strength: 5.0,
damage_kind: Crushing,
)

View File

@ -16,4 +16,5 @@ DashMelee(
recover_duration: 0.5,
charge_through: true,
is_interruptible: false,
damage_kind: Crushing,
)

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.15,
base_recover_duration: 0.4,
forward_movement: 0.3,
damage_kind: Crushing,
),
(
stage: 2,
@ -27,6 +28,7 @@ ComboMelee(
base_swing_duration: 0.15,
base_recover_duration: 0.3,
forward_movement: 0.5,
damage_kind: Crushing,
),
(
stage: 3,
@ -41,6 +43,7 @@ ComboMelee(
base_swing_duration: 0.15,
base_recover_duration: 0.3,
forward_movement: 0.5,
damage_kind: Crushing,
),
],
initial_energy_gain: 0,

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.15,
base_recover_duration: 0.3,
forward_movement: 1.0,
damage_kind: Crushing,
),
],
initial_energy_gain: 0,

View File

@ -12,4 +12,5 @@ Shockwave(
shockwave_duration: 1.0,
requires_ground: true,
move_efficiency: 0.05,
damage_kind: Crushing,
)

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.9,
forward_movement: 3.0,
damage_kind: Crushing,
),
],
initial_energy_gain: 0,

View File

@ -15,4 +15,5 @@ SpinMelee(
num_spins: 1,
specifier: None,
target: Some(OutOfGroup),
damage_kind: Crushing,
)

View File

@ -16,4 +16,5 @@ DashMelee(
recover_duration: 1.1,
charge_through: true,
is_interruptible: false,
damage_kind: Crushing,
)

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.15,
base_recover_duration: 0.4,
forward_movement: 3.0,
damage_kind: Crushing,
),
],
initial_energy_gain: 0,

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.15,
base_recover_duration: 0.3,
forward_movement: 1.0,
damage_kind: Crushing,
),
(
stage: 2,
@ -27,6 +28,7 @@ ComboMelee(
base_swing_duration: 0.15,
base_recover_duration: 0.15,
forward_movement: 1.0,
damage_kind: Crushing,
),
(
stage: 3,
@ -41,6 +43,7 @@ ComboMelee(
base_swing_duration: 0.125,
base_recover_duration: 0.9,
forward_movement: 1.0,
damage_kind: Crushing,
),
],
initial_energy_gain: 0,

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.15,
base_recover_duration: 0.4,
forward_movement: 3.0,
damage_kind: Crushing,
),
],
initial_energy_gain: 0,

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.15,
base_recover_duration: 0.3,
forward_movement: 1.0,
damage_kind: Crushing,
),
(
stage: 2,
@ -27,6 +28,7 @@ ComboMelee(
base_swing_duration: 0.15,
base_recover_duration: 0.15,
forward_movement: 1.0,
damage_kind: Crushing,
),
(
stage: 3,
@ -41,6 +43,7 @@ ComboMelee(
base_swing_duration: 0.125,
base_recover_duration: 0.9,
forward_movement: 1.0,
damage_kind: Crushing,
),
],
initial_energy_gain: 0,

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.2,
base_recover_duration: 0.4,
forward_movement: 5.0,
damage_kind: Crushing,
),
],
initial_energy_gain: 0,

View File

@ -9,4 +9,5 @@ BasicMelee(
range: 3.5,
max_angle: 20.0,
damage_effect: None,
damage_kind: Piercing,
)

View File

@ -9,4 +9,5 @@ BasicMelee(
range: 3.5,
max_angle: 15.0,
damage_effect: None,
damage_kind: Crushing,
)

View File

@ -9,4 +9,5 @@ BasicMelee(
range: 3.5,
max_angle: 20.0,
damage_effect: None,
damage_kind: Crushing,
)

View File

@ -14,4 +14,5 @@ ChargedMelee(
swing_duration: 0.12,
hit_timing: 0.2,
recover_duration: 0.3,
damage_kind: Crushing,
)

View File

@ -11,4 +11,5 @@ LeapMelee(
max_angle: 360.0,
forward_leap_strength: 20.0,
vertical_leap_strength: 8.0,
damage_kind: Crushing,
)

View File

@ -12,6 +12,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.45,
forward_movement: 0.0,
damage_kind: Crushing,
)],
initial_energy_gain: 50,
max_energy_gain: 150,

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.08,
base_recover_duration: 0.6,
forward_movement: 3.5,
damage_kind: Crushing,
),
(
stage: 2,
@ -27,6 +28,7 @@ ComboMelee(
base_swing_duration: 0.25,
base_recover_duration: 1.2,
forward_movement: 2.0,
damage_kind: Crushing,
),
],
initial_energy_gain: 0,

View File

@ -9,4 +9,5 @@ BasicMelee(
range: 3.5,
max_angle: 20.0,
damage_effect: None,
damage_kind: Piercing,
)

View File

@ -9,4 +9,5 @@ BasicMelee(
range: 3.0,
max_angle: 120.0,
damage_effect: None,
damage_kind: Crushing,
)

View File

@ -16,4 +16,5 @@ DashMelee(
recover_duration: 0.5,
charge_through: true,
is_interruptible: true,
damage_kind: Piercing,
)

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.075,
base_recover_duration: 0.4,
forward_movement: 0.7,
damage_kind: Piercing,
),
(
stage: 2,
@ -27,6 +28,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.5,
forward_movement: 0.7,
damage_kind: Piercing,
),
],
initial_energy_gain: 0,

View File

@ -1,9 +1,9 @@
BasicRanged(
energy_cost: 0,
buildup_duration: 0.5,
recover_duration: 0.35,
recover_duration: 0.4,
projectile: Fireball(
damage: 100.0,
damage: 90.0,
radius: 4.0,
energy_regen: 50,
),

View File

@ -12,4 +12,5 @@ Shockwave(
shockwave_duration: 0.5,
requires_ground: false,
move_efficiency: 0.1,
damage_kind: Energy,
)

View File

@ -16,4 +16,5 @@ DashMelee(
recover_duration: 0.5,
charge_through: true,
is_interruptible: true,
damage_kind: Piercing,
)

View File

@ -15,4 +15,5 @@ SpinMelee(
num_spins: 3,
specifier: None,
target: Some(OutOfGroup),
damage_kind: Slashing,
)

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.075,
base_recover_duration: 0.15,
forward_movement: 0.5,
damage_kind: Slashing,
),
(
stage: 2,
@ -27,6 +28,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.3,
forward_movement: 0.0,
damage_kind: Slashing,
),
(
stage: 3,
@ -41,6 +43,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.35,
forward_movement: 1.2,
damage_kind: Piercing,
),
],
initial_energy_gain: 0,

View File

@ -16,4 +16,5 @@ DashMelee(
recover_duration: 0.9,
charge_through: true,
is_interruptible: true,
damage_kind: Piercing,
)

View File

@ -13,6 +13,7 @@ ComboMelee(
base_swing_duration: 0.08,
base_recover_duration: 0.5,
forward_movement: 2.5,
damage_kind: Slashing,
),
(
stage: 2,
@ -27,6 +28,7 @@ ComboMelee(
base_swing_duration: 0.1,
base_recover_duration: 0.7,
forward_movement: 2.0,
damage_kind: Slashing,
),
],
initial_energy_gain: 0,

View File

@ -122,9 +122,11 @@ impl Attack {
target: &TargetInfo,
source: AttackSource,
dir: Dir,
kind: DamageKind,
mut emit_outcome: impl FnMut(Outcome),
) -> f32 {
let damage_reduction = Damage::compute_damage_reduction(target.inventory, target.stats);
let damage_reduction =
Damage::compute_damage_reduction(target.inventory, target.stats, Some(kind));
let block_reduction = match source {
AttackSource::Melee => {
if let (Some(CharacterState::BasicBlock(data)), Some(ori)) =
@ -177,8 +179,13 @@ impl Attack {
.filter(|d| d.target.map_or(true, |t| t == target_group))
.filter(|d| !(matches!(d.target, Some(GroupTarget::OutOfGroup)) && target_dodging))
{
let damage_reduction =
Attack::compute_damage_reduction(&target, attack_source, dir, |o| emit_outcome(o));
let damage_reduction = Attack::compute_damage_reduction(
&target,
attack_source,
dir,
damage.damage.kind,
|o| emit_outcome(o),
);
let change = damage.damage.calculate_health_change(
damage_reduction,
attacker.map(|a| a.uid),
@ -497,17 +504,36 @@ pub enum DamageSource {
Other,
}
/// DamageKind for the purpose of differentiating damage reduction
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub enum DamageKind {
/// Arrows/Sword dash
Piercing,
/// Swords/axes
Slashing,
/// Hammers
Crushing,
/// Staves/sceptres (TODO: differentiate further once there are more magic
/// weapons)
Energy,
}
#[cfg(not(target_arch = "wasm32"))]
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct Damage {
pub source: DamageSource,
pub kind: DamageKind,
pub value: f32,
}
#[cfg(not(target_arch = "wasm32"))]
impl Damage {
/// Returns the total damage reduction provided by all equipped items
pub fn compute_damage_reduction(inventory: Option<&Inventory>, stats: Option<&Stats>) -> f32 {
pub fn compute_damage_reduction(
inventory: Option<&Inventory>,
stats: Option<&Stats>,
kind: Option<DamageKind>,
) -> f32 {
let inventory_dr = if let Some(inventory) = inventory {
let protection = inventory
.equipped_items()
@ -524,6 +550,13 @@ impl Damage {
})
.sum::<Option<f32>>();
let kind_modifier = if matches!(kind, Some(DamageKind::Piercing)) {
0.75
} else {
1.0
};
let protection = protection.map(|dr| dr * kind_modifier);
const FIFTY_PERCENT_DR_THRESHOLD: f32 = 60.0;
match protection {
@ -842,7 +875,7 @@ pub fn combat_rating(
// Assumes a "standard" max health of 100
let health_rating = health.base_max() as f32
/ 100.0
/ (1.0 - Damage::compute_damage_reduction(Some(inventory), None)).max(0.00001);
/ (1.0 - Damage::compute_damage_reduction(Some(inventory), None, None)).max(0.00001);
// Assumes a standard person has earned 20 skill points in the general skill
// tree and 10 skill points for the weapon skill tree

View File

@ -1,6 +1,6 @@
use crate::{
assets::{self, Asset},
combat::{self, CombatEffect, Knockback},
combat::{self, CombatEffect, DamageKind, Knockback},
comp::{
aura, beam, buff, inventory::item::tool::ToolKind, projectile::ProjectileConstructor,
skills, Body, CharacterState, EnergySource, LightEmitter, StateUpdate,
@ -69,6 +69,7 @@ pub enum CharacterAbility {
range: f32,
max_angle: f32,
damage_effect: Option<CombatEffect>,
damage_kind: DamageKind,
},
BasicRanged {
energy_cost: f32,
@ -116,6 +117,7 @@ pub enum CharacterAbility {
recover_duration: f32,
charge_through: bool,
is_interruptible: bool,
damage_kind: DamageKind,
},
BasicBlock {
buildup_duration: f32,
@ -156,6 +158,7 @@ pub enum CharacterAbility {
knockback: f32,
forward_leap_strength: f32,
vertical_leap_strength: f32,
damage_kind: DamageKind,
},
SpinMelee {
buildup_duration: f32,
@ -174,6 +177,7 @@ pub enum CharacterAbility {
num_spins: u32,
specifier: Option<spin_melee::FrontendSpecifier>,
target: Option<combat::GroupTarget>,
damage_kind: DamageKind,
},
ChargedMelee {
energy_cost: f32,
@ -192,6 +196,7 @@ pub enum CharacterAbility {
hit_timing: f32,
recover_duration: f32,
specifier: Option<charged_melee::FrontendSpecifier>,
damage_kind: DamageKind,
},
ChargedRanged {
energy_cost: f32,
@ -209,6 +214,7 @@ pub enum CharacterAbility {
initial_projectile_speed: f32,
scaled_projectile_speed: f32,
move_speed: f32,
damage_kind: DamageKind,
},
Shockwave {
energy_cost: f32,
@ -224,6 +230,7 @@ pub enum CharacterAbility {
shockwave_duration: f32,
requires_ground: bool,
move_efficiency: f32,
damage_kind: DamageKind,
},
BasicBeam {
buildup_duration: f32,
@ -296,6 +303,7 @@ impl Default for CharacterAbility {
range: 3.5,
max_angle: 15.0,
damage_effect: None,
damage_kind: DamageKind::Crushing,
}
}
}
@ -1198,6 +1206,7 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
max_angle,
damage_effect,
energy_cost: _,
damage_kind,
} => CharacterState::BasicMelee(basic_melee::Data {
static_data: basic_melee::StaticData {
buildup_duration: Duration::from_secs_f32(*buildup_duration),
@ -1210,6 +1219,7 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
max_angle: *max_angle,
damage_effect: *damage_effect,
ability_info,
damage_kind: *damage_kind,
},
timer: Duration::default(),
stage_section: StageSection::Buildup,
@ -1270,6 +1280,7 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
recover_duration,
charge_through,
is_interruptible,
damage_kind,
} => CharacterState::DashMelee(dash_melee::Data {
static_data: dash_melee::StaticData {
base_damage: *base_damage,
@ -1289,6 +1300,7 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
recover_duration: Duration::from_secs_f32(*recover_duration),
is_interruptible: *is_interruptible,
ability_info,
damage_kind: *damage_kind,
},
auto_charge: false,
timer: Duration::default(),
@ -1376,6 +1388,7 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
max_angle,
forward_leap_strength,
vertical_leap_strength,
damage_kind,
} => CharacterState::LeapMelee(leap_melee::Data {
static_data: leap_melee::StaticData {
buildup_duration: Duration::from_secs_f32(*buildup_duration),
@ -1390,6 +1403,7 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
forward_leap_strength: *forward_leap_strength,
vertical_leap_strength: *vertical_leap_strength,
ability_info,
damage_kind: *damage_kind,
},
timer: Duration::default(),
stage_section: StageSection::Buildup,
@ -1412,6 +1426,7 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
num_spins,
specifier,
target,
damage_kind,
} => CharacterState::SpinMelee(spin_melee::Data {
static_data: spin_melee::StaticData {
buildup_duration: Duration::from_secs_f32(*buildup_duration),
@ -1431,6 +1446,7 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
target: *target,
ability_info,
specifier: *specifier,
damage_kind: *damage_kind,
},
timer: Duration::default(),
consecutive_spins: 1,
@ -1454,6 +1470,7 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
range,
max_angle,
specifier,
damage_kind,
} => CharacterState::ChargedMelee(charged_melee::Data {
static_data: charged_melee::StaticData {
energy_cost: *energy_cost,
@ -1473,6 +1490,7 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
recover_duration: Duration::from_secs_f32(*recover_duration),
ability_info,
specifier: *specifier,
damage_kind: *damage_kind,
},
stage_section: StageSection::Charge,
timer: Duration::default(),
@ -1495,6 +1513,7 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
initial_projectile_speed,
scaled_projectile_speed,
move_speed,
damage_kind,
} => CharacterState::ChargedRanged(charged_ranged::Data {
static_data: charged_ranged::StaticData {
buildup_duration: Duration::from_secs_f32(*buildup_duration),
@ -1512,6 +1531,7 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
scaled_projectile_speed: *scaled_projectile_speed,
move_speed: *move_speed,
ability_info,
damage_kind: *damage_kind,
},
timer: Duration::default(),
stage_section: StageSection::Buildup,
@ -1560,6 +1580,7 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
shockwave_duration,
requires_ground,
move_efficiency,
damage_kind,
} => CharacterState::Shockwave(shockwave::Data {
static_data: shockwave::StaticData {
buildup_duration: Duration::from_secs_f32(*buildup_duration),
@ -1575,6 +1596,7 @@ impl From<(&CharacterAbility, AbilityInfo)> for CharacterState {
requires_ground: *requires_ground,
move_efficiency: *move_efficiency,
ability_info,
damage_kind: *damage_kind,
},
timer: Duration::default(),
stage_section: StageSection::Buildup,

View File

@ -1,7 +1,7 @@
use crate::{
combat::{
Attack, AttackDamage, AttackEffect, CombatBuff, CombatEffect, CombatRequirement, Damage,
DamageSource, GroupTarget, Knockback, KnockbackDir,
DamageKind, DamageSource, GroupTarget, Knockback, KnockbackDir,
},
comp::item::Reagent,
uid::Uid,
@ -85,6 +85,7 @@ impl ProjectileConstructor {
let damage = AttackDamage::new(
Damage {
source: DamageSource::Projectile,
kind: DamageKind::Piercing,
value: damage,
},
Some(GroupTarget::OutOfGroup),
@ -115,6 +116,7 @@ impl ProjectileConstructor {
let damage = AttackDamage::new(
Damage {
source: DamageSource::Explosion,
kind: DamageKind::Energy,
value: damage,
},
Some(GroupTarget::OutOfGroup),
@ -144,6 +146,7 @@ impl ProjectileConstructor {
let damage = AttackDamage::new(
Damage {
source: DamageSource::Explosion,
kind: DamageKind::Energy,
value: damage,
},
Some(GroupTarget::OutOfGroup),

View File

@ -82,9 +82,9 @@ pub mod volumes;
#[cfg(not(target_arch = "wasm32"))]
pub use cached_spatial_grid::CachedSpatialGrid;
pub use combat::DamageSource;
#[cfg(not(target_arch = "wasm32"))]
pub use combat::{Damage, GroupTarget, Knockback, KnockbackDir};
pub use combat::{DamageKind, DamageSource};
#[cfg(not(target_arch = "wasm32"))]
pub use comp::inventory::loadout_builder::LoadoutBuilder;
#[cfg(not(target_arch = "wasm32"))]

View File

@ -1,7 +1,7 @@
use crate::{
combat::{
Attack, AttackDamage, AttackEffect, CombatEffect, CombatRequirement, Damage, DamageSource,
GroupTarget,
Attack, AttackDamage, AttackEffect, CombatEffect, CombatRequirement, Damage, DamageKind,
DamageSource, GroupTarget,
},
comp::{beam, Body, CharacterState, EnergyChange, EnergySource, Ori, Pos, StateUpdate},
event::ServerEvent,
@ -114,6 +114,7 @@ impl CharacterBehavior for Data {
let mut damage = AttackDamage::new(
Damage {
source: DamageSource::Energy,
kind: DamageKind::Energy,
value: self.static_data.damage,
},
Some(GroupTarget::OutOfGroup),

View File

@ -5,7 +5,7 @@ use crate::{
behavior::{CharacterBehavior, JoinData},
utils::*,
},
Damage, DamageSource, GroupTarget, Knockback, KnockbackDir,
Damage, DamageKind, DamageSource, GroupTarget, Knockback, KnockbackDir,
};
use serde::{Deserialize, Serialize};
use std::time::Duration;
@ -33,6 +33,8 @@ pub struct StaticData {
pub damage_effect: Option<CombatEffect>,
/// What key is used to press ability
pub ability_info: AbilityInfo,
/// Which kind of damage does this attack deal
pub damage_kind: DamageKind,
}
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
@ -103,6 +105,7 @@ impl CharacterBehavior for Data {
let mut damage = AttackDamage::new(
Damage {
source: DamageSource::Melee,
kind: self.static_data.damage_kind,
value: self.static_data.base_damage as f32,
},
Some(GroupTarget::OutOfGroup),

View File

@ -7,7 +7,7 @@ use crate::{
behavior::{CharacterBehavior, JoinData},
utils::{StageSection, *},
},
Damage, DamageSource, GroupTarget, Knockback, KnockbackDir,
Damage, DamageKind, DamageSource, GroupTarget, Knockback, KnockbackDir,
};
use serde::{Deserialize, Serialize};
use std::time::Duration;
@ -49,6 +49,8 @@ pub struct StaticData {
pub ability_info: AbilityInfo,
/// Used to specify the melee attack to the frontend
pub specifier: Option<FrontendSpecifier>,
/// What kind of damage the attack does
pub damage_kind: DamageKind,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
@ -170,6 +172,7 @@ impl CharacterBehavior for Data {
let damage = AttackDamage::new(
Damage {
source: DamageSource::Melee,
kind: self.static_data.damage_kind,
value: self.static_data.initial_damage as f32
+ self.charge_amount * self.static_data.scaled_damage as f32,
},

View File

@ -1,7 +1,7 @@
use crate::{
combat::{
Attack, AttackDamage, AttackEffect, CombatBuff, CombatEffect, CombatRequirement, Damage,
DamageSource, GroupTarget, Knockback, KnockbackDir,
DamageKind, DamageSource, GroupTarget, Knockback, KnockbackDir,
},
comp::{
projectile, Body, CharacterState, EnergyChange, EnergySource, LightEmitter, Projectile,
@ -46,6 +46,8 @@ pub struct StaticData {
pub move_speed: f32,
/// What key is used to press ability
pub ability_info: AbilityInfo,
/// What kind of damage the attack does
pub damage_kind: DamageKind,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
@ -107,6 +109,7 @@ impl CharacterBehavior for Data {
let damage = AttackDamage::new(
Damage {
source: DamageSource::Projectile,
kind: self.static_data.damage_kind,
value: self.static_data.initial_damage as f32
+ charge_frac * self.static_data.scaled_damage as f32,
},

View File

@ -5,7 +5,7 @@ use crate::{
behavior::{CharacterBehavior, JoinData},
utils::*,
},
Damage, DamageSource, GroupTarget, Knockback, KnockbackDir,
Damage, DamageKind, DamageSource, GroupTarget, Knockback, KnockbackDir,
};
use serde::{Deserialize, Serialize};
use std::time::Duration;
@ -37,6 +37,8 @@ pub struct Stage<T> {
pub base_recover_duration: T,
/// How much forward movement there is in the swing portion of the stage
pub forward_movement: f32,
/// What kind of damage this stage of the attack does
pub damage_kind: DamageKind,
}
impl Stage<f32> {
@ -54,6 +56,7 @@ impl Stage<f32> {
base_swing_duration: Duration::from_secs_f32(self.base_swing_duration),
base_recover_duration: Duration::from_secs_f32(self.base_recover_duration),
forward_movement: self.forward_movement,
damage_kind: self.damage_kind,
}
}
@ -195,6 +198,7 @@ impl CharacterBehavior for Data {
let damage = AttackDamage::new(
Damage {
source: DamageSource::Melee,
kind: self.static_data.stage_data[stage_index].damage_kind,
value: damage as f32,
},
Some(GroupTarget::OutOfGroup),

View File

@ -5,7 +5,7 @@ use crate::{
behavior::{CharacterBehavior, JoinData},
utils::*,
},
Damage, DamageSource, GroupTarget, Knockback, KnockbackDir,
Damage, DamageKind, DamageSource, GroupTarget, Knockback, KnockbackDir,
};
use serde::{Deserialize, Serialize};
use std::time::Duration;
@ -47,6 +47,8 @@ pub struct StaticData {
pub is_interruptible: bool,
/// What key is used to press ability
pub ability_info: AbilityInfo,
/// What kind of damage the attack does
pub damage_kind: DamageKind,
}
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
@ -141,6 +143,7 @@ impl CharacterBehavior for Data {
let damage = AttackDamage::new(
Damage {
source: DamageSource::Melee,
kind: self.static_data.damage_kind,
value: self.static_data.base_damage as f32
+ charge_frac * self.static_data.scaled_damage as f32,
},
@ -291,6 +294,7 @@ impl CharacterBehavior for Data {
let damage = AttackDamage::new(
Damage {
source: DamageSource::Melee,
kind: self.static_data.damage_kind,
value: self.static_data.base_damage as f32
+ charge_frac * self.static_data.scaled_damage as f32,
},

View File

@ -5,7 +5,7 @@ use crate::{
behavior::{CharacterBehavior, JoinData},
utils::{StageSection, *},
},
Damage, DamageSource, GroupTarget, Knockback, KnockbackDir,
Damage, DamageKind, DamageSource, GroupTarget, Knockback, KnockbackDir,
};
use serde::{Deserialize, Serialize};
use std::time::Duration;
@ -37,6 +37,8 @@ pub struct StaticData {
pub vertical_leap_strength: f32,
/// What key is used to press ability
pub ability_info: AbilityInfo,
/// What kind of damage the attack does
pub damage_kind: DamageKind,
}
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
@ -157,6 +159,7 @@ impl CharacterBehavior for Data {
let damage = AttackDamage::new(
Damage {
source: DamageSource::Melee,
kind: self.static_data.damage_kind,
value: self.static_data.base_damage as f32,
},
Some(GroupTarget::OutOfGroup),

View File

@ -1,7 +1,7 @@
use crate::{
combat::{
Attack, AttackDamage, AttackEffect, CombatEffect, CombatRequirement, Damage, DamageSource,
GroupTarget, Knockback,
Attack, AttackDamage, AttackEffect, CombatEffect, CombatRequirement, Damage, DamageKind,
DamageSource, GroupTarget, Knockback,
},
comp::{shockwave, CharacterState, StateUpdate},
event::ServerEvent,
@ -42,6 +42,8 @@ pub struct StaticData {
pub move_efficiency: f32,
/// What key is used to press ability
pub ability_info: AbilityInfo,
/// What kind of damage the attack does
pub damage_kind: DamageKind,
}
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
@ -88,6 +90,7 @@ impl CharacterBehavior for Data {
let damage = AttackDamage::new(
Damage {
source: DamageSource::Shockwave,
kind: self.static_data.damage_kind,
value: self.static_data.damage as f32,
},
Some(GroupTarget::OutOfGroup),

View File

@ -1,7 +1,7 @@
use crate::{
combat::{
Attack, AttackDamage, AttackEffect, CombatBuff, CombatEffect, CombatRequirement, Damage,
DamageSource, GroupTarget, Knockback,
DamageKind, DamageSource, GroupTarget, Knockback,
},
comp::{tool::ToolKind, CharacterState, EnergyChange, EnergySource, Melee, StateUpdate},
consts::GRAVITY,
@ -51,6 +51,8 @@ pub struct StaticData {
pub ability_info: AbilityInfo,
/// Used to specify the melee attack to the frontend
pub specifier: Option<FrontendSpecifier>,
/// What kind of damage the attack does
pub damage_kind: DamageKind,
}
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
@ -124,6 +126,7 @@ impl CharacterBehavior for Data {
let mut damage = AttackDamage::new(
Damage {
source: DamageSource::Melee,
kind: self.static_data.damage_kind,
value: self.static_data.base_damage as f32,
},
self.static_data.target,

View File

@ -77,8 +77,11 @@ impl<'a> System<'a> for Sys {
}
}
let damage_reduction =
Damage::compute_damage_reduction(read_data.inventories.get(entity), Some(&stat));
let damage_reduction = Damage::compute_damage_reduction(
read_data.inventories.get(entity),
Some(&stat),
None,
);
if (damage_reduction - 1.0).abs() < f32::EPSILON {
for (id, buff) in buff_comp.buffs.iter() {
if !buff.kind.is_buff() {

View File

@ -29,7 +29,7 @@ use common::{
terrain::{Block, BlockKind, SpriteKind, TerrainChunkSize},
uid::Uid,
vol::RectVolSize,
Damage, DamageSource, Explosion, LoadoutBuilder, RadiusEffect,
Damage, DamageKind, DamageSource, Explosion, LoadoutBuilder, RadiusEffect,
};
use common_net::{
msg::{DisconnectReason, Notification, PlayerListUpdate, ServerGeneral},
@ -1671,6 +1671,7 @@ fn handle_explosion(
effects: vec![
RadiusEffect::Entity(Effect::Damage(Damage {
source: DamageSource::Explosion,
kind: DamageKind::Energy,
value: 100.0 * power,
})),
RadiusEffect::TerrainDestruction(power),

View File

@ -26,7 +26,7 @@ use common::{
uid::{Uid, UidAllocator},
util::Dir,
vol::ReadVol,
Damage, DamageSource, Explosion, GroupTarget, RadiusEffect,
Damage, DamageKind, DamageSource, Explosion, GroupTarget, RadiusEffect,
};
use common_net::{msg::ServerGeneral, sync::WorldSyncExt};
use common_state::BlockChange;
@ -491,10 +491,14 @@ pub fn handle_land_on_ground(server: &Server, entity: EcsEntity, vel: Vec3<f32>)
if let Some(mut health) = state.ecs().write_storage::<comp::Health>().get_mut(entity) {
let damage = Damage {
source: DamageSource::Falling,
kind: DamageKind::Crushing,
value: falldmg,
};
let damage_reduction =
Damage::compute_damage_reduction(inventories.get(entity), stats.get(entity));
let damage_reduction = Damage::compute_damage_reduction(
inventories.get(entity),
stats.get(entity),
Some(DamageKind::Crushing),
);
let change = damage.calculate_health_change(damage_reduction, None, false, 0.0, 1.0);
health.change_by(change);
}

View File

@ -125,6 +125,7 @@ impl StateExt for State {
combat::Damage::compute_damage_reduction(
inventories.get(entity),
stats.get(entity),
Some(damage.kind),
),
source,
false,

View File

@ -3,7 +3,7 @@ use common::{
effect::Effect,
event::{EventBus, ServerEvent},
resources::DeltaTime,
Damage, DamageSource, Explosion, RadiusEffect,
Damage, DamageKind, DamageSource, Explosion, RadiusEffect,
};
use common_ecs::{Job, Origin, Phase, System};
use specs::{Entities, Join, Read, ReadStorage, WriteStorage};
@ -56,6 +56,7 @@ impl<'a> System<'a> for Sys {
effects: vec![
RadiusEffect::Entity(Effect::Damage(Damage {
source: DamageSource::Explosion,
kind: DamageKind::Energy,
value: 400.0,
})),
RadiusEffect::Entity(Effect::PoiseChange(PoiseChange {
@ -150,6 +151,7 @@ impl<'a> System<'a> for Sys {
effects: vec![
RadiusEffect::Entity(Effect::Damage(Damage {
source: DamageSource::Explosion,
kind: DamageKind::Energy,
value: 50.0,
})),
RadiusEffect::Entity(Effect::PoiseChange(PoiseChange {

View File

@ -1,6 +1,7 @@
use super::*;
use crate::audio::sfx::SfxEvent;
use common::{
combat::DamageKind,
comp::{
inventory::loadout_builder::LoadoutBuilder, item::tool::ToolKind, CharacterAbilityType,
CharacterState, InputKind, Item,
@ -80,6 +81,7 @@ fn maps_basic_melee() {
max_angle: 1.0,
ability_info: empty_ability_info(),
damage_effect: None,
damage_kind: DamageKind::Slashing,
},
timer: Duration::default(),
stage_section: states::utils::StageSection::Buildup,
@ -125,6 +127,7 @@ fn matches_ability_stage() {
base_swing_duration: Duration::from_millis(200),
base_recover_duration: Duration::from_millis(400),
forward_movement: 0.5,
damage_kind: DamageKind::Slashing,
}],
initial_energy_gain: 0.0,
max_energy_gain: 100.0,
@ -183,6 +186,7 @@ fn ignores_different_ability_stage() {
base_swing_duration: Duration::from_millis(200),
base_recover_duration: Duration::from_millis(400),
forward_movement: 0.5,
damage_kind: DamageKind::Slashing,
}],
initial_energy_gain: 0.0,
max_energy_gain: 100.0,

View File

@ -785,7 +785,8 @@ impl<'a> Widget for Bag<'a> {
});
let protection_txt = format!(
"{}%",
(100.0 * Damage::compute_damage_reduction(Some(inventory), Some(self.stats)))
(100.0
* Damage::compute_damage_reduction(Some(inventory), Some(self.stats), None,))
as i32
);
let health_txt = format!("{}", (self.health.maximum() as f32 / 10.0) as usize);