@tool ## Editor-time preview for a single ADT tile. extends Node3D const PREVIEW_NODE_NAME := "__adt_tile_preview__" const ADT_BUILDER_SCRIPT := preload("res://addons/mpq_extractor/loaders/adt_builder.gd") @export var extracted_dir: String = "res://extracted" @export var map_name: String = "Azeroth" @export var tile_x: int = 32 @export var tile_y: int = 48 @export var auto_rebuild_in_editor: bool = true @export var reload_now: bool = false var _last_signature := "" var _rebuild_queued := false func _ready() -> void: set_process(true) _queue_rebuild() func _process(_delta: float) -> void: if reload_now: reload_now = false _queue_rebuild() if Engine.is_editor_hint() and auto_rebuild_in_editor: var current_signature := _make_signature() if current_signature != _last_signature: _queue_rebuild() func _queue_rebuild() -> void: if _rebuild_queued or not is_inside_tree(): return _rebuild_queued = true call_deferred("_rebuild_preview") func _rebuild_preview() -> void: _rebuild_queued = false _clear_preview() _last_signature = _make_signature() if not ClassDB.class_exists("ADTLoader"): push_warning("ADTLoader not found. Rebuild GDExtension first.") return var abs_extracted := ProjectSettings.globalize_path(extracted_dir) var adt_path := "%s/World/Maps/%s/%s_%d_%d.adt" % [ abs_extracted, map_name, map_name, tile_x, tile_y ] if not FileAccess.file_exists(adt_path): push_warning("ADT not found: %s" % adt_path) return var loader = ClassDB.instantiate("ADTLoader") var data: Dictionary = loader.call("load_adt", adt_path) if data.is_empty() or not data.has("chunks"): push_warning("Failed to load ADT: %s" % adt_path) return var builder := ADT_BUILDER_SCRIPT.new() var terrain: Node3D = builder.build_scene(data, abs_extracted) terrain.name = PREVIEW_NODE_NAME add_child(terrain) func _clear_preview() -> void: var preview := get_node_or_null(PREVIEW_NODE_NAME) if preview: remove_child(preview) preview.free() func _make_signature() -> String: return "%s|%s|%d|%d" % [extracted_dir, map_name, tile_x, tile_y]