No atmos stacking (attempt 2) (#16687)

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
Tom Leys
2023-06-30 00:04:36 +12:00
committed by GitHub
parent ccf58fa657
commit 67df47f553
12 changed files with 165 additions and 14 deletions

View File

@@ -0,0 +1,31 @@
using Content.Shared.Construction.EntitySystems;
using JetBrains.Annotations;
using Robust.Shared.Map;
namespace Content.Shared.Construction.Conditions;
/// <summary>
/// Check for "Unstackable" condition commonly used by atmos devices and others which otherwise don't check on
/// collisions with other items.
/// </summary>
[UsedImplicitly]
[DataDefinition]
public sealed class NoUnstackableInTile : IConstructionCondition
{
public const string GuidebookString = "construction-step-condition-no-unstackable-in-tile";
public bool Condition(EntityUid user, EntityCoordinates location, Direction direction)
{
var sysMan = IoCManager.Resolve<IEntitySystemManager>();
var anchorable = sysMan.GetEntitySystem<SharedAnchorableSystem>();
return !anchorable.AnyUnstackablesAnchoredAt(location);
}
public ConstructionGuideEntry GenerateGuideEntry()
{
return new ConstructionGuideEntry
{
Localization = GuidebookString
};
}
}

View File

@@ -2,6 +2,7 @@
using Content.Shared.Tag;
using JetBrains.Annotations;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
namespace Content.Shared.Construction.Conditions
{
@@ -11,11 +12,20 @@ namespace Content.Shared.Construction.Conditions
{
public bool Condition(EntityUid user, EntityCoordinates location, Direction direction)
{
var tagSystem = IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<TagSystem>();
var entManager = IoCManager.Resolve<IEntityManager>();
var gridUid = location.GetGridUid(entManager);
foreach (var entity in location.GetEntitiesInTile(LookupFlags.Approximate | LookupFlags.Static))
if (!entManager.TryGetComponent<MapGridComponent>(gridUid, out var grid))
return true;
var tagQuery = entManager.GetEntityQuery<TagComponent>();
var sysMan = entManager.EntitySysManager;
var tagSystem = sysMan.GetEntitySystem<TagSystem>();
var lookup = sysMan.GetEntitySystem<EntityLookupSystem>();
foreach (var entity in lookup.GetEntitiesIntersecting(gridUid.Value, grid.LocalToTile(location)))
{
if (tagSystem.HasTag(entity, "Window"))
if (tagSystem.HasTag(entity, "Window", tagQuery))
return false;
}

View File

@@ -3,17 +3,28 @@ using Content.Shared.Containers.ItemSlots;
using Content.Shared.DoAfter;
using Content.Shared.Interaction;
using Content.Shared.Pulling.Components;
using Content.Shared.Tag;
using Content.Shared.Tools.Components;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Serialization;
namespace Content.Shared.Construction.EntitySystems;
public abstract class SharedAnchorableSystem : EntitySystem
{
[Dependency] private readonly TagSystem _tagSystem = default!;
protected EntityQuery<TagComponent> TagQuery;
public const string Unstackable = "Unstackable";
public override void Initialize()
{
base.Initialize();
TagQuery = GetEntityQuery<TagComponent>();
SubscribeLocalEvent<AnchorableComponent, InteractUsingEvent>(OnInteractUsing,
before: new[] { typeof(ItemSlotsSystem) }, after: new[] { typeof(SharedConstructionSystem) });
}
@@ -42,6 +53,38 @@ public abstract class SharedAnchorableSystem : EntitySystem
// TODO tool system is fixed now, make this actually shared.
}
public bool AnyUnstackablesAnchoredAt(EntityCoordinates location)
{
var gridUid = location.GetGridUid(EntityManager);
if (!TryComp<MapGridComponent>(gridUid, out var grid))
return false;
var enumerator = grid.GetAnchoredEntitiesEnumerator(grid.LocalToTile(location));
while (enumerator.MoveNext(out var entity))
{
// If we find another unstackable here, return true.
if (_tagSystem.HasTag(entity.Value, Unstackable, TagQuery))
{
return true;
}
}
return false;
}
public bool AnyUnstackable(EntityUid uid, EntityCoordinates location)
{
// If we are unstackable, iterate through any other entities anchored on the current square
if (_tagSystem.HasTag(uid, Unstackable, TagQuery))
{
return AnyUnstackablesAnchoredAt(location);
}
return false;
}
[Serializable, NetSerializable]
protected sealed class TryUnanchorCompletedEvent : SimpleDoAfterEvent
{