[gd_scene load_steps=8 format=3 uid="uid://df5fuj4vjr11p"] [ext_resource type="Script" path="res://addons/MetroidvaniaSystem/Database/MapViewer.gd" id="1_s16ok"] [ext_resource type="Script" path="res://addons/MetroidvaniaSystem/Database/MapOverlay.gd" id="2_pgyha"] [ext_resource type="Script" path="res://addons/MetroidvaniaSystem/Scripts/EditorIconButton.gd" id="2_tjngl"] [sub_resource type="ButtonGroup" id="ButtonGroup_lmh17"] [sub_resource type="GDScript" id="GDScript_fjyy3"] resource_name = "Settings" script/source = "@tool extends Button var plugin: EditorPlugin func _enter_tree() -> void: if owner: plugin = owner.plugin func _ready() -> void: if not plugin: return _pressed() await get_tree().process_frame for data in MetSys.settings.collectible_list: var collectible := add_collectible() collectible.set_data(data) func _pressed() -> void: for button in button_group.get_buttons(): button.exit() %Settings.show() func exit(): %Settings.hide() func add_collectible() -> Control: var collectible := preload(\"res://addons/MetroidvaniaSystem/Nodes/CollectibleElement.tscn\").instantiate() %CollectibleList.add_child(collectible) collectible.save_request.connect(save_collectible_list) return collectible func save_collectible_list(): var list: Array[Dictionary] for collectible in %CollectibleList.get_children(): if not collectible.is_queued_for_deletion(): list.append(collectible.get_data()) MetSys.settings.collectible_list = list ResourceSaver.save(MetSys.settings) " [sub_resource type="GDScript" id="GDScript_dicqo"] resource_name = "Finder" script/source = "@tool extends Button @onready var scan_progress: ProgressBar = %ScanProgress @onready var show_on_map: CheckButton = %ShowOnMap @onready var summary: VBoxContainer = %Summary var thread: Thread var found_elements: Array[Dictionary] func _ready() -> void: scan_progress.hide() show_on_map.hide() exit() func _pressed() -> void: for button in button_group.get_buttons(): button.exit() %Finder.show() func exit(): %Finder.hide() func start_scan() -> void: summary.hide() %ScanButton.disabled = true var collectible_list: Array[Dictionary] for item in %CollectibleList.get_children(): collectible_list.append(item.get_data2()) found_elements.clear() for item in summary.get_children(): item.free() thread = Thread.new() thread.start(scan_maps.bind(collectible_list)) set_process(true) func _process(delta: float) -> void: if not thread: set_process(false) return if thread.is_alive(): return thread.wait_to_finish() thread = null scan_progress.hide() show_on_map.show() summary.show() %ScanButton.disabled = false for item in %CollectibleList.get_children(): var data: Dictionary = item.get_data2() var count := 0 var count_label := setup_header(data) for found in found_elements: if found.element != data.element: continue count += 1 setup_found(found) count_label.text = str(count) summary.add_child(HSeparator.new()) func scan_maps(element_list: Array[Dictionary]): Thread.set_thread_safety_checks_enabled(false) var maps: Array[String] var folders: Array[String] folders.append(MetSys.settings.map_root_folder) while not folders.is_empty(): var folder := folders.pop_back() folders.append_array(Array(DirAccess.get_directories_at(folder)).map(func(subfolder: String) -> String: return folder.path_join(subfolder))) maps.append_array(Array(DirAccess.get_files_at(folder)).map(func(file: String) -> String: return folder.path_join(file))) scan_progress.max_value = maps.size() scan_progress.value = 0 scan_progress.show() show_on_map.hide() for map in maps: var lines := FileAccess.open(map, FileAccess.READ).get_as_text().split(\"\\n\") var current_element: Dictionary for line in lines: if not current_element.is_empty(): if line.begins_with(\"[\"): found_elements.append(current_element) current_element = {} elif line.begins_with(\"position =\"): current_element.position = str_to_var(line.get_slice(\"=\", 1)) else: continue for element in element_list: if line.begins_with(\"[node name=\\\"%s\" % element.element): current_element = element.duplicate() current_element.map = map break if not current_element.is_empty(): found_elements.append(current_element) scan_progress.value += 1 func complete_element(element: Dictionary): var found := preload(\"res://addons/MetroidvaniaSystem/Nodes/CollectibleFoundItem.tscn\").instantiate() found.set_element(element) found.hovered.connect(owner._on_item_hover.bind(found)) summary.add_child.call_deferred(found) func setup_header(data: Dictionary) -> Label: var hbox := HBoxContainer.new() summary.add_child(hbox) var tex := TextureRect.new() hbox.add_child(tex) tex.texture = data.get(\"icon\") var label := Label.new() hbox.add_child(label) label.text = data.element label = Label.new() hbox.add_child(label) return label func setup_found(data: Dictionary): var label := Label.new() summary.add_child(label) label.mouse_filter = Control.MOUSE_FILTER_PASS label.set_meta(&\"data\", data) data.map = data.map.trim_prefix(MetSys.settings.map_root_folder) var room := MetSys.map_data.get_cells_assigned_to(data.map) if \"position\" in data and not room.is_empty(): var top_left := Vector2i.MAX for coords in room: top_left.x = mini(coords.x, top_left.x) top_left.y = mini(coords.y, top_left.y) var pos := top_left + Vector2i(data.position / MetSys.settings.in_game_cell_size) data.coords = Vector3i(pos.x, pos.y, room[0].z) label.text = \"%s %s\" % [data.map, data.coords] else: label.text = \"%s\" % data.map label.mouse_entered.connect(owner._on_item_hover.bind(label)) func toggle_display_on_map(toggled_on: bool) -> void: if toggled_on: owner.extra_draw = draw_collectibles_on_map else: owner.extra_draw = Callable() owner.map_overlay.queue_redraw() func draw_collectibles_on_map(canvas_item: CanvasItem): for element in found_elements: var icon: Texture2D = element.icon var target_size := icon.get_size() * (minf(MetSys.CELL_SIZE.x, MetSys.CELL_SIZE.y) / minf(icon.get_width(), icon.get_height()) * 0.9) if \"coords\" in element: var coords: Vector3i = element.coords if coords.z != owner.current_layer: continue var pos := Vector2(coords.x + owner.map_offset.x, coords.y + owner.map_offset.y) * MetSys.CELL_SIZE canvas_item.draw_texture_rect(icon, Rect2(pos + MetSys.CELL_SIZE * 0.5 - target_size * 0.5, target_size), false) else: for coords in MetSys.map_data.get_cells_assigned_to(element.map): if coords.z != owner.current_layer: break var pos := Vector2(coords.x + owner.map_offset.x, coords.y + owner.map_offset.y) * MetSys.CELL_SIZE canvas_item.draw_texture_rect(icon, Rect2(pos + MetSys.CELL_SIZE * 0.5 - target_size * 0.5, target_size), false) break " [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qbvjg"] content_margin_left = 4.0 content_margin_right = 4.0 bg_color = Color(0, 0, 0, 0.501961) [node name="MapViewer" type="HBoxContainer"] anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 script = ExtResource("1_s16ok") metadata/_edit_lock_ = true [node name="Panel" type="PanelContainer" parent="."] custom_minimum_size = Vector2(200, 0) layout_mode = 2 size_flags_horizontal = 0 [node name="ScrollContainer" type="ScrollContainer" parent="Panel"] layout_mode = 2 [node name="VBoxContainer" type="VBoxContainer" parent="Panel/ScrollContainer"] layout_mode = 2 size_flags_horizontal = 3 size_flags_vertical = 3 [node name="Layer" type="VBoxContainer" parent="Panel/ScrollContainer/VBoxContainer"] layout_mode = 2 mouse_filter = 2 [node name="Label" type="Label" parent="Panel/ScrollContainer/VBoxContainer/Layer"] layout_mode = 2 text = "当前层" horizontal_alignment = 1 [node name="CurrentLayer" type="SpinBox" parent="Panel/ScrollContainer/VBoxContainer/Layer"] unique_name_in_owner = true layout_mode = 2 size_flags_horizontal = 4 [node name="RecenterButton" type="Button" parent="Panel/ScrollContainer/VBoxContainer/Layer"] unique_name_in_owner = true layout_mode = 2 size_flags_horizontal = 4 text = "重置视角" [node name="CheckButton" type="CheckButton" parent="Panel/ScrollContainer/VBoxContainer/Layer"] layout_mode = 2 size_flags_horizontal = 4 text = "预览映射" [node name="HSeparator" type="HSeparator" parent="Panel/ScrollContainer/VBoxContainer"] layout_mode = 2 [node name="Modes" type="VBoxContainer" parent="Panel/ScrollContainer/VBoxContainer"] layout_mode = 2 [node name="Settings" type="Button" parent="Panel/ScrollContainer/VBoxContainer/Modes"] layout_mode = 2 toggle_mode = true button_pressed = true button_group = SubResource("ButtonGroup_lmh17") text = "收集品设置" script = SubResource("GDScript_fjyy3") [node name="Finder" type="Button" parent="Panel/ScrollContainer/VBoxContainer/Modes"] layout_mode = 2 toggle_mode = true button_group = SubResource("ButtonGroup_lmh17") text = "收集品查找" script = SubResource("GDScript_dicqo") [node name="HSeparator2" type="HSeparator" parent="Panel/ScrollContainer/VBoxContainer"] layout_mode = 2 [node name="EditControls" type="VBoxContainer" parent="Panel/ScrollContainer/VBoxContainer"] layout_mode = 2 size_flags_vertical = 3 [node name="Settings" type="VBoxContainer" parent="Panel/ScrollContainer/VBoxContainer/EditControls"] unique_name_in_owner = true visible = false layout_mode = 2 size_flags_vertical = 3 [node name="ScrollContainer" type="ScrollContainer" parent="Panel/ScrollContainer/VBoxContainer/EditControls/Settings"] layout_mode = 2 size_flags_vertical = 3 vertical_scroll_mode = 2 [node name="CollectibleList" type="VBoxContainer" parent="Panel/ScrollContainer/VBoxContainer/EditControls/Settings/ScrollContainer"] unique_name_in_owner = true layout_mode = 2 size_flags_horizontal = 3 [node name="Button" type="Button" parent="Panel/ScrollContainer/VBoxContainer/EditControls/Settings"] layout_mode = 2 icon_alignment = 1 script = ExtResource("2_tjngl") icon_name = "Add" [node name="Finder" type="VBoxContainer" parent="Panel/ScrollContainer/VBoxContainer/EditControls"] unique_name_in_owner = true visible = false layout_mode = 2 size_flags_vertical = 3 [node name="ScanButton" type="Button" parent="Panel/ScrollContainer/VBoxContainer/EditControls/Finder"] unique_name_in_owner = true layout_mode = 2 text = "Scan Maps" [node name="ScanProgress" type="ProgressBar" parent="Panel/ScrollContainer/VBoxContainer/EditControls/Finder"] unique_name_in_owner = true visible = false layout_mode = 2 [node name="ShowOnMap" type="CheckButton" parent="Panel/ScrollContainer/VBoxContainer/EditControls/Finder"] unique_name_in_owner = true visible = false layout_mode = 2 text = "Display on Map" [node name="ScrollContainer" type="ScrollContainer" parent="Panel/ScrollContainer/VBoxContainer/EditControls/Finder"] layout_mode = 2 size_flags_vertical = 3 horizontal_scroll_mode = 3 vertical_scroll_mode = 2 [node name="Summary" type="VBoxContainer" parent="Panel/ScrollContainer/VBoxContainer/EditControls/Finder/ScrollContainer"] unique_name_in_owner = true layout_mode = 2 size_flags_horizontal = 3 size_flags_vertical = 0 [node name="MapOverlay" type="Control" parent="."] clip_contents = true layout_mode = 2 size_flags_horizontal = 3 script = ExtResource("2_pgyha") [node name="ColorRect" type="ColorRect" parent="MapOverlay"] modulate = Color(0, 0, 0, 0.12549) show_behind_parent = true layout_mode = 1 anchors_preset = 15 anchor_right = 1.0 anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 mouse_filter = 2 [node name="Map" type="Control" parent="MapOverlay"] unique_name_in_owner = true show_behind_parent = true anchors_preset = 0 size_flags_horizontal = 3 mouse_filter = 2 [node name="StatusLabel" type="Label" parent="MapOverlay"] unique_name_in_owner = true layout_mode = 0 offset_right = 1.0 offset_bottom = 23.0 theme_override_styles/normal = SubResource("StyleBoxFlat_qbvjg") vertical_alignment = 1 [connection signal="toggled" from="Panel/ScrollContainer/VBoxContainer/Layer/CheckButton" to="." method="toggle_mapped"] [connection signal="pressed" from="Panel/ScrollContainer/VBoxContainer/EditControls/Settings/Button" to="Panel/ScrollContainer/VBoxContainer/Modes/Settings" method="add_collectible"] [connection signal="pressed" from="Panel/ScrollContainer/VBoxContainer/EditControls/Finder/ScanButton" to="Panel/ScrollContainer/VBoxContainer/Modes/Finder" method="start_scan"] [connection signal="toggled" from="Panel/ScrollContainer/VBoxContainer/EditControls/Finder/ShowOnMap" to="Panel/ScrollContainer/VBoxContainer/Modes/Finder" method="toggle_display_on_map"]