Files
beyond/Assets/Scripts/GameState/GameStateManager.cs

333 lines
10 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
//using Gaia;
using Invector.vCharacterController;
using Invector.vCharacterController.AI;
using Invector.vCharacterController.AI.FSMBehaviour;
using PixelCrushers;
using Sirenix.OdinInspector;
using SRF.Components;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
namespace Beyond
{
public class GameStateManager : Saver//AutoSingleton<GameStateManager>
{
public enum Difficulty
{
EASY = 0,
NORMAL = 1,
HARD = 2,
COUNT
};
[Button]
public void SetDifficulty(Difficulty d)
{
m_saveData.difficulty = d;
switch (d)
{
case Difficulty.EASY:
m_enemyDamageModifier = 0.63f;
break;
case Difficulty.NORMAL:
m_enemyDamageModifier = 1f;
break;
case Difficulty.HARD:
m_enemyDamageModifier = 1.35f;
break;
}
}
[Serializable]
public class SaveData
{
public Difficulty difficulty = Difficulty.NORMAL;
}
private static GameStateManager s_instance = null;
private static bool s_isDestroyed = false;
private float m_enemyDamageModifier = 1f;
public SaveData m_saveData = new();
private HashSet<string> m_CompabStates;
private HashSet<string> m_IdleStates;
public static GameStateManager Instance// => s_instance;
{
get
{
if (s_instance)
{
return s_instance;
}
else if (s_isDestroyed)
{
//don't recreate object after scene destorys it
return null;
}
else
{
var inst = FindObjectOfType<GameStateManager>();
if (inst != null)
{
s_instance = inst;
return s_instance;
}
else
{
var go = new GameObject("_" + typeof(GameStateManager).Name);
go.AddComponent<GameStateManager>(); // _instance set by Awake() constructor
}
}
return s_instance;
}
}
//public void OnSc
public override void OnDestroy()
{
base.OnDestroy();
s_isDestroyed = true;
// Debug.Log("Destroying GameStateManager");
}
//[ShowInInspector]
public Difficulty GameDifficulty => m_saveData.difficulty;
public float EnemyDamageModifier => m_enemyDamageModifier;
public override void Awake()
{
base.Awake();
if (s_instance != null)
{
Debug.Log("GameStateManager already exists! destroying...");
Destroy(this);
return;
}
SceneManager.sceneLoaded += SceneManager_sceneUnloaded;
s_instance = this;
//SetDifficulty(Difficulty.NORMAL);
m_CompabStates = new HashSet<string>();
m_CompabStates.Add("Combat");
m_CompabStates.Add("Alert");
m_CompabStates.Add("Jump Chase");
m_CompabStates.Add("Jump");
m_CompabStates.Add("Chase");
m_IdleStates = new HashSet<string>();
m_IdleStates.Add("Idle");
m_IdleStates.Add("Flee");
m_IdleStates.Add("Patrol");
}
//reset isDestroyed, so object can be recreated for the next scene
private void SceneManager_sceneUnloaded(Scene arg0, LoadSceneMode arg1)
{
s_isDestroyed = false;
}
public enum State
{
NORMAL,
COMBAT
}
public UnityEvent<State> m_OnStateChanged = new UnityEvent<State>();
private HashSet<vFSMBehaviourController> m_combatControllers = new HashSet<vFSMBehaviourController>();
private State m_state = State.NORMAL, m_prevState = State.NORMAL;
public State CurrentState => m_state;
public bool m_changeCameraState;
public string m_cameraCombatState = "Combat";
public vThirdPersonInput m_thirdPersonInput;
private GenericInput m_jumpInput, m_rollInput;
protected bDrawHideMeleeWeapons m_weaponDraw;
protected vThirdPersonController m_thirdPersonController;
public bool m_autoDrawWeapon = true;
// Start is called before the first frame update
public HashSet<vFSMBehaviourController> GetActiveCombatcontrollers()
{
return m_combatControllers;
}
public override void Reset()
{
base.Reset();
saveAcrossSceneChanges = true;
m_saveData.difficulty = Difficulty.NORMAL;
}
[Button]
public void SetEasy()
{
m_saveData.difficulty = Difficulty.EASY;
}
[Button]
public void SetNormal()
{
m_saveData.difficulty = Difficulty.NORMAL;
}
[Button]
public void SetHard()
{
m_saveData.difficulty = Difficulty.HARD;
}
private void Start()
{
// m_state = State.NORMAL;
if (Player.Instance == null)
{
return;
}
if (m_thirdPersonInput == null)
m_thirdPersonInput = Player.Instance.GetComponent<vThirdPersonInput>();
if (m_weaponDraw == null)
m_weaponDraw = Player.Instance.GetComponent<bDrawHideMeleeWeapons>();
if (m_thirdPersonController == null)
m_thirdPersonController = Player.Instance.GetComponent<vThirdPersonController>();
var respawner = Player.Instance.GetComponent<Respawner>();
if (respawner != null)
{
respawner.m_onRespawned.AddListener(ResetState);
}
m_jumpInput = m_thirdPersonInput.jumpInput;
m_rollInput = m_thirdPersonInput.rollInput;
}
public override string RecordData()
{
return SaveSystem.Serialize(m_saveData);
}
public override void ApplyData(string s)
{
if (!String.IsNullOrEmpty(s))
{
m_saveData = SaveSystem.Deserialize<SaveData>(s);
SetDifficulty(m_saveData.difficulty);
}
}
public override void ApplyDataImmediate()
{
// Immediately restore Lua in case other scripts'
// Start() methods need to read values from it.
var data = SaveSystem.currentSavedGameData.GetData(key);
if (!String.IsNullOrEmpty(data))
{
m_saveData = SaveSystem.Deserialize<SaveData>(data);
SetDifficulty(m_saveData.difficulty);
}
}
private void ResetState()
{
foreach (var c in m_combatControllers)
{
c.ResetFSM();
}
m_combatControllers.Clear();
m_thirdPersonInput.ResetCameraState();
SetState(State.NORMAL);
}
public void SetState(State state)
{
if (m_state == state)
return;
m_prevState = m_state;
if (m_changeCameraState)
{
if (m_prevState == State.COMBAT)
{
m_thirdPersonInput.ResetCameraState();
//SetDefaultInputsForRollJump();
}
else if (state == State.COMBAT)
{
//SetRollInputOnJump();
m_thirdPersonInput.ChangeCameraState(m_cameraCombatState, true);
}
}
switch (state)
{
case State.COMBAT:
//SetRollInputOnJump();
if (m_autoDrawWeapon && m_weaponDraw != null)
{
m_weaponDraw.DrawWeapons();
}
break;
case State.NORMAL:
//SetDefaultInputsForRollJump();
if (m_autoDrawWeapon && m_weaponDraw != null)
{
m_weaponDraw.HideWeapons();
}
break;
}
m_state = state;
m_OnStateChanged?.Invoke(m_state);
}
/*
private void SetRollInputOnJump()
{
m_thirdPersonInput.rollInput = m_jumpInput;
m_thirdPersonInput.jumpInput = m_rollInput;
}
private void SetDefaultInputsForRollJump()
{
m_thirdPersonInput.rollInput = m_rollInput;
m_thirdPersonInput.jumpInput = m_jumpInput;
}
*/
public void OnCombat(vFSMBehaviourController combatController)
{
if (m_combatControllers.Count == 0)
{
SetState(State.COMBAT);
}
m_combatControllers.Add(combatController);
}
public void OnCombatEnd(vFSMBehaviourController combatController)
{
m_combatControllers.Remove(combatController);
if (m_combatControllers.Count == 0)
{
SetState(State.NORMAL);
}
}
// Update is called once per frame
//private float m_timer = 1;
private void Update()
{
foreach (var c in m_combatControllers)
{
//Debug.Log($"{c.name} is in {c.currentState.Name}");
string name = c.currentState.Name;
//if (!m_CompabStates.Contains(name))
if (m_IdleStates.Contains(name))
{
OnCombatEnd(c);
break;
}
}
}
}
}