Cleans up tag system (#28272)
* Updated tag system * Added params methods * Fixed tag integration tests * Fixed params methods recursion * Revert has All/Any tag one argument realisation * Updated tag integration tests * Shit happens * Added individual List/HashSet methods, docs, tests
This commit is contained in:
@@ -123,7 +123,6 @@ namespace Content.Client.Verbs
|
||||
if ((visibility & MenuVisibility.Invisible) == 0)
|
||||
{
|
||||
var spriteQuery = GetEntityQuery<SpriteComponent>();
|
||||
var tagQuery = GetEntityQuery<TagComponent>();
|
||||
|
||||
for (var i = entities.Count - 1; i >= 0; i--)
|
||||
{
|
||||
@@ -131,7 +130,7 @@ namespace Content.Client.Verbs
|
||||
|
||||
if (!spriteQuery.TryGetComponent(entity, out var spriteComponent) ||
|
||||
!spriteComponent.Visible ||
|
||||
_tagSystem.HasTag(entity, "HideContextMenu", tagQuery))
|
||||
_tagSystem.HasTag(entity, "HideContextMenu"))
|
||||
{
|
||||
entities.RemoveSwap(i);
|
||||
}
|
||||
|
||||
@@ -53,11 +53,13 @@ namespace Content.IntegrationTests.Tests.Tag
|
||||
|
||||
EntityUid sTagDummy = default;
|
||||
TagComponent sTagComponent = null!;
|
||||
Entity<TagComponent> sTagEntity = default;
|
||||
|
||||
await server.WaitPost(() =>
|
||||
{
|
||||
sTagDummy = sEntityManager.SpawnEntity(TagEntityId, MapCoordinates.Nullspace);
|
||||
sTagComponent = sEntityManager.GetComponent<TagComponent>(sTagDummy);
|
||||
sTagEntity = new Entity<TagComponent>(sTagDummy, sTagComponent);
|
||||
});
|
||||
|
||||
await server.WaitAssertion(() =>
|
||||
@@ -130,49 +132,64 @@ namespace Content.IntegrationTests.Tests.Tag
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
// Cannot add the starting tag again
|
||||
Assert.That(tagSystem.AddTag(sTagDummy, sTagComponent, StartingTag), Is.False);
|
||||
Assert.That(tagSystem.AddTags(sTagDummy, sTagComponent, StartingTag, StartingTag), Is.False);
|
||||
Assert.That(tagSystem.AddTags(sTagDummy, sTagComponent, new List<string> { StartingTag, StartingTag }), Is.False);
|
||||
Assert.That(tagSystem.AddTag(sTagEntity, StartingTag), Is.False);
|
||||
|
||||
Assert.That(tagSystem.AddTags(sTagEntity, StartingTag, StartingTag), Is.False);
|
||||
Assert.That(tagSystem.AddTags(sTagEntity, new List<ProtoId<TagPrototype>> { StartingTag, StartingTag }), Is.False);
|
||||
Assert.That(tagSystem.AddTags(sTagEntity, new HashSet<ProtoId<TagPrototype>> { StartingTag, StartingTag }), Is.False);
|
||||
|
||||
// Has the starting tag
|
||||
Assert.That(tagSystem.HasTag(sTagComponent, StartingTag), Is.True);
|
||||
|
||||
Assert.That(tagSystem.HasAllTags(sTagComponent, StartingTag, StartingTag), Is.True);
|
||||
Assert.That(tagSystem.HasAllTags(sTagComponent, new List<string> { StartingTag, StartingTag }), Is.True);
|
||||
Assert.That(tagSystem.HasAllTags(sTagComponent, new List<ProtoId<TagPrototype>> { StartingTag, StartingTag }), Is.True);
|
||||
Assert.That(tagSystem.HasAllTags(sTagComponent, new HashSet<ProtoId<TagPrototype>> { StartingTag, StartingTag }), Is.True);
|
||||
|
||||
Assert.That(tagSystem.HasAnyTag(sTagComponent, StartingTag, StartingTag), Is.True);
|
||||
Assert.That(tagSystem.HasAnyTag(sTagComponent, new List<string> { StartingTag, StartingTag }), Is.True);
|
||||
Assert.That(tagSystem.HasAnyTag(sTagComponent, new List<ProtoId<TagPrototype>> { StartingTag, StartingTag }), Is.True);
|
||||
Assert.That(tagSystem.HasAnyTag(sTagComponent, new HashSet<ProtoId<TagPrototype>> { StartingTag, StartingTag }), Is.True);
|
||||
|
||||
// Does not have the added tag yet
|
||||
Assert.That(tagSystem.HasTag(sTagComponent, AddedTag), Is.False);
|
||||
|
||||
Assert.That(tagSystem.HasAllTags(sTagComponent, AddedTag, AddedTag), Is.False);
|
||||
Assert.That(tagSystem.HasAllTags(sTagComponent, new List<string> { AddedTag, AddedTag }), Is.False);
|
||||
Assert.That(tagSystem.HasAllTags(sTagComponent, new List<ProtoId<TagPrototype>> { AddedTag, AddedTag }), Is.False);
|
||||
Assert.That(tagSystem.HasAllTags(sTagComponent, new HashSet<ProtoId<TagPrototype>> { AddedTag, AddedTag }), Is.False);
|
||||
|
||||
Assert.That(tagSystem.HasAnyTag(sTagComponent, AddedTag, AddedTag), Is.False);
|
||||
Assert.That(tagSystem.HasAnyTag(sTagComponent, new List<string> { AddedTag, AddedTag }), Is.False);
|
||||
Assert.That(tagSystem.HasAnyTag(sTagComponent, new List<ProtoId<TagPrototype>> { AddedTag, AddedTag }), Is.False);
|
||||
Assert.That(tagSystem.HasAnyTag(sTagComponent, new HashSet<ProtoId<TagPrototype>> { AddedTag, AddedTag }), Is.False);
|
||||
|
||||
// Has a combination of the two tags
|
||||
Assert.That(tagSystem.HasAnyTag(sTagComponent, StartingTag, AddedTag), Is.True);
|
||||
Assert.That(tagSystem.HasAnyTag(sTagComponent, new List<string> { StartingTag, AddedTag }), Is.True);
|
||||
Assert.That(tagSystem.HasAnyTag(sTagComponent, new List<ProtoId<TagPrototype>> { StartingTag, AddedTag }), Is.True);
|
||||
Assert.That(tagSystem.HasAnyTag(sTagComponent, new HashSet<ProtoId<TagPrototype>> { StartingTag, AddedTag }), Is.True);
|
||||
|
||||
// Does not have both tags
|
||||
Assert.That(tagSystem.HasAllTags(sTagComponent, StartingTag, AddedTag), Is.False);
|
||||
Assert.That(tagSystem.HasAllTags(sTagComponent, new List<string> { StartingTag, AddedTag }), Is.False);
|
||||
Assert.That(tagSystem.HasAllTags(sTagComponent, new List<ProtoId<TagPrototype>> { StartingTag, AddedTag }), Is.False);
|
||||
Assert.That(tagSystem.HasAllTags(sTagComponent, new HashSet<ProtoId<TagPrototype>> { StartingTag, AddedTag }), Is.False);
|
||||
|
||||
// Cannot remove a tag that does not exist
|
||||
Assert.That(tagSystem.RemoveTag(sTagDummy, sTagComponent, AddedTag), Is.False);
|
||||
Assert.That(tagSystem.RemoveTags(sTagDummy, sTagComponent, AddedTag, AddedTag), Is.False);
|
||||
Assert.That(tagSystem.RemoveTags(sTagDummy, sTagComponent, new List<string> { AddedTag, AddedTag }), Is.False);
|
||||
Assert.That(tagSystem.RemoveTag(sTagEntity, AddedTag), Is.False);
|
||||
|
||||
Assert.That(tagSystem.RemoveTags(sTagEntity, AddedTag, AddedTag), Is.False);
|
||||
Assert.That(tagSystem.RemoveTags(sTagEntity, new List<ProtoId<TagPrototype>> { AddedTag, AddedTag }), Is.False);
|
||||
Assert.That(tagSystem.RemoveTags(sTagEntity, new HashSet<ProtoId<TagPrototype>> { AddedTag, AddedTag }), Is.False);
|
||||
});
|
||||
|
||||
// Can add the new tag
|
||||
Assert.That(tagSystem.AddTag(sTagDummy, sTagComponent, AddedTag), Is.True);
|
||||
Assert.That(tagSystem.AddTag(sTagEntity, AddedTag), Is.True);
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
// Cannot add it twice
|
||||
Assert.That(tagSystem.AddTag(sTagDummy, sTagComponent, AddedTag), Is.False);
|
||||
Assert.That(tagSystem.AddTag(sTagEntity, AddedTag), Is.False);
|
||||
|
||||
// Cannot add existing tags
|
||||
Assert.That(tagSystem.AddTags(sTagDummy, sTagComponent, StartingTag, AddedTag), Is.False);
|
||||
Assert.That(tagSystem.AddTags(sTagDummy, sTagComponent, new List<string> { StartingTag, AddedTag }), Is.False);
|
||||
Assert.That(tagSystem.AddTags(sTagEntity, StartingTag, AddedTag), Is.False);
|
||||
Assert.That(tagSystem.AddTags(sTagEntity, new List<ProtoId<TagPrototype>> { StartingTag, AddedTag }), Is.False);
|
||||
Assert.That(tagSystem.AddTags(sTagEntity, new HashSet<ProtoId<TagPrototype>> { StartingTag, AddedTag }), Is.False);
|
||||
|
||||
// Now has two tags
|
||||
Assert.That(sTagComponent.Tags, Has.Count.EqualTo(2));
|
||||
@@ -180,65 +197,103 @@ namespace Content.IntegrationTests.Tests.Tag
|
||||
// Has both tags
|
||||
Assert.That(tagSystem.HasTag(sTagComponent, StartingTag), Is.True);
|
||||
Assert.That(tagSystem.HasTag(sTagComponent, AddedTag), Is.True);
|
||||
|
||||
Assert.That(tagSystem.HasAllTags(sTagComponent, StartingTag, StartingTag), Is.True);
|
||||
Assert.That(tagSystem.HasAllTags(sTagComponent, AddedTag, StartingTag), Is.True);
|
||||
Assert.That(tagSystem.HasAllTags(sTagComponent, new List<string> { StartingTag, AddedTag }), Is.True);
|
||||
Assert.That(tagSystem.HasAllTags(sTagComponent, new List<string> { AddedTag, StartingTag }), Is.True);
|
||||
Assert.That(tagSystem.HasAllTags(sTagComponent, new List<ProtoId<TagPrototype>> { StartingTag, AddedTag }), Is.True);
|
||||
Assert.That(tagSystem.HasAllTags(sTagComponent, new List<ProtoId<TagPrototype>> { AddedTag, StartingTag }), Is.True);
|
||||
Assert.That(tagSystem.HasAllTags(sTagComponent, new HashSet<ProtoId<TagPrototype>> { StartingTag, AddedTag }), Is.True);
|
||||
Assert.That(tagSystem.HasAllTags(sTagComponent, new HashSet<ProtoId<TagPrototype>> { AddedTag, StartingTag }), Is.True);
|
||||
|
||||
Assert.That(tagSystem.HasAnyTag(sTagComponent, StartingTag, AddedTag), Is.True);
|
||||
Assert.That(tagSystem.HasAnyTag(sTagComponent, AddedTag, StartingTag), Is.True);
|
||||
Assert.That(tagSystem.HasAnyTag(sTagComponent, new List<ProtoId<TagPrototype>> { StartingTag, AddedTag }), Is.True);
|
||||
Assert.That(tagSystem.HasAnyTag(sTagComponent, new List<ProtoId<TagPrototype>> { AddedTag, StartingTag }), Is.True);
|
||||
Assert.That(tagSystem.HasAnyTag(sTagComponent, new HashSet<ProtoId<TagPrototype>> { StartingTag, AddedTag }), Is.True);
|
||||
Assert.That(tagSystem.HasAnyTag(sTagComponent, new HashSet<ProtoId<TagPrototype>> { AddedTag, StartingTag }), Is.True);
|
||||
});
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
// Remove the existing starting tag
|
||||
Assert.That(tagSystem.RemoveTag(sTagDummy, sTagComponent, StartingTag), Is.True);
|
||||
Assert.That(tagSystem.RemoveTag(sTagEntity, StartingTag), Is.True);
|
||||
|
||||
// Remove the existing added tag
|
||||
Assert.That(tagSystem.RemoveTags(sTagDummy, sTagComponent, AddedTag, AddedTag), Is.True);
|
||||
Assert.That(tagSystem.RemoveTags(sTagEntity, AddedTag, AddedTag), Is.True);
|
||||
});
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
// No tags left to remove
|
||||
Assert.That(tagSystem.RemoveTags(sTagDummy, sTagComponent, new List<string> { StartingTag, AddedTag }), Is.False);
|
||||
Assert.That(tagSystem.RemoveTags(sTagEntity, new List<ProtoId<TagPrototype>> { StartingTag, AddedTag }), Is.False);
|
||||
|
||||
// No tags left in the component
|
||||
Assert.That(sTagComponent.Tags, Is.Empty);
|
||||
});
|
||||
|
||||
#if !DEBUG
|
||||
return;
|
||||
// It is run only in DEBUG build,
|
||||
// as the checks are performed only in DEBUG build.
|
||||
#if DEBUG
|
||||
// Has single
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.HasTag(sTagDummy, UnregisteredTag); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.HasTag(sTagComponent, UnregisteredTag); });
|
||||
|
||||
// HasAny entityUid methods
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.HasAnyTag(sTagDummy, UnregisteredTag); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.HasAnyTag(sTagDummy, UnregisteredTag, UnregisteredTag); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.HasAnyTag(sTagDummy, new List<ProtoId<TagPrototype>> { UnregisteredTag }); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.HasAnyTag(sTagDummy, new HashSet<ProtoId<TagPrototype>> { UnregisteredTag }); });
|
||||
|
||||
// HasAny component methods
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.HasAnyTag(sTagComponent, UnregisteredTag); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.HasAnyTag(sTagComponent, UnregisteredTag, UnregisteredTag); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.HasAnyTag(sTagComponent, new List<ProtoId<TagPrototype>> { UnregisteredTag }); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.HasAnyTag(sTagComponent, new HashSet<ProtoId<TagPrototype>> { UnregisteredTag }); });
|
||||
|
||||
// HasAll entityUid methods
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.HasAllTags(sTagDummy, UnregisteredTag); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.HasAllTags(sTagDummy, UnregisteredTag, UnregisteredTag); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.HasAllTags(sTagDummy, new List<ProtoId<TagPrototype>> { UnregisteredTag }); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.HasAllTags(sTagDummy, new HashSet<ProtoId<TagPrototype>> { UnregisteredTag }); });
|
||||
|
||||
// HasAll component methods
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.HasAllTags(sTagComponent, UnregisteredTag); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.HasAllTags(sTagComponent, UnregisteredTag, UnregisteredTag); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.HasAllTags(sTagComponent, new List<ProtoId<TagPrototype>> { UnregisteredTag }); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.HasAllTags(sTagComponent, new HashSet<ProtoId<TagPrototype>> { UnregisteredTag }); });
|
||||
|
||||
// RemoveTag single
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.RemoveTag(sTagDummy, UnregisteredTag); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.RemoveTag(sTagEntity, UnregisteredTag); });
|
||||
|
||||
// RemoveTags entityUid methods
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.RemoveTags(sTagDummy, UnregisteredTag); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.RemoveTags(sTagDummy, UnregisteredTag, UnregisteredTag); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.RemoveTags(sTagDummy, new List<ProtoId<TagPrototype>> { UnregisteredTag }); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.RemoveTags(sTagDummy, new HashSet<ProtoId<TagPrototype>> { UnregisteredTag }); });
|
||||
|
||||
// RemoveTags entity methods
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.RemoveTags(sTagEntity, UnregisteredTag); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.RemoveTags(sTagEntity, UnregisteredTag, UnregisteredTag); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.RemoveTags(sTagEntity, new List<ProtoId<TagPrototype>> { UnregisteredTag }); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.RemoveTags(sTagEntity, new HashSet<ProtoId<TagPrototype>> { UnregisteredTag }); });
|
||||
|
||||
// AddTag single
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.AddTag(sTagDummy, UnregisteredTag); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.AddTag(sTagEntity, UnregisteredTag); });
|
||||
|
||||
// AddTags entityUid methods
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.AddTags(sTagDummy, UnregisteredTag); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.AddTags(sTagDummy, UnregisteredTag, UnregisteredTag); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.AddTags(sTagDummy, new List<ProtoId<TagPrototype>> { UnregisteredTag }); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.AddTags(sTagDummy, new HashSet<ProtoId<TagPrototype>> { UnregisteredTag }); });
|
||||
|
||||
// AddTags entity methods
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.AddTags(sTagEntity, UnregisteredTag); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.AddTags(sTagEntity, UnregisteredTag, UnregisteredTag); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.AddTags(sTagEntity, new List<ProtoId<TagPrototype>> { UnregisteredTag }); });
|
||||
Assert.Throws<DebugAssertException>(() => { tagSystem.AddTags(sTagEntity, new HashSet<ProtoId<TagPrototype>> { UnregisteredTag }); });
|
||||
#endif
|
||||
|
||||
// Single
|
||||
Assert.Throws<DebugAssertException>(() =>
|
||||
{
|
||||
tagSystem.HasTag(sTagDummy, UnregisteredTag);
|
||||
});
|
||||
Assert.Throws<DebugAssertException>(() =>
|
||||
{
|
||||
tagSystem.HasTag(sTagComponent, UnregisteredTag);
|
||||
});
|
||||
|
||||
// Any
|
||||
Assert.Throws<DebugAssertException>(() =>
|
||||
{
|
||||
tagSystem.HasAnyTag(sTagDummy, UnregisteredTag);
|
||||
});
|
||||
Assert.Throws<DebugAssertException>(() =>
|
||||
{
|
||||
tagSystem.HasAnyTag(sTagComponent, UnregisteredTag);
|
||||
});
|
||||
|
||||
// All
|
||||
Assert.Throws<DebugAssertException>(() =>
|
||||
{
|
||||
tagSystem.HasAllTags(sTagDummy, UnregisteredTag);
|
||||
});
|
||||
Assert.Throws<DebugAssertException>(() =>
|
||||
{
|
||||
tagSystem.HasAllTags(sTagComponent, UnregisteredTag);
|
||||
});
|
||||
});
|
||||
await pair.CleanReturnAsync();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Linq;
|
||||
using Content.Shared.Administration;
|
||||
using Content.Shared.Tag;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Toolshed;
|
||||
using Robust.Shared.Toolshed.Syntax;
|
||||
using Robust.Shared.Toolshed.TypeParsers;
|
||||
@@ -13,14 +14,14 @@ public sealed class TagCommand : ToolshedCommand
|
||||
private TagSystem? _tag;
|
||||
|
||||
[CommandImplementation("list")]
|
||||
public IEnumerable<string> List([PipedArgument] IEnumerable<EntityUid> ent)
|
||||
public IEnumerable<ProtoId<TagPrototype>> List([PipedArgument] IEnumerable<EntityUid> ent)
|
||||
{
|
||||
return ent.SelectMany(x =>
|
||||
{
|
||||
if (TryComp<TagComponent>(x, out var tags))
|
||||
// Note: Cast is required for C# to figure out the type signature.
|
||||
return (IEnumerable<string>)tags.Tags;
|
||||
return Array.Empty<string>();
|
||||
return (IEnumerable<ProtoId<TagPrototype>>)tags.Tags;
|
||||
return Array.Empty<ProtoId<TagPrototype>>();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -72,7 +73,7 @@ public sealed class TagCommand : ToolshedCommand
|
||||
)
|
||||
{
|
||||
_tag ??= GetSys<TagSystem>();
|
||||
_tag.AddTags(input, @ref.Evaluate(ctx)!);
|
||||
_tag.AddTags(input, (IEnumerable<ProtoId<TagPrototype>>)@ref.Evaluate(ctx)!);
|
||||
return input;
|
||||
}
|
||||
|
||||
@@ -92,7 +93,7 @@ public sealed class TagCommand : ToolshedCommand
|
||||
)
|
||||
{
|
||||
_tag ??= GetSys<TagSystem>();
|
||||
_tag.RemoveTags(input, @ref.Evaluate(ctx)!);
|
||||
_tag.RemoveTags(input, (IEnumerable<ProtoId<TagPrototype>>)@ref.Evaluate(ctx)!);
|
||||
return input;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace Content.Server.Mech.Systems;
|
||||
public sealed class MechAssemblySystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly ContainerSystem _container = default!;
|
||||
[Dependency] private readonly TagSystem _tag = default!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
@@ -44,7 +45,7 @@ public sealed class MechAssemblySystem : EntitySystem
|
||||
|
||||
foreach (var (tag, val) in component.RequiredParts)
|
||||
{
|
||||
if (!val && tagComp.Tags.Contains(tag))
|
||||
if (!val && _tag.HasTag(tagComp, tag))
|
||||
{
|
||||
component.RequiredParts[tag] = true;
|
||||
_container.Insert(args.Used, component.PartsContainer);
|
||||
|
||||
@@ -13,6 +13,7 @@ using Robust.Shared.Collections;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Random;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
@@ -24,13 +25,15 @@ public sealed partial class DungeonJob
|
||||
* Run after the main dungeon generation
|
||||
*/
|
||||
|
||||
private static readonly ProtoId<TagPrototype> WallTag = "Wall";
|
||||
|
||||
private bool HasWall(MapGridComponent grid, Vector2i tile)
|
||||
{
|
||||
var anchored = _maps.GetAnchoredEntitiesEnumerator(_gridUid, _grid, tile);
|
||||
|
||||
while (anchored.MoveNext(out var uid))
|
||||
{
|
||||
if (_tagQuery.TryGetComponent(uid, out var tagComp) && tagComp.Tags.Contains("Wall"))
|
||||
if (_tag.HasTag(uid.Value, WallTag))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,10 +28,10 @@ public sealed partial class DungeonJob : Job<Dungeon>
|
||||
private readonly DecalSystem _decals;
|
||||
private readonly DungeonSystem _dungeon;
|
||||
private readonly EntityLookupSystem _lookup;
|
||||
private readonly TagSystem _tag;
|
||||
private readonly TileSystem _tile;
|
||||
private readonly SharedMapSystem _maps;
|
||||
private readonly SharedTransformSystem _transform;
|
||||
private EntityQuery<TagComponent> _tagQuery;
|
||||
|
||||
private readonly DungeonConfigPrototype _gen;
|
||||
private readonly int _seed;
|
||||
@@ -53,6 +53,7 @@ public sealed partial class DungeonJob : Job<Dungeon>
|
||||
DecalSystem decals,
|
||||
DungeonSystem dungeon,
|
||||
EntityLookupSystem lookup,
|
||||
TagSystem tag,
|
||||
TileSystem tile,
|
||||
SharedTransformSystem transform,
|
||||
DungeonConfigPrototype gen,
|
||||
@@ -72,10 +73,10 @@ public sealed partial class DungeonJob : Job<Dungeon>
|
||||
_decals = decals;
|
||||
_dungeon = dungeon;
|
||||
_lookup = lookup;
|
||||
_tag = tag;
|
||||
_tile = tile;
|
||||
_maps = _entManager.System<SharedMapSystem>();
|
||||
_transform = transform;
|
||||
_tagQuery = _entManager.GetEntityQuery<TagComponent>();
|
||||
|
||||
_gen = gen;
|
||||
_grid = grid;
|
||||
|
||||
@@ -10,6 +10,7 @@ using Content.Shared.GameTicking;
|
||||
using Content.Shared.Maps;
|
||||
using Content.Shared.Physics;
|
||||
using Content.Shared.Procedural;
|
||||
using Content.Shared.Tag;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.Console;
|
||||
@@ -31,6 +32,7 @@ public sealed partial class DungeonSystem : SharedDungeonSystem
|
||||
[Dependency] private readonly AnchorableSystem _anchorable = default!;
|
||||
[Dependency] private readonly DecalSystem _decals = default!;
|
||||
[Dependency] private readonly EntityLookupSystem _lookup = default!;
|
||||
[Dependency] private readonly TagSystem _tag = default!;
|
||||
[Dependency] private readonly TileSystem _tile = default!;
|
||||
[Dependency] private readonly MapLoaderSystem _loader = default!;
|
||||
[Dependency] private readonly SharedMapSystem _maps = default!;
|
||||
@@ -199,6 +201,7 @@ public sealed partial class DungeonSystem : SharedDungeonSystem
|
||||
_decals,
|
||||
this,
|
||||
_lookup,
|
||||
_tag,
|
||||
_tile,
|
||||
_transform,
|
||||
gen,
|
||||
@@ -231,6 +234,7 @@ public sealed partial class DungeonSystem : SharedDungeonSystem
|
||||
_decals,
|
||||
this,
|
||||
_lookup,
|
||||
_tag,
|
||||
_tile,
|
||||
_transform,
|
||||
gen,
|
||||
|
||||
@@ -246,7 +246,7 @@ public sealed partial class RevenantSystem
|
||||
foreach (var ent in lookup)
|
||||
{
|
||||
//break windows
|
||||
if (tags.HasComponent(ent) && _tag.HasAnyTag(ent, "Window"))
|
||||
if (tags.HasComponent(ent) && _tag.HasTag(ent, "Window"))
|
||||
{
|
||||
//hardcoded damage specifiers til i die.
|
||||
var dspec = new DamageSpecifier();
|
||||
|
||||
@@ -21,6 +21,7 @@ public sealed class SpreaderSystem : EntitySystem
|
||||
[Dependency] private readonly IPrototypeManager _prototype = default!;
|
||||
[Dependency] private readonly IRobustRandom _robustRandom = default!;
|
||||
[Dependency] private readonly SharedMapSystem _map = default!;
|
||||
[Dependency] private readonly TagSystem _tag = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Cached maximum number of updates per spreader prototype. This is applied per-grid.
|
||||
@@ -37,8 +38,7 @@ public sealed class SpreaderSystem : EntitySystem
|
||||
|
||||
public const float SpreadCooldownSeconds = 1;
|
||||
|
||||
[ValidatePrototypeId<TagPrototype>]
|
||||
private const string IgnoredTag = "SpreaderIgnore";
|
||||
private static readonly ProtoId<TagPrototype> IgnoredTag = "SpreaderIgnore";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void Initialize()
|
||||
@@ -189,7 +189,6 @@ public sealed class SpreaderSystem : EntitySystem
|
||||
var airtightQuery = GetEntityQuery<AirtightComponent>();
|
||||
var dockQuery = GetEntityQuery<DockingComponent>();
|
||||
var xformQuery = GetEntityQuery<TransformComponent>();
|
||||
var tagQuery = GetEntityQuery<TagComponent>();
|
||||
var blockedAtmosDirs = AtmosDirection.Invalid;
|
||||
|
||||
// Due to docking ports they may not necessarily be opposite directions.
|
||||
@@ -212,7 +211,7 @@ public sealed class SpreaderSystem : EntitySystem
|
||||
|
||||
// If we're on a blocked tile work out which directions we can go.
|
||||
if (!airtightQuery.TryGetComponent(ent, out var airtight) || !airtight.AirBlocked ||
|
||||
tagQuery.TryGetComponent(ent, out var tags) && tags.Tags.Contains(IgnoredTag))
|
||||
_tag.HasTag(ent.Value, IgnoredTag))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -250,8 +249,7 @@ public sealed class SpreaderSystem : EntitySystem
|
||||
|
||||
while (directionEnumerator.MoveNext(out var ent))
|
||||
{
|
||||
if (!airtightQuery.TryGetComponent(ent, out var airtight) || !airtight.AirBlocked ||
|
||||
tagQuery.TryGetComponent(ent, out var tags) && tags.Tags.Contains(IgnoredTag))
|
||||
if (!airtightQuery.TryGetComponent(ent, out var airtight) || !airtight.AirBlocked || _tag.HasTag(ent.Value, IgnoredTag))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -12,9 +12,10 @@ public abstract class SharedChameleonClothingSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly IComponentFactory _factory = default!;
|
||||
[Dependency] private readonly IPrototypeManager _proto = default!;
|
||||
[Dependency] private readonly SharedItemSystem _itemSystem = default!;
|
||||
[Dependency] private readonly ClothingSystem _clothingSystem = default!;
|
||||
[Dependency] private readonly MetaDataSystem _metaData = default!;
|
||||
[Dependency] private readonly SharedItemSystem _itemSystem = default!;
|
||||
[Dependency] private readonly TagSystem _tag = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -81,7 +82,7 @@ public abstract class SharedChameleonClothingSystem : EntitySystem
|
||||
return false;
|
||||
|
||||
// check if it is marked as valid chameleon target
|
||||
if (!proto.TryGetComponent(out TagComponent? tags, _factory) || !tags.Tags.Contains("WhitelistChameleon"))
|
||||
if (!proto.TryGetComponent(out TagComponent? tag, _factory) || !_tag.HasTag(tag, "WhitelistChameleon"))
|
||||
return false;
|
||||
|
||||
// check if it's valid clothing
|
||||
|
||||
@@ -12,13 +12,12 @@ namespace Content.Shared.Construction.Conditions
|
||||
public bool Condition(EntityUid user, EntityCoordinates location, Direction direction)
|
||||
{
|
||||
var entManager = IoCManager.Resolve<IEntityManager>();
|
||||
var tagQuery = entManager.GetEntityQuery<TagComponent>();
|
||||
var sysMan = entManager.EntitySysManager;
|
||||
var tagSystem = sysMan.GetEntitySystem<TagSystem>();
|
||||
|
||||
foreach (var entity in location.GetEntitiesInTile(LookupFlags.Static))
|
||||
{
|
||||
if (tagSystem.HasTag(entity, "Window", tagQuery))
|
||||
if (tagSystem.HasTag(entity, "Window"))
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Physics.Components;
|
||||
using Content.Shared.Tag;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Utility;
|
||||
using SharedToolSystem = Content.Shared.Tools.Systems.SharedToolSystem;
|
||||
@@ -32,16 +33,14 @@ public sealed partial class AnchorableSystem : EntitySystem
|
||||
[Dependency] private readonly TagSystem _tagSystem = default!;
|
||||
|
||||
private EntityQuery<PhysicsComponent> _physicsQuery;
|
||||
private EntityQuery<TagComponent> _tagQuery;
|
||||
|
||||
public const string Unstackable = "Unstackable";
|
||||
public readonly ProtoId<TagPrototype> Unstackable = "Unstackable";
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
_physicsQuery = GetEntityQuery<PhysicsComponent>();
|
||||
_tagQuery = GetEntityQuery<TagComponent>();
|
||||
|
||||
SubscribeLocalEvent<AnchorableComponent, InteractUsingEvent>(OnInteractUsing,
|
||||
before: new[] { typeof(ItemSlotsSystem) }, after: new[] { typeof(SharedConstructionSystem) });
|
||||
@@ -312,7 +311,7 @@ public sealed partial class AnchorableSystem : EntitySystem
|
||||
DebugTools.Assert(!Transform(uid).Anchored);
|
||||
|
||||
// If we are unstackable, iterate through any other entities anchored on the current square
|
||||
return _tagSystem.HasTag(uid, Unstackable, _tagQuery) && AnyUnstackablesAnchoredAt(location);
|
||||
return _tagSystem.HasTag(uid, Unstackable) && AnyUnstackablesAnchoredAt(location);
|
||||
}
|
||||
|
||||
public bool AnyUnstackablesAnchoredAt(EntityCoordinates location)
|
||||
@@ -327,10 +326,8 @@ public sealed partial class AnchorableSystem : EntitySystem
|
||||
while (enumerator.MoveNext(out var entity))
|
||||
{
|
||||
// If we find another unstackable here, return true.
|
||||
if (_tagSystem.HasTag(entity.Value, Unstackable, _tagQuery))
|
||||
{
|
||||
if (_tagSystem.HasTag(entity.Value, Unstackable))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
using Content.Shared.Tag;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Construction.Steps
|
||||
{
|
||||
public sealed partial class MultipleTagsConstructionGraphStep : ArbitraryInsertConstructionGraphStep
|
||||
{
|
||||
[DataField("allTags")]
|
||||
private List<string>? _allTags;
|
||||
private List<ProtoId<TagPrototype>>? _allTags;
|
||||
|
||||
[DataField("anyTags")]
|
||||
private List<string>? _anyTags;
|
||||
private List<ProtoId<TagPrototype>>? _anyTags;
|
||||
|
||||
private static bool IsNullOrEmpty<T>(ICollection<T>? list)
|
||||
{
|
||||
@@ -21,16 +22,12 @@ namespace Content.Shared.Construction.Steps
|
||||
if (IsNullOrEmpty(_allTags) && IsNullOrEmpty(_anyTags))
|
||||
return false; // Step is somehow invalid, we return.
|
||||
|
||||
// No tags at all.
|
||||
if (!entityManager.TryGetComponent(uid, out TagComponent? tags))
|
||||
return false;
|
||||
|
||||
var tagSystem = entityManager.EntitySysManager.GetEntitySystem<TagSystem>();
|
||||
|
||||
if (_allTags != null && !tagSystem.HasAllTags(tags, _allTags))
|
||||
if (_allTags != null && !tagSystem.HasAllTags(uid, _allTags))
|
||||
return false; // We don't have all the tags needed.
|
||||
|
||||
if (_anyTags != null && !tagSystem.HasAnyTag(tags, _anyTags))
|
||||
if (_anyTags != null && !tagSystem.HasAnyTag(uid, _anyTags))
|
||||
return false; // We don't have any of the tags needed.
|
||||
|
||||
// This entity is valid!
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Content.Shared.Tag;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Prototypes;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Timing;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -24,7 +25,7 @@ public abstract class SharedNavMapSystem : EntitySystem
|
||||
|
||||
[Robust.Shared.IoC.Dependency] private readonly TagSystem _tagSystem = default!;
|
||||
|
||||
private readonly string[] _wallTags = ["Wall", "Window"];
|
||||
private static readonly ProtoId<TagPrototype>[] WallTags = {"Wall", "Window"};
|
||||
private EntityQuery<NavMapDoorComponent> _doorQuery;
|
||||
|
||||
public override void Initialize()
|
||||
@@ -58,7 +59,7 @@ public abstract class SharedNavMapSystem : EntitySystem
|
||||
if (_doorQuery.HasComp(uid))
|
||||
return NavMapChunkType.Airlock;
|
||||
|
||||
if (_tagSystem.HasAnyTag(uid, _wallTags))
|
||||
if (_tagSystem.HasAnyTag(uid, WallTags))
|
||||
return NavMapChunkType.Wall;
|
||||
|
||||
return NavMapChunkType.Invalid;
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set;
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Tag
|
||||
namespace Content.Shared.Tag;
|
||||
|
||||
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(TagSystem))]
|
||||
public sealed partial class TagComponent : Component
|
||||
{
|
||||
[RegisterComponent, NetworkedComponent, Access(typeof(TagSystem))]
|
||||
public sealed partial class TagComponent : Component
|
||||
{
|
||||
[DataField("tags", customTypeSerializer: typeof(PrototypeIdHashSetSerializer<TagPrototype>))]
|
||||
[Access(typeof(TagSystem), Other = AccessPermissions.ReadExecute)] // FIXME Friends
|
||||
public HashSet<string> Tags = new();
|
||||
}
|
||||
[DataField, ViewVariables, AutoNetworkedField]
|
||||
public HashSet<ProtoId<TagPrototype>> Tags = new();
|
||||
}
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Tag
|
||||
{
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class TagComponentState : ComponentState
|
||||
{
|
||||
public TagComponentState(string[] tags)
|
||||
{
|
||||
Tags = tags;
|
||||
}
|
||||
|
||||
public string[] Tags { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,15 @@
|
||||
using Robust.Shared.Prototypes;
|
||||
|
||||
namespace Content.Shared.Tag
|
||||
namespace Content.Shared.Tag;
|
||||
|
||||
/// <summary>
|
||||
/// Prototype representing a tag in YAML.
|
||||
/// Meant to only have an ID property, as that is the only thing that
|
||||
/// gets saved in TagComponent.
|
||||
/// </summary>
|
||||
[Prototype("Tag")]
|
||||
public sealed partial class TagPrototype : IPrototype
|
||||
{
|
||||
/// <summary>
|
||||
/// Prototype representing a tag in YAML.
|
||||
/// Meant to only have an ID property, as that is the only thing that
|
||||
/// gets saved in TagComponent.
|
||||
/// </summary>
|
||||
[Prototype("Tag")]
|
||||
public sealed partial class TagPrototype : IPrototype
|
||||
{
|
||||
[ViewVariables]
|
||||
[IdDataField]
|
||||
public string ID { get; private set; } = default!;
|
||||
}
|
||||
[IdDataField, ViewVariables]
|
||||
public string ID { get; } = string.Empty;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user