mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
* Try fix invalid PVS index bug * bounds check * More Asserts * fix assert? * remove deletion * a * A!
118 lines
3.6 KiB
C#
118 lines
3.6 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using Robust.Shared.GameObjects;
|
|
using Robust.Shared.Map.Components;
|
|
using Robust.Shared.Utility;
|
|
|
|
namespace Robust.Server.GameStates;
|
|
|
|
// Partial class for handling entity events (move, deletion, etc)
|
|
internal sealed partial class PvsSystem
|
|
{
|
|
private void OnEntityMove(ref MoveEvent ev)
|
|
{
|
|
UpdatePosition(ev.Entity.Owner, ev.Entity.Comp1, ev.Entity.Comp2, ev.OldPosition.EntityId);
|
|
}
|
|
|
|
private void OnTransformStartup(EntityUid uid, TransformComponent component, ref TransformStartupEvent args)
|
|
{
|
|
if (component.ParentUid == EntityUid.Invalid)
|
|
return;
|
|
|
|
UpdatePosition(uid, component, MetaData(uid), EntityUid.Invalid);
|
|
}
|
|
|
|
private void OnEntityTerminating(ref EntityTerminatingEvent ev)
|
|
{
|
|
var meta = ev.Entity.Comp;
|
|
|
|
_deletedEntities.Add(meta.NetEntity);
|
|
_deletedTick.Add(_gameTiming.CurTick);
|
|
RemoveEntityFromChunk(ev.Entity.Owner, meta);
|
|
}
|
|
|
|
private void UpdatePosition(EntityUid uid, TransformComponent xform, MetaDataComponent meta, EntityUid oldParent)
|
|
{
|
|
if (meta.EntityLifeStage >= EntityLifeStage.Terminating)
|
|
{
|
|
DebugTools.AssertNull(meta.LastPvsLocation);
|
|
return;
|
|
}
|
|
|
|
// GridUid is only set after init.
|
|
if (!xform._gridInitialized)
|
|
_transform.InitializeGridUid(uid, xform);
|
|
|
|
if (xform.GridUid == uid)
|
|
return;
|
|
|
|
DebugTools.Assert(!HasComp<MapGridComponent>(uid));
|
|
DebugTools.Assert(!HasComp<MapComponent>(uid));
|
|
|
|
if (oldParent != xform.ParentUid)
|
|
{
|
|
HandleParentChange(uid, xform, meta);
|
|
return;
|
|
}
|
|
|
|
if (xform.ParentUid != xform.GridUid && xform.ParentUid != xform.MapUid)
|
|
return;
|
|
|
|
var location = new PvsChunkLocation(xform.ParentUid, GetChunkIndices(xform._localPosition));
|
|
if (meta.LastPvsLocation == location)
|
|
return;
|
|
|
|
RemoveEntityFromChunk(uid, meta);
|
|
AddEntityToChunk(uid, meta, location);
|
|
}
|
|
|
|
private void HandleParentChange(EntityUid uid, TransformComponent xform, MetaDataComponent meta)
|
|
{
|
|
RemoveEntityFromChunk(uid, meta);
|
|
|
|
// moving to null space?
|
|
if (xform.ParentUid == EntityUid.Invalid || xform.ParentUid == uid)
|
|
return;
|
|
|
|
var newRoot = (xform.GridUid ?? xform.MapUid);
|
|
if (newRoot == null)
|
|
{
|
|
AssertNullspace(xform.ParentUid);
|
|
return;
|
|
}
|
|
|
|
// If directly parented to the chunk, add as a direct child.
|
|
if (xform.ParentUid == newRoot)
|
|
{
|
|
var location = new PvsChunkLocation(newRoot.Value, GetChunkIndices(xform._localPosition));
|
|
AddEntityToChunk(uid, meta, location);
|
|
return;
|
|
}
|
|
|
|
// Else, mark the new parent's last chunk as dirty. Null implies it is already dirty.
|
|
if (MetaData(xform.ParentUid).LastPvsLocation is { } loc)
|
|
DirtyChunk(loc);
|
|
}
|
|
|
|
[Conditional("DEBUG")]
|
|
private void AssertNullspace(EntityUid uid)
|
|
{
|
|
if (uid == EntityUid.Invalid || !_xformQuery.TryGetComponent(uid, out var xform))
|
|
return;
|
|
|
|
DebugTools.AssertNull(xform.GridUid);
|
|
DebugTools.AssertNull(xform.MapUid);
|
|
AssertNullspace(xform.ParentUid);
|
|
}
|
|
|
|
internal void SyncMetadata(MetaDataComponent meta)
|
|
{
|
|
if (meta.PvsData == PvsIndex.Invalid)
|
|
return;
|
|
|
|
ref var ptr = ref _metadataMemory.GetRef(meta.PvsData.Index);
|
|
ptr.VisMask = meta.VisibilityMask;
|
|
ptr.LifeStage = meta.EntityLifeStage;
|
|
}
|
|
}
|