849 lines
19 KiB
Plaintext
849 lines
19 KiB
Plaintext
while game == nil do
|
|
wait(1 / 30)
|
|
end
|
|
|
|
local ChangeHistoryService = game:GetService "ChangeHistoryService"
|
|
local CoreGui = game:GetService "CoreGui"
|
|
|
|
---------------
|
|
--PLUGIN SETUP-
|
|
---------------
|
|
local loaded = false
|
|
local on = false
|
|
|
|
local On, Off
|
|
|
|
local this = PluginManager():CreatePlugin()
|
|
local mouse = this:GetMouse()
|
|
mouse.Button1Down:connect(function()
|
|
mouseDown(mouse)
|
|
end)
|
|
mouse.Button1Up:connect(function()
|
|
mouseUp(mouse)
|
|
end)
|
|
mouse.Move:connect(function()
|
|
mouseMove(mouse)
|
|
end)
|
|
|
|
local toolbar = this:CreateToolbar "Terrain"
|
|
local toolbarbutton = toolbar:CreateButton(
|
|
"Material Brush",
|
|
"Material Brush",
|
|
"materialBrush.png"
|
|
)
|
|
toolbarbutton.Click:connect(function()
|
|
if on then
|
|
Off()
|
|
elseif loaded then
|
|
On()
|
|
end
|
|
end)
|
|
|
|
game:WaitForChild "Workspace"
|
|
game.Workspace:WaitForChild "Terrain"
|
|
|
|
-----------------------------
|
|
--LOCAL FUNCTION DEFINITIONS-
|
|
-----------------------------
|
|
local c = game.Workspace.Terrain
|
|
local SetCell = c.SetCell
|
|
local SetWaterCell = c.SetWaterCell
|
|
-- local GetWaterCell = c.GetWaterCell
|
|
local GetCell = c.GetCell
|
|
local WorldToCellPreferSolid = c.WorldToCellPreferSolid
|
|
local CellCenterToWorld = c.CellCenterToWorld
|
|
local waterMaterial = 17
|
|
|
|
local brushTypes = { "Circular", "Square" }
|
|
-- local waterForceDirections = { "NegX", "X", "NegY", "Y", "NegZ", "Z" }
|
|
-- local waterForces = { "None", "Small", "Medium", "Strong", "Max" }
|
|
|
|
local mediumWaterForce = Enum.WaterForce.Medium
|
|
|
|
-----------------
|
|
--DEFAULT VALUES-
|
|
-----------------
|
|
local terrainSelectorGui, terrainSelected, radiusLabel, dragBar, closeEvent, helpFrame, currSelectionUpdate, currSelectionDestroy, lastCell, lastLastCell --, waterPanel
|
|
local dragging = false
|
|
-- local painting = false
|
|
|
|
--- exposed values to user via gui
|
|
local currentMaterial = Enum.CellMaterial.Grass
|
|
local radius = 3
|
|
local brushType = "Square"
|
|
-- local currWaterForceDirection = "NegX"
|
|
-- local currWaterForce = "None"
|
|
|
|
-- lua library load
|
|
local RbxGui = LoadLibrary "RbxGui"
|
|
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
|
|
end
|
|
|
|
if directionIsDown(lastCell, mouseCellPos) then
|
|
paintWaterfall(setCells)
|
|
return
|
|
end
|
|
|
|
local initX = setCells[1].xPos
|
|
local initZ = setCells[1].zPos
|
|
|
|
local endX = setCells[#setCells].xPos
|
|
local endZ = setCells[#setCells].zPos
|
|
|
|
local zWidth = math.abs(endZ - initZ)
|
|
local zMiddle = math.ceil(zWidth / 2 + initZ)
|
|
local xMiddle = math.ceil(zWidth / 2 + initX)
|
|
|
|
local down = endX - initX
|
|
local up, left, right = nil
|
|
if down < 0 then
|
|
down = Enum.WaterDirection.NegX
|
|
up = Enum.WaterDirection.X
|
|
left = Enum.WaterDirection.Z
|
|
right = Enum.WaterDirection.NegZ
|
|
else
|
|
down = Enum.WaterDirection.X
|
|
up = Enum.WaterDirection.NegX
|
|
left = Enum.WaterDirection.NegZ
|
|
right = Enum.WaterDirection.Z
|
|
end
|
|
|
|
if #setCells == 1 then
|
|
if not mouseCellPos or not lastCell then
|
|
return
|
|
end
|
|
|
|
local overallDirection = (mouseCellPos - lastCell).unit
|
|
if
|
|
math.abs(overallDirection.x) > math.abs(overallDirection.y)
|
|
and math.abs(overallDirection.x) > math.abs(overallDirection.z)
|
|
then
|
|
if overallDirection.x > 0 then
|
|
SetWaterCell(
|
|
c,
|
|
setCells[1].xPos,
|
|
setCells[1].yPos,
|
|
setCells[1].zPos,
|
|
mediumWaterForce,
|
|
Enum.WaterDirection.X
|
|
)
|
|
else
|
|
SetWaterCell(
|
|
c,
|
|
setCells[1].xPos,
|
|
setCells[1].yPos,
|
|
setCells[1].zPos,
|
|
mediumWaterForce,
|
|
Enum.WaterDirection.NegX
|
|
)
|
|
end
|
|
elseif
|
|
math.abs(overallDirection.z) > math.abs(overallDirection.y)
|
|
and math.abs(overallDirection.z) > math.abs(overallDirection.x)
|
|
then
|
|
if overallDirection.z > 0 then
|
|
SetWaterCell(
|
|
c,
|
|
setCells[1].xPos,
|
|
setCells[1].yPos,
|
|
setCells[1].zPos,
|
|
mediumWaterForce,
|
|
Enum.WaterDirection.Z
|
|
)
|
|
else
|
|
SetWaterCell(
|
|
c,
|
|
setCells[1].xPos,
|
|
setCells[1].yPos,
|
|
setCells[1].zPos,
|
|
mediumWaterForce,
|
|
Enum.WaterDirection.NegZ
|
|
)
|
|
end
|
|
elseif
|
|
math.abs(overallDirection.y) > math.abs(overallDirection.z)
|
|
and math.abs(overallDirection.y) > math.abs(overallDirection.x)
|
|
then
|
|
if overallDirection.y > 0 then
|
|
SetWaterCell(
|
|
c,
|
|
setCells[1].xPos,
|
|
setCells[1].yPos,
|
|
setCells[1].zPos,
|
|
mediumWaterForce,
|
|
Enum.WaterDirection.Y
|
|
)
|
|
else
|
|
SetWaterCell(
|
|
c,
|
|
setCells[1].xPos,
|
|
setCells[1].yPos,
|
|
setCells[1].zPos,
|
|
mediumWaterForce,
|
|
Enum.WaterDirection.NegY
|
|
)
|
|
end
|
|
end
|
|
else
|
|
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,
|
|
right
|
|
)
|
|
elseif setCells[i].zPos > zMiddle then
|
|
SetWaterCell(
|
|
c,
|
|
setCells[i].xPos,
|
|
setCells[i].yPos,
|
|
setCells[i].zPos,
|
|
mediumWaterForce,
|
|
left
|
|
)
|
|
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 cellPos = WorldToCellPreferSolid(c, mouseR.Hit.p)
|
|
|
|
local lowVec =
|
|
Vector3.new(cellPos.x - radius, cellPos.y - radius, cellPos.z - radius)
|
|
local highVec =
|
|
Vector3.new(cellPos.x + radius, cellPos.y + radius, cellPos.z + radius)
|
|
lowVec = CellCenterToWorld(c, lowVec.x, lowVec.y, lowVec.z)
|
|
highVec = CellCenterToWorld(c, highVec.x, highVec.y, highVec.z)
|
|
|
|
return Region3.new(
|
|
lowVec + Vector3.new(2, 2, 2),
|
|
highVec - Vector3.new(2, 2, 2)
|
|
)
|
|
end
|
|
|
|
function createSelection(mouseS, massSelection)
|
|
currSelectionUpdate, currSelectionDestroy = RbxUtil.SelectTerrainRegion(
|
|
calculateRegion(mouseS),
|
|
BrickColor.new "Lime green",
|
|
massSelection,
|
|
game.CoreGui
|
|
)
|
|
end
|
|
|
|
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
|
|
|
|
-- no dragging occured, lets set our water to be stagnant or be a waterfall
|
|
if lastCell and not lastLastCell then
|
|
local cellsToSet = paint(lastCell)
|
|
if directionIsDown(nil, lastCell) then
|
|
paintWaterfall(cellsToSet)
|
|
else
|
|
for i = 1, #cellsToSet do
|
|
SetWaterCell(
|
|
c,
|
|
cellsToSet[i].xPos,
|
|
cellsToSet[i].yPos,
|
|
cellsToSet[i].zPos,
|
|
Enum.WaterForce.None,
|
|
Enum.WaterDirection.NegX
|
|
)
|
|
end
|
|
end
|
|
return
|
|
end
|
|
|
|
if directionIsDown(lastLastCell, lastCell) then
|
|
local cellsToSet = paint(lastCell)
|
|
paintWaterfall(cellsToSet)
|
|
return
|
|
end
|
|
|
|
local overallDirection = (lastCell - lastLastCell).unit
|
|
local cellsToSet = paint(lastCell)
|
|
|
|
local absX, absY, absZ =
|
|
math.abs(overallDirection.X),
|
|
math.abs(overallDirection.Y),
|
|
math.abs(overallDirection.Z)
|
|
local direction
|
|
|
|
if absX > absY and absX > absZ then
|
|
if overallDirection.X > 0 then
|
|
direction = Enum.WaterDirection.X
|
|
else
|
|
direction = Enum.WaterDirection.NegX
|
|
end
|
|
elseif absY > absX and absY > absZ then
|
|
if overallDirection.Y > 0 then
|
|
direction = Enum.WaterDirection.Y
|
|
else
|
|
direction = Enum.WaterDirection.NegY
|
|
end
|
|
elseif absZ > absX and absZ > absY then
|
|
if overallDirection.Z > 0 then
|
|
direction = Enum.WaterDirection.Z
|
|
else
|
|
direction = Enum.WaterDirection.NegZ
|
|
end
|
|
end
|
|
|
|
if not direction then -- this should never be hit, but just in case
|
|
direction = Enum.WaterDirection.NegX
|
|
end
|
|
|
|
for i = 1, #cellsToSet do
|
|
SetWaterCell(
|
|
c,
|
|
cellsToSet[i].xPos,
|
|
cellsToSet[i].yPos,
|
|
cellsToSet[i].zPos,
|
|
mediumWaterForce,
|
|
direction
|
|
)
|
|
end
|
|
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
|
|
end
|
|
end
|
|
|
|
function mouseUp(_)
|
|
dragging = false
|
|
|
|
-- we need to fix directionality on last cell set (if water)
|
|
if currentMaterial == waterMaterial then
|
|
setPositionDirectionality()
|
|
end
|
|
|
|
ChangeHistoryService:SetWaypoint "MaterialPaint"
|
|
|
|
lastLastCell = nil
|
|
lastCell = nil
|
|
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()
|
|
end
|
|
end
|
|
end
|
|
|
|
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 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
|
|
end
|
|
end
|
|
|
|
local xRange, yRange, zRange =
|
|
math.abs(highX - lowX), math.abs(highY - lowY), math.abs(highZ - lowZ)
|
|
|
|
local xzPlaneArea = xRange * zRange
|
|
local xyPlaneArea = xRange * yRange
|
|
local yzPlaneArea = yRange * zRange
|
|
|
|
if xyPlaneArea > xzPlaneArea then
|
|
return true
|
|
end
|
|
|
|
if yzPlaneArea > xzPlaneArea then
|
|
return true
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
function destroySelection()
|
|
if currSelectionUpdate then
|
|
currSelectionUpdate = nil
|
|
end
|
|
if currSelectionDestroy then
|
|
currSelectionDestroy()
|
|
currSelectionDestroy = nil
|
|
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
|
|
end
|
|
end
|
|
|
|
return currCell
|
|
end
|
|
|
|
function interpolateOneDim(direction, currPos, goalPos, currCell)
|
|
if currPos ~= goalPos then
|
|
currCell = moveTowardsGoal(direction, currPos, goalPos, currCell)
|
|
paint(currCell)
|
|
end
|
|
|
|
return currCell
|
|
end
|
|
|
|
function paintBetweenPoints(lastCellP, newCell)
|
|
local currCell = lastCellP
|
|
|
|
while
|
|
currCell.X ~= newCell.X
|
|
or currCell.Z ~= newCell.Z
|
|
or currCell.Y ~= newCell.Y
|
|
do
|
|
currCell = interpolateOneDim("X", currCell.X, newCell.X, currCell)
|
|
currCell = interpolateOneDim("Z", currCell.Z, newCell.Z, currCell)
|
|
currCell = interpolateOneDim("Y", currCell.Y, newCell.Y, currCell)
|
|
end
|
|
end
|
|
|
|
On = function()
|
|
if not c then
|
|
return
|
|
end
|
|
this:Activate(true)
|
|
toolbarbutton:SetActive(true)
|
|
|
|
dragBar.Visible = true
|
|
on = true
|
|
end
|
|
|
|
Off = function()
|
|
toolbarbutton:SetActive(false)
|
|
|
|
destroySelection()
|
|
dragBar.Visible = false
|
|
on = false
|
|
end
|
|
|
|
------
|
|
--GUI-
|
|
------
|
|
|
|
--screengui
|
|
local g = Instance.new "ScreenGui"
|
|
g.Name = "MaterialPainterGui"
|
|
g.Parent = CoreGui
|
|
|
|
dragBar, containerFrame, helpFrame, closeEvent = RbxGui.CreatePluginFrame(
|
|
"Material Brush",
|
|
UDim2.new(0, 163, 0, 285),
|
|
UDim2.new(0, 0, 0, 0),
|
|
false,
|
|
g
|
|
)
|
|
dragBar.Visible = false
|
|
|
|
-- End dragging if it goes over the gui frame.
|
|
containerFrame.MouseEnter:connect(function()
|
|
dragging = false
|
|
end)
|
|
dragBar.MouseEnter:connect(function()
|
|
dragging = false
|
|
end)
|
|
|
|
helpFrame.Size = UDim2.new(0, 200, 0, 250)
|
|
helpFrame.ZIndex = 3
|
|
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.Position = UDim2.new(0, 4, 0, 4)
|
|
textHelp.BackgroundTransparency = 1
|
|
textHelp.TextWrap = true
|
|
textHelp.ZIndex = 4
|
|
textHelp.Text =
|
|
[[Changes existing terrain blocks to the specified material. Simply hold the mouse down and drag to 'paint' the terrain (only cells inside the selection box will be affected).
|
|
|
|
Size:
|
|
The size of the brush we paint terrain with.
|
|
|
|
Brush Type:
|
|
The shape we paint terrain with inside of our selection box.
|
|
|
|
Material Selection:
|
|
The terrain material we will paint.]]
|
|
textHelp.Parent = helpFrame
|
|
|
|
closeEvent.Event:connect(function()
|
|
Off()
|
|
end)
|
|
|
|
terrainSelectorGui, terrainSelected, forceTerrainSelection =
|
|
RbxGui.CreateTerrainMaterialSelector(
|
|
UDim2.new(1, -10, 0, 184),
|
|
UDim2.new(0, 5, 1, -190)
|
|
)
|
|
terrainSelectorGui.Parent = containerFrame
|
|
terrainSelectorGui.BackgroundTransparency = 1
|
|
terrainSelectorGui.BorderSizePixel = 0
|
|
terrainSelected.Event:connect(function(newMaterial)
|
|
currentMaterial = newMaterial
|
|
end)
|
|
|
|
-- Purpose:
|
|
-- Retrive the size text to display for a given radius, where 1 == 1 block and 2 == 3 blocks, etc.
|
|
function SizeText(radiusT)
|
|
return "Size: " .. (((radiusT - 1) * 2) + 1)
|
|
end
|
|
|
|
--current radius display label
|
|
radiusLabel = Instance.new "TextLabel"
|
|
radiusLabel.Name = "RadiusLabel"
|
|
radiusLabel.Position = UDim2.new(0, 10, 0, 5)
|
|
radiusLabel.Size = UDim2.new(1, -3, 0, 14)
|
|
radiusLabel.Text = SizeText(radius)
|
|
radiusLabel.TextColor3 = Color3.new(0.95, 0.95, 0.95)
|
|
radiusLabel.Font = Enum.Font.ArialBold
|
|
radiusLabel.FontSize = Enum.FontSize.Size14
|
|
radiusLabel.BorderColor3 = Color3.new(0, 0, 0)
|
|
radiusLabel.BackgroundTransparency = 1
|
|
radiusLabel.TextXAlignment = Enum.TextXAlignment.Left
|
|
radiusLabel.Parent = containerFrame
|
|
|
|
--radius slider
|
|
local radSliderGui, radSliderPosition =
|
|
RbxGui.CreateSlider(6, 0, UDim2.new(0, 0, 0, 18))
|
|
radSliderGui.Size = UDim2.new(1, -2, 0, 20)
|
|
radSliderGui.Position = UDim2.new(0, 0, 0, 24)
|
|
radSliderGui.Parent = containerFrame
|
|
local radBar = radSliderGui:FindFirstChild "Bar"
|
|
radBar.Size = UDim2.new(1, -20, 0, 5)
|
|
radBar.Position = UDim2.new(0, 10, 0.5, -3)
|
|
radSliderPosition.Value = radius
|
|
radSliderPosition.Changed:connect(function()
|
|
radius = radSliderPosition.Value
|
|
radiusLabel.Text = SizeText(radius)
|
|
destroySelection()
|
|
end)
|
|
|
|
local brushTypeChanged = function(newBrush)
|
|
brushType = newBrush
|
|
end
|
|
-- brush type drop-down
|
|
local brushDropDown, forceSelection =
|
|
RbxGui.CreateDropDownMenu(brushTypes, brushTypeChanged)
|
|
forceSelection "Square"
|
|
brushDropDown.Size = UDim2.new(1, -10, 0.01, 25)
|
|
brushDropDown.Position = UDim2.new(0, 5, 0, 65)
|
|
brushDropDown.Parent = containerFrame
|
|
|
|
local brushLabel = radiusLabel:Clone()
|
|
brushLabel.Name = "BrushLabel"
|
|
brushLabel.Text = "Brush Type"
|
|
brushLabel.Position = UDim2.new(0, 10, 0, 50)
|
|
brushLabel.Parent = containerFrame
|
|
|
|
this.Deactivation:connect(function()
|
|
Off()
|
|
end)
|
|
|
|
--------------------------
|
|
--SUCCESSFUL LOAD MESSAGE-
|
|
--------------------------
|
|
loaded = true
|