Revert "ctrl-rclick tweaks" (#7171)
This commit is contained in:
@@ -13,6 +13,9 @@ namespace Content.Client.Pulling
|
|||||||
base.Initialize();
|
base.Initialize();
|
||||||
|
|
||||||
UpdatesAfter.Add(typeof(PhysicsSystem));
|
UpdatesAfter.Add(typeof(PhysicsSystem));
|
||||||
|
|
||||||
|
SubscribeLocalEvent<SharedPullableComponent, PullableMoveMessage>(OnPullableMove);
|
||||||
|
SubscribeLocalEvent<SharedPullableComponent, PullableStopMovingMessage>(OnPullableStopMove);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
120
Content.Server/Physics/Controllers/PullController.cs
Normal file
120
Content.Server/Physics/Controllers/PullController.cs
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
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<TransformComponent>(puller).MapPosition;
|
||||||
|
var movingTo = pullable.MovingTo.Value.ToMap(EntityManager);
|
||||||
|
if (movingTo.MapId != pullerPosition.MapId)
|
||||||
|
{
|
||||||
|
_pullableSystem.StopMoveTo(pullable);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EntityManager.TryGetComponent<PhysicsComponent?>(pullable.Owner, out var physics) ||
|
||||||
|
physics.BodyType == BodyType.Static ||
|
||||||
|
movingTo.MapId != EntityManager.GetComponent<TransformComponent>(pullable.Owner).MapID)
|
||||||
|
{
|
||||||
|
_pullableSystem.StopMoveTo(pullable);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var movingPosition = movingTo.Position;
|
||||||
|
var ownerPosition = EntityManager.GetComponent<TransformComponent>(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,9 @@
|
|||||||
using Content.Server.Throwing;
|
|
||||||
using Content.Shared.Input;
|
using Content.Shared.Input;
|
||||||
using Content.Shared.Pulling;
|
using Content.Shared.Pulling;
|
||||||
using Content.Shared.Pulling.Components;
|
using Content.Shared.Pulling.Components;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Robust.Server.GameObjects;
|
using Robust.Server.GameObjects;
|
||||||
using Robust.Shared.Input.Binding;
|
using Robust.Shared.Input.Binding;
|
||||||
using Robust.Shared.Map;
|
|
||||||
using Robust.Shared.Players;
|
using Robust.Shared.Players;
|
||||||
|
|
||||||
namespace Content.Server.Pulling
|
namespace Content.Server.Pulling
|
||||||
@@ -19,6 +17,9 @@ namespace Content.Server.Pulling
|
|||||||
|
|
||||||
UpdatesAfter.Add(typeof(PhysicsSystem));
|
UpdatesAfter.Add(typeof(PhysicsSystem));
|
||||||
|
|
||||||
|
SubscribeLocalEvent<SharedPullableComponent, PullableMoveMessage>(OnPullableMove);
|
||||||
|
SubscribeLocalEvent<SharedPullableComponent, PullableStopMovingMessage>(OnPullableStopMove);
|
||||||
|
|
||||||
CommandBinds.Builder
|
CommandBinds.Builder
|
||||||
.Bind(ContentKeyFunctions.ReleasePulledObject, InputCmdHandler.FromDelegate(HandleReleasePulledObject))
|
.Bind(ContentKeyFunctions.ReleasePulledObject, InputCmdHandler.FromDelegate(HandleReleasePulledObject))
|
||||||
.Register<PullingSystem>();
|
.Register<PullingSystem>();
|
||||||
@@ -43,32 +44,5 @@ namespace Content.Server.Pulling
|
|||||||
|
|
||||||
TryStopPull(pullable);
|
TryStopPull(pullable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool TryMoveTo(SharedPullableComponent pullable, EntityCoordinates to)
|
|
||||||
{
|
|
||||||
if (!base.TryMoveTo(pullable, to)) return false;
|
|
||||||
|
|
||||||
var xformQuery = GetEntityQuery<TransformComponent>();
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ namespace Content.Shared.Pulling.Components
|
|||||||
if (Pulling != default)
|
if (Pulling != default)
|
||||||
{
|
{
|
||||||
// This is absolute paranoia but it's also absolutely necessary. Too many puller state bugs. - 20kdc
|
// 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);
|
Logger.ErrorS("c.go.c.pulling", "PULLING STATE CORRUPTION IMMINENT IN PULLER {0} - OnRemove called when Pulling is set!", Owner);
|
||||||
}
|
}
|
||||||
base.OnRemove();
|
base.OnRemove();
|
||||||
|
|||||||
@@ -1,8 +1,24 @@
|
|||||||
|
using System;
|
||||||
using System.Linq;
|
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.Physics.Pull;
|
||||||
using Content.Shared.Pulling.Components;
|
using Content.Shared.Pulling.Components;
|
||||||
|
using Content.Shared.Pulling.Events;
|
||||||
using JetBrains.Annotations;
|
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;
|
||||||
|
using Robust.Shared.Physics.Dynamics.Joints;
|
||||||
|
using Robust.Shared.Players;
|
||||||
|
using Robust.Shared.Utility;
|
||||||
|
|
||||||
namespace Content.Shared.Pulling
|
namespace Content.Shared.Pulling
|
||||||
{
|
{
|
||||||
@@ -37,6 +53,9 @@ namespace Content.Shared.Pulling
|
|||||||
var pullerPhysics = EntityManager.GetComponent<PhysicsComponent>(puller.Owner);
|
var pullerPhysics = EntityManager.GetComponent<PhysicsComponent>(puller.Owner);
|
||||||
var pullablePhysics = EntityManager.GetComponent<PhysicsComponent>(pullable.Owner);
|
var pullablePhysics = EntityManager.GetComponent<PhysicsComponent>(pullable.Owner);
|
||||||
|
|
||||||
|
// MovingTo shutdown
|
||||||
|
ForceSetMovingTo(pullable, null);
|
||||||
|
|
||||||
// Joint shutdown
|
// Joint shutdown
|
||||||
if (EntityManager.TryGetComponent<JointComponent?>(puller.Owner, out var jointComp))
|
if (EntityManager.TryGetComponent<JointComponent?>(puller.Owner, out var jointComp))
|
||||||
{
|
{
|
||||||
@@ -134,5 +153,31 @@ namespace Content.Shared.Pulling
|
|||||||
// DO NOT ADD ADDITIONAL LOGIC IN THIS FUNCTION. Do it in ForceRelationship.
|
// DO NOT ADD ADDITIONAL LOGIC IN THIS FUNCTION. Do it in ForceRelationship.
|
||||||
ForceRelationship(null, pullable);
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,11 @@ using Content.Shared.Physics.Pull;
|
|||||||
using Content.Shared.Pulling.Components;
|
using Content.Shared.Pulling.Components;
|
||||||
using Content.Shared.Pulling.Events;
|
using Content.Shared.Pulling.Events;
|
||||||
using Robust.Shared.Containers;
|
using Robust.Shared.Containers;
|
||||||
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Shared.IoC;
|
||||||
using Robust.Shared.Physics;
|
using Robust.Shared.Physics;
|
||||||
|
using Robust.Shared.Log;
|
||||||
|
|
||||||
namespace Content.Shared.Pulling
|
namespace Content.Shared.Pulling
|
||||||
{
|
{
|
||||||
@@ -26,12 +29,12 @@ namespace Content.Shared.Pulling
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!EntityManager.TryGetComponent<IPhysBody?>(pulled, out var physics))
|
if (!EntityManager.TryGetComponent<IPhysBody?>(pulled, out var _physics))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (physics.BodyType == BodyType.Static)
|
if (_physics.BodyType == BodyType.Static)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -178,7 +181,7 @@ namespace Content.Shared.Pulling
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool TryMoveTo(SharedPullableComponent pullable, EntityCoordinates to)
|
public bool TryMoveTo(SharedPullableComponent pullable, EntityCoordinates to)
|
||||||
{
|
{
|
||||||
if (pullable.Puller == null)
|
if (pullable.Puller == null)
|
||||||
{
|
{
|
||||||
@@ -190,8 +193,13 @@ namespace Content.Shared.Pulling
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Action handled under server
|
_pullSm.ForceSetMovingTo(pullable, to);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void StopMoveTo(SharedPullableComponent pullable)
|
||||||
|
{
|
||||||
|
_pullSm.ForceSetMovingTo(pullable, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using System.Diagnostics.CodeAnalysis;
|
|||||||
using Content.Shared.Alert;
|
using Content.Shared.Alert;
|
||||||
using Content.Shared.GameTicking;
|
using Content.Shared.GameTicking;
|
||||||
using Content.Shared.Input;
|
using Content.Shared.Input;
|
||||||
using Content.Shared.Movement.Components;
|
|
||||||
using Content.Shared.Physics.Pull;
|
using Content.Shared.Physics.Pull;
|
||||||
using Content.Shared.Pulling.Components;
|
using Content.Shared.Pulling.Components;
|
||||||
using Content.Shared.Rotatable;
|
using Content.Shared.Rotatable;
|
||||||
@@ -34,6 +33,9 @@ namespace Content.Shared.Pulling
|
|||||||
private readonly Dictionary<EntityUid, EntityUid> _pullers =
|
private readonly Dictionary<EntityUid, EntityUid> _pullers =
|
||||||
new();
|
new();
|
||||||
|
|
||||||
|
private readonly HashSet<SharedPullableComponent> _moving = new();
|
||||||
|
private readonly HashSet<SharedPullableComponent> _stoppedMoving = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If distance between puller and pulled entity lower that this threshold,
|
/// If distance between puller and pulled entity lower that this threshold,
|
||||||
/// pulled entity will not change its rotation.
|
/// pulled entity will not change its rotation.
|
||||||
@@ -49,6 +51,8 @@ namespace Content.Shared.Pulling
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private const float ThresholdRotAngle = 22.5f;
|
private const float ThresholdRotAngle = 22.5f;
|
||||||
|
|
||||||
|
public IReadOnlySet<SharedPullableComponent> Moving => _moving;
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
@@ -114,9 +118,19 @@ namespace Content.Shared.Pulling
|
|||||||
_alertsSystem.ClearAlert(component.Owner, AlertType.Pulled);
|
_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)
|
public void Reset(RoundRestartCleanupEvent ev)
|
||||||
{
|
{
|
||||||
_pullers.Clear();
|
_pullers.Clear();
|
||||||
|
_moving.Clear();
|
||||||
|
_stoppedMoving.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPullStarted(PullStartedMessage message)
|
private void OnPullStarted(PullStartedMessage message)
|
||||||
@@ -129,6 +143,16 @@ namespace Content.Shared.Pulling
|
|||||||
RemovePuller(message.Puller.Owner);
|
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)
|
private void PullerMoved(ref MoveEvent ev)
|
||||||
{
|
{
|
||||||
var puller = ev.Sender;
|
var puller = ev.Sender;
|
||||||
@@ -193,9 +217,6 @@ namespace Content.Shared.Pulling
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No leverage until this is tweaked more
|
|
||||||
if (player.IsWeightless(entityManager: EntityManager)) return false;
|
|
||||||
|
|
||||||
TryMoveTo(pullable, coords);
|
TryMoveTo(pullable, coords);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user