98 lines
3.9 KiB
Markdown
98 lines
3.9 KiB
Markdown
# 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
|