]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Fix AI singulo shenanigans (#31556)
authormetalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Sat, 31 Aug 2024 08:24:12 +0000 (18:24 +1000)
committerGitHub <noreply@github.com>
Sat, 31 Aug 2024 08:24:12 +0000 (18:24 +1000)
* weh

* Fix broken tests directly mutating entities from wrong thread.

* fix build

* gundam

* weher

* WHY

---------

Co-authored-by: Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
Content.Server/Singularity/EntitySystems/EventHorizonSystem.cs
Content.Server/Singularity/EntitySystems/GravityWellSystem.cs
Content.Shared/Physics/CollisionGroup.cs
Resources/Prototypes/Entities/Mobs/Player/narsie.yml
Resources/Prototypes/Entities/Mobs/Player/observer.yml
Resources/Prototypes/Entities/Mobs/Player/ratvar.yml
Resources/Prototypes/Entities/Structures/Power/Generation/Singularity/singularity.yml

index 6e3d9e925166ce860c43cb6746087a1ba98c1e8e..3bf820535f0f92bfeebccb31b5781cf333b565d7 100644 (file)
@@ -11,7 +11,9 @@ using Content.Shared.Tag;
 using Robust.Shared.Containers;
 using Robust.Shared.Map;
 using Robust.Shared.Map.Components;
+using Robust.Shared.Physics.Components;
 using Robust.Shared.Physics.Events;
+using Robust.Shared.Physics.Systems;
 using Robust.Shared.Timing;
 
 namespace Content.Server.Singularity.EntitySystems;
@@ -28,16 +30,20 @@ public sealed class EventHorizonSystem : SharedEventHorizonSystem
     [Dependency] private readonly IMapManager _mapMan = default!;
     [Dependency] private readonly IAdminLogManager _adminLogger = default!;
     [Dependency] private readonly SharedContainerSystem _containerSystem = default!;
+    [Dependency] private readonly SharedPhysicsSystem _physics = default!;
     [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
     [Dependency] private readonly TagSystem _tagSystem = default!;
     #endregion Dependencies
 
+    private EntityQuery<PhysicsComponent> _physicsQuery;
+
     public override void Initialize()
     {
         base.Initialize();
 
+        _physicsQuery = GetEntityQuery<PhysicsComponent>();
+
         SubscribeLocalEvent<MapGridComponent, EventHorizonAttemptConsumeEntityEvent>(PreventConsume);
-        SubscribeLocalEvent<GhostComponent, EventHorizonAttemptConsumeEntityEvent>(PreventConsume);
         SubscribeLocalEvent<StationDataComponent, EventHorizonAttemptConsumeEntityEvent>(PreventConsume);
         SubscribeLocalEvent<EventHorizonComponent, MapInitEvent>(OnHorizonMapInit);
         SubscribeLocalEvent<EventHorizonComponent, StartCollideEvent>(OnStartCollide);
@@ -159,24 +165,19 @@ public sealed class EventHorizonSystem : SharedEventHorizonSystem
     /// Attempts to consume all entities within a given distance of an entity;
     /// Excludes the center entity.
     /// </summary>
-    public void ConsumeEntitiesInRange(EntityUid uid, float range, TransformComponent? xform = null, EventHorizonComponent? eventHorizon = null)
+    public void ConsumeEntitiesInRange(EntityUid uid, float range, PhysicsComponent? body = null, EventHorizonComponent? eventHorizon = null)
     {
-        if (!Resolve(uid, ref xform, ref eventHorizon))
+        if (!Resolve(uid, ref body, ref eventHorizon))
             return;
 
-        var range2 = range * range;
-        var xformQuery = EntityManager.GetEntityQuery<TransformComponent>();
-        var epicenter = _xformSystem.GetWorldPosition(xform, xformQuery);
-        foreach (var entity in _lookup.GetEntitiesInRange(_xformSystem.GetMapCoordinates(uid, xform), range, flags: LookupFlags.Uncontained))
+        // TODO: Should be sundries + static-sundries but apparently this is load-bearing for SpawnAndDeleteAllEntitiesInTheSameSpot so go figure.
+        foreach (var entity in _lookup.GetEntitiesInRange(uid, range, flags: LookupFlags.Uncontained))
         {
             if (entity == uid)
                 continue;
-            if (!xformQuery.TryGetComponent(entity, out var entityXform))
-                continue;
 
-            // GetEntitiesInRange gets everything in a _square_ centered on the given position, but we are a _circle_. If we don't have this check and the station is rotated it is possible for the singularity to reach _outside of the containment field_ and eat the emitters.
-            var displacement = _xformSystem.GetWorldPosition(entityXform, xformQuery) - epicenter;
-            if (displacement.LengthSquared() > range2)
+            // See TODO above
+            if (_physicsQuery.TryComp(entity, out var otherBody) && !_physics.IsHardCollidable((uid, null, body), (entity, null, otherBody)))
                 continue;
 
             AttemptConsumeEntity(uid, entity, eventHorizon);
@@ -318,11 +319,11 @@ public sealed class EventHorizonSystem : SharedEventHorizonSystem
     /// </summary>
     public void ConsumeEverythingInRange(EntityUid uid, float range, TransformComponent? xform = null, EventHorizonComponent? eventHorizon = null)
     {
-        if (!Resolve(uid, ref xform, ref eventHorizon))
+        if (!Resolve(uid, ref eventHorizon))
             return;
 
         if (eventHorizon.ConsumeEntities)
-            ConsumeEntitiesInRange(uid, range, xform, eventHorizon);
+            ConsumeEntitiesInRange(uid, range, null, eventHorizon);
         if (eventHorizon.ConsumeTiles)
             ConsumeTilesInRange(uid, range, xform, eventHorizon);
     }
index 8c884d023c41abbfb53c8ee04f6eeaf8a8782687..7dcf3ef1ae5a109d56504c2ca0376d54077dc308 100644 (file)
@@ -2,6 +2,7 @@ using System.Numerics;
 using Content.Server.Singularity.Components;
 using Content.Shared.Atmos.Components;
 using Content.Shared.Ghost;
+using Content.Shared.Physics;
 using Content.Shared.Singularity.EntitySystems;
 using Robust.Shared.Map;
 using Robust.Shared.Map.Components;
@@ -33,9 +34,18 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
     /// </summary>
     public const float MinGravPulseRange = 0.00001f;
 
+    private EntityQuery<GravityWellComponent> _wellQuery;
+    private EntityQuery<MapComponent> _mapQuery;
+    private EntityQuery<MapGridComponent> _gridQuery;
+    private EntityQuery<PhysicsComponent> _physicsQuery;
+
     public override void Initialize()
     {
         base.Initialize();
+        _wellQuery = GetEntityQuery<GravityWellComponent>();
+        _mapQuery = GetEntityQuery<MapComponent>();
+        _gridQuery = GetEntityQuery<MapGridComponent>();
+        _physicsQuery = GetEntityQuery<PhysicsComponent>();
         SubscribeLocalEvent<GravityWellComponent, ComponentStartup>(OnGravityWellStartup);
 
         var vvHandle = _vvManager.GetTypeHandler<GravityWellComponent>();
@@ -111,11 +121,15 @@ public sealed class GravityWellSystem : SharedGravityWellSystem
     /// <param name="entity">The entity to check.</param>
     private bool CanGravPulseAffect(EntityUid entity)
     {
-        return !(
-            EntityManager.HasComponent<GhostComponent>(entity) ||
-            EntityManager.HasComponent<MapGridComponent>(entity) ||
-            EntityManager.HasComponent<MapComponent>(entity) ||
-            EntityManager.HasComponent<GravityWellComponent>(entity)
+        if (_physicsQuery.TryComp(entity, out var physics))
+        {
+            if (physics.CollisionLayer == (int) CollisionGroup.GhostImpassable)
+                return false;
+        }
+
+        return !(_gridQuery.HasComp(entity) ||
+                 _mapQuery.HasComp(entity) ||
+                 _wellQuery.HasComp(entity)
         );
     }
 
index 9f8c5ad9befbdc364b5761630cd92e594634bdff..0a11f93dbc81b2698d2220ce01983370d7b902d3 100644 (file)
@@ -22,13 +22,17 @@ public enum CollisionGroup
     GhostImpassable    = 1 << 5, // 32 Things impassible by ghosts/observers, ie blessed tiles or forcefields
     BulletImpassable   = 1 << 6, // 64 Can be hit by bullets
     InteractImpassable = 1 << 7, // 128 Blocks interaction/InRangeUnobstructed
+    // Y dis door passable when all the others impassable / collision.
     DoorPassable       = 1 << 8, // 256 Allows door to close over top, Like blast doors over conveyors for disposals rooms/cargo.
 
     MapGrid = MapGridHelpers.CollisionGroup, // Map grids, like shuttles. This is the actual grid itself, not the walls or other entities connected to the grid.
 
     // 32 possible groups
+    // Why dis exist
     AllMask = -1,
 
+    SingularityLayer = Opaque | Impassable | MidImpassable | HighImpassable | LowImpassable | BulletImpassable | InteractImpassable | DoorPassable,
+
     // Humanoids, etc.
     MobMask = Impassable | HighImpassable | MidImpassable | LowImpassable,
     MobLayer = Opaque | BulletImpassable,
index 7030572cf4723fe7e7c4b64a8ecc79d49e4810fb..5d07409b5f81574c2340c3ae567850caca357f61 100644 (file)
         restitution: 0.8
         density: 99999
         mask:
-        - AllMask
+        - SingularityLayer
         layer:
-        - AllMask
+        - SingularityLayer
       EventHorizonConsumer:
         shape:
           !type:PhysShapeCircle
             radius: 5
         hard: false
         mask:
-        - AllMask
+        - SingularityLayer
         layer:
-        - AllMask
+        - SingularityLayer
   - type: Input
     context: "ghost"
   - type: MovementIgnoreGravity
index 52994a72c65914f32a63e74d7470ec34b9faad12..5ceac9e773e06abce669749af8bd43c5a76496e1 100644 (file)
@@ -24,7 +24,7 @@
           !type:PhysShapeCircle
           radius: 0.35
         density: 15
-        mask:
+        layer:
         - GhostImpassable
 
 - type: entity
index 958c98f483e2fb92d5ef93bb20bad96573af1199..530f5e10374cce751645b3a6122ff0de91106b8f 100644 (file)
         restitution: 0.8
         density: 1
         mask:
-        - AllMask
+        - SingularityLayer
         layer:
-        - AllMask
+        - SingularityLayer
       EventHorizonConsumer:
         shape:
           !type:PhysShapeCircle
             radius: 5
         hard: false
         mask:
-        - AllMask
+        - SingularityLayer
         layer:
-        - AllMask
+        - SingularityLayer
   - type: Input
     context: "ghost"
   - type: MovementIgnoreGravity
index 25d219ab9459fe2f82ac72355d040d102b5dc20b..bf2c6cfcc0c9dd3bbb07d62e625adf66243dd201 100644 (file)
         restitution: 0.8
         density: 99999
         mask:
-        - AllMask
+        - SingularityLayer
         layer:
-        - AllMask
+        - SingularityLayer
       EventHorizonConsumer:
         shape:
           !type:PhysShapeCircle
             radius: 0.35
         hard: false
         mask:
-        - AllMask
+        - SingularityLayer
         layer:
-        - AllMask
+        - SingularityLayer
   - type: Singularity
     energy: 180
     level: 1