-- Measure the envelope a SIMPLE straight slip-ramp must live in. -- User's drawing: short stubs peeling off the mainline at a shallow angle, -- running roughly PARALLEL to the highway in the strip between the mainline -- edge and the PA lot's north edge, descending an S onto the apron. -- -- We need to know, in real numbers: -- 1. Where the mainline actually runs across the PA frontage (samples, -- heading, deck Y) -- is it straight enough for a parallel slip? -- 2. Where the lot's north edge is, and how wide the clear strip is -- between the mainline's south edge and that lot edge. -- 3. Deck Y vs apron Y (the height the S-curve must lose). -- 4. What is already sitting in that strip that a ramp would hit. local RS = game:GetService("ReplicatedStorage") local HttpService = game:GetService("HttpService") local Circuit = require(RS:WaitForChild("Shared"):WaitForChild("Circuit")) local samples = Circuit.samples local n = #samples local c = Circuit.PA_CENTER -- Nearest mainline sample to the PA centre. local bestIdx, bestD = 1, math.huge for i = 1, n do local p = samples[i].pos local d = (Vector3.new(p.X, 0, p.Z) - Vector3.new(c.X, 0, c.Z)).Magnitude if d < bestD then bestD, bestIdx = d, i end end -- Walk a band around the PA frontage and report heading + deck Y, so we can -- see how straight the mainline is and where a parallel slip could sit. local band = {} for k = -40, 40, 5 do local i = ((bestIdx - 1 + k) % n) + 1 local s = samples[i].pos local nx = samples[(i % n) + 1].pos local hdg = math.deg(math.atan2(nx.Z - s.Z, nx.X - s.X)) local d = (Vector3.new(s.X, 0, s.Z) - Vector3.new(c.X, 0, c.Z)).Magnitude table.insert(band, { k = k, idx = i, x = math.floor(s.X), y = math.floor(s.Y + 0.5), z = math.floor(s.Z), hdg = math.floor(hdg + 0.5), distPA = math.floor(d), }) end -- The apron / lot floor: bounds and surface height. local map = workspace:FindFirstChild("Map") local floor = map and map:FindFirstChild("PAFloor", true) local lot = nil if floor then lot = { name = floor.Name, surfaceY = floor.Position.Y + floor.Size.Y / 2, x_min = math.floor(floor.Position.X - floor.Size.X / 2), x_max = math.floor(floor.Position.X + floor.Size.X / 2), z_min = math.floor(floor.Position.Z - floor.Size.Z / 2), z_max = math.floor(floor.Position.Z + floor.Size.Z / 2), } end -- What already occupies the strip between the mainline and the lot's north -- edge? Anything here is a collision candidate for a parallel slip ramp. -- Strip = north third of the lot bbox, i.e. Z above (z_max - 220). local obstacles = {} if lot then local stripZ = lot.z_max - 220 for _, d in ipairs(workspace:GetDescendants()) do if d:IsA("BasePart") then local p = d.Position if p.Z >= stripZ and p.Z <= lot.z_max + 160 and p.X >= lot.x_min - 60 and p.X <= lot.x_max + 60 then local key = d.Name local e = obstacles[key] if not e then e = { n = 0, x_min = 1e9, x_max = -1e9, z_min = 1e9, z_max = -1e9, y_max = -1e9 } obstacles[key] = e end e.n += 1 e.x_min = math.min(e.x_min, p.X); e.x_max = math.max(e.x_max, p.X) e.z_min = math.min(e.z_min, p.Z); e.z_max = math.max(e.z_max, p.Z) e.y_max = math.max(e.y_max, p.Y + d.Size.Y / 2) end end end end local obsOut = {} for k, e in pairs(obstacles) do table.insert(obsOut, { name = k, n = e.n, x = math.floor(e.x_min) .. ".." .. math.floor(e.x_max), z = math.floor(e.z_min) .. ".." .. math.floor(e.z_max), ytop = math.floor(e.y_max), }) end table.sort(obsOut, function(a, b) return a.n > b.n end) while #obsOut > 25 do table.remove(obsOut) end return HttpService:JSONEncode({ bestIdx = bestIdx, nearestDist = math.floor(bestD), pa_center = { math.floor(c.X), math.floor(c.Y), math.floor(c.Z) }, pa_radius = Circuit.PA_RADIUS, band = band, lot = lot, strip_obstacles = obsOut, })