## Загрузчик Элвиннского леса — 3×3 ADT тайла из extracted/ extends Node3D 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" ## Центр Элвиннского леса (тайл 32,48), загружаем 3×3 вокруг него @export var center_x : int = 32 @export var center_y : int = 48 @export var radius : int = 1 ## 1 = 3×3, 2 = 5×5 func _ready() -> void: if not ClassDB.class_exists("ADTLoader"): push_error("ADTLoader не найден — пересобери GDExtension") return var abs_extracted := ProjectSettings.globalize_path(extracted_dir) print("Папка extracted: ", abs_extracted) var loader = ClassDB.instantiate("ADTLoader") var loaded := 0 for dy in range(-radius, radius + 1): for dx in range(-radius, radius + 1): var tx := center_x + dx var ty := center_y + dy var path := "%s/World/Maps/%s/%s_%d_%d.adt" % [ abs_extracted, map_name, map_name, tx, ty] print("Проверяю: ", path, " → ", FileAccess.file_exists(path)) if not FileAccess.file_exists(path): continue var data: Dictionary = loader.call("load_adt", path) if data.is_empty() or not data.has("chunks"): push_warning("Не удалось загрузить: ", path) continue # Debug first chunk of first tile only if loaded == 0: var chunks: Array = data.get("chunks", []) if chunks.size() > 0: var c0 = chunks[0] var origin0: Vector3 = c0.get("origin", Vector3.ZERO) var h: PackedFloat32Array = c0.get("heights", PackedFloat32Array()) print("DEBUG chunk[0] origin=", origin0) if h.size() > 0: print("DEBUG heights[0]=", h[0], " [72]=", h[72] if h.size()>72 else 0.0) var builder := ADT_BUILDER_SCRIPT.new() var terrain: Node3D = builder.build_scene(data, abs_extracted) add_child(terrain) loaded += 1 print("Загружен тайл %d,%d (%d чанков)" % [tx, ty, terrain.get_child_count()]) print("Всего тайлов загружено: ", loaded) # Print terrain AABB so you know where to fly await get_tree().process_frame var aabb := AABB(); var first := true for child in get_children(): if not (child is Node3D): continue for chunk in child.get_children(): if chunk is MeshInstance3D and chunk.mesh: var b: AABB = chunk.get_aabb() b.position += chunk.global_position if first: aabb = b; first = false else: aabb = aabb.merge(b) var bad_count := 0 for child in get_children(): if not (child is Node3D): continue for chunk in child.get_children(): if not (chunk is MeshInstance3D): continue var gpos: Vector3 = chunk.global_position var local_aabb: AABB = chunk.get_aabb() if abs(gpos.y) > 1000.0 or abs(local_aabb.position.y) > 1000.0 or local_aabb.size.y > 1000.0: if bad_count < 5: print("BAD chunk ", chunk.name, " gpos=", gpos, " local_aabb=", local_aabb) bad_count += 1 if bad_count > 0: print("Total bad chunks: ", bad_count) if not first: print("Terrain AABB center=", aabb.get_center(), " size=", aabb.size) print("Fly to: ", aabb.get_center() + Vector3(0, aabb.size.length() * 0.3, 0))