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(); }