Improved interpolation for riders

This commit is contained in:
Joshua Barretto 2022-01-15 21:43:20 +00:00
parent 6931514ae5
commit 5c37786185
3 changed files with 35 additions and 10 deletions

View File

@ -126,12 +126,19 @@ pub fn handle_mount(server: &mut Server, rider: EcsEntity, mount: EcsEntity) {
if let (Some(rider_uid), Some(mount_uid)) =
(uids.get(rider).copied(), uids.get(mount).copied())
{
drop(uids);
drop(healths);
let _ = state.link(Mounting {
mount: mount_uid,
rider: rider_uid,
});
let is_pet = match state.ecs().read_storage::<comp::Alignment>().get(mount) {
Some(comp::Alignment::Owned(owner)) if *owner == rider_uid => true,
_ => false,
};
if is_pet {
drop(uids);
drop(healths);
let _ = state.link(Mounting {
mount: mount_uid,
rider: rider_uid,
});
}
}
}
}

View File

@ -252,7 +252,9 @@ impl<'a> System<'a> for Sys {
// Don't send client physics updates about itself unless force update is
// set or the client is subject to
// server-authoritative physics
force_update.is_some() || player_physics_setting.server_authoritative()
force_update.is_some()
|| player_physics_setting.server_authoritative()
|| is_rider.get(entity).is_some()
} 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

View File

@ -2,9 +2,12 @@ use crate::ecs::comp::Interpolated;
use common::{
comp::{object, Body, Ori, Pos, Vel},
resources::DeltaTime,
link::Is,
mounting::Rider,
uid::UidAllocator,
};
use common_ecs::{Job, Origin, Phase, System};
use specs::{Entities, Join, Read, ReadStorage, WriteStorage};
use specs::{Entities, Join, Read, ReadStorage, WriteStorage, saveload::MarkerAllocator};
use tracing::warn;
use vek::*;
@ -14,12 +17,14 @@ pub struct Sys;
impl<'a> System<'a> for Sys {
#[allow(clippy::type_complexity)]
type SystemData = (
Read<'a, UidAllocator>,
Entities<'a>,
Read<'a, DeltaTime>,
ReadStorage<'a, Pos>,
ReadStorage<'a, Ori>,
ReadStorage<'a, Vel>,
ReadStorage<'a, Body>,
ReadStorage<'a, Is<Rider>>,
WriteStorage<'a, Interpolated>,
);
@ -29,18 +34,29 @@ impl<'a> System<'a> for Sys {
fn run(
_job: &mut Job<Self>,
(entities, dt, positions, orientations, velocities, bodies, mut interpolated): Self::SystemData,
(uid_allocator, entities, dt, positions, orientations, velocities, bodies, is_rider, mut interpolated): Self::SystemData,
) {
// Update interpolated positions and orientations
for (pos, ori, i, body, vel) in (
for (pos, ori, i, body, vel, is_rider) in (
&positions,
&orientations,
&mut interpolated,
&bodies,
&velocities,
is_rider.maybe(),
)
.join()
{
// Riders get their pos/ori set to that of their mount
let (pos, vel, ori) = if let Some(((mount_pos, mount_vel), mount_ori)) = is_rider
.and_then(|is_rider| uid_allocator.retrieve_entity_internal(is_rider.mount.into()))
.and_then(|mount| positions.get(mount).zip(velocities.get(mount)).zip(orientations.get(mount)))
{
(mount_pos, mount_vel, mount_ori)
} else {
(pos, vel, ori)
};
// Update interpolation values, but don't interpolate far things or objects
if i.pos.distance_squared(pos.0) < 64.0 * 64.0 && !matches!(body, Body::Object(_)) {
// Note, these values are specifically tuned for smoother motion with high