private PlanOfAction UseEarthSpike(List <PathfindingData> tilesOnBoard, PathfindingData targetData)
    {
        var earthSpike = abilityComponent.EquippedAbilities
                         .Find(ability => ability.DisplayName == "Earth Spike");

        if (!abilityComponent.SetCurrentAbility(earthSpike))
        {
            return(null);
        }

        var tilesInRange = abilityComponent.GetTilesInRange();

        PathfindingData target = null;

        foreach (var data in tilesInRange)
        {
            if (data.tile == targetData.tile)
            {
                target = data;
                break;
            }
        }

        return(new PlanOfAction(earthSpike, target, Targets.Enemy, tilesInRange));
    }
    public override UnitState HandleInput(Controller controller)
    {
        var swappedAbility = SwapActiveAbility(controller);

        if (swappedAbility != null)
        {
            BoardVisuals.RemoveTilesFromHighlightsByUnit(Owner);
            CleanIndicator();
            return(swappedAbility);
        }

        List <PathfindingData> tilesInRange = GetTilesInRange();

        // handling a special case where the targetting is programmatic.
        // will ecentually need to accomodate for this in a more robust way using OOP
        if (abilityComponent.CurrentAbility.AutoTargets)
        {
            PathfindingData autoTarget = tilesInRange.FirstOrDefault(
                element => element.tile.IsOccupied() && element.tile.OccupiedBy.GetComponent <Monster> ()
                );

            if (autoTarget == null)
            {
                AudioComponent.PlaySound(Sounds.ERROR);
                onAbilityCanceled();
                return(new PlayerIdleState(Owner));
            }

            if (Owner.EnergyComponent.AdjustEnergy(-abilityComponent.CurrentAbility.EnergyCost) &&
                abilityComponent.PrepAbility(tilesInRange, autoTarget))
            {
                onAbilityCommited(Owner, abilityComponent.IndexOfCurrentAbility());
                return(new PlayerActingState(Owner, tilesInRange, autoTarget));
            }
        }

        Point mousePosition = BoardUtility.mousePosFromScreenPoint();

        HighlightTiles(tilesInRange, mousePosition);

        // user clicks on a walkable tile which is in range....
        if (controller.DetectInputFor(ControlTypes.CONFIRM))
        {
            PathfindingData selectedTarget = tilesInRange.Find(
                element => element.tile.Position == mousePosition
                );

            // transition to acting state if it's a valid selection
            // and we successfully prep our ability for use
            bool targetIsValid = selectedTarget != null && selectedTarget.tile.isWalkable;
            if (targetIsValid && Owner.EnergyComponent.AdjustEnergy(-abilityComponent.CurrentAbility.EnergyCost) &&
                abilityComponent.PrepAbility(tilesInRange, selectedTarget))
            {
                onAbilityCommited(Owner, abilityComponent.IndexOfCurrentAbility());
                return(new PlayerActingState(Owner, tilesInRange, selectedTarget));
            }
        }

        return(null);
    }
Exemple #3
0
 public AIActingState(Unit Owner,
                      List <PathfindingData> tilesInRange, PathfindingData targetTile) : base(Owner)
 {
     this.tilesInRange     = tilesInRange;
     this.targetTile       = targetTile;
     this.abilityComponent = Owner.AbilityComponent;
 }
    private PlanOfAction MoveTowardsPlayer(List <PathfindingData> tilesOnBoard, PathfindingData targetData,
                                           List <PathfindingData> tilesFromPlayerPerspective)
    {
        // find my move range
        var movementAbility = abilityComponent.EquippedAbilities
                              .Find(ability => ability is MovementAbility);

        if (!abilityComponent.SetCurrentAbility(movementAbility))
        {
            return(null);
        }
        var tilesInRange = abilityComponent.GetTilesInRange();

        // Find all tiles a certain distance from the player
        var orderedPossibilities = tilesFromPlayerPerspective.OrderByDescending(data => data.shadow.distance).ToList();

        // find the first available move target
        PathfindingData moveTarget = FindFirstAvailable(tilesInRange, targetData, orderedPossibilities);

        if (moveTarget == null)
        {
            Debug.LogError("never found a valid target");
            return(null);
        }

        return(new PlanOfAction(movementAbility, moveTarget, Targets.Tile, tilesInRange));
    }
    private PlanOfAction Move(List <PathfindingData> tilesOnBoard, PathfindingData targetData,
                              List <PathfindingData> tilesFromPlayerPerspective, bool moveAway, bool checkSameAxis = true)
    {
        // find my move range
        var movementAbility = abilityComponent.EquippedAbilities
                              .Find(ability => ability is MovementAbility);

        if (!abilityComponent.SetCurrentAbility(movementAbility))
        {
            return(null);
        }
        var tilesInRange = abilityComponent.GetTilesInRange();

        // Find all tiles a certain distance from the player
        // cannot use Linq or it would lose the linkedlist of prev tile
        var orderedPossibilities = moveAway ?
                                   tilesFromPlayerPerspective.OrderBy(data => data.shadow.distance).ToList() :
                                   tilesFromPlayerPerspective.OrderByDescending(data => data.shadow.distance).ToList();

        // find the first available move target
        PathfindingData moveTarget = FindFirstAvailable(tilesInRange, targetData, orderedPossibilities, checkSameAxis);

        if (moveTarget == null)
        {
            Debug.LogError("never found a valid target");
            return(null);
        }

        return(new PlanOfAction(movementAbility, moveTarget, Targets.Tile, tilesInRange));
    }
 public PlanOfAction(Ability ability, List <PathfindingData> affectedTiles, PathfindingData targetLocation, Targets targetType, List <PathfindingData> tilesInRange)
 {
     this.ability        = ability;
     this.targetLocation = targetLocation;
     this.affectedTiles  = affectedTiles;
     this.targetType     = targetType;
     this.tilesInRange   = tilesInRange;
 }
 /// <summary>
 /// Initialize tile.
 /// </summary>
 /// <param name="world">World the tile is being initialized into.</param>
 /// <param name="renderer">SpriteRenderer of the tile.</param>
 public void Initialize(World world, SpriteRenderer renderer)
 {
     World           = world;
     Renderer        = renderer;
     MovementPenalty = 1f;
     Unit            = null;
     Pathfinding     = new PathfindingData();
 }
Exemple #8
0
 /// <summary>
 /// Node Constructor
 /// </summary>
 /// <param name="label">Label, or name of the node</param>
 /// <param name="x">x position of the node in the graph.</param>
 /// <param name="y">y position of the node in the graph</param>
 /// <param name="hex">GameObject hexagon associated with this node.</param>
 /// <param name="navigability">The navigability of the node</param>
 public Node(string label, int x, int y, GameObject hex, nodeTypes navigability)
 {
     this.label        = label;
     this.x            = x;
     this.y            = y;
     this.hex          = hex;
     this.navigability = navigability;
     this.searchData   = new PathfindingData(null, 0, 0, 0);
 }
    private PlanOfAction CloseRangePlan(List <PathfindingData> tilesOnBoard, PathfindingData targetData, List <PathfindingData> tilesFromPlayerPerspective)
    {
        // 1: 3/10 times move toward player, 7/10 use shockwave
        var seed = UnityEngine.Random.Range(0, 11);

        if (seed < 3)
        {
            return(MoveTowardsPlayer(tilesOnBoard, targetData, tilesFromPlayerPerspective));
        }
        else
        {
            return(UseShockwave(tilesOnBoard, targetData));
        }
    }
    private PlanOfAction LongRangePlan(List <PathfindingData> tilesOnBoard, PathfindingData targetData,
                                       List <PathfindingData> tilesFromPlayerPerspective)
    {
        // 2: 2/10 move towards player, 8/10 times use earth spike
        var seed = UnityEngine.Random.Range(0, 11);

        if (seed < 2)
        {
            return(MoveTowardsPlayer(tilesOnBoard, targetData, tilesFromPlayerPerspective));
        }
        else
        {
            return(UseEarthSpike(tilesOnBoard, targetData));
        }
    }
    private PathfindingData FindFirstAvailable(List <PathfindingData> tilesInRange,
                                               PathfindingData targetData, List <PathfindingData> ordered, bool checkSameAxis = false)
    {
        PathfindingData moveTarget  = null;
        var             prioritized = ordered.FindAll(data => data.tile.Position.x == targetData.tile.Position.x || data.tile.Position.y == targetData.tile.Position.y);

        if (checkSameAxis)
        {
            moveTarget = CheckXYAxis(tilesInRange, moveTarget, prioritized, targetData.tile);
        }
        if (moveTarget == null)
        {
            moveTarget = CheckRestOfPool(tilesInRange, ordered, moveTarget, targetData.tile);
        }

        return(moveTarget);
    }
    private PathfindingData FindFirstAvailable(List <PathfindingData> tilesInRange,
                                               PathfindingData targetData, List <PathfindingData> ordered)
    {
        PathfindingData moveTarget = null;

        foreach (var item in ordered)
        {
            for (int i = 0; i < tilesInRange.Count; i++)
            {
                if (tilesInRange[i].tile == item.tile)
                {
                    moveTarget = tilesInRange[i];
                    break;
                }
            }
        }

        return(moveTarget);
    }
    private PathfindingData CheckXYAxis(List <PathfindingData> tilesInRange, PathfindingData moveTarget, List <PathfindingData> prioritized, Tile playerTile)
    {
        foreach (var item in prioritized)
        {
            for (int i = 0; i < tilesInRange.Count; i++)
            {
                if (tilesInRange[i].tile == item.tile && item.shadow.distance >= minDistance)
                {
                    if (owner.Board.Pathfinding.GetUnobstructedDistance(playerTile, item.tile) == item.shadow.distance)
                    {
                        moveTarget = tilesInRange[i];
                        break;
                    }
                }
            }
        }

        return(moveTarget);
    }
    private PlanOfAction Attack(List <PathfindingData> tilesOnBoard, PathfindingData targetData, List <PathfindingData> tilesFromPlayerPerspective)
    {
        var attackAbility = abilityComponent.EquippedAbilities
                            .Find(ability => ability is AttackAbility);

        if (!abilityComponent.SetCurrentAbility(attackAbility))
        {
            return(null);
        }
        var tilesInRange = abilityComponent.GetTilesInRange();

        for (int i = 0; i < tilesInRange.Count; i++)
        {
            if (tilesInRange[i].tile == targetData.tile)
            {
                return(new PlanOfAction(attackAbility, tilesInRange[i], Targets.Enemy, tilesInRange));
            }
        }

        return(null);
    }
 private bool WithinShockwaveRange(List <PathfindingData> tilesOnBoard, PathfindingData targetData)
 {
     return(targetData.shadow.distance <= shockwaveRange);
 }
 private bool WeOccupyTheSameAxis(List <PathfindingData> tilesOnBoard, PathfindingData targetData)
 {
     return(owner.Position.x == targetData.tile.Position.x || owner.Position.y == targetData.tile.Position.y);
 }
 private bool ThereAreNoObstacles(List <PathfindingData> tilesOnBoard, PathfindingData targetData)
 {
     return(owner.Board.Pathfinding.GetUnobstructedDistance(owner.Board.TileAt(owner.Position), targetData.tile) == targetData.shadow.distance);
 }
 bool WeAreTooClose(List <PathfindingData> tilesOnBoard, PathfindingData targetData)
 {
     return(targetData.shadow.distance < minDistance);
 }
    private PathfindingData CheckRestOfPool(List <PathfindingData> tilesInRange, List <PathfindingData> ordered, PathfindingData moveTarget, Tile playerTile)
    {
        foreach (var item in ordered)
        {
            for (int i = 0; i < tilesInRange.Count; i++)
            {
                if (tilesInRange[i].tile == item.tile && item.shadow.distance >= minDistance)
                {
                    moveTarget = tilesInRange[i];
                    break;
                }
            }
        }

        return(moveTarget);
    }
 private bool CanAttack(List <PathfindingData> tilesOnBoard, PathfindingData targetData)
 {
     return(targetData.shadow.distance == 1);
 }