]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Prevent projectiles from being affected by TryThrow() (#16185)
authorLeon Friedrich <60421075+ElectroJr@users.noreply.github.com>
Sun, 7 May 2023 02:57:23 +0000 (14:57 +1200)
committerGitHub <noreply@github.com>
Sun, 7 May 2023 02:57:23 +0000 (12:57 +1000)
Content.Server/Explosion/EntitySystems/ExplosionSystem.Processing.cs
Content.Shared/Throwing/ThrowingSystem.cs

index 7f03e68aa4f9d9c5401312926924097a25fa26fa..3499d6644341ceb2f5b384408c2d44306796fe0d 100644 (file)
@@ -8,7 +8,9 @@ using Content.Shared.Explosion;
 using Content.Shared.FixedPoint;
 using Content.Shared.Maps;
 using Content.Shared.Physics;
+using Content.Shared.Projectiles;
 using Content.Shared.Spawners.Components;
+using Content.Shared.Tag;
 using Robust.Shared.Map;
 using Robust.Shared.Map.Components;
 using Robust.Shared.Physics;
@@ -199,7 +201,8 @@ public sealed partial class ExplosionSystem : EntitySystem
         EntityQuery<TransformComponent> xformQuery,
         EntityQuery<DamageableComponent> damageQuery,
         EntityQuery<PhysicsComponent> physicsQuery,
-        LookupFlags flags)
+        EntityQuery<TagComponent> tagQuery,
+        EntityQuery<ProjectileComponent> projectileQuery)
     {
         var gridBox = new Box2(tile * grid.TileSize, (tile + 1) * grid.TileSize);
 
@@ -217,7 +220,7 @@ public sealed partial class ExplosionSystem : EntitySystem
         // process those entities
         foreach (var xform in list)
         {
-            ProcessEntity(xform.Owner, epicenter, damage, throwForce, id, damageQuery, physicsQuery, xform);
+            ProcessEntity(xform.Owner, epicenter, damage, throwForce, id, xform, damageQuery, physicsQuery, xformQuery, tagQuery, projectileQuery);
         }
 
         // process anchored entities
@@ -226,7 +229,7 @@ public sealed partial class ExplosionSystem : EntitySystem
         foreach (var entity in anchoredList)
         {
             processed.Add(entity);
-            ProcessEntity(entity, epicenter, damage, throwForce, id, damageQuery, physicsQuery);
+            ProcessEntity(entity, epicenter, damage, throwForce, id, null, damageQuery, physicsQuery, xformQuery, tagQuery, projectileQuery);
         }
 
         // Walls and reinforced walls will break into girders. These girders will also be considered turf-blocking for
@@ -260,7 +263,7 @@ public sealed partial class ExplosionSystem : EntitySystem
         {
             // Here we only throw, no dealing damage. Containers n such might drop their entities after being destroyed, but
             // they should handle their own damage pass-through, with their own damage reduction calculation.
-            ProcessEntity(xform.Owner, epicenter, null, throwForce, id, damageQuery, physicsQuery, xform);
+            ProcessEntity(xform.Owner, epicenter, null, throwForce, id, xform, damageQuery, physicsQuery, xformQuery, tagQuery, projectileQuery);
         }
 
         return !tileBlocked;
@@ -299,7 +302,8 @@ public sealed partial class ExplosionSystem : EntitySystem
         EntityQuery<TransformComponent> xformQuery,
         EntityQuery<DamageableComponent> damageQuery,
         EntityQuery<PhysicsComponent> physicsQuery,
-        LookupFlags flags)
+        EntityQuery<TagComponent> tagQuery,
+        EntityQuery<ProjectileComponent> projectileQuery)
     {
         var gridBox = Box2.FromDimensions(tile * DefaultTileSize, (DefaultTileSize, DefaultTileSize));
         var worldBox = spaceMatrix.TransformBox(gridBox);
@@ -315,7 +319,7 @@ public sealed partial class ExplosionSystem : EntitySystem
         foreach (var xform in state.Item1)
         {
             processed.Add(xform.Owner);
-            ProcessEntity(xform.Owner, epicenter, damage, throwForce, id, damageQuery, physicsQuery, xform);
+            ProcessEntity(xform.Owner, epicenter, damage, throwForce, id, xform, damageQuery, physicsQuery, xformQuery, tagQuery, projectileQuery);
         }
 
         if (throwForce <= 0)
@@ -329,7 +333,7 @@ public sealed partial class ExplosionSystem : EntitySystem
 
         foreach (var xform in list)
         {
-            ProcessEntity(xform.Owner, epicenter, null, throwForce, id, damageQuery, physicsQuery, xform);
+            ProcessEntity(xform.Owner, epicenter, null, throwForce, id, xform, damageQuery, physicsQuery, xformQuery, tagQuery, projectileQuery);
         }
     }
 
@@ -375,9 +379,12 @@ public sealed partial class ExplosionSystem : EntitySystem
         DamageSpecifier? damage,
         float throwForce,
         string id,
+        TransformComponent? xform,
         EntityQuery<DamageableComponent> damageQuery,
         EntityQuery<PhysicsComponent> physicsQuery,
-        TransformComponent? xform = null)
+        EntityQuery<TransformComponent> transformQuery,
+        EntityQuery<TagComponent> tagQuery,
+        EntityQuery<ProjectileComponent> projectileQuery)
     {
         // damage
         if (damage != null && damageQuery.TryGetComponent(uid, out var damageable))
@@ -413,15 +420,22 @@ public sealed partial class ExplosionSystem : EntitySystem
         }
 
         // throw
-        if (xform != null
+        if (xform != null // null implies anchored
             && !xform.Anchored
             && throwForce > 0
             && !EntityManager.IsQueuedForDeletion(uid)
             && physicsQuery.TryGetComponent(uid, out var physics)
             && physics.BodyType == BodyType.Dynamic)
         {
-            // TODO purge throw helpers and pass in physics component
-            _throwingSystem.TryThrow(uid, xform.WorldPosition - epicenter.Position, throwForce);
+            var pos = _transformSystem.GetWorldPosition(xform, transformQuery);
+            _throwingSystem.TryThrow(
+                uid,
+                 pos - epicenter.Position,
+                physics,
+                xform,
+                projectileQuery,
+                tagQuery,
+                throwForce);
         }
 
         // TODO EXPLOSION puddle / flammable ignite?
@@ -567,14 +581,14 @@ sealed class Explosion
     private readonly EntityQuery<TransformComponent> _xformQuery;
     private readonly EntityQuery<PhysicsComponent> _physicsQuery;
     private readonly EntityQuery<DamageableComponent> _damageQuery;
+    private readonly EntityQuery<ProjectileComponent> _projectileQuery;
+    private readonly EntityQuery<TagComponent> _tagQuery;
 
     /// <summary>
     ///     Total area that the explosion covers.
     /// </summary>
     public readonly int Area;
 
-    private readonly LookupFlags _flags = LookupFlags.None;
-
     /// <summary>
     ///     factor used to scale the tile break chances.
     /// </summary>
@@ -625,14 +639,11 @@ sealed class Explosion
         _canCreateVacuum = canCreateVacuum;
         _entMan = entMan;
 
-        // yeah this should be a cvar, but this is only temporary anyways
-        // see lookup todo
-        if (Area > 100)
-            _flags |= LookupFlags.Approximate;
-
         _xformQuery = entMan.GetEntityQuery<TransformComponent>();
         _physicsQuery = entMan.GetEntityQuery<PhysicsComponent>();
         _damageQuery = entMan.GetEntityQuery<DamageableComponent>();
+        _tagQuery = entMan.GetEntityQuery<TagComponent>();
+        _projectileQuery = entMan.GetEntityQuery<ProjectileComponent>();
 
         if (spaceData != null)
         {
@@ -773,7 +784,8 @@ sealed class Explosion
                     _xformQuery,
                     _damageQuery,
                     _physicsQuery,
-                    _flags);
+                    _tagQuery,
+                    _projectileQuery);
 
                 // If the floor is not blocked by some dense object, damage the floor tiles.
                 if (canDamageFloor)
@@ -794,7 +806,8 @@ sealed class Explosion
                     _xformQuery,
                     _damageQuery,
                     _physicsQuery,
-                    _flags);
+                    _tagQuery,
+                    _projectileQuery);
             }
 
             if (!MoveNext())
index 1b7cfd7d6f0c6ef7f7c5e314c56da5a10f5be260..5b8f6b335a57a8fe1ebf785642852f2746f53f82 100644 (file)
@@ -1,6 +1,7 @@
 using Content.Shared.Gravity;
 using Content.Shared.Interaction;
 using Content.Shared.Movement.Components;
+using Content.Shared.Projectiles;
 using Content.Shared.Tag;
 using Robust.Shared.Physics;
 using Robust.Shared.Physics.Components;
@@ -32,22 +33,49 @@ public sealed class ThrowingSystem : EntitySystem
     /// <param name="direction">A vector pointing from the entity to its destination.</param>
     /// <param name="strength">How much the direction vector should be multiplied for velocity.</param>
     /// <param name="pushbackRatio">The ratio of impulse applied to the thrower - defaults to 10 because otherwise it's not enough to properly recover from getting spaced</param>
-    public void TryThrow(
-        EntityUid uid,
+    public void TryThrow(EntityUid uid,
         Vector2 direction,
         float strength = 1.0f,
         EntityUid? user = null,
-        float pushbackRatio = 5.0f,
-        PhysicsComponent? physics = null,
-        TransformComponent? transform = null,
-        EntityQuery<PhysicsComponent>? physicsQuery = null,
-        EntityQuery<TransformComponent>? xformQuery = null)
+        float pushbackRatio = 5.0f)
     {
-        if (strength <= 0 || direction == Vector2.Infinity || direction == Vector2.NaN || direction == Vector2.Zero)
+        var physicsQuery = GetEntityQuery<PhysicsComponent>();
+        if (!physicsQuery.TryGetComponent(uid, out var physics))
             return;
 
-        physicsQuery ??= GetEntityQuery<PhysicsComponent>();
-        if (physics == null && !physicsQuery.Value.TryGetComponent(uid, out physics))
+        var projectileQuery = GetEntityQuery<ProjectileComponent>();
+        var tagQuery = GetEntityQuery<TagComponent>();
+
+        TryThrow(
+            uid,
+            direction,
+            physics,
+            Transform(uid),
+            projectileQuery,
+            tagQuery,
+            strength,
+            user,
+            pushbackRatio);
+    }
+
+    /// <summary>
+    ///     Tries to throw the entity if it has a physics component, otherwise does nothing.
+    /// </summary>
+    /// <param name="uid">The entity being thrown.</param>
+    /// <param name="direction">A vector pointing from the entity to its destination.</param>
+    /// <param name="strength">How much the direction vector should be multiplied for velocity.</param>
+    /// <param name="pushbackRatio">The ratio of impulse applied to the thrower - defaults to 10 because otherwise it's not enough to properly recover from getting spaced</param>
+    public void TryThrow(EntityUid uid,
+        Vector2 direction,
+        PhysicsComponent physics,
+        TransformComponent transform,
+        EntityQuery<ProjectileComponent> projectileQuery,
+        EntityQuery<TagComponent> tagQuery,
+        float strength = 1.0f,
+        EntityUid? user = null,
+        float pushbackRatio = 5.0f)
+    {
+        if (strength <= 0 || direction == Vector2.Infinity || direction == Vector2.NaN || direction == Vector2.Zero)
             return;
 
         if ((physics.BodyType & (BodyType.Dynamic | BodyType.KinematicController)) == 0x0)
@@ -56,20 +84,17 @@ public sealed class ThrowingSystem : EntitySystem
             return;
         }
 
+        if (projectileQuery.HasComponent(uid))
+            return;
+
         var comp = EnsureComp<ThrownItemComponent>(uid);
         comp.Thrower = user;
+
         // Give it a l'il spin.
-        if (!_tagSystem.HasTag(uid, "NoSpinOnThrow"))
+        if (!tagQuery.TryGetComponent(uid, out var tag) || !_tagSystem.HasTag(tag, "NoSpinOnThrow"))
             _physics.ApplyAngularImpulse(uid, ThrowAngularImpulse, body: physics);
         else
-        {
-            if (transform == null)
-            {
-                xformQuery ??= GetEntityQuery<TransformComponent>();
-                transform = xformQuery.Value.GetComponent(uid);
-            }
             transform.LocalRotation = direction.ToWorldAngle() - Math.PI;
-        }
 
         if (user != null)
             _interactionSystem.ThrownInteraction(user.Value, uid);
@@ -100,7 +125,7 @@ public sealed class ThrowingSystem : EntitySystem
         // Give thrower an impulse in the other direction
         if (user != null &&
             pushbackRatio > 0.0f &&
-            physicsQuery.Value.TryGetComponent(user.Value, out var userPhysics) &&
+            TryComp(user.Value, out PhysicsComponent? userPhysics) &&
             _gravity.IsWeightless(user.Value, userPhysics))
         {
             var msg = new ThrowPushbackAttemptEvent();