Make arrows deal damage

This commit is contained in:
timokoesters 2019-09-21 14:43:24 +02:00
parent e3c02f8ac1
commit 2ba143a514
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_idvs::IDVStorage;
use vek::*;
@ -47,6 +48,7 @@ impl Component for Mass {
pub struct PhysicsState {
pub on_ground: bool,
pub on_wall: Option<Vec3<f32>>,
pub touch_entity: Option<Uid>,
pub in_fluid: bool,
}

View File

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

View File

@ -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<f32>,
radius: f32,
},
Damage {
uid: Uid,
power: u32,
cause: comp::HealthSource,
},
Destroy {
entity: EcsEntity,
cause: comp::HealthSource,

View File

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

View File

@ -19,9 +19,9 @@ impl<'a> System<'a> for Sys {
Read<'a, DeltaTime>,
Read<'a, EventBus<ServerEvent>>,
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,

View File

@ -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::<comp::Stats>().get_mut(entity) {
stats.health.change_by(-(power as i32), cause);
}
}
}
ServerEvent::Destroy { entity, cause } => {
let ecs = state.ecs_mut();
// Chat message