using System; using System.Collections.Generic; using Godot; using Limbo.Console.Sharp; using ParasiticGod.Scripts.Core; using ParasiticGod.Scripts.Core.Effects; namespace ParasiticGod.Scripts.Singletons; public partial class GameBus : Node { public static GameBus Instance { get; private set; } public Dictionary AllMiracles { get; private set; } public List FollowerTiers { get; private set; } public List HutTiers { get; private set; } private PackedScene _gameOverScene = GD.Load("res://Scenes/game_over.tscn"); private PackedScene _winScene = GD.Load("res://Scenes/win_screen.tscn"); private readonly GameState _gameState = new(); private readonly GameLogic _gameLogic = new(); public event Action StateChanged; public event Action MiraclePerformed; public event Action> MiraclesUnlocked; public event Action MiracleCompleted; public event Action BuffAdded; public event Action BuffRemoved; public event Action PopulationVisualsUpdated; public event Action AgeAdvanced; public event Action GameWon; public override void _EnterTree() { Instance = this; AllMiracles = MiracleLoader.LoadAllMiracles(); FollowerTiers = TierLoader.LoadTiers("res://Mods/Tiers/follower_tiers.json", "user://Mods/Tiers/follower_tiers.json"); HutTiers = TierLoader.LoadTiers("res://Mods/Tiers/hut_tiers.json","user://Mods/Tiers/hut_tiers.json"); GameWon += OnGameWon; } public override void _ExitTree() { Instance = null; GameWon -= OnGameWon; } public override void _Ready() { RegisterConsoleCommands(); } public override void _Process(double delta) { _gameLogic.UpdateGameState(_gameState, delta); StateChanged?.Invoke(_gameState); if (_gameState.Get(Stat.Corruption) >= 100) { GetTree().ChangeSceneToPacked(_gameOverScene); _gameState.Set(Stat.Corruption, 0); } } public void PerformMiracle(MiracleDefinition miracle) { if (_gameLogic.TryToPerformMiracle(_gameState, miracle)) { MiraclePerformed?.Invoke(miracle); var miraclesToUnlock = new List(); foreach (var effect in miracle.Effects) { if (effect is UnlockMiracleEffect unlockEffect) { foreach (var id in unlockEffect.MiraclesToUnlock) { if (AllMiracles.TryGetValue(id, out var def) && !_gameState.IsMiracleUnlocked(id)) { miraclesToUnlock.Add(def); _gameState.AddUnlockedMiracle(def.Id); } } } else if (effect is DestroySelfEffect) { MiracleCompleted?.Invoke(miracle); _gameState.RemoveUnlockedMiracle(miracle.Id); } } if (miraclesToUnlock.Count > 0) { MiraclesUnlocked?.Invoke(miraclesToUnlock); } if (!string.IsNullOrEmpty(miracle.AdvancesToAge)) { AgeAdvanced?.Invoke(miracle.AdvancesToAge); } } } public void NotifyPopulationVisualsUpdated() { PopulationVisualsUpdated?.Invoke(); } public void NotifyBuffAdded(Buff buff) { BuffAdded?.Invoke(buff); } public void NotifyBuffRemoved(Buff buff) { BuffRemoved?.Invoke(buff); } public void NotifyGameIsWon() { GameWon?.Invoke(); } public void SubscribeToStat(Stat stat, Action listener) => _gameState.Subscribe(stat, listener); public void UnsubscribeFromStat(Stat stat, Action listener) => _gameState.Unsubscribe(stat, listener); public GameState CurrentState => _gameState; [ConsoleCommand("set_stat", "Sets the value of a specified stat.")] private void SetStatCommand(Stat stat, double value) => _gameState.Set(stat, value); [ConsoleCommand("game_over")] private void GameOverCommand() => GetTree().ChangeSceneToPacked(_gameOverScene); [ConsoleCommand("win_game")] private void WinGameCommand() => GetTree().ChangeSceneToPacked(_winScene); private void OnGameWon() { GetTree().ChangeSceneToPacked(_winScene); } }