diff --git a/Content.IntegrationTests/Tests/FillLevelSpriteTest.cs b/Content.IntegrationTests/Tests/FillLevelSpriteTest.cs new file mode 100644 index 0000000000..37e777fa8c --- /dev/null +++ b/Content.IntegrationTests/Tests/FillLevelSpriteTest.cs @@ -0,0 +1,71 @@ +using System.Linq; +using Content.Shared.Chemistry.Components; +using Robust.Client.GameObjects; +using Robust.Shared.GameObjects; +using Robust.Shared.Prototypes; + +namespace Content.IntegrationTests.Tests; + +/// +/// Tests to see if any entity prototypes specify solution fill level sprites that don't exist. +/// +[TestFixture] +public sealed class FillLevelSpriteTest +{ + private static readonly string[] HandStateNames = ["left", "right"]; + + [Test] + public async Task FillLevelSpritesExist() + { + await using var pair = await PoolManager.GetServerClient(); + var client = pair.Client; + var protoMan = client.ResolveDependency(); + var componentFactory = client.ResolveDependency(); + + await client.WaitAssertion(() => + { + var protos = protoMan.EnumeratePrototypes() + .Where(p => !p.Abstract) + .Where(p => !pair.IsTestPrototype(p)) + .Where(p => p.TryGetComponent(out _, componentFactory)) + .OrderBy(p => p.ID) + .ToList(); + + foreach (var proto in protos) + { + Assert.That(proto.TryGetComponent(out var visuals, componentFactory)); + Assert.That(proto.TryGetComponent(out var sprite, componentFactory)); + + var rsi = sprite.BaseRSI; + + // Test base sprite fills + if (!string.IsNullOrEmpty(visuals.FillBaseName)) + { + for (var i = 1; i <= visuals.MaxFillLevels; i++) + { + 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}!"); + } + } + + // Test inhand sprite fills + if (!string.IsNullOrEmpty(visuals.InHandsFillBaseName)) + { + 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}!"); + } + + } + } + } + }); + + await pair.CleanReturnAsync(); + } +} diff --git a/Resources/Prototypes/Entities/Objects/Fun/darts.yml b/Resources/Prototypes/Entities/Objects/Fun/darts.yml index 36c841995e..c0b5eb3399 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/darts.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/darts.yml @@ -83,10 +83,6 @@ max: 1 - !type:DoActsBehavior acts: [ "Destruction" ] - - type: Appearance - - type: SolutionContainerVisuals - maxFillLevels: 1 - fillBaseName: dart - type: entity parent: Dart diff --git a/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml b/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml index ce0e0b629a..dd15a90baa 100644 --- a/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml +++ b/Resources/Prototypes/Entities/Objects/Specific/chemistry.yml @@ -233,6 +233,8 @@ sprite: Objects/Specific/Chemistry/beaker_cryostasis.rsi layers: - state: beakernoreact + - type: SolutionContainerVisuals + maxFillLevels: 0 - type: SolutionContainerManager solutions: beaker: @@ -251,6 +253,8 @@ sprite: Objects/Specific/Chemistry/beaker_bluespace.rsi layers: - state: beakerbluespace + - type: SolutionContainerVisuals + maxFillLevels: 0 - type: SolutionContainerManager solutions: beaker: