private readonly HashSet<EntityUid> _lookupEnts = new();
private readonly HashSet<EntityUid> _immuneEnts = new();
+ private readonly HashSet<Entity<NoFTLComponent>> _noFtls = new();
private EntityQuery<BodyComponent> _bodyQuery;
private EntityQuery<BuckleComponent> _buckleQuery;
- private EntityQuery<FTLBeaconComponent> _beaconQuery;
- private EntityQuery<GhostComponent> _ghostQuery;
+ private EntityQuery<FTLSmashImmuneComponent> _immuneQuery;
private EntityQuery<PhysicsComponent> _physicsQuery;
private EntityQuery<StatusEffectsComponent> _statusQuery;
private EntityQuery<TransformComponent> _xformQuery;
_bodyQuery = GetEntityQuery<BodyComponent>();
_buckleQuery = GetEntityQuery<BuckleComponent>();
- _beaconQuery = GetEntityQuery<FTLBeaconComponent>();
- _ghostQuery = GetEntityQuery<GhostComponent>();
+ _immuneQuery = GetEntityQuery<FTLSmashImmuneComponent>();
_physicsQuery = GetEntityQuery<PhysicsComponent>();
_statusQuery = GetEntityQuery<StatusEffectsComponent>();
_xformQuery = GetEntityQuery<TransformComponent>();
private void OnFtlShutdown(Entity<FTLComponent> ent, ref ComponentShutdown args)
{
- Del(ent.Comp.VisualizerEntity);
+ QueueDel(ent.Comp.VisualizerEntity);
ent.Comp.VisualizerEntity = null;
}
// Offset the start by buffer range just to avoid overlap.
var ftlStart = new EntityCoordinates(ftlMap, new Vector2(_index + width / 2f, 0f) - shuttleCenter);
+ // Store the matrix for the grid prior to movement. This means any entities we need to leave behind we can make sure their positions are updated.
+ // Setting the entity to map directly may run grid traversal (at least at time of writing this).
+ var oldMapUid = xform.MapUid;
+ var oldGridMatrix = _transform.GetWorldMatrix(xform);
_transform.SetCoordinates(entity.Owner, ftlStart);
+ LeaveNoFTLBehind((entity.Owner, xform), oldGridMatrix, oldMapUid);
// Reset rotation so they always face the same direction.
xform.LocalRotation = Angle.Zero;
MapId mapId;
+ QueueDel(entity.Comp1.VisualizerEntity);
+ entity.Comp1.VisualizerEntity = null;
+
if (!Exists(entity.Comp1.TargetCoordinates.EntityId))
{
// Uhh good luck
}
}
+ private void LeaveNoFTLBehind(Entity<TransformComponent> grid, Matrix3x2 oldGridMatrix, EntityUid? oldMapUid)
+ {
+ if (oldMapUid == null)
+ return;
+
+ _noFtls.Clear();
+ var oldGridRotation = oldGridMatrix.Rotation();
+ _lookup.GetGridEntities(grid.Owner, _noFtls);
+
+ foreach (var childUid in _noFtls)
+ {
+ if (!_xformQuery.TryComp(childUid, out var childXform))
+ continue;
+
+ // If we're not parented directly to the grid the matrix may be wrong.
+ var relative = _physics.GetRelativePhysicsTransform(childUid.Owner, (grid.Owner, grid.Comp));
+
+ _transform.SetCoordinates(
+ childUid,
+ childXform,
+ new EntityCoordinates(oldMapUid.Value,
+ Vector2.Transform(relative.Position, oldGridMatrix)), rotation: relative.Quaternion2D.Angle + oldGridRotation);
+ }
+ }
+
private void KnockOverKids(TransformComponent xform, ref ValueList<EntityUid> toKnock)
{
// Not recursive because probably not necessary? If we need it to be that's why this method is separate.
_biomes.ReserveTiles(xform.MapUid.Value, aabb, tileSet);
_lookupEnts.Clear();
_immuneEnts.Clear();
- _lookup.GetEntitiesIntersecting(xform.MapUid.Value, aabb, _lookupEnts, LookupFlags.Uncontained);
+ // TODO: Ideally we'd query first BEFORE moving grid but needs adjustments above.
+ _lookup.GetEntitiesIntersecting(xform.MapID, fixture.Shape, transform, _lookupEnts, LookupFlags.Uncontained);
foreach (var ent in _lookupEnts)
{
continue;
}
- if (_ghostQuery.HasComponent(ent) || _beaconQuery.HasComponent(ent))
+ // If it's on our grid ignore it.
+ if (!_xformQuery.TryComp(ent, out var childXform) || childXform.GridUid == uid)
+ {
+ continue;
+ }
+
+ if (_immuneQuery.HasComponent(ent))
{
continue;
}
continue;
}
- if (HasComp<FTLBeaconComponent>(ent))
- continue;
-
QueueDel(ent);
}
}