From 981eee59369db089950bdf64182e2f0da70f50d6 Mon Sep 17 00:00:00 2001 From: Sam Date: Sun, 18 Oct 2020 13:21:58 -0500 Subject: [PATCH] Transitioned knockback to an enum. --- common/src/combat.rs | 25 +++++++++++++++++++++++++ common/src/comp/ability.rs | 3 ++- common/src/comp/character_state.rs | 4 ++-- common/src/comp/inventory/item/tool.rs | 11 +++++------ common/src/comp/projectile.rs | 4 ++-- common/src/comp/shockwave.rs | 4 ++-- common/src/lib.rs | 2 +- common/src/states/basic_melee.rs | 4 ++-- common/src/states/charged_melee.rs | 4 ++-- common/src/states/charged_ranged.rs | 4 ++-- common/src/states/combo_melee.rs | 6 ++++-- common/src/states/dash_melee.rs | 4 ++-- common/src/states/leap_melee.rs | 4 ++-- common/src/states/shockwave.rs | 4 ++-- common/src/states/spin_melee.rs | 4 ++-- common/src/sys/melee.rs | 5 ++--- common/src/sys/projectile.rs | 5 +---- common/src/sys/shockwave.rs | 14 ++++---------- common/src/util/dir.rs | 7 +++++++ 19 files changed, 71 insertions(+), 47 deletions(-) diff --git a/common/src/combat.rs b/common/src/combat.rs index 3702d2e978..e80de3abe6 100644 --- a/common/src/combat.rs +++ b/common/src/combat.rs @@ -1,8 +1,10 @@ use crate::{ comp::{HealthChange, HealthSource, Loadout}, sync::Uid, + util::Dir, }; use serde::{Deserialize, Serialize}; +use vek::*; pub const BLOCK_EFFICIENCY: f32 = 0.9; @@ -159,3 +161,26 @@ impl Damage { } } } + +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub enum Knockback { + Away(f32), + Towards(f32), + Up(f32), + TowardsUp(f32), +} + +impl Knockback { + pub fn get_knockback(self, dir: Dir) -> Vec3 { + match self { + Knockback::Away(strength) => strength * *Dir::slerp(dir, Dir::new(Vec3::unit_z()), 0.5), + Knockback::Towards(strength) => { + strength * *Dir::slerp(-dir, Dir::new(Vec3::unit_z()), 0.5) + }, + Knockback::Up(strength) => strength * Vec3::unit_z(), + Knockback::TowardsUp(strength) => { + strength * *Dir::slerp(-dir, Dir::new(Vec3::unit_z()), 0.85) + }, + } + } +} diff --git a/common/src/comp/ability.rs b/common/src/comp/ability.rs index 453e905c05..ab0f92cd5d 100644 --- a/common/src/comp/ability.rs +++ b/common/src/comp/ability.rs @@ -8,6 +8,7 @@ use crate::{ *, }, sys::character_behavior::JoinData, + Knockback, }; use arraygen::Arraygen; use serde::{Deserialize, Serialize}; @@ -184,7 +185,7 @@ pub enum CharacterAbility { swing_duration: Duration, recover_duration: Duration, damage: u32, - knockback: f32, + knockback: Knockback, shockwave_angle: f32, shockwave_vertical_angle: f32, shockwave_speed: f32, diff --git a/common/src/comp/character_state.rs b/common/src/comp/character_state.rs index 7b459b60ee..f439fbcfdf 100644 --- a/common/src/comp/character_state.rs +++ b/common/src/comp/character_state.rs @@ -3,7 +3,7 @@ use crate::{ event::{LocalEvent, ServerEvent}, states::*, sys::character_behavior::JoinData, - Damages, + Damages, Knockback, }; use serde::{Deserialize, Serialize}; use specs::{Component, FlaggedStorage, VecStorage}; @@ -158,7 +158,7 @@ pub struct Attacking { pub max_angle: f32, pub applied: bool, pub hit_count: u32, - pub knockback: f32, + pub knockback: Knockback, } impl Component for Attacking { diff --git a/common/src/comp/inventory/item/tool.rs b/common/src/comp/inventory/item/tool.rs index c1b7833d55..78d0d40e96 100644 --- a/common/src/comp/inventory/item/tool.rs +++ b/common/src/comp/inventory/item/tool.rs @@ -4,7 +4,7 @@ use crate::{ comp::{body::object, projectile, Body, CharacterAbility, Gravity, LightEmitter, Projectile}, states::combo_melee, - Damage, Damages, Explosion, + Damage, Damages, Explosion, Knockback, }; use serde::{Deserialize, Serialize}; use std::time::Duration; @@ -302,7 +302,7 @@ impl Tool { Some(Damage::Projectile(40.0 * self.base_power())), None, )), - projectile::Effect::Knockback(10.0), + projectile::Effect::Knockback(Knockback::Away(10.0)), projectile::Effect::RewardEnergy(50), projectile::Effect::Vanish, ], @@ -345,8 +345,7 @@ impl Tool { Some(Damage::Projectile(40.0 * self.base_power())), None, )), - projectile::Effect::Knockback(10.0), - projectile::Effect::RewardEnergy(50), + projectile::Effect::Knockback(Knockback::Away(10.0)), projectile::Effect::Vanish, ], time_left: Duration::from_secs(15), @@ -489,7 +488,7 @@ impl Tool { swing_duration: Duration::from_millis(100), recover_duration: Duration::from_millis(300), damage: (200.0 * self.base_power()) as u32, - knockback: 25.0, + knockback: Knockback::Away(25.0), shockwave_angle: 360.0, shockwave_vertical_angle: 90.0, shockwave_speed: 20.0, @@ -530,7 +529,7 @@ impl Tool { swing_duration: Duration::from_millis(200), recover_duration: Duration::from_millis(800), damage: 500, - knockback: -40.0, + knockback: Knockback::TowardsUp(40.0), shockwave_angle: 90.0, shockwave_vertical_angle: 15.0, shockwave_speed: 20.0, diff --git a/common/src/comp/projectile.rs b/common/src/comp/projectile.rs index 121a6bdbb9..3b5888a456 100644 --- a/common/src/comp/projectile.rs +++ b/common/src/comp/projectile.rs @@ -1,4 +1,4 @@ -use crate::{sync::Uid, Damages, Explosion}; +use crate::{sync::Uid, Damages, Explosion, Knockback}; use serde::{Deserialize, Serialize}; use specs::{Component, FlaggedStorage}; use specs_idvs::IdvStorage; @@ -7,7 +7,7 @@ use std::time::Duration; #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] pub enum Effect { Damages(Damages), - Knockback(f32), + Knockback(Knockback), RewardEnergy(u32), Explode(Explosion), Vanish, diff --git a/common/src/comp/shockwave.rs b/common/src/comp/shockwave.rs index 15161bc673..2d5de87726 100644 --- a/common/src/comp/shockwave.rs +++ b/common/src/comp/shockwave.rs @@ -1,4 +1,4 @@ -use crate::{sync::Uid, Damages}; +use crate::{sync::Uid, Damages, Knockback}; use serde::{Deserialize, Serialize}; use specs::{Component, FlaggedStorage}; use specs_idvs::IdvStorage; @@ -10,7 +10,7 @@ pub struct Properties { pub vertical_angle: f32, pub speed: f32, pub damages: Damages, - pub knockback: f32, + pub knockback: Knockback, pub requires_ground: bool, pub duration: Duration, pub owner: Option, diff --git a/common/src/lib.rs b/common/src/lib.rs index 407328bd66..01b986408a 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -52,6 +52,6 @@ pub mod util; pub mod vol; pub mod volumes; -pub use combat::{Damage, Damages}; +pub use combat::{Damage, Damages, Knockback}; pub use explosion::Explosion; pub use loadout_builder::LoadoutBuilder; diff --git a/common/src/states/basic_melee.rs b/common/src/states/basic_melee.rs index e99ec7a03d..744c30c3b8 100644 --- a/common/src/states/basic_melee.rs +++ b/common/src/states/basic_melee.rs @@ -2,7 +2,7 @@ use crate::{ comp::{Attacking, CharacterState, EnergySource, StateUpdate}, states::utils::*, sys::character_behavior::{CharacterBehavior, JoinData}, - Damage, Damages, + Damage, Damages, Knockback, }; use serde::{Deserialize, Serialize}; use std::time::Duration; @@ -88,7 +88,7 @@ impl CharacterBehavior for Data { max_angle: 180_f32.to_radians(), applied: false, hit_count: 0, - knockback: self.static_data.knockback, + knockback: Knockback::Away(self.static_data.knockback), }); } else if self.timer < self.static_data.swing_duration { // Swings diff --git a/common/src/states/charged_melee.rs b/common/src/states/charged_melee.rs index 62f5b3e3fe..0da5ada515 100644 --- a/common/src/states/charged_melee.rs +++ b/common/src/states/charged_melee.rs @@ -2,7 +2,7 @@ use crate::{ comp::{Attacking, CharacterState, EnergySource, StateUpdate}, states::utils::{StageSection, *}, sys::character_behavior::*, - Damage, Damages, + Damage, Damages, Knockback, }; use serde::{Deserialize, Serialize}; use std::time::Duration; @@ -130,7 +130,7 @@ impl CharacterBehavior for Data { max_angle: self.static_data.max_angle.to_radians(), applied: false, hit_count: 0, - knockback, + knockback: Knockback::Away(knockback), }); // Starts swinging diff --git a/common/src/states/charged_ranged.rs b/common/src/states/charged_ranged.rs index 5805338bc8..3b19fa8268 100644 --- a/common/src/states/charged_ranged.rs +++ b/common/src/states/charged_ranged.rs @@ -6,7 +6,7 @@ use crate::{ event::ServerEvent, states::utils::*, sys::character_behavior::{CharacterBehavior, JoinData}, - Damage, Damages, + Damage, Damages, Knockback, }; use serde::{Deserialize, Serialize}; use std::time::Duration; @@ -102,7 +102,7 @@ impl CharacterBehavior for Data { Some(Damage::Projectile(damage)), None, )), - projectile::Effect::Knockback(knockback), + projectile::Effect::Knockback(Knockback::Away(knockback)), projectile::Effect::Vanish, ], time_left: Duration::from_secs(15), diff --git a/common/src/states/combo_melee.rs b/common/src/states/combo_melee.rs index bf5610a5e4..4ae0d24efd 100644 --- a/common/src/states/combo_melee.rs +++ b/common/src/states/combo_melee.rs @@ -2,7 +2,7 @@ use crate::{ comp::{Attacking, CharacterState, EnergySource, StateUpdate}, states::utils::*, sys::character_behavior::{CharacterBehavior, JoinData}, - Damage, Damages, + Damage, Damages, Knockback, }; use serde::{Deserialize, Serialize}; use std::time::Duration; @@ -137,7 +137,9 @@ impl CharacterBehavior for Data { max_angle: self.static_data.stage_data[stage_index].angle.to_radians(), applied: false, hit_count: 0, - knockback: self.static_data.stage_data[stage_index].knockback, + knockback: Knockback::Away( + self.static_data.stage_data[stage_index].knockback, + ), }); } }, diff --git a/common/src/states/dash_melee.rs b/common/src/states/dash_melee.rs index f117dc19b4..fbd83a2652 100644 --- a/common/src/states/dash_melee.rs +++ b/common/src/states/dash_melee.rs @@ -2,7 +2,7 @@ use crate::{ comp::{Attacking, CharacterState, EnergySource, StateUpdate}, states::utils::*, sys::character_behavior::{CharacterBehavior, JoinData}, - Damage, Damages, + Damage, Damages, Knockback, }; use serde::{Deserialize, Serialize}; use std::time::Duration; @@ -135,7 +135,7 @@ impl CharacterBehavior for Data { max_angle: self.static_data.angle.to_radians(), applied: false, hit_count: 0, - knockback, + knockback: Knockback::Away(knockback), }); } update.character = CharacterState::DashMelee(Data { diff --git a/common/src/states/leap_melee.rs b/common/src/states/leap_melee.rs index 1df206992a..d6b6f297af 100644 --- a/common/src/states/leap_melee.rs +++ b/common/src/states/leap_melee.rs @@ -2,7 +2,7 @@ use crate::{ comp::{Attacking, CharacterState, StateUpdate}, states::utils::{StageSection, *}, sys::character_behavior::{CharacterBehavior, JoinData}, - Damage, Damages, + Damage, Damages, Knockback, }; use serde::{Deserialize, Serialize}; use std::time::Duration; @@ -150,7 +150,7 @@ impl CharacterBehavior for Data { max_angle: self.static_data.max_angle.to_radians(), applied: false, hit_count: 0, - knockback: self.static_data.knockback, + knockback: Knockback::Away(self.static_data.knockback), }); update.character = CharacterState::LeapMelee(Data { diff --git a/common/src/states/shockwave.rs b/common/src/states/shockwave.rs index ab3c72e905..a9bb69cd07 100644 --- a/common/src/states/shockwave.rs +++ b/common/src/states/shockwave.rs @@ -3,7 +3,7 @@ use crate::{ event::ServerEvent, states::utils::*, sys::character_behavior::{CharacterBehavior, JoinData}, - Damage, Damages, + Damage, Damages, Knockback, }; use serde::{Deserialize, Serialize}; use std::time::Duration; @@ -20,7 +20,7 @@ pub struct StaticData { /// Base damage pub damage: u32, /// Knockback - pub knockback: f32, + pub knockback: Knockback, /// Angle of the shockwave pub shockwave_angle: f32, /// Vertical angle of the shockwave diff --git a/common/src/states/spin_melee.rs b/common/src/states/spin_melee.rs index 168b71cab7..73765d1607 100644 --- a/common/src/states/spin_melee.rs +++ b/common/src/states/spin_melee.rs @@ -5,7 +5,7 @@ use crate::{ character_behavior::{CharacterBehavior, JoinData}, phys::GRAVITY, }, - Damage, Damages, + Damage, Damages, Knockback, }; use serde::{Deserialize, Serialize}; use std::time::Duration; @@ -119,7 +119,7 @@ impl CharacterBehavior for Data { max_angle: 180_f32.to_radians(), applied: false, hit_count: 0, - knockback: self.static_data.knockback, + knockback: Knockback::Away(self.static_data.knockback), }); } else if self.timer < self.static_data.swing_duration { if !self.static_data.is_helicopter { diff --git a/common/src/sys/melee.rs b/common/src/sys/melee.rs index 66d2c20b32..35b77e8b61 100644 --- a/common/src/sys/melee.rs +++ b/common/src/sys/melee.rs @@ -150,12 +150,11 @@ impl<'a> System<'a> for Sys { attack.hit_count += 1; } - if attack.knockback != 0.0 && change.amount != 0 { + if change.amount != 0 { let kb_dir = Dir::new((pos_b.0 - pos.0).try_normalized().unwrap_or(*ori.0)); server_emitter.emit(ServerEvent::Knockback { entity: b, - impulse: attack.knockback - * *Dir::slerp(kb_dir, Dir::new(Vec3::new(0.0, 0.0, 1.0)), 0.5), + impulse: attack.knockback.get_knockback(kb_dir), }); } } diff --git a/common/src/sys/projectile.rs b/common/src/sys/projectile.rs index 59d8e8cbe2..725919c551 100644 --- a/common/src/sys/projectile.rs +++ b/common/src/sys/projectile.rs @@ -8,13 +8,11 @@ use crate::{ span, state::DeltaTime, sync::UidAllocator, - util::Dir, }; use specs::{ saveload::MarkerAllocator, Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage, }; use std::time::Duration; -use vek::*; /// This system is responsible for handling projectile effect triggers pub struct Sys; @@ -125,8 +123,7 @@ impl<'a> System<'a> for Sys { { local_emitter.emit(LocalEvent::ApplyImpulse { entity, - impulse: knockback - * *Dir::slerp(ori.0, Dir::new(Vec3::unit_z()), 0.5), + impulse: knockback.get_knockback(ori.0), }); } }, diff --git a/common/src/sys/shockwave.rs b/common/src/sys/shockwave.rs index dbdea44459..35a24691a7 100644 --- a/common/src/sys/shockwave.rs +++ b/common/src/sys/shockwave.rs @@ -212,17 +212,11 @@ impl<'a> System<'a> for Sys { change, }); shockwave_hit_list.hit_entities.push(*uid_b); - } - if shockwave.knockback != 0.0 { let kb_dir = Dir::new((pos_b.0 - pos.0).try_normalized().unwrap_or(*ori.0)); - let impulse = if shockwave.knockback < 0.0 { - shockwave.knockback - * *Dir::slerp(kb_dir, Dir::new(Vec3::new(0.0, 0.0, -1.0)), 0.85) - } else { - shockwave.knockback - * *Dir::slerp(kb_dir, Dir::new(Vec3::new(0.0, 0.0, 1.0)), 0.5) - }; - server_emitter.emit(ServerEvent::Knockback { entity: b, impulse }); + server_emitter.emit(ServerEvent::Knockback { + entity: b, + impulse: shockwave.knockback.get_knockback(kb_dir), + }); } } } diff --git a/common/src/util/dir.rs b/common/src/util/dir.rs index af9a29ced0..30cb4cfe07 100644 --- a/common/src/util/dir.rs +++ b/common/src/util/dir.rs @@ -98,6 +98,13 @@ impl std::ops::Deref for Dir { impl From> for Dir { fn from(dir: Vec3) -> Self { Dir::new(dir) } } + +impl std::ops::Neg for Dir { + type Output = Dir; + + fn neg(self) -> Dir { Dir::new(-self.0) } +} + /// Begone ye NaN's /// Slerp two `Vec3`s skipping the slerp if their directions are very close /// This avoids a case where `vek`s slerp produces NaN's