Don't allow anchorable overlap (#10461)
* Don't allow anchorable overlap Should significantly reduce incidents of wall pushing. * woops
This commit is contained in:
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user