]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
better fluid spreading (#14529)
authorSlava0135 <40753025+Slava0135@users.noreply.github.com>
Fri, 24 Mar 2023 14:09:52 +0000 (17:09 +0300)
committerGitHub <noreply@github.com>
Fri, 24 Mar 2023 14:09:52 +0000 (01:09 +1100)
Content.Server/Fluids/EntitySystems/FluidSpreaderSystem.cs
Content.Server/Fluids/EntitySystems/PuddleSystem.cs

index 84f0fc263d2456f610b5c547fc59e88a37b24baf..20f786d6cd82c6543b8195cd375bbaf584d5321e 100644 (file)
@@ -3,13 +3,13 @@ using System.Linq;
 using Content.Server.Fluids.Components;
 using Content.Shared;
 using Content.Shared.Directions;
+using Content.Shared.Maps;
 using Content.Shared.Physics;
 using JetBrains.Annotations;
 using Robust.Shared.Map;
 using Robust.Shared.Map.Components;
 using Robust.Shared.Physics;
-using Robust.Shared.Utility;
-using Robust.Shared.Physics.Components;
+using Robust.Shared.Physics.Systems;
 using Robust.Shared.Timing;
 
 namespace Content.Server.Fluids.EntitySystems;
@@ -23,6 +23,8 @@ public sealed class FluidSpreaderSystem : EntitySystem
     [Dependency] private readonly IGameTiming _gameTiming = default!;
     [Dependency] private readonly IMapManager _mapManager = default!;
     [Dependency] private readonly PuddleSystem _puddleSystem = default!;
+    [Dependency] private readonly SharedTransformSystem _transform = default!;
+    [Dependency] private readonly SharedPhysicsSystem _physics = default!;
 
     /// <summary>
     /// Adds an overflow component to the map data component tracking overflowing puddles
@@ -72,20 +74,19 @@ public sealed class FluidSpreaderSystem : EntitySystem
                 puddles.Clear();
                 var pos = transform.Coordinates;
 
-                var totalVolume = _puddleSystem.CurrentVolume(puddle.Owner, puddle);
+                var totalVolume = _puddleSystem.CurrentVolume(puddleUid, puddle);
                 exploreDirections.Shuffle();
                 foreach (var direction in exploreDirections)
                 {
                     var newPos = pos.Offset(direction);
-                    if (CheckTile(puddle.Owner, puddle, newPos, mapGrid,
-                            out var puddleComponent))
+                    if (CheckTile(puddleUid, puddle, newPos, mapGrid, puddleQuery, out var uid, out var component))
                     {
-                        puddles.Add(puddleComponent);
-                        totalVolume += _puddleSystem.CurrentVolume(puddleComponent.Owner, puddleComponent);
+                        puddles.Add(component);
+                        totalVolume += _puddleSystem.CurrentVolume(uid.Value, component);
                     }
                 }
 
-                _puddleSystem.EqualizePuddles(puddle.Owner, puddles, totalVolume, newIteration, puddle);
+                _puddleSystem.EqualizePuddles(puddleUid, puddles, totalVolume, newIteration, puddle);
             }
 
             fluidMapData.Puddles.Clear();
@@ -100,49 +101,57 @@ public sealed class FluidSpreaderSystem : EntitySystem
     /// </summary>
     /// <param name="srcUid">Entity Uid of original puddle</param>
     /// <param name="srcPuddle">PuddleComponent attached to srcUid</param>
-    /// <param name="pos">at which to check tile</param>
+    /// <param name="dstPos">at which to check tile</param>
     /// <param name="mapGrid">helper param needed to extract entities</param>
-    /// <param name="puddle">either found or newly created PuddleComponent.</param>
+    /// <param name="newPuddleUid">either found or newly created PuddleComponent.</param>
     /// <returns>true if tile is empty or occupied by a non-overflowing puddle (or a puddle close to being overflowing)</returns>
-    private bool CheckTile(EntityUid srcUid, PuddleComponent srcPuddle, EntityCoordinates pos, MapGridComponent mapGrid,
-        [NotNullWhen(true)] out PuddleComponent? puddle)
+    private bool CheckTile(EntityUid srcUid, PuddleComponent srcPuddle, EntityCoordinates dstPos, 
+        MapGridComponent mapGrid, EntityQuery<PuddleComponent> puddleQuery,
+        [NotNullWhen(true)] out EntityUid? newPuddleUid, [NotNullWhen(true)] out PuddleComponent? newPuddleComp)
     {
-        if (!mapGrid.TryGetTileRef(pos, out var tileRef)
+        if (!mapGrid.TryGetTileRef(dstPos, out var tileRef)
             || tileRef.Tile.IsEmpty)
         {
-            puddle = null;
+            newPuddleUid = null;
+            newPuddleComp = null;
             return false;
         }
 
-        var puddleCurrentVolume = _puddleSystem.CurrentVolume(srcUid, srcPuddle);
+        // check if puddle can spread there at all
+        var dstMap = dstPos.ToMap(EntityManager, _transform);
+        var dst = dstMap.Position;
+        var src = Transform(srcUid).MapPosition.Position;
+        var dir = src - dst;
+        var ray = new CollisionRay(dst, dir.Normalized, (int) (CollisionGroup.Impassable | CollisionGroup.HighImpassable));
+        var mapId = dstMap.MapId;
+        var results = _physics.IntersectRay(mapId, ray, dir.Length, returnOnFirstHit: true);
+        if (results.Any())
+        {
+            newPuddleUid = null;
+            newPuddleComp = null;
+            return false;
+        }
 
-        foreach (var entity in mapGrid.GetAnchoredEntities(pos))
+        var puddleCurrentVolume = _puddleSystem.CurrentVolume(srcUid, srcPuddle);
+        foreach (var entity in dstPos.GetEntitiesInTile())
         {
-            // If this is valid puddle check if we spread to it.
-            if (TryComp(entity, out PuddleComponent? existingPuddle))
+            if (puddleQuery.TryGetComponent(entity, out var existingPuddle))
             {
-                // If current puddle has more volume than current we skip that field
-                if (_puddleSystem.CurrentVolume(existingPuddle.Owner, existingPuddle) >= puddleCurrentVolume)
+                if (_puddleSystem.CurrentVolume(entity, existingPuddle) >= puddleCurrentVolume)
                 {
-                    puddle = null;
+                    newPuddleUid = null;
+                    newPuddleComp = null;
                     return false;
                 }
-
-                puddle = existingPuddle;
+                newPuddleUid = entity;
+                newPuddleComp = existingPuddle;
                 return true;
             }
-
-            // if not puddle is this tile blocked by an object like wall or door
-            if (TryComp(entity, out PhysicsComponent? physComponent)
-                && physComponent.CanCollide
-                && (physComponent.CollisionLayer & (int) CollisionGroup.MobMask) != 0)
-            {
-                puddle = null;
-                return false;
-            }
         }
 
-        puddle = _puddleSystem.SpawnPuddle(srcUid, pos, srcPuddle);
+        _puddleSystem.SpawnPuddle(srcUid, dstPos, srcPuddle, out var uid, out var comp);
+        newPuddleUid = uid;
+        newPuddleComp = comp;
         return true;
     }
 }
index 7eb16ec0cbf4a1dbe0f5909f49d7080e2c6e85bd..0a9f8a8332c40697fae9f5d903f36b3581b8098f 100644 (file)
@@ -266,17 +266,15 @@ namespace Content.Server.Fluids.EntitySystems
             return CurrentVolume(uid, puddle) > puddle.OverflowVolume;
         }
 
-        public PuddleComponent SpawnPuddle(EntityUid srcUid, EntityCoordinates pos, PuddleComponent? srcPuddleComponent = null)
+        public void SpawnPuddle(EntityUid srcUid, EntityCoordinates pos, PuddleComponent srcPuddleComponent, out EntityUid uid, out PuddleComponent component)
         {
             MetaDataComponent? metadata = null;
-            Resolve(srcUid, ref srcPuddleComponent, ref metadata);
+            Resolve(srcUid, ref metadata);
 
             var prototype = metadata?.EntityPrototype?.ID ?? "PuddleSmear"; // TODO Spawn a entity based on another entity
 
-            var destUid = EntityManager.SpawnEntity(prototype, pos);
-            var destPuddle = EntityManager.EnsureComponent<PuddleComponent>(destUid);
-
-            return destPuddle;
+            uid = EntityManager.SpawnEntity(prototype, pos);
+            component = EntityManager.EnsureComponent<PuddleComponent>(uid);
         }
     }
 }