Pipe prototypes (#2124)

* Pipe prototypes

* PipeDirection setter

* IRotatableNode

* NodeContainer passes rotation events to its nodes

* Removes duplicate pipe prototypes that are rotations of each other

* PipeDirectionHelpers

* PipeNode rotation

* icon removal

* Pipe icons

* Icon fix

* Fixes pipe sprites and icons

Co-authored-by: py01 <pyronetics01@gmail.com>
This commit is contained in:
py01
2020-10-08 09:53:56 -06:00
committed by GitHub
parent 621a39016f
commit 970f3bc82f
47 changed files with 278 additions and 296 deletions

View File

@@ -18,10 +18,10 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes
/// Connects with other <see cref="PipeNode"/>s whose <see cref="PipeNode.PipeDirection"/>
/// correctly correspond.
/// </summary>
public class PipeNode : Node, IGasMixtureHolder
public class PipeNode : Node, IGasMixtureHolder, IRotatableNode
{
[ViewVariables]
public PipeDirection PipeDirection => _pipeDirection;
public PipeDirection PipeDirection { get => _pipeDirection; set => SetPipeDirection(value); }
private PipeDirection _pipeDirection;
/// <summary>
@@ -64,8 +64,6 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes
private AppearanceComponent _appearance;
private PipeVisualState PipeVisualState => new PipeVisualState(PipeDirection, ConduitLayer);
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
@@ -94,22 +92,40 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes
_needsPipeNet = true;
}
void IRotatableNode.RotateEvent(RotateEvent ev)
{
var diff = ev.NewRotation - ev.OldRotation;
var newPipeDir = PipeDirection.None;
for (var i = 0; i < PipeDirectionHelpers.PipeDirections; i++)
{
var pipeDirection = (PipeDirection) (1 << i);
if (!PipeDirection.HasFlag(pipeDirection)) continue;
var angle = pipeDirection.ToAngle();
angle += diff;
newPipeDir |= angle.GetCardinalDir().ToPipeDirection();
}
PipeDirection = newPipeDir;
}
protected override IEnumerable<Node> GetReachableNodes()
{
foreach (CardinalDirection direction in Enum.GetValues(typeof(CardinalDirection)))
for (var i = 0; i < PipeDirectionHelpers.PipeDirections; i++)
{
PipeDirectionFromCardinal(direction, out var ownNeededConnection, out var theirNeededConnection);
if ((_pipeDirection & ownNeededConnection) == PipeDirection.None)
var pipeDirection = (PipeDirection) (1 << i);
var ownNeededConnection = pipeDirection;
var theirNeededConnection = ownNeededConnection.GetOpposite();
if (!_pipeDirection.HasFlag(ownNeededConnection))
{
continue;
}
var pipeNodesInDirection = Owner.GetComponent<SnapGridComponent>()
.GetInDir((Direction) direction)
.GetInDir(pipeDirection.ToDirection())
.Select(entity => entity.TryGetComponent<NodeContainerComponent>(out var container) ? container : null)
.Where(container => container != null)
.SelectMany(container => container.Nodes)
.OfType<PipeNode>()
.Where(pipeNode => (pipeNode._pipeDirection & theirNeededConnection) != PipeDirection.None);
.Where(pipeNode => pipeNode._pipeDirection.HasFlag(theirNeededConnection));
foreach (var pipeNode in pipeNodesInDirection)
{
yield return pipeNode;
@@ -117,47 +133,16 @@ namespace Content.Server.GameObjects.Components.NodeContainer.Nodes
}
}
private void PipeDirectionFromCardinal(CardinalDirection direction, out PipeDirection sameDir, out PipeDirection oppDir)
{
switch (direction)
{
case CardinalDirection.North:
sameDir = PipeDirection.North;
oppDir = PipeDirection.South;
break;
case CardinalDirection.South:
sameDir = PipeDirection.South;
oppDir = PipeDirection.North;
break;
case CardinalDirection.East:
sameDir = PipeDirection.East;
oppDir = PipeDirection.West;
break;
case CardinalDirection.West:
sameDir = PipeDirection.West;
oppDir = PipeDirection.East;
break;
default:
throw new ArgumentException("Invalid Direction.");
}
}
private void UpdateAppearance()
{
var pipeVisualStates = Owner.GetComponent<NodeContainerComponent>()
.Nodes
.OfType<PipeNode>()
.Select(pipeNode => pipeNode.PipeVisualState)
.ToArray();
_appearance?.SetData(PipeVisuals.VisualState, new PipeVisualStateSet(pipeVisualStates));
_appearance?.SetData(PipeVisuals.VisualState, new PipeVisualState(PipeDirection, ConduitLayer));
}
private enum CardinalDirection
private void SetPipeDirection(PipeDirection pipeDirection)
{
North = Direction.North,
South = Direction.South,
East = Direction.East,
West = Direction.West,
_pipeDirection = pipeDirection;
RefreshNodeGroup();
UpdateAppearance();
}
}
}