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().connect("pressed", self, "PlayerSceneCancelled") $"InformationWindows/BackgroundImageFileDialog".get_cancel().connect("pressed", self, "BackgroundFileCancelled") func PlayerSceneCancelled() -> void: if get_node(PLAYER_SCENE).text == PLAYER_SELECT_TEXT: get_node(USE_EMPTY_PLAYER_BUTTON).pressed = true func BackgroundFileCancelled() -> void: if get_node(BACKGROUND_IMAGE).text == BACKGROUND_SELECT_TEXT: get_node(USE_EMPTY_BACKGROUND).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).pressed = true get_node(ESC_SCRIPT).editable = false get_node(ESC_SCRIPT).text = SCRIPT_BLANK_TEXT get_node(USE_EMPTY_ROOM_SCRIPT).pressed = true get_node(BACKGROUND_IMAGE).text = BACKGROUND_BLANK_TEXT get_node(USE_EMPTY_ROOM_SPACER).visible = true get_node(USE_EMPTY_BACKGROUND).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".rect_size / 2 var dialog_pos: Vector2 = viewport_centre - dialog_start $"InformationWindows/BackgroundImageFileDialog".rect_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".rect_size / 2 var dialog_pos: Vector2 = viewport_centre - dialog_start $"InformationWindows/BackgroundImageFileDialog".rect_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:StreamTexture 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() # get_node(BACKGROUND_PREVIEW).rect_scale = Vector2.ONE var image_size = get_node(BACKGROUND_PREVIEW).texture.get_size() preview_scale.x = preview_size.x / image_size.x preview_scale.y = preview_size.y / image_size.y # print("scale = "+str(preview_scale)+", preview size = "+str(preview_size)+", image_size = "+str(image_size)) if preview_scale.y > preview_scale.x: get_node(BACKGROUND_PREVIEW).rect_scale = Vector2(preview_scale.x, preview_scale.x) else: # Image width will hit the preview boundary before the height will get_node(BACKGROUND_PREVIEW).rect_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 RoomName = get_node(ROOM_NAME).text if RoomName.length() < 1: $"InformationWindows/GenericErrorDialog".dialog_text = "Error!\n\nRoom name must be specified." $"InformationWindows/GenericErrorDialog".popup_centered() return var ScriptName = get_node(ESC_SCRIPT).text if get_node(USE_EMPTY_ROOM_SCRIPT).pressed == false: if ScriptName.length() < 5 or ! ScriptName.substr(ScriptName.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 BaseDir = ProjectSettings.get_setting(ROOM_PATH_SETTING) var ImageSize = Vector2(1,1) var NewRoom = ESCRoom.new() NewRoom.name = RoomName NewRoom.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: NewRoom.esc_script = "%s/%s/scripts/%s" % [BaseDir, RoomName, 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) NewRoom.player_scene = player_scene var Background = ESCBackground.new() Background.name = "Background" var BackgroundSize = 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 BackgroundSize = 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 BackgroundSize = Vector2(ProjectSettings.get_setting("display/window/size/width"), \ ProjectSettings.get_setting("display/window/size/height")) Background.rect_size = BackgroundSize NewRoom.add_child(Background) var NewTerrain = ESCTerrain.new() NewTerrain.name = "WalkableArea" var NewNavigationPolygonInstance = NavigationPolygonInstance.new() var NewNavigationPolygon = NavigationPolygon.new() NewNavigationPolygonInstance.navpoly = NewNavigationPolygon NewRoom.add_child(NewTerrain) NewTerrain.add_child(NewNavigationPolygonInstance) var Objects = Node2D.new() Objects.name = "RoomObjects" NewRoom.add_child(Objects) var StartPos = ESCLocation.new() StartPos.name = "StartPos" StartPos.is_start_location = true StartPos.global_id = "%s_start_pos" % RoomName StartPos.position = Vector2(int(BackgroundSize.x / 2), int(BackgroundSize.y / 2)) NewRoom.add_child(StartPos) get_tree().edited_scene_root.add_child(NewRoom) NewRoom.set_owner(get_tree().edited_scene_root) NewNavigationPolygonInstance.set_owner(NewRoom) NewTerrain.set_owner(NewRoom) Background.set_owner(NewRoom) Objects.set_owner(NewRoom) StartPos.set_owner(NewRoom) var dir = Directory.new() dir.make_dir_recursive("%s/%s/scripts" % [BaseDir, RoomName]) dir.make_dir_recursive("%s/%s/objects" % [BaseDir, RoomName]) dir.copy("res://addons/escoria-wizard/room_script_template.esc", "%s/%s/scripts/%s" % \ [BaseDir, RoomName, get_node(ESC_SCRIPT).text]) # Export scene var packed_scene = PackedScene.new() packed_scene.pack(get_tree().edited_scene_root.get_node(NewRoom.name)) # Flag suggestions from https://godotengine.org/qa/50437/how-to-turn-a-node-into-a-packedscene-via-gdscript ResourceSaver.save("%s/%s/%s.tscn" % [BaseDir, RoomName, RoomName], \ packed_scene, ResourceSaver.FLAG_CHANGE_PATH|ResourceSaver.FLAG_REPLACE_SUBRESOURCE_PATHS) NewRoom.queue_free() get_tree().edited_scene_root.get_node(NewRoom.name).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()