Encounter / Assets / Scripts / GameManager.cs
GameManager.cs
Raw
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);
    }
}