--[[ diag_elevation.luau -- measure the vertical relationship between the wangan mainline and the Daikoku PA, so the "elevate the highway over the PA" rebuild can be designed from real numbers instead of guesses. Reports, for the stretch of mainline nearest the PA: * the deck Y profile (is it flat? already climbing? in a tunnel?) * which SIDE of the carriageway the PA sits on, per sample * perpendicular distance from the mainline centreline to the PA centre * terrain/ground height under the PA and under the mainline Read-only. ]] local RS = game:GetService("ReplicatedStorage") local Workspace = game:GetService("Workspace") local Circuit = require(RS:WaitForChild("Shared"):WaitForChild("Circuit")) local samples = Circuit.samples local c = Circuit.PA_CENTER local n = #samples -- Nearest non-tunnel sample = where planPA anchors the junctions. local bestIdx, bestD = 1, math.huge for i, s in ipairs(samples) do local d = (Vector3.new(s.pos.X, 0, s.pos.Z) - Vector3.new(c.X, 0, c.Z)).Magnitude if not s.tunnel and d < bestD then bestIdx, bestD = i, d end end -- Ground probe: ray straight down, ignoring the built map so we hit terrain. local map = Workspace:FindFirstChild("Map") local rp = RaycastParams.new() rp.FilterType = Enum.RaycastFilterType.Exclude rp.FilterDescendantsInstances = map and { map } or {} local function groundY(x, z, fromY) local hit = Workspace:Raycast(Vector3.new(x, fromY, z), Vector3.new(0, -4000, 0), rp) return hit and math.floor(hit.Position.Y * 10) / 10 or nil end local rows = {} for k = -30, 30 do local i = ((bestIdx + k - 1) % n) + 1 local s = samples[i] local nxt = samples[(i % n) + 1] local fwd = (nxt.pos - s.pos) fwd = Vector3.new(fwd.X, 0, fwd.Z) if fwd.Magnitude < 0.01 then continue end fwd = fwd.Unit local right = Vector3.new(-fwd.Z, 0, fwd.X) local toPA = Vector3.new(c.X - s.pos.X, 0, c.Z - s.pos.Z) table.insert(rows, { k = k, i = i, y = math.floor(s.pos.Y * 10) / 10, tun = s.tunnel and 1 or 0, -- +1 => PA is to the RIGHT of travel, -1 => LEFT side = (toPA.Unit:Dot(right) >= 0) and 1 or -1, -- signed perpendicular offset and along-track offset to the PA centre perp = math.floor(toPA:Dot(right)), along = math.floor(toPA:Dot(fwd)), dist = math.floor(toPA.Magnitude), }) end local ys = {} for _, r in ipairs(rows) do table.insert(ys, r.y) end table.sort(ys) return game:GetService("HttpService"):JSONEncode({ bestIdx = bestIdx, bestDist = math.floor(bestD), paY = c.Y, mainYmin = ys[1], mainYmax = ys[#ys], groundUnderPA = groundY(c.X, c.Z, c.Y + 500), groundUnderMain = groundY(samples[bestIdx].pos.X, samples[bestIdx].pos.Z, samples[bestIdx].pos.Y + 500), ringRadius = (require(RS.Shared.Circuit) and Circuit.PA_RADIUS + 130) or 0, rows = rows, })