First commit for private source control. Older commits available on Github.
This commit is contained in:
BIN
Assets/Scripts/Framework/Managers/Levels/.DS_Store
vendored
Normal file
BIN
Assets/Scripts/Framework/Managers/Levels/.DS_Store
vendored
Normal file
Binary file not shown.
3
Assets/Scripts/Framework/Managers/Levels/Data.meta
Normal file
3
Assets/Scripts/Framework/Managers/Levels/Data.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fe1cec78ab0b4a05bdafb735afcfab5a
|
||||
timeCreated: 1773830332
|
||||
243
Assets/Scripts/Framework/Managers/Levels/Data/BaseItem.cs
Normal file
243
Assets/Scripts/Framework/Managers/Levels/Data/BaseItem.cs
Normal file
@@ -0,0 +1,243 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using BriarQueen.Data.Identifiers;
|
||||
using BriarQueen.Data.IO.Saves;
|
||||
using BriarQueen.Framework.Assets;
|
||||
using BriarQueen.Framework.Coordinators.Events;
|
||||
using BriarQueen.Framework.Events.Save;
|
||||
using BriarQueen.Framework.Events.UI;
|
||||
using BriarQueen.Framework.Managers.Audio;
|
||||
using BriarQueen.Framework.Managers.Interaction.Data;
|
||||
using BriarQueen.Framework.Managers.IO;
|
||||
using BriarQueen.Framework.Managers.Player;
|
||||
using BriarQueen.Framework.Managers.Player.Data;
|
||||
using BriarQueen.Framework.Managers.UI;
|
||||
using BriarQueen.Framework.Registries;
|
||||
using BriarQueen.Framework.Services.Destruction;
|
||||
using BriarQueen.Framework.Services.Settings;
|
||||
using BriarQueen.Framework.Services.Tutorials;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using PrimeTween;
|
||||
using UnityEngine;
|
||||
using VContainer;
|
||||
|
||||
namespace BriarQueen.Framework.Managers.Levels.Data
|
||||
{
|
||||
public class BaseItem : MonoBehaviour, IInteractable
|
||||
{
|
||||
[Header("Item Details")]
|
||||
[SerializeField]
|
||||
private ItemDataSo _itemData;
|
||||
|
||||
[Tooltip("Used for custom tooltip. Defaults to Item Name")]
|
||||
[SerializeField]
|
||||
private string _interactableTooltip = string.Empty;
|
||||
|
||||
[Header("Object Setup")]
|
||||
[SerializeField]
|
||||
protected CanvasGroup _canvasGroup;
|
||||
|
||||
protected AddressableManager AddressableManager;
|
||||
protected AssetRegistry AssetRegistry;
|
||||
protected DestructionService DestructionService;
|
||||
|
||||
protected EventCoordinator EventCoordinator;
|
||||
protected CancellationTokenSource PickupCts;
|
||||
|
||||
protected Sequence PickupSequence;
|
||||
protected PlayerManager PlayerManager;
|
||||
protected SaveManager SaveManager;
|
||||
protected SettingsService SettingsService;
|
||||
|
||||
protected TutorialService TutorialService;
|
||||
protected AudioManager AudioManager;
|
||||
|
||||
public ItemDataSo ItemData => _itemData;
|
||||
|
||||
public CanvasGroup CanvasGroup => _canvasGroup;
|
||||
|
||||
protected string InteractableTooltip => _interactableTooltip;
|
||||
|
||||
public GameObject GameObject => gameObject;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (_canvasGroup == null)
|
||||
_canvasGroup = GetComponent<CanvasGroup>();
|
||||
}
|
||||
|
||||
public virtual UICursorService.CursorStyle ApplicableCursorStyle => UICursorService.CursorStyle.Pickup;
|
||||
|
||||
public virtual string InteractableName =>
|
||||
!string.IsNullOrWhiteSpace(_interactableTooltip) ? _interactableTooltip : _itemData.ItemName;
|
||||
|
||||
/// <summary>
|
||||
/// Called when the item is interacted with. Defaults to Pickup.
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
public virtual async UniTask OnInteract(ItemDataSo item = null)
|
||||
{
|
||||
if (item != null)
|
||||
{
|
||||
EventCoordinator.Publish(new DisplayInteractEvent(InteractEventIDs.Get(ItemInteractKey.CantUseItem)));
|
||||
return;
|
||||
}
|
||||
|
||||
CheckCyclingTutorial();
|
||||
|
||||
if (!CheckEmptyHands())
|
||||
return;
|
||||
|
||||
await Pickup();
|
||||
await OnInteracted();
|
||||
}
|
||||
|
||||
public virtual UniTask EnterHover()
|
||||
{
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
public virtual UniTask ExitHover()
|
||||
{
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when item is interacted with.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected virtual UniTask OnInteracted()
|
||||
{
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
protected virtual bool CheckEmptyHands()
|
||||
{
|
||||
if (PlayerManager.GetEquippedTool() != ToolID.None)
|
||||
{
|
||||
EventCoordinator.Publish(new DisplayInteractEvent(InteractEventIDs.Get(ItemInteractKey.EmptyHands)));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void CheckCyclingTutorial()
|
||||
{
|
||||
TutorialService.DisplayTutorial(TutorialPopupID.ItemCycling);
|
||||
}
|
||||
|
||||
[Inject]
|
||||
public void Construct(EventCoordinator eventCoordinator, SaveManager saveManager, PlayerManager playerManager,
|
||||
DestructionService destructionService, SettingsService settingsService,
|
||||
AddressableManager addressableManager, AssetRegistry assetRegistry, TutorialService tutorialService,
|
||||
AudioManager audioManager)
|
||||
{
|
||||
EventCoordinator = eventCoordinator;
|
||||
SaveManager = saveManager;
|
||||
PlayerManager = playerManager;
|
||||
DestructionService = destructionService;
|
||||
SettingsService = settingsService;
|
||||
AddressableManager = addressableManager;
|
||||
AssetRegistry = assetRegistry;
|
||||
TutorialService = tutorialService;
|
||||
AudioManager = audioManager;
|
||||
}
|
||||
|
||||
protected virtual async UniTask Remove()
|
||||
{
|
||||
// TODO - Play Cut Vines SFX
|
||||
if (_canvasGroup == null) _canvasGroup = GetComponent<CanvasGroup>();
|
||||
|
||||
if (PickupSequence.isAlive)
|
||||
{
|
||||
PickupSequence.Complete();
|
||||
PickupCts?.Cancel();
|
||||
PickupCts?.Dispose();
|
||||
}
|
||||
|
||||
PickupCts = new CancellationTokenSource();
|
||||
|
||||
PickupSequence = Sequence.Create().Group(Tween.Alpha(_canvasGroup, new TweenSettings<float>
|
||||
{
|
||||
startValue = _canvasGroup.alpha,
|
||||
endValue = 0,
|
||||
settings = new TweenSettings
|
||||
{
|
||||
duration = 0.5f
|
||||
}
|
||||
}));
|
||||
|
||||
try
|
||||
{
|
||||
await PickupSequence.ToUniTask(cancellationToken: PickupCts.Token);
|
||||
await OnRemoved();
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
UpdateSaveGameOnRemoval();
|
||||
await DestructionService.Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSaveGameOnRemoval()
|
||||
{
|
||||
var save = SaveManager.CurrentSave;
|
||||
Debug.Log($"[Base Item] Found save - {save.SaveFileName}");
|
||||
|
||||
save.RemovedItems ??= new List<ItemSaveData>();
|
||||
|
||||
save.RemovedItems.Add(new ItemSaveData
|
||||
{
|
||||
UniqueIdentifier = _itemData.UniqueID
|
||||
});
|
||||
|
||||
EventCoordinator.PublishImmediate(new RequestGameSaveEvent());
|
||||
}
|
||||
|
||||
protected virtual UniTask OnRemoved()
|
||||
{
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
protected virtual async UniTask Pickup()
|
||||
{
|
||||
if (_canvasGroup == null) _canvasGroup = GetComponent<CanvasGroup>();
|
||||
|
||||
if (PickupSequence.isAlive)
|
||||
{
|
||||
PickupSequence.Complete();
|
||||
PickupCts?.Cancel();
|
||||
PickupCts?.Dispose();
|
||||
}
|
||||
|
||||
PickupCts = new CancellationTokenSource();
|
||||
|
||||
PickupSequence = Sequence.Create().Group(Tween.Alpha(_canvasGroup, new TweenSettings<float>
|
||||
{
|
||||
startValue = _canvasGroup.alpha,
|
||||
endValue = 0,
|
||||
settings = new TweenSettings
|
||||
{
|
||||
duration = 0.5f
|
||||
}
|
||||
}));
|
||||
|
||||
try
|
||||
{
|
||||
await PickupSequence.ToUniTask(cancellationToken: PickupCts.Token);
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
PlayerManager.CollectItem(_itemData);
|
||||
await DestructionService.Destroy(gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 529a2a922f6f48a982159e2dbc41c542
|
||||
timeCreated: 1770918505
|
||||
116
Assets/Scripts/Framework/Managers/Levels/Data/BaseLevel.cs
Normal file
116
Assets/Scripts/Framework/Managers/Levels/Data/BaseLevel.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
using System.Collections.Generic;
|
||||
using BriarQueen.Data.Identifiers;
|
||||
using BriarQueen.Framework.Coordinators.Events;
|
||||
using BriarQueen.Framework.Events.UI;
|
||||
using BriarQueen.Framework.Managers.Hints.Data;
|
||||
using BriarQueen.Framework.Managers.Interaction;
|
||||
using BriarQueen.Framework.Managers.IO;
|
||||
using BriarQueen.Framework.Managers.Player;
|
||||
using BriarQueen.Framework.Managers.Player.Data.Codex;
|
||||
using BriarQueen.Framework.Services.Destruction;
|
||||
using BriarQueen.Framework.Services.Settings;
|
||||
using BriarQueen.Framework.Services.Tutorials;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using VContainer;
|
||||
|
||||
namespace BriarQueen.Framework.Managers.Levels.Data
|
||||
{
|
||||
public class BaseLevel : MonoBehaviour
|
||||
{
|
||||
[Header("General")]
|
||||
[SerializeField]
|
||||
private LevelKey _levelKey;
|
||||
[SerializeField]
|
||||
private string _levelName;
|
||||
[Header("Items")]
|
||||
[SerializeField]
|
||||
public List<BaseItem> Pickups;
|
||||
|
||||
public List<CodexTrigger> CodexTriggers;
|
||||
|
||||
[Header("Setup")]
|
||||
[SerializeField]
|
||||
protected GraphicRaycaster _raycaster;
|
||||
|
||||
protected DestructionService DestructionService;
|
||||
|
||||
protected EventCoordinator EventCoordinator;
|
||||
protected InteractManager InteractManager;
|
||||
protected PlayerManager PlayerManager;
|
||||
protected SaveManager SaveManager;
|
||||
protected SettingsService SettingsService;
|
||||
protected TutorialService TutorialService;
|
||||
public virtual string SceneID => AssetKeyIdentifiers.Get(SceneKey.GameScene);
|
||||
public string LevelID => AssetKeyIdentifiers.Get(_levelKey);
|
||||
|
||||
public virtual string LevelName => _levelName;
|
||||
|
||||
public virtual bool IsPuzzleLevel { get; }
|
||||
|
||||
public virtual int CurrentLevelHintStage { get; set; }
|
||||
|
||||
public virtual Dictionary<int, BaseHint> Hints { get; }
|
||||
|
||||
[Inject]
|
||||
public void Construct(EventCoordinator eventCoordinator, InteractManager interactManager, SaveManager saveManager,
|
||||
DestructionService destructionService, SettingsService settingsService, PlayerManager playerManager,
|
||||
TutorialService tutorialService)
|
||||
{
|
||||
EventCoordinator = eventCoordinator;
|
||||
InteractManager = interactManager;
|
||||
SaveManager = saveManager;
|
||||
DestructionService = destructionService;
|
||||
SettingsService = settingsService;
|
||||
PlayerManager = playerManager;
|
||||
TutorialService = tutorialService;
|
||||
}
|
||||
|
||||
public async UniTask PostLoad()
|
||||
{
|
||||
InteractManager.AddUIRaycaster(_raycaster);
|
||||
EventCoordinator.Publish(new UIToggleHudEvent(true));
|
||||
|
||||
await PostLoadInternal();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called after Level Load, but before activating. Override for Implementations
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected virtual UniTask PostLoadInternal()
|
||||
{
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
public async UniTask PostActivate()
|
||||
{
|
||||
await PostActivateInternal();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called after a level is activated. Override for implementations.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected virtual UniTask PostActivateInternal()
|
||||
{
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
|
||||
public async UniTask PreUnload()
|
||||
{
|
||||
InteractManager.RemoveUIRaycaster(_raycaster);
|
||||
await PreUnloadInternal();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called before the level is destroyed. Override for cleanup, etc.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected virtual UniTask PreUnloadInternal()
|
||||
{
|
||||
return UniTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ccd49cd2f5c4e8b9cfd394f7844bdf8
|
||||
timeCreated: 1769725044
|
||||
301
Assets/Scripts/Framework/Managers/Levels/LevelManager.cs
Normal file
301
Assets/Scripts/Framework/Managers/Levels/LevelManager.cs
Normal file
@@ -0,0 +1,301 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using BriarQueen.Data.IO.Saves;
|
||||
using BriarQueen.Framework.Assets;
|
||||
using BriarQueen.Framework.Coordinators.Events;
|
||||
using BriarQueen.Framework.Events.Gameplay;
|
||||
using BriarQueen.Framework.Events.Progression;
|
||||
using BriarQueen.Framework.Events.Save;
|
||||
using BriarQueen.Framework.Events.UI;
|
||||
using BriarQueen.Framework.Managers.IO;
|
||||
using BriarQueen.Framework.Managers.Levels.Data;
|
||||
using BriarQueen.Framework.Registries;
|
||||
using BriarQueen.Framework.Services.Destruction;
|
||||
using BriarQueen.Framework.Services.Puzzles;
|
||||
using BriarQueen.Framework.Services.Puzzles.Base;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using VContainer;
|
||||
|
||||
namespace BriarQueen.Framework.Managers.Levels
|
||||
{
|
||||
public class LevelManager : IDisposable, IManager
|
||||
{
|
||||
private const float LEVEL_FADE_DURATION = 1f;
|
||||
|
||||
private readonly AddressableManager _addressableManager;
|
||||
private readonly AssetRegistry _assetRegistry;
|
||||
private readonly DestructionService _destructionService;
|
||||
private readonly EventCoordinator _eventCoordinator;
|
||||
private readonly object _lock = new();
|
||||
private readonly PuzzleService _puzzleService;
|
||||
private readonly SaveManager _saveManager;
|
||||
|
||||
private UniTask<bool> _activeLoadTask = UniTask.FromResult(false);
|
||||
private BaseLevel _currentLevel;
|
||||
|
||||
public bool Initialized { get; private set; }
|
||||
|
||||
[Inject]
|
||||
public LevelManager(
|
||||
AddressableManager addressableManager,
|
||||
AssetRegistry assetRegistry,
|
||||
DestructionService destructionService,
|
||||
EventCoordinator eventCoordinator,
|
||||
SaveManager saveManager,
|
||||
PuzzleService puzzleService)
|
||||
{
|
||||
_addressableManager = addressableManager;
|
||||
_assetRegistry = assetRegistry;
|
||||
_destructionService = destructionService;
|
||||
_eventCoordinator = eventCoordinator;
|
||||
_saveManager = saveManager;
|
||||
_puzzleService = puzzleService;
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
if (Initialized)
|
||||
return;
|
||||
|
||||
Debug.Log($"[{nameof(LevelManager)}] Initializing...");
|
||||
_saveManager.OnSaveRequested += OnSaveGameRequested;
|
||||
_eventCoordinator.Subscribe<UpdateHintProgressEvent>(OnHintStageUpdated);
|
||||
Debug.Log($"[{nameof(LevelManager)}] Initialized.");
|
||||
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (!Initialized)
|
||||
return;
|
||||
|
||||
_saveManager.OnSaveRequested -= OnSaveGameRequested;
|
||||
_eventCoordinator.Unsubscribe<UpdateHintProgressEvent>(OnHintStageUpdated);
|
||||
|
||||
Initialized = false;
|
||||
}
|
||||
|
||||
private void OnHintStageUpdated(UpdateHintProgressEvent evt)
|
||||
{
|
||||
if (_currentLevel == null || evt == null)
|
||||
return;
|
||||
|
||||
if (!string.Equals(evt.LevelID, _currentLevel.LevelID, StringComparison.Ordinal))
|
||||
return;
|
||||
|
||||
var incoming = Mathf.Max(0, evt.Stage);
|
||||
|
||||
if (evt.Force)
|
||||
{
|
||||
_currentLevel.CurrentLevelHintStage = incoming;
|
||||
return;
|
||||
}
|
||||
|
||||
var current = Mathf.Max(0, _currentLevel.CurrentLevelHintStage);
|
||||
_currentLevel.CurrentLevelHintStage = Mathf.Max(current, incoming);
|
||||
}
|
||||
|
||||
private void OnSaveGameRequested(SaveGame saveGame)
|
||||
{
|
||||
if (saveGame == null || _currentLevel == null)
|
||||
return;
|
||||
|
||||
saveGame.CurrentLevelID = _currentLevel.LevelID;
|
||||
saveGame.CurrentSceneID = _currentLevel.SceneID;
|
||||
|
||||
saveGame.LevelHintStages ??= new Dictionary<string, int>();
|
||||
saveGame.LevelHintStages[_currentLevel.LevelID] = Mathf.Max(0, _currentLevel.CurrentLevelHintStage);
|
||||
}
|
||||
|
||||
public UniTask<bool> LoadLevel(string levelAssetID)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(levelAssetID))
|
||||
{
|
||||
Debug.LogError("[LevelManager] LoadLevel called with null/empty levelAssetID.");
|
||||
return UniTask.FromResult(false);
|
||||
}
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
_activeLoadTask = LoadLevelInternal(levelAssetID);
|
||||
return _activeLoadTask;
|
||||
}
|
||||
}
|
||||
|
||||
private async UniTask<bool> LoadLevelInternal(string levelAssetID)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_assetRegistry == null)
|
||||
{
|
||||
Debug.LogError("[LevelManager] AssetRegistry is null.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_assetRegistry.TryGetReference(levelAssetID, out var levelRef) || levelRef == null)
|
||||
{
|
||||
Debug.LogError($"[LevelManager] No level reference found for id '{levelAssetID}'.");
|
||||
return false;
|
||||
}
|
||||
|
||||
_eventCoordinator.PublishImmediate(new FadeEvent(false, LEVEL_FADE_DURATION));
|
||||
await UniTask.Delay(TimeSpan.FromSeconds(LEVEL_FADE_DURATION));
|
||||
|
||||
if (_currentLevel != null)
|
||||
await UnloadLevelInternal();
|
||||
|
||||
var levelObj = await _addressableManager.InstantiateAsync(levelRef);
|
||||
if (levelObj == null)
|
||||
{
|
||||
Debug.LogError($"[LevelManager] Failed to instantiate level '{levelAssetID}'.");
|
||||
return false;
|
||||
}
|
||||
|
||||
var level = levelObj.GetComponent<BaseLevel>();
|
||||
if (level == null)
|
||||
{
|
||||
Debug.LogError($"[LevelManager] Instantiated level '{levelAssetID}' has no BaseLevel component. Destroying instance.");
|
||||
await _destructionService.Destroy(levelObj);
|
||||
return false;
|
||||
}
|
||||
|
||||
_currentLevel = level;
|
||||
|
||||
RestoreHintStageForCurrentLevel();
|
||||
await RestoreItemStateForCurrentLevel();
|
||||
|
||||
await _currentLevel.PostLoad();
|
||||
|
||||
if (_currentLevel is BasePuzzle puzzle)
|
||||
await _puzzleService.LoadPuzzle(puzzle);
|
||||
|
||||
_eventCoordinator.Publish(new LevelChangedEvent(_currentLevel));
|
||||
|
||||
_eventCoordinator.PublishImmediate(new FadeEvent(true, LEVEL_FADE_DURATION));
|
||||
await UniTask.Delay(TimeSpan.FromSeconds(LEVEL_FADE_DURATION));
|
||||
|
||||
if (_currentLevel != null)
|
||||
await _currentLevel.PostActivate();
|
||||
|
||||
_eventCoordinator.Publish(new RequestGameSaveEvent());
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError($"[LevelManager] Exception while loading '{levelAssetID}': {ex}");
|
||||
|
||||
if (_currentLevel != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _destructionService.Destroy(_currentLevel.gameObject);
|
||||
}
|
||||
catch (Exception destroyEx)
|
||||
{
|
||||
Debug.LogWarning($"[LevelManager] Failed to destroy broken level instance: {destroyEx}");
|
||||
}
|
||||
|
||||
_currentLevel = null;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void RestoreHintStageForCurrentLevel()
|
||||
{
|
||||
if (_currentLevel == null)
|
||||
return;
|
||||
|
||||
var save = _saveManager.CurrentSave;
|
||||
if (save?.LevelHintStages == null)
|
||||
{
|
||||
_currentLevel.CurrentLevelHintStage = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (save.LevelHintStages.TryGetValue(_currentLevel.LevelID, out var stage))
|
||||
_currentLevel.CurrentLevelHintStage = Mathf.Max(0, stage);
|
||||
else
|
||||
_currentLevel.CurrentLevelHintStage = 0;
|
||||
}
|
||||
|
||||
private async UniTask RestoreItemStateForCurrentLevel()
|
||||
{
|
||||
if (_currentLevel == null)
|
||||
return;
|
||||
|
||||
var save = _saveManager.CurrentSave;
|
||||
if (save == null)
|
||||
return;
|
||||
|
||||
var interactables = _currentLevel.Pickups;
|
||||
if (interactables == null || interactables.Count == 0)
|
||||
return;
|
||||
|
||||
foreach (var interactable in interactables)
|
||||
{
|
||||
if (interactable.ItemData == null)
|
||||
{
|
||||
Debug.Log($"[LevelManager] No Item Data for {interactable.InteractableName}");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (save.CollectedItems.Any(x => x.UniqueIdentifier == interactable.ItemData.UniqueID))
|
||||
await _destructionService.Destroy(interactable.gameObject);
|
||||
|
||||
if (save.RemovedItems.Any(x => x.UniqueIdentifier == interactable.ItemData.UniqueID))
|
||||
await _destructionService.Destroy(interactable.gameObject);
|
||||
}
|
||||
|
||||
var codexTriggers = _currentLevel.CodexTriggers;
|
||||
|
||||
foreach (var trigger in codexTriggers)
|
||||
{
|
||||
if (save.DiscoveredCodexEntries.Any(x => x.UniqueIdentifier == trigger.Entry.UniqueID))
|
||||
{
|
||||
if (trigger.RemoveTrigger)
|
||||
await _destructionService.Destroy(trigger.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public UniTask UnloadLevel()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (_activeLoadTask.Status == UniTaskStatus.Pending)
|
||||
return _activeLoadTask.ContinueWith(_ => UnloadLevelInternal());
|
||||
|
||||
return UnloadLevelInternal();
|
||||
}
|
||||
}
|
||||
|
||||
private async UniTask UnloadLevelInternal()
|
||||
{
|
||||
if (_currentLevel == null)
|
||||
return;
|
||||
|
||||
var level = _currentLevel;
|
||||
_currentLevel = null;
|
||||
|
||||
try
|
||||
{
|
||||
if (level is BasePuzzle puzzle)
|
||||
await _puzzleService.SavePuzzle(puzzle);
|
||||
|
||||
_eventCoordinator.Publish(new RequestGameSaveEvent());
|
||||
await level.PreUnload();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogWarning($"[LevelManager] Exception in PreUnload of {level.name}: {ex}");
|
||||
}
|
||||
|
||||
await _destructionService.Destroy(level.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 21e9be484b29431886214bcd47848292
|
||||
timeCreated: 1769778109
|
||||
Reference in New Issue
Block a user