Formatting improvements and modularisation of terrain plugins
This commit is contained in:
parent
ca31246727
commit
98561c76e0
|
|
@ -0,0 +1,34 @@
|
||||||
|
local New = require("../New").New
|
||||||
|
|
||||||
|
-- Create a standard dropdown. Use this for all dropdowns in the popup so it is easy to standardize.
|
||||||
|
-- name - What to use.
|
||||||
|
-- pos - Where to position the button. Should be of type UDim2.
|
||||||
|
-- text - Text to show in the button.
|
||||||
|
-- funcOnPress - Function to run when the button is pressed.
|
||||||
|
-- parent - What to set the parent as.
|
||||||
|
-- Return:
|
||||||
|
-- button - The button gui.
|
||||||
|
return function(
|
||||||
|
name: string,
|
||||||
|
pos: UDim2,
|
||||||
|
text: string,
|
||||||
|
funcOnPress: (...any) -> (),
|
||||||
|
parent: Instance,
|
||||||
|
size: UDim2?
|
||||||
|
)
|
||||||
|
local button = New "TextButton" {
|
||||||
|
Name = name,
|
||||||
|
Position = pos,
|
||||||
|
Size = size or UDim2.new(0, 120, 0, 40),
|
||||||
|
Text = text,
|
||||||
|
Style = Enum.ButtonStyle.RobloxButton,
|
||||||
|
TextColor3 = Color3.new(1, 1, 1),
|
||||||
|
Font = Enum.Font.ArialBold,
|
||||||
|
FontSize = Enum.FontSize.Size18,
|
||||||
|
}
|
||||||
|
|
||||||
|
button.MouseButton1Click:connect(funcOnPress)
|
||||||
|
button.Parent = parent
|
||||||
|
|
||||||
|
return button
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
local New = require("../New").New
|
||||||
|
|
||||||
|
-- Create a standard text label. Use this for all lables in the popup so it is easy to standardize.
|
||||||
|
-- labelName - What to set the text label name as.
|
||||||
|
-- pos - Where to position the label. Should be of type UDim2.
|
||||||
|
-- size - How large to make the label. Should be of type UDim2.
|
||||||
|
-- text - Text to display.
|
||||||
|
-- parent - What to set the text parent as.
|
||||||
|
-- Return:
|
||||||
|
-- Value is the created label.
|
||||||
|
return function(
|
||||||
|
labelName: string,
|
||||||
|
pos: UDim2,
|
||||||
|
size: UDim2,
|
||||||
|
text: string,
|
||||||
|
parent: Instance?
|
||||||
|
)
|
||||||
|
return New "TextLabel" {
|
||||||
|
Name = labelName,
|
||||||
|
Position = pos,
|
||||||
|
Size = size,
|
||||||
|
Text = text,
|
||||||
|
TextColor3 = Color3.new(0.95, 0.95, 0.95),
|
||||||
|
Font = Enum.Font.ArialBold,
|
||||||
|
FontSize = Enum.FontSize.Size14,
|
||||||
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
|
BackgroundTransparency = 1,
|
||||||
|
Parent = parent,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
@ -1,11 +1,17 @@
|
||||||
-- Local function definitions
|
--!strict
|
||||||
while game == nil do
|
while not game do
|
||||||
wait()
|
wait()
|
||||||
end
|
end
|
||||||
|
|
||||||
local ChangeHistoryService = game:GetService "ChangeHistoryService"
|
local ChangeHistoryService = game:GetService "ChangeHistoryService"
|
||||||
local CoreGui = game:GetService "CoreGui"
|
local CoreGui = game:GetService "CoreGui"
|
||||||
|
|
||||||
|
local CreateStandardButton = require "../Modules/Terrain/CreateStandardButton"
|
||||||
|
local CreateStandardLabel = require "../Modules/Terrain/CreateStandardLabel"
|
||||||
|
local News = require "../Modules/New"
|
||||||
|
local New = News.New
|
||||||
|
local Hydrate = News.Hydrate
|
||||||
|
|
||||||
---------------
|
---------------
|
||||||
--PLUGIN SETUP-
|
--PLUGIN SETUP-
|
||||||
---------------
|
---------------
|
||||||
|
|
@ -147,18 +153,20 @@ end)
|
||||||
|
|
||||||
terrainHelpFrame.Size = UDim2.new(0, 300, 0, 350)
|
terrainHelpFrame.Size = UDim2.new(0, 300, 0, 350)
|
||||||
|
|
||||||
local terrainHelpText = Instance.new "TextLabel"
|
local function helpText()
|
||||||
terrainHelpText.Name = "HelpText"
|
return New "TextLabel" {
|
||||||
terrainHelpText.Font = Enum.Font.ArialBold
|
Font = Enum.Font.ArialBold,
|
||||||
terrainHelpText.FontSize = Enum.FontSize.Size12
|
FontSize = Enum.FontSize.Size12,
|
||||||
terrainHelpText.TextColor3 = Color3.new(227 / 255, 227 / 255, 227 / 255)
|
TextColor3 = Color3.new(227 / 255, 227 / 255, 227 / 255),
|
||||||
terrainHelpText.TextXAlignment = Enum.TextXAlignment.Left
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
terrainHelpText.TextYAlignment = Enum.TextYAlignment.Top
|
TextYAlignment = Enum.TextYAlignment.Top,
|
||||||
terrainHelpText.Position = UDim2.new(0, 4, 0, 4)
|
BackgroundTransparency = 1,
|
||||||
terrainHelpText.Size = UDim2.new(1, -8, 0, 157)
|
TextWrap = true,
|
||||||
terrainHelpText.BackgroundTransparency = 1
|
Parent = terrainHelpFrame,
|
||||||
terrainHelpText.TextWrap = true
|
}
|
||||||
terrainHelpText.Text = [[Create terrain with hills, water.
|
end
|
||||||
|
|
||||||
|
local helpText1 = [[Create terrain with hills, water.
|
||||||
X-Offset and Z-Offset:
|
X-Offset and Z-Offset:
|
||||||
Center point of terrain that will be created.
|
Center point of terrain that will be created.
|
||||||
Terrain must be in a specific region. If part of the terrain is outside that region, it won't be created.
|
Terrain must be in a specific region. If part of the terrain is outside that region, it won't be created.
|
||||||
|
|
@ -170,13 +178,7 @@ Length: Terrain size in the Z direction
|
||||||
Amplitude:
|
Amplitude:
|
||||||
Maximum height of hills.
|
Maximum height of hills.
|
||||||
]]
|
]]
|
||||||
terrainHelpText.Parent = terrainHelpFrame
|
local helpText2 = [[Frequency:
|
||||||
|
|
||||||
local helpSecondText = terrainHelpText:clone()
|
|
||||||
helpSecondText.Name = "HelpSecondText"
|
|
||||||
helpSecondText.Position = UDim2.new(0, 0, 1, 0)
|
|
||||||
helpSecondText.Size = UDim2.new(1, 0, 0, 180)
|
|
||||||
helpSecondText.Text = [[Frequency:
|
|
||||||
How often hills are made.
|
How often hills are made.
|
||||||
|
|
||||||
Base Height:
|
Base Height:
|
||||||
|
|
@ -185,21 +187,34 @@ How high the base of terrain should be.
|
||||||
Water Height:
|
Water Height:
|
||||||
How high water should be. Terrain will overwrite water.
|
How high water should be. Terrain will overwrite water.
|
||||||
]]
|
]]
|
||||||
helpSecondText.Parent = terrainHelpText
|
local helpText3 = [[
|
||||||
|
|
||||||
local helpThirdText = helpSecondText:clone()
|
|
||||||
helpThirdText.Name = "HelpThirdText"
|
|
||||||
helpThirdText.Position = UDim2.new(0, 0, 0.6, 0)
|
|
||||||
helpThirdText.Size = UDim2.new(1, 0, 0, 180)
|
|
||||||
helpThirdText.Text = [[
|
|
||||||
|
|
||||||
Generate Button:
|
Generate Button:
|
||||||
Create the terrain.
|
Create the terrain.
|
||||||
|
|
||||||
Clear Button:
|
Clear Button:
|
||||||
Remove all terrain.
|
Remove all terrain.
|
||||||
]]
|
]]
|
||||||
helpThirdText.Parent = helpSecondText
|
|
||||||
|
Hydrate(helpText()) {
|
||||||
|
Name = "HelpText",
|
||||||
|
Position = UDim2.new(0, 4, 0, 4),
|
||||||
|
Size = UDim2.new(1, -8, 0, 157),
|
||||||
|
Text = helpText1,
|
||||||
|
Parent = terrainHelpFrame,
|
||||||
|
Hydrate(helpText()) {
|
||||||
|
Name = "HelpSecondText",
|
||||||
|
Position = UDim2.new(0, 0, 1, 0),
|
||||||
|
Size = UDim2.new(1, 0, 0, 180),
|
||||||
|
Text = helpText2,
|
||||||
|
Hydrate(helpText()) {
|
||||||
|
Name = "HelpThirdText",
|
||||||
|
Position = UDim2.new(0, 0, 0.6, 0),
|
||||||
|
Size = UDim2.new(1, 0, 0, 180),
|
||||||
|
Text = helpText3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
-- Used to create a highlighter.
|
-- Used to create a highlighter.
|
||||||
-- A highlighter is a open, rectuangular area displayed in 3D.
|
-- A highlighter is a open, rectuangular area displayed in 3D.
|
||||||
|
|
@ -225,21 +240,22 @@ function Highlighter.Create(_, ID, color)
|
||||||
highlighter.z = 0
|
highlighter.z = 0
|
||||||
|
|
||||||
-- Create the part that the highlighter will be attached to.
|
-- Create the part that the highlighter will be attached to.
|
||||||
highlighter.selectionPart = Instance.new "Part"
|
highlighter.selectionPart = New "Part" {
|
||||||
highlighter.selectionPart.Name = "SelectionPart"
|
Name = "SelectionPart",
|
||||||
highlighter.selectionPart.Archivable = false
|
Archivable = false,
|
||||||
highlighter.selectionPart.Transparency = 1
|
Transparency = 1,
|
||||||
highlighter.selectionPart.Anchored = true
|
Anchored = true,
|
||||||
highlighter.selectionPart.Locked = true
|
Locked = true,
|
||||||
highlighter.selectionPart.CanCollide = false
|
CanCollide = false,
|
||||||
highlighter.selectionPart.FormFactor = Enum.FormFactor.Custom
|
FormFactor = Enum.FormFactor.Custom,
|
||||||
|
}
|
||||||
|
|
||||||
highlighter.selectionBox = Instance.new "SelectionBox"
|
highlighter.selectionBox = New "SelectionBox" {
|
||||||
highlighter.selectionBox.Name = "box" .. ID
|
Name = "box" .. ID,
|
||||||
|
Archivable = false,
|
||||||
highlighter.selectionBox.Archivable = false
|
Color = color,
|
||||||
highlighter.selectionBox.Color = color
|
Adornee = highlighter.selectionPart,
|
||||||
highlighter.selectionBox.Adornee = highlighter.selectionPart
|
}
|
||||||
setmetatable(highlighter, Highlighter)
|
setmetatable(highlighter, Highlighter)
|
||||||
|
|
||||||
return highlighter
|
return highlighter
|
||||||
|
|
@ -257,7 +273,7 @@ end
|
||||||
|
|
||||||
-- Update where the highlighter is displayed.
|
-- Update where the highlighter is displayed.
|
||||||
-- cellPos - Where to display the highlighter, in cells.
|
-- cellPos - Where to display the highlighter, in cells.
|
||||||
function Highlighter:UpdatePosition(cellPos)
|
function Highlighter:UpdatePosition(cellPos: Vector3)
|
||||||
if not cellPos then
|
if not cellPos then
|
||||||
self:DisablePreview()
|
self:DisablePreview()
|
||||||
return
|
return
|
||||||
|
|
@ -269,17 +285,20 @@ function Highlighter:UpdatePosition(cellPos)
|
||||||
self.y = cellPos.y
|
self.y = cellPos.y
|
||||||
self.z = cellPos.z
|
self.z = cellPos.z
|
||||||
|
|
||||||
|
local width, length, height =
|
||||||
|
self.width :: number, self.length :: number, self.height :: number
|
||||||
|
|
||||||
local lowVec = CellCenterToWorld(
|
local lowVec = CellCenterToWorld(
|
||||||
c,
|
c,
|
||||||
cellPos.x - self.width / 2,
|
cellPos.x - width / 2,
|
||||||
cellPos.y - 1,
|
cellPos.y - 1,
|
||||||
cellPos.z - self.length / 2
|
cellPos.z - length / 2
|
||||||
)
|
)
|
||||||
local highVec = CellCenterToWorld(
|
local highVec = CellCenterToWorld(
|
||||||
c,
|
c,
|
||||||
cellPos.x + self.width / 2,
|
cellPos.x + width / 2,
|
||||||
cellPos.y + self.height,
|
cellPos.y + height,
|
||||||
cellPos.z + self.length / 2
|
cellPos.z + length / 2
|
||||||
)
|
)
|
||||||
regionToSelect = Region3.new(lowVec, highVec)
|
regionToSelect = Region3.new(lowVec, highVec)
|
||||||
|
|
||||||
|
|
@ -292,37 +311,17 @@ end
|
||||||
-- length - Length of the area (z direction)
|
-- length - Length of the area (z direction)
|
||||||
-- width - Width of the area (x direction)
|
-- width - Width of the area (x direction)
|
||||||
-- height - Height of the area (y direction)
|
-- height - Height of the area (y direction)
|
||||||
function Highlighter:UpdateDimensions(length, width, height)
|
function Highlighter:UpdateDimensions(
|
||||||
|
length: number,
|
||||||
|
width: number,
|
||||||
|
height: number
|
||||||
|
)
|
||||||
self.length = length
|
self.length = length
|
||||||
self.width = width
|
self.width = width
|
||||||
self.height = height
|
self.height = height
|
||||||
self:UpdatePosition(Vector3.new(self.x, self.y, self.z))
|
self:UpdatePosition(Vector3.new(self.x, self.y, self.z))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Create a standard text label. Use this for all lables in the popup so it is easy to standardize.
|
|
||||||
-- labelName - What to set the text label name as.
|
|
||||||
-- pos - Where to position the label. Should be of type UDim2.
|
|
||||||
-- size - How large to make the label. Should be of type UDim2.
|
|
||||||
-- text - Text to display.
|
|
||||||
-- parent - What to set the text parent as.
|
|
||||||
-- Return:
|
|
||||||
-- Value is the created label.
|
|
||||||
function CreateStandardLabel(labelName, pos, size, text, parent)
|
|
||||||
local label = Instance.new "TextLabel"
|
|
||||||
label.Name = labelName
|
|
||||||
label.Position = pos
|
|
||||||
label.Size = size
|
|
||||||
label.Text = text
|
|
||||||
label.TextColor3 = Color3.new(0.95, 0.95, 0.95)
|
|
||||||
label.Font = Enum.Font.ArialBold
|
|
||||||
label.FontSize = Enum.FontSize.Size14
|
|
||||||
label.TextXAlignment = Enum.TextXAlignment.Left
|
|
||||||
label.BackgroundTransparency = 1
|
|
||||||
label.Parent = parent
|
|
||||||
|
|
||||||
return label
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Create a standardized slider.
|
-- Create a standardized slider.
|
||||||
-- name - Name to use for the slider.
|
-- name - Name to use for the slider.
|
||||||
-- pos - Position to display the slider at.
|
-- pos - Position to display the slider at.
|
||||||
|
|
@ -333,7 +332,7 @@ end
|
||||||
-- Return:
|
-- Return:
|
||||||
-- sliderGui - Slider gui object.
|
-- sliderGui - Slider gui object.
|
||||||
-- sliderPosition - Object that can set the slider value.
|
-- sliderPosition - Object that can set the slider value.
|
||||||
function CreateStandardSlider(
|
local function CreateStandardSlider(
|
||||||
name,
|
name,
|
||||||
pos,
|
pos,
|
||||||
lengthBarPos,
|
lengthBarPos,
|
||||||
|
|
@ -345,21 +344,24 @@ function CreateStandardSlider(
|
||||||
local sliderGui, sliderPosition =
|
local sliderGui, sliderPosition =
|
||||||
RbxGui.CreateSlider(steps, 0, UDim2.new(0, 0, 0, 0))
|
RbxGui.CreateSlider(steps, 0, UDim2.new(0, 0, 0, 0))
|
||||||
|
|
||||||
sliderGui.Name = name
|
Hydrate(sliderGui) {
|
||||||
sliderGui.Parent = parent
|
Name = name,
|
||||||
sliderGui.Position = pos
|
Parent = parent,
|
||||||
sliderGui.Size = UDim2.new(1, 0, 0, 20)
|
Position = pos,
|
||||||
local lengthBar = sliderGui:FindFirstChild "Bar"
|
Size = UDim2.new(1, 0, 0, 20),
|
||||||
lengthBar.Size = UDim2.new(1, -21, 0, 5)
|
}
|
||||||
lengthBar.Position = lengthBarPos
|
Hydrate(sliderGui.Bar) {
|
||||||
|
Size = UDim2.new(1, -21, 0, 5),
|
||||||
|
Position = lengthBarPos,
|
||||||
|
}
|
||||||
|
|
||||||
if nil ~= funcOnChange then
|
if funcOnChange then
|
||||||
sliderPosition.Changed:connect(function()
|
sliderPosition.Changed:connect(function()
|
||||||
funcOnChange(sliderPosition)
|
funcOnChange(sliderPosition)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
if nil ~= initValue then
|
if initValue then
|
||||||
sliderPosition.Value = initValue
|
sliderPosition.Value = initValue
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -390,44 +392,6 @@ end
|
||||||
-- return dropdown, updateSelection
|
-- return dropdown, updateSelection
|
||||||
-- end
|
-- end
|
||||||
|
|
||||||
-- Keep common button properties here to make it easer to change them all at once.
|
|
||||||
-- These are the default properties to use for a button.
|
|
||||||
local buttonTextColor = Color3.new(1, 1, 1)
|
|
||||||
local buttonFont = Enum.Font.ArialBold
|
|
||||||
local buttonFontSize = Enum.FontSize.Size18
|
|
||||||
|
|
||||||
-- Create a standard dropdown. Use this for all dropdowns in the popup so it is easy to standardize.
|
|
||||||
-- name - What to use.
|
|
||||||
-- pos - Where to position the button. Should be of type UDim2.
|
|
||||||
-- text - Text to show in the button.
|
|
||||||
-- funcOnPress - Function to run when the button is pressed.
|
|
||||||
-- parent - What to set the parent as.
|
|
||||||
-- Return:
|
|
||||||
-- button - The button gui.
|
|
||||||
function CreateStandardButton(name, pos, text, funcOnPress, parent, size)
|
|
||||||
local button = Instance.new "TextButton"
|
|
||||||
button.Name = name
|
|
||||||
button.Position = pos
|
|
||||||
|
|
||||||
button.Size = UDim2.new(0, 120, 0, 40)
|
|
||||||
button.Text = text
|
|
||||||
|
|
||||||
if size then
|
|
||||||
button.Size = size
|
|
||||||
end
|
|
||||||
|
|
||||||
button.Style = Enum.ButtonStyle.RobloxButton
|
|
||||||
|
|
||||||
button.TextColor3 = buttonTextColor
|
|
||||||
button.Font = buttonFont
|
|
||||||
button.FontSize = buttonFontSize
|
|
||||||
|
|
||||||
button.MouseButton1Click:connect(funcOnPress)
|
|
||||||
button.Parent = parent
|
|
||||||
|
|
||||||
return button
|
|
||||||
end
|
|
||||||
|
|
||||||
local cancelValues = {
|
local cancelValues = {
|
||||||
cancelAction = false, -- Used to cancel currently occuring actions. If set to true then terrain generation will stop.
|
cancelAction = false, -- Used to cancel currently occuring actions. If set to true then terrain generation will stop.
|
||||||
progressBar = nil, -- Will store the progress bar when needed.
|
progressBar = nil, -- Will store the progress bar when needed.
|
||||||
|
|
@ -437,30 +401,31 @@ local cancelValues = {
|
||||||
|
|
||||||
-- Load the progress bar to display when drawing a river.
|
-- Load the progress bar to display when drawing a river.
|
||||||
-- text - Text to display.
|
-- text - Text to display.
|
||||||
function LoadProgressBar(text)
|
local function LoadProgressBar(text)
|
||||||
if cancelValues.progressBar == nil then
|
if cancelValues.progressBar then
|
||||||
cancelValues.isDrawing = true
|
|
||||||
|
|
||||||
-- Start the progress bar.
|
|
||||||
cancelValues.progressBar, cancelValues.setAmountFunc, cancelValues.bindForCancel =
|
|
||||||
RbxGui.CreateLoadingFrame(text)
|
|
||||||
|
|
||||||
cancelValues.progressBar.Position =
|
|
||||||
UDim2.new(0.5, -cancelValues.progressBar.Size.X.Offset / 2, 0, 15)
|
|
||||||
cancelValues.progressBar.Parent = g
|
|
||||||
|
|
||||||
cancelValues.bindForCancel.Event:connect(function(_)
|
|
||||||
cancelValues.cancelActions = true -- Set the flag that everything should stop.
|
|
||||||
|
|
||||||
coroutine.yield()
|
|
||||||
end)
|
|
||||||
else
|
|
||||||
print "Tried to start the progress bar when it was already running."
|
print "Tried to start the progress bar when it was already running."
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
cancelValues.isDrawing = true
|
||||||
|
|
||||||
|
-- Start the progress bar.
|
||||||
|
cancelValues.progressBar, cancelValues.setAmountFunc, cancelValues.bindForCancel =
|
||||||
|
RbxGui.CreateLoadingFrame(text)
|
||||||
|
|
||||||
|
cancelValues.progressBar.Position =
|
||||||
|
UDim2.new(0.5, -cancelValues.progressBar.Size.X.Offset / 2, 0, 15)
|
||||||
|
cancelValues.progressBar.Parent = g
|
||||||
|
|
||||||
|
cancelValues.bindForCancel.Event:connect(function(_)
|
||||||
|
cancelValues.cancelActions = true -- Set the flag that everything should stop.
|
||||||
|
|
||||||
|
coroutine.yield()
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Unload the progress bar.
|
-- Unload the progress bar.
|
||||||
function UnloadProgressBar()
|
local function UnloadProgressBar()
|
||||||
cancelValues.isDrawing = false
|
cancelValues.isDrawing = false
|
||||||
cancelValues.cancelActions = false
|
cancelValues.cancelActions = false
|
||||||
|
|
||||||
|
|
@ -520,8 +485,8 @@ offsetZSliderPosition.Value = (terrainOptions.zpos + 252) / 4 + 1
|
||||||
--FUNCTION DEFINITIONS-
|
--FUNCTION DEFINITIONS-
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
--makes a column of blocks from 1 up to height at location (x,z) in cluster c
|
-- makes a column of blocks from 1 up to height at location (x,z) in cluster c
|
||||||
function coordHeight(x, z, height)
|
local function coordHeight(x, z, height)
|
||||||
SetCells(
|
SetCells(
|
||||||
c,
|
c,
|
||||||
Region3int16.new(
|
Region3int16.new(
|
||||||
|
|
@ -534,10 +499,10 @@ function coordHeight(x, z, height)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
--makes a heightmap for a layer of mountains (width x depth)
|
-- 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 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
|
-- with a range of amplitudes between 0 and a
|
||||||
function mountLayer(width, depth, wf, df, a)
|
local function mountLayer(width, depth, wf, df, a)
|
||||||
local heightmap = {}
|
local heightmap = {}
|
||||||
for i = 0, width - 1 do
|
for i = 0, width - 1 do
|
||||||
heightmap[i] = {}
|
heightmap[i] = {}
|
||||||
|
|
@ -599,8 +564,8 @@ function mountLayer(width, depth, wf, df, a)
|
||||||
return heightmap
|
return heightmap
|
||||||
end
|
end
|
||||||
|
|
||||||
--makes a shell around block at coordinate x, z using heightmap
|
-- makes a shell around block at coordinate x, z using heightmap
|
||||||
function makeShell(x, z, heightmap, shellheightmap)
|
local function makeShell(x, z, heightmap, shellheightmap)
|
||||||
local originalheight = heightmap[x][z]
|
local originalheight = heightmap[x][z]
|
||||||
for i = x - 1, x + 1 do
|
for i = x - 1, x + 1 do
|
||||||
for k = z - 1, z + 1 do
|
for k = z - 1, z + 1 do
|
||||||
|
|
@ -628,13 +593,13 @@ end
|
||||||
-- Set the camera to look at the terrain from a distance so that all terrain will be in view.
|
-- Set the camera to look at the terrain from a distance so that all terrain will be in view.
|
||||||
-- centerX, centerZ - Center coordinate of land. This doesn't take into account clipping.
|
-- centerX, centerZ - Center coordinate of land. This doesn't take into account clipping.
|
||||||
-- length, width - Land dimensions.
|
-- length, width - Land dimensions.
|
||||||
function SetCamera(centerX, centerZ, length, width, height)
|
local function SetCamera(centerX, centerZ, length, width, height)
|
||||||
local currCamera = game.Workspace.CurrentCamera
|
local currCamera = game.Workspace.CurrentCamera
|
||||||
local cameraPos = Vector3.new(0, 400, 1600)
|
local cameraPos = Vector3.new(0, 400, 1600)
|
||||||
local cameraFocus = Vector3.new(0, height * 4, 0)
|
local cameraFocus = Vector3.new(0, height * 4, 0)
|
||||||
|
|
||||||
-- Nothing set so use the default.
|
-- Nothing set so use the default.
|
||||||
if nil ~= centerX then
|
if centerX then
|
||||||
local scale = 0
|
local scale = 0
|
||||||
local lengthScale = 0
|
local lengthScale = 0
|
||||||
local widthScale = 0
|
local widthScale = 0
|
||||||
|
|
@ -657,11 +622,7 @@ function SetCamera(centerX, centerZ, length, width, height)
|
||||||
widthScale = 0.7
|
widthScale = 0.7
|
||||||
end
|
end
|
||||||
|
|
||||||
if widthScale > lengthScale then
|
scale = widthScale > lengthScale and widthScale or lengthScale
|
||||||
scale = widthScale
|
|
||||||
else
|
|
||||||
scale = lengthScale
|
|
||||||
end
|
|
||||||
|
|
||||||
local distance = Vector3.new(0, (200 * scale) + 200, (1100 * scale))
|
local distance = Vector3.new(0, (200 * scale) + 200, (1100 * scale))
|
||||||
cameraPos =
|
cameraPos =
|
||||||
|
|
@ -675,12 +636,11 @@ function SetCamera(centerX, centerZ, length, width, height)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Create terrain based on the current properties.
|
-- Create terrain based on the current properties.
|
||||||
function GenerateTerrain()
|
local function GenerateTerrain()
|
||||||
toolbarbutton:SetActive(false)
|
toolbarbutton:SetActive(false)
|
||||||
|
|
||||||
generateOptions = terrainOptions:Clone()
|
generateOptions = terrainOptions:Clone()
|
||||||
|
|
||||||
-- Turn off the plugin
|
|
||||||
Off()
|
Off()
|
||||||
|
|
||||||
-- Create the progress bar that will track terrain creation completion.
|
-- Create the progress bar that will track terrain creation completion.
|
||||||
|
|
@ -977,37 +937,45 @@ end
|
||||||
|
|
||||||
local ConfirmationPopup
|
local ConfirmationPopup
|
||||||
|
|
||||||
|
-- Unload the conformation popup if it exists.
|
||||||
|
-- Does nothing if the popup isn't set.
|
||||||
|
local function ClearConformation()
|
||||||
|
if ConfirmationPopupObject then
|
||||||
|
ConfirmationPopupObject:Clear()
|
||||||
|
ConfirmationPopupObject = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Function used by the generate button. Prompts the user first.
|
-- Function used by the generate button. Prompts the user first.
|
||||||
-- Will not show if disabled or terrain is being processed.
|
-- Will not show if disabled or terrain is being processed.
|
||||||
function ConfirmGenerateTerrain()
|
local function ConfirmGenerateTerrain()
|
||||||
-- Only do if something isn't already being processed.
|
-- Only do if something isn't already being processed.
|
||||||
if nil == cancelValues.progressBar then
|
if cancelValues.progressBar or ConfirmationPopupObject then
|
||||||
if nil == ConfirmationPopupObject then
|
return
|
||||||
if not hideGenerateConformation then
|
elseif hideGenerateConformation then
|
||||||
ConfirmationPopupObject = ConfirmationPopup.Create(
|
GenerateTerrain()
|
||||||
"Generate Terrain?",
|
return
|
||||||
"Generate",
|
|
||||||
"Cancel",
|
|
||||||
function()
|
|
||||||
ClearConformation()
|
|
||||||
GenerateTerrain()
|
|
||||||
end,
|
|
||||||
ClearConformation,
|
|
||||||
function()
|
|
||||||
hideGenerateConformation = not hideGenerateConformation
|
|
||||||
return not hideGenerateConformation
|
|
||||||
end
|
|
||||||
)
|
|
||||||
else
|
|
||||||
GenerateTerrain()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
ConfirmationPopupObject = ConfirmationPopup.Create(
|
||||||
|
"Generate Terrain?",
|
||||||
|
"Generate",
|
||||||
|
"Cancel",
|
||||||
|
function()
|
||||||
|
ClearConformation()
|
||||||
|
GenerateTerrain()
|
||||||
|
end,
|
||||||
|
ClearConformation,
|
||||||
|
function()
|
||||||
|
hideGenerateConformation = not hideGenerateConformation
|
||||||
|
return not hideGenerateConformation
|
||||||
|
end
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Clears all terrain.
|
-- Clears all terrain.
|
||||||
-- Clearing is immediate.
|
-- Clearing is immediate.
|
||||||
function ClearTerrain()
|
local function ClearTerrain()
|
||||||
toolbarbutton:SetActive(false)
|
toolbarbutton:SetActive(false)
|
||||||
Off()
|
Off()
|
||||||
|
|
||||||
|
|
@ -1024,30 +992,29 @@ end
|
||||||
|
|
||||||
-- Function used by the clear button. Prompts the user first.
|
-- Function used by the clear button. Prompts the user first.
|
||||||
-- Will not show if disabled or terrain is being processed.
|
-- Will not show if disabled or terrain is being processed.
|
||||||
function ConfirmClearTerrain()
|
local function ConfirmClearTerrain()
|
||||||
-- Only do if something isn't already being processed.
|
-- Only do if something isn't already being processed.
|
||||||
if nil == cancelValues.progressBar then
|
if cancelValues.progressBar or ConfirmationPopupObject then
|
||||||
if nil == ConfirmationPopupObject then
|
return
|
||||||
if not hideClearConformation then
|
elseif hideClearConformation then
|
||||||
ConfirmationPopupObject = ConfirmationPopup.Create(
|
ClearTerrain()
|
||||||
"Clear Terrain?",
|
return
|
||||||
"Clear",
|
|
||||||
"Cancel",
|
|
||||||
function()
|
|
||||||
ClearConformation()
|
|
||||||
ClearTerrain()
|
|
||||||
end,
|
|
||||||
ClearConformation,
|
|
||||||
function()
|
|
||||||
hideClearConformation = not hideClearConformation
|
|
||||||
return not hideClearConformation
|
|
||||||
end
|
|
||||||
)
|
|
||||||
else
|
|
||||||
ClearTerrain()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
ConfirmationPopupObject = ConfirmationPopup.Create(
|
||||||
|
"Clear Terrain?",
|
||||||
|
"Clear",
|
||||||
|
"Cancel",
|
||||||
|
function()
|
||||||
|
ClearConformation()
|
||||||
|
ClearTerrain()
|
||||||
|
end,
|
||||||
|
ClearConformation,
|
||||||
|
function()
|
||||||
|
hideClearConformation = not hideClearConformation
|
||||||
|
return not hideClearConformation
|
||||||
|
end
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Used to create a highlighter.
|
-- Used to create a highlighter.
|
||||||
|
|
@ -1072,34 +1039,39 @@ function ConfirmationPopup.Create(
|
||||||
confirmFunction,
|
confirmFunction,
|
||||||
declineFunction
|
declineFunction
|
||||||
)
|
)
|
||||||
local popup = {}
|
local popup = {
|
||||||
popup.confirmButton = nil -- Hold the button to confirm a choice.
|
confirmButton = nil, -- Hold the button to confirm a choice.
|
||||||
popup.declineButton = nil -- Hold the button to decline a choice.
|
declineButton = nil, -- Hold the button to decline a choice.
|
||||||
popup.confirmationFrame = nil -- Hold the conformation frame.
|
confirmationFrame = nil, -- Hold the conformation frame.
|
||||||
popup.confirmationText = nil -- Hold the text label to display the conformation message.
|
confirmationText = nil, -- Hold the text label to display the conformation message.
|
||||||
popup.confirmationHelpText = nil -- Hold the text label to display the conformation message help.
|
confirmationHelpText = nil, -- Hold the text label to display the conformation message help.
|
||||||
|
}
|
||||||
|
|
||||||
popup.confirmationFrame = Instance.new "Frame"
|
popup.confirmationFrame = New "Frame" {
|
||||||
popup.confirmationFrame.Name = "ConfirmationFrame"
|
Name = "ConfirmationFrame",
|
||||||
popup.confirmationFrame.Size = UDim2.new(0, 280, 0, 140)
|
Size = UDim2.new(0, 280, 0, 140),
|
||||||
popup.confirmationFrame.Position = UDim2.new(
|
Position = UDim2.new(
|
||||||
0.5,
|
0.5,
|
||||||
-popup.confirmationFrame.Size.X.Offset / 2,
|
-popup.confirmationFrame.Size.X.Offset / 2,
|
||||||
0.5,
|
0.5,
|
||||||
-popup.confirmationFrame.Size.Y.Offset / 2
|
-popup.confirmationFrame.Size.Y.Offset / 2
|
||||||
)
|
),
|
||||||
popup.confirmationFrame.Style = Enum.FrameStyle.RobloxRound
|
Style = Enum.FrameStyle.RobloxRound,
|
||||||
popup.confirmationFrame.Parent = g
|
Parent = g,
|
||||||
|
}
|
||||||
|
|
||||||
popup.confirmLabel = CreateStandardLabel(
|
popup.confirmLabel = Hydrate(
|
||||||
"ConfirmLabel",
|
CreateStandardLabel(
|
||||||
UDim2.new(0, 0, 0, 15),
|
"ConfirmLabel",
|
||||||
UDim2.new(1, 0, 0, 24),
|
UDim2.new(0, 0, 0, 15),
|
||||||
confirmText,
|
UDim2.new(1, 0, 0, 24),
|
||||||
popup.confirmationFrame
|
confirmText,
|
||||||
)
|
popup.confirmationFrame
|
||||||
popup.confirmLabel.FontSize = Enum.FontSize.Size18
|
)
|
||||||
popup.confirmLabel.TextXAlignment = Enum.TextXAlignment.Center
|
) {
|
||||||
|
FontSize = Enum.FontSize.Size18,
|
||||||
|
TextXAlignment = Enum.TextXAlignment.Center,
|
||||||
|
}
|
||||||
|
|
||||||
-- Confirm
|
-- Confirm
|
||||||
popup.confirmButton = CreateStandardButton(
|
popup.confirmButton = CreateStandardButton(
|
||||||
|
|
@ -1126,19 +1098,19 @@ end
|
||||||
|
|
||||||
-- Clear the popup, free up assets.
|
-- Clear the popup, free up assets.
|
||||||
function ConfirmationPopup:Clear()
|
function ConfirmationPopup:Clear()
|
||||||
if nil ~= self.confirmButton then
|
if self.confirmButton then
|
||||||
self.confirmButton.Parent = nil
|
self.confirmButton.Parent = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
if nil ~= self.declineButton then
|
if self.declineButton then
|
||||||
self.declineButton.Parent = nil
|
self.declineButton.Parent = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
if nil ~= self.confirmationFrame then
|
if self.confirmationFrame then
|
||||||
self.confirmationFrame.Parent = nil
|
self.confirmationFrame.Parent = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
if nil ~= self.confirmLabel then
|
if self.confirmLabel then
|
||||||
self.confirmLabel.Parent = nil
|
self.confirmLabel.Parent = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -1163,7 +1135,8 @@ local widthLabel = CreateStandardLabel(
|
||||||
"",
|
"",
|
||||||
terrainFrame
|
terrainFrame
|
||||||
)
|
)
|
||||||
local _, _ --[[widthSliderGui, widthSliderPosition]] = CreateStandardSlider(
|
-- local _, _ widthSliderGui, widthSliderPosition =
|
||||||
|
CreateStandardSlider(
|
||||||
"WidthSliderGui",
|
"WidthSliderGui",
|
||||||
UDim2.new(0, 1, 0, 108),
|
UDim2.new(0, 1, 0, 108),
|
||||||
UDim2.new(0, 10, 0.5, -2),
|
UDim2.new(0, 10, 0.5, -2),
|
||||||
|
|
@ -1184,7 +1157,8 @@ local lengthLabel = CreateStandardLabel(
|
||||||
"",
|
"",
|
||||||
terrainFrame
|
terrainFrame
|
||||||
)
|
)
|
||||||
local _, _ --[[lengthSliderGui, lengthSliderPosition]] = CreateStandardSlider(
|
-- local _, _ lengthSliderGui, lengthSliderPosition =
|
||||||
|
CreateStandardSlider(
|
||||||
"LengthSliderGui",
|
"LengthSliderGui",
|
||||||
UDim2.new(0, 1, 0, 149),
|
UDim2.new(0, 1, 0, 149),
|
||||||
UDim2.new(0, 10, 0.5, -2),
|
UDim2.new(0, 10, 0.5, -2),
|
||||||
|
|
@ -1305,17 +1279,8 @@ CreateStandardButton(
|
||||||
UDim2.new(0, 150, 0, 40)
|
UDim2.new(0, 150, 0, 40)
|
||||||
)
|
)
|
||||||
|
|
||||||
-- Unload the conformation popup if it exists.
|
|
||||||
-- Does nothing if the popup isn't set.
|
|
||||||
function ClearConformation()
|
|
||||||
if nil ~= ConfirmationPopupObject then
|
|
||||||
ConfirmationPopupObject:Clear()
|
|
||||||
ConfirmationPopupObject = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Run when the popup is activated.
|
-- Run when the popup is activated.
|
||||||
On = function()
|
function On()
|
||||||
if not c then
|
if not c then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
@ -1326,7 +1291,7 @@ On = function()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Run when the popup is deactivated.
|
-- Run when the popup is deactivated.
|
||||||
Off = function()
|
function Off()
|
||||||
toolbarbutton:SetActive(false)
|
toolbarbutton:SetActive(false)
|
||||||
ClearConformation()
|
ClearConformation()
|
||||||
on = false
|
on = false
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
while game == nil do
|
while not game do
|
||||||
wait()
|
wait()
|
||||||
end
|
end
|
||||||
|
|
||||||
local ChangeHistoryService = game:GetService "ChangeHistoryService"
|
local ChangeHistoryService = game:GetService "ChangeHistoryService"
|
||||||
local CoreGui = game:GetService "CoreGui"
|
local CoreGui = game:GetService "CoreGui"
|
||||||
|
|
||||||
|
local CreateStandardLabel = require "../Modules/Terrain/CreateStandardLabel"
|
||||||
|
local New = require("../Modules/New").New
|
||||||
|
|
||||||
---------------
|
---------------
|
||||||
--PLUGIN SETUP-
|
--PLUGIN SETUP-
|
||||||
---------------
|
---------------
|
||||||
|
|
@ -96,19 +99,21 @@ function MouseHighlighter.Create(mouseUse)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Create the part that the highlighter will be attached to.
|
-- Create the part that the highlighter will be attached to.
|
||||||
highlighter.selectionPart = Instance.new "Part"
|
highlighter.selectionPart = New "Part" {
|
||||||
highlighter.selectionPart.Name = "SelectionPart"
|
Name = "SelectionPart",
|
||||||
highlighter.selectionPart.Archivable = false
|
Archivable = false,
|
||||||
highlighter.selectionPart.Transparency = 1
|
Transparency = 1,
|
||||||
highlighter.selectionPart.Anchored = true
|
Anchored = true,
|
||||||
highlighter.selectionPart.Locked = true
|
Locked = true,
|
||||||
highlighter.selectionPart.CanCollide = false
|
CanCollide = false,
|
||||||
highlighter.selectionPart.FormFactor = Enum.FormFactor.Custom
|
FormFactor = Enum.FormFactor.Custom,
|
||||||
|
}
|
||||||
|
highlighter.selectionBox = New "SelectionBox" {
|
||||||
|
Archivable = false,
|
||||||
|
Color = mouseHighlightColor,
|
||||||
|
Adornee = highlighter.selectionPart,
|
||||||
|
}
|
||||||
|
|
||||||
highlighter.selectionBox = Instance.new "SelectionBox"
|
|
||||||
highlighter.selectionBox.Archivable = false
|
|
||||||
highlighter.selectionBox.Color = mouseHighlightColor
|
|
||||||
highlighter.selectionBox.Adornee = highlighter.selectionPart
|
|
||||||
mouseH.TargetFilter = highlighter.selectionPart
|
mouseH.TargetFilter = highlighter.selectionPart
|
||||||
setmetatable(highlighter, MouseHighlighter)
|
setmetatable(highlighter, MouseHighlighter)
|
||||||
|
|
||||||
|
|
@ -119,7 +124,7 @@ function MouseHighlighter.Create(mouseUse)
|
||||||
-- Return:
|
-- Return:
|
||||||
-- success - Value is true if there was a plane intersection, false if not.
|
-- success - Value is true if there was a plane intersection, false if not.
|
||||||
-- cellPos - Value is the terrain cell intersection point if there is one, vectorPos if there isn't.
|
-- cellPos - Value is the terrain cell intersection point if there is one, vectorPos if there isn't.
|
||||||
PlaneIntersection = function(vectorPos)
|
function PlaneIntersection(vectorPos)
|
||||||
local currCamera = game.Workspace.CurrentCamera
|
local currCamera = game.Workspace.CurrentCamera
|
||||||
local startPos = Vector3.new(
|
local startPos = Vector3.new(
|
||||||
currCamera.CoordinateFrame.p.X,
|
currCamera.CoordinateFrame.p.X,
|
||||||
|
|
@ -147,7 +152,7 @@ function MouseHighlighter.Create(mouseUse)
|
||||||
|
|
||||||
-- Update where the highlighter is displayed.
|
-- Update where the highlighter is displayed.
|
||||||
-- position - Where to display the highlighter, in world space.
|
-- position - Where to display the highlighter, in world space.
|
||||||
UpdatePosition = function(position)
|
function UpdatePosition(position)
|
||||||
if not position then
|
if not position then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
@ -214,30 +219,6 @@ end
|
||||||
local mouseHighlighter = MouseHighlighter.Create(mouse)
|
local mouseHighlighter = MouseHighlighter.Create(mouse)
|
||||||
mouseHighlighter:DisablePreview()
|
mouseHighlighter:DisablePreview()
|
||||||
|
|
||||||
-- Create a standard text label. Use this for all lables in the popup so it is easy to standardize.
|
|
||||||
-- labelName - What to set the text label name as.
|
|
||||||
-- pos - Where to position the label. Should be of type UDim2.
|
|
||||||
-- size - How large to make the label. Should be of type UDim2.
|
|
||||||
-- text - Text to display.
|
|
||||||
-- parent - What to set the text parent as.
|
|
||||||
-- Return:
|
|
||||||
-- Value is the created label.
|
|
||||||
function CreateStandardLabel(labelName, pos, size, text, parent)
|
|
||||||
local label = Instance.new "TextLabel"
|
|
||||||
label.Name = labelName
|
|
||||||
label.Position = pos
|
|
||||||
label.Size = size
|
|
||||||
label.Text = text
|
|
||||||
label.TextColor3 = Color3.new(0.95, 0.95, 0.95)
|
|
||||||
label.Font = Enum.Font.ArialBold
|
|
||||||
label.FontSize = Enum.FontSize.Size14
|
|
||||||
label.TextXAlignment = Enum.TextXAlignment.Left
|
|
||||||
label.BackgroundTransparency = 1
|
|
||||||
label.Parent = parent
|
|
||||||
|
|
||||||
return label
|
|
||||||
end
|
|
||||||
|
|
||||||
------
|
------
|
||||||
--GUI-
|
--GUI-
|
||||||
------
|
------
|
||||||
|
|
@ -372,7 +353,7 @@ mouse.Button1Down:connect(onClicked)
|
||||||
mouseHighlighter.OnClicked = onClicked
|
mouseHighlighter.OnClicked = onClicked
|
||||||
|
|
||||||
-- Run when the popup is activated.
|
-- Run when the popup is activated.
|
||||||
On = function()
|
function On()
|
||||||
if not c then
|
if not c then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
@ -383,7 +364,7 @@ On = function()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Run when the popup is deactivated.
|
-- Run when the popup is deactivated.
|
||||||
Off = function()
|
function Off()
|
||||||
toolbarbutton:SetActive(false)
|
toolbarbutton:SetActive(false)
|
||||||
on = false
|
on = false
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
while game == nil do
|
while not game do
|
||||||
wait()
|
wait()
|
||||||
end
|
end
|
||||||
|
|
||||||
local ChangeHistoryService = game:GetService "ChangeHistoryService"
|
local ChangeHistoryService = game:GetService "ChangeHistoryService"
|
||||||
local CoreGui = game:GetService "CoreGui"
|
local CoreGui = game:GetService "CoreGui"
|
||||||
|
|
||||||
|
local CreateStandardLabel = require "../Modules/Terrain/CreateStandardLabel"
|
||||||
|
|
||||||
-----------------
|
-----------------
|
||||||
--DEFAULT VALUES-
|
--DEFAULT VALUES-
|
||||||
-----------------
|
-----------------
|
||||||
|
|
@ -170,30 +172,6 @@ end
|
||||||
-- Create the mouse movement highlighter.
|
-- Create the mouse movement highlighter.
|
||||||
local mouseHighlighter = MouseHighlighter.Create(mouse)
|
local mouseHighlighter = MouseHighlighter.Create(mouse)
|
||||||
|
|
||||||
-- Create a standard text label. Use this for all lables in the popup so it is easy to standardize.
|
|
||||||
-- labelName - What to set the text label name as.
|
|
||||||
-- pos - Where to position the label. Should be of type UDim2.
|
|
||||||
-- size - How large to make the label. Should be of type UDim2.
|
|
||||||
-- text - Text to display.
|
|
||||||
-- parent - What to set the text parent as.
|
|
||||||
-- Return:
|
|
||||||
-- Value is the created label.
|
|
||||||
function CreateStandardLabel(labelName, pos, size, text, parent)
|
|
||||||
local label = Instance.new "TextLabel"
|
|
||||||
label.Name = labelName
|
|
||||||
label.Position = pos
|
|
||||||
label.Size = size
|
|
||||||
label.Text = text
|
|
||||||
label.TextColor3 = Color3.new(0.95, 0.95, 0.95)
|
|
||||||
label.Font = Enum.Font.ArialBold
|
|
||||||
label.FontSize = Enum.FontSize.Size14
|
|
||||||
label.TextXAlignment = Enum.TextXAlignment.Left
|
|
||||||
label.BackgroundTransparency = 1
|
|
||||||
label.Parent = parent
|
|
||||||
|
|
||||||
return label
|
|
||||||
end
|
|
||||||
|
|
||||||
------
|
------
|
||||||
--GUI-
|
--GUI-
|
||||||
------
|
------
|
||||||
|
|
@ -283,11 +261,10 @@ mouse.Button1Down:connect(onClicked)
|
||||||
mouseHighlighter.OnClicked = onClicked
|
mouseHighlighter.OnClicked = onClicked
|
||||||
|
|
||||||
-- Run when the popup is activated.
|
-- Run when the popup is activated.
|
||||||
On = function()
|
function On()
|
||||||
if not c then
|
if not c then
|
||||||
return
|
return
|
||||||
end
|
elseif plugin then
|
||||||
if plugin then
|
|
||||||
plugin:Activate(true)
|
plugin:Activate(true)
|
||||||
end
|
end
|
||||||
if toolbarbutton then
|
if toolbarbutton then
|
||||||
|
|
@ -300,7 +277,7 @@ On = function()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Run when the popup is deactivated.
|
-- Run when the popup is deactivated.
|
||||||
Off = function()
|
function Off()
|
||||||
on = false
|
on = false
|
||||||
|
|
||||||
if toolbarbutton then
|
if toolbarbutton then
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
while game == nil do
|
while not game do
|
||||||
wait()
|
wait()
|
||||||
end
|
end
|
||||||
|
|
||||||
local ChangeHistoryService = game:GetService "ChangeHistoryService"
|
local ChangeHistoryService = game:GetService "ChangeHistoryService"
|
||||||
local CoreGui = game:GetService "CoreGui"
|
local CoreGui = game:GetService "CoreGui"
|
||||||
|
|
||||||
|
local CreateStandardLabel = require "../Modules/Terrain/CreateStandardLabel"
|
||||||
|
|
||||||
---------------
|
---------------
|
||||||
--PLUGIN SETUP-
|
--PLUGIN SETUP-
|
||||||
---------------
|
---------------
|
||||||
|
|
@ -116,45 +118,9 @@ function MouseHighlighter.Create(mouseUse)
|
||||||
-- Will hold a part the highlighter will be attached to. This will be moved where the mouse is.
|
-- Will hold a part the highlighter will be attached to. This will be moved where the mouse is.
|
||||||
highlighter.selectionPart = nil
|
highlighter.selectionPart = nil
|
||||||
|
|
||||||
-- Function to call when the mouse has moved. Updates where to display the highlighter.
|
|
||||||
local function MouseMoved()
|
|
||||||
if on then
|
|
||||||
UpdatePosition(mouseH.Hit)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Hook the mouse up to check for movement.
|
|
||||||
mouseH.Move:connect(function()
|
|
||||||
MouseMoved()
|
|
||||||
end)
|
|
||||||
|
|
||||||
mouseH.Button1Down:connect(function()
|
|
||||||
highlighter.mouseDown = true
|
|
||||||
end)
|
|
||||||
mouseH.Button1Up:connect(function()
|
|
||||||
highlighter.mouseDown = false
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- Create the part that the highlighter will be attached to.
|
|
||||||
highlighter.selectionPart = Instance.new "Part"
|
|
||||||
highlighter.selectionPart.Name = "SelectionPart"
|
|
||||||
highlighter.selectionPart.Archivable = false
|
|
||||||
highlighter.selectionPart.Transparency = 1
|
|
||||||
highlighter.selectionPart.Anchored = true
|
|
||||||
highlighter.selectionPart.Locked = true
|
|
||||||
highlighter.selectionPart.CanCollide = false
|
|
||||||
highlighter.selectionPart.FormFactor = Enum.FormFactor.Custom
|
|
||||||
|
|
||||||
highlighter.selectionBox = Instance.new "SelectionBox"
|
|
||||||
highlighter.selectionBox.Archivable = false
|
|
||||||
highlighter.selectionBox.Color = mouseHighlightColor
|
|
||||||
highlighter.selectionBox.Adornee = highlighter.selectionPart
|
|
||||||
mouseH.TargetFilter = highlighter.selectionPart
|
|
||||||
setmetatable(highlighter, MouseHighlighter)
|
|
||||||
|
|
||||||
-- Update where the highlighter is displayed.
|
-- Update where the highlighter is displayed.
|
||||||
-- position - Where to display the highlighter, in world space.
|
-- position - Where to display the highlighter, in world space.
|
||||||
function UpdatePosition(position)
|
local function UpdatePosition(position)
|
||||||
if not position then
|
if not position then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
@ -204,6 +170,42 @@ function MouseHighlighter.Create(mouseUse)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Function to call when the mouse has moved. Updates where to display the highlighter.
|
||||||
|
local function MouseMoved()
|
||||||
|
if on then
|
||||||
|
UpdatePosition(mouseH.Hit)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Hook the mouse up to check for movement.
|
||||||
|
mouseH.Move:connect(function()
|
||||||
|
MouseMoved()
|
||||||
|
end)
|
||||||
|
|
||||||
|
mouseH.Button1Down:connect(function()
|
||||||
|
highlighter.mouseDown = true
|
||||||
|
end)
|
||||||
|
mouseH.Button1Up:connect(function()
|
||||||
|
highlighter.mouseDown = false
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Create the part that the highlighter will be attached to.
|
||||||
|
highlighter.selectionPart = Instance.new "Part"
|
||||||
|
highlighter.selectionPart.Name = "SelectionPart"
|
||||||
|
highlighter.selectionPart.Archivable = false
|
||||||
|
highlighter.selectionPart.Transparency = 1
|
||||||
|
highlighter.selectionPart.Anchored = true
|
||||||
|
highlighter.selectionPart.Locked = true
|
||||||
|
highlighter.selectionPart.CanCollide = false
|
||||||
|
highlighter.selectionPart.FormFactor = Enum.FormFactor.Custom
|
||||||
|
|
||||||
|
highlighter.selectionBox = Instance.new "SelectionBox"
|
||||||
|
highlighter.selectionBox.Archivable = false
|
||||||
|
highlighter.selectionBox.Color = mouseHighlightColor
|
||||||
|
highlighter.selectionBox.Adornee = highlighter.selectionPart
|
||||||
|
mouseH.TargetFilter = highlighter.selectionPart
|
||||||
|
setmetatable(highlighter, MouseHighlighter)
|
||||||
|
|
||||||
return highlighter
|
return highlighter
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -231,30 +233,6 @@ g.Parent = CoreGui
|
||||||
-- UI gui load. Required for sliders.
|
-- UI gui load. Required for sliders.
|
||||||
local RbxGui = LoadLibrary "RbxGui"
|
local RbxGui = LoadLibrary "RbxGui"
|
||||||
|
|
||||||
-- Create a standard text label. Use this for all lables in the popup so it is easy to standardize.
|
|
||||||
-- labelName - What to set the text label name as.
|
|
||||||
-- pos - Where to position the label. Should be of type UDim2.
|
|
||||||
-- size - How large to make the label. Should be of type UDim2.
|
|
||||||
-- text - Text to display.
|
|
||||||
-- parent - What to set the text parent as.
|
|
||||||
-- Return:
|
|
||||||
-- Value is the created label.
|
|
||||||
function CreateStandardLabel(labelName, pos, size, text, parent)
|
|
||||||
local label = Instance.new "TextLabel"
|
|
||||||
label.Name = labelName
|
|
||||||
label.Position = pos
|
|
||||||
label.Size = size
|
|
||||||
label.Text = text
|
|
||||||
label.TextColor3 = Color3.new(0.95, 0.95, 0.95)
|
|
||||||
label.Font = Enum.Font.ArialBold
|
|
||||||
label.FontSize = Enum.FontSize.Size14
|
|
||||||
label.TextXAlignment = Enum.TextXAlignment.Left
|
|
||||||
label.BackgroundTransparency = 1
|
|
||||||
label.Parent = parent
|
|
||||||
|
|
||||||
return label
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Create a standardized slider.
|
-- Create a standardized slider.
|
||||||
-- name - Name to use for the slider.
|
-- name - Name to use for the slider.
|
||||||
-- pos - Position to display the slider at.
|
-- pos - Position to display the slider at.
|
||||||
|
|
@ -639,7 +617,7 @@ mouse.Button1Up:connect(function()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Run when the popup is activated.
|
-- Run when the popup is activated.
|
||||||
On = function()
|
function On()
|
||||||
if not c then
|
if not c then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
@ -651,7 +629,7 @@ On = function()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Run when the popup is deactivated.
|
-- Run when the popup is deactivated.
|
||||||
Off = function()
|
function Off()
|
||||||
toolbarbutton:SetActive(false)
|
toolbarbutton:SetActive(false)
|
||||||
on = false
|
on = false
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
while game == nil do
|
while not game do
|
||||||
wait()
|
wait()
|
||||||
end
|
end
|
||||||
|
|
||||||
local ChangeHistoryService = game:GetService "ChangeHistoryService"
|
local ChangeHistoryService = game:GetService "ChangeHistoryService"
|
||||||
local CoreGui = game:GetService "CoreGui"
|
local CoreGui = game:GetService "CoreGui"
|
||||||
|
|
||||||
|
-- local CreateStandardLabel = require "../Modules/Terrain/CreateStandardLabel"
|
||||||
|
|
||||||
---------------
|
---------------
|
||||||
--PLUGIN SETUP-
|
--PLUGIN SETUP-
|
||||||
---------------
|
---------------
|
||||||
|
|
@ -133,9 +135,7 @@ end
|
||||||
function brush(x, y, z)
|
function brush(x, y, z)
|
||||||
if depth == 0 then
|
if depth == 0 then
|
||||||
return
|
return
|
||||||
end
|
elseif depth > 0 then
|
||||||
|
|
||||||
if depth > 0 then
|
|
||||||
local findY = findLowPoint(x, y + depth, z)
|
local findY = findLowPoint(x, y + depth, z)
|
||||||
local yWithDepth = y + depth
|
local yWithDepth = y + depth
|
||||||
|
|
||||||
|
|
@ -171,9 +171,7 @@ end
|
||||||
function updatePreviewSelection(position)
|
function updatePreviewSelection(position)
|
||||||
if not position then
|
if not position then
|
||||||
return
|
return
|
||||||
end
|
elseif depth == 0 then -- or not mouse.Target
|
||||||
--if not mouse.Target then disablePreview() return end
|
|
||||||
if depth == 0 then
|
|
||||||
disablePreview()
|
disablePreview()
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
@ -307,21 +305,21 @@ function doFillCells(position, mouseDrag, needsCellPos)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mouseMoved()
|
function mouseMoved()
|
||||||
if on then
|
if not on then
|
||||||
if mousedown == true then
|
return
|
||||||
if mousemoving then
|
elseif mousedown == true then
|
||||||
return
|
if mousemoving then
|
||||||
end
|
return
|
||||||
|
|
||||||
mousemoving = true
|
|
||||||
local currMousePos = Vector2.new(mouse.X, mouse.Y)
|
|
||||||
local mouseDrag = currMousePos - lastMousePos
|
|
||||||
doFillCells(mouse.Hit, mouseDrag, true)
|
|
||||||
lastMousePos = currMousePos
|
|
||||||
mousemoving = false
|
|
||||||
end
|
end
|
||||||
updatePreviewSelection(mouse.Hit)
|
|
||||||
|
mousemoving = true
|
||||||
|
local currMousePos = Vector2.new(mouse.X, mouse.Y)
|
||||||
|
local mouseDrag = currMousePos - lastMousePos
|
||||||
|
doFillCells(mouse.Hit, mouseDrag, true)
|
||||||
|
lastMousePos = currMousePos
|
||||||
|
mousemoving = false
|
||||||
end
|
end
|
||||||
|
updatePreviewSelection(mouse.Hit)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Do a line/plane intersection. The line starts at the camera. The plane is at y == 0, normal(0, 1, 0)
|
-- Do a line/plane intersection. The line starts at the camera. The plane is at y == 0, normal(0, 1, 0)
|
||||||
|
|
@ -403,11 +401,10 @@ end
|
||||||
|
|
||||||
local brushDragBar
|
local brushDragBar
|
||||||
|
|
||||||
On = function()
|
function On()
|
||||||
if not c then
|
if not c then
|
||||||
return
|
return
|
||||||
end
|
elseif this then
|
||||||
if this then
|
|
||||||
this:Activate(true)
|
this:Activate(true)
|
||||||
end
|
end
|
||||||
if toolbarbutton then
|
if toolbarbutton then
|
||||||
|
|
@ -422,7 +419,7 @@ On = function()
|
||||||
on = true
|
on = true
|
||||||
end
|
end
|
||||||
|
|
||||||
Off = function()
|
function Off()
|
||||||
if toolbarbutton then
|
if toolbarbutton then
|
||||||
toolbarbutton:SetActive(false)
|
toolbarbutton:SetActive(false)
|
||||||
end
|
end
|
||||||
|
|
@ -474,30 +471,6 @@ function CreateStandardDropdown(
|
||||||
return dropdown, updateSelection
|
return dropdown, updateSelection
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Create a standard text label. Use this for all lables in the popup so it is easy to standardize.
|
|
||||||
-- labelName - What to set the text label name as.
|
|
||||||
-- pos - Where to position the label. Should be of type UDim2.
|
|
||||||
-- size - How large to make the label. Should be of type UDim2.
|
|
||||||
-- text - Text to display.
|
|
||||||
-- parent - What to set the text parent as.
|
|
||||||
-- Return:
|
|
||||||
-- Value is the created label.
|
|
||||||
-- local function CreateStandardLabel(labelName, pos, size, text, parent)
|
|
||||||
-- local label = Instance.new "TextLabel"
|
|
||||||
-- label.Name = labelName
|
|
||||||
-- label.Position = pos
|
|
||||||
-- label.Size = size
|
|
||||||
-- label.Text = text
|
|
||||||
-- label.TextColor3 = Color3.new(0.95, 0.95, 0.95)
|
|
||||||
-- label.Font = Enum.Font.ArialBold
|
|
||||||
-- label.FontSize = Enum.FontSize.Size14
|
|
||||||
-- label.TextXAlignment = Enum.TextXAlignment.Left
|
|
||||||
-- label.BackgroundTransparency = 1
|
|
||||||
-- label.Parent = parent
|
|
||||||
|
|
||||||
-- return label
|
|
||||||
-- end
|
|
||||||
|
|
||||||
-- Create a standardized slider.
|
-- Create a standardized slider.
|
||||||
-- name - Name to use for the slider.
|
-- name - Name to use for the slider.
|
||||||
-- pos - Position to display the slider at.
|
-- pos - Position to display the slider at.
|
||||||
|
|
@ -546,6 +519,7 @@ local g = Instance.new "ScreenGui"
|
||||||
g.Name = "TerrainBrushGui"
|
g.Name = "TerrainBrushGui"
|
||||||
g.Parent = CoreGui
|
g.Parent = CoreGui
|
||||||
|
|
||||||
|
local elevationFrame, elevationHelpFrame, elevationCloseEvent
|
||||||
brushDragBar, elevationFrame, elevationHelpFrame, elevationCloseEvent =
|
brushDragBar, elevationFrame, elevationHelpFrame, elevationCloseEvent =
|
||||||
RbxGui.CreatePluginFrame(
|
RbxGui.CreatePluginFrame(
|
||||||
"Terrain Brush",
|
"Terrain Brush",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
while game == nil do
|
--!strict
|
||||||
|
while not game do
|
||||||
wait()
|
wait()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -47,9 +48,13 @@ local craterDragBar, craterFrame, craterHelpFrame, craterCloseEvent = nil
|
||||||
--FUNCTION DEFINITIONS-
|
--FUNCTION DEFINITIONS-
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
--makes a crater at point (x, y, z) in cluster c
|
local function dist(x1, y1, x2, y2)
|
||||||
--cd is the depth factor, a percent of the depth of a perfect sphere
|
return math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2))
|
||||||
function makeCrater(x, y, z, cr, cd)
|
end
|
||||||
|
|
||||||
|
-- makes a crater at point (x, y, z) in cluster c
|
||||||
|
-- cd is the depth factor, a percent of the depth of a perfect sphere
|
||||||
|
local function makeCrater(x, y, z, cr, cd)
|
||||||
local heightmap = {}
|
local heightmap = {}
|
||||||
for i = x - (cr + 1), x + (cr + 1) do
|
for i = x - (cr + 1), x + (cr + 1) do
|
||||||
heightmap[i] = {}
|
heightmap[i] = {}
|
||||||
|
|
@ -112,10 +117,6 @@ function makeCrater(x, y, z, cr, cd)
|
||||||
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
|
local debounce = false
|
||||||
|
|
||||||
mouse.Button1Down:connect(function()
|
mouse.Button1Down:connect(function()
|
||||||
|
|
@ -139,11 +140,10 @@ mouse.Button1Down:connect(function()
|
||||||
ChangeHistoryService:SetWaypoint "Crater"
|
ChangeHistoryService:SetWaypoint "Crater"
|
||||||
end)
|
end)
|
||||||
|
|
||||||
On = function()
|
function On()
|
||||||
if not c then
|
if not c then
|
||||||
return
|
return
|
||||||
end
|
elseif this then
|
||||||
if this then
|
|
||||||
this:Activate(true)
|
this:Activate(true)
|
||||||
end
|
end
|
||||||
if toolbarbutton then
|
if toolbarbutton then
|
||||||
|
|
@ -155,7 +155,7 @@ On = function()
|
||||||
on = true
|
on = true
|
||||||
end
|
end
|
||||||
|
|
||||||
Off = function()
|
function Off()
|
||||||
if toolbarbutton then
|
if toolbarbutton then
|
||||||
toolbarbutton:SetActive(false)
|
toolbarbutton:SetActive(false)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
while game == nil do
|
--!strict
|
||||||
|
while not game do
|
||||||
wait()
|
wait()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -272,11 +273,10 @@ mouse.Button1Down:connect(function()
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
On = function()
|
function On()
|
||||||
if not c then
|
if not c then
|
||||||
return
|
return
|
||||||
end
|
elseif this then
|
||||||
if this then
|
|
||||||
this:Activate(true)
|
this:Activate(true)
|
||||||
end
|
end
|
||||||
if toolbarbutton then
|
if toolbarbutton then
|
||||||
|
|
@ -290,7 +290,7 @@ On = function()
|
||||||
on = true
|
on = true
|
||||||
end
|
end
|
||||||
|
|
||||||
Off = function()
|
function Off()
|
||||||
if toolbarbutton then
|
if toolbarbutton then
|
||||||
toolbarbutton:SetActive(false)
|
toolbarbutton:SetActive(false)
|
||||||
end
|
end
|
||||||
|
|
@ -311,6 +311,7 @@ local g = Instance.new "ScreenGui"
|
||||||
g.Name = "RoadGui"
|
g.Name = "RoadGui"
|
||||||
g.Parent = game:GetService "CoreGui"
|
g.Parent = game:GetService "CoreGui"
|
||||||
|
|
||||||
|
local roadHelpFrame
|
||||||
roadDragBar, roadFrame, roadHelpFrame, roadCloseEvent =
|
roadDragBar, roadFrame, roadHelpFrame, roadCloseEvent =
|
||||||
RbxGui.CreatePluginFrame(
|
RbxGui.CreatePluginFrame(
|
||||||
"Roads",
|
"Roads",
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
while game == nil do
|
while not game do
|
||||||
wait()
|
wait()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -12,6 +12,7 @@ local loaded = false
|
||||||
local on = false
|
local on = false
|
||||||
|
|
||||||
local On, Off
|
local On, Off
|
||||||
|
local mouseDown, mouseUp, mouseMove
|
||||||
|
|
||||||
local this = PluginManager():CreatePlugin()
|
local this = PluginManager():CreatePlugin()
|
||||||
local mouse = this:GetMouse()
|
local mouse = this:GetMouse()
|
||||||
|
|
@ -82,29 +83,173 @@ local RbxUtil = LoadLibrary "RbxUtility"
|
||||||
--FUNCTION DEFINITIONS-
|
--FUNCTION DEFINITIONS-
|
||||||
-----------------------
|
-----------------------
|
||||||
function paintWaterfall(setCells)
|
function paintWaterfall(setCells)
|
||||||
if setCells then
|
|
||||||
for i = 1, #setCells do
|
|
||||||
SetWaterCell(
|
|
||||||
c,
|
|
||||||
setCells[i].xPos,
|
|
||||||
setCells[i].yPos,
|
|
||||||
setCells[i].zPos,
|
|
||||||
mediumWaterForce,
|
|
||||||
Enum.WaterDirection.NegY
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function setWaterDirection(mouseCellPos, setCells)
|
|
||||||
if not setCells then
|
if not setCells then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if #setCells <= 0 then
|
for i = 1, #setCells do
|
||||||
return
|
SetWaterCell(
|
||||||
|
c,
|
||||||
|
setCells[i].xPos,
|
||||||
|
setCells[i].yPos,
|
||||||
|
setCells[i].zPos,
|
||||||
|
mediumWaterForce,
|
||||||
|
Enum.WaterDirection.NegY
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Factored out this stuff because I didn't like the mutability of the setCells arrays. - Heliodex
|
||||||
|
|
||||||
|
local function getSquareCell(x: number, y: number, z: number)
|
||||||
|
-- local tempCellPos = Vector3.new(x, y, z)
|
||||||
|
local oldMaterial, oldType, oldOrientation = GetCell(c, x, y, z)
|
||||||
|
if oldMaterial.Value <= 0 then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
return {
|
||||||
|
xPos = x,
|
||||||
|
yPos = y,
|
||||||
|
zPos = z,
|
||||||
|
theType = oldType,
|
||||||
|
orientation = oldOrientation,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function getSquare(cellPos)
|
||||||
|
local setCells = {}
|
||||||
|
local finalX = cellPos.x + radius - 1
|
||||||
|
local finalZ = cellPos.z + radius - 1
|
||||||
|
local finalY = cellPos.y + radius - 1
|
||||||
|
|
||||||
|
for x = cellPos.x - radius + 1, finalX do
|
||||||
|
for z = cellPos.z - radius + 1, finalZ do
|
||||||
|
for y = cellPos.y - radius + 1, finalY do
|
||||||
|
table.insert(setCells, getSquareCell(x, y, z))
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if directionIsDown(lastCell, mouseCellPos) then
|
return setCells
|
||||||
|
end
|
||||||
|
|
||||||
|
local function getCircularCell(
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
z: number,
|
||||||
|
cellPos,
|
||||||
|
radiusSquared
|
||||||
|
)
|
||||||
|
local tempCellPos = Vector3.new(x, y, z)
|
||||||
|
local holdDist = tempCellPos - cellPos
|
||||||
|
local distSq = (holdDist):Dot(holdDist)
|
||||||
|
if distSq >= radiusSquared then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local oldMaterial, oldType, oldOrientation = GetCell(c, x, y, z)
|
||||||
|
if oldMaterial.Value <= 0 then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
return {
|
||||||
|
xPos = x,
|
||||||
|
yPos = y,
|
||||||
|
zPos = z,
|
||||||
|
theType = oldType,
|
||||||
|
orientation = oldOrientation,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function getCircular(cellPos)
|
||||||
|
local setCells = {}
|
||||||
|
local finalX = cellPos.x + radius
|
||||||
|
local finalZ = cellPos.z + radius
|
||||||
|
local finalY = cellPos.y + radius
|
||||||
|
|
||||||
|
for x = cellPos.x - radius, finalX do
|
||||||
|
for z = cellPos.z - radius, finalZ do
|
||||||
|
for y = cellPos.y - radius, finalY do
|
||||||
|
table.insert(
|
||||||
|
setCells,
|
||||||
|
getCircularCell(x, y, z, cellPos, radius * radius)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return setCells
|
||||||
|
end
|
||||||
|
|
||||||
|
local function getAffectedCells(startPos)
|
||||||
|
if startPos and c then
|
||||||
|
if brushType == "Circular" then
|
||||||
|
return getCircular(startPos)
|
||||||
|
elseif brushType == "Square" then
|
||||||
|
return getSquare(startPos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return {}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function directionIsDown(fromCell, toCell)
|
||||||
|
if not toCell then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if toCell and fromCell then
|
||||||
|
local direction = (toCell - fromCell).unit
|
||||||
|
local absX, absY, absZ =
|
||||||
|
math.abs(direction.X), math.abs(direction.Y), math.abs(direction.Z)
|
||||||
|
if absY > absX and absY > absZ then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local viableCells = getAffectedCells(toCell)
|
||||||
|
if not viableCells or #viableCells < 2 then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local lowX, lowY, lowZ =
|
||||||
|
viableCells[1].xPos, viableCells[1].yPos, viableCells[1].zPos
|
||||||
|
local highX, highY, highZ = lowX, lowY, lowZ
|
||||||
|
|
||||||
|
for i = 2, #viableCells do
|
||||||
|
if viableCells[i].xPos < lowX then
|
||||||
|
lowX = viableCells[i].xPos
|
||||||
|
end
|
||||||
|
if viableCells[i].xPos > highX then
|
||||||
|
highX = viableCells[i].xPos
|
||||||
|
end
|
||||||
|
|
||||||
|
if viableCells[i].yPos < lowY then
|
||||||
|
lowY = viableCells[i].yPos
|
||||||
|
end
|
||||||
|
if viableCells[i].yPos > highY then
|
||||||
|
highY = viableCells[i].yPos
|
||||||
|
end
|
||||||
|
|
||||||
|
if viableCells[i].zPos < lowZ then
|
||||||
|
lowZ = viableCells[i].zPos
|
||||||
|
end
|
||||||
|
if viableCells[i].zPos > highZ then
|
||||||
|
highZ = viableCells[i].zPos
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local xRange, yRange, zRange =
|
||||||
|
math.abs(highX - lowX), math.abs(highY - lowY), math.abs(highZ - lowZ)
|
||||||
|
|
||||||
|
local xzPlaneArea = xRange * zRange
|
||||||
|
local xyPlaneArea = xRange * yRange
|
||||||
|
local yzPlaneArea = yRange * zRange
|
||||||
|
|
||||||
|
return xyPlaneArea > xzPlaneArea or yzPlaneArea > xzPlaneArea
|
||||||
|
end
|
||||||
|
|
||||||
|
local function setWaterDirection(mouseCellPos, setCells)
|
||||||
|
if not setCells or #setCells <= 0 then
|
||||||
|
return
|
||||||
|
elseif directionIsDown(lastCell, mouseCellPos) then
|
||||||
paintWaterfall(setCells)
|
paintWaterfall(setCells)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
@ -209,197 +354,122 @@ function setWaterDirection(mouseCellPos, setCells)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
return
|
||||||
for i = 1, #setCells do
|
end
|
||||||
if setCells[i].xPos == initX then
|
|
||||||
|
for i = 1, #setCells do
|
||||||
|
if setCells[i].xPos == initX then
|
||||||
|
SetWaterCell(
|
||||||
|
c,
|
||||||
|
setCells[i].xPos,
|
||||||
|
setCells[i].yPos,
|
||||||
|
setCells[i].zPos,
|
||||||
|
mediumWaterForce,
|
||||||
|
down
|
||||||
|
)
|
||||||
|
elseif setCells[i].xPos == endX then
|
||||||
|
SetWaterCell(
|
||||||
|
c,
|
||||||
|
setCells[i].xPos,
|
||||||
|
setCells[i].yPos,
|
||||||
|
setCells[i].zPos,
|
||||||
|
mediumWaterForce,
|
||||||
|
up
|
||||||
|
)
|
||||||
|
else
|
||||||
|
if setCells[i].zPos < zMiddle then
|
||||||
SetWaterCell(
|
SetWaterCell(
|
||||||
c,
|
c,
|
||||||
setCells[i].xPos,
|
setCells[i].xPos,
|
||||||
setCells[i].yPos,
|
setCells[i].yPos,
|
||||||
setCells[i].zPos,
|
setCells[i].zPos,
|
||||||
mediumWaterForce,
|
mediumWaterForce,
|
||||||
down
|
right
|
||||||
)
|
)
|
||||||
elseif setCells[i].xPos == endX then
|
elseif setCells[i].zPos > zMiddle then
|
||||||
SetWaterCell(
|
SetWaterCell(
|
||||||
c,
|
c,
|
||||||
setCells[i].xPos,
|
setCells[i].xPos,
|
||||||
setCells[i].yPos,
|
setCells[i].yPos,
|
||||||
setCells[i].zPos,
|
setCells[i].zPos,
|
||||||
mediumWaterForce,
|
mediumWaterForce,
|
||||||
up
|
left
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
if setCells[i].zPos < zMiddle then
|
if setCells[i].xPos < xMiddle then
|
||||||
SetWaterCell(
|
SetWaterCell(
|
||||||
c,
|
c,
|
||||||
setCells[i].xPos,
|
setCells[i].xPos,
|
||||||
setCells[i].yPos,
|
setCells[i].yPos,
|
||||||
setCells[i].zPos,
|
setCells[i].zPos,
|
||||||
mediumWaterForce,
|
mediumWaterForce,
|
||||||
right
|
down
|
||||||
)
|
)
|
||||||
elseif setCells[i].zPos > zMiddle then
|
elseif setCells[i].xPos > xMiddle then
|
||||||
SetWaterCell(
|
SetWaterCell(
|
||||||
c,
|
c,
|
||||||
setCells[i].xPos,
|
setCells[i].xPos,
|
||||||
setCells[i].yPos,
|
setCells[i].yPos,
|
||||||
setCells[i].zPos,
|
setCells[i].zPos,
|
||||||
mediumWaterForce,
|
mediumWaterForce,
|
||||||
left
|
up
|
||||||
)
|
)
|
||||||
else
|
|
||||||
if setCells[i].xPos < xMiddle then
|
|
||||||
SetWaterCell(
|
|
||||||
c,
|
|
||||||
setCells[i].xPos,
|
|
||||||
setCells[i].yPos,
|
|
||||||
setCells[i].zPos,
|
|
||||||
mediumWaterForce,
|
|
||||||
down
|
|
||||||
)
|
|
||||||
elseif setCells[i].xPos > xMiddle then
|
|
||||||
SetWaterCell(
|
|
||||||
c,
|
|
||||||
setCells[i].xPos,
|
|
||||||
setCells[i].yPos,
|
|
||||||
setCells[i].zPos,
|
|
||||||
mediumWaterForce,
|
|
||||||
up
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
function getSquare(cellPos, setCells)
|
|
||||||
local finalX = cellPos.x + radius - 1
|
|
||||||
local finalZ = cellPos.z + radius - 1
|
|
||||||
local finalY = cellPos.y + radius - 1
|
|
||||||
|
|
||||||
for x = cellPos.x - radius + 1, finalX do
|
|
||||||
for z = cellPos.z - radius + 1, finalZ do
|
|
||||||
for y = cellPos.y - radius + 1, finalY do
|
|
||||||
-- local tempCellPos = Vector3.new(x, y, z)
|
|
||||||
local oldMaterial, oldType, oldOrientation = GetCell(c, x, y, z)
|
|
||||||
if oldMaterial.Value > 0 then
|
|
||||||
table.insert(setCells, {
|
|
||||||
xPos = x,
|
|
||||||
yPos = y,
|
|
||||||
zPos = z,
|
|
||||||
theType = oldType,
|
|
||||||
orientation = oldOrientation,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function getCircular(cellPos, setCells)
|
|
||||||
local radiusSquared = radius * radius
|
|
||||||
|
|
||||||
local finalX = cellPos.x + radius
|
|
||||||
local finalZ = cellPos.z + radius
|
|
||||||
local finalY = cellPos.y + radius
|
|
||||||
|
|
||||||
for x = cellPos.x - radius, finalX do
|
|
||||||
for z = cellPos.z - radius, finalZ do
|
|
||||||
for y = cellPos.y - radius, finalY do
|
|
||||||
local tempCellPos = Vector3.new(x, y, z)
|
|
||||||
local holdDist = tempCellPos - cellPos
|
|
||||||
local distSq = (holdDist):Dot(holdDist)
|
|
||||||
if distSq < radiusSquared then
|
|
||||||
local oldMaterial, oldType, oldOrientation =
|
|
||||||
GetCell(c, x, y, z)
|
|
||||||
if oldMaterial.Value > 0 then
|
|
||||||
table.insert(setCells, {
|
|
||||||
xPos = x,
|
|
||||||
yPos = y,
|
|
||||||
zPos = z,
|
|
||||||
theType = oldType,
|
|
||||||
orientation = oldOrientation,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function paintCircular(cellPos, setCells)
|
|
||||||
getCircular(cellPos, setCells)
|
|
||||||
|
|
||||||
if currentMaterial ~= waterMaterial then
|
|
||||||
for i = 1, #setCells do
|
|
||||||
SetCell(
|
|
||||||
c,
|
|
||||||
setCells[i].xPos,
|
|
||||||
setCells[i].yPos,
|
|
||||||
setCells[i].zPos,
|
|
||||||
currentMaterial,
|
|
||||||
setCells[i].theType,
|
|
||||||
setCells[i].orientation
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function paintSquare(cellPos, setCells)
|
|
||||||
getSquare(cellPos, setCells)
|
|
||||||
|
|
||||||
if currentMaterial ~= waterMaterial then
|
|
||||||
for i = 1, #setCells do
|
|
||||||
SetCell(
|
|
||||||
c,
|
|
||||||
setCells[i].xPos,
|
|
||||||
setCells[i].yPos,
|
|
||||||
setCells[i].zPos,
|
|
||||||
currentMaterial,
|
|
||||||
setCells[i].theType,
|
|
||||||
setCells[i].orientation
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function paint(startPos)
|
|
||||||
if startPos and c then
|
|
||||||
local cellPos = startPos
|
|
||||||
local setCells = {}
|
|
||||||
|
|
||||||
if brushType == "Circular" then
|
|
||||||
paintCircular(cellPos, setCells)
|
|
||||||
elseif brushType == "Square" then
|
|
||||||
paintSquare(cellPos, setCells)
|
|
||||||
end
|
|
||||||
|
|
||||||
if currentMaterial == waterMaterial then
|
|
||||||
setWaterDirection(cellPos, setCells)
|
|
||||||
end
|
|
||||||
|
|
||||||
return setCells
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
function getAffectedCells(startPos)
|
|
||||||
local setCells = {}
|
|
||||||
|
|
||||||
if startPos and c then
|
|
||||||
if brushType == "Circular" then
|
|
||||||
getCircular(startPos, setCells)
|
|
||||||
elseif brushType == "Square" then
|
|
||||||
getSquare(startPos, setCells)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return setCells
|
return setCells
|
||||||
end
|
end
|
||||||
|
|
||||||
function calculateRegion(mouseR)
|
local function paintWith(
|
||||||
|
fn: (
|
||||||
|
Vector3
|
||||||
|
) -> { xPos: number, yPos: number, zPos: number },
|
||||||
|
cellPos: Vector3
|
||||||
|
)
|
||||||
|
local setCells = fn(cellPos)
|
||||||
|
|
||||||
|
if currentMaterial == waterMaterial then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
for i = 1, #setCells do
|
||||||
|
SetCell(
|
||||||
|
c,
|
||||||
|
setCells[i].xPos,
|
||||||
|
setCells[i].yPos,
|
||||||
|
setCells[i].zPos,
|
||||||
|
currentMaterial,
|
||||||
|
setCells[i].theType,
|
||||||
|
setCells[i].orientation
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
return setCells
|
||||||
|
end
|
||||||
|
|
||||||
|
local function paint(startPos)
|
||||||
|
if not (startPos and c) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local cellPos = startPos
|
||||||
|
local setCells
|
||||||
|
|
||||||
|
if brushType == "Circular" then
|
||||||
|
setCells = paintWith(getCircular, cellPos)
|
||||||
|
elseif brushType == "Square" then
|
||||||
|
setCells = paintWith(getSquare, cellPos)
|
||||||
|
end
|
||||||
|
|
||||||
|
if currentMaterial == waterMaterial then
|
||||||
|
return setWaterDirection(cellPos, setCells)
|
||||||
|
end
|
||||||
|
|
||||||
|
return setCells
|
||||||
|
end
|
||||||
|
|
||||||
|
local function calculateRegion(mouseR)
|
||||||
local cellPos = WorldToCellPreferSolid(c, mouseR.Hit.p)
|
local cellPos = WorldToCellPreferSolid(c, mouseR.Hit.p)
|
||||||
|
|
||||||
local lowVec =
|
local lowVec =
|
||||||
|
|
@ -415,7 +485,7 @@ function calculateRegion(mouseR)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
function createSelection(mouseS, massSelection)
|
local function createSelection(mouseS, massSelection)
|
||||||
currSelectionUpdate, currSelectionDestroy = RbxUtil.SelectTerrainRegion(
|
currSelectionUpdate, currSelectionDestroy = RbxUtil.SelectTerrainRegion(
|
||||||
calculateRegion(mouseS),
|
calculateRegion(mouseS),
|
||||||
BrickColor.new "Lime green",
|
BrickColor.new "Lime green",
|
||||||
|
|
@ -424,24 +494,19 @@ function createSelection(mouseS, massSelection)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
function updateSelection(mouseS)
|
local function updateSelection(mouseS)
|
||||||
if not currSelectionUpdate then
|
if not currSelectionUpdate then
|
||||||
createSelection(mouseS, radius > 4)
|
createSelection(mouseS, radius > 4)
|
||||||
else
|
|
||||||
currSelectionUpdate(
|
|
||||||
calculateRegion(mouseS),
|
|
||||||
BrickColor.new "Lime green"
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function setPositionDirectionality()
|
|
||||||
if nil == lastCell then
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
currSelectionUpdate(calculateRegion(mouseS), BrickColor.new "Lime green")
|
||||||
|
end
|
||||||
|
|
||||||
-- no dragging occured, lets set our water to be stagnant or be a waterfall
|
local function setPositionDirectionality()
|
||||||
if lastCell and not lastLastCell then
|
if nil == lastCell then
|
||||||
|
return
|
||||||
|
elseif lastCell and not lastLastCell then
|
||||||
|
-- no dragging occured, lets set our water to be stagnant or be a waterfall
|
||||||
local cellsToSet = paint(lastCell)
|
local cellsToSet = paint(lastCell)
|
||||||
if directionIsDown(nil, lastCell) then
|
if directionIsDown(nil, lastCell) then
|
||||||
paintWaterfall(cellsToSet)
|
paintWaterfall(cellsToSet)
|
||||||
|
|
@ -476,23 +541,14 @@ function setPositionDirectionality()
|
||||||
local direction
|
local direction
|
||||||
|
|
||||||
if absX > absY and absX > absZ then
|
if absX > absY and absX > absZ then
|
||||||
if overallDirection.X > 0 then
|
direction = overallDirection.X > 0 and Enum.WaterDirection.X
|
||||||
direction = Enum.WaterDirection.X
|
or Enum.WaterDirection.NegX
|
||||||
else
|
|
||||||
direction = Enum.WaterDirection.NegX
|
|
||||||
end
|
|
||||||
elseif absY > absX and absY > absZ then
|
elseif absY > absX and absY > absZ then
|
||||||
if overallDirection.Y > 0 then
|
direction = overallDirection.Y > 0 and Enum.WaterDirection.Y
|
||||||
direction = Enum.WaterDirection.Y
|
or Enum.WaterDirection.NegY
|
||||||
else
|
|
||||||
direction = Enum.WaterDirection.NegY
|
|
||||||
end
|
|
||||||
elseif absZ > absX and absZ > absY then
|
elseif absZ > absX and absZ > absY then
|
||||||
if overallDirection.Z > 0 then
|
direction = overallDirection.Z > 0 and Enum.WaterDirection.Z
|
||||||
direction = Enum.WaterDirection.Z
|
or Enum.WaterDirection.NegZ
|
||||||
else
|
|
||||||
direction = Enum.WaterDirection.NegZ
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if not direction then -- this should never be hit, but just in case
|
if not direction then -- this should never be hit, but just in case
|
||||||
|
|
@ -512,24 +568,27 @@ function setPositionDirectionality()
|
||||||
end
|
end
|
||||||
|
|
||||||
function mouseDown(mouseD)
|
function mouseDown(mouseD)
|
||||||
if on and mouseD.Target == game.Workspace.Terrain then
|
if not (on and mouseD.Target == game.Workspace.Terrain) then
|
||||||
dragging = true
|
return
|
||||||
if mouseD and mouseD.Hit then
|
|
||||||
if mouseD.Target == game.Workspace.Terrain then
|
|
||||||
local newCell = WorldToCellPreferSolid(c, mouseD.Hit.p)
|
|
||||||
if newCell then
|
|
||||||
local setCells = paint(newCell)
|
|
||||||
if
|
|
||||||
currentMaterial == waterMaterial
|
|
||||||
and directionIsDown(lastCell, newCell)
|
|
||||||
then
|
|
||||||
paintWaterfall(setCells)
|
|
||||||
end
|
|
||||||
lastCell = newCell
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
dragging = true
|
||||||
|
if
|
||||||
|
not (mouseD and mouseD.Hit and mouseD.Target == game.Workspace.Terrain)
|
||||||
|
then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local newCell = WorldToCellPreferSolid(c, mouseD.Hit.p)
|
||||||
|
if not newCell then
|
||||||
|
return
|
||||||
|
elseif
|
||||||
|
currentMaterial == waterMaterial
|
||||||
|
and directionIsDown(lastCell, newCell)
|
||||||
|
then
|
||||||
|
paintWaterfall(paint(newCell))
|
||||||
|
end
|
||||||
|
lastCell = newCell
|
||||||
end
|
end
|
||||||
|
|
||||||
function mouseUp(_)
|
function mouseUp(_)
|
||||||
|
|
@ -547,96 +606,29 @@ function mouseUp(_)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mouseMove(mouseM)
|
function mouseMove(mouseM)
|
||||||
if on then
|
if not on then
|
||||||
if mouseM.Target == game.Workspace.Terrain then
|
return
|
||||||
if lastCell ~= WorldToCellPreferSolid(c, mouseM.Hit.p) then
|
elseif mouseM.Target == game.Workspace.Terrain then
|
||||||
updateSelection(mouseM)
|
if lastCell == WorldToCellPreferSolid(c, mouseM.Hit.p) then
|
||||||
local newCell = WorldToCellPreferSolid(c, mouseM.Hit.p)
|
return
|
||||||
|
|
||||||
if dragging then
|
|
||||||
-- local painting = true
|
|
||||||
paint(newCell)
|
|
||||||
if lastCell and newCell then
|
|
||||||
if (lastCell - newCell).magnitude > 1 then
|
|
||||||
paintBetweenPoints(lastCell, newCell)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
lastLastCell = lastCell
|
|
||||||
lastCell = newCell
|
|
||||||
-- painting = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
destroySelection()
|
|
||||||
end
|
end
|
||||||
end
|
updateSelection(mouseM)
|
||||||
end
|
local newCell = WorldToCellPreferSolid(c, mouseM.Hit.p)
|
||||||
|
|
||||||
function directionIsDown(fromCell, toCell)
|
if not dragging then
|
||||||
if not toCell then
|
return
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
if toCell and fromCell then
|
|
||||||
local direction = (toCell - fromCell).unit
|
|
||||||
local absX, absY, absZ =
|
|
||||||
math.abs(direction.X), math.abs(direction.Y), math.abs(direction.Z)
|
|
||||||
if absY > absX and absY > absZ then
|
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
end
|
-- local painting = true
|
||||||
|
paint(newCell)
|
||||||
local viableCells = getAffectedCells(toCell)
|
if lastCell and newCell and (lastCell - newCell).magnitude > 1 then
|
||||||
if not viableCells then
|
paintBetweenPoints(lastCell, newCell)
|
||||||
return false
|
|
||||||
end
|
|
||||||
if #viableCells < 2 then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
local lowX, lowY, lowZ =
|
|
||||||
viableCells[1].xPos, viableCells[1].yPos, viableCells[1].zPos
|
|
||||||
local highX, highY, highZ = lowX, lowY, lowZ
|
|
||||||
|
|
||||||
for i = 2, #viableCells do
|
|
||||||
if viableCells[i].xPos < lowX then
|
|
||||||
lowX = viableCells[i].xPos
|
|
||||||
end
|
|
||||||
if viableCells[i].xPos > highX then
|
|
||||||
highX = viableCells[i].xPos
|
|
||||||
end
|
|
||||||
|
|
||||||
if viableCells[i].yPos < lowY then
|
|
||||||
lowY = viableCells[i].yPos
|
|
||||||
end
|
|
||||||
if viableCells[i].yPos > highY then
|
|
||||||
highY = viableCells[i].yPos
|
|
||||||
end
|
|
||||||
|
|
||||||
if viableCells[i].zPos < lowZ then
|
|
||||||
lowZ = viableCells[i].zPos
|
|
||||||
end
|
|
||||||
if viableCells[i].zPos > highZ then
|
|
||||||
highZ = viableCells[i].zPos
|
|
||||||
end
|
end
|
||||||
|
lastLastCell = lastCell
|
||||||
|
lastCell = newCell
|
||||||
|
-- painting = false
|
||||||
|
else
|
||||||
|
destroySelection()
|
||||||
end
|
end
|
||||||
|
|
||||||
local xRange, yRange, zRange =
|
|
||||||
math.abs(highX - lowX), math.abs(highY - lowY), math.abs(highZ - lowZ)
|
|
||||||
|
|
||||||
local xzPlaneArea = xRange * zRange
|
|
||||||
local xyPlaneArea = xRange * yRange
|
|
||||||
local yzPlaneArea = yRange * zRange
|
|
||||||
|
|
||||||
if xyPlaneArea > xzPlaneArea then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
if yzPlaneArea > xzPlaneArea then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function destroySelection()
|
function destroySelection()
|
||||||
|
|
@ -649,31 +641,33 @@ function destroySelection()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function moveTowardsGoal(direction, currPos, goalPos, currCell)
|
local function moveTowardsGoal(direction: string, currPos, goalPos, currCell)
|
||||||
if currPos ~= goalPos then
|
if currPos == goalPos then
|
||||||
if currPos < goalPos then
|
return currCell
|
||||||
if direction == "X" then
|
end
|
||||||
currCell = Vector3.new(currCell.X + 1, currCell.Y, currCell.Z)
|
|
||||||
elseif direction == "Y" then
|
if currPos < goalPos then
|
||||||
currCell = Vector3.new(currCell.X, currCell.Y + 1, currCell.Z)
|
if direction == "X" then
|
||||||
elseif direction == "Z" then
|
currCell = Vector3.new(currCell.X + 1, currCell.Y, currCell.Z)
|
||||||
currCell = Vector3.new(currCell.X, currCell.Y, currCell.Z + 1)
|
elseif direction == "Y" then
|
||||||
end
|
currCell = Vector3.new(currCell.X, currCell.Y + 1, currCell.Z)
|
||||||
elseif currPos > goalPos then
|
elseif direction == "Z" then
|
||||||
if direction == "X" then
|
currCell = Vector3.new(currCell.X, currCell.Y, currCell.Z + 1)
|
||||||
currCell = Vector3.new(currCell.X - 1, currCell.Y, currCell.Z)
|
end
|
||||||
elseif direction == "Y" then
|
elseif currPos > goalPos then
|
||||||
currCell = Vector3.new(currCell.X, currCell.Y - 1, currCell.Z)
|
if direction == "X" then
|
||||||
elseif direction == "Z" then
|
currCell = Vector3.new(currCell.X - 1, currCell.Y, currCell.Z)
|
||||||
currCell = Vector3.new(currCell.X, currCell.Y, currCell.Z - 1)
|
elseif direction == "Y" then
|
||||||
end
|
currCell = Vector3.new(currCell.X, currCell.Y - 1, currCell.Z)
|
||||||
|
elseif direction == "Z" then
|
||||||
|
currCell = Vector3.new(currCell.X, currCell.Y, currCell.Z - 1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return currCell
|
return currCell
|
||||||
end
|
end
|
||||||
|
|
||||||
function interpolateOneDim(direction, currPos, goalPos, currCell)
|
local function interpolateOneDim(direction, currPos, goalPos, currCell)
|
||||||
if currPos ~= goalPos then
|
if currPos ~= goalPos then
|
||||||
currCell = moveTowardsGoal(direction, currPos, goalPos, currCell)
|
currCell = moveTowardsGoal(direction, currPos, goalPos, currCell)
|
||||||
paint(currCell)
|
paint(currCell)
|
||||||
|
|
@ -696,7 +690,7 @@ function paintBetweenPoints(lastCellP, newCell)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
On = function()
|
function On()
|
||||||
if not c then
|
if not c then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
@ -707,7 +701,7 @@ On = function()
|
||||||
on = true
|
on = true
|
||||||
end
|
end
|
||||||
|
|
||||||
Off = function()
|
function Off()
|
||||||
toolbarbutton:SetActive(false)
|
toolbarbutton:SetActive(false)
|
||||||
|
|
||||||
destroySelection()
|
destroySelection()
|
||||||
|
|
@ -724,6 +718,7 @@ local g = Instance.new "ScreenGui"
|
||||||
g.Name = "MaterialPainterGui"
|
g.Name = "MaterialPainterGui"
|
||||||
g.Parent = CoreGui
|
g.Parent = CoreGui
|
||||||
|
|
||||||
|
local containerFrame
|
||||||
dragBar, containerFrame, helpFrame, closeEvent = RbxGui.CreatePluginFrame(
|
dragBar, containerFrame, helpFrame, closeEvent = RbxGui.CreatePluginFrame(
|
||||||
"Material Brush",
|
"Material Brush",
|
||||||
UDim2.new(0, 163, 0, 285),
|
UDim2.new(0, 163, 0, 285),
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
while game == nil do
|
while not game do
|
||||||
wait()
|
wait()
|
||||||
end
|
end
|
||||||
|
|
||||||
local ContentProvider = game:GetService "ContentProvider"
|
local ContentProvider = game:GetService "ContentProvider"
|
||||||
local CoreGui = game:GetService "CoreGui"
|
local CoreGui = game:GetService "CoreGui"
|
||||||
|
local News = require "../Modules/New"
|
||||||
|
local New = News.New
|
||||||
|
local Hydrate = News.Hydrate
|
||||||
|
|
||||||
---------------
|
---------------
|
||||||
--PLUGIN SETUP-
|
--PLUGIN SETUP-
|
||||||
|
|
@ -113,11 +116,10 @@ function hideLoadingDialog()
|
||||||
currStampGui.LoadingFrame.Visible = false
|
currStampGui.LoadingFrame.Visible = false
|
||||||
end
|
end
|
||||||
|
|
||||||
local partSelected = function(name, id, terrainShape)
|
local stampCon
|
||||||
if not id then
|
|
||||||
return
|
local function partSelected(name, id, terrainShape)
|
||||||
end
|
if not (id and name) then
|
||||||
if not name then
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -146,21 +148,23 @@ local partSelected = function(name, id, terrainShape)
|
||||||
and clusterTag:isA "Vector3Value"
|
and clusterTag:isA "Vector3Value"
|
||||||
and clusterTag.Value.X == 17
|
and clusterTag.Value.X == 17
|
||||||
then
|
then
|
||||||
local waterForceTag = Instance.new("StringValue", lastStampModel)
|
New "StringValue" {
|
||||||
waterForceTag.Name = "WaterForceTag"
|
Name = "WaterForceTag",
|
||||||
waterForceTag.Value = waterForceAndDirection[1]
|
Value = waterForceAndDirection[1],
|
||||||
|
Parent = lastStampModel,
|
||||||
local waterForceDirectionTag =
|
}
|
||||||
Instance.new("StringValue", lastStampModel)
|
New "StringValue" {
|
||||||
waterForceDirectionTag.Name = "WaterForceDirectionTag"
|
Name = "WaterForceDirectionTag",
|
||||||
waterForceDirectionTag.Value = waterForceAndDirection[2]
|
Value = waterForceAndDirection[2],
|
||||||
|
Parent = lastStampModel,
|
||||||
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
setupStamper(lastStampModel, mouse)
|
setupStamper(lastStampModel)
|
||||||
end
|
end
|
||||||
|
|
||||||
function updateWaterInfo()
|
local function updateWaterInfo()
|
||||||
if stampControl then
|
if stampControl then
|
||||||
stampControl.Destroy()
|
stampControl.Destroy()
|
||||||
end
|
end
|
||||||
|
|
@ -177,70 +181,203 @@ function updateWaterInfo()
|
||||||
local clusterTag = lastStampModel:FindFirstChild "ClusterMaterial"
|
local clusterTag = lastStampModel:FindFirstChild "ClusterMaterial"
|
||||||
-- we are going to stamp water, send info to stamper about this
|
-- we are going to stamp water, send info to stamper about this
|
||||||
if clusterTag and clusterTag.Value.X == 17 then
|
if clusterTag and clusterTag.Value.X == 17 then
|
||||||
local waterForceTag = Instance.new("StringValue", lastStampModel)
|
New "StringValue" {
|
||||||
waterForceTag.Name = "WaterForceTag"
|
Name = "WaterForceTag",
|
||||||
waterForceTag.Value = waterForceAndDirection[1]
|
Value = waterForceAndDirection[1],
|
||||||
|
Parent = lastStampModel,
|
||||||
local waterForceDirectionTag =
|
}
|
||||||
Instance.new("StringValue", lastStampModel)
|
New "StringValue" {
|
||||||
waterForceDirectionTag.Name = "WaterForceDirectionTag"
|
Name = "WaterForceDirectionTag",
|
||||||
waterForceDirectionTag.Value = waterForceAndDirection[2]
|
Value = waterForceAndDirection[2],
|
||||||
|
Parent = lastStampModel,
|
||||||
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
setupStamper(lastStampModel, mouse)
|
setupStamper(lastStampModel)
|
||||||
end
|
end
|
||||||
|
|
||||||
local dialogClosed = function()
|
local function dialogClosed()
|
||||||
if lastStampModel then
|
if not lastStampModel then
|
||||||
if stampControl then
|
return
|
||||||
stampControl.Destroy()
|
elseif stampControl then
|
||||||
end
|
stampControl.Destroy()
|
||||||
setupStamper(lastStampModel, mouse)
|
|
||||||
end
|
end
|
||||||
|
setupStamper(lastStampModel)
|
||||||
end
|
end
|
||||||
|
|
||||||
function pickPart()
|
local function pickPart()
|
||||||
if stampControl then
|
if stampControl then
|
||||||
stampControl.Destroy()
|
stampControl.Destroy()
|
||||||
end
|
end
|
||||||
setPanelVisibility(true)
|
setPanelVisibility(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
function keyHandler(key)
|
local function keyHandler(key)
|
||||||
if key == "f" then
|
if key ~= "f" then
|
||||||
handlePartShow()
|
return
|
||||||
end
|
elseif getPanelVisibility() then
|
||||||
end
|
-- handlePartShow
|
||||||
|
setPanelVisibility(false)
|
||||||
function partOn()
|
if lastStampModel then
|
||||||
pickPart()
|
if stampControl then
|
||||||
end
|
stampControl.Destroy()
|
||||||
|
end
|
||||||
function partOff()
|
setupStamper(lastStampModel)
|
||||||
setPanelVisibility(false)
|
|
||||||
if lastStampModel then
|
|
||||||
if stampControl then
|
|
||||||
stampControl.Destroy()
|
|
||||||
end
|
end
|
||||||
setupStamper(lastStampModel, mouse)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function handlePartShow()
|
|
||||||
if getPanelVisibility() then
|
|
||||||
partOff()
|
|
||||||
else
|
else
|
||||||
partOn()
|
pickPart()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
On = function()
|
function setupStamper(model)
|
||||||
if not game.Workspace.Terrain then
|
if not model then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
stampControl = getRbxStamper().SetupStamperDragger(model, mouse)
|
||||||
|
if not stampControl then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
stampCon = stampControl.Stamped.Changed:connect(function()
|
||||||
|
if stampControl.Stamped.Value then
|
||||||
|
stampControl.ReloadModel()
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
function updateRecentParts(newName, newId, newTerrainShape)
|
||||||
|
if not newId then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if this then
|
for i = 1, #recentButtonStack do
|
||||||
|
if recentButtonStack[i].Id == newId then -- already have item, nothing to do
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for i = #recentButtonStack - 1, 1, -1 do
|
||||||
|
recentButtonStack[i + 1].Id = recentButtonStack[i].Id
|
||||||
|
recentButtonStack[i + 1].Name = recentButtonStack[i].Name
|
||||||
|
recentButtonStack[i + 1].TerrainShape =
|
||||||
|
recentButtonStack[i].TerrainShape
|
||||||
|
|
||||||
|
recentButtonStack[i + 1].Button.Image =
|
||||||
|
recentButtonStack[i].Button.Image
|
||||||
|
end
|
||||||
|
|
||||||
|
recentButtonStack[1].Id = newId
|
||||||
|
recentButtonStack[1].Name = newName
|
||||||
|
recentButtonStack[1].TerrainShape = newTerrainShape
|
||||||
|
recentButtonStack[1].Button.Image = BaseUrl
|
||||||
|
.. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&aid="
|
||||||
|
.. tostring(newId)
|
||||||
|
end
|
||||||
|
|
||||||
|
------
|
||||||
|
--GUI-
|
||||||
|
------
|
||||||
|
|
||||||
|
function createGui()
|
||||||
|
--Insert Panel
|
||||||
|
currStampGui, setPanelVisibility, getPanelVisibility, waterTypeChangedEvent =
|
||||||
|
getRbxGui().CreateSetPanel(
|
||||||
|
userSetIds,
|
||||||
|
partSelected,
|
||||||
|
dialogClosed,
|
||||||
|
UDim2.new(0.8, 0, 0.9, 0),
|
||||||
|
UDim2.new(0.1, 0, 0.05, 0),
|
||||||
|
true
|
||||||
|
)
|
||||||
|
setPanelVisibility(false)
|
||||||
|
|
||||||
|
currStampGui.Parent = CoreGui
|
||||||
|
|
||||||
|
waterTypeChangedEvent.Event:connect(function(waterTable)
|
||||||
|
waterForceAndDirection = waterTable
|
||||||
|
updateWaterInfo()
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Loading Gui
|
||||||
|
New "Frame" {
|
||||||
|
Name = "LoadingFrame",
|
||||||
|
Style = Enum.FrameStyle.RobloxRound,
|
||||||
|
Size = UDim2.new(0, 350, 0, 60),
|
||||||
|
Visible = false,
|
||||||
|
Position = UDim2.new(0.5, -175, 0.5, -30),
|
||||||
|
Parent = currStampGui,
|
||||||
|
New "TextLabel" {
|
||||||
|
Name = "LoadingText",
|
||||||
|
BackgroundTransparency = 1,
|
||||||
|
Size = UDim2.new(0, 155, 1, 0),
|
||||||
|
Font = Enum.Font.ArialBold,
|
||||||
|
FontSize = Enum.FontSize.Size36,
|
||||||
|
Text = "Loading...",
|
||||||
|
TextColor3 = Color3.new(1, 1, 1),
|
||||||
|
TextStrokeTransparency = 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Recents Stack Gui
|
||||||
|
recentsFrame = New "Frame" {
|
||||||
|
BackgroundTransparency = 0.5,
|
||||||
|
Name = "RecentsFrame",
|
||||||
|
BackgroundColor3 = Color3.new(0, 0, 0),
|
||||||
|
Size = UDim2.new(0, 50, 0, 150),
|
||||||
|
Visible = false,
|
||||||
|
Parent = currStampGui,
|
||||||
|
}
|
||||||
|
|
||||||
|
local function recentButton()
|
||||||
|
return New "ImageButton" {
|
||||||
|
Style = Enum.ButtonStyle.RobloxButton,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 1, 3 do
|
||||||
|
recentButtonStack[i] = {}
|
||||||
|
recentButtonStack[i].Name = nil
|
||||||
|
recentButtonStack[i].Id = nil
|
||||||
|
recentButtonStack[i].TerrainShape = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
recentButtonStack[1].Button = Hydrate(recentButton()) {
|
||||||
|
Name = "RecentButtonOne",
|
||||||
|
Size = UDim2.new(0, 50, 0, 50),
|
||||||
|
Parent = recentsFrame,
|
||||||
|
}
|
||||||
|
recentButtonStack[2].Button = Hydrate(recentButton()) {
|
||||||
|
Name = "RecentButtonTwo",
|
||||||
|
Position = UDim2.new(0, 0, 0, 50),
|
||||||
|
Parent = recentsFrame,
|
||||||
|
}
|
||||||
|
recentButtonStack[3].Button = Hydrate(recentButton()) {
|
||||||
|
Name = "RecentButtonThree",
|
||||||
|
Position = UDim2.new(0, 0, 0, 100),
|
||||||
|
Parent = recentsFrame,
|
||||||
|
}
|
||||||
|
|
||||||
|
local buttonClicked = false
|
||||||
|
|
||||||
|
for i = 1, #recentButtonStack do
|
||||||
|
recentButtonStack[i].Button.MouseButton1Click:connect(function()
|
||||||
|
if buttonClicked then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
buttonClicked = true
|
||||||
|
partSelected(
|
||||||
|
recentButtonStack[i].Name,
|
||||||
|
recentButtonStack[i].Id,
|
||||||
|
recentButtonStack[i].TerrainShape
|
||||||
|
)
|
||||||
|
buttonClicked = false
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function On()
|
||||||
|
if not game.Workspace.Terrain then
|
||||||
|
return
|
||||||
|
elseif this then
|
||||||
this:Activate(true)
|
this:Activate(true)
|
||||||
mouse = this:GetMouse()
|
mouse = this:GetMouse()
|
||||||
end
|
end
|
||||||
|
|
@ -268,7 +405,7 @@ On = function()
|
||||||
on = true
|
on = true
|
||||||
end
|
end
|
||||||
|
|
||||||
Off = function()
|
function Off()
|
||||||
if toolbarbutton then
|
if toolbarbutton then
|
||||||
toolbarbutton:SetActive(false)
|
toolbarbutton:SetActive(false)
|
||||||
end
|
end
|
||||||
|
|
@ -301,144 +438,6 @@ Off = function()
|
||||||
on = false
|
on = false
|
||||||
end
|
end
|
||||||
|
|
||||||
function setupStamper(model, mouse)
|
|
||||||
if model then
|
|
||||||
stampControl = getRbxStamper().SetupStamperDragger(model, mouse)
|
|
||||||
if stampControl then
|
|
||||||
stampCon = stampControl.Stamped.Changed:connect(function()
|
|
||||||
if stampControl.Stamped.Value then
|
|
||||||
stampControl.ReloadModel()
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function updateRecentParts(newName, newId, newTerrainShape)
|
|
||||||
if newId then
|
|
||||||
for i = 1, #recentButtonStack do
|
|
||||||
if recentButtonStack[i].Id == newId then -- already have item, nothing to do
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
for i = #recentButtonStack - 1, 1, -1 do
|
|
||||||
recentButtonStack[i + 1].Id = recentButtonStack[i].Id
|
|
||||||
recentButtonStack[i + 1].Name = recentButtonStack[i].Name
|
|
||||||
recentButtonStack[i + 1].TerrainShape =
|
|
||||||
recentButtonStack[i].TerrainShape
|
|
||||||
|
|
||||||
recentButtonStack[i + 1].Button.Image =
|
|
||||||
recentButtonStack[i].Button.Image
|
|
||||||
end
|
|
||||||
|
|
||||||
recentButtonStack[1].Id = newId
|
|
||||||
recentButtonStack[1].Name = newName
|
|
||||||
recentButtonStack[1].TerrainShape = newTerrainShape
|
|
||||||
recentButtonStack[1].Button.Image = BaseUrl
|
|
||||||
.. "Game/Tools/ThumbnailAsset.ashx?fmt=png&wd=75&ht=75&aid="
|
|
||||||
.. tostring(newId)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
------
|
|
||||||
--GUI-
|
|
||||||
------
|
|
||||||
|
|
||||||
function createGui()
|
|
||||||
--Insert Panel
|
|
||||||
currStampGui, setPanelVisibility, getPanelVisibility, waterTypeChangedEvent =
|
|
||||||
getRbxGui().CreateSetPanel(
|
|
||||||
userSetIds,
|
|
||||||
partSelected,
|
|
||||||
dialogClosed,
|
|
||||||
UDim2.new(0.8, 0, 0.9, 0),
|
|
||||||
UDim2.new(0.1, 0, 0.05, 0),
|
|
||||||
true
|
|
||||||
)
|
|
||||||
setPanelVisibility(false)
|
|
||||||
|
|
||||||
currStampGui.Parent = CoreGui
|
|
||||||
|
|
||||||
waterTypeChangedEvent.Event:connect(function(waterTable)
|
|
||||||
waterForceAndDirection = waterTable
|
|
||||||
updateWaterInfo()
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- Loading Gui
|
|
||||||
local loadingFrame = Instance.new "Frame"
|
|
||||||
loadingFrame.Name = "LoadingFrame"
|
|
||||||
loadingFrame.Style = Enum.FrameStyle.RobloxRound
|
|
||||||
loadingFrame.Size = UDim2.new(0, 350, 0, 60)
|
|
||||||
loadingFrame.Visible = false
|
|
||||||
loadingFrame.Position = UDim2.new(0.5, -175, 0.5, -30)
|
|
||||||
|
|
||||||
local loadingText = Instance.new "TextLabel"
|
|
||||||
loadingText.Name = "LoadingText"
|
|
||||||
loadingText.BackgroundTransparency = 1
|
|
||||||
loadingText.Size = UDim2.new(0, 155, 1, 0)
|
|
||||||
loadingText.Font = Enum.Font.ArialBold
|
|
||||||
loadingText.FontSize = Enum.FontSize.Size36
|
|
||||||
loadingText.Text = "Loading..."
|
|
||||||
loadingText.TextColor3 = Color3.new(1, 1, 1)
|
|
||||||
loadingText.TextStrokeTransparency = 0
|
|
||||||
loadingText.Parent = loadingFrame
|
|
||||||
|
|
||||||
loadingFrame.Parent = currStampGui
|
|
||||||
|
|
||||||
-- Recents Stack Gui
|
|
||||||
recentsFrame = Instance.new "Frame"
|
|
||||||
recentsFrame.BackgroundTransparency = 0.5
|
|
||||||
recentsFrame.Name = "RecentsFrame"
|
|
||||||
recentsFrame.BackgroundColor3 = Color3.new(0, 0, 0)
|
|
||||||
recentsFrame.Size = UDim2.new(0, 50, 0, 150)
|
|
||||||
recentsFrame.Visible = false
|
|
||||||
recentsFrame.Parent = currStampGui
|
|
||||||
|
|
||||||
local recentButtonOne = Instance.new "ImageButton"
|
|
||||||
recentButtonOne.Style = Enum.ButtonStyle.RobloxButton
|
|
||||||
recentButtonOne.Name = "RecentButtonOne"
|
|
||||||
recentButtonOne.Size = UDim2.new(0, 50, 0, 50)
|
|
||||||
recentButtonOne.Parent = recentsFrame
|
|
||||||
|
|
||||||
local recentButtonTwo = recentButtonOne:clone()
|
|
||||||
recentButtonTwo.Name = "RecentButtonTwo"
|
|
||||||
recentButtonTwo.Position = UDim2.new(0, 0, 0, 50)
|
|
||||||
recentButtonTwo.Parent = recentsFrame
|
|
||||||
|
|
||||||
local recentButtonThree = recentButtonOne:clone()
|
|
||||||
recentButtonThree.Name = "RecentButtonThree"
|
|
||||||
recentButtonThree.Position = UDim2.new(0, 0, 0, 100)
|
|
||||||
recentButtonThree.Parent = recentsFrame
|
|
||||||
|
|
||||||
for i = 1, 3 do
|
|
||||||
recentButtonStack[i] = {}
|
|
||||||
recentButtonStack[i].Name = nil
|
|
||||||
recentButtonStack[i].Id = nil
|
|
||||||
recentButtonStack[i].TerrainShape = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
recentButtonStack[1].Button = recentButtonOne
|
|
||||||
recentButtonStack[2].Button = recentButtonTwo
|
|
||||||
recentButtonStack[3].Button = recentButtonThree
|
|
||||||
|
|
||||||
local buttonClicked = false
|
|
||||||
|
|
||||||
for i = 1, #recentButtonStack do
|
|
||||||
recentButtonStack[i].Button.MouseButton1Click:connect(function()
|
|
||||||
if buttonClicked then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
buttonClicked = true
|
|
||||||
partSelected(
|
|
||||||
recentButtonStack[i].Name,
|
|
||||||
recentButtonStack[i].Id,
|
|
||||||
recentButtonStack[i].TerrainShape
|
|
||||||
)
|
|
||||||
buttonClicked = false
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--------------------------
|
--------------------------
|
||||||
--SUCCESSFUL LOAD MESSAGE-
|
--SUCCESSFUL LOAD MESSAGE-
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
while game == nil do
|
while not game do
|
||||||
wait()
|
wait()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -6,6 +6,12 @@ local ChangeHistoryService = game:GetService "ChangeHistoryService"
|
||||||
local ContentProvider = game:GetService "ContentProvider"
|
local ContentProvider = game:GetService "ContentProvider"
|
||||||
local CoreGui = game:GetService "CoreGui"
|
local CoreGui = game:GetService "CoreGui"
|
||||||
|
|
||||||
|
local CreateStandardButton = require "../Modules/Terrain/CreateStandardButton"
|
||||||
|
local CreateStandardLabel = require "../Modules/Terrain/CreateStandardLabel"
|
||||||
|
local News = require "../Modules/New"
|
||||||
|
local New = News.New
|
||||||
|
local Hydrate = News.Hydrate
|
||||||
|
|
||||||
---------------
|
---------------
|
||||||
--PLUGIN SETUP-
|
--PLUGIN SETUP-
|
||||||
---------------
|
---------------
|
||||||
|
|
@ -13,6 +19,7 @@ local loaded = false
|
||||||
local on = false
|
local on = false
|
||||||
|
|
||||||
local On, Off
|
local On, Off
|
||||||
|
local mouseDown, mouseUp
|
||||||
|
|
||||||
local this = PluginManager():CreatePlugin()
|
local this = PluginManager():CreatePlugin()
|
||||||
local mouse = this:GetMouse()
|
local mouse = this:GetMouse()
|
||||||
|
|
@ -139,9 +146,6 @@ function MouseHighlighter.Create(mouseUse)
|
||||||
highlighter.selectionPart = nil
|
highlighter.selectionPart = nil
|
||||||
|
|
||||||
-- Hook the mouse up to check for movement.
|
-- Hook the mouse up to check for movement.
|
||||||
mouseH.Move:connect(function()
|
|
||||||
MouseMoved()
|
|
||||||
end)
|
|
||||||
|
|
||||||
mouseH.Button1Down:connect(function()
|
mouseH.Button1Down:connect(function()
|
||||||
highlighter.mouseDown = true
|
highlighter.mouseDown = true
|
||||||
|
|
@ -239,9 +243,7 @@ function MouseHighlighter.Create(mouseUse)
|
||||||
local function UpdatePosition(position)
|
local function UpdatePosition(position)
|
||||||
if not position then
|
if not position then
|
||||||
return
|
return
|
||||||
end
|
elseif not mouseH.Target then
|
||||||
|
|
||||||
if not mouseH.Target then
|
|
||||||
stopTween()
|
stopTween()
|
||||||
highlighter.selectionPart.Parent = nil
|
highlighter.selectionPart.Parent = nil
|
||||||
return
|
return
|
||||||
|
|
@ -297,12 +299,12 @@ function MouseHighlighter.Create(mouseUse)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Function to call when the mouse has moved. Updates where to display the highlighter.
|
-- Function to call when the mouse has moved. Updates where to display the highlighter.
|
||||||
function MouseMoved()
|
mouseH.Move:connect(function()
|
||||||
if on and not processing then
|
if on and not processing then
|
||||||
UpdatePosition(mouseH.Hit)
|
UpdatePosition(mouseH.Hit)
|
||||||
end
|
end
|
||||||
end
|
end)
|
||||||
|
|
||||||
return highlighter
|
return highlighter
|
||||||
end
|
end
|
||||||
|
|
@ -338,68 +340,6 @@ mouseHighlighter:DisablePreview()
|
||||||
local ConfirmationPopup = {}
|
local ConfirmationPopup = {}
|
||||||
ConfirmationPopup.__index = ConfirmationPopup
|
ConfirmationPopup.__index = ConfirmationPopup
|
||||||
|
|
||||||
-- Create a standard text label. Use this for all lables in the popup so it is easy to standardize.
|
|
||||||
-- labelName - What to set the text label name as.
|
|
||||||
-- pos - Where to position the label. Should be of type UDim2.
|
|
||||||
-- size - How large to make the label. Should be of type UDim2.
|
|
||||||
-- text - Text to display.
|
|
||||||
-- parent - What to set the text parent as.
|
|
||||||
-- Return:
|
|
||||||
-- Value is the created label.
|
|
||||||
function CreateStandardLabel(labelName, pos, size, text, parent)
|
|
||||||
local label = Instance.new "TextLabel"
|
|
||||||
label.Name = labelName
|
|
||||||
label.Position = pos
|
|
||||||
label.Size = size
|
|
||||||
label.Text = text
|
|
||||||
label.TextColor3 = Color3.new(0.95, 0.95, 0.95)
|
|
||||||
label.Font = Enum.Font.ArialBold
|
|
||||||
label.FontSize = Enum.FontSize.Size14
|
|
||||||
label.TextXAlignment = Enum.TextXAlignment.Left
|
|
||||||
label.BackgroundTransparency = 1
|
|
||||||
label.Parent = parent
|
|
||||||
|
|
||||||
return label
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Keep common button properties here to make it easer to change them all at once.
|
|
||||||
-- These are the default properties to use for a button.
|
|
||||||
local buttonTextColor = Color3.new(1, 1, 1)
|
|
||||||
local buttonFont = Enum.Font.ArialBold
|
|
||||||
local buttonFontSize = Enum.FontSize.Size18
|
|
||||||
|
|
||||||
-- Create a standard dropdown. Use this for all dropdowns in the popup so it is easy to standardize.
|
|
||||||
-- name - What to use.
|
|
||||||
-- pos - Where to position the button. Should be of type UDim2.
|
|
||||||
-- text - Text to show in the button.
|
|
||||||
-- funcOnPress - Function to run when the button is pressed.
|
|
||||||
-- parent - What to set the parent as.
|
|
||||||
-- Return:
|
|
||||||
-- button - The button gui.
|
|
||||||
function CreateStandardButton(name, pos, text, funcOnPress, parent, size)
|
|
||||||
local button = Instance.new "TextButton"
|
|
||||||
button.Name = name
|
|
||||||
button.Position = pos
|
|
||||||
|
|
||||||
button.Size = UDim2.new(0, 120, 0, 40)
|
|
||||||
button.Text = text
|
|
||||||
|
|
||||||
if size then
|
|
||||||
button.Size = size
|
|
||||||
end
|
|
||||||
|
|
||||||
button.Style = Enum.ButtonStyle.RobloxButton
|
|
||||||
|
|
||||||
button.TextColor3 = buttonTextColor
|
|
||||||
button.Font = buttonFont
|
|
||||||
button.FontSize = buttonFontSize
|
|
||||||
button.Parent = parent
|
|
||||||
|
|
||||||
button.MouseButton1Click:connect(funcOnPress)
|
|
||||||
|
|
||||||
return button
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Create a confirmation popup.
|
-- Create a confirmation popup.
|
||||||
--
|
--
|
||||||
-- confirmText - What to display in the popup.
|
-- confirmText - What to display in the popup.
|
||||||
|
|
@ -417,46 +357,54 @@ function ConfirmationPopup.Create(
|
||||||
confirmFunction,
|
confirmFunction,
|
||||||
declineFunction
|
declineFunction
|
||||||
)
|
)
|
||||||
local popup = {}
|
local popup = {
|
||||||
popup.confirmButton = nil -- Hold the button to confirm a choice.
|
confirmButton = nil, -- Hold the button to confirm a choice.
|
||||||
popup.declineButton = nil -- Hold the button to decline a choice.
|
declineButton = nil, -- Hold the button to decline a choice.
|
||||||
popup.confirmationFrame = nil -- Hold the conformation frame.
|
confirmationFrame = nil, -- Hold the conformation frame.
|
||||||
popup.confirmationText = nil -- Hold the text label to display the conformation message.
|
confirmationText = nil, -- Hold the text label to display the conformation message.
|
||||||
popup.confirmationHelpText = nil -- Hold the text label to display the conformation message help.
|
confirmationHelpText = nil, -- Hold the text label to display the conformation message help.
|
||||||
|
}
|
||||||
|
|
||||||
popup.confirmationFrame = Instance.new "Frame"
|
popup.confirmationFrame = New "Frame" {
|
||||||
popup.confirmationFrame.Name = "ConfirmationFrame"
|
Name = "ConfirmationFrame",
|
||||||
popup.confirmationFrame.Size = UDim2.new(0, 280, 0, 160)
|
Size = UDim2.new(0, 280, 0, 160),
|
||||||
popup.confirmationFrame.Position = UDim2.new(
|
Position = UDim2.new(
|
||||||
0.5,
|
0.5,
|
||||||
-popup.confirmationFrame.Size.X.Offset / 2,
|
-popup.confirmationFrame.Size.X.Offset / 2,
|
||||||
0.5,
|
0.5,
|
||||||
-popup.confirmationFrame.Size.Y.Offset / 2
|
-popup.confirmationFrame.Size.Y.Offset / 2
|
||||||
)
|
),
|
||||||
popup.confirmationFrame.Style = Enum.FrameStyle.RobloxRound
|
Style = Enum.FrameStyle.RobloxRound,
|
||||||
popup.confirmationFrame.Parent = screenGui
|
Parent = screenGui,
|
||||||
|
}
|
||||||
|
|
||||||
popup.confirmLabel = CreateStandardLabel(
|
popup.confirmLabel = Hydrate(
|
||||||
"ConfirmLabel",
|
CreateStandardLabel(
|
||||||
UDim2.new(0, 0, 0, 15),
|
"ConfirmLabel",
|
||||||
UDim2.new(1, 0, 0, 24),
|
UDim2.new(0, 0, 0, 15),
|
||||||
confirmText,
|
UDim2.new(1, 0, 0, 24),
|
||||||
popup.confirmationFrame
|
confirmText,
|
||||||
)
|
popup.confirmationFrame
|
||||||
popup.confirmLabel.FontSize = Enum.FontSize.Size18
|
)
|
||||||
popup.confirmLabel.TextXAlignment = Enum.TextXAlignment.Center
|
) {
|
||||||
|
FontSize = Enum.FontSize.Size18,
|
||||||
|
TextXAlignment = Enum.TextXAlignment.Center,
|
||||||
|
}
|
||||||
|
|
||||||
popup.confirmationHelpText = CreateStandardLabel(
|
popup.confirmationHelpText = Hydrate(
|
||||||
"ConfirmSmallLabel",
|
CreateStandardLabel(
|
||||||
UDim2.new(0, 0, 0, 40),
|
"ConfirmSmallLabel",
|
||||||
UDim2.new(1, 0, 0, 28),
|
UDim2.new(0, 0, 0, 40),
|
||||||
confirmSmallText,
|
UDim2.new(1, 0, 0, 28),
|
||||||
popup.confirmationFrame
|
confirmSmallText,
|
||||||
)
|
popup.confirmationFrame
|
||||||
popup.confirmationHelpText.FontSize = Enum.FontSize.Size14
|
)
|
||||||
popup.confirmationHelpText.TextWrap = true
|
) {
|
||||||
popup.confirmationHelpText.Font = Enum.Font.Arial
|
FontSize = Enum.FontSize.Size14,
|
||||||
popup.confirmationHelpText.TextXAlignment = Enum.TextXAlignment.Center
|
TextWrap = true,
|
||||||
|
Font = Enum.Font.Arial,
|
||||||
|
TextXAlignment = Enum.TextXAlignment.Center,
|
||||||
|
}
|
||||||
|
|
||||||
-- Confirm
|
-- Confirm
|
||||||
popup.confirmButton = CreateStandardButton(
|
popup.confirmButton = CreateStandardButton(
|
||||||
|
|
@ -509,68 +457,11 @@ end
|
||||||
--FUNCTION DEFINITIONS-
|
--FUNCTION DEFINITIONS-
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
local floodFill = function(x, y, z)
|
|
||||||
LoadProgressBar "Processing"
|
|
||||||
breadthFill(x, y, z)
|
|
||||||
UnloadProgressBar()
|
|
||||||
ChangeHistoryService:SetWaypoint "FloodFill"
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Function used when we try and flood fill. Prompts the user first.
|
|
||||||
-- Will not show if disabled or terrain is being processed.
|
|
||||||
function ConfirmFloodFill(x, y, z)
|
|
||||||
-- Only do if something isn't already being processed.
|
|
||||||
if not processing then
|
|
||||||
processing = true
|
|
||||||
if nil == ConfirmationPopupObject then
|
|
||||||
ConfirmationPopupObject = ConfirmationPopup.Create(
|
|
||||||
"Flood Fill At Selected Location?",
|
|
||||||
"This operation may take some time.",
|
|
||||||
"Fill",
|
|
||||||
"Cancel",
|
|
||||||
function()
|
|
||||||
ConfirmationPopupObject:Clear()
|
|
||||||
ConfirmationPopupObject = nil
|
|
||||||
floodFill(x, y, z)
|
|
||||||
ConfirmationPopupObject = nil
|
|
||||||
end,
|
|
||||||
function()
|
|
||||||
ConfirmationPopupObject:Clear()
|
|
||||||
ConfirmationPopupObject = nil
|
|
||||||
processing = false
|
|
||||||
end
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function mouseDown(mouseD)
|
|
||||||
if on and mouseD.Target == game.Workspace.Terrain then
|
|
||||||
startCell = mouseHighlighter:GetPosition()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function mouseUp(_)
|
|
||||||
if processing then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local upCell = mouseHighlighter:GetPosition()
|
|
||||||
if startCell == upCell then
|
|
||||||
ConfirmFloodFill(upCell.x, upCell.y, upCell.z)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function getMaterial(x, y, z)
|
|
||||||
local material = GetCell(c, x, y, z)
|
|
||||||
return material
|
|
||||||
end
|
|
||||||
|
|
||||||
-- function startLoadingFrame() end
|
-- function startLoadingFrame() end
|
||||||
|
|
||||||
-- Load the progress bar to display when drawing a river.
|
-- Load the progress bar to display when drawing a river.
|
||||||
-- text - Text to display.
|
-- text - Text to display.
|
||||||
function LoadProgressBar(text)
|
local function LoadProgressBar(text)
|
||||||
processing = true
|
processing = true
|
||||||
|
|
||||||
-- Start the progress bar.
|
-- Start the progress bar.
|
||||||
|
|
@ -597,31 +488,33 @@ function LoadProgressBar(text)
|
||||||
-- spin = false
|
-- spin = false
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local spinnerFrame = Instance.new "Frame"
|
local spinnerFrame = New "Frame" {
|
||||||
spinnerFrame.Name = "Spinner"
|
Name = "Spinner",
|
||||||
spinnerFrame.Size = UDim2.new(0, 80, 0, 80)
|
Size = UDim2.new(0, 80, 0, 80),
|
||||||
spinnerFrame.Position = UDim2.new(0.5, -40, 0.5, -55)
|
Position = UDim2.new(0.5, -40, 0.5, -55),
|
||||||
spinnerFrame.BackgroundTransparency = 1
|
BackgroundTransparency = 1,
|
||||||
spinnerFrame.Parent = progressBar
|
Parent = progressBar,
|
||||||
|
}
|
||||||
|
|
||||||
local spinnerIcons = {}
|
local spinnerIcons = {}
|
||||||
local spinnerNum = 1
|
local spinnerNum = 1
|
||||||
while spinnerNum <= 8 do
|
while spinnerNum <= 8 do
|
||||||
local spinnerImage = Instance.new "ImageLabel"
|
local spinnerImage = New "ImageLabel" {
|
||||||
spinnerImage.Name = "Spinner" .. spinnerNum
|
Name = "Spinner" .. spinnerNum,
|
||||||
spinnerImage.Size = UDim2.new(0, 16, 0, 16)
|
Size = UDim2.new(0, 16, 0, 16),
|
||||||
spinnerImage.Position = UDim2.new(
|
Position = UDim2.new(
|
||||||
0.5 + 0.3 * math.cos(math.rad(45 * spinnerNum)),
|
0.5 + 0.3 * math.cos(math.rad(45 * spinnerNum)),
|
||||||
-8,
|
-8,
|
||||||
0.5 + 0.3 * math.sin(math.rad(45 * spinnerNum)),
|
0.5 + 0.3 * math.sin(math.rad(45 * spinnerNum)),
|
||||||
-8
|
-8
|
||||||
)
|
),
|
||||||
spinnerImage.BackgroundTransparency = 1
|
BackgroundTransparency = 1,
|
||||||
spinnerImage.Image = "http://banland.xyz/asset?id=45880710"
|
Image = "http://banland.xyz/asset?id=45880710",
|
||||||
spinnerImage.Parent = spinnerFrame
|
Parent = spinnerFrame,
|
||||||
|
}
|
||||||
|
|
||||||
spinnerIcons[spinnerNum] = spinnerImage
|
spinnerIcons[spinnerNum] = spinnerImage
|
||||||
spinnerNum = spinnerNum + 1
|
spinnerNum += 1
|
||||||
end
|
end
|
||||||
|
|
||||||
--Make it spin
|
--Make it spin
|
||||||
|
|
@ -648,7 +541,7 @@ function LoadProgressBar(text)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Unload the progress bar.
|
-- Unload the progress bar.
|
||||||
function UnloadProgressBar()
|
local function UnloadProgressBar()
|
||||||
processing = false
|
processing = false
|
||||||
|
|
||||||
if progressBar then
|
if progressBar then
|
||||||
|
|
@ -663,36 +556,68 @@ function UnloadProgressBar()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function breadthFill(x, y, z)
|
local function floodFill(x, y, z)
|
||||||
local yDepthChecks = doBreadthFill(x, y, z)
|
LoadProgressBar "Processing"
|
||||||
while yDepthChecks and #yDepthChecks > 0 do
|
breadthFill(x, y, z)
|
||||||
local newYChecks = {}
|
UnloadProgressBar()
|
||||||
for i = 1, #yDepthChecks do
|
ChangeHistoryService:SetWaypoint "FloodFill"
|
||||||
local currYDepthChecks = doBreadthFill(
|
end
|
||||||
yDepthChecks[i].xPos,
|
|
||||||
yDepthChecks[i].yPos,
|
|
||||||
yDepthChecks[i].zPos
|
|
||||||
)
|
|
||||||
|
|
||||||
if not processing then
|
-- Function used when we try and flood fill. Prompts the user first.
|
||||||
return
|
-- Will not show if disabled or terrain is being processed.
|
||||||
end
|
local function ConfirmFloodFill(x, y, z)
|
||||||
|
-- Only do if something isn't already being processed.
|
||||||
|
if processing then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
if currYDepthChecks and #currYDepthChecks > 0 then
|
processing = true
|
||||||
for j = 1, #currYDepthChecks do
|
if ConfirmationPopupObject then
|
||||||
table.insert(newYChecks, {
|
return
|
||||||
xPos = currYDepthChecks[j].xPos,
|
end
|
||||||
yPos = currYDepthChecks[j].yPos,
|
|
||||||
zPos = currYDepthChecks[j].zPos,
|
ConfirmationPopupObject = ConfirmationPopup.Create(
|
||||||
})
|
"Flood Fill At Selected Location?",
|
||||||
end
|
"This operation may take some time.",
|
||||||
end
|
"Fill",
|
||||||
|
"Cancel",
|
||||||
|
function()
|
||||||
|
ConfirmationPopupObject:Clear()
|
||||||
|
ConfirmationPopupObject = nil
|
||||||
|
floodFill(x, y, z)
|
||||||
|
ConfirmationPopupObject = nil
|
||||||
|
end,
|
||||||
|
function()
|
||||||
|
ConfirmationPopupObject:Clear()
|
||||||
|
ConfirmationPopupObject = nil
|
||||||
|
processing = false
|
||||||
end
|
end
|
||||||
yDepthChecks = newYChecks
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
function mouseDown(mouseD)
|
||||||
|
if on and mouseD.Target == game.Workspace.Terrain then
|
||||||
|
startCell = mouseHighlighter:GetPosition()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function doBreadthFill(x, y, z)
|
function mouseUp(_)
|
||||||
|
if processing then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local upCell = mouseHighlighter:GetPosition()
|
||||||
|
if startCell == upCell then
|
||||||
|
ConfirmFloodFill(upCell.x, upCell.y, upCell.z)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function getMaterial(x, y, z)
|
||||||
|
local material = GetCell(c, x, y, z)
|
||||||
|
return material
|
||||||
|
end
|
||||||
|
|
||||||
|
local function doBreadthFill(x, y, z)
|
||||||
if getMaterial(x, y, z) ~= emptyMaterial then
|
if getMaterial(x, y, z) ~= emptyMaterial then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
@ -735,7 +660,36 @@ function doBreadthFill(x, y, z)
|
||||||
return yDepthChecks
|
return yDepthChecks
|
||||||
end
|
end
|
||||||
|
|
||||||
function cellInTerrain(x, y, z)
|
function breadthFill(x, y, z)
|
||||||
|
local yDepthChecks = doBreadthFill(x, y, z)
|
||||||
|
while yDepthChecks and #yDepthChecks > 0 do
|
||||||
|
local newYChecks = {}
|
||||||
|
for i = 1, #yDepthChecks do
|
||||||
|
local currYDepthChecks = doBreadthFill(
|
||||||
|
yDepthChecks[i].xPos,
|
||||||
|
yDepthChecks[i].yPos,
|
||||||
|
yDepthChecks[i].zPos
|
||||||
|
)
|
||||||
|
|
||||||
|
if
|
||||||
|
not (processing and currYDepthChecks and #currYDepthChecks > 0)
|
||||||
|
then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
for j = 1, #currYDepthChecks do
|
||||||
|
table.insert(newYChecks, {
|
||||||
|
xPos = currYDepthChecks[j].xPos,
|
||||||
|
yPos = currYDepthChecks[j].yPos,
|
||||||
|
zPos = currYDepthChecks[j].zPos,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
yDepthChecks = newYChecks
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function cellInTerrain(x, y, z)
|
||||||
if x < c.MaxExtents.Min.X or x >= c.MaxExtents.Max.X then
|
if x < c.MaxExtents.Min.X or x >= c.MaxExtents.Max.X then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
@ -811,8 +765,7 @@ end
|
||||||
On = function()
|
On = function()
|
||||||
if not c then
|
if not c then
|
||||||
return
|
return
|
||||||
end
|
elseif this then
|
||||||
if this then
|
|
||||||
this:Activate(true)
|
this:Activate(true)
|
||||||
end
|
end
|
||||||
if toolbarbutton then
|
if toolbarbutton then
|
||||||
|
|
@ -858,25 +811,27 @@ dragBar, containerFrame, helpFrame, closeEvent = RbxGui.CreatePluginFrame(
|
||||||
)
|
)
|
||||||
dragBar.Visible = false
|
dragBar.Visible = false
|
||||||
|
|
||||||
helpFrame.Size = UDim2.new(0, 200, 0, 190)
|
Hydrate(helpFrame) {
|
||||||
|
Size = UDim2.new(0, 200, 0, 190),
|
||||||
local textHelp = Instance.new "TextLabel"
|
-- "This will be pdfs in 2024" - Heliodex
|
||||||
textHelp.Name = "TextHelp"
|
New "TextLabel" {
|
||||||
textHelp.Font = Enum.Font.ArialBold
|
Name = "TextHelp",
|
||||||
textHelp.FontSize = Enum.FontSize.Size12
|
Font = Enum.Font.ArialBold,
|
||||||
textHelp.TextColor3 = Color3.new(1, 1, 1)
|
FontSize = Enum.FontSize.Size12,
|
||||||
textHelp.Size = UDim2.new(1, -6, 1, -6)
|
TextColor3 = Color3.new(1, 1, 1),
|
||||||
textHelp.Position = UDim2.new(0, 3, 0, 3)
|
Size = UDim2.new(1, -6, 1, -6),
|
||||||
textHelp.TextXAlignment = Enum.TextXAlignment.Left
|
Position = UDim2.new(0, 3, 0, 3),
|
||||||
textHelp.TextYAlignment = Enum.TextYAlignment.Top
|
TextXAlignment = Enum.TextXAlignment.Left,
|
||||||
textHelp.BackgroundTransparency = 1
|
TextYAlignment = Enum.TextYAlignment.Top,
|
||||||
textHelp.TextWrap = true
|
BackgroundTransparency = 1,
|
||||||
textHelp.Text = [[
|
TextWrap = true,
|
||||||
|
Text = [[
|
||||||
Quickly replace empty terrain cells with a selected material. Clicking the mouse will cause any empty terrain cells around the point clicked to be filled with the current material, and will also spread to surrounding empty cells (including any empty cells below, but not above).
|
Quickly replace empty terrain cells with a selected material. Clicking the mouse will cause any empty terrain cells around the point clicked to be filled with the current material, and will also spread to surrounding empty cells (including any empty cells below, but not above).
|
||||||
|
|
||||||
Simply click on a different material to fill with that material. The floating paint bucket and cube indicate where filling will start.
|
Simply click on a different material to fill with that material. The floating paint bucket and cube indicate where filling will start.
|
||||||
]]
|
]],
|
||||||
textHelp.Parent = helpFrame
|
},
|
||||||
|
}
|
||||||
|
|
||||||
closeEvent.Event:connect(function()
|
closeEvent.Event:connect(function()
|
||||||
Off()
|
Off()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue