Make arrows deal damage

This commit is contained in:
timokoesters 2019-09-21 14:43:24 +02:00
parent 1288a1ab65
commit c34d18f73f
No known key found for this signature in database
GPG Key ID: CD80BE9AAEE78097
6 changed files with 45 additions and 9 deletions

View File

@ -1,3 +1,4 @@
use crate::state::Uid;
use specs::{Component, FlaggedStorage, NullStorage}; use specs::{Component, FlaggedStorage, NullStorage};
use specs_idvs::IDVStorage; use specs_idvs::IDVStorage;
use vek::*; use vek::*;
@ -47,6 +48,7 @@ impl Component for Mass {
pub struct PhysicsState { pub struct PhysicsState {
pub on_ground: bool, pub on_ground: bool,
pub on_wall: Option<Vec3<f32>>, pub on_wall: Option<Vec3<f32>>,
pub touch_entity: Option<Uid>,
pub in_fluid: bool, pub in_fluid: bool,
} }

View File

@ -5,6 +5,7 @@ use specs_idvs::IDVStorage;
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
pub enum HealthSource { pub enum HealthSource {
Attack { by: Uid }, // TODO: Implement weapon Attack { by: Uid }, // TODO: Implement weapon
Projectile,
Suicide, Suicide,
World, World,
Revive, Revive,

View File

@ -1,6 +1,7 @@
use crate::comp; use crate::comp;
use parking_lot::Mutex; use parking_lot::Mutex;
use specs::Entity as EcsEntity; use specs::Entity as EcsEntity;
use sphynx::Uid;
use std::{collections::VecDeque, ops::DerefMut}; use std::{collections::VecDeque, ops::DerefMut};
use vek::*; use vek::*;
@ -25,6 +26,11 @@ pub enum ServerEvent {
pos: Vec3<f32>, pos: Vec3<f32>,
radius: f32, radius: f32,
}, },
Damage {
uid: Uid,
power: u32,
cause: comp::HealthSource,
},
Destroy { Destroy {
entity: EcsEntity, entity: EcsEntity,
cause: comp::HealthSource, cause: comp::HealthSource,

View File

@ -7,6 +7,7 @@ use {
vol::ReadVol, vol::ReadVol,
}, },
specs::{Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage}, specs::{Entities, Join, Read, ReadExpect, ReadStorage, System, WriteStorage},
sphynx::Uid,
vek::*, vek::*,
}; };
@ -41,6 +42,7 @@ pub struct Sys;
impl<'a> System<'a> for Sys { impl<'a> System<'a> for Sys {
type SystemData = ( type SystemData = (
Entities<'a>, Entities<'a>,
ReadStorage<'a, Uid>,
ReadExpect<'a, TerrainGrid>, ReadExpect<'a, TerrainGrid>,
Read<'a, DeltaTime>, Read<'a, DeltaTime>,
Read<'a, EventBus<LocalEvent>>, Read<'a, EventBus<LocalEvent>>,
@ -58,6 +60,7 @@ impl<'a> System<'a> for Sys {
&mut self, &mut self,
( (
entities, entities,
uids,
terrain, terrain,
dt, dt,
event_bus, event_bus,
@ -322,19 +325,21 @@ impl<'a> System<'a> for Sys {
} }
// Apply pushback // Apply pushback
for (pos, scale, mass, vel, _, _) in ( for (pos, scale, mass, vel, _, _, physics) in (
&positions, &positions,
scales.maybe(), scales.maybe(),
masses.maybe(), masses.maybe(),
&mut velocities, &mut velocities,
&bodies, &bodies,
!&mountings, !&mountings,
&mut physics_states,
) )
.join() .join()
{ {
let scale = scale.map(|s| s.0).unwrap_or(1.0); let scale = scale.map(|s| s.0).unwrap_or(1.0);
let mass = mass.map(|m| m.0).unwrap_or(scale); 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, &positions,
scales.maybe(), scales.maybe(),
masses.maybe(), masses.maybe(),
@ -357,6 +362,7 @@ impl<'a> System<'a> for Sys {
let force = (collision_dist - diff.magnitude()) * 2.0 * mass_other let force = (collision_dist - diff.magnitude()) * 2.0 * mass_other
/ (mass + mass_other); / (mass + mass_other);
vel.0 += Vec3::from(diff.normalized()) * force; vel.0 += Vec3::from(diff.normalized()) * force;
physics.touch_entity = Some(*other);
} }
} }
} }

View File

@ -19,9 +19,9 @@ impl<'a> System<'a> for Sys {
Read<'a, DeltaTime>, Read<'a, DeltaTime>,
Read<'a, EventBus<ServerEvent>>, Read<'a, EventBus<ServerEvent>>,
ReadStorage<'a, Pos>, ReadStorage<'a, Pos>,
ReadStorage<'a, Ori>,
ReadStorage<'a, Vel>, ReadStorage<'a, Vel>,
ReadStorage<'a, PhysicsState>, ReadStorage<'a, PhysicsState>,
WriteStorage<'a, Ori>,
WriteStorage<'a, Projectile>, WriteStorage<'a, Projectile>,
WriteStorage<'a, Stats>, WriteStorage<'a, Stats>,
); );
@ -35,8 +35,8 @@ impl<'a> System<'a> for Sys {
server_bus, server_bus,
positions, positions,
velocities, velocities,
orientations,
physics_states, physics_states,
mut orientations,
mut projectiles, mut projectiles,
mut stats, mut stats,
): Self::SystemData, ): Self::SystemData,
@ -44,17 +44,19 @@ impl<'a> System<'a> for Sys {
let mut server_emitter = server_bus.emitter(); let mut server_emitter = server_bus.emitter();
// Attacks // Attacks
for (entity, uid, pos, velocity, ori, physics, projectile) in ( for (entity, uid, pos, vel, physics, ori, projectile) in (
&entities, &entities,
&uids, &uids,
&positions, &positions,
&velocities, &velocities,
&orientations,
&physics_states, &physics_states,
&mut orientations,
&mut projectiles, &mut projectiles,
) )
.join() .join()
{ {
ori.0 = vel.0.normalized();
// Hit ground // Hit ground
if physics.on_ground { if physics.on_ground {
for effect in projectile.hit_ground.drain(..) { for effect in projectile.hit_ground.drain(..) {
@ -67,10 +69,17 @@ impl<'a> System<'a> for Sys {
} }
} }
} }
// TODO: Check entity hit // Hit entity
if false { if let Some(other) = physics.touch_entity {
for effect in projectile.hit_entity.drain(..) { for effect in projectile.hit_entity.drain(..) {
match effect { 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 { projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy {
entity, entity,
cause: HealthSource::World, cause: HealthSource::World,

View File

@ -304,12 +304,24 @@ impl Server {
comp::Body::Object(comp::object::Body::Arrow), comp::Body::Object(comp::object::Body::Arrow),
comp::Projectile { comp::Projectile {
hit_ground: vec![comp::projectile::Effect::Vanish], hit_ground: vec![comp::projectile::Effect::Vanish],
hit_entity: vec![], hit_entity: vec![
comp::projectile::Effect::Damage(10),
comp::projectile::Effect::Vanish,
],
}, },
) )
.build(); .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::<comp::Stats>().get_mut(entity) {
stats.health.change_by(-(power as i32), cause);
}
}
}
ServerEvent::Destroy { entity, cause } => { ServerEvent::Destroy { entity, cause } => {
let ecs = state.ecs_mut(); let ecs = state.ecs_mut();
// Chat message // Chat message