mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added entity event system, fixed fall damage
This commit is contained in:
parent
2fb8306b98
commit
98a913195b
30
common/src/comp/event.rs
Normal file
30
common/src/comp/event.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use specs::Component;
|
||||
use specs_idvs::IDVStorage;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use vek::*;
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct Events(pub Vec<EntityEvent>);
|
||||
|
||||
impl Deref for Events {
|
||||
type Target = Vec<EntityEvent>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for Events {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Component for Events {
|
||||
type Storage = IDVStorage<Self>;
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum EntityEvent {
|
||||
HitGround { vel: Vec3<f32> },
|
||||
}
|
@ -3,6 +3,7 @@ mod agent;
|
||||
mod animation;
|
||||
mod body;
|
||||
mod controller;
|
||||
mod event;
|
||||
mod inputs;
|
||||
mod inventory;
|
||||
mod last;
|
||||
@ -17,6 +18,7 @@ pub use agent::Agent;
|
||||
pub use animation::{Animation, AnimationInfo};
|
||||
pub use body::{humanoid, object, quadruped, quadruped_medium, Body};
|
||||
pub use controller::Controller;
|
||||
pub use event::{EntityEvent, Events};
|
||||
pub use inputs::{
|
||||
Attacking, CanBuild, Gliding, Jumping, MoveDir, OnGround, Respawning, Rolling, Wielding,
|
||||
};
|
||||
|
@ -161,6 +161,7 @@ impl State {
|
||||
ecs.register::<comp::ForceUpdate>();
|
||||
ecs.register::<comp::InventoryUpdate>();
|
||||
ecs.register::<comp::Inventory>();
|
||||
ecs.register::<comp::Events>();
|
||||
// Controller effects
|
||||
ecs.register::<comp::MoveDir>();
|
||||
ecs.register::<comp::OnGround>();
|
||||
|
33
common/src/sys/event_handler.rs
Normal file
33
common/src/sys/event_handler.rs
Normal file
@ -0,0 +1,33 @@
|
||||
use crate::{
|
||||
comp::{EntityEvent, Events, HealthSource, Stats},
|
||||
state::DeltaTime,
|
||||
};
|
||||
use log::warn;
|
||||
use specs::{Entities, Join, Read, System, WriteStorage};
|
||||
|
||||
/// This system kills players
|
||||
pub struct Sys;
|
||||
impl<'a> System<'a> for Sys {
|
||||
type SystemData = (
|
||||
Entities<'a>,
|
||||
WriteStorage<'a, Events>,
|
||||
WriteStorage<'a, Stats>,
|
||||
);
|
||||
|
||||
fn run(&mut self, (entities, mut events, mut stats): Self::SystemData) {
|
||||
for (entity, mut events) in (&entities, &mut events).join() {
|
||||
for event in events.drain(..) {
|
||||
match event {
|
||||
EntityEvent::HitGround { vel } => {
|
||||
if let Some(stat) = stats.get_mut(entity) {
|
||||
let falldmg = (vel.z / 1.5 + 6.0) as i32;
|
||||
if falldmg < 0 {
|
||||
stat.health.change_by(falldmg, HealthSource::World);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ pub mod agent;
|
||||
pub mod animation;
|
||||
pub mod combat;
|
||||
pub mod controller;
|
||||
mod event_handler;
|
||||
pub mod movement;
|
||||
pub mod phys;
|
||||
mod stats;
|
||||
@ -19,6 +20,7 @@ const MOVEMENT_SYS: &str = "movement_sys";
|
||||
const COMBAT_SYS: &str = "combat_sys";
|
||||
const ANIMATION_SYS: &str = "animation_sys";
|
||||
const STATS_SYS: &str = "stats_sys";
|
||||
const EVENT_HANDLER_SYS: &str = "event_handler_sys";
|
||||
|
||||
pub fn add_local_systems(dispatch_builder: &mut DispatcherBuilder) {
|
||||
dispatch_builder.add(agent::Sys, AGENT_SYS, &[]);
|
||||
@ -33,4 +35,9 @@ pub fn add_local_systems(dispatch_builder: &mut DispatcherBuilder) {
|
||||
dispatch_builder.add(combat::Sys, COMBAT_SYS, &[ACTION_STATE_SYS]);
|
||||
dispatch_builder.add(animation::Sys, ANIMATION_SYS, &[ACTION_STATE_SYS]);
|
||||
dispatch_builder.add(stats::Sys, STATS_SYS, &[COMBAT_SYS]);
|
||||
dispatch_builder.add(
|
||||
event_handler::Sys,
|
||||
EVENT_HANDLER_SYS,
|
||||
&[AGENT_SYS, PHYS_SYS, ACTION_STATE_SYS, COMBAT_SYS],
|
||||
);
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
use crate::{
|
||||
comp::HealthSource,
|
||||
comp::{
|
||||
ActionState, Body, Jumping, MoveDir, OnGround, Ori, Pos, Rolling, Scale, Stats, Vel,
|
||||
Wielding,
|
||||
ActionState, Body, EntityEvent, Events, Jumping, MoveDir, OnGround, Ori, Pos, Rolling,
|
||||
Scale, Stats, Vel, Wielding,
|
||||
},
|
||||
state::DeltaTime,
|
||||
terrain::TerrainMap,
|
||||
@ -42,7 +42,7 @@ impl<'a> System<'a> for Sys {
|
||||
WriteStorage<'a, Pos>,
|
||||
WriteStorage<'a, Vel>,
|
||||
WriteStorage<'a, Ori>,
|
||||
WriteStorage<'a, Stats>,
|
||||
WriteStorage<'a, Events>,
|
||||
);
|
||||
|
||||
fn run(
|
||||
@ -58,11 +58,11 @@ impl<'a> System<'a> for Sys {
|
||||
mut positions,
|
||||
mut velocities,
|
||||
mut orientations,
|
||||
mut stats,
|
||||
mut events,
|
||||
): Self::SystemData,
|
||||
) {
|
||||
// Apply movement inputs
|
||||
for (entity, a, scale, b, mut pos, mut vel, mut ori, mut stat) in (
|
||||
for (entity, a, scale, b, mut pos, mut vel, mut ori) in (
|
||||
&entities,
|
||||
&action_states,
|
||||
scales.maybe(),
|
||||
@ -70,7 +70,6 @@ impl<'a> System<'a> for Sys {
|
||||
&mut positions,
|
||||
&mut velocities,
|
||||
&mut orientations,
|
||||
&mut stats,
|
||||
)
|
||||
.join()
|
||||
{
|
||||
@ -210,12 +209,18 @@ impl<'a> System<'a> for Sys {
|
||||
|
||||
// When the resolution direction is pointing upwards, we must be on the ground
|
||||
if resolve_dir.z > 0.0 && vel.0.z <= 0.0 {
|
||||
// Check for fall damage
|
||||
let falldmg = (vel.0.z / 1.5 + 6.0) as i32;
|
||||
if falldmg < 0 {
|
||||
stat.health.change_by(falldmg, HealthSource::World);
|
||||
}
|
||||
on_ground = true;
|
||||
|
||||
// Hitting the ground
|
||||
const COLLISION_VEL: f32 = GRAVITY * 0.75; // Falling for 0.75 seconds
|
||||
if vel.0.z < -COLLISION_VEL {
|
||||
if events.get(entity).is_none() {
|
||||
events.insert(entity, Events::default());
|
||||
}
|
||||
events
|
||||
.get_mut(entity) // TODO: Use get_mut_or_default when updating to SPECS 15
|
||||
.map(|e| e.push(EntityEvent::HitGround { vel: vel.0 }));
|
||||
}
|
||||
}
|
||||
|
||||
// When the resolution direction is non-vertical, we must be colliding with a wall
|
||||
|
Loading…
Reference in New Issue
Block a user