forked from Shardstone/trail-into-darkness
First commit on my server, yey!
This commit is contained in:
208
Assets/Code/Core/GameModeGameState.cs
Normal file
208
Assets/Code/Core/GameModeGameState.cs
Normal file
@@ -0,0 +1,208 @@
|
||||
#nullable enable
|
||||
using Nox.Game;
|
||||
using Nox.Platform;
|
||||
using Nox.Game.UI;
|
||||
using Jovian.SaveSystem;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
|
||||
namespace Nox.Core {
|
||||
/// <summary>
|
||||
/// The Game Mode Game State which is the base state in which all GameModes need to run.
|
||||
/// Game Modes are any modes that involve gameplay and gameplay related scenes. This state is where the game runs.
|
||||
/// </summary>
|
||||
public class GameModeGameState : IGameState {
|
||||
private readonly GameDataState gameDataState;
|
||||
private readonly PlatformSettings platformSettings;
|
||||
private readonly PlayModeSettings bootstrapSettings;
|
||||
private readonly ISaveSystem saveSystem;
|
||||
private readonly ISceneTransition sceneTransition;
|
||||
private readonly AdventureData adventuredata;
|
||||
|
||||
private readonly Dictionary<PlayMode, IPlayMode?> playModeCache = new();
|
||||
|
||||
private IMenuView? pauseMenuView;
|
||||
private IPlayMode? playMode;
|
||||
private IPlayMode? suspendedPlayMode;
|
||||
private bool isTransitioning;
|
||||
|
||||
private PlayMode currentPlaymode;
|
||||
private bool stateEntered;
|
||||
private AsyncOperationHandle<AdventureSettings> advSettingsHandler;
|
||||
private AdventureSettings? adventureSettings;
|
||||
|
||||
public bool IsGameStateInitialized {
|
||||
get => stateEntered && (playMode == null || playMode.IsGameModeInitialized);
|
||||
}
|
||||
|
||||
public GameModeGameState(GameDataState gameDataState,
|
||||
BootstrapReferences bootstrapReferences,
|
||||
PlatformSettings platformSettings,
|
||||
ISaveSystem saveSystem,
|
||||
ISceneTransition sceneTransition,
|
||||
AdventureData adventuredata) {
|
||||
this.gameDataState = gameDataState;
|
||||
this.platformSettings = platformSettings;
|
||||
this.saveSystem = saveSystem;
|
||||
this.sceneTransition = sceneTransition;
|
||||
this.adventuredata = adventuredata;
|
||||
|
||||
bootstrapSettings = Addressables.LoadAssetAsync<PlayModeSettings>(bootstrapReferences.playModeSettings).WaitForCompletion();
|
||||
}
|
||||
|
||||
public void EnterGameState() {
|
||||
if(gameDataState.ActivePlayMode == PlayMode.None) {
|
||||
var sceneReference = Object.FindFirstObjectByType<SceneReference>();
|
||||
if(bootstrapSettings.gameModeData.Any(g => g.playMode == sceneReference.playMode)) {
|
||||
gameDataState.ChangePlayMode(sceneReference.playMode);
|
||||
}
|
||||
}
|
||||
advSettingsHandler = Addressables.LoadAssetAsync<AdventureSettings>("Assets/Database/Game/AdventureSettings.asset");
|
||||
adventureSettings = advSettingsHandler.WaitForCompletion();
|
||||
InitializeGameViews();
|
||||
currentPlaymode = gameDataState.ActivePlayMode;
|
||||
playMode?.EnterPlayMode();
|
||||
Debug.Log($"Initialized Game Mode: {gameDataState.ActivePlayMode}");
|
||||
stateEntered = true;
|
||||
}
|
||||
private void InitializeGameViews() {
|
||||
SwitchGameMode();
|
||||
pauseMenuView ??= new PauseMenuView(gameDataState, saveSystem, CaptureNoxSaveData);
|
||||
}
|
||||
|
||||
private NoxSavedDataSet? CaptureNoxSaveData() {
|
||||
var adventure = FindAdventurePlayMode();
|
||||
return adventure?.CaptureNoxSaveData();
|
||||
}
|
||||
|
||||
private AdventurePlayMode? FindAdventurePlayMode() {
|
||||
if(playMode is AdventurePlayMode active) {
|
||||
return active;
|
||||
}
|
||||
if(suspendedPlayMode is AdventurePlayMode suspended) {
|
||||
return suspended;
|
||||
}
|
||||
if(playModeCache.TryGetValue(PlayMode.Adventure, out var cached) && cached is AdventurePlayMode fromCache) {
|
||||
return fromCache;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void SwitchGameMode() {
|
||||
var activeParty = gameDataState.ActiveParty;
|
||||
|
||||
if(playModeCache.TryGetValue(gameDataState.ActivePlayMode, out var cached)) {
|
||||
playMode = cached;
|
||||
return;
|
||||
}
|
||||
|
||||
playMode = gameDataState.ActivePlayMode switch {
|
||||
PlayMode.Adventure => new AdventurePlayMode(platformSettings, activeParty, bootstrapSettings, gameDataState, saveSystem, adventureSettings, adventuredata),
|
||||
PlayMode.PauseMenu => new PauseMenuPlayMode(platformSettings, gameDataState, pauseMenuView!),
|
||||
PlayMode.Town => new TownPlayMode(platformSettings, activeParty),
|
||||
PlayMode.Rest => new RestPlayMode(platformSettings, activeParty),
|
||||
PlayMode.Combat => new CombatPlayMode(platformSettings, activeParty),
|
||||
_ => playMode
|
||||
};
|
||||
|
||||
playModeCache[gameDataState.ActivePlayMode] = playMode;
|
||||
}
|
||||
|
||||
public GameState Tick() {
|
||||
if(isTransitioning) {
|
||||
return GameState.GameMode;
|
||||
}
|
||||
|
||||
if(ShouldTransition()) {
|
||||
HandlePlayModeTransition();
|
||||
return GameState.GameMode;
|
||||
}
|
||||
|
||||
if(playMode is { IsGameModeInitialized: true }) {
|
||||
playMode.Tick();
|
||||
}
|
||||
|
||||
return GameState.GameMode;
|
||||
}
|
||||
|
||||
private bool ShouldTransition() {
|
||||
return currentPlaymode != gameDataState.ActivePlayMode
|
||||
&& gameDataState.ActivePlayMode != PlayMode.None;
|
||||
}
|
||||
|
||||
private bool IsPauseTransition() {
|
||||
return gameDataState.ActivePlayMode == PlayMode.PauseMenu
|
||||
|| (currentPlaymode == PlayMode.PauseMenu && suspendedPlayMode != null);
|
||||
}
|
||||
|
||||
private void HandlePlayModeTransition() {
|
||||
if(IsPauseTransition()) {
|
||||
ExecutePlayModeSwitch();
|
||||
return;
|
||||
}
|
||||
|
||||
isTransitioning = true;
|
||||
sceneTransition.FadeOut(() => {
|
||||
ExecutePlayModeSwitch();
|
||||
sceneTransition.FadeIn(() => {
|
||||
isTransitioning = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private void ExecutePlayModeSwitch() {
|
||||
var enteringPause = gameDataState.ActivePlayMode == PlayMode.PauseMenu;
|
||||
var resumingFromPause = currentPlaymode == PlayMode.PauseMenu
|
||||
&& suspendedPlayMode != null;
|
||||
|
||||
if(enteringPause) {
|
||||
suspendedPlayMode = playMode;
|
||||
}
|
||||
|
||||
playMode?.ExitGameMode();
|
||||
currentPlaymode = gameDataState.ActivePlayMode;
|
||||
|
||||
if(resumingFromPause) {
|
||||
playMode = suspendedPlayMode;
|
||||
suspendedPlayMode = null;
|
||||
playMode?.EnterPlayMode();
|
||||
return;
|
||||
}
|
||||
|
||||
SwitchGameMode();
|
||||
playMode?.EnterPlayMode();
|
||||
}
|
||||
|
||||
public void LateTick() {
|
||||
if(playMode is { IsGameModeInitialized: true }) {
|
||||
playMode.LateTick();
|
||||
}
|
||||
}
|
||||
public void Dispose() {
|
||||
suspendedPlayMode?.Dispose();
|
||||
playMode?.Dispose();
|
||||
}
|
||||
public void ExitGameState() {
|
||||
suspendedPlayMode?.ExitGameMode();
|
||||
suspendedPlayMode?.Dispose();
|
||||
suspendedPlayMode = null;
|
||||
playMode?.ExitGameMode();
|
||||
playMode?.Dispose();
|
||||
playMode = null;
|
||||
|
||||
foreach(var cached in playModeCache.Values) {
|
||||
if(cached != null && cached != playMode && cached != suspendedPlayMode) {
|
||||
cached.Dispose();
|
||||
}
|
||||
}
|
||||
playModeCache.Clear();
|
||||
|
||||
stateEntered = false;
|
||||
gameDataState.ChangePlayMode(PlayMode.None);
|
||||
advSettingsHandler.Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user