diff --git a/assets/voxygen/i18n/en/command.ftl b/assets/voxygen/i18n/en/command.ftl index 4f807e121b..cbc6007b08 100644 --- a/assets/voxygen/i18n/en/command.ftl +++ b/assets/voxygen/i18n/en/command.ftl @@ -91,4 +91,8 @@ command-unimplemented-teleporter-spawn = Teleporter spawning is not implemented command-kit-inventory-unavailable = Could not get inventory command-inventory-cant-fit-item = Can't fit item to inventory # Emitted by /disconnect_all when you dont exist (?) -command-you-dont-exist = You do not exist, so you cannot use this command \ No newline at end of file +command-you-dont-exist = You do not exist, so you cannot use this command +command-destroyed-tethers = All tethers destroyed! You are now free +command-destroyed-no-tethers = You're not connected to any tethers +command-dismounted = Dismounted +command-no-dismount = You're not riding or being ridden \ No newline at end of file diff --git a/common/src/mounting.rs b/common/src/mounting.rs index 94e90a4c6b..79b666b0d3 100644 --- a/common/src/mounting.rs +++ b/common/src/mounting.rs @@ -279,6 +279,14 @@ pub struct VolumeRiders { riders: HashSet>, } +impl VolumeRiders { + pub fn clear(&mut self) -> bool { + let res = !self.riders.is_empty(); + self.riders.clear(); + res + } +} + impl Component for VolumeRiders { type Storage = DenseVecStorage; } diff --git a/server/src/cmd.rs b/server/src/cmd.rs index e5eed4ad67..a6111bc423 100644 --- a/server/src/cmd.rs +++ b/server/src/cmd.rs @@ -4581,22 +4581,36 @@ fn handle_tether( fn handle_destroy_tethers( server: &mut Server, - _client: EcsEntity, + client: EcsEntity, target: EcsEntity, _args: Vec, _action: &ServerChatCommand, ) -> CmdResult<()> { - server + let mut destroyed = false; + destroyed |= server .state .ecs() .write_storage::>() - .remove(target); - server + .remove(target) + .is_some(); + destroyed |= server .state .ecs() .write_storage::>() - .remove(target); - Ok(()) + .remove(target) + .is_some(); + if destroyed { + server.notify_client( + client, + ServerGeneral::server_msg( + ChatType::CommandInfo, + Content::localized("command-destroyed-tethers"), + ), + ); + Ok(()) + } else { + Err(Content::localized("command-destroyed-no-tethers")) + } } fn handle_mount( @@ -4616,7 +4630,7 @@ fn handle_mount( server .state .link(common::mounting::Mounting { mount, rider }) - .map_err(|_| "Failed to tether entities".into()) + .map_err(|_| "Failed to mount entities".into()) } else { Err("Mount and/or rider doesn't have an Uid component.".into()) } @@ -4627,30 +4641,47 @@ fn handle_mount( fn handle_dismount( server: &mut Server, - _client: EcsEntity, + client: EcsEntity, target: EcsEntity, _args: Vec, _action: &ServerChatCommand, ) -> CmdResult<()> { - server + let mut destroyed = false; + destroyed |= server .state .ecs() .write_storage::>() - .remove(target); - server + .remove(target) + .is_some(); + destroyed |= server .state .ecs() .write_storage::>() - .remove(target); - server + .remove(target) + .is_some(); + destroyed |= server .state .ecs() .write_storage::>() - .remove(target); - server + .remove(target) + .is_some(); + destroyed |= server .state .ecs() .write_storage::() - .remove(target); - Ok(()) + .get_mut(target) + .map_or(false, |volume_riders| volume_riders.clear()); + + if destroyed { + server.notify_client( + client, + ServerGeneral::server_msg( + ChatType::CommandInfo, + Content::localized("command-dismounted"), + ), + ); + Ok(()) + } else { + Err(Content::localized("command-no-dismount")) + } } diff --git a/server/src/state_ext.rs b/server/src/state_ext.rs index fd6813230a..0a4734247c 100644 --- a/server/src/state_ext.rs +++ b/server/src/state_ext.rs @@ -31,6 +31,7 @@ use common::{ resources::{Secs, Time, TimeOfDay}, rtsim::{Actor, RtSimEntity}, slowjob::SlowJobPool, + tether::Tethered, uid::{IdMaps, Uid}, util::Dir, LoadoutBuilder, ViewDistances, @@ -1164,6 +1165,7 @@ impl StateExt for State { maintain_link::(self); maintain_link::(self); + maintain_link::(self); } fn delete_entity_recorded( diff --git a/voxygen/src/cmd.rs b/voxygen/src/cmd.rs index af0d794baf..6adf4d95d0 100644 --- a/voxygen/src/cmd.rs +++ b/voxygen/src/cmd.rs @@ -216,7 +216,8 @@ pub fn run_command( .ok_or("No player entity")?, ident => { return Err(format!( - "Expected target/selected/viewpoint/mount/rider found {ident}" + "Expected target/selected/viewpoint/mount/rider/self after '@' found \ + {ident}" )); }, };