/// <summary>
    /// Creates grey boxes at each point the player has clicked before, but
    /// the player pawn hasn't caught up to yet.
    /// </summary>
    /// <param name="tilemap">The map</param>
    /// <returns>The line segments to render</returns>
    IEnumerable <SegmentProperties> GenerateCheckpointLines(IMap tilemap)
    {
        var segments = new List <SegmentProperties>();

        foreach (var c in commandCheckpoints)
        {
            var worldSpace = GridSpaceConversion.GetWorldSpaceFromLogical(c, tilemap);
            var square     = LineElements.SquareSelectionSegments(worldSpace, Color.grey);
            segments.AddRange(square);
        }

        return(segments);
    }
Exemple #2
0
    public void LogicalTick()
    {
        if (currentMotionPath.Any())
        {
            animator.SetBool("IsMoving", true);
        }
        else
        {
            animator.SetBool("IsMoving", false);
        }

        while (currentMotionPath.Any())
        {
            var nextPosLogical = currentMotionPath.Dequeue();

            if (nextPosLogical == LogicalLocation)
            {
                continue;
            }
            else
            {
                var nextPosWorld = GridSpaceConversion.GetWorldSpaceFromLogical(
                    nextPosLogical,
                    tilePlacedComponent.Tilemap);

                float angle = 180.0f;
                if (nextPosLogical.x > LogicalLocation.x)
                {
                    angle = 90.0f;
                }
                else if (nextPosLogical.x < LogicalLocation.x)
                {
                    angle = -90.0f;
                }
                else if (nextPosLogical.y > LogicalLocation.y)
                {
                    angle = 0.0f;
                }

                logicalLocation = nextPosLogical;
                gameObject.transform.localPosition = nextPosWorld;
                gameObject.transform.localRotation = Quaternion.AngleAxis(angle, Vector3.back) * Quaternion.Euler(-90.0f, 0.0f, 0.0f);
                break;
            }
        }
    }
Exemple #3
0
    void Update()
    {
        if (GameStats.GameOver)
        {
            return;
        }

        if (mapNeedsRebuild)
        {
            cellGraph = LogicalCellGraph.BuildCellGraph(Map, GetGateLogicalPositions());
            playerController?.RebuildGraph(cellGraph);
            needsMouseUpdate = true;
            enemyBrain?.RebuildGraph(cellGraph);
            mapNeedsRebuild = false;
        }

        var mouseSceenSpace   = Input.mousePosition;
        var mouseWorldSpace   = Camera.main.ScreenToWorldPoint(mouseSceenSpace);
        var mouseGridSpace    = Map.WorldToCell(mouseWorldSpace);
        var mouseLogicalSpace = GridSpaceConversion.GetLogicalSpaceFromGridSpace(mouseGridSpace, Map);

        if (playerController != null)
        {
            bool onGrid = mouseLogicalSpace.x >= 0 && mouseLogicalSpace.y >= 0 && mouseLogicalSpace.x < cellGraph.SizeX && mouseLogicalSpace.y < cellGraph.SizeY;

            if (mouseLogicalSpace != lastMouseLogicalPosition || needsMouseUpdate)
            {
                needsMouseUpdate         = false;
                lastMouseLogicalPosition = mouseLogicalSpace;
                playerController.OnMouseMove(mouseLogicalSpace, !onGrid, cellGraph, Map);
            }

            if (Input.GetMouseButtonDown(0))
            {
                playerController.OnMouseClick();
                playerController.RebuildGraph(cellGraph);
                needsMouseUpdate = true;
            }
            var mesh = playerController.GenerateLineMesh(Map);
            meshFilter.mesh = mesh;
        }
    }
Exemple #4
0
    /// <summary>
    /// Creates line segments from a logical-coordinate-based path
    /// </summary>
    /// <param name="path">The logical path</param>
    /// <param name="tilemap">The map where the path originated from</param>
    /// <returns>A list of segments that can be drawn</returns>
    public static IEnumerable <SegmentProperties> SegmentsFromPath(LogicalPath path, IMap tilemap)
    {
        var points = new List <Vector3>();

        foreach (var cell in path.Path)
        {
            var world = GridSpaceConversion.GetWorldSpaceFromLogical(cell, tilemap);
            points.Add(world);
        }

        if (points.Count <= 1)
        {
            return(new List <SegmentProperties>());
        }

        Vector3     facingDir = Vector3.back;
        const float width     = 0.08f;
        Color       color     = Color.white;

        var     segments  = new SegmentProperties[points.Count - 1];
        Vector3 lastPoint = points.First();
        int     segIndex  = 0;

        for (int n = 1; n < points.Count; ++n)
        {
            var point = points[n];
            segments[segIndex++] = new SegmentProperties {
                Start           = lastPoint,
                End             = point,
                FacingDirection = facingDir,
                Style           = SegmentStyle.Dashed,
                Width           = width,
                Color           = color
            };
            lastPoint = point;
        }

        return(segments);
    }
    /// <summary>
    /// Creates a box around where the user has their mouse targeted.
    /// The appears might vary depending on the validity of that location
    /// </summary>
    /// <param name="tilemap">The map</param>
    /// <returns>The line segments to render</returns>
    IEnumerable <SegmentProperties> GenerateSelectionBoxLines(IMap tilemap)
    {
        if (lastMouseLocationOffGrid)
        {
            return(new List <SegmentProperties>());
        }

        List <SegmentProperties> segments = new List <SegmentProperties>();

        var selectedCellWorldSpace = GridSpaceConversion.GetWorldSpaceFromLogical(lastMouseLocation, tilemap);

        Color boxColor = Color.white;

        if (!pendingTargetActive)
        {
            boxColor = Color.red;
            segments.AddRange(LineElements.XSegments(selectedCellWorldSpace, boxColor));
        }

        segments.AddRange(LineElements.SquareSelectionSegments(selectedCellWorldSpace, boxColor));

        return(segments);
    }
Exemple #6
0
    /// <summary>
    /// Builds a logical cell grid from the game data
    /// </summary>
    /// <param name="tilemap">The game map</param>
    /// <param name="gateLocations">The locations of all the locked doors/gates</param>
    /// <returns>A logical cell graph which contains useful neighboring data</returns>
    public static LogicalCellGraph BuildCellGraph(IMap tilemap, IEnumerable <Vector3Int> gateLocations)
    {
        LogicalCellGraph graph = new LogicalCellGraph();
        var logicalSize        = tilemap.CellBounds.size / 2;
        var sizeX = logicalSize.x;
        var sizeY = logicalSize.y;

        int[,,] colors       = new int[sizeX, logicalSize.y, 4];
        LogicalCell[,] cells = new LogicalCell[sizeX, logicalSize.y];
        var gateLocationsSet = new HashSet <Vector3Int>();

        foreach (var g in gateLocations)
        {
            gateLocationsSet.Add(g);
        }

        for (int y = 0; y < sizeY; ++y)
        {
            for (int x = 0; x < sizeX; ++x)
            {
                var cell = new LogicalCell {
                    X = x, Y = y
                };
                var logicalSpace = GridSpaceConversion.GetLogicalSpaceFromCell(cell);

                if (gateLocationsSet.Contains(logicalSpace))
                {
                    colors[x, y, 0] = 0; // Reserved for gates
                    colors[x, y, 1] = 0;
                    colors[x, y, 2] = 0;
                    colors[x, y, 3] = 0;
                }
                else
                {
                    var gridSpace = GridSpaceConversion.GetGridSpaceFromLogical(logicalSpace, tilemap);

                    // I wouldn't typically depend on render state for logical stuff,
                    // But this game will be all about color so I think it's OK.
                    colors[x, y, 0] = tilemap.GetColor(new Vector3Int(gridSpace.x, gridSpace.y, 0)).GetHashCode();
                    colors[x, y, 1] = tilemap.GetColor(new Vector3Int(gridSpace.x + 1, gridSpace.y, 0)).GetHashCode();
                    colors[x, y, 2] = tilemap.GetColor(new Vector3Int(gridSpace.x, gridSpace.y + 1, 0)).GetHashCode();
                    colors[x, y, 3] = tilemap.GetColor(new Vector3Int(gridSpace.x + 1, gridSpace.y + 1, 0)).GetHashCode();
                }

                cells[x, y] = cell;
            }
        }

        for (int y = 0; y < sizeY; ++y)
        {
            for (int x = 0; x < sizeX; ++x)
            {
                HashSet <int> colorsInThisCell = new HashSet <int>(new int[] {
                    colors[x, y, 0],
                    colors[x, y, 1],
                    colors[x, y, 2],
                    colors[x, y, 3],
                });

                LogicalCell thisCell = cells[x, y];

                LogicalCell upNeighbor = null;
                for (int up = y + 1; up < sizeY; ++up)
                {
                    if (colorsInThisCell.Contains(colors[x, up, 0]) ||
                        colorsInThisCell.Contains(colors[x, up, 1]) ||
                        colorsInThisCell.Contains(colors[x, up, 2]) ||
                        colorsInThisCell.Contains(colors[x, up, 3]))
                    {
                        upNeighbor = cells[x, up];
                        break;
                    }
                }

                LogicalCell downNeighbor = null;
                for (int down = y - 1; down >= 0; --down)
                {
                    if (colorsInThisCell.Contains(colors[x, down, 0]) ||
                        colorsInThisCell.Contains(colors[x, down, 1]) ||
                        colorsInThisCell.Contains(colors[x, down, 2]) ||
                        colorsInThisCell.Contains(colors[x, down, 3]))
                    {
                        downNeighbor = cells[x, down];
                        break;
                    }
                }

                LogicalCell rightNeighbor = null;
                for (int right = x + 1; right < sizeX; ++right)
                {
                    if (colorsInThisCell.Contains(colors[right, y, 0]) ||
                        colorsInThisCell.Contains(colors[right, y, 1]) ||
                        colorsInThisCell.Contains(colors[right, y, 2]) ||
                        colorsInThisCell.Contains(colors[right, y, 3]))
                    {
                        rightNeighbor = cells[right, y];
                        break;
                    }
                }

                LogicalCell leftNeighbor = null;
                for (int left = x - 1; left >= 0; --left)
                {
                    if (colorsInThisCell.Contains(colors[left, y, 0]) ||
                        colorsInThisCell.Contains(colors[left, y, 1]) ||
                        colorsInThisCell.Contains(colors[left, y, 2]) ||
                        colorsInThisCell.Contains(colors[left, y, 3]))
                    {
                        leftNeighbor = cells[left, y];
                        break;
                    }
                }

                thisCell.SetNeighbors(upNeighbor, leftNeighbor, rightNeighbor, downNeighbor);
            }
        }

        graph.indexedCells = cells;

        return(graph);
    }