mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Addressed comments. Roll now only provides i-frames to melee attacks. It also reduces height of hitbox.
This commit is contained in:
parent
66850a5878
commit
37ecb165ef
@ -28,7 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Buff system
|
- Buff system
|
||||||
- Sneaking lets you be closer to enemies without being detected
|
- Sneaking lets you be closer to enemies without being detected
|
||||||
- Flight
|
- Flight
|
||||||
- Roll has i-frames
|
- Roll dodges melee attacks, and reduces the height of your hitbox
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
@ -119,9 +119,6 @@ pub enum CharacterAbility {
|
|||||||
movement_duration: Duration,
|
movement_duration: Duration,
|
||||||
recover_duration: Duration,
|
recover_duration: Duration,
|
||||||
roll_strength: f32,
|
roll_strength: f32,
|
||||||
buildup_iframes: bool,
|
|
||||||
movement_iframes: bool,
|
|
||||||
recover_iframes: bool,
|
|
||||||
},
|
},
|
||||||
ComboMelee {
|
ComboMelee {
|
||||||
stage_data: Vec<combo_melee::Stage>,
|
stage_data: Vec<combo_melee::Stage>,
|
||||||
@ -278,6 +275,16 @@ impl CharacterAbility {
|
|||||||
_ => true,
|
_ => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn default_roll() -> CharacterAbility {
|
||||||
|
CharacterAbility::Roll {
|
||||||
|
energy_cost: 100,
|
||||||
|
buildup_duration: Duration::from_millis(100),
|
||||||
|
movement_duration: Duration::from_millis(250),
|
||||||
|
recover_duration: Duration::from_millis(150),
|
||||||
|
roll_strength: 2.5,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
|
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
|
||||||
@ -302,7 +309,7 @@ impl From<Item> for ItemConfig {
|
|||||||
ability2: ability_drain.next(),
|
ability2: ability_drain.next(),
|
||||||
ability3: ability_drain.next(),
|
ability3: ability_drain.next(),
|
||||||
block_ability: None,
|
block_ability: None,
|
||||||
dodge_ability: Some(get_roll()),
|
dodge_ability: Some(CharacterAbility::default_roll()),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,19 +317,6 @@ impl From<Item> for ItemConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_roll() -> CharacterAbility {
|
|
||||||
CharacterAbility::Roll {
|
|
||||||
energy_cost: 100,
|
|
||||||
buildup_duration: Duration::from_millis(100),
|
|
||||||
movement_duration: Duration::from_millis(250),
|
|
||||||
recover_duration: Duration::from_millis(150),
|
|
||||||
roll_strength: 2.5,
|
|
||||||
buildup_iframes: true,
|
|
||||||
movement_iframes: true,
|
|
||||||
recover_iframes: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Arraygen, Clone, PartialEq, Default, Debug, Serialize, Deserialize)]
|
#[derive(Arraygen, Clone, PartialEq, Default, Debug, Serialize, Deserialize)]
|
||||||
#[gen_array(pub fn get_armor: &Option<Item>)]
|
#[gen_array(pub fn get_armor: &Option<Item>)]
|
||||||
pub struct Loadout {
|
pub struct Loadout {
|
||||||
@ -488,18 +482,12 @@ impl From<(&CharacterAbility, AbilityKey)> for CharacterState {
|
|||||||
movement_duration,
|
movement_duration,
|
||||||
recover_duration,
|
recover_duration,
|
||||||
roll_strength,
|
roll_strength,
|
||||||
buildup_iframes,
|
|
||||||
movement_iframes,
|
|
||||||
recover_iframes,
|
|
||||||
} => CharacterState::Roll(roll::Data {
|
} => CharacterState::Roll(roll::Data {
|
||||||
static_data: roll::StaticData {
|
static_data: roll::StaticData {
|
||||||
buildup_duration: *buildup_duration,
|
buildup_duration: *buildup_duration,
|
||||||
movement_duration: *movement_duration,
|
movement_duration: *movement_duration,
|
||||||
recover_duration: *recover_duration,
|
recover_duration: *recover_duration,
|
||||||
roll_strength: *roll_strength,
|
roll_strength: *roll_strength,
|
||||||
buildup_iframes: *buildup_iframes,
|
|
||||||
movement_iframes: *movement_iframes,
|
|
||||||
recover_iframes: *recover_iframes,
|
|
||||||
},
|
},
|
||||||
timer: Duration::default(),
|
timer: Duration::default(),
|
||||||
stage_section: StageSection::Buildup,
|
stage_section: StageSection::Buildup,
|
||||||
|
@ -145,20 +145,6 @@ impl CharacterState {
|
|||||||
// Check if state is the same without looking at the inner data
|
// Check if state is the same without looking at the inner data
|
||||||
std::mem::discriminant(self) == std::mem::discriminant(other)
|
std::mem::discriminant(self) == std::mem::discriminant(other)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_invincible(&self) -> bool {
|
|
||||||
if let CharacterState::Roll(data) = self {
|
|
||||||
use utils::StageSection;
|
|
||||||
match data.stage_section {
|
|
||||||
StageSection::Buildup => data.static_data.buildup_iframes,
|
|
||||||
StageSection::Movement => data.static_data.movement_iframes,
|
|
||||||
StageSection::Recover => data.static_data.recover_iframes,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for CharacterState {
|
impl Default for CharacterState {
|
||||||
|
@ -73,9 +73,9 @@ impl Collider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_z_limits(&self) -> (f32, f32) {
|
pub fn get_z_limits(&self, modifier: f32) -> (f32, f32) {
|
||||||
match self {
|
match self {
|
||||||
Collider::Box { z_min, z_max, .. } => (*z_min, *z_max),
|
Collider::Box { z_min, z_max, .. } => (*z_min * modifier, *z_max * modifier),
|
||||||
Collider::Point => (0.0, 0.0),
|
Collider::Point => (0.0, 0.0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,14 +15,8 @@ pub struct StaticData {
|
|||||||
pub movement_duration: Duration,
|
pub movement_duration: Duration,
|
||||||
/// How long it takes to recover from roll
|
/// How long it takes to recover from roll
|
||||||
pub recover_duration: Duration,
|
pub recover_duration: Duration,
|
||||||
/// How strong the roll is
|
/// Affects the speed and distance of the roll
|
||||||
pub roll_strength: f32,
|
pub roll_strength: f32,
|
||||||
/// Whether you are immune to damage in buildup
|
|
||||||
pub buildup_iframes: bool,
|
|
||||||
/// Whether you are immune to damage in movement
|
|
||||||
pub movement_iframes: bool,
|
|
||||||
/// Whether you are immune to damage in recover
|
|
||||||
pub recover_iframes: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{
|
comp::{
|
||||||
group, Beam, BeamSegment, Body, CharacterState, Energy, EnergyChange, EnergySource, Health,
|
group, Beam, BeamSegment, Body, Energy, EnergyChange, EnergySource, Health, HealthChange,
|
||||||
HealthChange, HealthSource, Last, Loadout, Ori, Pos, Scale,
|
HealthSource, Last, Loadout, Ori, Pos, Scale,
|
||||||
},
|
},
|
||||||
event::{EventBus, ServerEvent},
|
event::{EventBus, ServerEvent},
|
||||||
state::{DeltaTime, Time},
|
state::{DeltaTime, Time},
|
||||||
@ -34,7 +34,6 @@ impl<'a> System<'a> for Sys {
|
|||||||
ReadStorage<'a, Energy>,
|
ReadStorage<'a, Energy>,
|
||||||
WriteStorage<'a, BeamSegment>,
|
WriteStorage<'a, BeamSegment>,
|
||||||
WriteStorage<'a, Beam>,
|
WriteStorage<'a, Beam>,
|
||||||
ReadStorage<'a, CharacterState>,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
@ -57,7 +56,6 @@ impl<'a> System<'a> for Sys {
|
|||||||
energies,
|
energies,
|
||||||
mut beam_segments,
|
mut beam_segments,
|
||||||
mut beams,
|
mut beams,
|
||||||
char_states,
|
|
||||||
): Self::SystemData,
|
): Self::SystemData,
|
||||||
) {
|
) {
|
||||||
let mut server_emitter = server_bus.emitter();
|
let mut server_emitter = server_bus.emitter();
|
||||||
@ -114,16 +112,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Go through all other effectable entities
|
// Go through all other effectable entities
|
||||||
for (
|
for (b, uid_b, pos_b, last_pos_b_maybe, scale_b_maybe, health_b, body_b) in (
|
||||||
b,
|
|
||||||
uid_b,
|
|
||||||
pos_b,
|
|
||||||
last_pos_b_maybe,
|
|
||||||
scale_b_maybe,
|
|
||||||
health_b,
|
|
||||||
body_b,
|
|
||||||
char_state_b_maybe,
|
|
||||||
) in (
|
|
||||||
&entities,
|
&entities,
|
||||||
&uids,
|
&uids,
|
||||||
&positions,
|
&positions,
|
||||||
@ -132,7 +121,6 @@ impl<'a> System<'a> for Sys {
|
|||||||
scales.maybe(),
|
scales.maybe(),
|
||||||
&healths,
|
&healths,
|
||||||
&bodies,
|
&bodies,
|
||||||
char_states.maybe(),
|
|
||||||
)
|
)
|
||||||
.join()
|
.join()
|
||||||
{
|
{
|
||||||
@ -146,9 +134,6 @@ impl<'a> System<'a> for Sys {
|
|||||||
let rad_b = body_b.radius() * scale_b;
|
let rad_b = body_b.radius() * scale_b;
|
||||||
let height_b = body_b.height() * scale_b;
|
let height_b = body_b.height() * scale_b;
|
||||||
|
|
||||||
// Check if entity is immune to damage
|
|
||||||
let is_invincible = char_state_b_maybe.map_or(false, |c_s| c_s.is_invincible());
|
|
||||||
|
|
||||||
// Check if it is a hit
|
// Check if it is a hit
|
||||||
let hit = entity != b
|
let hit = entity != b
|
||||||
&& !health_b.is_dead
|
&& !health_b.is_dead
|
||||||
@ -175,9 +160,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
|
|
||||||
for (target, damage) in beam_segment.damages.iter() {
|
for (target, damage) in beam_segment.damages.iter() {
|
||||||
if let Some(target) = target {
|
if let Some(target) = target {
|
||||||
if *target != target_group
|
if *target != target_group {
|
||||||
|| (!matches!(target, GroupTarget::InGroup) && is_invincible)
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,8 +94,8 @@ impl<'a> System<'a> for Sys {
|
|||||||
let scale_b = scale_b_maybe.map_or(1.0, |s| s.0);
|
let scale_b = scale_b_maybe.map_or(1.0, |s| s.0);
|
||||||
let rad_b = body_b.radius() * scale_b;
|
let rad_b = body_b.radius() * scale_b;
|
||||||
|
|
||||||
// Check if entity is invincible
|
// Check if entity is dodging
|
||||||
let is_invincible = char_state_b_maybe.map_or(false, |c_s| c_s.is_invincible());
|
let is_dodge = char_state_b_maybe.map_or(false, |c_s| c_s.is_dodge());
|
||||||
|
|
||||||
// Check if it is a hit
|
// Check if it is a hit
|
||||||
if entity != b
|
if entity != b
|
||||||
@ -119,7 +119,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
for (target, damage) in attack.damages.iter() {
|
for (target, damage) in attack.damages.iter() {
|
||||||
if let Some(target) = target {
|
if let Some(target) = target {
|
||||||
if *target != target_group
|
if *target != target_group
|
||||||
|| (!matches!(target, GroupTarget::InGroup) && is_invincible)
|
|| (!matches!(target, GroupTarget::InGroup) && is_dodge)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{
|
comp::{
|
||||||
BeamSegment, Collider, Gravity, Mass, Mounting, Ori, PhysicsState, Pos, PreviousVelDtCache,
|
BeamSegment, CharacterState, Collider, Gravity, Mass, Mounting, Ori, PhysicsState, Pos,
|
||||||
Projectile, Scale, Shockwave, Sticky, Vel,
|
PreviousVelDtCache, Projectile, Scale, Shockwave, Sticky, Vel,
|
||||||
},
|
},
|
||||||
event::{EventBus, ServerEvent},
|
event::{EventBus, ServerEvent},
|
||||||
metrics::{PhysicsMetrics, SysMetrics},
|
metrics::{PhysicsMetrics, SysMetrics},
|
||||||
@ -71,6 +71,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
ReadStorage<'a, Projectile>,
|
ReadStorage<'a, Projectile>,
|
||||||
ReadStorage<'a, BeamSegment>,
|
ReadStorage<'a, BeamSegment>,
|
||||||
ReadStorage<'a, Shockwave>,
|
ReadStorage<'a, Shockwave>,
|
||||||
|
ReadStorage<'a, CharacterState>,
|
||||||
);
|
);
|
||||||
|
|
||||||
#[allow(clippy::or_fun_call)] // TODO: Pending review in #587
|
#[allow(clippy::or_fun_call)] // TODO: Pending review in #587
|
||||||
@ -99,6 +100,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
projectiles,
|
projectiles,
|
||||||
beams,
|
beams,
|
||||||
shockwaves,
|
shockwaves,
|
||||||
|
char_states,
|
||||||
): Self::SystemData,
|
): Self::SystemData,
|
||||||
) {
|
) {
|
||||||
let start_time = std::time::Instant::now();
|
let start_time = std::time::Instant::now();
|
||||||
@ -183,17 +185,38 @@ impl<'a> System<'a> for Sys {
|
|||||||
// TODO: if we need to avoid collisions for other things consider moving whether it
|
// TODO: if we need to avoid collisions for other things consider moving whether it
|
||||||
// should interact into the collider component or into a separate component
|
// should interact into the collider component or into a separate component
|
||||||
projectiles.maybe(),
|
projectiles.maybe(),
|
||||||
|
char_states.maybe(),
|
||||||
)
|
)
|
||||||
.par_join()
|
.par_join()
|
||||||
.filter(|(_, _, _, _, _, _, _, _, sticky, physics, _)| {
|
.filter(|(_, _, _, _, _, _, _, _, sticky, physics, _, _)| {
|
||||||
sticky.is_none() || (physics.on_wall.is_none() && !physics.on_ground)
|
sticky.is_none() || (physics.on_wall.is_none() && !physics.on_ground)
|
||||||
})
|
})
|
||||||
.map(|(e, p, v, vd, s, m, c, _, _, ph, pr)| (e, p, v, vd, s, m, c, ph, pr))
|
.map(|(e, p, v, vd, s, m, c, _, _, ph, pr, c_s)| (e, p, v, vd, s, m, c, ph, pr, c_s))
|
||||||
.fold(PhysicsMetrics::default,
|
.fold(
|
||||||
|mut metrics,(entity, pos, vel, vel_dt, scale, mass, collider, physics, projectile)| {
|
PhysicsMetrics::default,
|
||||||
|
|mut metrics,
|
||||||
|
(
|
||||||
|
entity,
|
||||||
|
pos,
|
||||||
|
vel,
|
||||||
|
vel_dt,
|
||||||
|
scale,
|
||||||
|
mass,
|
||||||
|
collider,
|
||||||
|
physics,
|
||||||
|
projectile,
|
||||||
|
char_state_maybe,
|
||||||
|
)| {
|
||||||
let scale = scale.map(|s| s.0).unwrap_or(1.0);
|
let scale = scale.map(|s| s.0).unwrap_or(1.0);
|
||||||
let radius = collider.map(|c| c.get_radius()).unwrap_or(0.5);
|
let radius = collider.map(|c| c.get_radius()).unwrap_or(0.5);
|
||||||
let z_limits = collider.map(|c| c.get_z_limits()).unwrap_or((-0.5, 0.5));
|
let modifier = if char_state_maybe.map_or(false, |c_s| c_s.is_dodge()) {
|
||||||
|
0.5
|
||||||
|
} else {
|
||||||
|
1.0
|
||||||
|
};
|
||||||
|
let z_limits = collider
|
||||||
|
.map(|c| c.get_z_limits(modifier))
|
||||||
|
.unwrap_or((-0.5 * modifier, 0.5 * modifier));
|
||||||
let mass = mass.map(|m| m.0).unwrap_or(scale);
|
let mass = mass.map(|m| m.0).unwrap_or(scale);
|
||||||
|
|
||||||
// Resets touch_entities in physics
|
// Resets touch_entities in physics
|
||||||
@ -215,6 +238,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
_,
|
_,
|
||||||
_,
|
_,
|
||||||
_,
|
_,
|
||||||
|
char_state_other_maybe,
|
||||||
) in (
|
) in (
|
||||||
&entities,
|
&entities,
|
||||||
&uids,
|
&uids,
|
||||||
@ -227,6 +251,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
!&mountings,
|
!&mountings,
|
||||||
!&beams,
|
!&beams,
|
||||||
!&shockwaves,
|
!&shockwaves,
|
||||||
|
char_states.maybe(),
|
||||||
)
|
)
|
||||||
.join()
|
.join()
|
||||||
{
|
{
|
||||||
@ -240,13 +265,22 @@ impl<'a> System<'a> for Sys {
|
|||||||
let collision_dist = scale * radius + scale_other * radius_other;
|
let collision_dist = scale * radius + scale_other * radius_other;
|
||||||
|
|
||||||
// Sanity check: skip colliding entities that are too far from each other
|
// Sanity check: skip colliding entities that are too far from each other
|
||||||
if (pos.0 - pos_other.0).xy().magnitude() > (vel_dt.0 - vel_dt_other.0).xy().magnitude() + collision_dist {
|
if (pos.0 - pos_other.0).xy().magnitude()
|
||||||
|
> (vel_dt.0 - vel_dt_other.0).xy().magnitude() + collision_dist
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let modifier_other =
|
||||||
|
if char_state_other_maybe.map_or(false, |c_s| c_s.is_dodge()) {
|
||||||
|
0.5
|
||||||
|
} else {
|
||||||
|
1.0
|
||||||
|
};
|
||||||
|
|
||||||
let z_limits_other = collider_other
|
let z_limits_other = collider_other
|
||||||
.map(|c| c.get_z_limits())
|
.map(|c| c.get_z_limits(modifier_other))
|
||||||
.unwrap_or((-0.5, 0.5));
|
.unwrap_or((-0.5 * modifier_other, 0.5 * modifier_other));
|
||||||
let mass_other = mass_other.map(|m| m.0).unwrap_or(scale_other);
|
let mass_other = mass_other.map(|m| m.0).unwrap_or(scale_other);
|
||||||
//This check after the pos check, as we currently don't have that many
|
//This check after the pos check, as we currently don't have that many
|
||||||
// massless entites [citation needed]
|
// massless entites [citation needed]
|
||||||
@ -257,7 +291,8 @@ impl<'a> System<'a> for Sys {
|
|||||||
metrics.entity_entity_collision_checks += 1;
|
metrics.entity_entity_collision_checks += 1;
|
||||||
|
|
||||||
const MIN_COLLISION_DIST: f32 = 0.3;
|
const MIN_COLLISION_DIST: f32 = 0.3;
|
||||||
let increments = ((vel_dt.0 - vel_dt_other.0).magnitude() / MIN_COLLISION_DIST)
|
let increments = ((vel_dt.0 - vel_dt_other.0).magnitude()
|
||||||
|
/ MIN_COLLISION_DIST)
|
||||||
.max(1.0)
|
.max(1.0)
|
||||||
.ceil() as usize;
|
.ceil() as usize;
|
||||||
let step_delta = 1.0 / increments as f32;
|
let step_delta = 1.0 / increments as f32;
|
||||||
@ -300,11 +335,11 @@ impl<'a> System<'a> for Sys {
|
|||||||
metrics
|
metrics
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.reduce(PhysicsMetrics::default, |old, new| {
|
.reduce(PhysicsMetrics::default, |old, new| PhysicsMetrics {
|
||||||
PhysicsMetrics {
|
entity_entity_collision_checks: old.entity_entity_collision_checks
|
||||||
entity_entity_collision_checks: old.entity_entity_collision_checks + new.entity_entity_collision_checks,
|
+ new.entity_entity_collision_checks,
|
||||||
entity_entity_collisions: old.entity_entity_collisions + new.entity_entity_collisions,
|
entity_entity_collisions: old.entity_entity_collisions
|
||||||
}
|
+ new.entity_entity_collisions,
|
||||||
});
|
});
|
||||||
physics_metrics.entity_entity_collision_checks = metrics.entity_entity_collision_checks;
|
physics_metrics.entity_entity_collision_checks = metrics.entity_entity_collision_checks;
|
||||||
physics_metrics.entity_entity_collisions = metrics.entity_entity_collisions;
|
physics_metrics.entity_entity_collisions = metrics.entity_entity_collisions;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{
|
comp::{
|
||||||
buff::{BuffChange, BuffSource},
|
buff::{BuffChange, BuffSource},
|
||||||
projectile, CharacterState, EnergyChange, EnergySource, Group, HealthSource, Loadout, Ori,
|
projectile, EnergyChange, EnergySource, Group, HealthSource, Loadout, Ori, PhysicsState,
|
||||||
PhysicsState, Pos, Projectile, Vel,
|
Pos, Projectile, Vel,
|
||||||
},
|
},
|
||||||
event::{EventBus, LocalEvent, ServerEvent},
|
event::{EventBus, LocalEvent, ServerEvent},
|
||||||
metrics::SysMetrics,
|
metrics::SysMetrics,
|
||||||
@ -35,7 +35,6 @@ impl<'a> System<'a> for Sys {
|
|||||||
WriteStorage<'a, Projectile>,
|
WriteStorage<'a, Projectile>,
|
||||||
ReadStorage<'a, Loadout>,
|
ReadStorage<'a, Loadout>,
|
||||||
ReadStorage<'a, Group>,
|
ReadStorage<'a, Group>,
|
||||||
ReadStorage<'a, CharacterState>,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
@ -54,7 +53,6 @@ impl<'a> System<'a> for Sys {
|
|||||||
mut projectiles,
|
mut projectiles,
|
||||||
loadouts,
|
loadouts,
|
||||||
groups,
|
groups,
|
||||||
char_states,
|
|
||||||
): Self::SystemData,
|
): Self::SystemData,
|
||||||
) {
|
) {
|
||||||
let start_time = std::time::Instant::now();
|
let start_time = std::time::Instant::now();
|
||||||
@ -104,18 +102,6 @@ impl<'a> System<'a> for Sys {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks if entity is immune to damage
|
|
||||||
// TODO: When projectiles are reduced down to a collection of (target, effect)s,
|
|
||||||
// move this check there so that future projectiles intended for allies cannot
|
|
||||||
// be dodged by those allies
|
|
||||||
let entity_invincible = uid_allocator
|
|
||||||
.retrieve_entity_internal(other.into())
|
|
||||||
.and_then(|e| char_states.get(e))
|
|
||||||
.map_or(false, |c_s| c_s.is_invincible());
|
|
||||||
if entity_invincible {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for effect in projectile.hit_entity.drain(..) {
|
for effect in projectile.hit_entity.drain(..) {
|
||||||
match effect {
|
match effect {
|
||||||
projectile::Effect::Damage(target, damage) => {
|
projectile::Effect::Damage(target, damage) => {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{
|
comp::{
|
||||||
group, Body, CharacterState, Health, HealthSource, Last, Loadout, Ori, PhysicsState, Pos,
|
group, Body, Health, HealthSource, Last, Loadout, Ori, PhysicsState, Pos, Scale, Shockwave,
|
||||||
Scale, Shockwave, ShockwaveHitEntities,
|
ShockwaveHitEntities,
|
||||||
},
|
},
|
||||||
event::{EventBus, LocalEvent, ServerEvent},
|
event::{EventBus, LocalEvent, ServerEvent},
|
||||||
state::{DeltaTime, Time},
|
state::{DeltaTime, Time},
|
||||||
@ -36,7 +36,6 @@ impl<'a> System<'a> for Sys {
|
|||||||
ReadStorage<'a, PhysicsState>,
|
ReadStorage<'a, PhysicsState>,
|
||||||
WriteStorage<'a, Shockwave>,
|
WriteStorage<'a, Shockwave>,
|
||||||
WriteStorage<'a, ShockwaveHitEntities>,
|
WriteStorage<'a, ShockwaveHitEntities>,
|
||||||
ReadStorage<'a, CharacterState>,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
@ -60,7 +59,6 @@ impl<'a> System<'a> for Sys {
|
|||||||
physics_states,
|
physics_states,
|
||||||
mut shockwaves,
|
mut shockwaves,
|
||||||
mut shockwave_hit_lists,
|
mut shockwave_hit_lists,
|
||||||
char_states,
|
|
||||||
): Self::SystemData,
|
): Self::SystemData,
|
||||||
) {
|
) {
|
||||||
let mut server_emitter = server_bus.emitter();
|
let mut server_emitter = server_bus.emitter();
|
||||||
@ -133,7 +131,6 @@ impl<'a> System<'a> for Sys {
|
|||||||
health_b,
|
health_b,
|
||||||
body_b,
|
body_b,
|
||||||
physics_state_b,
|
physics_state_b,
|
||||||
char_state_b_maybe,
|
|
||||||
) in (
|
) in (
|
||||||
&entities,
|
&entities,
|
||||||
&uids,
|
&uids,
|
||||||
@ -144,7 +141,6 @@ impl<'a> System<'a> for Sys {
|
|||||||
&healths,
|
&healths,
|
||||||
&bodies,
|
&bodies,
|
||||||
&physics_states,
|
&physics_states,
|
||||||
char_states.maybe(),
|
|
||||||
)
|
)
|
||||||
.join()
|
.join()
|
||||||
{
|
{
|
||||||
@ -180,9 +176,6 @@ impl<'a> System<'a> for Sys {
|
|||||||
GroupTarget::OutOfGroup
|
GroupTarget::OutOfGroup
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check if entity is immune to damage
|
|
||||||
let is_invincible = char_state_b_maybe.map_or(false, |c_s| c_s.is_invincible());
|
|
||||||
|
|
||||||
// Check if it is a hit
|
// Check if it is a hit
|
||||||
let hit = entity != b
|
let hit = entity != b
|
||||||
&& !health_b.is_dead
|
&& !health_b.is_dead
|
||||||
@ -200,9 +193,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
if hit {
|
if hit {
|
||||||
for (target, damage) in shockwave.damages.iter() {
|
for (target, damage) in shockwave.damages.iter() {
|
||||||
if let Some(target) = target {
|
if let Some(target) = target {
|
||||||
if *target != target_group
|
if *target != target_group {
|
||||||
|| (!matches!(target, GroupTarget::InGroup) && is_invincible)
|
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -647,14 +647,7 @@ pub fn handle_explosion(
|
|||||||
.get(entity_b)
|
.get(entity_b)
|
||||||
.map_or(false, |h| !h.is_dead);
|
.map_or(false, |h| !h.is_dead);
|
||||||
|
|
||||||
let is_invincible = ecs
|
if is_alive {
|
||||||
.read_storage::<comp::CharacterState>()
|
|
||||||
.get(entity_b)
|
|
||||||
.map_or(false, |c_s| c_s.is_invincible());
|
|
||||||
|
|
||||||
if is_alive
|
|
||||||
&& (matches!(target, Some(GroupTarget::InGroup)) || !is_invincible)
|
|
||||||
{
|
|
||||||
effect.modify_strength(strength);
|
effect.modify_strength(strength);
|
||||||
server.state().apply_effect(entity_b, effect, owner);
|
server.state().apply_effect(entity_b, effect, owner);
|
||||||
// Apply energy change
|
// Apply energy change
|
||||||
|
@ -158,9 +158,6 @@ fn maps_roll() {
|
|||||||
movement_duration: Duration::default(),
|
movement_duration: Duration::default(),
|
||||||
recover_duration: Duration::default(),
|
recover_duration: Duration::default(),
|
||||||
roll_strength: 0.0,
|
roll_strength: 0.0,
|
||||||
buildup_iframes: false,
|
|
||||||
movement_iframes: false,
|
|
||||||
recover_iframes: false,
|
|
||||||
},
|
},
|
||||||
timer: Duration::default(),
|
timer: Duration::default(),
|
||||||
stage_section: states::utils::StageSection::Buildup,
|
stage_section: states::utils::StageSection::Buildup,
|
||||||
|
Loading…
Reference in New Issue
Block a user