--[[ diag_paexit2.luau -- follow-up: the first pass looked for a "Road" folder, but the map's mainline lives under "Expressway". Also resolve which of the two ramps is the way OUT (the off-ramp rejoins the mainline), and give the pad-relative direction in terms the player can act on. ]] local Workspace = game:GetService("Workspace") local out = {} local function log(s) table.insert(out, s) end local map = Workspace:FindFirstChild("Map") if not map then return "FATAL: no Map" end local pad = map:FindFirstChild("SpawnPad", true) if not pad then return "FATAL: no SpawnPad" end local function bearing(from, to) local d = Vector3.new(to.X - from.X, 0, to.Z - from.Z) if d.Magnitude < 0.01 then return "--", 0, 0 end local deg = math.deg(math.atan2(d.X, -d.Z)) if deg < 0 then deg += 360 end local names = { "North", "North-East", "East", "South-East", "South", "South-West", "West", "North-West" } return names[math.floor(((deg + 22.5) % 360) / 45) + 1], d.Magnitude, deg end local expw = map:FindFirstChild("Expressway") log(string.format("pad at (%.0f, %.0f, %.0f)", pad.Position.X, pad.Position.Y, pad.Position.Z)) log("") if expw then local nearest, nearestD local count = 0 for _, d in ipairs(expw:GetDescendants()) do if d:IsA("BasePart") then count += 1 local dist = (Vector3.new(d.Position.X - pad.Position.X, 0, d.Position.Z - pad.Position.Z)).Magnitude if not nearestD or dist < nearestD then nearestD, nearest = dist, d end end end log(string.format("Expressway: %d parts", count)) if nearest then local dir, dist = bearing(pad.Position, nearest.Position) log( string.format( " nearest mainline part '%s' (%.0f, %.0f, %.0f)", nearest.Name, nearest.Position.X, nearest.Position.Y, nearest.Position.Z ) ) log(string.format(" -> %s of pad, %.0f studs, Y %+.0f vs pad", dir, dist, nearest.Position.Y - pad.Position.Y)) end end -- Ramp detail: where each ramp STARTS (ring end) and ENDS (mainline end). log("") log("--- ramp geometry (which way out) ---") for _, nm in ipairs({ "PAOnRamp", "PAOffRamp" }) do local p = map:FindFirstChild(nm, true) if not p then log(nm .. ": NOT FOUND") continue end -- A ramp deck is built with lookAt(mid, road): its LookVector points at the -- mainline end. Report both ends so the direction of travel is unambiguous. local halfLen = p.Size.Z / 2 local toRoad = p.CFrame * CFrame.new(0, 0, -halfLen) local toRing = p.CFrame * CFrame.new(0, 0, halfLen) local dir, dist = bearing(pad.Position, p.Position) log(string.format("%s centre %s of pad, %.0f studs", nm, dir, dist)) log(string.format(" ring end (%.0f, %.0f, %.0f)", toRing.Position.X, toRing.Position.Y, toRing.Position.Z)) log(string.format(" mainline end (%.0f, %.0f, %.0f)", toRoad.Position.X, toRoad.Position.Y, toRoad.Position.Z)) log(string.format(" length %.0f studs, width %.0f", p.Size.Z, p.Size.X)) end -- How far from the pad edge to the ring, in each cardinal direction? log("") log("--- getting from pad to ring ---") log(string.format("pad is %.0f x %.0f, so its edge is %.0f studs from centre", pad.Size.X, pad.Size.Z, pad.Size.X / 2)) local ringParts = {} for _, d in ipairs(map:GetDescendants()) do if d:IsA("BasePart") and d.Name:find("Ring") then table.insert(ringParts, d) end end if #ringParts > 0 then local minR, maxR = math.huge, 0 for _, p in ipairs(ringParts) do local r = (Vector3.new(p.Position.X - pad.Position.X, 0, p.Position.Z - pad.Position.Z)).Magnitude minR = math.min(minR, r) maxR = math.max(maxR, r) end log( string.format( "ring road lies %.0f..%.0f studs from the pad centre, in every direction (it encircles the lot)", minR, maxR ) ) end return table.concat(out, "\n")