Merge branch 'master' of https://github.com/space-wizards/space-station-14 into map-load-refactor

This commit is contained in:
ElectroJr
2025-02-16 16:52:51 +13:00
1624 changed files with 385006 additions and 263837 deletions

View File

@@ -7,6 +7,7 @@ using Content.Server.Nutrition.Components;
using Content.Server.Nutrition.EntitySystems;
using Content.Shared.Cargo.Prototypes;
using Content.Shared.IdentityManagement;
using Content.Shared.Prototypes;
using Content.Shared.Stacks;
using Content.Shared.Tag;
using Content.Shared.Whitelist;
@@ -104,51 +105,34 @@ public sealed class CargoTest
await using var pair = await PoolManager.GetServerClient();
var server = pair.Server;
var testMap = await pair.CreateTestMap();
var entManager = server.ResolveDependency<IEntityManager>();
var mapManager = server.ResolveDependency<IMapManager>();
var protoManager = server.ResolveDependency<IPrototypeManager>();
var protoManager = server.ProtoMan;
var compFact = server.ResolveDependency<IComponentFactory>();
await server.WaitAssertion(() =>
{
var mapId = testMap.MapId;
var grid = mapManager.CreateGridEntity(mapId);
var coord = new EntityCoordinates(grid.Owner, 0, 0);
var protoIds = protoManager.EnumeratePrototypes<EntityPrototype>()
.Where(p => !p.Abstract)
.Where(p => !pair.IsTestPrototype(p))
.Where(p => !p.Components.ContainsKey("MapGrid")) // Grids are not for sale.
.Select(p => p.ID)
.Where(p => p.Components.ContainsKey("StaticPrice"))
.ToList();
foreach (var proto in protoIds)
{
var ent = entManager.SpawnEntity(proto, coord);
// Sanity check
Assert.That(proto.TryGetComponent<StaticPriceComponent>(out var staticPriceComp, compFact), Is.True);
if (entManager.TryGetComponent<StackPriceComponent>(ent, out var stackpricecomp)
&& stackpricecomp.Price > 0)
if (proto.TryGetComponent<StackPriceComponent>(out var stackPriceComp, compFact) && stackPriceComp.Price > 0)
{
if (entManager.TryGetComponent<StaticPriceComponent>(ent, out var staticpricecomp))
{
Assert.That(staticpricecomp.Price, Is.EqualTo(0),
$"The prototype {proto} has a StackPriceComponent and StaticPriceComponent whose values are not compatible with each other.");
}
Assert.That(staticPriceComp.Price, Is.EqualTo(0),
$"The prototype {proto} has a StackPriceComponent and StaticPriceComponent whose values are not compatible with each other.");
}
if (entManager.HasComponent<StackComponent>(ent))
if (proto.HasComponent<StackComponent>(compFact))
{
if (entManager.TryGetComponent<StaticPriceComponent>(ent, out var staticpricecomp))
{
Assert.That(staticpricecomp.Price, Is.EqualTo(0),
$"The prototype {proto} has a StackComponent and StaticPriceComponent whose values are not compatible with each other.");
}
Assert.That(staticPriceComp.Price, Is.EqualTo(0),
$"The prototype {proto} has a StackComponent and StaticPriceComponent whose values are not compatible with each other.");
}
entManager.DeleteEntity(ent);
}
mapManager.DeleteMap(mapId);
});
await pair.CleanReturnAsync();

View File

@@ -0,0 +1,41 @@
using Content.Shared.Contraband;
using Robust.Shared.GameObjects;
using Robust.Shared.Prototypes;
namespace Content.IntegrationTests.Tests;
[TestFixture]
public sealed class ContrabandTest
{
[Test]
public async Task EntityShowDepartmentsAndJobs()
{
await using var pair = await PoolManager.GetServerClient();
var client = pair.Client;
var protoMan = client.ResolveDependency<IPrototypeManager>();
var componentFactory = client.ResolveDependency<IComponentFactory>();
await client.WaitAssertion(() =>
{
foreach (var proto in protoMan.EnumeratePrototypes<EntityPrototype>())
{
if (proto.Abstract || pair.IsTestPrototype(proto))
continue;
if (!proto.TryGetComponent<ContrabandComponent>(out var contraband, componentFactory))
continue;
Assert.That(protoMan.TryIndex(contraband.Severity, out var severity, false),
@$"{proto.ID} has a ContrabandComponent with a unknown severity.");
if (!severity.ShowDepartmentsAndJobs)
continue;
Assert.That(contraband.AllowedDepartments.Count + contraband.AllowedJobs.Count, Is.Not.EqualTo(0),
@$"{proto.ID} has a ContrabandComponent with ShowDepartmentsAndJobs but no allowed departments or jobs.");
}
});
await pair.CleanReturnAsync();
}
}

View File

@@ -39,6 +39,7 @@ namespace Content.IntegrationTests.Tests
.Where(p => !p.Abstract)
.Where(p => !pair.IsTestPrototype(p))
.Where(p => !p.Components.ContainsKey("MapGrid")) // This will smash stuff otherwise.
.Where(p => !p.Components.ContainsKey("RoomFill")) // This comp can delete all entities, and spawn others
.Select(p => p.ID)
.ToList();
@@ -101,6 +102,7 @@ namespace Content.IntegrationTests.Tests
.Where(p => !p.Abstract)
.Where(p => !pair.IsTestPrototype(p))
.Where(p => !p.Components.ContainsKey("MapGrid")) // This will smash stuff otherwise.
.Where(p => !p.Components.ContainsKey("RoomFill")) // This comp can delete all entities, and spawn others
.Select(p => p.ID)
.ToList();
foreach (var protoId in protoIds)
@@ -341,6 +343,7 @@ namespace Content.IntegrationTests.Tests
"DebugExceptionInitialize",
"DebugExceptionStartup",
"GridFill",
"RoomFill",
"Map", // We aren't testing a map entity in this test
"MapGrid",
"Broadphase",

View File

@@ -26,6 +26,7 @@ public sealed class LatheTest
var compFactory = server.ResolveDependency<IComponentFactory>();
var materialStorageSystem = server.System<SharedMaterialStorageSystem>();
var whitelistSystem = server.System<EntityWhitelistSystem>();
var latheSystem = server.System<SharedLatheSystem>();
await server.WaitAssertion(() =>
{
@@ -74,14 +75,14 @@ public sealed class LatheTest
}
}
// Collect all the recipes assigned to this lathe
var recipes = new List<ProtoId<LatheRecipePrototype>>();
recipes.AddRange(latheComp.StaticRecipes);
recipes.AddRange(latheComp.DynamicRecipes);
// Collect all possible recipes assigned to this lathe
var recipes = new HashSet<ProtoId<LatheRecipePrototype>>();
latheSystem.AddRecipesFromPacks(recipes, latheComp.StaticPacks);
latheSystem.AddRecipesFromPacks(recipes, latheComp.DynamicPacks);
if (latheProto.TryGetComponent<EmagLatheRecipesComponent>(out var emagRecipesComp, compFactory))
{
recipes.AddRange(emagRecipesComp.EmagStaticRecipes);
recipes.AddRange(emagRecipesComp.EmagDynamicRecipes);
latheSystem.AddRecipesFromPacks(recipes, emagRecipesComp.EmagStaticPacks);
latheSystem.AddRecipesFromPacks(recipes, emagRecipesComp.EmagDynamicPacks);
}
// Check each recipe assigned to this lathe

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using Content.Shared.Tag;
using Robust.Shared.GameObjects;
using Robust.Shared.Prototypes;
using Robust.Shared.Reflection;
using Robust.Shared.Serialization.Manager.Attributes;
@@ -29,7 +30,9 @@ public sealed class StaticFieldValidationTest
Assert.That(protoMan.ValidateStaticFields(typeof(StringValid), protos), Is.Empty);
Assert.That(protoMan.ValidateStaticFields(typeof(StringArrayValid), protos), Is.Empty);
Assert.That(protoMan.ValidateStaticFields(typeof(EntProtoIdValid), protos), Is.Empty);
Assert.That(protoMan.ValidateStaticFields(typeof(EntProtoIdTValid), protos), Is.Empty);
Assert.That(protoMan.ValidateStaticFields(typeof(EntProtoIdArrayValid), protos), Is.Empty);
Assert.That(protoMan.ValidateStaticFields(typeof(EntProtoIdTArrayValid), protos), Is.Empty);
Assert.That(protoMan.ValidateStaticFields(typeof(ProtoIdTestValid), protos), Is.Empty);
Assert.That(protoMan.ValidateStaticFields(typeof(ProtoIdArrayValid), protos), Is.Empty);
Assert.That(protoMan.ValidateStaticFields(typeof(ProtoIdListValid), protos), Is.Empty);
@@ -39,7 +42,9 @@ public sealed class StaticFieldValidationTest
Assert.That(protoMan.ValidateStaticFields(typeof(StringInvalid), protos), Has.Count.EqualTo(1));
Assert.That(protoMan.ValidateStaticFields(typeof(StringArrayInvalid), protos), Has.Count.EqualTo(2));
Assert.That(protoMan.ValidateStaticFields(typeof(EntProtoIdInvalid), protos), Has.Count.EqualTo(1));
Assert.That(protoMan.ValidateStaticFields(typeof(EntProtoIdTInvalid), protos), Has.Count.EqualTo(1));
Assert.That(protoMan.ValidateStaticFields(typeof(EntProtoIdArrayInvalid), protos), Has.Count.EqualTo(2));
Assert.That(protoMan.ValidateStaticFields(typeof(EntProtoIdTArrayInvalid), protos), Has.Count.EqualTo(2));
Assert.That(protoMan.ValidateStaticFields(typeof(ProtoIdTestInvalid), protos), Has.Count.EqualTo(1));
Assert.That(protoMan.ValidateStaticFields(typeof(ProtoIdArrayInvalid), protos), Has.Count.EqualTo(2));
Assert.That(protoMan.ValidateStaticFields(typeof(ProtoIdListInvalid), protos), Has.Count.EqualTo(2));
@@ -88,24 +93,48 @@ public sealed class StaticFieldValidationTest
public static EntProtoId Tag = "StaticFieldTestEnt";
}
[Reflect(false)]
private sealed class EntProtoIdTValid
{
public static EntProtoId<TransformComponent> Tag = "StaticFieldTestEnt";
}
[Reflect(false)]
private sealed class EntProtoIdInvalid
{
public static EntProtoId Tag = string.Empty;
}
[Reflect(false)]
private sealed class EntProtoIdTInvalid
{
public static EntProtoId<TransformComponent> Tag = string.Empty;
}
[Reflect(false)]
private sealed class EntProtoIdArrayValid
{
public static EntProtoId[] Tag = ["StaticFieldTestEnt", "StaticFieldTestEnt"];
}
[Reflect(false)]
private sealed class EntProtoIdTArrayValid
{
public static EntProtoId<TransformComponent>[] Tag = ["StaticFieldTestEnt", "StaticFieldTestEnt"];
}
[Reflect(false)]
private sealed class EntProtoIdArrayInvalid
{
public static EntProtoId[] Tag = [string.Empty, "StaticFieldTestEnt", string.Empty];
}
[Reflect(false)]
private sealed class EntProtoIdTArrayInvalid
{
public static EntProtoId<TransformComponent>[] Tag = [string.Empty, "StaticFieldTestEnt", string.Empty];
}
[Reflect(false)]
private sealed class ProtoIdTestValid
{

View File

@@ -59,12 +59,13 @@ namespace Content.IntegrationTests.Tests
"Reach",
"Train",
"Oasis",
"Cog",
"Gate",
"Amber",
"Loop",
"Plasma",
"Elkridge"
"Elkridge",
"Convex",
"Relic"
};
/// <summary>

View File

@@ -52,13 +52,16 @@ public sealed class ResearchTest
await using var pair = await PoolManager.GetServerClient();
var server = pair.Server;
var entMan = server.ResolveDependency<IEntityManager>();
var protoManager = server.ResolveDependency<IPrototypeManager>();
var compFact = server.ResolveDependency<IComponentFactory>();
var latheSys = entMan.System<SharedLatheSystem>();
await server.WaitAssertion(() =>
{
var allEnts = protoManager.EnumeratePrototypes<EntityPrototype>();
var allLathes = new HashSet<LatheComponent>();
var latheTechs = new HashSet<ProtoId<LatheRecipePrototype>>();
foreach (var proto in allEnts)
{
if (proto.Abstract)
@@ -69,30 +72,31 @@ public sealed class ResearchTest
if (!proto.TryGetComponent<LatheComponent>(out var lathe, compFact))
continue;
allLathes.Add(lathe);
}
var latheTechs = new HashSet<string>();
foreach (var lathe in allLathes)
{
if (lathe.DynamicRecipes == null)
continue;
latheSys.AddRecipesFromPacks(latheTechs, lathe.DynamicPacks);
foreach (var recipe in lathe.DynamicRecipes)
{
latheTechs.Add(recipe);
}
if (proto.TryGetComponent<EmagLatheRecipesComponent>(out var emag, compFact))
latheSys.AddRecipesFromPacks(latheTechs, emag.EmagDynamicPacks);
}
Assert.Multiple(() =>
{
// check that every recipe a tech adds can be made on some lathe
var unlockedTechs = new HashSet<ProtoId<LatheRecipePrototype>>();
foreach (var tech in protoManager.EnumeratePrototypes<TechnologyPrototype>())
{
unlockedTechs.UnionWith(tech.RecipeUnlocks);
foreach (var recipe in tech.RecipeUnlocks)
{
Assert.That(latheTechs, Does.Contain(recipe), $"Recipe \"{recipe}\" cannot be unlocked on any lathes.");
Assert.That(latheTechs, Does.Contain(recipe), $"Recipe '{recipe}' from tech '{tech.ID}' cannot be unlocked on any lathes.");
}
}
// now check that every dynamic recipe a lathe lists can be unlocked
foreach (var recipe in latheTechs)
{
Assert.That(unlockedTechs, Does.Contain(recipe), $"Recipe '{recipe}' is dynamic on a lathe but cannot be unlocked by research.");
}
});
});

View File

@@ -5,6 +5,7 @@ using Content.Server.Store.Systems;
using Content.Server.Traitor.Uplink;
using Content.Shared.FixedPoint;
using Content.Shared.Inventory;
using Content.Shared.Mind;
using Content.Shared.Store;
using Content.Shared.Store.Components;
using Content.Shared.StoreDiscount.Components;
@@ -64,6 +65,7 @@ public sealed class StoreTests
await server.WaitAssertion(() =>
{
var invSystem = entManager.System<InventorySystem>();
var mindSystem = entManager.System<SharedMindSystem>();
human = entManager.SpawnEntity("HumanUniformDummy", coordinates);
uniform = entManager.SpawnEntity("UniformDummy", coordinates);
@@ -72,6 +74,9 @@ public sealed class StoreTests
Assert.That(invSystem.TryEquip(human, uniform, "jumpsuit"));
Assert.That(invSystem.TryEquip(human, pda, "id"));
var mind = mindSystem.CreateMind(null);
mindSystem.TransferTo(mind, human, mind: mind);
FixedPoint2 originalBalance = 20;
uplinkSystem.AddUplink(human, originalBalance, null, true);