mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-14 19:29:36 +01:00
Make map-grids set TransformComponent.GridUid (#4040)
This commit is contained in:
@@ -17,6 +17,7 @@ namespace Robust.Client.GameObjects
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<ClientAppearanceComponent, ComponentInit>(OnAppearanceInit);
|
||||
SubscribeLocalEvent<ClientAppearanceComponent, ComponentStartup>(OnAppearanceStartup);
|
||||
SubscribeLocalEvent<ClientAppearanceComponent, ComponentHandleState>(OnAppearanceHandleState);
|
||||
}
|
||||
|
||||
@@ -32,7 +33,10 @@ namespace Robust.Client.GameObjects
|
||||
{
|
||||
visual.InitializeEntity(uid);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnAppearanceStartup(EntityUid uid, ClientAppearanceComponent component, ComponentStartup args)
|
||||
{
|
||||
MarkDirty(component);
|
||||
}
|
||||
|
||||
@@ -103,10 +107,9 @@ namespace Robust.Client.GameObjects
|
||||
var metaQuery = GetEntityQuery<MetaDataComponent>();
|
||||
while (_queuedUpdates.TryDequeue(out var appearance))
|
||||
{
|
||||
if (appearance.Deleted)
|
||||
continue;
|
||||
|
||||
appearance.AppearanceDirty = false;
|
||||
if (!appearance.Running)
|
||||
continue;
|
||||
|
||||
// If the entity is no longer within the clients PVS, don't bother updating.
|
||||
if ((metaQuery.GetComponent(appearance.Owner).Flags & MetaDataFlags.Detached) != 0 && !appearance.UpdateDetached)
|
||||
|
||||
@@ -16,6 +16,7 @@ using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Physics;
|
||||
using Robust.Shared.Players;
|
||||
using Robust.Shared.Threading;
|
||||
using Robust.Shared.Timing;
|
||||
@@ -253,8 +254,8 @@ internal sealed partial class PVSSystem : EntitySystem
|
||||
private void OnEntityMove(ref MoveEvent ev)
|
||||
{
|
||||
// GriddUid is only set after init.
|
||||
if (ev.Component.LifeStage < ComponentLifeStage.Initialized && ev.Component.GridUid == null)
|
||||
_transform.SetGridId(ev.Component, ev.Component.FindGridEntityId(GetEntityQuery<TransformComponent>()));
|
||||
if (!ev.Component._gridInitialized)
|
||||
_transform.InitializeGridUid(ev.Sender, ev.Component, GetEntityQuery<TransformComponent>(), GetEntityQuery<MapGridComponent>());
|
||||
|
||||
// since elements are cached grid-/map-relative, we dont need to update a given grids/maps children
|
||||
if (ev.Component.GridUid == ev.Sender)
|
||||
|
||||
@@ -167,6 +167,9 @@ public abstract class ComponentTreeSystem<TTreeComp, TComp> : EntitySystem
|
||||
var (comp, xform) = entry;
|
||||
|
||||
comp.TreeUpdateQueued = false;
|
||||
if (!comp.Running)
|
||||
continue;
|
||||
|
||||
if (!_updated.Add(comp.Owner))
|
||||
continue;
|
||||
|
||||
|
||||
@@ -43,6 +43,8 @@ internal sealed class RecursiveMoveSystem : EntitySystem
|
||||
TransformComponent xform,
|
||||
EntityQuery<TransformComponent> xformQuery)
|
||||
{
|
||||
// TODO maybe use a c# event? This event gets raised a lot.
|
||||
// Would probably help with server performance and is also the main bottleneck for replay scrubbing.
|
||||
var ev = new TreeRecursiveMoveEvent(xform);
|
||||
RaiseLocalEvent(uid, ref ev);
|
||||
|
||||
|
||||
@@ -94,6 +94,7 @@ namespace Robust.Shared.GameObjects
|
||||
public MapId MapID { get; internal set; }
|
||||
|
||||
internal bool _mapIdInitialized;
|
||||
internal bool _gridInitialized;
|
||||
|
||||
// TODO: Cache this.
|
||||
/// <summary>
|
||||
@@ -393,30 +394,6 @@ namespace Robust.Shared.GameObjects
|
||||
|
||||
[ViewVariables] internal EntityUid LerpParent { get; set; }
|
||||
|
||||
internal EntityUid? FindGridEntityId(EntityQuery<TransformComponent> xformQuery)
|
||||
{
|
||||
if (_entMan.HasComponent<MapComponent>(Owner))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (_entMan.HasComponent<MapGridComponent>(Owner))
|
||||
{
|
||||
return Owner;
|
||||
}
|
||||
|
||||
if (_parent.IsValid())
|
||||
{
|
||||
var parentXform = xformQuery.GetComponent(_parent);
|
||||
if (parentXform.GridUid != null || parentXform.LifeStage >= ComponentLifeStage.Initialized)
|
||||
return parentXform.GridUid;
|
||||
else
|
||||
return parentXform.FindGridEntityId(xformQuery);
|
||||
}
|
||||
|
||||
return _mapManager.TryFindGridAt(MapID, WorldPosition, out var mapgrid) ? mapgrid.Owner : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Detaches this entity from its parent.
|
||||
/// </summary>
|
||||
|
||||
@@ -92,11 +92,17 @@ namespace Robust.Shared.GameObjects
|
||||
SubscribeLocalEvent<MoveEvent>(OnMove);
|
||||
|
||||
SubscribeLocalEvent<TransformComponent, PhysicsBodyTypeChangedEvent>(OnBodyTypeChange);
|
||||
SubscribeLocalEvent<PhysicsComponent, ComponentStartup>(OnBodyStartup);
|
||||
SubscribeLocalEvent<CollisionChangeEvent>(OnPhysicsUpdate);
|
||||
|
||||
EntityManager.EntityInitialized += OnEntityInit;
|
||||
}
|
||||
|
||||
private void OnBodyStartup(EntityUid uid, PhysicsComponent component, ComponentStartup args)
|
||||
{
|
||||
UpdatePhysicsBroadphase(uid, Transform(uid), component);
|
||||
}
|
||||
|
||||
public override void Shutdown()
|
||||
{
|
||||
base.Shutdown();
|
||||
@@ -253,6 +259,7 @@ namespace Robust.Shared.GameObjects
|
||||
// ensure that the cached broadphase is correct.
|
||||
DebugTools.Assert(_timing.ApplyingState
|
||||
|| xform.Broadphase == null
|
||||
|| ev.Body.LifeStage <= ComponentLifeStage.Initializing
|
||||
|| !xform.Broadphase.Value.IsValid()
|
||||
|| ((xform.Broadphase.Value.CanCollide == ev.Body.CanCollide)
|
||||
&& (xform.Broadphase.Value.Static == (ev.Body.BodyType == BodyType.Static))));
|
||||
@@ -269,6 +276,9 @@ namespace Robust.Shared.GameObjects
|
||||
|
||||
private void UpdatePhysicsBroadphase(EntityUid uid, TransformComponent xform, PhysicsComponent body)
|
||||
{
|
||||
if (body.LifeStage <= ComponentLifeStage.Initializing)
|
||||
return;
|
||||
|
||||
if (xform.GridUid == uid)
|
||||
return;
|
||||
DebugTools.Assert(!_mapManager.IsGrid(uid));
|
||||
|
||||
@@ -289,7 +289,6 @@ public abstract partial class SharedMapSystem
|
||||
|
||||
private void OnGridAdd(EntityUid uid, MapGridComponent component, ComponentAdd args)
|
||||
{
|
||||
// GridID is not set yet so we don't include it.
|
||||
var msg = new GridAddEvent(uid);
|
||||
RaiseLocalEvent(uid, msg, true);
|
||||
}
|
||||
@@ -310,23 +309,8 @@ public abstract partial class SharedMapSystem
|
||||
|
||||
component.LastTileModifiedTick = curTick;
|
||||
|
||||
var mapId = xform.MapID;
|
||||
|
||||
if (MapManager.HasMapEntity(mapId))
|
||||
{
|
||||
var mapUid = MapManager.GetMapEntityIdOrThrow(mapId);
|
||||
|
||||
// Mapgrid moment
|
||||
if (mapUid != uid)
|
||||
_transform.SetParent(uid, xform, MapManager.GetMapEntityIdOrThrow(mapId), xformQuery);
|
||||
|
||||
_transform.SetGridIdNoRecursive(xform, uid);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just in case.
|
||||
_transform.SetGridId(xform, uid, xformQuery);
|
||||
}
|
||||
if (xform.MapUid != null && xform.MapUid != uid)
|
||||
_transform.SetParent(uid, xform, xform.MapUid.Value, xformQuery);
|
||||
|
||||
var msg = new GridInitializeEvent(uid);
|
||||
RaiseLocalEvent(uid, msg, true);
|
||||
|
||||
@@ -46,7 +46,7 @@ public abstract partial class SharedTransformSystem
|
||||
xform._parent = newGridUid;
|
||||
xform._anchored = true;
|
||||
|
||||
SetGridId(xform, newGridUid, xformQuery);
|
||||
SetGridId(uid, xform, newGridUid, xformQuery);
|
||||
var reParent = new EntParentChangedMessage(uid, oldGridUid, xform.MapID, xform);
|
||||
RaiseLocalEvent(uid, ref reParent, true);
|
||||
// TODO: Ideally shouldn't need to call the moveevent
|
||||
@@ -241,7 +241,7 @@ public abstract partial class SharedTransformSystem
|
||||
// Has to be done if _parent is set from ExposeData.
|
||||
if (component.ParentUid.IsValid())
|
||||
{
|
||||
// Note that _children is a SortedSet<EntityUid>,
|
||||
// Note that _children is a HashSet<EntityUid>,
|
||||
// so duplicate additions (which will happen) don't matter.
|
||||
|
||||
var parentXform = xformQuery.GetComponent(component.ParentUid);
|
||||
@@ -259,14 +259,14 @@ public abstract partial class SharedTransformSystem
|
||||
parentXform._children.Add(uid);
|
||||
}
|
||||
|
||||
if (component.GridUid == null)
|
||||
SetGridId(component, component.FindGridEntityId(xformQuery));
|
||||
|
||||
InitializeGridUid(uid, component, xformQuery, GetEntityQuery<MapGridComponent>());
|
||||
component.MatricesDirty = true;
|
||||
|
||||
DebugTools.Assert(component._gridUid == uid || !HasComp<MapGridComponent>(uid));
|
||||
if (!component._anchored)
|
||||
return;
|
||||
|
||||
DebugTools.Assert(component.ParentUid == component.GridUid && component.ParentUid.IsValid());
|
||||
MapGridComponent? grid;
|
||||
|
||||
// First try find grid via parent:
|
||||
@@ -292,6 +292,32 @@ public abstract partial class SharedTransformSystem
|
||||
component._anchored = false;
|
||||
}
|
||||
|
||||
internal void InitializeGridUid(
|
||||
EntityUid uid,
|
||||
TransformComponent xform,
|
||||
EntityQuery<TransformComponent> xformQuery,
|
||||
EntityQuery<MapGridComponent> gridQuery)
|
||||
{
|
||||
// Dont set pre-init, as the map grid component might not have been added yet.
|
||||
if (xform._gridInitialized || xform.LifeStage < ComponentLifeStage.Initializing)
|
||||
return;
|
||||
|
||||
xform._gridInitialized = true;
|
||||
DebugTools.Assert(xform.GridUid == null);
|
||||
if (gridQuery.HasComponent(uid))
|
||||
{
|
||||
xform._gridUid = uid;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!xform._parent.IsValid())
|
||||
return;
|
||||
|
||||
var parentXform = xformQuery.GetComponent(xform._parent);
|
||||
InitializeGridUid(xform._parent, parentXform, xformQuery, gridQuery);
|
||||
xform._gridUid = parentXform._gridUid;
|
||||
}
|
||||
|
||||
private void OnCompStartup(EntityUid uid, TransformComponent xform, ComponentStartup args)
|
||||
{
|
||||
// TODO PERFORMANCE remove AnchorStateChangedEvent and EntParentChangedMessage events here.
|
||||
@@ -324,38 +350,43 @@ public abstract partial class SharedTransformSystem
|
||||
/// <summary>
|
||||
/// Sets the <see cref="GridId"/> for the transformcomponent without updating its children. Does not Dirty it.
|
||||
/// </summary>
|
||||
internal void SetGridIdNoRecursive(TransformComponent xform, EntityUid? gridUid)
|
||||
internal void SetGridIdNoRecursive(EntityUid uid, TransformComponent xform, EntityUid? gridUid)
|
||||
{
|
||||
DebugTools.Assert(gridUid == uid || !HasComp<MapGridComponent>(uid));
|
||||
if (xform._gridUid == gridUid)
|
||||
return;
|
||||
|
||||
DebugTools.Assert(gridUid == null || HasComp<MapGridComponent>(gridUid));
|
||||
|
||||
xform._gridUid = gridUid;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="GridId"/> for the transformcomponent. Does not Dirty it.
|
||||
/// </summary>
|
||||
public void SetGridId(TransformComponent xform, EntityUid? gridId, EntityQuery<TransformComponent>? xformQuery = null)
|
||||
public void SetGridId(EntityUid uid, TransformComponent xform, EntityUid? gridId, EntityQuery<TransformComponent>? xformQuery = null)
|
||||
{
|
||||
if (xform._gridUid == gridId)
|
||||
if (!xform._gridInitialized || xform._gridUid == gridId || xform.GridUid == uid)
|
||||
return;
|
||||
|
||||
DebugTools.Assert(!HasComp<MapGridComponent>(uid));
|
||||
DebugTools.Assert(gridId == null || HasComp<MapGridComponent>(gridId));
|
||||
|
||||
xformQuery ??= GetEntityQuery<TransformComponent>();
|
||||
SetGridIdRecursive(xform, gridId, xformQuery.Value);
|
||||
SetGridIdRecursive(uid, xform, gridId, xformQuery.Value);
|
||||
}
|
||||
|
||||
private static void SetGridIdRecursive(TransformComponent xform, EntityUid? gridId, EntityQuery<TransformComponent> xformQuery)
|
||||
private void SetGridIdRecursive(EntityUid uid, TransformComponent xform, EntityUid? gridId, EntityQuery<TransformComponent> xformQuery)
|
||||
{
|
||||
if (!xform._gridInitialized || xform._gridUid == gridId || xform.GridUid == uid)
|
||||
return;
|
||||
|
||||
DebugTools.Assert(!HasComp<MapGridComponent>(uid));
|
||||
xform._gridUid = gridId;
|
||||
var childEnumerator = xform.ChildEnumerator;
|
||||
|
||||
while (childEnumerator.MoveNext(out var child))
|
||||
{
|
||||
SetGridIdRecursive(xformQuery.GetComponent(child.Value), gridId, xformQuery);
|
||||
SetGridIdRecursive(child.Value, xformQuery.GetComponent(child.Value), gridId, xformQuery);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,6 +504,7 @@ public abstract partial class SharedTransformSystem
|
||||
throw new InvalidOperationException($"Attempted to re-parent to a terminating object. Entity: {ToPrettyString(uid)}, new parent: {ToPrettyString(value.EntityId)}");
|
||||
}
|
||||
|
||||
// Check for recursive/circular transform hierarchies.
|
||||
if (xform.MapUid == newParent.MapUid)
|
||||
{
|
||||
var recursiveUid = value.EntityId;
|
||||
@@ -511,14 +543,23 @@ public abstract partial class SharedTransformSystem
|
||||
if (newParent != null)
|
||||
{
|
||||
xform.ChangeMapId(newParent.MapID, xformQuery);
|
||||
if (xform.GridUid != uid)
|
||||
SetGridId(xform, xform.FindGridEntityId(xformQuery), xformQuery);
|
||||
|
||||
if (!xform._gridInitialized)
|
||||
InitializeGridUid(uid, xform, xformQuery, GetEntityQuery<MapGridComponent>());
|
||||
else
|
||||
{
|
||||
if (!newParent._gridInitialized)
|
||||
InitializeGridUid(value.EntityId, newParent, xformQuery, GetEntityQuery<MapGridComponent>());
|
||||
SetGridId(uid, xform, newParent.GridUid);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xform.ChangeMapId(MapId.Nullspace, xformQuery);
|
||||
if (xform.GridUid != uid)
|
||||
SetGridId(xform, null, xformQuery);
|
||||
if (!xform._gridInitialized)
|
||||
InitializeGridUid(uid, xform, xformQuery, GetEntityQuery<MapGridComponent>());
|
||||
else
|
||||
SetGridId(uid, xform, null, xformQuery);
|
||||
}
|
||||
|
||||
if (xform.Initialized)
|
||||
@@ -1303,4 +1344,15 @@ public abstract partial class SharedTransformSystem
|
||||
DebugTools.Assert((MetaData(uid).Flags & MetaDataFlags.InContainer) == 0x0);
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void OnGridAdd(EntityUid uid, TransformComponent component, GridAddEvent args)
|
||||
{
|
||||
if (LifeStage(uid) > EntityLifeStage.Initialized)
|
||||
{
|
||||
SetGridId(uid, component, uid, GetEntityQuery<TransformComponent>());
|
||||
return;
|
||||
}
|
||||
component._gridInitialized = true;
|
||||
component._gridUid = uid;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ namespace Robust.Shared.GameObjects
|
||||
SubscribeLocalEvent<TransformComponent, ComponentStartup>(OnCompStartup);
|
||||
SubscribeLocalEvent<TransformComponent, ComponentGetState>(OnGetState);
|
||||
SubscribeLocalEvent<TransformComponent, ComponentHandleState>(OnHandleState);
|
||||
SubscribeLocalEvent<TransformComponent, GridAddEvent>(OnGridAdd);
|
||||
SubscribeLocalEvent<EntParentChangedMessage>(OnParentChange);
|
||||
}
|
||||
|
||||
@@ -145,8 +146,8 @@ namespace Robust.Shared.GameObjects
|
||||
return xform.Coordinates;
|
||||
|
||||
// GriddUid is only set after init.
|
||||
if (xform.LifeStage < ComponentLifeStage.Initialized && xform.GridUid == null)
|
||||
SetGridId(xform, xform.FindGridEntityId(xformQuery));
|
||||
if (!xform._gridInitialized)
|
||||
InitializeGridUid(xform.Owner, xform, xformQuery, GetEntityQuery<MapGridComponent>());
|
||||
|
||||
// Is the entity directly parented to the grid?
|
||||
if (xform.GridUid == xform.ParentUid)
|
||||
@@ -176,8 +177,8 @@ namespace Robust.Shared.GameObjects
|
||||
var parentXform = xformQuery.GetComponent(parentUid);
|
||||
|
||||
// GriddUid is only set after init.
|
||||
if (parentXform.LifeStage < ComponentLifeStage.Initialized && parentXform.GridUid == null)
|
||||
SetGridId(parentXform, parentXform.FindGridEntityId(xformQuery));
|
||||
if (!parentXform._gridInitialized)
|
||||
InitializeGridUid(parentUid, parentXform, xformQuery, GetEntityQuery<MapGridComponent>());
|
||||
|
||||
// Is the entity directly parented to the grid?
|
||||
if (parentXform.GridUid == parentUid)
|
||||
@@ -208,8 +209,8 @@ namespace Robust.Shared.GameObjects
|
||||
return (xform.Coordinates, xform.LocalRotation);
|
||||
|
||||
// GriddUid is only set after init.
|
||||
if (xform.LifeStage < ComponentLifeStage.Initialized && xform.GridUid == null)
|
||||
SetGridId(xform, xform.FindGridEntityId(xformQuery));
|
||||
if (!xform._gridInitialized)
|
||||
InitializeGridUid(xform.Owner, xform, xformQuery, GetEntityQuery<MapGridComponent>());
|
||||
|
||||
// Is the entity directly parented to the grid?
|
||||
if (xform.GridUid == xform.ParentUid)
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map.Components;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Physics;
|
||||
@@ -16,6 +14,7 @@ internal partial class MapManager
|
||||
{
|
||||
public IEnumerable<MapGridComponent> FindGridsIntersecting(MapId mapId, Box2Rotated bounds, bool approx = false)
|
||||
{
|
||||
DebugTools.Assert(mapId != MapId.Nullspace);
|
||||
var aabb = bounds.CalcBoundingBox();
|
||||
// TODO: We can do slower GJK checks to check if 2 bounds actually intersect, but WYCI.
|
||||
return FindGridsIntersecting(mapId, aabb, approx);
|
||||
@@ -23,6 +22,7 @@ internal partial class MapManager
|
||||
|
||||
public void FindGridsIntersectingApprox(MapId mapId, Box2 worldAABB, GridCallback callback)
|
||||
{
|
||||
DebugTools.Assert(mapId != MapId.Nullspace);
|
||||
if (!_gridTrees.TryGetValue(mapId, out var gridTree))
|
||||
return;
|
||||
|
||||
@@ -46,6 +46,7 @@ internal partial class MapManager
|
||||
|
||||
public void FindGridsIntersectingApprox<TState>(MapId mapId, Box2 worldAABB, ref TState state, GridCallback<TState> callback)
|
||||
{
|
||||
DebugTools.Assert(mapId != MapId.Nullspace);
|
||||
if (!_gridTrees.TryGetValue(mapId, out var gridTree))
|
||||
return;
|
||||
|
||||
@@ -71,6 +72,7 @@ internal partial class MapManager
|
||||
|
||||
public IEnumerable<MapGridComponent> FindGridsIntersecting(MapId mapId, Box2 worldAabb, bool approx = false)
|
||||
{
|
||||
DebugTools.Assert(mapId != MapId.Nullspace);
|
||||
if (!_gridTrees.ContainsKey(mapId)) return Enumerable.Empty<MapGridComponent>();
|
||||
|
||||
var xformQuery = EntityManager.GetEntityQuery<TransformComponent>();
|
||||
@@ -89,6 +91,7 @@ internal partial class MapManager
|
||||
EntityQuery<PhysicsComponent> physicsQuery,
|
||||
bool approx = false)
|
||||
{
|
||||
DebugTools.Assert(mapId != MapId.Nullspace);
|
||||
if (!_gridTrees.TryGetValue(mapId, out var gridTree)) return Enumerable.Empty<MapGridComponent>();
|
||||
|
||||
DebugTools.Assert(grids.Count == 0);
|
||||
@@ -161,6 +164,7 @@ internal partial class MapManager
|
||||
EntityQuery<TransformComponent> xformQuery,
|
||||
[NotNullWhen(true)] out MapGridComponent? grid)
|
||||
{
|
||||
DebugTools.Assert(mapId != MapId.Nullspace);
|
||||
// Need to enlarge the AABB by at least the grid shrinkage size.
|
||||
var aabb = new Box2(worldPos - 0.2f, worldPos + 0.2f);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user