feat: implement loadout management system, interactive pause menu, and weapon slot switching functionality
This commit is contained in:
@@ -0,0 +1,250 @@
|
||||
extends CanvasLayer
|
||||
|
||||
var bg: ColorRect
|
||||
var main_vbox: VBoxContainer
|
||||
var resume_btn: Button
|
||||
var loadouts_btn: Button
|
||||
var exit_btn: Button
|
||||
|
||||
var loadout_editor: Control
|
||||
var loadout_list_vbox: VBoxContainer
|
||||
var edit_panel: PanelContainer
|
||||
var name_edit: LineEdit
|
||||
var primary1_opt: OptionButton
|
||||
var primary2_opt: OptionButton
|
||||
var special_opt: OptionButton
|
||||
var save_loadout_btn: Button
|
||||
var back_to_main_btn: Button
|
||||
|
||||
var editing_index: int = -1
|
||||
|
||||
var quit_dialog: ConfirmationDialog
|
||||
|
||||
func _ready() -> void:
|
||||
process_mode = Node.PROCESS_MODE_ALWAYS
|
||||
layer = 100 # Ensure it's on top
|
||||
visible = false
|
||||
|
||||
_build_ui()
|
||||
_connect_signals()
|
||||
|
||||
func _input(event: InputEvent) -> void:
|
||||
if event.is_action_pressed("ui_cancel"):
|
||||
if visible:
|
||||
_resume()
|
||||
else:
|
||||
_pause()
|
||||
|
||||
func _pause() -> void:
|
||||
visible = true
|
||||
get_tree().paused = true
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
|
||||
_show_main_menu()
|
||||
|
||||
func _resume() -> void:
|
||||
visible = false
|
||||
get_tree().paused = false
|
||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
|
||||
|
||||
func _build_ui() -> void:
|
||||
bg = ColorRect.new()
|
||||
bg.color = Color(0, 0, 0, 0.7)
|
||||
bg.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
add_child(bg)
|
||||
|
||||
# Main Menu
|
||||
main_vbox = VBoxContainer.new()
|
||||
main_vbox.set_anchors_preset(Control.PRESET_CENTER)
|
||||
main_vbox.add_theme_constant_override("separation", 20)
|
||||
bg.add_child(main_vbox)
|
||||
|
||||
var title = Label.new()
|
||||
title.text = "PAUSED"
|
||||
title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
title.add_theme_font_size_override("font_size", 48)
|
||||
main_vbox.add_child(title)
|
||||
|
||||
resume_btn = Button.new()
|
||||
resume_btn.text = "Resume"
|
||||
resume_btn.custom_minimum_size = Vector2(200, 50)
|
||||
main_vbox.add_child(resume_btn)
|
||||
|
||||
loadouts_btn = Button.new()
|
||||
loadouts_btn.text = "Loadouts"
|
||||
loadouts_btn.custom_minimum_size = Vector2(200, 50)
|
||||
main_vbox.add_child(loadouts_btn)
|
||||
|
||||
exit_btn = Button.new()
|
||||
exit_btn.text = "Exit Game"
|
||||
exit_btn.custom_minimum_size = Vector2(200, 50)
|
||||
main_vbox.add_child(exit_btn)
|
||||
|
||||
# Loadout Editor Root
|
||||
loadout_editor = Control.new()
|
||||
loadout_editor.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
bg.add_child(loadout_editor)
|
||||
|
||||
var editor_hbox = HBoxContainer.new()
|
||||
editor_hbox.set_anchors_preset(Control.PRESET_CENTER)
|
||||
editor_hbox.add_theme_constant_override("separation", 40)
|
||||
loadout_editor.add_child(editor_hbox)
|
||||
|
||||
# Loadout List
|
||||
var left_vbox = VBoxContainer.new()
|
||||
editor_hbox.add_child(left_vbox)
|
||||
|
||||
var list_title = Label.new()
|
||||
list_title.text = "Your Loadouts"
|
||||
list_title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
left_vbox.add_child(list_title)
|
||||
|
||||
loadout_list_vbox = VBoxContainer.new()
|
||||
left_vbox.add_child(loadout_list_vbox)
|
||||
|
||||
back_to_main_btn = Button.new()
|
||||
back_to_main_btn.text = "Back to Menu"
|
||||
back_to_main_btn.custom_minimum_size = Vector2(0, 40)
|
||||
left_vbox.add_child(back_to_main_btn)
|
||||
|
||||
# Edit Panel
|
||||
edit_panel = PanelContainer.new()
|
||||
editor_hbox.add_child(edit_panel)
|
||||
|
||||
var edit_vbox = VBoxContainer.new()
|
||||
edit_vbox.add_theme_constant_override("separation", 10)
|
||||
edit_panel.add_child(edit_vbox)
|
||||
|
||||
var edit_title = Label.new()
|
||||
edit_title.text = "Edit Loadout"
|
||||
edit_title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
edit_vbox.add_child(edit_title)
|
||||
|
||||
name_edit = LineEdit.new()
|
||||
name_edit.placeholder_text = "Loadout Name"
|
||||
name_edit.custom_minimum_size = Vector2(250, 0)
|
||||
edit_vbox.add_child(name_edit)
|
||||
|
||||
edit_vbox.add_child(_create_label("Primary 1:"))
|
||||
primary1_opt = OptionButton.new()
|
||||
edit_vbox.add_child(primary1_opt)
|
||||
|
||||
edit_vbox.add_child(_create_label("Primary 2:"))
|
||||
primary2_opt = OptionButton.new()
|
||||
edit_vbox.add_child(primary2_opt)
|
||||
|
||||
edit_vbox.add_child(_create_label("Special:"))
|
||||
special_opt = OptionButton.new()
|
||||
edit_vbox.add_child(special_opt)
|
||||
|
||||
save_loadout_btn = Button.new()
|
||||
save_loadout_btn.text = "Save Loadout"
|
||||
save_loadout_btn.custom_minimum_size = Vector2(0, 40)
|
||||
edit_vbox.add_child(save_loadout_btn)
|
||||
|
||||
# Quit Dialog
|
||||
quit_dialog = ConfirmationDialog.new()
|
||||
quit_dialog.title = "Quit Game"
|
||||
quit_dialog.dialog_text = "Are you sure you want to close the game?"
|
||||
add_child(quit_dialog)
|
||||
|
||||
func _create_label(text: String) -> Label:
|
||||
var l = Label.new()
|
||||
l.text = text
|
||||
return l
|
||||
|
||||
func _connect_signals() -> void:
|
||||
resume_btn.pressed.connect(_resume)
|
||||
loadouts_btn.pressed.connect(_show_loadouts)
|
||||
exit_btn.pressed.connect(_show_exit_dialog)
|
||||
back_to_main_btn.pressed.connect(_show_main_menu)
|
||||
save_loadout_btn.pressed.connect(_save_current_loadout)
|
||||
quit_dialog.confirmed.connect(_quit_game)
|
||||
|
||||
func _show_main_menu() -> void:
|
||||
main_vbox.visible = true
|
||||
loadout_editor.visible = false
|
||||
|
||||
func _show_loadouts() -> void:
|
||||
main_vbox.visible = false
|
||||
loadout_editor.visible = true
|
||||
edit_panel.visible = false
|
||||
_populate_loadout_list()
|
||||
|
||||
func _populate_loadout_list() -> void:
|
||||
for c in loadout_list_vbox.get_children():
|
||||
c.queue_free()
|
||||
|
||||
for i in range(LoadoutManager.loadouts.size()):
|
||||
var l = LoadoutManager.loadouts[i]
|
||||
var hbox = HBoxContainer.new()
|
||||
|
||||
var btn = Button.new()
|
||||
var is_active = (i == LoadoutManager.active_loadout_index)
|
||||
btn.text = l["name"] + (" (Active)" if is_active else "")
|
||||
btn.custom_minimum_size = Vector2(200, 40)
|
||||
btn.pressed.connect(func(): _edit_loadout(i))
|
||||
hbox.add_child(btn)
|
||||
|
||||
var equip_btn = Button.new()
|
||||
equip_btn.text = "Equip"
|
||||
equip_btn.disabled = is_active
|
||||
equip_btn.pressed.connect(func(): _equip_loadout(i))
|
||||
hbox.add_child(equip_btn)
|
||||
|
||||
loadout_list_vbox.add_child(hbox)
|
||||
|
||||
func _equip_loadout(idx: int) -> void:
|
||||
LoadoutManager.active_loadout_index = idx
|
||||
LoadoutManager.save_loadouts()
|
||||
_populate_loadout_list()
|
||||
|
||||
func _edit_loadout(idx: int) -> void:
|
||||
editing_index = idx
|
||||
var l = LoadoutManager.loadouts[idx]
|
||||
name_edit.text = l["name"]
|
||||
|
||||
_populate_options(primary1_opt, "primary", l["primary_1"])
|
||||
_populate_options(primary2_opt, "primary", l["primary_2"])
|
||||
_populate_options(special_opt, "special", l["special"])
|
||||
|
||||
edit_panel.visible = true
|
||||
|
||||
func _populate_options(opt: OptionButton, category: String, current_id: String) -> void:
|
||||
opt.clear()
|
||||
var idx = 0
|
||||
var select_idx = 0
|
||||
|
||||
# Always add "none" as first option
|
||||
opt.add_item("None", 0)
|
||||
opt.set_item_metadata(0, "none")
|
||||
if current_id == "none": select_idx = 0
|
||||
idx += 1
|
||||
|
||||
for key in LoadoutManager.weapon_db:
|
||||
if key == "none": continue
|
||||
var w = LoadoutManager.weapon_db[key]
|
||||
if w["category"] == category:
|
||||
opt.add_item(w["name"], idx)
|
||||
opt.set_item_metadata(idx, key)
|
||||
if key == current_id:
|
||||
select_idx = idx
|
||||
idx += 1
|
||||
|
||||
opt.select(select_idx)
|
||||
|
||||
func _save_current_loadout() -> void:
|
||||
if editing_index >= 0 and editing_index < LoadoutManager.loadouts.size():
|
||||
var l = LoadoutManager.loadouts[editing_index]
|
||||
l["name"] = name_edit.text
|
||||
l["primary_1"] = primary1_opt.get_item_metadata(primary1_opt.get_selected_id())
|
||||
l["primary_2"] = primary2_opt.get_item_metadata(primary2_opt.get_selected_id())
|
||||
l["special"] = special_opt.get_item_metadata(special_opt.get_selected_id())
|
||||
LoadoutManager.save_loadouts()
|
||||
_populate_loadout_list()
|
||||
edit_panel.visible = false
|
||||
|
||||
func _show_exit_dialog() -> void:
|
||||
quit_dialog.popup_centered()
|
||||
|
||||
func _quit_game() -> void:
|
||||
get_tree().quit()
|
||||
Reference in New Issue
Block a user