diff --git a/common/src/comp/stats.rs b/common/src/comp/stats.rs index 59dc2668b8..10813901ee 100644 --- a/common/src/comp/stats.rs +++ b/common/src/comp/stats.rs @@ -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 { diff --git a/common/src/sys/stats.rs b/common/src/sys/stats.rs index 8120bb82df..86e91111fa 100644 --- a/common/src/sys/stats.rs +++ b/common/src/sys/stats.rs @@ -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 { diff --git a/server/src/client.rs b/server/src/client.rs index 5c4806a1fc..e22d8d2e95 100644 --- a/server/src/client.rs +++ b/server/src/client.rs @@ -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()); diff --git a/server/src/lib.rs b/server/src/lib.rs index 9912863eb4..d2919c790b 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -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::(), - &self.state.ecs().read_storage::(), - &self.state.ecs().read_storage::(), - &self.state.ecs().read_storage::(), - &self.state.ecs().read_storage::(), - self.state.ecs().read_storage::().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::().get(entity) { - Some(pos) => pos.0, - None => return false, - }; - // Get client view distance - let client_vd = match state.ecs().read_storage::().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::() .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::() .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::(), + &self.state.ecs().read_storage::(), + &self.state.ecs().read_storage::(), + &self.state.ecs().read_storage::(), + &self.state.ecs().read_storage::(), + self.state.ecs().read_storage::().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::().get(entity) { + Some(pos) => pos.0, + None => return false, + }; + // Get client view distance + let client_vd = match state.ecs().read_storage::().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), } } diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index bd80a71f51..7e1b73e106 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -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;