@tool class_name LevelSet extends Resource @export var title: String: set(value): title = value resource_name = title @export var id: String @export var start_scene: PackedScene @export var end_scene: PackedScene @export_dir var levels_dir: String: set(value): levels_dir = value if Engine.is_editor_hint(): update_levels() @export_tool_button("Update Levels") var _update_levels_action = update_levels @export var levels: Array[LevelInfo] = [] func has_id(level_id: String) -> bool: for info in levels: if info.id == level_id: return true return false func has_level(level: Level) -> bool: for info in levels: if info.scene_path == level.scene_file_path: return true return false func update_levels() -> void: levels.clear() var dir = DirAccess.open(levels_dir) if dir: dir.list_dir_begin() var file = dir.get_next() while file != "": if not dir.current_is_dir() and file.ends_with(".tscn") or file.ends_with(".scn"): var scene := load(levels_dir + "/" + file) as PackedScene if scene and scene.can_instantiate(): var level = scene.instantiate() if level is Level: if has_id(level.id): _popup_alert("Duplicate level ID: %s" % level.id) else: levels.append(LevelInfo.from_level(level)) level.free() file = dir.get_next() # sort levels by level order levels.sort_custom(func(a, b): return a.order < b.order) emit_changed() notify_property_list_changed() func _popup_alert(message: String) -> void: var popup = AcceptDialog.new() popup.dialog_text = message EditorInterface.popup_dialog_centered(popup)