Add item sprite test (#21599)
This commit is contained in:
@@ -1,7 +1,9 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Robust.Shared.GameObjects;
|
using Robust.Shared.GameObjects;
|
||||||
using Robust.Shared.Map;
|
using Robust.Shared.Map;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.UnitTesting;
|
using Robust.UnitTesting;
|
||||||
|
|
||||||
namespace Content.IntegrationTests.Pair;
|
namespace Content.IntegrationTests.Pair;
|
||||||
@@ -95,4 +97,33 @@ public sealed partial class TestPair
|
|||||||
await Client.ExecuteCommand(cmd);
|
await Client.ExecuteCommand(cmd);
|
||||||
await RunTicksSync(numTicks);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
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>
|
/// <summary>
|
||||||
/// Initialize the pool manager.
|
/// Initialize the pool manager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
64
Content.IntegrationTests/Tests/Sprite/ItemSpriteTest.cs
Normal file
64
Content.IntegrationTests/Tests/Sprite/ItemSpriteTest.cs
Normal file
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -94,7 +94,7 @@ namespace Content.IntegrationTests.Tests
|
|||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
foreach (var proto in PoolManager.GetPrototypesWithComponent<StorageFillComponent>(server))
|
foreach (var proto in pair.GetPrototypesWithComponent<StorageFillComponent>())
|
||||||
{
|
{
|
||||||
if (proto.HasComponent<EntityStorageComponent>(compFact))
|
if (proto.HasComponent<EntityStorageComponent>(compFact))
|
||||||
continue;
|
continue;
|
||||||
@@ -174,7 +174,7 @@ namespace Content.IntegrationTests.Tests
|
|||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
foreach (var proto in PoolManager.GetPrototypesWithComponent<StorageFillComponent>(server))
|
foreach (var proto in pair.GetPrototypesWithComponent<StorageFillComponent>())
|
||||||
{
|
{
|
||||||
if (proto.HasComponent<StorageComponent>(compFact))
|
if (proto.HasComponent<StorageComponent>(compFact))
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
id: BaseTorso
|
id: BaseTorso
|
||||||
name: "torso"
|
name: "torso"
|
||||||
parent: BasePart
|
parent: BasePart
|
||||||
|
abstract: true
|
||||||
components:
|
components:
|
||||||
- type: BodyPart
|
- type: BodyPart
|
||||||
partType: Torso
|
partType: Torso
|
||||||
@@ -31,6 +32,7 @@
|
|||||||
id: BaseHead
|
id: BaseHead
|
||||||
name: "head"
|
name: "head"
|
||||||
parent: BasePart
|
parent: BasePart
|
||||||
|
abstract: true
|
||||||
components:
|
components:
|
||||||
- type: BodyPart
|
- type: BodyPart
|
||||||
partType: Head
|
partType: Head
|
||||||
@@ -45,6 +47,7 @@
|
|||||||
id: BaseLeftArm
|
id: BaseLeftArm
|
||||||
name: "left arm"
|
name: "left arm"
|
||||||
parent: BasePart
|
parent: BasePart
|
||||||
|
abstract: true
|
||||||
components:
|
components:
|
||||||
- type: BodyPart
|
- type: BodyPart
|
||||||
partType: Arm
|
partType: Arm
|
||||||
@@ -54,6 +57,7 @@
|
|||||||
id: BaseRightArm
|
id: BaseRightArm
|
||||||
name: "right arm"
|
name: "right arm"
|
||||||
parent: BasePart
|
parent: BasePart
|
||||||
|
abstract: true
|
||||||
components:
|
components:
|
||||||
- type: BodyPart
|
- type: BodyPart
|
||||||
partType: Arm
|
partType: Arm
|
||||||
@@ -63,6 +67,7 @@
|
|||||||
id: BaseLeftHand
|
id: BaseLeftHand
|
||||||
name: "left hand"
|
name: "left hand"
|
||||||
parent: BasePart
|
parent: BasePart
|
||||||
|
abstract: true
|
||||||
components:
|
components:
|
||||||
- type: BodyPart
|
- type: BodyPart
|
||||||
partType: Hand
|
partType: Hand
|
||||||
@@ -72,6 +77,7 @@
|
|||||||
id: BaseRightHand
|
id: BaseRightHand
|
||||||
name: "right hand"
|
name: "right hand"
|
||||||
parent: BasePart
|
parent: BasePart
|
||||||
|
abstract: true
|
||||||
components:
|
components:
|
||||||
- type: BodyPart
|
- type: BodyPart
|
||||||
partType: Hand
|
partType: Hand
|
||||||
@@ -81,6 +87,7 @@
|
|||||||
id: BaseLeftLeg
|
id: BaseLeftLeg
|
||||||
name: "left leg"
|
name: "left leg"
|
||||||
parent: BasePart
|
parent: BasePart
|
||||||
|
abstract: true
|
||||||
components:
|
components:
|
||||||
- type: BodyPart
|
- type: BodyPart
|
||||||
partType: Leg
|
partType: Leg
|
||||||
@@ -91,6 +98,7 @@
|
|||||||
id: BaseRightLeg
|
id: BaseRightLeg
|
||||||
name: "right leg"
|
name: "right leg"
|
||||||
parent: BasePart
|
parent: BasePart
|
||||||
|
abstract: true
|
||||||
components:
|
components:
|
||||||
- type: BodyPart
|
- type: BodyPart
|
||||||
partType: Leg
|
partType: Leg
|
||||||
@@ -101,6 +109,7 @@
|
|||||||
id: BaseLeftFoot
|
id: BaseLeftFoot
|
||||||
name: "left foot"
|
name: "left foot"
|
||||||
parent: BasePart
|
parent: BasePart
|
||||||
|
abstract: true
|
||||||
components:
|
components:
|
||||||
- type: BodyPart
|
- type: BodyPart
|
||||||
partType: Foot
|
partType: Foot
|
||||||
@@ -110,6 +119,7 @@
|
|||||||
id: BaseRightFoot
|
id: BaseRightFoot
|
||||||
name: "right foot"
|
name: "right foot"
|
||||||
parent: BasePart
|
parent: BasePart
|
||||||
|
abstract: true
|
||||||
components:
|
components:
|
||||||
- type: BodyPart
|
- type: BodyPart
|
||||||
partType: Foot
|
partType: Foot
|
||||||
|
|||||||
@@ -13,3 +13,8 @@
|
|||||||
- type: Tag
|
- type: Tag
|
||||||
tags:
|
tags:
|
||||||
- Trash
|
- 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
|
||||||
|
|||||||
@@ -443,6 +443,7 @@
|
|||||||
parent: BaseItem
|
parent: BaseItem
|
||||||
id: FoodPacketTrash
|
id: FoodPacketTrash
|
||||||
description: This is rubbish.
|
description: This is rubbish.
|
||||||
|
abstract: true
|
||||||
components:
|
components:
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Consumable/Food/snacks.rsi
|
sprite: Objects/Consumable/Food/snacks.rsi
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
id: IDCardStandard
|
id: IDCardStandard
|
||||||
name: identification card
|
name: identification card
|
||||||
description: A card necessary to access various areas aboard the station.
|
description: A card necessary to access various areas aboard the station.
|
||||||
noSpawn: true
|
abstract: true
|
||||||
components:
|
components:
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
sprite: Objects/Misc/id_cards.rsi
|
sprite: Objects/Misc/id_cards.rsi
|
||||||
|
|||||||
@@ -117,8 +117,6 @@
|
|||||||
whitelist:
|
whitelist:
|
||||||
components:
|
components:
|
||||||
- Hands # no use giving a mouse a storage implant, but a monkey is another story...
|
- Hands # no use giving a mouse a storage implant, but a monkey is another story...
|
||||||
- type: Item
|
|
||||||
size: Ginormous
|
|
||||||
- type: Storage
|
- type: Storage
|
||||||
maxSlots: 4
|
maxSlots: 4
|
||||||
maxItemSize: Small
|
maxItemSize: Small
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
id: CableStack
|
id: CableStack
|
||||||
noSpawn: true
|
abstract: true
|
||||||
parent: BaseItem
|
parent: BaseItem
|
||||||
name: cable stack
|
name: cable stack
|
||||||
suffix: Full
|
suffix: Full
|
||||||
|
|||||||
Reference in New Issue
Block a user