null
nil
-
true
true
0
0
-0.699999988
-0
0
1
1
-0
0
0
1
0
ConfigTool
http://www.roblox.com/asset/?id=59102714
Configure Parts
-
false
-0.5
0.5
0
0
-0.5
0.5
0
0
199
-35
1.60000002
3.5
0
0
-1
0
1
0
1
0
0
true
0.5
0.300000012
-0.5
0.5
0
0
-0.5
0.5
0
0
true
256
Handle
0
-0.5
0.5
0
0
0
0
0
-0.5
0.5
0
0
0
0
0
0
2
1
1
0.800000012
2
-
2
2
http://www.roblox.com/asset/?id=16884681
5
Mesh
0
0
0
0.600000024
0.600000024
0.600000024
http://www.roblox.com/asset/?id=16884673
1
1
1
-
false
ConfigurationLocal
-- general functions
function waitForProperty(instance, name)
while not instance[name] do
instance.Changed:wait()
end
end
function waitForChild(instance, name)
while not instance:FindFirstChild(name) do
instance.ChildAdded:wait()
end
end
local RbxGui
if LoadLibrary then
RbxGui = LoadLibrary("RbxGui")
else
return
end
local isRestricted = (game.PlaceId == 41324860 or game.PlaceId == 129686177)
local Tool = script.Parent
enabled = true
game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=59785529")
game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=61423967")
game:GetService("ContentProvider"):Preload("http://www.roblox.com/asset/?id=61427382")
local configIconImage = "http://www.roblox.com/asset/?id=59785529"
local configIconOverImage = "http://www.roblox.com/asset/?id=61423967"
local configIconHoverImage = "http://www.roblox.com/asset/?id=61427382"
local highlightedImage = nil
waitForChild(Tool, "PlayerOwner")
local playerOwner = Tool.PlayerOwner
local STATIC_BASE_PLATE = nil
local ServiceConnections
local guiMain
local screen
local selectionGui
local player
local playerArea
local canTween = true
local gridRecalc
local lastPart
local lastConfig = nil
local lastVehicleSeat = nil
local origValueMap = {}
local valueConnections = {}
local objectValueSelect = {}
local adornmentTable = {}
local colorPaletteSelectMode = false
local needsIconReset = false
local textSize = 5
--Constants
local width = UDim.new(3, 0)
local height = 20
local transparency = 0.5
local buttonColor = BrickColor.new("Mid gray")
local frameColor = BrickColor.new("Pastel yellow")
local function isInModel(part)
if part == game.Workspace then
return false, nil
elseif part:IsA("Model") then
return true, part
else
return isInModel(part.Parent)
end
end
function constrained(valueObject)
return (valueObject:IsA("IntConstrainedValue") or valueObject:IsA("DoubleConstrainedValue"))
end
function sharedProcess(name, parentFrame)
local subFrame = Instance.new("Frame")
subFrame.Name = name
subFrame.Size = UDim2.new(1.0, 0, 0, height)
subFrame.BackgroundTransparency = 1.0
subFrame.BorderSizePixel = 0
local label = Instance.new("TextLabel")
label.Font = Enum.Font.ArialBold
label.Position = UDim2.new(0.0, 0, 0.0, 0)
label.Size = UDim2.new(0.5, 0, 1.0, 0)
label.FontSize = textSize
label.TextColor = BrickColor.White()
label.Text = name
label.Parent = subFrame
label.BackgroundTransparency = 1.0
label.BorderSizePixel = 0
return subFrame
end
function createTextBox(size, text)
local textBox = Instance.new("TextBox")
textBox.Position = UDim2.new(0.5, 1, 0.0, 1)
textBox.Size = size
textBox.BackgroundTransparency = 1
textBox.FontSize = textSize - 3
textBox.TextColor3 = Color3.new(1,1,1)
textBox.Text = text
textBox.ZIndex = 2
local textBoxBacking = Instance.new("TextButton")
textBoxBacking.Text = ""
textBoxBacking.Style = Enum.ButtonStyle.RobloxButtonDefault
textBoxBacking.Size = UDim2.new(1,0,1,0)
textBoxBacking.Parent = textBox
return textBox
end
function setCheckBoxValue(checkBox, value)
if value then
checkBox.Text = "X"
else
checkBox.Text = ""
end
end
function createCheckBox(value)
local checkBox = Instance.new("TextButton")
checkBox.Position = UDim2.new(0.75, -(height-4)/2, 0.0, 2)
checkBox.Size = UDim2.new(0.0, height-4, 0.0, height-4)
checkBox.Style = Enum.ButtonStyle.RobloxButtonDefault
checkBox.TextColor3 = Color3.new(1,1,1)
checkBox.FontSize = textSize
setCheckBoxValue(checkBox, value)
return checkBox
end
function processBoolValue(value, guiFrame)
local subFrame = sharedProcess(value.Name, guiFrame)
local checkBox = createCheckBox(value.Value)
--Tie the two values together... we'll need to break these connections later
checkBox.MouseButton1Down:connect(function() value.Value = not(value.Value) end)
valueConnections[#valueConnections+1] = value.Changed:connect(function(newValue) setCheckBoxValue(checkBox, newValue) end)
checkBox.Parent = subFrame
return subFrame
end
function processConstrainedNumberValue(value, guiFrame)
local subFrame = sharedProcess(value.Name, guiFrame)
local textBox = createTextBox(UDim2.new(0.5,-2, 1.0, -2), value.ConstrainedValue, function(textBox) value.ConstrainedValue = textBox.Text end)
textBox.Name = value.Name
--Tie the two values together... we'll need to break these connections later
textBox.Changed:connect(function(prop)
if prop == "Text" then
local prevValue = value.ConstrainedValue
if textBox.Text ~= "" then
pcall(function() value.ConstrainedValue = textBox.Text end)
end
textBox.Text = value.ConstrainedValue
end
end)
valueConnections[#valueConnections+1] = value.Changed:connect(function(newValue) textBox.Text = newValue end)
textBox.Parent = subFrame
return subFrame;
end
function processIntValue(value, guiFrame)
local subFrame = sharedProcess(value.Name, guiFrame)
local textBox = createTextBox(UDim2.new(0.5,-2, 1.0, -2), value.Value, function(textBox) value.Value = textBox.Text end)
textBox.Name = value.Name
--Tie the two values together... we'll need to break these connections later
textBox.Changed:connect(function(prop)
if prop == "Text" then
local prevValue = value.Value
if textBox.Text ~= "" then
pcall(function() value.Value = textBox.Text end)
end
textBox.Text = value.Value
end
end)
valueConnections[#valueConnections+1] = value.Changed:connect(function(newValue) textBox.Text = newValue end)
textBox.Parent = subFrame
return subFrame;
end
function processPropertyValue(object, name, field, guiFrame)
origValueMap[name] = object[field]
local subFrame = sharedProcess(name, guiFrame)
local textBox = createTextBox(UDim2.new(0.5,-2, 1.0, -2), object[field], function(textBox) object[field] = textBox.Text end)
textBox.Name = name
--Tie the two values together... we'll need to break these connections later
textBox.Changed:connect(function(prop)
if prop == "Text" then
if textBox.Text ~= "" then
local success = pcall(function() object[field] = textBox.Text end)
end
textBox.Text = object[field]
end
end)
valueConnections[#valueConnections+1] = object.Changed:connect(function(property) if property == field then textBox.Text = object[field] end end)
textBox.Parent = subFrame
return subFrame
end
function processEnumValue(value, guiFrame)
local subFrame = sharedProcess(value.Name, guiFrame)
local valueChildren = value:GetChildren()
local enumNames = {}
for i = 1, #valueChildren do
if valueChildren[i]:IsA("BoolValue") and valueChildren[i].Value == true then
table.insert(enumNames,valueChildren[i].Name)
end
end
local valueToChange = value
local enumSelect = function(item)
valueToChange.Value = tostring(item)
end
local dropDownEnumMenu, updateEnumSelection = RbxGui.CreateDropDownMenu(enumNames, enumSelect)
dropDownEnumMenu.Position = UDim2.new(0.5,0,0,0)
dropDownEnumMenu.Size = UDim2.new(0.5,0,0,20)
dropDownEnumMenu.Parent = subFrame
for i = 1, #valueChildren do
if value.Value == valueChildren[i].Name then
dropDownEnumMenu.DropDownMenuButton.Text = valueChildren[i].Name
break
end
end
return subFrame
end
function processNumberValue(value, guiFrame)
return processIntValue(value, guiFrame)
end
function processStringValue(value, guiFrame)
return processIntValue(value, guiFrame)
end
function inBaseplate(instance)
if instance == STATIC_BASE_PLATE then return true end
local instanceCopy = instance
while instanceCopy and (instanceCopy.Parent ~= nil or instanceCopy.Parent ~= game.Workspace) do
if instanceCopy.Parent == STATIC_BASE_PLATE then
return true
end
instanceCopy = instanceCopy.Parent
end
return false
end
function onMouseLeave(hoverSelection, selectedButtonTable, oldButton)
if oldButton[0] then
local notSelected = true;
local selectionText = "";
for key, value in pairs(selectedButtonTable) do
if oldButton[0] == value then
notSelected = false
else
selectionText = value.BackgroundColor.Name;
end
end
if notSelected then
hoverSelection.Text = selectionText;
oldButton[0].Parent.BackgroundColor = BrickColor.Black();
end
end
oldButton[0] = nil
end
function onMouseEnter(hoverSelection, guiButton, selectedButtonTable, oldButton)
onMouseLeave(hoverSelection, selectedButtonTable, oldButton)
hoverSelection.Text = guiButton.BackgroundColor.Name
if guiButton ~= selectedButton then
guiButton.Parent.BackgroundColor = BrickColor.White();
oldButton[0] = guiButton
end
end
function changeColorSelection(colorHolder, paletteFrame, guiButton, selectedButtonTable)
if selectedButtonTable[colorHolder] ~= nil then
selectedButtonTable[colorHolder].Parent.BackgroundColor = BrickColor.Black();
end
guiButton.Parent.BackgroundColor = BrickColor.Yellow();
colorHolder.BackgroundColor = guiButton.BackgroundColor
selectedButtonTable[colorHolder] = guiButton
end
function onMouseUp(colorHolder, paletteFrame, guiButton, selectedButtonTable)
changeColorSelection(colorHolder, paletteFrame, guiButton, selectedButtonTable)
onMouseLeavePalette(paletteFrame)
end
function onShowColorDialog(paletteFrame)
paletteFrame.Visible = not(paletteFrame.Visible)
colorPaletteSelectMode = true
end
function onMouseEnterPalette(mouse)
colorPaletteSelectMode = true
end
function onMouseLeavePalette(paletteFrame)
colorPaletteSelectMode = false
paletteFrame.Visible = false
end
function processBrickColorValue(value, guiFrame)
local subFrame = sharedProcess(value.Name, guiFrame)
local sideBar = Instance.new("Frame")
sideBar.Position = UDim2.new(0.5, 0, 0.0, 0)
sideBar.Size = UDim2.new(0.5, 0, 1.0, 0)
sideBar.BackgroundTransparency = 1.0
sideBar.Parent = subFrame
sideBar.BorderSizePixel = 0
local primaryColor = Instance.new("TextButton")
primaryColor.Position = UDim2.new(0.0, 1, 0.0, 1)
primaryColor.Size = UDim2.new(0.0, height-2, 0, height-2)
primaryColor.Text = ""
primaryColor.FontSize = textSize
primaryColor.BackgroundColor = value.Value
primaryColor.BorderColor = BrickColor.Black()
primaryColor.Parent = sideBar
local hoverSelection = Instance.new("TextLabel")
hoverSelection.Position = UDim2.new(0.0, height+2, 0.0, 0)
hoverSelection.Size = UDim2.new(1.0, -height - 4, 1.0, 0)
hoverSelection.Text = ""
hoverSelection.Font = Enum.Font.ArialBold
hoverSelection.FontSize = textSize
hoverSelection.BackgroundTransparency = 1.0
hoverSelection.BorderSizePixel = 0
hoverSelection.TextColor = BrickColor.White()
hoverSelection.Text = primaryColor.BackgroundColor.Name;
hoverSelection.Parent = sideBar
local paletteFrame = Instance.new("Frame")
paletteFrame.Position = UDim2.new(primaryColor.Position.X.Scale, primaryColor.Position.X.Offset + height, primaryColor.Position.Y.Scale, primaryColor.Position.Y.Offset - height*7)
paletteFrame.Size = UDim2.new(0, height*8, 0, height*8)
paletteFrame.BackgroundColor = BrickColor.White()
paletteFrame.BorderColor = BrickColor.White()
paletteFrame.Visible = false;
paletteFrame.Parent = sideBar
paletteFrame.ZIndex = 2
paletteFrame.MouseEnter:connect(function() onMouseEnterPalette(mouse) end)
paletteFrame.MouseLeave:connect(function() onMouseLeavePalette(paletteFrame, mouse) end)
primaryColor.MouseButton1Down:connect(function() onShowColorDialog(paletteFrame) end)
local selectedButtonTable = {}
local colorButtonTable = {}
local oldButton = {}
for xOffset = 0, 7 do
for yOffset = 0,7 do
local guiFrame = Instance.new("Frame")
guiFrame.Position = UDim2.new(1.0/8 * xOffset, 0, 1.0/8*yOffset, 0)
guiFrame.Size = UDim2.new(1.0/8, 0, 1.0/8, 0)
guiFrame.BackgroundColor = BrickColor.White();
guiFrame.BorderSizePixel = 0
guiFrame.Parent = paletteFrame;
guiFrame.ZIndex = 2
local guiButton = Instance.new("TextButton")
guiButton.FontSize = textSize
guiButton.Position = UDim2.new(0.0, 1, 0.0, 1)
guiButton.Size = UDim2.new(1.0, -2, 1.0, -2)
guiButton.Text = ""
guiButton.BorderSizePixel = 0
guiButton.AutoButtonColor = false
local color = BrickColor.palette(xOffset + yOffset*8)
colorButtonTable[color.Number] = guiButton
guiButton.BackgroundColor = color
guiButton.MouseEnter:connect(function() onMouseEnter(hoverSelection, guiButton, selectedButtonTable, oldButton) end)
guiButton.MouseButton1Up:connect(function() onMouseUp(primaryColor, paletteFrame, guiButton, selectedButtonTable, oldButton) end)
guiButton.MouseButton1Up:connect(function() value.Value = guiButton.BackgroundColor end)
guiButton.Parent = guiFrame
guiButton.ZIndex = 2
if guiButton.BackgroundColor == primaryColor.BackgroundColor then
guiFrame.BackgroundColor = BrickColor.White()
selectedButtonTable[primaryColor] = guiButton
end
end
end
valueConnections[#valueConnections+1] = value.Changed:connect(function(newValue) changeColorSelection(primaryColor, paletteFrame, colorButtonTable[newValue.Number], selectedButtonTable) end)
return subFrame
end
function onObjectValueMouseClick(guiFrame, value, objectButton)
objectValueSelect["Value"] = value
objectValueSelect["Frame"] = guiFrame
objectValueSelect["Enabled"] = true
onObjectValueMouseLeave(value, objectButton)
end
function onObjectValueMouseEnter(value, objectButton)
objectValueSelect["HoverValue"] = value
if value.Value then
objectButton.BackgroundColor = BrickColor.Blue()
else
objectButton.BackgroundColor = BrickColor.White()
end
end
function onObjectValueMouseLeave(value, objectButton)
if objectValueSelect["HoverValue"] == value then
objectValueSelect["HoverValue"] = nil
end
objectButton.BackgroundColor = buttonColor
end
function onObjectValueCancel()
if objectValueSelect["Enabled"] then
objectValueSelect["Enabled"] = false
objectValueSelect["Frame"].Visible = true
objectValueSelect["Frame"] = nil
objectValueSelect["Value"] = nil
end
end
function on3dObjectValueButton1Up(mouse, guiMain)
local part = mouse.Target
if part ~= nil then
objectValueSelect["Value"].Value = part
objectValueSelect["Enabled"] = false
objectValueSelect["Frame"].Visible = true
objectValueSelect["Frame"] = nil
objectValueSelect["Value"] = nil
end
end
function on3dObjectValueMouseMove(mouse, guiMain)
end
function setObjectButtonText(guiFrame, objectButton, objectValue)
if objectValueSelect["Enabled"] and objectValue == objectValueSelect["Value"] then
guiFrame.Visible = true
objectValueSelect["Enabled"] = false
objectValueSelect["Value"] = nil
end
if objectValue.Value ~= nil then
objectButton.Text = objectValue.Value.Name
else
objectButton.Text = "[nil]"
end
objectButton.BackgroundColor = buttonColor
end
function processObjectValue(value, playerGui, guiFrame)
local subFrame = sharedProcess(value.Name, guiFrame)
local objectButton = Instance.new("TextButton")
objectButton.FontSize = textSize
objectButton.Position = UDim2.new(0.5, 2, 0.0, 2)
objectButton.Size = UDim2.new(0.5, -4, 1.0, -4)
objectButton.BackgroundColor = BrickColor.White()
objectButton.TextColor = BrickColor.Black()
objectButton.Parent = subFrame
objectButton.AutoButtonColor = false
objectButton.MouseButton1Click:connect(function() onObjectValueMouseClick(guiFrame, value, objectButton) end)
objectButton.MouseEnter:connect(function() onObjectValueMouseEnter(value, objectButton) end)
objectButton.MouseLeave:connect(function() onObjectValueMouseLeave(value, objectButton) end)
valueConnections[#valueConnections+1] = value.Changed:connect(function(newObjectValue) setObjectButtonText(guiFrame, objectButton, value) end)
setObjectButtonText(guiFrame, objectButton, value)
return subFrame
end
function processValue(value, playerGui, guiFrame)
if constrained(value) then origValueMap[value.Name] = value.ConstrainedValue
else origValueMap[value.Name] = value.Value end
if #value:GetChildren() > 0 and value:IsA("StringValue") then
return processEnumValue(value, guiFrame)
else
if value.className == "BoolValue" then
return processBoolValue(value, guiFrame)
elseif value.className == "IntValue" then
return processIntValue(value, guiFrame)
elseif value.className == "NumberValue" then
return processNumberValue(value, guiFrame)
elseif value.className == "StringValue" then
return processStringValue(value, guiFrame)
elseif value.className == "ObjectValue" then
return processObjectValue(value, playerGui, guiFrame)
elseif value.className == "BrickColorValue" then
return processBrickColorValue(value, guiFrame)
elseif value.className == "IntConstrainedValue" or value.className == "DoubleConstrainedValue" then
return processConstrainedNumberValue(value, guiFrame)
else
return nil
end
end
end
function killFrame(frame)
screen.Enabled = false
frame:remove()
end
function closeFrame(frame)
lastPart = nil
if frame.Parent == nil then return end
frame:TweenSizeAndPosition(UDim2.new(0,0,0,0),UDim2.new(0.5,0,0.5,0),Enum.EasingDirection.In,Enum.EasingStyle.Back,0.5, true, function() killFrame(frame) end)
end
function allowTween()
canTween = true
end
function openFrame(frame,size)
if not canTween then return end
canTween = false
screen.Enabled = true
frame.Size = UDim2.new(0,0,0,0)
frame.Position = UDim2.new(0.5,0,0.5,0)
frame:TweenSizeAndPosition(size,UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Back,0.5,true, function() allowTween() end)
end
function sharedMain(name, playerGui)
local parentFrame = Instance.new("Frame")
parentFrame.Style = Enum.FrameStyle.RobloxRound
parentFrame.Active = true
parentFrame.Name = "MainFrame"
parentFrame.Size = UDim2.new(1, 0, 1, 0)
parentFrame.BackgroundTransparency = 1
local titleLabel = Instance.new("TextLabel")
titleLabel.Name = "TitleLabel"
titleLabel.Font = Enum.Font.ArialBold
titleLabel.FontSize = textSize + 2
titleLabel.Size = UDim2.new(1.0, 0.0, 0.0, height)
titleLabel.TextColor = BrickColor.White()
titleLabel.BackgroundColor = BrickColor.new("Cool yellow")
titleLabel.BackgroundTransparency = 1
titleLabel.Text = name
titleLabel.Parent = parentFrame
local closeButton = Instance.new("TextButton")
closeButton.Name = "CloseButton"
closeButton.Style = Enum.ButtonStyle.RobloxButtonDefault
closeButton.Size = UDim2.new(0,20,0,20)
closeButton.Position = UDim2.new(1,-16,0,-5)
closeButton.Text = "X"
closeButton.TextColor3 = Color3.new(1,1,1)
closeButton.Font = Enum.Font.ArialBold
closeButton.FontSize = Enum.FontSize.Size18
closeButton.Parent = parentFrame
local closeCon = nil
closeCon = closeButton.MouseButton1Click:connect(function()
closeCon:disconnect()
removeBillboards()
screen.Enabled = false
cancelSelectionGui()
end)
local scrollFrame, scrollUpButton, scrollDownButton, recalculateFunction = RbxGui.CreateScrollingFrame()
gridRecalc = recalculateFunction
scrollFrame.Name = "ValueContainer"
scrollFrame.Size = UDim2.new(1,-17,1,-50)
scrollFrame.Position = UDim2.new(0,0,0,25)
scrollFrame.Parent = parentFrame
local changerCon = nil
delay(1,function()
if scrollFrame and scrollFrame.Parent then
changerCon = scrollFrame.Changed:connect(function(prop)
if prop == "AbsoluteSize" then
if scrollFrame.AbsoluteSize.Y < 38 then
changerCon:disconnect()
closeFrame(parentFrame)
else
gridRecalc()
end
end
end)
end
end)
local dieCon
dieCon = scrollFrame.AncestryChanged:connect(function(child,parent)
if parent == nil then
dieCon:disconnect()
if changerCon then changerCon:disconnect() end
end
end)
local scrollButtonFrame = Instance.new("Frame")
scrollButtonFrame.Name = "ScrollButtonFrame"
scrollButtonFrame.Position = UDim2.new(1,-17,0,25)
scrollButtonFrame.Size = UDim2.new(0,17,1,-50)
scrollButtonFrame.BackgroundTransparency = 1
scrollButtonFrame.Parent = parentFrame
scrollUpButton.Parent = scrollButtonFrame
scrollDownButton.Parent = scrollButtonFrame
scrollDownButton.Position = UDim2.new(0,0,1,-17)
return parentFrame
end
function sharedButtons(parentFrame, valueChildren)
local buttonFrame = Instance.new("Frame")
buttonFrame.Name = "Buttons"
buttonFrame.BackgroundTransparency = 1.0
buttonFrame.Size = UDim2.new(1.0, 0.0, 0.0, height)
buttonFrame.Position = UDim2.new(0.0, 0, 1, -25)
buttonFrame.Parent = parentFrame
valueChildren = valueChildren + 1
local okButton = Instance.new("TextButton")
okButton.FontSize = textSize
okButton.Name = "OkButton"
okButton.Font = Enum.Font.ArialBold
okButton.TextColor = BrickColor.White()
okButton.Style = Enum.ButtonStyle.RobloxButton
okButton.Text = "Ok"
okButton.Size = UDim2.new(.25, -4, 0.0, height + 5)
okButton.Position = UDim2.new(0.55, 2, 0.0, 2)
okButton.BackgroundColor = buttonColor
okButton.MouseButton1Click:connect(function() removeSelectionGui() end)
okButton.Parent = buttonFrame
local cancelButton = okButton:clone()
cancelButton.Name = "cancelButton"
cancelButton.Text = "Cancel"
cancelButton.Position = UDim2.new(0.200000003, 2, 0, 2)
cancelButton.MouseButton1Click:connect(function() cancelSelectionGui() end)
cancelButton.Parent = buttonFrame
end
function processVehicleSeat(vehicleSeat, playerGui, valueChildren)
local parentFrame = sharedMain(vehicleSeat.Name, playerGui)
lastVehicleSeat = vehicleSeat
local valueChildren = 1
local fields = {"MaxSpeed", "Steer", "Torque", "TurnSpeed"}
for pos, field in pairs(fields) do
local newFrame = processPropertyValue(vehicleSeat, field, field, guiFrame)
if newFrame then
newFrame.Position = UDim2.new(0.0, 0, 0.0, (valueChildren*height) - height)
newFrame.Parent = parentFrame.ValueContainer
valueChildren = valueChildren + 1
end
end
sharedButtons(parentFrame, valueChildren)
return parentFrame
end
function processConfiguration(config, playerGui)
local parentFrame = sharedMain(config.Name, playerGui)
lastConfig = config
local valueChildren = 1
local children = config:GetChildren()
if children then
for pos, child in pairs(children) do
local newFrame = processValue(child, playerGui, parentFrame)
if newFrame then
newFrame.Position = UDim2.new(0.0, 0, 0.0, (valueChildren*height) - height)
newFrame.Parent = parentFrame.ValueContainer
valueChildren = valueChildren + 1
end
end
end
sharedButtons(parentFrame, valueChildren)
return parentFrame
end
function on3dMouseMove(mouse, guiMain)
if mouse.Target and canSelectObject(mouse.Target) then
local part = mouse.Target
if part:IsA("VehicleSeat") then
foundPart = part
else
foundPart = findConfiguration(part)
end
if foundPart then
if objectValueSelect["HoverBox"] then
local isModel, model = isInModel(part)
local adornee = part
if isModel then
adornee = model
end
objectValueSelect["HoverBox"].Adornee = adornee
local billboard = getBillboard(adornee)
local configBadge = billboard:FindFirstChild("ConfigBadge",true)
if configBadge then
configBadge.Image = configIconOverImage
highlightedImage = configBadge
end
end
needsIconReset = true
else
if needsIconReset then
if objectValueSelect["HoverBox"] then objectValueSelect["HoverBox"].Adornee = nil end
needsIconReset = false
if highlightedImage then
highlightedImage.Image = configIconImage
end
end
end
else
if needsIconReset then
if objectValueSelect["HoverBox"] then objectValueSelect["HoverBox"].Adornee = nil end
needsIconReset = false
if highlightedImage then
highlightedImage.Image = configIconImage
end
end
end
if objectValueSelect["Enabled"] then
on3dObjectValueMouseMove(mouse, guiMain)
end
end
function cancelSelectionGui()
lastPart = nil
if selectionGui ~= nil then
closeFrame(selectionGui)
selectionGui = nil
for pos, connection in pairs(valueConnections) do
connection:disconnect()
end
valueConnections = {}
end
showConfigurationAnnotations()
if lastConfig then
local configValues = lastConfig:GetChildren()
for i = 1, #configValues do
if origValueMap[configValues[i].Name] ~= nil then
if constrained(configValues[i]) then configValues[i].ConstrainedValue = origValueMap[configValues[i].Name]
else configValues[i].Value = origValueMap[configValues[i].Name] end
origValueMap[configValues[i].Name] = nil
end
end
elseif lastVehicleSeat then
lastVehicleSeat.MaxSpeed = origValueMap["MaxSpeed"]
origValueMap["MaxSpeed"] = nil
lastVehicleSeat.Steer = origValueMap["Steer"]
origValueMap["Steer"] = nil
lastVehicleSeat.Torque = origValueMap["Torque"]
origValueMap["Torque"] = nil
lastVehicleSeat.TurnSpeed = origValueMap["TurnSpeed"]
origValueMap["TurnSpeed"] = nil
end
end
function removeSelectionGui()
if selectionGui ~= nil then
closeFrame(selectionGui)
for pos, connection in pairs(valueConnections) do
connection:disconnect()
end
valueConnections = {}
end
if objectValueSelect["HoverBox"] then objectValueSelect["HoverBox"].Adornee = nil end
showConfigurationAnnotations()
if lastConfig then
local configValues = lastConfig:GetChildren()
for i = 1, #configValues do
if origValueMap[configValues[i].Name] ~= nil then
origValueMap[configValues[i].Name] = nil
end
end
end
end
function canSelectObject(part)
if isRestricted then
waitForChild(playerArea,"PlayerArea")
if isRestricted and playerArea:FindFirstChild("PlayerArea") and part:IsDescendantOf(playerArea.PlayerArea) then
return part and not (part.Locked) and part:IsA("BasePart")
else
return false
end
end
return part and not (part.Locked) and part:IsA("BasePart")
end
local function findConfigInModel(model)
local children = model:GetChildren()
for i = 1, #children do
if children[i]:IsA("Configuration") or children[i]:IsA("VehicleSeat") then
return children[i]
end
end
for i = 1, #children do
if #children[i]:GetChildren() > 0 then
local returnValue = findConfigInModel(children[i])
if returnValue ~= nil then
return returnValue
end
end
end
return nil
end
function findConfiguration(part)
local partInModel, model = isInModel(part)
if partInModel then
local isModelConfig = findConfigInModel(model)
return isModelConfig
else
local children = part:GetChildren()
if children then
for pos, child in pairs(children) do
if child:IsA("Configuration") or child:IsA("VehicleSeat") then
return child
end
end
end
end
return nil
end
function removeBillboards()
local guis = guiMain:GetChildren()
for i = 1, #guis do
if guis[i]:IsA("Frame") then
guis[i]:remove()
end
end
end
function on3dButton1Up(mouse, guiMain, playerGui)
if objectValueSelect["Enabled"] then
on3dObjectValueButton1Up(mouse, guiMain)
return
elseif canSelectObject(mouse.Target) then
local part = mouse.Target
local foundPart = nil
if part:IsA("VehicleSeat") then
foundPart = part
else
foundPart = findConfiguration(part)
end
if foundPart then
if foundPart == lastPart then
return
end
lastPart = foundPart
removeBillboards()
screen.Enabled = true
if foundPart:IsA("Configuration") then
selectionGui = processConfiguration(foundPart, playerGui)
else
selectionGui = processVehicleSeat(foundPart, playerGui)
end
selectionGui.Parent = guiMain
openFrame(selectionGui, selectionGui.Size)
local hasModel, model = isInModel(part)
if hasModel then
screen.Adornee = model
else
screen.Adornee = part
end
if highlightedImage then
highlightedImage.Image = configIconImage
end
end
else
cancelSelectionGui()
end
end
function onEquippedLocal(mouse)
local character = script.Parent.Parent
player = game.Players:GetPlayerFromCharacter(character)
if player == nil then return end
if playerOwner.Value and playerOwner.Value ~= player then return end
playerOwner.Value = player
if isRestricted then
waitForChild(game.Workspace,"BuildingAreas")
waitForChild(game.Workspace.BuildingAreas,"Area1")
waitForChild(game.Workspace.BuildingAreas.Area1,"Player")
local areas = game.Workspace.BuildingAreas:GetChildren()
for i = 1, #areas do
if areas[i]:FindFirstChild("Player") and areas[i].Player.Value == player.Name then
playerArea = areas[i]
break
end
end
waitForChild(playerArea,"PlayerArea")
STATIC_BASE_PLATE = playerArea.PlayerArea
end
if not screen then
screen = Instance.new("BillboardGui")
screen.Name = "ConfigGui"
screen.Size = UDim2.new(0,360,0,180)
screen.Enabled = false
screen.Active = true
screen.Parent = player.PlayerGui
screen.AlwaysOnTop = true
guiMain = Instance.new("Frame")
guiMain.BackgroundTransparency = 1
guiMain.Size = UDim2.new(1,0,1,0)
guiMain.Parent = screen
else
removeBillboards()
lastPart = nil
screen.Parent = player.PlayerGui
end
setUpConfigurationService(guiMain)
showConfigurationAnnotations()
mouse.Icon = "http://www.roblox.com/asset?id=66887593"
mouse.Button1Up:connect(function() on3dButton1Up(mouse, guiMain, player.PlayerGui) end)
mouse.Move:connect(function() on3dMouseMove(mouse, guiMain) end)
objectValueSelect.HoverBox = Instance.new("SelectionBox")
objectValueSelect.HoverBox.Name = "HoverBox"
objectValueSelect.HoverBox.Color = BrickColor.new("Really blue")
objectValueSelect.HoverBox.Transparency = 0.5
objectValueSelect.HoverBox.Adornee = nil
objectValueSelect.HoverBox.Parent = player.PlayerGui;
end
function onUnequippedLocal()
local guiChildren = game.Players.LocalPlayer.PlayerGui:GetChildren()
for i = 1, #guiChildren do
if guiChildren[i]:IsA("BillboardGui") then
guiChildren[i].Parent = nil
end
end
destroyConfigurationService()
objectValueSelect.HoverBox:Remove()
if screen then
screen.Parent = nil
end
player = nil
hideConfigurationAnnotations()
objectValueSelect = {}
end
local configTable = {}
function createVisualAnnotation(config, guiMain)
local selection = Instance.new("SelectionBox")
selection.Name = "Annotation"
selection.Color = BrickColor.new("Really blue")
selection.Transparency = 0.5
selection.Parent = guiMain.Parent
return selection
end
function configurationParentChanged(data, part)
local isModel, model = isInModel(part)
if not isModel then
data["VisualAnnotation"].Adornee = part
else
data["VisualAnnotation"].Adornee = model
end
end
function showConfigurationAnnotations()
for config, data in pairs(configTable) do
data["VisualAnnotation"].Visible = true
end
end
function hideConfigurationAnnotations()
for config, data in pairs(configTable) do
data["VisualAnnotation"].Visible = false
end
end
local function isInMyArea(part)
if part.Parent == nil then return false end
if part.Parent:FindFirstChild("Player") and part.Parent.Player:IsA("StringValue") then
if part.Parent.Player.Value == player.Name then
return true
else
return false
end
elseif part.Parent == game.Workspace.BuildingAreas or part.Parent == game.Workspace then
return false
else
return isInMyArea(part.Parent)
end
end
function findBillboard(guiTable)
if not guiTable then return end
for i = 1, #guiTable do
if guiTable[i] and guiTable[i]:IsA("BillboardGui") then
return guiTable[i]
end
end
end
function getBillboard(adornee)
local guiKey = adornee
local billboard = findBillboard(adornmentTable[guiKey])
if not billboard then
local screen = Instance.new("BillboardGui")
screen.Name = adornee.Name .. "BadgeGUI"
screen.Size = UDim2.new(1.5,0,1.5,0)
screen.Enabled = true
screen.Active = true
screen.AlwaysOnTop = true
screen.ExtentsOffset = Vector3.new(0,0,0)
screen.Adornee = adornee
screen.Parent = game.Players.LocalPlayer.PlayerGui
if not adornmentTable[guiKey] then
adornmentTable[guiKey] = {}
end
table.insert(adornmentTable[guiKey],screen)
return screen
end
return billboard
end
function hasBadge(adornee)
local screen = getBillboard(adornee)
if not screen then return false end
return screen:FindFirstChild("Badge",true)
end
function removeBadge(adornee)
local screen = getBillboard(adornee)
local badge = screen:FindFirstChild("ConfigBadge",true)
if badge then badge:remove() end
end
function giveConfigBadge(adornee)
local billboard = getBillboard(adornee)
local configBadge = Instance.new("ImageLabel")
configBadge.Name = "ConfigBadge"
configBadge.BackgroundTransparency = 1
configBadge.Image = configIconImage
configBadge.Size = UDim2.new(1,0,1,0)
configBadge.Parent = billboard
billboard.Parent = game.Players.LocalPlayer.PlayerGui
local badgeCon = configBadge.Changed:connect(function(prop)
if prop == "AbsoluteSize" then
configBadge.Visible = (configBadge.AbsoluteSize.X > 10)
end
end)
local enterCon = configBadge.MouseEnter:connect(function()
configBadge.Image = configIconHoverImage
end)
local leaveCon = configBadge.MouseLeave:connect(function()
configBadge.Image = configIconImage
end)
local killCon = nil
killCon = configBadge.AncestryChanged:connect(function(child,parent)
if parent == nil then
killCon:disconnect()
badgeCon:disconnect()
enterCon:disconnect()
leaveCon:disconnect()
end
end)
end
function configurationAdded(config, guiMain)
if configTable[config] then
return
end
if isRestricted and not inBaseplate(config) then return end
local data = {}
data.Configuration = config
data.VisualAnnotation = createVisualAnnotation(config, guiMain)
if config:IsA("Configuration") then
data.Connection = config.AncestryChanged:connect(function(child, newParent)
if child == config then
configurationParentChanged(data, newParent)
end
end)
configurationParentChanged(data, config.Parent)
else
configurationParentChanged(data, config)
end
local partInModel, model = isInModel(config.Parent)
if partInModel then
if not hasBadge(model) then
giveConfigBadge(model)
end
else
if not hasBadge(config.Parent) then
giveConfigBadge(config.Parent)
end
end
configTable[config] = data
end
function configurationRemoved(config)
local data = configTable[config]
if not(data) then
--I have no opinion about this
return
end
if data.Connection then
data.Connection:disconnect()
end
data.VisualAnnotation:Remove()
removeBadge(config.Parent)
configTable[config] = nil
end
function findVehicleSeats(object, guiMain)
if object:IsA("VehicleSeat") then
configurationAdded(object, guiMain)
end
for index,child in pairs(object:GetChildren()) do
findVehicleSeats(child, guiMain)
end
end
function setUpConfigurationService(guiMain)
ServiceConnections = {}
local collectionService = game:GetService("CollectionService")
ServiceConnections[#ServiceConnections+1] = collectionService.ItemAdded:connect(function(instance) if instance:IsA("Configuration") then configurationAdded(instance, guiMain) end end)
ServiceConnections[#ServiceConnections+1] = collectionService.ItemRemoved:connect(function(instance) if instance:IsA("Configuration") then configurationRemoved(instance) end end)
local configs = collectionService:GetCollection("Configuration")
if configs then
for pos, config in pairs(configs) do
configurationAdded(config, guiMain)
end
end
ServiceConnections[#ServiceConnections+1] = game.workspace.DescendantAdded:connect(function(instance) if instance:IsA("VehicleSeat") then configurationAdded(instance, guiMain) end end)
ServiceConnections[#ServiceConnections+1] = game.workspace.DescendantRemoving:connect(function(instance) if instance:IsA("VehicleSeat") then configurationRemoved(instance) end end)
findVehicleSeats(game.workspace, guiMain)
end
function destroyConfigurationService()
for config, data in pairs(configTable) do
configurationRemoved(config)
end
for index, connection in pairs(ServiceConnections) do
connection:disconnect()
end
ServiceConnections = {}
end
Tool.Equipped:connect(onEquippedLocal)
Tool.Unequipped:connect(onUnequippedLocal)
-
PlayerOwner
[null]