Add currency panel
This commit is contained in:
97
.opencode/plans/currency-panel.md
Normal file
97
.opencode/plans/currency-panel.md
Normal 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
|
||||||
35
core/currency/currency_panel.gd
Normal file
35
core/currency/currency_panel.gd
Normal 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
|
||||||
1
core/currency/currency_panel.gd.uid
Normal file
1
core/currency/currency_panel.gd.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://blfou5xiynxqf
|
||||||
15
docs/gyms/tiny_sword/currency_panel.tscn
Normal file
15
docs/gyms/tiny_sword/currency_panel.tscn
Normal 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
|
||||||
@@ -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="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="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="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://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="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="PackedScene" uid="uid://djedqovgngrx5" path="res://docs/gyms/tiny_sword/buildings/farm/farm.tscn" id="10_1lv5i"]
|
||||||
[ext_resource type="Resource" uid="uid://dpbndqxvsffa0" path="res://docs/gyms/tiny_sword/currencies/magic_gold.tres" id="20_no27p"]
|
[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://brctmnpmhjas6" path="res://docs/gyms/tiny_sword/currencies/mana_stone.tres" id="22_rbyxa"]
|
[ext_resource type="PackedScene" uid="uid://bf8lqbexvnx6e" path="res://docs/gyms/tiny_sword/buildings/monastery/monastery.tscn" id="13_no27p"]
|
||||||
[ext_resource type="Resource" uid="uid://t6du7gm2ywbi" path="res://docs/gyms/tiny_sword/currencies/cognite.tres" id="23_vrcrd"]
|
[ext_resource type="PackedScene" uid="uid://dirvi76rkoowf" path="res://goals_debug_ui.tscn" id="10_qifrv"]
|
||||||
[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://cur_panel_scene_uid" path="res://docs/gyms/tiny_sword/currency_panel.tscn" id="9_cpnl"]
|
||||||
|
|
||||||
[node name="TinySwords" type="Node" unique_id=498237642]
|
[node name="TinySwords" type="Node" unique_id=498237642]
|
||||||
|
|
||||||
@@ -87,83 +78,16 @@ anchors_preset = 0
|
|||||||
offset_right = 40.0
|
offset_right = 40.0
|
||||||
offset_bottom = 40.0
|
offset_bottom = 40.0
|
||||||
|
|
||||||
[node name="GoldCurrencyTile" parent="LevelGameState/UI" unique_id=1440583137 node_paths=PackedStringArray("game_state") instance=ExtResource("7_0cs5o")]
|
[node name="CurrencyPanel" parent="LevelGameState/UI" unique_id=2000000001 instance=ExtResource("9_cpnl")]
|
||||||
layout_mode = 0
|
layout_mode = 1
|
||||||
offset_right = 160.0
|
offset_left = 5.0
|
||||||
offset_bottom = 31.0
|
offset_top = 5.0
|
||||||
currency = ExtResource("9_1363k")
|
offset_right = 255.0
|
||||||
game_state = NodePath("../..")
|
offset_bottom = 345.0
|
||||||
|
|
||||||
[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="GoalsDebugUI" parent="LevelGameState/UI" unique_id=1494700185 instance=ExtResource("10_qifrv")]
|
[node name="GoalsDebugUI" parent="LevelGameState/UI" unique_id=1494700185 instance=ExtResource("10_qifrv")]
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
offset_left = 1275.0
|
offset_left = 265.0
|
||||||
offset_top = 4.0
|
offset_top = 5.0
|
||||||
offset_right = 1913.0
|
offset_right = 1913.0
|
||||||
offset_bottom = 263.0
|
offset_bottom = 263.0
|
||||||
|
|||||||
Reference in New Issue
Block a user