diff --git a/Content.Server/GameObjects/Components/GUI/HandsComponent.cs b/Content.Server/GameObjects/Components/GUI/HandsComponent.cs index f5403a6928..a7c0c49289 100644 --- a/Content.Server/GameObjects/Components/GUI/HandsComponent.cs +++ b/Content.Server/GameObjects/Components/GUI/HandsComponent.cs @@ -13,7 +13,7 @@ using Content.Shared.GameObjects.Components.Items; using Content.Shared.GameObjects.Components.Mobs; using Content.Shared.GameObjects.EntitySystems; using Content.Shared.Health.BodySystem; -using Content.Shared.Physics; +using Content.Shared.Physics.Pull; using Robust.Server.GameObjects; using Robust.Server.GameObjects.Components.Container; using Robust.Server.GameObjects.EntitySystemMessages; @@ -547,15 +547,9 @@ namespace Content.Server.GameObjects.Components.GUI return; } - var isOwnerContained = ContainerHelpers.TryGetContainer(Owner, out var ownerContainer); - var isPullableContained = ContainerHelpers.TryGetContainer(pullable.Owner, out var pullableContainer); - - if (isOwnerContained || isPullableContained) + if (!Owner.IsInSameOrNoContainer(pullable.Owner)) { - if (ownerContainer != pullableContainer) - { - return; - } + return; } if (IsPulling) @@ -564,10 +558,8 @@ namespace Content.Server.GameObjects.Components.GUI } PulledObject = pullable.Owner.GetComponent(); - var controller = PulledObject!.EnsureController(); - controller!.StartPull(Owner.GetComponent()); - - AddPullingStatuses(); + var controller = PulledObject.EnsureController(); + controller.StartPull(Owner.GetComponent()); } public void MovePulledObject(GridCoordinates puller, GridCoordinates to) @@ -579,6 +571,27 @@ namespace Content.Server.GameObjects.Components.GUI } } + public override void HandleMessage(ComponentMessage message, IComponent? component) + { + base.HandleMessage(message, component); + + if (!(message is PullMessage pullMessage) || + pullMessage.Puller.Owner != Owner) + { + return; + } + + switch (message) + { + case PullStartedMessage msg: + AddPullingStatuses(msg.Pulled.Owner); + break; + case PullStoppedMessage msg: + RemovePullingStatuses(msg.Pulled.Owner); + break; + } + } + public override void HandleNetworkMessage(ComponentMessage message, INetChannel channel, ICommonSession? session = null) { base.HandleNetworkMessage(message, channel, session); @@ -689,10 +702,9 @@ namespace Content.Server.GameObjects.Components.GUI } } - private void AddPullingStatuses() + private void AddPullingStatuses(IEntity pulled) { - if (PulledObject?.Owner != null && - PulledObject.Owner.TryGetComponent(out ServerStatusEffectsComponent pulledStatus)) + if (pulled.TryGetComponent(out ServerStatusEffectsComponent pulledStatus)) { pulledStatus.ChangeStatusEffectIcon(StatusEffect.Pulled, "/Textures/Interface/StatusEffects/Pull/pulled.png"); @@ -705,10 +717,9 @@ namespace Content.Server.GameObjects.Components.GUI } } - private void RemovePullingStatuses() + private void RemovePullingStatuses(IEntity pulled) { - if (PulledObject?.Owner != null && - PulledObject.Owner.TryGetComponent(out ServerStatusEffectsComponent pulledStatus)) + if (pulled.TryGetComponent(out ServerStatusEffectsComponent pulledStatus)) { pulledStatus.RemoveStatusEffect(StatusEffect.Pulled); } @@ -719,12 +730,6 @@ namespace Content.Server.GameObjects.Components.GUI } } - public override void StopPull() - { - RemovePullingStatuses(); - base.StopPull(); - } - void IBodyPartAdded.BodyPartAdded(BodyPartAddedEventArgs eventArgs) { if (eventArgs.Part.PartType != BodyPartType.Hand) diff --git a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs index 478f0123d2..41640a0fac 100644 --- a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs @@ -12,6 +12,7 @@ using Content.Shared.GameObjects.EntitySystems; using Content.Shared.Input; using Content.Shared.Interfaces.GameObjects.Components; using Content.Shared.Physics; +using Content.Shared.Physics.Pull; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Server.Interfaces.Player; diff --git a/Content.Server/GlobalVerbs/PullingVerb.cs b/Content.Server/GlobalVerbs/PullingVerb.cs index 0b864eb075..6213d443a5 100644 --- a/Content.Server/GlobalVerbs/PullingVerb.cs +++ b/Content.Server/GlobalVerbs/PullingVerb.cs @@ -4,6 +4,7 @@ using Content.Shared.GameObjects.Components.Items; using Content.Shared.GameObjects.EntitySystems; using Content.Shared.GameObjects.Verbs; using Content.Shared.Physics; +using Content.Shared.Physics.Pull; using Robust.Server.Interfaces.GameObjects; using Robust.Shared.GameObjects.Components; using Robust.Shared.Interfaces.GameObjects; diff --git a/Content.Shared/GameObjects/Components/Items/SharedHandsComponent.cs b/Content.Shared/GameObjects/Components/Items/SharedHandsComponent.cs index 47a15e5f10..02919bcf8e 100644 --- a/Content.Shared/GameObjects/Components/Items/SharedHandsComponent.cs +++ b/Content.Shared/GameObjects/Components/Items/SharedHandsComponent.cs @@ -1,8 +1,9 @@ #nullable enable using System; -using Content.Shared.Physics; +using Content.Shared.Physics.Pull; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Components; +using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -26,8 +27,27 @@ namespace Content.Shared.GameObjects.Components.Items { controller.StopPull(); } + } - PulledObject = null; + public override void HandleMessage(ComponentMessage message, IComponent? component) + { + base.HandleMessage(message, component); + + if (!(message is PullMessage pullMessage) || + pullMessage.Puller.Owner != Owner) + { + return; + } + + switch (message) + { + case PullStartedMessage msg: + PulledObject = msg.Pulled; + break; + case PullStoppedMessage _: + PulledObject = null; + break; + } } } diff --git a/Content.Shared/GameObjects/EntitySystems/SharedMoverSystem.cs b/Content.Shared/GameObjects/EntitySystems/SharedMoverSystem.cs index 7c9a4537a2..49f77ad735 100644 --- a/Content.Shared/GameObjects/EntitySystems/SharedMoverSystem.cs +++ b/Content.Shared/GameObjects/EntitySystems/SharedMoverSystem.cs @@ -3,6 +3,7 @@ using System.Diagnostics.CodeAnalysis; using Content.Shared.GameObjects.Components.Items; using Content.Shared.GameObjects.Components.Movement; using Content.Shared.Physics; +using Content.Shared.Physics.Pull; using Robust.Shared.Configuration; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Components; diff --git a/Content.Shared/Physics/PullController.cs b/Content.Shared/Physics/Pull/PullController.cs similarity index 68% rename from Content.Shared/Physics/PullController.cs rename to Content.Shared/Physics/Pull/PullController.cs index c0ea728571..02b199a345 100644 --- a/Content.Shared/Physics/PullController.cs +++ b/Content.Shared/Physics/Pull/PullController.cs @@ -1,15 +1,16 @@ #nullable enable using System; -using Content.Shared.GameObjects.Components.Items; using Content.Shared.GameObjects.EntitySystems; +using Robust.Shared.Containers; using Robust.Shared.GameObjects.Components; using Robust.Shared.Interfaces.Map; using Robust.Shared.IoC; using Robust.Shared.Map; using Robust.Shared.Maths; using Robust.Shared.Physics; +using Robust.Shared.Utility; -namespace Content.Shared.Physics +namespace Content.Shared.Physics.Pull { public class PullController : VirtualController { @@ -25,15 +26,50 @@ namespace Content.Shared.Physics public ICollidableComponent? Puller => _puller; - public void StartPull(ICollidableComponent? pull) + public void StartPull(ICollidableComponent puller) { - _puller = pull; + DebugTools.AssertNotNull(puller); + + if (_puller == puller) + { + return; + } + + _puller = puller; + + if (ControlledComponent == null) + { + return; + } + + var message = new PullStartedMessage(this, _puller, ControlledComponent); + + _puller.Owner.SendMessage(null, message); + ControlledComponent.Owner.SendMessage(null, message); } public void StopPull() { + var oldPuller = _puller; + + if (oldPuller == null) + { + return; + } + _puller = null; - ControlledComponent?.TryRemoveController(); + + if (ControlledComponent == null) + { + return; + } + + var message = new PullStoppedMessage(this, oldPuller, ControlledComponent); + + oldPuller.Owner.SendMessage(null, message); + ControlledComponent.Owner.SendMessage(null, message); + + ControlledComponent.TryRemoveController(); } public void TryMoveTo(GridCoordinates from, GridCoordinates to) @@ -68,12 +104,18 @@ namespace Content.Shared.Physics return; } + if (!_puller.Owner.IsInSameOrNoContainer(ControlledComponent.Owner)) + { + StopPull(); + return; + } + // Are we outside of pulling range? var dist = _puller.Owner.Transform.WorldPosition - ControlledComponent.Owner.Transform.WorldPosition; if (dist.Length > DistBeforeStopPull) { - _puller.Owner.GetComponent().StopPull(); + StopPull(); } else if (_movingTo.HasValue) { diff --git a/Content.Shared/Physics/Pull/PullMessage.cs b/Content.Shared/Physics/Pull/PullMessage.cs new file mode 100644 index 0000000000..811eae404e --- /dev/null +++ b/Content.Shared/Physics/Pull/PullMessage.cs @@ -0,0 +1,19 @@ +using Robust.Shared.GameObjects; +using Robust.Shared.GameObjects.Components; + +namespace Content.Shared.Physics.Pull +{ + public class PullMessage : ComponentMessage + { + public readonly PullController Controller; + public readonly ICollidableComponent Puller; + public readonly ICollidableComponent Pulled; + + protected PullMessage(PullController controller, ICollidableComponent puller, ICollidableComponent pulled) + { + Controller = controller; + Puller = puller; + Pulled = pulled; + } + } +} diff --git a/Content.Shared/Physics/Pull/PullStartedMessage.cs b/Content.Shared/Physics/Pull/PullStartedMessage.cs new file mode 100644 index 0000000000..263c0b8db1 --- /dev/null +++ b/Content.Shared/Physics/Pull/PullStartedMessage.cs @@ -0,0 +1,12 @@ +using Robust.Shared.GameObjects.Components; + +namespace Content.Shared.Physics.Pull +{ + public class PullStartedMessage : PullMessage + { + public PullStartedMessage(PullController controller, ICollidableComponent puller, ICollidableComponent pulled) : + base(controller, puller, pulled) + { + } + } +} diff --git a/Content.Shared/Physics/Pull/PullStoppedMessage.cs b/Content.Shared/Physics/Pull/PullStoppedMessage.cs new file mode 100644 index 0000000000..c018558341 --- /dev/null +++ b/Content.Shared/Physics/Pull/PullStoppedMessage.cs @@ -0,0 +1,12 @@ +using Robust.Shared.GameObjects.Components; + +namespace Content.Shared.Physics.Pull +{ + public class PullStoppedMessage : PullMessage + { + public PullStoppedMessage(PullController controller, ICollidableComponent puller, ICollidableComponent pulled) : + base(controller, puller, pulled) + { + } + } +}