diff options
| author | Radio <radiohotline@disroot.org> | 2026-06-04 15:15:11 +0300 |
|---|---|---|
| committer | Radio <radiohotline@disroot.org> | 2026-06-04 15:15:11 +0300 |
| commit | 9d74b49ab62908d4acf53dde444413886b8b28e5 (patch) | |
| tree | 0cb785267ea7e239b19d88684c0d64b9bd5d52f0 /addons/escoria-wizard/item_creator.gd | |
| parent | 2c85d452ad02a5f89cd43bad7f9de31d0e4fa0c1 (diff) | |
escoria setup and old branch archives
Diffstat (limited to 'addons/escoria-wizard/item_creator.gd')
| -rw-r--r-- | addons/escoria-wizard/item_creator.gd | 318 |
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 |
