Esempio n. 1
0
    private IEnumerator ActionLoop()
    {
        state = State.ACTION;

        for (int i = 0; i < actions.Count; i++)
        {
            BattleAction act = actions[i];
            if (act.type == BattleAction.Type.DAMAGE && act.attacker.inventory.GetFirstUsableItemTuple(ItemCategory.WEAPON).currentCharges <= 0)
            {
                continue;                 //Broken weapon
            }
            if (act.type != BattleAction.Type.DAMAGE && act.attacker.inventory.GetFirstUsableItemTuple(ItemCategory.SUPPORT).currentCharges <= 0)
            {
                continue;                 //Broken staff
            }

            yield return(new WaitForSeconds(1f * currentGameSpeed.value));

            BattleAnimator.AnimationInfo animationInfo = new BattleAnimator.AnimationInfo();

            // Deal damage
            bool isCrit = false;
            if (act.type == BattleAction.Type.DAMAGE)
            {
                int damage = act.AttemptAttack(useTrueHit.value);
                if (damage != -1 && act.AttemptCrit())
                {
                    damage = (int)(damage * BattleCalc.CRIT_MODIFIER);
                    isCrit = true;
                }
                act.defender.TakeDamage(damage, isCrit);
                BattleAnimator.HitType hitType = (damage < 0) ? BattleAnimator.HitType.MISS : (isCrit) ? BattleAnimator.HitType.CRIT : BattleAnimator.HitType.NORMAL;
                animationInfo.side       = act.side;
                animationInfo.weaponType = act.weaponAtk.weaponType;
                animationInfo.hitType    = hitType;
                animationInfo.leathal    = !act.defender.IsAlive();
                animationInfo.damage     = damage;

                if (damage > 0)
                {
                    if (act.side == AttackSide.LEFT)
                    {
                        _attackerDealtDamage = true;
                    }
                    else
                    {
                        _defenderDealtDamage = true;
                    }
                }

                act.attacker.inventory.ReduceItemCharge(ItemCategory.WEAPON);
            }
            else
            {
                // Heal or buff
                if (act.staffAtk.weaponType == WeaponType.MEDKIT)
                {
                    int health = act.GetHeals();
                    act.defender.TakeHeals(health);
                    //StartCoroutine(DamageDisplay(act.leftSide, health, false, false));
                }
                else if (act.staffAtk.weaponType == WeaponType.BARRIER)
                {
                    act.defender.ReceiveBuff(act.attacker.GetEquippedWeapon(ItemCategory.SUPPORT).boost, true, true);
                }
                act.attacker.inventory.ReduceItemCharge(ItemCategory.SUPPORT);
                _attackerDealtDamage = true;
            }

            //Animate!!
            waitForAnimation = true;
            battleAnimator.PlayAttack(animationInfo);
            while (waitForAnimation)
            {
                yield return(null);
            }

            //Check Death
            // Debug.Log("Check death");
            if (!act.defender.IsAlive())
            {
                yield return(new WaitForSeconds(1f * currentGameSpeed.value));

                if (act.defender.stats.charData.deathQuote != null)
                {
                    Debug.Log("Death quote");
                    state = State.DEATH;
                    dialogueMode.value    = (int)DialogueMode.QUOTE;
                    currentDialogue.value = dialogue = act.defender.stats.charData.deathQuote;
                    showDialogueEvent.Invoke();
                    lockControls.value = false;

                    while (state == State.DEATH)
                    {
                        yield return(null);
                    }
                }
                break;
            }
        }

        //Handle exp
        yield return(StartCoroutine(ShowExpGain()));

        //Broken weapons
        yield return(StartCoroutine(HandleBrokenWeapons()));

        //Drop Items
        if (!actions[0].attacker.IsAlive() && actions[0].attacker.faction == Faction.ENEMY)
        {
            yield return(StartCoroutine(DropItems(actions[0].attacker, actions[0].defender)));
        }
        else if (!actions[0].defender.IsAlive() && actions[0].defender.faction == Faction.ENEMY)
        {
            yield return(StartCoroutine(DropItems(actions[0].defender, actions[0].attacker)));
        }

        //Give debuffs
        if (actions[0].type == BattleAction.Type.DAMAGE)
        {
            actions[0].attacker.ActivateSkills(SkillActivation.POSTCOMBAT, actions[0].defender);
            actions[0].defender.ActivateSkills(SkillActivation.POSTCOMBAT, actions[0].attacker);
            actions[0].defender.stats.fatigueAmount = Mathf.Min(actions[0].defender.fatigueCap, actions[0].defender.stats.fatigueAmount + 1);
        }

        //Clean up
        state = State.INIT;
        currentAction.value = ActionMode.NONE;
        battleAnimator.CleanupScene();
        battleAnimationObject.SetActive(false);
        uiCanvas.SetActive(true);
        actions[0].attacker.EndSkills(SkillActivation.INITCOMBAT, actions[0].defender);
        actions[0].attacker.EndSkills(SkillActivation.PRECOMBAT, actions[0].defender);
        actions[0].defender.EndSkills(SkillActivation.PRECOMBAT, actions[0].attacker);
        actions.Clear();
        if (currentTurn.value == Faction.PLAYER)
        {
            lockControls.value = false;
        }
        _currentCharacter.End();
        _currentCharacter = null;

        yield return(new WaitForSeconds(0.5f * currentGameSpeed.value));

        //Music
        stopTransitionMusicEvent.Invoke();

        //Send game finished
        battleFinishedEvent.Invoke();
    }