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
		
	
| [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"]
 |