Fix walls and other unanchorable objects being unanchored by the G.O.R.I.L.L.A gauntlet (#41219)

* Initial commit

* Review fixes

* Bitwise? Yeah my wisdom score is a 10

* Review comments
This commit is contained in:
SlamBamActionman
2025-11-01 16:16:51 +01:00
committed by GitHub
parent 026541b985
commit 9133aca00b
4 changed files with 43 additions and 8 deletions

View File

@@ -1,3 +1,4 @@
using System.Diagnostics.CodeAnalysis;
using Content.Shared.Administration.Logs;
using Content.Shared.Examine;
using Content.Shared.Construction.Components;

View File

@@ -3,6 +3,7 @@ using Content.Shared.Administration.Logs;
using Content.Shared.Camera;
using Content.Shared.CCVar;
using Content.Shared.Construction.Components;
using Content.Shared.Construction.EntitySystems;
using Content.Shared.Database;
using Content.Shared.Friction;
using Content.Shared.Projectiles;
@@ -11,6 +12,7 @@ using Robust.Shared.Map;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Serialization;
using Robust.Shared.Timing;
namespace Content.Shared.Throwing;
@@ -35,11 +37,16 @@ public sealed class ThrowingSystem : EntitySystem
[Dependency] private readonly SharedCameraRecoilSystem _recoil = default!;
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
[Dependency] private readonly IConfigurationManager _configManager = default!;
[Dependency] private readonly AnchorableSystem _anchorable = default!;
private EntityQuery<AnchorableComponent> _anchorableQuery;
public override void Initialize()
{
base.Initialize();
_anchorableQuery = GetEntityQuery<AnchorableComponent>();
Subs.CVar(_configManager, CCVars.TileFrictionModifier, value => _frictionModifier = value, true);
Subs.CVar(_configManager, CCVars.AirFriction, value => _airDamping = value, true);
}
@@ -56,7 +63,7 @@ public sealed class ThrowingSystem : EntitySystem
bool animated = true,
bool playSound = true,
bool doSpin = true,
bool unanchor = false)
ThrowingUnanchorStrength unanchor = ThrowingUnanchorStrength.None)
{
var thrownPos = _transform.GetMapCoordinates(uid);
var mapPos = _transform.ToMapCoordinates(coordinates);
@@ -77,7 +84,7 @@ public sealed class ThrowingSystem : EntitySystem
/// <param name="friction">friction value used for the distance calculation. If set to null this defaults to the standard tile values</param>
/// <param name="compensateFriction">True will adjust the throw so the item stops at the target coordinates. False means it will land at the target and keep sliding.</param>
/// <param name="doSpin">Whether spin will be applied to the thrown entity.</param>
/// <param name="unanchor">If true and the thrown entity has <see cref="AnchorableComponent"/>, unanchor the thrown entity</param>
/// <param name="unanchor">If set to Unanchorable, if the entity has <see cref="AnchorableComponent"/> and is unanchorable, it will unanchor the thrown entity. If set to All, it will unanchor the entity regardless.</param>
public void TryThrow(EntityUid uid,
Vector2 direction,
float baseThrowSpeed = 10.0f,
@@ -89,7 +96,7 @@ public sealed class ThrowingSystem : EntitySystem
bool animated = true,
bool playSound = true,
bool doSpin = true,
bool unanchor = false)
ThrowingUnanchorStrength unanchor = ThrowingUnanchorStrength.None)
{
var physicsQuery = GetEntityQuery<PhysicsComponent>();
if (!physicsQuery.TryGetComponent(uid, out var physics))
@@ -119,7 +126,7 @@ public sealed class ThrowingSystem : EntitySystem
/// <param name="friction">friction value used for the distance calculation. If set to null this defaults to the standard tile values</param>
/// <param name="compensateFriction">True will adjust the throw so the item stops at the target coordinates. False means it will land at the target and keep sliding.</param>
/// <param name="doSpin">Whether spin will be applied to the thrown entity.</param>
/// <param name="unanchor">If true and the thrown entity has <see cref="AnchorableComponent"/>, unanchor the thrown entity</param>
/// <param name="unanchor">If set to Unanchorable, if the entity has <see cref="AnchorableComponent"/> and is unanchorable, it will unanchor the thrown entity. If set to All, it will unanchor the entity regardless.</param>
public void TryThrow(EntityUid uid,
Vector2 direction,
PhysicsComponent physics,
@@ -134,12 +141,16 @@ public sealed class ThrowingSystem : EntitySystem
bool animated = true,
bool playSound = true,
bool doSpin = true,
bool unanchor = false)
ThrowingUnanchorStrength unanchor = ThrowingUnanchorStrength.None)
{
if (baseThrowSpeed <= 0 || direction == Vector2Helpers.Infinity || direction == Vector2Helpers.NaN || direction == Vector2.Zero || friction < 0)
return;
if (unanchor && HasComp<AnchorableComponent>(uid))
// Unanchor the entity if applicable
if (unanchor == ThrowingUnanchorStrength.All ||
unanchor == ThrowingUnanchorStrength.Unanchorable &&
_anchorableQuery.TryComp(uid, out var anchorableComponent) &&
(anchorableComponent.Flags & AnchorableFlags.Unanchorable) != 0)
_transform.Unanchor(uid);
if ((physics.BodyType & (BodyType.Dynamic | BodyType.KinematicController)) == 0x0)
@@ -243,4 +254,26 @@ public sealed class ThrowingSystem : EntitySystem
if (pushEv.Push)
_physics.ApplyLinearImpulse(user.Value, -impulseVector / physics.Mass * pushbackRatio * MathF.Min(massLimit, physics.Mass), body: userPhysics);
}
}
/// <summary>
/// If a throwing action should attempt to unanchor anchored entities.
/// </summary>
[Serializable, NetSerializable]
public enum ThrowingUnanchorStrength : byte
{
/// <summary>
/// No entites will be unanchored.
/// </summary>
None,
/// <summary>
/// Only entities that can be unanchored (e.g. via wrench) will be unanchored.
/// </summary>
Unanchorable,
/// <summary>
/// All entities will be unanchored.
/// </summary>
All,
}

View File

@@ -1,3 +1,4 @@
using Content.Shared.Throwing;
using Robust.Shared.GameStates;
namespace Content.Shared.Weapons.Melee.Components;
@@ -26,7 +27,7 @@ public sealed partial class MeleeThrowOnHitComponent : Component
/// Whether or not anchorable entities should be unanchored when hit.
/// </summary>
[DataField, AutoNetworkedField]
public bool UnanchorOnHit;
public ThrowingUnanchorStrength UnanchorOnHit = ThrowingUnanchorStrength.None;
/// <summary>
/// How long should this stun the target, if applicable?

View File

@@ -188,7 +188,7 @@
path: "/Audio/Weapons/Guns/Gunshots/kinetic_accel.ogg"
- type: CorePoweredThrower
- type: MeleeThrowOnHit
unanchorOnHit: true
unanchorOnHit: Unanchorable
- type: ItemSlots
slots:
core_slot: