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
|
||||
while game == nil do
|
||||
--!strict
|
||||
while not game do
|
||||
wait()
|
||||
end
|
||||
|
||||
local ChangeHistoryService = game:GetService "ChangeHistoryService"
|
||||
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-
|
||||
---------------
|
||||
|
|
@ -147,18 +153,20 @@ end)
|
|||
|
||||
terrainHelpFrame.Size = UDim2.new(0, 300, 0, 350)
|
||||
|
||||
local terrainHelpText = Instance.new "TextLabel"
|
||||
terrainHelpText.Name = "HelpText"
|
||||
terrainHelpText.Font = Enum.Font.ArialBold
|
||||
terrainHelpText.FontSize = Enum.FontSize.Size12
|
||||
terrainHelpText.TextColor3 = Color3.new(227 / 255, 227 / 255, 227 / 255)
|
||||
terrainHelpText.TextXAlignment = Enum.TextXAlignment.Left
|
||||
terrainHelpText.TextYAlignment = Enum.TextYAlignment.Top
|
||||
terrainHelpText.Position = UDim2.new(0, 4, 0, 4)
|
||||
terrainHelpText.Size = UDim2.new(1, -8, 0, 157)
|
||||
terrainHelpText.BackgroundTransparency = 1
|
||||
terrainHelpText.TextWrap = true
|
||||
terrainHelpText.Text = [[Create terrain with hills, water.
|
||||
local function helpText()
|
||||
return New "TextLabel" {
|
||||
Font = Enum.Font.ArialBold,
|
||||
FontSize = Enum.FontSize.Size12,
|
||||
TextColor3 = Color3.new(227 / 255, 227 / 255, 227 / 255),
|
||||
TextXAlignment = Enum.TextXAlignment.Left,
|
||||
TextYAlignment = Enum.TextYAlignment.Top,
|
||||
BackgroundTransparency = 1,
|
||||
TextWrap = true,
|
||||
Parent = terrainHelpFrame,
|
||||
}
|
||||
end
|
||||
|
||||
local helpText1 = [[Create terrain with hills, water.
|
||||
X-Offset and Z-Offset:
|
||||
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.
|
||||
|
|
@ -170,13 +178,7 @@ Length: Terrain size in the Z direction
|
|||
Amplitude:
|
||||
Maximum height of hills.
|
||||
]]
|
||||
terrainHelpText.Parent = terrainHelpFrame
|
||||
|
||||
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:
|
||||
local helpText2 = [[Frequency:
|
||||
How often hills are made.
|
||||
|
||||
Base Height:
|
||||
|
|
@ -185,21 +187,34 @@ How high the base of terrain should be.
|
|||
Water Height:
|
||||
How high water should be. Terrain will overwrite water.
|
||||
]]
|
||||
helpSecondText.Parent = terrainHelpText
|
||||
|
||||
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 = [[
|
||||
|
||||
local helpText3 = [[
|
||||
|
||||
Generate Button:
|
||||
Create the terrain.
|
||||
|
||||
Clear Button:
|
||||
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.
|
||||
-- A highlighter is a open, rectuangular area displayed in 3D.
|
||||
|
|
@ -225,21 +240,22 @@ function Highlighter.Create(_, ID, color)
|
|||
highlighter.z = 0
|
||||
|
||||
-- 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.selectionPart = New "Part" {
|
||||
Name = "SelectionPart",
|
||||
Archivable = false,
|
||||
Transparency = 1,
|
||||
Anchored = true,
|
||||
Locked = true,
|
||||
CanCollide = false,
|
||||
FormFactor = Enum.FormFactor.Custom,
|
||||
}
|
||||
|
||||
highlighter.selectionBox = Instance.new "SelectionBox"
|
||||
highlighter.selectionBox.Name = "box" .. ID
|
||||
|
||||
highlighter.selectionBox.Archivable = false
|
||||
highlighter.selectionBox.Color = color
|
||||
highlighter.selectionBox.Adornee = highlighter.selectionPart
|
||||
highlighter.selectionBox = New "SelectionBox" {
|
||||
Name = "box" .. ID,
|
||||
Archivable = false,
|
||||
Color = color,
|
||||
Adornee = highlighter.selectionPart,
|
||||
}
|
||||
setmetatable(highlighter, Highlighter)
|
||||
|
||||
return highlighter
|
||||
|
|
@ -257,7 +273,7 @@ end
|
|||
|
||||
-- Update where the highlighter is displayed.
|
||||
-- cellPos - Where to display the highlighter, in cells.
|
||||
function Highlighter:UpdatePosition(cellPos)
|
||||
function Highlighter:UpdatePosition(cellPos: Vector3)
|
||||
if not cellPos then
|
||||
self:DisablePreview()
|
||||
return
|
||||
|
|
@ -269,17 +285,20 @@ function Highlighter:UpdatePosition(cellPos)
|
|||
self.y = cellPos.y
|
||||
self.z = cellPos.z
|
||||
|
||||
local width, length, height =
|
||||
self.width :: number, self.length :: number, self.height :: number
|
||||
|
||||
local lowVec = CellCenterToWorld(
|
||||
c,
|
||||
cellPos.x - self.width / 2,
|
||||
cellPos.x - width / 2,
|
||||
cellPos.y - 1,
|
||||
cellPos.z - self.length / 2
|
||||
cellPos.z - length / 2
|
||||
)
|
||||
local highVec = CellCenterToWorld(
|
||||
c,
|
||||
cellPos.x + self.width / 2,
|
||||
cellPos.y + self.height,
|
||||
cellPos.z + self.length / 2
|
||||
cellPos.x + width / 2,
|
||||
cellPos.y + height,
|
||||
cellPos.z + length / 2
|
||||
)
|
||||
regionToSelect = Region3.new(lowVec, highVec)
|
||||
|
||||
|
|
@ -292,37 +311,17 @@ end
|
|||
-- length - Length of the area (z direction)
|
||||
-- width - Width of the area (x 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.width = width
|
||||
self.height = height
|
||||
self:UpdatePosition(Vector3.new(self.x, self.y, self.z))
|
||||
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.
|
||||
-- name - Name to use for the slider.
|
||||
-- pos - Position to display the slider at.
|
||||
|
|
@ -333,7 +332,7 @@ end
|
|||
-- Return:
|
||||
-- sliderGui - Slider gui object.
|
||||
-- sliderPosition - Object that can set the slider value.
|
||||
function CreateStandardSlider(
|
||||
local function CreateStandardSlider(
|
||||
name,
|
||||
pos,
|
||||
lengthBarPos,
|
||||
|
|
@ -345,21 +344,24 @@ function CreateStandardSlider(
|
|||
local sliderGui, sliderPosition =
|
||||
RbxGui.CreateSlider(steps, 0, UDim2.new(0, 0, 0, 0))
|
||||
|
||||
sliderGui.Name = name
|
||||
sliderGui.Parent = parent
|
||||
sliderGui.Position = pos
|
||||
sliderGui.Size = UDim2.new(1, 0, 0, 20)
|
||||
local lengthBar = sliderGui:FindFirstChild "Bar"
|
||||
lengthBar.Size = UDim2.new(1, -21, 0, 5)
|
||||
lengthBar.Position = lengthBarPos
|
||||
Hydrate(sliderGui) {
|
||||
Name = name,
|
||||
Parent = parent,
|
||||
Position = pos,
|
||||
Size = UDim2.new(1, 0, 0, 20),
|
||||
}
|
||||
Hydrate(sliderGui.Bar) {
|
||||
Size = UDim2.new(1, -21, 0, 5),
|
||||
Position = lengthBarPos,
|
||||
}
|
||||
|
||||
if nil ~= funcOnChange then
|
||||
if funcOnChange then
|
||||
sliderPosition.Changed:connect(function()
|
||||
funcOnChange(sliderPosition)
|
||||
end)
|
||||
end
|
||||
|
||||
if nil ~= initValue then
|
||||
if initValue then
|
||||
sliderPosition.Value = initValue
|
||||
end
|
||||
|
||||
|
|
@ -390,44 +392,6 @@ end
|
|||
-- return dropdown, updateSelection
|
||||
-- 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 = {
|
||||
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.
|
||||
|
|
@ -437,30 +401,31 @@ local cancelValues = {
|
|||
|
||||
-- Load the progress bar to display when drawing a river.
|
||||
-- text - Text to display.
|
||||
function LoadProgressBar(text)
|
||||
if cancelValues.progressBar == nil 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
|
||||
local function LoadProgressBar(text)
|
||||
if cancelValues.progressBar then
|
||||
print "Tried to start the progress bar when it was already running."
|
||||
return
|
||||
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
|
||||
|
||||
-- Unload the progress bar.
|
||||
function UnloadProgressBar()
|
||||
local function UnloadProgressBar()
|
||||
cancelValues.isDrawing = false
|
||||
cancelValues.cancelActions = false
|
||||
|
||||
|
|
@ -520,8 +485,8 @@ offsetZSliderPosition.Value = (terrainOptions.zpos + 252) / 4 + 1
|
|||
--FUNCTION DEFINITIONS-
|
||||
-----------------------
|
||||
|
||||
--makes a column of blocks from 1 up to height at location (x,z) in cluster c
|
||||
function coordHeight(x, z, height)
|
||||
-- makes a column of blocks from 1 up to height at location (x,z) in cluster c
|
||||
local function coordHeight(x, z, height)
|
||||
SetCells(
|
||||
c,
|
||||
Region3int16.new(
|
||||
|
|
@ -534,10 +499,10 @@ function coordHeight(x, z, height)
|
|||
)
|
||||
end
|
||||
|
||||
--makes a heightmap for a layer of mountains (width x depth)
|
||||
--with a width frequency wf and depthfrequency df (width should be divisible by wf, depth should be divisible by df) (for unsquished results, width/wf = depth/df)
|
||||
--with a range of amplitudes between 0 and a
|
||||
function mountLayer(width, depth, wf, df, a)
|
||||
-- makes a heightmap for a layer of mountains (width x depth)
|
||||
-- with a width frequency wf and depthfrequency df (width should be divisible by wf, depth should be divisible by df) (for unsquished results, width/wf = depth/df)
|
||||
-- with a range of amplitudes between 0 and a
|
||||
local function mountLayer(width, depth, wf, df, a)
|
||||
local heightmap = {}
|
||||
for i = 0, width - 1 do
|
||||
heightmap[i] = {}
|
||||
|
|
@ -599,8 +564,8 @@ function mountLayer(width, depth, wf, df, a)
|
|||
return heightmap
|
||||
end
|
||||
|
||||
--makes a shell around block at coordinate x, z using heightmap
|
||||
function makeShell(x, z, heightmap, shellheightmap)
|
||||
-- makes a shell around block at coordinate x, z using heightmap
|
||||
local function makeShell(x, z, heightmap, shellheightmap)
|
||||
local originalheight = heightmap[x][z]
|
||||
for i = x - 1, x + 1 do
|
||||
for k = z - 1, z + 1 do
|
||||
|
|
@ -628,13 +593,13 @@ end
|
|||
-- 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.
|
||||
-- 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 cameraPos = Vector3.new(0, 400, 1600)
|
||||
local cameraFocus = Vector3.new(0, height * 4, 0)
|
||||
|
||||
-- Nothing set so use the default.
|
||||
if nil ~= centerX then
|
||||
if centerX then
|
||||
local scale = 0
|
||||
local lengthScale = 0
|
||||
local widthScale = 0
|
||||
|
|
@ -657,11 +622,7 @@ function SetCamera(centerX, centerZ, length, width, height)
|
|||
widthScale = 0.7
|
||||
end
|
||||
|
||||
if widthScale > lengthScale then
|
||||
scale = widthScale
|
||||
else
|
||||
scale = lengthScale
|
||||
end
|
||||
scale = widthScale > lengthScale and widthScale or lengthScale
|
||||
|
||||
local distance = Vector3.new(0, (200 * scale) + 200, (1100 * scale))
|
||||
cameraPos =
|
||||
|
|
@ -675,12 +636,11 @@ function SetCamera(centerX, centerZ, length, width, height)
|
|||
end
|
||||
|
||||
-- Create terrain based on the current properties.
|
||||
function GenerateTerrain()
|
||||
local function GenerateTerrain()
|
||||
toolbarbutton:SetActive(false)
|
||||
|
||||
generateOptions = terrainOptions:Clone()
|
||||
|
||||
-- Turn off the plugin
|
||||
Off()
|
||||
|
||||
-- Create the progress bar that will track terrain creation completion.
|
||||
|
|
@ -977,37 +937,45 @@ end
|
|||
|
||||
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.
|
||||
-- Will not show if disabled or terrain is being processed.
|
||||
function ConfirmGenerateTerrain()
|
||||
local function ConfirmGenerateTerrain()
|
||||
-- Only do if something isn't already being processed.
|
||||
if nil == cancelValues.progressBar then
|
||||
if nil == ConfirmationPopupObject then
|
||||
if not hideGenerateConformation then
|
||||
ConfirmationPopupObject = ConfirmationPopup.Create(
|
||||
"Generate Terrain?",
|
||||
"Generate",
|
||||
"Cancel",
|
||||
function()
|
||||
ClearConformation()
|
||||
GenerateTerrain()
|
||||
end,
|
||||
ClearConformation,
|
||||
function()
|
||||
hideGenerateConformation = not hideGenerateConformation
|
||||
return not hideGenerateConformation
|
||||
end
|
||||
)
|
||||
else
|
||||
GenerateTerrain()
|
||||
end
|
||||
end
|
||||
if cancelValues.progressBar or ConfirmationPopupObject then
|
||||
return
|
||||
elseif hideGenerateConformation then
|
||||
GenerateTerrain()
|
||||
return
|
||||
end
|
||||
|
||||
ConfirmationPopupObject = ConfirmationPopup.Create(
|
||||
"Generate Terrain?",
|
||||
"Generate",
|
||||
"Cancel",
|
||||
function()
|
||||
ClearConformation()
|
||||
GenerateTerrain()
|
||||
end,
|
||||
ClearConformation,
|
||||
function()
|
||||
hideGenerateConformation = not hideGenerateConformation
|
||||
return not hideGenerateConformation
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
-- Clears all terrain.
|
||||
-- Clearing is immediate.
|
||||
function ClearTerrain()
|
||||
local function ClearTerrain()
|
||||
toolbarbutton:SetActive(false)
|
||||
Off()
|
||||
|
||||
|
|
@ -1024,30 +992,29 @@ end
|
|||
|
||||
-- Function used by the clear button. Prompts the user first.
|
||||
-- Will not show if disabled or terrain is being processed.
|
||||
function ConfirmClearTerrain()
|
||||
local function ConfirmClearTerrain()
|
||||
-- Only do if something isn't already being processed.
|
||||
if nil == cancelValues.progressBar then
|
||||
if nil == ConfirmationPopupObject then
|
||||
if not hideClearConformation then
|
||||
ConfirmationPopupObject = ConfirmationPopup.Create(
|
||||
"Clear Terrain?",
|
||||
"Clear",
|
||||
"Cancel",
|
||||
function()
|
||||
ClearConformation()
|
||||
ClearTerrain()
|
||||
end,
|
||||
ClearConformation,
|
||||
function()
|
||||
hideClearConformation = not hideClearConformation
|
||||
return not hideClearConformation
|
||||
end
|
||||
)
|
||||
else
|
||||
ClearTerrain()
|
||||
end
|
||||
end
|
||||
if cancelValues.progressBar or ConfirmationPopupObject then
|
||||
return
|
||||
elseif hideClearConformation then
|
||||
ClearTerrain()
|
||||
return
|
||||
end
|
||||
|
||||
ConfirmationPopupObject = ConfirmationPopup.Create(
|
||||
"Clear Terrain?",
|
||||
"Clear",
|
||||
"Cancel",
|
||||
function()
|
||||
ClearConformation()
|
||||
ClearTerrain()
|
||||
end,
|
||||
ClearConformation,
|
||||
function()
|
||||
hideClearConformation = not hideClearConformation
|
||||
return not hideClearConformation
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
-- Used to create a highlighter.
|
||||
|
|
@ -1072,34 +1039,39 @@ function ConfirmationPopup.Create(
|
|||
confirmFunction,
|
||||
declineFunction
|
||||
)
|
||||
local popup = {}
|
||||
popup.confirmButton = nil -- Hold the button to confirm a choice.
|
||||
popup.declineButton = nil -- Hold the button to decline a choice.
|
||||
popup.confirmationFrame = nil -- Hold the conformation frame.
|
||||
popup.confirmationText = nil -- Hold the text label to display the conformation message.
|
||||
popup.confirmationHelpText = nil -- Hold the text label to display the conformation message help.
|
||||
local popup = {
|
||||
confirmButton = nil, -- Hold the button to confirm a choice.
|
||||
declineButton = nil, -- Hold the button to decline a choice.
|
||||
confirmationFrame = nil, -- Hold the conformation frame.
|
||||
confirmationText = nil, -- Hold the text label to display the conformation message.
|
||||
confirmationHelpText = nil, -- Hold the text label to display the conformation message help.
|
||||
}
|
||||
|
||||
popup.confirmationFrame = Instance.new "Frame"
|
||||
popup.confirmationFrame.Name = "ConfirmationFrame"
|
||||
popup.confirmationFrame.Size = UDim2.new(0, 280, 0, 140)
|
||||
popup.confirmationFrame.Position = UDim2.new(
|
||||
0.5,
|
||||
-popup.confirmationFrame.Size.X.Offset / 2,
|
||||
0.5,
|
||||
-popup.confirmationFrame.Size.Y.Offset / 2
|
||||
)
|
||||
popup.confirmationFrame.Style = Enum.FrameStyle.RobloxRound
|
||||
popup.confirmationFrame.Parent = g
|
||||
popup.confirmationFrame = New "Frame" {
|
||||
Name = "ConfirmationFrame",
|
||||
Size = UDim2.new(0, 280, 0, 140),
|
||||
Position = UDim2.new(
|
||||
0.5,
|
||||
-popup.confirmationFrame.Size.X.Offset / 2,
|
||||
0.5,
|
||||
-popup.confirmationFrame.Size.Y.Offset / 2
|
||||
),
|
||||
Style = Enum.FrameStyle.RobloxRound,
|
||||
Parent = g,
|
||||
}
|
||||
|
||||
popup.confirmLabel = CreateStandardLabel(
|
||||
"ConfirmLabel",
|
||||
UDim2.new(0, 0, 0, 15),
|
||||
UDim2.new(1, 0, 0, 24),
|
||||
confirmText,
|
||||
popup.confirmationFrame
|
||||
)
|
||||
popup.confirmLabel.FontSize = Enum.FontSize.Size18
|
||||
popup.confirmLabel.TextXAlignment = Enum.TextXAlignment.Center
|
||||
popup.confirmLabel = Hydrate(
|
||||
CreateStandardLabel(
|
||||
"ConfirmLabel",
|
||||
UDim2.new(0, 0, 0, 15),
|
||||
UDim2.new(1, 0, 0, 24),
|
||||
confirmText,
|
||||
popup.confirmationFrame
|
||||
)
|
||||
) {
|
||||
FontSize = Enum.FontSize.Size18,
|
||||
TextXAlignment = Enum.TextXAlignment.Center,
|
||||
}
|
||||
|
||||
-- Confirm
|
||||
popup.confirmButton = CreateStandardButton(
|
||||
|
|
@ -1126,19 +1098,19 @@ end
|
|||
|
||||
-- Clear the popup, free up assets.
|
||||
function ConfirmationPopup:Clear()
|
||||
if nil ~= self.confirmButton then
|
||||
if self.confirmButton then
|
||||
self.confirmButton.Parent = nil
|
||||
end
|
||||
|
||||
if nil ~= self.declineButton then
|
||||
if self.declineButton then
|
||||
self.declineButton.Parent = nil
|
||||
end
|
||||
|
||||
if nil ~= self.confirmationFrame then
|
||||
if self.confirmationFrame then
|
||||
self.confirmationFrame.Parent = nil
|
||||
end
|
||||
|
||||
if nil ~= self.confirmLabel then
|
||||
if self.confirmLabel then
|
||||
self.confirmLabel.Parent = nil
|
||||
end
|
||||
|
||||
|
|
@ -1163,7 +1135,8 @@ local widthLabel = CreateStandardLabel(
|
|||
"",
|
||||
terrainFrame
|
||||
)
|
||||
local _, _ --[[widthSliderGui, widthSliderPosition]] = CreateStandardSlider(
|
||||
-- local _, _ widthSliderGui, widthSliderPosition =
|
||||
CreateStandardSlider(
|
||||
"WidthSliderGui",
|
||||
UDim2.new(0, 1, 0, 108),
|
||||
UDim2.new(0, 10, 0.5, -2),
|
||||
|
|
@ -1184,7 +1157,8 @@ local lengthLabel = CreateStandardLabel(
|
|||
"",
|
||||
terrainFrame
|
||||
)
|
||||
local _, _ --[[lengthSliderGui, lengthSliderPosition]] = CreateStandardSlider(
|
||||
-- local _, _ lengthSliderGui, lengthSliderPosition =
|
||||
CreateStandardSlider(
|
||||
"LengthSliderGui",
|
||||
UDim2.new(0, 1, 0, 149),
|
||||
UDim2.new(0, 10, 0.5, -2),
|
||||
|
|
@ -1305,17 +1279,8 @@ CreateStandardButton(
|
|||
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.
|
||||
On = function()
|
||||
function On()
|
||||
if not c then
|
||||
return
|
||||
end
|
||||
|
|
@ -1326,7 +1291,7 @@ On = function()
|
|||
end
|
||||
|
||||
-- Run when the popup is deactivated.
|
||||
Off = function()
|
||||
function Off()
|
||||
toolbarbutton:SetActive(false)
|
||||
ClearConformation()
|
||||
on = false
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
while game == nil do
|
||||
while not game do
|
||||
wait()
|
||||
end
|
||||
|
||||
local ChangeHistoryService = game:GetService "ChangeHistoryService"
|
||||
local CoreGui = game:GetService "CoreGui"
|
||||
|
||||
local CreateStandardLabel = require "../Modules/Terrain/CreateStandardLabel"
|
||||
local New = require("../Modules/New").New
|
||||
|
||||
---------------
|
||||
--PLUGIN SETUP-
|
||||
---------------
|
||||
|
|
@ -96,19 +99,21 @@ function MouseHighlighter.Create(mouseUse)
|
|||
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.selectionPart = New "Part" {
|
||||
Name = "SelectionPart",
|
||||
Archivable = false,
|
||||
Transparency = 1,
|
||||
Anchored = true,
|
||||
Locked = true,
|
||||
CanCollide = false,
|
||||
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
|
||||
setmetatable(highlighter, MouseHighlighter)
|
||||
|
||||
|
|
@ -119,7 +124,7 @@ function MouseHighlighter.Create(mouseUse)
|
|||
-- Return:
|
||||
-- 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.
|
||||
PlaneIntersection = function(vectorPos)
|
||||
function PlaneIntersection(vectorPos)
|
||||
local currCamera = game.Workspace.CurrentCamera
|
||||
local startPos = Vector3.new(
|
||||
currCamera.CoordinateFrame.p.X,
|
||||
|
|
@ -147,7 +152,7 @@ function MouseHighlighter.Create(mouseUse)
|
|||
|
||||
-- Update where the highlighter is displayed.
|
||||
-- position - Where to display the highlighter, in world space.
|
||||
UpdatePosition = function(position)
|
||||
function UpdatePosition(position)
|
||||
if not position then
|
||||
return
|
||||
end
|
||||
|
|
@ -214,30 +219,6 @@ end
|
|||
local mouseHighlighter = MouseHighlighter.Create(mouse)
|
||||
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-
|
||||
------
|
||||
|
|
@ -372,7 +353,7 @@ mouse.Button1Down:connect(onClicked)
|
|||
mouseHighlighter.OnClicked = onClicked
|
||||
|
||||
-- Run when the popup is activated.
|
||||
On = function()
|
||||
function On()
|
||||
if not c then
|
||||
return
|
||||
end
|
||||
|
|
@ -383,7 +364,7 @@ On = function()
|
|||
end
|
||||
|
||||
-- Run when the popup is deactivated.
|
||||
Off = function()
|
||||
function Off()
|
||||
toolbarbutton:SetActive(false)
|
||||
on = false
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
while game == nil do
|
||||
while not game do
|
||||
wait()
|
||||
end
|
||||
|
||||
local ChangeHistoryService = game:GetService "ChangeHistoryService"
|
||||
local CoreGui = game:GetService "CoreGui"
|
||||
|
||||
local CreateStandardLabel = require "../Modules/Terrain/CreateStandardLabel"
|
||||
|
||||
-----------------
|
||||
--DEFAULT VALUES-
|
||||
-----------------
|
||||
|
|
@ -170,30 +172,6 @@ end
|
|||
-- Create the mouse movement highlighter.
|
||||
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-
|
||||
------
|
||||
|
|
@ -283,11 +261,10 @@ mouse.Button1Down:connect(onClicked)
|
|||
mouseHighlighter.OnClicked = onClicked
|
||||
|
||||
-- Run when the popup is activated.
|
||||
On = function()
|
||||
function On()
|
||||
if not c then
|
||||
return
|
||||
end
|
||||
if plugin then
|
||||
elseif plugin then
|
||||
plugin:Activate(true)
|
||||
end
|
||||
if toolbarbutton then
|
||||
|
|
@ -300,7 +277,7 @@ On = function()
|
|||
end
|
||||
|
||||
-- Run when the popup is deactivated.
|
||||
Off = function()
|
||||
function Off()
|
||||
on = false
|
||||
|
||||
if toolbarbutton then
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
while game == nil do
|
||||
while not game do
|
||||
wait()
|
||||
end
|
||||
|
||||
local ChangeHistoryService = game:GetService "ChangeHistoryService"
|
||||
local CoreGui = game:GetService "CoreGui"
|
||||
|
||||
local CreateStandardLabel = require "../Modules/Terrain/CreateStandardLabel"
|
||||
|
||||
---------------
|
||||
--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.
|
||||
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.
|
||||
-- position - Where to display the highlighter, in world space.
|
||||
function UpdatePosition(position)
|
||||
local function UpdatePosition(position)
|
||||
if not position then
|
||||
return
|
||||
end
|
||||
|
|
@ -204,6 +170,42 @@ function MouseHighlighter.Create(mouseUse)
|
|||
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
|
||||
end
|
||||
|
||||
|
|
@ -231,30 +233,6 @@ g.Parent = CoreGui
|
|||
-- UI gui load. Required for sliders.
|
||||
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.
|
||||
-- name - Name to use for the slider.
|
||||
-- pos - Position to display the slider at.
|
||||
|
|
@ -639,7 +617,7 @@ mouse.Button1Up:connect(function()
|
|||
end)
|
||||
|
||||
-- Run when the popup is activated.
|
||||
On = function()
|
||||
function On()
|
||||
if not c then
|
||||
return
|
||||
end
|
||||
|
|
@ -651,7 +629,7 @@ On = function()
|
|||
end
|
||||
|
||||
-- Run when the popup is deactivated.
|
||||
Off = function()
|
||||
function Off()
|
||||
toolbarbutton:SetActive(false)
|
||||
on = false
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
while game == nil do
|
||||
while not game do
|
||||
wait()
|
||||
end
|
||||
|
||||
local ChangeHistoryService = game:GetService "ChangeHistoryService"
|
||||
local CoreGui = game:GetService "CoreGui"
|
||||
|
||||
-- local CreateStandardLabel = require "../Modules/Terrain/CreateStandardLabel"
|
||||
|
||||
---------------
|
||||
--PLUGIN SETUP-
|
||||
---------------
|
||||
|
|
@ -133,9 +135,7 @@ end
|
|||
function brush(x, y, z)
|
||||
if depth == 0 then
|
||||
return
|
||||
end
|
||||
|
||||
if depth > 0 then
|
||||
elseif depth > 0 then
|
||||
local findY = findLowPoint(x, y + depth, z)
|
||||
local yWithDepth = y + depth
|
||||
|
||||
|
|
@ -171,9 +171,7 @@ end
|
|||
function updatePreviewSelection(position)
|
||||
if not position then
|
||||
return
|
||||
end
|
||||
--if not mouse.Target then disablePreview() return end
|
||||
if depth == 0 then
|
||||
elseif depth == 0 then -- or not mouse.Target
|
||||
disablePreview()
|
||||
return
|
||||
end
|
||||
|
|
@ -307,21 +305,21 @@ function doFillCells(position, mouseDrag, needsCellPos)
|
|||
end
|
||||
|
||||
function mouseMoved()
|
||||
if on then
|
||||
if mousedown == true then
|
||||
if mousemoving then
|
||||
return
|
||||
end
|
||||
|
||||
mousemoving = true
|
||||
local currMousePos = Vector2.new(mouse.X, mouse.Y)
|
||||
local mouseDrag = currMousePos - lastMousePos
|
||||
doFillCells(mouse.Hit, mouseDrag, true)
|
||||
lastMousePos = currMousePos
|
||||
mousemoving = false
|
||||
if not on then
|
||||
return
|
||||
elseif mousedown == true then
|
||||
if mousemoving then
|
||||
return
|
||||
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
|
||||
updatePreviewSelection(mouse.Hit)
|
||||
end
|
||||
|
||||
-- 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
|
||||
|
||||
On = function()
|
||||
function On()
|
||||
if not c then
|
||||
return
|
||||
end
|
||||
if this then
|
||||
elseif this then
|
||||
this:Activate(true)
|
||||
end
|
||||
if toolbarbutton then
|
||||
|
|
@ -422,7 +419,7 @@ On = function()
|
|||
on = true
|
||||
end
|
||||
|
||||
Off = function()
|
||||
function Off()
|
||||
if toolbarbutton then
|
||||
toolbarbutton:SetActive(false)
|
||||
end
|
||||
|
|
@ -474,30 +471,6 @@ function CreateStandardDropdown(
|
|||
return dropdown, updateSelection
|
||||
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.
|
||||
-- name - Name to use for the slider.
|
||||
-- pos - Position to display the slider at.
|
||||
|
|
@ -546,6 +519,7 @@ local g = Instance.new "ScreenGui"
|
|||
g.Name = "TerrainBrushGui"
|
||||
g.Parent = CoreGui
|
||||
|
||||
local elevationFrame, elevationHelpFrame, elevationCloseEvent
|
||||
brushDragBar, elevationFrame, elevationHelpFrame, elevationCloseEvent =
|
||||
RbxGui.CreatePluginFrame(
|
||||
"Terrain Brush",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
while game == nil do
|
||||
--!strict
|
||||
while not game do
|
||||
wait()
|
||||
end
|
||||
|
||||
|
|
@ -47,9 +48,13 @@ local craterDragBar, craterFrame, craterHelpFrame, craterCloseEvent = nil
|
|||
--FUNCTION DEFINITIONS-
|
||||
-----------------------
|
||||
|
||||
--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
|
||||
function makeCrater(x, y, z, cr, cd)
|
||||
local function dist(x1, y1, x2, y2)
|
||||
return math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2))
|
||||
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 = {}
|
||||
for i = x - (cr + 1), x + (cr + 1) do
|
||||
heightmap[i] = {}
|
||||
|
|
@ -112,10 +117,6 @@ function makeCrater(x, y, z, cr, cd)
|
|||
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
|
||||
|
||||
mouse.Button1Down:connect(function()
|
||||
|
|
@ -139,11 +140,10 @@ mouse.Button1Down:connect(function()
|
|||
ChangeHistoryService:SetWaypoint "Crater"
|
||||
end)
|
||||
|
||||
On = function()
|
||||
function On()
|
||||
if not c then
|
||||
return
|
||||
end
|
||||
if this then
|
||||
elseif this then
|
||||
this:Activate(true)
|
||||
end
|
||||
if toolbarbutton then
|
||||
|
|
@ -155,7 +155,7 @@ On = function()
|
|||
on = true
|
||||
end
|
||||
|
||||
Off = function()
|
||||
function Off()
|
||||
if toolbarbutton then
|
||||
toolbarbutton:SetActive(false)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
while game == nil do
|
||||
--!strict
|
||||
while not game do
|
||||
wait()
|
||||
end
|
||||
|
||||
|
|
@ -272,11 +273,10 @@ mouse.Button1Down:connect(function()
|
|||
end
|
||||
end)
|
||||
|
||||
On = function()
|
||||
function On()
|
||||
if not c then
|
||||
return
|
||||
end
|
||||
if this then
|
||||
elseif this then
|
||||
this:Activate(true)
|
||||
end
|
||||
if toolbarbutton then
|
||||
|
|
@ -290,7 +290,7 @@ On = function()
|
|||
on = true
|
||||
end
|
||||
|
||||
Off = function()
|
||||
function Off()
|
||||
if toolbarbutton then
|
||||
toolbarbutton:SetActive(false)
|
||||
end
|
||||
|
|
@ -311,6 +311,7 @@ local g = Instance.new "ScreenGui"
|
|||
g.Name = "RoadGui"
|
||||
g.Parent = game:GetService "CoreGui"
|
||||
|
||||
local roadHelpFrame
|
||||
roadDragBar, roadFrame, roadHelpFrame, roadCloseEvent =
|
||||
RbxGui.CreatePluginFrame(
|
||||
"Roads",
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
while game == nil do
|
||||
while not game do
|
||||
wait()
|
||||
end
|
||||
|
||||
|
|
@ -12,6 +12,7 @@ local loaded = false
|
|||
local on = false
|
||||
|
||||
local On, Off
|
||||
local mouseDown, mouseUp, mouseMove
|
||||
|
||||
local this = PluginManager():CreatePlugin()
|
||||
local mouse = this:GetMouse()
|
||||
|
|
@ -82,29 +83,173 @@ local RbxUtil = LoadLibrary "RbxUtility"
|
|||
--FUNCTION DEFINITIONS-
|
||||
-----------------------
|
||||
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
|
||||
return
|
||||
end
|
||||
if #setCells <= 0 then
|
||||
return
|
||||
for i = 1, #setCells do
|
||||
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
|
||||
|
||||
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)
|
||||
return
|
||||
end
|
||||
|
|
@ -209,197 +354,122 @@ function setWaterDirection(mouseCellPos, setCells)
|
|||
)
|
||||
end
|
||||
end
|
||||
else
|
||||
for i = 1, #setCells do
|
||||
if setCells[i].xPos == initX then
|
||||
return
|
||||
end
|
||||
|
||||
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(
|
||||
c,
|
||||
setCells[i].xPos,
|
||||
setCells[i].yPos,
|
||||
setCells[i].zPos,
|
||||
mediumWaterForce,
|
||||
down
|
||||
right
|
||||
)
|
||||
elseif setCells[i].xPos == endX then
|
||||
elseif setCells[i].zPos > zMiddle then
|
||||
SetWaterCell(
|
||||
c,
|
||||
setCells[i].xPos,
|
||||
setCells[i].yPos,
|
||||
setCells[i].zPos,
|
||||
mediumWaterForce,
|
||||
up
|
||||
left
|
||||
)
|
||||
else
|
||||
if setCells[i].zPos < zMiddle then
|
||||
if setCells[i].xPos < xMiddle then
|
||||
SetWaterCell(
|
||||
c,
|
||||
setCells[i].xPos,
|
||||
setCells[i].yPos,
|
||||
setCells[i].zPos,
|
||||
mediumWaterForce,
|
||||
right
|
||||
down
|
||||
)
|
||||
elseif setCells[i].zPos > zMiddle then
|
||||
elseif setCells[i].xPos > xMiddle then
|
||||
SetWaterCell(
|
||||
c,
|
||||
setCells[i].xPos,
|
||||
setCells[i].yPos,
|
||||
setCells[i].zPos,
|
||||
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
|
||||
|
||||
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
|
||||
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 lowVec =
|
||||
|
|
@ -415,7 +485,7 @@ function calculateRegion(mouseR)
|
|||
)
|
||||
end
|
||||
|
||||
function createSelection(mouseS, massSelection)
|
||||
local function createSelection(mouseS, massSelection)
|
||||
currSelectionUpdate, currSelectionDestroy = RbxUtil.SelectTerrainRegion(
|
||||
calculateRegion(mouseS),
|
||||
BrickColor.new "Lime green",
|
||||
|
|
@ -424,24 +494,19 @@ function createSelection(mouseS, massSelection)
|
|||
)
|
||||
end
|
||||
|
||||
function updateSelection(mouseS)
|
||||
local function updateSelection(mouseS)
|
||||
if not currSelectionUpdate then
|
||||
createSelection(mouseS, radius > 4)
|
||||
else
|
||||
currSelectionUpdate(
|
||||
calculateRegion(mouseS),
|
||||
BrickColor.new "Lime green"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
function setPositionDirectionality()
|
||||
if nil == lastCell then
|
||||
return
|
||||
end
|
||||
currSelectionUpdate(calculateRegion(mouseS), BrickColor.new "Lime green")
|
||||
end
|
||||
|
||||
-- no dragging occured, lets set our water to be stagnant or be a waterfall
|
||||
if lastCell and not lastLastCell then
|
||||
local function setPositionDirectionality()
|
||||
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)
|
||||
if directionIsDown(nil, lastCell) then
|
||||
paintWaterfall(cellsToSet)
|
||||
|
|
@ -476,23 +541,14 @@ function setPositionDirectionality()
|
|||
local direction
|
||||
|
||||
if absX > absY and absX > absZ then
|
||||
if overallDirection.X > 0 then
|
||||
direction = Enum.WaterDirection.X
|
||||
else
|
||||
direction = Enum.WaterDirection.NegX
|
||||
end
|
||||
direction = overallDirection.X > 0 and Enum.WaterDirection.X
|
||||
or Enum.WaterDirection.NegX
|
||||
elseif absY > absX and absY > absZ then
|
||||
if overallDirection.Y > 0 then
|
||||
direction = Enum.WaterDirection.Y
|
||||
else
|
||||
direction = Enum.WaterDirection.NegY
|
||||
end
|
||||
direction = overallDirection.Y > 0 and Enum.WaterDirection.Y
|
||||
or Enum.WaterDirection.NegY
|
||||
elseif absZ > absX and absZ > absY then
|
||||
if overallDirection.Z > 0 then
|
||||
direction = Enum.WaterDirection.Z
|
||||
else
|
||||
direction = Enum.WaterDirection.NegZ
|
||||
end
|
||||
direction = overallDirection.Z > 0 and Enum.WaterDirection.Z
|
||||
or Enum.WaterDirection.NegZ
|
||||
end
|
||||
|
||||
if not direction then -- this should never be hit, but just in case
|
||||
|
|
@ -512,24 +568,27 @@ function setPositionDirectionality()
|
|||
end
|
||||
|
||||
function mouseDown(mouseD)
|
||||
if on and mouseD.Target == game.Workspace.Terrain then
|
||||
dragging = true
|
||||
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
|
||||
if not (on and mouseD.Target == game.Workspace.Terrain) then
|
||||
return
|
||||
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
|
||||
|
||||
function mouseUp(_)
|
||||
|
|
@ -547,96 +606,29 @@ function mouseUp(_)
|
|||
end
|
||||
|
||||
function mouseMove(mouseM)
|
||||
if on then
|
||||
if mouseM.Target == game.Workspace.Terrain then
|
||||
if lastCell ~= WorldToCellPreferSolid(c, mouseM.Hit.p) then
|
||||
updateSelection(mouseM)
|
||||
local newCell = WorldToCellPreferSolid(c, mouseM.Hit.p)
|
||||
|
||||
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()
|
||||
if not on then
|
||||
return
|
||||
elseif mouseM.Target == game.Workspace.Terrain then
|
||||
if lastCell == WorldToCellPreferSolid(c, mouseM.Hit.p) then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
updateSelection(mouseM)
|
||||
local newCell = WorldToCellPreferSolid(c, mouseM.Hit.p)
|
||||
|
||||
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
|
||||
if not dragging then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local viableCells = getAffectedCells(toCell)
|
||||
if not viableCells then
|
||||
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
|
||||
-- local painting = true
|
||||
paint(newCell)
|
||||
if lastCell and newCell and (lastCell - newCell).magnitude > 1 then
|
||||
paintBetweenPoints(lastCell, newCell)
|
||||
end
|
||||
lastLastCell = lastCell
|
||||
lastCell = newCell
|
||||
-- painting = false
|
||||
else
|
||||
destroySelection()
|
||||
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
|
||||
|
||||
function destroySelection()
|
||||
|
|
@ -649,31 +641,33 @@ function destroySelection()
|
|||
end
|
||||
end
|
||||
|
||||
function moveTowardsGoal(direction, currPos, goalPos, currCell)
|
||||
if currPos ~= goalPos then
|
||||
if currPos < goalPos then
|
||||
if direction == "X" then
|
||||
currCell = Vector3.new(currCell.X + 1, currCell.Y, currCell.Z)
|
||||
elseif direction == "Y" then
|
||||
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
|
||||
elseif currPos > goalPos then
|
||||
if direction == "X" then
|
||||
currCell = Vector3.new(currCell.X - 1, currCell.Y, currCell.Z)
|
||||
elseif direction == "Y" then
|
||||
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
|
||||
local function moveTowardsGoal(direction: string, currPos, goalPos, currCell)
|
||||
if currPos == goalPos then
|
||||
return currCell
|
||||
end
|
||||
|
||||
if currPos < goalPos then
|
||||
if direction == "X" then
|
||||
currCell = Vector3.new(currCell.X + 1, currCell.Y, currCell.Z)
|
||||
elseif direction == "Y" then
|
||||
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
|
||||
elseif currPos > goalPos then
|
||||
if direction == "X" then
|
||||
currCell = Vector3.new(currCell.X - 1, currCell.Y, currCell.Z)
|
||||
elseif direction == "Y" then
|
||||
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
|
||||
|
||||
return currCell
|
||||
end
|
||||
|
||||
function interpolateOneDim(direction, currPos, goalPos, currCell)
|
||||
local function interpolateOneDim(direction, currPos, goalPos, currCell)
|
||||
if currPos ~= goalPos then
|
||||
currCell = moveTowardsGoal(direction, currPos, goalPos, currCell)
|
||||
paint(currCell)
|
||||
|
|
@ -696,7 +690,7 @@ function paintBetweenPoints(lastCellP, newCell)
|
|||
end
|
||||
end
|
||||
|
||||
On = function()
|
||||
function On()
|
||||
if not c then
|
||||
return
|
||||
end
|
||||
|
|
@ -707,7 +701,7 @@ On = function()
|
|||
on = true
|
||||
end
|
||||
|
||||
Off = function()
|
||||
function Off()
|
||||
toolbarbutton:SetActive(false)
|
||||
|
||||
destroySelection()
|
||||
|
|
@ -724,6 +718,7 @@ local g = Instance.new "ScreenGui"
|
|||
g.Name = "MaterialPainterGui"
|
||||
g.Parent = CoreGui
|
||||
|
||||
local containerFrame
|
||||
dragBar, containerFrame, helpFrame, closeEvent = RbxGui.CreatePluginFrame(
|
||||
"Material Brush",
|
||||
UDim2.new(0, 163, 0, 285),
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
while game == nil do
|
||||
while not game do
|
||||
wait()
|
||||
end
|
||||
|
||||
local ContentProvider = game:GetService "ContentProvider"
|
||||
local CoreGui = game:GetService "CoreGui"
|
||||
local News = require "../Modules/New"
|
||||
local New = News.New
|
||||
local Hydrate = News.Hydrate
|
||||
|
||||
---------------
|
||||
--PLUGIN SETUP-
|
||||
|
|
@ -113,11 +116,10 @@ function hideLoadingDialog()
|
|||
currStampGui.LoadingFrame.Visible = false
|
||||
end
|
||||
|
||||
local partSelected = function(name, id, terrainShape)
|
||||
if not id then
|
||||
return
|
||||
end
|
||||
if not name then
|
||||
local stampCon
|
||||
|
||||
local function partSelected(name, id, terrainShape)
|
||||
if not (id and name) then
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -146,21 +148,23 @@ local partSelected = function(name, id, terrainShape)
|
|||
and clusterTag:isA "Vector3Value"
|
||||
and clusterTag.Value.X == 17
|
||||
then
|
||||
local waterForceTag = Instance.new("StringValue", lastStampModel)
|
||||
waterForceTag.Name = "WaterForceTag"
|
||||
waterForceTag.Value = waterForceAndDirection[1]
|
||||
|
||||
local waterForceDirectionTag =
|
||||
Instance.new("StringValue", lastStampModel)
|
||||
waterForceDirectionTag.Name = "WaterForceDirectionTag"
|
||||
waterForceDirectionTag.Value = waterForceAndDirection[2]
|
||||
New "StringValue" {
|
||||
Name = "WaterForceTag",
|
||||
Value = waterForceAndDirection[1],
|
||||
Parent = lastStampModel,
|
||||
}
|
||||
New "StringValue" {
|
||||
Name = "WaterForceDirectionTag",
|
||||
Value = waterForceAndDirection[2],
|
||||
Parent = lastStampModel,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
setupStamper(lastStampModel, mouse)
|
||||
setupStamper(lastStampModel)
|
||||
end
|
||||
|
||||
function updateWaterInfo()
|
||||
local function updateWaterInfo()
|
||||
if stampControl then
|
||||
stampControl.Destroy()
|
||||
end
|
||||
|
|
@ -177,70 +181,203 @@ function updateWaterInfo()
|
|||
local clusterTag = lastStampModel:FindFirstChild "ClusterMaterial"
|
||||
-- we are going to stamp water, send info to stamper about this
|
||||
if clusterTag and clusterTag.Value.X == 17 then
|
||||
local waterForceTag = Instance.new("StringValue", lastStampModel)
|
||||
waterForceTag.Name = "WaterForceTag"
|
||||
waterForceTag.Value = waterForceAndDirection[1]
|
||||
|
||||
local waterForceDirectionTag =
|
||||
Instance.new("StringValue", lastStampModel)
|
||||
waterForceDirectionTag.Name = "WaterForceDirectionTag"
|
||||
waterForceDirectionTag.Value = waterForceAndDirection[2]
|
||||
New "StringValue" {
|
||||
Name = "WaterForceTag",
|
||||
Value = waterForceAndDirection[1],
|
||||
Parent = lastStampModel,
|
||||
}
|
||||
New "StringValue" {
|
||||
Name = "WaterForceDirectionTag",
|
||||
Value = waterForceAndDirection[2],
|
||||
Parent = lastStampModel,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
setupStamper(lastStampModel, mouse)
|
||||
setupStamper(lastStampModel)
|
||||
end
|
||||
|
||||
local dialogClosed = function()
|
||||
if lastStampModel then
|
||||
if stampControl then
|
||||
stampControl.Destroy()
|
||||
end
|
||||
setupStamper(lastStampModel, mouse)
|
||||
local function dialogClosed()
|
||||
if not lastStampModel then
|
||||
return
|
||||
elseif stampControl then
|
||||
stampControl.Destroy()
|
||||
end
|
||||
setupStamper(lastStampModel)
|
||||
end
|
||||
|
||||
function pickPart()
|
||||
local function pickPart()
|
||||
if stampControl then
|
||||
stampControl.Destroy()
|
||||
end
|
||||
setPanelVisibility(true)
|
||||
end
|
||||
|
||||
function keyHandler(key)
|
||||
if key == "f" then
|
||||
handlePartShow()
|
||||
end
|
||||
end
|
||||
|
||||
function partOn()
|
||||
pickPart()
|
||||
end
|
||||
|
||||
function partOff()
|
||||
setPanelVisibility(false)
|
||||
if lastStampModel then
|
||||
if stampControl then
|
||||
stampControl.Destroy()
|
||||
local function keyHandler(key)
|
||||
if key ~= "f" then
|
||||
return
|
||||
elseif getPanelVisibility() then
|
||||
-- handlePartShow
|
||||
setPanelVisibility(false)
|
||||
if lastStampModel then
|
||||
if stampControl then
|
||||
stampControl.Destroy()
|
||||
end
|
||||
setupStamper(lastStampModel)
|
||||
end
|
||||
setupStamper(lastStampModel, mouse)
|
||||
end
|
||||
end
|
||||
|
||||
function handlePartShow()
|
||||
if getPanelVisibility() then
|
||||
partOff()
|
||||
else
|
||||
partOn()
|
||||
pickPart()
|
||||
end
|
||||
end
|
||||
|
||||
On = function()
|
||||
if not game.Workspace.Terrain then
|
||||
function setupStamper(model)
|
||||
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
|
||||
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)
|
||||
mouse = this:GetMouse()
|
||||
end
|
||||
|
|
@ -268,7 +405,7 @@ On = function()
|
|||
on = true
|
||||
end
|
||||
|
||||
Off = function()
|
||||
function Off()
|
||||
if toolbarbutton then
|
||||
toolbarbutton:SetActive(false)
|
||||
end
|
||||
|
|
@ -301,144 +438,6 @@ Off = function()
|
|||
on = false
|
||||
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-
|
||||
--------------------------
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
while game == nil do
|
||||
while not game do
|
||||
wait()
|
||||
end
|
||||
|
||||
|
|
@ -6,6 +6,12 @@ local ChangeHistoryService = game:GetService "ChangeHistoryService"
|
|||
local ContentProvider = game:GetService "ContentProvider"
|
||||
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-
|
||||
---------------
|
||||
|
|
@ -13,6 +19,7 @@ local loaded = false
|
|||
local on = false
|
||||
|
||||
local On, Off
|
||||
local mouseDown, mouseUp
|
||||
|
||||
local this = PluginManager():CreatePlugin()
|
||||
local mouse = this:GetMouse()
|
||||
|
|
@ -139,9 +146,6 @@ function MouseHighlighter.Create(mouseUse)
|
|||
highlighter.selectionPart = nil
|
||||
|
||||
-- Hook the mouse up to check for movement.
|
||||
mouseH.Move:connect(function()
|
||||
MouseMoved()
|
||||
end)
|
||||
|
||||
mouseH.Button1Down:connect(function()
|
||||
highlighter.mouseDown = true
|
||||
|
|
@ -239,9 +243,7 @@ function MouseHighlighter.Create(mouseUse)
|
|||
local function UpdatePosition(position)
|
||||
if not position then
|
||||
return
|
||||
end
|
||||
|
||||
if not mouseH.Target then
|
||||
elseif not mouseH.Target then
|
||||
stopTween()
|
||||
highlighter.selectionPart.Parent = nil
|
||||
return
|
||||
|
|
@ -297,12 +299,12 @@ function MouseHighlighter.Create(mouseUse)
|
|||
end
|
||||
end
|
||||
|
||||
-- Function to call when the mouse has moved. Updates where to display the highlighter.
|
||||
function MouseMoved()
|
||||
-- Function to call when the mouse has moved. Updates where to display the highlighter.
|
||||
mouseH.Move:connect(function()
|
||||
if on and not processing then
|
||||
UpdatePosition(mouseH.Hit)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
return highlighter
|
||||
end
|
||||
|
|
@ -338,68 +340,6 @@ mouseHighlighter:DisablePreview()
|
|||
local 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.
|
||||
--
|
||||
-- confirmText - What to display in the popup.
|
||||
|
|
@ -417,46 +357,54 @@ function ConfirmationPopup.Create(
|
|||
confirmFunction,
|
||||
declineFunction
|
||||
)
|
||||
local popup = {}
|
||||
popup.confirmButton = nil -- Hold the button to confirm a choice.
|
||||
popup.declineButton = nil -- Hold the button to decline a choice.
|
||||
popup.confirmationFrame = nil -- Hold the conformation frame.
|
||||
popup.confirmationText = nil -- Hold the text label to display the conformation message.
|
||||
popup.confirmationHelpText = nil -- Hold the text label to display the conformation message help.
|
||||
local popup = {
|
||||
confirmButton = nil, -- Hold the button to confirm a choice.
|
||||
declineButton = nil, -- Hold the button to decline a choice.
|
||||
confirmationFrame = nil, -- Hold the conformation frame.
|
||||
confirmationText = nil, -- Hold the text label to display the conformation message.
|
||||
confirmationHelpText = nil, -- Hold the text label to display the conformation message help.
|
||||
}
|
||||
|
||||
popup.confirmationFrame = Instance.new "Frame"
|
||||
popup.confirmationFrame.Name = "ConfirmationFrame"
|
||||
popup.confirmationFrame.Size = UDim2.new(0, 280, 0, 160)
|
||||
popup.confirmationFrame.Position = UDim2.new(
|
||||
0.5,
|
||||
-popup.confirmationFrame.Size.X.Offset / 2,
|
||||
0.5,
|
||||
-popup.confirmationFrame.Size.Y.Offset / 2
|
||||
)
|
||||
popup.confirmationFrame.Style = Enum.FrameStyle.RobloxRound
|
||||
popup.confirmationFrame.Parent = screenGui
|
||||
popup.confirmationFrame = New "Frame" {
|
||||
Name = "ConfirmationFrame",
|
||||
Size = UDim2.new(0, 280, 0, 160),
|
||||
Position = UDim2.new(
|
||||
0.5,
|
||||
-popup.confirmationFrame.Size.X.Offset / 2,
|
||||
0.5,
|
||||
-popup.confirmationFrame.Size.Y.Offset / 2
|
||||
),
|
||||
Style = Enum.FrameStyle.RobloxRound,
|
||||
Parent = screenGui,
|
||||
}
|
||||
|
||||
popup.confirmLabel = CreateStandardLabel(
|
||||
"ConfirmLabel",
|
||||
UDim2.new(0, 0, 0, 15),
|
||||
UDim2.new(1, 0, 0, 24),
|
||||
confirmText,
|
||||
popup.confirmationFrame
|
||||
)
|
||||
popup.confirmLabel.FontSize = Enum.FontSize.Size18
|
||||
popup.confirmLabel.TextXAlignment = Enum.TextXAlignment.Center
|
||||
popup.confirmLabel = Hydrate(
|
||||
CreateStandardLabel(
|
||||
"ConfirmLabel",
|
||||
UDim2.new(0, 0, 0, 15),
|
||||
UDim2.new(1, 0, 0, 24),
|
||||
confirmText,
|
||||
popup.confirmationFrame
|
||||
)
|
||||
) {
|
||||
FontSize = Enum.FontSize.Size18,
|
||||
TextXAlignment = Enum.TextXAlignment.Center,
|
||||
}
|
||||
|
||||
popup.confirmationHelpText = CreateStandardLabel(
|
||||
"ConfirmSmallLabel",
|
||||
UDim2.new(0, 0, 0, 40),
|
||||
UDim2.new(1, 0, 0, 28),
|
||||
confirmSmallText,
|
||||
popup.confirmationFrame
|
||||
)
|
||||
popup.confirmationHelpText.FontSize = Enum.FontSize.Size14
|
||||
popup.confirmationHelpText.TextWrap = true
|
||||
popup.confirmationHelpText.Font = Enum.Font.Arial
|
||||
popup.confirmationHelpText.TextXAlignment = Enum.TextXAlignment.Center
|
||||
popup.confirmationHelpText = Hydrate(
|
||||
CreateStandardLabel(
|
||||
"ConfirmSmallLabel",
|
||||
UDim2.new(0, 0, 0, 40),
|
||||
UDim2.new(1, 0, 0, 28),
|
||||
confirmSmallText,
|
||||
popup.confirmationFrame
|
||||
)
|
||||
) {
|
||||
FontSize = Enum.FontSize.Size14,
|
||||
TextWrap = true,
|
||||
Font = Enum.Font.Arial,
|
||||
TextXAlignment = Enum.TextXAlignment.Center,
|
||||
}
|
||||
|
||||
-- Confirm
|
||||
popup.confirmButton = CreateStandardButton(
|
||||
|
|
@ -509,68 +457,11 @@ end
|
|||
--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
|
||||
|
||||
-- Load the progress bar to display when drawing a river.
|
||||
-- text - Text to display.
|
||||
function LoadProgressBar(text)
|
||||
local function LoadProgressBar(text)
|
||||
processing = true
|
||||
|
||||
-- Start the progress bar.
|
||||
|
|
@ -597,31 +488,33 @@ function LoadProgressBar(text)
|
|||
-- spin = false
|
||||
end)
|
||||
|
||||
local spinnerFrame = Instance.new "Frame"
|
||||
spinnerFrame.Name = "Spinner"
|
||||
spinnerFrame.Size = UDim2.new(0, 80, 0, 80)
|
||||
spinnerFrame.Position = UDim2.new(0.5, -40, 0.5, -55)
|
||||
spinnerFrame.BackgroundTransparency = 1
|
||||
spinnerFrame.Parent = progressBar
|
||||
local spinnerFrame = New "Frame" {
|
||||
Name = "Spinner",
|
||||
Size = UDim2.new(0, 80, 0, 80),
|
||||
Position = UDim2.new(0.5, -40, 0.5, -55),
|
||||
BackgroundTransparency = 1,
|
||||
Parent = progressBar,
|
||||
}
|
||||
|
||||
local spinnerIcons = {}
|
||||
local spinnerNum = 1
|
||||
while spinnerNum <= 8 do
|
||||
local spinnerImage = Instance.new "ImageLabel"
|
||||
spinnerImage.Name = "Spinner" .. spinnerNum
|
||||
spinnerImage.Size = UDim2.new(0, 16, 0, 16)
|
||||
spinnerImage.Position = UDim2.new(
|
||||
0.5 + 0.3 * math.cos(math.rad(45 * spinnerNum)),
|
||||
-8,
|
||||
0.5 + 0.3 * math.sin(math.rad(45 * spinnerNum)),
|
||||
-8
|
||||
)
|
||||
spinnerImage.BackgroundTransparency = 1
|
||||
spinnerImage.Image = "http://banland.xyz/asset?id=45880710"
|
||||
spinnerImage.Parent = spinnerFrame
|
||||
local spinnerImage = New "ImageLabel" {
|
||||
Name = "Spinner" .. spinnerNum,
|
||||
Size = UDim2.new(0, 16, 0, 16),
|
||||
Position = UDim2.new(
|
||||
0.5 + 0.3 * math.cos(math.rad(45 * spinnerNum)),
|
||||
-8,
|
||||
0.5 + 0.3 * math.sin(math.rad(45 * spinnerNum)),
|
||||
-8
|
||||
),
|
||||
BackgroundTransparency = 1,
|
||||
Image = "http://banland.xyz/asset?id=45880710",
|
||||
Parent = spinnerFrame,
|
||||
}
|
||||
|
||||
spinnerIcons[spinnerNum] = spinnerImage
|
||||
spinnerNum = spinnerNum + 1
|
||||
spinnerNum += 1
|
||||
end
|
||||
|
||||
--Make it spin
|
||||
|
|
@ -648,7 +541,7 @@ function LoadProgressBar(text)
|
|||
end
|
||||
|
||||
-- Unload the progress bar.
|
||||
function UnloadProgressBar()
|
||||
local function UnloadProgressBar()
|
||||
processing = false
|
||||
|
||||
if progressBar then
|
||||
|
|
@ -663,36 +556,68 @@ function UnloadProgressBar()
|
|||
end
|
||||
end
|
||||
|
||||
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
|
||||
)
|
||||
local function floodFill(x, y, z)
|
||||
LoadProgressBar "Processing"
|
||||
breadthFill(x, y, z)
|
||||
UnloadProgressBar()
|
||||
ChangeHistoryService:SetWaypoint "FloodFill"
|
||||
end
|
||||
|
||||
if not processing then
|
||||
return
|
||||
end
|
||||
-- Function used when we try and flood fill. Prompts the user first.
|
||||
-- Will not show if disabled or terrain is being processed.
|
||||
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
|
||||
for j = 1, #currYDepthChecks do
|
||||
table.insert(newYChecks, {
|
||||
xPos = currYDepthChecks[j].xPos,
|
||||
yPos = currYDepthChecks[j].yPos,
|
||||
zPos = currYDepthChecks[j].zPos,
|
||||
})
|
||||
end
|
||||
end
|
||||
processing = true
|
||||
if ConfirmationPopupObject then
|
||||
return
|
||||
end
|
||||
|
||||
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
|
||||
yDepthChecks = newYChecks
|
||||
)
|
||||
end
|
||||
|
||||
function mouseDown(mouseD)
|
||||
if on and mouseD.Target == game.Workspace.Terrain then
|
||||
startCell = mouseHighlighter:GetPosition()
|
||||
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
|
||||
return
|
||||
end
|
||||
|
|
@ -735,7 +660,36 @@ function doBreadthFill(x, y, z)
|
|||
return yDepthChecks
|
||||
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
|
||||
return false
|
||||
end
|
||||
|
|
@ -811,8 +765,7 @@ end
|
|||
On = function()
|
||||
if not c then
|
||||
return
|
||||
end
|
||||
if this then
|
||||
elseif this then
|
||||
this:Activate(true)
|
||||
end
|
||||
if toolbarbutton then
|
||||
|
|
@ -858,25 +811,27 @@ dragBar, containerFrame, helpFrame, closeEvent = RbxGui.CreatePluginFrame(
|
|||
)
|
||||
dragBar.Visible = false
|
||||
|
||||
helpFrame.Size = UDim2.new(0, 200, 0, 190)
|
||||
|
||||
local textHelp = Instance.new "TextLabel"
|
||||
textHelp.Name = "TextHelp"
|
||||
textHelp.Font = Enum.Font.ArialBold
|
||||
textHelp.FontSize = Enum.FontSize.Size12
|
||||
textHelp.TextColor3 = Color3.new(1, 1, 1)
|
||||
textHelp.Size = UDim2.new(1, -6, 1, -6)
|
||||
textHelp.Position = UDim2.new(0, 3, 0, 3)
|
||||
textHelp.TextXAlignment = Enum.TextXAlignment.Left
|
||||
textHelp.TextYAlignment = Enum.TextYAlignment.Top
|
||||
textHelp.BackgroundTransparency = 1
|
||||
textHelp.TextWrap = true
|
||||
textHelp.Text = [[
|
||||
Hydrate(helpFrame) {
|
||||
Size = UDim2.new(0, 200, 0, 190),
|
||||
-- "This will be pdfs in 2024" - Heliodex
|
||||
New "TextLabel" {
|
||||
Name = "TextHelp",
|
||||
Font = Enum.Font.ArialBold,
|
||||
FontSize = Enum.FontSize.Size12,
|
||||
TextColor3 = Color3.new(1, 1, 1),
|
||||
Size = UDim2.new(1, -6, 1, -6),
|
||||
Position = UDim2.new(0, 3, 0, 3),
|
||||
TextXAlignment = Enum.TextXAlignment.Left,
|
||||
TextYAlignment = Enum.TextYAlignment.Top,
|
||||
BackgroundTransparency = 1,
|
||||
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).
|
||||
|
||||
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()
|
||||
Off()
|
||||
|
|
|
|||
Loading…
Reference in New Issue