private ISawmill _sawmill = default!;
+ private EntityQuery<MapGridComponent> _gridQuery;
+ private EntityQuery<TransformComponent> _xformQuery;
+
+ private ValueList<MapId> _mapIds = new();
+ private ValueList<(Box2Rotated Bounds, MapId MapId)> _gridBounds = new();
+
/// <inheritdoc/>
public override void Initialize()
{
_sawmill = _logManager.GetSawmill("station");
+ _gridQuery = GetEntityQuery<MapGridComponent>();
+ _xformQuery = GetEntityQuery<TransformComponent>();
+
SubscribeLocalEvent<GameRunLevelChangedEvent>(OnRoundEnd);
SubscribeLocalEvent<PostGameMapLoad>(OnPostGameMapLoad);
SubscribeLocalEvent<StationDataComponent, ComponentStartup>(OnStationAdd);
/// </summary>
public Filter GetInStation(StationDataComponent dataComponent, float range = 32f)
{
- // Could also use circles if you wanted.
- var bounds = new ValueList<Box2>(dataComponent.Grids.Count);
var filter = Filter.Empty();
- var mapIds = new ValueList<MapId>();
- var xformQuery = GetEntityQuery<TransformComponent>();
+ _mapIds.Clear();
+ // First collect all valid map IDs where station grids exist
foreach (var gridUid in dataComponent.Grids)
{
- if (!TryComp(gridUid, out MapGridComponent? grid) ||
- !xformQuery.TryGetComponent(gridUid, out var xform))
+ if (!_xformQuery.TryGetComponent(gridUid, out var xform))
continue;
var mapId = xform.MapID;
- var position = _transform.GetWorldPosition(xform, xformQuery);
- var bound = grid.LocalAABB.Enlarged(range).Translated(position);
+ if (!_mapIds.Contains(mapId))
+ _mapIds.Add(mapId);
+ }
+
+ // Cache the rotated bounds for each grid
+ _gridBounds.Clear();
- bounds.Add(bound);
- if (!mapIds.Contains(mapId))
+ foreach (var gridUid in dataComponent.Grids)
+ {
+ if (!_gridQuery.TryComp(gridUid, out var grid) ||
+ !_xformQuery.TryGetComponent(gridUid, out var gridXform))
{
- mapIds.Add(xform.MapID);
+ continue;
}
+
+ var (worldPos, worldRot) = _transform.GetWorldPositionRotation(gridXform);
+ var localBounds = grid.LocalAABB.Enlarged(range);
+
+ // Create a rotated box using the grid's transform
+ var rotatedBounds = new Box2Rotated(
+ localBounds,
+ worldRot,
+ worldPos);
+
+ _gridBounds.Add((rotatedBounds, gridXform.MapID));
}
foreach (var session in Filter.GetAllPlayers(_player))
{
var entity = session.AttachedEntity;
- if (entity == null || !xformQuery.TryGetComponent(entity, out var xform))
+ if (entity == null || !_xformQuery.TryGetComponent(entity, out var xform))
continue;
var mapId = xform.MapID;
- if (!mapIds.Contains(mapId))
+ if (!_mapIds.Contains(mapId))
continue;
- var position = _transform.GetWorldPosition(xform, xformQuery);
+ // Check if the player is directly on any station grid
+ var gridUid = xform.GridUid;
+ if (gridUid != null && dataComponent.Grids.Contains(gridUid.Value))
+ {
+ filter.AddPlayer(session);
+ continue;
+ }
+
+ // If not directly on a grid, check against cached rotated bounds
+ var position = _transform.GetWorldPosition(xform);
- foreach (var bound in bounds)
+ foreach (var (bounds, boundsMapId) in _gridBounds)
{
- if (!bound.Contains(position))
+ // Skip bounds on different maps
+ if (boundsMapId != mapId)
+ continue;
+
+ if (!bounds.Contains(position))
continue;
filter.AddPlayer(session);