roblonium-web/Game/FinobeTools/ClassicTool.rbxm

2319 lines
76 KiB
Plaintext

<roblox xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.roblox.com/roblox.xsd" version="4">
<External>null</External>
<External>nil</External>
<Item class="Tool" referent="RBX0">
<Properties>
<bool name="Enabled">true</bool>
<CoordinateFrame name="Grip">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
<R00>1</R00>
<R01>0</R01>
<R02>0</R02>
<R10>0</R10>
<R11>1</R11>
<R12>0</R12>
<R20>0</R20>
<R21>0</R21>
<R22>1</R22>
</CoordinateFrame>
<string name="Name">ClassicTool</string>
<Content name="TextureId"><url>http://www.roblox.com/asset/?id=59105322</url></Content>
</Properties>
<Item class="LocalScript" referent="RBX1">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">ClassicToolController</string>
<ProtectedString name="Source">local Tool = script.Parent
local keyUpCon = nil
local gui = nil
local connections = {}
local buttons = {}
local colorButton,SurfaceButton,MaterialButton,ResizeButton,draggerButton = nil
game:GetService(&quot;ContentProvider&quot;):Preload(&quot;http://www.roblox.com/asset?id=59103051&quot;)
game:GetService(&quot;ContentProvider&quot;):Preload(&quot;http://www.roblox.com/asset?id=59103080&quot;)
game:GetService(&quot;ContentProvider&quot;):Preload(&quot;http://www.roblox.com/asset?id=59103092&quot;)
game:GetService(&quot;ContentProvider&quot;):Preload(&quot;http://www.roblox.com/asset?id=59103119&quot;)
game:GetService(&quot;ContentProvider&quot;):Preload(&quot;http://www.roblox.com/asset?id=59103152&quot;)
function makeImageButton(buttonName, image, position, parent, hotKeyString)
&#9;local button = Instance.new(&quot;ImageButton&quot;)
&#9;button.Name = buttonName
&#9;button.Style = Enum.ButtonStyle.RobloxButton
&#9;button.Size = UDim2.new(0,45,0,45)
&#9;if position then button.Position = position end
&#9;button.Parent = parent
&#9;local buttonImage = Instance.new(&quot;ImageLabel&quot;)
&#9;buttonImage.Name = &quot;ButtonImage&quot;
&#9;buttonImage.BackgroundTransparency = 1
&#9;buttonImage.Size = UDim2.new(1,12,1,12)
&#9;buttonImage.Position = UDim2.new(0,-6,0,-6)
&#9;buttonImage.Image = image
&#9;buttonImage.Parent = button
&#9;if hotKeyString then
&#9;&#9;local textShortcut = Instance.new(&quot;TextLabel&quot;)
&#9;&#9;textShortcut.Text = hotKeyString
&#9;&#9;textShortcut.Name = &quot;TextShortcut&quot;
&#9;&#9;textShortcut.Font = Enum.Font.ArialBold
&#9;&#9;textShortcut.BackgroundTransparency = 1
&#9;&#9;textShortcut.FontSize = Enum.FontSize.Size14
&#9;&#9;textShortcut.TextColor3 = Color3.new(1,1,1)
&#9;&#9;textShortcut.Size = UDim2.new(0,textShortcut.TextBounds.X,0,textShortcut.TextBounds.X)
&#9;&#9;textShortcut.Parent = button
&#9;end
&#9;return button
end
function deactivateTool(script)
&#9;local enable = script:FindFirstChild(&quot;Active&quot;)
&#9;if enable and enable:IsA(&quot;BoolValue&quot;) then
&#9;&#9;enable.Value = false
&#9;end
end
function deactivateAllTools()
&#9;local toolChildren = Tool:GetChildren()
&#9;for i = 1, #toolChildren do
&#9;&#9;if toolChildren[i]:IsA(&quot;BaseScript&quot;) and toolChildren[i] ~= script then
&#9;&#9;&#9;deactivateTool(toolChildren[i])
&#9;&#9;end
&#9;end
&#9;for i = 1, #buttons do
&#9;&#9;buttons[i].Selected = false
&#9;end
end
function goToTool(toolName, button)
&#9;deactivateAllTools()
&#9;button.Selected = true
&#9;wait() -- give scripts a heartbeat to get set straight
&#9;local toolScript = Tool:FindFirstChild(toolName)
&#9;if toolScript and toolScript:IsA(&quot;BaseScript&quot;) then
&#9;&#9;local enable = toolScript:FindFirstChild(&quot;Active&quot;)
&#9;&#9;if enable and enable:IsA(&quot;BoolValue&quot;) then
&#9;&#9;&#9;enable.Value = true
&#9;&#9;end
&#9;end
end
function makeClassicControlGui()
&#9;clearAllConnections()
&#9;local classicGui = Instance.new(&quot;ScreenGui&quot;)
&#9;classicGui.Name = &quot;ClassicGui&quot;
&#9;
&#9;local classicFrame = Instance.new(&quot;Frame&quot;)
&#9;classicFrame.Name = &quot;ClassicFrame&quot;
&#9;classicFrame.BackgroundTransparency = 1
&#9;classicFrame.Size = UDim2.new(0,246,0,45)
&#9;classicFrame.Position = UDim2.new(0.5, -113, 1, -130)
&#9;classicFrame.Parent = classicGui
&#9;colorButton = makeImageButton(&quot;ColorButton&quot;,&quot;http://www.roblox.com/asset?id=59103051&quot;,UDim2.new(0,0,0.5,-23), classicFrame, &quot;F&quot;)
&#9;local colorCon = colorButton.MouseButton1Click:connect(function() goToTool(&quot;Color&quot;, colorButton) end)
&#9;table.insert(connections,colorCon)
&#9;table.insert(buttons,colorButton)
&#9;SurfaceButton = makeImageButton(&quot;SurfaceButton&quot;,&quot;http://www.roblox.com/asset?id=59103080&quot;,UDim2.new(0,90,0.5,-23), classicFrame, &quot;H&quot;)
&#9;local surfaceCon = SurfaceButton.MouseButton1Click:connect(function() goToTool(&quot;Surface&quot;, SurfaceButton) end)
&#9;table.insert(connections,surfaceCon)
&#9;table.insert(buttons,SurfaceButton)
&#9;MaterialButton = makeImageButton(&quot;MaterialButton&quot;,&quot;http://www.roblox.com/asset?id=59103092&quot;,UDim2.new(0,45,0.5,-23), classicFrame, &quot;G&quot;)
&#9;local materialCon = MaterialButton.MouseButton1Click:connect(function() goToTool(&quot;Material&quot;, MaterialButton) end)
&#9;table.insert(connections,materialCon)
&#9;table.insert(buttons,MaterialButton)
&#9;ResizeButton = makeImageButton(&quot;ResizeButton&quot;,&quot;http://www.roblox.com/asset?id=59103119&quot;,UDim2.new(0,180,0.5,-23), classicFrame, &quot;K&quot;)
&#9;local resizeCon = ResizeButton.MouseButton1Click:connect(function() goToTool(&quot;Resize&quot;, ResizeButton) end)
&#9;table.insert(connections,resizeCon)
&#9;table.insert(buttons,ResizeButton)
&#9;draggerButton = makeImageButton(&quot;ResizeButton&quot;,&quot;http://www.roblox.com/asset?id=59103152&quot;,UDim2.new(0,135,0.5,-23), classicFrame, &quot;J&quot;)
&#9;local draggerCon = draggerButton.MouseButton1Click:connect(function() goToTool(&quot;Dragger&quot;, draggerButton) end)
&#9;table.insert(connections,draggerCon)
&#9;table.insert(buttons,draggerButton)
&#9;return classicGui
end
function clearAllConnections()
&#9;for i = 1, #connections do
&#9;&#9;connections[i]:disconnect()
&#9;end
&#9;connections = {}
end
function hotKey(key)
&#9;key = key:lower()
&#9;if key == &quot;f&quot; then
&#9;&#9;goToTool(&quot;Color&quot;, colorButton)
&#9;elseif key == &quot;g&quot; then
&#9;&#9;goToTool(&quot;Material&quot;, MaterialButton)
&#9;elseif key == &quot;h&quot; then
&#9;&#9;goToTool(&quot;Surface&quot;, SurfaceButton)
&#9;elseif key == &quot;j&quot; then
&#9;&#9;goToTool(&quot;Dragger&quot;, draggerButton)
&#9;elseif key == &quot;k&quot; then
&#9;&#9;goToTool(&quot;Resize&quot;, ResizeButton)
&#9;end
end
function onEquippedLocal(mouse)
&#9;Tool.Mouse.Value = mouse
&#9;if not gui then
&#9;&#9;gui = makeClassicControlGui()
&#9;end
&#9;gui.Parent = game.Players.LocalPlayer.PlayerGui
&#9;keyUpCon = mouse.KeyUp:connect(function(key) hotKey(key) end)
end
function onUnequippedLocal()
&#9;if keyUpCon then keyUpCon:disconnect() end
&#9;deactivateAllTools()
&#9;gui.Parent = nil&#9;
end
Tool.Equipped:connect(onEquippedLocal)
Tool.Unequipped:connect(onUnequippedLocal)
</ProtectedString>
</Properties>
</Item>
<Item class="Part" referent="RBX2">
<Properties>
<bool name="Anchored">false</bool>
<float name="BackParamA">-0.5</float>
<float name="BackParamB">0.5</float>
<token name="BackSurface">0</token>
<token name="BackSurfaceInput">0</token>
<float name="BottomParamA">-0.5</float>
<float name="BottomParamB">0.5</float>
<token name="BottomSurface">0</token>
<token name="BottomSurfaceInput">0</token>
<int name="BrickColor">199</int>
<CoordinateFrame name="CFrame">
<X>0.999433637</X>
<Y>7.98012686</Y>
<Z>-12.5012054</Z>
<R00>-1.50203878e-005</R00>
<R01>1.50579854e-006</R01>
<R02>-1.00000012</R02>
<R10>9.8371238e-006</R10>
<R11>1</R11>
<R12>1.50565256e-006</R12>
<R20>1.00000012</R20>
<R21>-9.83710197e-006</R21>
<R22>-1.50204023e-005</R22>
</CoordinateFrame>
<bool name="CanCollide">true</bool>
<float name="Elasticity">0.5</float>
<float name="Friction">0.300000012</float>
<float name="FrontParamA">-0.5</float>
<float name="FrontParamB">0.5</float>
<token name="FrontSurface">0</token>
<token name="FrontSurfaceInput">0</token>
<float name="LeftParamA">-0.5</float>
<float name="LeftParamB">0.5</float>
<token name="LeftSurface">0</token>
<token name="LeftSurfaceInput">0</token>
<bool name="Locked">true</bool>
<token name="Material">256</token>
<string name="Name">Handle</string>
<float name="Reflectance">0</float>
<float name="RightParamA">-0.5</float>
<float name="RightParamB">0.5</float>
<token name="RightSurface">0</token>
<token name="RightSurfaceInput">0</token>
<Vector3 name="RotVelocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<float name="TopParamA">-0.5</float>
<float name="TopParamB">0.5</float>
<token name="TopSurface">0</token>
<token name="TopSurfaceInput">0</token>
<float name="Transparency">0</float>
<Vector3 name="Velocity">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<token name="formFactorRaw">2</token>
<token name="shape">1</token>
<Vector3 name="size">
<X>1</X>
<Y>0.800000012</Y>
<Z>2</Z>
</Vector3>
</Properties>
<Item class="SpecialMesh" referent="RBX3">
<Properties>
<token name="LODX">2</token>
<token name="LODY">2</token>
<Content name="MeshId"><url>http://www.roblox.com/asset/?id=15952510</url></Content>
<token name="MeshType">5</token>
<string name="Name">Mesh</string>
<Vector3 name="Offset">
<X>0</X>
<Y>0</Y>
<Z>0</Z>
</Vector3>
<Vector3 name="Scale">
<X>0.400000006</X>
<Y>0.400000006</Y>
<Z>0.400000006</Z>
</Vector3>
<Content name="TextureId"><url>http://www.roblox.com/asset/?id=15952494</url></Content>
<Vector3 name="VertexColor">
<X>1</X>
<Y>1</Y>
<Z>1</Z>
</Vector3>
</Properties>
</Item>
<Item class="Sound" referent="RBX4">
<Properties>
<bool name="Looped">false</bool>
<string name="Name">Sound</string>
<float name="Pitch">1</float>
<bool name="PlayOnRemove">false</bool>
<Content name="SoundId"><url>rbxasset://sounds/swordslash.wav</url></Content>
<float name="Volume">1</float>
</Properties>
</Item>
<Item class="Sound" referent="RBX5">
<Properties>
<bool name="Looped">false</bool>
<string name="Name">Sound</string>
<float name="Pitch">1</float>
<bool name="PlayOnRemove">false</bool>
<Content name="SoundId"><url>rbxasset://sounds/unsheath.wav</url></Content>
<float name="Volume">1</float>
</Properties>
</Item>
<Item class="Sound" referent="RBX6">
<Properties>
<bool name="Looped">false</bool>
<string name="Name">Sound</string>
<float name="Pitch">1</float>
<bool name="PlayOnRemove">false</bool>
<Content name="SoundId"><url>rbxasset://sounds/swordslash.wav</url></Content>
<float name="Volume">1</float>
</Properties>
</Item>
<Item class="Sound" referent="RBX7">
<Properties>
<bool name="Looped">false</bool>
<string name="Name">Sound</string>
<float name="Pitch">1</float>
<bool name="PlayOnRemove">false</bool>
<Content name="SoundId"><url>rbxasset://sounds/unsheath.wav</url></Content>
<float name="Volume">1</float>
</Properties>
</Item>
</Item>
<Item class="LocalScript" referent="RBX8">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">Color</string>
<ProtectedString name="Source">-- basic functions
function waitForChild(instance, name)
&#9;while not instance:findFirstChild(name) do
&#9;&#9;instance.ChildAdded:wait()
&#9;end
end
local Tool = script.Parent
enabled = true
local menu
local origTexture = &#9;Tool.TextureId
local localAssetBase = &quot;rbxasset://textures/ui/&quot;
local currentColorButton = nil
game:GetService(&quot;ContentProvider&quot;):Preload(&quot;rbxasset://icons/color_sel.png&quot;)
local buttonDownCon, mouseMoveCon
local clickCons = {}
function onButton1Down(mouse)
&#9;if not enabled then
&#9;&#9;return
&#9;end
&#9;enabled = false
&#9;mouse.Icon = &quot;rbxasset://textures\\GunWaitCursor.png&quot;
&#9;wait(.5)
&#9;mouse.Icon = &quot;rbxasset://textures\\GunCursor.png&quot;
&#9;enabled = true
end
local selectionBox
local selectionLasso
function setSelectionBox(part)
&#9;unsetSelectionBox()
&#9;selectionBox.Adornee = part
&#9;selectionLasso.Part = part
end
function unsetSelectionBox()
&#9;selectionBox.Adornee = nil
&#9;selectionLasso.Part = nil
end
function canSelectObject(part)
&#9;return part and not (part.Locked) and (part.Position - Tool.Parent.Head.Position).Magnitude &lt; 60
end
function on3dButton1Down(mouse)
&#9;local part = mouse.Target
&#9;if canSelectObject(part) then
&#9;&#9;if Instance.Lock(part) then
&#9;&#9;&#9;color = Tool.Color.CurrentColor.Value
&#9;&#9;&#9;if color == nil then
&#9;&#9;&#9;&#9;Instance.Unlock(part)
&#9;&#9;&#9;&#9;return
&#9;&#9;&#9;end
&#9;&#9;&#9;part.BrickColor = color
&#9;&#9;&#9;Instance.Unlock(part)
&#9;&#9;end
&#9;end
end
function on3dMouseMove(mouse)
&#9;mouse.Icon =&quot;rbxasset://textures\\FillCursor.png&quot;
&#9;local part = mouse.Target
&#9;if canSelectObject(part) then
&#9;&#9;setSelectionBox(part)
&#9;else
&#9;&#9;unsetSelectionBox()
&#9;end
end
function makeColorMenu()
&#9;local paintGui = Instance.new(&quot;ScreenGui&quot;)
&#9;paintGui.Name = &quot;PaintGui&quot;
&#9;local paintMenu = Instance.new(&quot;ImageLabel&quot;)
&#9;paintMenu.Name = &quot;PaintMenu&quot;
&#9;paintMenu.Position = UDim2.new(0,0,1,-600)
&#9;paintMenu.Size = UDim2.new(0,120,0,500)
&#9;paintMenu.BackgroundTransparency = 1
&#9;paintMenu.ZIndex = 2
&#9;paintMenu.Image = localAssetBase .. &quot;PaintMenu.png&quot;
&#9;paintMenu.Parent = paintGui
&#9;local paintColorButton = Instance.new(&quot;ImageButton&quot;)
&#9;paintColorButton.BorderSizePixel = 0
&#9;paintColorButton.ZIndex = 3
&#9;paintColorButton.Size = UDim2.new(0.200000003, 0,0.0500000007, 0)
&#9;local selection = Instance.new(&quot;Frame&quot;)
&#9;selection.Name = &quot;Selection&quot;
&#9;selection.BorderSizePixel = 0
&#9;selection.BackgroundColor3 = Color3.new(1,1,1)
&#9;selection.BackgroundTransparency = 1
&#9;selection.ZIndex = 2
&#9;selection.Size = UDim2.new(1.1,0,1.1,0)
&#9;selection.Position = UDim2.new(-0.05,0,-0.05,0)
&#9;selection.Parent = paintColorButton
&#9;local header = 0.08
&#9;local spacing = 18
&#9;local count = 1
&#9;local function findNextColor()
&#9;&#9;colorName = tostring(BrickColor.new(count))
&#9;&#9;while colorName == &quot;Medium stone grey&quot; do
&#9;&#9;&#9;count = count + 1
&#9;&#9;&#9;colorName = tostring(BrickColor.new(count))
&#9;&#9;end
&#9;&#9;return count
&#9;end
&#9;for i = 0,15 do
&#9;&#9;for j = 1, 4 do
&#9;&#9;&#9;newButton = paintColorButton:clone()
&#9;&#9;&#9;newButton.BackgroundColor3 = BrickColor.new(findNextColor()).Color
&#9;&#9;&#9;newButton.Name = tostring(BrickColor.new(count))
&#9;&#9;&#9;count = count + 1
&#9;&#9;&#9;if j == 1 then newButton.Position = UDim2.new(0.08,0,i/spacing + header,0)
&#9;&#9;&#9;elseif j == 2 then newButton.Position = UDim2.new(0.29,0,i/spacing + header,0)
&#9;&#9;&#9;elseif j == 3 then newButton.Position = UDim2.new(0.5,0,i/spacing + header,0)
&#9;&#9;&#9;elseif j == 4 then newButton.Position = UDim2.new(0.71,0,i/spacing + header,0) end
&#9;&#9;&#9;newButton.Parent = paintMenu
&#9;&#9;end
&#9;end
&#9;local paintButtons = paintMenu:GetChildren()
&#9;for i = 1, #paintButtons do
&#9;&#9;local newCon = paintButtons[i].MouseButton1Click:connect(function()
&#9;&#9;&#9;Tool.Color.CurrentColor.Value = BrickColor.new(paintButtons[i].Name)
&#9;&#9;&#9;if currentColorButton then
&#9;&#9;&#9;&#9;if currentColorButton:FindFirstChild(&quot;Selection&quot;) then
&#9;&#9;&#9;&#9;&#9;currentColorButton.Selection.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;currentColorButton = paintButtons[i]
&#9;&#9;&#9;paintButtons[i].Selection.BackgroundTransparency = 0
&#9;&#9;end)
&#9;&#9;local anotherCon = paintButtons[i].MouseEnter:connect(function()
&#9;&#9;&#9;paintButtons[i].Selection.BackgroundTransparency = 0
&#9;&#9;end)
&#9;&#9;local oneMoreCon = paintButtons[i].MouseLeave:connect(function()
&#9;&#9;&#9;if paintButtons[i] ~= currentColorButton then paintButtons[i].Selection.BackgroundTransparency = 1 end
&#9;&#9;end)
&#9;&#9;table.insert(clickCons,newCon)
&#9;&#9;table.insert(clickCons,anotherCon)
&#9;&#9;table.insert(clickCons,oneMoreCon)
&#9;end
&#9;return paintGui
end
function onEquippedLocal(mouse)
&#9;Tool.TextureId = &quot;rbxasset://icons/color_sel.png&quot;
&#9;local character = script.Parent.Parent
&#9;local player = game.Players:GetPlayerFromCharacter(character)
&#9;buttonDownCon = mouse.Button1Down:connect(function() on3dButton1Down(mouse) end)
&#9;mouseMoveCon = mouse.Move:connect(function() on3dMouseMove(mouse) end)
&#9;mouse.Icon =&quot;rbxasset://textures\\FillCursor.png&quot;
&#9;selectionBox = Instance.new(&quot;SelectionBox&quot;)
&#9;selectionBox.Color = Tool.Color.CurrentColor.Value
&#9;selectionBox.Adornee = nil
&#9;selectionBox.Parent = player.PlayerGui
&#9;selectionLasso = Instance.new(&quot;SelectionPartLasso&quot;)
&#9;selectionLasso.Name = &quot;Model Delete Lasso&quot;
&#9;selectionLasso.Humanoid = character.Humanoid
&#9;selectionLasso.Part = nil
&#9;selectionLasso.Visible = true
&#9;selectionLasso.archivable = false
&#9;selectionLasso.Color = Tool.Color.CurrentColor.Value
&#9;selectionLasso.Parent = game.workspace
&#9;menu = makeColorMenu()
&#9;menu.Parent = game.Players.LocalPlayer.PlayerGui
end
function onUnequippedLocal()
&#9;if menu then menu:remove() end
&#9;Tool.TextureId = origTexture
&#9;for i = 1, #clickCons do
&#9;&#9;clickCons[i]:disconnect()
&#9;end
&#9;clickCons = {}
&#9;if selectionBox then selectionBox:Remove() end
&#9;if selectionLasso then selectionLasso:Remove() end
&#9;if mouseMoveCon then mouseMoveCon:disconnect() end
&#9;if buttonDownCon then buttonDownCon:disconnect() end
end
waitForChild(Tool.Color,&quot;CurrentColor&quot;)
waitForChild(Tool.Color,&quot;Active&quot;)
Tool.Color.CurrentColor.Changed:connect(function()
&#9;if selectionBox then selectionBox.Color = Tool.Color.CurrentColor.Value end
&#9;if selectionLasso then selectionLasso.Color = Tool.Color.CurrentColor.Value end
end)
script.Active.Changed:connect(function(prop)
&#9;if script.Active.Value == true then
&#9;&#9;onEquippedLocal(Tool.Mouse.Value)
&#9;else
&#9;&#9;onUnequippedLocal()
&#9;end
end)</ProtectedString>
</Properties>
<Item class="BoolValue" referent="RBX9">
<Properties>
<string name="Name">Active</string>
<bool name="Value">false</bool>
</Properties>
</Item>
<Item class="BrickColorValue" referent="RBX10">
<Properties>
<string name="Name">CurrentColor</string>
<int name="Value">194</int>
</Properties>
</Item>
</Item>
<Item class="LocalScript" referent="RBX11">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">Material</string>
<ProtectedString name="Source">-- basic functions
function waitForChild(instance, name)
&#9;while not instance:findFirstChild(name) do
&#9;&#9;instance.ChildAdded:wait()
&#9;end
end
local Tool = script.Parent
waitForChild(Tool.Material,&quot;Active&quot;)
waitForChild(Tool.Material,&quot;CurrentMaterial&quot;)
enabled = true
local origTexture = &#9;Tool.TextureId
local localAssetBase = &quot;rbxasset://textures/ui/&quot;
game:GetService(&quot;ContentProvider&quot;):Preload(&quot;rbxasset://icons/material_sel.png&quot;)
local menu
local selectionBox
local selectionLasso
local selectedButton
local value = nil
local downCons = {}
local currentMaterialButton = nil
function setSelectionBox(part)
&#9;unsetSelectionBox()
&#9;selectionBox.Adornee = part
&#9;selectionLasso.Part = part
end
function unsetSelectionBox()
&#9;selectionBox.Adornee = nil
&#9;selectionLasso.Part = nil
end
local MaterialEnum = {}
MaterialEnum[&quot;Plastic&quot;] = Enum.Material.Plastic
MaterialEnum[&quot;Wood&quot;] = Enum.Material.Wood
MaterialEnum[&quot;Slate&quot;] = Enum.Material.Slate
MaterialEnum[&quot;CorrodedMetal&quot;] = Enum.Material.CorrodedMetal
MaterialEnum[&quot;Ice&quot;] = Enum.Material.Ice
MaterialEnum[&quot;Grass&quot;] = Enum.Material.Grass
MaterialEnum[&quot;Foil&quot;] = Enum.Material.Foil
MaterialEnum[&quot;DiamondPlate&quot;] = Enum.Material.DiamondPlate
MaterialEnum[&quot;Concrete&quot;] = Enum.Material.Concrete
function on3dButton1Down(mouse)
&#9;local part = mouse.Target
&#9;if part and not (part.Locked) then
&#9;&#9;if Instance.Lock(part) then
&#9;&#9;&#9;part.Material = MaterialEnum[Tool.Material.CurrentMaterial.Value]
&#9;&#9;&#9;Instance.Unlock(part)
&#9;&#9;end
&#9;end
end
function canSelectObject(part)
&#9;return part and not (part.Locked) and (part.Position - Tool.Parent.Head.Position).Magnitude &lt; 60
end
function on3dMouseMove(mouse)
&#9;mouse.Icon =&quot;rbxasset://textures\\MaterialCursor.png&quot;
&#9;local part = mouse.Target
&#9;if canSelectObject(part) then
&#9;&#9;setSelectionBox(part)
&#9;else
&#9;&#9;unsetSelectionBox()
&#9;end
end
function createMaterialMenu()
&#9;local materialGui = Instance.new(&quot;ScreenGui&quot;)
&#9;materialGui.Name = &quot;MaterialGui&quot;
&#9;local materialMenu = Instance.new(&quot;ImageLabel&quot;)
&#9;materialMenu.Name = &quot;MaterialMenu&quot;
&#9;materialMenu.Position = UDim2.new(0,0,1,-350)
&#9;materialMenu.Size = UDim2.new(0,100,0,250)
&#9;materialMenu.BackgroundTransparency = 1
&#9;materialMenu.ZIndex = 2
&#9;materialMenu.Image = localAssetBase .. &quot;MaterialMenu.png&quot;
&#9;materialMenu.Parent = materialGui
&#9;local textures = {&quot;Plastic&quot;,&quot;Wood&quot;,&quot;Slate&quot;,&quot;CorrodedMetal&quot;,&quot;Ice&quot;,&quot;Grass&quot;,&quot;Foil&quot;,&quot;DiamondPlate&quot;,&quot;Concrete&quot;}
&#9;local materialButtons = {}
&#9;local materialButton = Instance.new(&quot;ImageButton&quot;)
&#9;materialButton.BackgroundTransparency = 1
&#9;materialButton.Size = UDim2.new(0.400000003, 0,0.16, 0)
&#9;materialButton.ZIndex = 4
&#9;local selection = Instance.new(&quot;Frame&quot;)
&#9;selection.Name = &quot;Selection&quot;
&#9;selection.BorderSizePixel = 0
&#9;selection.BackgroundColor3 = Color3.new(1,1,1)
&#9;selection.BackgroundTransparency = 1
&#9;selection.ZIndex = 3
&#9;selection.Size = UDim2.new(1.1,0,1.1,0)
&#9;selection.Position = UDim2.new(-0.05,0,-0.05,0)
&#9;selection.Parent = materialButton
&#9;local current = 1
&#9;local function getTextureAndName(button)
&#9;&#9;if current &gt; #textures then
&#9;&#9;&#9;button:remove()
&#9;&#9;&#9;return false
&#9;&#9;end
&#9;&#9;button.Image = localAssetBase .. textures[current] .. &quot;.png&quot;
&#9;&#9;button.Name = textures[current]
&#9;&#9;current = current + 1
&#9;&#9;return true
&#9;end
&#9;local ySpacing = 0.10
&#9;local xSpacing = 0.07
&#9;for i = 1,5 do
&#9;&#9;for j = 1,2 do
&#9;&#9;&#9;local button = materialButton:clone()
&#9;&#9;&#9;button.Position = UDim2.new((j -1)/2.2 + xSpacing,0,ySpacing + (i - 1)/5.5,0)
&#9;&#9;&#9;if getTextureAndName(button) then button.Parent = materialMenu else button:remove() end
&#9;&#9;&#9;table.insert(materialButtons,button)
&#9;&#9;end
&#9;end
&#9;for i = 1, #materialButtons do
&#9;&#9;local newCon = materialButtons[i].MouseButton1Click:connect(function()
&#9;&#9;&#9;Tool.Material.CurrentMaterial.Value = materialButtons[i].Name
&#9;&#9;&#9;if currentMaterialButton then
&#9;&#9;&#9;&#9;if currentMaterialButton:FindFirstChild(&quot;Selection&quot;) then
&#9;&#9;&#9;&#9;&#9;currentMaterialButton.Selection.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;currentMaterialButton = materialButtons[i]
&#9;&#9;&#9;materialButtons[i].Selection.BackgroundTransparency = 0
&#9;&#9;end)
&#9;&#9;local enterCon = materialButtons[i].MouseEnter:connect(function()
&#9;&#9;&#9;materialButtons[i].Selection.BackgroundTransparency = 0
&#9;&#9;end)
&#9;&#9;local leaveCon = materialButtons[i].MouseLeave:connect(function()
&#9;&#9;&#9;if materialButtons[i] ~= currentMaterialButton then materialButtons[i].Selection.BackgroundTransparency = 1 end
&#9;&#9;end)
&#9;&#9;table.insert(downCons, newCon)
&#9;&#9;table.insert(downCons, enterCon)
&#9;&#9;table.insert(downCons, leaveCon)
&#9;end
&#9;return materialGui
end
function onEquippedLocal(mouse)
&#9;Tool.TextureId = &quot;rbxasset://icons/material_sel.png&quot;
&#9;value = nil
&#9;selectedButton = nil
&#9;local character = script.Parent.Parent
&#9;local player = game.Players:GetPlayerFromCharacter(character)
&#9;selectedButton = nil
&#9;button1DownCon = mouse.Button1Down:connect(function() on3dButton1Down(mouse) end)
&#9;mouseMoveCon = mouse.Move:connect(function() on3dMouseMove(mouse) end)
&#9;mouse.Icon =&quot;rbxasset://textures\\MaterialCursor.png&quot;
&#9;selectionBox = Instance.new(&quot;SelectionBox&quot;)
&#9;selectionBox.Color = BrickColor.Yellow()
&#9;selectionBox.Adornee = nil
&#9;selectionBox.Parent = player.PlayerGui
&#9;selectionLasso = Instance.new(&quot;SelectionPartLasso&quot;)
&#9;selectionLasso.Name = &quot;Model Material Lasso&quot;
&#9;selectionLasso.Humanoid = character.Humanoid
&#9;selectionLasso.Parent = game.workspace
&#9;selectionLasso.Part = nil
&#9;selectionLasso.Visible = true
&#9;selectionLasso.archivable = false
&#9;selectionLasso.Color = BrickColor.Green()
&#9;menu = createMaterialMenu()
&#9;menu.Parent = game.Players.LocalPlayer.PlayerGui
end
function onUnequippedLocal()
&#9;if button1DownCon then button1DownCon:disconnect() end
&#9;if mouseMoveCon then mouseMoveCon:disconnect() end
&#9;for i = 1, #downCons do
&#9;&#9;downCons[i]:disconnect()
&#9;end
&#9;downCons = {}
&#9;menu:remove()
&#9;Tool.TextureId = origTexture
&#9;if selectionBox then selectionBox:Remove() end
&#9;if selectionLasso then selectionLasso:Remove() end
end
script.Active.Changed:connect(function(prop)
&#9;if script.Active.Value == true then
&#9;&#9;onEquippedLocal(Tool.Mouse.Value)
&#9;else
&#9;&#9;onUnequippedLocal()
&#9;end
end)
</ProtectedString>
</Properties>
<Item class="BoolValue" referent="RBX12">
<Properties>
<string name="Name">Active</string>
<bool name="Value">false</bool>
</Properties>
</Item>
<Item class="StringValue" referent="RBX13">
<Properties>
<string name="Name">CurrentMaterial</string>
<string name="Value">Plastic</string>
</Properties>
</Item>
</Item>
<Item class="LocalScript" referent="RBX14">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">Resize</string>
<ProtectedString name="Source">-- basic functions
function waitForChild(instance, name)
&#9;while not instance:findFirstChild(name) do
&#9;&#9;instance.ChildAdded:wait()
&#9;end
end
local Tool = script.Parent
waitForChild(Tool.Resize,&quot;Active&quot;)
enabled = true
local origTexture = &#9;Tool.TextureId
game:GetService(&quot;ContentProvider&quot;):Preload(&quot;rbxasset://icons/resize_sel.png&quot;)
local selectionBox
local selectionLasso
local handles
local previousDistance
local needsCursor = true
local currMouseTarget
local connections = {}
function onHandlesDown(normal)
&#9;previousDistance = 0
end
function onHandlesDrag(normal, distance)
&#9;
&#9;if handles.Adornee then
&#9;&#9;local delta = distance - previousDistance
&#9;&#9;if math.abs(delta) &gt;= handles.Adornee.ResizeIncrement then
&#9;&#9;&#9;local sizeDelta = math.floor(delta / handles.Adornee.ResizeIncrement + 0.5) * handles.Adornee.ResizeIncrement
&#9;&#9;&#9;if handles.Adornee:Resize(normal, sizeDelta) then
&#9;&#9;&#9;&#9;previousDistance = distance
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
end
function onButton1Down(mouse)
&#9;local success = pcall(function() theMouse = mouse.Target end)
&#9;if success then
&#9;&#9;if canSelect(mouse.Target) then
&#9;&#9;&#9;selectionBox.Adornee = mouse.Target
&#9;&#9;&#9;selectionLasso.Part = mouse.Target
&#9;&#9;&#9;handles.Adornee = mouse.Target
&#9;&#9;&#9;handles.Faces = mouse.Target.ResizeableFaces
&#9;&#9;else
&#9;&#9;&#9;selectionBox.Adornee = nil
&#9;&#9;&#9;selectionLasso.Part = nil
&#9;&#9;&#9;handles.Adornee = nil
&#9;&#9;end
&#9;end
end
function mouseTargetChanged(mouse)
&#9;if canSelect(mouse.Target) then
&#9;&#9;if needsCursor then
&#9;&#9;&#9;mouse.Icon =&quot;rbxasset://textures\\DragCursor.png&quot;
&#9;&#9;&#9;needsCursor = false
&#9;&#9;end
&#9;else
&#9;&#9;needsCursor = true
&#9;&#9;mouse.Icon = &quot;&quot;
&#9;end
end
local function isPartOfModel(object)
&#9;if object and object ~= game.Workspace and object:IsA(&quot;Model&quot;) then
&#9;&#9;return true
&#9;elseif not object or object == game.Workspace then
&#9;&#9;return false
&#9;else
&#9;&#9;return isPartOfModel(object.Parent)
&#9;end
end
function canSelect(object)
&#9;local isModel = isPartOfModel(object)
&#9;return object and object:IsA(&quot;BasePart&quot;) and not object.Locked and not isPartOfModel(object)
end
function onEquippedLocal(mouse)
&#9;currMouseTarget = nil
&#9;table.insert(connections,mouse.Button1Down:connect(function() onButton1Down(mouse) end) )
&#9;table.insert(connections, mouse.Move:connect(function()
&#9;&#9;&#9;if currMouseTarget ~= mouse.Target then
&#9;&#9;&#9;&#9;mouseTargetChanged(mouse)
&#9;&#9;&#9;&#9;currMouseTarget = mouse.Target
&#9;&#9;&#9;end
&#9;&#9;end)
&#9;)
&#9;local character = script.Parent.Parent
&#9;local player = game.Players:GetPlayerFromCharacter(character)
&#9;
&#9;selectionBox = Instance.new(&quot;SelectionBox&quot;)
&#9;selectionBox.Color = BrickColor.Blue()
&#9;selectionBox.Adornee = nil
&#9;selectionBox.Parent = player.PlayerGui
&#9;selectionLasso = Instance.new(&quot;SelectionPartLasso&quot;)
&#9;selectionLasso.Name = &quot;Model Delete Lasso&quot;
&#9;selectionLasso.Humanoid = character.Humanoid
&#9;selectionLasso.Parent = game.workspace
&#9;selectionLasso.Part = nil
&#9;selectionLasso.Visible = true
&#9;selectionLasso.archivable = false
&#9;selectionLasso.Color = BrickColor.Red()
&#9;handles = Instance.new(&quot;Handles&quot;)
&#9;handles.Color = BrickColor.Blue()
&#9;handles.Adornee = nil
&#9;handles.MouseDrag:connect(onHandlesDrag)
&#9;handles.MouseButton1Down:connect(onHandlesDown)
&#9;handles.Parent = player.PlayerGui
end
function onUnequippedLocal()
&#9;Tool.TextureId = origTexture
&#9;selectionBox:Remove()
&#9;selectionLasso:Remove()
&#9;handles:Remove()
&#9;for i = 1, #connections do
&#9;&#9;if connections[i] then connections[i]:disconnect() end
&#9;end
&#9;connections = {}
end
script.Active.Changed:connect(function(prop)
&#9;if script.Active.Value == true then
&#9;&#9;onEquippedLocal(Tool.Mouse.Value)
&#9;else
&#9;&#9;onUnequippedLocal()
&#9;end
end)
</ProtectedString>
</Properties>
<Item class="BoolValue" referent="RBX15">
<Properties>
<string name="Name">Active</string>
<bool name="Value">false</bool>
</Properties>
</Item>
</Item>
<Item class="LocalScript" referent="RBX16">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">Surface</string>
<ProtectedString name="Source">-- basic functions
function waitForChild(instance, name)
&#9;while not instance:findFirstChild(name) do
&#9;&#9;instance.ChildAdded:wait()
&#9;end
end
local Tool = script.Parent
local menu
waitForChild(Tool.Surface,&quot;Active&quot;)
waitForChild(Tool.Surface,&quot;CurrentSurface&quot;)
enabled = true
local origTexture = &#9;Tool.TextureId
local localAssetBase = &quot;rbxasset://textures/ui/&quot;
game:GetService(&quot;ContentProvider&quot;):Preload(&quot;rbxasset://icons/surface_sel.png&quot;)
local selectionSurface
local selectionLasso
local currentSurfaceButton = nil
local mouseMoveCon, button1DownCon
local conArray = {}
function setSelectionSurface(part, surface)
&#9;unsetSelectionSurface()
&#9;selectionSurface.Adornee = part
&#9;selectionSurface.TargetSurface = surface
&#9;selectionLasso.Part = part
end
function unsetSelectionSurface()
&#9;selectionSurface.Adornee = nil
&#9;selectionLasso.Part = nil
end
local SurfaceEnum = {}
SurfaceEnum[&quot;Smooth&quot;] = Enum.SurfaceType.Smooth
SurfaceEnum[&quot;Studs&quot;] = Enum.SurfaceType.Studs
SurfaceEnum[&quot;Inlet&quot;] = Enum.SurfaceType.Inlet
SurfaceEnum[&quot;Universal&quot;] = Enum.SurfaceType.Universal
SurfaceEnum[&quot;Glue&quot;] = Enum.SurfaceType.Glue
SurfaceEnum[&quot;Weld&quot;] = Enum.SurfaceType.Weld
SurfaceEnum[&quot;Hinge&quot;] = Enum.SurfaceType.Hinge
SurfaceEnum[&quot;Motor&quot;] = Enum.SurfaceType.Motor
function canSelectObject(part, surface)
&#9;return part and not (part.Locked) and part:IsA(&quot;BasePart&quot;) and (part.Position - Tool.Parent.Head.Position).Magnitude &lt; 60 and
&#9;&#9;(not(part:IsA(&quot;WedgePart&quot;)) or surface ~= Enum.NormalId.Front)
end
function on3dMouseMove(mouse)
&#9;local part = mouse.Target
&#9;local surface = mouse.TargetSurface
&#9;if canSelectObject(part, surface) then
&#9;&#9;setSelectionSurface(part, surface)
&#9;else
&#9;&#9;unsetSelectionSurface()
&#9;end
end
function on3dButton1Down(mouse)
&#9;local part = selectionSurface.Adornee
&#9;if part then
&#9;&#9;local normalId = selectionSurface.TargetSurface
&#9;&#9;local surface = Tool.Surface.CurrentSurface.Value
&#9;&#9;if surface == nil then return end
&#9;&#9;--Apply the selected surface to the current parts
&#9;&#9;if normalId == Enum.NormalId.Top then
&#9;&#9;&#9;part.TopSurface = surface
&#9;&#9;elseif normalId == Enum.NormalId.Bottom then
&#9;&#9;elseif normalId == Enum.NormalId.Front then
&#9;&#9;&#9;part.BottomSurface = surface
&#9;&#9;&#9;part.FrontSurface = surface
&#9;&#9;elseif normalId == Enum.NormalId.Back then
&#9;&#9;&#9;part.BackSurface = surface
&#9;&#9;elseif normalId == Enum.NormalId.Left then
&#9;&#9;&#9;part.LeftSurface = surface
&#9;&#9;elseif normalId == Enum.NormalId.Right then
&#9;&#9;&#9;part.RightSurface = surface
&#9;&#9;end
&#9;end
end
function createSurfaceMenu()
&#9;local surfaceGui = Instance.new(&quot;ScreenGui&quot;)
&#9;surfaceGui.Name = &quot;SurfaceGui&quot;
&#9;local surfaceMenu = Instance.new(&quot;ImageLabel&quot;)
&#9;surfaceMenu.Name = &quot;SurfaceMenu&quot;
&#9;surfaceMenu.Position = UDim2.new(0,0,1,-400)
&#9;surfaceMenu.Size = UDim2.new(0,150,0,300)
&#9;surfaceMenu.BackgroundTransparency = 1
&#9;surfaceMenu.ZIndex = 2
&#9;surfaceMenu.Image = localAssetBase .. &quot;SurfaceMenu.png&quot;
&#9;surfaceMenu.Parent = surfaceGui
&#9;textures = {&quot;Smooth&quot;, &quot;Studs&quot;, &quot;Inlets&quot;, &quot;Universal&quot;, &quot;Glue&quot;, &quot;Weld&quot;, &quot;Hinge&quot;, &quot;Motor&quot;}
&#9;current = 1
&#9;local surfaceButtons = {}
&#9;local surfaceButton = Instance.new(&quot;ImageButton&quot;)
&#9;surfaceButton.BackgroundTransparency = 1
&#9;surfaceButton.Size = UDim2.new(0.400000003, 0,0.19, 0)
&#9;surfaceButton.ZIndex = 4
&#9;
&#9;local selection = Instance.new(&quot;Frame&quot;)
&#9;selection.Name = &quot;Selection&quot;
&#9;selection.BorderSizePixel = 0
&#9;selection.BackgroundColor3 = Color3.new(1,1,1)
&#9;selection.BackgroundTransparency = 1
&#9;selection.ZIndex = 3
&#9;selection.Size = UDim2.new(1.1,0,1.1,0)
&#9;selection.Position = UDim2.new(-0.05,0,-0.05,0)
&#9;selection.Parent = surfaceButton
&#9;local function getTextureAndName(button)
&#9;&#9;if current &gt; #textures then
&#9;&#9;&#9;button:remove()
&#9;&#9;&#9;return false
&#9;&#9;end
&#9;&#9;button.Image = localAssetBase .. textures[current] .. &quot;.png&quot;
&#9;&#9;if textures[current] == &quot;Inlets&quot; then --nice hack to adjust for inconsistent namings
&#9;&#9;&#9;button.Name = &quot;Inlet&quot;
&#9;&#9;else
&#9;&#9;&#9;button.Name = textures[current]
&#9;&#9;end
&#9;&#9;current = current + 1
&#9;&#9;return true
&#9;end
&#9;local ySpacing = 0.14
&#9;local xSpacing = 0.07
&#9;for i = 1,4 do
&#9;&#9;for j = 1,2 do
&#9;&#9;&#9;local button = surfaceButton:clone()
&#9;&#9;&#9;button.Position = UDim2.new((j -1)/2.2 + xSpacing,0,ySpacing + (i - 1)/4.6,0)
&#9;&#9;&#9;getTextureAndName(button)
&#9;&#9;&#9;button.Parent = surfaceMenu
&#9;&#9;&#9;table.insert(surfaceButtons,button)
&#9;&#9;end
&#9;end
&#9;for i = 1, #surfaceButtons do
&#9;&#9;local newCon = surfaceButtons[i].MouseButton1Click:connect(function()
&#9;&#9;&#9;Tool.Surface.CurrentSurface.Value = surfaceButtons[i].Name
&#9;&#9;&#9;if currentSurfaceButton then
&#9;&#9;&#9;&#9;if currentSurfaceButton:FindFirstChild(&quot;Selection&quot;) then
&#9;&#9;&#9;&#9;&#9;currentSurfaceButton.Selection.BackgroundTransparency = 1
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;currentSurfaceButton = surfaceButtons[i]
&#9;&#9;&#9;surfaceButtons[i].Selection.BackgroundTransparency = 0
&#9;&#9;end)
&#9;&#9;local enterCon = surfaceButtons[i].MouseEnter:connect(function()
&#9;&#9;&#9;surfaceButtons[i].Selection.BackgroundTransparency = 0
&#9;&#9;end)
&#9;&#9;local leaveCon = surfaceButtons[i].MouseLeave:connect(function()
&#9;&#9;&#9;if surfaceButtons[i] ~= currentSurfaceButton then surfaceButtons[i].Selection.BackgroundTransparency = 1 end
&#9;&#9;end)
&#9;&#9;table.insert(conArray,newCon)
&#9;&#9;table.insert(conArray,enterCon)
&#9;&#9;table.insert(conArray,leaveCon)
&#9;end
&#9;return surfaceGui
end
function onEquippedLocal(mouse)
&#9;Tool.TextureId = &quot;rbxasset://icons/surface_sel.png&quot;
&#9;local character = script.Parent.Parent
&#9;local player = game.Players:GetPlayerFromCharacter(character)
&#9;mouseMoveCon = mouse.Move:connect(function() on3dMouseMove(mouse) end)
&#9;button1DownCon = mouse.Button1Down:connect(function() on3dButton1Down(mouse) end)
&#9;selectionSurface = Instance.new(&quot;SurfaceSelection&quot;)
&#9;selectionSurface.Color = BrickColor.Red()
&#9;selectionSurface.Adornee = nil
&#9;selectionSurface.Parent = player.PlayerGui
&#9;selectionLasso = Instance.new(&quot;SelectionPartLasso&quot;)
&#9;selectionLasso.Name = &quot;Model Surface Lasso&quot;
&#9;selectionLasso.Humanoid = character.Humanoid
&#9;selectionLasso.Parent = game.workspace
&#9;selectionLasso.Part = nil
&#9;selectionLasso.Visible = true
&#9;selectionLasso.archivable = false
&#9;selectionLasso.Color = BrickColor.Yellow()
&#9;menu = createSurfaceMenu()
&#9;menu.Parent = game.Players.LocalPlayer.PlayerGui
end
function onUnequippedLocal()
&#9;if mouseMoveCon then mouseMoveCon:disconnect() end
&#9;if button1DownCon then button1DownCon:disconnect() end
&#9;for i = 1, #conArray do
&#9;&#9;if conArray[i] then conArray[i]:disconnect() end
&#9;end
&#9;conArray = {}
&#9;menu:remove()
&#9;Tool.TextureId = origTexture
&#9;if selectionBox then selectionBox:Remove() end
&#9;if selectionLasso then selectionLasso:Remove() end
&#9;if selectionSurface then selectionSurface:Remove() end
end
script.Active.Changed:connect(function(prop)
&#9;if script.Active.Value == true then
&#9;&#9;onEquippedLocal(Tool.Mouse.Value)
&#9;else
&#9;&#9;onUnequippedLocal()
&#9;end
end)
</ProtectedString>
</Properties>
<Item class="BoolValue" referent="RBX17">
<Properties>
<string name="Name">Active</string>
<bool name="Value">false</bool>
</Properties>
</Item>
<Item class="StringValue" referent="RBX18">
<Properties>
<string name="Name">CurrentSurface</string>
<string name="Value">Smooth</string>
</Properties>
</Item>
</Item>
<Item class="ObjectValue" referent="RBX19">
<Properties>
<string name="Name">Mouse</string>
<Ref name="Value">null</Ref>
</Properties>
</Item>
<Item class="LocalScript" referent="RBX20">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">Dragger</string>
<ProtectedString name="Source">-- basic functions
function waitForChild(instance, name)
&#9;while not instance:findFirstChild(name) do
&#9;&#9;instance.ChildAdded:wait()
&#9;end
end
local Tool = script.Parent
waitForChild(Tool.Dragger, &quot;Active&quot;)
local gui = nil
local connections = {}
function deactivateTool(script)
&#9;local enable = script:FindFirstChild(&quot;Active&quot;)
&#9;if enable and enable:IsA(&quot;BoolValue&quot;) then
&#9;&#9;enable.Value = false
&#9;end
end
function deactivateAllTools()
&#9;local toolChildren = script:GetChildren()
&#9;for i = 1, #toolChildren do
&#9;&#9;if toolChildren[i]:IsA(&quot;BaseScript&quot;) and toolChildren[i] ~= script then
&#9;&#9;&#9;deactivateTool(toolChildren[i])
&#9;&#9;end
&#9;end
end
function switchGrid(type)
&#9;deactivateAllTools()
&#9;wait()
&#9;if type == &quot;1&quot; then
&#9;&#9;script.OldDragger.Active.Value = true
&#9;&#9;gui.DraggerButton.Selected = true
&#9;&#9;gui.Dragger4xButton.Selected = false
&#9;else
&#9;&#9;script.NewDragger.Active.Value = true
&#9;&#9;gui.DraggerButton.Selected = false
&#9;&#9;gui.Dragger4xButton.Selected = true
&#9;end
end
function makeTextButton(buttonName, text, position, parent)
&#9;local button = Instance.new(&quot;TextButton&quot;)
&#9;button.Name = buttonName
&#9;button.Style = Enum.ButtonStyle.RobloxButton
&#9;button.Size = UDim2.new(0,100,0,40)
&#9;if position then button.Position = position end
&#9;button.Parent = parent
&#9;button.Text = text
&#9;button.Font = Enum.Font.ArialBold
&#9;button.FontSize = Enum.FontSize.Size18
&#9;button.TextColor3 = Color3.new(1,1,1)
&#9;return button
end
function makeDraggerGui()
&#9;local draggerGui = Instance.new(&quot;ScreenGui&quot;)
&#9;draggerGui.Name = &quot;DraggerGui&quot;
&#9;local draggerButton = makeTextButton(&quot;DraggerButton&quot;,&quot;1x1 Grid&quot;,UDim2.new(0.5,-100,0,0),draggerGui)
&#9;local dragger4xButton = makeTextButton(&quot;Dragger4xButton&quot;,&quot;4x4 Grid&quot;,UDim2.new(0.5,0,0,0),draggerGui)
&#9;local con = draggerButton.MouseButton1Click:connect(function() switchGrid(&quot;1&quot;) end)
&#9;local con2 = dragger4xButton.MouseButton1Click:connect(function() switchGrid(&quot;4&quot;) end)
&#9;table.insert(connections,con)
&#9;table.insert(connections,con2)
&#9;return draggerGui
end
function onEquippedLocal(mouse)
&#9;Tool.Mouse.Value = mouse
&#9;if not gui then
&#9;&#9;gui = makeDraggerGui()
&#9;end
&#9;gui.Parent = game.Players.LocalPlayer.PlayerGui
&#9;script.NewDragger.Active.Value = true
&#9;gui.Dragger4xButton.Selected = true
end
function onUnequippedLocal()
&#9;for i = 1, #connections do
&#9;&#9;connections[i]:disconnect()
&#9;end
&#9;connections = {}
&#9;gui:remove()
&#9;gui = nil
&#9;deactivateAllTools()
end
script.Active.Changed:connect(function(prop)
&#9;if script.Active.Value == true then
&#9;&#9;onEquippedLocal(Tool.Mouse.Value)
&#9;else
&#9;&#9;onUnequippedLocal()
&#9;end
end)
</ProtectedString>
</Properties>
<Item class="LocalScript" referent="RBX21">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">OldDragger</string>
<ProtectedString name="Source">-- basic functions
function waitForChild(instance, name)
&#9;while not instance:findFirstChild(name) do
&#9;&#9;instance.ChildAdded:wait()
&#9;end
end
local Tool = script.Parent.Parent
waitForChild(Tool.Dragger.OldDragger, &quot;Active&quot;)
enabled = true
local origTexture = &#9;Tool.TextureId
game:GetService(&quot;ContentProvider&quot;):Preload(&quot;rbxasset://icons/freemove_sel.png&quot;)
local selectionBox
local currentSelection
local currentSelectionColors = {}
local selectionLasso
local inGui = false
local inPalette = false
local connections = {}
function canSelectObject(part)
&#9;return part and not (part.Locked) and (part.Position - Tool.Parent.Head.Position).Magnitude &lt; 60
end
function findModel(part)
&#9;while part ~= nil do
&#9;&#9;if part:IsA(&quot;Model&quot;) and part ~= game.Workspace then
&#9;&#9;&#9;return part
&#9;&#9;elseif part == game.Workspace then
&#9;&#9;&#9;return nil
&#9;&#9;end
&#9;&#9;part = part.Parent
&#9;end
&#9;return nil
end
function startDrag(mousePart, hitPoint, collection)
&#9;dragger = Instance.new(&quot;Dragger&quot;)
&#9;pcall(function() dragger:MouseDown(mousePart, hitPoint, collection) end)
end
function collectBaseParts(object, collection)
&#9;if object == nil then return end
&#9;if object:IsA(&quot;BasePart&quot;) then
&#9;&#9;collection[#collection+1] = object
&#9;end
&#9;for index,child in pairs(object:GetChildren()) do
&#9;&#9;collectBaseParts(child, collection)
&#9;end
end
function onMouseDown(mouse)
&#9;mouse.Icon =&quot;rbxasset://textures\\GrabRotateCursor.png&quot;
&#9;local part = mouse.Target
&#9;if canSelectObject(part) then
&#9;&#9;local hitPoint = mouse.Hit:toObjectSpace(part.CFrame).p
&#9;&#9;if trySelection(part) then
&#9;&#9;&#9;local instances = {}
&#9;&#9;&#9;collectBaseParts(currentSelection, instances)
&#9;&#9;&#9;startDrag(part, hitPoint, instances)
&#9;&#9;&#9;return
&#9;&#9;end
&#9;end
&#9;onMouseUp(mouse)
end
function onMouseUp(mouse)
&#9;mouse.Icon =&quot;rbxasset://textures\\GrabCursor.png&quot;
&#9;if dragger ~= nil then
&#9;&#9;pcall(function() dragger:MouseUp() end)
&#9;&#9;dragger = nil
&#9;end
end
function trySelection(part)
&#9;if canSelectObject(part) then
&#9;&#9;selectionLasso.Part = part
&#9;&#9;local model = findModel(part)
&#9;&#9;if model then &#9;&#9;
&#9;&#9;&#9;return setSelection(model)
&#9;&#9;else
&#9;&#9;&#9;return setSelection(part)
&#9;&#9;end
&#9;else
&#9;&#9;clearSelection()
&#9;&#9;return false
&#9;end
end
function onKeyDown(key)
&#9;if dragger ~= nil then
&#9;&#9;if key == &apos;R&apos; or key == &apos;r&apos; then
&#9;&#9;&#9;dragger:AxisRotate(Enum.Axis.Y)
&#9;&#9;elseif key == &apos;T&apos; or key == &apos;t&apos; then
&#9;&#9;&#9;dragger:AxisRotate(Enum.Axis.Z)
&#9;&#9;end
&#9;end
end
local alreadyMoving
function onMouseMove(mouse)
&#9;if alreadyMoving then
&#9;&#9;return
&#9;end
&#9;alreadyMoving = true
&#9;if dragger ~= nil then
&#9;&#9;pcall(function() dragger:MouseMove(mouse.UnitRay) end)
&#9;else
&#9;&#9;trySelection(mouse.Target)
&#9;end
&#9;alreadyMoving = false
end
function saveSelectionColor(instance)
&#9;if instance:IsA(&quot;BasePart&quot;) then
&#9;&#9;currentSelectionColors[instance] = instance.BrickColor
&#9;&#9;if instance.BrickColor == BrickColor.Blue() then
&#9;&#9;&#9;instance.BrickColor = BrickColor.new(&quot;Deep blue&quot;)
&#9;&#9;else
&#9;&#9;&#9;instance.BrickColor = BrickColor.Blue()
&#9;&#9;end
&#9;end
&#9;local children = instance:GetChildren()
&#9;if children then
&#9;&#9;for pos, child in pairs(children) do
&#9;&#9;&#9;saveSelectionColor(child)
&#9;&#9;end
&#9;end
end
&#9;
function setSelection(partOrModel)
&#9;if partOrModel ~= currentSelection then
&#9;&#9;clearSelection()
&#9;&#9;currentSelection = partOrModel
&#9;&#9;saveSelectionColor(currentSelection)
&#9;&#9;selectionBox.Adornee = currentSelection
&#9;&#9;return true
&#9;else
&#9;&#9;if currentSelection ~= nil then
&#9;&#9;&#9;return true
&#9;&#9;end
&#9;end
&#9;return false
end
function clearSelection()
&#9;if currentSelection ~= nil then
&#9;&#9;for part, color in pairs(currentSelectionColors) do
&#9;&#9;&#9;part.BrickColor = color
&#9;&#9;end
&#9;&#9;selectionBox.Adornee = nil
&#9;end
&#9;currentSelectionColors = {}
&#9;currentSelection = nil
&#9;
&#9;if(selectionLasso) then
&#9;&#9;selectionLasso.Part = nil
&#9;end
&#9;if(selectionBox) then
&#9;&#9;selectionBox.Adornee = nil
&#9;end
end
function onEquippedLocal(mouse)
&#9;wait(0.1)
&#9;Tool.TextureId = &quot;rbxasset://icons/freemove_sel.png&quot;
&#9;local character = script.Parent.Parent
&#9;local player = game.Players:GetPlayerFromCharacter(character)
&#9;guiMain = Instance.new(&quot;ScreenGui&quot;)
&#9;guiMain.Parent = game.Players.LocalPlayer.PlayerGui
&#9;inGui = false
&#9;inPalette = false
&#9;mouse.Icon =&quot;rbxasset://textures\\GrabCursor.png&quot;
&#9;local con = mouse.Button1Down:connect(function() onMouseDown(mouse) end)
&#9;table.insert(connections,con)
&#9;con = mouse.Button1Up:connect(function() onMouseUp(mouse) end)
&#9;con = table.insert(connections,con)
&#9;con = mouse.Move:connect(function() onMouseMove(mouse) end)
&#9;table.insert(connections,con)
&#9;con = mouse.KeyDown:connect(function(string) onKeyDown(string) end)
&#9;table.insert(connections,con)
&#9;selectionBox = Instance.new(&quot;SelectionBox&quot;)
&#9;selectionBox.Name = &quot;Model Delete Selection&quot;
&#9;selectionBox.Color = BrickColor.Blue()
&#9;selectionBox.Adornee = nil
&#9;selectionBox.Parent = game.Players.LocalPlayer.PlayerGui
&#9;selectionLasso = Instance.new(&quot;SelectionPartLasso&quot;)
&#9;selectionLasso.Name = &quot;Model Drag Lasso&quot;
&#9;selectionLasso.Humanoid = game.Players.LocalPlayer.Character.Humanoid
&#9;selectionLasso.archivable = false
&#9;selectionLasso.Visible = true
&#9;selectionLasso.Parent = game.workspace
&#9;selectionLasso.Color = BrickColor.Blue()
&#9;alreadyMoving = false
end
function onUnequippedLocal()
&#9;for i = 1, #connections do
&#9;&#9;connections[i]:disconnect()
&#9;end
&#9;connections = {}
&#9;Tool.TextureId = origTexture
&#9;clearSelection()
&#9;selectionBox:Remove()
&#9;selectionLasso:Remove()
end
script.Active.Changed:connect(function()
&#9;if script.Active.Value then
&#9;&#9;onEquippedLocal(Tool.Mouse.Value)
&#9;else
&#9;&#9;onUnequippedLocal()
&#9;end
end)
</ProtectedString>
</Properties>
<Item class="BoolValue" referent="RBX22">
<Properties>
<string name="Name">Active</string>
<bool name="Value">false</bool>
</Properties>
</Item>
</Item>
<Item class="BoolValue" referent="RBX23">
<Properties>
<string name="Name">Active</string>
<bool name="Value">false</bool>
</Properties>
</Item>
<Item class="LocalScript" referent="RBX24">
<Properties>
<bool name="Disabled">false</bool>
<Content name="LinkedSource"><null></null></Content>
<string name="Name">NewDragger</string>
<ProtectedString name="Source">local Tool = script.Parent.Parent
game:GetService(&quot;ContentProvider&quot;):Preload(&quot;rbxasset://icons/freemove_sel.png&quot;)
local selectionBox
local currentSelection
local currentSelectionColors = {}
local Mouse = nil
local player = nil
local instances = {}
local maxDragDistance = 60
local connections = {}
while not Tool:FindFirstChild(&quot;ErrorBox&quot;) do Tool.ChildAdded:wait() end
local errorBox = Tool.ErrorBox
local lastTargetCFrame = nil
function canSelectObject(part)
&#9;return part and not (part.Locked) and (part.Position - script.Parent.Parent.Parent.Head.Position).Magnitude &lt; maxDragDistance
end
function findModel(part)
&#9;while part ~= nil do
&#9;&#9;if part.className == &quot;Model&quot; then
&#9;&#9;&#9;return part
&#9;&#9;end
&#9;&#9;part = part.Parent
&#9;end
&#9;return nil
end
function isPart(object)
&#9;return object and (object:IsA(&quot;Part&quot;) or object:IsA(&quot;TrussPart&quot;) or object:IsA(&quot;WedgePart&quot;) or object:IsA(&quot;VehicleSeat&quot;))
end
function positionPartsAtCFrame3(collection, aCFrame)
&#9;local insertCFrame
&#9;if collection[1]:IsA(&quot;Model&quot;) then
&#9;&#9;-- we assume model has at least one part in it; need to find first part
&#9;&#9;i = 1
&#9;&#9;while (i &lt; (#collection[1]:GetChildren()) and not isPart(collection[1]:GetChildren()[i])) do
&#9;&#9;&#9;i = i + 1
&#9;&#9;end
&#9;&#9;insertCFrame = collection[1]:GetChildren()[i].CFrame
&#9;&#9;for i, object in pairs(collection[1]:GetChildren()) do
&#9;&#9;&#9;if isPart(object) then
&#9;&#9;&#9;&#9;local posPartInWorld = object.Position
&#9;&#9;&#9;&#9;local posPart1InWorld = insertCFrame.p
&#9;&#9;&#9;&#9;local newPosPartInWorld = posPartInWorld - posPart1InWorld + aCFrame.p
&#9;
&#9;&#9;&#9;&#9;local x, y, z, R00, R01, R02, R10, R11, R12, R20, R21, R22 = object.CFrame:components()
&#9;&#9;&#9;&#9;object.CFrame = CFrame.new(newPosPartInWorld.x, newPosPartInWorld.y, newPosPartInWorld.z, R00, R01, R02, R10, R11, R12, R20, R21, R22)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;else
&#9;&#9;collection[1].CFrame = aCFrame
&#9;end
end
function getBoundingBox2(partOrModel)
-- for models, the bounding box is defined as the minimum and maximum individual part bounding boxes
-- relative to the first part&apos;s coordinate frame.
&#9;local minVec = Vector3.new(math.huge, math.huge, math.huge)
&#9;local maxVec = Vector3.new(-math.huge, -math.huge, -math.huge)
&#9;if isPart(partOrModel) then
&#9;&#9;minVec = -0.5 * partOrModel.Size
&#9;&#9;maxVec = -minVec
&#9;elseif partOrModel:IsA(&quot;Terrain&quot;) then
&#9;&#9;minVec = Vector3.new(-2, -2, -2)
&#9;&#9;maxVec = Vector3.new(2, 2, 2)
&#9;else
&#9;&#9;local part1 = partOrModel:GetChildren()[1]
&#9;&#9;for i, object in pairs(partOrModel:GetChildren()) do
&#9;&#9;&#9;if isPart(object) then
&#9;&#9;&#9;&#9;boxMinInWorld = object.CFrame:pointToWorldSpace(-0.5 * object.Size)
&#9;&#9;&#9;&#9;boxMinInPart1 = part1.CFrame:pointToObjectSpace(boxMinInWorld)
&#9;&#9;&#9;&#9;boxMaxInWorld = object.CFrame:pointToWorldSpace(0.5 * object.Size)
&#9;&#9;&#9;&#9;boxMaxInPart1 = part1.CFrame:pointToObjectSpace(boxMaxInWorld)
&#9;&#9;&#9;&#9;local minX = minVec.x
&#9;&#9;&#9;&#9;local minY = minVec.y
&#9;&#9;&#9;&#9;local minZ = minVec.z
&#9;&#9;&#9;&#9;local maxX = maxVec.x
&#9;&#9;&#9;&#9;local maxY = maxVec.y
&#9;&#9;&#9;&#9;local maxZ = maxVec.z
&#9;&#9;&#9;&#9;if boxMinInPart1.x &lt; minVec.x then
&#9;&#9;&#9;&#9;&#9;minX = boxMinInPart1.x
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if boxMinInPart1.y &lt; minVec.y then
&#9;&#9;&#9;&#9;&#9;minY = boxMinInPart1.y
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if boxMinInPart1.z &lt; minVec.z then
&#9;&#9;&#9;&#9;&#9;minZ = boxMinInPart1.z
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if boxMaxInPart1.x &lt; minX then
&#9;&#9;&#9;&#9;&#9;minX = boxMaxInPart1.x
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if boxMaxInPart1.y &lt; minY then
&#9;&#9;&#9;&#9;&#9;minY = boxMaxInPart1.y
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if boxMaxInPart1.z &lt; minZ then
&#9;&#9;&#9;&#9;&#9;minZ = boxMaxInPart1.z
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if boxMinInPart1.x &gt; maxVec.x then
&#9;&#9;&#9;&#9;&#9;maxX = boxMinInPart1.x
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if boxMinInPart1.y &gt; maxVec.y then
&#9;&#9;&#9;&#9;&#9;maxY = boxMinInPart1.y
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if boxMinInPart1.z &gt; maxVec.z then
&#9;&#9;&#9;&#9;&#9;maxZ = boxMinInPart1.z
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if boxMaxInPart1.x &gt; maxX then
&#9;&#9;&#9;&#9;&#9;maxX = boxMaxInPart1.x
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if boxMaxInPart1.y &gt; maxY then
&#9;&#9;&#9;&#9;&#9;maxY = boxMaxInPart1.y
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if boxMaxInPart1.z &gt; maxZ then
&#9;&#9;&#9;&#9;&#9;maxZ = boxMaxInPart1.z
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;minVec = Vector3.new(minX, minY, minZ)
&#9;&#9;&#9;&#9;maxVec = Vector3.new(maxX, maxY, maxZ)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;return minVec, maxVec
end
-- function to do the same as above, but in world coordinates (really only used for region3-based bounds-checking)
function getBoundingBoxInWorldCoordinates(partOrModel)
&#9;local minVec = Vector3.new(math.huge, math.huge, math.huge)
&#9;local maxVec = Vector3.new(-math.huge, -math.huge, -math.huge)
&#9;if partOrModel:IsA(&quot;Part&quot;) or partOrModel:IsA(&quot;WedgePart&quot;) or partOrModel:IsA(&quot;TrussPart&quot;)then
&#9;&#9;vec1 = partOrModel.CFrame:pointToWorldSpace(-0.5 * partOrModel.Size)
&#9;&#9;vec2 = partOrModel.CFrame:pointToWorldSpace(0.5 * partOrModel.Size)
&#9;&#9;minVec = Vector3.new(math.min(vec1.X, vec2.X), math.min(vec1.Y, vec2.Y), math.min(vec1.Z, vec2.Z))
&#9;&#9;maxVec = Vector3.new(math.max(vec1.X, vec2.X), math.max(vec1.Y, vec2.Y), math.max(vec1.Z, vec2.Z))
&#9;elseif partOrModel:IsA(&quot;Terrain&quot;) then
&#9;&#9;-- we shouldn&apos;t have to deal with this case
&#9;&#9;--minVec = Vector3.new(-2, -2, -2)
&#9;&#9;--maxVec = Vector3.new(2, 2, 2)
&#9;else
&#9;&#9;local part1 = partOrModel:GetChildren()[1]
&#9;&#9;for i, object in pairs(partOrModel:GetChildren()) do
&#9;&#9;&#9;if (object:IsA(&quot;Part&quot;) or object:IsA(&quot;WedgePart&quot;) or object:IsA(&quot;TrussPart&quot;)) then
&#9;&#9;&#9;&#9;boxMinInWorld = object.CFrame:pointToWorldSpace(-0.5 * object.Size)
&#9;&#9;&#9;&#9;boxMinInPart1 = part1.CFrame:pointToObjectSpace(boxMinInWorld)
&#9;&#9;&#9;&#9;boxMaxInWorld = object.CFrame:pointToWorldSpace(0.5 * object.Size)
&#9;&#9;&#9;&#9;boxMaxInPart1 = part1.CFrame:pointToObjectSpace(boxMaxInWorld)
&#9;&#9;&#9;&#9;local minX = minVec.x
&#9;&#9;&#9;&#9;local minY = minVec.y
&#9;&#9;&#9;&#9;local minZ = minVec.z
&#9;&#9;&#9;&#9;local maxX = maxVec.x
&#9;&#9;&#9;&#9;local maxY = maxVec.y
&#9;&#9;&#9;&#9;local maxZ = maxVec.z
&#9;&#9;&#9;&#9;if boxMinInWorld.x &lt; minVec.x then
&#9;&#9;&#9;&#9;&#9;minX = boxMinInWorld.x
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if boxMinInWorld.y &lt; minVec.y then
&#9;&#9;&#9;&#9;&#9;minY = boxMinInWorld.y
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if boxMinInWorld.z &lt; minVec.z then
&#9;&#9;&#9;&#9;&#9;minZ = boxMinInWorld.z
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if boxMaxInWorld.x &lt; minX then
&#9;&#9;&#9;&#9;&#9;minX = boxMaxInWorld.x
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if boxMaxInWorld.y &lt; minY then
&#9;&#9;&#9;&#9;&#9;minY = boxMaxInWorld.y
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if boxMaxInWorld.z &lt; minZ then
&#9;&#9;&#9;&#9;&#9;minZ = boxMaxInWorld.z
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if boxMinInWorld.x &gt; maxVec.x then
&#9;&#9;&#9;&#9;&#9;maxX = boxMinInWorld.x
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if boxMinInWorld.y &gt; maxVec.y then
&#9;&#9;&#9;&#9;&#9;maxY = boxMinInWorld.y
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if boxMinInWorld.z &gt; maxVec.z then
&#9;&#9;&#9;&#9;&#9;maxZ = boxMinInWorld.z
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if boxMaxInWorld.x &gt; maxX then
&#9;&#9;&#9;&#9;&#9;maxX = boxMaxInWorld.x
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if boxMaxInWorld.y &gt; maxY then
&#9;&#9;&#9;&#9;&#9;maxY = boxMaxInWorld.y
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;if boxMaxInWorld.z &gt; maxZ then
&#9;&#9;&#9;&#9;&#9;maxZ = boxMaxInWorld.z
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;minVec = Vector3.new(minX, minY, minZ)
&#9;&#9;&#9;&#9;maxVec = Vector3.new(maxX, maxY, maxZ)
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;return minVec, maxVec
end
function getTargetPartBoundingBox(targetPart)
&#9;if targetPart.Parent:FindFirstChild(&quot;RobloxModel&quot;) ~= nil then
&#9;&#9;return getBoundingBox2(targetPart.Parent)
&#9;else
&#9;&#9;return getBoundingBox2(targetPart)
&#9;end
end
function getMouseTargetCFrame(targetPart)
&#9;if targetPart.Parent:FindFirstChild(&quot;RobloxModel&quot;) ~= nil then
&#9;&#9;return targetPart.Parent:GetChildren()[1].CFrame
&#9;else
&#9;&#9;return targetPart.CFrame
&#9;end
end
function getClosestAlignedWorldDirection(aVector3InWorld)
&#9;local xDir = Vector3.new(1,0,0)
&#9;local yDir = Vector3.new(0,1,0)
&#9;local zDir = Vector3.new(0,0,1)
&#9;local xDot = aVector3InWorld.x * xDir.x + aVector3InWorld.y * xDir.y + aVector3InWorld.z * xDir.z
&#9;local yDot = aVector3InWorld.x * yDir.x + aVector3InWorld.y * yDir.y + aVector3InWorld.z * yDir.z
&#9;local zDot = aVector3InWorld.x * zDir.x + aVector3InWorld.y * zDir.y + aVector3InWorld.z * zDir.z
&#9;if math.abs(xDot) &gt; math.abs(yDot) and math.abs(xDot) &gt; math.abs(zDot) then
&#9;&#9;if xDot &gt; 0 then
&#9;&#9;&#9;return 0
&#9;&#9;else
&#9;&#9;&#9;return 3
&#9;&#9;end
&#9;elseif math.abs(yDot) &gt; math.abs(xDot) and math.abs(yDot) &gt; math.abs(zDot) then
&#9;&#9;if yDot &gt; 0 then
&#9;&#9;&#9;return 1
&#9;&#9;else
&#9;&#9;&#9;return 4
&#9;&#9;end
&#9;else
&#9;&#9;if zDot &gt; 0 then
&#9;&#9;&#9;return 2
&#9;&#9;else
&#9;&#9;&#9;return 5
&#9;&#9;end
&#9;end
end
function findConfigAtMouseTarget(collection)
-- *Critical Assumption* :
--&#9;&#9;&#9;&#9;This function assumes the target CF axes are orthogonal with the target bounding box faces
--&#9;&#9;&#9;&#9;And, it assumes the insert CF axes are orthongonal with the insert bounding box faces
--&#9;&#9;&#9;&#9;Therefore, insertion will not work with angled faces on wedges or other &quot;non-block&quot; parts, nor
--&#9;&#9;&#9;&#9;will it work for parts in a model that are not orthogonally aligned with the model&apos;s CF.
&#9;local grid = 4.0
&#9;local admissibleConfig = false
&#9;local targetConfig = CFrame.new(0,0,0)
&#9;local minBB, maxBB = getBoundingBox2(collection[1])
&#9;local diagBB = maxBB - minBB
&#9;local insertCFrame
&#9;if collection[1]:IsA(&quot;Model&quot;) then
&#9;&#9;i = 1
&#9;&#9;while (i &lt; (#collection[1]:GetChildren()) and not isPart(collection[1]:GetChildren()[i])) do
&#9;&#9;&#9;i = i + 1
&#9;&#9;end
&#9;&#9;insertCFrame = collection[1]:GetChildren()[i].CFrame
&#9;else
&#9;&#9;insertCFrame = collection[1].CFrame
&#9;end
&#9;Mouse.TargetFilter = collection[1]
&#9;local targetPart = Mouse.Target
&#9;if targetPart == nil then
&#9;&#9;return admissibleConfig, targetConfig
&#9;end
&#9;-- test mouse hit location
&#9;local minBBTarget, maxBBTarget = getTargetPartBoundingBox(targetPart)
&#9;local diagBBTarget = maxBBTarget - minBBTarget
&#9;local targetCFrame = getMouseTargetCFrame(targetPart)
&#9;local hitCFrame = Mouse.Hit
&#9;local mouseHitInWorld = hitCFrame.p
&#9;--local targetVectorInWorld = targetCFrame:vectorToWorldSpace(Vector3.FromNormalId(Mouse.TargetSurface))
&#9;if targetPart:IsA(&quot;Terrain&quot;) then
&#9;&#9;if not cluster then cluster = game.Workspace.Terrain end
&#9;&#9;-- the prefer solid is messing things up very slightly!! (because the TargetSurface stays correct when the cells are shifted very slightly prematurely)
&#9;&#9;cellID = cluster:WorldToCellPreferSolid(mouseHitInWorld)
&#9;&#9;targetCFrame = CFrame.new(cluster:CellCenterToWorld(cellID.x, cellID.y, cellID.z))
&#9;end
&#9;local targetVectorInWorld = targetCFrame:vectorToWorldSpace(Vector3.FromNormalId(Mouse.TargetSurface))
&#9;local mouseHitInTarget = targetCFrame:pointToObjectSpace(mouseHitInWorld)
&#9;local targetRefPointInTarget
&#9;local clampToSurface
&#9;if getClosestAlignedWorldDirection(targetVectorInWorld) == 0 then
&#9;&#9;targetRefPointInTarget = targetCFrame:vectorToObjectSpace(Vector3.new(1, -1, 1))
&#9;&#9;insertRefPointInInsert = insertCFrame:vectorToObjectSpace(Vector3.new(-1, -1, 1))
&#9;&#9;clampToSurface = Vector3.new(0,1,1)
&#9;elseif getClosestAlignedWorldDirection(targetVectorInWorld) == 3 then
&#9;&#9;targetRefPointInTarget = targetCFrame:vectorToObjectSpace(Vector3.new(-1, -1, -1))
&#9;&#9;insertRefPointInInsert = insertCFrame:vectorToObjectSpace(Vector3.new(1, -1, -1))
&#9;&#9;clampToSurface = Vector3.new(0,1,1)
&#9;elseif getClosestAlignedWorldDirection(targetVectorInWorld) == 1 then
&#9;&#9;targetRefPointInTarget = targetCFrame:vectorToObjectSpace(Vector3.new(-1, 1, 1))
&#9;&#9;insertRefPointInInsert = insertCFrame:vectorToObjectSpace(Vector3.new(-1, -1, 1))
&#9;&#9;clampToSurface = Vector3.new(1,0,1)&#9;&#9;
&#9;elseif getClosestAlignedWorldDirection(targetVectorInWorld) == 4 then
&#9;&#9;targetRefPointInTarget = targetCFrame:vectorToObjectSpace(Vector3.new(-1, -1, 1))
&#9;&#9;insertRefPointInInsert = insertCFrame:vectorToObjectSpace(Vector3.new(-1, 1, 1))
&#9;&#9;clampToSurface = Vector3.new(1,0,1)
&#9;elseif getClosestAlignedWorldDirection(targetVectorInWorld) == 2 then
&#9;&#9;targetRefPointInTarget = targetCFrame:vectorToObjectSpace(Vector3.new(-1, -1, 1))
&#9;&#9;insertRefPointInInsert = insertCFrame:vectorToObjectSpace(Vector3.new(-1, -1, -1))
&#9;&#9;clampToSurface = Vector3.new(1,1,0)
&#9;else
&#9;&#9;targetRefPointInTarget = targetCFrame:vectorToObjectSpace(Vector3.new(1, -1, -1))
&#9;&#9;insertRefPointInInsert = insertCFrame:vectorToObjectSpace(Vector3.new(1, -1, 1))
&#9;&#9;clampToSurface = Vector3.new(1,1,0)
&#9;end
&#9;targetRefPointInTarget = targetRefPointInTarget * (0.5 * diagBBTarget) + 0.5 * (maxBBTarget + minBBTarget)
&#9;insertRefPointInInsert = insertRefPointInInsert * (0.5 * diagBB) + 0.5 * (maxBB + minBB)
&#9;
&#9;-- To Do: For cases that are not aligned to the world grid, account for the minimal rotation
&#9;-- needed to bring the Insert part(s) into alignment with the Target Part
&#9;-- Apply the rotation here
&#9;local delta = mouseHitInTarget - targetRefPointInTarget
&#9;local deltaClamped = Vector3.new(grid * math.modf(delta.x/grid), grid * math.modf(delta.y/grid), grid * math.modf(delta.z/grid))
&#9;deltaClamped = deltaClamped * clampToSurface
&#9;local targetTouchInTarget = deltaClamped + targetRefPointInTarget
&#9;local TargetTouchRelToWorld = targetCFrame:pointToWorldSpace(targetTouchInTarget)
&#9;local InsertTouchInWorld = insertCFrame:vectorToWorldSpace(insertRefPointInInsert)
&#9;local posInsertOriginInWorld = TargetTouchRelToWorld - InsertTouchInWorld
&#9;local x, y, z, R00, R01, R02, R10, R11, R12, R20, R21, R22 = insertCFrame:components()
&#9;targetConfig = CFrame.new(posInsertOriginInWorld.x, posInsertOriginInWorld.y, posInsertOriginInWorld.z, R00, R01, R02, R10, R11, R12, R20, R21, R22)
&#9;admissibleConfig = true
&#9;return admissibleConfig, targetConfig
end
function startDrag(mousePart, hitPoint, collection)
&#9;lastTargetCFrame = nil
&#9;dragger = Instance.new(&quot;Dragger&quot;)
&#9;pcall(function() dragger:MouseDown(mousePart, hitPoint, collection) end)
end
function collectBaseParts(object, collection)
&#9;if object == nil then return end
&#9;--if object:IsA(&quot;BasePart&quot;) then
&#9;if isPart(object) then
&#9;&#9;collection[#collection+1] = object
&#9;end
&#9;for index,child in pairs(object:GetChildren()) do
&#9;&#9;collectBaseParts(child, collection)
&#9;end
end
function onMouseDown(mouse)
&#9;mouse.Icon =&quot;rbxasset://textures\\GrabRotateCursor.png&quot;
&#9;local part = mouse.Target
&#9;if canSelectObject(part) then
&#9;&#9;local hitPoint = mouse.Hit:toObjectSpace(part.CFrame).p
&#9;&#9;if trySelection(part) then
&#9;&#9;&#9;instances = {}
&#9;&#9;&#9;game.JointsService:ClearJoinAfterMoveJoints()
&#9;&#9;&#9;game.JointsService:SetJoinAfterMoveInstance(mouse.Target)
&#9;&#9;&#9;collectBaseParts(currentSelection, instances)
&#9;&#9;&#9;startDrag(part, hitPoint, instances)
&#9;&#9;&#9;return
&#9;&#9;end
&#9;end
end
-- stampability-checking functions (copied from StampScript)
function flashRedBox(targetModel)
&#9;if not player then return end
&#9;errorBox.Parent = player.PlayerGui
&#9;errorBox.Adornee = targetModel
&#9;delay(0,function()
&#9;&#9;for i = 1, 3 do
&#9;&#9;&#9;errorBox.Visible = true
&#9;&#9;&#9;wait(0.13)
&#9;&#9;&#9;errorBox.Visible = false
&#9;&#9;&#9;wait(0.13)
&#9;&#9;end
&#9;&#9;errorBox.Adornee = nil
&#9;&#9;errorBox.Parent = Tool
&#9;end)
end
-- below function should work as a Region3 query, returning true if a single cluster part is within this region
function clusterPartsInRegion(startVector, endVector)
&#9;if not cluster then return false end
&#9;local startCell = cluster:WorldToCell(startVector)
&#9;local endCell = cluster:WorldToCell(endVector)
&#9;local startX = startCell.X
&#9;local startY = startCell.Y
&#9;local startZ = startCell.Z
&#9;local endX = endCell.X
&#9;local endY = endCell.Y
&#9;local endZ = endCell.Z
&#9;if startX &lt; cluster.MaxExtents.Min.X then startX = cluster.MaxExtents.Min.X end
&#9;if startY &lt; cluster.MaxExtents.Min.Y then startY = cluster.MaxExtents.Min.Y end
&#9;if startZ &lt; cluster.MaxExtents.Min.Z then startZ = cluster.MaxExtents.Min.Z end
&#9;if endX &gt; cluster.MaxExtents.Max.X then endX = cluster.MaxExtents.Max.X end
&#9;if endY &gt; cluster.MaxExtents.Max.Y then endY = cluster.MaxExtents.Max.Y end
&#9;if endZ &gt; cluster.MaxExtents.Max.Z then endZ = cluster.MaxExtents.Max.Z end
&#9;--print(startX, endX)
&#9;--print(startY, endY)
&#9;--print(startZ, endZ)
&#9;for x = startX, endX do
&#9;&#9;for y = startY, endY do
&#9;&#9;&#9;for z = startZ, endZ do
&#9;&#9;&#9;&#9;--if game.Workspace.Cluster:GetCell(x, y, z) &gt; 0 then return true end
&#9;&#9;&#9;&#9;if (cluster:GetCell(x, y, z).Value) &gt; 0 then return true end
&#9;&#9;&#9;end
&#9;&#9;end
&#9;end
&#9;return false
end
-- helper function to determine if a character can be pushed upwards by a certain amount
-- FILL THIS OUT!!! -- character is 5 studs tall, we&apos;ll check a 1.5 x 1.5 x 4.5 box around char, with center .5 studs below torsocenter
function spaceAboveCharacter(charTorso, newTorsoY)
&#9;local partsAboveChar = game.Workspace:FindPartsInRegion3(Region3.new(Vector3.new(charTorso.Position.X, newTorsoY, charTorso.Position.Z) - Vector3.new(.75, 2.75, .75), Vector3.new(charTorso.Position.X, newTorsoY, charTorso.Position.Z) + Vector3.new(.75, 1.75, .75)), charTorso.Parent, 100)
&#9;for j = 1, #partsAboveChar do
&#9;&#9;if partsAboveChar[j].CanCollide and not partsAboveChar[j]:IsDescendantOf(currentSelection) then return false end
&#9;end
&#9;if clusterPartsInRegion(Vector3.new(charTorso.Position.X, newTorsoY, charTorso.Position.Z) - Vector3.new(.75, 2.75, .75), Vector3.new(charTorso.Position.X, newTorsoY, charTorso.Position.Z) + Vector3.new(.75, 1.75, .75)) then return false end
&#9;return true
end
local insertBoundingBoxOverlapVector = Vector3.new(1, 1, 1)
function onMouseUp(mouse)
&#9;mouse.Icon =&quot;rbxasset://textures\\GrabCursor.png&quot;
&#9;local thingToPlace = {}
&#9;thingToPlace[1] = currentSelection
&#9;if dragger ~= nil then
&#9;&#9;local minBB, maxBB = getBoundingBoxInWorldCoordinates(currentSelection)
&#9;&#9;local configFound, targetCFrame = findConfigAtMouseTarget(thingToPlace)
&#9;&#9;if configFound then
&#9;&#9;&#9;-- don&apos;t drag into terrain
&#9;&#9;&#9;if clusterPartsInRegion(minBB+insertBoundingBoxOverlapVector, maxBB-insertBoundingBoxOverlapVector) then flashRedBox(currentSelection) return end
&#9;&#9;&#9;
&#9;&#9;&#9;local blockingParts = game.Workspace:FindPartsInRegion3(Region3.new(minBB+insertBoundingBoxOverlapVector, maxBB-insertBoundingBoxOverlapVector), currentSelection, 100)
&#9;&#9;&#9;for b = 1, #blockingParts do
&#9;&#9;&#9;&#9;-- put code back here if we want to prevent dragger from dragging into other stamped models (once Region3 fix goes out)
&#9;&#9;&#9;end
&#9;&#9;&#9;local alreadyPushedUp = {}
&#9;&#9;&#9;-- if no blocking model below, then see if stamping on top of a character
&#9;&#9;&#9;for b = 1, #blockingParts do
&#9;&#9;&#9;&#9;if blockingParts[b].Parent and not alreadyPushedUp[blockingParts[b].Parent] and blockingParts[b].Parent:FindFirstChild(&quot;Humanoid&quot;) and blockingParts[b].Parent:FindFirstChild(&quot;Humanoid&quot;):IsA(&quot;Humanoid&quot;) then
&#9;&#9;&#9;&#9;&#9;local blockingPersonTorso = blockingParts[b].Parent:FindFirstChild(&quot;Torso&quot;)
&#9;&#9;&#9;&#9;&#9;alreadyPushedUp[blockingParts[b].Parent] = true
&#9;&#9;&#9;&#9;&#9;if blockingPersonTorso then
&#9;&#9;&#9;&#9;&#9;&#9;-- if so, let&apos;s push the person upwards so they pop on top of the stamped model/part (but only if there&apos;s space above them)
&#9;&#9;&#9;&#9;&#9;&#9;local newY = maxBB.Y + 3
&#9;&#9;&#9;&#9;&#9;&#9;if spaceAboveCharacter(blockingPersonTorso, newY) then
&#9;&#9;&#9;&#9;&#9;&#9;&#9;blockingPersonTorso.CFrame = blockingPersonTorso.CFrame + Vector3.new(0, newY - blockingPersonTorso.CFrame.p.Y, 0)
&#9;&#9;&#9;&#9;&#9;&#9;else
&#9;&#9;&#9;&#9;&#9;&#9;&#9;-- if no space, we just error
&#9;&#9;&#9;&#9;&#9;&#9;&#9;flashRedBox(currentSelection)
&#9;&#9;&#9;&#9;&#9;&#9;&#9;return
&#9;&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;end
&#9;&#9;&#9;Mouse.TargetFilter = nil
&#9;&#9;&#9;pcall(function() dragger:MouseUp() end)
&#9;&#9;&#9;game.JointsService:CreateJoinAfterMoveJoints()
&#9;&#9;&#9;dragger = nil
&#9;&#9;end
&#9;end
end
function trySelection(part)
&#9;if canSelectObject(part) then
&#9;&#9;local model = findModel(part)
&#9;&#9;if model then &#9;&#9;
&#9;&#9;&#9;return setSelection(model)
&#9;&#9;else
&#9;&#9;&#9;return setSelection(part)
&#9;&#9;end
&#9;else
&#9;&#9;clearSelection()
&#9;&#9;return false
&#9;end
end
function onKeyDown(key)
&#9;if dragger ~= nil then
&#9;&#9;if key == &apos;R&apos; or key == &apos;r&apos; then
&#9;&#9;&#9;pcall(function() dragger:AxisRotate(Enum.Axis.Y) end)
&#9;&#9;elseif key == &apos;T&apos; or key == &apos;t&apos; then
&#9;&#9;&#9;pcall(function() dragger:AxisRotate(Enum.Axis.Z) end)
&#9;&#9;end
&#9;end
end
local alreadyMoving = false
function onMouseMove(mouse)
&#9;if alreadyMoving then
&#9;&#9;return
&#9;end
&#9;alreadyMoving = true
&#9;if dragger ~= nil then
&#9;&#9;local thingToDrag = {}
&#9;&#9;thingToDrag[1] = currentSelection
&#9;
&#9;&#9;pcall(function() dragger:MouseMove(mouse.UnitRay) end)-- needed to break welds properly
&#9;&#9;configFound, targetCFrame = findConfigAtMouseTarget(thingToDrag)
&#9;&#9;if configFound then
&#9;&#9;&#9;local minBB, maxBB = getBoundingBoxInWorldCoordinates(currentSelection)
&#9;
&#9;&#9;&#9;-- need to offset by distance to be dragged
&#9;&#9;&#9;local currModelCFrame
&#9;&#9;&#9;if currentSelection:IsA(&quot;Model&quot;) then
&#9;&#9;&#9;&#9;-- we assume model has at least one part in it; need to find first part
&#9;&#9;&#9;&#9;i = 1
&#9;&#9;&#9;&#9;while (i &lt; (#currentSelection:GetChildren()) and not isPart(currentSelection:GetChildren()[i])) do
&#9;&#9;&#9;&#9;&#9;i = i + 1
&#9;&#9;&#9;&#9;end
&#9;&#9;&#9;&#9;currModelCFrame = currentSelection:GetChildren()[i].CFrame
&#9;&#9;&#9;else currModelCFrame = currentSelection.CFrame end
&#9;&#9;&#9;minBB = minBB + targetCFrame.p - currModelCFrame.p
&#9;&#9;&#9;maxBB = maxBB + targetCFrame.p - currModelCFrame.p
&#9;&#9;&#9;-- don&apos;t drag into terrain
&#9;&#9;&#9;if clusterPartsInRegion(minBB+insertBoundingBoxOverlapVector, maxBB-insertBoundingBoxOverlapVector) then
&#9;&#9;&#9;&#9;if lastTargetCFrame then positionPartsAtCFrame3(thingToDrag, lastTargetCFrame) end
&#9;&#9;&#9;&#9;alreadyMoving = false
&#9;&#9;&#9;&#9;return
&#9;&#9;&#9;end
&#9;&#9;&#9;
&#9;&#9;&#9;local blockingParts = game.Workspace:FindPartsInRegion3(Region3.new(minBB+insertBoundingBoxOverlapVector, maxBB-insertBoundingBoxOverlapVector), currentSelection, 100)
&#9;&#9;&#9;for b = 1, #blockingParts do
&#9;&#9;&#9;&#9;-- put code back here if we want to prevent dragger from dragging into other stamped models (once Region3 fix goes out)
&#9;&#9;&#9;end
&#9;&#9;&#9;positionPartsAtCFrame3(thingToDrag, targetCFrame)
&#9;&#9;&#9;lastTargetCFrame = targetCFrame
&#9;&#9;end
&#9;else
&#9;&#9;trySelection(mouse.Target)
&#9;end
&#9;alreadyMoving = false
end
function saveSelectionColor(instance)
&#9;if instance:IsA(&quot;BasePart&quot;) then
&#9;&#9;currentSelectionColors[instance] = instance.BrickColor
&#9;&#9;if instance.BrickColor == BrickColor.Blue() then
&#9;&#9;&#9;instance.BrickColor = BrickColor.new(&quot;Deep blue&quot;)
&#9;&#9;else
&#9;&#9;&#9;instance.BrickColor = BrickColor.Blue()
&#9;&#9;end
&#9;end
&#9;local children = instance:GetChildren()
&#9;if children then
&#9;&#9;for pos, child in pairs(children) do
&#9;&#9;&#9;saveSelectionColor(child)
&#9;&#9;end
&#9;end
end
&#9;
function setSelection(partOrModel)
&#9;if partOrModel ~= currentSelection then
&#9;&#9;clearSelection()
&#9;&#9;currentSelection = partOrModel
&#9;&#9;saveSelectionColor(currentSelection)
&#9;&#9;selectionBox.Adornee = currentSelection
&#9;&#9;return true
&#9;elseif partOrModel == nil then
&#9;&#9;clearSelection()
&#9;&#9;return false
&#9;end
&#9;return partOrModel == currentSelection
end
function clearSelection()
&#9;if currentSelection ~= nil then
&#9;&#9;for part, color in pairs(currentSelectionColors) do
&#9;&#9;&#9;part.BrickColor = color
&#9;&#9;end
&#9;&#9;selectionBox.Adornee = nil
&#9;end
&#9;currentSelectionColors = {}
&#9;currentSelection = nil
&#9;if(selectionBox) then
&#9;&#9;selectionBox.Adornee = nil
&#9;end
end
function onEquippedLocal(mouse)
&#9;Mouse = mouse
&#9;local character = script.Parent.Parent.Parent
&#9;player = game.Players:GetPlayerFromCharacter(character)
&#9;mouse.Icon =&quot;rbxasset://textures\\GrabCursor.png&quot;
&#9;local con = Mouse.Button1Down:connect(function() onMouseDown(Mouse) end)
&#9;table.insert(connections,con)
&#9;con = Mouse.Button1Up:connect(function() onMouseUp(Mouse) end)
&#9;con = table.insert(connections,con)
&#9;con = Mouse.Move:connect(function() onMouseMove(Mouse) end)
&#9;table.insert(connections,con)
&#9;con = Mouse.KeyDown:connect(function(string) onKeyDown(string) end)
&#9;table.insert(connections,con)
&#9;selectionBox = Instance.new(&quot;SelectionBox&quot;)
&#9;selectionBox.Name = &quot;Model Delete Selection&quot;
&#9;selectionBox.Color = BrickColor.Blue()
&#9;selectionBox.Adornee = nil
&#9;selectionBox.Parent = player.PlayerGui
&#9;alreadyMoving = false
end
function onUnequippedLocal()
&#9;for i = 1, #connections do
&#9;&#9;connections[i]:disconnect()
&#9;end
&#9;connections = {}
&#9;clearSelection()
&#9;selectionBox:Remove()
end
script.Active.Changed:connect(function()
&#9;if script.Active.Value then
&#9;&#9;onEquippedLocal(Tool.Mouse.Value)
&#9;else
&#9;&#9;onUnequippedLocal()
&#9;end
end)</ProtectedString>
</Properties>
<Item class="BoolValue" referent="RBX25">
<Properties>
<string name="Name">Active</string>
<bool name="Value">false</bool>
</Properties>
</Item>
</Item>
</Item>
<Item class="SelectionBox" referent="RBX26">
<Properties>
<Ref name="Adornee">null</Ref>
<int name="Color">21</int>
<string name="Name">ErrorBox</string>
<float name="Transparency">0</float>
<bool name="Visible">false</bool>
</Properties>
</Item>
</Item>
</roblox>