Arena polish: in-run HUD, no free loot, retire-with-winnings
- HUD arena status (top center): live wave number and run gold, driven by GameState signals, torn down cleanly on HUD.reset() - Free floor weapons removed: the initial sword/shield spawn is gone and manually placed level.tscn weapons are deleted server-side at init. Gear now only enters play via the armory or enemy drops. - Retire to Camp: new escape-menu button (shown only while alive in an active run) banks 100% of run gold and keeps all gear - the counterweight to death's 10% settlement. Exit Game and window close also bank winnings before quitting. - CLAUDE.md rewritten for the gladiator arena era: core loop, autoloads, economy API, RPC patterns, verification workflow.
This commit is contained in:
@@ -11,6 +11,9 @@ var tab_hint: Control = null
|
||||
var keybind_hint: Control = null
|
||||
var escape_menu: Control = null
|
||||
var run_results: Control = null
|
||||
var arena_status: Control = null
|
||||
var _wave_label: Label = null
|
||||
var _gold_label: Label = null
|
||||
|
||||
# Player reference
|
||||
var local_player: Character = null
|
||||
@@ -81,6 +84,7 @@ func _create_ui_components():
|
||||
_create_tab_hint()
|
||||
_create_keybind_hint()
|
||||
_create_escape_menu()
|
||||
_create_arena_status()
|
||||
|
||||
## Create action bar at bottom of screen
|
||||
func _create_action_bar():
|
||||
@@ -150,6 +154,57 @@ func _create_escape_menu():
|
||||
else:
|
||||
push_error("[HUD] Failed to load escape_menu.tscn")
|
||||
|
||||
## Create the arena status readout (wave + run gold, top center)
|
||||
func _create_arena_status():
|
||||
arena_status = PanelContainer.new()
|
||||
arena_status.name = "ArenaStatus"
|
||||
arena_status.set_anchors_preset(Control.PRESET_CENTER_TOP)
|
||||
arena_status.offset_top = 10
|
||||
arena_status.grow_horizontal = Control.GROW_DIRECTION_BOTH
|
||||
add_child(arena_status)
|
||||
|
||||
var margin = MarginContainer.new()
|
||||
margin.add_theme_constant_override("margin_left", 18)
|
||||
margin.add_theme_constant_override("margin_right", 18)
|
||||
margin.add_theme_constant_override("margin_top", 6)
|
||||
margin.add_theme_constant_override("margin_bottom", 6)
|
||||
arena_status.add_child(margin)
|
||||
|
||||
var hbox = HBoxContainer.new()
|
||||
hbox.add_theme_constant_override("separation", 24)
|
||||
margin.add_child(hbox)
|
||||
|
||||
_wave_label = Label.new()
|
||||
_wave_label.add_theme_font_size_override("font_size", 22)
|
||||
_wave_label.add_theme_color_override("font_color", Color(1.0, 0.8, 0.0))
|
||||
_wave_label.add_theme_color_override("font_outline_color", Color.BLACK)
|
||||
_wave_label.add_theme_constant_override("outline_size", 2)
|
||||
hbox.add_child(_wave_label)
|
||||
|
||||
_gold_label = Label.new()
|
||||
_gold_label.add_theme_font_size_override("font_size", 22)
|
||||
_gold_label.add_theme_color_override("font_color", Color(1.0, 0.85, 0.2))
|
||||
_gold_label.add_theme_color_override("font_outline_color", Color.BLACK)
|
||||
_gold_label.add_theme_constant_override("outline_size", 2)
|
||||
hbox.add_child(_gold_label)
|
||||
|
||||
# Live updates from the economy
|
||||
GameState.wave_changed.connect(_on_wave_changed)
|
||||
GameState.run_gold_changed.connect(_on_run_gold_changed)
|
||||
|
||||
# Seed with current values (run may already be underway)
|
||||
_on_wave_changed(GameState.current_wave)
|
||||
_on_run_gold_changed(GameState.run_gold)
|
||||
print("[HUD] Arena status created")
|
||||
|
||||
func _on_wave_changed(wave: int):
|
||||
if _wave_label:
|
||||
_wave_label.text = "Wave %d" % wave if wave > 0 else "Prepare..."
|
||||
|
||||
func _on_run_gold_changed(gold: int):
|
||||
if _gold_label:
|
||||
_gold_label.text = "Gold +%d" % gold
|
||||
|
||||
## Show all UI components
|
||||
func show_hud():
|
||||
show()
|
||||
@@ -165,6 +220,13 @@ func reset():
|
||||
_disconnect_player_signals()
|
||||
local_player = null
|
||||
|
||||
# Drop GameState connections so they don't fire on freed labels
|
||||
# (and don't double-connect when the next run creates a new status bar)
|
||||
if GameState.wave_changed.is_connected(_on_wave_changed):
|
||||
GameState.wave_changed.disconnect(_on_wave_changed)
|
||||
if GameState.run_gold_changed.is_connected(_on_run_gold_changed):
|
||||
GameState.run_gold_changed.disconnect(_on_run_gold_changed)
|
||||
|
||||
for child in get_children():
|
||||
child.queue_free()
|
||||
|
||||
@@ -176,6 +238,9 @@ func reset():
|
||||
keybind_hint = null
|
||||
escape_menu = null
|
||||
run_results = null
|
||||
arena_status = null
|
||||
_wave_label = null
|
||||
_gold_label = null
|
||||
print("[HUD] Reset - all UI components removed")
|
||||
|
||||
## Player signal callbacks
|
||||
|
||||
Reference in New Issue
Block a user