public void AddConnection(WirePiece piece) { if (GetConnectedPole(piece) != Pole.None && !_connections.Contains(piece)) { _connections.Add(piece); } }
public void CloseLoop(WirePiece piece) { if (PreviousSelectedWirePiece != null && PreviousSelectedWirePiece != piece) { ConnectToPrevious(piece); } PreviousSelectedWirePiece = null; }
public Pole GetConnectedPole(WirePiece piece) { foreach (var connection in _connectionCells) { if (connection.Value.DrawableBase == piece) { return(connection.Key); } } return(Pole.None); }
public bool TryConnectToCharacterOverBridge(GridCell cell, GridCell bridge, CharacterBase character, bool userConnection = true) { if (character.CanConnectViaCell(bridge)) { var posDiff = cell.GridPos - bridge.GridPos; posDiff.Normalize(); Direction direction = Direction.None; if (posDiff == Vector2.right) { direction = Direction.Right; } else if (posDiff == Vector2.left) { direction = Direction.Left; } else if (posDiff == Vector2.down) { direction = Direction.Top; } else if (posDiff == Vector2.up) { direction = Direction.Bottom; } if (direction != Direction.None) { PreviousSelectedWirePiece.AddConnectionOnGrid(direction, character.PositionOnGrid); PreviousSelectedWirePiece.UpdateConnections(); character.AddConnection(PreviousSelectedWirePiece); } if (userConnection) { PreviousSelectedWirePiece = null; } return(true); } if (userConnection) { PreviousSelectedWirePiece = null; } return(false); }
private void ConnectToPrevious(WirePiece piece) { if (PreviousSelectedWirePiece != null) { var posDiff = piece.PositionOnGrid - PreviousSelectedWirePiece.PositionOnGrid; posDiff.Normalize(); Direction direction = Direction.None; if (posDiff == Vector2.right) { direction = Direction.Right; } else if (posDiff == Vector2.left) { direction = Direction.Left; } else if (posDiff == Vector2.down) { direction = Direction.Top; } else if (posDiff == Vector2.up) { direction = Direction.Bottom; } if (direction != Direction.None) { PreviousSelectedWirePiece.AddConnectionOnGrid(direction, piece.PositionOnGrid); piece.AddConnectionOnGrid(direction.GetOpposite(), PreviousSelectedWirePiece.PositionOnGrid); PreviousSelectedWirePiece.UpdateConnections(); piece.UpdateConnections(); } } _grid.SetGridCells(piece.transform.position, piece); PreviousSelectedWirePiece = piece; _wirePieces.Add(piece); var gridCell = _grid.GetGridCell(piece.transform.position); gridCell.ShowDebugValue(SettingsManager.Settings.ShowVoltage.Value || SettingsManager.Settings.ShowCurrent.Value); }
public void ReverseRemoveConnections(WirePiece piece) { var connections = piece.Connections; foreach (var connection in connections) { // Let connections know about removal var drawable = connection.Value; if (drawable.Type == DrawableBase.DrawableType.Wire) { var wire = drawable as WirePiece; wire.RemoveConnection(connection.Key.GetOpposite()); } else { var character = drawable as CharacterBase; character.RemoveConnection(piece); } } }
public static Rectangle[] GetWireSourceRect(WirePiece wirePiece) { int x = textureOffsetX; int y = textureOffsetY; Rectangle[] wireSourceRect = new Rectangle[1]; if (wirePiece.State == "selected") y += (Array.IndexOf(WireOrientations, wirePiece.Orientation) + TotalOrientations) * (PieceHeight + texturePaddingY); else y += Array.IndexOf(WireOrientations, wirePiece.Orientation) * (PieceHeight + texturePaddingY); //wires between a selected target and the current node will be colored differently to indicate the path. wireSourceRect[0] = new Rectangle(x, y, PieceWidth, PieceHeight); return wireSourceRect; }
public void DeleteWirePiece(WirePiece piece) { if (GameState.CurrentState == GameStates.Game) { var currLevel = ApplicationController.Instance.LevelController.CurrentLevel; if (currLevel.MaxWire != -1) { currLevel.MaxWire += 1; } } _wirePieces.Remove(piece); // If piece is bridge, search endpoint of connection it bridges and remove the connection if (piece.IsBridge) { var direction = piece.WireType == WirePiece.VisualType.HorizontalBridge ? Vector2.left : Vector2.up; var gridPos = piece.PositionOnGrid; var gridPosToCheck = gridPos + direction; var gridCellToCheck = _grid.GetGridCell((int)gridPosToCheck.x, (int)gridPosToCheck.y); var connectionStartFound = false; while (gridCellToCheck != null && !connectionStartFound) { var drawable = gridCellToCheck.DrawableBase; if (drawable.Type == DrawableBase.DrawableType.Wire) { var wirePiece = drawable as WirePiece; if (wirePiece.IsBridge == false) { connectionStartFound = true; var connection = wirePiece.GetConnection(direction.GetDirection().GetOpposite()); wirePiece.RemoveConnection(direction.GetDirection().GetOpposite()); // Reverse remove connection if (connection.Type == DrawableBase.DrawableType.Wire) { var connectedWire = connection as WirePiece; connectedWire.RemoveConnection(direction.GetDirection()); } else { var connectedChar = connection as CharacterBase; connectedChar.RemoveConnection(wirePiece); } } } else { direction *= -1; } gridPosToCheck += direction; gridCellToCheck = _grid.GetGridCell((int)gridPosToCheck.x, (int)gridPosToCheck.y); } } ReverseRemoveConnections(piece); piece.Destroy(); }
public static Mesh GenerateWire(Pt start, Pt startControl, Pt endControl, Pt end, int numSegments, WirePiece piece, Mode mode, int seed, Pt raiseBy) { const int bézierSteps = 16; var tubeRevSteps = mode == Mode.Collider ? 4 : 16; var rnd = new Rnd(seed); var thickness = mode != Mode.Wire ? _wireRadiusHighlight : _wireRadius; var iStart = startControl * .8 + endControl * .2; var iEnd = startControl * .2 + endControl * .8; var interpolatedPoints = Ut.NewArray <Pt>(numSegments - 1, i => raiseBy + iStart + (iEnd - iStart) * i / (numSegments - 2)); var controlPointsB = Ut.NewArray <Pt>(numSegments - 1, i => { var p1 = interpolatedPoints[i]; var p2 = i == numSegments - 2 ? endControl : interpolatedPoints[i + 1]; var v = (p2 - p1).Normalize() * p1.Distance(p2) * .25; var dummy = v.X > .5 ? new Pt(0, 1, 0) : new Pt(1, 0, 0); var perpendicular = dummy * v; v = (p1 + v).Rotate(p1, p1 + perpendicular, 45 * rnd.NextDouble()); v = v.Rotate(p1, p2, 360 * rnd.NextDouble()); return(v); }); var controlPointsA = Ut.NewArray <Pt>(numSegments - 1, i => 2 * interpolatedPoints[i] - controlPointsB[i]); if (piece == WirePiece.Uncut) { if (mode == Mode.Collider) { var points = new[] { start, startControl }.Concat(interpolatedPoints).Concat(new[] { endControl, end }).ToArray(); return(toMesh(createFaces(false, true, tubeFromCurve(points, thickness, tubeRevSteps)))); } else { var points = new[] { new { ControlBefore = default(Pt), Point = start, ControlAfter = startControl } } .Concat(interpolatedPoints.Select((p, i) => new { ControlBefore = controlPointsA[i], Point = p, ControlAfter = controlPointsB[i] })) .Concat(new[] { new { ControlBefore = endControl, Point = end, ControlAfter = default(Pt) } }) .SelectConsecutivePairs(false, (one, two) => bézier(one.Point, one.ControlAfter, two.ControlBefore, two.Point, bézierSteps)) .SelectMany((x, i) => i == 0 ? x : x.Skip(1)) .ToArray(); return(toMesh(createFaces(false, true, tubeFromCurve(points, thickness, tubeRevSteps)))); } } var partialWire = new Func <IEnumerable <CPC>, IEnumerable <VertexInfo[]> >(pts => { var points = pts .SelectConsecutivePairs(false, (one, two) => bézier(one.Point, one.ControlAfter, two.ControlBefore, two.Point, bézierSteps)) .SelectMany((x, i) => i == 0 ? x : x.Skip(1)) .ToArray(); var reserveForCopper = 6; var discardCopper = 2; if (piece == WirePiece.Cut) { var tube = tubeFromCurve(points, thickness, tubeRevSteps).SkipLast(reserveForCopper).ToArray(); var capCenter = points[points.Length - 1 - reserveForCopper]; var normal = capCenter - points[points.Length - 2 - reserveForCopper]; var cap = tube[tube.Length - 1].SelectConsecutivePairs(true, (v1, v2) => new[] { capCenter, v2.Point, v1.Point }.Select(p => new VertexInfo { Point = p, Normal = normal }).ToArray()).ToArray(); return(createFaces(false, true, tube).Concat(cap)); } else { var copper = tubeFromCurve(points.TakeLast(reserveForCopper + 2).SkipLast(discardCopper).ToArray(), thickness / 2, tubeRevSteps).Skip(1).ToArray(); var copperCapCenter = points[points.Length - 1 - discardCopper]; var copperNormal = copperCapCenter - points[points.Length - 2]; var copperCap = copper[copper.Length - 1].SelectConsecutivePairs(true, (v1, v2) => new[] { copperCapCenter, v2.Point, v1.Point }.Select(p => new VertexInfo { Point = p, Normal = copperNormal }).ToArray()).ToArray(); return(createFaces(false, true, copper).Concat(copperCap)); } }); var cutOffEarly = false;// rnd.Next(2) == 0; var angleForward = rnd.Next(2) == 0; var rotAngle = (rnd.NextDouble() * 10 + 1) * (angleForward ? -1 : 1); var rotAxisStart = start; var rotAxisEnd = startControl; Func <Pt, Pt> rot = p => p.Rotate(rotAxisStart, rotAxisEnd, rotAngle); var beforeCut = new[] { new CPC { ControlBefore = default(Pt), Point = start, ControlAfter = startControl } } .Concat(interpolatedPoints.Take((cutOffEarly ? numSegments : numSegments + 1) / 2).Select((p, i) => new CPC { ControlBefore = rot(controlPointsA[i]), Point = rot(p), ControlAfter = rot(controlPointsB[i]) })); var bcTube = partialWire(beforeCut); var cutOffPoint = (cutOffEarly ? numSegments - 2 : numSegments - 1) / 2; rotAngle = (rnd.NextDouble() * 10 + 1) * (angleForward ? -1 : 1); rotAxisStart = end; rotAxisEnd = endControl; var afterCut = new[] { new CPC { ControlBefore = default(Pt), Point = end, ControlAfter = endControl } } .Concat(interpolatedPoints.Skip(cutOffPoint).Select((p, i) => new CPC { ControlBefore = rot(controlPointsB[i + cutOffPoint]), Point = rot(p), ControlAfter = rot(controlPointsA[i + cutOffPoint]) }).Reverse()); var acTube = partialWire(afterCut); return(toMesh(bcTube.Concat(acTube).ToArray())); }
public CircuitNode(WirePiece wirePiece) { WirePiece = wirePiece; }
public static Mesh GenerateWire(System.Random rnd, int lengthIndex, int color, WirePiece piece, bool highlight) { var length = GetWireLength(lengthIndex); var thickness = highlight ? _wireRadiusHighlight : _wireRadius; var firstControlHeight = highlight ? _firstControlHeightHighlight : _firstControlHeight; var interpolateHeight = highlight ? _interpolateHeightHighlight : _interpolateHeight; var start = pt(0, 0, 0); var startControl = pt(length / 10, 0, firstControlHeight); var endControl = pt(length * 9 / 10, 0, firstControlHeight); var end = pt(length, 0, 0); var numSegments = new[] { 6, 4, 4 }[lengthIndex]; var bézierSteps = 16; var tubeRevSteps = 16; var interpolateStart = pt(0, 0, interpolateHeight); var interpolateEnd = pt(length, 0, interpolateHeight); var intermediatePoints = newArray(numSegments - 1, i => interpolateStart + (interpolateEnd - interpolateStart) * (i + 1) / numSegments + pt(rnd.NextDouble() - .5, rnd.NextDouble() - .5, rnd.NextDouble() - .5) * _wireMaxSegmentDeviation); var deviations = newArray(numSegments - 1, _ => pt(rnd.NextDouble(), rnd.NextDouble(), rnd.NextDouble()) * _wireMaxBézierDeviation); if (piece == WirePiece.Uncut) { var points = new[] { new { ControlBefore = default(Pt), Point = start, ControlAfter = startControl } } .Concat(intermediatePoints.Select((p, i) => new { ControlBefore = p - deviations[i], Point = p, ControlAfter = p + deviations[i] })) .Concat(new[] { new { ControlBefore = endControl, Point = end, ControlAfter = default(Pt) } }) .SelectConsecutivePairs(false, (one, two) => bézier(one.Point, one.ControlAfter, two.ControlBefore, two.Point, bézierSteps)) .SelectMany((x, i) => i == 0 ? x : x.Skip(1)) .ToArray(); return(toMesh(createFaces(false, true, tubeFromCurve(points, thickness, tubeRevSteps)), _colors[color])); } var partialWire = new Func <IEnumerable <CPC>, IEnumerable <VertexInfo[]> >(pts => { var points = pts .SelectConsecutivePairs(false, (one, two) => bézier(one.Point, one.ControlAfter, two.ControlBefore, two.Point, bézierSteps)) .SelectMany((x, i) => i == 0 ? x : x.Skip(1)) .ToArray(); var reserveForCopper = 6; var discardCopper = 2; if (piece == WirePiece.Cut) { var tube = tubeFromCurve(points, thickness, tubeRevSteps).SkipLast(reserveForCopper).ToArray(); var capCenter = points[points.Length - 1 - reserveForCopper]; var normal = capCenter - points[points.Length - 2 - reserveForCopper]; var cap = tube[tube.Length - 1].SelectConsecutivePairs(true, (v1, v2) => new[] { capCenter, v2.Point, v1.Point }.Select(p => new VertexInfo { Point = p, Normal = normal }).ToArray()).ToArray(); return(createFaces(false, true, tube).Concat(cap)); } else { var copper = tubeFromCurve(points.TakeLast(reserveForCopper + 2).SkipLast(discardCopper).ToArray(), thickness / 2, tubeRevSteps).Skip(1).ToArray(); var copperCapCenter = points[points.Length - 1 - discardCopper]; var copperNormal = copperCapCenter - points[points.Length - 2]; var copperCap = copper[copper.Length - 1].SelectConsecutivePairs(true, (v1, v2) => new[] { copperCapCenter, v2.Point, v1.Point }.Select(p => new VertexInfo { Point = p, Normal = copperNormal }).ToArray()).ToArray(); return(createFaces(false, true, copper).Concat(copperCap)); } }); var rotAngle = (rnd.NextDouble() * 7 + 5) * (rnd.Next(2) == 0 ? -1 : 1); var rotAxisStart = new Pt(0, 0, 0); var rotAxisEnd = new Pt(rnd.NextDouble() * .01, rnd.NextDouble() * .01, 1); Func <Pt, Pt> rot = p => p.Rotate(rotAxisStart, rotAxisEnd, rotAngle); var beforeCut = new[] { new CPC { ControlBefore = default(Pt), Point = start, ControlAfter = startControl } } .Concat(intermediatePoints.Take(numSegments / 2).Select((p, i) => new CPC { ControlBefore = rot(p - deviations[i]), Point = rot(p), ControlAfter = rot(p + deviations[i]) })); var bcTube = partialWire(beforeCut); var cutOffPoint = (numSegments - 1) / 2; rotAngle = (rnd.NextDouble() * 7 + 5) * (rnd.Next(2) == 0 ? -1 : 1); rotAxisStart = new Pt(length, 0, 0); rotAxisEnd = new Pt(length + rnd.NextDouble() * .01, rnd.NextDouble() * .01, 1); var afterCut = new[] { new CPC { ControlBefore = default(Pt), Point = end, ControlAfter = endControl } } .Concat(intermediatePoints.Skip(cutOffPoint).Select((p, i) => new CPC { ControlBefore = rot(p + deviations[i + cutOffPoint]), Point = rot(p), ControlAfter = rot(p - deviations[i + cutOffPoint]) }).Reverse()); var acTube = partialWire(afterCut); return(toMesh(bcTube.Concat(acTube).ToArray(), _colors[color])); }
public void RemoveConnection(WirePiece piece) { _connections.Remove(piece); }
private void TryBridgeWirePiece(WirePiece wirePiece, WirePiece previousWirePiece, int iteration) { var bridgePos = wirePiece.PositionOnGrid; var previousPos = previousWirePiece.PositionOnGrid; var wireController = ApplicationController.Instance.WireController; var diff = bridgePos - previousPos; diff.Normalize(); if (diff.magnitude != 1) { return; } var continuePos = previousPos + diff * (iteration + 1); var continueCell = GetGridCell((int)continuePos.x, (int)continuePos.y); var bridgeCell = GetGridCell((int)bridgePos.x, (int)bridgePos.y); if (continueCell == null) { wireController.CloseLoop(wirePiece); } else { var bridgePopup = CreateBridgePopup.Instance as CreateBridgePopup; bridgePopup.TogglePopup(true); bridgePopup.SetScreenPosition(bridgeCell.CenterInScreenCoord); UnityAction CanceledAction = null; CanceledAction = () => { wirePiece.ClearBridges(previousWirePiece); bridgePopup.OnPopupCanceled.RemoveListener(CanceledAction); bridgePopup.OnCreateBridgeConfirmed.RemoveAllListeners(); }; bridgePopup.OnPopupCanceled.AddListener(CanceledAction); UnityAction <bool> ConfirmAction = null; ConfirmAction = (value) => { bridgePopup.OnPopupCanceled.RemoveListener(CanceledAction); if (!value) { wireController.CloseLoop(wirePiece); } else { var continueDrawable = continueCell.DrawableBase; if (continueDrawable == null) { wireController.AddWirePiece(continueCell); wirePiece.IsBridge = value; wireController.PreviousSelectedWirePiece = null; } else { if (continueDrawable.Type == DrawableBase.DrawableType.Wire) { var wireDrawable = continueDrawable as WirePiece; wirePiece.IsBridge = value; if (wireDrawable.WireType == WirePiece.VisualType.Horizontal || wireDrawable.WireType == WirePiece.VisualType.Vertical) { TryBridgeWirePiece(wireDrawable, previousWirePiece, ++iteration); } else { wireController.CloseLoop(continueDrawable as WirePiece); } } else { var result = wireController.TryConnectToCharacterOverBridge(continueCell, bridgeCell, continueDrawable as CharacterBase); wirePiece.IsBridge = result; if (!result) { wireController.CloseLoop(wirePiece); } } } } bridgePopup.OnCreateBridgeConfirmed.RemoveListener(ConfirmAction); }; bridgePopup.OnCreateBridgeConfirmed.AddListener(ConfirmAction); } }