Gladiator arena: gold economy, outfitting shop, permadeath runs

Turns the sandbox into a survival roguelike loop: outfit your gladiator
with banked gold, enter the arena, earn gold from kills and wave clears,
die, keep 10% of your total value (floored at the 500 fresh-start).

Economy (GameState autoload):
- banked_gold, owned items, and loadout persist to user://save.cfg
- Kill gold (basic 10g, armed 25g) credited server-side to the killer
- Wave-clear bonus (25 + 5/wave) for all players; wave synced to peers
- Death settlement liquidates gear, guarded against double-fire

Character creation / shop:
- Menu reframed: armory shop + live Character Sheet loadout preview
- Character Sheet gains preview mode (renders from loadout, no player)
- Buy/Equip with hand rules; two-handers and off-hands displace each
  other symmetrically (shop and in-game pickups)
- Chosen loadout auto-equips on spawn via existing RPC path

Combat feel:
- Attacks snap to camera facing and lock direction for the swing
- Dash commits to its direction for the full duration
- Weapon slots show name text when no icon is set
- Hitbox/hurtbox debug meshes hidden by default (H toggles)

Death is final: players no longer respawn; a results screen shows waves,
time, kills, and the settlement, then returns to camp. Armed enemies no
longer respawn (were an infinite gold farm and respawned invisible).
This commit is contained in:
2026-07-01 23:38:59 +01:00
parent 97ebbb1618
commit 1562b37563
25 changed files with 1023 additions and 43 deletions
+36
View File
@@ -5,6 +5,8 @@ class_name WeaponSlot
# References
@onready var icon_rect: TextureRect = $SlotPanel/MarginContainer/IconRect
var tooltip: PanelContainer = null
# Fallback name display for weapons without an icon texture
var _name_label: Label = null
# Weapon data
var weapon_data: WeaponData = null
@@ -53,9 +55,43 @@ func _update_display():
if weapon_data and weapon_data.icon:
icon_rect.texture = weapon_data.icon
icon_rect.modulate = Color.WHITE
_set_name_fallback("")
elif weapon_data:
# No icon on this weapon - show its name in the slot instead
icon_rect.texture = null
icon_rect.modulate = Color.WHITE
_set_name_fallback(weapon_data.weapon_name)
else:
icon_rect.texture = null
icon_rect.modulate = Color(0.3, 0.3, 0.3, 0.5) # Dim empty slot
_set_name_fallback("")
## Show/hide the fallback name label ("" hides it)
func _set_name_fallback(text: String):
if text == "":
if _name_label:
_name_label.hide()
return
if not _name_label:
_name_label = Label.new()
_name_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
_name_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
_name_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
_name_label.add_theme_font_size_override("font_size", 12)
_name_label.add_theme_color_override("font_color", Color(1.0, 0.85, 0.4))
_name_label.add_theme_color_override("font_outline_color", Color.BLACK)
_name_label.add_theme_constant_override("outline_size", 2)
_name_label.set_anchors_preset(Control.PRESET_FULL_RECT)
_name_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
var container = get_node_or_null("SlotPanel/MarginContainer")
if container:
container.add_child(_name_label)
else:
add_child(_name_label)
_name_label.text = text
_name_label.show()
## Show tooltip on mouse enter
func _on_mouse_entered():