Advertisement
21-9is10

EAT MY SPAGHETTI CODE!!!

Feb 27th, 2020
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 51.18 KB | None | 0 0
  1. --Source code extracted from https://www.roblox.com/library/741785194/VisualPlugin-useful-building-plugin
  2.  
  3. --'Proudly made in the UK' ... by an Anglophile living in the US.
  4. --Look around for NOTE comments all over the source code; thay contain helpful tips on using VisualPlugin.
  5. local version={shape='rbxasset://textures/ui/Lobby/Buttons/scroll_up.png',sub='C.U.L8r'}
  6.  
  7. local defaults={
  8.     planeV={1,0,1},
  9.     planeS={.7,0,1},
  10.     planeTop={false},
  11.     planeTrans={.4,0,1},
  12.     selBoxSize={.05,0,1},
  13.     --1 for box, 2 for plane.
  14.     selMode={2,1,nil,1},
  15.     maxParts={187,0},
  16.    
  17.     decRound={3},
  18.     debugP={false},
  19.     saveIncrs={true},
  20.     newPartDist={7,0},
  21.     guiScaling={1,.5},
  22.     handleIntensity={1},
  23.     selectsFirst={true},
  24.     selectLocked={false},
  25.     fromAllEdges={false},
  26.     screenTipDelay={.5,0},
  27.     maxUndo={-1,-1,nil,1},
  28.     resizeNegative={false},
  29.     blocking={false,'NO_TOUCH'},
  30.     --Maximum ancestry to search.
  31.     selectsSameCFrame={2,0,nil,1},
  32.     clearAllOnIncrementClear={false},
  33.    
  34.     mods={{
  35.         --[[
  36.         game.workspace:
  37.         findFirstChild
  38.         'ModuleTest',
  39.         ]]
  40.     }},
  41.    
  42.     --NOTE: Some settings are restricted from editing!
  43.     forceRestart={false,'NO_TOUCH'},
  44.     usedB4={true,'NO_TOUCH'},
  45. }
  46.  
  47. local materialIds={
  48.     SmoothPlastic
  49.     =703387192,
  50.     CorrodedMetal
  51.     =843920084,
  52.     DiamondPlate
  53.     =844342054,
  54.     Cobblestone
  55.     =843920069,
  56.     WoodPlanks
  57.     =843920072,
  58.     Concrete
  59.     =843920069,
  60.     Granite
  61.     =843920074,
  62.     Plastic
  63.     =844342043,
  64.     Fabric
  65.     =843920050,
  66.     Marble
  67.     =843920026,
  68.     Pebble
  69.     =843920063,
  70.     Brick
  71.     =843920065,
  72.     Slate
  73.     =843920055,
  74.     Grass
  75.     =843920051,
  76.     Metal
  77.     =845896371,
  78.     Wood
  79.     =843920048,
  80.     Sand
  81.     =843920044,
  82.     Foil
  83.     =844342044,
  84.     Neon
  85.     =703387192,
  86.     Ice
  87.     =843920041,
  88.     Glass
  89.     =844342043,
  90. }
  91.  
  92. local materialCount=0
  93. for i,g in pairs(materialIds) do
  94.     materialCount=materialCount+1
  95. end
  96.  
  97. --------------------------------------------------------------------------------------------------------
  98.  
  99. local plugin=getfenv().plugin
  100. print('The plugin object does'
  101. ..(plugin and''or'n\'t')..' exist.')
  102.  
  103. while not script.Parent:
  104. isA'Tool' and not plugin do
  105.     wait()
  106. end
  107.  
  108. local player=game.
  109. Players.LocalPlayer
  110. local tool=not plugin
  111. and script.Parent or nil
  112. local mouse=(plugin and plugin or player):GetMouse()
  113. local core=plugin and game.CoreGui or player.PlayerGui
  114. local util=require(script
  115. :WaitForChild'Util')
  116. local active
  117.  
  118. local permsF=require(script:
  119. WaitForChild'AdminPermissions')
  120. local partF=permsF.OnNewPartCreation
  121. local verify=permsF.VerifySelection
  122.  
  123. local selFuncs
  124. local commands
  125. local canDoStuff
  126.  
  127. local rs=game['Run Service']
  128. local gui=script.VisualPlugin:clone()
  129. local handlesF=script.Handles:clone()
  130. local mf=gui:WaitForChild'MainFrame'
  131. local cmds=mf:WaitForChild'Commands'
  132. local config=gui:WaitForChild'Config'
  133.  
  134. local sm=mf:WaitForChild'Submodes'
  135. local smTemplate=sm['1']:clone()
  136. local incBox=sm.Increment.TextBox
  137. local clTemplate=script:
  138. WaitForChild'SpecialGui'.Colour
  139. clTemplate.Visible=false
  140.  
  141. local id=plugin and plugin:
  142. GetStudioUserId()or player.userId
  143. local hue=1.07773e-8*id
  144. -3.1896e-17*id^2+.5
  145. --NOTE: There would be a VIP feature based on the client's user ID.
  146. local vip=id>0
  147. and id<1630229
  148.  
  149. --NOTE: The hue of your plugin client varies by the client's user ID.
  150. function accColour()
  151.     return id<1 and Color3
  152.     .new(.7,.7,.7)or Color3
  153.     .fromHSV(hue%1,.75,.95)
  154.     --return BrickColor.new'Gold'.Color
  155. end
  156.  
  157. --Indicies are numbers, values are part tables.
  158. --Index 0 of said table is optionally a group
  159. local selGroups={}
  160. --Indicies are numbers, values are selection tables.
  161. local selections={}
  162. --Indicies are numbers, values are parts.
  163. local selI
  164.  
  165. --Stealing from DataBrain?  Never mind?
  166. --[[
  167. local src=game.InsertService:LoadAsset(284294874):children()[1].Source:gsub('\n',' ')
  168. local matStr=select(3,src:find('local materials = ({.+}) local BasicMaterials'))
  169. local materials=loadstring('return '..matStr)()
  170. local basicMatStr=select(3,src:find('local BasicMaterials = ({.+}) local button'))
  171. local basicMaterials=loadstring('return '..basicMatStr)()
  172. ]]
  173.  
  174. if plugin then
  175.     defaults.maxUndo
  176.     [2]='NO_TOUCH'
  177. else
  178.     if not plugin then
  179.         defaults.selectLocked
  180.         [2]='NO_TOUCH'
  181.     end
  182. end
  183.  
  184. local toolSettings={}
  185. local settings=setmetatable({},{
  186.     __index=function(t,i)
  187.         local v=plugin and
  188.         plugin:GetSetting(i)
  189.         or toolSettings[i]
  190.         if v=='true' then
  191.             return true
  192.         elseif v=='false' then
  193.             return false end
  194.         return v
  195.     end,
  196.     __newindex=function(t,i,v)
  197.         i=tostring(i)
  198.         if plugin then
  199.             if type(v)=='boolean' then
  200.                 v=tostring(v)end
  201.             plugin:SetSetting(i,v)
  202.         else
  203.             toolSettings[i]=v
  204.         end
  205.         if reRender then
  206.             reRender()
  207.         end
  208.     end,
  209. })
  210.  
  211. if defaults.forceRestart[1]
  212. or not settings.usedB4
  213. or not plugin then
  214.     print'Settings restored.'
  215.     for i,g in pairs(defaults) do
  216.         settings[i]=g[1]
  217.     end
  218. else
  219.     for i,g in pairs(defaults) do
  220.         if settings[i]==nil --THIS IS WHY THE BOOLEAN SETTINGS WERE SWITCHING TO TRUE;
  221.             --'not settings[i]' improperly returns true when the setting it set to false.
  222.         or g[2]=='NO_TOUCH' then
  223.             toolSettings[i]=g[1]
  224.             settings[i]=g[1]
  225.         end
  226.     end
  227. end
  228.  
  229. local Print=print
  230. local doPrint=settings.debugP
  231. local print=function(...)
  232.     if doPrint then
  233.         return Print(unpack(0<#{...}
  234.         and{os.time(),'-',...}or{}))
  235.     end
  236. end
  237.  
  238. local twIndex=0
  239. local toolWaypoints={}
  240. local origData,pData={},{}
  241. function createWaypoint(t)
  242.     if plugin then
  243.         game.ChangeHistoryService
  244.         :SetWaypoint'0x18E014'
  245.     else
  246.         if not t then
  247.             t={}
  248.             local proceed
  249.             for i2 in pairs(origData) do
  250.                 if tonumber(i2) then
  251.                     local n=pData[i2]
  252.                     local o=origData[i2]
  253.                     if not proceed and(o.cf~=n.CFrame
  254.                     or o.size~=o.part.Size)then
  255.                         proceed=true
  256.                     end
  257.                    
  258.                     t[i2]={undo=
  259.                     {cf=o.cf,size=o
  260.                     .size},redo={cf=
  261.                     n.cf,size=n.size
  262.                     },parts=o.parts}
  263.                 end
  264.             end
  265.             if not proceed then
  266.                 return
  267.             end
  268.         end
  269.         addToolWaypoint(t)
  270.     end
  271. end
  272.  
  273. function addToolWaypoint(t)
  274.     print'Tool waypoint created.'
  275.     --Clears the stuff after the last state.
  276.     for i=1,#toolWaypoints do
  277.         toolWaypoints[i]
  278.         =toolWaypoints[i+twIndex]
  279.     end
  280.    
  281.     --Adds a new position thingy.
  282.     twIndex=0
  283.     local max=settings.maxUndo
  284.     for i=max>-1 and max-1
  285.     or#toolWaypoints,0,-1 do
  286.         toolWaypoints[i+1]
  287.         =toolWaypoints[i]
  288.         or t
  289.     end
  290. end
  291.  
  292. function undo()
  293.     if plugin and game.
  294.     ChangeHistoryService
  295.     :GetCanUndo() then
  296.         game.ChangeHistoryService:Undo()
  297.        
  298.     elseif twIndex
  299.     <#toolWaypoints then
  300.         twIndex=twIndex+1
  301.         local w=toolWaypoints[twIndex]
  302.         print('The mode is '..(w.mode
  303.         or'null')..' ('..twIndex..')')
  304.         if w.mode=='del'then
  305.             for i,g in pairs(w[1]) do
  306.                 g.part.Parent=g.par
  307.             end
  308.         elseif w.mode=='ins'then
  309.             for i,g in pairs(w[1]) do
  310.                 removeSelection(g.part)
  311.                 g.part.Parent=nil
  312.             end
  313.         elseif w.mode=='colour'then
  314.             local parents={}
  315.             for i,g in pairs(w[2]) do
  316.                 removeSelection(g[1])
  317.                 parents[i]=g[1].Parent
  318.                 for i2,g2 in pairs(g) do
  319.                     g2.Parent=nil
  320.                 end
  321.             end
  322.            
  323.             for i,g in pairs(w[1]) do
  324.                 for i2,g2 in pairs(g) do
  325.                     g2.Parent=parents[i]
  326.                 end
  327.                 addSelection(g[1])
  328.             end
  329.         else
  330.             for i,g in pairs(w) do
  331.                 for i2,g2 in pairs(g.parts) do
  332.                     setCFrame(g2,g.undo.cf)
  333.                     setSize(g2,g.undo.size)
  334.                 end
  335.             end
  336.         end
  337.     end
  338.     setSubmode()
  339. end
  340.  
  341. function redo()
  342.     if plugin and game.
  343.     ChangeHistoryService
  344.     :GetCanRedo() then
  345.         game.ChangeHistoryService:Redo()
  346.     elseif twIndex>0 then
  347.         twIndex=twIndex-1
  348.         local w=toolWaypoints[twIndex+1]
  349.         if w.mode=='del'then
  350.             for i,g in pairs(w[1]) do
  351.                 removeSelection(g.part)
  352.                 g.part.Parent=nil
  353.             end
  354.         elseif w.mode=='ins'then
  355.             for i,g in pairs(w[1]) do
  356.                 g.part.Parent=g.par
  357.             end
  358.         elseif w.mode=='colour'then
  359.             local parents={}
  360.             for i,g in pairs(w[1]) do
  361.                 removeSelection(g[1])
  362.                 parents[i]=g[1].Parent
  363.                 for i2,g2 in pairs(g) do
  364.                     g2.Parent=nil
  365.                 end
  366.             end
  367.            
  368.             for i,g in pairs(w[2]) do
  369.                 for i2,g2 in pairs(g) do
  370.                     g2.Parent=parents[i]
  371.                 end
  372.                 addSelection(g[1])
  373.             end
  374.         else
  375.             for i,g in pairs(w) do
  376.                 for i2,g2 in pairs(g.parts) do
  377.                     setCFrame(g2,g.redo.cf)
  378.                     setSize(g2,g.redo.size)
  379.                 end
  380.             end
  381.         end
  382.     end
  383.     setSubmode()
  384. end
  385.  
  386. function duplicate()
  387.     local t,c={}
  388.     for i,g in pairs(selGroups) do
  389.         for i2,g2 in pairs(g) do
  390.             c=g2:clone()
  391.             c.Parent=g2.Parent
  392.             selGroups[i][i2]=c
  393.             t[#t+1]={part=c
  394.             ,par=g2.Parent}
  395.         end
  396.         selections[i].destroy()
  397.         selections[i]=selFuncs
  398.         [settings.selMode][2](c)
  399.     end
  400.     setMode(nil,1)
  401.     createWaypoint
  402.     {mode='ins',t}
  403.     upd8GameSel()
  404. end
  405.  
  406. function delete()
  407.     local t=getSelection()
  408.     for i,g in pairs(t) do
  409.         removeSelection(g)
  410.         t[i]={part=g,
  411.         par=g.Parent}
  412.         g.Parent=nil
  413.     end
  414.    
  415.     createWaypoint
  416.     {mode='del',t}
  417.     t={}
  418. end
  419.  
  420. --------------------------------------------------------------------------------------------------------
  421.  
  422. function selContains(p)
  423.     for i,g in pairs(selGroups) do
  424.         for i2,g2 in pairs(g) do
  425.             if g2==p then
  426.                 return{g,i,i2}
  427.             end
  428.         end
  429.     end
  430. end
  431.  
  432. function clearSelection()
  433.     for i,g in pairs(selections) do
  434.         g.destroy()end
  435.     selections={}
  436.     selGroups={}
  437.     setMode()
  438. end
  439.  
  440. function getSelection(groups)
  441.     local t={}
  442.     for i,g in pairs(selGroups) do
  443.         if groups and g[0] then
  444.             t[#t+1]=g[0]
  445.         else
  446.             for i=1,#g do
  447.                 t[#t+1]=g[i]
  448.             end
  449.         end
  450.     end
  451.     return t
  452. end
  453.  
  454. --[[
  455. function setSelection(t)
  456.     clearSelection()
  457.     if active then
  458.         for i,g in pairs(t) do
  459.             if type(g)~='table' then
  460.                 g={g}end
  461.             selGroups[i]=g
  462.             selections[i]=selFuncs
  463.             [settings.selMode][2](g[1])
  464.         end
  465.         setMode(nil,settings.
  466.         selectsFirst and 1 or#t)
  467.     end
  468.     return t
  469. end
  470.  
  471. function setSel(t)
  472.     local t=t or{}
  473.     for i=1,math.max(#selGroups,#t) do
  474.         selGroups[i]=t[i]end
  475. end
  476. ]]
  477.  
  478. local addWhenUpd8=true
  479. function upd8GameSel()
  480.     if plugin then
  481.         addWhenUpd8=false
  482.         game.Selection:Set(
  483.             getSelection(true))
  484.         addWhenUpd8=true
  485.     end
  486. end
  487.  
  488. --The part does not have to be a BasePart.
  489. function addSelection(p,solo)
  490.     if active then
  491.         local solo=solo
  492.         and not p:isA'Model'
  493.         local t=solo and{{p
  494.         }}or getSelParts(p)
  495.         local c=#selGroups
  496.         if #t>0 then
  497.             if t[1][1]:
  498.             isA'BasePart'then
  499.                 for i=1,#t do
  500.                     local doIt=true
  501.                     if not solo then
  502.                         for i2=1,#t[i] do
  503.                             if selContains(t
  504.                             [i][i2]) then
  505.                                 doIt=false
  506.                             end
  507.                         end
  508.                     end
  509.                    
  510.                     if doIt then
  511.                         c=c+1
  512.                         t[i][0]=t[0]
  513.                         selGroups[c]=t[i]
  514.                         selections[c]=selFuncs
  515.                         [settings.selMode]
  516.                         [2](t[i][1])
  517.                     end
  518.                 end
  519.                 print'Selecktetto.'
  520.                 setMode(nil,settings.selectsFirst and 1 or c)
  521.             end
  522.             --Returns the part if success.
  523.             return p
  524.         end
  525.     end
  526. end
  527.  
  528. function removeSelection(p)
  529.     local parts=selContains(p)
  530.     if not parts then
  531.         return end
  532.    
  533.     local t=getSelParts(p)
  534.     for i in pairs(selGroups) do
  535.         local sel=selGroups[i]
  536.         while sel and((t[0]and selGroups
  537.         [i][0]==t[0])or sel==parts[1])do
  538.             selections[i].destroy()
  539.             sel=selGroups[i+1]
  540.             for i2=i+1,#selGroups+1 do
  541.                 selections[i2-1]
  542.                 =selections[i2]
  543.                 selGroups[i2-1]
  544.                 =selGroups[i2]
  545.             end
  546.         end
  547.     end
  548.    
  549.     local pl=#selGroups~=1
  550.     print('There '..(pl and'are'or'is')
  551.     ..' currently '..#selGroups..' part'
  552.     ..(pl and's'or'')..' selected after removal.')
  553.     setMode(nil,selI
  554.     >#selections and
  555.         (settings.
  556.     selectsFirst and 1
  557.     or#selections)
  558.     or nil)
  559.     return p
  560. end
  561.  
  562. function toggleSelection(p,...)
  563.     if not removeSelection(p,...) then
  564.         addSelection(p,...)
  565.     end
  566. end
  567.  
  568. local stInfo,snapped={}
  569. local submode,increment
  570. local handles
  571. local adornee
  572. local mode=1
  573.  
  574. local secK=not plugin
  575. and'Control'or'Shift'
  576. local secondOn
  577. local binders={}
  578.  
  579. game:service'UserInputService'
  580. .InputBegan:connect(function(inp)
  581.     if inp.UserInputType
  582.     .Name=='Keyboard'
  583.     and inp.KeyCode
  584.     .Name:find(secK)then
  585.         print'Special key pressed.'
  586.         secondOn=true
  587.     end
  588. end)
  589. game:service'UserInputService'
  590. .InputEnded:connect(function(inp)
  591.     if inp.UserInputType
  592.     .Name=='Keyboard'
  593.     and inp.KeyCode
  594.     .Name:find(secK)then
  595.         print'Special key released.'
  596.         secondOn=false
  597.     end
  598. end)
  599.  
  600. function bindH(t)
  601.     if active then
  602.         game.ContextActionService
  603.         :BindAction(t.name,
  604.         function(nme,state)
  605.             if state.Name
  606.             =='Begin'then
  607.                 if not secondOn
  608.                 ==not t.second then
  609.                     t.func()
  610.                 else
  611.                     for i,g in pairs(binders) do
  612.                         if g~=t
  613.                         and g.bind
  614.                         ==t.bind then
  615.                             g.func()
  616.                         end
  617.                     end
  618.                 end
  619.             end
  620.         end,false
  621.         ,t.bind)
  622.     end
  623. end
  624.  
  625. function bind(
  626. n,f,k,second)
  627.     binders
  628.     [n]={
  629.     bind=k,
  630.     func=f,
  631.     name=n,
  632.     second=
  633.     second}
  634.    
  635.     local override=true
  636.     --[[
  637.     for i,g in pairs(binders) do
  638.         if g.bind==k and g.
  639.         second~=second then
  640.             override=false
  641.         end
  642.     end
  643.     ]]
  644.     if override then
  645.         bindH(binders[n])
  646.     end
  647. end
  648.  
  649. function unbind(n)
  650.     game.ContextActionService
  651.     :UnbindAction(n)
  652.     binders[n]=nil
  653. end
  654.  
  655. function rsBind(n,f)
  656.     rs:BindToRenderStep(n,666,f)
  657. end
  658.  
  659. function rsUnbind(n,f)
  660.     rs:UnbindFromRenderStep(n)
  661. end
  662.  
  663. local tempParts={}
  664. --Used for creating a bounding box.
  665. function forObjCentre(handles,a)
  666.     local p=Instance.new'Part'
  667.     p.Size=util.bounding(a)[2]
  668.     p.Position=a.Position
  669.     --p.Transparency=1
  670.     p.Anchored=true
  671.    
  672.     --p.Parent=game.workspace
  673.     handles.Adornee=p
  674.     tempParts[1]=p
  675.     return p
  676. end
  677.  
  678. function forGroup(handles,a)
  679.     if not plugin then
  680.         return forObjCentre(handles,a)
  681.     end
  682.    
  683.     local p=Instance.new'Part'
  684.     p.Position,p.Size=unpack(util
  685.     .bounding(getSelection()))
  686.     --p.Transparency=1
  687.     p.Anchored=true
  688.    
  689.     --p.Parent=game.workspace
  690.     handles.Adornee=p
  691.     tempParts[1]=p
  692.     return p
  693. end
  694.  
  695. local edgeSaved
  696. function forEdge(handles,a,changed)
  697.     local p=Instance.new'Part'
  698.     handles.Adornee=nil
  699.     p.Anchored=true
  700.     tempParts[1]=p
  701.        
  702.     if changed or not edgeSaved then
  703.         local sel=Instance.new'SelectionBox'
  704.         sel.SurfaceColor3=accColour()
  705.         sel.SurfaceTransparency=0
  706.         sel.Parent=core
  707.         sel.Transparency=1
  708.         sel.Adornee=p
  709.        
  710.         local cft={}
  711.         local edge,relV3,mag
  712.         for i,g in pairs(settings.fromAllEdges
  713.         and(function()
  714.             local t={}
  715.             scanParts(game.
  716.             workspace,t,
  717.             function(p)
  718.                 return p:
  719.                 isA'BasePart'
  720.             end)
  721.             return t
  722.         end)()or selGroups) do
  723.             cft[i]=util.surroundingCF(type(g
  724.             )=='table' and g[1] or g)
  725.         end
  726.        
  727.         local dunn
  728.         spawn(function()
  729.             while not dunn and wait() do
  730.                 if mouse.Hit then
  731.                     mag=nil
  732.                     for i,g in pairs(cft) do
  733.                         for i2,g2 in pairs(g) do
  734.                             local cMag=(mouse.
  735.                             Hit.p-g2[2].p).magnitude
  736.                             if not mag or cMag<mag then
  737.                                 edge=g[i2][2]
  738.                                 relV3=g2[1]
  739.                                 mag=cMag
  740.                             end
  741.                         end
  742.                     end
  743.                    
  744.                     local dist=math.min(1/10*(
  745.                         game.workspace.CurrentCamera.
  746.                         CFrame.p-edge.p).magnitude,1)
  747.                     p.Size=dist*Vector3.new(1,1,1)
  748.                     p.CFrame=edge
  749.                 end
  750.             end
  751.         end)
  752.        
  753.         mouse.Button1Up:wait()
  754.         p.Size=Vector3.new()
  755.         edgeSaved=edge
  756.         sel:destroy()
  757.         dunn=true
  758.     else
  759.         p.CFrame=edgeSaved
  760.     end
  761.    
  762.     p.Size=Vector3.new()
  763.     handles.Adornee=p
  764.     return p
  765. end
  766.  
  767. function partDataTable(p)
  768.     local bm=p[1]:FindFirstChildOfClass'BlockMesh'
  769.     return{cf=p[1].CFrame,size=p[1].Size*(
  770.     bm and bm.Scale or Vector3.new(1,1,1)),
  771.     anchored=p[1].Anchored,parts=p}
  772. end
  773.  
  774. function newPart()
  775.     local sG=selGroups[1]
  776.     local p=Instance.new'Part'
  777.     local dist=settings.newPartDist
  778.     local pos
  779.     if plugin then
  780.         local cf=game.workspace.CurrentCamera.CFrame
  781.         pos=cf.p+dist*cf.lookVector
  782.     else
  783.         local cf=player.Character:GetPrimaryPartCFrame()
  784.         pos=cf.p+dist*Vector3.new(cf.lookVector.x,0,cf.lookVector.z)
  785.     end
  786.     p.Position=pos
  787.     p.Size=Vector3.new(1,1,1)
  788.     p.Parent=sG and(sG[0]or sG[1
  789.     ].Parent)or game.workspace
  790.     p.BottomSurface='Smooth'
  791.     p.TopSurface='Smooth'
  792.     p.Anchored=true
  793.     addSelection(p)
  794.     upd8GameSel()
  795.    
  796.     if not plugin then
  797.         partF(p,player)end
  798.     return p
  799. end
  800.  
  801. local welds=game
  802. .JointsService
  803. :children()
  804. function weldSelection()
  805.     local main=selGroups[selI][1]
  806.     for i,g in pairs(selGroups) do
  807.         for i2,g2 in
  808.          pairs(g) do
  809.             if i2>=2
  810.             or i~=selI then
  811.                 local w=Instance.new'Weld'
  812.                 w.Parent=game.JointsService
  813.                 w.Part0,w.Part1,w.C0
  814.                 =main,g2,main.CFrame
  815.                 :inverse()*g2.CFrame
  816.                 welds[#welds+1]=w
  817.             end
  818.         end
  819.     end
  820. end
  821.  
  822. function getWelded(p)
  823.     local t,T={}
  824.     if not p then
  825.         T=getSelection()
  826.     elseif type(p)
  827.     =='userdata'then
  828.         T={p
  829.         }end
  830.    
  831.     for i,g in pairs(welds) do
  832.         for i2,g2 in pairs(T) do
  833.             local doIt=p~=g2
  834.             for i3,g3 in pairs(t) do
  835.                 if( g3.Part0==g.Part0
  836.                 and g3.Part1==g.Part1)
  837.                 or( g3.Part1==g.Part0
  838.                 and g3.Part0==g.Part1)then
  839.             doIt=false end end
  840.             if doIt and(g.Part0==g2 or g.Part1==g2)then
  841.                 t[#t+1]=g
  842.                 for i3,g3 in pairs(getWelded(g2)) do
  843.                     t[#t+1]=g3
  844.                 end
  845.             end
  846.         end
  847.     end
  848.     return t
  849. end
  850.  
  851. function begin(p,a,t)
  852.     if t.groupI*t
  853.     .selI<2 then
  854.         stInfo={}
  855.         origData={}
  856.         createST()
  857.         snapped=0
  858.         upd8ST()
  859.         origData.temp={}
  860.         for i,g in pairs(tempParts) do
  861.             origData.temp[i]
  862.             =partDataTable{g}
  863.         end
  864.        
  865.         for i,g in pairs(getWelded()) do
  866.             g.Parent=nil end
  867.     end
  868.    
  869.     if t.groupI<2 then
  870.         local c={}
  871.         for i,g in pairs(
  872.          selGroups
  873.         [t.selI]) do
  874.             c[#c+1]=g
  875.         end
  876.         origData[t.selI]
  877.         =partDataTable(c)
  878.     end
  879.     p.Anchored=true
  880. end
  881.  
  882. function release(p,a,t)
  883.     p.Anchored=origData
  884.     [t.selI].anchored
  885.     if t.index<2 then
  886.         pData={}
  887.         print'Released.'
  888.         removeST()
  889.     end
  890.    
  891.     pData[t.selI]
  892.     =partDataTable{p}
  893.     if t.last then
  894.         createWaypoint()
  895.         for i,g in pairs(getWelded()) do
  896.             g.C0=g.Part0.
  897.             CFrame:inverse()
  898.             *g.Part1.CFrame
  899.             g.Parent=game.JointsService
  900.         end
  901.     end
  902. end
  903.  
  904. --NOTE: This code makes it possible for the server to move parts for FE compatibility.
  905. local cp=require(script.CrossPeer)
  906. function callCPFunc(name,...)
  907.     cp[name](...)
  908.     if not plugin then
  909.         script.Move:FireServer(name,...)
  910.     end
  911. end
  912.  
  913. function setSize(...)
  914.     callCPFunc('setSize',...)
  915. end
  916.  
  917. function setCFrame(...)
  918.     callCPFunc('setCFrame',...)
  919. end
  920.  
  921. local colourMode={
  922.     materialInfo=(function()
  923.         local t={}
  924.         for i,g in pairs(materialIds) do
  925.             t[i]={transparency
  926.             =i=='Plastic'and 0
  927.             or 01,dim={0,1,0}}
  928.         end
  929.         return t
  930.     end)(),
  931. }
  932.  
  933. function colourFromCoords(v,brickColor)
  934.     local c=Color3
  935.     .fromHSV(v[1],1
  936.     -v[2],(1-v[3]))
  937.    
  938.     if brickColor then
  939.         return BrickColor.
  940.         new(c).Color
  941.     end
  942.     return c
  943. end
  944.  
  945. function lookGui()
  946.     local upd88s={}
  947.     local mat=script.
  948.     SpecialGui.Material:clone()
  949.     local fr,c=mat.Table.Frame,0
  950.     for i,g in pairs(materialIds) do
  951.         local sl=c==0 and
  952.          fr or fr:clone()
  953.         local il=sl
  954.         .ImageLabel
  955.        
  956.         sl.ImageLabel.Image
  957.         ='rbxassetid://'..g
  958.         il.ImageRectSize
  959.         =140*Vector2.new(5
  960.         ,7/materialCount)
  961.         il.TextLabel.Text=i
  962.         sl.LayoutOrder=c
  963.         sl.Name=i
  964.         sl.Parent
  965.         =mat.Table
  966.         c=c+1
  967.        
  968.         local function upd88()
  969.             local il=sl
  970.             .ImageLabel
  971.             local colour
  972.             =colourFromCoords(
  973.                 colourMode.
  974.                 materialInfo[
  975.                 i].dim,true)
  976.             local trans
  977.             =colourMode.
  978.             materialInfo[i
  979.             ].transparency
  980.             il.TransDisplay.
  981.             BackgroundTransparency=trans
  982.             sl.ImageLabel.TransDisplay.
  983.             BackgroundColor3=colour
  984.             il.ImageColor3=colour
  985.             sl.ImageLabel
  986.             .TextBox.Text
  987.             =toNum(trans)
  988.            
  989.             local eCol=.1313*colour
  990.             .r+.6781*colour.g+.1566
  991.             *colour.b>=.5 and Color3
  992.             .new()or Color3.new(1,1,1)
  993.             il.TextBox.TextColor3,il
  994.             .TextLabel.TextColor3,il
  995.             .TransDisplay.TextColor3
  996.             ,il.Frame.BackgroundColor3
  997.             =eCol,eCol,eCol,eCol
  998.         end
  999.         upd88s[i
  1000.         ]=upd88
  1001.        
  1002.         il.TextBox.FocusLost
  1003.         :connect(function()
  1004.             local txt=il.
  1005.             TextBox.Text
  1006.             local n=tonumber(txt)
  1007.             if n and 0<=n
  1008.             and n<=1 then
  1009.                 colourMode.materialInfo[i].
  1010.                 transparency=tonumber(txt)
  1011.             end
  1012.             upd88()
  1013.         end)
  1014.        
  1015.         il.TransDisplay.
  1016.         MouseButton1Down:
  1017.         connect(function()
  1018.             colourMode.materialInfo
  1019.             [i].dim=colourGui(mat.
  1020.             Colours,colourMode
  1021.             .materialInfo[i].
  1022.             dim,true,i)upd88()
  1023.         end)
  1024.        
  1025.         upd88()
  1026.     end
  1027.    
  1028.     mat.Colour.
  1029.     MouseButton1Down:
  1030.     connect(function()
  1031.         local dim=colourGui(mat.Colours
  1032.         ,colourMode.materialInfo.Plastic
  1033.         .colour,true,'All materials')
  1034.        
  1035.         for i,g
  1036.         in pairs(colourMode
  1037.         .materialInfo) do
  1038.             g.dim=dim
  1039.             upd88s[i]()
  1040.         end
  1041.     end)
  1042.    
  1043.     return mat,function()
  1044.         local doIt
  1045.         for i2,g2 in pairs(colourMode
  1046.             .materialInfo) do
  1047.             if g2.transparency<1 then
  1048.                 doIt=true
  1049.             end
  1050.         end
  1051.        
  1052.         if doIt then
  1053.             local oParts,nParts={},{}
  1054.             for i,g in pairs(selGroups) do
  1055.                 selections[i]:destroy()
  1056.                 local parent=g[1].Parent
  1057.                 oParts[i]={}nParts[i]={}
  1058.                 for i2,g2 in pairs(g) do
  1059.                     g2.Parent=nil
  1060.                     oParts[i][1
  1061.                     +#oParts
  1062.                     [i]]=g2
  1063.                 end
  1064.                
  1065.                 local count=0
  1066.                 selGroups[i]=g
  1067.                 for i2,g2 in pairs(colourMode
  1068.                     .materialInfo) do
  1069.                     if g2.transparency<1 then
  1070.                         local p=g[1]:clone()
  1071.                        
  1072.                         p.Material=i2
  1073.                         p.Parent=parent
  1074.                         p.Transparency=g2.transparency
  1075.                         p.Color=colourFromCoords(g2.dim)
  1076.                         count=count+1
  1077.                         g[count]=p
  1078.                         nParts[i][1
  1079.                         +#nParts
  1080.                         [i]]=p
  1081.                     end
  1082.                 end
  1083.                
  1084.                 for i2=#g,count+1,-1 do
  1085.                     g[i2]=nil
  1086.                 end
  1087.                
  1088.                 selections[i]=selFuncs
  1089.                 [settings.selMode][2](g[1])
  1090.             end
  1091.            
  1092.             createWaypoint{oParts,
  1093.             nParts,mode='colour'}
  1094.             upd8GameSel()
  1095.         else
  1096.             warn'You can\'t do it when all materials are invisible!'
  1097.         end
  1098.     end
  1099. end
  1100.  
  1101. function colourGui(parent,dim,brickColor,str)
  1102.     print'Colour grid creates.'
  1103.     local col=clTemplate:clone()
  1104.     local chuser=col.Choosers
  1105.     local p=chuser.ColourFrame
  1106.     local sl=chuser.SlideFrame
  1107.     local dim=dim or{0,1,0}
  1108.     local pC=p.Colour
  1109.     col.Parent=parent
  1110.     local colourT={}
  1111.     col.Visible=true
  1112.     col.Desc.Text
  1113.     =str or''
  1114.    
  1115.     wait()
  1116.     local cSize=p.AbsoluteSize
  1117.     chuser.Size=chuser.Size-UDim2
  1118.     .new(0,cSize.x%8,0,cSize.y%8)
  1119.     local X,Y=p.AbsoluteSize
  1120.     .x/8,p.AbsoluteSize.y/8
  1121.     --print(X,Y)
  1122.    
  1123.     local function
  1124.     updateGrid(pos)
  1125.     local colour=colourFromCoords(dim,brickColor)
  1126.         for x=0,X do
  1127.             for y=1,Y do
  1128.                 local c=colourFromCoords(x>0
  1129.                 and{(x-.5)/X,(y-.5)/Y,dim[3]
  1130.                 }or{dim[1],dim[2],(y-.5)
  1131.                 /Y},brickColor and x>0)
  1132.                 colourT[x][y].BackgroundColor3=c
  1133.             end
  1134.         end
  1135.        
  1136.         local b
  1137.         if colour then
  1138.             b=BrickColor.new(colour)
  1139.             col.BrickColorButton.Colour.
  1140.             BackgroundColor3=b.Color
  1141.             col.Color3Button.Colour.
  1142.             BackgroundColor3=colour
  1143.         end
  1144.        
  1145.         col.Value.Text
  1146.         =colour and(brickColor
  1147.         and b.Number..' '..b.Name
  1148.        
  1149.         or math.floor(255*colour.r)..' '
  1150.         ..math.floor(255*colour.g)..' '
  1151.         ..math.floor(255*colour.b))or''
  1152.     end
  1153.    
  1154.     for x=0,X do
  1155.         colourT[x]={}
  1156.         for y=1,Y do
  1157.             local c=(x>0 or y>1)
  1158.             and pC:clone() or pC
  1159.             c.LayoutOrder=x+y*X
  1160.             colourT[x][y]=c
  1161.             c.Parent=x>0
  1162.             and p or sl
  1163.         end
  1164.     end
  1165.    
  1166.     p.InputBegan:connect(function(input)
  1167.         if input.UserInputType.
  1168.         Name=='MouseButton1' then
  1169.             local pos=input.Position
  1170.             pos=(Vector2.new(pos.X,pos
  1171.             .Y)-p.AbsolutePosition
  1172.             )/Vector2.new(X*8,Y*8)
  1173.             colourMode.colour
  1174.             =colourFromCoords({pos.X,
  1175.             pos.Y,dim[3]},brickColor)
  1176.             dim[1],dim[2]
  1177.             =pos.X,pos.Y
  1178.             updateGrid(pos)
  1179.         end
  1180.     end)
  1181.     sl.InputBegan:connect(function(input)
  1182.         if input.UserInputType.
  1183.         Name=='MouseButton1' then
  1184.             local pos=(input.Position.Y
  1185.             -p.AbsolutePosition.Y)/Y/8
  1186.             colourMode.colour
  1187.             =colourFromCoords({dim[1
  1188.             ],dim[2],pos},brickColor)
  1189.             dim[3]=pos
  1190.             updateGrid(pos)
  1191.         end
  1192.     end)
  1193.    
  1194.     col.BrickColorButton
  1195.     .MouseButton1Down
  1196.     :connect(function()
  1197.         brickColor
  1198.         =true
  1199.         updateGrid()
  1200.     end)
  1201.     col.Color3Button
  1202.     .MouseButton1Down
  1203.     :connect(function()
  1204.         brickColor
  1205.         =false
  1206.         updateGrid()
  1207.     end)
  1208.    
  1209.     updateGrid()
  1210.     col.Button.MouseButton1Down:wait()
  1211.     print'Finally.'
  1212.     col:destroy()
  1213.     return dim
  1214. end
  1215.  
  1216. commands={
  1217.     {name='move',
  1218.         key='z',
  1219.         colour=Color3.new(),
  1220.         handles=handlesF.MoveHandles,
  1221.         current={
  1222.             submode=1,
  1223.             incr={1},
  1224.         },
  1225.         submodes={
  1226.             'axis',
  1227.             'first',
  1228.             'object',
  1229.             'similar',
  1230.             'axis-oid',
  1231.         },
  1232.         submodeFunc={
  1233.             [1]=forGroup,
  1234.             [5]=forObjCentre,
  1235.         },
  1236.        
  1237.         MouseDrag=function(part,main,i,face,dist)
  1238.             local new,isBloqued
  1239.             local initial=part.CFrame
  1240.             local orig=origData[i.selI].cf
  1241.             local inc=commands[mode].current.incr[1]
  1242.             snapped=math.floor(dist/inc+.5)*inc
  1243.            
  1244.             local sm=commands[mode].current.submode-1
  1245.             if sm<1 then
  1246.                 new=orig+snapped*Vector3.FromNormalId(face)
  1247.                
  1248.             elseif sm<2 then
  1249.                 new=orig+main.CFrame
  1250.                 [({'right','up','look'})
  1251.                 [util.axisIndexFromNormal(face)]..'Vector']*
  1252.                 snapped*util.signForNormal(face)
  1253.                
  1254.             elseif sm<3 then
  1255.                 new=orig*CFrame.new(snapped*
  1256.                 Vector3.FromNormalId(face))
  1257.                
  1258.             elseif sm<4 then
  1259.                 new=orig*CFrame.new(
  1260.                 snapped*Vector3.FromNormalId(
  1261.                 util.localNormal(
  1262.                 part,util.globalNormal(main,face))))
  1263.                
  1264.             elseif sm<5 then
  1265.                 new=orig*CFrame.new(
  1266.                 snapped*Vector3.FromNormalId(
  1267.                 util.localNormal(part,face)))          
  1268.             end
  1269.            
  1270.             if i.groupI<2 and i.isAdorneer and tempParts[1] then
  1271.                 tempParts[1].CFrame=(sm<2 and plugin)and new*main
  1272.                 .CFrame:inverse()*tempParts[1].CFrame or CFrame.new(new.p)
  1273.             end
  1274.            
  1275.             setCFrame(part,new)
  1276.             --if not isBloqued then
  1277.                 stInfo[i.index]=snapped
  1278.             --end
  1279.            
  1280.             if i.last then
  1281.                 upd8ST()
  1282.             end
  1283.         end,
  1284.         MouseButton1Down=begin,
  1285.         MouseButton1Up=release,
  1286.     },
  1287.     {name='resize',
  1288.         key='x',
  1289.         colour=Color3.fromRGB(0,120,215),
  1290.         handles=handlesF.ResizeHandles,
  1291.         current={
  1292.             submode=1,
  1293.             incr={1},
  1294.         },
  1295.         submodes={
  1296.             'side',
  1297.             'centre',
  1298.             'uniform',
  1299.             'scale',
  1300.             'part scale',
  1301.             'edge scale',
  1302.         },
  1303.         submodeFunc={
  1304.             [4]=forGroup,
  1305.             [5]=forObjCentre,
  1306.             [6]=forEdge,
  1307.         },
  1308.         MouseDrag=function(part,main,i,face,dist)
  1309.             local initial={part.CFrame,part.Size}
  1310.             local orig=origData[i.selI]
  1311.             local size=orig.size
  1312.             local cf=orig.cf
  1313.             local sign=1
  1314.            
  1315.             local a=util.axisFromNormal(face)
  1316.             local axis=Vector3.FromAxis(a)
  1317.             local sm=commands[mode].current.submode
  1318.             local inc=commands[mode].current.incr[1]
  1319.            
  1320.             if sm<2 then
  1321.                 snapped=math.floor(dist/inc+.5)*inc
  1322.             else
  1323.                 snapped=math.floor(dist/inc*2+.5)*inc
  1324.             end
  1325.            
  1326.             if sm<3 then
  1327.                 size=size+snapped*
  1328.                 Vector3.FromAxis(a)
  1329.                 if size[a.Name]<0 then
  1330.                     sign=-1
  1331.                     size=size-
  1332.                     size[a.Name]*
  1333.                     axis*(settings.
  1334.                     resizeNegative
  1335.                     and 2 or 1)
  1336.                 end
  1337.             else
  1338.                 local m=snapped/(origData.temp[1]or
  1339.                 origData[i.selI]).size[a.Name]+1
  1340.                 local M=(settings.resizeNegative
  1341.                 and math.abs(m)or math.max(m,0))
  1342.                 size=M*size
  1343.                 if sm>3 then
  1344.                     cf=cf-(cf.p-origData
  1345.                     .temp[1].cf.p)*(1-m)
  1346.                     tempParts[1].Size=M*
  1347.                     origData.temp[1].size
  1348.                     tempParts[1].CFrame=
  1349.                     origData.temp[1].cf
  1350.                 end
  1351.                 if m<0 then
  1352.                     sign=-1
  1353.                 end
  1354.             end
  1355.            
  1356.            
  1357.             if sm<2 then
  1358.                 cf=cf*CFrame.new((
  1359.                 sign*size-orig.size)
  1360.                 [a.Name]*Vector3.
  1361.                 FromNormalId(face)/2)
  1362.             end
  1363.            
  1364.             local rSize=setSize(part,size)
  1365.             stInfo[i.index]=size[a.Name]
  1366.             setCFrame(part,cf)
  1367.             if i.last then
  1368.                 upd8ST()
  1369.             end
  1370.         end,
  1371.         MouseButton1Down=begin,
  1372.         MouseButton1Up=release,
  1373.     },
  1374.     {name='rotate',
  1375.         key='c',
  1376.         colour=Color3.new(1,1,1),
  1377.         handles=handlesF.RotateHandles,
  1378.         current={
  1379.             submode=1,
  1380.             incr={30},
  1381.         },
  1382.         submodes={
  1383.             'part',
  1384.             'group',
  1385.             'first',
  1386.             'base',
  1387.             'edge',
  1388.             'face',
  1389.         },
  1390.         submodeFunc={
  1391.             [2]=forGroup,
  1392.             [4]=forObjCentre,
  1393.             [5]=forEdge,
  1394.         },
  1395.         MouseDrag=function(part,main,i,axis,rad,dist)
  1396.             local init=part.CFrame
  1397.             local orig=origData[i.selI]
  1398.             local sm=commands[mode].current.submode
  1399.             local inc=commands[mode].current.incr[1]
  1400.            
  1401.             --Rotate face only.
  1402.             if sm>5 then
  1403.                 local a=math.floor(rad/math.pi*2+.5)
  1404.                 local size,sizeT,tempA,tempI=orig.size,{}
  1405.                 for i,g in pairs(Enum.Axis:GetEnumItems()) do
  1406.                     if g~=axis and a%2>0 then
  1407.                         if tempA then
  1408.                             local temp=
  1409.                             size[tempA]
  1410.                             sizeT[tempI]=
  1411.                             size[g.Name]
  1412.                             sizeT[i]=temp
  1413.                         else
  1414.                             tempA,tempI
  1415.                             =g.Name,i
  1416.                         end
  1417.                     else
  1418.                         sizeT[i]=
  1419.                         size[g.Name]
  1420.                     end
  1421.                 end
  1422.                
  1423.                 setSize(part,Vector3.new(unpack(sizeT)))
  1424.                 setCFrame(part,orig.cf*CFrame.fromAxisAngle(
  1425.                     Vector3.FromAxis(axis),a*math.pi/2))
  1426.                 return
  1427.             end
  1428.            
  1429.             --Every other type of rotation.
  1430.             local cf
  1431.             local a=math.deg(rad)%360
  1432.             if a>180 then
  1433.                 a=a-360 end
  1434.             snapped=math.floor(a/inc+.5)*inc
  1435.             local rot=CFrame.fromAxisAngle(
  1436.                 Vector3.FromAxis(axis),math.rad(snapped))
  1437.             if sm<2 then
  1438.                 cf=orig.cf*rot
  1439.             elseif tempParts[1] then
  1440.                 local rotCF=origData.temp[1].cf
  1441.                 cf=rotCF*(rot*(rotCF:inverse()*orig.cf))
  1442.                 tempParts[1].CFrame=rotCF*rot
  1443.             else
  1444.                 local ocf=origData[selI].cf
  1445.                 cf=ocf*(rot*(ocf:inverse()*orig.cf))
  1446.             end
  1447.             setCFrame(part,cf)
  1448.            
  1449.             --[[
  1450.             local isBloquing
  1451.             if settings.blocking then
  1452.                 local p=part.Position
  1453.                 part.Position=Vector3.new()
  1454.                 part.Position=p
  1455.                 if part.Position~=p then
  1456.                     part.CFrame=init
  1457.                     isBloquing=true
  1458.                 end
  1459.             end
  1460.             ]]
  1461.            
  1462.             --if not isBloquing then
  1463.                 stInfo[i.index]=snapped
  1464.             --end
  1465.             if i.last then
  1466.                 upd8ST()
  1467.             end
  1468.         end,
  1469.         MouseButton1Down=begin,
  1470.         --A bit broken, may fix later on Roblox's part.
  1471.         MouseButton1Up=release,
  1472.     },
  1473.     {name='utility',
  1474.         key='v',
  1475.         colour=Color3.new(1),
  1476.         current={
  1477.             submode=1,
  1478.         },
  1479.         submodes={
  1480.             'duplicate',
  1481.             'new part',
  1482.             'weld',
  1483.         },
  1484.         submodeFunc={
  1485.             duplicate,
  1486.             --[[ NOTE: 3D selection is actually very ineffective.
  1487.             function()
  1488.                 local sel={}
  1489.                 local bounds={}
  1490.                 local iter,dunn=1
  1491.                
  1492.                 local evt=mouse.Button1Up:
  1493.                 connect(function()
  1494.                     iter=iter+1
  1495.                     dunn=iter>3
  1496.                 end)
  1497.                
  1498.                 local p=Instance.new'Part'
  1499.                 local sel=Instance.new'SelectionBox'
  1500.                 sel.SurfaceColor3=accColour()
  1501.                 sel.SurfaceTransparency=0
  1502.                 sel.Parent=core
  1503.                 p.Size=Vector3.new()
  1504.                 sel.Transparency=1
  1505.                 sel.Adornee=p
  1506.                
  1507.                 rsBind('region',function()
  1508.                     if iter<2 then
  1509.                         bounds[1]=
  1510.                         mouse.Hit.p
  1511.                     elseif iter<3 then
  1512.                         bounds[2]=
  1513.                         mouse.Hit.p-
  1514.                         Vector3.new(0,
  1515.                         mouse.Hit.p.y-
  1516.                         bounds[1].y)
  1517.                     else
  1518.                         bounds[2]=
  1519.                         bounds[2]+
  1520.                         Vector3.new(0,
  1521.                         mouse.Hit.p.y-
  1522.                         bounds[2].y)
  1523.                     end
  1524.                    
  1525.                     if #bounds>1 then
  1526.                         sel.SurfaceTransparency
  1527.                         =settings.planeTrans
  1528.                         p.Position=Vector3.new(
  1529.                             (bounds[1].x+
  1530.                             bounds[2].x)/2,
  1531.                             (bounds[1].y+
  1532.                             bounds[2].y)/2,
  1533.                             (bounds[1].z+
  1534.                             bounds[2].z)/2
  1535.                         )
  1536.                         p.Size=Vector3.new(
  1537.                             math.abs(bounds[
  1538.                             1].x-bounds[2].x),
  1539.                             math.abs(bounds[
  1540.                             1].y-bounds[2].y),
  1541.                             math.abs(bounds[
  1542.                             1].z-bounds[2].z)
  1543.                         )
  1544.                     else
  1545.                         p.Position
  1546.                         =bounds[1]
  1547.                     end
  1548.                 end)
  1549.                
  1550.                 while not dunn do
  1551.                     wait()end
  1552.                 evt:disconnect()
  1553.                 sel:destroy()
  1554.                 unbind'enter'
  1555.                
  1556.                 for i,g in pairs(game.workspace
  1557.                 :FindPartsInRegion3(Region3.new(
  1558.                 Vector3.new(math.min(bounds[1].x,
  1559.                 bounds[2].x),math.min(bounds[1].y,
  1560.                 bounds[2].y),math.min(bounds[1].z,
  1561.                 bounds[2].z)),Vector3.new(math.max(
  1562.                 bounds[1].x,bounds[2].x),math.max(
  1563.                 bounds[1].y,bounds[2].y),math.max(
  1564.                 bounds[1].z,bounds[2].z))))) do
  1565.                     addSelection(g)
  1566.                 end
  1567.                
  1568.                 upd8GameSel()
  1569.             end,
  1570.             ]]
  1571.             newPart,
  1572.             weldSelection,
  1573.         }
  1574.     },
  1575.     {name='look',
  1576.         key='n',
  1577.         colour=Color3.new(0,1),
  1578.         current={
  1579.             submode=1,
  1580.         },
  1581.         submodes={
  1582.             lookGui,
  1583.         },
  1584.         submodeFunc={},
  1585.     },
  1586. }
  1587.  
  1588. local modeIndicies={}
  1589. for i,g in pairs(commands) do
  1590.     modeIndicies[g.name]=i
  1591. end
  1592.  
  1593. --NOTE: an unused modding API.  No plans as of 2017-11-27 to do anything about it.
  1594. for i,g in pairs(defaults.mods[1]) do
  1595.     print(tostring(g.Parent))
  1596.     local m=require(g)
  1597.     for tI,t in pairs(m[1]and m or{m}) do
  1598.         local mode=tonumber(t.Mode)
  1599.         or modeIndicies[t.Mode
  1600.         or'utility']
  1601.        
  1602.         local cmd=commands[mode]
  1603.         if cmd then
  1604.             local oldCount
  1605.             =#cmd.submodes
  1606.             cmd.submodes[oldCount
  1607.             +1]=t.Submode
  1608.            
  1609.             for i2,g2 in pairs(t) do
  1610.                 if type(g2)=='function' then
  1611.                     if i2=='SelectionChange' then
  1612.                         cmd.submodeFunc
  1613.                         [oldCount+1]=g2
  1614.                     else
  1615.                         local f=cmd[i2]
  1616.                         cmd[i2]=function(...)
  1617.                             if cmd.current
  1618.                             .submode>oldCount then
  1619.                                 g2(getfenv(),...)
  1620.                             else
  1621.                                 f(...)
  1622.                             end
  1623.                         end
  1624.                     end
  1625.                 end
  1626.             end
  1627.         end
  1628.     end
  1629. end
  1630.  
  1631. --[[
  1632. for i,g in pairs(commands) do
  1633.     for i2,g2 in pairs(g) do
  1634.         if type(g2)=='function' then
  1635.         end
  1636.     end
  1637. end
  1638. ]]
  1639.  
  1640. --Argument passed in is a part.
  1641. selFuncs={
  1642.     {'box',function(part)
  1643.         if plugin then
  1644.             return{
  1645.                 part=part,
  1646.                 destroy=function()end
  1647.             }
  1648.         end
  1649.        
  1650.         local box=Instance.new'SelectionBox'
  1651.         box.LineThickness=settings.selBoxSize
  1652.         box.Color3=commands[mode].colour
  1653.         box.Parent=core
  1654.         box.Adornee=part
  1655.        
  1656.         return{
  1657.             part=part,
  1658.             destroy=function()
  1659.                 box:destroy()
  1660.             end,
  1661.         }
  1662.     end},
  1663.     {'plane',function(part)
  1664.         local hue=0
  1665.         local fol=Instance.new'Folder'
  1666.         fol.Name='Selection'
  1667.         fol.Parent=core
  1668.        
  1669.         for i,g in pairs(Enum.NormalId:GetEnumItems()) do
  1670.             local sg=Instance.new'SurfaceGui'
  1671.             sg.AlwaysOnTop=settings.planeTop
  1672.             sg.CanvasSize=Vector2.new(1,1)
  1673.             sg.Adornee=part
  1674.             sg.Parent=fol
  1675.             sg.Face=g
  1676.            
  1677.             local fr=Instance.new'Frame'
  1678.             fr.BackgroundColor3=Color3.fromHSV(hue
  1679.             %1,settings.planeS,settings.planeV)
  1680.             fr.BackgroundTransparency=settings.planeTrans
  1681.             fr.Size=UDim2.new(1,0,1,0)
  1682.             fr.BorderSizePixel=0
  1683.             fr.Parent=sg
  1684.            
  1685.             if(i%2==1) then
  1686.                 hue=hue+1/2
  1687.             else
  1688.                 hue=hue-1/3
  1689.             end
  1690.         end
  1691.        
  1692.         return{
  1693.             part=part,
  1694.             destroy=function()
  1695.                 fol:destroy()
  1696.             end,
  1697.         }
  1698.     end},
  1699. }
  1700.  
  1701. --rem is a table for reference purposes.
  1702. function scanParts(par,t,f,rem)
  1703.     t=t or{}
  1704.     for i,g in pairs(par:children()) do
  1705.         if scanParts(g,t
  1706.         ,f,rem)==0 then
  1707.         return end
  1708.        
  1709.         if not f or f(g) then
  1710.             t[#t+1]=g
  1711.             if rem then
  1712.                 if rem[1]<1 then
  1713.                     for i in pairs(t) do
  1714.                         t[i]=nil
  1715.                     end
  1716.                     t[1]='nope'
  1717.                     return
  1718.                 else
  1719.                     rem[1]
  1720.                     =rem[1]-1
  1721.                 end
  1722.             end
  1723.         end
  1724.     end
  1725. end
  1726.  
  1727. function isValidPart(p)
  1728.     return(plugin or(verify(p,player)and not(p.Parent:findFirstChild'Animate'and p.Parent
  1729.     :findFirstChild'Humanoid'))and(settings.selectLocked or not p.Locked))or not p:isA'BasePart'
  1730. end
  1731.  
  1732. function getMousePart()
  1733.     return mouse.Target
  1734. end
  1735.  
  1736. --Gets the parts to be selected from the target.
  1737. local groupLvl=0
  1738. function getSelParts(part)
  1739.     local orig=part
  1740.     if part:isA'BasePart' then
  1741.         if groupLvl<0 then
  1742.             local lvls=-1
  1743.             local par=part
  1744.             while par~=game do
  1745.                 par=par.Parent
  1746.                 lvls=lvls+1
  1747.             end
  1748.             for i=1,lvls+groupLvl do
  1749.                 --if part.Parent.Parent~=game then
  1750.                     part=part.Parent
  1751.                 --end
  1752.             end
  1753.         else
  1754.             for i=1,groupLvl do
  1755.                 if part.Parent.Parent~=game then
  1756.                     part=part.Parent
  1757.                 end
  1758.             end
  1759.         end
  1760.     end
  1761.    
  1762.     if not part:isA'BasePart'then
  1763.         local t,count,max={}
  1764.         ,0,settings.maxParts
  1765.         scanParts(part
  1766.         ,t,function(p)
  1767.             return p:isA'BasePart'
  1768.             and isValidPart(p)
  1769.         end,{max})
  1770.         print(#t)
  1771.        
  1772.         if t[1]=='nope'then
  1773.         return{}end
  1774.         print('This selection has '
  1775.         ..count..' parts.')
  1776.         for i,g in pairs(t) do
  1777.             t[i]={g}end
  1778.         t[0]=part
  1779.         return t
  1780.     end
  1781.    
  1782.     local t=isValidPart(
  1783.      part)and{part}or{}
  1784.     local par=part
  1785.     for i=1,settings.
  1786.     selectsSameCFrame do
  1787.         if par.Parent
  1788.         ==game then
  1789.             break
  1790.         end
  1791.         par=par.Parent or par
  1792.     end
  1793.    
  1794.     scanParts(par,t,function(p)
  1795.         return p~=part and
  1796.             p:isA'BasePart' and
  1797.             p.CFrame==part.CFrame and
  1798.             p.Size==part.Size and
  1799.             isValidPart(part)
  1800.     end)
  1801.    
  1802.     if #t>0 then
  1803.         --[[
  1804.         print('We have got '..#t..' part'
  1805.         ..(#t>2 and's'or'')..' selected.')
  1806.         ]]
  1807.         return{t}
  1808.     else
  1809.         return{}
  1810.     end
  1811. end
  1812.  
  1813. --[[ May allow for both box and plane selection?
  1814. setSelMode=function(s)
  1815.     settings.selMode=s
  1816.     for selI,sel in pairs(selGroups) do
  1817.         selections[selI]:destroy()
  1818.         selections[selI]=addSelection(sel)
  1819.     end
  1820. end
  1821. ]]
  1822.  
  1823. function reRender()
  1824.     mf.UIScale.Scale
  1825.     =settings.guiScaling
  1826.     config.UIScale.Scale
  1827.     =settings.guiScaling
  1828.     print'Rerenderring.'
  1829.     for i,g in pairs(selections) do
  1830.         g.destroy()
  1831.         selections[i]=selFuncs[settings.
  1832.         selMode][2](selGroups[i][1])
  1833.     end
  1834. end
  1835.  
  1836. function fromNum(n)
  1837.     return (''..n):gsub('%.(.'
  1838.     ..string.rep('.?',settings
  1839.     .decRound-1)..').*',',%1')
  1840. end
  1841. function toNum(s,p)
  1842.     if p then
  1843.         local f=s
  1844.         :sub(1,1)
  1845.         local rem
  1846.         =toNum(s
  1847.         :sub(2))
  1848.         if'+'==
  1849.          f then
  1850.             return p+rem
  1851.         elseif f
  1852.         =='-'then
  1853.             return p-rem
  1854.         elseif f
  1855.         =='*'then
  1856.             return p*rem
  1857.         elseif f
  1858.         =='/'then
  1859.             return p/rem
  1860.         elseif f
  1861.             =='%'then
  1862.             return p%rem
  1863.         end
  1864.     end
  1865.    
  1866.     if tonumber(s) then
  1867.         return s+0
  1868.     end
  1869.    
  1870.     local ftTable={s:find'^(%d+)\'%-?([%d%.]*)"?$'}
  1871.     if #ftTable>0 then
  1872.         return ftTable[3]+(ftTable[4]or 0)/12
  1873.     end
  1874.    
  1875.     for i,g in pairs{
  1876.         km=105e+3/32,
  1877.          m=105e+0/32,
  1878.         cm=105e-2/32,
  1879.         mm=105e-3/32,
  1880.        
  1881.         ft=1,
  1882.         yd=3,mi=5280,
  1883.         ['in']=1/12,
  1884.     }do
  1885.         local m={s:find('^([%d%.]+)%s*'..i..'$')}
  1886.         if m[3] then
  1887.             return g*m[3]
  1888.         end
  1889.     end
  1890. end
  1891.  
  1892. --Saves the increments stored in 'commands' for future use.
  1893. function updateConfigIncrs()
  1894.     local t={}
  1895.     for i,g in pairs(commands) do
  1896.         if g.current then
  1897.             t[i]=g.current.incr
  1898.         end
  1899.     end
  1900.     settings.incrs=t
  1901.     print'Saved.'
  1902. end
  1903.  
  1904. local defaultIncrs={}
  1905. for i,g in pairs(commands) do
  1906.     local t={}
  1907.     for i2,g2 in pairs(g.
  1908.     current.incr or{}) do
  1909.         t[i2]=g2 end
  1910.     defaultIncrs[i]=t
  1911. end
  1912.  
  1913. --Loads the increments from settings, if set to do so.
  1914. if settings.saveIncrs
  1915. and settings.incrs then
  1916.     local settingIncrs=settings.incrs
  1917.     for i,g in pairs(commands) do
  1918.         local incrs=settingIncrs[i]
  1919.         if g.current and incrs then
  1920.             g.current.incr=incrs
  1921.         end
  1922.     end
  1923. else
  1924.     updateConfigIncrs()
  1925. end
  1926.  
  1927. bind('increment',function()
  1928.     incBox:CaptureFocus()
  1929. end,'k')
  1930.  
  1931. incBox.Undo.MouseEnter:connect(function()
  1932.     incBox.TextColor3=accColour()
  1933.     local incr=commands[mode].current.incr
  1934.     incBox.Text=fromNum(incr[2]or incr[1])
  1935. end)
  1936. incBox.Undo.MouseLeave:connect(function()
  1937.     incBox.TextColor3=Color3.new(1,1,1)
  1938.     incBox.Text=fromNum(commands[mode].current.incr[1])
  1939. end)
  1940. incBox.Undo.MouseButton1Click:connect(function()
  1941.     incBox.TextColor3=Color3.new(1,1,1)
  1942.     local incr=commands[mode].current.incr
  1943.     incBox.Text=fromNum(incr[2])
  1944.     local first=incr[1]
  1945.     for i=1,#incr do
  1946.         incr[i]=incr[i+1] or first
  1947.     end
  1948.     updateConfigIncrs()
  1949. end)
  1950.  
  1951. incBox.Redo.MouseEnter:connect(function()
  1952.     incBox.TextColor3=accColour()
  1953.     local incr=commands[mode].current.incr
  1954.     incBox.Text=fromNum(incr[#incr])
  1955. end)
  1956. incBox.Redo.MouseLeave:connect(function()
  1957.     incBox.TextColor3=Color3.new(1,1,1)
  1958.     incBox.Text=fromNum(commands[mode].current.incr[1])
  1959. end)
  1960. incBox.Redo.MouseButton1Click:connect(function()
  1961.     incBox.TextColor3=Color3.new(1,1,1)
  1962.     local incr=commands[mode].current.incr
  1963.     local last=incr[#incr]
  1964.     incBox.Text=fromNum(last)
  1965.     for i=#incr,1,-1 do
  1966.         incr[i]=incr[i-1] or last
  1967.     end
  1968.     updateConfigIncrs()
  1969. end)
  1970.  
  1971. --Resets the increments
  1972. bind('clearIncs',function()
  1973.     print'Increments clearing.'
  1974.     if settings.clearAllOnIncrementClear then
  1975.         for i,g in pairs(commands) do
  1976.             g.current.incr={}
  1977.             --Not all modes need increments!
  1978.             for i2,g2 in pairs(
  1979.                 defaultIncrs[i]) do
  1980.                 g.current.incr[i2]=g2 end
  1981.         end else
  1982.             commands[mode].current.incr={}
  1983.             for i,g in pairs(defaultIncrs[mode]) do
  1984.                 commands[mode].current.incr[i]=g end
  1985.     end
  1986.    
  1987.     local incr=commands[mode].current.incr
  1988.     incBox.Text=fromNum(incr[1])
  1989.     updateConfigIncrs()
  1990. end,'m',true)
  1991.  
  1992. incBox.FocusLost:connect(function()
  1993.     local incr=commands
  1994.     [mode].current.incr
  1995.     local v=toNum(incBox
  1996.     .Text,incr[1])
  1997.    
  1998.     if v and v>0 then
  1999.         incBox.Text=v
  2000.         for i=#incr,0,-1 do
  2001.             incr[i+1]=incr[i] or v
  2002.         end
  2003.         updateConfigIncrs()
  2004.     else
  2005.         incBox.Text=incr[1]
  2006.     end
  2007. end)
  2008.  
  2009. local lvlBox=sm.Level.TextBox
  2010. bind('level',function()
  2011.     lvlBox:CaptureFocus()
  2012. end,'l')
  2013. lvlBox.FocusLost:connect(function()
  2014.     local v=toNum(lvlBox.Text)
  2015.     if v then
  2016.         lvlBox.Text=v
  2017.         groupLvl=v
  2018.     else       
  2019.         lvlBox.Text
  2020.         =groupLvl
  2021.     end
  2022. end)
  2023.  
  2024. config.Visible=false
  2025. sm.Config.Button.MouseButton1Click:connect(function()
  2026.     config.Visible=not config.Visible
  2027. end)
  2028. bind('config',function()
  2029.     config.Visible=not config.Visible
  2030. end,Enum.KeyCode.RightBracket)
  2031.  
  2032. local configTypes={}
  2033. for i,g in pairs(config:children()) do
  2034.     if g:isA'Frame' then
  2035.         configTypes[g.Name]=g:clone()
  2036.         g:destroy()
  2037.     end
  2038. end
  2039.  
  2040. defaults.selMode[3]=#selFuncs
  2041. for i,g in pairs(defaults) do
  2042.     local ty=type(g[1])
  2043.     local typeFrame=configTypes[ty]
  2044.     if typeFrame and g[2]~='NO_TOUCH' then
  2045.         local tf=typeFrame:clone()
  2046.         tf.TextLabel.Text=i
  2047.        
  2048.         if ty=='number' then
  2049.             local tb=tf.TextBox
  2050.             tb.Text=fromNum(settings[i])
  2051.             tb.FocusLost:connect(function()
  2052.                 local n=toNum(tb.
  2053.                 Text,settings[i])
  2054.                 if n
  2055.                 and (not g[2] or n>=g[2])
  2056.                 and (not g[3] or n<=g[3])
  2057.                 and (not g[4] or n%g[4]==0) then
  2058.                     settings[i]=n
  2059.                     print'Ja, the setting was changed.'
  2060.                 end
  2061.                 tb.Text=fromNum(settings[i])
  2062.             end)
  2063.            
  2064.         elseif ty=='boolean' then
  2065.             local upd8=function()
  2066.                 tf.TextLabel.TextColor3=settings[i] and accColour() or Color3.new(1,1,1)
  2067.             end
  2068.             upd8()
  2069.             tf.Button.MouseButton1Click:connect(function()
  2070.                 settings[i]=not settings[i]
  2071.                 upd8()
  2072.             end)
  2073.            
  2074.         end
  2075.         tf.Name=i
  2076.         tf.Parent=config
  2077.     end
  2078. end
  2079.  
  2080. --Set to the function keys!
  2081. local toolKeys={'Q','E','R','T','U','P'}
  2082. for i,g in pairs(toolKeys) do
  2083.     toolKeys[i]=g end
  2084.  
  2085. function setSubmode(ii)
  2086.     if ii then
  2087.         print'Submode set.'
  2088.     end
  2089.     local m=commands[mode]
  2090.     local prev=m.current.submode
  2091.     local i=ii or prev
  2092.     if m.submodes[i] then
  2093.         if type(m.submodes[prev])=='string' then
  2094.             sm[prev].TextLabel.TextColor3=Color3.new(1,1,1)
  2095.         end
  2096.         if type(m.submodes[i])=='string' then
  2097.             sm[i].TextLabel.TextColor3=accColour()
  2098.         end
  2099.        
  2100.         m.current.submode=i
  2101.         for i,g in pairs(tempParts) do
  2102.             g:destroy()
  2103.             tempParts[i]=nil
  2104.         end
  2105.        
  2106.         --Calls any selection-changing methods if any.
  2107.         canDoStuff=false
  2108.         local func=m.submodeFunc[i]
  2109.         if handles and handles.Adornee then
  2110.             handles.Adornee=type(func)
  2111.             =='function'and func(handles
  2112.             ,selGroups[selI][1],ii~=nil)
  2113.             or adornee
  2114.         elseif ii and not m.handles then
  2115.             func()
  2116.         end
  2117.         canDoStuff=true
  2118.     end
  2119. end
  2120.  
  2121. --Also used to change the main part, however not the submode.
  2122. function setMode(s,ii)
  2123.     reactiv8()
  2124.     local m=commands[mode]
  2125.     selI=ii or 1
  2126.    
  2127.     --Clone the handle as to not overlap events.
  2128.     if m.handles then
  2129.         m.handles.Adornee=nil
  2130.         handles=m.handles:clone()
  2131.         m.handles:destroy()
  2132.         m.handles=handles
  2133.     end
  2134.    
  2135.     mode=s or mode
  2136.     submode=1
  2137.    
  2138.     cmds[m.name].Keybind.
  2139.     TextColor3=Color3.new(1,1,1)
  2140.     m=commands[mode]
  2141.     cmds[m.name].Keybind.
  2142.     TextColor3=accColour()
  2143.    
  2144.     --Responsible for updating the handles and what not.
  2145.     if selections[selI] then
  2146.         if s then
  2147.             print('Mode '..s)
  2148.             reRender()
  2149.         end
  2150.        
  2151.         adornee=selections[selI].part
  2152.         handles=m.handles
  2153.         if handles then
  2154.             handles.Parent=core
  2155.             handles.Adornee=adornee
  2156.    
  2157.             print('The adornee is '..tostring(adornee)..'.')
  2158.             for i,g in pairs(m) do
  2159.                 if type(g)=='function' then
  2160.                     --Connects each command event to the handle so that it may function.
  2161.                     --handles[i]:connect(g)
  2162.                     handles[i]:connect(function(...)
  2163.                         --Iterates over each object in the selection.
  2164.                         if canDoStuff then
  2165.                             local index=0
  2166.                             local args={...}
  2167.                             --[[NOTE: The handleIntensity setting determines the proportion
  2168.                                 between how far you pull the handle and how far the object moves.]]
  2169.                             if i=='MouseDrag' then
  2170.                                 args[2]=args
  2171.                                 [2]*settings
  2172.                                 .handleIntensity
  2173.                             end
  2174.                            
  2175.                             for i2,g2 in pairs(selGroups) do
  2176.                                 for i3=1,#g2 do
  2177.                                     index=index+1
  2178.                                     g(g2[i3],adornee,{
  2179.                                         index=index,
  2180.                                         selI=i2,groupI=i3,
  2181.                                         isAdorneer=i2==selI and i3==1,
  2182.                                         last=i2==#selGroups and i3==#g2,
  2183.                                     },unpack(args))
  2184.                                 end
  2185.                             end
  2186.                         end
  2187.                     end)
  2188.                 end
  2189.             end
  2190.         end
  2191.        
  2192.         --[[
  2193.         if m.Activated then
  2194.             local index=0
  2195.             for i,g in pairs(selGroups) do
  2196.                 for i2,g2 in pairs(g) do
  2197.                     index=index+1
  2198.                     m.Activated(g2,adornee,{
  2199.                         index=index,
  2200.                         selI=i,groupI=i2,
  2201.                         isAdorneer=i==selI and i2==1,
  2202.                         last=i==#selGroups and i2==#g,
  2203.                     })
  2204.                 end
  2205.             end
  2206.         end
  2207.         ]]
  2208.     end
  2209.    
  2210.     --Now for the GUI stuffs.
  2211.     if s then
  2212.         local
  2213.         i,c=1
  2214.         while sm:findFirstChild(i) do
  2215.             sm:findFirstChild(i):destroy()
  2216.             i=i+1
  2217.         end
  2218.        
  2219.         for i,g in pairs(m.submodes) do
  2220.             if type(g)=='string' then
  2221.                 c=smTemplate:clone()
  2222.                 c.TextLabel.Text=g
  2223.                
  2224.             elseif type(g)
  2225.             =='function'then
  2226.                 local t={g(i)}
  2227.                 c=t[1]
  2228.                 if t[2
  2229.                 ]then
  2230.                     m.submodeFunc[i]=t[2]
  2231.                 end
  2232.             end
  2233.            
  2234.             local kl=c:findFirstChild('KeyLabel',true)
  2235.             if kl then
  2236.                 kl.Text=(plugin
  2237.                 and i<11)and i%10
  2238.                 or toolKeys[i] or''
  2239.             end
  2240.            
  2241.             local b=c:findFirstChild'Button'
  2242.             if b then
  2243.                 b.MouseButton1Click
  2244.                 :connect(function()
  2245.                     setSubmode(i)
  2246.                 end)
  2247.             end
  2248.             c.Name=i
  2249.             c.Parent=sm
  2250.             c.Visible=true
  2251.         end
  2252.        
  2253.         if m.current.incr then
  2254.             sm.Increment.Visible=true
  2255.             sm.Increment.TextBox.Text
  2256.             =toNum(m.current.incr[1])
  2257.         else
  2258.             sm.Increment.Visible=false
  2259.         end
  2260.     end
  2261.     setSubmode()
  2262. end
  2263.  
  2264. local button=plugin and plugin:CreateToolbar'VisualPlugin':
  2265. CreateButton(id,'Windowzhiuh.','rbxasset://textures/ui/TixIcon.png')
  2266.  
  2267. --Activates the plugin.
  2268. function activ8(a)
  2269.     local willBeActive=a~=nil and a or not active
  2270.     print('Active was set to '..(willBeActive and 'on.' or 'off.'))
  2271.     gui.Parent=willBeActive and core or script
  2272.    
  2273.     if willBeActive then
  2274.         reactiv8()
  2275.         for i,g in pairs(binders) do
  2276.             bindH(g)
  2277.         end
  2278.     else
  2279.         for i,g in pairs(binders) do
  2280.             game.ContextActionService
  2281.             :UnbindAction(i)
  2282.         end
  2283.        
  2284.         if plugin then
  2285.             print'Lost.'
  2286.             button:SetActive(false)
  2287.         end
  2288.     end
  2289.    
  2290.     active=willBeActive
  2291.     if active then
  2292.         if settings.setToSelection then
  2293.             for i,g in pairs(game.Selection:Get()) do
  2294.                 addSelection(g)
  2295.             end
  2296.         end
  2297.     else
  2298.         clearSelection()
  2299.     end
  2300. end
  2301.  
  2302. function reactiv8()
  2303.     if not active and plugin then
  2304.         plugin:Activate(true)
  2305.         button:SetActive(true)
  2306.     end
  2307. end
  2308.  
  2309. if plugin then
  2310.     button.Click:connect(activ8)
  2311. else
  2312.     tool.Equipped:connect(activ8)
  2313.     tool.Unequipped:connect(activ8)
  2314. end
  2315.  
  2316. sm.Re.Visible=plugin~=nil
  2317. sm.Re.Button.MouseButton1Click
  2318. :connect(function()
  2319.     reactiv8()
  2320. end)
  2321.  
  2322. if plugin then
  2323.     plugin.Deactivation:connect(function()
  2324.         local rt=plugin:GetSelectedRibbonTool().Name
  2325.         if active and'None'~=rt
  2326.         and'Select'~=rt then
  2327.             print'Deactivated.'
  2328.         end
  2329.     end)
  2330. end
  2331.  
  2332. local timeSC
  2333. local screentip=gui.ScreenTip
  2334. local delayTime=settings.screenTipDelay
  2335. gui.ScreenTip.Visible=false
  2336. function createST()
  2337.     if not screentip.Visible then
  2338.         screentip.Visible=true
  2339.         upd8ST('')
  2340.     end
  2341. end
  2342.  
  2343. --If nothing is passed into s, we get the stInfo by default.
  2344. function upd8ST(s)
  2345.     timeSC=tick()
  2346.     screentip.Position=UDim2
  2347.     .new(0,mouse.X,0,mouse.Y)
  2348.     if s then
  2349.         screentip.Text=s
  2350.     else
  2351.         local t,b={}
  2352.         screentip.Text=fromNum(snapped)
  2353.         for i,g in pairs(stInfo) do
  2354.             b=true
  2355.             local g=fromNum(g)
  2356.             for i2,g2 in pairs(t) do
  2357.                 if g==g2 then
  2358.                     b=false
  2359.                     break
  2360.                 end
  2361.             end
  2362.             if b then
  2363.                 t[#t+1]=g
  2364.             end
  2365.         end
  2366.         if #t>0 and t[1]~=snapped then
  2367.             screentip.Text=screentip.Text..' ('
  2368.             ..table.concat(t,', ')..')'
  2369.         end
  2370.     end
  2371.    
  2372.     screentip.Visible=true
  2373.     local size=screentip.TextBounds
  2374.     screentip.Size=UDim2.new(0,size.X+5,0,size.Y)
  2375.    
  2376.     delay(delayTime,function()
  2377.         if tick()-delayTime+.1>=timeSC then
  2378.             removeST()
  2379.         end
  2380.     end)
  2381.    
  2382.     --[[The oh-so-requested 'undo rotation'.
  2383.     if mode==3 then
  2384.         delay(3,function()
  2385.             if tick()-3+.1>=timeSC then
  2386.                 print'Luhh.'
  2387.                 createWaypoint()
  2388.             end
  2389.         end)
  2390.     end
  2391.     ]]
  2392. end
  2393.  
  2394. function removeST()
  2395.     screentip.Visible=false
  2396. end
  2397.  
  2398. mouse.Button1Down:connect(function()
  2399.     local p=getMousePart()
  2400.     if canDoStuff and p then
  2401.         toggleSelection(p)
  2402.         upd8GameSel()
  2403.     end
  2404. end)
  2405.  
  2406. --NOTE: Right click is for changing the main part.
  2407. mouse.Button2Down:connect(function()
  2408.     local p=getMousePart()
  2409.     if canDoStuff and p then
  2410.         local c=selContains(p)
  2411.         if c then
  2412.             setMode(nil,c[2])
  2413.         end
  2414.     end
  2415. end)
  2416.  
  2417. --Only actually changed the selection if a setting is turnt up.
  2418. game.Selection.SelectionChanged:connect(function()
  2419.     if not addWhenUpd8 or not active then
  2420.         return
  2421.     end
  2422.    
  2423.     print'Selection changed.'
  2424.     local prevSel=getSelection()
  2425.     local sel=game.Selection:Get()
  2426.     print('There were '..#prevSel..' selected.')
  2427.     print('There are now '..#sel..' selected.')
  2428.    
  2429.     doPrint=false
  2430.     for i,g in pairs(prevSel) do
  2431.         local doIt=true
  2432.         for i2,g2 in pairs(sel) do
  2433.             if g2==g then
  2434.                 doIt=false
  2435.                 break
  2436.             end
  2437.         end
  2438.         if doIt then
  2439.             removeSelection(g)
  2440.         end
  2441.     end
  2442.    
  2443.     local changed
  2444.     doPrint=settings.debugP
  2445.     for i,g in pairs(sel) do
  2446.         local doIt=true
  2447.         for i2,g2 in pairs(prevSel) do
  2448.             if g2==g then
  2449.                 doIt=false
  2450.                 break
  2451.             end
  2452.         end
  2453.         if doIt and not addSelection(g,true) then
  2454.             sel[i],changed=nil,true
  2455.         end
  2456.     end
  2457.     if changed then
  2458.         wait()
  2459.         game.Selection:Set(sel)
  2460.     end
  2461.    
  2462.     --[[
  2463.     clearSelection()
  2464.     if active and settings.setToSelection then
  2465.         for i,g in pairs(game.Selection:Get()) do
  2466.             if g:isA'BasePart'then
  2467.                 addSelection(g,true)
  2468.             elseif g:isA'Model'then
  2469.                 addSelection(g)
  2470.             end
  2471.         end
  2472.     end
  2473.     ]]
  2474. end)
  2475.  
  2476. --Just GUI stuff.
  2477. local c=0
  2478. local template=cmds.Template
  2479. for i,g in pairs(commands) do
  2480.     c=c+1
  2481.     local clone
  2482.     =template:clone()
  2483.     clone.Name=g.name
  2484.     clone.LayoutOrder=c
  2485.     clone.KeyName.Text=g.name
  2486.     clone.Parent=template.Parent
  2487.     clone.Keybind.Text=g.key:upper()
  2488.    
  2489.     --[[
  2490.     clone.MouseEnter:
  2491.     connect(function(x,y)
  2492.         clone.Keybind.
  2493.         BackgroundColor3
  2494.         =accColour()
  2495.     end)
  2496.    
  2497.     clone.MouseLeave:
  2498.     connect(function(x,y)
  2499.         clone.Keybind.
  2500.         BackgroundColor3
  2501.         =Color3.new(1,1,1)
  2502.     end)
  2503.     ]]
  2504.    
  2505.     --Der maneras of changing mode.
  2506.     clone.MouseButton1Click
  2507.     :connect(function(x,y)
  2508.         print'Inputted.'
  2509.         setMode(i)
  2510.     end)
  2511.     bind(g.name,function(n)
  2512.         setMode(i)
  2513.     end,g.key)
  2514. end
  2515. cmds.Size=UDim2
  2516. .new(1,0,0,math.
  2517. ceil(c/2)*15+1)
  2518. template.
  2519. Visible
  2520. =false
  2521.  
  2522. --Binds our submode keys.
  2523. --NOTE: If Ctrl+NUM is pressed whilst in tool mode, it switches to that mode number.
  2524. for i=1,10 do
  2525.     local sm=i
  2526.     bind('NKsubmode'
  2527.     ..i,function(n)
  2528.         setSubmode(sm)
  2529.     end,''..i%10
  2530.     ,not plugin)
  2531. end
  2532.  
  2533. if not plugin then
  2534.     for i,g in pairs(toolKeys) do
  2535.         local sm=i
  2536.         bind('TKsubmode'
  2537.         ..i,function(n)
  2538.             setSubmode(sm)
  2539.         end,Enum.KeyCode[g])
  2540.     end
  2541. end
  2542.  
  2543. local fr=sm.Version.Frame
  2544. fr.Image.Image=version.shape
  2545. fr.Version.Text=type(version.sub)=='number'
  2546.     and fromNum(version.sub)or version.sub
  2547. fr.Version.TextColor3=accColour()
  2548.  
  2549. --NOTE: The coloured bar below the version identifier is used for tracking the client's user ID.
  2550. local dColours={[0]=
  2551.     Color3.new(1,0,0),
  2552.     Color3.new(1,1,0),
  2553.     Color3.new(0,1,0),
  2554.     Color3.new(0,1,1),
  2555.     Color3.new(0,0,1),
  2556.     Color3.new(1,0,1),
  2557.    
  2558.     Color3.new(0,0,0),--6
  2559.     Color3.new(1,1,1),--7
  2560.     Color3.new(.3,.3,.3),--8
  2561.     Color3.new(.7,.7,.7),--9
  2562. }
  2563. local tId,i=id,0
  2564. local sq=fr.Line:WaitForChild'Square':clone()
  2565. sq.Name='IDer'
  2566. repeat
  2567.     local tSq=sq:clone()
  2568.     tSq.BackgroundColor3
  2569.     =dColours[tId%10]
  2570.     tId=math.floor(tId/10)
  2571.     tSq.LayoutOrder=-i
  2572.     tSq.Parent=fr.Line
  2573.     i=i+1
  2574. until tId<1
  2575. fr.Line.Square:destroy()
  2576.  
  2577. script.ServerEvt.
  2578. Disabled=plugin~=nil
  2579. if not plugin then
  2580.     mf.Position=mf.Position
  2581.     +UDim2.new(0,0,0,250)
  2582. end
  2583.  
  2584. --[[NOTE:
  2585.     The special key (SPC) is ctrl/cmd in tool mode or shift in plugin mode.
  2586.     SPC + B = deselect all objects.
  2587.     SPC + Z = undo.
  2588.     SPC + Y = redo.
  2589.     SPC + X = delete.
  2590.     SPC + C = duplicate.
  2591.     SPC + M = reset increments.
  2592. ]]
  2593. bind('deselect',function()
  2594.     clearSelection()   
  2595.     upd8GameSel()
  2596. end,'b',true)
  2597.  
  2598. local udr=sm.UDR
  2599. udr.Delete.Button.MouseButton1Click:connect(delete)
  2600. udr.Undo.Button.MouseButton1Click:connect(undo)
  2601. udr.Redo.Button.MouseButton1Click:connect(redo)
  2602. bind('duplicate',duplicate,'c',true)
  2603. bind('delete',delete,'x',true)
  2604. bind('undo',undo,'z',true)
  2605. bind('redo',redo,'y',true)
  2606.  
  2607. --------------------------------------------------------------------------------------------------------
  2608.  
  2609. setMode(1)
  2610. reRender()
  2611. print'Dunn.'
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement