333 lines
10 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |