using Robust.Shared.Audio.Systems;
using Robust.Shared.Network;
using Robust.Shared.Map.Components;
+using Robust.Shared.Physics;
namespace Content.Shared.Doors.Systems;
[ValidatePrototypeId<TagPrototype>]
public const string DoorBumpTag = "DoorBumpOpener";
- /// <summary>
- /// A body must have an intersection percentage larger than this in order to be considered as colliding with a
- /// door. Used for safety close-blocking and crushing.
- /// </summary>
- /// <remarks>
- /// The intersection percentage relies on WORLD AABBs. So if this is too small, and the grid is rotated 45
- /// degrees, then an entity outside of the airlock may be crushed.
- /// </remarks>
- public const float IntersectPercentage = 0.2f;
-
/// <summary>
/// A set of doors that are currently opening, closing, or just queued to open/close after some delay.
/// </summary>
private readonly HashSet<Entity<DoorComponent>> _activeDoors = new();
+ private readonly HashSet<Entity<PhysicsComponent>> _doorIntersecting = new();
+
public override void Initialize()
{
base.Initialize();
_activeDoors.Add(ent);
RaiseLocalEvent(ent, new DoorStateChangedEvent(door.State));
- AppearanceSystem.SetData(ent, DoorVisuals.State, door.State);
}
protected bool SetState(EntityUid uid, DoorState state, DoorComponent? door = null)
door.State = state;
Dirty(uid, door);
RaiseLocalEvent(uid, new DoorStateChangedEvent(state));
+
AppearanceSystem.SetData(uid, DoorVisuals.State, door.State);
return true;
}
if (!TryComp<MapGridComponent>(xform.GridUid, out var mapGridComp))
yield break;
var tileRef = _mapSystem.GetTileRef(xform.GridUid.Value, mapGridComp, xform.Coordinates);
- var doorWorldBounds = _entityLookup.GetWorldBounds(tileRef);
+
+ _doorIntersecting.Clear();
+
+ _entityLookup.GetLocalEntitiesIntersecting(xform.GridUid.Value, tileRef.GridIndices, _doorIntersecting, gridComp: mapGridComp);
// TODO SLOTH fix electro's code.
// ReSharper disable once InconsistentNaming
- var doorAABB = _entityLookup.GetWorldAABB(uid);
- foreach (var otherPhysics in PhysicsSystem.GetCollidingEntities(Transform(uid).MapID, doorWorldBounds))
+ foreach (var otherPhysics in _doorIntersecting)
{
if (otherPhysics.Comp == physics)
continue;
+ if (!otherPhysics.Comp.CanCollide)
+ continue;
+
//TODO: Make only shutters ignore these objects upon colliding instead of all airlocks
// Excludes Glasslayer for windows, GlassAirlockLayer for windoors, TableLayer for tables
- if (!otherPhysics.Comp.CanCollide || otherPhysics.Comp.CollisionLayer == (int) CollisionGroup.GlassLayer || otherPhysics.Comp.CollisionLayer == (int) CollisionGroup.GlassAirlockLayer || otherPhysics.Comp.CollisionLayer == (int) CollisionGroup.TableLayer)
+ if (otherPhysics.Comp.CollisionLayer == (int) CollisionGroup.GlassLayer || otherPhysics.Comp.CollisionLayer == (int) CollisionGroup.GlassAirlockLayer || otherPhysics.Comp.CollisionLayer == (int) CollisionGroup.TableLayer)
continue;
//If the colliding entity is a slippable item ignore it by the airlock
if ((physics.CollisionMask & otherPhysics.Comp.CollisionLayer) == 0 && (otherPhysics.Comp.CollisionMask & physics.CollisionLayer) == 0)
continue;
- if (_entityLookup.GetWorldAABB(otherPhysics.Owner).IntersectPercentage(doorAABB) < IntersectPercentage)
- continue;
-
yield return otherPhysics.Owner;
}
}
var otherUid = args.OtherEntity;
if (Tags.HasTag(otherUid, DoorBumpTag))
- TryOpen(uid, door, otherUid, quiet: door.State == DoorState.Denying);
+ TryOpen(uid, door, otherUid, quiet: door.State == DoorState.Denying, predicted: true);
}
#endregion
var (uid, door, physics) = ent;
if (door.BumpOpen)
{
- foreach (var other in PhysicsSystem.GetContactingEntities(uid, physics, approximate: true))
+ foreach (var other in PhysicsSystem.GetContactingEntities(uid, physics))
{
if (Tags.HasTag(other, DoorBumpTag) && TryOpen(uid, door, other, quiet: true))
break;