This commit is contained in:
watrabi
2025-09-18 17:55:52 -04:00
commit 977f1ff4b8
15030 changed files with 17324420 additions and 0 deletions
+570
View File
@@ -0,0 +1,570 @@
-- Local function definitions
local c = game.Workspace.Terrain
local SetCell = c.SetCell
local GetCell = c.GetCell
local SetCells = c.SetCells
local AutoWedge = c.AutowedgeCells
-----------------
--DEFAULT VALUES-
-----------------
loaded = false
xpos = 0
zpos = 0
width = 512
length = 512
a = 30
f = 8
on = false
---------------
--PLUGIN SETUP-
---------------
self = PluginManager():CreatePlugin()
self.Deactivation:connect(function()
Off()
end)
toolbar = self:CreateToolbar("Terrain")
toolbarbutton = toolbar:CreateButton("", "Terrain Generator", "terrain.png")
toolbarbutton.Click:connect(function()
if on then
Off()
elseif loaded then
On()
end
end)
-----------------------
--FUNCTION DEFINITIONS-
-----------------------
--makes a column of blocks from 1 up to height at location (x,z) in cluster c
function coordHeight(x, z, height)
SetCells(c, Region3int16.new(Vector3int16.new(x, 1, z), Vector3int16.new(x, height, z)), 1, 0, 0)
end
--makes a heightmap for a layer of mountains (width x depth)
--with a width frequency wf and depthfrequency df (width should be divisible by wf, depth should be divisible by df) (for unsquished results, width/wf = depth/df)
--with a range of amplitudes between 0 and a
function mountLayer(width, depth, wf, df, a)
local heightmap = {}
for i = 0, width-1 do
heightmap[i] = {}
for k = 0, depth-1 do
heightmap[i][k] = 0
end
end
math.randomseed(tick())
local corners = {}
for i = 0,wf do
corners[i] = {}
for k = 0, df do
corners[i][k] = a*math.random()
end
end
for i = 0, wf do
corners[i][0] = 0
corners[i][math.floor(df)] = 0
end
for k = 0, df do
corners[0][k]=0
corners[math.floor(wf)][k]=0
end
for i = 0, width-(width/wf), width/wf do
for k = 0, depth-(depth/df), depth/df do
local c1 = corners[i/(width/wf)][k/(depth/df)]
local c2 = corners[i/(width/wf)][(k+depth/df)/(depth/df)]
local c3 = corners[(i+width/wf)/(width/wf)][k/(depth/df)]
local c4 = corners[(i+width/wf)/(width/wf)][(k+depth/df)/(depth/df)]
for x = i, i+(width/wf)-1 do
for z = k, k+(depth/df)-1 do
local avgc1c3 = (math.abs(x-i)*c3 + math.abs(x-(i+width/wf))*c1)/(width/wf)
local avgc2c4 = (math.abs(x-i)*c4 + math.abs(x-(i+width/wf))*c2)/(width/wf)
local avg = math.floor((math.abs(z-k)*avgc2c4 + math.abs(z-(k+depth/df))*avgc1c3)/(depth/df))
if (avg > 100) then
print(avg)
avg = 1
end
heightmap[x][z]= avg
end
end
end
end
return heightmap
end
--makes a shell around block at coordinate x, z using heightmap
function makeShell(x, z, heightmap, shellheightmap)
local originalheight = heightmap[x][z]
for i = x - 1, x + 1 do
for k = z - 1, z + 1 do
if shellheightmap[i][k] < originalheight then
for h = originalheight, shellheightmap[i][k] - 2, -1 do
if h > 0 then
SetCell(c, i, h, k, 1, 0, 0)
end
end
shellheightmap[i][k] = originalheight
end
end
end
return shellheightmap
end
function setCamera()
local currCamera = game.Workspace.CurrentCamera
currCamera.CoordinateFrame = CFrame.new(0, 400, 1600)
currCamera.Focus = CFrame.new(0, 255, 0)
end
function onGenerate()
generate.BorderColor3 = Color3.new(0, 0, 0)
generate.BackgroundColor3 = Color3.new(0.5, 0.5, 0.5)
generate.BackgroundTransparency = 0.5
frame.Visible = false
toolbarbutton:SetActive(false)
on = false
if g:FindFirstChild("gload") == nil then
gload = Instance.new("Frame", g)
gload.Name = "gload"
gload.Position = UDim2.new(0.4, 0, 0.025, 0)
gload.Size = UDim2.new(0.2, 0, 0.05, 0)
gload.BackgroundTransparency = 0.5
gfill = Instance.new("Frame", gload)
gfill.Name = "gfill"
gfill.Position = UDim2.new(0, 0, 0, 0)
gfill.Size = UDim2.new(0, 0, 1, 0)
gfill.BackgroundColor3 = Color3.new(1, 0.25, 0)
gfill.BackgroundTransparency = 0.5
gloadstatus = Instance.new("TextLabel", gload)
gloadstatus.Position = UDim2.new(0.4, 0, 0.4, 0)
gloadstatus.Size = UDim2.new(0.2, 0, 0.2, 0)
gloadstatus.Text = ""
gloadstatus.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
gloadstatus.TextColor3 = Color3.new(1, 1, 1)
gloadstatus.Font = Enum.Font.ArialBold
gloadstatus.FontSize = Enum.FontSize.Size14
gloadstatus.BorderColor3 = Color3.new(0, 0, 0)
gloadstatus.BackgroundTransparency = 1
else
gload = g:FindFirstChild("gload")
gfill = gload:FindFirstChild("gfill")
gload.Visible = 1
gfill.Visible = 1
gfill.Size = UDim2.new(0, 0, 1, 0)
gloadstatus.Text = ""
end
--Generate Terrain
-- offset terrain additionally by whatever the smallest cell is
--xpos2 = xpos + game.Workspace.Terrain.MaxExtents.Min.X
--zpos2 = zpos + game.Workspace.Terrain.MaxExtents.Min.Z
xpos2 = xpos - width/2
zpos2 = zpos - length/2
-- make sure we can see all the terrain
if game.Workspace.CurrentCamera.CoordinateFrame.p.Y < 255 then
setCamera()
end
--make 3 layers of mountains (you can change the frequency and amplitude of each layer and add or remove layers as you see fit (but don't forget to add the new layers to the loop below)
a1 = mountLayer(width, length, f*width/512, f*length/512, 3/5*a)
a2 = mountLayer(width, length, 2*f*width/512, 2*f*length/512, 2/5*a)
heightmap = {}
for x = 0, width - 1 do
heightmap[x + xpos2] = {}
for z = 0, length - 1 do
heightmap[x + xpos2][z + zpos2] = a1[x][z] + a2[x][z]
end
end
shellheightmap = {}
for x = 0, width - 1 do
shellheightmap[x + xpos2] = {}
for z = 0, length - 1 do
shellheightmap[x + xpos2][z + zpos2] = heightmap[x + xpos2][z + zpos2]
end
end
gprogress = 0
gloadstatus.Text = "Generating Terrain Shape..."
k = 1 + zpos2
local waitCount = 0
while k < length - 1 + zpos2 do
for x = 1 + xpos2, width - 2 + xpos2 do
coordHeight(x, k, heightmap[x][k])
shellheightmap = makeShell(x, k, heightmap, shellheightmap)
end
k = k + 1
gprogress = gprogress + 2/(length * 3)
gfill.Size = UDim2.new(gprogress, 0, 1, 0)
if waitCount > 5 then waitCount = 0 wait(0.01) else waitCount = waitCount + 1 end
end
gloadstatus.Text = "Smoothing Terrain..."
k = 1 + zpos2
waitCount = 0
local maxHeight = -1
local oldK = k
while k < length - 1 + zpos2 do
for x = 1 + xpos2, width - 2 + xpos2 do
height = shellheightmap[x][k]
if height == nil then
height = -1
end
if height > maxHeight then
maxHeight = height
end
end
k = k + 1
gprogress = gprogress + 1/(length * 3)
gfill.Size = UDim2.new(gprogress, 0, 1, 0)
if waitCount > 10 then
waitCount = 0
AutoWedge(c, Region3int16.new(Vector3int16.new(1 + xpos2, 0, oldK), Vector3int16.new(width - 2 + xpos2, maxHeight, k)))
oldK = k+1
maxHeight = -1
wait()
else waitCount = waitCount + 1 end
if k == length - 2 + zpos2 then
AutoWedge(c, Region3int16.new(Vector3int16.new(1 + xpos2, 0, oldK), Vector3int16.new(width - 2 + xpos2, maxHeight, k)))
gfill.Parent.Visible = false
gfill.Visible = false
end
end
--Generate Terrain End
end
function onReset()
reset.BorderColor3 = Color3.new(0, 0, 0)
reset.BackgroundColor3 = Color3.new(0.5, 0.5, 0.5)
reset.BackgroundTransparency = 0.5
frame.Visible = false
toolbarbutton:SetActive(false)
on = false
if g:FindFirstChild("rload") == nil then
rload = Instance.new("Frame", g)
rload.Name = "rload"
rload.Position = UDim2.new(0.4, 0, 0.025, 0)
rload.Size = UDim2.new(0.2, 0, 0.05, 0)
rload.BackgroundTransparency = 0.5
rfill = Instance.new("Frame", rload)
rfill.Name = "rfill"
rfill.Position = UDim2.new(0, 0, 0, 0)
rfill.Size = UDim2.new(0, 0, 1, 0)
rfill.BackgroundColor3 = Color3.new(1, 0.25, 0)
rfill.BackgroundTransparency = 0.5
else
rload = g:FindFirstChild("rload")
rfill = rload:FindFirstChild("rfill")
rload.Visible = 1
rfill.Visible = 1
rfill.Size = UDim2.new(0, 0, 1, 0)
end
--Erase Terrain
local xMax = c.MaxExtents.Max.X
local yMax = c.MaxExtents.Max.Y
local zMax = c.MaxExtents.Max.Z
local xMin = c.MaxExtents.Min.X
local yMin = c.MaxExtents.Min.Y
local zMin = c.MaxExtents.Min.Z
rprogress = 0
local waitCount = 0
z = zMax
while z >= zMin do
SetCells(c, Region3int16.new(Vector3int16.new(xMin, yMin, z), Vector3int16.new(xMax, yMax, z)), 0, 0, 0)
z = z - 1
rprogress = rprogress + 1/(zMax - zMin + 1)
rfill.Size = UDim2.new(rprogress, 0, 1, 0)
if z == zMin then
reset.BorderColor3 = Color3.new(0, 0, 0)
rfill.Parent.Visible = false
rfill.Visible = false
end
if waitCount > 5 then waitCount = 0 wait(0.001) else waitCount = waitCount + 1 end
end
--Erase Terrain End
end
function On()
self:Activate(true)
toolbarbutton:SetActive(true)
frame.Visible = true
for w = 0, 0.6, 0.1 do
frame.Size = UDim2.new(w, 0, w + 0.2, 0)
wait(0.0000001)
end
title.Text = "Terrain Generation"
xposl.Text = "X-Offset: "..xpos
zposl.Text = "Z-Offset: "..zpos
widthl.Text = "Width: "..width
lengthl.Text = "Length: "..length
ampl.Text = "Amplitude: "..a
freql.Text = "Frequency: "..f
generate.Text = "Generate"
reset.Text = "Reset"
on = true
end
function Off()
toolbarbutton:SetActive(false)
title.Text = ""
xposl.Text = ""
zposl.Text = ""
widthl.Text = ""
lengthl.Text = ""
ampl.Text = ""
freql.Text = ""
generate.Text = ""
reset.Text = ""
for w = 0.6, 0, -0.1 do
frame.Size = UDim2.new(w, 0, w + 0.2, 0)
wait(0.0000001)
end
frame.Visible = false
on = false
end
------
--GUI-
------
--load library for with sliders
local RbxGui = LoadLibrary("RbxGui")
--screengui
g = Instance.new("ScreenGui", game:GetService("CoreGui"))
--frame
frame = Instance.new("Frame", g)
frame.Size = UDim2.new(0.6, 0, 0.8, 0)
frame.Position = UDim2.new(0.2, 0, 0.1, 0)
frame.BackgroundTransparency = 0.5
frame.Visible = false
--title
title = Instance.new("TextLabel", frame)
title.Position = UDim2.new(0.4, 0, 0.05, 0)
title.Size = UDim2.new(0.2, 0, 0.05, 0)
title.Text = ""
title.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
title.TextColor3 = Color3.new(1, 1, 1)
title.Font = Enum.Font.ArialBold
title.FontSize = Enum.FontSize.Size24
title.BorderColor3 = Color3.new(0, 0, 0)
title.BackgroundTransparency = 1
--current xoffset display label
xposl = Instance.new("TextLabel", frame)
xposl.Position = UDim2.new(0.05, 0, 0.2, 0)
xposl.Size = UDim2.new(0.1, 0, 0.05, 0)
xposl.Text = ""
xposl.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
xposl.TextColor3 = Color3.new(1, 1, 1)
xposl.Font = Enum.Font.ArialBold
xposl.FontSize = Enum.FontSize.Size14
xposl.BorderColor3 = Color3.new(0, 0, 0)
xposl.BackgroundTransparency = 1
--xoffset slider
xposSliderGui, xposSliderPosition = RbxGui.CreateSlider(128, 0, UDim2.new(0.2, 0, 0.22, 0))
xposSliderGui.Parent = frame
xposBar = xposSliderGui:FindFirstChild("Bar")
xposBar.Size = UDim2.new(0.75, 0, 0, 5)
xposSliderPosition.Value = (xpos+252)/4 + 1
xposSliderPosition.Changed:connect(function()
xpos = (xposSliderPosition.Value - 1) * 4 - 252
xposl.Text = "X-Offset: "..xpos
end)
--current zoffset display label
zposl = Instance.new("TextLabel", frame)
zposl.Position = UDim2.new(0.05, 0, 0.3, 0)
zposl.Size = UDim2.new(0.1, 0, 0.05, 0)
zposl.Text = ""
zposl.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
zposl.TextColor3 = Color3.new(1, 1, 1)
zposl.Font = Enum.Font.ArialBold
zposl.FontSize = Enum.FontSize.Size14
zposl.BorderColor3 = Color3.new(0, 0, 0)
zposl.BackgroundTransparency = 1
--zoffset slider
zposSliderGui, zposSliderPosition = RbxGui.CreateSlider(128, 0, UDim2.new(0.2, 0, 0.32, 0))
zposSliderGui.Parent = frame
zposBar = zposSliderGui:FindFirstChild("Bar")
zposBar.Size = UDim2.new(0.75, 0, 0, 5)
zposSliderPosition.Value = (zpos+252)/4 + 1
zposSliderPosition.Changed:connect(function()
zpos = (zposSliderPosition.Value - 1) * 4 - 252
zposl.Text = "Z-Offset: "..zpos
end)
--current width display label
widthl = Instance.new("TextLabel", frame)
widthl.Position = UDim2.new(0.05, 0, 0.4, 0)
widthl.Size = UDim2.new(0.1, 0, 0.05, 0)
widthl.Text = ""
widthl.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
widthl.TextColor3 = Color3.new(1, 1, 1)
widthl.Font = Enum.Font.ArialBold
widthl.FontSize = Enum.FontSize.Size14
widthl.BorderColor3 = Color3.new(0, 0, 0)
widthl.BackgroundTransparency = 1
--width slider
widthSliderGui, widthSliderPosition = RbxGui.CreateSlider(4, 0, UDim2.new(0.2, 0, 0.42, 0))
widthSliderGui.Parent = frame
widthbar = widthSliderGui:FindFirstChild("Bar")
widthbar.Size = UDim2.new(0.75, 0, 0, 5)
widthSliderPosition.Value = 4
widthSliderPosition.Changed:connect(function()
width = math.pow(2, widthSliderPosition.Value + 5)
widthl.Text = "Width: "..width
end)
--current length display label
lengthl = Instance.new("TextLabel", frame)
lengthl.Position = UDim2.new(0.05, 0, 0.5, 0)
lengthl.Size = UDim2.new(0.1, 0, 0.05, 0)
lengthl.Text = ""
lengthl.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
lengthl.TextColor3 = Color3.new(1, 1, 1)
lengthl.Font = Enum.Font.ArialBold
lengthl.FontSize = Enum.FontSize.Size14
lengthl.BorderColor3 = Color3.new(0, 0, 0)
lengthl.BackgroundTransparency = 1
--length slider
lengthSliderGui, lengthSliderPosition = RbxGui.CreateSlider(4, 0, UDim2.new(0.2, 0, 0.52, 0))
lengthSliderGui.Parent = frame
lengthbar = lengthSliderGui:FindFirstChild("Bar")
lengthbar.Size = UDim2.new(0.75, 0, 0, 5)
lengthSliderPosition.Value = 4
lengthSliderPosition.Changed:connect(function()
length = math.pow(2, lengthSliderPosition.Value + 5)
lengthl.Text = "Length: "..length
end)
--current amplitude display label
ampl = Instance.new("TextLabel", frame)
ampl.Position = UDim2.new(0.05, 0, 0.6, 0)
ampl.Size = UDim2.new(0.1, 0, 0.05, 0)
ampl.Text = ""
ampl.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
ampl.TextColor3 = Color3.new(1, 1, 1)
ampl.Font = Enum.Font.ArialBold
ampl.FontSize = Enum.FontSize.Size14
ampl.BorderColor3 = Color3.new(0, 0, 0)
ampl.BackgroundTransparency = 1
--amplitude slider
ampSliderGui, ampSliderPosition = RbxGui.CreateSlider(62, 0, UDim2.new(0.2, 0, 0.62, 0))
ampSliderGui.Parent = frame
ampbar = ampSliderGui:FindFirstChild("Bar")
ampbar.Size = UDim2.new(0.75, 0, 0, 5)
ampSliderPosition.Value = a + 1
ampSliderPosition.Changed:connect(function()
a = ampSliderPosition.Value + 1
ampl.Text = "Amplitude: "..a
end)
--current frequency display label
freql = Instance.new("TextLabel", frame)
freql.Position = UDim2.new(0.05, 0, 0.7, 0)
freql.Size = UDim2.new(0.1, 0, 0.05, 0)
freql.Text = ""
freql.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
freql.TextColor3 = Color3.new(1, 1, 1)
freql.Font = Enum.Font.ArialBold
freql.FontSize = Enum.FontSize.Size14
freql.BorderColor3 = Color3.new(0, 0, 0)
freql.BackgroundTransparency = 1
--frequency slider
freqSliderGui, freqSliderPosition = RbxGui.CreateSlider(8, 0, UDim2.new(0.2, 0, 0.72, 0))
freqSliderGui.Parent = frame
freqbar = freqSliderGui:FindFirstChild("Bar")
freqbar.Size = UDim2.new(0.75, 0, 0, 5)
freqSliderPosition.Value = 4
freqSliderPosition.Changed:connect(function()
f = math.pow(2, freqSliderPosition.Value - 1)
freql.Text = "Frequency: "..f
end)
--generate button
generate = Instance.new("TextButton", frame)
generate.Position = UDim2.new(0.275, 0, 0.85, 0)
generate.Size = UDim2.new(0.2, 0, 0.1, 0)
generate.Text = ""
generate.BackgroundColor3 = Color3.new(0.5, 0.5, 0.5)
generate.TextColor3 = Color3.new(1, 1, 1)
generate.Font = Enum.Font.ArialBold
generate.FontSize = Enum.FontSize.Size14
generate.BorderColor3 = Color3.new(0, 0, 0)
generate.BackgroundTransparency = 0.5
generate.MouseEnter:connect(function()
generate.BorderColor3 = Color3.new(1, 1, 1)
generate.BackgroundColor3 = Color3.new(0, 0, 0)
generate.BackgroundTransparency = 0.2
end)
generate.MouseButton1Click:connect(onGenerate)
generate.MouseLeave:connect(function()
generate.BorderColor3 = Color3.new(0, 0, 0)
generate.BackgroundColor3 = Color3.new(0.5, 0.5, 0.5)
generate.BackgroundTransparency = 0.5
end)
--reset button
reset = Instance.new("TextButton", frame)
reset.Position = UDim2.new(0.525, 0, 0.85, 0)
reset.Size = UDim2.new(0.2, 0, 0.1, 0)
reset.Text = ""
reset.BackgroundColor3 = Color3.new(0.5, 0.5, 0.5)
reset.TextColor3 = Color3.new(1, 1, 1)
reset.Font = Enum.Font.ArialBold
reset.FontSize = Enum.FontSize.Size14
reset.BorderColor3 = Color3.new(0, 0, 0)
reset.BackgroundTransparency = 0.5
reset.MouseEnter:connect(function()
reset.BorderColor3 = Color3.new(1, 1, 1)
reset.BackgroundColor3 = Color3.new(0, 0, 0)
reset.BackgroundTransparency = 0.2
end)
reset.MouseButton1Click:connect(onReset)
reset.MouseLeave:connect(function()
reset.BorderColor3 = Color3.new(0, 0, 0)
reset.BackgroundColor3 = Color3.new(0.5, 0.5, 0.5)
reset.BackgroundTransparency = 0.5
end)
--------------------------
--SUCCESSFUL LOAD MESSAGE-
--------------------------
loaded = true
print("Terrain Plugin Loaded")
+240
View File
@@ -0,0 +1,240 @@
-----------------
--DEFAULT VALUES-
-----------------
loaded = false
on = false
---------------
--PLUGIN SETUP-
---------------
self = PluginManager():CreatePlugin()
mouse = self:GetMouse()
mouse.Button1Down:connect(function() onClicked(mouse) end)
self.Deactivation:connect(function()
Off()
end)
toolbar = self:CreateToolbar("Terrain")
toolbarbutton = toolbar:CreateButton("", "Builder", "builder.png")
toolbarbutton.Click:connect(function()
if on then
Off()
elseif loaded then
On()
end
end)
-----------------------
--FUNCTION DEFINITIONS-
-----------------------
function dist(x1, y1, x2, y2)
return math.sqrt(math.pow(x2-x1, 2) + math.pow(y2-y1, 2))
end
function dist3d(x1, y1, z1, x2, y2, z2)
return math.sqrt(math.pow(dist(x1, y1, x2, y2), 2) + math.pow(z2-z1, 2))
end
--converts the coordinate coord into a cluster coordinate where clusterlength is the length of the cluster in the same dimension as coord
function clusterCoord(coord, clusterlength)
return math.floor((coord + clusterlength/2)/4)
end
--makes a wedge at location x, y, z
--sets cell x, y, z to default material if parameter is provided, if not sets cell x, y, z to be whatever material it previously was
--returns true if made a wedge, false if the cell remains a block
function MakeWedge(x, y, z, defaultmaterial)
local c = game.Workspace.Terrain
--gather info about all the cells around x, y, z
surroundings = {} --surroundings is a 3 x 3 x 3 array of the material of the cells adjacent to x, y, z
for i = x - 1, x + 1 do
surroundings[i] = {}
for j = y - 1, y + 1 do
surroundings[i][j] = {}
for k = z - 1, z + 1 do
local material, wedge, rotation = c:GetCell(i, j, k)
surroundings[i][j][k] = material.Value
end
end
end
--make some useful arrays and counters
local sides = {} --sides is an array of the material of the 4 adjacent sides
sides[0] = surroundings[x - 1][y][z]
sides[1] = surroundings[x][y][z + 1]
sides[2] = surroundings[x + 1][y][z]
sides[3] = surroundings[x][y][z - 1]
local adjacentSides = 0
for n = 0, 3 do
if sides[n] > 0 then
adjacentSides = adjacentSides + 1
end
end
local sidesAbove = {} --sides is an array of the material of the 4 adjacent sides 1 height above
sidesAbove[0] = surroundings[x - 1][y + 1][z]
sidesAbove[1] = surroundings[x][y + 1][z + 1]
sidesAbove[2] = surroundings[x + 1][y + 1][z]
sidesAbove[3] = surroundings[x][y + 1][z - 1]
local adjacentSidesAbove = 0
for n = 0, 3 do
if sidesAbove[n] > 0 then
adjacentSidesAbove = adjacentSidesAbove + 1
end
end
local corners = {} --corners is an array of the material of the 4 adjacent corners
corners[0] = surroundings[x - 1][y][z - 1]
corners[1] = surroundings[x - 1][y][z + 1]
corners[2] = surroundings[x + 1][y][z + 1]
corners[3] = surroundings[x + 1][y][z - 1]
local adjacentCorners = 0
for n = 0, 3 do
if corners[n] > 0 then
adjacentCorners = adjacentCorners + 1
end
end
local cornersAbove = {} --corners is an array of the material of the 4 adjacent corners 1 height above
cornersAbove[0] = surroundings[x - 1][y + 1][z - 1]
cornersAbove[1] = surroundings[x - 1][y + 1][z + 1]
cornersAbove[2] = surroundings[x + 1][y + 1][z + 1]
cornersAbove[3] = surroundings[x + 1][y + 1][z - 1]
local adjacentCornersAbove = 0
for n = 0, 3 do
if cornersAbove[n] > 0 then
adjacentCornersAbove = adjacentCornersAbove + 1
end
end
--determine what type of wedge to make
local material = nil
local wedge = nil
local rotation = nil
if defaultmaterial then
material = defaultmaterial
else
material, wedge, rotation = c:GetCell(x, y, z) --start with the existing material, wedge, and rotation
end
wedge = 0 --default wedge is a block
rotation = 0 --default rotation is 0
--type 1: 45 degree ramp //must not have a block on top and must have a block under, and be surrounded by 1 side; or 3 sides and the 2 corners between them
if surroundings[x][y + 1][z] == 0 and surroundings[x][y - 1][z] > 0 then
if adjacentSides == 1 then
for n = 0, 3 do
if sides[n] > 0 then
wedge = 1
rotation = (n + 1) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
elseif adjacentSides == 3 then
for n = 0, 3 do
if sides[n] > 0 and corners[(n + 1) % 4] > 0 and sides[(n + 1) % 4] > 0 and corners[(n + 2) % 4] > 0 and sides[(n + 2) % 4] > 0 then
wedge = 1
rotation = (n + 2) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
end
--type 2: 45 degree corner //must not have a block on top and must have a block under, and be surrounded by 2 sides and the 1 corner between them; or 3 sides and 1 corner between 2 of them (facing towards that corner)
if surroundings[x][y + 1][z] == 0 and surroundings[x][y - 1][z] > 0 then
for n = 0, 3 do
if sides[n] > 0 and corners[(n + 1) % 4] > 0 and sides[(n + 1) % 4] > 0 and (adjacentSides == 2 or (adjacentSides == 3 and (corners[(n + 3) % 4] > 0 or (sides[(n + 2) % 4] > 0 and corners[(n + 2) % 4] > 0) or (sides[(n + 3) % 4] > 0 and corners[n] > 0)))) then
wedge = 2
rotation = (n + 2) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
--type 3: 45 degree inverse corner //surrounded by three sides or 4 sides and 3 corners, with nothing above or else a block on top surrounded on 2 sides and the corner between them
if adjacentSides == 3 and surroundings[x][y + 1][z] > 0 then
if adjacentCorners > 1 then
for n = 0, 3 do
if (corners[n] == 0 or cornersAbove[n] == 0) and (sides[(n - 1) % 4] == 0 or sides[n] == 0) and (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] > 0 and sidesAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 3) % 4] == 0) then
wedge = 3
rotation = (n + 3) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
elseif adjacentSides == 4 and adjacentCorners == 3 then
for n = 0, 3 do
if corners[n] == 0 and (surroundings[x][y + 1][z] == 0 or (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] > 0 and cornersAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 3) % 4] == 0)) then
wedge = 3
rotation = (n + 3) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
--type 4: half a cube, as if it were cut diagonally from front to back //surrounded by 2 sides
if adjacentSides == 2 and adjacentCorners < 4 then
for n = 0, 3 do
if sides[n] == 0 and sides[(n + 1) % 4] == 0 and (surroundings[x][y + 1][z] == 0 or (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] == 0 and sidesAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 3) % 4] > 0)) then
wedge = 4
rotation = n
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
c:SetCell(x, y, z, material, wedge, rotation)
return false
end
function onClicked(mouse)
if on then
c = game.Workspace.Terrain
local cellPos = c:WorldToCellPreferEmpty(Vector3.new(mouse.Hit.x, mouse.Hit.y, mouse.Hit.z))
local x = cellPos.x
local y = cellPos.y
local z = cellPos.z
c:SetCell(x, y, z, 1, 0, 0)
for i = x - 1, x + 1 do
for j = y - 1, y + 1 do
for k = z - 1, z + 1 do
MakeWedge(i, j, k)
end
end
end
print("Block built at: "..x..", "..y..", "..z)
end
end
function On()
self:Activate(true)
toolbarbutton:SetActive(true)
on = true
end
function Off()
toolbarbutton:SetActive(false)
on = false
end
------
--GUI-
------
--screengui
g = Instance.new("ScreenGui", game:GetService("CoreGui"))
--------------------------
--SUCCESSFUL LOAD MESSAGE-
--------------------------
loaded = true
print("Builder Plugin Loaded")
+234
View File
@@ -0,0 +1,234 @@
-----------------
--DEFAULT VALUES-
-----------------
loaded = false
on = false
---------------
--PLUGIN SETUP-
---------------
self = PluginManager():CreatePlugin()
mouse = self:GetMouse()
mouse.Button1Down:connect(function() onClicked(mouse) end)
self.Deactivation:connect(function()
Off()
end)
toolbar = self:CreateToolbar("Terrain")
toolbarbutton = toolbar:CreateButton("", "Remover", "remover.png")
toolbarbutton.Click:connect(function()
if on then
Off()
elseif loaded then
On()
end
end)
-----------------------
--FUNCTION DEFINITIONS-
-----------------------
function dist(x1, y1, x2, y2)
return math.sqrt(math.pow(x2-x1, 2) + math.pow(y2-y1, 2))
end
function dist3d(x1, y1, z1, x2, y2, z2)
return math.sqrt(math.pow(dist(x1, y1, x2, y2), 2) + math.pow(z2-z1, 2))
end
--makes a wedge at location x, y, z
--sets cell x, y, z to default material if parameter is provided, if not sets cell x, y, z to be whatever material it previously was
--returns true if made a wedge, false if the cell remains a block
function MakeWedge(x, y, z, defaultmaterial)
local c = game.Workspace.Terrain
--gather info about all the cells around x, y, z
surroundings = {} --surroundings is a 3 x 3 x 3 array of the material of the cells adjacent to x, y, z
for i = x - 1, x + 1 do
surroundings[i] = {}
for j = y - 1, y + 1 do
surroundings[i][j] = {}
for k = z - 1, z + 1 do
local material, wedge, rotation = c:GetCell(i, j, k)
surroundings[i][j][k] = material.Value
end
end
end
--make some useful arrays and counters
local sides = {} --sides is an array of the material of the 4 adjacent sides
sides[0] = surroundings[x - 1][y][z]
sides[1] = surroundings[x][y][z + 1]
sides[2] = surroundings[x + 1][y][z]
sides[3] = surroundings[x][y][z - 1]
local adjacentSides = 0
for n = 0, 3 do
if sides[n] > 0 then
adjacentSides = adjacentSides + 1
end
end
local sidesAbove = {} --sides is an array of the material of the 4 adjacent sides 1 height above
sidesAbove[0] = surroundings[x - 1][y + 1][z]
sidesAbove[1] = surroundings[x][y + 1][z + 1]
sidesAbove[2] = surroundings[x + 1][y + 1][z]
sidesAbove[3] = surroundings[x][y + 1][z - 1]
local adjacentSidesAbove = 0
for n = 0, 3 do
if sidesAbove[n] > 0 then
adjacentSidesAbove = adjacentSidesAbove + 1
end
end
local corners = {} --corners is an array of the material of the 4 adjacent corners
corners[0] = surroundings[x - 1][y][z - 1]
corners[1] = surroundings[x - 1][y][z + 1]
corners[2] = surroundings[x + 1][y][z + 1]
corners[3] = surroundings[x + 1][y][z - 1]
local adjacentCorners = 0
for n = 0, 3 do
if corners[n] > 0 then
adjacentCorners = adjacentCorners + 1
end
end
local cornersAbove = {} --corners is an array of the material of the 4 adjacent corners 1 height above
cornersAbove[0] = surroundings[x - 1][y + 1][z - 1]
cornersAbove[1] = surroundings[x - 1][y + 1][z + 1]
cornersAbove[2] = surroundings[x + 1][y + 1][z + 1]
cornersAbove[3] = surroundings[x + 1][y + 1][z - 1]
local adjacentCornersAbove = 0
for n = 0, 3 do
if cornersAbove[n] > 0 then
adjacentCornersAbove = adjacentCornersAbove + 1
end
end
--determine what type of wedge to make
local material = nil
local wedge = nil
local rotation = nil
if defaultmaterial then
material = defaultmaterial
else
material, wedge, rotation = c:GetCell(x, y, z) --start with the existing material, wedge, and rotation
end
wedge = 0 --default wedge is a block
rotation = 0 --default rotation is 0
--type 1: 45 degree ramp //must not have a block on top and must have a block under, and be surrounded by 1 side; or 3 sides and the 2 corners between them
if surroundings[x][y + 1][z] == 0 and surroundings[x][y - 1][z] > 0 then
if adjacentSides == 1 then
for n = 0, 3 do
if sides[n] > 0 then
wedge = 1
rotation = (n + 1) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
elseif adjacentSides == 3 then
for n = 0, 3 do
if sides[n] > 0 and corners[(n + 1) % 4] > 0 and sides[(n + 1) % 4] > 0 and corners[(n + 2) % 4] > 0 and sides[(n + 2) % 4] > 0 then
wedge = 1
rotation = (n + 2) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
end
--type 2: 45 degree corner //must not have a block on top and must have a block under, and be surrounded by 2 sides and the 1 corner between them; or 3 sides and 1 corner between 2 of them (facing towards that corner)
if surroundings[x][y + 1][z] == 0 and surroundings[x][y - 1][z] > 0 then
for n = 0, 3 do
if sides[n] > 0 and corners[(n + 1) % 4] > 0 and sides[(n + 1) % 4] > 0 and (adjacentSides == 2 or (adjacentSides == 3 and (corners[(n + 3) % 4] > 0 or (sides[(n + 2) % 4] > 0 and corners[(n + 2) % 4] > 0) or (sides[(n + 3) % 4] > 0 and corners[n] > 0)))) then
wedge = 2
rotation = (n + 2) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
--type 3: 45 degree inverse corner //surrounded by three sides or 4 sides and 3 corners, with nothing above or else a block on top surrounded on 2 sides and the corner between them
if adjacentSides == 3 and surroundings[x][y + 1][z] > 0 then
if adjacentCorners > 1 then
for n = 0, 3 do
if (corners[n] == 0 or cornersAbove[n] == 0) and (sides[(n - 1) % 4] == 0 or sides[n] == 0) and (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] > 0 and sidesAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 3) % 4] == 0) then
wedge = 3
rotation = (n + 3) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
elseif adjacentSides == 4 and adjacentCorners == 3 then
for n = 0, 3 do
if corners[n] == 0 and (surroundings[x][y + 1][z] == 0 or (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] > 0 and cornersAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 3) % 4] == 0)) then
wedge = 3
rotation = (n + 3) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
--type 4: half a cube, as if it were cut diagonally from front to back //surrounded by 2 sides
if adjacentSides == 2 and adjacentCorners < 4 then
for n = 0, 3 do
if sides[n] == 0 and sides[(n + 1) % 4] == 0 and (surroundings[x][y + 1][z] == 0 or (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] == 0 and sidesAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 3) % 4] > 0)) then
wedge = 4
rotation = n
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
c:SetCell(x, y, z, material, wedge, rotation)
return false
end
function onClicked(mouse)
if on then
c = game.Workspace.Terrain
local cellPos = c:WorldToCellPreferSolid(Vector3.new(mouse.Hit.x, mouse.Hit.y, mouse.Hit.z))
local x = cellPos.x
local y = cellPos.y
local z = cellPos.z
c:SetCell(x, y, z, 0, 0, 0)
for i = x - 1, x + 1 do
for j = y - 1, y + 1 do
for k = z - 1, z + 1 do
MakeWedge(i, j, k)
end
end
end
print("Block destroyed at: "..x..", "..y..", "..z)
end
end
function On()
self:Activate(true)
toolbarbutton:SetActive(true)
on = true
end
function Off()
toolbarbutton:SetActive(false)
on = false
end
------
--GUI-
------
--screengui
g = Instance.new("ScreenGui", game:GetService("CoreGui"))
--------------------------
--SUCCESSFUL LOAD MESSAGE-
--------------------------
loaded = true
print("Remover Plugin Loaded")
+459
View File
@@ -0,0 +1,459 @@
-----------------
--DEFAULT VALUES-
-----------------
loaded = false
on = false
mousedown = false
r = 0
s = 1
---------------
--PLUGIN SETUP-
---------------
self = PluginManager():CreatePlugin()
self.Deactivation:connect(function()
Off()
end)
toolbar = self:CreateToolbar("Terrain")
toolbarbutton = toolbar:CreateButton("", "Elevation Adjuster", "elevation.png")
toolbarbutton.Click:connect(function()
if on then
Off()
elseif loaded then
On()
end
end)
mouse = self:GetMouse()
mouse.Button1Down:connect(function()
onClicked(mouse)
end)
mouse.Button1Up:connect(function() mousedown = false end)
-----------------------
--FUNCTION DEFINITIONS-
-----------------------
--find height at coordinate x, z
function findHeight(x, z)
c = game.Workspace.Terrain
h = 0
material, wedge, rotation = c:GetCell(x, h + 1, z)
while material.Value > 0 do
h = h + 1
material, wedge, rotation = c:GetCell(x, h + 1, z)
end
return h
end
--makes a shell around block at coordinate x, z using heightmap
function makeShell(x, z, heightmap, shellheightmap)
local c = game.Workspace.Terrain
local originalheight = heightmap[x][z]
for i = x - 1, x + 1 do
for k = z - 1, z + 1 do
if shellheightmap[i][k] < originalheight then
for h = originalheight, shellheightmap[i][k] - 2, -1 do
if h > 0 then
c:SetCell(i, h, k, 1, 0, 0)
end
end
shellheightmap[i][k] = originalheight
end
end
end
return shellheightmap
end
--makes a wedge at location x, y, z using info from heightmap instead of GetCell
--sets cell x, y, z to default material if parameter is provided, if not sets cell x, y, z to be whatever material it previously was
--returns true if made a wedge, false if the cell remains a block
function MakeWedge(x, y, z, heightmap, defaultmaterial)
local c = game.Workspace.Terrain
--gather info about all the cells around x, y, z
local surroundings = {} --surroundings is a 3 x 3 x 3 array of the cells adjacent to x, y, z (1 if a cell is there, 0 if not)
for i = x - 1, x + 1 do
surroundings[i] = {}
for j = y - 1, y + 1 do
surroundings[i][j] = {}
for k = z - 1, z + 1 do
heightmapi = heightmap[i]
height = nil
if heightmapi then
height = heightmapi[k]
end
if height and height >= j then
surroundings[i][j][k] = 1
else
surroundings[i][j][k] = 0
end
end
end
end
--make some useful arrays and counters
local sides = {} --sides is an array of the material of the 4 adjacent sides
sides[0] = surroundings[x - 1][y][z]
sides[1] = surroundings[x][y][z + 1]
sides[2] = surroundings[x + 1][y][z]
sides[3] = surroundings[x][y][z - 1]
local adjacentSides = 0
for n = 0, 3 do
if sides[n] > 0 then
adjacentSides = adjacentSides + 1
end
end
local sidesAbove = {} --sides is an array of the material of the 4 adjacent sides 1 height above
sidesAbove[0] = surroundings[x - 1][y + 1][z]
sidesAbove[1] = surroundings[x][y + 1][z + 1]
sidesAbove[2] = surroundings[x + 1][y + 1][z]
sidesAbove[3] = surroundings[x][y + 1][z - 1]
local adjacentSidesAbove = 0
for n = 0, 3 do
if sidesAbove[n] > 0 then
adjacentSidesAbove = adjacentSidesAbove + 1
end
end
local corners = {} --corners is an array of the material of the 4 adjacent corners
corners[0] = surroundings[x - 1][y][z - 1]
corners[1] = surroundings[x - 1][y][z + 1]
corners[2] = surroundings[x + 1][y][z + 1]
corners[3] = surroundings[x + 1][y][z - 1]
local adjacentCorners = 0
for n = 0, 3 do
if corners[n] > 0 then
adjacentCorners = adjacentCorners + 1
end
end
local cornersAbove = {} --corners is an array of the material of the 4 adjacent corners 1 height above
cornersAbove[0] = surroundings[x - 1][y + 1][z - 1]
cornersAbove[1] = surroundings[x - 1][y + 1][z + 1]
cornersAbove[2] = surroundings[x + 1][y + 1][z + 1]
cornersAbove[3] = surroundings[x + 1][y + 1][z - 1]
local adjacentCornersAbove = 0
for n = 0, 3 do
if cornersAbove[n] > 0 then
adjacentCornersAbove = adjacentCornersAbove + 1
end
end
--determine what type of wedge to make
local material = nil
local wedge = nil
local rotation = nil
if defaultmaterial then
material = defaultmaterial
else
material, wedge, rotation = c:GetCell(x, y, z) --start with the existing material, wedge, and rotation
end
wedge = 0 --default wedge is a block
rotation = 0 --default rotation is 0
--type 1: 45 degree ramp //must not have a block on top and must have a block under, and be surrounded by 1 side; or 3 sides and the 2 corners between them
if surroundings[x][y + 1][z] == 0 and surroundings[x][y - 1][z] > 0 then
if adjacentSides == 1 then
for n = 0, 3 do
if sides[n] > 0 then
wedge = 1
rotation = (n + 1) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
elseif adjacentSides == 3 then
for n = 0, 3 do
if sides[n] > 0 and corners[(n + 1) % 4] > 0 and sides[(n + 1) % 4] > 0 and corners[(n + 2) % 4] > 0 and sides[(n + 2) % 4] > 0 then
wedge = 1
rotation = (n + 2) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
end
--type 2: 45 degree corner //must not have a block on top and must have a block under, and be surrounded by 2 sides and the 1 corner between them; or 3 sides and 1 corner between 2 of them (facing towards that corner)
if surroundings[x][y + 1][z] == 0 and surroundings[x][y - 1][z] > 0 then
for n = 0, 3 do
if sides[n] > 0 and corners[(n + 1) % 4] > 0 and sides[(n + 1) % 4] > 0 and (adjacentSides == 2 or (adjacentSides == 3 and (corners[(n + 3) % 4] > 0 or (sides[(n + 2) % 4] > 0 and corners[(n + 2) % 4] > 0) or (sides[(n + 3) % 4] > 0 and corners[n] > 0)))) then
wedge = 2
rotation = (n + 2) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
--type 3: 45 degree inverse corner //surrounded by three sides or 4 sides and 3 corners, with nothing above or else a block on top surrounded on 2 sides and the corner between them
if adjacentSides == 3 and surroundings[x][y + 1][z] > 0 then
if adjacentCorners > 1 then
for n = 0, 3 do
if (corners[n] == 0 or cornersAbove[n] == 0) and (sides[(n - 1) % 4] == 0 or sides[n] == 0) and (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] > 0 and sidesAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 3) % 4] == 0) then
wedge = 3
rotation = (n + 3) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
elseif adjacentSides == 4 and adjacentCorners == 3 then
for n = 0, 3 do
if corners[n] == 0 and (surroundings[x][y + 1][z] == 0 or (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] > 0 and cornersAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 3) % 4] == 0)) then
wedge = 3
rotation = (n + 3) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
--type 4: half a cube, as if it were cut diagonally from front to back //surrounded by 2 sides
if adjacentSides == 2 and adjacentCorners < 4 then
for n = 0, 3 do
if sides[n] == 0 and sides[(n + 1) % 4] == 0 and (surroundings[x][y + 1][z] == 0 or (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] == 0 and sidesAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 3) % 4] > 0)) then
wedge = 4
rotation = n
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
c:SetCell(x, y, z, material, wedge, rotation)
return false
end
--elevates terrain at point (x, y, z) in cluster c
--within radius r1 from x, z the elevation should become y + d
--from radius r1 to r2 the elevation should be a gradient
function elevate(x, y, z, r1, r2, d, range)
local c = game.Workspace.Terrain
for i = x - (range + 2), x + (range + 2) do
if oldheightmap[i] == nil then
oldheightmap[i] = {}
end
for k = z - (range + 2), z + (range + 2) do
if oldheightmap[i][k] == nil then
oldheightmap[i][k] = findHeight(i, k)
end
--figure out the height to make coordinate (i, k)
local distance = dist(i, k, x, z)
if distance < r1 then
height = y + d
elseif distance < r2 then
height = math.floor((y + d) * (1 - (distance - r1)/(r2 - r1)) + oldheightmap[i][k] * (distance - r1)/(r2 - r1))
else
height = oldheightmap[i][k]
end
if height == 0 then
height = -1
end
--heightmap[i][k] should be the current height of coordinate (i, k)
if heightmap[i] == nil then
heightmap[i] = {}
end
if heightmap[i][k] == nil then
heightmap[i][k] = oldheightmap[i][k]
end
--the height is either greater than or less than the current height
if height > heightmap[i][k] then
for h = heightmap[i][k] - 2, height do
c:SetCell(i, h, k, 1, 0, 0)
end
heightmap[i][k] = height
elseif height < heightmap[i][k] then
for h = heightmap[i][k], height + 1, -1 do
c:SetCell(i, h, k, 0, 0, 0)
end
heightmap[i][k] = height
end
end
end
--copy heightmap into shellheightmap
shellheightmap = {}
for i = x - (range + 2), x + (range + 2) do
if shellheightmap[i] == nil then
shellheightmap[i] = {}
end
for k = z - (range + 2), z + (range + 2) do
shellheightmap[i][k] = heightmap[i][k]
end
end
--shell everything
for i = x - range , x + range do
for k = z - range, z + range do
if shellheightmap[i][k] ~= oldheightmap[i][k] then
shellheightmap = makeShell(i, k, heightmap, shellheightmap)
end
end
end
for i = x - (range + 2), x + (range + 2) do
for k = z - (range + 2), z + (range + 2) do
heightmap[i][k] = shellheightmap[i][k]
end
end
for i = x - (range + 1), x + (range + 1) do
for k = z - (range + 1), z + (range + 1) do
local height = heightmap[i][k]
if height == nil then
height = -1
end
for h = height, 1, -1 do
if not MakeWedge(i, h, k, heightmap, 1) then
break
end
end
end
end
end
function dist(x1, y1, x2, y2)
return math.sqrt(math.pow(x2-x1, 2) + math.pow(y2-y1, 2))
end
function dist3d(x1, y1, z1, x2, y2, z2)
return math.sqrt(math.pow(dist(x1, z1, x2, z2), 2) + math.pow(math.abs(y2-y1)*100/d, 2))
end
function onClicked(mouse)
if on then
local c = game.Workspace.Terrain
oldheightmap = {}
heightmap = {}
local cellPos = c:WorldToCellPreferSolid(Vector3.new(mouse.Hit.x, mouse.Hit.y, mouse.Hit.z))
local x = cellPos.X
local y = cellPos.Y
local z = cellPos.Z
mousedown = true
local originalY = mouse.Y
local prevY = originalY
local d = 0
local range = 0
while mousedown == true do
if math.abs(mouse.Y - prevY) >= 5 then
prevY = mouse.Y
r2 = r + math.floor(50 * 1/s * math.abs(originalY - prevY)/mouse.ViewSizeY)
if r2 > range then
range = r2
end
d = math.floor(50 * (originalY - prevY)/mouse.ViewSizeY)
elevate(x, y, z, r, r2, d, range)
end
wait(0)
end
print("Elevated at: "..x..", "..y..", "..z)
end
end
function On()
self:Activate(true)
toolbarbutton:SetActive(true)
frame.Visible = true
for w = 0, 0.3, 0.06 do
frame.Size = UDim2.new(w, 0, w/2, 0)
wait(0.0000001)
end
radl.Text = "Radius: "..r
sfl.Text = "Slope: "..s
on = true
end
function Off()
toolbarbutton:SetActive(false)
radl.Text = ""
sfl.Text = ""
for w = 0.3, 0, -0.06 do
frame.Size = UDim2.new(w, 0, w/2, 0)
wait(0.0000001)
end
frame.Visible = false
on = false
end
------
--GUI-
------
--load library for with sliders
local RbxGui = LoadLibrary("RbxGui")
--screengui
g = Instance.new("ScreenGui", game:GetService("CoreGui"))
--frame
frame = Instance.new("Frame", g)
frame.Position = UDim2.new(0.35, 0, 0.8, 0)
frame.Size = UDim2.new(0.3, 0, 0.15, 0)
frame.BackgroundTransparency = 0.5
frame.Visible = false
--current radius display label
radl = Instance.new("TextLabel", frame)
radl.Position = UDim2.new(0.05, 0, 0.1, 0)
radl.Size = UDim2.new(0.2, 0, 0.35, 0)
radl.Text = ""
radl.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
radl.TextColor3 = Color3.new(0.95, 0.95, 0.95)
radl.Font = Enum.Font.ArialBold
radl.FontSize = Enum.FontSize.Size14
radl.BorderColor3 = Color3.new(0, 0, 0)
radl.BackgroundTransparency = 1
--radius slider
radSliderGui, radSliderPosition = RbxGui.CreateSlider(11, 0, UDim2.new(0.3, 0, 0.26, 0))
radSliderGui.Parent = frame
radBar = radSliderGui:FindFirstChild("Bar")
radBar.Size = UDim2.new(0.65, 0, 0, 5)
radSliderPosition.Value = r + 1
radSliderPosition.Changed:connect(function()
r = radSliderPosition.Value - 1
radl.Text = "Radius: "..r
end)
--current slope factor display label
sfl = Instance.new("TextLabel", frame)
sfl.Position = UDim2.new(0.05, 0, 0.55, 0)
sfl.Size = UDim2.new(0.2, 0, 0.35, 0)
sfl.Text = ""
sfl.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
sfl.TextColor3 = Color3.new(0.95, 0.95, 0.95)
sfl.Font = Enum.Font.ArialBold
sfl.FontSize = Enum.FontSize.Size14
sfl.BorderColor3 = Color3.new(0, 0, 0)
sfl.BackgroundTransparency = 1
--slope factor slider
sfSliderGui, sfSliderPosition = RbxGui.CreateSlider(16, 0, UDim2.new(0.3, 0, 0.71, 0))
sfSliderGui.Parent = frame
sfBar = sfSliderGui:FindFirstChild("Bar")
sfBar.Size = UDim2.new(0.65, 0, 0, 5)
sfSliderPosition.Value = s * 10 - 0.4
sfSliderPosition.Changed:connect(function()
s = sfSliderPosition.Value / 10 + 0.4
sfl.Text = "Slope: "..s
end)
--------------------------
--SUCCESSFUL LOAD MESSAGE-
--------------------------
loaded = true
print("Elevation Plugin Loaded")
+427
View File
@@ -0,0 +1,427 @@
-----------------
--DEFAULT VALUES-
-----------------
loaded = false
on = false
r = 5
d = 0
mousedown = false
---------------
--PLUGIN SETUP-
---------------
self = PluginManager():CreatePlugin()
self.Deactivation:connect(function()
Off()
end)
toolbar = self:CreateToolbar("Terrain")
toolbarbutton = toolbar:CreateButton("", "Elevation Brush", "brush.png")
toolbarbutton.Click:connect(function()
if on then
Off()
elseif loaded then
On()
end
end)
mouse = self:GetMouse()
mouse.Button1Down:connect(function()
onClicked(mouse)
end)
mouse.Button1Up:connect(function() mousedown = false end)
-----------------------
--FUNCTION DEFINITIONS-
-----------------------
--makes a column of blocks from 1 up to height at location (x,z) in cluster c
--if add is true, blocks below height will be added
--if clear is true, blocks above height will be cleared
function coordHeight(x, z, height, add, clear)
c = game.Workspace.Terrain
if add then
for h = 1, height do
c:SetCell(x, h, z, 1, 0, 0)
end
end
if clear then
ysize = c.MaxExtents.Max.Y
for h = height + 1, ysize - 1 do
c:SetCell(x, h, z, 0, 0, 0)
end
end
end
--find height at coordinate x, z
function getHeight(x, z)
c = game.Workspace.Terrain
h = 0
material, wedge, rotation = c:GetCell(x, h + 1, z)
while material.Value > 0 do
h = h + 1
material, wedge, rotation = c:GetCell(x, h + 1, z)
end
return h
end
function dist(x1, y1, x2, y2)
return math.sqrt(math.pow(x2-x1, 2) + math.pow(y2-y1, 2))
end
function dist3d(x1, y1, z1, x2, y2, z2)
return math.sqrt(math.pow(dist(x1, z1, x2, z2), 2) + math.pow(math.abs(y2-y1)*100/d, 2))
end
--makes a wedge at location x, y, z using info from heightmap instead of GetCell
--sets cell x, y, z to default material if parameter is provided, if not sets cell x, y, z to be whatever material it previously was
--returns true if made a wedge, false if the cell remains a block
function MakeWedge(x, y, z, heightmap, defaultmaterial)
local c = game.Workspace.Terrain
--gather info about all the cells around x, y, z
local surroundings = {} --surroundings is a 3 x 3 x 3 array of the cells adjacent to x, y, z (1 if a cell is there, 0 if not)
for i = x - 1, x + 1 do
surroundings[i] = {}
for j = y - 1, y + 1 do
surroundings[i][j] = {}
for k = z - 1, z + 1 do
heightmapi = heightmap[i]
height = nil
if heightmapi then
height = heightmapi[k]
end
if height and height >= j then
surroundings[i][j][k] = 1
else
surroundings[i][j][k] = 0
end
end
end
end
--make some useful arrays and counters
local sides = {} --sides is an array of the material of the 4 adjacent sides
sides[0] = surroundings[x - 1][y][z]
sides[1] = surroundings[x][y][z + 1]
sides[2] = surroundings[x + 1][y][z]
sides[3] = surroundings[x][y][z - 1]
local adjacentSides = 0
for n = 0, 3 do
if sides[n] > 0 then
adjacentSides = adjacentSides + 1
end
end
local sidesAbove = {} --sides is an array of the material of the 4 adjacent sides 1 height above
sidesAbove[0] = surroundings[x - 1][y + 1][z]
sidesAbove[1] = surroundings[x][y + 1][z + 1]
sidesAbove[2] = surroundings[x + 1][y + 1][z]
sidesAbove[3] = surroundings[x][y + 1][z - 1]
local adjacentSidesAbove = 0
for n = 0, 3 do
if sidesAbove[n] > 0 then
adjacentSidesAbove = adjacentSidesAbove + 1
end
end
local corners = {} --corners is an array of the material of the 4 adjacent corners
corners[0] = surroundings[x - 1][y][z - 1]
corners[1] = surroundings[x - 1][y][z + 1]
corners[2] = surroundings[x + 1][y][z + 1]
corners[3] = surroundings[x + 1][y][z - 1]
local adjacentCorners = 0
for n = 0, 3 do
if corners[n] > 0 then
adjacentCorners = adjacentCorners + 1
end
end
local cornersAbove = {} --corners is an array of the material of the 4 adjacent corners 1 height above
cornersAbove[0] = surroundings[x - 1][y + 1][z - 1]
cornersAbove[1] = surroundings[x - 1][y + 1][z + 1]
cornersAbove[2] = surroundings[x + 1][y + 1][z + 1]
cornersAbove[3] = surroundings[x + 1][y + 1][z - 1]
local adjacentCornersAbove = 0
for n = 0, 3 do
if cornersAbove[n] > 0 then
adjacentCornersAbove = adjacentCornersAbove + 1
end
end
--determine what type of wedge to make
local material = nil
local wedge = nil
local rotation = nil
if defaultmaterial then
material = defaultmaterial
else
material, wedge, rotation = c:GetCell(x, y, z) --start with the existing material, wedge, and rotation
end
wedge = 0 --default wedge is a block
rotation = 0 --default rotation is 0
--type 1: 45 degree ramp //must not have a block on top and must have a block under, and be surrounded by 1 side; or 3 sides and the 2 corners between them
if surroundings[x][y + 1][z] == 0 and surroundings[x][y - 1][z] > 0 then
if adjacentSides == 1 then
for n = 0, 3 do
if sides[n] > 0 then
wedge = 1
rotation = (n + 1) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
elseif adjacentSides == 3 then
for n = 0, 3 do
if sides[n] > 0 and corners[(n + 1) % 4] > 0 and sides[(n + 1) % 4] > 0 and corners[(n + 2) % 4] > 0 and sides[(n + 2) % 4] > 0 then
wedge = 1
rotation = (n + 2) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
end
--type 2: 45 degree corner //must not have a block on top and must have a block under, and be surrounded by 2 sides and the 1 corner between them; or 3 sides and 1 corner between 2 of them (facing towards that corner)
if surroundings[x][y + 1][z] == 0 and surroundings[x][y - 1][z] > 0 then
for n = 0, 3 do
if sides[n] > 0 and corners[(n + 1) % 4] > 0 and sides[(n + 1) % 4] > 0 and (adjacentSides == 2 or (adjacentSides == 3 and (corners[(n + 3) % 4] > 0 or (sides[(n + 2) % 4] > 0 and corners[(n + 2) % 4] > 0) or (sides[(n + 3) % 4] > 0 and corners[n] > 0)))) then
wedge = 2
rotation = (n + 2) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
--type 3: 45 degree inverse corner //surrounded by three sides or 4 sides and 3 corners, with nothing above or else a block on top surrounded on 2 sides and the corner between them
if adjacentSides == 3 and surroundings[x][y + 1][z] > 0 then
if adjacentCorners > 1 then
for n = 0, 3 do
if (corners[n] == 0 or cornersAbove[n] == 0) and (sides[(n - 1) % 4] == 0 or sides[n] == 0) and (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] > 0 and sidesAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 3) % 4] == 0) then
wedge = 3
rotation = (n + 3) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
elseif adjacentSides == 4 and adjacentCorners == 3 then
for n = 0, 3 do
if corners[n] == 0 and (surroundings[x][y + 1][z] == 0 or (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] > 0 and cornersAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 3) % 4] == 0)) then
wedge = 3
rotation = (n + 3) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
--type 4: half a cube, as if it were cut diagonally from front to back //surrounded by 2 sides
if adjacentSides == 2 and adjacentCorners < 4 then
for n = 0, 3 do
if sides[n] == 0 and sides[(n + 1) % 4] == 0 and (surroundings[x][y + 1][z] == 0 or (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] == 0 and sidesAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 3) % 4] > 0)) then
wedge = 4
rotation = n
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
c:SetCell(x, y, z, material, wedge, rotation)
return false
end
--brushes terrain at point (x, y, z) in cluster c
function brush(x, y, z, r, d)
c = game.Workspace.Terrain
for i = x - (r + 3), x + (r + 3) do
for k = z - (r + 3), z + (r + 3) do
if d >= 0 then
inc = 1
material = 1
heightoffset = 0
add = true
else
inc = -1
material = 0
heightoffset = 1
add = false
end
heightmapi = heightmap[i]
if heightmapi then
heightmapik = heightmapi[k]
else
heightmap[i] = {}
end
if dist(x, z, i, k) < r then
coordHeight(i, k, y + d, add, not add)
end
heightmap[i][k] = getHeight(i, k)
end
end
for ri = 0, r + 2 do
i = x - ri
for k = z - (r + 2), z + (r + 2) do
height = heightmap[i][k]
if height == nil then
height = -1
end
for h = height, 0, -1 do
if not MakeWedge(i, h, k, heightmap, 1) then
break
end
end
end
i = x + ri
for k = z - (r + 2), z + (r + 2) do
height = heightmap[i][k]
if height == nil then
height = -1
end
for h = height, 0, -1 do
if not MakeWedge(i, h, k, heightmap, 1) then
break
end
end
end
end
wait(0)
end
function onClicked(mouse)
if on then
c = game.Workspace.Terrain
heightmap = {}
mousedown = true
brushheight = nil
while mousedown == true do
local cellPos = c:WorldToCellPreferSolid(Vector3.new(mouse.Hit.x, mouse.Hit.y, mouse.Hit.z))
local x = cellPos.x
local y = cellPos.y
local z = cellPos.z
if brushheight == nil then
brushheight = y
end
brush(x, brushheight, z, r, d)
print("Brushed at: "..x..", "..brushheight..", "..z)
end
end
end
function On()
self:Activate(true)
toolbarbutton:SetActive(true)
frame.Visible = true
for w = 0, 0.3, 0.06 do
frame.Size = UDim2.new(w, 0, w/2, 0)
wait(0.0000001)
end
radl.Text = "Radius: "..r
dfl.Text = "Height: "..d
on = true
end
function Off()
toolbarbutton:SetActive(false)
radl.Text = ""
dfl.Text = ""
for w = 0.3, 0, -0.06 do
frame.Size = UDim2.new(w, 0, w/2, 0)
wait(0.0000001)
end
frame.Visible = false
on = false
end
------
--GUI-
------
--load library for with sliders
local RbxGui = LoadLibrary("RbxGui")
--screengui
g = Instance.new("ScreenGui", game:GetService("CoreGui"))
--frame
frame = Instance.new("Frame", g)
frame.Position = UDim2.new(0.35, 0, 0.8, 0)
frame.Size = UDim2.new(0.3, 0, 0.15, 0)
frame.BackgroundTransparency = 0.5
frame.Visible = false
--current radius display label
radl = Instance.new("TextLabel", frame)
radl.Position = UDim2.new(0.05, 0, 0.1, 0)
radl.Size = UDim2.new(0.2, 0, 0.35, 0)
radl.Text = ""
radl.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
radl.TextColor3 = Color3.new(0.95, 0.95, 0.95)
radl.Font = Enum.Font.ArialBold
radl.FontSize = Enum.FontSize.Size14
radl.BorderColor3 = Color3.new(0, 0, 0)
radl.BackgroundTransparency = 1
--radius slider
radSliderGui, radSliderPosition = RbxGui.CreateSlider(5, 0, UDim2.new(0.3, 0, 0.26, 0))
radSliderGui.Parent = frame
radBar = radSliderGui:FindFirstChild("Bar")
radBar.Size = UDim2.new(0.65, 0, 0, 5)
radSliderPosition.Value = r - 1
radSliderPosition.Changed:connect(function()
r = radSliderPosition.Value + 1
radl.Text = "Radius: "..r
end)
--current depth factor display label
dfl = Instance.new("TextLabel", frame)
dfl.Position = UDim2.new(0.05, 0, 0.55, 0)
dfl.Size = UDim2.new(0.2, 0, 0.35, 0)
dfl.Text = ""
dfl.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
dfl.TextColor3 = Color3.new(0.95, 0.95, 0.95)
dfl.Font = Enum.Font.ArialBold
dfl.FontSize = Enum.FontSize.Size14
dfl.BorderColor3 = Color3.new(0, 0, 0)
dfl.BackgroundTransparency = 1
--depth factor slider
dfSliderGui, dfSliderPosition = RbxGui.CreateSlider(61, 0, UDim2.new(0.3, 0, 0.71, 0))
dfSliderGui.Parent = frame
dfBar = dfSliderGui:FindFirstChild("Bar")
dfBar.Size = UDim2.new(0.65, 0, 0, 5)
dfSliderPosition.Value = d + 31
dfSliderPosition.Changed:connect(function()
d = dfSliderPosition.Value - 31
dfl.Text = "Height: "..d
end)
--------------------------
--SUCCESSFUL LOAD MESSAGE-
--------------------------
loaded = true
print("Elevation Plugin Loaded")
+131
View File
@@ -0,0 +1,131 @@
-----------------
--DEFAULT VALUES-
-----------------
loaded = false
on = false
---------------
--PLUGIN SETUP-
---------------
self = PluginManager():CreatePlugin()
mouse = self:GetMouse()
mouse.Button1Down:connect(function() onClicked(mouse) end)
self.Deactivation:connect(function()
Off()
end)
toolbar = self:CreateToolbar("Terrain")
toolbarbutton = toolbar:CreateButton("", "Plateau", "plateaus.png")
toolbarbutton.Click:connect(function()
if on then
Off()
elseif loaded then
On()
end
end)
-----------------------
--FUNCTION DEFINITIONS-
-----------------------
--makes a plateau starting at point (x, y, z)
function makePlateau(x, y, z)
c = game.Workspace.Terrain
q = {}
index = 0
q[index] = x
q[index+1] = y
q[index+2] = z
insertindex = 3
c:SetCell(q[index], q[index+1], q[index+2], 0, 0, 0)
while q[index] do
insertindex = plateauHelper(insertindex, 0, 1, 0)
insertindex = plateauHelper(insertindex, -1, 0, -1)
insertindex = plateauHelper(insertindex, -1, 0, 0)
insertindex = plateauHelper(insertindex, -1, 0, 1)
insertindex = plateauHelper(insertindex, 0, 0, -1)
insertindex = plateauHelper(insertindex, 0, 0, 1)
insertindex = plateauHelper(insertindex, 1, 0, -1)
insertindex = plateauHelper(insertindex, 1, 0, 0)
insertindex = plateauHelper(insertindex, 1, 0, 1)
q[index] = nil
q[index + 1] = nil
q[index + 2] = nil
index = index + 3
if index % 1000 == 0 then
wait()
end
end
end
function plateauHelper(insertindex, xoffset, yoffset, zoffset)
material, wedge, rotation = c:GetCell(q[index] + xoffset, q[index+1] + yoffset, q[index+2] + zoffset)
if material.Value > 0 then
q[insertindex] = q[index] + xoffset
q[insertindex+1] = q[index+1] + yoffset
q[insertindex+2] = q[index+2] + zoffset
c:SetCell(q[index] + xoffset, q[index+1] + yoffset, q[index+2] + zoffset, 0, 0, 0)
insertindex = insertindex + 3
end
return insertindex
end
function dist(x1, y1, x2, y2)
return math.sqrt(math.pow(x2-x1, 2) + math.pow(y2-y1, 2))
end
function dist3d(x1, y1, z1, x2, y2, z2)
return math.sqrt(math.pow(dist(x1, y1, x2, y2), 2) + math.pow(z2-z1, 2))
end
function onClicked(mouse)
if on then
c = game.Workspace.Terrain
local cellPos = c:WorldToCellPreferSolid(Vector3.new(mouse.Hit.x, mouse.Hit.y, mouse.Hit.z))
local x = cellPos.x
local y = cellPos.y
local z = cellPos.z
print("Plateau formed at: "..x..", "..y..", "..z)
makePlateau(x, y, z)
end
end
function On()
self:Activate(true)
toolbarbutton:SetActive(true)
on = true
end
function Off()
toolbarbutton:SetActive(false)
on = false
end
------
--GUI-
------
--screengui
g = Instance.new("ScreenGui", game:GetService("CoreGui"))
--------------------------
--SUCCESSFUL LOAD MESSAGE-
--------------------------
loaded = true
print("Plateaus Plugin Loaded")
+386
View File
@@ -0,0 +1,386 @@
-----------------
--DEFAULT VALUES-
-----------------
loaded = false
on = false
r = 20
d = 20
---------------
--PLUGIN SETUP-
---------------
self = PluginManager():CreatePlugin()
mouse = self:GetMouse()
mouse.Button1Down:connect(function() onClicked(mouse) end)
self.Deactivation:connect(function()
Off()
end)
toolbar = self:CreateToolbar("Terrain")
toolbarbutton = toolbar:CreateButton("", "Crater", "craters.png")
toolbarbutton.Click:connect(function()
if on then
Off()
elseif loaded then
On()
end
end)
-----------------------
--FUNCTION DEFINITIONS-
-----------------------
--makes a wedge at location x, y, z using info from heightmap instead of GetCell
--sets cell x, y, z to default material if parameter is provided, if not sets cell x, y, z to be whatever material it previously was
--returns true if made a wedge, false if the cell remains a block
function MakeWedge(x, y, z, heightmap, defaultmaterial)
local c = game.Workspace.Terrain
--gather info about all the cells around x, y, z
local surroundings = {} --surroundings is a 3 x 3 x 3 array of the cells adjacent to x, y, z (1 if a cell is there, 0 if not)
for i = x - 1, x + 1 do
surroundings[i] = {}
for j = y - 1, y + 1 do
surroundings[i][j] = {}
for k = z - 1, z + 1 do
heightmapi = heightmap[i]
height = nil
if heightmapi then
height = heightmapi[k]
end
if height then
if height >= j then
surroundings[i][j][k] = 1
else
surroundings[i][j][k] = 0
end
else -- need to get info from cell when our heightmap doesn't exist there! [otherwise, we can get holes through the terrain]
local material, wedge, rotation = c:GetCell(i, j, k)
surroundings[i][j][k] = material.Value
end
end
end
end
--make some useful arrays and counters
local sides = {} --sides is an array of the material of the 4 adjacent sides
sides[0] = surroundings[x - 1][y][z]
sides[1] = surroundings[x][y][z + 1]
sides[2] = surroundings[x + 1][y][z]
sides[3] = surroundings[x][y][z - 1]
local adjacentSides = 0
for n = 0, 3 do
if sides[n] > 0 then
adjacentSides = adjacentSides + 1
end
end
local sidesAbove = {} --sides is an array of the material of the 4 adjacent sides 1 height above
sidesAbove[0] = surroundings[x - 1][y + 1][z]
sidesAbove[1] = surroundings[x][y + 1][z + 1]
sidesAbove[2] = surroundings[x + 1][y + 1][z]
sidesAbove[3] = surroundings[x][y + 1][z - 1]
local adjacentSidesAbove = 0
for n = 0, 3 do
if sidesAbove[n] > 0 then
adjacentSidesAbove = adjacentSidesAbove + 1
end
end
local corners = {} --corners is an array of the material of the 4 adjacent corners
corners[0] = surroundings[x - 1][y][z - 1]
corners[1] = surroundings[x - 1][y][z + 1]
corners[2] = surroundings[x + 1][y][z + 1]
corners[3] = surroundings[x + 1][y][z - 1]
local adjacentCorners = 0
for n = 0, 3 do
if corners[n] > 0 then
adjacentCorners = adjacentCorners + 1
end
end
local cornersAbove = {} --corners is an array of the material of the 4 adjacent corners 1 height above
cornersAbove[0] = surroundings[x - 1][y + 1][z - 1]
cornersAbove[1] = surroundings[x - 1][y + 1][z + 1]
cornersAbove[2] = surroundings[x + 1][y + 1][z + 1]
cornersAbove[3] = surroundings[x + 1][y + 1][z - 1]
local adjacentCornersAbove = 0
for n = 0, 3 do
if cornersAbove[n] > 0 then
adjacentCornersAbove = adjacentCornersAbove + 1
end
end
--determine what type of wedge to make
local material = nil
local wedge = nil
local rotation = nil
if defaultmaterial then
material = defaultmaterial
else
material, wedge, rotation = c:GetCell(x, y, z) --start with the existing material, wedge, and rotation
end
wedge = 0 --default wedge is a block
rotation = 0 --default rotation is 0
--type 1: 45 degree ramp //must not have a block on top and must have a block under, and be surrounded by 1 side; or 3 sides and the 2 corners between them
if surroundings[x][y + 1][z] == 0 and surroundings[x][y - 1][z] > 0 then
if adjacentSides == 1 then
for n = 0, 3 do
if sides[n] > 0 then
wedge = 1
rotation = (n + 1) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
elseif adjacentSides == 3 then
for n = 0, 3 do
if sides[n] > 0 and corners[(n + 1) % 4] > 0 and sides[(n + 1) % 4] > 0 and corners[(n + 2) % 4] > 0 and sides[(n + 2) % 4] > 0 then
wedge = 1
rotation = (n + 2) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
end
--type 2: 45 degree corner //must not have a block on top and must have a block under, and be surrounded by 2 sides and the 1 corner between them; or 3 sides and 1 corner between 2 of them (facing towards that corner)
if surroundings[x][y + 1][z] == 0 and surroundings[x][y - 1][z] > 0 then
for n = 0, 3 do
if sides[n] > 0 and corners[(n + 1) % 4] > 0 and sides[(n + 1) % 4] > 0 and (adjacentSides == 2 or (adjacentSides == 3 and (corners[(n + 3) % 4] > 0 or (sides[(n + 2) % 4] > 0 and corners[(n + 2) % 4] > 0) or (sides[(n + 3) % 4] > 0 and corners[n] > 0)))) then
wedge = 2
rotation = (n + 2) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
--type 3: 45 degree inverse corner //surrounded by three sides or 4 sides and 3 corners, with nothing above or else a block on top surrounded on 2 sides and the corner between them
if adjacentSides == 3 and surroundings[x][y + 1][z] > 0 then
if adjacentCorners > 1 then
for n = 0, 3 do
if (corners[n] == 0 or cornersAbove[n] == 0) and (sides[(n - 1) % 4] == 0 or sides[n] == 0) and (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] > 0 and sidesAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 3) % 4] == 0) then
wedge = 3
rotation = (n + 3) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
elseif adjacentSides == 4 and adjacentCorners == 3 then
for n = 0, 3 do
if corners[n] == 0 and (surroundings[x][y + 1][z] == 0 or (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] > 0 and cornersAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 3) % 4] == 0)) then
wedge = 3
rotation = (n + 3) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
--type 4: half a cube, as if it were cut diagonally from front to back //surrounded by 2 sides
if adjacentSides == 2 and adjacentCorners < 4 then
for n = 0, 3 do
if sides[n] == 0 and sides[(n + 1) % 4] == 0 and (surroundings[x][y + 1][z] == 0 or (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] == 0 and sidesAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 3) % 4] > 0)) then
wedge = 4
rotation = n
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
c:SetCell(x, y, z, material, wedge, rotation)
return false
end
--makes a crater at point (x, y, z) in cluster c
--d is the depth factor, a percent of the depth of a perfect sphere
function makeCrater(x, y, z, r, d)
c = game.Workspace.Terrain
local heightmap = {}
for i = x - (r + 1), x + (r + 1) do
heightmap[i] = {}
end
for j = 0, r + 1 do
local cellschanged = false
for i = x - (r + 1), x + (r + 1) do
for k = z - (r + 1), z + (r + 1) do
distance = math.sqrt(math.pow(dist(x, z, i, k), 2) + math.pow(y - (y - j*(100/d)), 2))
if distance < r then
c:SetCell(i, y + j, k, 0, 0, 0)
c:SetCell(i, y - j, k, 0, 0, 0)
cellschanged = true
elseif heightmap[i] and heightmap[i][k] == nil then
material, wedge, rotation = c:GetCell(i, y - j, k)
if material.Value > 0 then
heightmap[i][k] = y - j
end
end
end
end
if cellschanged == false then
break
end
wait(0)
end
for ri = 0, r do
wait(0)
i = x - ri
for k = z - r, z + r do
height = heightmap[i][k]
if height == nil then
height = -1
end
for h = height, 0, -1 do
if not MakeWedge(i, h, k, heightmap, nil) then
break
end
end
end
i = x + ri
for k = z - r, z + r do
height = heightmap[i][k]
if height == nil then
height = -1
end
for h = height, 0, -1 do
if not MakeWedge(i, h, k, heightmap, nil) then
break
end
end
end
end
end
function dist(x1, y1, x2, y2)
return math.sqrt(math.pow(x2-x1, 2) + math.pow(y2-y1, 2))
end
local debounce = false
function onClicked(mouse)
if on and not debounce then
debounce = true
c = game.Workspace.Terrain
local cellPos = c:WorldToCellPreferSolid(Vector3.new(mouse.Hit.x, mouse.Hit.y, mouse.Hit.z))
local x = cellPos.x
local y = cellPos.y
local z = cellPos.z
makeCrater(x, y, z, r, d)
print("Crater formed at: "..x..", "..y..", "..z)
debounce = false
end
end
function On()
self:Activate(true)
toolbarbutton:SetActive(true)
frame.Visible = true
for w = 0, 0.3, 0.06 do
frame.Size = UDim2.new(w, 0, w/2, 0)
wait(0)
end
radl.Text = "Radius: "..r
dfl.Text = "Depth: "..d.."%"
on = true
end
function Off()
toolbarbutton:SetActive(false)
radl.Text = ""
dfl.Text = ""
for w = 0.3, 0, -0.06 do
frame.Size = UDim2.new(w, 0, w/2, 0)
wait(0)
end
frame.Visible = false
on = false
end
------
--GUI-
------
--load library for with sliders
local RbxGui = LoadLibrary("RbxGui")
--screengui
g = Instance.new("ScreenGui", game:GetService("CoreGui"))
--frame
frame = Instance.new("Frame", g)
frame.Position = UDim2.new(0.35, 0, 0.8, 0)
frame.Size = UDim2.new(0.3, 0, 0.15, 0)
frame.BackgroundTransparency = 0.5
frame.Visible = false
--current radius display label
radl = Instance.new("TextLabel", frame)
radl.Position = UDim2.new(0.05, 0, 0.1, 0)
radl.Size = UDim2.new(0.2, 0, 0.35, 0)
radl.Text = ""
radl.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
radl.TextColor3 = Color3.new(0.95, 0.95, 0.95)
radl.Font = Enum.Font.ArialBold
radl.FontSize = Enum.FontSize.Size14
radl.BorderColor3 = Color3.new(0, 0, 0)
radl.BackgroundTransparency = 1
--radius slider
radSliderGui, radSliderPosition = RbxGui.CreateSlider(128, 0, UDim2.new(0.3, 0, 0.26, 0))
radSliderGui.Parent = frame
radBar = radSliderGui:FindFirstChild("Bar")
radBar.Size = UDim2.new(0.65, 0, 0, 5)
radSliderPosition.Value = r
radSliderPosition.Changed:connect(function()
r = radSliderPosition.Value
radl.Text = "Radius: "..r
end)
--current depth factor display label
dfl = Instance.new("TextLabel", frame)
dfl.Position = UDim2.new(0.05, 0, 0.55, 0)
dfl.Size = UDim2.new(0.2, 0, 0.35, 0)
dfl.Text = ""
dfl.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
dfl.TextColor3 = Color3.new(0.95, 0.95, 0.95)
dfl.Font = Enum.Font.ArialBold
dfl.FontSize = Enum.FontSize.Size14
dfl.BorderColor3 = Color3.new(0, 0, 0)
dfl.BackgroundTransparency = 1
--depth factor slider
dfSliderGui, dfSliderPosition = RbxGui.CreateSlider(100, 0, UDim2.new(0.3, 0, 0.71, 0))
dfSliderGui.Parent = frame
dfBar = dfSliderGui:FindFirstChild("Bar")
dfBar.Size = UDim2.new(0.65, 0, 0, 5)
dfSliderPosition.Value = d
dfSliderPosition.Changed:connect(function()
d = dfSliderPosition.Value
dfl.Text = "Depth: "..d.."%"
end)
--------------------------
--SUCCESSFUL LOAD MESSAGE-
--------------------------
loaded = true
print("Craters Plugin Loaded")
+383
View File
@@ -0,0 +1,383 @@
-----------------
--DEFAULT VALUES-
-----------------
loaded = false
on = false
r = 20
d = 50
---------------
--PLUGIN SETUP-
---------------
self = PluginManager():CreatePlugin()
mouse = self:GetMouse()
mouse.Button1Down:connect(function() onClicked(mouse) end)
self.Deactivation:connect(function()
Off()
end)
toolbar = self:CreateToolbar("Terrain")
toolbarbutton = toolbar:CreateButton("", "Orb", "orbs.png")
toolbarbutton.Click:connect(function()
if on then
Off()
elseif loaded then
On()
end
end)
-----------------------
--FUNCTION DEFINITIONS-
-----------------------
--find height at coordinate x, z
function getHeight(x, z)
c = game.Workspace.Terrain
h = 0
material, wedge, rotation = c:GetCell(x, h + 1, z)
while material.Value > 0 do
h = h + 1
material, wedge, rotation = c:GetCell(x, h + 1, z)
end
return h
end
--makes a wedge at location x, y, z using info from heightmap instead of GetCell
--sets cell x, y, z to default material if parameter is provided, if not sets cell x, y, z to be whatever material it previously was
--returns true if made a wedge, false if the cell remains a block
function MakeWedge(x, y, z, heightmap, defaultmaterial)
local c = game.Workspace.Terrain
--gather info about all the cells around x, y, z
local surroundings = {} --surroundings is a 3 x 3 x 3 array of the cells adjacent to x, y, z (1 if a cell is there, 0 if not)
for i = x - 1, x + 1 do
surroundings[i] = {}
for j = y - 1, y + 1 do
surroundings[i][j] = {}
for k = z - 1, z + 1 do
heightmapi = heightmap[i]
height = nil
if heightmapi then
height = heightmapi[k]
end
if height and height >= j then
surroundings[i][j][k] = 1
else
surroundings[i][j][k] = 0
end
end
end
end
--make some useful arrays and counters
local sides = {} --sides is an array of the material of the 4 adjacent sides
sides[0] = surroundings[x - 1][y][z]
sides[1] = surroundings[x][y][z + 1]
sides[2] = surroundings[x + 1][y][z]
sides[3] = surroundings[x][y][z - 1]
local adjacentSides = 0
for n = 0, 3 do
if sides[n] > 0 then
adjacentSides = adjacentSides + 1
end
end
local sidesAbove = {} --sides is an array of the material of the 4 adjacent sides 1 height above
sidesAbove[0] = surroundings[x - 1][y + 1][z]
sidesAbove[1] = surroundings[x][y + 1][z + 1]
sidesAbove[2] = surroundings[x + 1][y + 1][z]
sidesAbove[3] = surroundings[x][y + 1][z - 1]
local adjacentSidesAbove = 0
for n = 0, 3 do
if sidesAbove[n] > 0 then
adjacentSidesAbove = adjacentSidesAbove + 1
end
end
local corners = {} --corners is an array of the material of the 4 adjacent corners
corners[0] = surroundings[x - 1][y][z - 1]
corners[1] = surroundings[x - 1][y][z + 1]
corners[2] = surroundings[x + 1][y][z + 1]
corners[3] = surroundings[x + 1][y][z - 1]
local adjacentCorners = 0
for n = 0, 3 do
if corners[n] > 0 then
adjacentCorners = adjacentCorners + 1
end
end
local cornersAbove = {} --corners is an array of the material of the 4 adjacent corners 1 height above
cornersAbove[0] = surroundings[x - 1][y + 1][z - 1]
cornersAbove[1] = surroundings[x - 1][y + 1][z + 1]
cornersAbove[2] = surroundings[x + 1][y + 1][z + 1]
cornersAbove[3] = surroundings[x + 1][y + 1][z - 1]
local adjacentCornersAbove = 0
for n = 0, 3 do
if cornersAbove[n] > 0 then
adjacentCornersAbove = adjacentCornersAbove + 1
end
end
--determine what type of wedge to make
local material = nil
local wedge = nil
local rotation = nil
if defaultmaterial then
material = defaultmaterial
else
material, wedge, rotation = c:GetCell(x, y, z) --start with the existing material, wedge, and rotation
end
wedge = 0 --default wedge is a block
rotation = 0 --default rotation is 0
--type 1: 45 degree ramp //must not have a block on top and must have a block under, and be surrounded by 1 side; or 3 sides and the 2 corners between them
if surroundings[x][y + 1][z] == 0 and surroundings[x][y - 1][z] > 0 then
if adjacentSides == 1 then
for n = 0, 3 do
if sides[n] > 0 then
wedge = 1
rotation = (n + 1) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
elseif adjacentSides == 3 then
for n = 0, 3 do
if sides[n] > 0 and corners[(n + 1) % 4] > 0 and sides[(n + 1) % 4] > 0 and corners[(n + 2) % 4] > 0 and sides[(n + 2) % 4] > 0 then
wedge = 1
rotation = (n + 2) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
end
--type 2: 45 degree corner //must not have a block on top and must have a block under, and be surrounded by 2 sides and the 1 corner between them; or 3 sides and 1 corner between 2 of them (facing towards that corner)
if surroundings[x][y + 1][z] == 0 and surroundings[x][y - 1][z] > 0 then
for n = 0, 3 do
if sides[n] > 0 and corners[(n + 1) % 4] > 0 and sides[(n + 1) % 4] > 0 and (adjacentSides == 2 or (adjacentSides == 3 and (corners[(n + 3) % 4] > 0 or (sides[(n + 2) % 4] > 0 and corners[(n + 2) % 4] > 0) or (sides[(n + 3) % 4] > 0 and corners[n] > 0)))) then
wedge = 2
rotation = (n + 2) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
--type 3: 45 degree inverse corner //surrounded by three sides or 4 sides and 3 corners, with nothing above or else a block on top surrounded on 2 sides and the corner between them
if adjacentSides == 3 and surroundings[x][y + 1][z] > 0 then
if adjacentCorners > 1 then
for n = 0, 3 do
if (corners[n] == 0 or cornersAbove[n] == 0) and (sides[(n - 1) % 4] == 0 or sides[n] == 0) and (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] > 0 and sidesAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 3) % 4] == 0) then
wedge = 3
rotation = (n + 3) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
elseif adjacentSides == 4 and adjacentCorners == 3 then
for n = 0, 3 do
if corners[n] == 0 and (surroundings[x][y + 1][z] == 0 or (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] > 0 and cornersAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 3) % 4] == 0)) then
wedge = 3
rotation = (n + 3) % 4
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
--type 4: half a cube, as if it were cut diagonally from front to back //surrounded by 2 sides
if adjacentSides == 2 and adjacentCorners < 4 then
for n = 0, 3 do
if sides[n] == 0 and sides[(n + 1) % 4] == 0 and (surroundings[x][y + 1][z] == 0 or (sidesAbove[n] == 0 and sidesAbove[(n + 1) % 4] == 0 and sidesAbove[(n + 2) % 4] > 0 and sidesAbove[(n + 3) % 4] > 0)) then
wedge = 4
rotation = n
c:SetCell(x, y, z, material, wedge, rotation)
return true
end
end
end
c:SetCell(x, y, z, material, wedge, rotation)
return false
end
--makes an orb at point (x, y, z) in cluster c
--d is the depth factor, a percent of the depth of a perfect sphere
function makeBall(x, y, z, r, d)
c = game.Workspace.Terrain
local heightmap = {}
for i = x - (r + 1), x + (r + 1) do
heightmap[i] = {}
end
for j = 0, r + 1 do
local cellschanged = false
for i = x - (r + 1), x + (r + 1) do
for k = z - (r + 1), z + (r + 1) do
distance = math.sqrt(math.pow(dist(x, z, i, k), 2) + math.pow(j*(100/d), 2))
if distance < r then
c:SetCell(i, y - j, k, 1, 0, 1)
c:SetCell(i, y + j, k, 1, 0, 1)
cellschanged = true
heightmap[i][k] = y + j
elseif heightmap[i][k] == nil then
heightmap[i][k] = getHeight(i, k)
end
end
end
if cellschanged == false then
break
end
wait(0)
end
for ri = 0, r do
wait(0)
i = x - ri
for k = z - r, z + r do
height = heightmap[i][k]
if height == nil then
height = -1
end
for h = height, 0, -1 do
if not MakeWedge(i, h, k, heightmap) then
break
end
end
end
i = x + ri
for k = z - r, z + r do
height = heightmap[i][k]
if height == nil then
height = -1
end
for h = height, 0, -1 do
if not MakeWedge(i, h, k, heightmap) then
break
end
end
end
end
end
function dist(x1, y1, x2, y2)
return math.sqrt(math.pow(x2-x1, 2) + math.pow(y2-y1, 2))
end
local debounce = false
function onClicked(mouse)
if on and not debounce then
debounce = true
c = game.Workspace.Terrain
local cellPos = c:WorldToCellPreferEmpty(Vector3.new(mouse.Hit.x, mouse.Hit.y, mouse.Hit.z))
local x = cellPos.x
local y = cellPos.y
local z = cellPos.z
makeBall(x, y, z, r, d)
print("Orb created at: "..x..", "..y..", "..z)
debounce = false
end
end
function On()
self:Activate(true)
toolbarbutton:SetActive(true)
frame.Visible = true
for w = 0, 0.3, 0.06 do
frame.Size = UDim2.new(w, 0, w/2, 0)
wait(0)
end
radl.Text = "Radius: "..r
dfl.Text = "Height: "..d.."%"
on = true
end
function Off()
toolbarbutton:SetActive(false)
radl.Text = ""
dfl.Text = ""
for w = 0.3, 0, -0.06 do
frame.Size = UDim2.new(w, 0, w/2, 0)
wait(0)
end
frame.Visible = false
on = false
end
------
--GUI-
------
--load library for with sliders
local RbxGui = LoadLibrary("RbxGui")
--screengui
g = Instance.new("ScreenGui", game:GetService("CoreGui"))
--frame
frame = Instance.new("Frame", g)
frame.Position = UDim2.new(0.35, 0, 0.8, 0)
frame.Size = UDim2.new(0.3, 0, 0.15, 0)
frame.BackgroundTransparency = 0.5
frame.Visible = false
--current radius display label
radl = Instance.new("TextLabel", frame)
radl.Position = UDim2.new(0.05, 0, 0.1, 0)
radl.Size = UDim2.new(0.2, 0, 0.35, 0)
radl.Text = ""
radl.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
radl.TextColor3 = Color3.new(0.95, 0.95, 0.95)
radl.Font = Enum.Font.ArialBold
radl.FontSize = Enum.FontSize.Size14
radl.BorderColor3 = Color3.new(0, 0, 0)
radl.BackgroundTransparency = 1
--radius slider
radSliderGui, radSliderPosition = RbxGui.CreateSlider(128, 0, UDim2.new(0.3, 0, 0.26, 0))
radSliderGui.Parent = frame
radBar = radSliderGui:FindFirstChild("Bar")
radBar.Size = UDim2.new(0.65, 0, 0, 5)
radSliderPosition.Value = r
radSliderPosition.Changed:connect(function()
r = radSliderPosition.Value
radl.Text = "Radius: "..r
end)
--current depth factor display label
dfl = Instance.new("TextLabel", frame)
dfl.Position = UDim2.new(0.05, 0, 0.55, 0)
dfl.Size = UDim2.new(0.2, 0, 0.35, 0)
dfl.Text = ""
dfl.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
dfl.TextColor3 = Color3.new(0.95, 0.95, 0.95)
dfl.Font = Enum.Font.ArialBold
dfl.FontSize = Enum.FontSize.Size14
dfl.BorderColor3 = Color3.new(0, 0, 0)
dfl.BackgroundTransparency = 1
--depth factor slider
dfSliderGui, dfSliderPosition = RbxGui.CreateSlider(100, 0, UDim2.new(0.3, 0, 0.71, 0))
dfSliderGui.Parent = frame
dfBar = dfSliderGui:FindFirstChild("Bar")
dfBar.Size = UDim2.new(0.65, 0, 0, 5)
dfSliderPosition.Value = d
dfSliderPosition.Changed:connect(function()
d = dfSliderPosition.Value
dfl.Text = "Height: "..d.."%"
end)
--------------------------
--SUCCESSFUL LOAD MESSAGE-
--------------------------
loaded = true
print("Orbs Plugin Loaded")
+202
View File
@@ -0,0 +1,202 @@
-----------------
--DEFAULT VALUES-
-----------------
loaded = false
x1 = 200
y1 = 200
x2 = 300
y2 = 300
h = 20
on = false
mode = 0
---------------
--PLUGIN SETUP-
---------------
self = PluginManager():CreatePlugin()
mouse = self:GetMouse()
mouse.Button1Down:connect(function() onClicked(mouse) end)
self.Deactivation:connect(function()
Off()
end)
toolbar = self:CreateToolbar("Terrain")
toolbarbutton = toolbar:CreateButton("", "Roads: Click once to set the starting point and again to set the endpoint of the road.", "roads.png")
toolbarbutton.Click:connect(function()
if on then
Off()
elseif loaded then
On()
end
end)
-----------------------
--FUNCTION DEFINITIONS-
-----------------------
--makes a column of blocks from 0 up to height at location (x,z) in cluster c
function coordHeight(x, z, height)
c = game.Workspace.Terrain
for h = 1, height do
c:SetCell(x, h, z, 1, 0, 0)
end
end
function coordCheck(x, z, height)
c = game.Workspace.Terrain
for h = height, 0, -1 do
material, wedge, rotation = c:GetCell(x, h, z)
if material.Value > 0 then
return true
elseif height == 0 then
return false
end
end
end
function dist(x1, y1, x2, y2)
return math.sqrt(math.pow(x2-x1, 2) + math.pow(y2-y1, 2))
end
function dist3d(x1, y1, z1, x2, y2, z2)
return math.sqrt(math.pow(dist(x1, y1, x2, y2), 2) + math.pow(z2-z1, 2))
end
--create a path between coordinates (x1,z1) and (x2,z2) at height h in cluster c
--a path is a road with height of 3 instead of 1, and it builds a bridge if there is no existing land under it
--if you want path to come from x direction, make it start at the place
--if you want it to come from z direction, make it end at the place
--if p is true, turns on pillars, otherwise pillars are off
function makePath(x1, z1, x2, z2, h, p)
c = game.Workspace.Terrain
if x2 < x1 then
incx = -1
n = 1
else
incx = 1
n = -1
end
for x = x1, x2+n, incx do
c:SetCell(x, h+1, z1, 0, 0, 0)
c:SetCell(x, h+1, z1-1, 0, 0, 0)
c:SetCell(x, h+1, z1+1, 0, 0, 0)
c:SetCell(x, h+2, z1, 0, 0, 0)
c:SetCell(x, h+2, z1-1, 0, 0, 0)
c:SetCell(x, h+2, z1+1, 0, 0, 0)
c:SetCell(x, h+3, z1, 0, 0, 0)
c:SetCell(x, h+3, z1-1, 0, 0, 0)
c:SetCell(x, h+3, z1+1, 0, 0, 0)
c:SetCell(x, h, z1, 1, 0, 0)
c:SetCell(x, h, z1-1, 1, 0, 0)
c:SetCell(x, h, z1+1, 1, 0, 0)
end
if p then
for x = x1, x2+n, 16*incx do
if coordCheck(x, z1, h-1) then
coordHeight(x, z1, h-1)
end
if coordCheck(x, z1-1, h-1) then
coordHeight(x, z1-1, h-1)
end
if coordCheck(x, z1+1, h-1) then
coordHeight(x, z1+1, h-1)
end
end
end
if z2 < z1 then
incz = -1
m = 1
n = 2
else
incz = 1
m = -1
n = -2
end
for z = z1+m, z2+n, incz do
c:SetCell(x2, h+1, z, 0, 0, 0)
c:SetCell(x2-1, h+1, z, 0, 0, 0)
c:SetCell(x2+1, h+1, z, 0, 0, 0)
c:SetCell(x2, h+2, z, 0, 0, 0)
c:SetCell(x2-1, h+2, z, 0, 0, 0)
c:SetCell(x2+1, h+2, z, 0, 0, 0)
c:SetCell(x2, h+3, z, 0, 0, 0)
c:SetCell(x2-1, h+3, z, 0, 0, 0)
c:SetCell(x2+1, h+3, z, 0, 0, 0)
c:SetCell(x2, h, z, 1, 0, 0)
c:SetCell(x2-1, h, z, 1, 0, 0)
c:SetCell(x2+1, h, z, 1, 0, 0)
end
if p then
for z = z1+m, z2+n, 16*incz do
if coordCheck(x2, z, h-1) then
coordHeight(x2, z, h-1)
end
if coordCheck(x2-1, z, h-1) then
coordHeight(x2-1, z, h-1)
end
if coordCheck(x2+1, z, h-1) then
coordHeight(x2+1, z, h-1)
end
end
end
end
function onClicked (mouse)
if on then
c = game.Workspace.Terrain
local cellPos = c:WorldToCellPreferSolid(Vector3.new(mouse.Hit.x, mouse.Hit.y, mouse.Hit.z))
local x = cellPos.x
local y = cellPos.y
local z = cellPos.z
if mode == 0 then
x1 = x
y1 = z
h = y
mode = 1
elseif mode == 1 then
x2 = x
y2 = z
makePath(x1, y1, x2, y2, h, true, c)
mode = 0
else
end
end
end
function On()
self:Activate(true)
toolbarbutton:SetActive(true)
mode = 0
on = true
end
function Off()
toolbarbutton:SetActive(false)
on = false
end
------
--GUI-
------
--screengui
g = Instance.new("ScreenGui", game:GetService("CoreGui"))
--------------------------
--SUCCESSFUL LOAD MESSAGE-
--------------------------
loaded = true
print("Roads Plugin Loaded")
+204
View File
@@ -0,0 +1,204 @@
-----------------
--DEFAULT VALUES-
-----------------
loaded = false
on = false
---------------
--PLUGIN SETUP-
---------------
self = PluginManager():CreatePlugin()
mouse = self:GetMouse()
mouse.Button1Down:connect(function() onClicked(mouse) end)
self.Deactivation:connect(function()
Off()
end)
toolbar = self:CreateToolbar("Terrain")
toolbarbutton = toolbar:CreateButton("", "Tree", "trees.png")
toolbarbutton.Click:connect(function()
if on then
Off()
elseif loaded then
On()
end
end)
-----------------------
--FUNCTION DEFINITIONS-
-----------------------
local Base = Instance.new("Part")
Base.Name = "Trunk"
Base.formFactor = "Custom"
Base.TopSurface = 0
Base.BottomSurface = 0
Base.Anchored = false
Base.BrickColor = BrickColor.new("Reddish brown")
local Leaves = Base:Clone()
Leaves.Name = "Leaves"
Leaves.CanCollide = false
Leaves.BrickColor = BrickColor.new("Dark green")
local leafmesh = Instance.new("SpecialMesh")
leafmesh.MeshType = "FileMesh"
leafmesh.MeshId = "http://www.watrbx.wtf/asset/?id=1290033"
leafmesh.TextureId = "http://www.watrbx.wtf/asset/?id=2861779"
leafmesh.Parent = Leaves
Instance.new("CylinderMesh",Base)
-- get dot product of yz angles
function dot(c1,c2)
local m = CFrame.Angles(math.pi/2,0,0)
return (c1*m).lookVector:Dot((c2*m).lookVector)
end
-- multiplier for various sizes of foliage
local leaf_mult = {
Vector3.new(1.5,1.5,1.2);
Vector3.new(1.5,1,1.5);
Vector3.new(1.2,1.5,1.5);
Vector3.new(1.5,1.5,1.5);
}
function Welder(p0, p1)
local w = Instance.new("Weld")
w.Part0 = p0
w.Part1 = p1
local CJ = CFrame.new(p0.Position)
w.C0 = p0.CFrame:inverse() * CJ
w.C1 = p1.CFrame:inverse() * CJ
w.Parent = p0
end
function Branch(base,c)
if c <= 0 then
-- if the complexity has run out, generate some foliage
local leaves = Leaves:Clone()
local vol = base.Size.x+base.Size.y+base.Size.z -- determine size based on branch size
leaves.Mesh.Scale = leaf_mult[math.random(1,#leaf_mult)]*math.random(vol/3*10,vol/3*12)/10
leaves.Size = leaves.Mesh.Scale*0.75
leaves.CFrame = base.CFrame * CFrame.new(0,base.Size.y/2,0) -- center foliage at top of branch
leaves.Parent = base.Parent
Welder(leaves, base)
else
-- otherwise, make some more branches
local pos = base.CFrame*CFrame.new(0,base.Size/2,0)
local height = base.Size.y
local width = base.Size.x
local nb = math.random(2,2) -- # of possible branches (2 seems to work fine for now)
local r = math.random(45,135) -- rotation of branches on y axis
-- branch split angle difference
-- the less complexity, the greater the possible angle
-- minimum: 20-75; maximum: 40-80
local da = math.random(20+55/c,40+40/c)
-- branch angle (overall angle of all branches)
local ba = math.random(-da/3,da/3)
-- ba+da/2 shouldn't be near or greater than 90 degrees
for i=0,nb-1 do -- for each branch
local branch = base:Clone()
branch.Name = "Branch"
local h = height*math.random(95,115)/100 -- height .95 to 1.15 of original
-- make new cframe
-- move new to top of base, then apply branch angle (ba)
local new = branch.CFrame * CFrame.new(0,height/2,0) * CFrame.Angles(0,0,math.rad(ba))
-- next, rotate branch so that it faces away from others, also apply overall rotation (r)
-- also, apply the split angle (da)
-- finally, move branch upward by half it's size
new = new * CFrame.Angles(0,i*(math.pi*2/nb)+r,math.rad(da/2)) * CFrame.new(0,h/2,0)
-- determine width by branch's final angle; greater the angle, smaller the width
-- also shave off a bit of width for more dramatic change in size
-- a frustum cone mesh would really help here
local w = dot(new,branch.CFrame)*width*0.9
branch.Size = Vector3.new(w,h,w)
branch.CFrame = new
branch.Parent = base.Parent
Welder(branch, base)
-- create the next set of branches with one less complexity
Branch(branch,c-1)
end
end
--wait() -- remove to generate faster
end
-- Main Function ----------------
function GenerateTree(location,complexity,width,height)
--[[
location: position tree will "sprout" out of
complexity: # of times to branch out
determines overall size and quality of tree
produces between m^c+(m^(c+1)-1)/(m-1) parts,
where c is complexity,
and m is either the min or max # of possible branches
(currently, both min and max are 2)
width: initial x/z size of tree base
determines overall thickness of tree
height: initial y size of tree base
contributes to sparseness of tree
]]
print("TreeGen - complexity: " .. complexity .. ", width: " .. width .. ", height: " .. height)
local tree = Instance.new("Model")
tree.Name = "Tree"
tree.Parent = workspace
local base = Base:Clone()
base.Parent = tree
base.Size = Vector3.new(width,height,width)
-- move up by half its height, and rotate randomly
base.CFrame = CFrame.new(location) * CFrame.new(0,height/2,0) * CFrame.Angles(0,math.rad(math.random(1,360)),0)
leafmesh.VertexColor = Vector3.new((math.random() * .1) + .9, (math.random() * .4) + .6, 1)
-- start branching
Branch(base,complexity)
return base
end
function onClicked(mouse)
if on then
local targetPart = mouse.Target
local newTrunk = GenerateTree(mouse.Hit.p, math.random(3,6), math.random(2,4), math.random(5,10))
if targetPart and targetPart:IsA("Terrain") then Welder(newTrunk, targetPart) end -- make trees stick to terrain
end
end
function On()
self:Activate(true)
toolbarbutton:SetActive(true)
on = true
end
function Off()
toolbarbutton:SetActive(false)
on = false
end
------
--GUI-
------
--screengui
g = Instance.new("ScreenGui", game:GetService("CoreGui"))
--------------------------
--SUCCESSFUL LOAD MESSAGE-
--------------------------
loaded = true
print("Tree Plugin Loaded")
+836
View File
@@ -0,0 +1,836 @@
-- Local function definitions
local c = game.Workspace.Terrain
local SetCell = c.SetCell
local GetCell = c.GetCell
local WorldToCellPreferSolid = c.WorldToCellPreferSolid
local CellCornerToWorld = c.CellCornerToWorld
local WorldToCell = c.WorldToCell
local AutoWedge = c.AutowedgeCells
-----------------
--DEFAULT VALUES-
-----------------
loaded = false
on = false
materialNames = {"Empty", "Grass", "Sand", "Granite", "Brick"}
local currentMaterial = 1
local debounce = false
local startCell = nil
local endCell = nil
local regionSelected = false
local dragging = false
local cloning = false
local cloneHitCell = nil
local boxSize = Vector3.new(0, 0, 0)
-- for region resizing
local handles = Instance.new("Handles")
local handlesWereDragged = false
local dragStartX = 0
local dragStartY = 0
local dragStartZ = 0
local dragEndX = 0
local dragEndY = 0
local dragEndZ = 0
local selectionBox = Instance.new("Part")
selectionBox.Anchored = true
selectionBox.CanCollide = false
selectionBox.formFactor = "Custom"
selectionBox.BottomSurface = "Smooth"
selectionBox.TopSurface = "Smooth"
selectionBox.BrickColor = BrickColor.new("Bright blue")
selectionBox.Transparency = .7
local selectionLasso = Instance.new("SelectionBox")
selectionLasso.Adornee = selectionBox
local cloneBox = Instance.new("Part")
cloneBox.Anchored = true
cloneBox.CanCollide = false
cloneBox.formFactor = "Custom"
cloneBox.BottomSurface = "Smooth"
cloneBox.TopSurface = "Smooth"
cloneBox.BrickColor = BrickColor.new("Deep orange")
cloneBox.Transparency = .5
local cloneLasso = Instance.new("SelectionBox")
cloneLasso.Color = BrickColor.new("Deep orange")
cloneLasso.Adornee = cloneBox
---------------
--PLUGIN SETUP-
---------------
self = PluginManager():CreatePlugin()
mouse = self:GetMouse()
mouse.Button1Down:connect(function() mouseDown(mouse) end)
mouse.Button1Up:connect(function() mouseUp(mouse) end)
mouse.Move:connect(function() mouseMove(mouse) end)
self.Deactivation:connect(function()
Off()
end)
toolbar = self:CreateToolbar("Terrain")
toolbarbutton = toolbar:CreateButton("", "RegionEdit", "")
toolbarbutton.Click:connect(function()
if on then
Off()
elseif loaded then
On()
end
end)
-----------------------
--FUNCTION DEFINITIONS-
-----------------------
function putCloneDown()
startX = math.min(startCell.x, endCell.x)
startY = math.min(startCell.y, endCell.y)
startZ = math.min(startCell.z, endCell.z)
endX = math.max(startCell.x, endCell.x)
endY = math.max(startCell.y, endCell.y)
endZ = math.max(startCell.z, endCell.Z)
centerX = math.floor((startX + endX)/2)
centerY = math.floor((startY + endY)/2)
centerZ = math.floor((startZ + endZ)/2)
xOffset = cloneHitCell.x - centerX
yOffset = cloneHitCell.y - centerY
zOffset = cloneHitCell.z - centerZ
xStep = 1
yStep = 1
zStep = 1
if xOffset > 0 then
-- go backwards on x axis
tempVal = startX
startX = endX
endX = tempVal
xStep = -1
end
if yOffset > 0 then
-- go backwards on y axis
tempVal = startY
startY = endY
endY = tempVal
yStep = -1
end
if zOffset > 0 then
-- go backwards on z axis
tempVal = startZ
startZ = endZ
endZ = tempVal
zStep = -1
end
local count = 0
for x = startX, endX, xStep do
for y = startY, endY, yStep do
for z = startZ, endZ, zStep do
local mat, typ, orient = GetCell(c, x, y, z)
SetCell(c, x+xOffset, y+yOffset, z+zOffset, mat, typ, orient)
count = count + 1
end
end
if count > 10000 then count = 0 wait() end
end
-- switch the selected region to the new one :)
startCell = Vector3.new(startX+xOffset, startY+yOffset, startZ+zOffset)
endCell = Vector3.new(endX+xOffset, endY+yOffset, endZ+zOffset)
-- make the clone button look deselected now, if it's not
if clone then
clone.BorderColor3 = Color3.new(0, 0, 0)
clone.BackgroundColor3 = Color3.new(0.5, 0.5, 0.5)
clone.BackgroundTransparency = 0.5
end
end
function dragRegion(face, dist)
startX = math.min(startCell.x, endCell.x)
startY = math.min(startCell.y, endCell.y)
startZ = math.min(startCell.z, endCell.z)
endX = math.max(startCell.x, endCell.x)
endY = math.max(startCell.y, endCell.y)
endZ = math.max(startCell.z, endCell.Z)
if face == Enum.NormalId.Front then
dragStartZ = -math.floor(dist)
elseif face == Enum.NormalId.Back then
dragEndZ = math.floor(dist)
elseif face == Enum.NormalId.Bottom then
dragStartY = -math.floor(dist)
elseif face == Enum.NormalId.Top then
dragEndY = math.floor(dist)
elseif face == Enum.NormalId.Left then
dragStartX = -math.floor(dist)
elseif face == Enum.NormalId.Right then
dragEndX = math.floor(dist)
else return end
-- update the box display
local newStartX = math.min(startCell.x + dragStartX, endCell.x + dragEndX)
local newStartY = math.min(startCell.y + dragStartY, endCell.y + dragEndY)
local newStartZ = math.min(startCell.z + dragStartZ, endCell.z + dragEndZ)
local newEndX = math.max(startCell.x + dragStartX, endCell.x + dragEndX)
local newEndY = math.max(startCell.y + dragStartY, endCell.y + dragEndY)
local newEndZ = math.max(startCell.z + dragStartZ, endCell.z + dragEndZ)
local boxStart = CellCornerToWorld(c, newStartX, newStartY, newStartZ)
local boxEnd = CellCornerToWorld(c, newEndX + 1, newEndY + 1, newEndZ + 1)
boxSize = boxEnd - boxStart
local boxCenter = (boxEnd + boxStart)/2
selectionBox.Size = boxSize
selectionBox.CFrame = CFrame.new(boxCenter)
handlesWereDragged = true
end
function mouseDown(mouse)
if on and not debounce and mouse.Target then
startCell = nil
endCell = nil
regionSelected = false
handles.Visible = false
selectionBox.Parent = nil
selectionLasso.Visible = false
local tempCell = WorldToCellPreferSolid(c, Vector3.new(mouse.Hit.x, mouse.Hit.y, mouse.Hit.z))
if GetCell(c, tempCell.x, tempCell.y, tempCell.z).Value == 0 then return end
dragging = true
startCell = tempCell
elseif on and cloning and cloneHitCell and regionSelected then
regionSelected = false
handles.Visible = false
print("Cloning")
putCloneDown()
-- update selection box to new coords
startX = math.min(startCell.x, endCell.x)
startY = math.min(startCell.y, endCell.y)
startZ = math.min(startCell.z, endCell.z)
endX = math.max(startCell.x, endCell.x)
endY = math.max(startCell.y, endCell.y)
endZ = math.max(startCell.z, endCell.Z)
local boxStart = CellCornerToWorld(c, startX, startY, startZ)
local boxEnd = CellCornerToWorld(c, endX + 1, endY + 1, endZ + 1)
boxSize = boxEnd - boxStart
local boxCenter = (boxEnd + boxStart)/2
selectionBox.Size = boxSize
selectionBox.CFrame = CFrame.new(boxCenter)
--startCell = nil
--endCell = nil
--selectionLasso.Visible = false
handles.Visible = true
regionSelected = true
cloneLasso.Visible = false
cloning = false
debounce = false
end
end
function mouseUp(mouse)
dragging = false
if not startCell or not endCell then return end
if cloning then return end
regionSelected = true
print("Region Selected: "..startCell.x..", "..startCell.y..", "..startCell.z.." to "..endCell.x..", "..endCell.y..", "..endCell.z)
-- enforce ordering on startCell and endCell
startX = math.min(startCell.x, endCell.x)
startY = math.min(startCell.y, endCell.y)
startZ = math.min(startCell.z, endCell.z)
endX = math.max(startCell.x, endCell.x)
endY = math.max(startCell.y, endCell.y)
endZ = math.max(startCell.z, endCell.Z)
startCell = Vector3.new(startX, startY, startZ)
endCell = Vector3.new(endX, endY, endZ)
-- handle handle [lulz]
handles.Visible = true
if handlesWereDragged then
newStartX = math.min(startCell.x + dragStartX, endCell.x + dragEndX)
newStartY = math.min(startCell.y + dragStartY, endCell.y + dragEndY)
newStartZ = math.min(startCell.z + dragStartZ, endCell.z + dragEndZ)
newEndX = math.max(startCell.x + dragStartX, endCell.x + dragEndX)
newEndY = math.max(startCell.y + dragStartY, endCell.y + dragEndY)
newEndZ = math.max(startCell.z + dragStartZ, endCell.z + dragEndZ)
startCell = Vector3.new(newStartX, newStartY, newStartZ)
endCell = Vector3.new(newEndX, newEndY, newEndZ)
handlesWereDragged = false
end
dragStartX = 0
dragStartY = 0
dragStartZ = 0
dragEndX = 0
dragEndY = 0
dragEndZ = 0
end
function mouseMove(mouse)
if on and cloning and regionSelected then
cloneHitCell = WorldToCell(c, Vector3.new(mouse.Hit.x, mouse.Hit.y, mouse.Hit.z))
startX = math.min(startCell.x, endCell.x)
startY = math.min(startCell.y, endCell.y)
startZ = math.min(startCell.z, endCell.z)
endX = math.max(startCell.x, endCell.x)
endY = math.max(startCell.y, endCell.y)
endZ = math.max(startCell.z, endCell.Z)
centerX = math.floor((startX + endX)/2)
centerY = math.floor((startY + endY)/2)
centerZ = math.floor((startZ + endZ)/2)
xOffset = cloneHitCell.x - centerX
yOffset = cloneHitCell.y - centerY
zOffset = cloneHitCell.z - centerZ
cloneBox.CFrame = selectionBox.CFrame + 4 * Vector3.new(xOffset, yOffset, zOffset) -- since cells are 4x4x4
cloneLasso.Visible = true
return
end
if not startCell or not dragging or debounce then return end
endCell = WorldToCellPreferSolid(c, Vector3.new(mouse.Hit.x, mouse.Hit.y, mouse.Hit.z))
startX = math.min(startCell.x, endCell.x)
startY = math.min(startCell.y, endCell.y)
startZ = math.min(startCell.z, endCell.z)
endX = math.max(startCell.x, endCell.x)
endY = math.max(startCell.y, endCell.y)
endZ = math.max(startCell.z, endCell.Z)
local boxStart = CellCornerToWorld(c, startX, startY, startZ)
local boxEnd = CellCornerToWorld(c, endX + 1, endY + 1, endZ + 1)
boxSize = boxEnd - boxStart
local boxCenter = (boxEnd + boxStart)/2
selectionBox.Size = boxSize
selectionBox.CFrame = CFrame.new(boxCenter)
--selectionBox.Parent = game.Workspace
selectionLasso.Visible = true
end
function onFill(newMaterial)
if debounce then
print("Cannot perform that operation until the previous one is complete.")
return
elseif not regionSelected then
print("Please select a region first.")
return
else
debounce = true
print("Filling region.")
startX = math.min(startCell.x, endCell.x)
startY = math.min(startCell.y, endCell.y)
startZ = math.min(startCell.z, endCell.z)
endX = math.max(startCell.x, endCell.x)
endY = math.max(startCell.y, endCell.y)
endZ = math.max(startCell.z, endCell.Z)
--c:SetCells(Region3int16.new(Vector3int16.new(startX, startY, startZ), Vector3int16.new(endX-startX, endY-startY, endZ-startZ)), newMaterial, 0, 0)
local count = 0
for x = startX, endX do
for y = startY, endY do
for z = startZ, endZ do
SetCell(c, x, y, z, newMaterial, 0, 0)
count = count + 1
end
end
if count > 10000 then count = 0 wait() end
end
debounce = false
end
end
function onMaterialChange(newMaterial)
if debounce then
print("Cannot perform that operation until the previous one is complete.")
return
elseif not regionSelected then
print("Please select a region first.")
return
elseif newMaterial == 0 then
print("Cannot change material to Empty. Use Fill button to erase a region.")
return
else
debounce = true
print("Changing material of region.")
startX = math.min(startCell.x, endCell.x)
startY = math.min(startCell.y, endCell.y)
startZ = math.min(startCell.z, endCell.z)
endX = math.max(startCell.x, endCell.x)
endY = math.max(startCell.y, endCell.y)
endZ = math.max(startCell.z, endCell.Z)
local count = 0
for x = startX, endX do
for y = startY, endY do
for z = startZ, endZ do
local mat, typ, orient = GetCell(c, x, y, z)
if mat.Value > 0 then SetCell(c, x, y, z, newMaterial, typ, orient) end
count = count + 1
end
end
if count > 10000 then count = 0 wait() end
end
debounce = false
end
end
function onRotate()
if debounce then
print("Cannot perform that operation until the previous one is complete.")
return
elseif not regionSelected then
print("Please select a region first.")
return
else
debounce = true
print("Rotating region.")
startX = math.min(startCell.x, endCell.x)
startY = math.min(startCell.y, endCell.y)
startZ = math.min(startCell.z, endCell.z)
endX = math.max(startCell.x, endCell.x)
endY = math.max(startCell.y, endCell.y)
endZ = math.max(startCell.z, endCell.Z)
local xCenter = (startX+endX)/2
local zCenter = (startZ+endZ)/2
local xSize = (endX - startX)
local zSize = (endZ - startZ)
local xHalfSize = math.floor(xSize / 2)
local zHalfSize = math.floor(zSize / 2)
local newXCenter = math.floor(xCenter) - zHalfSize + zSize/2
local newZCenter = math.floor(zCenter) - xHalfSize + xSize/2
for y = startY, endY do
-- extract the y-slice
local cellTable = {}
for x = startX, endX do
xIndex = x - xCenter
if (startX+endX)%2 == 1 then
if xIndex > 0 then xIndex = math.ceil(xIndex)
else xIndex = math.floor(xIndex) end
end
cellTable[xIndex] = {}
for z = startZ, endZ do
local mat, typ, orient = GetCell(c, x, y, z)
zIndex = z - zCenter
if (startZ+endZ)%2 == 1 then
if zIndex > 0 then zIndex = math.ceil(zIndex)
else zIndex = math.floor(zIndex) end
end
-- store in our table
cellTable[xIndex][zIndex] = Vector3.new(mat.Value, typ.Value, orient.Value)
-- and clear the y-slice, so we don't get duplication errors
SetCell(c, x, y, z, 0, 0, 0)
end
end
wait()
-- put it back, rotated into the y-slice
for x = math.floor(xCenter) - zHalfSize, math.floor(xCenter) - zHalfSize + zSize do
for z = math.floor(zCenter) - xHalfSize, math.floor(zCenter) - xHalfSize + xSize do
xIndex = x - newXCenter
zIndex = z - newZCenter
if zSize%2 == 1 then
if xIndex > 0 then xIndex = math.ceil(xIndex)
else xIndex = math.floor(xIndex) end
end
if xSize%2 == 1 then
if zIndex > 0 then zIndex = math.ceil(zIndex)
else zIndex = math.floor(zIndex) end
end
SetCell(c, x, y, z, cellTable[zIndex][-xIndex].x, cellTable[zIndex][-xIndex].y, (cellTable[zIndex][-xIndex].z + 3)%4)
end
end
wait()
end
-- update selection to follow rotation
startCell = Vector3.new(math.floor(xCenter) - zHalfSize, startY, math.floor(zCenter) - xHalfSize)
endCell = Vector3.new(math.floor(xCenter) - zHalfSize + zSize, endY, math.floor(zCenter) - xHalfSize + xSize)
local boxStart = CellCornerToWorld(c, startCell.X, startCell.Y, startCell.Z)
local boxEnd = CellCornerToWorld(c, endCell.X + 1, endCell.Y + 1, endCell.Z + 1)
boxSize = boxEnd - boxStart
local boxCenter = (boxEnd + boxStart)/2
selectionBox.Size = boxSize
selectionBox.CFrame = CFrame.new(boxCenter)
selectionLasso.Visible = true
debounce = false
end
end
function onAutoWedge()
if debounce then
print("Cannot perform that operation until the previous one is complete.")
return
elseif not regionSelected then
print("Please select a region first.")
return
elseif newMaterial == 0 then
print("Cannot change material to Empty. Use Fill button to erase a region.")
return
else
debounce = true
print("Smoothing region.")
startX = math.min(startCell.x, endCell.x)
startY = math.min(startCell.y, endCell.y)
startZ = math.min(startCell.z, endCell.z)
endX = math.max(startCell.x, endCell.x)
endY = math.max(startCell.y, endCell.y)
endZ = math.max(startCell.z, endCell.Z)
local count = 0
local numCellsInLayer = (endY - startY)*(endX - startX)
for z = startZ, endZ do
AutoWedge(c, Region3int16.new(Vector3int16.new(startX, startY, z), Vector3int16.new(endX, endY, z)))
if count > 10000 then count = 0 wait() else count = count + numCellsInLayer end
end
debounce = false
end
end
function onClone()
if debounce then
print("Cannot perform that operation until the previous one is complete.")
return
elseif not regionSelected then
print("Please select a region first.")
return
else
debounce = true
cloneHitCell = nil
cloning = true
cloneBox.Size = boxSize
end
end
function On()
self:Activate(true)
toolbarbutton:SetActive(true)
frame.Visible = true
for w = 0, 0.2, 0.1 do
frame.Size = UDim2.new(w, 0, w, 0)
wait(0.0000001)
end
title.Text = "Region Editing"
--freql.Text = materialString
fill.Text = "Fill"
matChange.Text = "Set Material"
clone.Text = "Clone"
autoWedge.Text = "Smooth"
rotate.Text = "Rotate"
on = true
end
function Off()
selectionLasso.Visible = false
cloneLasso.Visible = false
startCell = nil
endCell = nil
regionSelected = false
handles.Visible = false
selectionBox.Parent = nil
-- reset variables
currentMaterial = 1
startCell = nil
endCell = nil
regionSelected = false
dragging = false
cloning = false
cloneHitCell = nil
boxSize = Vector3.new(0, 0, 0)
debounce = false
-- for region resizing
handlesWereDragged = false
dragStartX = 0
dragStartY = 0
dragStartZ = 0
dragEndX = 0
dragEndY = 0
dragEndZ = 0
toolbarbutton:SetActive(false)
title.Text = ""
fill.Text = ""
clone.Text = ""
rotate.Text = ""
matChange.Text = ""
autoWedge.Text = ""
for w = 0.2, 0, -0.1 do
frame.Size = UDim2.new(w, 0, w, 0)
wait(0.0000001)
end
frame.Visible = false
on = false
end
function updateMaterialChoice(choice)
if choice == "Grass" then
currentMaterial = 1
elseif choice == "Sand" then
currentMaterial = 2
elseif choice == "Empty" then
currentMaterial = 0
elseif choice == "Brick" then
currentMaterial = 3
elseif choice == "Granite" then
currentMaterial = 4
end
end
------
--GUI-
------
--screengui
g = Instance.new("ScreenGui", game:GetService("CoreGui"))
selectionLasso.Visible = false
selectionLasso.Parent = g
cloneLasso.Visible = false
cloneLasso.Parent = g
handles.Visible = false
handles.Adornee = selectionBox
handles.Parent = g
handles.MouseDrag:connect(dragRegion)
--load library for with sliders
local RbxGui = LoadLibrary("RbxGui")
--screengui
g = Instance.new("ScreenGui", game:GetService("CoreGui"))
--frame
frame = Instance.new("Frame", g)
frame.Size = UDim2.new(0.2, 0, 0.2, 0)
frame.Position = UDim2.new(0, 0, 0, 0)
frame.BackgroundTransparency = 0.5
frame.Visible = false
--title
title = Instance.new("TextLabel", frame)
title.Position = UDim2.new(0.4, 0, 0.05, 0)
title.Size = UDim2.new(0.2, 0, 0.05, 0)
title.Text = ""
title.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
title.TextColor3 = Color3.new(1, 1, 1)
title.Font = Enum.Font.ArialBold
title.FontSize = Enum.FontSize.Size24
title.BorderColor3 = Color3.new(0, 0, 0)
title.BackgroundTransparency = 1
--[[current frequency display label
freql = Instance.new("TextLabel", frame)
freql.Position = UDim2.new(0.15, 0, 0.4, 0)
freql.Size = UDim2.new(0.1, 0, 0.05, 0)
freql.Text = ""
freql.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
freql.TextColor3 = Color3.new(1, 1, 1)
freql.Font = Enum.Font.ArialBold
freql.FontSize = Enum.FontSize.Size14
freql.BorderColor3 = Color3.new(0, 0, 0)
freql.BackgroundTransparency = 1
--frequency slider
freqSliderGui, freqSliderPosition = RbxGui.CreateSlider(3, 0, UDim2.new(0.2, 0, 0.72, 0))
freqSliderGui.Parent = frame
freqbar = freqSliderGui:FindFirstChild("Bar")
freqbar.Size = UDim2.new(0.75, 0, 0, 5)
freqSliderPosition.Value = 2
freqSliderPosition.Changed:connect(function()
f = freqSliderPosition.Value
if (f == 1) then materialString = "Material: Empty"
elseif (f == 2) then materialString = "Material: Grass"
elseif (f == 3) then materialString = "Material: Sand"
else materialString = "Material: Undefined" end
freql.Text = materialString
end)]]--
local materialSelect, externalMaterialSelectFunction = RbxGui.CreateDropDownMenu(materialNames, updateMaterialChoice)
materialSelect.Name = "MaterialSelect"
materialSelect.Position = UDim2.new(.05, 0, .2, 0)
materialSelect.Size = UDim2.new(.6, 0, .3, 0)
materialSelect.Parent = frame
--fill region button
fill = Instance.new("TextButton", frame)
fill.Position = UDim2.new(0.370, 0, 0.85, 0)
fill.Size = UDim2.new(0.15, 0, 0.1, 0)
fill.Text = ""
fill.BackgroundColor3 = Color3.new(0.5, 0.5, 0.5)
fill.TextColor3 = Color3.new(1, 1, 1)
fill.Font = Enum.Font.ArialBold
fill.FontSize = Enum.FontSize.Size14
fill.BorderColor3 = Color3.new(0, 0, 0)
fill.BackgroundTransparency = 0.5
fill.MouseEnter:connect(function()
fill.BorderColor3 = Color3.new(1, 1, 1)
fill.BackgroundColor3 = Color3.new(0, 0, 0)
fill.BackgroundTransparency = 0.2
end)
fill.MouseButton1Click:connect(function() onFill(currentMaterial) end)
fill.MouseLeave:connect(function()
fill.BorderColor3 = Color3.new(0, 0, 0)
fill.BackgroundColor3 = Color3.new(0.5, 0.5, 0.5)
fill.BackgroundTransparency = 0.5
end)
matChange = Instance.new("TextButton", frame)
matChange.Position = UDim2.new(0.025, 0, 0.85, 0)
matChange.Size = UDim2.new(0.325, 0, 0.1, 0)
matChange.Text = ""
matChange.BackgroundColor3 = Color3.new(0.5, 0.5, 0.5)
matChange.TextColor3 = Color3.new(1, 1, 1)
matChange.Font = Enum.Font.ArialBold
matChange.FontSize = Enum.FontSize.Size14
matChange.BorderColor3 = Color3.new(0, 0, 0)
matChange.BackgroundTransparency = 0.5
matChange.MouseEnter:connect(function()
matChange.BorderColor3 = Color3.new(1, 1, 1)
matChange.BackgroundColor3 = Color3.new(0, 0, 0)
matChange.BackgroundTransparency = 0.2
end)
matChange.MouseButton1Click:connect(function() onMaterialChange(currentMaterial) end)
matChange.MouseLeave:connect(function()
matChange.BorderColor3 = Color3.new(0, 0, 0)
matChange.BackgroundColor3 = Color3.new(0.5, 0.5, 0.5)
matChange.BackgroundTransparency = 0.5
end)
--clone region button
clone = Instance.new("TextButton", frame)
clone.Position = UDim2.new(0.5325, 0, 0.85, 0)
clone.Size = UDim2.new(0.2, 0, 0.1, 0)
clone.Text = ""
clone.BackgroundColor3 = Color3.new(0.5, 0.5, 0.5)
clone.TextColor3 = Color3.new(1, 1, 1)
clone.Font = Enum.Font.ArialBold
clone.FontSize = Enum.FontSize.Size14
clone.BorderColor3 = Color3.new(0, 0, 0)
clone.BackgroundTransparency = 0.5
clone.MouseEnter:connect(function()
clone.BorderColor3 = Color3.new(1, 1, 1)
clone.BackgroundColor3 = Color3.new(0, 0, 0)
clone.BackgroundTransparency = 0.2
end)
clone.MouseButton1Click:connect(onClone)
clone.MouseLeave:connect(function()
clone.BorderColor3 = Color3.new(0, 0, 0)
clone.BackgroundColor3 = Color3.new(0.5, 0.5, 0.5)
clone.BackgroundTransparency = 0.5
end)
--autowedge button
autoWedge = Instance.new("TextButton", frame)
autoWedge.Position = UDim2.new(0.75, 0, 0.85, 0)
autoWedge.Size = UDim2.new(0.2, 0, 0.1, 0)
autoWedge.Text = ""
autoWedge.BackgroundColor3 = Color3.new(0.5, 0.5, 0.5)
autoWedge.TextColor3 = Color3.new(1, 1, 1)
autoWedge.Font = Enum.Font.ArialBold
autoWedge.FontSize = Enum.FontSize.Size14
autoWedge.BorderColor3 = Color3.new(0, 0, 0)
autoWedge.BackgroundTransparency = 0.5
autoWedge.MouseEnter:connect(function()
autoWedge.BorderColor3 = Color3.new(1, 1, 1)
autoWedge.BackgroundColor3 = Color3.new(0, 0, 0)
autoWedge.BackgroundTransparency = 0.2
end)
autoWedge.MouseButton1Click:connect(onAutoWedge)
autoWedge.MouseLeave:connect(function()
autoWedge.BorderColor3 = Color3.new(0, 0, 0)
autoWedge.BackgroundColor3 = Color3.new(0.5, 0.5, 0.5)
autoWedge.BackgroundTransparency = 0.5
end)
--rotate button
rotate = Instance.new("TextButton", frame)
rotate.Position = UDim2.new(0.75, 0, 0.45, 0)
rotate.Size = UDim2.new(0.2, 0, 0.1, 0)
rotate.Text = ""
rotate.BackgroundColor3 = Color3.new(0.5, 0.5, 0.5)
rotate.TextColor3 = Color3.new(1, 1, 1)
rotate.Font = Enum.Font.ArialBold
rotate.FontSize = Enum.FontSize.Size14
rotate.BorderColor3 = Color3.new(0, 0, 0)
rotate.BackgroundTransparency = 0.5
rotate.MouseEnter:connect(function()
rotate.BorderColor3 = Color3.new(1, 1, 1)
rotate.BackgroundColor3 = Color3.new(0, 0, 0)
rotate.BackgroundTransparency = 0.2
end)
rotate.MouseButton1Click:connect(onRotate)
rotate.MouseLeave:connect(function()
rotate.BorderColor3 = Color3.new(0, 0, 0)
rotate.BackgroundColor3 = Color3.new(0.5, 0.5, 0.5)
rotate.BackgroundTransparency = 0.5
end)
--------------------------
--SUCCESSFUL LOAD MESSAGE-
--------------------------
loaded = true
print("Region Editing Plugin Loaded")
@@ -0,0 +1,334 @@
-----------------------------
--LOCAL FUNCTION DEFINITIONS-
-----------------------------
local c = game.Workspace.Terrain
local SetCell = c.SetCell
local GetCell = c.GetCell
local WorldToCellPreferSolid = c.WorldToCellPreferSolid
-----------------
--DEFAULT VALUES-
-----------------
loaded = false
on = false
local materialToImageMap = {}
local materialNames = {"Grass","Sand", "Brick", "Granite"}
local currentMaterial = 1
local changedDragging = 0
local debounce = false
local dragging = false
local r = 5
for i,v in pairs(materialNames) do
materialToImageMap[v] = {}
if v == "Grass" then
materialToImageMap[v].Regular = "http://www.watrbx.wtf/asset/?id=56563112"
elseif v == "Sand" then
materialToImageMap[v].Regular = "http://www.watrbx.wtf/asset/?id=62356652"
elseif v == "Brick" then
materialToImageMap[v].Regular = "http://www.watrbx.wtf/asset/?id=65961537"
materialToImageMap[v].Over = "http://www.watrbx.wtf/asset/?id=65961537"
elseif v == "Granite" then
materialToImageMap[v].Regular = "http://www.watrbx.wtf/asset/?id=65961588"
materialToImageMap[v].Over = "http://www.watrbx.wtf/asset/?id=65961588"
end
end
for i,v in pairs(materialNames) do
game:GetService("ContentProvider"):Preload(materialToImageMap[v].Regular)
end
---------------
--PLUGIN SETUP-
---------------
self = PluginManager():CreatePlugin()
mouse = self:GetMouse()
mouse.Button1Down:connect(function() mouseDown(mouse) end)
mouse.Button1Up:connect(function() mouseUp(mouse) end)
mouse.Move:connect(function() mouseMove(mouse) end)
self.Deactivation:connect(function()
Off()
end)
toolbar = self:CreateToolbar("Terrain")
toolbarbutton = toolbar:CreateButton("", "Material Brush", "materialBrush.png")
toolbarbutton.Click:connect(function()
if on then
Off()
elseif loaded then
On()
end
end)
-----------------------
--FUNCTION DEFINITIONS-
-----------------------
function paint(mouse)
if mouse and mouse.Hit and c and not debounce then
debounce = true
local count = 0
local cellPos = WorldToCellPreferSolid(c, mouse.Hit.p)
for x = cellPos.x - r, cellPos.x + r do
for y = cellPos.y - r, cellPos.y + r do
for z = cellPos.z - r, cellPos.z + r do
local tempCellPos = Vector3.new(x, y, z)
local distSq = (tempCellPos - cellPos):Dot(tempCellPos - cellPos)
if (distSq < r*r) then
local oldMaterial, oldType, oldOrientation = GetCell(c, x, y, z)
if oldMaterial.Value > 0 then SetCell(c, x, y, z, currentMaterial, oldType, oldOrientation) end
end
count = count + 1
end
end
if count > 10000 then count = 0 wait() end
end
debounce = false
end
end
function mouseDown(mouse)
changedDragging = tick()
if on and mouse.Target == game.Workspace.Terrain then
dragging = true
tweeningFrame = true
frame:TweenPosition(UDim2.new(0,-245,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.5,true,function()
hintFrame.Visible = true
tweeningFrame = false
end)
paint(mouse)
end
end
function mouseUp(mouse)
dragging = false
changedDragging = tick()
delay(5,function()
local timeDiff = (changedDragging + 5) - tick()
if timeDiff < 0.2 then
tweeningFrame = true
hintFrame.Visible = false
frame:TweenPosition(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.5,true,function()
tweeningFrame = false
end)
end
end)
end
function mouseMove(mouse)
if on and dragging then
paint(mouse)
end
end
function On()
self:Activate(true)
toolbarbutton:SetActive(true)
local gui = game:GetService("CoreGui"):FindFirstChild("MaterialPainterGui",true)
frame.Position = UDim2.new(0,0,0,0)
frame.Visible = true
hintFrame.Visible = false
halfFrame.Parent = gui
title.Text = "Material Painter"
radl.Text = "Radius: "..r
on = true
end
function Off()
toolbarbutton:SetActive(false)
title.Text = ""
radl.Text = ""
frame.Visible = false
hintFrame.Visible = false
halfFrame.Parent = nil
on = false
end
function updateMaterialChoice(choice)
if choice == "Grass" then
currentMaterial = 1
elseif choice == "Sand" then
currentMaterial = 2
elseif choice == "Erase" then
currentMaterial = 0
elseif choice == "Brick" then
currentMaterial = 3
elseif choice == "Granite" then
currentMaterial = 4
end
end
------
--GUI-
------
--load library for with sliders
local RbxGui = LoadLibrary("RbxGui")
local tweeningFrame = false
--screengui
g = Instance.new("ScreenGui", game:GetService("CoreGui"))
g.Name = "MaterialPainterGui"
local selectedButton = nil
--frame
frame = Instance.new("Frame", g)
frame.Size = UDim2.new(0, 245, 0, 230)
frame.Position = UDim2.new(0, 0, 0, 0)
frame.BackgroundTransparency = 0.5
frame.BorderSizePixel = 0
frame.BackgroundColor3 = Color3.new(0,0,0)
frame.Visible = false
frame.Active = true
hintFrame = Instance.new("Frame",g)
hintFrame.BackgroundTransparency = 0.5
hintFrame.BackgroundColor3 = Color3.new(0,0,0)
hintFrame.Size = UDim2.new(0,15,0,230)
hintFrame.Visible = false
halfFrame = Instance.new("Frame",g)
halfFrame.Name = "HalfFrame"
halfFrame.Size = UDim2.new(0,123,0,230)
halfFrame.BackgroundTransparency = 1
halfFrame.MouseEnter:connect(function()
if not dragging and frame.Position ~= UDim2.new(0, 0, 0, 0) and not tweeningFrame then
tweeningFrame = true
hintFrame.Visible = false
frame:TweenPosition(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quad,0.2,true,function() tweeningFrame = false end)
end
end)
--title
title = Instance.new("TextLabel", frame)
title.Position = UDim2.new(0, 0, 0, 3)
title.Size = UDim2.new(1, 0, 0, 24)
title.Text = ""
title.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
title.TextColor3 = Color3.new(1, 1, 1)
title.Font = Enum.Font.ArialBold
title.FontSize = Enum.FontSize.Size18
title.BorderColor3 = Color3.new(0, 0, 0)
title.BackgroundTransparency = 1
--current radius display label
radl = Instance.new("TextLabel", frame)
radl.Position = UDim2.new(0, 10, 1, -20)
radl.Size = UDim2.new(0.2, 0, 0, 14)
radl.Text = ""
radl.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
radl.TextColor3 = Color3.new(0.95, 0.95, 0.95)
radl.Font = Enum.Font.Arial
radl.FontSize = Enum.FontSize.Size14
radl.BorderColor3 = Color3.new(0, 0, 0)
radl.BackgroundTransparency = 1
--radius slider
radSliderGui, radSliderPosition = RbxGui.CreateSlider(10, 0, UDim2.new(0, 75, 1, -15))
radSliderGui.Parent = frame
radBar = radSliderGui:FindFirstChild("Bar")
radBar.Size = UDim2.new(0.65, 0, 0, 5)
radSliderPosition.Value = r - 1
radSliderPosition.Changed:connect(function()
r = radSliderPosition.Value
radl.Text = "Radius: "..r
end)
local scrollFrame, scrollUp, scrollDown, recalculateScroll = RbxGui.CreateScrollingFrame(nil,"grid")
scrollFrame.Size = UDim2.new(0,240,0,170)
scrollFrame.Position = UDim2.new(0.5,-scrollFrame.Size.X.Offset/2,0,30)
scrollFrame.Parent = frame
scrollUp.Parent = frame
scrollUp.Visible = false
scrollUp.Position = UDim2.new(1,-19,0,30)
scrollDown.Parent = frame
scrollDown.Visible = false
scrollDown.Position = UDim2.new(1,-19,0,30 - 17 + scrollFrame.Size.Y.Offset)
scrollFrame.ChildRemoved:connect(function()
if #scrollFrame:GetChildren() < 35 then
scrollUp.Visible = false
scrollDown.Visible = false
end
end)
scrollFrame.ChildAdded:connect(function()
if #scrollFrame:GetChildren() >= 35 then
scrollUp.Visible = true
scrollDown.Visible = true
end
end)
function createMaterialButton(name)
local buttonWrap = Instance.new("TextButton")
buttonWrap.Text = ""
buttonWrap.Size = UDim2.new(0,32,0,32)
buttonWrap.BackgroundColor3 = Color3.new(1,1,1)
buttonWrap.BorderSizePixel = 0
buttonWrap.BackgroundTransparency = 1
buttonWrap.AutoButtonColor = false
buttonWrap.Name = tostring(name) .. "Button"
local imageButton = Instance.new("ImageButton")
imageButton.AutoButtonColor = false
imageButton.BackgroundTransparency = 1
imageButton.Size = UDim2.new(0,30,0,30)
imageButton.Position = UDim2.new(0,1,0,1)
imageButton.Name = tostring(name) .. "Button"
imageButton.Parent = buttonWrap
imageButton.Image = materialToImageMap[name].Regular
imageButton.MouseEnter:connect(function()
buttonWrap.BackgroundTransparency = 0
end)
imageButton.MouseLeave:connect(function()
if selectedButton ~= buttonWrap then
buttonWrap.BackgroundTransparency = 1
end
end)
imageButton.MouseButton1Click:connect(function()
updateMaterialChoice(name)
if selectedButton ~= buttonWrap then
buttonWrap.BackgroundTransparency = 0
selectedButton.BackgroundTransparency = 1
selectedButton = buttonWrap
end
end)
return buttonWrap
end
for i = 1, #materialNames do
local imageButton = createMaterialButton(materialNames[i])
if materialNames[i] == "Grass" then
selectedButton = imageButton
imageButton.BackgroundTransparency = 0
end
imageButton.Parent = scrollFrame
end
recalculateScroll()
--------------------------
--SUCCESSFUL LOAD MESSAGE-
--------------------------
loaded = true
Binary file not shown.

After

Width:  |  Height:  |  Size: 1006 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

+124
View File
@@ -0,0 +1,124 @@
-----------------
--DEFAULT VALUES-
-----------------
loaded = false
on = false
t = 720
---------------
--PLUGIN SETUP-
---------------
--make internal representation of plugin (needed to call functions like CreateToolbar() and Activate())
self = PluginManager():CreatePlugin()
--Deactivation event is sent when another plugin calls Activate(), turn off when Deactivation event is received
self.Deactivation:connect(function()
Off()
end)
--make a new toolbar, "Utilities" is the name of it, if another plugin also uses a toolbar named "Utilities" they will both create buttons on the same one
toolbar = self:CreateToolbar("Utilities")
--make a button on the toolbar, the first parameter is the text on the button, second is the tooltip, and last is the icon
toolbarbutton = toolbar:CreateButton("", "Time of Day", "time.png")
--make button turn plugin on and off
toolbarbutton.Click:connect(function()
if on then
Off()
elseif loaded then
On()
end
end)
-----------------------
--FUNCTION DEFINITIONS-
-----------------------
--converts time in minutes into a string of the format "hours:minutes:seconds" (seconds are always 00)
function timestring(t)
local tsTemp = "%0.2d:%0.2d:00"
return tsTemp:format(math.floor(t/60), math.floor(t%60))
end
function On()
self:Activate(true)
toolbarbutton:SetActive(true)
frame.Visible = true
for w = 0, 0.8, 0.16 do
frame.Size = UDim2.new(w, 0, w/9, 0)
wait(0.0000001)
end
title.Text = "Time of Day: "..timestring(t)
on = true
end
function Off()
toolbarbutton:SetActive(false)
title.Text = ""
for w = 0.8, 0, -0.16 do
frame.Size = UDim2.new(w, 0, w/9, 0)
wait(0.0000001)
end
frame.Visible = false
on = false
end
------
--GUI-
------
--screengui
g = Instance.new("ScreenGui", game:GetService("CoreGui"))
--frame
frame = Instance.new("Frame", g)
frame.Position = UDim2.new(0.1, 0, 0.85, 0)
frame.Size = UDim2.new(0.8, 0, 0.1, 0)
frame.BackgroundTransparency = 0.7
frame.Visible = false
--title
title = Instance.new("TextLabel", frame)
title.Position = UDim2.new(0.4, 0, 0.25, 0)
title.Size = UDim2.new(0.2, 0, 0.05, 0)
title.Text = ""
title.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
title.TextColor3 = Color3.new(1, 1, 1)
title.Font = Enum.Font.ArialBold
title.FontSize = Enum.FontSize.Size24
title.BorderColor3 = Color3.new(0, 0, 0)
title.BackgroundTransparency = 1
--slider
local RbxGui = LoadLibrary("RbxGui")
sliderGui, sliderPosition = RbxGui.CreateSlider(1440, frame.AbsoluteSize.x * 0.95, UDim2.new(0.025, 0, 0.7, 0))
sliderGui.Parent = frame
bar = sliderGui:FindFirstChild("Bar")
bar.Size = UDim2.new(0.95, 0, 0, 5)
sliderPosition.Value = t
sliderPosition.Changed:connect(function()
t = sliderPosition.Value
ts = timestring(t)
title.Text = "Time of Day: "..ts
title.Text = "Time of Day: "..ts
game:GetService("Lighting").TimeOfDay = ts
end)
--------------------------
--SUCCESSFUL LOAD MESSAGE-
--------------------------
loaded = true
print("Time of Day Plugin Loaded")
+212
View File
@@ -0,0 +1,212 @@
-----------------
--DEFAULT VALUES-
-----------------
on = false
loaded = false
---------------
--PLUGIN SETUP-
---------------
self = PluginManager():CreatePlugin()
mouse = self:GetMouse()
mouse.Button1Down:connect(function() eventl.Text = "Button1Down" end)
mouse.Button1Up:connect(function() eventl.Text = "Button1Up" end)
mouse.Button2Down:connect(function() eventl.Text = "Button2Down" end)
mouse.Button2Up:connect(function() eventl.Text = "Button2Up" end)
mouse.WheelForward:connect(function() eventl.Text = "WheelForward" end)
mouse.WheelBackward:connect(function() eventl.Text = "WheelBackward" end)
mouse.KeyDown:connect(function(key) eventl.Text = "KeyDown("..key..")" end)
mouse.KeyUp:connect(function(key) eventl.Text = "KeyUp("..key..")" end)
mouse.Move:connect(function()
hitl.Text = mouse.Hit.p.x..", "..mouse.Hit.p.y..", "..mouse.Hit.p.z
terrain = game.Workspace.Terrain
if terrain then
cellPos = terrain:WorldToCellPreferSolid(mouse.Hit.p)
if cellPos then
terrainl.Text = cellPos.x..", "..cellPos.y..", "..cellPos.z
else
terrainl.Text = ""
end
end
screenl.Text = mouse.X..", "..mouse.Y
end)
self.Deactivation:connect(function()
Off()
end)
toolbar = self:CreateToolbar("Utilities")
toolbarbutton = toolbar:CreateButton("", "Input Info: Check coordinates of where you click and see input events triggered.", "inputinfo.png")
toolbarbutton.Click:connect(function()
if on then
Off()
elseif loaded then
On()
end
end)
-----------------------
--FUNCTION DEFINITIONS-
-----------------------
function On()
self:Activate(true)
toolbarbutton:SetActive(true)
frame.Visible = true
eventt.Text = ""
eventl.Text = ""
hitt.Text = ""
hitl.Text = ""
terraint.Text = ""
terrainl.Text = ""
screent.Text = ""
screenl.Text = ""
for w = 0, 0.6, 0.12 do
frame.Size = UDim2.new(w, 0, w/4, 0)
wait(0.0000001)
end
eventt.Text = "Last Input Event: "
hitt.Text = "World Coordinates: "
terraint.Text = "Terrain Coordinates: "
screent.Text = "Screen Coordinates: "
on = true
end
function Off()
toolbarbutton:SetActive(false)
eventt.Text = ""
eventl.Text = ""
hitt.Text = ""
hitl.Text = ""
terraint.Text = ""
terrainl.Text = ""
screent.Text = ""
screenl.Text = ""
for w = 0.6, 0, -0.12 do
frame.Size = UDim2.new(w, 0, w/4, 0)
wait(0.0000001)
end
frame.Visible = false
on = false
end
------
--GUI-
------
--screengui
g = Instance.new("ScreenGui", game:GetService("CoreGui"))
--frame
frame = Instance.new("Frame", g)
frame.Position = UDim2.new(0.2, 0, 0.8, 0)
frame.Size = UDim2.new(0.6, 0, 0.2, 0)
frame.BackgroundTransparency = 0.5
frame.Visible = false
--last event title
eventt = Instance.new("TextLabel", frame)
eventt.Position = UDim2.new(0.1, 0, 0.125, 0)
eventt.Size = UDim2.new(0.2, 0, 0.15, 0)
eventt.Text = ""
eventt.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
eventt.TextColor3 = Color3.new(0.95, 0.95, 0.95)
eventt.Font = Enum.Font.ArialBold
eventt.FontSize = Enum.FontSize.Size14
eventt.BorderColor3 = Color3.new(0, 0, 0)
eventt.BackgroundTransparency = 1
--last event display label
eventl = Instance.new("TextLabel", frame)
eventl.Position = UDim2.new(0.4, 0, 0.125, 0)
eventl.Size = UDim2.new(0.5, 0, 0.15, 0)
eventl.Text = ""
eventl.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
eventl.TextColor3 = Color3.new(0.95, 0.95, 0.95)
eventl.Font = Enum.Font.ArialBold
eventl.FontSize = Enum.FontSize.Size14
eventl.BorderColor3 = Color3.new(0, 0, 0)
eventl.BackgroundTransparency = 1
--current world coordinates title
hitt = Instance.new("TextLabel", frame)
hitt.Position = UDim2.new(0.1, 0, 0.325, 0)
hitt.Size = UDim2.new(0.2, 0, 0.15, 0)
hitt.Text = ""
hitt.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
hitt.TextColor3 = Color3.new(0.95, 0.95, 0.95)
hitt.Font = Enum.Font.ArialBold
hitt.FontSize = Enum.FontSize.Size14
hitt.BorderColor3 = Color3.new(0, 0, 0)
hitt.BackgroundTransparency = 1
--current world coordinates display label
hitl = Instance.new("TextLabel", frame)
hitl.Position = UDim2.new(0.4, 0, 0.325, 0)
hitl.Size = UDim2.new(0.5, 0, 0.15, 0)
hitl.Text = ""
hitl.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
hitl.TextColor3 = Color3.new(0.95, 0.95, 0.95)
hitl.Font = Enum.Font.ArialBold
hitl.FontSize = Enum.FontSize.Size14
hitl.BorderColor3 = Color3.new(0, 0, 0)
hitl.BackgroundTransparency = 1
--current terrain coordinates title
terraint = Instance.new("TextLabel", frame)
terraint.Position = UDim2.new(0.1, 0, 0.525, 0)
terraint.Size = UDim2.new(0.2, 0, 0.15, 0)
terraint.Text = ""
terraint.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
terraint.TextColor3 = Color3.new(0.95, 0.95, 0.95)
terraint.Font = Enum.Font.ArialBold
terraint.FontSize = Enum.FontSize.Size14
terraint.BorderColor3 = Color3.new(0, 0, 0)
terraint.BackgroundTransparency = 1
--current terrain coordinates display label
terrainl = Instance.new("TextLabel", frame)
terrainl.Position = UDim2.new(0.4, 0, 0.525, 0)
terrainl.Size = UDim2.new(0.5, 0, 0.15, 0)
terrainl.Text = ""
terrainl.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
terrainl.TextColor3 = Color3.new(0.95, 0.95, 0.95)
terrainl.Font = Enum.Font.ArialBold
terrainl.FontSize = Enum.FontSize.Size14
terrainl.BorderColor3 = Color3.new(0, 0, 0)
terrainl.BackgroundTransparency = 1
--current screen coordinates title
screent = Instance.new("TextLabel", frame)
screent.Position = UDim2.new(0.1, 0, 0.725, 0)
screent.Size = UDim2.new(0.2, 0, 0.15, 0)
screent.Text = ""
screent.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
screent.TextColor3 = Color3.new(0.95, 0.95, 0.95)
screent.Font = Enum.Font.ArialBold
screent.FontSize = Enum.FontSize.Size14
screent.BorderColor3 = Color3.new(0, 0, 0)
screent.BackgroundTransparency = 1
--current screen coordinates display label
screenl = Instance.new("TextLabel", frame)
screenl.Position = UDim2.new(0.4, 0, 0.725, 0)
screenl.Size = UDim2.new(0.5, 0, 0.15, 0)
screenl.Text = ""
screenl.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
screenl.TextColor3 = Color3.new(0.95, 0.95, 0.95)
screenl.Font = Enum.Font.ArialBold
screenl.FontSize = Enum.FontSize.Size14
screenl.BorderColor3 = Color3.new(0, 0, 0)
screenl.BackgroundTransparency = 1
--------------------------
--SUCCESSFUL LOAD MESSAGE-
--------------------------
loaded = true
print("Input Info Plugin Loaded")
@@ -0,0 +1,772 @@
-- we'll load this later; workaround for strange crash
local RbxStamper = nil
local stampControl = nil
local stampingCon = nil
-----------------
--DEFAULT VALUES-
-----------------
local on = false
local loaded = false
local selectionConnection = nil
local myModel = nil
local whichStep = 1
local backEnabled = false
local continueEnabled = false
local bbPreviewCoroutine = nil
local facePreviewCoroutine = nil
local bbPreview = Instance.new("Part")
bbPreview.Name = "SideSelectionBox"
bbPreview.Transparency = .7
bbPreview.formFactor = "Custom"
bbPreview.Size = Vector3.new(4, 4, 4)
bbPreview.Transparency = 1
bbPreview.CanCollide = false
bbPreview.Anchored = true
bbPreview.CFrame = CFrame.new(0, 0, 0)
bbPreview.TopSurface = "Smooth"
bbPreview.BottomSurface = "Smooth"
local alignmentVect = Vector3.new(0, 0, 0)
local alignToFaceText = "[None]"
local unstampableFacesText = "[None]"
local unstampableFaces = {false, false, false, false, false, false}
local unjoinableFacesText = "[None]"
local unjoinableFaces = {false, false, false, false, false, false}
local SURFACE_FROM_NUMBER = {Enum.NormalId.Back, Enum.NormalId.Bottom, Enum.NormalId.Front, Enum.NormalId.Left, Enum.NormalId.Right, Enum.NormalId.Top}
local ALIGN_TO_FACE_MAPPING = {1, nil, 3, 2, 0, nil}
local UNSTAMPABLE_FACE_MAPPING = {"3", "-2", "-3", "-1", "1", "2"}
local SURFACE_TO_NUMBER = {}
local REVERSE_ALIGN_TO_FACE_MAPPING = {}
local REVERSE_UNSTAMPABLE_FACE_MAPPING = {}
for i = 1, #SURFACE_FROM_NUMBER do
SURFACE_TO_NUMBER[SURFACE_FROM_NUMBER[i]] = i
end
for i = 1, #ALIGN_TO_FACE_MAPPING do
if ALIGN_TO_FACE_MAPPING[i] then REVERSE_ALIGN_TO_FACE_MAPPING[ALIGN_TO_FACE_MAPPING[i]] = SURFACE_FROM_NUMBER[i] end
end
for i = 1, #UNSTAMPABLE_FACE_MAPPING do
REVERSE_UNSTAMPABLE_FACE_MAPPING[tonumber(UNSTAMPABLE_FACE_MAPPING[i])] = i
end
---------------
--PLUGIN SETUP-
---------------
self = PluginManager():CreatePlugin()
mouse = self:GetMouse()
mouse.Button1Down:connect(function() onClicked(mouse) end)
self.Deactivation:connect(function()
Off()
end)
toolbar = self:CreateToolbar("Utilities")
toolbarbutton = toolbar:CreateButton("", "Stamper Wizard: Make models you can stamp out!", "stampwizard.png")
toolbarbutton.Click:connect(function()
if on then
Off()
elseif loaded then
On()
end
end)
-----------------------
--FUNCTION DEFINITIONS-
-----------------------
function roundToGrid(vect)
return Vector3.new(math.ceil(vect.X/4)*4, math.ceil(vect.Y/4)*4, math.ceil(vect.Z/4)*4)
end
function toAlignmentString(vect)
local aString = ""
aString = aString .. tostring(math.floor(vect.X*100 + .5) / 100) .. ", "
aString = aString .. tostring(math.floor(vect.Y*100 + .5) / 100) .. ", "
aString = aString .. tostring(math.floor(vect.Z*100 + .5) / 100)
return aString
end
function updateBBPreview()
while bbPreviewBox.Visible do
myModel:SetIdentityOrientation()
local myModelSize = myModel:GetModelSize()
bbPreview.Size = roundToGrid(myModelSize)
bbPreview.CFrame = myModel:GetModelCFrame() + alignmentVect*(bbPreview.Size - myModelSize)*.5
if whichStep == 3 then selectedLabel.Text = "Size: " .. tostring(bbPreview.Size)
elseif whichStep == 4 then selectedLabel.Text = "Alignment: " .. toAlignmentString(alignmentVect)
elseif whichStep == 5 then selectedLabel.Text = alignToFaceText
elseif whichStep == 6 then selectedLabel.Text = unjoinableFacesText
elseif whichStep == 7 then selectedLabel.Text = unstampableFacesText end
wait(.1)
end
bbPreviewCoroutine = nil
end
function getFaceArrayText(array)
local currText = ""
local foundOne = false
for i = 1, 6 do
if array[i] then
if foundOne then currText = currText .. ", " end
currText = currText .. string.gsub(tostring(SURFACE_FROM_NUMBER[i]), "Enum.NormalId.", "")
foundOne = true
end
end
if not foundOne then return "[None]" else return currText end
end
function loadMetaData(myModel)
if not myModel or not myModel:IsA("Model") then return end
if myModel.PrimaryPart then myPrimaryPart = myModel.PrimaryPart end
local jTag = myModel:FindFirstChild("Justification")
local aTag = myModel:FindFirstChild("AutoAlignToFace")
local usTag = myModel:FindFirstChild("UnstampableFaces")
local ujTag = myModel:FindFirstChild("UnjoinableFaces")
if jTag then
alignmentVect = -jTag.Value + Vector3.new(1, 1, 1)
end
if aTag then
alignToFaceSelection.TargetSurface = REVERSE_ALIGN_TO_FACE_MAPPING[aTag.Value]
alignToFaceText = string.gsub(tostring(alignToFaceSelection.TargetSurface), "Enum.NormalId.", "")
end
if usTag then
local uString = usTag.Value
for i = 1, 6 do unstampableFaces[i] = false end
for w in string.gmatch(uString, "[^,]*") do
if tonumber(w) then unstampableFaces[REVERSE_UNSTAMPABLE_FACE_MAPPING[tonumber(w)]] = true end
end
unstampableFacesText = getFaceArrayText(unstampableFaces)
end
if ujTag then
local uString = ujTag.Value
for i = 1, 6 do unjoinableFaces[i] = false end
for w in string.gmatch(uString, "[^,]*") do
if tonumber(w) then unjoinableFaces[REVERSE_UNSTAMPABLE_FACE_MAPPING[tonumber(w)]] = true end
end
unjoinableFacesText = getFaceArrayText(unjoinableFaces)
end
end
function setupStamper(stampModel)
if stampControl then stampControl.Destroy() end
if stampingCon then
stampingCon:disconnect()
stampingCon = nil
end
stampControl = RbxStamper.SetupStamperDragger(stampModel, mouse)
stampingCon = stampControl.Stamped.Changed:connect(function()
if stampControl and stampControl.Stamped.Value then
stampControl.ReloadModel()
end
end)
end
local stampTesting = false
function testStamperModel()
if stampTesting then
stopStampTest()
else
startStampTest()
end
end
local stampedModelListener = nil
local stampedModels = {}
function listenForStampedModels(childAdded)
if childAdded and childAdded.Parent == game.Workspace and childAdded:FindFirstChild("RobloxStamper", true) then
table.insert(stampedModels, childAdded)
end
end
function insertStamperTags(parentModel)
local stampTag = parentModel:FindFirstChild("RobloxStamper")
if not stampTag then
stampTag = Instance.new("BoolValue")
stampTag.Name = "RobloxStamper"
stampTag.Parent = parentModel
end
local modelTag = parentModel:FindFirstChild("RobloxModel")
if not modelTag then
modelTag = Instance.new("BoolValue")
modelTag.Name = "RobloxModel"
modelTag.Parent = parentModel
end
end
function startStampTest()
stampTesting = true
testButton.Text = "Stop testing"
-- start listening for all models stamped via testing mechanism
stampedModelListener = game.Workspace.ChildAdded:connect(listenForStampedModels)
local cloneInstance = myModel:Clone()
finishModel(cloneInstance)
insertStamperTags(cloneInstance)
cloneInstance:ResetOrientationToIdentity()
cloneInstance:BreakJoints()
setupStamper(cloneInstance)
end
function stopStampTest()
stampTesting = false
testButton.Text = "Test it!"
if stampControl then
stampControl.Destroy()
end
-- remove all models stamped via testing mechanism
if stampedModelListener then stampedModelListener:disconnect() end
for i = 1, #stampedModels do stampedModels[i]:Remove() end
stampedModels = {}
end
-- just returns the first ancestor of type "Model", but nil if that model is a direct parent of the game (like game.Workspace)
function getModelFromPart(part)
if not part then return {} end
if part.Parent == game then return {} end
if part:IsA("Model") then
return {part}
else
return getModelFromPart(part.Parent)
end
end
function onClicked(mouse)
if surfaceSelection.Visible then
if whichStep == 5 then
if alignToFaceSelection.Visible and alignToFaceSelection.TargetSurface == surfaceSelection.TargetSurface then
-- turn off that face
alignToFaceText = "[None]"
alignToFaceSelection.Visible = false
else
alignToFaceSelection.TargetSurface = surfaceSelection.TargetSurface
alignToFaceSelection.Visible = true
alignToFaceText = string.gsub(tostring(alignToFaceSelection.TargetSurface), "Enum.NormalId.", "")
end
elseif whichStep == 6 then
local whichFace = SURFACE_TO_NUMBER[surfaceSelection.TargetSurface]
local unjoinableFaceSelector = unjoinableFaceSelections[whichFace]
if unjoinableFaceSelector.Visible then
unjoinableFaceSelector.Visible = false
unjoinableFaces[whichFace] = false
unjoinableFacesText = getFaceArrayText(unjoinableFaces)
else
unjoinableFaceSelector.Visible = true
unjoinableFaces[whichFace] = true
unjoinableFacesText = getFaceArrayText(unjoinableFaces)
end
elseif whichStep == 7 then
local whichFace = SURFACE_TO_NUMBER[surfaceSelection.TargetSurface]
local unstampableFaceSelector = unstampableFaceSelections[whichFace]
if unstampableFaceSelector.Visible then
unstampableFaceSelector.Visible = false
unstampableFaces[whichFace] = false
unstampableFacesText = getFaceArrayText(unstampableFaces)
else
unstampableFaceSelector.Visible = true
unstampableFaces[whichFace] = true
unstampableFacesText = getFaceArrayText(unstampableFaces)
end
end
elseif whichStep == 1 then
-- allow them to click directly on the model they want to choose
if mouse.Target then game.Selection:Set(getModelFromPart(mouse.Target)) end
elseif whichStep == 2 then
-- allow them to click directly on the part they want to choose
if mouse.Target then game.Selection:Set({mouse.Target}) end
end
end
function updateFacePreview()
while bbPreview.Parent do
if mouse.Target == bbPreview and (whichStep ~= 5 or (mouse.TargetSurface ~= Enum.NormalId.Top and mouse.TargetSurface ~= Enum.NormalId.Bottom)) then
surfaceSelection.TargetSurface = mouse.TargetSurface
surfaceSelection.Visible = true
if (whichStep == 5 and alignToFaceSelection.Visible and alignToFaceSelection.TargetSurface == surfaceSelection.TargetSurface) then surfaceSelection.Color = BrickColor.new("Toothpaste")
elseif (whichStep == 6 and unjoinableFaces[SURFACE_TO_NUMBER[surfaceSelection.TargetSurface]]) then surfaceSelection.Color = BrickColor.new("New Yeller")
elseif (whichStep == 7 and unstampableFaces[SURFACE_TO_NUMBER[surfaceSelection.TargetSurface]]) then surfaceSelection.Color = BrickColor.new("Really red")
else surfaceSelection.Color = BrickColor.new("Light stone grey") end
else
surfaceSelection.Visible = false
end
wait(.1)
end
facePreviewCoroutine = nil
end
function alignmentTruncate(num)
if num < -1 then return -1
elseif num > 1 then return 1
else return num end
end
function dragBB(face, dist)
if face == Enum.NormalId.Front then
alignmentVect = Vector3.new(alignmentVect.X, alignmentVect.Y, alignmentTruncate(math.ceil(-dist/20)))
elseif face == Enum.NormalId.Back then
alignmentVect = Vector3.new(alignmentVect.X, alignmentVect.Y, alignmentTruncate(math.floor(dist/20)))
elseif face == Enum.NormalId.Bottom then
alignmentVect = Vector3.new(alignmentVect.X, alignmentTruncate(math.ceil(-dist/20)), alignmentVect.Z)
elseif face == Enum.NormalId.Top then
alignmentVect = Vector3.new(alignmentVect.X, alignmentTruncate(math.floor(dist/20)), alignmentVect.Z)
elseif face == Enum.NormalId.Left then
alignmentVect = Vector3.new(alignmentTruncate(math.ceil(-dist/20)), alignmentVect.Y, alignmentVect.Z)
elseif face == Enum.NormalId.Right then
alignmentVect = Vector3.new(alignmentTruncate(math.floor(dist/20)), alignmentVect.Y, alignmentVect.Z)
else return end
end
function refreshPage(whichPage)
print("refresh")
if whichPage == 1 then
-- Select Model
continueButton.Text = "Continue"
infoBox.Text = "Select the model you want to turn into a stamper part."
if myModel then selectedLabel.Text = myModel.Name setContinueEnabled(true) if #game.Selection:Get() ~= 1 or game.Selection:Get()[1] ~= myModel then game.Selection:Set({myModel}) end else selectedLabel.Text = "[None]" setContinueEnabled(false) end
elseif whichPage == 2 then
-- Select Primary Part
bbPreviewBox.Visible = false
infoBox.Text = "Select one part inside your model to be the \"key part\"."
if myPrimaryPart then selectedLabel.Text = myPrimaryPart.Name setContinueEnabled(true) if #game.Selection:Get() ~= 1 or game.Selection:Get()[1] ~= myPrimaryPart then game.Selection:Set({myPrimaryPart}) end else selectedLabel.Text = "[None]" setContinueEnabled(false) end
elseif whichPage == 3 then
-- Create Bounding Box
alignmentHandles.Visible = false
myModel.PrimaryPart = myPrimaryPart
infoBox.Text = "Rotate and adjust the model so the green bounding box looks good."
if #game.Selection:Get() ~= 1 or game.Selection:Get()[1] ~= myModel then game.Selection:Set({myModel}) end
setContinueEnabled(true)
elseif whichPage == 4 then
-- Set Alignment Within Bounding Box
infoBox.Text = "Move the green bounding box so your model is aligned correctly inside it."
alignToFaceSelection.Visible = false
surfaceSelection.Visible = false
alignmentHandles.Visible = true
if #game.Selection:Get() ~= 1 or game.Selection:Get()[1] ~= myModel then game.Selection:Set({myModel}) end
bbPreview.Parent = nil
setContinueEnabled(true)
elseif whichPage == 5 then
-- AutoAlignToFace
alignmentHandles.Visible = false
if (alignToFaceText ~= "[None]") then alignToFaceSelection.Visible = true end
for i = 1, 6 do unjoinableFaceSelections[i].Visible = false end
infoBox.Text = "[Optional Step]: Select a side to be \"always facing the wall\"."
if #game.Selection:Get() ~= 0 then game.Selection:Set({}) end
setContinueEnabled(true)
elseif whichPage == 6 then
-- Unjoinable Faces
alignToFaceSelection.Visible = false
for i = 1, 6 do unjoinableFaceSelections[i].Visible = unjoinableFaces[i] end
for i = 1, 6 do unstampableFaceSelections[i].Visible = false end
infoBox.Text = "[Optional Step]: Select any sides you don't want things to join to when stamping."
if #game.Selection:Get() ~= 0 then game.Selection:Set({}) end
setContinueEnabled(true)
elseif whichPage == 7 then
-- Unstampable Faces
for i = 1, 6 do unstampableFaceSelections[i].Visible = unstampableFaces[i] end
for i = 1, 6 do unjoinableFaceSelections[i].Visible = false end
infoBox.Text = "[Optional Step]: Select any sides you don't want to be stampable or have things stamp to."
continueButton.Text = "Continue"
testButton.Visible = false
if #game.Selection:Get() ~= 0 then game.Selection:Set({}) end
setContinueEnabled(true)
stopStampTest()
elseif whichPage == 8 then
-- Test it out!
for i = 1, 6 do unstampableFaceSelections[i].Visible = false end
bbPreview.Parent = nil
selectedLabel.Text = myModel.Name
infoBox.Text = "Test it out! Click \"Finish\" when it's ready to publish!"
continueButton.Text = "Finish"
testButton.Visible = true
setContinueEnabled(true)
end
if whichPage >=3 and whichPage <= 7 then
bbPreviewBox.Visible = true
if not bbPreviewCoroutine then
bbPreviewCoroutine = coroutine.create(updateBBPreview)
coroutine.resume(bbPreviewCoroutine)
end
if whichPage > 4 then
bbPreview.Parent = game.Workspace
if not facePreviewCoroutine then
facePreviewCoroutine = coroutine.create(updateFacePreview)
coroutine.resume(facePreviewCoroutine)
end
end
end
stepText.Text = "Step " .. tostring(whichPage) .. " of 8"
end
function setContinueEnabled(isEnabled)
if isEnabled then
continueButton.TextColor3 = Color3.new(1, 1, 1)
else
continueButton.TextColor3 = Color3.new(.5, .5, .5)
end
continueEnabled = isEnabled
end
function setBackEnabled(isEnabled)
if isEnabled then
backButton.TextColor3 = Color3.new(1, 1, 1)
else
backButton.TextColor3 = Color3.new(.5, .5, .5)
end
backEnabled = isEnabled
end
function onSelect()
print("onSelect")
local selected = game.Selection:Get()
if whichStep == 1 then -- looking for a single model to be selected
if #selected == 1 and selected[1] == myModel then return end
if #selected == 1 and selected[1]:IsA("Model") and selected[1] ~= game.Workspace then
myModel = selected[1]
myPrimaryPart = nil
else
myModel = nil
myPrimaryPart = nil
end
refreshPage(1)
elseif whichStep == 2 then
if #selected == 1 and selected[1] == myPrimaryPart then return end
if #selected == 1 and selected[1]:IsA("BasePart") and selected[1].Parent == myModel then
myPrimaryPart = selected[1]
else
myPrimaryPart = nil
end
refreshPage(2)
end
end
function On()
self:Activate(true)
toolbarbutton:SetActive(true)
frame.Visible = true
for w = 0, 0.6, 0.12 do
frame.Size = UDim2.new(w, 0, 2*w/3, 0)
wait()
end
on = true
-- connect to the game's selection
selectionConnection = game.Selection.SelectionChanged:connect(onSelect)
refreshPage(whichStep)
end
function Off()
toolbarbutton:SetActive(false)
for w = 0.6, 0, -0.12 do
frame.Size = UDim2.new(w, 0, 2*w/3, 0)
wait()
end
frame.Visible = false
on = false
if selectionConnection then selectionConnection:disconnect() selectionConnection = nil end
alignmentHandles.Visible = false
surfaceSelection.Visible = false
alignToFaceSelection.Visible = false
for i = 1, 6 do unstampableFaceSelections[i].Visible = false end
for i = 1, 6 do unjoinableFaceSelections[i].Visible = false end
stopStampTest()
if whichStep ~= 3 then bbPreviewBox.Visible = false end
bbPreview.Parent = nil
end
function resetWizard()
bbPreview.Parent = nil
bbPreviewBox.Visible = false
wait(.5) -- so that we can kill our coroutines safely
myModel = nil
myPrimaryPart = nil
whichStep = 1
for i = 1, 6 do unstampableFaces[i] = false end
for i = 1, 6 do unjoinableFaces[i] = false end
alignToFaceText = "[None]"
alignmentVect = Vector3.new(0, 0, 0)
testButton.Visible = false
setBackEnabled(false)
setContinueEnabled(false)
alignmentHandles.Visible = false
surfaceSelection.Visible = false
alignToFaceSelection.Visible = false
for i = 1, 6 do unstampableFaceSelections[i].Visible = false unstampableFaces[i] = false end
for i = 1, 6 do unjoinableFaceSelections[i].Visible = false unjoinableFaces[i] = false end
refreshPage(whichStep)
end
function finishModel(model)
if alignmentVect.magnitude > .04 then
local alignTag = model:FindFirstChild("Justification")
if not alignTag then alignTag = Instance.new("Vector3Value") end
alignTag.Name = "Justification"
alignTag.Value = -alignmentVect + Vector3.new(1, 1, 1)
alignTag.Parent = model
elseif model:FindFirstChild("Justification") then model.Justification:Remove() end
if alignToFaceText ~= "[None]" then
local autoAlignToFaceTag = model:FindFirstChild("AutoAlignToFace")
if not autoAlignToFaceTag then autoAlignToFaceTag = Instance.new("NumberValue") end
autoAlignToFaceTag.Name = "AutoAlignToFace"
autoAlignToFaceTag.Value = ALIGN_TO_FACE_MAPPING[SURFACE_TO_NUMBER[alignToFaceSelection.TargetSurface]]
autoAlignToFaceTag.Parent = model
elseif model:FindFirstChild("AutoAlignToFace") then model.AutoAlignToFace:Remove() end
local unstampableFaceString = ""
local foundOne = false
for i = 1, #unstampableFaces do
if unstampableFaces[i] then
if foundOne then unstampableFaceString = unstampableFaceString .. ", " end
unstampableFaceString = unstampableFaceString .. UNSTAMPABLE_FACE_MAPPING[i]
foundOne = true
end
end
if foundOne then
local unstampableFaceTag = model:FindFirstChild("UnstampableFaces")
if not unstampableFaceTag then unstampableFaceTag = Instance.new("StringValue") end
unstampableFaceTag.Name = "UnstampableFaces"
unstampableFaceTag.Value = unstampableFaceString
unstampableFaceTag.Parent = model
elseif model:FindFirstChild("UnstampableFaces") then model.UnstampableFaces:Remove() end
local unjoinableFaceString = ""
foundOne = false
for i = 1, #unjoinableFaces do
if unjoinableFaces[i] then
if foundOne then unjoinableFaceString = unjoinableFaceString .. ", " end
unjoinableFaceString = unjoinableFaceString .. UNSTAMPABLE_FACE_MAPPING[i]
foundOne = true
end
end
if foundOne then
local unjoinableFaceTag = model:FindFirstChild("UnjoinableFaces")
if not unjoinableFaceTag then unjoinableFaceTag = Instance.new("StringValue") end
unjoinableFaceTag.Name = "UnjoinableFaces"
unjoinableFaceTag.Value = unjoinableFaceString
unjoinableFaceTag.Parent = model
elseif model:FindFirstChild("UnjoinableFaces") then model.UnjoinableFaces:Remove() end
end
function goBack()
if backEnabled then
whichStep = whichStep - 1
if whichStep == 1 then setBackEnabled(false) end
setContinueEnabled(true)
refreshPage(whichStep)
end
end
function goForwards()
if continueEnabled then
whichStep = whichStep + 1
setContinueEnabled(false)
setBackEnabled(true)
if whichStep == 9 then
stopStampTest()
finishModel(myModel)
resetWizard()
--Off() -- if we want to auto-close the wizard after we finish
else
if whichStep == 2 then
-- upon selecting a model, we propagate all other values with the current model's values
loadMetaData(myModel)
end
refreshPage(whichStep)
end
end
end
------
--GUI-
------
--screengui
g = Instance.new("ScreenGui", game:GetService("CoreGui"))
--frame
frame = Instance.new("Frame", g)
frame.Position = UDim2.new(0.2, 20, 0, 0)
frame.Size = UDim2.new(0.6, -40, .4, 0)
frame.Style = Enum.FrameStyle.RobloxRound
frame.BackgroundTransparency = 0.5
frame.Visible = false
titleText = Instance.new("TextLabel", frame)
titleText.Name = "Title"
titleText.BackgroundTransparency = 1
titleText.Font = Enum.Font.ArialBold
titleText.FontSize = Enum.FontSize.Size24
titleText.Size = UDim2.new(1, 0, 0, 24)
titleText.Text = "Stamper Model Maker"
titleText.TextColor3 = Color3.new(1,1,1)
titleText.TextYAlignment = Enum.TextYAlignment.Center
stepText = titleText:Clone()
stepText.Name = "StepsLabel"
stepText.Text = "Step 1 of 6"
stepText.Position = UDim2.new(0, -5, .81, 0)
stepText.Font = Enum.Font.Arial
stepText.Parent = frame
infoBox = Instance.new("TextLabel", frame)
infoBox.Name = "InfoBox"
infoBox.Font = Enum.Font.Arial
infoBox.FontSize = Enum.FontSize.Size24
infoBox.Size = UDim2.new(1,0,0,24)
infoBox.Position = UDim2.new(0, 0, 0.15, 0)
infoBox.BackgroundTransparency = 0.75
infoBox.TextColor3 = Color3.new(1,1,1)
infoBox.Text = "Select the model you want to turn into a stamper part."
infoBox.TextWrap = false
infoBox.TextXAlignment = Enum.TextXAlignment.Left
infoBox.TextYAlignment = Enum.TextYAlignment.Top
infoBox.Visible = true
modelInfoFrame = Instance.new("Frame", frame)
modelInfoFrame.Style = Enum.FrameStyle.RobloxRound
modelInfoFrame.Name = "ModelInfo"
modelInfoFrame.Position = UDim2.new(.395, 0, .325, 0)
modelInfoFrame.Size = UDim2.new(.2, 0, .4, 0)
selectedLabel = stepText:Clone()
selectedLabel.Name = "SelectionLabel"
selectedLabel.Text = "[None]"
selectedLabel.Position = UDim2.new(0, 0, .35, 0)
selectedLabel.Parent = modelInfoFrame
backButton = Instance.new("TextButton", frame)
backButton.Name = "Back"
backButton.Font = Enum.Font.Arial
backButton.FontSize = Enum.FontSize.Size18
backButton.Size = UDim2.new(0, 200, 0, 50)
backButton.Position = UDim2.new(0, 1, 1, -55)
backButton.BackgroundTransparency = 1
backButton.Style = Enum.ButtonStyle.RobloxButtonDefault
backButton.Text = "Back"
backButton.TextColor3 = Color3.new(0.5, 0.5, 0.5)
backButton.MouseButton1Click:connect(goBack)
continueButton = backButton:Clone()
continueButton.Name = "Continue"
continueButton.Text = "Continue"
continueButton.Position = UDim2.new(1, -200, 1, -55)
continueButton.MouseButton1Click:connect(goForwards)
continueButton.Parent = frame
testButton = backButton:Clone()
testButton.Name = "Test"
testButton.Text = "Test it!"
testButton.TextColor3 = Color3.new(1, 1, 1)
testButton.Position = UDim2.new(1, -200, 1, -110)
testButton.MouseButton1Click:connect(testStamperModel)
testButton.Visible = false
testButton.Parent = frame
bbPreviewBox = Instance.new("SelectionBox")
bbPreviewBox.Color = BrickColor.new("Lime green")
bbPreviewBox.Adornee = bbPreview
bbPreviewBox.Visible = false
bbPreviewBox.Parent = frame
alignmentHandles = Instance.new("Handles")
alignmentHandles.Visible = false
alignmentHandles.Adornee = bbPreview
alignmentHandles.Parent = frame
alignmentHandles.MouseDrag:connect(dragBB)
alignmentHandles.Color = BrickColor.new("Lime green")
surfaceSelection = Instance.new("SurfaceSelection")
surfaceSelection.Name = "SurfaceSelection"
surfaceSelection.Color = BrickColor.new("White")
surfaceSelection.Transparency = .8
surfaceSelection.Visible = false
surfaceSelection.Adornee = bbPreview
alignToFaceSelection = surfaceSelection:Clone()
alignToFaceSelection.Name = "AlignToFaceSelection"
alignToFaceSelection.Color = BrickColor.new("Cyan")
unstampableFaceSelections = {}
for i = 1, 6 do
local newUnstampableFaceSelection = alignToFaceSelection:Clone()
newUnstampableFaceSelection.Name = "UnstampableFaceSelection"
newUnstampableFaceSelection.Color = BrickColor.new("Bright red")
newUnstampableFaceSelection.TargetSurface = SURFACE_FROM_NUMBER[i]
newUnstampableFaceSelection.Parent = frame
table.insert(unstampableFaceSelections, newUnstampableFaceSelection)
end
unjoinableFaceSelections = {}
for i = 1, 6 do
local newUnjoinableFaceSelection = alignToFaceSelection:Clone()
newUnjoinableFaceSelection.Name = "UnjoinableFaceSelection"
newUnjoinableFaceSelection.Color = BrickColor.new("Deep orange")
newUnjoinableFaceSelection.TargetSurface = SURFACE_FROM_NUMBER[i]
newUnjoinableFaceSelection.Parent = frame
table.insert(unjoinableFaceSelections, newUnjoinableFaceSelection)
end
alignToFaceSelection.Parent = frame
surfaceSelection.Parent = frame
-- load the lib'ary!
RbxStamper = LoadLibrary("RbxStamper")
if not RbxStamper then
print("Error: RbxStamper Library Load Fail! Returning")
return nil
end
--------------------------
--SUCCESSFUL LOAD MESSAGE-
--------------------------
loaded = true
print("StamperWizard Plugin Loaded")
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

+748
View File
@@ -0,0 +1,748 @@
--[[
This tool is designed to create bodies of water in terrain, below is an explanation of all the parameters that are adjustable (also accessible from the help menu in the tool)
Length: Adjusts the z-axis size of the lake
Width: Adjusts the x-axis size of the lake
Depth: Adjusts the y-axis size of the lake, this size is always from the currently selected terrain cell down
Curvature:
Approximates a spherical or ellipsoid shape that curves the lake inward. 100% is the maximum amount of curve (like a perfectly round sphere), 0% is no curve (like an above-ground swimming pool)
Water Level:
The percentage to the top of the lake that is full of water (this is a percentage of the depth slider, not volume of the lake)
Lake Types:
Elliptical: draws a lake that approximates an ellpsoid
Circular: the same thing as Elliptical, except it locks the length and width sliders so they are always the same.
Rectangular: creates a lake to the exact shape of what is selected, which is always rectangular
Water Type:
These are directions that the water force will be applied to. All cardinal directions are allows (x,y,z and their negatives)
Water Force:
The amount of force to be applied to the specified water type. Current choices are None, Small, Medium, Strong, and Max.
Create Walls:
builds walls around the the lake when created, so all water is encapsulated on its sides by a material (material selected by Material Selection scrollbar)
Remove Above:
Removes cells that are above the lake to be generated. The cells to be removed are the ones inside the red selection box.
Material Selection:
The material used to create walls, if this option is selected.
]]
-- Local function definitions
local c = game.Workspace.Terrain
local SetCell = c.SetCell
local SetWaterCell = c.SetWaterCell
local SetCells = c.SetCells
local GetCell = c.GetCell
local WorldToCellPreferSolid = c.WorldToCellPreferSolid
local CellCenterToWorld = c.CellCenterToWorld
local AutoWedge = c.AutowedgeCell
local AutoWedgeCells = c.AutowedgeCells
local maxYExtents = c.MaxExtents.Max.Y
-- UI variables
local dragBar = nil
local containerFrame = nil
local buttonDownTick = nil
local doubleClickTime = 0.4
local didCancelCreate = false
local loadingFrame, updateLoadingGuiPercent, cancelLoadingPressed = nil
local currentSelection = nil
local groundSelection = nil
local shapes = {"Elliptical", "Circular", "Rectangular"}
local waterTypes = {"NegX","X","NegY","Y","NegZ","Z"}
local waterForces = {"None", "Small", "Medium", "Strong", "Max"}
-----------------
--DEFAULT VALUES-
-----------------
local loaded = false
local on = false
local debounce = false
local lastCell = nil
local zeroVector = Vector3.new(0,0,0)
local selectionUpdateFunc, destroyFunc = nil
local selectionGroundUpdateFunc, destroyGroundFunc = nil
-- values exposed to user
local currMaterial = Enum.CellMaterial.Grass
local radius = 15
local depth = 15
local xWidth = 15
local zWidth = 15
local waterLevel = 1.01
local percentOfSphere = 1.01
local createWalls = true
local removeAbove = true
local currLakeShape = nil
local currWaterType = 0
local currWaterForce = 0
--load libraries
local RbxGui = LoadLibrary("RbxGui")
local RbxUtil = LoadLibrary("RbxUtility")
---------------
--PLUGIN SETUP-
---------------
self = PluginManager():CreatePlugin()
self.Deactivation:connect(function() Off() end)
mouse = self:GetMouse()
mouse.Button1Down:connect(function() onMouseButtonDown() end)
mouse.Button1Up:connect(function() onMouseButtonUp() end)
mouse.Move:connect(function() mouseMove() end)
toolbar = self:CreateToolbar("Water")
toolbarbutton = toolbar:CreateButton("", "Lake Creator", "lake.png")
toolbarbutton.Click:connect(function()
if on then
Off()
elseif loaded then
On()
end
end)
-----------------------
--FUNCTION DEFINITIONS-
-----------------------
-- srs translation from region3 to region3int16
function Region3ToRegion3int16(region3)
local theLowVec = region3.CFrame.p - (region3.Size/2) + Vector3.new(2,2,2)
local lowCell = WorldToCellPreferSolid(c,theLowVec)
local theHighVec = region3.CFrame.p + (region3.Size/2) - Vector3.new(2,2,2)
local highCell = WorldToCellPreferSolid(c, theHighVec)
local highIntVec = Vector3int16.new(highCell.x,highCell.y,highCell.z)
local lowIntVec = Vector3int16.new(lowCell.x,lowCell.y,lowCell.z)
return Region3int16.new(lowIntVec,highIntVec)
end
function cancelLakeCreate()
loadingFrame.Visible = false
didCancelCreate = true
end
function makeRectangularLake(x,y,z)
-- first, find region we need to cut out
local selectionToCutout = currentSelection
local selectionToFill = groundSelection
local innerRegion = Region3.new(( selectionToFill.CFrame.p - selectionToFill.Size/2) + Vector3.new(4,4,4),
( selectionToFill.CFrame.p + selectionToFill.Size/2) - Vector3.new(4,0,4))
-- first, clear out all cells around selection if user specified so
if removeAbove then
SetCells(c,Region3ToRegion3int16(selectionToCutout),0,0,0)
end
-- Make walls around lake if we specified so
if createWalls then
-- now fill in all cells with our border material
SetCells(c,Region3ToRegion3int16(selectionToFill), currMaterial,0,0)
-- cutout the cells in the lake
SetCells(c,Region3ToRegion3int16(innerRegion), 0,0,0)
else
SetCells(c,Region3ToRegion3int16(innerRegion),0,0,0)
end
-- last, fill with water to the appropriate level
local waterHeight = ((selectionToFill.CFrame.p.y + selectionToFill.Size.y/2) - (selectionToFill.CFrame.p.y - selectionToFill.Size.y/2)) * waterLevel
local lowerVec,higherVec = nil
if createWalls then
lowerVec = innerRegion.CFrame.p - innerRegion.Size/2
higherVec = innerRegion.CFrame.p + innerRegion.Size/2
else
lowerVec = selectionToFill.CFrame.p - selectionToFill.Size/2
higherVec = selectionToFill.CFrame.p + selectionToFill.Size/2
end
higherVec = Vector3.new(higherVec.x, lowerVec.y + waterHeight - 4, higherVec.z)
local waterRegion = Region3ToRegion3int16(Region3.new(lowerVec,higherVec))
-- todo: make this call do force/direction when can be mass set
SetCells(c, waterRegion, Enum.CellMaterial.Water, 0, 0)
for k = lowerVec.z + 2,higherVec.z - 2,4 do
for j = lowerVec.y + 2,higherVec.y - 2,4 do
for i = lowerVec.x + 2, higherVec.x - 2,4 do
local cellPos = WorldToCellPreferSolid(c,Vector3.new(i,j,k))
SetWaterCell(c,cellPos.x,cellPos.y,cellPos.z,currWaterForce,currWaterType)
end
end
end
end
function drillDownColumn(x,y,z, percentInEllipsoid, lowY, absoluteWaterLine)
local waterOrEmptyCells = 0
if percentInEllipsoid <= 1 then
waterOrEmptyCells = (math.pow(percentInEllipsoid,2) * depth * percentOfSphere) + (math.pow(percentInEllipsoid,2) * percentOfSphere)
waterOrEmptyCells = math.max(depth - waterOrEmptyCells,0)
end
local waterCells = math.max(absoluteWaterLine - (y - waterOrEmptyCells),0)
local emptyCells = waterOrEmptyCells - waterCells
if waterCells > 0 then
local emptyCellsLowY = math.max(y - emptyCells - waterCells + 1,2)
-- todo: make this call do force/direction when can be mass set
SetCells(c,Region3int16.new(Vector3int16.new(x,emptyCellsLowY,z),Vector3int16.new(x, y - emptyCells, z)),Enum.CellMaterial.Water,0,0)
for i = emptyCellsLowY, y - emptyCells do
SetWaterCell(c,x,i,z,currWaterForce,currWaterType)
end
end
if emptyCells > 0 then
local emptyCellsLowY = math.max(y - emptyCells + 1,2)
SetCells(c,Region3int16.new(Vector3int16.new(x,emptyCellsLowY,z),Vector3int16.new(x,y,z)),Enum.CellMaterial.Empty,0,0)
end
if createWalls then
local materialCells = math.max(depth - waterOrEmptyCells,0)
if materialCells > 0 then
SetCells(c,Region3int16.new(Vector3int16.new(x,math.max(lowY - 1,1),z),Vector3int16.new(x,lowY + (materialCells - 1),z)),currMaterial,0,0)
end
end
end
function makeEllipsoidLake(x,y,z)
local startTime = tick()
-- check to see if we should remove terrain above
local topSelection = currentSelection
local bottomSelection = groundSelection
if topSelection ~= bottomSelection then
local removeRegion = Region3.new(bottomSelection.CFrame.p + Vector3.new(-bottomSelection.Size.x/2,bottomSelection.Size.y/2,-bottomSelection.Size.z/2), topSelection.CFrame.p + topSelection.Size/2)
SetCells(c, Region3ToRegion3int16(removeRegion), 0, 0, 0)
end
-- reset our processing gui
updateLoadingGuiPercent(0)
-- calculate how many steps we will use for processing (For updating processing gui)
local totalSteps = (xWidth*2 + 3) * (zWidth*2 + 3)
totalSteps = totalSteps * 2
local currStep = 0
local percentDone = 0
-- some variables we can precompute before O(n^2) loop
local lowY = y - (depth - 1)
local absoluteWaterLine = y - (depth * (1 - waterLevel))
-- loop thru xz plane to determine what cells to nuke/fill
for k = z - (zWidth + 1), z + (zWidth + 1) do
-- used in inner loop, but set here for effeciency
local zEllipsoidComponent = math.pow((z - k)/zWidth,2)
for i = x - (xWidth + 1), x + (xWidth + 1) do
-- check to see if we have canceled, if not keep going
if didCancelCreate then
didCancelCreate = false
return
end
-- using ellipsoid equation to detemine if cell should be deleted
local percentInEllipsoid = math.pow((x - i)/xWidth,2) + zEllipsoidComponent
-- at each xz coordinate, drill down depth and set cells in larger chunks
drillDownColumn(i,y,k, percentInEllipsoid, lowY, absoluteWaterLine)
-- update our processing gui
currStep = currStep + 1
percentDone = currStep/totalSteps
updateLoadingGuiPercent(percentDone)
-- do a calculated wait every once and awhile (stops studio from hanging)
currStep = currStep + 1
local first, fraction = math.modf(currStep/1000)
if fraction == 0 then wait() end
end
if not loadingFrame.Visible then
loadingFrame.Visible = (tick() - startTime) > 0.5 and percentDone < 0.4
end
end
end
-- makes a crater at point (x, y, z) in cluster c
function makeCrater(x, y, z)
-- we need to autowedge a bit outside of selection, allows for smoother terain around lakes
local autoWedgeSelection = Region3.new( (groundSelection.CFrame.p - groundSelection.Size/2) - Vector3.new(8,8,8),
(groundSelection.CFrame.p + groundSelection.Size/2) + Vector3.new(8,8,8))
disablePreview()
if currLakeShape == "Rectangular" then -- simply cut out the selection box for the lake
makeRectangularLake(x, y, z)
else -- we want something to approximate curves for our lake
makeEllipsoidLake(x, y, z)
end
AutoWedgeCells(c,Region3ToRegion3int16(autoWedgeSelection))
loadingFrame.Visible = false
end
function disablePreview()
if destroyFunc then
destroyFunc()
selectionUpdateFunc = nil
destroyGroundFunc()
selectionGroundUpdateFunc = nil
end
end
-- creates selection boxes around the areas that will be affected by lake creator
function createSelections()
selectionUpdateFunc, destroyFunc = RbxUtil.SelectTerrainRegion(Region3.new(zeroVector,zeroVector),
BrickColor.new("Really red"),
true,
game.CoreGui)
selectionGroundUpdateFunc, destroyGroundFunc = RbxUtil.SelectTerrainRegion( Region3.new(zeroVector,zeroVector),
BrickColor.new("Toothpaste"),
true,
game.CoreGui)
end
-- moves selections boxes to the current cell region
function updateSelections()
if not selectionUpdateFunc then
createSelections()
return
end
if not lastCell then
lastCell = WorldToCellPreferSolid(c, mouse.Hit.p)
end
local selectionBelowMinYExtents = lastCell.y - depth + 1 <= 0
local startPos = CellCenterToWorld(c, lastCell.x,lastCell.y,lastCell.z)
local minOverallVec = nil
if createWalls then
minOverallVec = startPos - Vector3.new(xWidth*4,(depth - 1) *4,zWidth*4) - Vector3.new(2,6,2)
else
minOverallVec = startPos - Vector3.new(xWidth*4,(depth - 1) *4,zWidth*4) - Vector3.new(2,2,2)
end
local minDeletionVec = startPos - Vector3.new(xWidth*4,0,zWidth*4) - Vector3.new(2,-2.5,2)
local maxOverallVec = startPos + Vector3.new(xWidth*4,(depth)*4,zWidth*4) + Vector3.new(2,2,2)
local maxGroundVec = startPos + Vector3.new(xWidth*4,0,zWidth*4) + Vector3.new(2,2,2)
if selectionBelowMinYExtents then
local yMin = WorldToCellPreferSolid(c, Vector3.new(0,1,0)) + Vector3.new(2,2,2)
minOverallVec = Vector3.new(minOverallVec.x,yMin,minOverallVec.z)
end
if removeAbove then
currentSelection = Region3.new(minDeletionVec, maxOverallVec)
selectionUpdateFunc(currentSelection)
groundSelection = Region3.new(minOverallVec, maxGroundVec)
selectionGroundUpdateFunc(groundSelection)
else
currentSelection = Region3.new(zeroVector,zeroVector)
selectionUpdateFunc(currentSelection)
groundSelection = Region3.new(minOverallVec, maxGroundVec)
selectionGroundUpdateFunc(groundSelection)
end
end
function onMouseButtonDown()
buttonDownTick = tick()
end
function onMouseButtonUp()
if tick() - buttonDownTick < doubleClickTime then
onClicked()
end
end
function onClicked()
if on and not debounce then
debounce = true
local cellPos = WorldToCellPreferSolid(c, mouse.Hit.p)
local x = cellPos.x
local y = cellPos.y
local z = cellPos.z
makeCrater(x, y, z)
debounce = false
end
end
function mouseMove()
if on then
if not mouse.Target then disablePreview() return end
if debounce then return end
local newCell = WorldToCellPreferSolid(c, mouse.Hit.p)
if newCell == lastCell then return end
lastCell = newCell
updateSelections()
end
end
function On()
self:Activate(true)
toolbarbutton:SetActive(true)
dragBar.Visible = true
didCancelCreate = false
on = true
end
function Off()
toolbarbutton:SetActive(false)
dragBar.Visible = false
disablePreview()
cancelLakeCreate()
on = false
end
function createMenuButton(size,position,text,fontsize,name,parent)
local button = Instance.new("TextButton",parent)
button.AutoButtonColor = false
button.Name = name
button.BackgroundTransparency = 1
button.Position = position
button.Size = size
button.Font = Enum.Font.ArialBold
button.FontSize = fontsize
button.Text = text
button.TextColor3 = Color3.new(1,1,1)
button.BorderSizePixel = 0
button.BackgroundColor3 = Color3.new(20/255,20/255,20/255)
button.MouseEnter:connect(function ( )
if button.Selected then return end
button.BackgroundTransparency = 0
end)
button.MouseLeave:connect(function ( )
if button.Selected then return end
button.BackgroundTransparency = 1
end)
return button
end
------
--GUI-
------
--screengui
local g = Instance.new("ScreenGui", game:GetService("CoreGui"))
g.Name = "LakeToolGui"
dragBar, containerFrame, helpFrame, closeEvent = RbxGui.CreatePluginFrame("Lake Creator",UDim2.new(0,163,0,400),UDim2.new(0,0,0,0),true,g)
dragBar.Visible = false
closeEvent.Event:connect(function ( )
Off()
end)
helpFrame.Size = UDim2.new(0,300,0,552)
local helpFirstText = Instance.new("TextLabel",helpFrame)
helpFirstText.Name = "HelpText"
helpFirstText.Font = Enum.Font.ArialBold
helpFirstText.FontSize = Enum.FontSize.Size12
helpFirstText.TextColor3 = Color3.new(227/255,227/255,227/255)
helpFirstText.TextXAlignment = Enum.TextXAlignment.Left
helpFirstText.TextYAlignment = Enum.TextYAlignment.Top
helpFirstText.Position = UDim2.new(0,4,0,4)
helpFirstText.Size = UDim2.new(1,-8,0,177)
helpFirstText.BackgroundTransparency = 1
helpFirstText.TextWrap = true
helpFirstText.Text = "Length: Adjusts the z-axis size of the lake\nWidth: Adjusts the x-axis size of the lake\nDepth: Adjusts the y-axis size of the lake, this size is always from the currently selected terrain cell down\n\nCurvature: \nApproximates a spherical or ellipsoid shape that curves the lake inward. 100% is the maximum amount of curve (like a perfectly round sphere), 0% is no curve (like an above-ground swimming pool)\nWater Level:\nThe percentage to the top of the lake that is full of water (this is a percentage of the depth slider, not volume of the lake)"
local helpSecondText = helpFirstText:clone()
helpSecondText.Name = "HelpSecondText"
helpSecondText.Position = UDim2.new(0,0,1,0)
helpSecondText.Size = UDim2.new(1,0,0,212)
helpSecondText.Text = "Lake Types:\nElliptical: draws a lake that approximates an ellpsoid\nCircular: the same thing as Elliptical, except it locks the length and width sliders so they are always the same.\nRectangular: creates a lake to the exact shape of what is selected, which is always rectangular\n\nWater Type:\nThese are directions that the water force will be applied to. All cardinal directions are allows (x,y,z and their negatives)\n\nWater Force: \nThe amount of force to be applied to the specified water type. Current choices are None, Small, Medium, Strong, and Max."
helpSecondText.Parent = helpFirstText
local helpThirdText = helpSecondText:clone()
helpThirdText.Size = UDim2.new(1,0,0,159)
helpThirdText.Name = "HelpThirdText"
helpThirdText.Text = "Create Walls: \nbuilds walls around the the lake when created, so all water is encapsulated on its sides by a material (material selected by Material Selection scrollbar)\n\nRemove Above: \nRemoves cells that are above the lake to be generated. The cells to be removed are the ones inside the red selection box.\n\nMaterial Selection: \nThe material used to create walls, if this option is selected."
helpThirdText.Parent = helpSecondText
local linkImage = Instance.new("ImageLabel",containerFrame)
linkImage.Name = "LinkImage"
linkImage.BackgroundTransparency = 1
linkImage.Visible = false
linkImage.Size = UDim2.new(0,15,0,15)
linkImage.Position = UDim2.new(0,120,0,51)
game:GetService("ContentProvider"):Preload("http://gametest.watrbx.wtf/asset/?id=129724452")
linkImage.Image = "http://gametest.watrbx.wtf/asset/?id=129724452" --todo: put this in a better spot
--current width display label
local lengthLabel = Instance.new("TextLabel", containerFrame)
lengthLabel.Name = "LengthTextLabel"
lengthLabel.Position = UDim2.new(0, 8, 0, 10)
lengthLabel.Size = UDim2.new(0, 67, 0, 14)
lengthLabel.Text = ""
lengthLabel.TextColor3 = Color3.new(0.95, 0.95, 0.95)
lengthLabel.Font = Enum.Font.ArialBold
lengthLabel.FontSize = Enum.FontSize.Size14
lengthLabel.TextXAlignment = Enum.TextXAlignment.Left
lengthLabel.BackgroundTransparency = 1
local lengthSliderPosition, widthSliderPosition, widthSliderGui, lengthSliderGui = nil
--length slider
lengthSliderGui, lengthSliderPosition = RbxGui.CreateSlider(128, 0, UDim2.new(0,0,0,0))
lengthSliderGui.Parent = containerFrame
lengthSliderGui.Position = UDim2.new(0,1,0,26)
lengthSliderGui.Size = UDim2.new(0,160,0,20)
local lengthBar = lengthSliderGui:FindFirstChild("Bar")
lengthBar.Size = UDim2.new(1, -20, 0, 5)
lengthBar.Position = UDim2.new(0,10,0.5,-2)
lengthSliderPosition.Changed:connect(function()
zWidth = lengthSliderPosition.Value
lengthLabel.Text = "Length: ".. zWidth
if currLakeShape == "Circular" then
widthSliderPosition.Value = zWidth
end
end)
lengthSliderPosition.Value = zWidth
--current width display label
local widthLabel = Instance.new("TextLabel", containerFrame)
widthLabel.Name = "WidthTextLabel"
widthLabel.Position = UDim2.new(0, 8, 0, 51)
widthLabel.Size = UDim2.new(0, 59, 0, 14)
widthLabel.Text = ""
widthLabel.TextColor3 = Color3.new(0.95, 0.95, 0.95)
widthLabel.Font = Enum.Font.ArialBold
widthLabel.FontSize = Enum.FontSize.Size14
widthLabel.TextXAlignment = Enum.TextXAlignment.Left
widthLabel.BackgroundTransparency = 1
--width slider
widthSliderGui, widthSliderPosition = RbxGui.CreateSlider(128,0, UDim2.new(0,0,0,0))
widthSliderGui.Parent = containerFrame
widthSliderGui.Position = UDim2.new(0,1,0,67)
widthSliderGui.Size = UDim2.new(0,160,0,20)
local widthBar = widthSliderGui:FindFirstChild("Bar")
widthBar.Size = UDim2.new(1, -20, 0, 5)
widthBar.Position = UDim2.new(0,10,0.5,-2)
widthSliderPosition.Changed:connect(function()
xWidth = widthSliderPosition.Value
widthLabel.Text = "Width: " .. xWidth
if currLakeShape == "Circular" then
lengthSliderPosition.Value = xWidth
end
end)
widthSliderPosition.Value = xWidth
--current depth factor display label
local depthlabel = Instance.new("TextLabel", containerFrame)
depthlabel.Name = "DepthTextLabel"
depthlabel.Size = UDim2.new(0, 61, 0, 14)
depthlabel.Text = ""
depthlabel.TextColor3 = Color3.new(0.95, 0.95, 0.95)
depthlabel.Font = Enum.Font.ArialBold
depthlabel.FontSize = Enum.FontSize.Size14
depthlabel.Position = UDim2.new(0,8,0,90)
depthlabel.Size = UDim2.new(0,61,0,14)
depthlabel.TextXAlignment = Enum.TextXAlignment.Left
depthlabel.BackgroundTransparency = 1
--depth factor slider
local dfSliderGui, dfSliderPosition = RbxGui.CreateSlider(maxYExtents,0, UDim2.new(0,0,0,0))
dfSliderGui.Position = UDim2.new(0,1,0,106)
dfSliderGui.Size = UDim2.new(0,160,0,20)
dfSliderGui.Parent = containerFrame
local dfBar = dfSliderGui:FindFirstChild("Bar")
dfBar.Size = UDim2.new(1,-20,0,5)
dfBar.Position = UDim2.new(0,10,0.5,-2)
dfSliderPosition.Changed:connect(function()
depth = dfSliderPosition.Value
depthlabel.Text = "Depth: ".. depth
end)
dfSliderPosition.Value = depth
-- curvature text label
local curvatureLabel = Instance.new("TextLabel", containerFrame)
curvatureLabel.Name = "CurvatureTextLabel"
curvatureLabel.Size = UDim2.new(0, 106, 0, 14)
curvatureLabel.Text = ""
curvatureLabel.TextColor3 = Color3.new(0.95, 0.95, 0.95)
curvatureLabel.Font = Enum.Font.ArialBold
curvatureLabel.FontSize = Enum.FontSize.Size14
curvatureLabel.Position = UDim2.new(0,8,0,141)
curvatureLabel.Size = UDim2.new(0,106,0,14)
curvatureLabel.TextXAlignment = Enum.TextXAlignment.Left
curvatureLabel.BackgroundTransparency = 1
--curvature factor slider
local curveSliderGui, curveSliderPosition = RbxGui.CreateSlider(101,0, UDim2.new(0,0,0,0))
curveSliderGui.Position = UDim2.new(0,1,0,157)
curveSliderGui.Size = UDim2.new(0,160,0,20)
curveSliderGui.Parent = containerFrame
local curveBar = curveSliderGui:FindFirstChild("Bar")
curveBar.Size = UDim2.new(1,-20,0,5)
curveBar.Position = UDim2.new(0,10,0.5,-2)
curveSliderPosition.Changed:connect(function()
percentOfSphere = (curveSliderPosition.Value - 1)/100
curvatureLabel.Text = "Curvature: ".. tostring(percentOfSphere) * 100 .. "%"
end)
curveSliderPosition.Value = percentOfSphere * 100
-- water level text label
local waterLevelLabel = Instance.new("TextLabel", containerFrame)
waterLevelLabel.Name = "WaterLevelTextLabel"
waterLevelLabel.Size = UDim2.new(0.2, 0, 0.35, 0)
waterLevelLabel.Text = ""
waterLevelLabel.TextColor3 = Color3.new(0.95, 0.95, 0.95)
waterLevelLabel.Font = Enum.Font.ArialBold
waterLevelLabel.FontSize = Enum.FontSize.Size14
waterLevelLabel.Position = UDim2.new(0,8,0,180)
waterLevelLabel.Size = UDim2.new(0,118,0,14)
waterLevelLabel.TextXAlignment = Enum.TextXAlignment.Left
waterLevelLabel.BackgroundTransparency = 1
--depth factor slider
local waterLevelSliderGui, waterLevelSliderPosition = RbxGui.CreateSlider(101,0, UDim2.new(0,0,0,0))
waterLevelSliderGui.Position = UDim2.new(0,1,0,196)
waterLevelSliderGui.Size = UDim2.new(0,160,0,20)
waterLevelSliderGui.Parent = containerFrame
local waterLevelBar = waterLevelSliderGui:FindFirstChild("Bar")
waterLevelBar.Size = UDim2.new(1,-20,0,5)
waterLevelBar.Position = UDim2.new(0,10,0.5,-2)
waterLevelSliderPosition.Changed:connect(function()
waterLevel = (waterLevelSliderPosition.Value - 1)/100
waterLevelLabel.Text = "Water Level: ".. tostring(waterLevel) * 100 .. "%"
end)
waterLevelSliderPosition.Value = waterLevel * 100
local lakeShapeSelectedFunc = function ( item )
currLakeShape = item
if currLakeShape == "Circular" then
local maxSize = math.max(xWidth,zWidth)
lengthSliderPosition.Value = maxSize
widthSliderPosition.Value = maxSize
linkImage.Visible = true
else
linkImage.Visible = false
end
end
local lakeShape, onShapeSelected = RbxGui.CreateDropDownMenu(shapes,lakeShapeSelectedFunc)
onShapeSelected("Elliptical")
lakeShape.ZIndex = 2
lakeShape.Size = UDim2.new(0,150,0,32)
lakeShape.Position = UDim2.new(0,5,0,244)
lakeShape.Parent = containerFrame
local lakeTypeLabel = curvatureLabel:clone()
lakeTypeLabel.Name = "LakeTypeLabel"
lakeTypeLabel.Text = "Lake Type"
lakeTypeLabel.Position = UDim2.new(0, 8, 0, 229)
lakeTypeLabel.Size = UDim2.new(0,64,0,14)
lakeTypeLabel.Parent = containerFrame
local waterTypeLabel = lakeTypeLabel:clone()
waterTypeLabel.Name = "WaterTypeLabel"
waterTypeLabel.Text = "Water Type"
waterTypeLabel.Position = UDim2.new(0, 8, 0, 278)
waterTypeLabel.Size = UDim2.new(0, 98, 0, 14)
waterTypeLabel.Parent = containerFrame
local waterTypeSelectedFunc = function ( item )
currWaterType = item
end
local waterType, forceWaterType = RbxGui.CreateDropDownMenu(waterTypes,waterTypeSelectedFunc)
forceWaterType("NegX")
waterType.Size = UDim2.new(0,150,0,32)
waterType.Position = UDim2.new(0,5,0,294)
waterType.Parent = containerFrame
local waterForceLabel = lakeTypeLabel:clone()
waterForceLabel.Name = "WaterForceLabel"
waterForceLabel.Text = "Water Force"
waterForceLabel.Position = UDim2.new(0, 8, 0, 326)
waterForceLabel.Size = UDim2.new(0, 98, 0, 14)
waterForceLabel.Parent = containerFrame
local waterForceSelectedFunc = function ( item )
currWaterForce = item
end
local waterForce, forceWaterForce = RbxGui.CreateDropDownMenu(waterForces,waterForceSelectedFunc)
forceWaterForce("None")
waterForce.Size = UDim2.new(0,150,0,32)
waterForce.Position = UDim2.new(0,5,0,340)
waterForce.Parent = containerFrame
-- create walls toggle
local createWallsLabel = Instance.new("TextLabel", containerFrame)
createWallsLabel.Name = "CreateWallsTextLabel"
createWallsLabel.Size = UDim2.new(0.2, 0, 0.35, 0)
createWallsLabel.Text = "Create Walls"
createWallsLabel.TextColor3 = Color3.new(0.95, 0.95, 0.95)
createWallsLabel.Font = Enum.Font.ArialBold
createWallsLabel.FontSize = Enum.FontSize.Size14
createWallsLabel.Position = UDim2.new(0,40,0,391)
createWallsLabel.Size = UDim2.new(0,80,0,14)
createWallsLabel.TextXAlignment = Enum.TextXAlignment.Left
createWallsLabel.BackgroundTransparency = 1
local createWallsToggle = Instance.new("TextButton",createWallsLabel)
createWallsToggle.Name = "CreateWallsToggle"
createWallsToggle.Style = Enum.ButtonStyle.RobloxButton
createWallsToggle.Size = UDim2.new(0,32,0,32)
createWallsToggle.Position = UDim2.new(0,-34,0.5,-16)
createWallsToggle.Text = "X"
createWallsToggle.Font = Enum.Font.ArialBold
createWallsToggle.FontSize = Enum.FontSize.Size18
createWallsToggle.TextColor3 = Color3.new(1,1,1)
createWallsToggle.MouseButton1Click:connect(function()
createWalls = not createWalls
if createWalls then
createWallsToggle.Text = "X"
else
createWallsToggle.Text = ""
end
end)
local removeAboveLabel = createWallsLabel:clone()
removeAboveLabel.Name = "RemoveAboveLabel"
removeAboveLabel.Text = "Remove Above"
removeAboveLabel.Position = UDim2.new(0,40,0,424)
removeAboveLabel.Size = UDim2.new(0,93,0,14)
removeAboveLabel.CreateWallsToggle.Name = "RemoveAboveToggle"
removeAboveLabel.RemoveAboveToggle.MouseButton1Click:connect(function( )
removeAbove = not removeAbove
if removeAbove then
removeAboveLabel.RemoveAboveToggle.Text = "X"
else
removeAboveLabel.RemoveAboveToggle.Text = ""
end
updateSelections()
end)
removeAboveLabel.Parent = containerFrame
local materialSelectionGui,newMaterialEvent,forceMaterialFunc = RbxGui.CreateTerrainMaterialSelector(UDim2.new(1,0,0,82),UDim2.new(0,0,0,450))
materialSelectionGui.BackgroundTransparency = 1
materialSelectionGui.Parent = containerFrame
newMaterialEvent.Event:connect(function(newMat)
currMaterial = newMat
end)
loadingFrame, updateLoadingGuiPercent, cancelLoadingPressed = RbxGui.CreateLoadingFrame("Processing")
loadingFrame.Visible = false
loadingFrame.Parent = g
cancelLoadingPressed.Event:connect(function() cancelLakeCreate() end)
--------------------------
--SUCCESSFUL LOAD MESSAGE-
--------------------------
loaded = true
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 B