Example #1
0
    /// <summary>
    /// Get manhatten distance from start tile to end tile
    /// </summary>
    /// <param name="a_nodeA"></param>
    /// <param name="a_nodeB"></param>
    /// <returns></returns>
    public int GetManhattenDistance(GridTileInfo a_nodeA, GridTileInfo a_nodeB)
    {
        int ix = Mathf.Abs(a_nodeA.xCoord - a_nodeB.xCoord); //x1 - x2
        int iy = Mathf.Abs(a_nodeA.zCoord - a_nodeB.zCoord); //z1 - z2

        return(ix + iy);                                     //Return the sum
    }
Example #2
0
    // Update is called once per frame
    void Update()
    {
        ControlTurnTips(); // Update different UI tips about game phase

        // Player input
        currentMouseOverTile = null; // Clear the last hovered tile

        // If the player cursor is not on UI element
        if (!EventSystem.current.IsPointerOverGameObject())
        {
            // If the player cursor is on a tile
            RaycastHit hit;
            if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, Mathf.Infinity))
            {
                // Debug.Log(hit.collider.tag);
                if (hit.collider.tag == "Tile")
                {
                    currentMouseOverTile = hit.collider.GetComponent <GridTileInfo>();
                }
            }

            // If the player cursor is on a tile
            if (currentMouseOverTile != null)
            {
                PlayerHoverTile(currentMouseOverTile);

                // If the player clicked LMB on hovering tile
                if (Input.GetMouseButtonDown(0))
                {
                    PlayerSelectedTile(currentMouseOverTile);
                }
            }
        }
    }
Example #3
0
    /// <summary>
    /// When player finish current turn
    /// </summary>
    public void PlayerFinishTurn()
    {
        // Player cannot finish turn when an unit is still in animation
        if (inPlayerUnitAnimation)
        {
            return;
        }

        playerTurn = false;
        currentSelectedUnitTile = null;


        // Clear map marks
        bool[] clearFlags = { true, true };
        ClearMapMarks(clearFlags);

        // If there is no more enemy left in this level
        if (EnemyManager.thisLevelEnemies.Count == 0)
        {
            GameManager.sGameManager.LevelFinished(); // Finish current level and enters evolve phase
        }
        else
        {
            // Zoom out camera
            if (!GameManager.cameraZoomedOut)
            {
                GameManager.sGameManager.ZoomCamera();
            }

            enemyTurnTip.SetActive(true);                            // Show enemy turn UI tip
            StartCoroutine(EnemyManager.sEnemyManager.ActEnemies()); // Start enemy turn
        }
    }
Example #4
0
    public static void CreateMap()
    {
        MapManager instance = (MapManager)FindObjectOfType(typeof(MapManager));

        instance.currentMap = new GridTileInfo[instance.mapSizeX, instance.mapSizeZ];

        GameObject newMapObject = Instantiate(new GameObject(), Vector3.zero, Quaternion.identity);

        newMapObject.name = "Grid";

        for (int i = 0; i < instance.mapSizeX; i++)
        {
            GameObject newColumnObject = Instantiate(new GameObject(), newMapObject.transform);
            newColumnObject.name = "Column_" + i.ToString();

            for (int j = 0; j < instance.mapSizeZ; j++)
            {
                GameObject newTile = Instantiate(instance.tilePrefab, Vector3.right * i + Vector3.forward * j, instance.tilePrefab.transform.rotation);
                newTile.transform.parent = newColumnObject.transform;
                GridTileInfo newTileInfo = newTile.GetComponent <GridTileInfo>();
                newTileInfo.xCoord        = i;
                newTileInfo.zCoord        = j;
                instance.currentMap[i, j] = newTileInfo;
            }
        }
    }
Example #5
0
    public override void OnInspectorGUI()
    {
        GUIStyle style     = new GUIStyle();
        bool     showClose = true;

        base.OnInspectorGUI();
        //test = false;
        ScriptableObjectGridStructure origin = (ScriptableObjectGridStructure)target;
        BattleTileInfo bti;
        GridTileInfo   gti = null;

        if (origin.GridInfo.Count > 0)
        {
            EditorGUILayout.Space();
            for (int x = 0; x < 6; x++)
            {
                EditorGUILayout.BeginHorizontal();
                for (int y = 0; y < 12; y++)
                {
                    //Debug.Log(x + "   " + y);
                    bti      = origin.GridInfo.Where(r => r.Pos == new Vector2Int(x, y)).First();
                    bti.name = x + "," + y;
                    if (firstOpen)
                    {
                        gti = new GridTileInfo(new Vector2Int(x, y), bti);
                        TilesInfo.Add(gti, bti.BattleTileState == BattleTileStateType.Empty ? true : false);
                    }
                    else
                    {
                        gti = TilesInfo.Where(r => r.Key.Pos == new Vector2Int(x, y)).First().Key;
                    }

                    showClose = EditorGUILayout.ToggleLeft(x + "," + y, TilesInfo.Where(r => r.Key.Pos == new Vector2Int(x, y)).First().Value, GUILayout.Width(40));
                    if (showClose != TilesInfo[gti])
                    {
                        if (showClose)
                        {
                            differentGti = gti;
                        }
                        else
                        {
                            differentGti = null;
                        }
                    }
                    TilesInfo[gti]      = showClose;
                    bti.BattleTileState = showClose ? BattleTileStateType.Empty : BattleTileStateType.Blocked;
                    //Debug.Log(showClose);
                }
                EditorGUILayout.EndHorizontal();
            }

            if (differentGti != null)
            {
                ShowTileObject(ref differentGti.Tile);
            }
            firstOpen = false;
        }

        EditorUtility.SetDirty(origin);
    }
Example #6
0
 public ScenarioData(int xTiles, int zTiles)
 {
     gridWidth  = xTiles;
     gridHeight = zTiles;
     tileArray  = new GridTileInfo[xTiles, zTiles];
     for (int i = 0; i < xTiles; i++)
     {
         for (int j = 0; j < zTiles; j++)
         {
             tileArray [i, j] = new GridTileInfo();
         }
     }
 }
Example #7
0
    /// <summary>
    /// Return a list of GridTileInfo that represents the shortest path from start tile to end tile
    /// </summary>
    /// <param name="start"></param>
    /// <param name="end"></param>
    /// <returns></returns>
    public List <GridTileInfo> FindPath(GridTileInfo start, GridTileInfo end)
    {
        List <GridTileInfo>    OpenList   = new List <GridTileInfo>();    //List of nodes for the open list
        HashSet <GridTileInfo> ClosedList = new HashSet <GridTileInfo>(); //Hashset of nodes for the closed list

        OpenList.Add(start);                                              //Add the starting node to the open list to begin the program

        while (OpenList.Count > 0)                                        //Whilst there is something in the open list
        {
            GridTileInfo CurrentNode = OpenList[0];                       //Create a node and set it to the first item in the open list
            for (int i = 1; i < OpenList.Count; i++)                      //Loop through the open list starting from the second object
            {
                if (OpenList[i].ihCost + OpenList[i].igCost < CurrentNode.ihCost + CurrentNode.igCost ||
                    OpenList[i].ihCost + OpenList[i].igCost == CurrentNode.ihCost + CurrentNode.igCost && OpenList[i].ihCost < CurrentNode.ihCost) //If the f cost of that object is less than or equal to the f cost of the current node
                {
                    CurrentNode = OpenList[i];                                                                                                     //Set the current node to that object
                }
            }
            OpenList.Remove(CurrentNode);         //Remove that from the open list
            ClosedList.Add(CurrentNode);          //And add it to the closed list

            if (CurrentNode == end)               //If the current node is the same as the target node
            {
                return(GetFinalPath(start, end)); //Calculate the final path
            }

            foreach (GridTileInfo NeighborNode in GetNeighboringNodes(CurrentNode))                                                                 //Loop through each neighbor of the current node
            {
                if (NeighborNode.isObstacle || (NeighborNode.containingObject != null && NeighborNode != end) || ClosedList.Contains(NeighborNode)) //If the neighbor is a wall or (not empty and not the end node) or has already been checked
                {
                    continue;                                                                                                                       //Skip it
                }
                int MoveCost = CurrentNode.igCost + GetManhattenDistance(CurrentNode, NeighborNode);                                                //Get the F cost of that neighbor

                if (MoveCost < NeighborNode.igCost || !OpenList.Contains(NeighborNode))                                                             //If the f cost is greater than the g cost or it is not in the open list
                {
                    NeighborNode.igCost     = MoveCost;                                                                                             //Set the g cost to the f cost
                    NeighborNode.ihCost     = GetManhattenDistance(NeighborNode, end);                                                              //Set the h cost
                    NeighborNode.parentTile = CurrentNode;                                                                                          //Set the parent of the node for retracing steps

                    if (!OpenList.Contains(NeighborNode))                                                                                           //If the neighbor is not in the openlist
                    {
                        OpenList.Add(NeighborNode);                                                                                                 //Add it to the list
                    }
                }
            }
        }

        // Return null if cannot find path
        return(null);
    }
Example #8
0
    /// <summary>
    /// Return a list of neighbor tiles of a tile
    /// </summary>
    /// <param name="checkedTile"></param>
    /// <returns></returns>
    public static List <GridTileInfo> GetNeighboringNodes(GridTileInfo checkedTile)
    {
        List <GridTileInfo> NeighborList = new List <GridTileInfo>(); //Make a new list of all available neighbors.
        int icheckX;                                                  //Variable to check if the XPosition is within range of the node array to avoid out of range errors.
        int icheckZ;                                                  //Variable to check if the ZPosition is within range of the node array to avoid out of range errors.

        //Check the right side of the current node.
        icheckX = checkedTile.xCoord + 1;
        icheckZ = checkedTile.zCoord;
        if (icheckX >= 0 && icheckX < sMapManager.mapSizeX)                 //If the XPosition is in range of the array
        {
            if (icheckZ >= 0 && icheckZ < sMapManager.mapSizeZ)             //If the YPosition is in range of the array
            {
                NeighborList.Add(sMapManager.currentMap[icheckX, icheckZ]); //Add the grid to the available neighbors list
            }
        }
        //Check the Left side of the current node.
        icheckX = checkedTile.xCoord - 1;
        icheckZ = checkedTile.zCoord;
        if (icheckX >= 0 && icheckX < sMapManager.mapSizeX)                 //If the XPosition is in range of the array
        {
            if (icheckZ >= 0 && icheckZ < sMapManager.mapSizeZ)             //If the YPosition is in range of the array
            {
                NeighborList.Add(sMapManager.currentMap[icheckX, icheckZ]); //Add the grid to the available neighbors list
            }
        }
        //Check the Top side of the current node.
        icheckX = checkedTile.xCoord;
        icheckZ = checkedTile.zCoord + 1;
        if (icheckX >= 0 && icheckX < sMapManager.mapSizeX)                 //If the XPosition is in range of the array
        {
            if (icheckZ >= 0 && icheckZ < sMapManager.mapSizeZ)             //If the YPosition is in range of the array
            {
                NeighborList.Add(sMapManager.currentMap[icheckX, icheckZ]); //Add the grid to the available neighbors list
            }
        }
        //Check the Bottom side of the current node.
        icheckX = checkedTile.xCoord;
        icheckZ = checkedTile.zCoord - 1;
        if (icheckX >= 0 && icheckX < sMapManager.mapSizeX)                 //If the XPosition is in range of the array
        {
            if (icheckZ >= 0 && icheckZ < sMapManager.mapSizeZ)             //If the YPosition is in range of the array
            {
                NeighborList.Add(sMapManager.currentMap[icheckX, icheckZ]); //Add the grid to the available neighbors list
            }
        }

        return(NeighborList);//Return the neighbors list.
    }
Example #9
0
    /// <summary>
    /// Update the player units that are reproducing
    /// </summary>
    public IEnumerator UpdateReproducingPlayerUnits()
    {
        reproductionPhaseTip.SetActive(true); // Show reproduction phase UI tip

        foreach (PlayerUnit p in GameManager.playerUnits)
        {
            // Wait if there is a player unit currently ready to reproduce
            while (playerUnitReproducing)
            {
                yield return(null);
            }

            yield return(new WaitForSeconds(p.moveAnimationInterval));

            // Focus cam on reproducing unit

            p.turnsLeftForReproduce--;

            // If the clone is ready to reproduce
            if (p.turnsLeftForReproduce == 0)
            {
                // If there is empty neighbor to place new clone
                if (ShowRange(p.GetComponent <MapObjectInfo>().currentOccupyingTile, 1, true) > 0)
                {
                    currentSelectedUnitTile = p.GetComponent <MapObjectInfo>().currentOccupyingTile;
                    playerUnitReproducing   = true;
                }
            }
        }

        reproductionPhaseTip.SetActive(false); // Hide reproduction phase UI tip

        // Copy new clones to player unit list in GameManager
        foreach (PlayerUnit p in newCloneReproduced)
        {
            GameManager.playerUnits.Add(p);
        }

        // Clear new clone list
        newCloneReproduced.Clear();

        // Make existing player units be able to move in the next turn
        foreach (PlayerUnit p in GameManager.playerUnits)
        {
            p.hasMoved = false;
        }

        playerTurn = true; // Let player play the turn
    }
Example #10
0
    public List <GridTileInfo> GetFinalPath(GridTileInfo start, GridTileInfo end)
    {
        List <GridTileInfo> finalPath   = new List <GridTileInfo>(); //List to hold the path sequentially
        GridTileInfo        currentTile = end;                       //Node to store the current node being checked

        while (currentTile != start)                                 //While loop to work through each node going through the parents to the beginning of the path
        {
            finalPath.Add(currentTile);                              //Add that node to the final path
            currentTile = currentTile.parentTile;                    //Move onto its parent node
        }

        finalPath.Reverse(); //Reverse the path to get the correct order

        return(finalPath);   //Return the final path
    }
Example #11
0
    /// <summary>
    /// Find a route
    /// </summary>
    /// <returns></returns>
    public List <GridTileInfo> FindRoute()
    {
        int                 shortestRoute = MapManager.sMapManager.mapSizeX * MapManager.sMapManager.mapSizeZ;
        GridTileInfo        occupyingTile = GetComponent <MapObjectInfo>().currentOccupyingTile;
        List <GridTileInfo> finalRoute    = null;

        // Test all player units
        foreach (PlayerUnit p in GameManager.playerUnits)
        {
            // Try to get a route to p
            List <GridTileInfo> route = MapManager.sMapManager.FindPath(occupyingTile, p.GetComponent <MapObjectInfo>().currentOccupyingTile);

            // If there is a route and the route is currently the shortest
            if (route != null && route.Count < shortestRoute)
            {
                shortestRoute = route.Count;
                finalRoute    = route;
            }
        }

        return(finalRoute);

        // If there is no player unit that is reachable by this enemy
        if (finalRoute == null)
        {
            PlayerUnit closestPlayerUnit = null;

            // Test all player manhatten distance
            foreach (PlayerUnit p in GameManager.playerUnits)
            {
                // Get manhatten distance
                int distance = MapManager.sMapManager.GetManhattenDistance(occupyingTile, p.GetComponent <MapObjectInfo>().currentOccupyingTile);

                // If this player has the closest manhatten distance
                if (distance < shortestRoute)
                {
                    shortestRoute     = distance;
                    closestPlayerUnit = p;
                }
            }
        }
        else
        {
            return(finalRoute);
        }
    }
Example #12
0
    public List <IntPoint2D> GetAdjacentRoadTiles(IntPoint2D startTile)
    {
        List <IntPoint2D> tileList = new List <IntPoint2D> ();
        GridTileInfo      tileInfo = tileArray [startTile.xCoord, startTile.yCoord];

        if (tileInfo.IsRoad())
        {
            tileList.Add(startTile);
        }
        else
        {
            IntPoint2D topLeft = startTile;
            int        sideLen = 1;
            if (!tileInfo.IsClear())
            {
                topLeft = tileInfo.GetTopLeftOfBuilding();
                sideLen = tileInfo.GetSides();
            }
            // now we need to check each adjacent tile
            for (int step = 0; step < sideLen; step++)
            {
                IntPoint2D tileLoc = new IntPoint2D(topLeft.xCoord + step, topLeft.yCoord - 1);
                if (IsRoadTile(tileLoc))
                {
                    tileList.Add(tileLoc);
                }
                tileLoc = new IntPoint2D(topLeft.xCoord + step, topLeft.yCoord + sideLen);
                if (IsRoadTile(tileLoc))
                {
                    tileList.Add(tileLoc);
                }
                tileLoc = new IntPoint2D(topLeft.xCoord - 1, topLeft.yCoord + step);
                if (IsRoadTile(tileLoc))
                {
                    tileList.Add(tileLoc);
                }
                tileLoc = new IntPoint2D(topLeft.xCoord + sideLen, topLeft.yCoord + step);
                if (IsRoadTile(tileLoc))
                {
                    tileList.Add(tileLoc);
                }
            }
        }
        return(tileList);
    }
Example #13
0
    /// <summary>
    /// When player selected a unit
    /// </summary>
    /// <param name="selectedUnit"></param>
    //public void PlayerSelectUnit(PlayerUnit selectedUnit)
    //{

    //}

    /// <summary>
    /// When player ended a unit's act
    /// </summary>
    public void UnitFinishAct()
    {
        // Mark the selected unit as moved
        currentSelectedUnitTile.containingObject.GetComponent <PlayerUnit>().hasMoved = true;
        currentSelectedUnitTile = null;

        // Clear previous map marks
        bool[] clearFlags = { true, true };
        ClearMapMarks(clearFlags);

        // Mark the player finished an unit's act, and can select other unit
        playerUnitAct = false;

        // Check if finish turn
        if (!GameManager.playerUnits.Exists(u => (!u.hasMoved || !u.isReproducing)))
        {
            PlayerFinishTurn();
        }
    }
Example #14
0
    /// <summary>
    /// Show the path from the selected player clone tile to the player selected destination tile
    /// </summary>
    /// <param name="selectedTile"></param>
    /// <param name="destinationTile"></param>
    public void ShowPath(GridTileInfo selectedTile, GridTileInfo destinationTile)
    {
        // Clear previous map marks
        bool[] clearFlags = { false, true };
        ClearMapMarks(clearFlags);

        // Show route
        List <GridTileInfo> route = MapManager.sMapManager.FindPath(selectedTile, destinationTile);

        if (route == null || route.Count > currentSelectedUnitTile.containingObject.GetComponent <PlayerUnit>().moveRange)
        {
            // No valid route
        }
        else
        {
            foreach (GridTileInfo tile in MapManager.sMapManager.FindPath(selectedTile, destinationTile))
            {
                tile.marks[1].SetActive(true);
            }
        }
    }
Example #15
0
    /// <summary>
    /// Show a range for the current action of the current selected player unit
    /// Can show move range, attack range, etc.
    /// </summary>
    /// <param name="selectedTile"></param>
    /// <param name="range"></param>
    /// <param name="isEmpty"></param>
    /// <returns></returns>
    public int ShowRange(GridTileInfo selectedTile, int range, bool isEmpty)
    {
        // Clear previous map marks
        bool[] clearFlags = { true, true };
        ClearMapMarks(clearFlags);

        int availableTileCount = 0;

        // Show range
        foreach (GridTileInfo tile in MapManager.sMapManager.currentMap)
        {
            // If tile is not obstacle and empty (if showed tile has to be empty)
            if (!tile.isObstacle && (tile.containingObject == null || !isEmpty) && MapManager.sMapManager.GetManhattenDistance(selectedTile, tile) <= range)
            {
                tile.marks[0].SetActive(true);

                // Count available tile
                availableTileCount++;
            }
        }

        return(availableTileCount);
    }
Example #16
0
    public IEnumerator UnitReproduce(GridTileInfo targetTile)
    {
        yield return(new WaitForSeconds(moveAnimationInterval));

        GameObject newClone     = Instantiate(gameObject);
        PlayerUnit newCloneUnit = newClone.GetComponent <PlayerUnit>();

        newCloneUnit.GetComponent <MapObjectInfo>().currentOccupyingTile = null; // Reset new clone's MapObjectInfo's occupying tile info, because it has not been placed on the map yet

        // Place new clone on target tile
        MapManager.PlaceObject(newClone.transform, targetTile.xCoord, targetTile.zCoord);

        newCloneUnit.InitiateClone();

        // Add new clone to new clone list
        TurnManager.newCloneReproduced.Add(newCloneUnit);

        // Clear selected tile in TurnManager;
        TurnManager.currentSelectedUnitTile = null;

        yield return(new WaitForSeconds(moveAnimationInterval));

        // If new clone meet the win requirement
        if (GameManager.sGameManager.CheckWinCondition(newCloneUnit))
        {
            //GameManager.playerUnits.Add(newCloneUnit);
            GameManager.sGameManager.PlayerWin();
        }

        // Finish reproduction
        TurnManager.playerUnitReproducing = false;
        isReproducing = false;

        // Finish animation
        TurnManager.inPlayerUnitAnimation = false;
    }
Example #17
0
    /// <summary>
    /// When player clicked on a tile
    /// </summary>
    /// <param name="selectedTile"></param>
    public void PlayerSelectedTile(GridTileInfo selectedTile)
    {
        // Player cannot select tile during an unit animation
        if (inPlayerUnitAnimation)
        {
            return;
        }

        // If it's currently in evolve phase
        if (GameManager.inEvolvePhase)
        {
            // If player selected a clone unit
            if (selectedTile.containingObject != null)
            {
                // Open evolve shop for the selected unit
                GameManager.sGameManager.StartEvolve(selectedTile.containingObject.GetComponent <PlayerUnit>());
            }

            return;
        }

        // If one of the player's unit is ready to reproduce
        if (playerUnitReproducing)
        {
            // If the player selected a valid tile
            if (selectedTile.marks[0].activeInHierarchy)
            {
                inPlayerUnitAnimation = true; // Start animation

                StartCoroutine(currentSelectedUnitTile.containingObject.GetComponent <PlayerUnit>().UnitReproduce(selectedTile));
            }

            // Stop player from doing other things before finish the reproduction phase
            return;
        }

        // Player cannot select tile when it's not player's turn
        if (!playerTurn)
        {
            return;
        }

        // If there is no unit that has moved but did not finish act yet
        if (!playerUnitAct)
        {
            // If the player selected a tile with a player unit
            if (selectedTile.containingObject != null && selectedTile.containingObject.GetComponent <PlayerUnit>())
            {
                PlayerUnit selectedUnit = selectedTile.containingObject.GetComponent <PlayerUnit>();

                // If the unit has not moved in this turn yet and is not reproducing
                if (!selectedUnit.hasMoved && !selectedUnit.isReproducing)
                {
                    currentSelectedUnitTile = selectedTile;

                    // Show move range of just selected unit
                    ShowRange(selectedTile, selectedUnit.moveRange, true);
                }
            }

            // If the player selected a tile with no object and there is already a selected unit and the selected tile is within move range
            if (currentSelectedUnitTile != null && selectedTile.containingObject == null && selectedTile.marks[1].activeInHierarchy)
            {
                // Clear previous map marks
                bool[] clearFlags = { true, true };
                ClearMapMarks(clearFlags);

                // If their is a valid path to the selected tile
                List <GridTileInfo> path = MapManager.sMapManager.FindPath(currentSelectedUnitTile, selectedTile);

                if (path != null)
                {
                    inPlayerUnitAnimation = true; // Start animation

                    // Start move player unit
                    StartCoroutine(currentSelectedUnitTile.containingObject.GetComponent <PlayerUnit>().UnitMove(path));
                }
            }
        }
        else
        {
            // If the player selected an enemy that's within range
            if (selectedTile.marks[0].activeInHierarchy && selectedTile.containingObject != null && selectedTile.containingObject.GetComponent <EnemyUnit>())
            {
                inPlayerUnitAnimation = true;                                                                                                                              // Start animation

                StartCoroutine(currentSelectedUnitTile.containingObject.GetComponent <PlayerUnit>().UnitAttack(selectedTile.containingObject.GetComponent <EnemyUnit>())); // Unit attack selected enemy
            }
        }
    }
Example #18
0
    /// <summary>
    /// If the player hover the mouse above a tile
    /// </summary>
    /// <param name="hoverTile"></param>
    public void PlayerHoverTile(GridTileInfo hoverTile)
    {
        // Player cannot select tile when it's not player's turn
        if (!playerTurn)
        {
            // If there is a player unit ready to reproduce
            if (playerUnitReproducing)
            {
                // Clear previous map marks
                bool[] clearFlags = { false, true };
                ClearMapMarks(clearFlags);

                // If the hovered tile is valid for place new clone
                if (hoverTile.marks[0].activeInHierarchy)
                {
                    hoverTile.marks[1].SetActive(true); // Highlight hovering tile
                }
            }

            return;
        }

        // If player did not select a unit
        if (currentSelectedUnitTile == null)
        {
            // Clear previous map marks
            bool[] clearFlags = { true, true };
            ClearMapMarks(clearFlags);

            // If the tile has a player unit
            if (hoverTile.containingObject != null && hoverTile.containingObject.GetComponent <PlayerUnit>())
            {
                //// If the player unit can move
                //if ()

                hoverTile.marks[0].SetActive(true); // Highlight tile
            }
        }

        // If player selected a unit, and the unit has not moved yet
        if (currentSelectedUnitTile != null && !playerUnitAct)
        {
            // Clear previous map marks
            bool[] clearFlags = { false, true };
            ClearMapMarks(clearFlags);

            // If the tile is within the unit's move range
            if (hoverTile.marks[0].activeInHierarchy)
            {
                ShowPath(currentSelectedUnitTile, hoverTile);
            }
        }

        // If a player unit just moved and is in act phase
        if (playerUnitAct)
        {
            // Clear previous map marks
            bool[] clearFlags = { false, true };
            ClearMapMarks(clearFlags);

            // If the player selected an enemy within range
            if (hoverTile.marks[0].activeInHierarchy && hoverTile.containingObject != null && hoverTile.containingObject.GetComponent <EnemyUnit>())
            {
                // Mark selected enemy
                hoverTile.marks[1].SetActive(true);
            }
        }
    }