mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fix double roll bug
This commit is contained in:
parent
b0ea959f67
commit
c80351f6ca
@ -374,11 +374,13 @@ impl Client {
|
|||||||
pos,
|
pos,
|
||||||
vel,
|
vel,
|
||||||
ori,
|
ori,
|
||||||
|
action_state,
|
||||||
} => match self.state.ecs().entity_from_uid(entity) {
|
} => match self.state.ecs().entity_from_uid(entity) {
|
||||||
Some(entity) => {
|
Some(entity) => {
|
||||||
self.state.write_component(entity, pos);
|
self.state.write_component(entity, pos);
|
||||||
self.state.write_component(entity, vel);
|
self.state.write_component(entity, vel);
|
||||||
self.state.write_component(entity, ori);
|
self.state.write_component(entity, ori);
|
||||||
|
self.state.write_component(entity, action_state);
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
},
|
},
|
||||||
|
26
common/src/comp/action_state.rs
Normal file
26
common/src/comp/action_state.rs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
use specs::{Component, FlaggedStorage, NullStorage, VecStorage};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct ActionState {
|
||||||
|
pub moving: bool,
|
||||||
|
pub on_ground: bool,
|
||||||
|
pub attacking: bool,
|
||||||
|
pub rolling: bool,
|
||||||
|
pub gliding: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ActionState {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
moving: false,
|
||||||
|
on_ground: false,
|
||||||
|
attacking: false,
|
||||||
|
rolling: false,
|
||||||
|
gliding: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Component for ActionState {
|
||||||
|
type Storage = FlaggedStorage<Self, VecStorage<Self>>;
|
||||||
|
}
|
@ -7,6 +7,7 @@ mod inventory;
|
|||||||
mod phys;
|
mod phys;
|
||||||
mod player;
|
mod player;
|
||||||
mod stats;
|
mod stats;
|
||||||
|
mod action_state;
|
||||||
|
|
||||||
// Reexports
|
// Reexports
|
||||||
pub use agent::Agent;
|
pub use agent::Agent;
|
||||||
@ -18,3 +19,4 @@ pub use inventory::{item, Inventory};
|
|||||||
pub use phys::{ForceUpdate, Ori, Pos, Vel};
|
pub use phys::{ForceUpdate, Ori, Pos, Vel};
|
||||||
pub use player::Player;
|
pub use player::Player;
|
||||||
pub use stats::{Dying, HealthSource, Stats};
|
pub use stats::{Dying, HealthSource, Stats};
|
||||||
|
pub use action_state::ActionState;
|
||||||
|
@ -23,9 +23,6 @@ sphynx::sum_type! {
|
|||||||
Actor(comp::Actor),
|
Actor(comp::Actor),
|
||||||
Player(comp::Player),
|
Player(comp::Player),
|
||||||
Stats(comp::Stats),
|
Stats(comp::Stats),
|
||||||
Attacking(comp::Attacking),
|
|
||||||
Rolling(comp::Rolling),
|
|
||||||
Gliding(comp::Gliding),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Automatically derive From<T> for EcsCompPhantom
|
// Automatically derive From<T> for EcsCompPhantom
|
||||||
@ -39,9 +36,6 @@ sphynx::sum_type! {
|
|||||||
Actor(PhantomData<comp::Actor>),
|
Actor(PhantomData<comp::Actor>),
|
||||||
Player(PhantomData<comp::Player>),
|
Player(PhantomData<comp::Player>),
|
||||||
Stats(PhantomData<comp::Stats>),
|
Stats(PhantomData<comp::Stats>),
|
||||||
Attacking(PhantomData<comp::Attacking>),
|
|
||||||
Rolling(PhantomData<comp::Rolling>),
|
|
||||||
Gliding(PhantomData<comp::Gliding>),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl sphynx::CompPacket for EcsCompPacket {
|
impl sphynx::CompPacket for EcsCompPacket {
|
||||||
|
@ -35,6 +35,7 @@ pub enum ServerMsg {
|
|||||||
pos: comp::Pos,
|
pos: comp::Pos,
|
||||||
vel: comp::Vel,
|
vel: comp::Vel,
|
||||||
ori: comp::Ori,
|
ori: comp::Ori,
|
||||||
|
action_state: comp::ActionState,
|
||||||
},
|
},
|
||||||
TerrainChunkUpdate {
|
TerrainChunkUpdate {
|
||||||
key: Vec2<i32>,
|
key: Vec2<i32>,
|
||||||
|
@ -102,9 +102,6 @@ impl State {
|
|||||||
ecs.register_synced::<comp::Actor>();
|
ecs.register_synced::<comp::Actor>();
|
||||||
ecs.register_synced::<comp::Player>();
|
ecs.register_synced::<comp::Player>();
|
||||||
ecs.register_synced::<comp::Stats>();
|
ecs.register_synced::<comp::Stats>();
|
||||||
ecs.register_synced::<comp::Attacking>();
|
|
||||||
ecs.register_synced::<comp::Rolling>();
|
|
||||||
ecs.register_synced::<comp::Gliding>();
|
|
||||||
|
|
||||||
// Register components synced by other means
|
// Register components synced by other means
|
||||||
ecs.register::<comp::Pos>();
|
ecs.register::<comp::Pos>();
|
||||||
@ -112,10 +109,14 @@ impl State {
|
|||||||
ecs.register::<comp::Ori>();
|
ecs.register::<comp::Ori>();
|
||||||
ecs.register::<comp::MoveDir>();
|
ecs.register::<comp::MoveDir>();
|
||||||
ecs.register::<comp::OnGround>();
|
ecs.register::<comp::OnGround>();
|
||||||
ecs.register::<comp::AnimationInfo>();
|
|
||||||
ecs.register::<comp::Controller>();
|
ecs.register::<comp::Controller>();
|
||||||
|
ecs.register::<comp::Attacking>();
|
||||||
|
ecs.register::<comp::Rolling>();
|
||||||
|
ecs.register::<comp::Gliding>();
|
||||||
|
ecs.register::<comp::ActionState>();
|
||||||
|
|
||||||
// Register client-local components
|
// Register client-local components
|
||||||
|
ecs.register::<comp::AnimationInfo>();
|
||||||
ecs.register::<comp::Jumping>();
|
ecs.register::<comp::Jumping>();
|
||||||
|
|
||||||
// Register server-local components
|
// Register server-local components
|
||||||
|
60
common/src/sys/action_state.rs
Normal file
60
common/src/sys/action_state.rs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
use crate::{
|
||||||
|
comp::{
|
||||||
|
Animation, AnimationInfo, Attacking, ForceUpdate, Gliding, Jumping, OnGround, Ori, Pos,
|
||||||
|
Rolling, Vel, ActionState,
|
||||||
|
},
|
||||||
|
state::DeltaTime,
|
||||||
|
};
|
||||||
|
use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage};
|
||||||
|
|
||||||
|
/// This system will set the ActionState component as specified by other components
|
||||||
|
pub struct Sys;
|
||||||
|
impl<'a> System<'a> for Sys {
|
||||||
|
type SystemData = (
|
||||||
|
Entities<'a>,
|
||||||
|
Read<'a, DeltaTime>,
|
||||||
|
ReadStorage<'a, Vel>,
|
||||||
|
ReadStorage<'a, OnGround>,
|
||||||
|
ReadStorage<'a, Jumping>,
|
||||||
|
ReadStorage<'a, Gliding>,
|
||||||
|
ReadStorage<'a, Attacking>,
|
||||||
|
ReadStorage<'a, Rolling>,
|
||||||
|
WriteStorage<'a, ActionState>,
|
||||||
|
);
|
||||||
|
|
||||||
|
fn run(
|
||||||
|
&mut self,
|
||||||
|
(
|
||||||
|
entities,
|
||||||
|
dt,
|
||||||
|
velocities,
|
||||||
|
on_grounds,
|
||||||
|
jumpings,
|
||||||
|
glidings,
|
||||||
|
attackings,
|
||||||
|
rollings,
|
||||||
|
mut action_states,
|
||||||
|
): Self::SystemData,
|
||||||
|
) {
|
||||||
|
for (entity, vel, on_ground, jumping, gliding, attacking, rolling, mut action_state) in (
|
||||||
|
&entities,
|
||||||
|
&velocities,
|
||||||
|
on_grounds.maybe(),
|
||||||
|
jumpings.maybe(),
|
||||||
|
glidings.maybe(),
|
||||||
|
attackings.maybe(),
|
||||||
|
rollings.maybe(),
|
||||||
|
&mut action_states,
|
||||||
|
)
|
||||||
|
.join()
|
||||||
|
{
|
||||||
|
*action_state = ActionState {
|
||||||
|
on_ground: on_ground.is_some(),
|
||||||
|
moving: vel.0.magnitude_squared() > 10.0,
|
||||||
|
attacking: attacking.is_some(),
|
||||||
|
rolling: rolling.is_some(),
|
||||||
|
gliding: gliding.is_some(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{
|
comp::{
|
||||||
Animation, AnimationInfo, Attacking, ForceUpdate, Gliding, Jumping, OnGround, Ori, Pos,
|
Animation, AnimationInfo, ForceUpdate, ActionState
|
||||||
Rolling, Vel,
|
|
||||||
},
|
},
|
||||||
state::DeltaTime,
|
state::DeltaTime,
|
||||||
};
|
};
|
||||||
@ -13,12 +12,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
type SystemData = (
|
type SystemData = (
|
||||||
Entities<'a>,
|
Entities<'a>,
|
||||||
Read<'a, DeltaTime>,
|
Read<'a, DeltaTime>,
|
||||||
ReadStorage<'a, Vel>,
|
ReadStorage<'a, ActionState>,
|
||||||
ReadStorage<'a, OnGround>,
|
|
||||||
ReadStorage<'a, Jumping>,
|
|
||||||
ReadStorage<'a, Gliding>,
|
|
||||||
ReadStorage<'a, Attacking>,
|
|
||||||
ReadStorage<'a, Rolling>,
|
|
||||||
WriteStorage<'a, AnimationInfo>,
|
WriteStorage<'a, AnimationInfo>,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -27,23 +21,13 @@ impl<'a> System<'a> for Sys {
|
|||||||
(
|
(
|
||||||
entities,
|
entities,
|
||||||
dt,
|
dt,
|
||||||
velocities,
|
action_states,
|
||||||
on_grounds,
|
|
||||||
jumpings,
|
|
||||||
glidings,
|
|
||||||
attackings,
|
|
||||||
rollings,
|
|
||||||
mut animation_infos,
|
mut animation_infos,
|
||||||
): Self::SystemData,
|
): Self::SystemData,
|
||||||
) {
|
) {
|
||||||
for (entity, vel, on_ground, jumping, gliding, attacking, rolling, mut animation_info) in (
|
for (entity, a, mut animation_info) in (
|
||||||
&entities,
|
&entities,
|
||||||
&velocities,
|
&action_states,
|
||||||
on_grounds.maybe(),
|
|
||||||
jumpings.maybe(),
|
|
||||||
glidings.maybe(),
|
|
||||||
attackings.maybe(),
|
|
||||||
rollings.maybe(),
|
|
||||||
&mut animation_infos,
|
&mut animation_infos,
|
||||||
)
|
)
|
||||||
.join()
|
.join()
|
||||||
@ -56,11 +40,11 @@ impl<'a> System<'a> for Sys {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let animation = match (
|
let animation = match (
|
||||||
on_ground.is_some(),
|
a.on_ground,
|
||||||
vel.0.magnitude_squared() > 10.0, // Moving
|
a.moving,
|
||||||
attacking.is_some(),
|
a.attacking,
|
||||||
gliding.is_some(),
|
a.gliding,
|
||||||
rolling.is_some(),
|
a.rolling,
|
||||||
) {
|
) {
|
||||||
(_, _, true, true, _) => impossible_animation("Attack while gliding"),
|
(_, _, true, true, _) => impossible_animation("Attack while gliding"),
|
||||||
(_, _, true, _, true) => impossible_animation("Roll while attacking"),
|
(_, _, true, _, true) => impossible_animation("Roll while attacking"),
|
||||||
|
@ -4,6 +4,7 @@ pub mod combat;
|
|||||||
pub mod controller;
|
pub mod controller;
|
||||||
pub mod phys;
|
pub mod phys;
|
||||||
mod stats;
|
mod stats;
|
||||||
|
mod action_state;
|
||||||
|
|
||||||
// External
|
// External
|
||||||
use specs::DispatcherBuilder;
|
use specs::DispatcherBuilder;
|
||||||
@ -11,6 +12,7 @@ use specs::DispatcherBuilder;
|
|||||||
// System names
|
// System names
|
||||||
const AGENT_SYS: &str = "agent_sys";
|
const AGENT_SYS: &str = "agent_sys";
|
||||||
const CONTROLLER_SYS: &str = "controller_sys";
|
const CONTROLLER_SYS: &str = "controller_sys";
|
||||||
|
const ACTION_STATE_SYS: &str = "action_state_sys";
|
||||||
const PHYS_SYS: &str = "phys_sys";
|
const PHYS_SYS: &str = "phys_sys";
|
||||||
const COMBAT_SYS: &str = "combat_sys";
|
const COMBAT_SYS: &str = "combat_sys";
|
||||||
const ANIMATION_SYS: &str = "animation_sys";
|
const ANIMATION_SYS: &str = "animation_sys";
|
||||||
@ -18,9 +20,10 @@ const STATS_SYS: &str = "stats_sys";
|
|||||||
|
|
||||||
pub fn add_local_systems(dispatch_builder: &mut DispatcherBuilder) {
|
pub fn add_local_systems(dispatch_builder: &mut DispatcherBuilder) {
|
||||||
dispatch_builder.add(agent::Sys, AGENT_SYS, &[]);
|
dispatch_builder.add(agent::Sys, AGENT_SYS, &[]);
|
||||||
dispatch_builder.add(controller::Sys, CONTROLLER_SYS, &[]);
|
dispatch_builder.add(controller::Sys, CONTROLLER_SYS, &[AGENT_SYS]);
|
||||||
dispatch_builder.add(phys::Sys, PHYS_SYS, &[]);
|
dispatch_builder.add(phys::Sys, PHYS_SYS, &[CONTROLLER_SYS]);
|
||||||
dispatch_builder.add(combat::Sys, COMBAT_SYS, &[]);
|
dispatch_builder.add(action_state::Sys, ACTION_STATE_SYS, &[CONTROLLER_SYS, PHYS_SYS]);
|
||||||
dispatch_builder.add(animation::Sys, ANIMATION_SYS, &[]);
|
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(stats::Sys, STATS_SYS, &[COMBAT_SYS]);
|
||||||
}
|
}
|
||||||
|
@ -166,6 +166,7 @@ impl Server {
|
|||||||
state.write_component(entity, comp::Pos(spawn_point));
|
state.write_component(entity, comp::Pos(spawn_point));
|
||||||
state.write_component(entity, comp::Vel(Vec3::zero()));
|
state.write_component(entity, comp::Vel(Vec3::zero()));
|
||||||
state.write_component(entity, comp::Ori(Vec3::unit_y()));
|
state.write_component(entity, comp::Ori(Vec3::unit_y()));
|
||||||
|
state.write_component(entity, comp::ActionState::default());
|
||||||
// Make sure physics are accepted.
|
// Make sure physics are accepted.
|
||||||
state.write_component(entity, comp::ForceUpdate);
|
state.write_component(entity, comp::ForceUpdate);
|
||||||
|
|
||||||
@ -210,74 +211,6 @@ impl Server {
|
|||||||
// Tick the world
|
// Tick the world
|
||||||
self.world.tick(dt);
|
self.world.tick(dt);
|
||||||
|
|
||||||
// Sync deaths.
|
|
||||||
let ecs = &self.state.ecs();
|
|
||||||
let clients = &mut self.clients;
|
|
||||||
let todo_kill = (&ecs.entities(), &ecs.read_storage::<comp::Dying>())
|
|
||||||
.join()
|
|
||||||
.map(|(entity, dying)| {
|
|
||||||
// Chat message
|
|
||||||
if let Some(player) = ecs.read_storage::<comp::Player>().get(entity) {
|
|
||||||
let msg = if let comp::HealthSource::Attack { by } = dying.cause {
|
|
||||||
ecs.entity_from_uid(by.into()).and_then(|attacker| {
|
|
||||||
ecs.read_storage::<comp::Player>()
|
|
||||||
.get(attacker)
|
|
||||||
.map(|attacker_alias| {
|
|
||||||
format!(
|
|
||||||
"{} was killed by {}",
|
|
||||||
&player.alias, &attacker_alias.alias
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
.unwrap_or(format!("{} died", &player.alias));
|
|
||||||
|
|
||||||
clients.notify_registered(ServerMsg::Chat(msg));
|
|
||||||
}
|
|
||||||
|
|
||||||
entity
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
// Actually kill them
|
|
||||||
for entity in todo_kill {
|
|
||||||
if let Some(client) = self.clients.get_mut(&entity) {
|
|
||||||
self.state.write_component(entity, comp::Vel(Vec3::zero()));
|
|
||||||
self.state.write_component(entity, comp::ForceUpdate);
|
|
||||||
client.force_state(ClientState::Dead);
|
|
||||||
} else {
|
|
||||||
if let Err(err) = self.state.ecs_mut().delete_entity_synced(entity) {
|
|
||||||
warn!("Failed to delete client not found in kill list: {:?}", err);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle respawns
|
|
||||||
let todo_respawn = (
|
|
||||||
&self.state.ecs().entities(),
|
|
||||||
&self.state.ecs().read_storage::<comp::Respawning>(),
|
|
||||||
)
|
|
||||||
.join()
|
|
||||||
.map(|(entity, _)| entity)
|
|
||||||
.collect::<Vec<EcsEntity>>();
|
|
||||||
|
|
||||||
for entity in todo_respawn {
|
|
||||||
if let Some(client) = self.clients.get_mut(&entity) {
|
|
||||||
client.allow_state(ClientState::Character);
|
|
||||||
self.state.write_component(entity, comp::Stats::default());
|
|
||||||
self.state
|
|
||||||
.ecs_mut()
|
|
||||||
.write_storage::<comp::Pos>()
|
|
||||||
.get_mut(entity)
|
|
||||||
.map(|pos| pos.0.z += 100.0);
|
|
||||||
self.state.write_component(entity, comp::Vel(Vec3::zero()));
|
|
||||||
self.state.write_component(entity, comp::ForceUpdate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5) Fetch any generated `TerrainChunk`s and insert them into the terrain.
|
// 5) Fetch any generated `TerrainChunk`s and insert them into the terrain.
|
||||||
// Also, send the chunk data to anybody that is close by.
|
// Also, send the chunk data to anybody that is close by.
|
||||||
if let Ok((key, chunk)) = self.chunk_rx.try_recv() {
|
if let Ok((key, chunk)) = self.chunk_rx.try_recv() {
|
||||||
@ -618,11 +551,12 @@ impl Server {
|
|||||||
state.write_component(entity, player);
|
state.write_component(entity, player);
|
||||||
|
|
||||||
// Sync physics
|
// Sync physics
|
||||||
for (&uid, &pos, &vel, &ori) in (
|
for (&uid, &pos, &vel, &ori, &action_state) in (
|
||||||
&state.ecs().read_storage::<Uid>(),
|
&state.ecs().read_storage::<Uid>(),
|
||||||
&state.ecs().read_storage::<comp::Pos>(),
|
&state.ecs().read_storage::<comp::Pos>(),
|
||||||
&state.ecs().read_storage::<comp::Vel>(),
|
&state.ecs().read_storage::<comp::Vel>(),
|
||||||
&state.ecs().read_storage::<comp::Ori>(),
|
&state.ecs().read_storage::<comp::Ori>(),
|
||||||
|
&state.ecs().read_storage::<comp::ActionState>(),
|
||||||
)
|
)
|
||||||
.join()
|
.join()
|
||||||
{
|
{
|
||||||
@ -631,6 +565,7 @@ impl Server {
|
|||||||
pos,
|
pos,
|
||||||
vel,
|
vel,
|
||||||
ori,
|
ori,
|
||||||
|
action_state,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -645,12 +580,13 @@ impl Server {
|
|||||||
.notify_registered(ServerMsg::EcsSync(self.state.ecs_mut().next_sync_package()));
|
.notify_registered(ServerMsg::EcsSync(self.state.ecs_mut().next_sync_package()));
|
||||||
|
|
||||||
// Sync physics
|
// Sync physics
|
||||||
for (entity, &uid, &pos, &vel, &ori, force_update) in (
|
for (entity, &uid, &pos, &vel, &ori, &action_state, force_update) in (
|
||||||
&self.state.ecs().entities(),
|
&self.state.ecs().entities(),
|
||||||
&self.state.ecs().read_storage::<Uid>(),
|
&self.state.ecs().read_storage::<Uid>(),
|
||||||
&self.state.ecs().read_storage::<comp::Pos>(),
|
&self.state.ecs().read_storage::<comp::Pos>(),
|
||||||
&self.state.ecs().read_storage::<comp::Vel>(),
|
&self.state.ecs().read_storage::<comp::Vel>(),
|
||||||
&self.state.ecs().read_storage::<comp::Ori>(),
|
&self.state.ecs().read_storage::<comp::Ori>(),
|
||||||
|
&self.state.ecs().read_storage::<comp::ActionState>(),
|
||||||
self.state.ecs().read_storage::<comp::ForceUpdate>().maybe(),
|
self.state.ecs().read_storage::<comp::ForceUpdate>().maybe(),
|
||||||
)
|
)
|
||||||
.join()
|
.join()
|
||||||
@ -660,6 +596,7 @@ impl Server {
|
|||||||
pos,
|
pos,
|
||||||
vel,
|
vel,
|
||||||
ori,
|
ori,
|
||||||
|
action_state,
|
||||||
};
|
};
|
||||||
|
|
||||||
let state = &self.state;
|
let state = &self.state;
|
||||||
@ -694,6 +631,74 @@ impl Server {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sync deaths.
|
||||||
|
let ecs = &self.state.ecs();
|
||||||
|
let clients = &mut self.clients;
|
||||||
|
let todo_kill = (&ecs.entities(), &ecs.read_storage::<comp::Dying>())
|
||||||
|
.join()
|
||||||
|
.map(|(entity, dying)| {
|
||||||
|
// Chat message
|
||||||
|
if let Some(player) = ecs.read_storage::<comp::Player>().get(entity) {
|
||||||
|
let msg = if let comp::HealthSource::Attack { by } = dying.cause {
|
||||||
|
ecs.entity_from_uid(by.into()).and_then(|attacker| {
|
||||||
|
ecs.read_storage::<comp::Player>()
|
||||||
|
.get(attacker)
|
||||||
|
.map(|attacker_alias| {
|
||||||
|
format!(
|
||||||
|
"{} was killed by {}",
|
||||||
|
&player.alias, &attacker_alias.alias
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
.unwrap_or(format!("{} died", &player.alias));
|
||||||
|
|
||||||
|
clients.notify_registered(ServerMsg::Chat(msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
entity
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
// Actually kill them
|
||||||
|
for entity in todo_kill {
|
||||||
|
if let Some(client) = self.clients.get_mut(&entity) {
|
||||||
|
self.state.write_component(entity, comp::Vel(Vec3::zero()));
|
||||||
|
self.state.write_component(entity, comp::ForceUpdate);
|
||||||
|
client.force_state(ClientState::Dead);
|
||||||
|
} else {
|
||||||
|
if let Err(err) = self.state.ecs_mut().delete_entity_synced(entity) {
|
||||||
|
warn!("Failed to delete client not found in kill list: {:?}", err);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle respawns
|
||||||
|
let todo_respawn = (
|
||||||
|
&self.state.ecs().entities(),
|
||||||
|
&self.state.ecs().read_storage::<comp::Respawning>(),
|
||||||
|
)
|
||||||
|
.join()
|
||||||
|
.map(|(entity, _)| entity)
|
||||||
|
.collect::<Vec<EcsEntity>>();
|
||||||
|
|
||||||
|
for entity in todo_respawn {
|
||||||
|
if let Some(client) = self.clients.get_mut(&entity) {
|
||||||
|
client.allow_state(ClientState::Character);
|
||||||
|
self.state.write_component(entity, comp::Stats::default());
|
||||||
|
self.state
|
||||||
|
.ecs_mut()
|
||||||
|
.write_storage::<comp::Pos>()
|
||||||
|
.get_mut(entity)
|
||||||
|
.map(|pos| pos.0.z += 100.0);
|
||||||
|
self.state.write_component(entity, comp::Vel(Vec3::zero()));
|
||||||
|
self.state.write_component(entity, comp::ForceUpdate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Remove all force flags.
|
// Remove all force flags.
|
||||||
self.state
|
self.state
|
||||||
.ecs_mut()
|
.ecs_mut()
|
||||||
|
Loading…
Reference in New Issue
Block a user