Skip to content

Instantly share code, notes, and snippets.

@spaghettiSyntax
Last active January 31, 2020 19:11
Show Gist options
  • Save spaghettiSyntax/ce2c924056d09a8aeb336af3ad8e359f to your computer and use it in GitHub Desktop.
Save spaghettiSyntax/ce2c924056d09a8aeb336af3ad8e359f to your computer and use it in GitHub Desktop.
Battle Manager
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