]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Fix walls and other unanchorable objects being unanchored by the G.O.R.I.L.L.A gauntl...
authorSlamBamActionman <83650252+SlamBamActionman@users.noreply.github.com>
Sat, 1 Nov 2025 15:16:51 +0000 (16:16 +0100)
committerGitHub <noreply@github.com>
Sat, 1 Nov 2025 15:16:51 +0000 (15:16 +0000)
* Initial commit

* Review fixes

* Bitwise? Yeah my wisdom score is a 10

* Review comments

Content.Shared/Construction/EntitySystems/AnchorableSystem.cs
Content.Shared/Throwing/ThrowingSystem.cs
Content.Shared/Weapons/Melee/Components/MeleeThrowOnHitComponent.cs
Resources/Prototypes/Entities/Objects/Specific/Research/anomaly.yml

index d53a100acc65d9ecd88822b4dcc5926c9e8cf64e..3985bd30510f12ca3f47f34c86bb77f9b2d91ae0 100644 (file)
@@ -1,3 +1,4 @@
+using System.Diagnostics.CodeAnalysis;
 using Content.Shared.Administration.Logs;
 using Content.Shared.Examine;
 using Content.Shared.Construction.Components;
index 6b121baf58a697517be05e5d5649776bcefec947..61ea2de26cf0dc631a7137cfeea8c7bec62b1209 100644 (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,
 }
index 42b72efede7b94b96e4bfb5f55b513f54c029255..2c16ea7582efdb146ee78b5928d33831d5fe49a8 100644 (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?
index 71dbed0aace21bb937bcfe245e10fa4c808bb0a4..e9b365de9a18201a828d6756e32565e1cc6e8a22 100644 (file)
       path: "/Audio/Weapons/Guns/Gunshots/kinetic_accel.ogg"
   - type: CorePoweredThrower
   - type: MeleeThrowOnHit
-    unanchorOnHit: true
+    unanchorOnHit: Unanchorable
   - type: ItemSlots
     slots:
       core_slot: