Add currency panel

This commit is contained in:
2026-04-24 00:55:00 +02:00
parent 4e6d7e41ed
commit b8a5e153c1
5 changed files with 161 additions and 89 deletions

View File

@@ -0,0 +1,97 @@
# Plan: Create CurrencyPanel Widget
## Goal
Regroup the 9 individual CurrencyTile nodes in tiny_sword.tscn into a single dynamic `CurrencyPanel` widget that automatically retrieves and displays all currencies from the LevelGameState catalogue.
## Changes
### 1. Create `CurrencyPanel` script (`core/currency/currency_panel.gd`)
**New file**: `res://core/currency/currency_panel.gd`
**Class**: `class_name CurrencyPanel`, extends `PanelContainer`
**Structure**:
```gdscript
class_name CurrencyPanel
extends PanelContainer
const CURRENCY_TILE_SCENE: PackedScene = preload("res://currency_tile.tscn")
@onready var _tiles_container: VBoxContainer = $CurrencyTiles
var _game_state: LevelGameState
func _ready() -> void:
_game_state = find_parent("LevelGameState")
if _game_state == null:
push_error("CurrencyPanel: No LevelGameState found in parent hierarchy")
return
_build_currency_tiles()
_game_state.ready.connect(_on_game_state_ready)
func _build_currency_tiles() -> void:
# Clear existing children
for child in _tiles_container.get_children():
child.queue_free()
if _game_state.currency_catalogue == null:
return
for currency in _game_state.currency_catalogue.currencies:
if currency == null:
continue
var tile: CurrencyTile = CURRENCY_TILE_SCENE.instantiate()
# Set exports before add_child() so they're available in _ready()
tile.currency = currency
tile.game_state = _game_state
_tiles_container.add_child(tile)
func _on_game_state_ready() -> void:
pass
```
**Why this works with existing CurrencyTile**: CurrencyTile uses `@export` for `currency` and `game_state`. When `instantiate()` is called, `_ready()` is NOT invoked yet - it fires when the node is added to the scene tree. By setting properties before `add_child()`, `_ready()` sees them as non-null. The DebugIncomeButton is preserved since CurrencyTile is unchanged.
### 2. Update tiny_sword.tscn scene
**Replace**: 9 individual CurrencyTile nodes under `LevelGameState/UI` with a single CurrencyPanel hierarchy.
**Remove from scene**:
- All 9 individual CurrencyTile nodes: `GoldCurrencyTile`, `WorkerCurrencyTile`, `FoodCurrencyTile`, `WoodCurrencyTile`, `AscensionCurrencyTile`, `MagicGoldTile`, `ManaStoneTile`, `CogniteTile`, `PhilosoperStoneTile`
- ExtResource `7_0cs5o` (currency_tile.tscn) - no longer referenced directly
- All 9 individual currency resource ExtResources: `9_1363k` (gold), `10_i1cck` (worker), `11_hskcg` (food), `12_l6a68` (wood), `15_ascension`, `20_no27p` (magic_gold), `22_rbyxa` (mana_stone), `23_vrcrd` (cognite), `24_eaq6h` (philosoper_stone)
**Add to scene**:
- ExtResource `8_cpnl``res://core/currency/currency_panel.gd`
- New node hierarchy:
```
LevelGameState/UI (Control, layout_mode=3)
CurrencyPanel (PanelContainer, layout_mode=1, pos 5,5 size 250x340, script=8_cpnl)
CurrencyTiles (VBoxContainer, separation=4) ← script-less, populated at runtime
GoalsDebugUI (repositioned: offset_left=265)
```
**Keep**: GoalsDebugUI (repositioned slightly from offset_left=1275 to offset_left=265 to account for panel width)
## File Structure After Changes
```
core/
level_game_state.gd # unchanged (ready is built-in)
currency/
currency_panel.gd # NEW: dynamic panel widget
docs/gyms/tiny_sword/
tiny_sword.tscn # 9 tiles → 1 panel hierarchy (cleaner)
```
## No Changes Needed
- **`level_game_state.gd`**: The `ready` signal is built-in for Godot nodes - no addition needed.
- **`currency_label.gd` (CurrencyTile)**: Unchanged - DebugIncomeButton preserved.
## Testing
- Run Godot headless to verify scene loads without errors
- Verify all 9 currencies appear in the CurrencyPanel
- Verify currency values update on changes (currency_changed signal)
- Verify DebugIncomeButton works on each tile
- Verify the panel doesn't overlap with GoalsDebugUI

View File

@@ -0,0 +1,35 @@
## Dynamically displays all currencies from the LevelGameState catalogue as CurrencyTile widgets.
class_name CurrencyPanel
extends PanelContainer
const CURRENCY_TILE_SCENE: PackedScene = preload("res://currency_tile.tscn")
@onready var _tiles_container: VBoxContainer = $CurrencyTiles
var _game_state: LevelGameState
func _ready() -> void:
_game_state = find_parent("LevelGameState")
if _game_state == null:
push_error("CurrencyPanel: No LevelGameState found in parent hierarchy")
return
_build_currency_tiles()
_game_state.ready.connect(_on_game_state_ready)
func _build_currency_tiles() -> void:
for child in _tiles_container.get_children():
child.queue_free()
if _game_state.currency_catalogue == null:
return
for currency in _game_state.currency_catalogue.currencies:
if currency == null:
continue
var tile: CurrencyTile = CURRENCY_TILE_SCENE.instantiate()
tile.currency = currency
tile.game_state = _game_state
_tiles_container.add_child(tile)
func _on_game_state_ready() -> void:
pass

View File

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

View File

@@ -0,0 +1,15 @@
[gd_scene format=3 uid="uid://cur_panel_scene_uid"]
[ext_resource type="Script" uid="uid://9_vbox" path="res://core/currency/currency_panel.gd" id="1_cpnl"]
[node name="CurrencyPanel" type="PanelContainer" unique_id=3000000001]
custom_minimum_size = Vector2(250, 340)
offset_left = 5.0
offset_top = 5.0
offset_right = 255.0
offset_bottom = 345.0
script = ExtResource("1_cpnl")
[node name="CurrencyTiles" type="VBoxContainer" parent="." unique_id=3000000002]
layout_mode = 2
theme_override_constants/separation = 4

View File

@@ -9,22 +9,13 @@
[ext_resource type="Resource" uid="uid://umi37hotcq8m" path="res://docs/gyms/tiny_sword/research/ts_research_catalogue.tres" id="5_v0pty"]
[ext_resource type="Script" uid="uid://srkiu4qe8s2m" path="res://core/prestige/prestige_manager.gd" id="5_x77df"]
[ext_resource type="Resource" uid="uid://dwmfvmusfskk6" path="res://docs/gyms/tiny_sword/prestige/primary_prestige.tres" id="6_xnhlc"]
[ext_resource type="PackedScene" uid="uid://btkxru2gdjsgc" path="res://currency_tile.tscn" id="7_0cs5o"]
[ext_resource type="Resource" uid="uid://w4u1hddplb4e" path="res://docs/gyms/tiny_sword/currencies/gold.tres" id="9_1363k"]
[ext_resource type="PackedScene" uid="uid://djedqovgngrx5" path="res://docs/gyms/tiny_sword/buildings/farm/farm.tscn" id="10_1lv5i"]
[ext_resource type="Resource" uid="uid://dfxk30o34qe2s" path="res://docs/gyms/tiny_sword/currencies/worker.tres" id="10_i1cck"]
[ext_resource type="PackedScene" uid="uid://dirvi76rkoowf" path="res://goals_debug_ui.tscn" id="10_qifrv"]
[ext_resource type="Resource" uid="uid://bxg2au0ijp242" path="res://docs/gyms/tiny_sword/currencies/food.tres" id="11_hskcg"]
[ext_resource type="PackedScene" uid="uid://cf01wvy3f17i" path="res://docs/gyms/tiny_sword/buildings/forestry/forestry.tscn" id="11_pyqyw"]
[ext_resource type="Resource" uid="uid://bgsk8h4w80h45" path="res://docs/gyms/tiny_sword/currencies/wood.tres" id="12_l6a68"]
[ext_resource type="PackedScene" uid="uid://bf8lqbexvnx6e" path="res://docs/gyms/tiny_sword/buildings/monastery/monastery.tscn" id="13_no27p"]
[ext_resource type="PackedScene" uid="uid://rejxvjwybkll" path="res://sandbox/tiny_swords/Terrain/Resources/Wood/Trees/tree_1.tscn" id="14_0cs5o"]
[ext_resource type="PackedScene" uid="uid://bp5ng4vu4ot4a" path="res://docs/gyms/tiny_sword/buildings/alchemy_tower/alchemy_tower.tscn" id="14_hum8s"]
[ext_resource type="Resource" uid="uid://bfrb0ayrljac2" path="res://docs/gyms/tiny_sword/currencies/ascension.tres" id="15_ascension"]
[ext_resource type="Resource" uid="uid://dpbndqxvsffa0" path="res://docs/gyms/tiny_sword/currencies/magic_gold.tres" id="20_no27p"]
[ext_resource type="Resource" uid="uid://brctmnpmhjas6" path="res://docs/gyms/tiny_sword/currencies/mana_stone.tres" id="22_rbyxa"]
[ext_resource type="Resource" uid="uid://t6du7gm2ywbi" path="res://docs/gyms/tiny_sword/currencies/cognite.tres" id="23_vrcrd"]
[ext_resource type="Resource" uid="uid://co4fiqgluwit0" path="res://docs/gyms/tiny_sword/currencies/philosoper_stone.tres" id="24_eaq6h"]
[ext_resource type="PackedScene" uid="uid://djedqovgngrx5" path="res://docs/gyms/tiny_sword/buildings/farm/farm.tscn" id="10_1lv5i"]
[ext_resource type="PackedScene" uid="uid://cf01wvy3f17i" path="res://docs/gyms/tiny_sword/buildings/forestry/forestry.tscn" id="11_pyqyw"]
[ext_resource type="PackedScene" uid="uid://bf8lqbexvnx6e" path="res://docs/gyms/tiny_sword/buildings/monastery/monastery.tscn" id="13_no27p"]
[ext_resource type="PackedScene" uid="uid://dirvi76rkoowf" path="res://goals_debug_ui.tscn" id="10_qifrv"]
[ext_resource type="PackedScene" uid="uid://cur_panel_scene_uid" path="res://docs/gyms/tiny_sword/currency_panel.tscn" id="9_cpnl"]
[node name="TinySwords" type="Node" unique_id=498237642]
@@ -87,83 +78,16 @@ anchors_preset = 0
offset_right = 40.0
offset_bottom = 40.0
[node name="GoldCurrencyTile" parent="LevelGameState/UI" unique_id=1440583137 node_paths=PackedStringArray("game_state") instance=ExtResource("7_0cs5o")]
layout_mode = 0
offset_right = 160.0
offset_bottom = 31.0
currency = ExtResource("9_1363k")
game_state = NodePath("../..")
[node name="WorkerCurrencyTile" parent="LevelGameState/UI" unique_id=1164876942 node_paths=PackedStringArray("game_state") instance=ExtResource("7_0cs5o")]
layout_mode = 0
offset_top = 32.0
offset_right = 160.0
offset_bottom = 63.0
currency = ExtResource("10_i1cck")
game_state = NodePath("../..")
[node name="FoodCurrencyTile" parent="LevelGameState/UI" unique_id=1814936562 node_paths=PackedStringArray("game_state") instance=ExtResource("7_0cs5o")]
layout_mode = 0
offset_top = 63.0
offset_right = 160.0
offset_bottom = 94.0
currency = ExtResource("11_hskcg")
game_state = NodePath("../..")
[node name="WoodCurrencyTile" parent="LevelGameState/UI" unique_id=338003163 node_paths=PackedStringArray("game_state") instance=ExtResource("7_0cs5o")]
layout_mode = 0
offset_top = 94.0
offset_right = 160.0
offset_bottom = 125.0
currency = ExtResource("12_l6a68")
game_state = NodePath("../..")
[node name="AscensionCurrencyTile" parent="LevelGameState/UI" unique_id=705032705 node_paths=PackedStringArray("game_state") instance=ExtResource("7_0cs5o")]
layout_mode = 0
offset_top = 125.0
offset_right = 160.0
offset_bottom = 156.0
currency = ExtResource("15_ascension")
game_state = NodePath("../..")
[node name="MagicGoldTile" parent="LevelGameState/UI" unique_id=707573446 node_paths=PackedStringArray("game_state") instance=ExtResource("7_0cs5o")]
layout_mode = 0
offset_top = 152.0
offset_right = 203.0
offset_bottom = 183.0
currency = ExtResource("20_no27p")
game_state = NodePath("../..")
[node name="ManaStoneTile" parent="LevelGameState/UI" unique_id=1333819600 node_paths=PackedStringArray("game_state") instance=ExtResource("7_0cs5o")]
layout_mode = 0
offset_left = 1.0
offset_top = 178.0
offset_right = 204.0
offset_bottom = 209.0
currency = ExtResource("22_rbyxa")
game_state = NodePath("../..")
[node name="CogniteTile" parent="LevelGameState/UI" unique_id=150108085 node_paths=PackedStringArray("game_state") instance=ExtResource("7_0cs5o")]
layout_mode = 0
offset_left = 1.0
offset_top = 210.0
offset_right = 204.0
offset_bottom = 241.0
currency = ExtResource("23_vrcrd")
game_state = NodePath("../..")
[node name="PhilosoperStoneTile" parent="LevelGameState/UI" unique_id=1360957288 node_paths=PackedStringArray("game_state") instance=ExtResource("7_0cs5o")]
layout_mode = 0
offset_left = 1.0
offset_top = 240.0
offset_right = 204.0
offset_bottom = 271.0
currency = ExtResource("24_eaq6h")
game_state = NodePath("../..")
[node name="CurrencyPanel" parent="LevelGameState/UI" unique_id=2000000001 instance=ExtResource("9_cpnl")]
layout_mode = 1
offset_left = 5.0
offset_top = 5.0
offset_right = 255.0
offset_bottom = 345.0
[node name="GoalsDebugUI" parent="LevelGameState/UI" unique_id=1494700185 instance=ExtResource("10_qifrv")]
layout_mode = 1
offset_left = 1275.0
offset_top = 4.0
offset_left = 265.0
offset_top = 5.0
offset_right = 1913.0
offset_bottom = 263.0