Esempio n. 1
0
 /// <summary>
 /// Finds Hexes in given min and max radius from center.
 /// </summary>
 /// <param name="centerHex">Start hex.</param>
 /// <param name="minRange">Min. Range to search.</param>
 /// <param name="maxRange">Max. Range to search.</param>
 /// <returns>Enumarates and returns found HexTiles.</returns>
 public IEnumerable <HexTile> HexesInRange(HexCoord centerHex, int minRange, int maxRange)
 {
     for (int r = Mathf.Max(centerHex.r - maxRange, 0); r <= Mathf.Min(centerHex.r + maxRange, _hexGrid.Length - 1);
          r++)
     {
         int calculatedQ = (centerHex.q + r / 2);
         for (int q = Mathf.Max(calculatedQ - maxRange, 0);
              q <= Mathf.Min(calculatedQ + maxRange, _hexGrid[r].Length - 1); q++)
         {
             //if (!IsCordinateValid(q, r)) continue;
             HexTile tempHex = GetHexTileDirect(q, r);
             if (centerHex != tempHex.Coord)
             {
                 float distance = Mathf.Abs(HexCoord.Distance(centerHex, tempHex.Coord));
                 if (distance <= maxRange && distance >= minRange)
                 {
                     yield return(tempHex);
                 }
             }
         }
     }
 }
    /// <summary>
    /// To be called, when a Hex is clicked while the game is in Battle state.
    /// Processes and decides how the input should be handled.
    /// </summary>
    /// <param name="targetHex"></param>
    private void OnHexClickedBattle(HexTile targetHex)
    {
        if (!_selectedUnit)
        {
            SelectHex(targetHex);
            return;
        }

        //Still animating.
        if (_activeUnit.IsBusy || _activeUnit.IsAnySkillBusy)
        {
            return;
        }

        if (targetHex.IsOccupied)
        {
            HexUnit occupyingUnit = targetHex.OccupyingObject.GetComponent <HexUnit>();

            if (occupyingUnit)
            {
                //Ability will handle it.
                if (_hexTileCache.Contains(CACHE_DIRECT_ACTION, targetHex))
                {
                    //Deactivate normal attacks to prevent double cast.
                    if (_activeUnit.MeleeAttack)
                    {
                        _activeUnit.MeleeAttack.Deactivate();
                    }
                    if (_activeUnit.RangedAttack)
                    {
                        _activeUnit.RangedAttack.Deactivate();
                    }
                    return;
                }

                if (_hexTileCache.Contains(CACHE_DIRECT_ATTACK, targetHex))
                {
                    //Deactivate active ability to prevent double cast.
                    Ability activeSkill = _activeUnit.ActiveSkill();
                    if (activeSkill)
                    {
                        activeSkill.Deactivate();
                    }

                    if (_activeUnit.RangedAttack)
                    {
                        if (HexCoord.Distance(targetHex.Coord, _selectedHex.Coord) > 1)
                        {
                            _activeUnit.MeleeAttack.Deactivate();
                            _activeUnit.RangedAttack.ActivateAutoCast(occupyingUnit.gameObject);
                            return;
                        }
                        _activeUnit.RangedAttack.Deactivate();
                    }
                    _activeUnit.MeleeAttack.ActivateAutoCast(occupyingUnit.gameObject);
                    return;
                }

                //Look if we can melee attack with movement.
                //Only check cached attack tuples found with Breadth First Search.
                List <HexCoord> shortestPath = null;
                foreach (Tuple <HexTile, HexTile> tuple in _cachedMoveActions.Where(c => c.second == targetHex))
                {
                    List <HexCoord> path = _pathGraphSearch.GetShortestPath(_selectedHex.Coord, tuple.first.Coord);
                    if (shortestPath == null)
                    {
                        shortestPath = path;
                    }
                    else if (shortestPath.Count > path.Count)
                    {
                        shortestPath = path;
                    }

                    //Can't find a shorter path, early exit.
                    if (shortestPath.Count == 1)
                    {
                        break;
                    }
                }
                if (shortestPath != null && shortestPath.Count > 0)
                {
                    _queuedActions.Enqueue(() => _activeUnit.MeleeAttack.ActivateAutoCast(occupyingUnit.gameObject));
                    _activeUnit.Move(_selectedHex, shortestPath, _hexGrid);
                    return;
                }
            }
            SelectHex(targetHex);
        }
        else
        {
            //If we can move there, move.
            if (_hexTileCache.Contains(CACHE_MOVES, targetHex))
            {
                //Deactivate active ability to prevent double cast.
                Ability activeSkill = _activeUnit.ActiveSkill();
                if (activeSkill)
                {
                    activeSkill.Deactivate();
                }
                //Deactivate normal attacks to prevent double cast.
                if (_activeUnit.MeleeAttack)
                {
                    _activeUnit.MeleeAttack.Deactivate();
                }
                if (_activeUnit.RangedAttack)
                {
                    _activeUnit.RangedAttack.Deactivate();
                }

                List <HexCoord> path = _pathGraphSearch.GetShortestPath(_selectedHex.Coord, targetHex.Coord);
                if (path != null && path.Count > 0)
                {
                    _activeUnit.Move(_selectedHex, path, _hexGrid);
                }
            }
            else
            {
                SelectHex(targetHex);
            }
        }
    }