mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-01 10:15:45 +00:00
179 lines
5.9 KiB
GDScript3
179 lines
5.9 KiB
GDScript3
|
|
@tool
|
|||
|
|
extends PanelContainer
|
|||
|
|
|
|||
|
|
# Displays all weapons from the ItemsDatabase in a grid format
|
|||
|
|
# Shows sprite and name, with tooltip showing resource path
|
|||
|
|
# Clicking opens the weapon resource in the inspector
|
|||
|
|
|
|||
|
|
signal weapon_selected(weapon_resource_path: String)
|
|||
|
|
|
|||
|
|
var _editor_interface: EditorInterface
|
|||
|
|
var _grid_container: HFlowContainer
|
|||
|
|
var _items_database_path := "res://Resources/ItemsDatabase.tres"
|
|||
|
|
|
|||
|
|
func setup(editor_interface: EditorInterface) -> void:
|
|||
|
|
_editor_interface = editor_interface
|
|||
|
|
|
|||
|
|
func _ready() -> void:
|
|||
|
|
_build_ui()
|
|||
|
|
refresh_weapons()
|
|||
|
|
|
|||
|
|
func _build_ui() -> void:
|
|||
|
|
# Main margin container
|
|||
|
|
var margin = MarginContainer.new()
|
|||
|
|
margin.add_theme_constant_override("margin_left", 8)
|
|||
|
|
margin.add_theme_constant_override("margin_top", 8)
|
|||
|
|
margin.add_theme_constant_override("margin_right", 8)
|
|||
|
|
margin.add_theme_constant_override("margin_bottom", 8)
|
|||
|
|
add_child(margin)
|
|||
|
|
|
|||
|
|
# Main vbox
|
|||
|
|
var vbox = VBoxContainer.new()
|
|||
|
|
vbox.add_theme_constant_override("separation", 8)
|
|||
|
|
margin.add_child(vbox)
|
|||
|
|
|
|||
|
|
# Header with title and refresh button
|
|||
|
|
var header_hbox = HBoxContainer.new()
|
|||
|
|
vbox.add_child(header_hbox)
|
|||
|
|
|
|||
|
|
var title = Label.new()
|
|||
|
|
title.text = "Weapons"
|
|||
|
|
title.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
|||
|
|
header_hbox.add_child(title)
|
|||
|
|
|
|||
|
|
var refresh_button = Button.new()
|
|||
|
|
refresh_button.text = "Refresh"
|
|||
|
|
refresh_button.pressed.connect(refresh_weapons)
|
|||
|
|
header_hbox.add_child(refresh_button)
|
|||
|
|
|
|||
|
|
vbox.add_child(HSeparator.new())
|
|||
|
|
|
|||
|
|
# Scroll container for grid
|
|||
|
|
var scroll = ScrollContainer.new()
|
|||
|
|
scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
|||
|
|
scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
|
|||
|
|
vbox.add_child(scroll)
|
|||
|
|
|
|||
|
|
# Flow container for responsive wrapping
|
|||
|
|
_grid_container = HFlowContainer.new()
|
|||
|
|
_grid_container.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
|||
|
|
_grid_container.add_theme_constant_override("h_separation", 8)
|
|||
|
|
_grid_container.add_theme_constant_override("v_separation", 8)
|
|||
|
|
scroll.add_child(_grid_container)
|
|||
|
|
|
|||
|
|
func refresh_weapons() -> void:
|
|||
|
|
if not _grid_container:
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
# Clear existing items
|
|||
|
|
for child in _grid_container.get_children():
|
|||
|
|
child.queue_free()
|
|||
|
|
|
|||
|
|
# Load ItemsDatabase
|
|||
|
|
if not ResourceLoader.exists(_items_database_path):
|
|||
|
|
_add_error_label("ItemsDatabase not found at: " + _items_database_path)
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
var items_database = load(_items_database_path)
|
|||
|
|
if items_database == null:
|
|||
|
|
_add_error_label("Failed to load ItemsDatabase")
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
var loot_items = items_database.get("LootItems")
|
|||
|
|
if loot_items == null:
|
|||
|
|
_add_error_label("No LootItems found in database")
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
# Filter for weapons only (items with WeaponData3D)
|
|||
|
|
var weapon_count = 0
|
|||
|
|
for loot_item in loot_items:
|
|||
|
|
var weapon_data = loot_item.get("WeaponData3D")
|
|||
|
|
if weapon_data != null:
|
|||
|
|
_create_weapon_tile(loot_item, weapon_data)
|
|||
|
|
weapon_count += 1
|
|||
|
|
|
|||
|
|
if weapon_count == 0:
|
|||
|
|
_add_error_label("No weapons found in database")
|
|||
|
|
|
|||
|
|
func _create_weapon_tile(loot_item: Resource, weapon_data: Resource) -> void:
|
|||
|
|
var button = Button.new()
|
|||
|
|
button.custom_minimum_size = Vector2(100, 110)
|
|||
|
|
button.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
|
|||
|
|
button.size_flags_vertical = Control.SIZE_SHRINK_BEGIN
|
|||
|
|
|
|||
|
|
var vbox = VBoxContainer.new()
|
|||
|
|
vbox.add_theme_constant_override("separation", 2)
|
|||
|
|
vbox.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|||
|
|
|
|||
|
|
var sprite: Texture2D = loot_item.get("InventorySprite")
|
|||
|
|
|
|||
|
|
var texture_rect = TextureRect.new()
|
|||
|
|
texture_rect.custom_minimum_size = Vector2(64, 64)
|
|||
|
|
texture_rect.expand_mode = TextureRect.EXPAND_FIT_WIDTH_PROPORTIONAL
|
|||
|
|
texture_rect.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
|
|||
|
|
texture_rect.texture_filter = CanvasItem.TEXTURE_FILTER_NEAREST
|
|||
|
|
texture_rect.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|||
|
|
|
|||
|
|
if sprite:
|
|||
|
|
texture_rect.texture = sprite
|
|||
|
|
vbox.add_child(texture_rect)
|
|||
|
|
else:
|
|||
|
|
var placeholder_label = Label.new()
|
|||
|
|
placeholder_label.text = "No Icon"
|
|||
|
|
placeholder_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|||
|
|
placeholder_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
|||
|
|
placeholder_label.custom_minimum_size = Vector2(64, 64)
|
|||
|
|
placeholder_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|||
|
|
placeholder_label.add_theme_font_size_override("font_size", 10)
|
|||
|
|
vbox.add_child(placeholder_label)
|
|||
|
|
|
|||
|
|
var name_label = Label.new()
|
|||
|
|
var item_name: String = loot_item.get("ItemName")
|
|||
|
|
name_label.text = item_name if item_name else "Unknown"
|
|||
|
|
name_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|||
|
|
name_label.vertical_alignment = VERTICAL_ALIGNMENT_TOP
|
|||
|
|
name_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
|||
|
|
name_label.custom_minimum_size = Vector2(90, 0)
|
|||
|
|
name_label.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
|||
|
|
name_label.clip_text = true
|
|||
|
|
name_label.max_lines_visible = 2
|
|||
|
|
name_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|||
|
|
name_label.add_theme_font_size_override("font_size", 11)
|
|||
|
|
name_label.add_theme_constant_override("line_spacing", -2)
|
|||
|
|
vbox.add_child(name_label)
|
|||
|
|
|
|||
|
|
button.add_child(vbox)
|
|||
|
|
vbox.set_anchors_preset(Control.PRESET_FULL_RECT)
|
|||
|
|
vbox.add_theme_constant_override("margin_left", 4)
|
|||
|
|
vbox.add_theme_constant_override("margin_top", 4)
|
|||
|
|
vbox.add_theme_constant_override("margin_right", 4)
|
|||
|
|
vbox.add_theme_constant_override("margin_bottom", 4)
|
|||
|
|
|
|||
|
|
var weapon_path = weapon_data.resource_path
|
|||
|
|
if weapon_path:
|
|||
|
|
button.tooltip_text = weapon_path
|
|||
|
|
else:
|
|||
|
|
button.tooltip_text = "Built-in resource (no file path)"
|
|||
|
|
|
|||
|
|
button.pressed.connect(_on_weapon_clicked.bind(weapon_data, weapon_path))
|
|||
|
|
|
|||
|
|
_grid_container.add_child(button)
|
|||
|
|
|
|||
|
|
func _on_weapon_clicked(weapon_data: Resource, weapon_path: String) -> void:
|
|||
|
|
if not _editor_interface:
|
|||
|
|
push_error("Editor interface not available")
|
|||
|
|
return
|
|||
|
|
|
|||
|
|
# Select the weapon resource in the inspector
|
|||
|
|
if weapon_data:
|
|||
|
|
_editor_interface.edit_resource(weapon_data)
|
|||
|
|
_editor_interface.get_inspector().set_current_tab(0)
|
|||
|
|
weapon_selected.emit(weapon_path)
|
|||
|
|
|
|||
|
|
func _add_error_label(error_message: String) -> void:
|
|||
|
|
var label = Label.new()
|
|||
|
|
label.text = error_message
|
|||
|
|
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|||
|
|
label.modulate = Color.ORANGE_RED
|
|||
|
|
_grid_container.add_child(label)
|
|||
|
|
|