Hello there! I want to make random map generator that contains plots of different sizes like in SCP-3008. I got only this script that works if all plots are 50x50 studs. But if I add plot with different size,script breaks.
local debris = game:GetService('Debris')
local mapmodule = require(game.ServerStorage.Modules.Map)
local mapfolder = workspace.Map
local wallsFolder = workspace.Walls
local StandartSize = 50
local foodScript = require(game.ReplicatedStorage.Modules.Food)
function Find(tbl,val)
for _, i in pairs(tbl) do
if i[1] == val[1] and i[2] == val[2] then
return true
end
end
return false
end
function isInRegion(c,a,b)
--a-=Vector3.new(0.1,0.1,0.1)
--a+=Vector3.new(0.1,0.1,0.1)
local PosCBetweenB = (c - b).Unit * (c - b).Magnitude
local PosCBetweenA = (c - a).Unit * (c - a).Magnitude
local PosBetween = (a - b).Unit * (a - b).Magnitude
if math.abs(PosCBetweenB.Z) < math.abs(PosBetween.Z) and math.abs(PosCBetweenA.Z) < math.abs(PosBetween.Z)
and math.abs(PosCBetweenB.X) < math.abs(PosBetween.X) and math.abs(PosCBetweenA.X) < math.abs(PosBetween.X) then
if a.X == c.X and a.Z ~= c.Z or
a.X ~= c.X and a.Z == c.Z and
b.X == c.X and b.Z ~= c.Z or
b.X ~= c.X and b.Z == c.Z then
return false
end
return true
else
return false
end
end
local function GetParentUntil(instance)
if instance and instance.Parent and instance.Parent:GetAttribute('Pickupable') or instance.Parent:GetAttribute('Model') then
return instance.Parent
elseif not instance then
return false
elseif instance.Parent == workspace or instance:GetAttribute('Location') then
return false
else
return GetParentUntil(instance.Parent)
end
end
function smallRound(num)
local drob = num - math.floor(num)
--if math.abs(drob) < 0.09 then
-- return math.abs( math.floor(num))
--end
--return math.floor(num)
if drob < 0.05 then
return math.floor(num)
end
return math.floor(num)
end
function checkOnCollision(vector1,vector2,list)
local selfV0 = vector1
local selfV1 = vector2
local sizeS = Vector3.new(math.abs(selfV0.X-selfV1.X),math.abs(selfV0.Y-selfV1.Y),math.abs(selfV0.Z-selfV1.Z))
local bottomLeftCornerSelf = selfV0
local topLeftCornerSelf = selfV0+Vector3.new(sizeS.X,0,0)
local bottomRightCornerSelf = selfV0 + Vector3.new(0,0,sizeS.Z)
local topRightCornerSelf = selfV1
for _, i in pairs(list) do
local v0 = i[1]
local v1 = i[2]
local size = Vector3.new(math.abs(v0.X-v1.X),0,math.abs(v0.Z-v1.Z))
local bottomLeftCorner = v0
local topLeftCorner = v0+Vector3.new(size.X,0,0)
local bottomRightCorner = v0 + Vector3.new(0,0,size.Z)
local topRightCorner = v1
local xmin = math.min(selfV0.X,selfV1.X)
local xmax = math.max(selfV0.X,selfV1.X)
local zmin = math.min(selfV0.Z,selfV1.Z)
local zmax = math.max(selfV0.Z,selfV1.Z)
local region = Region3.new(v0+Vector3.new(-0.1,10,-0.2),v1+Vector3.new(0.1,10,0.1))
local totalFalse = 0
local isBetween0 = isInRegion(bottomLeftCornerSelf,v0,v1)
local isBetween1 = isInRegion(topLeftCornerSelf,v0,v1)
local isBetween2 = isInRegion(bottomRightCornerSelf,v0,v1)
local isBetween3 = isInRegion(topRightCornerSelf,v0,v1)
if isBetween0 or isBetween1 or isBetween2 or isBetween3 or totalFalse >= 4 then
return true,isBetween0,isBetween1,isBetween2,isBetween3,totalFalse
else
--return false
end
end
return false
end
function getLocationPos(list,x,z)
local possibleLocations = {}
local pos1
local pos2
for _, i in pairs(list) do
local v0 = i[1]
local v1 = i[2]
local size = Vector3.new(math.abs(v1.X-v0.X),0,math.abs(v1.Z-v0.Z))
local bottomLeftCorner = v0
local topLeftCorner = v0+Vector3.new(size.X,0,0)
local bottomRightCorner = v0 + Vector3.new(0,0,size.Z)
local topRightCorner = v1
for _, i in pairs(game.ServerStorage.Locations:GetChildren()) do
local iSize = i:GetExtentsSize()
pos1 = bottomLeftCorner+Vector3.new(0,0,iSize.Z)
pos2 = bottomLeftCorner+Vector3.new(iSize.X,0,iSize.Z*2)
local isCollides,a0,a1,a2,a3,f = checkOnCollision(pos1,pos2,list)
if not isCollides then
if pos1.X <= x and pos1.Z <= z and pos2.X <= x and pos2.Z <= z then
table.insert(possibleLocations,{i.Name,pos1})
continue
end
end
pos1 = bottomLeftCorner+Vector3.new(iSize.X,0,0)
pos2 = bottomLeftCorner+Vector3.new(iSize.X*2,0,iSize.Z)
local isCollides,a0,a1,a2,a3,f = checkOnCollision(pos1,pos2,list)
--print(a0,a1,a2,a3,f)
if not isCollides then
if pos1.X <= x and pos1.Z <= z and pos2.X <= x and pos2.Z <= z then
table.insert(possibleLocations,{i.Name,pos1})
continue
end
end
end
for _, i in pairs(possibleLocations) do
local locationName,pos = mapmodule.ChooseRandomLocationOfList(possibleLocations)
if locationName then
local location = game.ServerStorage.Locations[locationName]:Clone()
location:SetPrimaryPartCFrame(CFrame.new(pos))
location.Parent = workspace.Map
AnalizePlot(location)
return location,pos1,pos2
end
end
end
return false
end
function Standart(xsize,zsize)
workspace.MapLoaded.Value = false
local occupied = {}
mapfolder:ClearAllChildren()
wallsFolder:ClearAllChildren()
local x = 0
local MaxXmult = 1
local xMultiplier
local zMultiplier
local plots = {}
while x < xsize*zsize do
if #occupied > 0 then
local location,pos1,pos2 = getLocationPos(occupied,xsize,zsize)
if pos1 and pos2 then
table.insert(occupied,{pos1,pos2})
else
break
end
else
local location = game.ServerStorage.Locations:GetChildren()[math.random(1,#game.ServerStorage.Locations:GetChildren())]:Clone()
print('An')
local size = location:GetExtentsSize()
--location.Parent = workspace.Map
--location:SetPrimaryPartCFrame(CFrame.new(Vector3.new(0,0,0)))
table.insert(occupied,{Vector3.new(0,0,0),Vector3.new(0+size.X,0,size.Z)})
end
wait()
x+=1
end
local xmapsize = xsize
local zmapSize = zsize
local westWall = Instance.new('Part',wallsFolder) ; westWall.Anchored = true ; westWall.Size = Vector3.new(10,500,zsize*StandartSize+100)
local eastWall = Instance.new('Part',wallsFolder) ; eastWall.Anchored = true ; eastWall.Size = Vector3.new(10,500,zsize*StandartSize+100)
local southWall = Instance.new('Part',wallsFolder) ; southWall.Anchored = true ; southWall.Size = Vector3.new(xsize*StandartSize+100,500,10)
local northWall = Instance.new('Part',wallsFolder) ; northWall.Anchored = true ; northWall.Size = Vector3.new(xsize*StandartSize+100,500,10)
westWall.Position = Vector3.new(xmapsize + 5,0,zmapSize/2)
eastWall.Position = Vector3.new(-5,0,zmapSize/2)
southWall.Position = Vector3.new(xmapsize/2,0,zmapSize+5)
northWall.Position = Vector3.new(xmapsize/2,0,-5)
local roof = Instance.new('Part',wallsFolder) ; roof.Anchored = true ; roof.Size = Vector3.new(xmapsize+10,10,zmapSize+10)
roof.Position = Vector3.new(xmapsize/2,250+5,zmapSize/2)
workspace.MapLoaded.Value = true
end
script.Parent.Event:Connect(function(xsize,zsize,roadSize)
Standart(xsize,zsize)
end)
The problem is I dont know how to properly check on collision with plots.