Properly handle cleanup of old entity controller during possession on both the client and server sides

This commit is contained in:
Imbris 2022-02-20 23:41:18 -05:00
parent 1a744808f0
commit 6f9ff17ce8
2 changed files with 17 additions and 4 deletions

View File

@ -1828,7 +1828,19 @@ impl Client {
},
ServerGeneral::SetPlayerEntity(uid) => {
if let Some(entity) = self.state.ecs().entity_from_uid(uid.0) {
*self.state.ecs_mut().write_resource() = PlayerEntity(Some(entity));
let old_player_entity = core::mem::replace(
&mut *self.state.ecs_mut().write_resource(),
PlayerEntity(Some(entity)),
);
if let Some(old_entity) = old_player_entity.0 {
// Transfer controller to the new entity.
let mut controllers = self.state.ecs().write_storage::<Controller>();
if let Some(controller) = controllers.remove(old_entity) {
if let Err(e) = controllers.insert(entity, controller) {
error!(?e, "Failed to insert controller when setting new player entity!");
}
}
}
} else {
return Err(Error::Other("Failed to find entity from uid.".to_owned()));
}

View File

@ -172,6 +172,9 @@ pub fn handle_possess(server: &mut Server, possessor_uid: Uid, possesse_uid: Uid
return;
}
// TODO: Limit possessible entities to those in the client's subscribed
// regions.
// Transfer client component. Note: we require this component for possession.
if let Some(client) = clients.remove(possessor) {
client.send_fallible(ServerGeneral::SetPlayerEntity(possesse_uid));
@ -274,10 +277,8 @@ pub fn handle_possess(server: &mut Server, possessor_uid: Uid, possesse_uid: Uid
// Remove will of the entity
ecs.write_storage::<comp::Agent>().remove(possesse);
// Reset controller of former shell
// TODO: client needs to do this on their side as well since we don't sync
// controllers.
if let Some(c) = ecs.write_storage::<comp::Controller>().get_mut(possessor) {
c.reset();
*c = Default::default();
}
let clients = ecs.read_storage::<Client>();