Handle removing/inserting SyncFrom::ClientEntity components properly during possession.

This commit is contained in:
Imbris 2022-02-21 23:23:53 -05:00
parent 63ed36bdde
commit c2ad763b9c
2 changed files with 40 additions and 3 deletions

View File

@ -284,6 +284,7 @@ pub fn handle_possess(server: &mut Server, possessor_uid: Uid, possesse_uid: Uid
); );
inventory.replace_loadout_item(EquipSlot::ActiveMainhand, Some(debug_item)); inventory.replace_loadout_item(EquipSlot::ActiveMainhand, Some(debug_item));
} }
drop(inventories);
// Remove will of the entity // Remove will of the entity
ecs.write_storage::<comp::Agent>().remove(possesse); ecs.write_storage::<comp::Agent>().remove(possesse);
@ -292,13 +293,23 @@ pub fn handle_possess(server: &mut Server, possessor_uid: Uid, possesse_uid: Uid
*c = Default::default(); *c = Default::default();
} }
// Send client new `SyncFrom::ClientEntity` components and tell it to
// deletes these on the old entity.
let clients = ecs.read_storage::<Client>(); let clients = ecs.read_storage::<Client>();
let client = clients let client = clients
.get(possesse) .get(possesse)
.expect("We insert this component above and have exclusive access to the world."); .expect("We insert this component above and have exclusive access to the world.");
// TODO: send client new `SyncFrom::ClientEntity` components use crate::sys::sentinel::TrackedStorages;
// TODO: also make sure the client deletes the ones on the old entity use specs::SystemData;
// when `SetPlayerEntity` is recieved. let tracked_storages = TrackedStorages::fetch(ecs);
let comp_sync_package = tracked_storages.create_sync_from_client_entity_switch(
possessor_uid,
possesse_uid,
possesse,
);
if !comp_sync_package.is_empty() {
client.send_fallible(ServerGeneral::CompSync(comp_sync_package));
}
} }
} }

View File

@ -96,6 +96,31 @@ macro_rules! trackers {
Some(EntityPackage { uid, comps }) Some(EntityPackage { uid, comps })
} }
/// Create sync package for switching a client to another entity specifically to
/// remove/add components that are only synced for the client's entity.
pub fn create_sync_from_client_entity_switch(
&self,
old_uid: Uid,
new_uid: Uid,
new_entity: specs::Entity,
) -> CompSyncPackage<EcsCompPacket> {
let mut comp_sync_package = CompSyncPackage::new();
$(
if matches!(
<$component_type as NetSync>::SYNC_FROM,
SyncFrom::ClientEntity,
) {
comp_sync_package.comp_removed::<$component_type>(old_uid);
if let Some(comp) = self.$component_name.get(new_entity).cloned() {
comp_sync_package.comp_inserted(new_uid, comp);
}
}
)*
comp_sync_package
}
} }
/// Contains an [`UpdateTracker`] for every synced component (that uses this method of /// Contains an [`UpdateTracker`] for every synced component (that uses this method of
@ -225,6 +250,7 @@ macro_rules! trackers {
comp_sync_package comp_sync_package
} }
} }
} }
} }