From 2ba143a51456aa6bdf583c49ffbd72de491b93ea Mon Sep 17 00:00:00 2001 From: timokoesters Date: Sat, 21 Sep 2019 14:43:24 +0200 Subject: [PATCH] Make arrows deal damage --- common/src/comp/phys.rs | 2 ++ common/src/comp/stats.rs | 1 + common/src/event.rs | 6 ++++++ common/src/sys/phys.rs | 10 ++++++++-- common/src/sys/projectile.rs | 21 +++++++++++++++------ server/src/lib.rs | 14 +++++++++++++- 6 files changed, 45 insertions(+), 9 deletions(-) diff --git a/common/src/comp/phys.rs b/common/src/comp/phys.rs index eb22625800..41d4b9bf19 100644 --- a/common/src/comp/phys.rs +++ b/common/src/comp/phys.rs @@ -1,3 +1,4 @@ +use crate::state::Uid; use specs::{Component, FlaggedStorage, NullStorage}; use specs_idvs::IDVStorage; use vek::*; @@ -47,6 +48,7 @@ impl Component for Mass { pub struct PhysicsState { pub on_ground: bool, pub on_wall: Option>, + pub touch_entity: Option, pub in_fluid: bool, } diff --git a/common/src/comp/stats.rs b/common/src/comp/stats.rs index 1a97e59ae8..37adfed283 100644 --- a/common/src/comp/stats.rs +++ b/common/src/comp/stats.rs @@ -5,6 +5,7 @@ use specs_idvs::IDVStorage; #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] pub enum HealthSource { Attack { by: Uid }, // TODO: Implement weapon + Projectile, Suicide, World, Revive, diff --git a/common/src/event.rs b/common/src/event.rs index 3c743ca952..4a94817a32 100644 --- a/common/src/event.rs +++ b/common/src/event.rs @@ -1,6 +1,7 @@ use crate::comp; use parking_lot::Mutex; use specs::Entity as EcsEntity; +use sphynx::Uid; use std::{collections::VecDeque, ops::DerefMut}; use vek::*; @@ -25,6 +26,11 @@ pub enum ServerEvent { pos: Vec3, radius: f32, }, + Damage { + uid: Uid, + power: u32, + cause: comp::HealthSource, + }, Destroy { entity: EcsEntity, cause: comp::HealthSource, diff --git a/common/src/sys/phys.rs b/common/src/sys/phys.rs index e63234a5c1..cafebf1694 100644 --- a/common/src/sys/phys.rs +++ b/common/src/sys/phys.rs @@ -7,6 +7,7 @@ use { vol::ReadVol, }, specs::{Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage}, + sphynx::Uid, vek::*, }; @@ -41,6 +42,7 @@ pub struct Sys; impl<'a> System<'a> for Sys { type SystemData = ( Entities<'a>, + ReadStorage<'a, Uid>, ReadExpect<'a, TerrainGrid>, Read<'a, DeltaTime>, Read<'a, EventBus>, @@ -58,6 +60,7 @@ impl<'a> System<'a> for Sys { &mut self, ( entities, + uids, terrain, dt, event_bus, @@ -322,19 +325,21 @@ impl<'a> System<'a> for Sys { } // Apply pushback - for (pos, scale, mass, vel, _, _) in ( + for (pos, scale, mass, vel, _, _, physics) in ( &positions, scales.maybe(), masses.maybe(), &mut velocities, &bodies, !&mountings, + &mut physics_states, ) .join() { let scale = scale.map(|s| s.0).unwrap_or(1.0); let mass = mass.map(|m| m.0).unwrap_or(scale); - for (pos_other, scale_other, mass_other, _, _) in ( + for (other, pos_other, scale_other, mass_other, _, _) in ( + &uids, &positions, scales.maybe(), masses.maybe(), @@ -357,6 +362,7 @@ impl<'a> System<'a> for Sys { let force = (collision_dist - diff.magnitude()) * 2.0 * mass_other / (mass + mass_other); vel.0 += Vec3::from(diff.normalized()) * force; + physics.touch_entity = Some(*other); } } } diff --git a/common/src/sys/projectile.rs b/common/src/sys/projectile.rs index 0d9d84a8b9..4c9ee95452 100644 --- a/common/src/sys/projectile.rs +++ b/common/src/sys/projectile.rs @@ -19,9 +19,9 @@ impl<'a> System<'a> for Sys { Read<'a, DeltaTime>, Read<'a, EventBus>, ReadStorage<'a, Pos>, - ReadStorage<'a, Ori>, ReadStorage<'a, Vel>, ReadStorage<'a, PhysicsState>, + WriteStorage<'a, Ori>, WriteStorage<'a, Projectile>, WriteStorage<'a, Stats>, ); @@ -35,8 +35,8 @@ impl<'a> System<'a> for Sys { server_bus, positions, velocities, - orientations, physics_states, + mut orientations, mut projectiles, mut stats, ): Self::SystemData, @@ -44,17 +44,19 @@ impl<'a> System<'a> for Sys { let mut server_emitter = server_bus.emitter(); // Attacks - for (entity, uid, pos, velocity, ori, physics, projectile) in ( + for (entity, uid, pos, vel, physics, ori, projectile) in ( &entities, &uids, &positions, &velocities, - &orientations, &physics_states, + &mut orientations, &mut projectiles, ) .join() { + ori.0 = vel.0.normalized(); + // Hit ground if physics.on_ground { for effect in projectile.hit_ground.drain(..) { @@ -67,10 +69,17 @@ impl<'a> System<'a> for Sys { } } } - // TODO: Check entity hit - if false { + // Hit entity + if let Some(other) = physics.touch_entity { for effect in projectile.hit_entity.drain(..) { match effect { + projectile::Effect::Damage(power) => { + server_emitter.emit(ServerEvent::Damage { + uid: other, + power, + cause: HealthSource::Projectile, + }) + } projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy { entity, cause: HealthSource::World, diff --git a/server/src/lib.rs b/server/src/lib.rs index 7e0ecc4e5c..84f71b80f4 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -304,12 +304,24 @@ impl Server { comp::Body::Object(comp::object::Body::Arrow), comp::Projectile { hit_ground: vec![comp::projectile::Effect::Vanish], - hit_entity: vec![], + hit_entity: vec![ + comp::projectile::Effect::Damage(10), + comp::projectile::Effect::Vanish, + ], }, ) .build(); } + ServerEvent::Damage { uid, power, cause } => { + let ecs = state.ecs_mut(); + if let Some(entity) = ecs.entity_from_uid(uid.into()) { + if let Some(stats) = ecs.write_storage::().get_mut(entity) { + stats.health.change_by(-(power as i32), cause); + } + } + } + ServerEvent::Destroy { entity, cause } => { let ecs = state.ecs_mut(); // Chat message