diff --git a/Content.Server/Fluids/Components/SprayComponent.cs b/Content.Server/Fluids/Components/SprayComponent.cs
index e5362eb4e9..128fdecfa7 100644
--- a/Content.Server/Fluids/Components/SprayComponent.cs
+++ b/Content.Server/Fluids/Components/SprayComponent.cs
@@ -32,10 +32,10 @@ public sealed partial class SprayComponent : Component
///
/// How much the player is pushed back for each spray.
///
- [ViewVariables(VVAccess.ReadWrite), DataField]
- public float PushbackAmount = 2f;
+ [DataField]
+ public float PushbackAmount = 5f;
- [ViewVariables(VVAccess.ReadWrite), DataField(required: true)]
+ [DataField(required: true)]
[Access(typeof(SpraySystem), Other = AccessPermissions.ReadExecute)] // FIXME Friends
public SoundSpecifier SpraySound { get; private set; } = default!;
}
diff --git a/Content.Server/Fluids/EntitySystems/SpraySystem.cs b/Content.Server/Fluids/EntitySystems/SpraySystem.cs
index a1f195bf43..d8da0cde3d 100644
--- a/Content.Server/Fluids/EntitySystems/SpraySystem.cs
+++ b/Content.Server/Fluids/EntitySystems/SpraySystem.cs
@@ -3,14 +3,16 @@ using Content.Server.Chemistry.EntitySystems;
using Content.Server.Fluids.Components;
using Content.Server.Gravity;
using Content.Server.Popups;
+using Content.Shared.CCVar;
+using Content.Shared.Chemistry.EntitySystems;
using Content.Shared.FixedPoint;
using Content.Shared.Fluids;
using Content.Shared.Interaction;
using Content.Shared.Timing;
using Content.Shared.Vapor;
-using Content.Shared.Chemistry.EntitySystems;
using Robust.Server.GameObjects;
using Robust.Shared.Audio.Systems;
+using Robust.Shared.Configuration;
using Robust.Shared.Physics.Components;
using Robust.Shared.Prototypes;
using System.Numerics;
@@ -30,6 +32,9 @@ public sealed class SpraySystem : EntitySystem
[Dependency] private readonly VaporSystem _vapor = default!;
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
+ [Dependency] private readonly IConfigurationManager _cfg = default!;
+
+ private float _gridImpulseMultiplier;
public override void Initialize()
{
@@ -37,6 +42,7 @@ public sealed class SpraySystem : EntitySystem
SubscribeLocalEvent(OnAfterInteract);
SubscribeLocalEvent(OnActivateInWorld);
+ Subs.CVar(_cfg, CCVars.GridImpulseMultiplier, UpdateGridMassMultiplier, true);
}
private void OnActivateInWorld(Entity entity, ref UserActivateInWorldEvent args)
@@ -51,6 +57,11 @@ public sealed class SpraySystem : EntitySystem
Spray(entity, args.User, targetMapPos);
}
+ private void UpdateGridMassMultiplier(float value)
+ {
+ _gridImpulseMultiplier = value;
+ }
+
private void OnAfterInteract(Entity entity, ref AfterInteractEvent args)
{
if (args.Handled)
@@ -156,7 +167,21 @@ public sealed class SpraySystem : EntitySystem
if (TryComp(user, out var body))
{
if (_gravity.IsWeightless(user, body))
- _physics.ApplyLinearImpulse(user, -impulseDirection.Normalized() * entity.Comp.PushbackAmount, body: body);
+ {
+ // push back the player
+ _physics.ApplyLinearImpulse(user, -impulseDirection * entity.Comp.PushbackAmount, body: body);
+ }
+ else
+ {
+ // push back the grid the player is standing on
+ var userTransform = Transform(user);
+ if (userTransform.GridUid == userTransform.ParentUid)
+ {
+ // apply both linear and angular momentum depending on the player position
+ // multiply by a cvar because grid mass is currently extremely small compared to all other masses
+ _physics.ApplyLinearImpulse(userTransform.GridUid.Value, -impulseDirection * _gridImpulseMultiplier * entity.Comp.PushbackAmount, userTransform.LocalPosition);
+ }
+ }
}
}
diff --git a/Content.Shared/CCVar/CCVars.Shuttle.cs b/Content.Shared/CCVar/CCVars.Shuttle.cs
index 74d3bf8cfb..47fc816c05 100644
--- a/Content.Shared/CCVar/CCVars.Shuttle.cs
+++ b/Content.Shared/CCVar/CCVars.Shuttle.cs
@@ -182,4 +182,16 @@ public sealed partial class CCVars
///
public static readonly CVarDef EmergencyShuttleAutoCallExtensionTime =
CVarDef.Create("shuttle.auto_call_extension_time", 45, CVar.SERVERONLY);
+
+ ///
+ /// Impulse multiplier for player interactions that move grids (other than shuttle thrusters, gyroscopes and grid collisons).
+ /// At the moment this only affects the pushback in SpraySystem.
+ /// A higher value means grids have a lower effective mass and therefore will get pushed stronger.
+ /// A value of 0 will disable pushback.
+ /// The default has been chosen such that a one tile grid roughly equals 2/3 Urist masses.
+ /// TODO: Make grid mass a sane number so we can get rid of this.
+ /// At the moment they have a very low mass of roughly 0.48 kg per tile independent of any walls or anchored objects on them.
+ ///
+ public static readonly CVarDef GridImpulseMultiplier =
+ CVarDef.Create("shuttle.grid_impulse_multiplier", 0.01f, CVar.SERVERONLY);
}