Example #1
0
    public override void Pick(PlanOfAttack plan)
    {
        int index           = Random.Range(0, pickers.Count);
        BaseAbilityPicker p = pickers[index];

        p.Pick(plan);
    }
    public override void Pick(PlanOfAttack plan)
    {
        plan.ability = Find(card);
        plan.target  = target;
        bool noNeedToHeal = true;

        if (plan.ability != null)
        {
            List <Tile> targets = new List <Tile>(GetComponentInParent <BattleController>().board.tiles.Values);
            foreach (Tile t in targets)
            {
                if (t.content != null && t.content.GetComponent <Alliance>().IsMatch(owner.GetComponent <Alliance>(), target) && plan.ability.GetComponent <AbilityEffectTarget>().IsTarget(t))
                {
                    if (!t.content.GetComponent <Health>().FullHP || t.content.GetComponent <Unit>().beingHealed)
                    {
                        noNeedToHeal = false;
                    }
                }
            }
        }

        if (noNeedToHeal)
        {
            plan.ability = null;
        }
    }
Example #3
0
    public PlanOfAttack Evaluate()
    {
        PlanOfAttack  poa     = new PlanOfAttack();
        AttackPattern pattern = actor.GetComponentInChildren <AttackPattern>();

        if (pattern)
        {
            pattern.Pick(poa);
        }
        else
        {
            DefaultAttackPattern(poa);
        }

        if (IsPositionIndependent(poa))
        {
            PlanPositionIndependent(poa);
        }
        else if (IsDirectionIndependent(poa))
        {
            PlanDirectionIndependent(poa);
        }
        else
        {
            PlanDirectionDependent(poa);
        }

        if (poa.ability == null)
        {
            MoveTowardOpponent(poa);
        }

        return(poa);
    }
Example #4
0
    //position and facing angle matter. checks every facing for best option
    void PlanDirectionDependent(PlanOfAttack poa)
    {
        Tile                startTile      = actor.tile;
        Directions          startDirection = actor.dir;
        List <AttackOption> list           = new List <AttackOption>();
        List <Tile>         moveOptions    = GetMoveOptions();

        for (int i = 0; i < moveOptions.Count; ++i)
        {
            Tile moveTile = moveOptions[i];
            actor.Place(moveTile);

            for (int j = 0; j < 4; ++j)
            {
                actor.dir = (Directions)j;
                AttackOption ao = new AttackOption();
                ao.target    = moveTile;
                ao.direction = actor.dir;
                RateFireLocation(poa, ao);
                ao.AddMoveTarget(moveTile);
                list.Add(ao);
            }
        }

        actor.Place(startTile);
        actor.dir = startDirection;
        PickBestOption(poa, list);
    }
Example #5
0
        private void PlanDirectionDependent(PlanOfAttack poa)
        {
            Tile        startTile      = actor.tile;
            Directions  startDirection = actor.dir;
            var         list           = new List <AttackOption>();
            List <Tile> moveOptions    = GetMoveOptions();

            // Loop on the move options (movement range)
            for (int i = 0; i < moveOptions.Count; ++i)
            {
                Tile moveTile = moveOptions[i];
                actor.Place(moveTile);

                // Loop on the directions.
                for (int j = 0; j < 4; ++j)
                {
                    actor.dir = (Directions)j;
                    var actionOption = new AttackOption();
                    actionOption.target    = moveTile;
                    actionOption.direction = actor.dir;
                    RateFireLocation(poa, actionOption);
                    actionOption.AddMoveTarget(moveTile);
                    list.Add(actionOption);
                }
            }

            // Place the actor back to the initial tile. If we didn't do this, the
            // AI would be out of sync with the visuals.
            actor.Place(startTile);
            actor.dir = startDirection;
            PickBestOption(poa, list);
        }
    void RateFireLocation(PlanOfAttack poa, AttackOption option)
    {
        if (poa.ability != null)
        {
            AbilityRange range = poa.ability.GetComponent <AbilityRange>();
            List <Tile>  tiles = range.GetTilesInRange(owner.board);
            option.targets = tiles;
            for (int i = 0; i < tiles.Count; ++i)
            {
                Tile tile = tiles[i];
                if (!poa.ability.GetComponent <AbilityEffectTarget>().IsTarget(tile))
                {
                    continue;
                }

                bool isMatch = IsAbilityTargetMatch(poa, tile);
                if (isMatch && poa.ability.GetComponent <BaseAbilityEffect>() is HealAbilityEffect)
                {
                    if (tile.content.GetComponent <Health>().FullHP)
                    {
                        option.AddMark(tile, false);
                        option.AddMark(tile, false);
                    }
                    else
                    {
                        option.AddMark(tile, isMatch);
                    }
                }
                option.AddMark(tile, isMatch);
            }
        }
    }
Example #7
0
        /// <summary>
        /// Sets the plan of attack's move location and fire location to
        /// a random position (within the possible move options).
        /// </summary>
        ///
        /// <param name="poa">The plan of attack.</param>
        private void PlanPositionIndependent(PlanOfAttack poa)
        {
            List <Tile> moveOptions = GetMoveOptions();
            Tile        tile        = moveOptions[Random.Range(0, moveOptions.Count)];

            poa.moveLocation = poa.fireLocation = tile.pos;
        }
Example #8
0
 public void Pick(PlanOfAttack plan)
 {
     pickers[index].Pick(plan);
     index++;
     if (index >= pickers.Count)
     {
         index = 0;
     }
 }
Example #9
0
    public PlanOfAttack Evaluate()
    {
        string       state;
        PlanOfAttack poa = new PlanOfAttack();

        poa.complete = false;
        state        = EvaluateState();
        if (actor.lastState != state)
        {
            actor.lastState = state;
            if (state == "Default")
            {
                bc.GetComponentInChildren <BattleMessageController>().Display(actor.name + " feels normal");
            }
            else if (state == "Shaken")
            {
                bc.GetComponentInChildren <BattleMessageController>().Display(actor.name + " feels shaken");
            }
            else if (state == "Emboldened")
            {
                bc.GetComponentInChildren <BattleMessageController>().Display(actor.name + " feels emboldened");
            }
            actor.transform.Find(state + " " + actor.GetComponentInChildren <Job>().name + " Attack Pattern").GetComponent <AttackPattern>().index = 0;
        }
        AttackPattern pattern = actor.transform.Find(state + " " + actor.GetComponentInChildren <Job>().name + " Attack Pattern").GetComponent <AttackPattern>();

        if (pattern)
        {
            pattern.Pick(poa);
        }
        else
        {
            DefaultAttackPattern(poa);
        }
        if (poa.complete == false)
        {
            if (IsPositionIndependent(poa))
            {
                PlanPositionIndependent(poa);
            }
            else if (IsDirectionIndependent(poa))
            {
                PlanDirectionIndependent(poa);
            }
            else
            {
                PlanDirectionDependent(poa);
            }

            if (poa.ability == null)
            {
                MoveTowardOpponent(poa);
            }
        }
        return(poa);
    }
    public override void Pick(PlanOfAttack finalPlan)
    {
        PlanOfAttack optionalPlan = new PlanOfAttack();
        PlanOfAttack plan         = new PlanOfAttack();

        for (int i = 0; i < pickers.Count; i++)
        {
            BaseAbilityPicker p = pickers[i];
            p.Pick(plan);
            cp.Evaluate(plan);
            if (plan.ability == null)
            {
                optionalPlan = plan;
                continue;
            }
            Debug.Log(plan.ability.name);
            Debug.Log(plan.unit.name);
            string    unit    = plan.unit.name;
            string    ability = plan.ability.name;
            Unit.Pair pair    = new Unit.Pair(unit, ability);
            if (owner.pairings.Contains(pair))
            {
                pair = (Unit.Pair)owner.pairings[owner.pairings.IndexOf(pair)];
            }
            else
            {
                owner.pairings.Add(pair);
                max         = pair.damage;
                abilityName = pair.ability;
            }
            if (pair.damage >= max)
            {
                max                       = pair.damage;
                abilityName               = pair.ability;
                finalPlan.ability         = plan.ability;
                finalPlan.target          = plan.target;
                finalPlan.moveLocation    = plan.moveLocation;
                finalPlan.fireLocation    = plan.fireLocation;
                finalPlan.attackDirection = plan.attackDirection;
                finalPlan.unit            = plan.unit;
            }
            bmc.Display("Current max: " + max + " by " + abilityName);
            StartCoroutine(Wait());
        }
        max = 0;
        if (finalPlan.ability == null)
        {
            finalPlan.ability         = optionalPlan.ability;
            finalPlan.target          = optionalPlan.target;
            finalPlan.moveLocation    = optionalPlan.moveLocation;
            finalPlan.fireLocation    = optionalPlan.fireLocation;
            finalPlan.attackDirection = optionalPlan.attackDirection;
            finalPlan.unit            = optionalPlan.unit;
        }
        finalPlan.complete = true;
    }
Example #11
0
 public override void Pick(PlanOfAttack plan)
 {
     plan.target  = target;
     plan.ability = Find(ability);
     if (plan.ability == null)
     {
         plan.ability = Default();
         plan.target  = Targets.Foe;
     }
 }
Example #12
0
 public void Change(Unit current)
 {
     actor        = current;
     hasUnitMoved = false;
     hasUnitActed = false;
     lockMove     = false;
     startTile    = actor.tile;
     startDir     = actor.dir;
     plan         = null;
 }
Example #13
0
    void PickBestOption(PlanOfAttack poa, List <AttackOption> list)
    {
        int bestScore = 1;
        List <AttackOption> bestOptions = new List <AttackOption>();

        for (int i = 0; i < list.Count; ++i)
        {
            AttackOption option = list[i];
            int          score  = option.GetScore(actor, poa.ability);
            if (score > bestScore)
            {
                bestScore = score;
                bestOptions.Clear();
                bestOptions.Add(option);
            }
            else if (score == bestScore)
            {
                bestOptions.Add(option);
            }
        }

        if (bestOptions.Count == 0)
        {
            poa.ability = null;             // Clear ability as a sign not to perform it
            return;
        }

        List <AttackOption> finalPicks = new List <AttackOption>();

        bestScore = 0;
        for (int i = 0; i < bestOptions.Count; ++i)
        {
            AttackOption option = bestOptions[i];
            int          score  = option.bestAngleBasedScore;
            if (score > bestScore)
            {
                bestScore = score;
                finalPicks.Clear();
                finalPicks.Add(option);
            }
            else if (score == bestScore)
            {
                finalPicks.Add(option);
            }
        }

        AttackOption choice = finalPicks[UnityEngine.Random.Range(0, finalPicks.Count)];

        poa.fireLocation = choice.target.pos;
        Debug.Log(choice.target.pos);
        poa.unit            = choice.target.content;
        poa.attackDirection = choice.direction;
        poa.moveLocation    = choice.bestMoveTile.pos;
    }
Example #14
0
 public override void Pick(PlanOfAttack plan)
 {
     for (int i = 0; i < pickers.Count; i++)
     {
         BaseCardPicker p = pickers[i];
         p.Pick(plan);
         if (plan.ability != null)
         {
             break;
         }
     }
 }
    public IEnumerator AIMoveSequence(PlanOfAttack attack)
    {
        Tile location = owner.board.GetTile(attack.moveLocation);

        if (location != null)
        {
            actor.acting = true;
            yield return(StartCoroutine(actor.GetComponent <Movement>().Traverse(location)));

            actor.acting = false;
        }
    }
    public IEnumerator AIAttackSequence(PlanOfAttack attack)
    {
        actor.acting = true;
        if (attack.ability.GetComponent <AbilityManaCost>().amount <= actor.GetComponent <Mana>().MP)
        {
            List <Tile> targets = attack.fireLocations;
            attack.ability.Perform(targets);
            yield return(StartCoroutine(AIReloadCardSequence(attack.ability)));
        }
        yield return(new WaitForSeconds(1 - (actor.GetComponent <Stats>()[StatTypes.DEX] * .02f)));

        yield return(new WaitForSeconds(AIThoughtLatency));

        actor.acting = false;
    }
    bool IsAbilityTargetMatch(PlanOfAttack poa, Tile tile)
    {
        bool isMatch = false;

        if (poa.target == Targets.Tile)
        {
            isMatch = true;
        }
        else if (poa.target != Targets.None)
        {
            Alliance other = tile.content.GetComponentInChildren <Alliance>();
            if (other != null && alliance.IsMatch(other, poa.target))
            {
                isMatch = true;
            }
        }
        return(isMatch);
    }
Example #18
0
        private void PlanDirectionIndependent(PlanOfAttack poa)
        {
            Tile         startTile    = actor.tile;
            var          map          = new Dictionary <Tile, AttackOption>();
            AbilityRange abilityRange = poa.ability.GetComponent <AbilityRange>();
            List <Tile>  moveOptions  = GetMoveOptions();

            // Loop on the move options (movement range).
            for (int i = 0; i < moveOptions.Count; ++i)
            {
                Tile moveTile = moveOptions[i];
                actor.Place(moveTile);
                List <Tile> fireOptions = abilityRange.GetTilesInRange(bc.board);

                // Loop on the fire options (ability range).
                for (int j = 0; j < fireOptions.Count; ++j)
                {
                    Tile         fireTile     = fireOptions[j];
                    AttackOption attackOption = null;
                    if (map.ContainsKey(fireTile))
                    {
                        attackOption = map[fireTile];
                    }
                    else
                    {
                        attackOption           = new AttackOption();
                        attackOption.target    = fireTile;
                        attackOption.direction = actor.dir;
                        map[fireTile]          = attackOption;
                        RateFireLocation(poa, attackOption);
                    }

                    attackOption.AddMoveTarget(moveTile);
                }
            }

            // Place the actor back to the initial tile. If we didn't do this, the
            // AI would be out of sync with the visuals.
            actor.Place(startTile);
            var list = new List <AttackOption>(map.Values);

            PickBestOption(poa, list);
        }
 void Update()
 {
     if (!AssessHand())
     {
         if (!actor.acting && !actor.beingHealed)
         {
             AIThoughtLatency = 1 / actor.GetComponent <Stats>()[StatTypes.WIS];
             PlanOfAttack plan = Evaluate();
             if (plan.fireLocations.Count > 0 && plan.ability != null && plan.moveLocation == actor.tile.pos)
             {
                 StartCoroutine(AIAttackSequence(plan));
             }
             else
             {
                 StartCoroutine(AIMoveSequence(plan));
             }
         }
     }
 }
Example #20
0
        private void RateFireLocation(PlanOfAttack poa, AttackOption attackOption)
        {
            AbilityArea area  = poa.ability.GetComponent <AbilityArea>();
            List <Tile> tiles = area.GetTilesInArea(bc.board, attackOption.target.pos);

            attackOption.areaTargets   = tiles;
            attackOption.isCasterMatch = IsAbilityTargetMatch(poa, actor.tile);

            for (int i = 0; i < tiles.Count; ++i)
            {
                Tile tile = tiles[i];
                if (actor.tile == tiles[i] || !poa.ability.IsTarget(tile))
                {
                    continue;
                }

                bool isMatch = IsAbilityTargetMatch(poa, tile);
                attackOption.AddMark(tile, isMatch);
            }
        }
    void MoveTowardOpponent(PlanOfAttack poa)
    {
        List <Tile> moveOptions = GetMoveOptions();

        FindNearestFoe();
        if (nearestFoe != null)
        {
            Tile toCheck = nearestFoe.tile;
            while (toCheck != null)
            {
                if (moveOptions.Contains(toCheck))
                {
                    poa.moveLocation = toCheck.pos;
                    return;
                }
                toCheck = toCheck.prev;
            }
        }
        poa.moveLocation = actor.tile.pos;
    }
Example #22
0
    public PlanOfAttack Evaluate(PlanOfAttack poa)
    {
        if (IsPositionIndependent(poa))
        {
            PlanPositionIndependent(poa);
        }
        else if (IsDirectionIndependent(poa))
        {
            PlanDirectionIndependent(poa);
        }
        else
        {
            PlanDirectionDependent(poa);
        }

        if (poa.ability == null)
        {
            MoveTowardOpponent(poa);
        }
        return(poa);
    }
Example #23
0
        /// <summary>
        /// Determines if the ability target's is a match (should use ability).
        /// </summary>
        ///
        /// <param name="poa">The plan of attack.</param>
        /// <param name="tile">The tile to check.</param>
        ///
        /// <returns>True if the ability target's is a match , False otherwise.</returns>
        private bool IsAbilityTargetMatch(PlanOfAttack poa, Tile tile)
        {
            bool isMatch = false;

            // If the target is a Tile, it's automatically a match.
            if (poa.target == Targets.Tile)
            {
                isMatch = true;
            }
            // If the target is a Unit (Ally, Foe, Self), use the unit's alliance
            // to determine if it's a match.
            else if (poa.target != Targets.None)
            {
                Alliance other = tile.content.GetComponentInChildren <Alliance>();
                if (other != null && alliance.IsMatch(other, poa.target))
                {
                    isMatch = true;
                }
            }

            return(isMatch);
        }
Example #24
0
    void PlanDirectionIndependent(PlanOfAttack poa)
    {
        Tile startTile = actor.tile;
        Dictionary <Tile, AttackOption> map = new Dictionary <Tile, AttackOption>();
        AbilityRange ar          = poa.ability.GetComponent <AbilityRange>();
        List <Tile>  moveOptions = GetMoveOptions();

        for (int i = 0; i < moveOptions.Count; ++i)
        {
            Tile moveTile = moveOptions[i];
            actor.Place(moveTile);
            List <Tile> fireOptions = ar.GetTilesInRange(bc.board);

            for (int j = 0; j < fireOptions.Count; ++j)
            {
                Tile         fireTile = fireOptions[j];
                AttackOption ao       = null;
                if (map.ContainsKey(fireTile))
                {
                    ao = map[fireTile];
                }
                else
                {
                    ao            = new AttackOption();
                    map[fireTile] = ao;
                    ao.target     = fireTile;
                    ao.direction  = actor.dir;
                    RateFireLocation(poa, ao);
                }

                ao.AddMoveTarget(moveTile);
            }
        }

        actor.Place(startTile);
        List <AttackOption> list = new List <AttackOption>(map.Values);

        PickBestOption(poa, list);
    }
Example #25
0
    public PlanOfAttack Evaluate()
    {
        // create and fill out a plan of attack
        PlanOfAttack poa = new PlanOfAttack();

        // step 1: what ability to use
        AttackPattern pattern = actor.GetComponentInChildren <AttackPattern>();

        if (pattern)
        {
            pattern.Pick(poa);
        }
        else
        {
            DefaultAttackPattern(poa);
        }

        // step 2: where to move and aim to best use
        if (IsPositionIndependent(poa))
        {
            PlanPositionIndependent(poa);
        }
        else if (IsDirectionIndependent(poa))
        {
            PlanDirectionIndependent(poa);
        }
        else
        {
            PlanDirectionDependent(poa);
        }

        if (poa.ability == null)
        {
            MoveTowardOpponent(poa);
        }

        // return plan
        return(poa);
    }
Example #26
0
    // Create and fill out a plan of attack
    public PlanOfAttack Evaluate()
    {
        PlanOfAttack poa = new PlanOfAttack();

        // Step 1: Decide what ability to use
        AttackPattern pattern = actor.GetComponentInChildren <AttackPattern>();

        if (pattern)
        {
            pattern.Pick(poa);
        }
        else
        {
            DefaultAttackPattern(poa);
        }

        // Step 2: Determine where to move and aim to best use the ability
        if (IsPositionIndependent(poa))
        {
            PlanPositionIndependent(poa);
        }
        else if (IsDirectionIndependent(poa))
        {
            PlanDirectionIndependent(poa);
        }
        else
        {
            PlanDirectionDependent(poa);
        }

        if (poa.ability == null)
        {
            MoveTowardOpponent(poa);
        }

        // Return the completed plan
        return(poa);
    }
Example #27
0
        public PlanOfAttack Evaluate()
        {
            var           poa     = new PlanOfAttack();
            AttackPattern pattern = actor.GetComponentInChildren <AttackPattern>();

            if (pattern)
            {
                pattern.Pick(poa);
            }
            else
            {
                // TODO: Remove default pattern and throw instead?
                DefaultAttackPattern(poa);
            }

            if (IsPositionIndependent(poa))
            {
                PlanPositionIndependent(poa);
            }
            else if (IsDirectionIndependent(poa))
            {
                PlanDirectionIndependent(poa);
            }
            else
            {
                PlanDirectionDependent(poa);
            }

            if (poa.ability == null)
            {
                // TODO: Flee if low HP.
                MoveTowardOpponent(poa);
            }


            return(poa);
        }
Example #28
0
 public abstract void Pick(PlanOfAttack plan);
Example #29
0
 /// <summary>
 /// Sets the default attack pattern on the plan of attack.
 ///
 /// @todo What if the the actor has no ability?
 /// </summary>
 ///
 /// <param name="poa">The plan of attack.</param>
 private void DefaultAttackPattern(PlanOfAttack poa)
 {
     poa.ability = actor.GetComponentInChildren <Ability>();
     poa.target  = Targets.Foe;
 }
Example #30
0
        /// <summary>
        /// Determines if the plan of attack's ability is direction independent.
        /// </summary>
        ///
        /// <param name="poa">The plan of attack.</param>
        ///
        /// <returns>True if the ability is direction independent, False otherwise.</returns>
        private bool IsDirectionIndependent(PlanOfAttack poa)
        {
            var range = poa.ability.GetComponent <AbilityRange>();

            return(!range.directionOriented);
        }