Пример #1
0
 public void AddConnection(WirePiece piece)
 {
     if (GetConnectedPole(piece) != Pole.None && !_connections.Contains(piece))
     {
         _connections.Add(piece);
     }
 }
Пример #2
0
        public void CloseLoop(WirePiece piece)
        {
            if (PreviousSelectedWirePiece != null && PreviousSelectedWirePiece != piece)
            {
                ConnectToPrevious(piece);
            }

            PreviousSelectedWirePiece = null;
        }
Пример #3
0
        public Pole GetConnectedPole(WirePiece piece)
        {
            foreach (var connection in _connectionCells)
            {
                if (connection.Value.DrawableBase == piece)
                {
                    return(connection.Key);
                }
            }

            return(Pole.None);
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
                }
            }
        }
Пример #7
0
        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;
        }
Пример #8
0
        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();
        }
Пример #9
0
        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()));
        }
Пример #10
0
 public CircuitNode(WirePiece wirePiece)
 {
     WirePiece = wirePiece;
 }
Пример #11
0
        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]));
        }
Пример #12
0
 public void RemoveConnection(WirePiece piece)
 {
     _connections.Remove(piece);
 }
Пример #13
0
        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);
            }
        }