mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Always sync components for a client's entity even if it has no position
or has sync_me false in `Presence`.
This commit is contained in:
parent
ba7d7481d7
commit
997babca18
@ -269,6 +269,28 @@ impl RegionMap {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Checks if this entity is located in the `RegionMap` using the provided
|
||||||
|
/// position to limit which regions are checked.
|
||||||
|
///
|
||||||
|
/// May produce false negatives (e.g. if for some reason the entity is not
|
||||||
|
/// in a region near the provided position).
|
||||||
|
pub fn in_region_map_relaxed(&self, entity: specs::Entity, pos: Vec3<f32>) -> bool {
|
||||||
|
let id = entity.id();
|
||||||
|
let pos = pos.map(|e| e as i32);
|
||||||
|
|
||||||
|
// Compute key for most likely region
|
||||||
|
let key = Self::pos_key(pos);
|
||||||
|
if let Some(region) = self.regions.get(&key) && region.entities().contains(id) { return true }
|
||||||
|
|
||||||
|
// Get the base of the four nearest regions.
|
||||||
|
let quad_base = Self::pos_key(pos - (REGION_SIZE / 2) as i32);
|
||||||
|
[(0, 0), (0, 1), (1, 0), (1, 1)]
|
||||||
|
.iter()
|
||||||
|
.map(|&offset| Vec2::<i32>::from(offset) + quad_base)
|
||||||
|
// skip key we already checked
|
||||||
|
.any(|k| k != key && self.regions.get(&key).is_some_and(|r| r.entities().contains(id)))
|
||||||
|
}
|
||||||
|
|
||||||
fn key_index(&self, key: Vec2<i32>) -> Option<usize> {
|
fn key_index(&self, key: Vec2<i32>) -> Option<usize> {
|
||||||
self.regions.get_full(&key).map(|(i, _, _)| i)
|
self.regions.get_full(&key).map(|(i, _, _)| i)
|
||||||
}
|
}
|
||||||
|
@ -362,8 +362,6 @@ impl<'a> System<'a> for Sys {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Sync clients that don't have a position?
|
|
||||||
|
|
||||||
// Sync inventories
|
// Sync inventories
|
||||||
for (inventory, update, client) in (inventories, &mut inventory_updates, &clients).join() {
|
for (inventory, update, client) in (inventories, &mut inventory_updates, &clients).join() {
|
||||||
client.send_fallible(ServerGeneral::InventoryUpdate(
|
client.send_fallible(ServerGeneral::InventoryUpdate(
|
||||||
@ -372,18 +370,19 @@ impl<'a> System<'a> for Sys {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this seems like the ideal spot to sync other components for clients
|
|
||||||
// that don't have a position or otherwise aren't included in the regions that
|
|
||||||
// the client is subscribed to...
|
|
||||||
//
|
|
||||||
// Maybe we can pass a bool into `create_sync_from_client_package`... renamed it
|
|
||||||
// to create_sync_package_for_client_entity(?)
|
|
||||||
// create_client_sync_package(?)
|
|
||||||
//
|
|
||||||
// Sync components that are only synced for the client's own entity.
|
// Sync components that are only synced for the client's own entity.
|
||||||
for (entity, client) in (&entities, &clients).join() {
|
for (entity, client, maybe_pos) in (&entities, &clients, positions.maybe()).join() {
|
||||||
let comp_sync_package =
|
// Include additional components for clients that aren't in a region (e.g. due
|
||||||
trackers.create_sync_from_client_package(&tracked_storages, entity);
|
// to having no position or have sync_me as `false`) since those
|
||||||
|
// won't be synced above.
|
||||||
|
let include_all_comps =
|
||||||
|
!maybe_pos.is_some_and(|pos| region_map.in_region_map_relaxed(entity, pos.0));
|
||||||
|
|
||||||
|
let comp_sync_package = trackers.create_sync_from_client_package(
|
||||||
|
&tracked_storages,
|
||||||
|
entity,
|
||||||
|
include_all_comps,
|
||||||
|
);
|
||||||
if !comp_sync_package.is_empty() {
|
if !comp_sync_package.is_empty() {
|
||||||
client.send_fallible(ServerGeneral::CompSync(
|
client.send_fallible(ServerGeneral::CompSync(
|
||||||
comp_sync_package,
|
comp_sync_package,
|
||||||
|
@ -231,10 +231,14 @@ macro_rules! trackers {
|
|||||||
|
|
||||||
|
|
||||||
/// Create sync package for components that are only synced for the client's entity.
|
/// Create sync package for components that are only synced for the client's entity.
|
||||||
|
///
|
||||||
|
/// This can optionally include components that are synced "for any entity" for cases
|
||||||
|
/// where other mechanisms don't sync those components.
|
||||||
pub fn create_sync_from_client_package(
|
pub fn create_sync_from_client_package(
|
||||||
&self,
|
&self,
|
||||||
comps: &TrackedStorages,
|
comps: &TrackedStorages,
|
||||||
entity: specs::Entity,
|
entity: specs::Entity,
|
||||||
|
include_all_comps: bool,
|
||||||
) -> CompSyncPackage<EcsCompPacket> {
|
) -> CompSyncPackage<EcsCompPacket> {
|
||||||
// TODO: this type repeats the entity uid for each component but
|
// TODO: this type repeats the entity uid for each component but
|
||||||
// we know they will all be the same here, using it for now for
|
// we know they will all be the same here, using it for now for
|
||||||
@ -249,10 +253,10 @@ macro_rules! trackers {
|
|||||||
};
|
};
|
||||||
|
|
||||||
$(
|
$(
|
||||||
if matches!(
|
if match <$component_type as NetSync>::SYNC_FROM {
|
||||||
<$component_type as NetSync>::SYNC_FROM,
|
SyncFrom::ClientEntity => true,
|
||||||
SyncFrom::ClientEntity,
|
SyncFrom::AnyEntity => include_all_comps,
|
||||||
) {
|
} {
|
||||||
comp_sync_package.add_component_update(
|
comp_sync_package.add_component_update(
|
||||||
&self.$component_name,
|
&self.$component_name,
|
||||||
&comps.$component_name,
|
&comps.$component_name,
|
||||||
|
Loading…
Reference in New Issue
Block a user