using Robust.Shared.Containers;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
+using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Events;
+using Robust.Shared.Physics.Systems;
using Robust.Shared.Timing;
namespace Content.Server.Singularity.EntitySystems;
[Dependency] private readonly IMapManager _mapMan = default!;
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
+ [Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly SharedTransformSystem _xformSystem = default!;
[Dependency] private readonly TagSystem _tagSystem = default!;
#endregion Dependencies
+ private EntityQuery<PhysicsComponent> _physicsQuery;
+
public override void Initialize()
{
base.Initialize();
+ _physicsQuery = GetEntityQuery<PhysicsComponent>();
+
SubscribeLocalEvent<MapGridComponent, EventHorizonAttemptConsumeEntityEvent>(PreventConsume);
- SubscribeLocalEvent<GhostComponent, EventHorizonAttemptConsumeEntityEvent>(PreventConsume);
SubscribeLocalEvent<StationDataComponent, EventHorizonAttemptConsumeEntityEvent>(PreventConsume);
SubscribeLocalEvent<EventHorizonComponent, MapInitEvent>(OnHorizonMapInit);
SubscribeLocalEvent<EventHorizonComponent, StartCollideEvent>(OnStartCollide);
/// Attempts to consume all entities within a given distance of an entity;
/// Excludes the center entity.
/// </summary>
- public void ConsumeEntitiesInRange(EntityUid uid, float range, TransformComponent? xform = null, EventHorizonComponent? eventHorizon = null)
+ public void ConsumeEntitiesInRange(EntityUid uid, float range, PhysicsComponent? body = null, EventHorizonComponent? eventHorizon = null)
{
- if (!Resolve(uid, ref xform, ref eventHorizon))
+ if (!Resolve(uid, ref body, ref eventHorizon))
return;
- var range2 = range * range;
- var xformQuery = EntityManager.GetEntityQuery<TransformComponent>();
- var epicenter = _xformSystem.GetWorldPosition(xform, xformQuery);
- foreach (var entity in _lookup.GetEntitiesInRange(_xformSystem.GetMapCoordinates(uid, xform), range, flags: LookupFlags.Uncontained))
+ // TODO: Should be sundries + static-sundries but apparently this is load-bearing for SpawnAndDeleteAllEntitiesInTheSameSpot so go figure.
+ foreach (var entity in _lookup.GetEntitiesInRange(uid, range, flags: LookupFlags.Uncontained))
{
if (entity == uid)
continue;
- if (!xformQuery.TryGetComponent(entity, out var entityXform))
- continue;
- // GetEntitiesInRange gets everything in a _square_ centered on the given position, but we are a _circle_. If we don't have this check and the station is rotated it is possible for the singularity to reach _outside of the containment field_ and eat the emitters.
- var displacement = _xformSystem.GetWorldPosition(entityXform, xformQuery) - epicenter;
- if (displacement.LengthSquared() > range2)
+ // See TODO above
+ if (_physicsQuery.TryComp(entity, out var otherBody) && !_physics.IsHardCollidable((uid, null, body), (entity, null, otherBody)))
continue;
AttemptConsumeEntity(uid, entity, eventHorizon);
/// </summary>
public void ConsumeEverythingInRange(EntityUid uid, float range, TransformComponent? xform = null, EventHorizonComponent? eventHorizon = null)
{
- if (!Resolve(uid, ref xform, ref eventHorizon))
+ if (!Resolve(uid, ref eventHorizon))
return;
if (eventHorizon.ConsumeEntities)
- ConsumeEntitiesInRange(uid, range, xform, eventHorizon);
+ ConsumeEntitiesInRange(uid, range, null, eventHorizon);
if (eventHorizon.ConsumeTiles)
ConsumeTilesInRange(uid, range, xform, eventHorizon);
}
using Content.Server.Singularity.Components;
using Content.Shared.Atmos.Components;
using Content.Shared.Ghost;
+using Content.Shared.Physics;
using Content.Shared.Singularity.EntitySystems;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
/// </summary>
public const float MinGravPulseRange = 0.00001f;
+ private EntityQuery<GravityWellComponent> _wellQuery;
+ private EntityQuery<MapComponent> _mapQuery;
+ private EntityQuery<MapGridComponent> _gridQuery;
+ private EntityQuery<PhysicsComponent> _physicsQuery;
+
public override void Initialize()
{
base.Initialize();
+ _wellQuery = GetEntityQuery<GravityWellComponent>();
+ _mapQuery = GetEntityQuery<MapComponent>();
+ _gridQuery = GetEntityQuery<MapGridComponent>();
+ _physicsQuery = GetEntityQuery<PhysicsComponent>();
SubscribeLocalEvent<GravityWellComponent, ComponentStartup>(OnGravityWellStartup);
var vvHandle = _vvManager.GetTypeHandler<GravityWellComponent>();
/// <param name="entity">The entity to check.</param>
private bool CanGravPulseAffect(EntityUid entity)
{
- return !(
- EntityManager.HasComponent<GhostComponent>(entity) ||
- EntityManager.HasComponent<MapGridComponent>(entity) ||
- EntityManager.HasComponent<MapComponent>(entity) ||
- EntityManager.HasComponent<GravityWellComponent>(entity)
+ if (_physicsQuery.TryComp(entity, out var physics))
+ {
+ if (physics.CollisionLayer == (int) CollisionGroup.GhostImpassable)
+ return false;
+ }
+
+ return !(_gridQuery.HasComp(entity) ||
+ _mapQuery.HasComp(entity) ||
+ _wellQuery.HasComp(entity)
);
}
GhostImpassable = 1 << 5, // 32 Things impassible by ghosts/observers, ie blessed tiles or forcefields
BulletImpassable = 1 << 6, // 64 Can be hit by bullets
InteractImpassable = 1 << 7, // 128 Blocks interaction/InRangeUnobstructed
+ // Y dis door passable when all the others impassable / collision.
DoorPassable = 1 << 8, // 256 Allows door to close over top, Like blast doors over conveyors for disposals rooms/cargo.
MapGrid = MapGridHelpers.CollisionGroup, // Map grids, like shuttles. This is the actual grid itself, not the walls or other entities connected to the grid.
// 32 possible groups
+ // Why dis exist
AllMask = -1,
+ SingularityLayer = Opaque | Impassable | MidImpassable | HighImpassable | LowImpassable | BulletImpassable | InteractImpassable | DoorPassable,
+
// Humanoids, etc.
MobMask = Impassable | HighImpassable | MidImpassable | LowImpassable,
MobLayer = Opaque | BulletImpassable,