143 lines
3.6 KiB
C#
143 lines
3.6 KiB
C#
using Godot;
|
|
using Godot.Collections;
|
|
using Mr.BrickAdventures.scripts.components;
|
|
|
|
namespace Mr.BrickAdventures.Autoloads;
|
|
|
|
/// <summary>
|
|
/// Game orchestrator - handles scene transitions and game flow.
|
|
/// State lives in GameStateStore; query it directly for reads/writes.
|
|
/// </summary>
|
|
public partial class GameManager : Node
|
|
{
|
|
[Export] public Array<PackedScene> LevelScenes { get; set; } = [];
|
|
|
|
public PlayerController Player
|
|
{
|
|
get => GetPlayer();
|
|
private set => _player = value;
|
|
}
|
|
|
|
private PlayerController _player;
|
|
private SpeedRunManager SpeedRunManager => SpeedRunManager.Instance;
|
|
private GameStateStore Store => GameStateStore.Instance;
|
|
|
|
public static GameManager Instance { get; private set; }
|
|
|
|
public override void _Ready()
|
|
{
|
|
Instance = this;
|
|
EventBus.Instance.PlayerSpawned += OnPlayerSpawned;
|
|
}
|
|
|
|
public override void _ExitTree()
|
|
{
|
|
if (Instance == this) Instance = null;
|
|
if (EventBus.Instance != null)
|
|
EventBus.Instance.PlayerSpawned -= OnPlayerSpawned;
|
|
}
|
|
|
|
private void OnPlayerSpawned(PlayerController player)
|
|
{
|
|
_player = player;
|
|
player.TreeExiting += () => { if (_player == player) _player = null; };
|
|
}
|
|
|
|
#region Game Flow
|
|
|
|
public void StartNewGame()
|
|
{
|
|
Store?.ResetAll();
|
|
SpeedRunManager?.StartTimer();
|
|
GetTree().ChangeSceneToPacked(LevelScenes[0]);
|
|
SaveSystem.Instance.SaveGame();
|
|
EventBus.EmitGameStarted();
|
|
}
|
|
|
|
public void ContinueGame()
|
|
{
|
|
var save = SaveSystem.Instance;
|
|
if (!save.LoadGame())
|
|
{
|
|
GD.PrintErr("Failed to load game. Starting a new game instead.");
|
|
StartNewGame();
|
|
return;
|
|
}
|
|
|
|
var idx = Store?.Player.CurrentLevel ?? 0;
|
|
if (idx < LevelScenes.Count)
|
|
{
|
|
GetTree().ChangeSceneToPacked(LevelScenes[idx]);
|
|
EventBus.EmitGameContinued();
|
|
}
|
|
else
|
|
{
|
|
GD.PrintErr("No levels unlocked to continue.");
|
|
}
|
|
}
|
|
|
|
public void RestartGame()
|
|
{
|
|
Store?.ResetAll();
|
|
GetTree().ChangeSceneToPacked(LevelScenes[0]);
|
|
SaveSystem.Instance.SaveGame();
|
|
}
|
|
|
|
public void OnLevelComplete()
|
|
{
|
|
if (Store == null) return;
|
|
|
|
var levelIndex = Store.Player.CurrentLevel;
|
|
Store.MarkLevelComplete(levelIndex);
|
|
Store.CommitSessionCoins();
|
|
Store.CommitSessionSkills();
|
|
|
|
var completionTime = SpeedRunManager?.GetCurrentLevelTime() ?? 0.0;
|
|
EventBus.EmitLevelCompleted(levelIndex, GetTree().CurrentScene, completionTime);
|
|
|
|
Store.ResetSession();
|
|
TryToGoToNextLevel();
|
|
SaveSystem.Instance.SaveGame();
|
|
}
|
|
|
|
public void TryToGoToNextLevel()
|
|
{
|
|
if (Store == null) return;
|
|
|
|
var next = Store.Player.CurrentLevel + 1;
|
|
if (next < LevelScenes.Count && Store.IsLevelUnlocked(next))
|
|
{
|
|
Store.Player.CurrentLevel = next;
|
|
GetTree().ChangeSceneToPacked(LevelScenes[next]);
|
|
EventBus.EmitLevelStarted(next, GetTree().CurrentScene);
|
|
}
|
|
}
|
|
|
|
public void PauseGame()
|
|
{
|
|
Engine.TimeScale = 0;
|
|
EventBus.EmitGamePaused();
|
|
}
|
|
|
|
public void ResumeGame()
|
|
{
|
|
Engine.TimeScale = 1;
|
|
EventBus.EmitGameResumed();
|
|
}
|
|
|
|
public void QuitGame() => GetTree().Quit();
|
|
|
|
#endregion
|
|
|
|
#region Player Lookup
|
|
|
|
public PlayerController GetPlayer()
|
|
{
|
|
if (_player != null && IsInstanceValid(_player)) return _player;
|
|
_player = null;
|
|
return null;
|
|
}
|
|
|
|
#endregion
|
|
}
|