Properly check conditions for when the client's physics components should be synced

This commit is contained in:
Imbris 2023-06-05 18:23:07 -04:00
parent 396c08e7ee
commit cdca700297
3 changed files with 40 additions and 14 deletions

View File

@ -2257,10 +2257,17 @@ impl Client {
.apply_entity_sync_package(entity_sync_package, uid);
},
ServerGeneral::CompSync(comp_sync_package, force_counter) => {
// TODO: Test with and without sync_me = true commented out to see if results are
// as expected. (client shouldn't normally receive updates if client physics is
// enabled)
let b = self.position();
self.force_update_counter = force_counter;
self.state
.ecs_mut()
.apply_comp_sync_package(comp_sync_package);
if b != self.position() {
println!("{b:?}");
}
},
ServerGeneral::CreateEntity(entity_package) => {
self.state.ecs_mut().apply_entity_package(entity_package);

View File

@ -709,7 +709,7 @@ impl StateExt for State {
self.ecs()
.write_resource::<IdMaps>()
.add_character(id, entity);
presence.sync_me = true;
//presence.sync_me = true;
Ok(())
} else {
Err("PresenceKind is not LoadingCharacter")

View File

@ -4,6 +4,8 @@ use common::{
calendar::Calendar,
comp::{Collider, ForceUpdate, InventoryUpdate, Last, Ori, Player, Pos, Presence, Vel},
event::EventBus,
link::Is,
mounting::Rider,
outcome::Outcome,
region::{Event as RegionEvent, RegionMap},
resources::{PlayerPhysicsSettings, Time, TimeOfDay, TimeScale},
@ -247,18 +249,13 @@ impl<'a> System<'a> for Sys {
{
// Decide how regularly to send physics updates.
let send_now = if client_entity == &entity {
let player_physics_setting = players
.get(entity)
.and_then(|p| {
player_physics_settings.settings.get(&p.uuid()).copied()
})
.unwrap_or_default();
// Don't send client physics updates about itself unless force update is
// set or the client is subject to
// server-authoritative physics
force_updates.get(entity).map_or(false, |f| f.is_forced())
|| player_physics_setting.server_authoritative()
|| is_rider.get(entity).is_some()
should_sync_client_physics(
entity,
&player_physics_settings,
&players,
&force_updates,
is_rider,
)
} else if matches!(collider, Some(Collider::Voxel { .. })) {
// Things with a voxel collider (airships, etc.) need to have very
// stable physics so we always send updated
@ -338,7 +335,8 @@ impl<'a> System<'a> for Sys {
);
if include_all_comps && let Some(&pos) = maybe_pos {
add_physics_components(true, &mut comp_sync_package, uid, pos, last_pos, ori, vel);
let send_now = should_sync_client_physics(entity, &player_physics_settings, &players, &force_updates, is_rider);
add_physics_components(send_now, &mut comp_sync_package, uid, pos, last_pos, ori, vel);
}
if !comp_sync_package.is_empty() {
@ -448,6 +446,27 @@ impl<'a> System<'a> for Sys {
}
}
/// Determines whether a client should receive an update about its own physics
/// components.
fn should_sync_client_physics(
entity: specs::Entity,
player_physics_settings: &PlayerPhysicsSettings,
players: &ReadStorage<'_, Player>,
force_updates: &WriteStorage<'_, ForceUpdate>,
is_rider: &ReadStorage<'_, Is<Rider>>,
) -> bool {
let player_physics_setting = players
.get(entity)
.and_then(|p| player_physics_settings.settings.get(&p.uuid()).copied())
.unwrap_or_default();
// Don't send client physics updates about itself unless force update is
// set or the client is subject to
// server-authoritative physics
force_updates.get(entity).map_or(false, |f| f.is_forced())
|| player_physics_setting.server_authoritative()
|| is_rider.contains(entity)
}
/// Adds physics components if `send_now` is true or `Option<Last<T>>` is
/// `None`.
///