diff --git a/Autoloads/AchievementManager.cs b/Autoloads/AchievementManager.cs index bf400cd..2b13f76 100644 --- a/Autoloads/AchievementManager.cs +++ b/Autoloads/AchievementManager.cs @@ -9,6 +9,8 @@ namespace Mr.BrickAdventures.Autoloads; /// public partial class AchievementManager : Node { + public static AchievementManager Instance { get; private set; } + [Export] private string AchievementsFolderPath = "res://achievements/"; [Export] private PackedScene AchievementPopupScene { get; set; } @@ -16,9 +18,15 @@ public partial class AchievementManager : Node public override void _Ready() { + Instance = this; LoadAchievementsFromFolder(); } + public override void _ExitTree() + { + if (Instance == this) Instance = null; + } + private void LoadAchievementsFromFolder() { using var dir = DirAccess.Open(AchievementsFolderPath); diff --git a/Autoloads/ConsoleManager.cs b/Autoloads/ConsoleManager.cs index af11c8e..06b9298 100644 --- a/Autoloads/ConsoleManager.cs +++ b/Autoloads/ConsoleManager.cs @@ -6,41 +6,39 @@ namespace Mr.BrickAdventures.Autoloads; public partial class ConsoleManager : Node { - private GameManager _gameManager; + private GameManager GameManager => GameManager.Instance; + private AchievementManager AchievementManager => AchievementManager.Instance; private SkillManager _skillManager; private SkillUnlockerComponent _skillUnlockerComponent; - private AchievementManager _achievementManager; public override void _Ready() { - _gameManager = GameManager.Instance; - _achievementManager = GetNode(Constants.AchievementManagerPath); _skillManager = SkillManager.Instance; } private void AddCoinsCommand(int amount) { - _gameManager.AddCoins(amount); + GameManager.AddCoins(amount); } private void SetCoinsCommand(int amount) { - _gameManager.SetCoins(amount); + GameManager.SetCoins(amount); } private void SetLivesCommand(int amount) { - _gameManager.SetLives(amount); + GameManager.SetLives(amount); } private void AddLivesCommand(int amount) { - _gameManager.AddLives(amount); + GameManager.AddLives(amount); } private void SetHealthCommand(float amount) { - var playerHealthComponent = _gameManager.Player.GetNode("HealthComponent"); + var playerHealthComponent = GameManager.Player.GetNode("HealthComponent"); if (playerHealthComponent != null) { playerHealthComponent.Health = amount; @@ -49,7 +47,7 @@ public partial class ConsoleManager : Node private void ResetSessionCommand() { - _gameManager.ResetCurrentSessionState(); + GameManager.ResetCurrentSessionState(); } private void UnlockSkillCommand(string skillName) @@ -62,14 +60,14 @@ public partial class ConsoleManager : Node return; } - _gameManager.UnlockSkill(skill); + GameManager.UnlockSkill(skill); _skillManager.ActivateSkill(skill); _skillUnlockerComponent.EmitSignal(SkillUnlockerComponent.SignalName.SkillUnlocked, skill); } private bool GetSkillManagement() { - var player = _gameManager.Player; + var player = GameManager.Player; if (player == null || !IsInstanceValid(player)) { return false; @@ -100,7 +98,7 @@ public partial class ConsoleManager : Node return; } - _gameManager.RemoveSkill(skill.Name); + GameManager.RemoveSkill(skill.Name); _skillManager.DeactivateSkill(skill); } @@ -110,24 +108,24 @@ public partial class ConsoleManager : Node foreach (var skill in _skillManager.AvailableSkills) { - _gameManager.RemoveSkill(skill.Name); + GameManager.RemoveSkill(skill.Name); _skillManager.DeactivateSkill(skill); } } private void GoToNextLevelCommand() { - _gameManager.OnLevelComplete(); + GameManager.OnLevelComplete(); } private void UnlockAchievementCommand(string achievementId) { - _achievementManager.UnlockAchievement(achievementId); + AchievementManager.UnlockAchievement(achievementId); } private void ResetAchievementCommand(string achievementId) { - _achievementManager.LockAchievement(achievementId); + AchievementManager.LockAchievement(achievementId); } } \ No newline at end of file diff --git a/Autoloads/GameManager.cs b/Autoloads/GameManager.cs index 6ea7457..80583c8 100644 --- a/Autoloads/GameManager.cs +++ b/Autoloads/GameManager.cs @@ -52,6 +52,12 @@ public partial class GameManager : Node #region Coin Operations + /// + /// Adds coins permanently to the player's saved total (Store.Player.Coins). + /// Use this for out-of-gameplay grants (e.g. console commands, rewards). + /// During active gameplay, coins collected in a level go through + /// and are only committed on level completion. + /// public void AddCoins(int amount) { if (Store != null) diff --git a/Autoloads/GhostManager.cs b/Autoloads/GhostManager.cs index 931227a..1ca2478 100644 --- a/Autoloads/GhostManager.cs +++ b/Autoloads/GhostManager.cs @@ -7,8 +7,13 @@ namespace Mr.BrickAdventures.Autoloads; public partial class GhostManager : Node { + public static GhostManager Instance { get; private set; } + [Export] private PackedScene GhostPlayerScene { get; set; } - + + public override void _Ready() => Instance = this; + public override void _ExitTree() { if (Instance == this) Instance = null; } + public bool IsRecording { get; private set; } = false; public bool IsPlaybackEnabled { get; private set; } = true; diff --git a/Autoloads/SaveSystem.cs b/Autoloads/SaveSystem.cs index f0d36a4..e825515 100644 --- a/Autoloads/SaveSystem.cs +++ b/Autoloads/SaveSystem.cs @@ -174,19 +174,3 @@ public partial class SaveSystem : Node } } } - -/// -/// Serializable DTO for save data - no Godot types. -/// -public class SaveDataDto -{ - public int Version { get; set; } - public int Coins { get; set; } - public int Lives { get; set; } - public int CurrentLevel { get; set; } - public List CompletedLevels { get; set; } - public List UnlockedLevels { get; set; } - public List UnlockedSkillNames { get; set; } - public List UnlockedAchievements { get; set; } - public Dictionary Statistics { get; set; } -} \ No newline at end of file diff --git a/Autoloads/SpeedRunManager.cs b/Autoloads/SpeedRunManager.cs index edfdfda..7f1c876 100644 --- a/Autoloads/SpeedRunManager.cs +++ b/Autoloads/SpeedRunManager.cs @@ -11,8 +11,7 @@ public partial class SpeedRunManager : Node public override void _ExitTree() { if (Instance == this) Instance = null; } public bool IsRunning { get; private set; } = false; - public bool IsVisible { get; private set; } = false; - + private double _startTime; private double _levelStartTime; private List _splits = []; @@ -21,7 +20,7 @@ public partial class SpeedRunManager : Node public override void _Process(double delta) { - if (!IsRunning || !IsVisible) return; + if (!IsRunning) return; EmitSignalTimeUpdated(GetCurrentTotalTime(), GetCurrentLevelTime()); } diff --git a/scripts/Events/GhostEventHandler.cs b/scripts/Events/GhostEventHandler.cs index 3fe6e5e..f068b77 100644 --- a/scripts/Events/GhostEventHandler.cs +++ b/scripts/Events/GhostEventHandler.cs @@ -7,25 +7,27 @@ namespace Mr.BrickAdventures.scripts.Events; [GlobalClass] public partial class GhostEventHandler : Node { - private GhostManager _ghostManager; - public override void _Ready() { - _ghostManager = GetNode(Constants.GhostManagerPath); - EventBus.Instance.LevelStarted += OnLevelStarted; EventBus.Instance.LevelCompleted += OnLevelCompleted; } + public override void _ExitTree() + { + EventBus.Instance.LevelStarted -= OnLevelStarted; + EventBus.Instance.LevelCompleted -= OnLevelCompleted; + } + private void OnLevelStarted(int levelIndex, Node currentScene) { GD.Print($"GhostEventHandler: Level {levelIndex} started."); - _ghostManager.StartRecording(levelIndex); - _ghostManager.SpawnGhostPlayer(levelIndex, currentScene); + GhostManager.Instance.StartRecording(levelIndex); + GhostManager.Instance.SpawnGhostPlayer(levelIndex, currentScene); } private void OnLevelCompleted(int levelIndex, Node currentScene, double completionTime) { - _ghostManager.StopRecording(true, completionTime); + GhostManager.Instance.StopRecording(true, completionTime); } } \ No newline at end of file diff --git a/scripts/State/SaveDataDto.cs b/scripts/State/SaveDataDto.cs new file mode 100644 index 0000000..71229f8 --- /dev/null +++ b/scripts/State/SaveDataDto.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; + +namespace Mr.BrickAdventures.scripts.State; + +/// +/// Serializable DTO for save data - no Godot types. +/// +public class SaveDataDto +{ + public int Version { get; set; } + public int Coins { get; set; } + public int Lives { get; set; } + public int CurrentLevel { get; set; } + public List CompletedLevels { get; set; } + public List UnlockedLevels { get; set; } + public List UnlockedSkillNames { get; set; } + public List UnlockedAchievements { get; set; } + public Dictionary Statistics { get; set; } +} diff --git a/scripts/State/SaveDataDto.cs.uid b/scripts/State/SaveDataDto.cs.uid new file mode 100644 index 0000000..6656acc --- /dev/null +++ b/scripts/State/SaveDataDto.cs.uid @@ -0,0 +1 @@ +uid://lmtb7ckjp5mr diff --git a/scripts/UI/SpeedRunHud.cs b/scripts/UI/SpeedRunHud.cs index 033bd82..fcb3ea2 100644 --- a/scripts/UI/SpeedRunHud.cs +++ b/scripts/UI/SpeedRunHud.cs @@ -9,15 +9,9 @@ public partial class SpeedRunHud : Control { [Export] private Label _timerLabel; - private SpeedRunManager _speedRunManager; - public override void _Ready() { - _speedRunManager = GetNode(Constants.SpeedRunManagerPath); - - _speedRunManager.TimeUpdated += OnTimerUpdated; - - Visible = _speedRunManager.IsVisible; + SpeedRunManager.Instance.TimeUpdated += OnTimerUpdated; } private void OnTimerUpdated(double totalTime, double levelTime)