Don't allow anchorable overlap (#10461)

* Don't allow anchorable overlap

Should significantly reduce incidents of wall pushing.

* woops
This commit is contained in:
metalgearsloth
2022-08-11 12:11:29 +10:00
committed by GitHub
parent 3764b556a1
commit 1347aed0b2
3 changed files with 53 additions and 7 deletions

View File

@@ -1,5 +1,4 @@
using System.Threading;
using System.Threading.Tasks;
using Content.Server.Administration.Logs;
using Content.Server.Coordinates.Helpers;
using Content.Server.Popups;
@@ -11,6 +10,7 @@ using Content.Shared.Database;
using Content.Shared.Examine;
using Content.Shared.Pulling.Components;
using Content.Shared.Tools.Components;
using Robust.Shared.Map;
using Robust.Shared.Player;
namespace Content.Server.Construction
@@ -18,6 +18,7 @@ namespace Content.Server.Construction
public sealed class AnchorableSystem : SharedAnchorableSystem
{
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly ToolSystem _toolSystem = default!;
[Dependency] private readonly PullingSystem _pullingSystem = default!;
@@ -71,6 +72,12 @@ namespace Content.Server.Construction
{
component.CancelToken = null;
var xform = Transform(uid);
if (TryComp<PhysicsComponent>(uid, out var anchorBody) &&
!TileFree(xform.Coordinates, anchorBody))
{
_popup.PopupEntity(Loc.GetString("anchorable-occupied"), uid, Filter.Entities(args.User));
return;
}
// Snap rotation to cardinal (multiple of 90)
var rot = xform.LocalRotation;
@@ -81,8 +88,9 @@ namespace Content.Server.Construction
_pullingSystem.TryStopPull(pullable);
}
// TODO: Anchoring snaps rn anyway!
if (component.Snap)
xform.Coordinates = xform.Coordinates.SnapToGrid();
xform.Coordinates = xform.Coordinates.SnapToGrid(EntityManager, _mapManager);
RaiseLocalEvent(uid, new BeforeAnchoredEvent(args.User, args.Using), false);
xform.Anchored = true;
@@ -97,6 +105,34 @@ namespace Content.Server.Construction
);
}
private bool TileFree(EntityCoordinates coordinates, PhysicsComponent anchorBody)
{
// Probably ignore CanCollide on the anchoring body?
var gridUid = coordinates.GetGridUid(EntityManager);
if (!_mapManager.TryGetGrid(gridUid, out var grid))
return false;
var tileIndices = grid.TileIndicesFor(coordinates);
var enumerator = grid.GetAnchoredEntitiesEnumerator(tileIndices);
var bodyQuery = GetEntityQuery<PhysicsComponent>();
while (enumerator.MoveNext(out var ent))
{
if (!bodyQuery.TryGetComponent(ent, out var body) ||
!body.CanCollide)
continue;
if ((body.CollisionMask & anchorBody.CollisionLayer) != 0x0 ||
(body.CollisionLayer & anchorBody.CollisionMask) != 0x0)
{
return false;
}
}
return true;
}
/// <summary>
/// Checks if a tool can change the anchored status.
/// </summary>
@@ -135,14 +171,24 @@ namespace Content.Server.Construction
SharedPullableComponent? pullable = null,
ToolComponent? usingTool = null)
{
if (!Resolve(uid, ref anchorable, ref transform)) return;
if (!Resolve(uid, ref anchorable, ref transform))
return;
// Optional resolves.
Resolve(uid, ref pullable, false);
if (!Resolve(usingUid, ref usingTool)) return;
if (!Resolve(usingUid, ref usingTool))
return;
if (!Valid(uid, userUid, usingUid, true, anchorable, usingTool)) return;
if (!Valid(uid, userUid, usingUid, true, anchorable, usingTool))
return;
if (TryComp<PhysicsComponent>(uid, out var anchorBody) &&
!TileFree(transform.Coordinates, anchorBody))
{
_popup.PopupEntity(Loc.GetString("anchorable-occupied"), uid, Filter.Entities(userUid));
return;
}
anchorable.CancelToken = new CancellationTokenSource();

View File

@@ -1,4 +1,3 @@
using System.Threading.Tasks;
using Content.Shared.Construction.Components;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.Interaction;

View File

@@ -1,2 +1,3 @@
anchorable-anchored = Anchored
anchorable-unanchored = Unanchored
anchorable-unanchored = Unanchored
anchorable-occupied = Tile occupied