added some amazing changes
This commit is contained in:
@@ -78,6 +78,21 @@ var equipment_buttons: Dictionary = {} # slot_name -> button
|
||||
var inventory_items_list: Array = [] # Flat list of items for navigation
|
||||
var inventory_rows_list: Array = [] # List of HBoxContainers (rows)
|
||||
|
||||
# Level-up stat allocation (when pending_level_up)
|
||||
var level_up_label: Label = null
|
||||
var level_up_stat_buttons: Array = [] # Buttons for STR, DEX, INT, END, WIS, LCK, PER
|
||||
var level_up_stat_container: HBoxContainer = null
|
||||
var selected_level_up_stat_index: int = -1
|
||||
const STAT_DESCRIPTIONS: Dictionary = {
|
||||
"str": "STR: Physical damage, carry capacity.",
|
||||
"dex": "DEX: Dodge, hit chance, move & attack speed.",
|
||||
"int": "INT: Spell damage, mana, sight.",
|
||||
"end": "END: Max HP.",
|
||||
"wis": "WIS: Mana regen, resistances.",
|
||||
"lck": "LCK: Critical hit chance.",
|
||||
"per": "PER: Trap detection, perception."
|
||||
}
|
||||
|
||||
# Equipment slot buttons
|
||||
var equipment_slots: Dictionary = {
|
||||
"mainhand": null,
|
||||
@@ -116,6 +131,9 @@ func _ready():
|
||||
_create_exp_ui()
|
||||
_create_coin_ui()
|
||||
|
||||
# Level-up stat allocation UI (label + stat buttons)
|
||||
_setup_level_up_ui()
|
||||
|
||||
# Setup selection rectangle (already in scene, just configure it)
|
||||
_setup_selection_rectangle()
|
||||
|
||||
@@ -208,6 +226,16 @@ func _update_stats():
|
||||
var race_text = char_stats.race
|
||||
stats_label.text = "Stats - " + race_text
|
||||
|
||||
# Level-up UI: "Level X - LEVEL UP" in green, stat allocation buttons
|
||||
var pending = char_stats.pending_level_up and char_stats.pending_stat_points > 0
|
||||
if level_up_label:
|
||||
level_up_label.visible = pending
|
||||
if pending:
|
||||
level_up_label.text = "Level " + str(char_stats.level) + " - LEVEL UP"
|
||||
level_up_label.add_theme_color_override("font_color", Color(0.2, 1.0, 0.4))
|
||||
if level_up_stat_container:
|
||||
level_up_stat_container.visible = pending
|
||||
|
||||
# Base stats: Level, STR, DEX, END, INT, WIS, LCK, PER (HP/MP are bars below)
|
||||
if label_base_stats:
|
||||
label_base_stats.text = "Level\n\nSTR\nDEX\nEND\nINT\nWIS\nLCK\nPER"
|
||||
@@ -279,6 +307,82 @@ func _update_stats():
|
||||
fill_style.bg_color = Color(0.9, 0.3, 0.2)
|
||||
weight_progress_bar.add_theme_stylebox_override("fill", fill_style)
|
||||
|
||||
func _setup_level_up_ui() -> void:
|
||||
if not stats_panel:
|
||||
return
|
||||
level_up_label = Label.new()
|
||||
level_up_label.name = "LevelUpLabel"
|
||||
level_up_label.add_theme_font_size_override("font_size", 14)
|
||||
level_up_label.add_theme_color_override("font_color", Color(0.2, 1.0, 0.4))
|
||||
if ResourceLoader.exists("res://assets/fonts/standard_font.png"):
|
||||
var fr = load("res://assets/fonts/standard_font.png")
|
||||
if fr:
|
||||
level_up_label.add_theme_font_override("font", fr)
|
||||
level_up_label.visible = false
|
||||
stats_panel.add_child(level_up_label)
|
||||
stats_panel.move_child(level_up_label, 1)
|
||||
level_up_stat_container = HBoxContainer.new()
|
||||
level_up_stat_container.name = "LevelUpStatButtons"
|
||||
level_up_stat_container.add_theme_constant_override("separation", 4)
|
||||
level_up_stat_container.visible = false
|
||||
for stat_name in CharacterStats.LEVEL_UP_STAT_NAMES:
|
||||
var btn = Button.new()
|
||||
btn.name = "LevelUp_" + stat_name
|
||||
btn.text = stat_name.to_upper()
|
||||
btn.custom_minimum_size = Vector2(32, 24)
|
||||
btn.flat = true
|
||||
if ResourceLoader.exists("res://assets/fonts/standard_font.png"):
|
||||
var fr = load("res://assets/fonts/standard_font.png")
|
||||
if fr:
|
||||
btn.add_theme_font_override("font", fr)
|
||||
btn.add_theme_font_size_override("font_size", 9)
|
||||
btn.focus_mode = Control.FOCUS_ALL
|
||||
btn.pressed.connect(_on_level_up_stat_pressed.bind(stat_name))
|
||||
btn.mouse_entered.connect(_on_level_up_stat_hover_entered.bind(stat_name))
|
||||
btn.mouse_exited.connect(_on_level_up_stat_hover_exited)
|
||||
btn.gui_input.connect(_on_level_up_stat_gui_input.bind(stat_name, btn))
|
||||
level_up_stat_container.add_child(btn)
|
||||
level_up_stat_buttons.append(btn)
|
||||
stats_panel.add_child(level_up_stat_container)
|
||||
stats_panel.move_child(level_up_stat_container, 2)
|
||||
|
||||
func _on_level_up_stat_pressed(stat_name: String) -> void:
|
||||
if not local_player or not local_player.character_stats:
|
||||
return
|
||||
if local_player.character_stats.allocate_stat_point(stat_name):
|
||||
if sfx_armour:
|
||||
sfx_armour.play()
|
||||
_update_stats()
|
||||
if not local_player.character_stats.pending_level_up:
|
||||
selected_type = "equipment"
|
||||
selected_level_up_stat_index = -1
|
||||
var next_index = _find_next_filled_equipment_slot(-1, 1)
|
||||
if next_index >= 0:
|
||||
equipment_selection_index = next_index
|
||||
selected_slot = equipment_slots_list[next_index]
|
||||
selected_item = local_player.character_stats.equipment[selected_slot]
|
||||
else:
|
||||
selected_slot = ""
|
||||
selected_item = null
|
||||
if inventory_items_list.size() > 0:
|
||||
selected_type = "item"
|
||||
inventory_selection_row = 0
|
||||
inventory_selection_col = 0
|
||||
_update_ui()
|
||||
|
||||
func _on_level_up_stat_hover_entered(stat_name: String) -> void:
|
||||
if info_label and stat_name in STAT_DESCRIPTIONS:
|
||||
info_label.text = STAT_DESCRIPTIONS[stat_name]
|
||||
|
||||
func _on_level_up_stat_hover_exited() -> void:
|
||||
if info_label:
|
||||
_update_info_panel()
|
||||
|
||||
func _on_level_up_stat_gui_input(event: InputEvent, stat_name: String, btn: Button) -> void:
|
||||
if event is InputEventKey and event.pressed and not event.echo:
|
||||
if event.keycode == KEY_ENTER or event.keycode == KEY_KP_ENTER or event.keycode == KEY_SPACE:
|
||||
_on_level_up_stat_pressed(stat_name)
|
||||
|
||||
func _create_equipment_slots():
|
||||
# Equipment slot order: mainhand, offhand, headgear, armour, boots, accessory
|
||||
var slot_names = ["mainhand", "offhand", "headgear", "armour", "boots", "accessory"]
|
||||
@@ -1062,6 +1166,17 @@ func _navigate_equipment(direction: String):
|
||||
var next_index = _find_next_filled_equipment_slot(equipment_selection_index, -1)
|
||||
if next_index >= 0:
|
||||
equipment_selection_index = next_index
|
||||
elif local_player and local_player.character_stats and local_player.character_stats.pending_level_up and local_player.character_stats.pending_stat_points > 0 and level_up_stat_buttons.size() > 0:
|
||||
selected_type = "level_up_stat"
|
||||
selected_level_up_stat_index = 0
|
||||
selected_slot = ""
|
||||
selected_item = null
|
||||
level_up_stat_buttons[0].call_deferred("grab_focus")
|
||||
if info_label and CharacterStats.LEVEL_UP_STAT_NAMES.size() > 0:
|
||||
var sn = CharacterStats.LEVEL_UP_STAT_NAMES[0]
|
||||
if sn in STAT_DESCRIPTIONS:
|
||||
info_label.text = STAT_DESCRIPTIONS[sn]
|
||||
return
|
||||
"right":
|
||||
var next_index = _find_next_filled_equipment_slot(equipment_selection_index, 1)
|
||||
if next_index >= 0:
|
||||
@@ -1125,6 +1240,44 @@ func _navigate_equipment(direction: String):
|
||||
_update_selection_rectangle()
|
||||
_update_info_panel()
|
||||
|
||||
func _navigate_level_up_stats(direction: String) -> void:
|
||||
var n = level_up_stat_buttons.size()
|
||||
if n == 0:
|
||||
return
|
||||
match direction:
|
||||
"left":
|
||||
selected_level_up_stat_index = (selected_level_up_stat_index - 1 + n) % n
|
||||
level_up_stat_buttons[selected_level_up_stat_index].call_deferred("grab_focus")
|
||||
if info_label and selected_level_up_stat_index < CharacterStats.LEVEL_UP_STAT_NAMES.size():
|
||||
var sn = CharacterStats.LEVEL_UP_STAT_NAMES[selected_level_up_stat_index]
|
||||
if sn in STAT_DESCRIPTIONS:
|
||||
info_label.text = STAT_DESCRIPTIONS[sn]
|
||||
"right":
|
||||
if selected_level_up_stat_index >= n - 1:
|
||||
# Past last stat: go to equipment
|
||||
selected_type = "equipment"
|
||||
selected_level_up_stat_index = -1
|
||||
selected_slot = ""
|
||||
selected_item = null
|
||||
var next_index = _find_next_filled_equipment_slot(-1, 1)
|
||||
if next_index >= 0:
|
||||
equipment_selection_index = next_index
|
||||
selected_slot = equipment_slots_list[next_index]
|
||||
selected_item = local_player.character_stats.equipment[selected_slot] if local_player and local_player.character_stats else null
|
||||
_update_selection_from_navigation()
|
||||
_update_selection_rectangle()
|
||||
_update_info_panel()
|
||||
return
|
||||
selected_level_up_stat_index += 1
|
||||
level_up_stat_buttons[selected_level_up_stat_index].call_deferred("grab_focus")
|
||||
if info_label and selected_level_up_stat_index < CharacterStats.LEVEL_UP_STAT_NAMES.size():
|
||||
var sn = CharacterStats.LEVEL_UP_STAT_NAMES[selected_level_up_stat_index]
|
||||
if sn in STAT_DESCRIPTIONS:
|
||||
info_label.text = STAT_DESCRIPTIONS[sn]
|
||||
"up", "down":
|
||||
pass
|
||||
# Don't call _update_info_panel - we've set stat description above
|
||||
|
||||
func _on_inventory_item_pressed(item: Item):
|
||||
if not local_player or not local_player.character_stats:
|
||||
return
|
||||
@@ -1221,7 +1374,9 @@ func _input(event):
|
||||
direction = "down"
|
||||
|
||||
if direction != "":
|
||||
if selected_type == "equipment":
|
||||
if selected_type == "level_up_stat":
|
||||
_navigate_level_up_stats(direction)
|
||||
elif selected_type == "equipment":
|
||||
_navigate_equipment(direction)
|
||||
else:
|
||||
_navigate_inventory(direction)
|
||||
@@ -1239,6 +1394,16 @@ func _input(event):
|
||||
_handle_e_key()
|
||||
get_viewport().set_input_as_handled()
|
||||
return
|
||||
|
||||
# Attack: Allocate level-up stat when a stat button is focused
|
||||
if event.is_action_pressed("attack") and not event.is_echo():
|
||||
var fc = get_viewport().gui_get_focus_owner()
|
||||
if level_up_stat_container and fc and is_instance_valid(level_up_stat_container) and fc.get_parent() == level_up_stat_container:
|
||||
var idx = level_up_stat_buttons.find(fc)
|
||||
if idx >= 0 and idx < CharacterStats.LEVEL_UP_STAT_NAMES.size():
|
||||
_on_level_up_stat_pressed(CharacterStats.LEVEL_UP_STAT_NAMES[idx])
|
||||
get_viewport().set_input_as_handled()
|
||||
return
|
||||
|
||||
func _handle_f_key():
|
||||
if not local_player or not local_player.character_stats:
|
||||
@@ -1562,6 +1727,7 @@ func _open_inventory():
|
||||
selected_slot = ""
|
||||
|
||||
_update_ui()
|
||||
_update_stats()
|
||||
|
||||
if not local_player:
|
||||
_find_local_player()
|
||||
|
||||
Reference in New Issue
Block a user