diff --git a/server/src/cmd.rs b/server/src/cmd.rs index 2274a4c017..5df26620af 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -37,9 +37,11 @@ use common::{ npc::{self, get_npc_name}, resources::{BattleMode, PlayerPhysicsSettings, Time, TimeOfDay}, terrain::{Block, BlockKind, SpriteKind, TerrainChunkSize}, - uid::Uid, + uid::{Uid, UidAllocator}, vol::{ReadVol, RectVolSize}, Damage, DamageKind, DamageSource, Explosion, LoadoutBuilder, RadiusEffect, + link::Is, + mounting::Rider, }; use common_net::{ msg::{DisconnectReason, Notification, PlayerListUpdate, ServerGeneral}, @@ -50,7 +52,7 @@ use core::{cmp::Ordering, convert::TryFrom, time::Duration}; use hashbrown::{HashMap, HashSet}; use humantime::Duration as HumanDuration; use rand::Rng; -use specs::{storage::StorageEntry, Builder, Entity as EcsEntity, Join, WorldExt}; +use specs::{storage::StorageEntry, Builder, Entity as EcsEntity, Join, WorldExt, saveload::MarkerAllocator}; use std::{str::FromStr, sync::Arc}; use vek::*; use wiring::{Circuit, Wire, WiringAction, WiringActionEffect, WiringElement}; @@ -201,11 +203,29 @@ fn position_mut( descriptor: &str, f: impl for<'a> FnOnce(&'a mut comp::Pos) -> T, ) -> CmdResult { - let mut pos_storage = server.state.ecs_mut().write_storage::(); - pos_storage + let entity = server.state + .ecs() + .read_storage::>() + .get(entity) + .and_then(|is_rider| server.state + .ecs() + .read_resource::() + .retrieve_entity_internal(is_rider.mount.into())) + .unwrap_or(entity); + + let res = server.state + .ecs() + .write_storage::() .get_mut(entity) .map(f) - .ok_or_else(|| format!("Cannot get position for {:?}!", descriptor)) + .ok_or_else(|| format!("Cannot get position for {:?}!", descriptor)); + if res.is_ok() { + let _ = server.state + .ecs() + .write_storage::() + .insert(entity, comp::ForceUpdate); + } + res } fn insert_or_replace_component( @@ -766,8 +786,7 @@ fn handle_jump( if let (Some(x), Some(y), Some(z)) = parse_args!(args, f32, f32, f32) { position_mut(server, target, "target", |current_pos| { current_pos.0 += Vec3::new(x, y, z) - })?; - insert_or_replace_component(server, target, comp::ForceUpdate, "target") + }) } else { Err(action.help_string()) } @@ -783,8 +802,7 @@ fn handle_goto( if let (Some(x), Some(y), Some(z)) = parse_args!(args, f32, f32, f32) { position_mut(server, target, "target", |current_pos| { current_pos.0 = Vec3::new(x, y, z) - })?; - insert_or_replace_component(server, target, comp::ForceUpdate, "target") + }) } else { Err(action.help_string()) } @@ -819,8 +837,7 @@ fn handle_site( position_mut(server, target, "target", |current_pos| { current_pos.0 = site_pos - })?; - insert_or_replace_component(server, target, comp::ForceUpdate, "target") + }) } else { Err(action.help_string()) } @@ -847,8 +864,7 @@ fn handle_home( target, comp::Waypoint::temp_new(home_pos, time), "target", - )?; - insert_or_replace_component(server, target, comp::ForceUpdate, "target") + ) } fn handle_kill( @@ -1118,8 +1134,7 @@ fn handle_tp( let player_pos = position(server, player, "player")?; position_mut(server, target, "target", |target_pos| { *target_pos = player_pos - })?; - insert_or_replace_component(server, target, comp::ForceUpdate, "target") + }) } fn handle_spawn( diff --git a/server/src/sys/entity_sync.rs b/server/src/sys/entity_sync.rs index 4aa48699a3..5c0e30556c 100644 --- a/server/src/sys/entity_sync.rs +++ b/server/src/sys/entity_sync.rs @@ -15,12 +15,11 @@ use common::{ vol::RectVolSize, link::Is, mounting::Rider, - uid::UidAllocator, }; use common_ecs::{Job, Origin, Phase, System}; use common_net::{msg::ServerGeneral, sync::CompSyncPackage}; use itertools::Either; -use specs::{Entities, Join, Read, ReadExpect, ReadStorage, Write, WriteStorage, saveload::MarkerAllocator}; +use specs::{Entities, Join, Read, ReadExpect, ReadStorage, Write, WriteStorage}; use vek::*; /// This system will send physics updates to the client @@ -30,15 +29,15 @@ pub struct Sys; impl<'a> System<'a> for Sys { #[allow(clippy::type_complexity)] type SystemData = ( - (Read<'a, UidAllocator>, Entities<'a>), + Entities<'a>, Read<'a, Tick>, ReadExpect<'a, TimeOfDay>, ReadExpect<'a, Calendar>, ReadExpect<'a, RegionMap>, ReadStorage<'a, Uid>, - WriteStorage<'a, Pos>, - WriteStorage<'a, Vel>, - WriteStorage<'a, Ori>, + ReadStorage<'a, Pos>, + ReadStorage<'a, Vel>, + ReadStorage<'a, Ori>, ReadStorage<'a, Inventory>, ReadStorage<'a, RegionSubscription>, ReadStorage<'a, Presence>, @@ -65,15 +64,15 @@ impl<'a> System<'a> for Sys { fn run( job: &mut Job, ( - (uid_allocator, entities), + entities, tick, time_of_day, calendar, region_map, uids, - mut positions, - mut velocities, - mut orientations, + positions, + velocities, + orientations, inventories, subscriptions, presences, @@ -111,24 +110,6 @@ impl<'a> System<'a> for Sys { // 5. Inform clients of the component changes for that entity // - Throttle update rate base on distance to each client - // Propagate `ForceUpdate`s to mounts - let mut propagate_mounts = Vec::new(); - for (entity, _, is_rider) in ( - &entities, - &force_updates, - &is_rider, - ).join() { - propagate_mounts.push((is_rider.mount, entity)); - } - for (mount_uid, rider) in propagate_mounts { - let Some(mount) = uid_allocator - .retrieve_entity_internal(mount_uid.into()) - else { continue }; - positions.get(rider).copied().map(|pos| positions.insert(mount, pos)); - velocities.get(rider).copied().map(|vel| velocities.insert(mount, vel)); - orientations.get(rider).copied().map(|ori| orientations.insert(mount, ori)); - } - // Sync physics and other components // via iterating through regions (in parallel) diff --git a/voxygen/src/session/mod.rs b/voxygen/src/session/mod.rs index a329f66e1d..7b047da0db 100644 --- a/voxygen/src/session/mod.rs +++ b/voxygen/src/session/mod.rs @@ -689,7 +689,7 @@ impl PlayState for SessionState { !&client.state().ecs().read_storage::>(), ) .join() - .filter(|(entity, _, mount_state)| *entity != client.entity()) + .filter(|(entity, _, _)| *entity != client.entity()) .map(|(entity, pos, _)| { (entity, player_pos.0.distance_squared(pos.0)) })