@tool extends Control const ROOM_NAME = "MarginContainer/MarginContainer/VBoxContainer/MarginContainer/GridContainer/RoomName" const GLOBAL_ID = "MarginContainer/MarginContainer/VBoxContainer/MarginContainer/GridContainer/GlobalID" const PLAYER_SCENE = "MarginContainer/MarginContainer/VBoxContainer/MarginContainer/GridContainer/PlayerScene" const SELECT_PLAYER_SCENE = "MarginContainer/MarginContainer/VBoxContainer/MarginContainer/GridContainer/SelectPlayerScene" const SELECT_PLAYER_SCENE_SPACER = "MarginContainer/MarginContainer/VBoxContainer/MarginContainer/GridContainer/SelectPlayerSceneSpacer" const USE_EMPTY_PLAYER_BUTTON = "MarginContainer/MarginContainer/VBoxContainer/MarginContainer/GridContainer/UseEmptyPlayerButton" const ESC_SCRIPT = "MarginContainer/MarginContainer/VBoxContainer/MarginContainer/GridContainer/ESCScript" const USE_EMPTY_ROOM_SCRIPT = "MarginContainer/MarginContainer/VBoxContainer/MarginContainer/GridContainer/UseEmptyRoomScript" const USE_EMPTY_ROOM_SPACER = "MarginContainer/MarginContainer/VBoxContainer/MarginContainer/GridContainer/UseEmptyRoomSpacer" const BACKGROUND_IMAGE = "MarginContainer/MarginContainer/VBoxContainer/MarginContainer/GridContainer/BackgroundImage" const USE_EMPTY_BACKGROUND = "MarginContainer/MarginContainer/VBoxContainer/MarginContainer/GridContainer/UseEmptyBackground" const SELECT_BACKGROUND = "MarginContainer/MarginContainer/VBoxContainer/MarginContainer/GridContainer/SelectBackground" const SELECT_BACKGROUNDSPACER = "MarginContainer/MarginContainer/VBoxContainer/MarginContainer/GridContainer/SelectBackgroundSpacer" const ROOM_FOLDER_PATH = "MarginContainer/MarginContainer/VBoxContainer/MarginContainer/GridContainer/RoomFolder" const ROOM_BACKGROUND = "MarginContainer/MarginContainer/VBoxContainer/PreviewSection/CenterContainer/RoomBackground" const BACKGROUND_PREVIEW = "MarginContainer/MarginContainer/VBoxContainer/PreviewSection/Control/BackgroundPreview" const SCRIPT_BLANK_TEXT = "Room will not have a script configured." const SCRIPT_SELECT_TEXT = "Please select script." const PLAYER_BLANK_TEXT = "Scene will be left blank." const PLAYER_SELECT_TEXT = "Please select scene." const BACKGROUND_BLANK_TEXT = "Image will be left blank." const BACKGROUND_SELECT_TEXT = "Please select image." const ROOM_PATH_SETTING = "escoria/wizard/path_to_rooms" var settings_modified: bool func _ready() -> void: $"InformationWindows/PlayerSceneFileDialog".get_cancel_button().connect("pressed", Callable(self, "player_scene_cancelled")) $"InformationWindows/BackgroundImageFileDialog".get_cancel_button().connect("pressed", Callable(self, "background_file_cancelled")) func player_scene_cancelled() -> void: if get_node(PLAYER_SCENE).text == PLAYER_SELECT_TEXT: get_node(USE_EMPTY_PLAYER_BUTTON).button_pressed = true func background_file_cancelled() -> void: if get_node(BACKGROUND_IMAGE).text == BACKGROUND_SELECT_TEXT: get_node(USE_EMPTY_BACKGROUND).button_pressed = true func room_creator_reset() -> void: get_node(ROOM_NAME).text = "" get_node(GLOBAL_ID).text = "" get_node(PLAYER_SCENE).text = PLAYER_BLANK_TEXT get_node(SELECT_PLAYER_SCENE).visible = false get_node(SELECT_PLAYER_SCENE_SPACER).visible = true get_node(USE_EMPTY_PLAYER_BUTTON).button_pressed = true get_node(ESC_SCRIPT).editable = false get_node(ESC_SCRIPT).text = SCRIPT_BLANK_TEXT get_node(USE_EMPTY_ROOM_SCRIPT).button_pressed = true get_node(BACKGROUND_IMAGE).text = BACKGROUND_BLANK_TEXT get_node(USE_EMPTY_ROOM_SPACER).visible = true get_node(USE_EMPTY_BACKGROUND).button_pressed = true get_node(SELECT_BACKGROUND).visible = false get_node(SELECT_BACKGROUNDSPACER).visible = true get_node(BACKGROUND_PREVIEW).visible = true get_node(ROOM_BACKGROUND).visible = true get_node(BACKGROUND_PREVIEW).texture = null get_node(ROOM_FOLDER_PATH).text = ProjectSettings.get_setting(ROOM_PATH_SETTING) $InformationWindows/RoomFolderDialog.current_dir = ProjectSettings.get_setting(ROOM_PATH_SETTING) settings_modified = false func _on_RoomName_text_changed(new_text: String) -> void: get_node(GLOBAL_ID).text = new_text settings_modified = true func _on_GlobalID_text_changed(_new_text: String) -> void: settings_modified = true func _on_UseEmptyPlayerButton_toggled(button_pressed: bool) -> void: if button_pressed == true: get_node(SELECT_PLAYER_SCENE).visible = false get_node(SELECT_PLAYER_SCENE_SPACER).visible = true get_node(PLAYER_SCENE).text = PLAYER_BLANK_TEXT else: get_node(SELECT_PLAYER_SCENE).visible = true get_node(SELECT_PLAYER_SCENE_SPACER).visible = false get_node(PLAYER_SCENE).text = PLAYER_SELECT_TEXT $"InformationWindows/PlayerSceneFileDialog".popup_centered() func _on_SelectPlayerScene_pressed() -> void: $"InformationWindows/PlayerSceneFileDialog".visible = true $"InformationWindows/PlayerSceneFileDialog".invalidate() func _on_PlayerSceneFileDialog_file_selected(path: String) -> void: settings_modified = true get_node(PLAYER_SCENE).text = path func _on_UseEmptyRoomScript_toggled(button_pressed: bool) -> void: if button_pressed == true: get_node(ESC_SCRIPT).editable = false get_node(ESC_SCRIPT).text = SCRIPT_BLANK_TEXT else: get_node(ESC_SCRIPT).editable = true get_node(ESC_SCRIPT).text = "%s.esc" % get_node(GLOBAL_ID).text func _on_SelectRoomScript_pressed() -> void: $"InformationWindows/ESCScriptFileDialog".visible = true $"InformationWindows/ESCScriptFileDialog".invalidate() func _on_ESCScriptFileDialog_file_selected(path: String) -> void: settings_modified = true get_node(ESC_SCRIPT).text = path func _on_UseEmptyBackground_toggled(button_pressed: bool) -> void: if button_pressed == true: get_node(SELECT_BACKGROUND).visible = false get_node(SELECT_BACKGROUNDSPACER).visible = true get_node(BACKGROUND_IMAGE).text = BACKGROUND_BLANK_TEXT get_node(BACKGROUND_PREVIEW).texture = null get_node(ROOM_BACKGROUND).visible = true else: get_node(SELECT_BACKGROUND).visible = true get_node(SELECT_BACKGROUNDSPACER).visible = false get_node(BACKGROUND_IMAGE).text = BACKGROUND_SELECT_TEXT var viewport_centre: Vector2 = get_viewport_rect().size / 2 var dialog_start: Vector2 = $"InformationWindows/BackgroundImageFileDialog".size / 2 var dialog_pos: Vector2 = viewport_centre - dialog_start $"InformationWindows/BackgroundImageFileDialog".position = dialog_pos $"InformationWindows/BackgroundImageFileDialog".popup_centered() func _on_SelectBackground_pressed() -> void: var viewport_centre: Vector2 = get_viewport_rect().size / 2 var dialog_start: Vector2 = $"InformationWindows/BackgroundImageFileDialog".size / 2 var dialog_pos: Vector2 = viewport_centre - dialog_start $"InformationWindows/BackgroundImageFileDialog".position = dialog_pos $"InformationWindows/BackgroundImageFileDialog".visible = true $"InformationWindows/BackgroundImageFileDialog".invalidate() func _on_BackgroundImageFileDialog_file_selected(path: String) -> void: settings_modified = true get_node(BACKGROUND_IMAGE).text = path var image_stream_texture:CompressedTexture2D image_stream_texture = load(path) get_node(BACKGROUND_PREVIEW).texture = image_stream_texture get_node(ROOM_BACKGROUND).visible = false set_preview_scale() func set_preview_scale() -> void: var preview_scale = Vector2.ONE # 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 var preview_size = get_node(ROOM_BACKGROUND).get_size() var image_size = get_node(BACKGROUND_PREVIEW).texture.get_size() preview_scale.x = clampf(preview_size.x/ image_size.x, 0, 1) preview_scale.y = clampf(preview_size.y/ image_size.y, 0, 1) if preview_scale.y > preview_scale.x: get_node(BACKGROUND_PREVIEW).scale = Vector2(preview_scale.x, preview_scale.x) else: # Image width will hit the preview boundary before the height will get_node(BACKGROUND_PREVIEW).scale = Vector2(preview_scale.y, preview_scale.y) func _on_ClearButton_pressed() -> void: if settings_modified: $InformationWindows/ClearConfirmationDialog.popup_centered() func _on_MainMenuButton_pressed() -> void: if settings_modified: $InformationWindows/MainMenuConfirmationDialog.popup_centered() else: get_node("../Menu").visible = true get_node("../RoomCreator").visible = false func _on_ClearConfirmationDialog_confirmed() -> void: room_creator_reset() func _on_MainMenuConfirmationDialog_confirmed() -> void: get_node("../Menu").visible = true get_node("../RoomCreator").visible = false func _on_ChangeRoomFolderButton_pressed() -> void: $"InformationWindows/RoomFolderDialog".popup_centered() func _on_RoomFolderDialog_dir_selected(dir: String) -> void: ProjectSettings.set_setting(ROOM_PATH_SETTING, dir) var property_info = { "name": ROOM_PATH_SETTING, "type": TYPE_STRING } ProjectSettings.add_property_info(property_info) get_node(ROOM_FOLDER_PATH).text = dir func _on_CreateButton_pressed() -> void: var room_name = get_node(ROOM_NAME).text if room_name.length() < 1: $"InformationWindows/GenericErrorDialog".dialog_text = "Error!\n\nRoom name must be specified." $"InformationWindows/GenericErrorDialog".popup_centered() return var script_name = get_node(ESC_SCRIPT).text if get_node(USE_EMPTY_ROOM_SCRIPT).button_pressed == false: if script_name.length() < 5 or ! script_name.substr(script_name.length() - 4) == ".esc": $"InformationWindows/GenericErrorDialog".dialog_text = "Error!\n\n" \ + "Room ESC script must be a filename ending in '.esc'" $"InformationWindows/GenericErrorDialog".popup_centered() return if "/" in get_node(ESC_SCRIPT).text: $"InformationWindows/GenericErrorDialog".dialog_text = "Error!\n\n" \ + "Please remove any '/' characters from the name of the Room ESC script." $"InformationWindows/GenericErrorDialog".popup_centered() return var base_dir = ProjectSettings.get_setting(ROOM_PATH_SETTING) var new_room = ESCRoom.new() new_room.name = room_name new_room.global_id = get_node(GLOBAL_ID).text if ! get_node(ESC_SCRIPT).text == SCRIPT_SELECT_TEXT and ! get_node(ESC_SCRIPT).text == SCRIPT_BLANK_TEXT: new_room.esc_script = "%s/%s/scripts/%s" % [base_dir, room_name, get_node(ESC_SCRIPT).text] if ! get_node(PLAYER_SCENE).text == PLAYER_SELECT_TEXT and ! get_node(PLAYER_SCENE).text == PLAYER_BLANK_TEXT: var player_scene = load(get_node(PLAYER_SCENE).text) new_room.player_scene = player_scene var background = ESCBackground.new() background.name = "Background" var background_size = Vector2.ONE if ! get_node(BACKGROUND_IMAGE).text == BACKGROUND_SELECT_TEXT and ! get_node(BACKGROUND_IMAGE).text == BACKGROUND_BLANK_TEXT: background.texture = get_node(BACKGROUND_PREVIEW).texture background_size = background.texture.get_size() else: # Set TextureRect to have the same size as the Viewport so that the room # works even if no texture is set in the TextureRect background_size = Vector2(ProjectSettings.get_setting("display/window/size/viewport_width"), \ ProjectSettings.get_setting("display/window/size/viewport_height")) background.size = background_size new_room.add_child(background) background.set_owner(new_room) var new_terrain = ESCTerrain.new() new_terrain.name = "WalkableArea" var new_navigation_polygon_instance = NavigationRegion2D.new() var new_navigation_polygon = NavigationPolygon.new() new_navigation_polygon_instance.navigation_polygon = new_navigation_polygon new_terrain.add_child(new_navigation_polygon_instance) new_navigation_polygon_instance.set_owner(new_terrain) new_room.add_child(new_terrain) new_terrain.set_owner(new_room) var objects = Node2D.new() objects.name = "RoomObjects" new_room.add_child(objects) objects.set_owner(new_room) var start_pos = ESCLocation.new() start_pos.name = "StartPos" start_pos.is_start_location = true start_pos.global_id = "%s_start_pos" % room_name start_pos.position = Vector2(int(background_size.x / 2), int(background_size.y / 2)) new_room.add_child(start_pos) start_pos.set_owner(new_room) DirAccess.make_dir_recursive_absolute("%s/%s/scripts" % [base_dir, room_name]) DirAccess.make_dir_recursive_absolute("%s/%s/objects" % [base_dir, room_name]) DirAccess.copy_absolute("res://addons/escoria-wizard/room_script_template.esc", "%s/%s/scripts/%s" % \ [base_dir, room_name, get_node(ESC_SCRIPT).text]) # Export scene var packed_scene = PackedScene.new() packed_scene.pack(new_room) # Flag suggestions from https://godotengine.org/qa/50437/how-to-turn-a-node-into-a-packedscene-via-gdscript var error = ResourceSaver.save(packed_scene, "%s/%s/%s.tscn" % [base_dir, room_name, room_name], \ ResourceSaver.FLAG_CHANGE_PATH|ResourceSaver.FLAG_REPLACE_SUBRESOURCE_PATHS) if error != OK: push_error("An error occurred while saving the scene to disk.") new_room.queue_free() # Scan the filesystem so that the new folders show up in the file browser. # Without this you might not see the objects/scripts folders in the filetree. var ep = EditorPlugin.new() ep.get_editor_interface().get_resource_filesystem().scan() ep.free() $InformationWindows/CreateCompleteDialog.popup_centered()