forked from Shardstone/trail-into-darkness
202 lines
8.7 KiB
C#
202 lines
8.7 KiB
C#
using Jovian.Calendar;
|
|
using Jovian.PopupSystem;
|
|
using Jovian.PopupSystem.UI;
|
|
using Jovian.SaveSystem;
|
|
using Jovian.ZoneSystem;
|
|
using Nox.Core;
|
|
using Nox.Platform;
|
|
using Nox.Game.UI;
|
|
using Nox.UI;
|
|
using ZLinq;
|
|
using UnityEngine;
|
|
using UnityEngine.AddressableAssets;
|
|
using PlayMode = Nox.Core.PlayMode;
|
|
|
|
namespace Nox.Game {
|
|
public class AdventureData {
|
|
public bool isPartyMoving;
|
|
public int currentDay = 0;
|
|
public int suppliesAvailable = -1;
|
|
public float currentTime = -1f;
|
|
public DayPhase currentDayPhase = DayPhase.Morning;
|
|
}
|
|
|
|
public class AdventurePlayMode : IPlayMode {
|
|
private readonly PlatformSettings platformSettings;
|
|
private readonly PlayModeSettings bootstrapSettings;
|
|
private readonly GameDataState gameDataState;
|
|
private readonly ISaveSystem saveSystem;
|
|
private readonly PartyDefinition partyDefinition;
|
|
private readonly AdventureSettings adventureSettings;
|
|
private AdventureData adventureData;
|
|
private AdventureModePrefabs scenePrefabs;
|
|
private ICameraController cameraController;
|
|
private MapReference mapRef;
|
|
private PartyMovementHandler partyMovementHandler;
|
|
private PartyReference partyRef;
|
|
private MapLocationsReference mapLocationsReference;
|
|
private InputSystem_Actions inputActions;
|
|
private AdventureView adventureView;
|
|
private ZoneSystem zoneSystem;
|
|
private GuiReferences guiReferences;
|
|
private TimeHandler timeHandler;
|
|
private PartyInventoryHandler partyInventoryHandler;
|
|
private PartyGuiView partyGuiView;
|
|
private IPopupSystem popupSystem;
|
|
|
|
public AdventurePlayMode(
|
|
PlatformSettings platformSettings,
|
|
PartyDefinition partyDefinition,
|
|
PlayModeSettings bootstrapSettings,
|
|
GameDataState gameDataState,
|
|
ISaveSystem saveSystem,
|
|
AdventureSettings adventureSettings,
|
|
AdventureData adventureData) {
|
|
this.platformSettings = platformSettings;
|
|
this.partyDefinition = partyDefinition;
|
|
this.bootstrapSettings = bootstrapSettings;
|
|
this.gameDataState = gameDataState;
|
|
this.saveSystem = saveSystem;
|
|
this.adventureSettings = adventureSettings;
|
|
this.adventureData = adventureData;
|
|
}
|
|
|
|
public bool IsGameModeInitialized { get; private set; }
|
|
|
|
public void EnterPlayMode() {
|
|
inputActions = platformSettings.inputSettings.inputActions;
|
|
if(IsGameModeInitialized) {
|
|
inputActions.Player.Enable();
|
|
inputActions.UI.PauseMenu.Enable();
|
|
partyMovementHandler.ConsumeNextClick();
|
|
return;
|
|
}
|
|
Addressables.LoadSceneAsync(bootstrapSettings.gameModeData.AsValueEnumerable().FirstOrDefault(g => g.playMode == PlayMode.Adventure)?.scene)
|
|
.WaitForCompletion().ActivateAsync().completed += InitializeGameMode;
|
|
}
|
|
|
|
private void InitializeGameMode(AsyncOperation obj) {
|
|
inputActions.Player.Enable();
|
|
inputActions.UI.PauseMenu.Enable();
|
|
Debug.Log("Entering Adventure Play Mode");
|
|
if(partyDefinition == null) {
|
|
var sessions = saveSystem.GetAllSessions().AsValueEnumerable().OrderByDescending(s => s.lastSaveDateUtc).ToList();
|
|
if(sessions.Count == 0) {
|
|
return;
|
|
}
|
|
|
|
var latestSession = sessions[0];
|
|
var slots = saveSystem.GetSlots(latestSession.sessionId).AsValueEnumerable().OrderByDescending(s => s.timestampUtc).ToList();
|
|
if(slots.Count == 0) {
|
|
return;
|
|
}
|
|
|
|
var latestSlot = slots[0];
|
|
var saveData = saveSystem.Load<NoxSaveData>(latestSlot);
|
|
Debug.Log($"Loaded save {latestSlot.DisplayLabel}");
|
|
if(saveData == null) {
|
|
Debug.LogError("Failed to load save data");
|
|
return;
|
|
}
|
|
|
|
NoxSaveData.RestoreSavedData(saveSystem, gameDataState, ref adventureData);
|
|
Debug.LogWarning("AdventurePlayMode started from the Adventure Scene. Loading the last Autosave");
|
|
}
|
|
|
|
scenePrefabs ??= Addressables.LoadAssetAsync<AdventureModePrefabs>("AdventureMapPrefabs").WaitForCompletion();
|
|
mapRef ??= Object.FindFirstObjectByType<MapReference>();
|
|
partyRef ??= Object.FindFirstObjectByType<PartyReference>();
|
|
if(partyRef && gameDataState.savedPartyPosition.HasValue) {
|
|
partyRef.transform.position = gameDataState.savedPartyPosition.Value;
|
|
}
|
|
mapLocationsReference ??= Object.FindFirstObjectByType<MapLocationsReference>();
|
|
if(!mapRef) {
|
|
mapRef ??= Object.Instantiate(scenePrefabs.mapReferencePrefab);
|
|
}
|
|
cameraController ??= new CameraController(platformSettings, mapRef);
|
|
cameraController.Initialize();
|
|
|
|
if(adventureData.suppliesAvailable == -1) {
|
|
adventureData.suppliesAvailable = adventureSettings.maxSupplies;
|
|
}
|
|
if(Mathf.Approximately(adventureData.currentTime, -1f)) {
|
|
adventureData.currentTime = 0.25f;
|
|
}
|
|
|
|
partyInventoryHandler ??= new PartyInventoryHandler(adventureData, adventureSettings);
|
|
partyInventoryHandler.Initialize();
|
|
|
|
var calendarSettings = Addressables.LoadAssetAsync<CalendarSettings>("CalendarSettings").WaitForCompletion();
|
|
var worldClock = new WorldClock(calendarSettings);
|
|
timeHandler ??= new TimeHandler(adventureSettings, adventureData, worldClock);
|
|
zoneSystem ??= new ZoneSystem(mapRef.zonesObjectHolder);
|
|
|
|
partyMovementHandler ??= new PartyMovementHandler(partyRef, cameraController, mapLocationsReference, platformSettings.inputSettings, zoneSystem, adventureData, adventureSettings);
|
|
partyMovementHandler.Initialize();
|
|
|
|
guiReferences ??= Object.FindFirstObjectByType<GuiReferences>();
|
|
adventureView ??= new AdventureView(gameDataState, guiReferences, inputActions, adventureData, adventureSettings, worldClock);
|
|
adventureView.Initialize();
|
|
|
|
if(partyGuiView == null && guiReferences.partyMemberSlotPrefab != null) {
|
|
var portraitsHolder = Addressables.LoadAssetAsync<PortraitsHolder>("PortraitsHolder").WaitForCompletion();
|
|
|
|
if(popupSystem == null) {
|
|
var popupSettings = Addressables.LoadAssetAsync<PopupSettings>("PopupSettings").WaitForCompletion();
|
|
var popupViewPrefab = Addressables.LoadAssetAsync<GameObject>("PopupReferencePrefab").WaitForCompletion().GetComponent<PopupReference>();
|
|
var guiCanvas = guiReferences.GetComponentInParent<Canvas>().transform;
|
|
popupSystem = new PopupSystem(popupSettings, popupViewPrefab, guiCanvas);
|
|
popupSystem.RegisterCategory(PopupCategory.Character, priority: 10);
|
|
}
|
|
|
|
partyGuiView = new PartyGuiView(guiReferences.portraitsContainer, guiReferences.partyMemberSlotPrefab, portraitsHolder, popupSystem);
|
|
partyGuiView.Initialize(partyDefinition);
|
|
}
|
|
|
|
IsGameModeInitialized = true;
|
|
}
|
|
|
|
public void Tick() {
|
|
if(!IsGameModeInitialized) {
|
|
return;
|
|
}
|
|
|
|
timeHandler.Tick();
|
|
partyInventoryHandler.Tick();
|
|
partyMovementHandler.Tick();
|
|
adventureView.Tick();
|
|
partyGuiView?.Tick();
|
|
popupSystem?.Tick(Time.deltaTime);
|
|
|
|
if(inputActions.UI.PauseMenu.WasPerformedThisFrame()) {
|
|
gameDataState.ChangePlayMode(PlayMode.PauseMenu);
|
|
}
|
|
}
|
|
public void LateTick() {
|
|
if(!IsGameModeInitialized) {
|
|
return;
|
|
}
|
|
cameraController.Tick();
|
|
}
|
|
public NoxSavedDataSet CaptureNoxSaveData() {
|
|
return new NoxSavedDataSet {
|
|
activePlayMode = PlayMode.Adventure,
|
|
activeParty = partyDefinition,
|
|
partyPosition = partyRef ? SerializableVector3.FromVector3(partyRef.transform.position) : SerializableVector3.Zero
|
|
};
|
|
}
|
|
|
|
public void ExitGameMode() {
|
|
inputActions.Player.Disable();
|
|
inputActions.UI.PauseMenu.Disable();
|
|
}
|
|
public void Dispose() {
|
|
cameraController?.Dispose();
|
|
partyMovementHandler?.Dispose();
|
|
partyGuiView?.Dispose();
|
|
popupSystem?.Dispose();
|
|
}
|
|
}
|
|
|
|
}
|