cirnogodot/addons/weapon_creator/ItemCreatorDialog.gd

357 lines
11 KiB
GDScript

@tool
extends BaseCreatorDialog
# Dialog for creating new items
# Provides input fields for all item properties
signal item_data_confirmed(item_data: Dictionary)
# UI elements
var _item_name_edit: LineEdit
var _item_key_edit: LineEdit
var _short_name_edit: LineEdit
var _description_edit: TextEdit
var _sprite_picker: EditorResourcePicker
var _sprite_preview: TextureRect
var _selected_sprite: Texture2D = null
var _item_type_option: OptionButton
var _tier_spin: SpinBox
var _price_spin: SpinBox
var _amount_spin: SpinBox
var _max_spin: SpinBox
var _pickup_if_maxed_check: CheckBox
var _consume_on_use_check: CheckBox
var _selectable_check: CheckBox
const ITEM_TYPE_NAMES = [
"KeycardRed",
"KeycardBlue",
"KeycardGreen",
"Ammo",
"Medkit",
"FrogBomb",
"Bomb",
"Mine",
"Battery",
"Weapon",
"Power",
"Points",
"Credits",
"KeyItem"
]
func _configure_window() -> void:
size = settings.get("item_dialog_size") if settings else Vector2i(750, 850)
transient = false
exclusive = false
unresizable = false
func _update_title() -> void:
var action_text = "Duplicate" if not prefill_data.is_empty() else "Create New"
title = action_text + " Item"
func _get_saved_position() -> Vector2i:
if settings:
var pos = settings.get("item_dialog_position")
return pos if pos else Vector2i.ZERO
return Vector2i.ZERO
func _save_dialog_size() -> void:
if settings:
settings.set("item_dialog_size", size)
settings.call("save_settings")
func _save_dialog_position() -> void:
if settings:
settings.set("item_dialog_position", position)
settings.call("save_settings")
func _build_content(container: VBoxContainer) -> void:
_build_basic_info_section(container)
_build_properties_section(container)
func _build_buttons(parent: VBoxContainer) -> void:
var button_hbox = HBoxContainer.new()
button_hbox.alignment = BoxContainer.ALIGNMENT_CENTER
button_hbox.add_theme_constant_override("separation", 8)
parent.add_child(button_hbox)
var cancel_button = Button.new()
cancel_button.text = "Cancel"
cancel_button.custom_minimum_size = Vector2(100, 0)
cancel_button.pressed.connect(_on_cancel_pressed)
button_hbox.add_child(cancel_button)
var create_button = Button.new()
create_button.text = "Create"
create_button.custom_minimum_size = Vector2(100, 0)
create_button.pressed.connect(_on_create_pressed)
button_hbox.add_child(create_button)
func _build_basic_info_section(content_vbox: VBoxContainer) -> void:
# Basic Info Section
content_vbox.add_child(_create_section_label("Basic Information"))
var name_input = _create_input("Item Name:")
content_vbox.add_child(name_input["container"])
_item_name_edit = name_input["edit"]
var key_input = _create_input("Item Key:")
content_vbox.add_child(key_input["container"])
_item_key_edit = key_input["edit"]
var short_name_input = _create_input("Short Name:")
content_vbox.add_child(short_name_input["container"])
_short_name_edit = short_name_input["edit"]
var desc_label = Label.new()
desc_label.text = "Description:"
content_vbox.add_child(desc_label)
_description_edit = TextEdit.new()
_description_edit.custom_minimum_size = Vector2(0, 60)
_description_edit.wrap_mode = TextEdit.LINE_WRAPPING_BOUNDARY
content_vbox.add_child(_description_edit)
content_vbox.add_child(HSeparator.new())
# Sprite Section
var sprite_label = Label.new()
sprite_label.text = "Inventory Sprite"
sprite_label.add_theme_font_size_override("font_size", 14)
content_vbox.add_child(sprite_label)
var sprite_container = HBoxContainer.new()
sprite_container.add_theme_constant_override("separation", 8)
content_vbox.add_child(sprite_container)
# Left side: Label and resource picker
var left_vbox = VBoxContainer.new()
left_vbox.size_flags_horizontal = Control.SIZE_EXPAND_FILL
left_vbox.add_theme_constant_override("separation", 4)
sprite_container.add_child(left_vbox)
var picker_hbox = HBoxContainer.new()
picker_hbox.add_theme_constant_override("separation", 4)
left_vbox.add_child(picker_hbox)
var picker_label = Label.new()
picker_label.text = "Sprite:"
picker_label.custom_minimum_size = Vector2(120, 0)
picker_hbox.add_child(picker_label)
_sprite_picker = EditorResourcePicker.new()
_sprite_picker.base_type = "Texture2D"
_sprite_picker.editable = true
_sprite_picker.size_flags_horizontal = Control.SIZE_EXPAND_FILL
_sprite_picker.resource_changed.connect(_on_sprite_resource_changed)
_sprite_picker.resource_selected.connect(_on_resource_picker_opening)
picker_hbox.add_child(_sprite_picker)
if editor_interface:
_setup_sprite_picker()
# Right side: Preview
var preview_container = PanelContainer.new()
preview_container.custom_minimum_size = Vector2(64, 64)
sprite_container.add_child(preview_container)
_sprite_preview = TextureRect.new()
_sprite_preview.custom_minimum_size = Vector2(64, 64)
_sprite_preview.expand_mode = TextureRect.EXPAND_FIT_WIDTH_PROPORTIONAL
_sprite_preview.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
preview_container.add_child(_sprite_preview)
func _build_properties_section(content_vbox: VBoxContainer) -> void:
content_vbox.add_child(HSeparator.new())
# Properties Section
var properties_label = Label.new()
properties_label.text = "Properties"
properties_label.add_theme_font_size_override("font_size", 16)
content_vbox.add_child(properties_label)
var type_hbox = HBoxContainer.new()
content_vbox.add_child(type_hbox)
var type_label = Label.new()
type_label.text = "Item Type:"
type_label.custom_minimum_size = Vector2(120, 0)
type_hbox.add_child(type_label)
_item_type_option = OptionButton.new()
_item_type_option.size_flags_horizontal = Control.SIZE_EXPAND_FILL
for item_type in ITEM_TYPE_NAMES:
_item_type_option.add_item(item_type)
type_hbox.add_child(_item_type_option)
var tier_spin = _create_spinbox("Tier:", 0, 0, 100, 1)
content_vbox.add_child(tier_spin["container"])
_tier_spin = tier_spin["spinbox"]
var price_spin = _create_spinbox("Price:", 0, 0, 999999, 1)
content_vbox.add_child(price_spin["container"])
_price_spin = price_spin["spinbox"]
var amount_spin = _create_spinbox("Amount:", 1, 0, 999999, 1)
content_vbox.add_child(amount_spin["container"])
_amount_spin = amount_spin["spinbox"]
var max_spin = _create_spinbox("Max:", 1, 0, 999999, 1)
content_vbox.add_child(max_spin["container"])
_max_spin = max_spin["spinbox"]
_pickup_if_maxed_check = CheckBox.new()
_pickup_if_maxed_check.text = "Pickup If Maxed"
content_vbox.add_child(_pickup_if_maxed_check)
_consume_on_use_check = CheckBox.new()
_consume_on_use_check.text = "Consume On Use"
content_vbox.add_child(_consume_on_use_check)
_selectable_check = CheckBox.new()
_selectable_check.text = "Selectable"
content_vbox.add_child(_selectable_check)
func _apply_prefill_data() -> void:
if prefill_data.is_empty():
return
if prefill_data.has("item_name"):
_item_name_edit.text = str(prefill_data["item_name"])
if prefill_data.has("item_key"):
_item_key_edit.text = str(prefill_data["item_key"])
if prefill_data.has("short_name"):
_short_name_edit.text = str(prefill_data["short_name"])
if prefill_data.has("description"):
_description_edit.text = str(prefill_data["description"])
if prefill_data.has("sprite_resource") and prefill_data["sprite_resource"] != null:
_selected_sprite = prefill_data["sprite_resource"]
_sprite_preview.texture = _selected_sprite
_sprite_picker.edited_resource = _selected_sprite
if prefill_data.has("item_type"):
_item_type_option.selected = int(prefill_data["item_type"])
if prefill_data.has("tier"):
_tier_spin.value = int(prefill_data["tier"])
if prefill_data.has("price"):
_price_spin.value = int(prefill_data["price"])
if prefill_data.has("amount"):
_amount_spin.value = int(prefill_data["amount"])
if prefill_data.has("max"):
_max_spin.value = int(prefill_data["max"])
if prefill_data.has("pickup_if_maxed"):
_pickup_if_maxed_check.button_pressed = bool(prefill_data["pickup_if_maxed"])
if prefill_data.has("consume_on_use"):
_consume_on_use_check.button_pressed = bool(prefill_data["consume_on_use"])
if prefill_data.has("selectable"):
_selectable_check.button_pressed = bool(prefill_data["selectable"])
func _on_sprite_resource_changed(resource: Resource) -> void:
if resource is Texture2D:
_selected_sprite = resource
_sprite_preview.texture = resource
print("Sprite resource changed: ", resource.resource_path if resource.resource_path else "[Unsaved Resource]")
elif resource == null:
_selected_sprite = null
_sprite_preview.texture = null
print("Sprite resource cleared")
else:
push_warning("Selected resource is not a Texture2D")
call_deferred("_restore_window_focus")
func _on_resource_picker_opening(_resource: Resource, _inspect: bool) -> void:
pass
func _restore_window_focus() -> void:
if visible:
move_to_foreground()
func _setup_sprite_picker() -> void:
if _sprite_picker and editor_interface:
_sprite_picker.toggle_mode = false
func _on_create_pressed() -> void:
var item_name = _item_name_edit.text.strip_edges()
var item_key = _item_key_edit.text.strip_edges()
if item_name.is_empty():
_show_error("Item Name cannot be empty")
return
if item_key.is_empty():
_show_error("Item Key cannot be empty")
return
var item_data = {
"item_name": item_name,
"item_key": item_key,
"short_name": _short_name_edit.text.strip_edges(),
"description": _description_edit.text,
"sprite_resource": _selected_sprite,
"item_type": _item_type_option.selected,
"tier": int(_tier_spin.value),
"price": int(_price_spin.value),
"amount": int(_amount_spin.value),
"max": int(_max_spin.value),
"pickup_if_maxed": _pickup_if_maxed_check.button_pressed,
"consume_on_use": _consume_on_use_check.button_pressed,
"selectable": _selectable_check.button_pressed
}
_save_dialog_size()
item_data_confirmed.emit(item_data)
queue_free()
func _on_cancel_pressed() -> void:
_save_dialog_size()
queue_free()
func _show_error(message: String) -> void:
var dialog = AcceptDialog.new()
dialog.dialog_text = message
dialog.title = "Error"
add_child(dialog)
dialog.popup_centered()
dialog.confirmed.connect(func(): dialog.queue_free())
# Helper methods
func _create_input(label_text: String) -> Dictionary:
var hbox = HBoxContainer.new()
var label = Label.new()
label.text = label_text
label.custom_minimum_size = Vector2(120, 0)
hbox.add_child(label)
var edit = LineEdit.new()
edit.size_flags_horizontal = Control.SIZE_EXPAND_FILL
hbox.add_child(edit)
return {"container": hbox, "edit": edit}
func _create_spinbox(label_text: String, default_value: float, min_value: float, max_value: float, step: float) -> Dictionary:
var hbox = HBoxContainer.new()
var label = Label.new()
label.text = label_text
label.custom_minimum_size = Vector2(120, 0)
hbox.add_child(label)
var spinbox = SpinBox.new()
spinbox.min_value = min_value
spinbox.max_value = max_value
spinbox.step = step
spinbox.value = default_value
spinbox.size_flags_horizontal = Control.SIZE_EXPAND_FILL
hbox.add_child(spinbox)
return {"container": hbox, "spinbox": spinbox}
func _create_section_label(text: String) -> Label:
var label = Label.new()
label.text = text
label.add_theme_font_size_override("font_size", 16)
return label