From 8ae0e7e80c5f65ec4560e085b6071a7f30744328 Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Sat, 23 Aug 2025 18:28:05 +0200 Subject: [PATCH] Add buff management for miracles; implement checks for active buffs and update buff identifiers --- Mods/Miracles/gods_endurance.json | 1 + Mods/Miracles/harness_the_sun.json | 1 + Scenes/Main/MiracleButton.cs | 17 +++++++++++++++++ Scripts/Components/ActiveBuffsManager.cs | 6 +++--- Scripts/Core/Effects/ApplyBuffEffect.cs | 8 ++++++++ Scripts/Core/Effects/Buff.cs | 3 ++- Scripts/Core/GameLogic.cs | 2 ++ Scripts/Core/GameState.cs | 5 +++++ Scripts/Core/MiracleDto.cs | 1 + Scripts/Core/MiracleLoader.cs | 1 + Scripts/Core/Stat.cs | 1 + 11 files changed, 42 insertions(+), 4 deletions(-) diff --git a/Mods/Miracles/gods_endurance.json b/Mods/Miracles/gods_endurance.json index 92deae5..247432e 100644 --- a/Mods/Miracles/gods_endurance.json +++ b/Mods/Miracles/gods_endurance.json @@ -7,6 +7,7 @@ "effects": [ { "type": "ApplyBuff", + "buffId": "gods_endurance", "targetStat": "FaithPerFollower", "multiplier": 2.0, "duration": 60 diff --git a/Mods/Miracles/harness_the_sun.json b/Mods/Miracles/harness_the_sun.json index a2ce405..c1956d1 100644 --- a/Mods/Miracles/harness_the_sun.json +++ b/Mods/Miracles/harness_the_sun.json @@ -7,6 +7,7 @@ "effects": [ { "type": "ApplyBuff", + "buffId": "harness_the_sun", "targetStat": "CorruptionPerSecond", "multiplier": -1.5, "duration": 120 diff --git a/Scenes/Main/MiracleButton.cs b/Scenes/Main/MiracleButton.cs index 821d35d..0502b41 100644 --- a/Scenes/Main/MiracleButton.cs +++ b/Scenes/Main/MiracleButton.cs @@ -85,6 +85,11 @@ public partial class MiracleButton : Button { missingRequirements.Add("Already unlocked subsequent powers."); } + + if (IsBuffAlreadyActive(state)) + { + missingRequirements.Add("This buff is already active."); + } if (missingRequirements.Any()) { @@ -145,4 +150,16 @@ public partial class MiracleButton : Button return unlockEffect.MiraclesToUnlock.All(state.IsMiracleUnlocked); } + + private bool IsBuffAlreadyActive(GameState state) + { + var buffEffect = _miracle.Effects.OfType().FirstOrDefault(); + + if (buffEffect == null || string.IsNullOrEmpty(buffEffect.BuffId)) + { + return false; + } + + return state.IsBuffActive(buffEffect.BuffId); + } } \ No newline at end of file diff --git a/Scripts/Components/ActiveBuffsManager.cs b/Scripts/Components/ActiveBuffsManager.cs index fb0e688..1e002bb 100644 --- a/Scripts/Components/ActiveBuffsManager.cs +++ b/Scripts/Components/ActiveBuffsManager.cs @@ -34,16 +34,16 @@ public partial class ActiveBuffsManager : Node var buffInstance = _activeBuffScene.Instantiate(); AddChild(buffInstance); buffInstance.SetBuff(buff); - _activeBuffUis.Add(buff.Id, buffInstance); + _activeBuffUis.Add(buff.InstanceId, buffInstance); _buffAddedSfx?.Play(); } private void OnBuffRemoved(Buff buff) { - if (_activeBuffUis.TryGetValue(buff.Id, out var buffUi)) + if (_activeBuffUis.TryGetValue(buff.InstanceId, out var buffUi)) { buffUi.QueueFree(); - _activeBuffUis.Remove(buff.Id); + _activeBuffUis.Remove(buff.InstanceId); _buffRemovedSfx?.Play(); } } diff --git a/Scripts/Core/Effects/ApplyBuffEffect.cs b/Scripts/Core/Effects/ApplyBuffEffect.cs index 1763530..8d40908 100644 --- a/Scripts/Core/Effects/ApplyBuffEffect.cs +++ b/Scripts/Core/Effects/ApplyBuffEffect.cs @@ -6,12 +6,19 @@ namespace ParasiticGod.Scripts.Core.Effects; [GlobalClass] public partial class ApplyBuffEffect : Effect { + [Export] public string BuffId { get; set; } [Export] public Stat TargetStat { get; set; } [Export] public float Multiplier { get; set; } = 2.0f; [Export] public double Duration { get; set; } = 30.0; public override void Execute(GameState gameState) { + if (gameState.IsBuffActive(BuffId)) + { + GD.Print($"Buff '{BuffId}' is already active. Cannot apply again."); + return; + } + var newBuff = new Buff { Name = $"{TargetStat} x{Multiplier}", @@ -20,6 +27,7 @@ public partial class ApplyBuffEffect : Effect }; gameState.ActiveBuffs.Add(newBuff); + gameState.AddActiveBuff(BuffId); GameBus.Instance.NotifyBuffAdded(newBuff); } diff --git a/Scripts/Core/Effects/Buff.cs b/Scripts/Core/Effects/Buff.cs index 2722225..0bafe85 100644 --- a/Scripts/Core/Effects/Buff.cs +++ b/Scripts/Core/Effects/Buff.cs @@ -4,7 +4,8 @@ namespace ParasiticGod.Scripts.Core.Effects; public class Buff { - public Guid Id { get; } = Guid.NewGuid(); // Unique identifier + public Guid InstanceId { get; } = Guid.NewGuid(); // Unique identifier + public string BuffId { get; set; } // Identifier for the type of buff public string Name { get; set; } // For display purposes public float Multiplier { get; set; } = 1.0f; public double Duration { get; set; } diff --git a/Scripts/Core/GameLogic.cs b/Scripts/Core/GameLogic.cs index c468676..0922a64 100644 --- a/Scripts/Core/GameLogic.cs +++ b/Scripts/Core/GameLogic.cs @@ -17,6 +17,7 @@ public class GameLogic state.Modify(Stat.Faith, faithPerSecond * delta); state.Modify(Stat.Production, state.Get(Stat.ProductionPerSecond) * delta); state.Modify(Stat.Corruption, state.Get(Stat.CorruptionPerSecond) * delta); + state.Modify(Stat.Followers, state.Get(Stat.FollowersPerSecond) * delta); for (var i = state.ActiveBuffs.Count - 1; i >= 0; i--) { @@ -26,6 +27,7 @@ public class GameLogic { GameBus.Instance.NotifyBuffRemoved(buff); state.ActiveBuffs.RemoveAt(i); + state.RemoveActiveBuff(buff.BuffId); } } } diff --git a/Scripts/Core/GameState.cs b/Scripts/Core/GameState.cs index 45c1697..019cb03 100644 --- a/Scripts/Core/GameState.cs +++ b/Scripts/Core/GameState.cs @@ -8,6 +8,7 @@ public class GameState { private readonly Dictionary _stats = new(); private readonly HashSet _unlockedMiracleIds = []; + private readonly HashSet _activeBuffIds = []; public List ActiveBuffs { get; } = []; @@ -38,4 +39,8 @@ public class GameState public bool IsMiracleUnlocked(string miracleId) => _unlockedMiracleIds.Contains(miracleId); public void AddUnlockedMiracle(string miracleId) => _unlockedMiracleIds.Add(miracleId); public void RemoveUnlockedMiracle(string miracleId) => _unlockedMiracleIds.Remove(miracleId); + + public bool IsBuffActive(string buffId) => _activeBuffIds.Contains(buffId); + public void AddActiveBuff(string buffId) => _activeBuffIds.Add(buffId); + public void RemoveActiveBuff(string buffId) => _activeBuffIds.Remove(buffId); } \ No newline at end of file diff --git a/Scripts/Core/MiracleDto.cs b/Scripts/Core/MiracleDto.cs index 698c0a9..0af1ce5 100644 --- a/Scripts/Core/MiracleDto.cs +++ b/Scripts/Core/MiracleDto.cs @@ -12,6 +12,7 @@ public class EffectDto public double Value { get; set; } // --- For "ApplyBuff" Effect --- + public string BuffId { get; set; } public float Multiplier { get; set; } public double Duration { get; set; } diff --git a/Scripts/Core/MiracleLoader.cs b/Scripts/Core/MiracleLoader.cs index dbc974a..6667e29 100644 --- a/Scripts/Core/MiracleLoader.cs +++ b/Scripts/Core/MiracleLoader.cs @@ -101,6 +101,7 @@ public static class MiracleLoader applyBuffEffect.TargetStat = effectDto.TargetStat; applyBuffEffect.Multiplier = effectDto.Multiplier; applyBuffEffect.Duration = effectDto.Duration; + applyBuffEffect.BuffId = effectDto.BuffId; break; case ConvertResourceEffect convertResourceEffect: convertResourceEffect.FromResource = effectDto.FromResource; diff --git a/Scripts/Core/Stat.cs b/Scripts/Core/Stat.cs index e8aebb3..0452861 100644 --- a/Scripts/Core/Stat.cs +++ b/Scripts/Core/Stat.cs @@ -11,6 +11,7 @@ public enum Stat // Passive Generation Stats ProductionPerSecond, CorruptionPerSecond, + FollowersPerSecond, // Modifying Stats FaithPerFollower