using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using UnityEngine; using UnityEngine.SceneManagement; /// <summary> /// Primary center handler for managing encounter generation and holding /// </summary> public class GameManager : MonoBehaviour { public enum Encounters { Shop, Enemy, Event } public static GameManager Instance { get; private set; } private Encounter<Shop> shopEncounter; private Encounter<GameObject[]> enemyEncounter; private Encounter<Event> eventEncounter; private bool CursedAuraFlag = false; private GeneralUI uiRetainer; // Handles calls to change the UI private EncounterGenerator encounterGen; // Handles generating the Emcounters private bool enemyLayout; private bool shopLayout; private bool eventLayout; private GameObject uiContainer; // Container for the UI Canvas' private GameObject shopUIObjectRef; // Retainer for the Shop UI Canvas private GameObject enemyUIObjectRef; // Retainer for the Enemy UI Canvas private GameObject playerObject; private GameObject[] allyObjects; private Encounters encounterType; public Encounters GetEncounterType() => encounterType; /// <summary> /// Gets the numerical value for the Encounter /// </summary> /// <returns>Numerical Encounter Value</returns> public int GetEncounterValue() => encounterGen.GetEncounterValue(); /// <summary> /// Singleton Generation call /// </summary> private void Awake() => GenerateSingleton(); /// <summary> /// Singleton Generation for Game Manager /// </summary> private void GenerateSingleton() { if (Instance != null && Instance != this) Destroy(this); else { Instance = this; DontDestroyOnLoad(gameObject); } } private async void Start() { await AbilityBrain.LoadAllAspects(); uiRetainer = GeneralUI.Instance; GatherReferences(); playerObject = Globals.Player.CreatePlayerObject(); // TODO ---> Remove this! GenerateAlly("Phyll"); allyObjects = PositionHandler.Instance.PositionAlly(allyObjects); GeneralUI.Instance.GenerateGUIs(allyObjects); // TODO----> Remove this! // Generates a new encounter generator every game to reset conditions encounterGen = new EncounterGenerator(); encounterGen.GenerateEncounter(); RefreshModifiers(true); uiRetainer.SetInformation(); while (AbilityBrain.GetLoadingState() == null) await Task.Yield(); AbilityBrain.ModificationChecks(playerObject.GetComponent<Player>()); Ability curse = AbilityBrain.GetCurseAbilityReference(); if (playerObject.GetComponent<Player>().GetInventory().Abilities.Contains(curse)) { AbilityBrain.InitializeCursedAuraComponents(); CursedAuraFlag = true; } } private void GatherReferences() { shopUIObjectRef = Resources.Load<GameObject>("Prefabs/Town UI Object"); enemyUIObjectRef = Resources.Load<GameObject>("Prefabs/Enemy UI Object"); // TODO ---> Add gatherings for the other needed UI references } private void Update() { if (enemyLayout) { GetObject(1); enemyLayout = false; } else if (shopLayout) { GameObject instance = GetObject(0); instance.GetComponentInChildren<TownUI>().EnableShopLayout(); shopLayout = false; } else if (eventLayout) { GetObject(2); uiRetainer.EnableEventLayout(); eventLayout = false; } // Detects if the scene is now the game over scene if (SceneManager.GetActiveScene().buildIndex is 2) { GameOverUI.Instance.InjectGameMangerInfo(this); // Wipes out the active game manager upon game over screen being loaded and giving necessary information to the screen // Also wipes out the BattleHandler, SpellManager, and ItemManager, but will be reset upon a new game being loaded Destroy(this.gameObject); } } public void IndicateEncounterType(int v, object encounter) { if (shopEncounter != null || enemyEncounter != null || eventEncounter != null) { shopEncounter = null; enemyEncounter = null; eventEncounter = null; } switch (v) { case 0: { shopEncounter = encounter as Encounter<Shop>; shopLayout = true; break; } case 1: { enemyEncounter = encounter as Encounter<GameObject[]>; enemyLayout = true; break; } case 2: { eventEncounter = encounter as Encounter<Event>; eventLayout = true; break; } } MusicManager.Instance.DetermineNewSoundtrack(true); } public GameObject GetObject(int index) { if (uiContainer != null) Destroy(uiContainer); GameObject output = null; switch (index) { case 0: // Shop Encounter { output = Instantiate(shopUIObjectRef); encounterType = Encounters.Shop; output.GetComponent<TownUI>().InsertShopInfo(shopEncounter.Value); break; } case 1: // Enemy Encounter { output = Instantiate(enemyUIObjectRef); encounterType = Encounters.Enemy; EnemyUI UIRef = output.GetComponent<EnemyUI>(); UIRef.InsertEnemyInfo(enemyEncounter.Value); break; } case 2: // Event Encounter encounterType = Encounters.Event; break; default: throw new NullReferenceException(); } uiContainer = output; return output; } public void EndEncounter(Player playerState, Ally[] allies = null) { AbilityBrain.EndEncounterChecks(playerState, allies); // Regenerate percentage of mana after the end of every Encounter playerState.IncreaseMana(playerState.GatherStats().GetStat(EntityStats.Stat.MPRegen, (int)(playerState.RetrieveMaxMana() * playerState.GetManaRegen()))); playerState.StatusChanged(); GeneralUI.Instance.SetInformation(false); if (allies != null) { foreach (Ally ally in allies) { ally.IncreaseMana(ally.GatherStats().GetStat(EntityStats.Stat.MPRegen, (int)(ally.RetrieveMaxMana() * ally.GetManaRegen()))); ally.StatusChanged(); GeneralUI.Instance.UpdateGUIs(allyObjects); } } // Sets the ally states for all of the party members if allies are available if (playerState.GetInventory().CurrentPartyMembers.Count > 0) { List<PartyMember> partyMember = playerState.GetInventory().CurrentPartyMembers; for (int i = 0; i < allies.Length; i++) { for (int j = 0; j < partyMember.Count; j++) { if (partyMember[j].GetMemberName().Equals(allies[i].GetName())) { partyMember[j].SetAllyState(allies[i]); break; } } } } // Reset the containers shopEncounter = null; enemyEncounter = null; eventEncounter = null; Destroy(uiContainer); // Generate a new encounter encounterGen.GenerateEncounter(); RefreshModifiers(); } public EncounterGenerator GetEncounterGenerator() => encounterGen; public GameObject GetPlayerObject() => playerObject; public void GenerateAlly(string allyName) { GameObject allyObject; try { allyObject = Resources.Load<GameObject>($"Entities/Allies/{allyName}"); } catch { allyObject = null; } if (allyObject != null) { if (allyObjects == null) { allyObjects = new GameObject[3]; allyObjects[0] = allyObject; } else { for (int i = 0; i < allyObjects.Length; i++) { if (allyObjects[i] == null) { allyObjects[i] = allyObject; break; } } } } } public GameObject[] GetAllyObjects() => allyObjects.Length is not 0 ? allyObjects : null; public void RefreshModifiers(bool enteringGame = false) { playerObject.GetComponent<Player>().GetInventory().RefreshApparel(enteringGame); foreach (GameObject ally in allyObjects) ally.GetComponent<Ally>().GetInventory().RefreshApparel(enteringGame); } }