mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fix death
This commit is contained in:
parent
45e30d0c84
commit
370e7db1ee
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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());
|
||||
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user