You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			418 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Plaintext
		
	
		
		
			
		
	
	
			418 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Plaintext
		
	
| 
											2 years ago
										 | [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"] |