Add enemy creation and viewer functionality with filtering options

This commit is contained in:
MaddoScientisto 2026-02-26 21:58:48 +01:00
commit 18683c0680
32 changed files with 1009 additions and 411 deletions

View file

@ -1,5 +1,5 @@
@tool
extends PanelContainer
extends BaseViewer
# Displays all items from the ItemsDatabase in a grid format
# Shows sprite, name, and item type badge
@ -10,13 +10,8 @@ signal duplicate_item_requested(item_data: Dictionary)
signal item_deleted(item_name: String, item_path: String)
signal item_duplication_started(item_name: String)
var _editor_interface: EditorInterface
var _grid_container: HFlowContainer
var _items_database_path := "res://Resources/ItemsDatabase.tres"
var _show_2d_checkbox: CheckBox
var _show_3d_checkbox: CheckBox
var _show_neither_checkbox: CheckBox
var _dock: PanelContainer
const SETTING_SHOW_2D = "weapon_creator/item_filter_show_2d"
const SETTING_SHOW_3D = "weapon_creator/item_filter_show_3d"
@ -57,90 +52,49 @@ const ITEM_TYPE_NAMES = [
"KeyItem"
]
func setup(editor_interface: EditorInterface, dock: PanelContainer = null) -> void:
_editor_interface = editor_interface
_dock = dock
if _show_2d_checkbox:
_show_2d_checkbox.button_pressed = _load_filter_setting(SETTING_SHOW_2D, true)
if _show_3d_checkbox:
_show_3d_checkbox.button_pressed = _load_filter_setting(SETTING_SHOW_3D, true)
if _show_neither_checkbox:
_show_neither_checkbox.button_pressed = _load_filter_setting(SETTING_SHOW_NEITHER, true)
refresh_items()
func _supports_2d_3d_filter() -> bool:
return true
func _ready() -> void:
_build_ui()
refresh_items()
func _get_filter_setting_2d_key() -> String:
return SETTING_SHOW_2D
func _get_filter_setting_3d_key() -> String:
return SETTING_SHOW_3D
# Override to add the "Neither" checkbox
func _build_ui() -> void:
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)
super._build_ui()
var vbox = VBoxContainer.new()
vbox.add_theme_constant_override("separation", 8)
margin.add_child(vbox)
# Find the header_hbox and add the Neither checkbox after 3D checkbox
var margin = get_child(0) as MarginContainer
var vbox = margin.get_child(0) as VBoxContainer
var header_hbox = vbox.get_child(0) as HBoxContainer
var header_hbox = HBoxContainer.new()
vbox.add_child(header_hbox)
# The refresh button is the last child, so insert before it
var refresh_button = header_hbox.get_child(header_hbox.get_child_count() - 1)
_show_neither_checkbox = CheckBox.new()
_show_neither_checkbox.text = "Neither"
_show_neither_checkbox.button_pressed = _load_filter_setting(SETTING_SHOW_NEITHER, true)
_show_neither_checkbox.toggled.connect(_on_filter_changed)
_show_neither_checkbox.tooltip_text = "Show items that don't have 2D or 3D properties set"
header_hbox.add_child(_show_neither_checkbox)
header_hbox.move_child(_show_neither_checkbox, header_hbox.get_child_count() - 2)
func _build_header_buttons(header_hbox: HBoxContainer) -> void:
var create_button = Button.new()
create_button.text = "Create Item"
create_button.pressed.connect(_on_create_item_pressed)
header_hbox.add_child(create_button)
var spacer = Control.new()
spacer.size_flags_horizontal = Control.SIZE_EXPAND_FILL
header_hbox.add_child(spacer)
_show_2d_checkbox = CheckBox.new()
_show_2d_checkbox.text = "2D"
_show_2d_checkbox.button_pressed = true
_show_2d_checkbox.toggled.connect(_on_filter_changed)
header_hbox.add_child(_show_2d_checkbox)
_show_3d_checkbox = CheckBox.new()
_show_3d_checkbox.text = "3D"
_show_3d_checkbox.button_pressed = true
_show_3d_checkbox.toggled.connect(_on_filter_changed)
header_hbox.add_child(_show_3d_checkbox)
_show_neither_checkbox = CheckBox.new()
_show_neither_checkbox.text = "Neither"
_show_neither_checkbox.button_pressed = true
_show_neither_checkbox.toggled.connect(_on_filter_changed)
_show_neither_checkbox.tooltip_text = "Show items that don't have 2D or 3D properties set"
header_hbox.add_child(_show_neither_checkbox)
var refresh_button = Button.new()
refresh_button.text = "Refresh"
refresh_button.pressed.connect(refresh_items)
header_hbox.add_child(refresh_button)
vbox.add_child(HSeparator.new())
var scroll = ScrollContainer.new()
scroll.size_flags_vertical = Control.SIZE_EXPAND_FILL
scroll.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
vbox.add_child(scroll)
_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_items() -> void:
if not _grid_container:
return
func setup(editor_interface: EditorInterface, dock: PanelContainer = null) -> void:
super.setup(editor_interface, dock)
for child in _grid_container.get_children():
child.queue_free()
if _show_neither_checkbox:
_show_neither_checkbox.button_pressed = _load_filter_setting(SETTING_SHOW_NEITHER, true)
func refresh() -> void:
_clear_grid()
if not ResourceLoader.exists(_items_database_path):
_add_error_label("ItemsDatabase not found at: " + _items_database_path)
@ -156,8 +110,8 @@ func refresh_items() -> void:
_add_error_label("No LootItems found in database")
return
var show_2d = _show_2d_checkbox == null or _show_2d_checkbox.button_pressed
var show_3d = _show_3d_checkbox == null or _show_3d_checkbox.button_pressed
var show_2d = _should_show_2d()
var show_3d = _should_show_3d()
var show_neither = _show_neither_checkbox == null or _show_neither_checkbox.button_pressed
var item_count = 0
@ -180,7 +134,7 @@ func refresh_items() -> void:
item_count += 1
if item_count == 0:
_add_error_label("No items match the current filter")
_add_info_label("No items match current filters")
func _item_has_2d(loot_item: Resource) -> bool:
var weapon_data = loot_item.get("WeaponData")
@ -192,25 +146,14 @@ func _item_has_3d(loot_item: Resource) -> bool:
var drop_scene_3d = loot_item.get("DropScenePath3D")
return weapon_data_3d != null or (drop_scene_3d != null and drop_scene_3d != "")
func _on_filter_changed(_toggled: bool) -> void:
_save_filter_settings()
refresh_items()
func _load_filter_setting(key: String, default_value: bool) -> bool:
if not _editor_interface:
return default_value
var editor_settings = _editor_interface.get_editor_settings()
if editor_settings and editor_settings.has_setting(key):
return editor_settings.get_setting(key)
return default_value
# Override to save the Neither checkbox setting
func _save_filter_settings() -> void:
super._save_filter_settings()
if not _editor_interface:
return
var editor_settings = _editor_interface.get_editor_settings()
if editor_settings:
editor_settings.set_setting(SETTING_SHOW_2D, _show_2d_checkbox.button_pressed)
editor_settings.set_setting(SETTING_SHOW_3D, _show_3d_checkbox.button_pressed)
if editor_settings and _show_neither_checkbox:
editor_settings.set_setting(SETTING_SHOW_NEITHER, _show_neither_checkbox.button_pressed)
func _create_item_tile(loot_item: Resource, has_2d: bool, has_3d: bool) -> void:
@ -416,10 +359,9 @@ func _duplicate_item(loot_item: Resource) -> void:
var item_name = loot_item.get("ItemName") if loot_item else "Unknown"
if _dock:
_dock.call("add_log", "=== Duplicating Item ===", Color.CYAN)
_dock.call("add_log", "Source: " + item_name, Color.CYAN)
_dock.call("add_log", "Opening creation dialog with prefilled data...", Color.CYAN)
_log_to_dock("=== Duplicating Item ===", Color.CYAN)
_log_to_dock("Source: " + item_name, Color.CYAN)
_log_to_dock("Opening creation dialog with prefilled data...", Color.CYAN)
print("Duplicating item: ", item_name)
@ -454,7 +396,7 @@ func _duplicate_item(loot_item: Resource) -> void:
func _on_duplicate_item_confirmed(item_data: Dictionary) -> void:
duplicate_item_requested.emit(item_data)
get_tree().create_timer(0.5).timeout.connect(refresh_items)
get_tree().create_timer(0.5).timeout.connect(refresh)
func _copy_item_resource_path(loot_item: Resource) -> void:
if loot_item and loot_item.resource_path:
@ -540,14 +482,7 @@ func _perform_delete(loot_item: Resource, dialog: ConfirmationDialog) -> void:
_dock.call("add_log", "✓ Removed from ItemsDatabase", Color.GREEN)
_dock.call("add_log", "Note: Linked assets were NOT deleted", Color.YELLOW)
refresh_items()
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)
refresh()
func _on_create_item_pressed() -> void:
if not _editor_interface: