mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Allow projectiles to react to triggers
This commit is contained in:
parent
39e5530d45
commit
e3c02f8ac1
@ -9,6 +9,7 @@ mod last;
|
||||
mod location;
|
||||
mod phys;
|
||||
mod player;
|
||||
pub mod projectile;
|
||||
mod stats;
|
||||
mod visual;
|
||||
|
||||
@ -24,5 +25,6 @@ pub use last::Last;
|
||||
pub use location::Waypoint;
|
||||
pub use phys::{ForceUpdate, Mass, Ori, PhysicsState, Pos, Scale, Vel};
|
||||
pub use player::Player;
|
||||
pub use projectile::Projectile;
|
||||
pub use stats::{Equipment, Exp, HealthSource, Level, Stats};
|
||||
pub use visual::LightEmitter;
|
||||
|
18
common/src/comp/projectile.rs
Normal file
18
common/src/comp/projectile.rs
Normal file
@ -0,0 +1,18 @@
|
||||
use specs::{Component, FlaggedStorage, NullStorage};
|
||||
use specs_idvs::IDVStorage;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub enum Effect {
|
||||
Damage(u32),
|
||||
Vanish,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Projectile {
|
||||
pub hit_ground: Vec<Effect>,
|
||||
pub hit_entity: Vec<Effect>,
|
||||
}
|
||||
|
||||
impl Component for Projectile {
|
||||
type Storage = FlaggedStorage<Self, IDVStorage<Self>>;
|
||||
}
|
@ -25,7 +25,7 @@ pub enum ServerEvent {
|
||||
pos: Vec3<f32>,
|
||||
radius: f32,
|
||||
},
|
||||
Die {
|
||||
Destroy {
|
||||
entity: EcsEntity,
|
||||
cause: comp::HealthSource,
|
||||
},
|
||||
|
@ -157,6 +157,7 @@ impl State {
|
||||
ecs.register::<comp::Inventory>();
|
||||
ecs.register::<comp::Admin>();
|
||||
ecs.register::<comp::Waypoint>();
|
||||
ecs.register::<comp::Projectile>();
|
||||
|
||||
// Register synced resources used by the ECS.
|
||||
ecs.insert_synced(TimeOfDay(0.0));
|
||||
|
@ -4,6 +4,7 @@ pub mod combat;
|
||||
pub mod controller;
|
||||
pub mod movement;
|
||||
pub mod phys;
|
||||
mod projectile;
|
||||
mod stats;
|
||||
|
||||
// External
|
||||
@ -14,6 +15,7 @@ const AGENT_SYS: &str = "agent_sys";
|
||||
const CONTROLLER_SYS: &str = "controller_sys";
|
||||
const PHYS_SYS: &str = "phys_sys";
|
||||
const MOVEMENT_SYS: &str = "movement_sys";
|
||||
const PROJECTILE_SYS: &str = "projectile_sys";
|
||||
const COMBAT_SYS: &str = "combat_sys";
|
||||
const STATS_SYS: &str = "stats_sys";
|
||||
const CLEANUP_SYS: &str = "cleanup_sys";
|
||||
@ -22,7 +24,8 @@ pub fn add_local_systems(dispatch_builder: &mut DispatcherBuilder) {
|
||||
dispatch_builder.add(agent::Sys, AGENT_SYS, &[]);
|
||||
dispatch_builder.add(controller::Sys, CONTROLLER_SYS, &[AGENT_SYS]);
|
||||
dispatch_builder.add(movement::Sys, MOVEMENT_SYS, &[]);
|
||||
dispatch_builder.add(combat::Sys, COMBAT_SYS, &[CONTROLLER_SYS]);
|
||||
dispatch_builder.add(projectile::Sys, PROJECTILE_SYS, &[CONTROLLER_SYS]);
|
||||
dispatch_builder.add(combat::Sys, COMBAT_SYS, &[PROJECTILE_SYS]);
|
||||
dispatch_builder.add(stats::Sys, STATS_SYS, &[COMBAT_SYS]);
|
||||
dispatch_builder.add(
|
||||
phys::Sys,
|
||||
|
84
common/src/sys/projectile.rs
Normal file
84
common/src/sys/projectile.rs
Normal file
@ -0,0 +1,84 @@
|
||||
use crate::{
|
||||
comp::{
|
||||
projectile, ActionState::*, CharacterState, Controller, ForceUpdate, HealthSource, Ori,
|
||||
PhysicsState, Pos, Projectile, Stats, Vel,
|
||||
},
|
||||
event::{EventBus, ServerEvent},
|
||||
state::{DeltaTime, Uid},
|
||||
};
|
||||
use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage};
|
||||
use std::time::Duration;
|
||||
use vek::*;
|
||||
|
||||
/// This system is responsible for handling projectile effect triggers
|
||||
pub struct Sys;
|
||||
impl<'a> System<'a> for Sys {
|
||||
type SystemData = (
|
||||
Entities<'a>,
|
||||
ReadStorage<'a, Uid>,
|
||||
Read<'a, DeltaTime>,
|
||||
Read<'a, EventBus<ServerEvent>>,
|
||||
ReadStorage<'a, Pos>,
|
||||
ReadStorage<'a, Ori>,
|
||||
ReadStorage<'a, Vel>,
|
||||
ReadStorage<'a, PhysicsState>,
|
||||
WriteStorage<'a, Projectile>,
|
||||
WriteStorage<'a, Stats>,
|
||||
);
|
||||
|
||||
fn run(
|
||||
&mut self,
|
||||
(
|
||||
entities,
|
||||
uids,
|
||||
dt,
|
||||
server_bus,
|
||||
positions,
|
||||
velocities,
|
||||
orientations,
|
||||
physics_states,
|
||||
mut projectiles,
|
||||
mut stats,
|
||||
): Self::SystemData,
|
||||
) {
|
||||
let mut server_emitter = server_bus.emitter();
|
||||
|
||||
// Attacks
|
||||
for (entity, uid, pos, velocity, ori, physics, projectile) in (
|
||||
&entities,
|
||||
&uids,
|
||||
&positions,
|
||||
&velocities,
|
||||
&orientations,
|
||||
&physics_states,
|
||||
&mut projectiles,
|
||||
)
|
||||
.join()
|
||||
{
|
||||
// Hit ground
|
||||
if physics.on_ground {
|
||||
for effect in projectile.hit_ground.drain(..) {
|
||||
match effect {
|
||||
projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy {
|
||||
entity,
|
||||
cause: HealthSource::World,
|
||||
}),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: Check entity hit
|
||||
if false {
|
||||
for effect in projectile.hit_entity.drain(..) {
|
||||
match effect {
|
||||
projectile::Effect::Vanish => server_emitter.emit(ServerEvent::Destroy {
|
||||
entity,
|
||||
cause: HealthSource::World,
|
||||
}),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -21,7 +21,7 @@ impl<'a> System<'a> for Sys {
|
||||
|
||||
for (entity, mut stat) in (&entities, &mut stats).join() {
|
||||
if stat.should_die() && !stat.is_dead {
|
||||
event_emitter.emit(ServerEvent::Die {
|
||||
event_emitter.emit(ServerEvent::Destroy {
|
||||
entity,
|
||||
cause: match stat.health.last_change {
|
||||
Some(change) => change.2,
|
||||
|
@ -203,6 +203,7 @@ impl Server {
|
||||
pos: comp::Pos,
|
||||
vel: comp::Vel,
|
||||
body: comp::Body,
|
||||
projectile: comp::Projectile,
|
||||
) -> EcsEntityBuilder {
|
||||
state
|
||||
.ecs_mut()
|
||||
@ -211,6 +212,7 @@ impl Server {
|
||||
.with(vel)
|
||||
.with(comp::Ori(Vec3::unit_y()))
|
||||
.with(body)
|
||||
.with(projectile)
|
||||
}
|
||||
|
||||
pub fn create_player_character(
|
||||
@ -288,7 +290,7 @@ impl Server {
|
||||
}
|
||||
}
|
||||
|
||||
ServerEvent::Shoot(entity, dir) => {
|
||||
ServerEvent::Shoot(entity, dir /*, projectile*/) => {
|
||||
let pos = state
|
||||
.ecs()
|
||||
.read_storage::<comp::Pos>()
|
||||
@ -300,11 +302,15 @@ impl Server {
|
||||
comp::Pos(pos),
|
||||
comp::Vel(dir * 100.0),
|
||||
comp::Body::Object(comp::object::Body::Arrow),
|
||||
comp::Projectile {
|
||||
hit_ground: vec![comp::projectile::Effect::Vanish],
|
||||
hit_entity: vec![],
|
||||
},
|
||||
)
|
||||
.build();
|
||||
}
|
||||
|
||||
ServerEvent::Die { entity, cause } => {
|
||||
ServerEvent::Destroy { entity, cause } => {
|
||||
let ecs = state.ecs_mut();
|
||||
// Chat message
|
||||
if let Some(player) = ecs.read_storage::<comp::Player>().get(entity) {
|
||||
@ -327,7 +333,7 @@ impl Server {
|
||||
clients.notify_registered(ServerMsg::kill(msg));
|
||||
}
|
||||
|
||||
// Give EXP to the client
|
||||
// Give EXP to the killer if entity had stats
|
||||
let mut stats = ecs.write_storage::<comp::Stats>();
|
||||
|
||||
if let Some(entity_stats) = stats.get(entity).cloned() {
|
||||
|
Loading…
Reference in New Issue
Block a user