-- READ-ONLY inventory of the Daikoku Futo PA area so the capture camera can be -- anchored to real geometry instead of guessed coordinates. -- -- Wanted: -- * what top-level containers/models exist for the PA -- * every distinct part-name PREFIX in the PA region, with counts -- * the PA's world-space bounding box + centre (for framing) -- * key landmarks: slip ramps, apron/parking deck, any building/structure local out = {} local function say(s) table.insert(out, s) end local map = workspace:FindFirstChild("Map") if not map then return "Map MISSING" end -- 1. Top-level structure of Map say("=== Map children ===") for _, c in ipairs(map:GetChildren()) do local n = 0 for _, d in ipairs(c:GetDescendants()) do if d:IsA("BasePart") then n += 1 end end say((" %s (%s) parts=%d"):format(c.Name, c.ClassName, n)) end -- 2. Anything whose name mentions PA / Daikoku / parking say("=== named PA-ish objects (models/folders) ===") local seen = 0 for _, d in ipairs(map:GetDescendants()) do if not d:IsA("BasePart") then local nm = d.Name if nm:match("PA") or nm:lower():match("daikoku") or nm:lower():match("park") or nm:lower():match("apron") or nm:lower():match("rest") then local n = 0 for _, x in ipairs(d:GetDescendants()) do if x:IsA("BasePart") then n += 1 end end say((" %s (%s) parts=%d parent=%s"):format(d.Name, d.ClassName, n, d.Parent.Name)) seen += 1 if seen > 40 then say(" ...(truncated)") break end end end end if seen == 0 then say(" (none found by name)") end -- 3. Locate the PA by its slip ramps: the apron is where the ramps land. local land = {} for _, s in ipairs({ "PAWestSlip", "PAEastSlip" }) do local best, bestK = nil, -1 for _, d in ipairs(map:GetDescendants()) do if d:IsA("BasePart") then local k = d.Name:match("^" .. s .. "_Deck_(%d+)$") if k and tonumber(k) > bestK then bestK = tonumber(k); best = d end end end if best then land[s] = best.Position say(("%s landing: (%.0f, %.0f, %.0f)"):format(s, best.Position.X, best.Position.Y, best.Position.Z)) end end local anchor if land.PAWestSlip and land.PAEastSlip then anchor = (land.PAWestSlip + land.PAEastSlip) / 2 elseif land.PAWestSlip then anchor = land.PAWestSlip elseif land.PAEastSlip then anchor = land.PAEastSlip end if not anchor then return table.concat(out, "\n") .. "\nNO SLIP LANDINGS -> cannot anchor" end say(("PA anchor (between landings): (%.0f, %.0f, %.0f)"):format(anchor.X, anchor.Y, anchor.Z)) -- 4. Every part within 1400 studs of the anchor, grouped by name prefix. local function flat(v) return Vector3.new(v.X, 0, v.Z) end local counts, mins, maxs = {}, {}, {} local lo = Vector3.new(math.huge, math.huge, math.huge) local hi = Vector3.new(-math.huge, -math.huge, -math.huge) local total = 0 for _, d in ipairs(map:GetDescendants()) do if d:IsA("BasePart") then if (flat(d.Position) - flat(anchor)).Magnitude < 1400 then total += 1 -- prefix = name with trailing _ stripped local pre = d.Name:gsub("_%d+$", "") counts[pre] = (counts[pre] or 0) + 1 lo = Vector3.new(math.min(lo.X, d.Position.X), math.min(lo.Y, d.Position.Y), math.min(lo.Z, d.Position.Z)) hi = Vector3.new(math.max(hi.X, d.Position.X), math.max(hi.Y, d.Position.Y), math.max(hi.Z, d.Position.Z)) end end end say(("=== %d parts within 1400 studs of PA anchor ==="):format(total)) local keys = {} for k in pairs(counts) do table.insert(keys, k) end table.sort(keys, function(a, b) return counts[a] > counts[b] end) for idx, k in ipairs(keys) do if idx > 30 then say((" ...and %d more prefixes"):format(#keys - 30)) break end say((" %-28s %d"):format(k, counts[k])) end say(("bbox: (%.0f,%.0f,%.0f) .. (%.0f,%.0f,%.0f)"):format(lo.X, lo.Y, lo.Z, hi.X, hi.Y, hi.Z)) say(("bbox size: %.0f x %.0f x %.0f"):format(hi.X - lo.X, hi.Y - lo.Y, hi.Z - lo.Z)) local ctr = (lo + hi) / 2 say(("bbox centre: (%.0f, %.0f, %.0f)"):format(ctr.X, ctr.Y, ctr.Z)) return table.concat(out, "\n")