diff --git a/Content.Server/Physics/Controllers/PullController.cs b/Content.Server/Physics/Controllers/PullController.cs index dd7271b49e..b8a7d81040 100644 --- a/Content.Server/Physics/Controllers/PullController.cs +++ b/Content.Server/Physics/Controllers/PullController.cs @@ -1,10 +1,6 @@ -using System; -using System.Collections.Generic; -using Content.Shared.Pulling; +using Content.Shared.Pulling; using Content.Shared.Pulling.Components; -using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Maths; +using Content.Shared.Rotatable; using Robust.Shared.Physics; using Robust.Shared.Physics.Controllers; @@ -37,6 +33,22 @@ namespace Content.Server.Physics.Controllers [Dependency] private readonly SharedPullingSystem _pullableSystem = default!; + // TODO: Move this stuff to pullingsystem + /// + /// If distance between puller and pulled entity lower that this threshold, + /// pulled entity will not change its rotation. + /// Helps with small distance jittering + /// + private const float ThresholdRotDistance = 1; + + /// + /// If difference between puller and pulled angle lower that this threshold, + /// pulled entity will not change its rotation. + /// Helps with diagonal movement jittering + /// As of further adjustments, should divide cleanly into 90 degrees + /// + private const float ThresholdRotAngle = 22.5f; + public override void Initialize() { UpdatesAfter.Add(typeof(MoverController)); @@ -50,9 +62,46 @@ namespace Content.Server.Physics.Controllers if (component.Pulling == null || !TryComp(component.Pulling.Value, out var pullable)) return; + UpdatePulledRotation(uid, pullable.Owner); + + if (TryComp(pullable.Owner, out var physics)) + physics.WakeBody(); + _pullableSystem.StopMoveTo(pullable); } + private void UpdatePulledRotation(EntityUid puller, EntityUid pulled) + { + // TODO: update once ComponentReference works with directed event bus. + if (!TryComp(pulled, out RotatableComponent? rotatable)) + return; + + if (!rotatable.RotateWhilePulling) + return; + + var pulledXform = Transform(pulled); + + var dir = Transform(puller).WorldPosition - pulledXform.WorldPosition; + if (dir.LengthSquared > ThresholdRotDistance * ThresholdRotDistance) + { + var oldAngle = pulledXform.WorldRotation; + var newAngle = Angle.FromWorldVec(dir); + + var diff = newAngle - oldAngle; + if (Math.Abs(diff.Degrees) > (ThresholdRotAngle / 2f)) + { + // Ok, so this bit is difficult because ideally it would look like it's snapping to sane angles. + // Otherwise PIANO DOOR STUCK! happens. + // But it also needs to work with station rotation / align to the local parent. + // So... + var baseRotation = pulledXform.Parent?.WorldRotation ?? 0f; + var localRotation = newAngle - baseRotation; + var localRotationSnapped = Angle.FromDegrees(Math.Floor((localRotation.Degrees / ThresholdRotAngle) + 0.5f) * ThresholdRotAngle); + pulledXform.LocalRotation = localRotationSnapped; + } + } + } + public override void UpdateBeforeSolve(bool prediction, float frameTime) { base.UpdateBeforeSolve(prediction, frameTime); diff --git a/Content.Shared/Pulling/Systems/SharedPullingSystem.cs b/Content.Shared/Pulling/Systems/SharedPullingSystem.cs index e87bcd3819..72cce36d5e 100644 --- a/Content.Shared/Pulling/Systems/SharedPullingSystem.cs +++ b/Content.Shared/Pulling/Systems/SharedPullingSystem.cs @@ -37,21 +37,6 @@ namespace Content.Shared.Pulling private readonly HashSet _moving = new(); private readonly HashSet _stoppedMoving = new(); - /// - /// If distance between puller and pulled entity lower that this threshold, - /// pulled entity will not change its rotation. - /// Helps with small distance jittering - /// - private const float ThresholdRotDistance = 1; - - /// - /// If difference between puller and pulled angle lower that this threshold, - /// pulled entity will not change its rotation. - /// Helps with diagonal movement jittering - /// As of further adjustments, should divide cleanly into 90 degrees - /// - private const float ThresholdRotAngle = 22.5f; - public IReadOnlySet Moving => _moving; public override void Initialize() @@ -63,7 +48,6 @@ namespace Content.Shared.Pulling SubscribeLocalEvent(Reset); SubscribeLocalEvent(OnPullStarted); SubscribeLocalEvent(OnPullStopped); - SubscribeLocalEvent(PullerMoved); SubscribeLocalEvent(HandleContainerInsert); SubscribeLocalEvent(PullableHandlePullStarted); @@ -154,33 +138,6 @@ namespace Content.Shared.Pulling _stoppedMoving.Add(component); } - private void PullerMoved(ref MoveEvent ev) - { - var puller = ev.Sender; - - if (!TryGetPulled(ev.Sender, out var pulled)) - { - return; - } - - // The pulled object may have already been deleted. - // TODO: Work out why. Monkey + meat spike is a good test for this, - // assuming you're still pulling the monkey when it gets gibbed. - if (Deleted(pulled.Value)) - { - return; - } - - if (!EntityManager.TryGetComponent(pulled.Value, out IPhysBody? physics)) - { - return; - } - - UpdatePulledRotation(puller, pulled.Value); - - physics.WakeBody(); - } - // TODO: When Joint networking is less shitcodey fix this to use a dedicated joints message. private void HandleContainerInsert(EntInsertedIntoContainerMessage message) { @@ -251,37 +208,5 @@ namespace Content.Shared.Pulling { return _pullers.ContainsKey(puller); } - - private void UpdatePulledRotation(EntityUid puller, EntityUid pulled) - { - // TODO: update once ComponentReference works with directed event bus. - if (!EntityManager.TryGetComponent(pulled, out RotatableComponent? rotatable)) - return; - - if (!rotatable.RotateWhilePulling) - return; - - var pulledXform = EntityManager.GetComponent(pulled); - - var dir = EntityManager.GetComponent(puller).WorldPosition - pulledXform.WorldPosition; - if (dir.LengthSquared > ThresholdRotDistance * ThresholdRotDistance) - { - var oldAngle = pulledXform.WorldRotation; - var newAngle = Angle.FromWorldVec(dir); - - var diff = newAngle - oldAngle; - if (Math.Abs(diff.Degrees) > (ThresholdRotAngle / 2f)) - { - // Ok, so this bit is difficult because ideally it would look like it's snapping to sane angles. - // Otherwise PIANO DOOR STUCK! happens. - // But it also needs to work with station rotation / align to the local parent. - // So... - var baseRotation = pulledXform.Parent?.WorldRotation ?? 0f; - var localRotation = newAngle - baseRotation; - var localRotationSnapped = Angle.FromDegrees(Math.Floor((localRotation.Degrees / ThresholdRotAngle) + 0.5f) * ThresholdRotAngle); - pulledXform.LocalRotation = localRotationSnapped; - } - } - } } }