Last active
January 31, 2020 19:11
-
-
Save spaghettiSyntax/ce2c924056d09a8aeb336af3ad8e359f to your computer and use it in GitHub Desktop.
Battle Manager
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.UI; | |
using UnityEngine.SceneManagement; | |
using Random = UnityEngine.Random; | |
using System; | |
public class BattleManager : MonoBehaviour | |
{ | |
public static BattleManager _instance; | |
public bool battleActive; | |
public GameObject battleScene; | |
public Transform[] characterPositions; | |
public Transform[] enemyPositions; | |
public BattleCharacter[] characterPrefabs; | |
public BattleCharacter[] enemyPrefabs; | |
public List<BattleCharacter> activeBattler = new List<BattleCharacter>(); | |
public int currentActiveBattler; | |
public int currentTurn; | |
public bool turnWaiting; | |
public GameObject uiButtonHolder; | |
public BattleMove[] movesList; | |
public GameObject enemyAttackEffect; | |
public DamageText damageText; | |
public Text[] charName, charHP, charMP; | |
public GameObject targetMenu; | |
public BattleTargetButton[] targetButtons; | |
public GameObject spellMenu; | |
public BattleSpellButton[] spellButtons; | |
public BattleNotification battleNotification; | |
public int chanceToFlee = 35; | |
public bool fleeRollSuccessful = false; | |
public bool allEnemiesDead = false; | |
public bool allCharactersDead = false; | |
public float endBattleSceneTimer = 1.5f; | |
public string gameOverScene; | |
public int rewardExp; | |
public string[] rewardItems; | |
public bool ableToFlee; | |
public GameObject fleeButton; | |
// Item Screen | |
[Header("Item Menu")] | |
public GameObject itemMenu; | |
public ItemButton[] itemButtons; | |
public string selectedItem; | |
public Item activeItem; | |
public Text itemName; | |
public Text itemDescription; | |
public Text useButtonText; | |
private bool fleeing; | |
// Start is called before the first frame update | |
void Start() | |
{ | |
_instance = this; | |
DontDestroyOnLoad(gameObject); | |
} | |
// Update is called once per frame | |
void Update() | |
{ | |
if (Input.GetKeyDown(KeyCode.T)) | |
{ | |
BattleStart(new string[] | |
{ | |
"Eyeball" | |
//"Skeleton", | |
//"Spider" | |
}, false); | |
} | |
if (battleActive) | |
{ | |
if (turnWaiting) | |
{ | |
if (activeBattler[currentTurn].isCharacter) | |
{ | |
if (activeBattler[currentTurn].charName == "Tim") | |
{ | |
currentActiveBattler = 0; | |
} | |
uiButtonHolder.SetActive(true); | |
} | |
else | |
{ | |
uiButtonHolder.SetActive(false); | |
// Start enemy attack turns | |
StartCoroutine(EnemyMoveCoroutine()); | |
} | |
} | |
} | |
//TODO: Redo flee success roll notification | |
//if (allEnemiesDead || allCharactersDead | |
// || fleeRollSuccessful) | |
//{ | |
// endBattleSceneTimer -= Time.deltaTime; | |
// if (fleeRollSuccessful) | |
// { | |
// battleNotification.notificationText.text = "Flee success!"; | |
// battleNotification.Activate(); | |
// } | |
// if (endBattleSceneTimer <= 0) | |
// { | |
// battleActive = false; | |
// battleScene.SetActive(false); | |
// GameManager._instance.battleActive = false; | |
// AudioManager._instance.PlayBGM(3); | |
// fleeRollSuccessful = false; | |
// allEnemiesDead = false; | |
// allCharactersDead = false; | |
// } | |
//} | |
if (Input.GetKeyDown(KeyCode.N)) | |
{ | |
NextTurn(); | |
} | |
} | |
public void BattleStart(string[] enemiesToSpawn, bool fleeStatus) | |
{ | |
ableToFlee = fleeStatus; | |
if (!battleActive) | |
{ | |
battleActive = true; | |
GameManager._instance.battleActive = true; | |
transform.position = new Vector3(Camera.main.transform.position.x, Camera.main.transform.position.y, transform.position.z); | |
battleScene.SetActive(true); | |
AudioManager._instance.PlayBGM(0); | |
// Spawn Characters | |
for (int i = 0; i < characterPositions.Length; i++) | |
{ | |
if (GameManager._instance.charStats[i].gameObject.activeInHierarchy) | |
{ | |
for (int j = 0; j < characterPrefabs.Length; j++) | |
{ | |
if (characterPrefabs[j].charName == GameManager._instance.charStats[i].charName) | |
{ | |
BattleCharacter battleCharacter = Instantiate(characterPrefabs[j], characterPositions[i].position, characterPositions[i].rotation); | |
battleCharacter.transform.parent = characterPositions[i]; | |
activeBattler.Add(battleCharacter); | |
CharInfo character = GameManager._instance.charStats[i]; | |
activeBattler[i].currentHP = character.currentHP; | |
activeBattler[i].maxHP = character.maxHP; | |
activeBattler[i].currentMP = character.currentMP; | |
activeBattler[i].maxMP = character.maxMP; | |
activeBattler[i].strength = character.strength; | |
activeBattler[i].defense = character.defense; | |
activeBattler[i].weaponPower = character.weaponPower; | |
activeBattler[i].armorPower = character.armorPower; | |
} | |
} | |
} | |
} | |
// Spawn Enemies | |
for (int i = 0; i < enemiesToSpawn.Length; i++) | |
{ | |
if (enemiesToSpawn[i] != "") | |
{ | |
for (int j = 0; j < enemyPrefabs.Length; j++) | |
{ | |
if (enemyPrefabs[j].charName == enemiesToSpawn[i]) | |
{ | |
BattleCharacter battleEnemy = Instantiate(enemyPrefabs[j], enemyPositions[i].position, enemyPositions[i].rotation); | |
battleEnemy.transform.parent = enemyPositions[i]; | |
activeBattler.Add(battleEnemy); | |
} | |
} | |
} | |
} | |
turnWaiting = true; | |
currentTurn = UnityEngine.Random.Range(0, activeBattler.Count); | |
UpdateUICharInfo(); | |
} | |
} | |
private void NextTurn() | |
{ | |
currentTurn++; | |
if (currentTurn >= activeBattler.Count) | |
{ | |
currentTurn = 0; | |
} | |
turnWaiting = true; | |
UpdateUICharInfo(); | |
UpdateBattle(); | |
} | |
public void UpdateBattle() | |
{ | |
allEnemiesDead = true; | |
allCharactersDead = true; | |
for (int i = 0; i < activeBattler.Count; i++) | |
{ | |
if (activeBattler[i].currentHP <= 0) | |
{ | |
activeBattler[i].currentHP = 0; | |
} | |
// Handle dead battler character | |
if (activeBattler[i].currentHP == 0) | |
{ | |
if (activeBattler[i].isCharacter) | |
{ | |
activeBattler[i].spriteRenderer.sprite = activeBattler[i].deadSprite; | |
} | |
else | |
{ | |
activeBattler[i].EnemyFade(); | |
} | |
} | |
else | |
{ | |
if (activeBattler[i].isCharacter) | |
{ | |
allCharactersDead = false; | |
activeBattler[i].spriteRenderer.sprite = activeBattler[i].aliveSprite; | |
} | |
else | |
{ | |
allEnemiesDead = false; | |
} | |
} | |
} | |
if (allEnemiesDead || allCharactersDead) | |
{ | |
if (allEnemiesDead) | |
{ | |
//TODO: End battle in victory | |
StartCoroutine(EndBattleCoroutine()); | |
} | |
else | |
{ | |
//TODO: End battle in failure | |
StartCoroutine(GameOverCoroutine()); | |
} | |
if (endBattleSceneTimer <= 0) | |
{ | |
battleScene.SetActive(false); | |
GameManager._instance.battleActive = false; | |
battleActive = false; | |
} | |
} | |
else | |
{ | |
// Check if current active battler has HP | |
while (activeBattler[currentTurn].currentHP == 0) | |
{ | |
currentTurn++; | |
if (currentTurn >= activeBattler.Count) | |
{ | |
currentTurn = 0; | |
} | |
} | |
} | |
} | |
public void CharacterAttack(string moveName, int selectedTarget) | |
{ | |
int movePower = 0; | |
for (int i = 0; i < movesList.Length; i++) | |
{ | |
if (movesList[i].moveName == moveName) | |
{ | |
// Instantiate attack effect on appropriate character | |
Instantiate(movesList[i].attackEffect, | |
activeBattler[selectedTarget].transform.position, | |
activeBattler[selectedTarget].transform.rotation); | |
// Grab move power of appropriate move | |
movePower = movesList[i].movePower; | |
} | |
} | |
// Disable buttons to prevent double attacks | |
uiButtonHolder.SetActive(false); | |
targetMenu.SetActive(false); | |
// Effect to show which enemy just attacked | |
Instantiate(enemyAttackEffect, | |
activeBattler[currentTurn].transform.position, | |
activeBattler[currentTurn].transform.rotation); | |
DealDamage(selectedTarget, movePower); | |
NextTurn(); | |
} | |
// A co-routine is something that can happen outside the normal order of Unity | |
public IEnumerator EnemyMoveCoroutine() | |
{ | |
// Setting spacing between enemy attacks | |
turnWaiting = false; | |
yield return new WaitForSeconds(1f); | |
EnemyAttack(); | |
yield return new WaitForSeconds(1f); | |
NextTurn(); | |
} | |
public void EnemyAttack() | |
{ | |
List<int> characters = new List<int>(); | |
for (int i = 0; i < activeBattler.Count; i++) | |
{ | |
if (activeBattler[i].isCharacter && activeBattler[i].currentHP > 0) | |
{ | |
characters.Add(i); | |
} | |
} | |
int selectedTarget = characters[Random.Range(0, characters.Count)]; | |
int selectAttack = Random.Range(0, activeBattler[currentTurn].movesAvailable.Length); | |
int movePower = 0; | |
if (activeBattler[currentTurn].currentHP > 0) | |
{ | |
// Pick random character for enemy to attack | |
for (int i = 0; i < movesList.Length; i++) | |
{ | |
if (movesList[i].moveName == activeBattler[currentTurn].movesAvailable[selectAttack]) | |
{ | |
// Instantiate attack effect on appropriate character | |
Instantiate(movesList[i].attackEffect, | |
activeBattler[selectedTarget].transform.position, | |
activeBattler[selectedTarget].transform.rotation); | |
// Grab move power of appropriate move | |
movePower = movesList[i].movePower; | |
} | |
} | |
// Effect to show which enemy just attacked | |
Instantiate(enemyAttackEffect, | |
activeBattler[currentTurn].transform.position, | |
activeBattler[currentTurn].transform.rotation); | |
DealDamage(selectedTarget, movePower); | |
} | |
} | |
public void DealDamage(int target, int movePower) | |
{ | |
// High level boss with a bunch of attack power will do a ton more damage. | |
float attackPower = activeBattler[currentTurn].strength + activeBattler[currentTurn].weaponPower; | |
float defensePower = activeBattler[target].defense + activeBattler[target].armorPower; | |
float randomNum = Random.Range(0.9f, 1.1f); | |
float damageCalculation; | |
if (defensePower != 0f) | |
{ | |
damageCalculation = (attackPower / defensePower) * movePower * randomNum; | |
} | |
else | |
{ | |
damageCalculation = 0.1f; | |
} | |
int damageToGive = Mathf.RoundToInt(damageCalculation); | |
Debug.Log(activeBattler[currentTurn].charName + " is dealing " | |
+ damageToGive + " (Mathf.RoundToInt(" + damageCalculation + ")) damage to " | |
+ activeBattler[target].charName); | |
activeBattler[target].currentHP -= damageToGive; | |
if (activeBattler[target].isCharacter) | |
{ | |
GameManager._instance.charStats[target].currentHP -= damageToGive; | |
} | |
Instantiate(damageText, activeBattler[target].transform.position, activeBattler[target].transform.rotation).SetDamage(damageToGive); | |
UpdateUICharInfo(); | |
} | |
public void UpdateUICharInfo() | |
{ | |
for (int i = 0; i < charName.Length; i++) | |
{ | |
if (activeBattler.Count > i) | |
{ | |
if (activeBattler[i].isCharacter) | |
{ | |
charName[i].gameObject.SetActive(true); | |
BattleCharacter charInfo = activeBattler[i]; | |
charName[i].text = charInfo.charName; | |
charHP[i].text = Mathf.Clamp(charInfo.currentHP, 0, int.MaxValue) + " / " + charInfo.maxHP; | |
charMP[i].text = Mathf.Clamp(charInfo.currentMP, 0, int.MaxValue) + " / " + charInfo.maxMP; | |
GameManager._instance.charStats[i].currentHP = activeBattler[i].currentHP; | |
GameManager._instance.charStats[i].currentMP = activeBattler[i].currentMP; | |
} | |
else | |
{ | |
charName[i].gameObject.SetActive(false); | |
} | |
} | |
else | |
{ | |
charName[i].gameObject.SetActive(true); | |
} | |
} | |
} | |
public void OpenTargetMenu(string moveName) | |
{ | |
targetMenu.SetActive(true); | |
List<int> enemy = new List<int>(); | |
for (int i = 0; i < activeBattler.Count; i++) | |
{ | |
if (!activeBattler[i].isCharacter) | |
{ | |
enemy.Add(i); | |
} | |
} | |
for (int i = 0; i < targetButtons.Length; i++) | |
{ | |
if (enemy.Count > i && activeBattler[enemy[i]].currentHP > 0) | |
{ | |
targetButtons[i].gameObject.SetActive(true); | |
targetButtons[i].moveName = moveName; | |
targetButtons[i].selectedTarget = enemy[i]; | |
targetButtons[i].targetName.text = activeBattler[enemy[i]].charName; | |
} | |
else | |
{ | |
targetButtons[i].gameObject.SetActive(false); | |
} | |
} | |
} | |
public void OpenSpellMenu() | |
{ | |
// Bring up spell menu | |
spellMenu.SetActive(true); | |
// Find out which spells character has and display button | |
for (int i = 0; i < spellButtons.Length; i++) | |
{ | |
if (activeBattler[currentTurn].movesAvailable.Length > i) | |
{ | |
spellButtons[i].gameObject.SetActive(true); | |
spellButtons[i].spellName = activeBattler[currentTurn].movesAvailable[i]; | |
spellButtons[i].spellText.text = spellButtons[i].spellName; | |
// Find out cost of spell to use | |
for (int j = 0; j < movesList.Length; j++) | |
{ | |
if (movesList[j].moveName == spellButtons[i].spellName) | |
{ | |
spellButtons[i].spellCost = movesList[j].moveCost; | |
spellButtons[i].spellCostText.text = spellButtons[i].spellCost.ToString(); | |
} | |
} | |
} | |
else | |
{ | |
spellButtons[i].gameObject.SetActive(false); | |
} | |
} | |
} | |
public void OpenItemMenu() | |
{ | |
GameManager._instance.SortItems(); | |
itemMenu.SetActive(true); | |
ShowItems(); | |
} | |
public void ShowItems() | |
{ | |
GameManager._instance.SortItems(); | |
for (int i = 0; i < itemButtons.Length; i++) | |
{ | |
itemButtons[i].buttonValue = i; | |
if (GameManager._instance.itemsHeld[i] != "") | |
{ | |
itemButtons[i].buttonImage.gameObject.SetActive(true); | |
itemButtons[i].buttonImage.sprite = GameManager._instance.GetItemDetails(GameManager._instance.itemsHeld[i]).itemSprite; | |
itemButtons[i].amountText.text = GameManager._instance.numberOfItems[i].ToString(); | |
} | |
else | |
{ | |
itemButtons[i].buttonImage.gameObject.SetActive(false); | |
itemButtons[i].amountText.text = ""; | |
} | |
} | |
} | |
public void SelectItem(Item selectedItem) | |
{ | |
activeItem = selectedItem; | |
if (selectedItem.isItem) | |
{ | |
useButtonText.text = "Use"; | |
} | |
if (activeItem.isWeapon || activeItem.isArmor) | |
{ | |
useButtonText.text = "Equip"; | |
} | |
itemName.text = activeItem.itemName; | |
itemDescription.text = activeItem.description; | |
} | |
public void UseItem() | |
{ | |
activeItem.Use(currentActiveBattler); | |
GameManager._instance.SortItems(); | |
UpdateUICharInfo(); | |
} | |
public void CloseItemMenu() | |
{ | |
itemMenu.SetActive(false); | |
} | |
public void Flee() | |
{ | |
int fleeRoll = Random.Range(0, 100); | |
if (fleeRoll < chanceToFlee) | |
{ | |
// End Battle | |
//TODO: Redo succesfull flee notification | |
//fleeRollSuccessful = true; | |
fleeing = true; | |
StartCoroutine(EndBattleCoroutine()); | |
} | |
else | |
{ | |
// Not successful | |
NextTurn(); | |
battleNotification.notificationText.text = "Couldn't flee!"; | |
battleNotification.Activate(); | |
} | |
} | |
public IEnumerator EndBattleCoroutine() | |
{ | |
battleActive = false; | |
uiButtonHolder.SetActive(false); | |
targetMenu.SetActive(false); | |
spellMenu.SetActive(false); | |
//TODO: Close item menu, too | |
//itemMenu.SetActive(false); | |
yield return new WaitForSeconds(0.5f); | |
UIFade._instance.FadeToBlack(); | |
yield return new WaitForSeconds(1.5f); | |
for (int i = 0; i < activeBattler.Count; i++) | |
{ | |
if (activeBattler[i].isCharacter) | |
{ | |
for (int j = 0; j < GameManager._instance.charStats.Length; j++) | |
{ | |
if (activeBattler[i].charName == GameManager._instance.charStats[j].charName) | |
{ | |
GameManager._instance.charStats[j].currentHP = activeBattler[i].currentHP; | |
GameManager._instance.charStats[j].currentMP = activeBattler[i].currentMP; | |
} | |
} | |
} | |
// Remove characters from memory | |
Destroy(activeBattler[i].gameObject); | |
} | |
UIFade._instance.FadeFromBlack(); | |
battleScene.SetActive(false); | |
activeBattler.Clear(); | |
currentTurn = 0; | |
//GameManager._instance.battleActive = false; | |
if (fleeing) | |
{ | |
GameManager._instance.battleActive = false; | |
AudioManager._instance.PlayBGM(FindObjectOfType<CameraController>().musicToPlay); | |
fleeing = false; | |
} | |
else | |
{ | |
BattleReward._instance.OpenRewardScreen(rewardExp, rewardItems); | |
} | |
} | |
public IEnumerator GameOverCoroutine() | |
{ | |
battleActive = false; | |
UIFade._instance.FadeToBlack(); | |
yield return new WaitForSeconds(1.5f); | |
battleScene.SetActive(false); | |
SceneManager.LoadScene(gameOverScene); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment