summaryrefslogtreecommitdiff
path: root/addons/escoria-wizard/item_creator.gd
diff options
context:
space:
mode:
authorRadio <radiohotline@disroot.org>2026-06-04 15:15:11 +0300
committerRadio <radiohotline@disroot.org>2026-06-04 15:15:11 +0300
commit9d74b49ab62908d4acf53dde444413886b8b28e5 (patch)
tree0cb785267ea7e239b19d88684c0d64b9bd5d52f0 /addons/escoria-wizard/item_creator.gd
parent2c85d452ad02a5f89cd43bad7f9de31d0e4fa0c1 (diff)
escoria setup and old branch archives
Diffstat (limited to 'addons/escoria-wizard/item_creator.gd')
-rw-r--r--addons/escoria-wizard/item_creator.gd318
1 files changed, 318 insertions, 0 deletions
diff --git a/addons/escoria-wizard/item_creator.gd b/addons/escoria-wizard/item_creator.gd
new file mode 100644
index 0000000..6a279b8
--- /dev/null
+++ b/addons/escoria-wizard/item_creator.gd
@@ -0,0 +1,318 @@
+@tool
+extends MarginContainer
+
+
+const ITEM_NAME_NODE = "VBoxContainer/Content/GridContainer/ItemName"
+const GLOBAL_ID_NODE = "VBoxContainer/Content/GridContainer/ItemGlobalID"
+const INTERACTIVE_NODE = "VBoxContainer/Content/GridContainer/StartsInteractiveCheckBox"
+const ACTION_NODE = "VBoxContainer/Content/GridContainer/DefaultActionOption"
+const PREVIEW_NODE = "VBoxContainer/Content/GridContainer/Preview/Preview"
+const IMAGE_SIZE_NODE = "VBoxContainer/Content/GridContainer/ImageSize"
+const IMAGE_PATH_NODE = "VBoxContainer/Content/GridContainer/ImagePath"
+const LOAD_NODE = "LoadObjectGraphic/LoadObjectFileDialog"
+const CONFIRM_NODE = "Windows/ConfirmationDialog"
+const OBJECT_HEADING_NODE = "VBoxContainer/HelperHeading/CenterContainer/ObjectHeading"
+const OBJECT_DESC_NODE = "VBoxContainer/Description/ObjectDescription"
+const INVENTORY_HEADING_NODE = "VBoxContainer/HelperHeading/CenterContainer/InventoryHeading"
+const INVENTORY_DESC_NODE = "VBoxContainer/Description/InventoryDescription"
+const INVENTORY_PATH_NODE = "VBoxContainer/Content/GridContainer/InventoryPath"
+const INVENTORY_PATH_LABEL_NODE = "VBoxContainer/Content/GridContainer/InventoryPathLabel"
+const INVENTORY_PATH_SPACER_NODE = "VBoxContainer/Content/GridContainer/BlankItem7"
+const CREATE_BUTTON_NODE = "VBoxContainer/Buttons/CenterContainer/HBoxContainer/CreateButton"
+const ERROR_WINDOW_NODE = "Windows/ErrorDialog"
+const INVENTORY_PREV_NODE = "VBoxContainer/Content/GridContainer/Preview/InventoryPreview"
+const OBJECT_PREV_NODE = "VBoxContainer/Content/GridContainer/Preview/ObjectPreview"
+const BACKGROUND_OBJ_NODE = "VBoxContainer/Control/CenterContainer/HBoxContainer/BackgroundObjectCheckBox"
+const CHANGE_PATH_NODE = "VBoxContainer/Content/GridContainer/ChangePathButton"
+
+var source_image:Image
+var image_stream_texture:CompressedTexture2D
+var image_has_been_loaded:bool
+var image_size:Vector2
+var main_menu_requested:bool
+var inventory_mode:bool
+var settings_modified:bool
+var preview_size:Vector2
+
+
+# Called when the node enters the scene tree for the first time.
+func _ready() -> void:
+ # Capture the size of the window before we update its contents so we have
+ # the absolute size before it gets scaled contents applied to it
+ preview_size = get_node(PREVIEW_NODE).size
+ inventory_mode = not get_node(BACKGROUND_OBJ_NODE).pressed
+ item_creator_reset()
+
+
+func item_creator_reset() -> void:
+ get_node(ITEM_NAME_NODE).text = "replace_me"
+ get_node(GLOBAL_ID_NODE).text = ""
+ get_node(IMAGE_PATH_NODE).text = ""
+ get_node(INTERACTIVE_NODE).button_pressed = true
+
+ if get_node(ACTION_NODE).get_item_count() > 0:
+ get_node(ACTION_NODE).clear()
+
+ for option_list in ["look", "pick up", "open", "close", "use", "push", "pull", "talk"]:
+ get_node(ACTION_NODE).add_item(option_list)
+
+ get_node(ACTION_NODE).selected = 0
+ image_size = Vector2.ZERO
+ image_has_been_loaded = false
+ main_menu_requested = false
+ settings_modified = false
+ get_node(PREVIEW_NODE).texture = null
+
+ if inventory_mode:
+ get_node(INVENTORY_PATH_NODE).text = ProjectSettings.get_setting("escoria/ui/inventory_items_path")
+ get_node(CREATE_BUTTON_NODE).text = "Create Inventory"
+ get_node(INVENTORY_PREV_NODE).visible = true
+ get_node(OBJECT_PREV_NODE).visible = false
+
+ for loop in [INVENTORY_PATH_NODE, INVENTORY_PATH_LABEL_NODE, INVENTORY_PATH_SPACER_NODE, \
+ CHANGE_PATH_NODE]:
+ get_node(loop).visible = true
+ else:
+ get_node(CREATE_BUTTON_NODE).text = "Create Object"
+ get_node(INVENTORY_PREV_NODE).visible = false
+ get_node(OBJECT_PREV_NODE).visible = true
+ for loop in [INVENTORY_PATH_NODE, INVENTORY_PATH_LABEL_NODE, INVENTORY_PATH_SPACER_NODE, \
+ CHANGE_PATH_NODE]:
+ get_node(loop).visible = false
+
+ for loop in [OBJECT_HEADING_NODE, OBJECT_DESC_NODE]:
+ get_node(loop).visible = not inventory_mode
+
+ for loop in [INVENTORY_HEADING_NODE, INVENTORY_DESC_NODE, INVENTORY_PATH_NODE]:
+ get_node(loop).visible = inventory_mode
+ $Windows/FileDialog.current_dir = ProjectSettings.get_setting("escoria/ui/inventory_items_path")
+
+func resize_image() -> void:
+ # Calculate the scale to make the preview as big as possible in the preview window depending on
+ # the height to width ratio of the frame
+ image_size = image_stream_texture.get_size()
+ var preview_scale = Vector2.ONE
+ preview_scale.x = preview_size.x / image_size.x
+ preview_scale.y = preview_size.y / image_size.y
+
+ if preview_scale.y > preview_scale.x:
+ get_node(PREVIEW_NODE).scale = Vector2(preview_scale.x, preview_scale.x)
+ else:
+ get_node(PREVIEW_NODE).scale = Vector2(preview_scale.y, preview_scale.y)
+
+func background_on_ItemName_text_changed(new_text: String) -> void:
+ get_node(GLOBAL_ID_NODE).text = new_text
+ settings_modified = true
+
+
+func load_button_pressed() -> void:
+ get_node(LOAD_NODE).popup_centered()
+
+
+func LoadObjectFileDialog_file_selected(path: String) -> void:
+ image_stream_texture = load(path)
+
+ get_node(PREVIEW_NODE).texture = image_stream_texture
+
+ resize_image()
+
+ get_node(IMAGE_SIZE_NODE).text = "(%s, %s)" % [image_size.x, image_size.y]
+
+ get_node(IMAGE_PATH_NODE).text = path
+ image_has_been_loaded = true
+ settings_modified = true
+ get_node(INVENTORY_PREV_NODE).visible = false
+ get_node(OBJECT_PREV_NODE).visible = false
+
+
+func _on_CreateButton_pressed() -> void:
+ var inventory_path = ProjectSettings.get_setting("escoria/ui/inventory_items_path")
+ if not DirAccess.dir_exists_absolute(inventory_path):
+ get_node(ERROR_WINDOW_NODE).dialog_text = \
+ "Folder %s does not exist. Please create or change the destination" % inventory_path
+ get_node(ERROR_WINDOW_NODE).popup_centered()
+ return
+
+ if not image_has_been_loaded:
+ get_node(ERROR_WINDOW_NODE).dialog_text = \
+ "No image has been loaded."
+ get_node(ERROR_WINDOW_NODE).popup_centered()
+ return
+
+ if get_node(ITEM_NAME_NODE).text == "replace_me":
+ get_node(ERROR_WINDOW_NODE).dialog_text = \
+ "Please change the object name."
+ get_node(ERROR_WINDOW_NODE).popup_centered()
+ return
+
+ if inventory_mode == false:
+ if not EditorPlugin.new().get_editor_interface().get_selection().get_selected_nodes():
+ get_node(ERROR_WINDOW_NODE).dialog_text = \
+ "Please select a node in the scene tree\nto attach the object to."
+ get_node(ERROR_WINDOW_NODE).popup_centered()
+ return
+
+ var item = ESCItem.new()
+ item.name = get_node(ITEM_NAME_NODE).text
+ item.global_id = get_node(GLOBAL_ID_NODE).text
+ item.is_interactive = get_node(INTERACTIVE_NODE).pressed
+ item.tooltip_name = get_node(ITEM_NAME_NODE).text
+
+ var selected_index = get_node(ACTION_NODE).selected
+ item.default_action = get_node(ACTION_NODE).get_item_text(selected_index)
+
+ # Make the item by default it's usable straight out of the inventory
+ if inventory_mode == true:
+ var new_pool_array: PackedStringArray = item.combine_when_selected_action_is_in
+ new_pool_array.append("use")
+ item.combine_when_selected_action_is_in = new_pool_array
+
+ # Add Dialog Position to the background item
+ var interact_position = ESCLocation.new()
+ interact_position.name = "interact_position"
+ interact_position.position.y = image_size.y * 2
+ item.add_child(interact_position)
+
+ # Add Collision shape to the background item
+ var rectangle_shape = RectangleShape2D.new()
+ var collision_shape = CollisionShape2D.new()
+
+ collision_shape.shape = rectangle_shape
+ collision_shape.shape.extents = image_size / 2
+ item.add_child(collision_shape)
+
+ # Add sprite to the background item
+ var item_sprite = Sprite2D.new()
+ item_sprite.texture = get_node(PREVIEW_NODE).texture
+ item.add_child(item_sprite)
+
+ if not inventory_mode:
+ # Create in scene tree
+ # Attach to currently selected node in scene tree
+ var current_node = EditorPlugin.new().get_editor_interface().get_selection().get_selected_nodes()[0]
+ current_node.add_child(item)
+ var owning_node = get_tree().edited_scene_root
+ item.set_owner(owning_node)
+ # Make it so all the nodes can be seen in the scene tree
+ collision_shape.set_owner(owning_node)
+ interact_position.set_owner(owning_node)
+ item_sprite.set_owner(owning_node)
+
+ get_node("Windows/CreateCompleteDialog").dialog_text = \
+ "Background object %s created.\n\n" % item + \
+ "Note that you can right-click the node in the\n" + \
+ "scene tree and select \"Save branch as scene\"\n" + \
+ "if you'd like to reuse this item."
+ print("Background object %s created." % item)
+ get_node("Windows/CreateCompleteDialog").popup_centered()
+ else:
+ get_tree().edited_scene_root.add_child(item)
+ # Make it so all the nodes can be seen in the scene tree
+ collision_shape.set_owner(item)
+ interact_position.set_owner(item)
+ item_sprite.set_owner(item)
+
+ item.set_owner(get_tree().edited_scene_root)
+ # Export scene - create in inventory folder
+ var packed_scene = PackedScene.new()
+
+ packed_scene.pack(get_tree().edited_scene_root.get_node(item.name))
+
+ # Flag suggestions from https://godotengine.org/qa/50437/how-to-turn-a-node-into-a-packedscene-via-gdscript
+ var err = ResourceSaver.save(packed_scene, "%s/%s.tscn" % [inventory_path, get_node(ITEM_NAME_NODE).text], \
+ ResourceSaver.FLAG_CHANGE_PATH|ResourceSaver.FLAG_REPLACE_SUBRESOURCE_PATHS)
+ if err:
+ get_node(ERROR_WINDOW_NODE).dialog_text = \
+ "Failed to save the item. Please make sure you can\n" + \
+ "write to the destination folder" % inventory_path
+ get_node(ERROR_WINDOW_NODE).popup_centered()
+ return
+ else:
+ item.queue_free()
+ get_tree().edited_scene_root.get_node(item.name).queue_free()
+ get_node("Windows/CreateCompleteDialog").dialog_text = \
+ "Inventory item %s/%s.tscn created." % [inventory_path, get_node(ITEM_NAME_NODE).text]
+ print("Inventory item %s/%s.tscn created." % [inventory_path, get_node(ITEM_NAME_NODE).text])
+ get_node("Windows/CreateCompleteDialog").popup_centered()
+
+
+func Item_on_ClearButton_pressed() -> void:
+ if settings_modified == true:
+ main_menu_requested = false
+ get_node(CONFIRM_NODE).dialog_text = "WARNING!\n\n" + \
+ "If you continue you will lose the current object."
+ get_node(CONFIRM_NODE).popup_centered()
+
+
+func _on_ObjectConfirmationDialog_confirmed() -> void:
+ if main_menu_requested == true:
+ switch_to_main_menu()
+ else:
+ item_creator_reset()
+
+
+func Item_on_ExitButton_pressed() -> void:
+ if settings_modified == true:
+ main_menu_requested = true
+ get_node(CONFIRM_NODE).dialog_text = "WARNING!\n\n" + \
+ "If you continue you will lose the current object."
+ get_node(CONFIRM_NODE).popup_centered()
+ else:
+ switch_to_main_menu()
+
+
+func switch_to_main_menu() -> void:
+ get_node("../Menu").visible = true
+ get_node("../ItemCreator").visible = false
+
+
+func _on_StartsInteractiveCheckBox_pressed() -> void:
+ settings_modified = true
+
+
+func _on_ItemGlobalID_text_changed(_new_text: String) -> void:
+ settings_modified = true
+
+
+func _on_DefaultActionOption_item_selected(_index: int) -> void:
+ settings_modified = true
+
+
+func _on_CreateCompleteDialog_confirmed() -> void:
+ item_creator_reset()
+
+
+func _on_BackgroundObjectCheckBox_toggled(button_pressed: bool) -> void:
+ if button_pressed == false:
+ $VBoxContainer/Control/CenterContainer/HBoxContainer/InventoryItemCheckBox.set_pressed_no_signal(true)
+ inventory_mode = true
+ else:
+ $VBoxContainer/Control/CenterContainer/HBoxContainer/InventoryItemCheckBox.set_pressed_no_signal(false)
+ inventory_mode = false
+
+ item_creator_reset()
+
+
+func _on_InventoryItemCheckBox_toggled(button_pressed: bool) -> void:
+ if button_pressed == false:
+ $VBoxContainer/Control/CenterContainer/HBoxContainer/BackgroundObjectCheckBox.set_pressed_no_signal(true)
+ inventory_mode = false
+ else:
+ $VBoxContainer/Control/CenterContainer/HBoxContainer/BackgroundObjectCheckBox.set_pressed_no_signal(false)
+ inventory_mode = true
+
+ item_creator_reset()
+
+
+func _on_ChangePathButton_pressed():
+ $"Windows/FileDialog".popup_centered()
+
+
+func _on_FileDialog_dir_selected(dir: String) -> void:
+ ProjectSettings.set_setting("escoria/ui/inventory_items_path", dir)
+ var property_info = {
+ "name": "escoria/ui/inventory_items_path",
+ "type": TYPE_STRING
+ }
+ ProjectSettings.add_property_info(property_info)
+ get_node(INVENTORY_PATH_NODE).text = dir