public void ShadeInitializesWithCorrectMoves() { BattleMove darkFogMove = _shade1.AvailableMoves.FirstOrDefault(m => { bool found = false; StatusMove statusMove = m as StatusMove; if (statusMove != null) { found = statusMove.Status is BlindStatus && statusMove.ExecutionText == $"draws a dark fog about {Globals.TargetReplaceText}" && statusMove.Accuracy == 60; } return(found); }); Assert.NotNull(darkFogMove); BattleMove shadeAbsorbingTechnique = _shade1.AvailableMoves.FirstOrDefault(m => m is ShadeAbsorbingMove); Assert.NotNull(shadeAbsorbingTechnique); BattleMove buildMalevolenceMove = _shade1.AvailableMoves.FirstOrDefault(m => m is SpecialMove && m.Description == "dark energy gather" && m.ExecutionText == "gathers dark energy"); Assert.NotNull(buildMalevolenceMove); BattleMove malevolenceAttack = _shade1.AvailableMoves.FirstOrDefault(m => m is ConditionalPowerAttackBattleMove && m.ExecutionText == "unleashes their dark power!"); Assert.NotNull(malevolenceAttack); }
IEnumerator battle2() { this.battleSequence = false; // print accuracy of move float diff = Math.Abs(this.targetCenter.transform.position.x - this.target.transform.position.x); float accuracy = (1f - (diff / (this.targetLine.GetComponent <RectTransform>().rect.width / 2f))) * 100f; this.aimText.GetComponent <UnityEngine.UI.Text>().text = accuracy.ToString() + "%"; // determine who attacks first Character firstAttacker; Character secondAttacker; Move firstMove; Move secondMove; string firstName; string secondName; float firstAccuracy; float secondAccuracy; if (this.garou.getCurrentStats().getSpd() > this.enemy.getCurrentStats().getSpd()) { firstAttacker = this.garou; secondAttacker = this.enemy; firstMove = getSelectedMove(); secondMove = getEnemyMove(); firstName = "Garou"; secondName = this.enemy.getName(); firstAccuracy = accuracy; System.Random rnd = new System.Random(); secondAccuracy = rnd.Next(1, 100); } else { firstAttacker = this.enemy; secondAttacker = this.garou; firstMove = getEnemyMove(); secondMove = getSelectedMove(); firstName = this.enemy.getName(); secondName = "Garou"; System.Random rnd = new System.Random(); firstAccuracy = rnd.Next(1, 100); secondAccuracy = accuracy; } // first attacker loses energy reduceEnergy(firstAttacker, firstMove.getCost(), firstMove.getPenalty()); // end match if first attacker dies on energy cost if (setWinOrLose()) { yield break; } // first move setExpositionText(firstName + " used " + firstMove.getName() + "!"); yield return(new WaitForSeconds(1)); // determine if first move hits and crit bool[] hc = hitAndCrit(firstAttacker, firstMove, firstAccuracy); bool firstMoveHits = hc[0]; bool firstMoveCrits = hc[1]; float eff = getEffectiveness(firstMove.getType(), secondAttacker); // move does not affect target if (eff > -0.0001f && eff < 0.001f) { setExpositionText("Doesn't affect " + secondName + "..."); yield return(new WaitForSeconds(1)); } else { if (firstMoveHits) { // hit // determine type of first move if (firstMove.GetType() == typeof(DamageMove)) { damageAttack(firstAttacker, firstMove, eff, firstMoveCrits); yield return(new WaitForSeconds(1)); if (firstMoveCrits) { setExpositionText("It's a critical hit!"); yield return(new WaitForSeconds(1)); } // effectiveness if (eff >= 2.0f) { setExpositionText("It's Super Effective!"); yield return(new WaitForSeconds(1)); } else if (eff <= 0.5f) { setExpositionText("Not very effective..."); yield return(new WaitForSeconds(1)); } // end match if health is 0 if (setWinOrLose()) { yield break; } } else if (firstMove.GetType() == typeof(StatusMove)) { StatusMove firstStatusMove = (StatusMove)firstMove; Resources.Status status = firstStatusMove.getStatus(); if (firstStatusMove.getTarget()) { // target is enemy if (secondAttacker.getStatus() != Resources.Status.Healthy) { // already has a status ailment setExpositionText(secondName + " is already " + getStatusText(status) + "!"); yield return(new WaitForSeconds(1)); } else { if (firstMoveCrits) { // crit secondAttacker.setStatus(getBadStatus(status)); setExpositionText("It's a Crit!"); yield return(new WaitForSeconds(1)); setExpositionText(secondName + " has been " + getStatusText(getBadStatus(status)) + "!"); yield return(new WaitForSeconds(1)); } else { // normal secondAttacker.setStatus(status); setExpositionText(secondName + " has been " + getStatusText(status) + "!"); yield return(new WaitForSeconds(1)); } } } else { // target is self } } else if (firstMove.GetType() == typeof(StatMove)) { StatMove firstStatMove = (StatMove)firstMove; Resources.StatType[] stats = firstStatMove.getStats(); int f = firstStatMove.getFactor(); if (firstMoveCrits) { f++; setExpositionText("It's a Crit!"); yield return(new WaitForSeconds(1)); } foreach (Resources.StatType stat in stats) { if (firstStatMove.getTarget()) { // target is enemy if (secondAttacker.changeStat(stat, f)) { // stat already max or min if (f > 0) { setExpositionText(secondName + "'s " + stat.ToString() + " won't go any higher!"); } else { setExpositionText(secondName + "'s " + stat.ToString() + " can't go any lower!"); } } else { // stat can increase or decrease if (f > 0) { setExpositionText(secondName + "'s " + stat.ToString() + " increased by " + f.ToString() + "!"); } else { setExpositionText(secondName + "'s " + stat.ToString() + " decreased by " + f.ToString() + "!"); } } } else { // target is self if (firstAttacker.changeStat(stat, f)) { // stat is already max or min if (f > 0) { setExpositionText(secondName + "'s " + stat.ToString() + " won't go any higher!"); } else { setExpositionText(secondName + "'s " + stat.ToString() + " can't go any lower!"); } } else { // stat can increase or decrease if (f > 0) { setExpositionText(firstName + "'s " + stat.ToString() + " increased by " + f.ToString() + "!"); } else { setExpositionText(firstName + "'s " + stat.ToString() + " decreased by " + f.ToString() + "!"); } } } yield return(new WaitForSeconds(1)); } } } else { // miss if (firstMove.GetType() == typeof(DamageMove)) { setExpositionText(firstName + "'s attack missed..."); yield return(new WaitForSeconds(1)); } else { setExpositionText(firstName + " failed..."); yield return(new WaitForSeconds(1)); } } this.cursorLocation = CursorLocation.Fight; } // second attacker loses energy reduceEnergy(secondAttacker, secondMove.getCost(), secondMove.getPenalty()); // end match if first attacker dies on energy cost if (setWinOrLose()) { yield break; } // second move setExpositionText(secondName + " used " + secondMove.getName() + "!"); yield return(new WaitForSeconds(1)); // determine if second move hits and crit bool[] hc2 = hitAndCrit(secondAttacker, secondMove, secondAccuracy); bool secondMoveHits = hc2[0]; bool secondMoveCrits = hc2[1]; float eff2 = getEffectiveness(secondMove.getType(), firstAttacker); // move does not affect target if (eff2 > -0.0001f && eff2 < 0.001f) { setExpositionText("Doesn't affect " + firstName + "..."); yield return(new WaitForSeconds(1)); } else { if (secondMoveHits) { // hit // determine type of first move if (secondMove.GetType() == typeof(DamageMove)) { damageAttack(secondAttacker, secondMove, eff2, secondMoveCrits); yield return(new WaitForSeconds(1)); if (secondMoveCrits) { setExpositionText("It's a critical hit!"); yield return(new WaitForSeconds(1)); } // effectiveness if (eff2 >= 2.0f) { setExpositionText("It's Super Effective!"); yield return(new WaitForSeconds(1)); } else if (eff2 <= 0.5f) { setExpositionText("Not very effective..."); yield return(new WaitForSeconds(1)); } // end match if health is 0 if (setWinOrLose()) { yield break; } } else if (secondMove.GetType() == typeof(StatusMove)) { StatusMove secondStatusMove = (StatusMove)secondMove; Resources.Status status = secondStatusMove.getStatus(); if (secondStatusMove.getTarget()) { // target is enemy if (firstAttacker.getStatus() != Resources.Status.Healthy) { // already has a status ailment setExpositionText(firstName + " is already " + getStatusText(status) + "!"); yield return(new WaitForSeconds(1)); } else { if (secondMoveCrits) { // crit firstAttacker.setStatus(getBadStatus(status)); setExpositionText("It's a Crit!"); yield return(new WaitForSeconds(1)); setExpositionText(firstName + " has been " + getStatusText(getBadStatus(status)) + "!"); yield return(new WaitForSeconds(1)); } else { // normal firstAttacker.setStatus(status); setExpositionText(firstName + " has been " + getStatusText(status) + "!"); yield return(new WaitForSeconds(1)); } } } else { // target is self } } else if (secondMove.GetType() == typeof(StatMove)) { StatMove secondStatMove = (StatMove)secondMove; Resources.StatType[] stats = secondStatMove.getStats(); int f = secondStatMove.getFactor(); if (secondMoveCrits) { f++; setExpositionText("It's a Crit!"); yield return(new WaitForSeconds(1)); } foreach (Resources.StatType stat in stats) { if (secondStatMove.getTarget()) { // target is enemy if (firstAttacker.changeStat(stat, f)) { // stat already max or min if (f > 0) { setExpositionText(firstName + "'s " + stat.ToString() + " won't go any higher!"); } else { setExpositionText(firstName + "'s " + stat.ToString() + " can't go any lower!"); } } else { // stat can increase or decrease if (f > 0) { setExpositionText(firstName + "'s " + stat.ToString() + " increased by " + f.ToString() + "!"); } else { setExpositionText(firstName + "'s " + stat.ToString() + " decreased by " + f.ToString() + "!"); } } } else { // target is self if (secondAttacker.changeStat(stat, f)) { // stat is already max or min if (f > 0) { setExpositionText(secondName + "'s " + stat.ToString() + " won't go any higher!"); } else { setExpositionText(secondName + "'s " + stat.ToString() + " can't go any lower!"); } } else { // stat can increase or decrease if (f > 0) { setExpositionText(secondName + "'s " + stat.ToString() + " increased by " + f.ToString() + "!"); } else { setExpositionText(secondName + "'s " + stat.ToString() + " decreased by " + f.ToString() + "!"); } } } yield return(new WaitForSeconds(1)); } } } else { // miss if (secondMove.GetType() == typeof(DamageMove)) { setExpositionText(secondName + "'s attack missed..."); yield return(new WaitForSeconds(1)); } else { setExpositionText(secondName + " failed..."); yield return(new WaitForSeconds(1)); } } } // apply poison / burn damage float poison = 0.06f; float burn = 0.04f; float badlyPoison = 0.1f; float badlyBurn = 0.06f; int garouTotalHealth = this.garou.getOriginalStats().getHp(); int enemyTotalHealth = this.enemy.getOriginalStats().getHp(); Resources.Status garouStatus = this.garou.getStatus(); Resources.Status enemyStatus = this.enemy.getStatus(); // apply garou damage for status if (garouStatus == Resources.Status.Poison) { reduceHealth(this.garou, (int)Math.Round((float)garouTotalHealth * poison)); setExpositionText("Garou is hurt by poison!"); yield return(new WaitForSeconds(1)); } else if (garouStatus == Resources.Status.Burn) { reduceHealth(this.garou, (int)Math.Round((float)garouTotalHealth * burn)); setExpositionText("Garou is hurt by its burn!"); yield return(new WaitForSeconds(1)); } else if (garouStatus == Resources.Status.BadlyPoison) { reduceHealth(this.garou, (int)Math.Round((float)garouTotalHealth * badlyPoison)); setExpositionText("Garou is hurt by poison!"); yield return(new WaitForSeconds(1)); } else if (garouStatus == Resources.Status.BadlyBurn) { reduceHealth(this.garou, (int)Math.Round((float)garouTotalHealth * badlyBurn)); setExpositionText("Garou is hurt by its burn!"); yield return(new WaitForSeconds(1)); } // end match if garou dies on status damage if (setWinOrLose()) { yield break; } // apply enemy damage for status if (enemyStatus == Resources.Status.Poison) { reduceHealth(this.enemy, (int)Math.Round((float)enemyTotalHealth * poison)); setExpositionText(this.enemy.getName() + " is hurt by poison!"); yield return(new WaitForSeconds(1)); } else if (enemyStatus == Resources.Status.Burn) { reduceHealth(this.enemy, (int)Math.Round((float)enemyTotalHealth * burn)); setExpositionText(this.enemy.getName() + " is hurt by its burn!"); yield return(new WaitForSeconds(1)); } else if (enemyStatus == Resources.Status.BadlyPoison) { reduceHealth(this.enemy, (int)Math.Round((float)enemyTotalHealth * badlyPoison)); setExpositionText(this.enemy.getName() + " is hurt by poison!"); yield return(new WaitForSeconds(1)); } else if (enemyStatus == Resources.Status.BadlyBurn) { reduceHealth(this.enemy, (int)Math.Round((float)enemyTotalHealth * badlyBurn)); setExpositionText(this.enemy.getName() + " is hurt by its burn!"); yield return(new WaitForSeconds(1)); } // end match if enemy dies on status damage if (setWinOrLose()) { yield break; } this.battleState = BattleState.WhatWillYouDo; this.cursorLocation = CursorLocation.Fight; }