Esempio n. 1
0
    // Finds selectable tiles and updates currentTile as current, occupied
    public void FindSelectableTiles(Tile startTile, float movementRange)
    {
        // if selectable tiles were not removed do not recompute.
        if (selectableTiles.Count > 0)
        {
            foreach (Tile tile in selectableTiles)
            {
                tile.selectable = true;
            }
            return;
        }

        // init Dijkstra
        PriorityQueue <TileDistancePair> processing = new PriorityQueue <TileDistancePair>();


        // Compute Adjacency List and reset all distances.
        InitPathFinding(startTile);

        startTile.selectable = true;
        selectableTiles.Add(startTile);

        processing.Enqueue(new TileDistancePair(0, startTile));


        // relax edges with minimum SP estimate
        while (processing.Count() > 0)
        {
            TileDistancePair temp             = processing.Dequeue();
            float            distanceEstimate = temp.d;
            Tile             node             = temp.t;
            if ((int)Math.Round(distanceEstimate) == node.distance)
            {
                foreach (Tile neighbour in node.adjacencyList)
                {
                    int newEstimate = node.distance + neighbour.movementCost;

                    if (neighbour.walkable && neighbour.distance > newEstimate && newEstimate <= movementRange)
                    {
                        if (!neighbour.occupied)
                        {
                            neighbour.selectable = true;
                            selectableTiles.Add(neighbour);
                        }
                        else
                        {
                            UnitsInSelectableRange.Add(neighbour);
                        }


                        neighbour.distance = newEstimate;
                        neighbour.parent   = node;
                        processing.Enqueue(new TileDistancePair(newEstimate, neighbour));
                    }
                }
            }
        }
    }
Esempio n. 2
0
    // selectable means that only selectable tiles will be added (for walking within the selectable tile zone)
    // playerTargeting means that the only occupied tile allowed will be the goal tile (to allow targeting of units)
    public static void GeneratePath(Map map, Tile start, Tile goal, bool selectable = false, bool playerTargeting = false)
    {
        var frontier = new PriorityQueue <TileDistancePair>();

        map.InitPathFinding(start);
        start.parent = null;

        frontier.Enqueue(new TileDistancePair(0, start));

        while (frontier.Count() > 0)
        {
            TileDistancePair temp    = frontier.Dequeue();
            Tile             current = temp.t;
            if (current.Equals(goal))
            {
                break;
            }

            foreach (Tile neighbour in current.adjacencyList)
            {
                int newEstimate = current.distance + neighbour.movementCost;

                if (neighbour.walkable && neighbour.distance > newEstimate) // && (!neighbour.occupied || (playerTargeting && neighbour == goal)) )
                {
                    // check if neighbour is selectable, if 'selectable' setting is activated
                    if (selectable && !neighbour.selectable && !map.UnitsInSelectableRange.Contains(neighbour))
                    {
                        continue;
                    }

                    neighbour.distance = newEstimate;
                    neighbour.parent   = current;
                    float priority = newEstimate + Heuristic(neighbour, goal);
                    frontier.Enqueue(new TileDistancePair(priority, neighbour));
                }
            }
        }
    }
Esempio n. 3
0
    // Need to write for all the targeting styles
    public bool PlayerTargetInAttackRange(Tile startTile, float attackRange, Unit player)
    {
        /*int[] hor = { -1, 0, 1, 0 };
         * int[] vert = { 0, 1, 0, -1 };
         *
         * int currX = startTile.gridPosition.x, currY = startTile.gridPosition.y;
         *
         * bool[] passable = new bool[4];
         *
         * for (int i = 0; i < 4; i++)
         * {
         *  passable[i] = true;
         * }
         *
         * for (int i = 1; i <= attackRange; i++)
         * {
         *  for (int j = 0; j < 4; j++)
         *  {
         *      int newX = currX + i * hor[j];
         *      int newY = currY + i * vert[j];
         *
         *      if (newX >= 0 && newX < mapSize.x && newY >= 0 && newY < mapSize.y)
         *      {
         *          Tile newTile = tileList[newX][newY];
         *          if (newTile.walkable && passable[j])
         *          {
         *              if (newTile == player.currentTile)
         *              {
         *                  return true;
         *              }
         *          }
         *          else
         *          {
         *              passable[j] = false;
         *          }
         *      }
         *  }
         * }*/

        PriorityQueue <TileDistancePair> processing = new PriorityQueue <TileDistancePair>();

        // Compute Adjacency List and reset all distances.
        InitPathFinding(startTile);

        attackableTiles.Add(startTile);

        processing.Enqueue(new TileDistancePair(0, startTile));

        // relax edges with minimum SP estimate
        while (processing.Count() > 0)
        {
            TileDistancePair temp             = processing.Dequeue();
            float            distanceEstimate = temp.d;
            Tile             node             = temp.t;
            if ((int)Math.Round(distanceEstimate) == node.distance)
            {
                foreach (Tile neighbour in node.adjacencyList)
                {
                    int newEstimate = node.distance + 1;

                    if (neighbour.walkable && neighbour.distance > newEstimate && newEstimate <= attackRange)
                    {
                        if (neighbour == player.currentTile)
                        {
                            return(true);
                        }
                        neighbour.attackable = true;
                        attackableTiles.Add(neighbour);
                        neighbour.distance = newEstimate;
                        processing.Enqueue(new TileDistancePair(newEstimate, neighbour));
                    }
                }
            }
        }
        return(false);
    }
Esempio n. 4
0
    public void FindAttackableTiles(Tile startTile, float attackRange, TargetingStyle targetingStyle = TargetingStyle.SINGLE)
    {
        #region Basic Targeting (Deprecated)

        /*if (targetingStyle == TargetingStyle.SINGLE || targetingStyle == TargetingStyle.MULTI || targetingStyle == TargetingStyle.SELFSINGLE)
         * {
         *  int[] hor = { -1, 0, 1, 0 };
         *  int[] vert = { 0, 1, 0, -1 };
         *
         *  int currX = startTile.gridPosition.x, currY = startTile.gridPosition.y;
         *
         *  bool[] passable = new bool[4];
         *  for (int i = 0; i < 4; i++)
         *  {
         *      passable[i] = true;
         *  }
         *
         *  for (int i = 1; i <= attackRange; i++)
         *  {
         *      for (int j = 0; j < 4; j++)
         *      {
         *          int newX = currX + i * hor[j];
         *          int newY = currY + i * vert[j];
         *
         *          if (newX >= 0 && newX < mapSize.x && newY >= 0 && newY < mapSize.y)
         *          {
         *              if (tileList[newX][newY].walkable && passable[j])
         *              {
         *                  tileList[newX][newY].attackable = true;
         *                  attackableTiles.Add(tileList[newX][newY]);
         *              }
         *              else
         *              {
         *                  passable[j] = false;
         *              }
         *          }
         *      }
         *  }
         * }*/
        #endregion

        #region Basic Targeting
        if (targetingStyle == TargetingStyle.SINGLE || targetingStyle == TargetingStyle.MULTI ||
            targetingStyle == TargetingStyle.SELFSINGLE)
        {
            PriorityQueue <TileDistancePair> processing = new PriorityQueue <TileDistancePair>();

            // Compute Adjacency List and reset all distances.
            InitPathFinding(startTile);

            attackableTiles.Add(startTile);

            processing.Enqueue(new TileDistancePair(0, startTile));

            // relax edges with minimum SP estimate
            while (processing.Count() > 0)
            {
                TileDistancePair temp             = processing.Dequeue();
                float            distanceEstimate = temp.d;
                Tile             node             = temp.t;
                if ((int)Math.Round(distanceEstimate) == node.distance)
                {
                    foreach (Tile neighbour in node.adjacencyList)
                    {
                        int newEstimate = node.distance + 1;

                        if (neighbour.walkable && neighbour.distance > newEstimate && newEstimate <= attackRange)
                        {
                            neighbour.attackable = true;
                            attackableTiles.Add(neighbour);
                            neighbour.distance = newEstimate;
                            processing.Enqueue(new TileDistancePair(newEstimate, neighbour));
                        }
                    }
                }
            }
        }
        #endregion

        #region Self Targeting
        if (targetingStyle == TargetingStyle.SELF || targetingStyle == TargetingStyle.SELFSINGLE)
        {
            startTile.attackable = true;
            attackableTiles.Add(startTile);
        }
        #endregion

        #region Radius Targeting
        if (targetingStyle == TargetingStyle.RADIUS)
        {
            // init Dijkstra
            PriorityQueue <TileDistancePair> processing = new PriorityQueue <TileDistancePair>();


            // Compute Adjacency List and reset all distances.
            InitPathFinding(startTile, true);

            attackableTiles.Add(startTile);

            processing.Enqueue(new TileDistancePair(0, startTile));

            // relax edges with minimum SP estimate
            while (processing.Count() > 0)
            {
                TileDistancePair temp             = processing.Dequeue();
                float            distanceEstimate = temp.d;
                Tile             node             = temp.t;
                if ((int)Math.Round(distanceEstimate) == node.distance)
                {
                    foreach (Tile neighbour in node.adjacencyList)
                    {
                        int newEstimate = node.distance + 1;

                        if (neighbour.walkable && neighbour.distance > newEstimate && newEstimate <= attackRange)
                        {
                            neighbour.attackable = true;
                            attackableTiles.Add(neighbour);
                            neighbour.distance = newEstimate;
                            processing.Enqueue(new TileDistancePair(newEstimate, neighbour));
                        }
                    }
                }
            }
        }
        #endregion

        #region Obstacle Targeting
        if (targetingStyle == TargetingStyle.OBSTACLES)
        {
            int[] hor  = { -1, 0, 1, 0 };
            int[] vert = { 0, 1, 0, -1 };

            int currX = startTile.gridPosition.x, currY = startTile.gridPosition.y;

            bool[] passable = new bool[4];
            for (int i = 0; i < 4; i++)
            {
                passable[i] = true;
            }

            for (int i = 1; i <= attackRange; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    int newX = currX + i * hor[j];
                    int newY = currY + i * vert[j];

                    if (newX >= 0 && newX < mapSize.x && newY >= 0 && newY < mapSize.y)
                    {
                        if (!tileList[newX][newY].walkable)
                        {
                            tileList[newX][newY].attackable = true;
                            attackableTiles.Add(tileList[newX][newY]);
                        }
                        else
                        {
                            passable[j] = false;
                        }
                    }
                }
            }
        }
        #endregion
    }