Stop caching connected tubes and discover them on each step (#1554)

This commit is contained in:
DrSmugleaf
2020-08-01 03:45:40 +02:00
committed by GitHub
parent bf30a68a5e
commit 9277ed5248
7 changed files with 50 additions and 151 deletions

View File

@@ -1,5 +1,4 @@
using System.Collections.Generic; using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Maths; using Robust.Shared.Maths;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
@@ -26,13 +25,13 @@ namespace Content.Server.GameObjects.Components.Disposal
var directions = ConnectableDirections(); var directions = ConnectableDirections();
var previousTube = holder.PreviousTube; var previousTube = holder.PreviousTube;
if (previousTube == null || !Connected.ContainsValue(previousTube)) if (previousTube == null)
{ {
return directions[0]; return directions[0];
} }
var first = Connected.GetValueOrDefault(directions[0]); var previousDirection = DirectionTo(previousTube);
return previousTube == first ? directions[1] : directions[0]; return previousDirection == directions[0] ? directions[1] : directions[0];
} }
public override void ExposeData(ObjectSerializer serializer) public override void ExposeData(ObjectSerializer serializer)

View File

@@ -26,7 +26,7 @@ namespace Content.Server.GameObjects.Components.Disposal
return TryInsert(holderComponent); return TryInsert(holderComponent);
} }
public bool TryInsert(DisposalHolderComponent holder) private bool TryInsert(DisposalHolderComponent holder)
{ {
if (!Contents.Insert(holder.Owner)) if (!Contents.Insert(holder.Owner))
{ {

View File

@@ -35,16 +35,16 @@ namespace Content.Server.GameObjects.Components.Disposal
public override Direction NextDirection(DisposalHolderComponent holder) public override Direction NextDirection(DisposalHolderComponent holder)
{ {
var next = Owner.Transform.LocalRotation; var next = Owner.Transform.LocalRotation.GetDir();
var directions = ConnectableDirections().Skip(1).ToArray(); var directions = ConnectableDirections().Skip(1).ToArray();
if (Connected.TryGetValue(next.GetDir(), out var forwardTube) && if (holder.PreviousTube == null ||
holder.PreviousTube == forwardTube) DirectionTo(holder.PreviousTube) == next)
{ {
return _random.Pick(directions); return _random.Pick(directions);
} }
return next.GetDir(); return next;
} }
public override void ExposeData(ObjectSerializer serializer) public override void ExposeData(ObjectSerializer serializer)

View File

@@ -1,5 +1,4 @@
using System; using System;
using System.Collections.Generic;
using Robust.Shared.GameObjects; using Robust.Shared.GameObjects;
using Robust.Shared.Maths; using Robust.Shared.Maths;
@@ -25,14 +24,14 @@ namespace Content.Server.GameObjects.Components.Disposal
var directions = ConnectableDirections(); var directions = ConnectableDirections();
var previousTube = holder.PreviousTube; var previousTube = holder.PreviousTube;
var forward = directions[0]; var forward = directions[0];
if (previousTube == null || !Connected.ContainsValue(previousTube))
if (previousTube == null)
{ {
return forward; return forward;
} }
var forwardTube = Connected.GetValueOrDefault(forward);
var backward = directions[1]; var backward = directions[1];
return previousTube == forwardTube ? backward : forward; return DirectionTo(previousTube) == forward ? backward : forward;
} }
} }
} }

View File

@@ -1,5 +1,5 @@
using System; #nullable enable
using System.Collections.Generic; using System;
using System.Linq; using System.Linq;
using Content.Server.Interfaces.GameObjects.Components.Interaction; using Content.Server.Interfaces.GameObjects.Components.Interaction;
using Content.Shared.GameObjects; using Content.Shared.GameObjects;
@@ -34,20 +34,13 @@ namespace Content.Server.GameObjects.Components.Disposal
private bool _connected; private bool _connected;
private bool _broken; private bool _broken;
private string _clangSound; private string _clangSound = default!;
/// <summary> /// <summary>
/// Container of entities that are currently inside this tube /// Container of entities that are currently inside this tube
/// </summary> /// </summary>
[ViewVariables] [ViewVariables]
public Container Contents { get; private set; } public Container Contents { get; private set; } = default!;
/// <summary>
/// Dictionary of tubes connecting to this one mapped by their direction
/// </summary>
[ViewVariables]
protected Dictionary<Direction, IDisposalTubeComponent> Connected { get; } =
new Dictionary<Direction, IDisposalTubeComponent>();
[ViewVariables] [ViewVariables]
private bool Anchored => private bool Anchored =>
@@ -67,10 +60,32 @@ namespace Content.Server.GameObjects.Components.Disposal
return NextDirection(holder).ToVec(); return NextDirection(holder).ToVec();
} }
public IDisposalTubeComponent NextTube(DisposalHolderComponent holder) protected Direction DirectionTo(IDisposalTubeComponent other)
{
return (other.Owner.Transform.WorldPosition - Owner.Transform.WorldPosition).GetDir();
}
public IDisposalTubeComponent? NextTube(DisposalHolderComponent holder)
{ {
var nextDirection = NextDirection(holder); var nextDirection = NextDirection(holder);
return Connected.GetValueOrDefault(nextDirection); var snapGrid = Owner.GetComponent<SnapGridComponent>();
var tube = snapGrid
.GetInDir(nextDirection)
.Select(x => x.TryGetComponent(out IDisposalTubeComponent c) ? c : null)
.FirstOrDefault(x => x != null && x != this);
if (tube == null)
{
return null;
}
var oppositeDirection = new Angle(nextDirection.ToAngle().Theta + Math.PI).GetDir();
if (!tube.CanConnect(oppositeDirection, this))
{
return null;
}
return tube;
} }
public bool Remove(DisposalHolderComponent holder) public bool Remove(DisposalHolderComponent holder)
@@ -105,45 +120,25 @@ namespace Content.Server.GameObjects.Components.Disposal
} }
_connected = true; _connected = true;
var snapGrid = Owner.GetComponent<SnapGridComponent>();
foreach (var direction in ConnectableDirections())
{
var tube = snapGrid
.GetInDir(direction)
.Select(x => x.TryGetComponent(out IDisposalTubeComponent c) ? c : null)
.FirstOrDefault(x => x != null && x != this);
if (tube == null)
{
continue;
}
var oppositeDirection = new Angle(direction.ToAngle().Theta + Math.PI).GetDir();
if (!tube.AdjacentConnected(oppositeDirection, this))
{
continue;
}
Connected.Add(direction, tube);
}
} }
public bool AdjacentConnected(Direction direction, IDisposalTubeComponent tube) public bool CanConnect(Direction direction, IDisposalTubeComponent with)
{ {
if (!_connected)
{
return false;
}
if (_broken) if (_broken)
{ {
return false; return false;
} }
if (Connected.ContainsKey(direction) || if (!ConnectableDirections().Contains(direction))
!ConnectableDirections().Contains(direction))
{ {
return false; return false;
} }
Connected.Add(direction, tube);
return true; return true;
} }
@@ -165,64 +160,6 @@ namespace Content.Server.GameObjects.Components.Disposal
holder.ExitDisposals(); holder.ExitDisposals();
} }
foreach (var connected in Connected.Values)
{
connected.AdjacentDisconnected(this);
}
Connected.Clear();
}
public void AdjacentDisconnected(IDisposalTubeComponent adjacent)
{
foreach (var pair in Connected)
{
foreach (var entity in Contents.ContainedEntities)
{
if (!entity.TryGetComponent(out DisposalHolderComponent holder))
{
continue;
}
if (holder.PreviousTube == adjacent)
{
holder.PreviousTube = null;
}
if (holder.NextTube == adjacent)
{
holder.NextTube = null;
}
}
if (pair.Value == adjacent)
{
Connected.Remove(pair.Key);
}
}
}
public void MoveEvent(MoveEvent moveEvent)
{
if (!_connected)
{
return;
}
foreach (var tube in Connected.Values)
{
var distance = (tube.Owner.Transform.WorldPosition - Owner.Transform.WorldPosition).Length;
// Disconnect distance threshold
if (distance < 1.25)
{
continue;
}
AdjacentDisconnected(tube);
tube.AdjacentDisconnected(this);
}
} }
public void PopupDirections(IEntity entity) public void PopupDirections(IEntity entity)
@@ -299,7 +236,7 @@ namespace Content.Server.GameObjects.Components.Disposal
{ {
base.Startup(); base.Startup();
if (!Owner.GetComponent<CollidableComponent>().Anchored) if (!Owner.EnsureComponent<CollidableComponent>().Anchored)
{ {
return; return;
} }
@@ -318,7 +255,7 @@ namespace Content.Server.GameObjects.Components.Disposal
Disconnect(); Disconnect();
} }
public override void HandleMessage(ComponentMessage message, IComponent component) public override void HandleMessage(ComponentMessage message, IComponent? component)
{ {
base.HandleMessage(message, component); base.HandleMessage(message, component);

View File

@@ -1,6 +1,5 @@
#nullable enable #nullable enable
using Robust.Server.GameObjects.Components.Container; using Robust.Server.GameObjects.Components.Container;
using Robust.Shared.GameObjects.Components.Transform;
using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.Maths; using Robust.Shared.Maths;
@@ -15,9 +14,7 @@ namespace Content.Server.GameObjects.Components.Disposal
IDisposalTubeComponent? NextTube(DisposalHolderComponent holder); IDisposalTubeComponent? NextTube(DisposalHolderComponent holder);
bool Remove(DisposalHolderComponent holder); bool Remove(DisposalHolderComponent holder);
bool TransferTo(DisposalHolderComponent holder, IDisposalTubeComponent to); bool TransferTo(DisposalHolderComponent holder, IDisposalTubeComponent to);
bool AdjacentConnected(Direction direction, IDisposalTubeComponent tube); bool CanConnect(Direction direction, IDisposalTubeComponent with);
void AdjacentDisconnected(IDisposalTubeComponent adjacent);
void MoveEvent(MoveEvent moveEvent);
void PopupDirections(IEntity entity); void PopupDirections(IEntity entity);
} }
} }

View File

@@ -1,33 +0,0 @@
using Content.Server.GameObjects.Components.Disposal;
using JetBrains.Annotations;
using Robust.Shared.GameObjects.Components.Transform;
using Robust.Shared.GameObjects.Systems;
namespace Content.Server.GameObjects.EntitySystems
{
[UsedImplicitly]
public class DisposalTubeSystem : EntitySystem
{
private void MoveEvent(MoveEvent moveEvent)
{
if (moveEvent.Sender.TryGetComponent(out IDisposalTubeComponent tube))
{
tube.MoveEvent(moveEvent);
}
}
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<MoveEvent>(MoveEvent);
}
public override void Shutdown()
{
base.Shutdown();
UnsubscribeLocalEvent<MoveEvent>();
}
}
}