extends Node const ROOM_HEIGHT: float = 4.0 const WALL_THICKNESS: float = 0.4 const CORRIDOR_WIDTH: float = 4.0 var rng: RandomNumberGenerator var rooms: Array = [] func generate(parent: Node3D, seed: int, scale_difficulty: float = 1.0) -> Dictionary: rng = RandomNumberGenerator.new() rng.seed = seed rooms.clear() var room_count: int = rng.randi_range(5, 8) var pos := Vector3(0, 0, 0) var dir := Vector3(0, 0, -1) for i in range(room_count): var w: float = rng.randf_range(8.0, 14.0) var d: float = rng.randf_range(8.0, 14.0) rooms.append({"pos": pos, "size": Vector3(w, ROOM_HEIGHT, d)}) if i == room_count - 1: break var corridor_len: float = rng.randf_range(4.0, 8.0) var step: Vector3 = dir * (max(w, d) * 0.5 + corridor_len + 4.0) pos += step if rng.randf() < 0.5: var rotate_left: bool = rng.randf() < 0.5 dir = dir.rotated(Vector3.UP, PI * 0.5 * (1 if rotate_left else -1)) _build_geometry(parent) return {"rooms": rooms, "spawn": rooms[0].pos + Vector3(0, 1, 0), "boss": rooms[-1].pos} func _build_geometry(parent: Node3D) -> void: for r in rooms: _build_room(parent, r.pos, r.size) for i in range(rooms.size() - 1): _build_corridor(parent, rooms[i].pos, rooms[i + 1].pos) func _build_room(parent: Node3D, center: Vector3, size: Vector3) -> void: _add_floor(parent, center, Vector2(size.x, size.z)) var hw: float = size.x * 0.5 var hd: float = size.z * 0.5 _add_wall(parent, center + Vector3(0, ROOM_HEIGHT * 0.5, -hd), Vector3(size.x, ROOM_HEIGHT, WALL_THICKNESS)) _add_wall(parent, center + Vector3(0, ROOM_HEIGHT * 0.5, hd), Vector3(size.x, ROOM_HEIGHT, WALL_THICKNESS)) _add_wall(parent, center + Vector3(-hw, ROOM_HEIGHT * 0.5, 0), Vector3(WALL_THICKNESS, ROOM_HEIGHT, size.z)) _add_wall(parent, center + Vector3(hw, ROOM_HEIGHT * 0.5, 0), Vector3(WALL_THICKNESS, ROOM_HEIGHT, size.z)) func _build_corridor(parent: Node3D, from: Vector3, to: Vector3) -> void: var mid: Vector3 = (from + to) * 0.5 var d: float = from.distance_to(to) var dir: Vector3 = (to - from).normalized() _add_floor(parent, Vector3(mid.x, 0, mid.z), Vector2(d, CORRIDOR_WIDTH) if abs(dir.x) > abs(dir.z) else Vector2(CORRIDOR_WIDTH, d)) func _add_floor(parent: Node3D, center: Vector3, size: Vector2) -> void: var body := StaticBody3D.new() body.collision_layer = 1 body.collision_mask = 0 var mesh := MeshInstance3D.new() var box := BoxMesh.new() box.size = Vector3(size.x, 0.4, size.y) mesh.mesh = box var mat := StandardMaterial3D.new() mat.albedo_color = Color(0.25, 0.22, 0.2) mesh.material_override = mat mesh.position = Vector3(0, -0.2, 0) var col := CollisionShape3D.new() var shape := BoxShape3D.new() shape.size = Vector3(size.x, 0.4, size.y) col.shape = shape col.position = Vector3(0, -0.2, 0) body.add_child(mesh) body.add_child(col) body.position = center parent.add_child(body) func _add_wall(parent: Node3D, center: Vector3, size: Vector3) -> void: var body := StaticBody3D.new() body.collision_layer = 1 body.collision_mask = 0 var mesh := MeshInstance3D.new() var box := BoxMesh.new() box.size = size mesh.mesh = box var mat := StandardMaterial3D.new() mat.albedo_color = Color(0.35, 0.32, 0.28) mesh.material_override = mat var col := CollisionShape3D.new() var shape := BoxShape3D.new() shape.size = size col.shape = shape body.add_child(mesh) body.add_child(col) body.position = center parent.add_child(body)