Add Active Buffs management and UI integration

This commit is contained in:
2025-08-23 04:20:42 +02:00
parent 32c75c6fe8
commit 5719c3f920
16 changed files with 217 additions and 51 deletions

View File

@@ -1,9 +1,11 @@
[gd_scene load_steps=21 format=3 uid="uid://bfil8sd154327"]
[gd_scene load_steps=23 format=3 uid="uid://bfil8sd154327"]
[ext_resource type="Script" uid="uid://t71ewkpa5uqs" path="res://Scenes/Main/Main.cs" id="1_p8rbg"]
[ext_resource type="Script" uid="uid://b77vh831r1e3c" path="res://Scenes/Main/MiraclePanel.cs" id="2_hcu3t"]
[ext_resource type="PackedScene" uid="uid://rj1fsdlhju5y" path="res://Scenes/Main/miracle_button.tscn" id="3_qdkat"]
[ext_resource type="Texture2D" uid="uid://dg6ac3jb1366r" path="res://Sprites/globe.svg" id="4_i3fi7"]
[ext_resource type="Script" uid="uid://ddshg236tlltt" path="res://Scripts/ActiveBuffsManager.cs" id="4_xggvw"]
[ext_resource type="PackedScene" uid="uid://b417dl07c13uc" path="res://Scenes/Main/buff_button.tscn" id="5_xd21n"]
[ext_resource type="PackedScene" uid="uid://be5d0d3aweg0l" path="res://Scenes/Huts/HutMarker.tscn" id="6_cv8e0"]
[ext_resource type="Script" uid="uid://dj2wyrq07gfp2" path="res://Scripts/PopulationVisualizer.cs" id="8_cv8e0"]
[ext_resource type="PackedScene" uid="uid://8w7tvsgkev1y" path="res://Scenes/tree.tscn" id="8_hcu3t"]
@@ -112,56 +114,8 @@ vertical_scroll_mode = 0
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="Button" type="Button" parent="UiLayer/Control/Main/ScrollContainer2/HBoxContainer"]
layout_mode = 2
disabled = true
text = "Effect"
[node name="Button2" type="Button" parent="UiLayer/Control/Main/ScrollContainer2/HBoxContainer"]
layout_mode = 2
disabled = true
text = "Effect"
[node name="Button3" type="Button" parent="UiLayer/Control/Main/ScrollContainer2/HBoxContainer"]
layout_mode = 2
disabled = true
text = "Effect"
[node name="Button4" type="Button" parent="UiLayer/Control/Main/ScrollContainer2/HBoxContainer"]
layout_mode = 2
disabled = true
text = "Effect"
[node name="Button5" type="Button" parent="UiLayer/Control/Main/ScrollContainer2/HBoxContainer"]
layout_mode = 2
disabled = true
text = "Effect"
[node name="Button6" type="Button" parent="UiLayer/Control/Main/ScrollContainer2/HBoxContainer"]
layout_mode = 2
disabled = true
text = "Effect"
[node name="Button7" type="Button" parent="UiLayer/Control/Main/ScrollContainer2/HBoxContainer"]
layout_mode = 2
disabled = true
text = "Effect"
[node name="Button8" type="Button" parent="UiLayer/Control/Main/ScrollContainer2/HBoxContainer"]
layout_mode = 2
disabled = true
text = "Effect"
[node name="Button9" type="Button" parent="UiLayer/Control/Main/ScrollContainer2/HBoxContainer"]
layout_mode = 2
disabled = true
text = "Effect"
[node name="Button10" type="Button" parent="UiLayer/Control/Main/ScrollContainer2/HBoxContainer"]
layout_mode = 2
disabled = true
text = "Effect"
script = ExtResource("4_xggvw")
_activeBuffScene = ExtResource("5_xd21n")
[node name="Camera2D" type="Camera2D" parent="."]

View File

@@ -0,0 +1,10 @@
[gd_scene load_steps=2 format=3 uid="uid://b417dl07c13uc"]
[ext_resource type="Script" uid="uid://chnf0t5xdosys" path="res://Scripts/ActiveBuffUi.cs" id="1_7ujuu"]
[node name="BuffButton" type="Button"]
focus_mode = 0
disabled = true
button_mask = 0
text = "Effect"
script = ExtResource("1_7ujuu")

31
Scripts/ActiveBuffUi.cs Normal file
View File

@@ -0,0 +1,31 @@
using Godot;
using ParasiticGod.Scripts.Core.Effects;
namespace ParasiticGod.Scripts;
[GlobalClass]
public partial class ActiveBuffUi : Button
{
private Buff _buff;
public void SetBuff(Buff buff)
{
_buff = buff;
Disabled = true;
UpdateDisplay();
}
public override void _Process(double delta)
{
if (_buff != null)
{
UpdateDisplay();
}
}
private void UpdateDisplay()
{
Text = _buff.Name;
TooltipText = $"x{_buff.Multiplier:F1} to {_buff.Name.Split(' ')[0]}\n{_buff.Duration:F0}s remaining";
}
}

View File

@@ -0,0 +1 @@
uid://chnf0t5xdosys

View File

@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using Godot;
using ParasiticGod.Scripts.Core;
using ParasiticGod.Scripts.Core.Effects;
using ParasiticGod.Scripts.Singletons;
namespace ParasiticGod.Scripts;
[GlobalClass]
public partial class ActiveBuffsManager : Node
{
[Export] private PackedScene _activeBuffScene;
private readonly Dictionary<Guid, ActiveBuffUi> _activeBuffUis = new();
public override void _Ready()
{
GameBus.Instance.BuffAdded += OnBuffAdded;
GameBus.Instance.BuffRemoved += OnBuffRemoved;
}
public override void _ExitTree()
{
if (GameBus.Instance == null) return;
GameBus.Instance.BuffAdded -= OnBuffAdded;
GameBus.Instance.BuffRemoved -= OnBuffRemoved;
}
private void OnBuffAdded(Buff buff)
{
var buffInstance = _activeBuffScene.Instantiate<ActiveBuffUi>();
AddChild(buffInstance);
buffInstance.SetBuff(buff);
_activeBuffUis.Add(buff.Id, buffInstance);
}
private void OnBuffRemoved(Buff buff)
{
if (_activeBuffUis.TryGetValue(buff.Id, out var buffUi))
{
buffUi.QueueFree();
_activeBuffUis.Remove(buff.Id);
}
}
}

View File

@@ -0,0 +1 @@
uid://ddshg236tlltt

View File

@@ -1,4 +1,5 @@
using Godot;
using ParasiticGod.Scripts.Singletons;
namespace ParasiticGod.Scripts.Core.Effects;
@@ -13,11 +14,13 @@ public partial class ApplyBuffEffect : Effect
{
var newBuff = new Buff
{
Name = $"{TargetStat} x{Multiplier}",
Multiplier = Multiplier,
Duration = Duration
};
gameState.ActiveBuffs.Add(newBuff);
GameBus.Instance.NotifyBuffAdded(newBuff);
}
public override string ToString()

View File

@@ -1,7 +1,11 @@
using System;
namespace ParasiticGod.Scripts.Core.Effects;
public class Buff
{
public Guid Id { get; } = Guid.NewGuid(); // Unique identifier
public string Name { get; set; } // For display purposes
public float Multiplier { get; set; } = 1.0f;
public double Duration { get; set; }
}

View File

@@ -1,4 +1,5 @@
using System;
using ParasiticGod.Scripts.Singletons;
namespace ParasiticGod.Scripts.Core;
@@ -23,6 +24,7 @@ public class GameLogic
buff.Duration -= delta;
if (buff.Duration <= 0)
{
GameBus.Instance.NotifyBuffRemoved(buff);
state.ActiveBuffs.RemoveAt(i);
}
}

View File

@@ -18,6 +18,8 @@ public partial class GameBus : Node
public event Action<MiracleDefinition> MiraclePerformed;
public event Action<List<MiracleDefinition>> MiraclesUnlocked;
public event Action<MiracleDefinition> MiracleCompleted;
public event Action<Buff> BuffAdded;
public event Action<Buff> BuffRemoved;
public event Action PopulationVisualsUpdated;
public override void _EnterTree()
@@ -80,6 +82,16 @@ public partial class GameBus : Node
PopulationVisualsUpdated?.Invoke();
}
public void NotifyBuffAdded(Buff buff)
{
BuffAdded?.Invoke(buff);
}
public void NotifyBuffRemoved(Buff buff)
{
BuffRemoved?.Invoke(buff);
}
public void SubscribeToStat(Stat stat, Action<double> listener) => _gameState.Subscribe(stat, listener);
public void UnsubscribeFromStat(Stat stat, Action<double> listener) => _gameState.Unsubscribe(stat, listener);

BIN
Sprites/grey.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

34
Sprites/grey.png.import Normal file
View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cdqtebn40jnu7"
path="res://.godot/imported/grey.png-ed957cc0cb4168c6c55571190cb072a9.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Sprites/grey.png"
dest_files=["res://.godot/imported/grey.png-ed957cc0cb4168c6c55571190cb072a9.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

BIN
Sprites/grey_inlay.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dl8gejfyt34sl"
path="res://.godot/imported/grey_inlay.png-f92e2929bc6af2d8c940ba7c30359f4a.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Sprites/grey_inlay.png"
dest_files=["res://.godot/imported/grey_inlay.png-f92e2929bc6af2d8c940ba7c30359f4a.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

BIN
Sprites/grey_pressed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://13n1kf5nlb6i"
path="res://.godot/imported/grey_pressed.png-bfad8d00b793dd314961b15e0757bbdf.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://Sprites/grey_pressed.png"
dest_files=["res://.godot/imported/grey_pressed.png-bfad8d00b793dd314961b15e0757bbdf.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1