Transitioned knockback to an enum.

This commit is contained in:
Sam 2020-10-18 13:21:58 -05:00
parent 1ccbdec35c
commit 981eee5936
19 changed files with 71 additions and 47 deletions

View File

@ -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<f32> {
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)
},
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -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<Uid>,

View File

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

View File

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

View File

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

View File

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

View File

@ -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,
),
});
}
},

View File

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

View File

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

View File

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

View File

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

View File

@ -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),
});
}
}

View File

@ -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),
});
}
},

View File

@ -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),
});
}
}
}

View File

@ -98,6 +98,13 @@ impl std::ops::Deref for Dir {
impl From<Vec3<f32>> for Dir {
fn from(dir: Vec3<f32>) -> 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