diff --git a/common/net/src/synced_components.rs b/common/net/src/synced_components.rs old mode 100644 new mode 100755 index dbcf4aa25d..e9a50d92f0 --- a/common/net/src/synced_components.rs +++ b/common/net/src/synced_components.rs @@ -46,7 +46,7 @@ macro_rules! synced_components { beam_segment: BeamSegment, alignment: Alignment, stance: Stance, - pet_state: PetStates, + pet_state: PetState, // TODO: change this to `SyncFrom::ClientEntity` and sync the bare minimum // from other entities (e.g. just keys needed to show appearance // based on their loadout). Also, it looks like this actually has @@ -74,9 +74,9 @@ macro_rules! reexport_comps { ($($name:ident: $type:ident,)*) => { mod inner { pub use common::comp::*; + pub use common::comp::pet::PetState; use common::link::Is; use common::mounting::{Mount, Rider, VolumeRider}; - use common::comp::pet::PetState; // We alias these because the identifier used for the // component's type is reused as an enum variant name // in the macro's that we pass to `synced_components!`. @@ -86,7 +86,6 @@ macro_rules! reexport_comps { pub type IsMount = Is; pub type IsRider = Is; pub type IsVolumeRider = Is; - pub type PetStates = PetState; } // Re-export all the component types. So that uses of `synced_components!` outside this @@ -108,7 +107,7 @@ synced_components!(reexport_comps); use crate::sync::{NetSync, SyncFrom}; // These are synced from any entity within range. -impl NetSync for PetStates { +impl NetSync for PetState { const SYNC_FROM: SyncFrom = SyncFrom::AnyEntity; } diff --git a/common/src/comp/pet.rs b/common/src/comp/pet.rs old mode 100644 new mode 100755 index a250232023..0b8f8f40e6 --- a/common/src/comp/pet.rs +++ b/common/src/comp/pet.rs @@ -111,7 +111,6 @@ impl Component for Pet { #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize, Default)] pub struct PetState { - pub stay: bool, pub stay_pos: Option, } diff --git a/common/src/event.rs b/common/src/event.rs index 9af01e45e2..81d09a7517 100644 --- a/common/src/event.rs +++ b/common/src/event.rs @@ -200,7 +200,7 @@ pub enum ServerEvent { Mount(EcsEntity, EcsEntity), MountVolume(EcsEntity, VolumePos), Unmount(EcsEntity), - ToggleStay(EcsEntity), + ToggleStay(EcsEntity, EcsEntity), Possess(Uid, Uid), /// Inserts default components for a character when loading into the game InitCharacterData { diff --git a/common/systems/src/controller.rs b/common/systems/src/controller.rs index e8e017b216..35d87a0981 100644 --- a/common/systems/src/controller.rs +++ b/common/systems/src/controller.rs @@ -68,7 +68,7 @@ impl<'a> System<'a> for Sys { .id_maps .uid_entity(pet_uid) { - server_emitter.emit(ServerEvent::ToggleStay(pet_entity)); + server_emitter.emit(ServerEvent::ToggleStay(entity, pet_entity)); } }, ControlEvent::RemoveBuff(buff_id) => { diff --git a/server/agent/src/data.rs b/server/agent/src/data.rs old mode 100644 new mode 100755 index 667b9e38dc..64000bdb08 --- a/server/agent/src/data.rs +++ b/server/agent/src/data.rs @@ -53,7 +53,6 @@ pub struct AgentData<'a> { pub light_emitter: Option<&'a LightEmitter>, pub glider_equipped: bool, pub is_gliding: bool, - pub is_stay: bool, pub stay_pos: Option, pub health: Option<&'a Health>, pub char_state: &'a CharacterState, diff --git a/server/src/events/interaction.rs b/server/src/events/interaction.rs old mode 100644 new mode 100755 index de65be28a0..44aa88feaa --- a/server/src/events/interaction.rs +++ b/server/src/events/interaction.rs @@ -202,29 +202,34 @@ pub fn handle_unmount(server: &mut Server, rider: EcsEntity) { state.ecs().write_storage::>().remove(rider); } -pub fn handle_toggle_stay(server: &mut Server, pet: EcsEntity) { +pub fn handle_toggle_stay(server: &mut Server, command_giver: EcsEntity, pet: EcsEntity) { let state = server.state_mut(); - if state + let mut is_owner = false; + let positions = state.ecs().read_storage::(); + if let Some(owner_uid) = state.ecs().uid_from_entity(command_giver) { + is_owner = matches!( + state + .ecs() + .read_storage::() + .get(pet), + Some(comp::Alignment::Owned(pet_owner)) if *pet_owner == owner_uid, + ); + } + let prev_pet_pos = state .ecs() .read_storage::() .get(pet) - .map_or(false, |s| s.stay) - { + .and_then(|s| s.stay_pos); + let mut new_pet_pos = None; + if prev_pet_pos.is_none() { + new_pet_pos = state.ecs().read_storage::().get(pet).copied(); + } + if is_owner && within_mounting_range(positions.get(command_giver), positions.get(pet)) { let _ = state .ecs() .write_storage::() .insert(pet, PetState { - stay: false, - stay_pos: None, - }); - } else { - let current_pos = state.ecs().read_storage::().get(pet).copied(); - let _ = state - .ecs() - .write_storage::() - .insert(pet, PetState { - stay: true, - stay_pos: current_pos, + stay_pos: new_pet_pos, }); } } diff --git a/server/src/events/mod.rs b/server/src/events/mod.rs index e0edde427f..b4a965761e 100644 --- a/server/src/events/mod.rs +++ b/server/src/events/mod.rs @@ -144,7 +144,9 @@ impl Server { handle_mount_volume(self, mounter, volume) }, ServerEvent::Unmount(mounter) => handle_unmount(self, mounter), - ServerEvent::ToggleStay(pet) => handle_toggle_stay(self, pet), + ServerEvent::ToggleStay(command_giver, pet) => { + handle_toggle_stay(self, command_giver, pet) + }, ServerEvent::Possess(possessor_uid, possesse_uid) => { handle_possess(self, possessor_uid, possesse_uid) }, diff --git a/server/src/sys/agent.rs b/server/src/sys/agent.rs old mode 100644 new mode 100755 index 2ca2a3520b..07cb7b4961 --- a/server/src/sys/agent.rs +++ b/server/src/sys/agent.rs @@ -161,8 +161,6 @@ impl<'a> System<'a> for Sys { matches!(&*item.kind(), comp::item::ItemKind::Glider) }); - let is_stay = pet_state.map_or(false, |s| s.stay); - let stay_pos = pet_state.and_then(|s| s.stay_pos); let is_gliding = matches!( @@ -235,7 +233,6 @@ impl<'a> System<'a> for Sys { light_emitter, glider_equipped, is_gliding, - is_stay, stay_pos, health: read_data.healths.get(entity), char_state, diff --git a/server/src/sys/agent/behavior_tree.rs b/server/src/sys/agent/behavior_tree.rs old mode 100644 new mode 100755 index 273b50a7c3..9e8b385997 --- a/server/src/sys/agent/behavior_tree.rs +++ b/server/src/sys/agent/behavior_tree.rs @@ -406,7 +406,7 @@ fn do_pickup_loot(bdata: &mut BehaviorData) -> bool { fn follow_if_far_away(bdata: &mut BehaviorData) -> bool { if let Some(Target { target, .. }) = bdata.agent.target { if let Some(tgt_pos) = bdata.read_data.positions.get(target) { - let stay = bdata.agent_data.is_stay; + let stay = bdata.agent_data.stay_pos.is_some(); if stay { let stay_pos = bdata.agent_data.stay_pos.map_or(Pos(Vec3::zero()), |v| v); let distance_from_stay = stay_pos.0.distance_squared(bdata.agent_data.pos.0); @@ -443,7 +443,7 @@ fn attack_if_owner_hurt(bdata: &mut BehaviorData) -> bool { } else { false }; - let stay = bdata.agent_data.is_stay; + let stay = bdata.agent_data.stay_pos.is_some(); if owner_recently_attacked && !stay { bdata.agent_data.attack_target_attacker( bdata.agent, diff --git a/server/src/sys/pets.rs b/server/src/sys/pets.rs old mode 100644 new mode 100755 index c5d8faf232..7789f0d27c --- a/server/src/sys/pets.rs +++ b/server/src/sys/pets.rs @@ -58,7 +58,10 @@ impl<'a> System<'a> for Sys { .collect(); for (pet_entity, owner_pos) in lost_pets.iter() { - let stay = pet_state.get(*pet_entity).map_or(false, |f| f.stay); + let stay = pet_state + .get(*pet_entity) + .and_then(|f| f.stay_pos) + .is_some(); if let Some(mut pet_pos) = positions.get_mut(*pet_entity) && !stay{ // Move the pets to their owner's position // TODO: Create a teleportation event to handle this instead of diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs old mode 100644 new mode 100755 index 51e8805b02..e19ecb34c9 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -1504,7 +1504,7 @@ impl Hud { let alignments = ecs.read_storage::(); let is_mounts = ecs.read_storage::>(); let is_riders = ecs.read_storage::>(); - let is_stay = ecs.read_storage::(); + let pet_state = ecs.read_storage::(); let stances = ecs.read_storage::(); let time = ecs.read_resource::