Fix death

This commit is contained in:
timokoesters 2019-06-30 22:25:37 +02:00
parent 45e30d0c84
commit 370e7db1ee
No known key found for this signature in database
GPG Key ID: CD80BE9AAEE78097
5 changed files with 78 additions and 67 deletions

View File

@ -47,6 +47,11 @@ impl Stats {
// TODO: Remove
self.health.current == 0
}
pub fn revive(&mut self) {
self.health
.set_to(self.health.get_maximum(), HealthSource::Revive);
self.is_dead = false;
}
}
impl Stats {

View File

@ -18,8 +18,7 @@ impl<'a> System<'a> for Sys {
fn run(&mut self, (entities, dt, mut stats, mut dyings): Self::SystemData) {
for (entity, mut stat) in (&entities, &mut stats).join() {
if stat.should_die() && !stat.is_dead {
// TODO: Replace is_dead with client states
if let Err(err) = dyings.insert(
let _ = dyings.insert(
entity,
Dying {
cause: match stat.health.last_change {
@ -30,9 +29,7 @@ impl<'a> System<'a> for Sys {
}
},
},
) {
warn!("Inserting Dying for an entity failed: {:?}", err);
}
);
stat.is_dead = true;
}
if let Some(change) = &mut stat.health.last_change {

View File

@ -75,6 +75,7 @@ impl Clients {
for client in self.clients.values_mut() {
if client.client_state == ClientState::Spectator
|| client.client_state == ClientState::Character
|| client.client_state == ClientState::Dead
{
client.notify(msg.clone());
}
@ -85,6 +86,7 @@ impl Clients {
for (_entity, client) in self.clients.iter_mut().filter(|(e, _)| f(**e)) {
if client.client_state == ClientState::Spectator
|| client.client_state == ClientState::Character
|| client.client_state == ClientState::Dead
{
client.notify(msg.clone());
}
@ -102,7 +104,8 @@ impl Clients {
pub fn notify_ingame_except(&mut self, except_entity: EcsEntity, msg: ServerMsg) {
for (entity, client) in self.clients.iter_mut() {
if (client.client_state == ClientState::Spectator
|| client.client_state == ClientState::Character)
|| client.client_state == ClientState::Character
|| client.client_state == ClientState::Dead)
&& *entity != except_entity
{
client.notify(msg.clone());
@ -118,7 +121,8 @@ impl Clients {
) {
for (entity, client) in self.clients.iter_mut().filter(|(e, _)| f(**e)) {
if (client.client_state == ClientState::Spectator
|| client.client_state == ClientState::Character)
|| client.client_state == ClientState::Character
|| client.client_state == ClientState::Dead)
&& *entity != except_entity
{
client.notify(msg.clone());

View File

@ -587,58 +587,6 @@ impl Server {
self.clients
.notify_registered(ServerMsg::EcsSync(self.state.ecs_mut().next_sync_package()));
// Sync physics
for (entity, &uid, &pos, &vel, &ori, &action_state, force_update) in (
&self.state.ecs().entities(),
&self.state.ecs().read_storage::<Uid>(),
&self.state.ecs().read_storage::<comp::Pos>(),
&self.state.ecs().read_storage::<comp::Vel>(),
&self.state.ecs().read_storage::<comp::Ori>(),
&self.state.ecs().read_storage::<comp::ActionState>(),
self.state.ecs().read_storage::<comp::ForceUpdate>().maybe(),
)
.join()
{
let msg = ServerMsg::EntityPhysics {
entity: uid.into(),
pos,
vel,
ori,
action_state,
};
let state = &self.state;
let clients = &mut self.clients;
let in_vd = |entity| {
// Get client position.
let client_pos = match state.ecs().read_storage::<comp::Pos>().get(entity) {
Some(pos) => pos.0,
None => return false,
};
// Get client view distance
let client_vd = match state.ecs().read_storage::<comp::Player>().get(entity) {
Some(comp::Player {
view_distance: Some(vd),
..
}) => *vd,
_ => return false,
};
(pos.0 - client_pos)
.map2(TerrainChunkSize::SIZE, |d, sz| {
(d.abs() as u32 / sz).checked_sub(2).unwrap_or(0)
})
.magnitude_squared()
< client_vd.pow(2)
};
match force_update {
Some(_) => clients.notify_ingame_if(msg, in_vd),
None => clients.notify_ingame_if_except(entity, msg, in_vd),
}
}
// Sync deaths.
let ecs = &self.state.ecs();
let clients = &mut self.clients;
@ -698,16 +646,65 @@ impl Server {
.ecs_mut()
.write_storage::<comp::Stats>()
.get_mut(entity)
.map(|stats| {
stats
.health
.set_to(stats.health.get_maximum(), comp::HealthSource::Revive)
});
.map(|stats| stats.revive());
self.state
.ecs_mut()
.write_storage::<comp::Pos>()
.get_mut(entity)
.map(|pos| pos.0.z += 100.0);
.map(|pos| pos.0.z += 20.0);
self.state.write_component(entity, comp::ForceUpdate);
}
}
// Sync physics
for (entity, &uid, &pos, &vel, &ori, &action_state, force_update) in (
&self.state.ecs().entities(),
&self.state.ecs().read_storage::<Uid>(),
&self.state.ecs().read_storage::<comp::Pos>(),
&self.state.ecs().read_storage::<comp::Vel>(),
&self.state.ecs().read_storage::<comp::Ori>(),
&self.state.ecs().read_storage::<comp::ActionState>(),
self.state.ecs().read_storage::<comp::ForceUpdate>().maybe(),
)
.join()
{
let msg = ServerMsg::EntityPhysics {
entity: uid.into(),
pos,
vel,
ori,
action_state,
};
let state = &self.state;
let clients = &mut self.clients;
let in_vd = |entity| {
// Get client position.
let client_pos = match state.ecs().read_storage::<comp::Pos>().get(entity) {
Some(pos) => pos.0,
None => return false,
};
// Get client view distance
let client_vd = match state.ecs().read_storage::<comp::Player>().get(entity) {
Some(comp::Player {
view_distance: Some(vd),
..
}) => *vd,
_ => return false,
};
(pos.0 - client_pos)
.map2(TerrainChunkSize::SIZE, |d, sz| {
(d.abs() as u32 / sz).checked_sub(2).unwrap_or(0)
})
.magnitude_squared()
< client_vd.pow(2)
};
match force_update {
Some(_) => clients.notify_ingame_if(msg, in_vd),
None => clients.notify_ingame_if_except(entity, msg, in_vd),
}
}

View File

@ -108,8 +108,16 @@ impl PlayState for SessionState {
return PlayStateResult::Shutdown;
}
Event::InputUpdate(GameInput::Attack, state) => {
self.controller.attack = state;
self.controller.respawn = state; // TODO: Don't do both
if state {
if let ClientState::Character = current_client_state {
self.controller.attack = state;
} else {
self.controller.respawn = state; // TODO: Don't do both
}
} else {
self.controller.attack = state;
self.controller.respawn = state;
}
}
Event::InputUpdate(GameInput::Roll, state) => {
self.controller.roll = state;