]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
expanded FillLevelSpriteTest test and fixed found issues (#34165)
authorIgnaz "Ian" Kraft <ignaz.k@live.de>
Sat, 3 Jan 2026 01:20:41 +0000 (02:20 +0100)
committerGitHub <noreply@github.com>
Sat, 3 Jan 2026 01:20:41 +0000 (01:20 +0000)
* fix clustersoap eaten sprite

* also assure that every entity with the SolutionContainerVisualsComponent has a AppearanceComponent

* use the new sprite system + fix the fill for cardboard arrows and the mosin

* fix merge issue

Content.IntegrationTests/Tests/FillLevelSpriteTest.cs
Resources/Prototypes/Entities/Objects/Specific/Janitorial/soap.yml
Resources/Prototypes/Entities/Objects/Weapons/Guns/Projectiles/arrows.yml
Resources/Prototypes/Entities/Objects/Weapons/Throwable/scattering_grenades.yml
Resources/Textures/Objects/Weapons/Guns/Snipers/bolt_gun_wood.rsi/equipped-back-fill-1.png [moved from Resources/Textures/Objects/Weapons/Guns/Snipers/bolt_gun_wood.rsi/equipped-backpack-fill-1.png with 100% similarity]
Resources/Textures/Objects/Weapons/Guns/Snipers/bolt_gun_wood.rsi/meta.json

index 37e777fa8cf82ee26bd1dc16ee7c4c216ff1e10c..99354e16c1d09dcc93c854f6391a88c6878e0d3c 100644 (file)
@@ -1,5 +1,7 @@
 using System.Linq;
+using Content.Shared.Chemistry;
 using Content.Shared.Chemistry.Components;
+using Content.Shared.Prototypes;
 using Robust.Client.GameObjects;
 using Robust.Shared.GameObjects;
 using Robust.Shared.Prototypes;
@@ -13,14 +15,17 @@ namespace Content.IntegrationTests.Tests;
 public sealed class FillLevelSpriteTest
 {
     private static readonly string[] HandStateNames = ["left", "right"];
+    private static readonly string[] EquipStateNames = ["back", "suitstorage"];
 
     [Test]
     public async Task FillLevelSpritesExist()
     {
-        await using var pair = await PoolManager.GetServerClient();
+        await using var pair = await PoolManager.GetServerClient(new PoolSettings { Connected = true });
         var client = pair.Client;
         var protoMan = client.ResolveDependency<IPrototypeManager>();
         var componentFactory = client.ResolveDependency<IComponentFactory>();
+        var entMan = client.ResolveDependency<IEntityManager>();
+        var spriteSystem = client.System<SpriteSystem>();
 
         await client.WaitAssertion(() =>
         {
@@ -31,39 +36,70 @@ public sealed class FillLevelSpriteTest
                 .OrderBy(p => p.ID)
                 .ToList();
 
-            foreach (var proto in protos)
+            Assert.Multiple(() =>
             {
-                Assert.That(proto.TryGetComponent<SolutionContainerVisualsComponent>(out var visuals, componentFactory));
-                Assert.That(proto.TryGetComponent<SpriteComponent>(out var sprite, componentFactory));
-
-                var rsi = sprite.BaseRSI;
-
-                // Test base sprite fills
-                if (!string.IsNullOrEmpty(visuals.FillBaseName))
+                foreach (var proto in protos)
                 {
-                    for (var i = 1; i <= visuals.MaxFillLevels; i++)
+                    Assert.That(proto.TryGetComponent<SolutionContainerVisualsComponent>(out var visuals, componentFactory));
+                    Assert.That(proto.TryGetComponent<SpriteComponent>(out var sprite, componentFactory));
+                    if (!proto.HasComponent<AppearanceComponent>(componentFactory))
                     {
-                        var state = $"{visuals.FillBaseName}{i}";
-                        Assert.That(rsi.TryGetState(state, out _), @$"{proto.ID} has SolutionContainerVisualsComponent with
-                            MaxFillLevels = {visuals.MaxFillLevels}, but {rsi.Path} doesn't have state {state}!");
+                        Assert.Fail(@$"{proto.ID} has SolutionContainerVisualsComponent but no AppearanceComponent.");
                     }
-                }
 
-                // Test inhand sprite fills
-                if (!string.IsNullOrEmpty(visuals.InHandsFillBaseName))
-                {
-                    for (var i = 1; i <= visuals.InHandsMaxFillLevels; i++)
+                    // Test base sprite fills
+                    if (!string.IsNullOrEmpty(visuals.FillBaseName) && visuals.MaxFillLevels > 0)
                     {
-                        foreach (var handname in HandStateNames)
+                        var entity = entMan.Spawn(proto.ID);
+                        if (!spriteSystem.LayerMapTryGet(entity, SolutionContainerLayers.Fill, out var fillLayerId, false))
+                        {
+                            Assert.Fail(@$"{proto.ID} has SolutionContainerVisualsComponent but no fill layer map.");
+                        }
+                        if (!spriteSystem.TryGetLayer(entity, fillLayerId, out var fillLayer, false))
+                        {
+                            Assert.Fail(@$"{proto.ID} somehow lost a layer.");
+                        }
+                        var rsi = fillLayer.ActualRsi;
+
+                        for (var i = 1; i <= visuals.MaxFillLevels; i++)
                         {
-                            var state = $"inhand-{handname}{visuals.InHandsFillBaseName}{i}";
+                            var state = $"{visuals.FillBaseName}{i}";
                             Assert.That(rsi.TryGetState(state, out _), @$"{proto.ID} has SolutionContainerVisualsComponent with
-                                InHandsMaxFillLevels = {visuals.InHandsMaxFillLevels}, but {rsi.Path} doesn't have state {state}!");
+                                MaxFillLevels = {visuals.MaxFillLevels}, but {rsi.Path} doesn't have state {state}!");
                         }
+                    }
 
+                    // Test inhand sprite fills
+                    if (!string.IsNullOrEmpty(visuals.InHandsFillBaseName) && visuals.InHandsMaxFillLevels > 0)
+                    {
+                        var rsi = sprite.BaseRSI;
+                        for (var i = 1; i <= visuals.InHandsMaxFillLevels; i++)
+                        {
+                            foreach (var handname in HandStateNames)
+                            {
+                                var state = $"inhand-{handname}{visuals.InHandsFillBaseName}{i}";
+                                Assert.That(rsi.TryGetState(state, out _), @$"{proto.ID} has SolutionContainerVisualsComponent with
+                                    InHandsMaxFillLevels = {visuals.InHandsMaxFillLevels}, but {rsi.Path} doesn't have state {state}!");
+                            }
+                        }
+                    }
+
+                    // Test equipped sprite fills
+                    if (!string.IsNullOrEmpty(visuals.EquippedFillBaseName) && visuals.EquippedMaxFillLevels > 0)
+                    {
+                        var rsi = sprite.BaseRSI;
+                        for (var i = 1; i <= visuals.EquippedMaxFillLevels; i++)
+                        {
+                            foreach (var equipName in EquipStateNames)
+                            {
+                                var state = $"equipped-{equipName}{visuals.EquippedFillBaseName}{i}";
+                                Assert.That(rsi.TryGetState(state, out _), @$"{proto.ID} has SolutionContainerVisualsComponent with
+                                    EquippedMaxFillLevels = {visuals.EquippedMaxFillLevels}, but {rsi.Path} doesn't have state {state}!");
+                            }
+                        }
                     }
                 }
-            }
+            });
         });
 
         await pair.CleanReturnAsync();
index e4cfd8d347d0981de8b11e7fee3d01921a5ffcab..69eff77aebc195d22304c0861ddc364abf761701 100644 (file)
   description: A tiny piece of syndicate soap.
   categories: [ HideSpawnMenu ]
   components:
-  - type: Sprite
-    layers:
-    - state: syndie-soaplet
   - type: SolutionContainerManager
     solutions:
       soap:
-        maxVol: 10
+        maxVol: 1.5 # 50 / 30 = 1.666
         reagents:
         - ReagentId: SoapReagent
-          Quantity: 10
+          Quantity: 1.5
+  - type: SolutionContainerVisuals
+    maxFillLevels: 0
+  - type: Sprite
+    layers:
+    - state: syndie-soaplet
   - type: Slippery
   - type: StepTrigger
     intersectRatio: 0.04
       path: "/Audio/Effects/Fluids/splat.ogg"
       params:
         volume: -8
+  - type: Residue
+    residueAdjective: residue-slippery
+    residueColor: residue-red
 
 - type: entity
   parent: BaseSoap
index 0a577b51dbb3d669519feddc265fc178f8d4d7aa..d61b78f1edb07a6db619f2747339c7cc470fc0ee 100644 (file)
       color: brown
     - state: tip
       color: brown
+    - state: solution1
+      map: ["enum.SolutionContainerLayers.Fill"]
+      visible: false
   - type: Projectile
     damage:
       types:
index 6bff4fbd4468606409e10b70bde955cefcf0a4db..627835ddd37909e2628b44359099bef7905c30f6 100644 (file)
     sprite: Objects/Specific/Janitorial/soap.rsi
     layers:
     - state: syndie-4
+      map: ["enum.SolutionContainerLayers.Fill"]
   - type: ScatteringGrenade
     fillPrototype: SoapletSyndie
     capacity: 30
index c9436ead7b98c0db1015a507f13919a4b70fd5fd..7c9dbbe1194dd16c7d4ffb59d36db2c931fd865c 100644 (file)
@@ -53,7 +53,7 @@
             "directions": 4
         },
         {
-            "name": "equipped-backpack-fill-1",
+            "name": "equipped-back-fill-1",
             "directions": 4
         },
         {