diff --git a/Content.Client/Pulling/PullingSystem.cs b/Content.Client/Pulling/PullingSystem.cs index 556dadd00d..04b2195a46 100644 --- a/Content.Client/Pulling/PullingSystem.cs +++ b/Content.Client/Pulling/PullingSystem.cs @@ -13,9 +13,6 @@ namespace Content.Client.Pulling base.Initialize(); UpdatesAfter.Add(typeof(PhysicsSystem)); - - SubscribeLocalEvent(OnPullableMove); - SubscribeLocalEvent(OnPullableStopMove); } } } diff --git a/Content.Server/Physics/Controllers/PullController.cs b/Content.Server/Physics/Controllers/PullController.cs deleted file mode 100644 index fc93d4cf46..0000000000 --- a/Content.Server/Physics/Controllers/PullController.cs +++ /dev/null @@ -1,120 +0,0 @@ -using System; -using System.Collections.Generic; -using Content.Shared.Pulling; -using Robust.Shared.GameObjects; -using Robust.Shared.IoC; -using Robust.Shared.Maths; -using Robust.Shared.Physics; -using Robust.Shared.Physics.Controllers; - -namespace Content.Server.Physics.Controllers -{ - public sealed class PullController : VirtualController - { - // Parameterization for pulling: - // Speeds. Note that the speed is mass-independent (multiplied by mass). - // Instead, tuning to mass is done via the mass values below. - // Note that setting the speed too high results in overshoots (stabilized by drag, but bad) - private const float AccelModifierHigh = 15f; - private const float AccelModifierLow = 60.0f; - // High/low-mass marks. Curve is constant-lerp-constant, i.e. if you can even pull an item, - // you'll always get at least AccelModifierLow and no more than AccelModifierHigh. - private const float AccelModifierHighMass = 70.0f; // roundstart saltern emergency closet - private const float AccelModifierLowMass = 5.0f; // roundstart saltern emergency crowbar - // Used to control settling (turns off pulling). - private const float MaximumSettleVelocity = 0.1f; - private const float MaximumSettleDistance = 0.01f; - // Settle shutdown control. - // Mustn't be too massive, as that causes severe mispredicts *and can prevent it ever resolving*. - // Exists to bleed off "I pulled my crowbar" overshoots. - // Minimum velocity for shutdown to be necessary. This prevents stuff getting stuck b/c too much shutdown. - private const float SettleMinimumShutdownVelocity = 0.25f; - // Distance in which settle shutdown multiplier is at 0. It then scales upwards linearly with closer distances. - private const float SettleShutdownDistance = 1.0f; - // Velocity change of -LinearVelocity * frameTime * this - private const float SettleShutdownMultiplier = 20.0f; - - [Dependency] private readonly SharedPullingSystem _pullableSystem = default!; - - public override void Initialize() - { - UpdatesAfter.Add(typeof(MoverController)); - - base.Initialize(); - } - - public override void UpdateBeforeSolve(bool prediction, float frameTime) - { - base.UpdateBeforeSolve(prediction, frameTime); - - foreach (var pullable in _pullableSystem.Moving) - { - // There's a 1-frame delay between stopping moving something and it leaving the Moving set. - // This can include if leaving the Moving set due to not being pulled anymore, - // or due to being deleted. - - if (pullable.Deleted) - { - continue; - } - - if (pullable.MovingTo == null) - { - continue; - } - - if (pullable.Puller is not {Valid: true} puller) - { - continue; - } - - // Now that's over with... - - var pullerPosition = EntityManager.GetComponent(puller).MapPosition; - var movingTo = pullable.MovingTo.Value.ToMap(EntityManager); - if (movingTo.MapId != pullerPosition.MapId) - { - _pullableSystem.StopMoveTo(pullable); - continue; - } - - if (!EntityManager.TryGetComponent(pullable.Owner, out var physics) || - physics.BodyType == BodyType.Static || - movingTo.MapId != EntityManager.GetComponent(pullable.Owner).MapID) - { - _pullableSystem.StopMoveTo(pullable); - continue; - } - - var movingPosition = movingTo.Position; - var ownerPosition = EntityManager.GetComponent(pullable.Owner).MapPosition.Position; - - var diff = movingPosition - ownerPosition; - var diffLength = diff.Length; - - if ((diffLength < MaximumSettleDistance) && (physics.LinearVelocity.Length < MaximumSettleVelocity)) - { - physics.LinearVelocity = Vector2.Zero; - _pullableSystem.StopMoveTo(pullable); - continue; - } - - var impulseModifierLerp = Math.Min(1.0f, Math.Max(0.0f, (physics.Mass - AccelModifierLowMass) / (AccelModifierHighMass - AccelModifierLowMass))); - var impulseModifier = MathHelper.Lerp(AccelModifierLow, AccelModifierHigh, impulseModifierLerp); - var multiplier = diffLength < 1 ? impulseModifier * diffLength : impulseModifier; - // Note the implication that the real rules of physics don't apply to pulling control. - var accel = diff.Normalized * multiplier; - // Now for the part where velocity gets shutdown... - if ((diffLength < SettleShutdownDistance) && (physics.LinearVelocity.Length >= SettleMinimumShutdownVelocity)) - { - // Shutdown velocity increases as we get closer to centre - var scaling = (SettleShutdownDistance - diffLength) / SettleShutdownDistance; - accel -= physics.LinearVelocity * SettleShutdownMultiplier * scaling; - } - physics.WakeBody(); - var impulse = accel * physics.Mass * frameTime; - physics.ApplyLinearImpulse(impulse); - } - } - } -} diff --git a/Content.Server/Pulling/PullingSystem.cs b/Content.Server/Pulling/PullingSystem.cs index f7ea0aae57..3aae7dfd57 100644 --- a/Content.Server/Pulling/PullingSystem.cs +++ b/Content.Server/Pulling/PullingSystem.cs @@ -1,9 +1,11 @@ +using Content.Server.Throwing; using Content.Shared.Input; using Content.Shared.Pulling; using Content.Shared.Pulling.Components; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Shared.Input.Binding; +using Robust.Shared.Map; using Robust.Shared.Players; namespace Content.Server.Pulling @@ -17,9 +19,6 @@ namespace Content.Server.Pulling UpdatesAfter.Add(typeof(PhysicsSystem)); - SubscribeLocalEvent(OnPullableMove); - SubscribeLocalEvent(OnPullableStopMove); - CommandBinds.Builder .Bind(ContentKeyFunctions.ReleasePulledObject, InputCmdHandler.FromDelegate(HandleReleasePulledObject)) .Register(); @@ -44,5 +43,32 @@ namespace Content.Server.Pulling TryStopPull(pullable); } + + public override bool TryMoveTo(SharedPullableComponent pullable, EntityCoordinates to) + { + if (!base.TryMoveTo(pullable, to)) return false; + + var xformQuery = GetEntityQuery(); + var pullableXform = xformQuery.GetComponent(pullable.Owner); + var targetPos = to.ToMap(EntityManager); + + if (targetPos.MapId != pullableXform.MapID) return false; + + var pullablePos = pullableXform.WorldPosition; + + if (pullablePos.EqualsApprox(targetPos.Position, 0.01f)) return false; + + var vec = (targetPos.Position - pullablePos); + + // Just move it to the spot for finetuning + if (vec.Length < 0.15f) + { + pullableXform.WorldPosition = targetPos.Position; + return true; + } + + pullable.Owner.TryThrow(vec, 3f); + return true; + } } } diff --git a/Content.Shared/Pulling/Components/SharedPullerComponent.cs b/Content.Shared/Pulling/Components/SharedPullerComponent.cs index 4e3976168b..d77a6cdc32 100644 --- a/Content.Shared/Pulling/Components/SharedPullerComponent.cs +++ b/Content.Shared/Pulling/Components/SharedPullerComponent.cs @@ -28,6 +28,7 @@ namespace Content.Shared.Pulling.Components if (Pulling != default) { // This is absolute paranoia but it's also absolutely necessary. Too many puller state bugs. - 20kdc + // Good thing Pulling is nullable now. Logger.ErrorS("c.go.c.pulling", "PULLING STATE CORRUPTION IMMINENT IN PULLER {0} - OnRemove called when Pulling is set!", Owner); } base.OnRemove(); diff --git a/Content.Shared/Pulling/Systems/SharedPullingStateManagementSystem.cs b/Content.Shared/Pulling/Systems/SharedPullingStateManagementSystem.cs index 95f9d7a8cb..579dc5f4e0 100644 --- a/Content.Shared/Pulling/Systems/SharedPullingStateManagementSystem.cs +++ b/Content.Shared/Pulling/Systems/SharedPullingStateManagementSystem.cs @@ -1,24 +1,8 @@ -using System; using System.Linq; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using Content.Shared.GameTicking; -using Content.Shared.Input; using Content.Shared.Physics.Pull; using Content.Shared.Pulling.Components; -using Content.Shared.Pulling.Events; using JetBrains.Annotations; -using Robust.Shared.Containers; -using Robust.Shared.GameObjects; -using Robust.Shared.Input.Binding; -using Robust.Shared.IoC; -using Robust.Shared.Log; -using Robust.Shared.Map; -using Robust.Shared.Maths; using Robust.Shared.Physics; -using Robust.Shared.Physics.Dynamics.Joints; -using Robust.Shared.Players; -using Robust.Shared.Utility; namespace Content.Shared.Pulling { @@ -53,9 +37,6 @@ namespace Content.Shared.Pulling var pullerPhysics = EntityManager.GetComponent(puller.Owner); var pullablePhysics = EntityManager.GetComponent(pullable.Owner); - // MovingTo shutdown - ForceSetMovingTo(pullable, null); - // Joint shutdown if (EntityManager.TryGetComponent(puller.Owner, out var jointComp)) { @@ -153,31 +134,5 @@ namespace Content.Shared.Pulling // DO NOT ADD ADDITIONAL LOGIC IN THIS FUNCTION. Do it in ForceRelationship. ForceRelationship(null, pullable); } - - public void ForceSetMovingTo(SharedPullableComponent pullable, EntityCoordinates? movingTo) - { - if (pullable.MovingTo == movingTo) - { - return; - } - - // Don't allow setting a MovingTo if there's no puller. - // The other half of this guarantee (shutting down a MovingTo if the puller goes away) is enforced in ForceRelationship. - if ((pullable.Puller == null) && (movingTo != null)) - { - return; - } - - pullable.MovingTo = movingTo; - - if (movingTo == null) - { - RaiseLocalEvent(pullable.Owner, new PullableStopMovingMessage()); - } - else - { - RaiseLocalEvent(pullable.Owner, new PullableMoveMessage()); - } - } } } diff --git a/Content.Shared/Pulling/Systems/SharedPullingSystem.Actions.cs b/Content.Shared/Pulling/Systems/SharedPullingSystem.Actions.cs index 9406f58fca..dc9dfca3a2 100644 --- a/Content.Shared/Pulling/Systems/SharedPullingSystem.Actions.cs +++ b/Content.Shared/Pulling/Systems/SharedPullingSystem.Actions.cs @@ -4,11 +4,8 @@ using Content.Shared.Physics.Pull; using Content.Shared.Pulling.Components; using Content.Shared.Pulling.Events; using Robust.Shared.Containers; -using Robust.Shared.GameObjects; using Robust.Shared.Map; -using Robust.Shared.IoC; using Robust.Shared.Physics; -using Robust.Shared.Log; namespace Content.Shared.Pulling { @@ -29,12 +26,12 @@ namespace Content.Shared.Pulling return false; } - if (!EntityManager.TryGetComponent(pulled, out var _physics)) + if (!EntityManager.TryGetComponent(pulled, out var physics)) { return false; } - if (_physics.BodyType == BodyType.Static) + if (physics.BodyType == BodyType.Static) { return false; } @@ -181,7 +178,7 @@ namespace Content.Shared.Pulling return true; } - public bool TryMoveTo(SharedPullableComponent pullable, EntityCoordinates to) + public virtual bool TryMoveTo(SharedPullableComponent pullable, EntityCoordinates to) { if (pullable.Puller == null) { @@ -193,13 +190,8 @@ namespace Content.Shared.Pulling return false; } - _pullSm.ForceSetMovingTo(pullable, to); + // Action handled under server return true; } - - public void StopMoveTo(SharedPullableComponent pullable) - { - _pullSm.ForceSetMovingTo(pullable, null); - } } } diff --git a/Content.Shared/Pulling/Systems/SharedPullingSystem.cs b/Content.Shared/Pulling/Systems/SharedPullingSystem.cs index a36aec2a14..632459649f 100644 --- a/Content.Shared/Pulling/Systems/SharedPullingSystem.cs +++ b/Content.Shared/Pulling/Systems/SharedPullingSystem.cs @@ -4,6 +4,7 @@ using System.Diagnostics.CodeAnalysis; using Content.Shared.Alert; using Content.Shared.GameTicking; using Content.Shared.Input; +using Content.Shared.Movement.Components; using Content.Shared.Physics.Pull; using Content.Shared.Pulling.Components; using Content.Shared.Rotatable; @@ -33,9 +34,6 @@ namespace Content.Shared.Pulling private readonly Dictionary _pullers = new(); - 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. @@ -51,8 +49,6 @@ namespace Content.Shared.Pulling /// private const float ThresholdRotAngle = 22.5f; - public IReadOnlySet Moving => _moving; - public override void Initialize() { base.Initialize(); @@ -106,7 +102,7 @@ namespace Content.Shared.Pulling { if (args.Pulled.Owner != uid) return; - + _alertsSystem.ShowAlert(component.Owner, AlertType.Pulled); } @@ -118,19 +114,9 @@ namespace Content.Shared.Pulling _alertsSystem.ClearAlert(component.Owner, AlertType.Pulled); } - public override void Update(float frameTime) - { - base.Update(frameTime); - - _moving.ExceptWith(_stoppedMoving); - _stoppedMoving.Clear(); - } - public void Reset(RoundRestartCleanupEvent ev) { _pullers.Clear(); - _moving.Clear(); - _stoppedMoving.Clear(); } private void OnPullStarted(PullStartedMessage message) @@ -143,16 +129,6 @@ namespace Content.Shared.Pulling RemovePuller(message.Puller.Owner); } - protected void OnPullableMove(EntityUid uid, SharedPullableComponent component, PullableMoveMessage args) - { - _moving.Add(component); - } - - protected void OnPullableStopMove(EntityUid uid, SharedPullableComponent component, PullableStopMovingMessage args) - { - _stoppedMoving.Add(component); - } - private void PullerMoved(ref MoveEvent ev) { var puller = ev.Sender; @@ -217,6 +193,9 @@ namespace Content.Shared.Pulling return false; } + // No leverage until this is tweaked more + if (player.IsWeightless(entityManager: EntityManager)) return false; + TryMoveTo(pullable, coords); return false;