private void FillSubMenu(BattleStats currentEntity) { // We extract the attack data from the demon and fill in the menu CharacterData currentCharacter = (CharacterData)currentEntity.battleData; for (int currIndex = 0; currIndex < currentCharacter.demonData.attackList.Count; ++currIndex) { AttackData currAttack = currentCharacter.demonData.attackList[currIndex]; currentMenuParent.GetChild(currIndex).GetComponent <TextMeshProUGUI>().text = currAttack.attackName; currentMenuParent.GetChild(currIndex).gameObject.SetActive(true); } }
// Perform using an item on the selected character public IEnumerator PerformItemAction(InventoryItem currentItem, BattleStats targetedCharacter) { // Display the action box battleUIController.ToggleActionBox(true, "Used " + currentItem.SpecifiedItem.itemName + " on " + ((CharacterData)targetedCharacter.battleData).characterName + "."); // TODO: Animation for item usage yield return(new WaitForSeconds(1f)); // Restore amount if (currentItem.SpecifiedItem.itemType == ItemType.HEALTH) { targetedCharacter.CurrentHP += currentItem.SpecifiedItem.itemAmount; battleUIController.ToggleActionBox(true, "Restored " + currentItem.SpecifiedItem.itemAmount + " HP."); } else if (currentItem.SpecifiedItem.itemType == ItemType.SP) { targetedCharacter.CurrentSP += currentItem.SpecifiedItem.itemAmount; battleUIController.ToggleActionBox(true, "Restored " + currentItem.SpecifiedItem.itemAmount + " SP."); } GameManager.Instance.PlayerReference.GetComponent <PlayerInventory>().RemoveItemFromInventory(currentItem, 1); yield return(new WaitForSeconds(1f)); battleUIController.ToggleActionBox(false); // We then increment the turn order and change to the next turn // If we are on an entity that has died, we skip their turn SetCurrentTurnOrder = currentTurnIndex + 1; while (GetCurrentCharacterInTurnOrder().CurrentHP <= 0) { SetCurrentTurnOrder = currentTurnIndex + 1; } // We shift the turn indicator to be on the current character turnIndicator.transform.position = GetCurrentCharacterInTurnOrder().gameObject.transform.position; turnIndicator.transform.position += new Vector3(0, turnIndicatorYOffset, 0); if (GetCurrentCharacterInTurnOrder().battleData is CharacterData) { battleUIController.ShowMenus(); currentState = BattleStates.PLAYER_TURN; } else if (GetCurrentCharacterInTurnOrder().battleData is EnemyData) { battleUIController.CurrentState = BattleMenuStates.INACTIVE; currentState = BattleStates.ENEMY_TURN; EnemyAI(); } yield return(null); }
// We compare the speeds of the called object and the other data that was passed in public bool CompareSpeeds(BattleStats other) { if (ReturnModdedStat("Speed") > other.ReturnModdedStat("Speed")) { return(true); } else if (ReturnModdedStat("Speed") < other.ReturnModdedStat("Speed")) { return(false); } else { // If we have a tie in speed, we will randomly decide which one will be faster return(Random.Range(0, 2) == 1); } }
// Determines the order of who goes first // First in array = fastest; last = slowest // Uses insertion sort private void DetermineOrderOfAttacks() { listOfAllEntitiesInTurnOrder = new List <BattleStats>(FindObjectsOfType <BattleStats>()); for (int compareIndex = 0; compareIndex < listOfAllEntitiesInTurnOrder.Count; ++compareIndex) { for (int iteratorIndex = compareIndex + 1; iteratorIndex < listOfAllEntitiesInTurnOrder.Count; ++iteratorIndex) { // We check to see if we the current entity is faster than the current iterator if (listOfAllEntitiesInTurnOrder[iteratorIndex].CompareSpeeds(listOfAllEntitiesInTurnOrder[compareIndex]) == true) { BattleStats temp = listOfAllEntitiesInTurnOrder[iteratorIndex]; listOfAllEntitiesInTurnOrder[iteratorIndex] = listOfAllEntitiesInTurnOrder[compareIndex]; listOfAllEntitiesInTurnOrder[compareIndex] = temp; } } } }
// Spawns the party into battle. private void SpawnParty() { PlayerInventory playerInventory = GameManager.Instance.PlayerReference.GetComponent <PlayerInventory>(); listOfAllParty = new List <BattleStats>(); int currLocationIndex = 0; for (int currIndex = 0; currIndex < playerInventory.GetPartyInvetorySize(); ++currIndex) { BattleStats partyMember = Instantiate(characterPrefab, partySpawnLocations[currLocationIndex].position, Quaternion.identity).GetComponent <BattleStats>(); partyMember.battleData = playerInventory.GetInventoryCharacterAtIndex(currIndex).SpecifiedCharacter; partyMember.InitalizeEntity(playerInventory.GetInventoryCharacterAtIndex(currIndex)); listOfAllParty.Add(partyMember); currLocationIndex++; } }
// A helper method that depending on what is passed in will determine what UI wil be updated public void SavePlayerStatsToUI(BattleStats currentPartyMember, InventoryParty currentPartyMemberStats, bool isOriginal) { // Displays the character that is levling up levelUpMenu.transform.GetChild(2).GetComponent <Image>().sprite = currentPartyMember.gameObject.transform.GetChild(0).GetComponent <SpriteRenderer>().sprite; // If true, we are going to modify the slider value that represnts the original player stats if (isOriginal) { // The base player levelUpMenu.transform.GetChild(4).GetChild(0).GetComponent <Slider>().value = currentPartyMember.ReturnModdedStat("MaxHP"); levelUpMenu.transform.GetChild(4).GetChild(1).GetComponent <Slider>().value = currentPartyMember.ReturnModdedStat("MaxSP"); levelUpMenu.transform.GetChild(4).GetChild(2).GetComponent <Slider>().value = currentPartyMember.ReturnModdedStat("BaseAttack"); levelUpMenu.transform.GetChild(4).GetChild(3).GetComponent <Slider>().value = currentPartyMember.ReturnModdedStat("BaseDefense"); // The Demon Stats levelUpMenu.transform.GetChild(5).GetChild(0).GetComponent <Slider>().value = currentPartyMember.ReturnModdedStat("PhysicalAttack"); levelUpMenu.transform.GetChild(5).GetChild(1).GetComponent <Slider>().value = currentPartyMember.ReturnModdedStat("PhysicalDefense"); levelUpMenu.transform.GetChild(5).GetChild(2).GetComponent <Slider>().value = currentPartyMember.ReturnModdedStat("SpecialAttack"); levelUpMenu.transform.GetChild(5).GetChild(3).GetComponent <Slider>().value = currentPartyMember.ReturnModdedStat("SpecialDefense"); levelUpMenu.transform.GetChild(5).GetChild(4).GetComponent <Slider>().value = currentPartyMember.ReturnModdedStat("Speed"); levelUpMenu.transform.GetChild(5).GetChild(5).GetComponent <Slider>().value = currentPartyMember.ReturnModdedStat("Luck"); } else { // The base player levelUpMenu.transform.GetChild(4).GetChild(0).GetChild(1).GetComponent <Slider>().value = currentPartyMember.ReturnModdedStat("MaxHP"); levelUpMenu.transform.GetChild(4).GetChild(1).GetChild(1).GetComponent <Slider>().value = currentPartyMember.ReturnModdedStat("MaxSP"); levelUpMenu.transform.GetChild(4).GetChild(2).GetChild(1).GetComponent <Slider>().value = currentPartyMember.ReturnModdedStat("BaseAttack"); levelUpMenu.transform.GetChild(4).GetChild(3).GetChild(1).GetComponent <Slider>().value = currentPartyMember.ReturnModdedStat("BaseDefense"); // The Demon Stats levelUpMenu.transform.GetChild(5).GetChild(0).GetChild(1).GetComponent <Slider>().value = currentPartyMember.ReturnModdedStat("PhysicalAttack"); levelUpMenu.transform.GetChild(5).GetChild(1).GetChild(1).GetComponent <Slider>().value = currentPartyMember.ReturnModdedStat("PhysicalDefense"); levelUpMenu.transform.GetChild(5).GetChild(2).GetChild(1).GetComponent <Slider>().value = currentPartyMember.ReturnModdedStat("SpecialAttack"); levelUpMenu.transform.GetChild(5).GetChild(3).GetChild(1).GetComponent <Slider>().value = currentPartyMember.ReturnModdedStat("SpecialDefense"); levelUpMenu.transform.GetChild(5).GetChild(4).GetChild(1).GetComponent <Slider>().value = currentPartyMember.ReturnModdedStat("Speed"); levelUpMenu.transform.GetChild(5).GetChild(5).GetChild(1).GetComponent <Slider>().value = currentPartyMember.ReturnModdedStat("Luck"); } levelUpMenu.transform.GetChild(3).GetComponentInChildren <TextMeshProUGUI>().text = currentPartyMemberStats.SpecifiedCharacter.characterName + " leveled up! Now at level " + currentPartyMemberStats.CharacterLevel + "!"; }
// Spawns in enemies from the event private void SpawnEnemies() { listOfAllEnemies = new List <BattleStats>(); int currSpawnIndex = 0; foreach (EnemyData currentData in currentBattleEvent.listOfEnemiesInFight) { BattleStats newEnemy = Instantiate(characterPrefab, enemySpawnLocations[currSpawnIndex].position, Quaternion.identity).GetComponent <BattleStats>(); newEnemy.battleData = currentData; newEnemy.InitalizeEntity(currentData.maxHealthPoints, currentData.maxSkillPoints); // We level up the enemy in here based on their current level for (int iterator = currentData.currentLevel; iterator > 0; iterator--) { newEnemy.LevelUpStats(); } listOfAllEnemies.Add(newEnemy); currSpawnIndex++; } }
// Performs an attack action using the current character on the targeted character public IEnumerator PerformAttackAction(int attackIndex, BattleStats targetedCharacter) { AttackData currentAttack = null; string nameOfAttacker = ""; string nameOfTarget = ""; int damageDealt = 0; if (GetCurrentCharacterInTurnOrder().battleData is CharacterData) { // Player atacks enemy CharacterData currentCharacter = (CharacterData)GetCurrentCharacterInTurnOrder().battleData; EnemyData targeted = (EnemyData)targetedCharacter.battleData; currentAttack = currentCharacter.demonData.attackList[attackIndex]; nameOfAttacker = currentCharacter.characterName; nameOfTarget = targeted.enemyName; // Sets the text box to show the attack battleUIController.ToggleActionBox(true, currentAttack.attackName); // TODO: Associate animation with character //GetCurrentCharacterInTurnOrder().gameObject.GetComponent<Animator> currentDemon.attackList[attackIndex].attackAnimation; } else if (GetCurrentCharacterInTurnOrder().battleData is EnemyData) { // Enemy attacks player EnemyData currentEnemy = (EnemyData)GetCurrentCharacterInTurnOrder().battleData; CharacterData targeted = (CharacterData)targetedCharacter.battleData; currentAttack = currentEnemy.attackList[attackIndex]; nameOfAttacker = currentEnemy.enemyName; nameOfTarget = targeted.characterName; // Sets the text box to show the attack battleUIController.ToggleActionBox(true, currentAttack.attackName); // TODO: Associate animation with character //GetCurrentCharacterInTurnOrder().gameObject.GetComponent<Animator> currentDemon.attackList[attackIndex].attackAnimation; } yield return(new WaitForSeconds(1f)); // Deal damage damageDealt = targetedCharacter.DealDamage(GetCurrentCharacterInTurnOrder(), currentAttack); switch (targetedCharacter.GetAttackEffectiveness(currentAttack)) { case AffinityValues.NORMAL: battleUIController.ToggleActionBox(true, nameOfAttacker + " delt " + damageDealt + " damage to " + nameOfTarget + "."); break; case AffinityValues.WEAK: battleUIController.ToggleActionBox(true, nameOfAttacker + " hits " + nameOfTarget + "'s weakspot for " + damageDealt + " damage!"); break; case AffinityValues.RESISTANT: battleUIController.ToggleActionBox(true, nameOfTarget + " resisted " + nameOfTarget + "'s move...only dealt " + damageDealt + " damage."); break; case AffinityValues.NULL: battleUIController.ToggleActionBox(true, nameOfTarget + " is immune to " + nameOfTarget + "'s attack...did " + damageDealt + " damage."); break; } yield return(new WaitForSeconds(1f)); // Checks if the target is dead if (targetedCharacter.CurrentHP <= 0) { battleUIController.ToggleActionBox(true, nameOfTarget + " is defeated!"); // We move it to the back of the line in the turn order and deactivate it. if (targetedCharacter.battleData is CharacterData) { targetedCharacter.gameObject.SetActive(false); listOfAllParty.Remove(targetedCharacter); listOfAllParty.Add(targetedCharacter); } else if (targetedCharacter.battleData is EnemyData) { targetedCharacter.gameObject.SetActive(false); listOfAllEnemies.Remove(targetedCharacter); listOfAllEnemies.Add(targetedCharacter); } listOfAllEntitiesInTurnOrder.Remove(targetedCharacter); listOfAllEntitiesInTurnOrder.Add(targetedCharacter); } yield return(new WaitForSeconds(1f)); // We check if a side is wiped, else we continue switch (CheckWhoWon()) { case 0: // No one lost yet so we then increment the turn order and change to the next turn SetCurrentTurnOrder = currentTurnIndex + 1; while (GetCurrentCharacterInTurnOrder().CurrentHP <= 0) { SetCurrentTurnOrder = currentTurnIndex + 1; } // We shift the turn indicator to be on the current character turnIndicator.transform.position = GetCurrentCharacterInTurnOrder().gameObject.transform.position; turnIndicator.transform.position += new Vector3(0, turnIndicatorYOffset, 0); if (GetCurrentCharacterInTurnOrder().battleData is CharacterData) { // Hide action box battleUIController.ToggleActionBox(false); yield return(null); battleUIController.ShowMenus(); currentState = BattleStates.PLAYER_TURN; } else if (GetCurrentCharacterInTurnOrder().battleData is EnemyData) { battleUIController.CurrentState = BattleMenuStates.INACTIVE; currentState = BattleStates.ENEMY_TURN; EnemyAI(); } yield return(null); break; case 1: // The player won, so we change to the player victory battleUIController.ToggleActionBox(true, "You won!"); yield return(new WaitForSeconds(2f)); // We then reward the player with the rewards for winning StartCoroutine(PostWinActions()); break; case -1: // The enemy won, so we change to the enemy victory battleUIController.ToggleActionBox(true, "You lost..."); yield return(new WaitForSeconds(2f)); currentState = BattleStates.ENEMY_WIN; currentBattleEvent.EventOutcome(); break; } }
// Calculates how damage will be dealt to this entity // Returns the amount of damage done public int DealDamage(BattleStats attacker, AttackData currentAttack) { int attackPower = 0; int defensePower = 0; // If the attacker is the player, we are attacking an enemy if (attacker.battleData is CharacterData) { if (currentAttack.attackType == AttackType.PHYSICAL) { // Because the attack is physical, we calculate the math based on physical power attackPower = attacker.ReturnModdedStat("BaseAttack") + currentAttack.attackPower + attacker.ReturnModdedStat("PhysicalAttack"); defensePower = ReturnModdedStat("PhysicalDefense"); } else if (currentAttack.attackType == AttackType.SPECIAL) { // Because the attack is special, we calculate the math based on special power attackPower = attacker.ReturnModdedStat("BaseAttack") + currentAttack.attackPower + attacker.ReturnModdedStat("SpecialAttack"); defensePower = ReturnModdedStat("SpecialDefense"); // We also deduct SP from the user as well attacker.CurrentSP -= currentAttack.attackCost; } } // If the attacker is an enemy, we are attacking a party member else if (attacker.battleData is EnemyData) { if (currentAttack.attackType == AttackType.PHYSICAL) { // Because the attack is physical, we calculate the math based on physical power attackPower = currentAttack.attackPower + attacker.ReturnModdedStat("PhysicalAttack"); defensePower = ReturnModdedStat("BaseDefense") + ReturnModdedStat("PhysicalDefense"); } else if (currentAttack.attackType == AttackType.SPECIAL) { // Because the attack is special, we calculate the math based on special power attackPower = currentAttack.attackPower + attacker.ReturnModdedStat("SpecialAttack"); defensePower = ReturnModdedStat("BaseDefense") + ReturnModdedStat("SpecialDefense"); // We also deduct SP from the user as well attacker.CurrentSP -= currentAttack.attackCost; } } // Modifies the total attack power depending on the affinity of the attack switch (GetAttackEffectiveness(currentAttack)) { case AffinityValues.RESISTANT: attackPower /= 2; break; case AffinityValues.WEAK: attackPower *= 2; break; case AffinityValues.NULL: attackPower *= 0; break; } // We then calculate the final damage, clamping the damage to 0 and infinity (cannot be negative) int finalDamage = (int)Mathf.Clamp(attackPower - defensePower, 0, Mathf.Infinity); currentHP -= finalDamage; // We then return the total damage output return(finalDamage); }