Beispiel #1
0
 public void DetectedEnemy(Creature target)
 {
     if (!CombatManager.Instance.CombatMode)
     {
         _creature.SetTargetCreature(target);
         _instigator = true;
         _creature.InitiateCombat();
     }
     else
     {
         CombatManager.AddToCombat(_creature);
     }
 }
Beispiel #2
0
    protected virtual IEnumerator RunCombatLogicTree()
    {
        switch (_currentState)
        {
        case State.Fleeing:
            GetPath();
            yield return(_creature.AIMoveCreature());

            _creature.EndTurn();
            yield break;

        case State.Dead:
            yield break;

            /*case State.Idle:
             * case State.Wander:
             * case State.Patrol:
             * case State.Guard:
             * case State.Chase:
             * default:
             *  break;*/
        }

        if (WantsToHeal())
        {
            var healed = TryToHeal();
            if (!healed && HealthVeryLow())
            {
                _currentState = State.Fleeing;
                GetPath();
                yield return(_creature.AIMoveCreature());

                _creature.EndTurn();
            }
            else if (healed)
            {
                yield return(_creature.AnimController.UseAnimWait);
            }
        }

        if (_aggression == Aggression.Hostile)
        {
            var chanceToHit = _creature.GetChanceToHit(1, Player.Instance);
            if (chanceToHit < MINCHANCETOHIT)
            {
                _currentState = State.Fleeing;
                GetPath();
                yield return(_creature.AIMoveCreature());

                _creature.EndTurn();
                yield break;
            }
        }

        var foundTarget  = false;
        var distToTarget = 0;

        if (_instigator)
        {
            _targetCreature = _creature.TargetCreature;
            distToTarget    = HexMaker.Instance.GetDistanceToCoord(_creature.Coord, _targetCreature.Coord,
                                                                   _creature.TargetPath, wantToMove: false);
            CombatManager.AddToCombat(_targetCreature);
            foundTarget = true;
        }
        else
        {
            foundTarget = TryGetTarget(out distToTarget);
        }

        if (!foundTarget)
        {
            _creature.EndTurn();
            yield break;
        }

        //If not possible for AI to get to target
        if (distToTarget < 0)
        {
            _currentState = State.Fleeing;
            GetPath();
            yield return(_creature.AIMoveCreature());

            _creature.EndTurn();
            yield break;
        }

        var weaponInfo = _creature.GetAttackTypeInfo();
        var path       = _creature.TargetPath.ToArray();

        _creature.TargetPath.Clear();
        var dist = distToTarget - weaponInfo.Range;

        for (var i = 0; i < path.Length; i++)
        {
            _creature.TargetPath.Add(path[i]);
            if (dist > 1)
            {
                yield return(_creature.AIMoveCreature());
            }
            else
            {
                if (CombatManager.ViewUnobscured(_creature, _targetCreature))
                {
                    break;
                }

                yield return(_creature.AIMoveCreature());
            }

            dist--;
            distToTarget--;
            _creature.TargetPath.Remove(path[i]);

            if (_creature.MaxCanMoveDist <= 0)
            {
                _creature.TargetPath.Clear();
                _creature.EndTurn();
                yield break;
            }
        }

        _creature.TargetPath.Clear();

        if (_creature.MaxCanMoveDist <= 0)
        {
            _creature.EndTurn();
            yield break;
        }

        if (_creature.TargetCreature != null)
        {
            var chanceToHit   = _creature.GetChanceToHit(distToTarget, _targetCreature);
            var attackSuccess = _creature.TryAttackCreature();
            var firstAttack   = true;
            var tryAgain      = attackSuccess != AttackSuccess.NotEnoutAP;
            while (firstAttack || tryAgain)
            {
                switch (attackSuccess)
                {
                case AttackSuccess.None:
                case AttackSuccess.NoTarget:
                case AttackSuccess.NoChanceToHit:
                    tryAgain = false;
                    break;

                case AttackSuccess.NotEnoutAP:
                    if (firstAttack)
                    {
                        var inactiveNull = _creature.InactiveItem == null || _creature.InactiveItem.Info == null;
                        if (inactiveNull || _creature.InactiveItem.Info is WeaponInfo)
                        {
                            var attackInfo = _creature.GetAttackTypeInfo(false);
                            if (!attackInfo.IsValidWeapon || _creature.MaxCanMoveDist < attackInfo.ActionPointCost ||
                                (!inactiveNull && !_creature.InactiveItem.CanUseItem()))
                            {
                                yield return(null);

                                tryAgain = false;
                                break;
                            }

                            yield return(_creature.SwapQuickbarItems());

                            tryAgain = true;
                            break;
                        }
                    }

                    tryAgain = false;
                    break;

                case AttackSuccess.NoAmmo:
                    var canReload = _creature.TryReloadWeapon(_creature.ActiveItem);
                    if (canReload)
                    {
                        //wait for anim to finish
                        yield return(null);

                        tryAgain = true;
                    }
                    else
                    {
                        tryAgain = false;
                    }

                    break;

                case AttackSuccess.AttackMissed:
                    //wait for anim to finish
                    yield return(null);

                    break;

                case AttackSuccess.AttackHit:
                case AttackSuccess.AttackCritical:
                    //wait for anim to finish
                    yield return(null);

                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }

                firstAttack = false;
                if (tryAgain)
                {
                    attackSuccess = _creature.TryAttackCreature();
                }
            }

            yield return(null);
        }

        yield return(null);

        _creature.EndTurn();
    }