]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Add item sprite test (#21599)
authorLeon Friedrich <60421075+ElectroJr@users.noreply.github.com>
Sat, 18 Nov 2023 06:26:08 +0000 (19:26 +1300)
committerGitHub <noreply@github.com>
Sat, 18 Nov 2023 06:26:08 +0000 (17:26 +1100)
Content.IntegrationTests/Pair/TestPair.Helpers.cs
Content.IntegrationTests/PoolManager.cs
Content.IntegrationTests/Tests/Sprite/ItemSpriteTest.cs [new file with mode: 0644]
Content.IntegrationTests/Tests/StorageTest.cs
Resources/Prototypes/Body/Parts/base.yml
Resources/Prototypes/Body/Parts/rat.yml
Resources/Prototypes/Entities/Objects/Consumable/Food/snacks.yml
Resources/Prototypes/Entities/Objects/Misc/identification_cards.yml
Resources/Prototypes/Entities/Objects/Misc/subdermal_implants.yml
Resources/Prototypes/Entities/Objects/Tools/cable_coils.yml

index 574644f67ee20ff3290565401c7da1e9ea8c6533..554807b2d25051682e28ff374677251cb919e397 100644 (file)
@@ -1,7 +1,9 @@
 #nullable enable
+using System.Collections.Generic;
 using System.Linq;
 using Robust.Shared.GameObjects;
 using Robust.Shared.Map;
+using Robust.Shared.Prototypes;
 using Robust.UnitTesting;
 
 namespace Content.IntegrationTests.Pair;
@@ -95,4 +97,33 @@ public sealed partial class TestPair
         await Client.ExecuteCommand(cmd);
         await RunTicksSync(numTicks);
     }
+
+    /// <summary>
+    /// Retrieve all entity prototypes that have some component.
+    /// </summary>
+    public List<EntityPrototype> GetPrototypesWithComponent<T>(
+        HashSet<string>? ignored = null,
+        bool ignoreAbstract = true,
+        bool ignoreTestPrototypes = true)
+        where T : IComponent
+    {
+        var id = Server.ResolveDependency<IComponentFactory>().GetComponentName(typeof(T));
+        var list = new List<EntityPrototype>();
+        foreach (var proto in Server.ProtoMan.EnumeratePrototypes<EntityPrototype>())
+        {
+            if (ignored != null && ignored.Contains(proto.ID))
+                continue;
+
+            if (ignoreAbstract && proto.Abstract)
+                continue;
+
+            if (ignoreTestPrototypes && IsTestPrototype(proto))
+                continue;
+
+            if (proto.Components.ContainsKey(id))
+                list.Add(proto);
+        }
+
+        return list;
+    }
 }
index a2015f3fdba20af11b68cd218f2d67fe46c00da9..d60f6cb4bd1341060c8cfb51b353eb16244c509a 100644 (file)
@@ -425,25 +425,6 @@ we are just going to end this here to save a lot of time. This is the exception
         Assert.That(passed);
     }
 
-    /// <summary>
-    ///     Helper method that retrieves all entity prototypes that have some component.
-    /// </summary>
-    public static List<EntityPrototype> GetPrototypesWithComponent<T>(RobustIntegrationTest.IntegrationInstance instance) where T : IComponent
-    {
-        var protoMan = instance.ResolveDependency<IPrototypeManager>();
-        var compFact = instance.ResolveDependency<IComponentFactory>();
-
-        var id = compFact.GetComponentName(typeof(T));
-        var list = new List<EntityPrototype>();
-        foreach (var ent in protoMan.EnumeratePrototypes<EntityPrototype>())
-        {
-            if (ent.Components.ContainsKey(id))
-                list.Add(ent);
-        }
-
-        return list;
-    }
-
     /// <summary>
     /// Initialize the pool manager.
     /// </summary>
diff --git a/Content.IntegrationTests/Tests/Sprite/ItemSpriteTest.cs b/Content.IntegrationTests/Tests/Sprite/ItemSpriteTest.cs
new file mode 100644 (file)
index 0000000..96f710d
--- /dev/null
@@ -0,0 +1,64 @@
+#nullable enable
+using System.Collections.Generic;
+using Content.Shared.Item;
+using Robust.Client.GameObjects;
+using Robust.Shared.GameObjects;
+using Robust.Shared.Prototypes;
+
+namespace Content.IntegrationTests.Tests.Sprite;
+
+/// <summary>
+/// This test checks that all items have a visible sprite. The general rationale is that all items can be picked up
+/// by players, thus they need to be visible and have a sprite that can be rendered on screen and in their hands GUI.
+/// This has nothing to do with in-hand sprites.
+/// </summary>
+/// <remarks>
+/// If a prototype fails this test, its probably either because it:
+/// - Should be marked abstract
+/// - inherits from BaseItem despite not being an item
+/// - Shouldn't have an item component
+/// - Is missing the required sprite information.
+/// If none of the abveo are true, it might need to be added to the list of ignored components, see
+/// <see cref="_ignored"/>
+/// </remarks>
+[TestFixture]
+public sealed class PrototypeSaveTest
+{
+    private static HashSet<string> _ignored = new()
+    {
+        // The only prototypes that should get ignored are those that REQUIRE setup to get a sprite. At that point it is
+        // the responsibility of the spawner to ensure that a valid sprite is set.
+        "HandVirtualItem"
+    };
+
+    [Test]
+    public async Task AllItemsHaveSpritesTest()
+    {
+        var settings = new PoolSettings() {Connected = true}; // client needs to be in-game
+        await using var pair = await PoolManager.GetServerClient(settings);
+        List<EntityPrototype> badPrototypes = new();
+
+        await pair.Client.WaitPost(() =>
+        {
+            foreach (var proto in pair.GetPrototypesWithComponent<ItemComponent>(_ignored))
+            {
+                var dummy = pair.Client.EntMan.Spawn(proto.ID);
+                pair.Client.EntMan.RunMapInit(dummy, pair.Client.MetaData(dummy));
+                var spriteComponent = pair.Client.EntMan.GetComponentOrNull<SpriteComponent>(dummy);
+                if (spriteComponent?.Icon == null)
+                    badPrototypes.Add(proto);
+                pair.Client.EntMan.DeleteEntity(dummy);
+            }
+        });
+
+        Assert.Multiple(() =>
+        {
+            foreach (var proto in badPrototypes)
+            {
+                Assert.Fail($"Item prototype has no sprite: {proto.ID}. It should probably either be marked as abstract, not be an item, or have a valid sprite");
+            }
+        });
+
+        await pair.CleanReturnAsync();
+    }
+}
index a5944f43949f2f4252b0f7c24484b9168598e9a1..c618616cd2776b9c0915c3d0982e87c1651e5d50 100644 (file)
@@ -94,7 +94,7 @@ namespace Content.IntegrationTests.Tests
 
             Assert.Multiple(() =>
             {
-                foreach (var proto in PoolManager.GetPrototypesWithComponent<StorageFillComponent>(server))
+                foreach (var proto in pair.GetPrototypesWithComponent<StorageFillComponent>())
                 {
                     if (proto.HasComponent<EntityStorageComponent>(compFact))
                         continue;
@@ -174,7 +174,7 @@ namespace Content.IntegrationTests.Tests
 
             Assert.Multiple(() =>
             {
-                foreach (var proto in PoolManager.GetPrototypesWithComponent<StorageFillComponent>(server))
+                foreach (var proto in pair.GetPrototypesWithComponent<StorageFillComponent>())
                 {
                     if (proto.HasComponent<StorageComponent>(compFact))
                         continue;
index e293d8845dbb7df97342915796a6441d1ca52194..a27059f59f309a29078c10f03e6138f856614626 100644 (file)
@@ -23,6 +23,7 @@
   id: BaseTorso
   name: "torso"
   parent: BasePart
+  abstract: true
   components:
   - type: BodyPart
     partType: Torso
@@ -31,6 +32,7 @@
   id: BaseHead
   name: "head"
   parent: BasePart
+  abstract: true
   components:
   - type: BodyPart
     partType: Head
@@ -45,6 +47,7 @@
   id: BaseLeftArm
   name: "left arm"
   parent: BasePart
+  abstract: true
   components:
   - type: BodyPart
     partType: Arm
@@ -54,6 +57,7 @@
   id: BaseRightArm
   name: "right arm"
   parent: BasePart
+  abstract: true
   components:
   - type: BodyPart
     partType: Arm
@@ -63,6 +67,7 @@
   id: BaseLeftHand
   name: "left hand"
   parent: BasePart
+  abstract: true
   components:
   - type: BodyPart
     partType: Hand
@@ -72,6 +77,7 @@
   id: BaseRightHand
   name: "right hand"
   parent: BasePart
+  abstract: true
   components:
   - type: BodyPart
     partType: Hand
@@ -81,6 +87,7 @@
   id: BaseLeftLeg
   name: "left leg"
   parent: BasePart
+  abstract: true
   components:
   - type: BodyPart
     partType: Leg
@@ -91,6 +98,7 @@
   id: BaseRightLeg
   name: "right leg"
   parent: BasePart
+  abstract: true
   components:
   - type: BodyPart
     partType: Leg
   id: BaseLeftFoot
   name: "left foot"
   parent: BasePart
+  abstract: true
   components:
   - type: BodyPart
     partType: Foot
   id: BaseRightFoot
   name: "right foot"
   parent: BasePart
+  abstract: true
   components:
   - type: BodyPart
     partType: Foot
index ad8eecf3dfc91a5b9e5edd6f596a7c62ceec4a50..6a66eecc489ec55d4b4997c1b475358ab9b54fc2 100644 (file)
@@ -13,3 +13,8 @@
   - type: Tag
     tags:
       - Trash
+  # TODO get a proper rat king & servant torso sprite.
+  # currently their torso is just a small dead rat....
+  - type: Sprite
+    sprite: Mobs/Animals/mouse.rsi
+    state: splat-0
index 82c31a01c5c533cf34615d6a20eed5f5541b052c..8294f64fe1c222aa0679737af242003f397f3f92 100644 (file)
   parent: BaseItem
   id: FoodPacketTrash
   description: This is rubbish.
+  abstract: true
   components:
   - type: Sprite
     sprite: Objects/Consumable/Food/snacks.rsi
index 0e5238316fef7827e545bfc44a8c6d8f91b22ebd..5e8807f7706d01ee04a205ba5868b32e0c67da9a 100644 (file)
@@ -3,7 +3,7 @@
   id: IDCardStandard
   name: identification card
   description: A card necessary to access various areas aboard the station.
-  noSpawn: true
+  abstract: true
   components:
   - type: Sprite
     sprite: Objects/Misc/id_cards.rsi
index f893ba91d4ed972346247fc1c81e716da036cd2a..0ab56e02c5863bc87c974bd898b86178c9eeb295 100644 (file)
       whitelist:
         components:
         - Hands # no use giving a mouse a storage implant, but a monkey is another story...
-    - type: Item
-      size: Ginormous
     - type: Storage
       maxSlots: 4
       maxItemSize: Small
index 1b9746704952f2d0715a1dc3c3f4961ff13599e1..b090b384470be78b8454796014a1a40b9cf45908 100644 (file)
@@ -4,7 +4,7 @@
 
 - type: entity
   id: CableStack
-  noSpawn: true
+  abstract: true
   parent: BaseItem
   name: cable stack
   suffix: Full