Exemple #1
0
    // Checks for each unit to see if it could potentially be reached, and if so adds to the lists.
    private void ScanForUnits()
    {
        //@todo Unit scan doesn't consider "faction" yet, in case you want to use it for player-friendly units as well
        Unit currentUnit = unitManager.currentTurnUnit;

        int maxDistance = currentUnit.unitStats.movementDistance + 6;           //@todo Replace the +6 with the longest-range ability the unit has

        // Getting Friendly units
        //@todo only do so if the current AI unit has beneficial spells that can be cast on allies; do so during the
        foreach (Unit attemptUnit in unitManager.tempEnemyUnitList)
        {
            if (currentUnit.Equals(attemptUnit))                // If the unit is itself
            {
                self = new OtherUnit(attemptUnit, 0, null, true);
                friendlyUnits.Add(self);
                continue;
            }

            int unitDistance = LandTileMap.instance.GetTileDistance(currentUnit.currentTile, attemptUnit.currentTile);
            if (maxDistance >= unitDistance)
            {
                OtherUnit otherUnit;

                LandTile [] pathTowards = LandTileMap.instance.RequestPath(currentUnit.currentTile, attemptUnit.currentTile, currentUnit.unitStats.canMoveDiagonally, false);
                if (pathTowards.Length != 0 && pathTowards.Length <= currentUnit.unitStats.movementDistance)
                {
                    otherUnit = new OtherUnit(attemptUnit, unitDistance, pathTowards, true);
                }
                else                        // No path or out of our movement range means there's no walkable path
                {
                    otherUnit = new OtherUnit(attemptUnit, unitDistance, pathTowards);
                }

                friendlyUnits.Add(otherUnit);
            }
        }

        // Getting Hostile units
        foreach (Unit attemptUnit in unitManager.tempFriendlyUnitList)
        {
            int unitDistance = LandTileMap.instance.GetTileDistance(currentUnit.currentTile, attemptUnit.currentTile);
            if (maxDistance >= unitDistance)
            {
                OtherUnit otherUnit;

                LandTile [] pathTowards = LandTileMap.instance.RequestPath(currentUnit.currentTile, attemptUnit.currentTile, currentUnit.unitStats.canMoveDiagonally, false);
                if (pathTowards.Length != 0 && pathTowards.Length <= currentUnit.unitStats.movementDistance)
                {
                    otherUnit = new OtherUnit(attemptUnit, unitDistance, pathTowards, true);
                }
                else                        // No path or out of our movement range means there's no walkable path
                {
                    otherUnit = new OtherUnit(attemptUnit, unitDistance, pathTowards);
                }

                enemyUnits.Add(otherUnit);
            }
        }
    }
Exemple #2
0
    public AIAttackAction(OtherUnit targetUnit, int score, LandTile tileToMoveTo = null)
    {
        this.targetUnit = targetUnit;
        this.score      = score;

        if (tileToMoveTo == null)
        {
            return;
        }
        this.tileToMoveTo = tileToMoveTo;
        requiresMovement  = true;
    }
Exemple #3
0
    public AIAbilityAction(OtherUnit targetUnit, Ability abilityToUse, int score, LandTile tileToMoveTo = null)
    {
        this.targetUnit   = targetUnit;
        this.abilityToUse = abilityToUse;
        this.score        = score;

        if (tileToMoveTo == null)
        {
            return;
        }
        this.tileToMoveTo = tileToMoveTo;
        requiresMovement  = true;
    }
Exemple #4
0
    private LandTile FindPointToMoveTo()
    {
        //@todo Does adding a "is being threatened" tag to tiles improve this performance-wise?
        //@todo Has the option of returning its current position

        Unit currentUnit = unitManager.currentTurnUnit;

        LandTile [] possibleTiles = LandTileMap.instance.RequestRange(currentUnit.transform.position, currentUnit.unitStats.movementDistance, currentUnit.unitStats.canMoveDiagonally, true, false, false);
        if (possibleTiles.Length == 0)
        {
            return(null);
        }

        LandTile tileToMoveTo = null;

        if (enemyUnits.Count != 0)
        {
            // Am I ranged/wizard? Move away from closest target
            //@todo Find way of recognizing spellcasters/healers etc. Could be class-based, but not preferable. If Intelligence>Attack?
            if (currentUnit.unitStats.attackRange > 1 || currentUnit.unitStats.intelligence > currentUnit.unitStats.attackPower)
            {
                int [] tileScores  = new int [possibleTiles.Length];
                int    lowestValue = 9999;
                int    lowestIndex = 0;

                for (int i = 0; i < possibleTiles.Length; i++)                      // Calculates the 'safest' spot by adding up the tile's distance to each enemy and picking the lowest
                {
                    foreach (OtherUnit enemy in enemyUnits)                         //@todo Better ways to do this?
                    {
                        tileScores [i] += LandTileMap.instance.GetTileDistance(currentUnit.currentTile, enemy.unit.currentTile);
                        if (tileScores [i] < lowestValue)
                        {
                            lowestValue = tileScores [i];
                            lowestIndex = i;
                        }
                    }
                }

                return(tileToMoveTo = possibleTiles [lowestIndex]);
            }

            int       lowestHealth      = 9999;
            OtherUnit lowestHealthEnemy = null;
            // Scan for lowest health enemy, move towards that one
            foreach (OtherUnit enemy in enemyUnits)
            {
                if (enemy.canReach && enemy.unit.unitStats.currentHealth < lowestHealth)
                {
                    LandTile testingTile = enemy.pathToTarget [Mathf.Clamp(enemy.pathToTarget.Length - 2, 0, enemy.pathToTarget.Length - 1)];
                    if ((possibleTiles.Contains <LandTile> (testingTile) || currentUnit.currentTile == testingTile) && testingTile.unitOnTile == null)
                    {
                        lowestHealthEnemy = enemy;
                        lowestHealth      = enemy.unit.unitStats.currentHealth;
                    }
                }
            }
            if (lowestHealthEnemy != null)
            {
                if (LandTileMap.instance.GetTileDistance(currentUnit.currentTile, lowestHealthEnemy.unit.currentTile) < currentUnit.unitStats.attackRange)
                {
                    return(null);                       // if we're already in range of the lowest health unit; we don't have to move.
                }
                else
                {
                    return(tileToMoveTo = lowestHealthEnemy.pathToTarget [Mathf.Clamp(lowestHealthEnemy.pathToTarget.Length - 2, 0, lowestHealthEnemy.pathToTarget.Length)]);
                }
            }

            // If there were no possible enemies to path to, move in the general direction of one
            //@todo doesn't consider movement costs yet
            if (tileToMoveTo == null)
            {
                for (int i = 0; i < enemyUnits.Count - 1; i++)
                {
                    int random = Random.Range(i, enemyUnits.Count);
                    if (enemyUnits [random].pathToTarget != null && enemyUnits[random].pathToTarget.Length != 0)
                    {
                        tileToMoveTo = enemyUnits [random].pathToTarget [Mathf.Clamp(currentUnit.unitStats.movementDistance, 0, enemyUnits [random].pathToTarget.Length - 1)];

                        break;
                    }
                }
            }
        }

        // If all else fails, pick a random tile within movement range
        if (tileToMoveTo == null)
        {
            tileToMoveTo = possibleTiles [Random.Range(0, possibleTiles.Length - 1)];
        }

        return(tileToMoveTo);
    }