Guest User

Untitled

a guest
Aug 5th, 2020
235
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 48.01 KB | None | 0 0
  1. --by imalex4
  2.  
  3.  
  4.  
  5.  
  6. --The settings are pretty good as they are.
  7.  
  8.  
  9. --SOME SETTINGS
  10. --================================================================================================================================
  11.    
  12. --NOTE: if you only want certain people to be able to use the body scanner screen, then go to line 1015
  13.    
  14. local clickdistance = 12 --the max distance (from the humanoid's head) at which a character can use the body scanner's screen
  15.  
  16. local increment = .05 --this is how often a ray is cast; if this were .5, a ray would be cast at the item every .5 studs; the lower the number, the more detail BUT ALSO possibly more lag
  17.                         --NOTE: for really small items (scan area of less than 9 square studs) that need to be scanned in more detail, this number will be divided in two
  18.  
  19. local scanlocation = CFrame.new(0, -200, 0) --scanned items must be brought into Workspace to be scanned; this is where they will be brought in
  20.  
  21. local ignoretransparentitems = true --transparent items will not be scanned
  22.  
  23.  
  24. --=========================================================================================================================================
  25.  
  26. local numofscanimages
  27. local numofpeopleinscanner
  28. local hinge = script.Parent.Parent.Parent.rotatingassembly.poweredpart.HingeConstraint
  29. local transparentname = 'transparent' .. math.random(1, 9999)
  30. local raycaststartdistance = .1 --this is how far back from the object's bounding box we will start the raycast; example: if we want to raycast to the top of the object and the top of object's bounding box is at Y = 10, then we will start raycast at Y = 10 + raycaststartdistance
  31. local currentitem --this is the part/model that is currently being scanned
  32. local dotsize = 2 --the scan image will be made of many dots; this is the size of each dot
  33. local makedotinfo = {}
  34. local generalinfoarray = {}   --layout:  generalinfoarray[dotholder] has { ['message'], ['itemowner'], ['currentitemholder'], ['scannedthing']}
  35. local peopleinscanner = {} --machine will only scan if there is only one person in this table; each item will be a character model
  36. local debounces = {} --true means you cannot do the function
  37. local gui = script.Parent.SurfaceGui
  38. local interface = gui.interface
  39. local scanimages
  40. local scanimagesindex = 0 --set to 1 when images are loaded
  41. local timeofscanstart = 0
  42. debounces['previousimage'] = true
  43. debounces['nextimage'] = true
  44.  
  45.  
  46. script.Parent.dot.Size = UDim2.new(0, dotsize, 0, dotsize)
  47.  
  48. if not game.ServerStorage:FindFirstChild('meshpartsforscanner') or game.ServerStorage.meshpartsforscanner.ClassName ~= 'Folder' then
  49.     print("NOTE: you need to follow the instructions inside of bodyscanner.readme")
  50. end
  51.  
  52.  
  53.  
  54.  
  55. --==========this is not used, as I found out about GetBoundingBox ================NOTE: not tested
  56.  
  57. function getcenterofmodel(model) --it is expected that 'model' is a model and it has a primary part and all meshes have been removed with 'changemeshesformodel'; center is returned as a vector3 in world coordinates
  58.     --NOTE: not tested and note used
  59.     local lowestx, greatestx, lowesty, greatesty, lowestz, greatestz
  60.     for _, v in pairs(model:GetDescendants()) do
  61.         if v and v:IsA('BasePart') then
  62.             local position = v.Position
  63.             local size = v.Size
  64.             local edges = {} --edges will be 1 through 8 and they go in this order: upper left, upper right, lower left, lower right of the brick's left face (from a perspective of looking at the left face of a standard brick) and then upper left, upper right, lower left, lower right from the perspective of looking at the right face
  65.             local middleofface = v.CFrame:ToWorldSpace(CFrame.new(v.Size.X/-2, 0, 0))  --this represents the cframe which is the center of the left or right face of the brick
  66.             edges[1] = (middleofface * CFrame.new(0, (v.Size.Y / 2), 0) * CFrame.new(0, 0, v.Size.Z / -2)).Position
  67.             edges[2] = (middleofface * CFrame.new(0, (v.Size.Y / 2), 0) * CFrame.new(0, 0, v.Size.Z / 2)).Position
  68.             edges[3] = (middleofface * CFrame.new(0, (v.Size.Y / -2), 0) * CFrame.new(0, 0, v.Size.Z / -2)).Position
  69.             edges[4] = (middleofface * CFrame.new(0, (v.Size.Y / -2), 0) * CFrame.new(0, 0, v.Size.Z / 2)).Position
  70.            
  71.             middleofface = v.CFrame:ToWorldSpace(CFrame.new(v.Size.X/2, 0, 0))
  72.             edges[5] = (middleofface * CFrame.new(0, (v.Size.Y / 2), 0) * CFrame.new(0, 0, v.Size.Z / 2)).Position
  73.             edges[6] = (middleofface * CFrame.new(0, (v.Size.Y / 2), 0) * CFrame.new(0, 0, v.Size.Z / -2)).Position
  74.             edges[7] = (middleofface * CFrame.new(0, (v.Size.Y / -2), 0) * CFrame.new(0, 0, v.Size.Z / 2)).Position
  75.             edges[8] = (middleofface * CFrame.new(0, (v.Size.Y / -2), 0) * CFrame.new(0, 0, v.Size.Z / -2)).Position
  76.             for i = 1, 8 do
  77.                 if not lowestx or edges[i].X < lowestx then
  78.                     lowestx = edges[i].X
  79.                 end
  80.                 if not greatestx or edges[i].X > greatestx then
  81.                     greatestx = edges[i].X
  82.                 end
  83.                
  84.                 if not lowesty or edges[i].Y < lowesty then
  85.                     lowesty = edges[i].Y
  86.                 end
  87.                 if not greatesty or edges[i].Y > greatesty then
  88.                     greatesty = edges[i].Y
  89.                 end
  90.                
  91.                 if not lowestz or edges[i].Z < lowestz then
  92.                     lowestz = edges[i].Z
  93.                 end
  94.                 if not greatestz or edges[i].Z > greatestz then
  95.                     greatestz = edges[i].Z
  96.                 end
  97.             end
  98.            
  99.         end
  100.     end--for _, v in pairs
  101.    
  102.     local center = Vector3.new( (lowestx + greatestx) / 2, (lowesty + greatesty) / 2, (lowestz + greatestz) / 2  )
  103.        
  104. end
  105.  
  106. function giveprimarypart(currentitem, model) --in case we go into recursion, currentitem keeps track of where we are (whose children are we looking through)
  107.     if model:IsA("Model") and model.PrimaryPart == nil then
  108.         for _, v in pairs(currentitem:GetChildren()) do
  109.             if v and v:IsA("BasePart") then
  110.                 model.PrimaryPart = v
  111.                 break
  112.             end
  113.         end --for _, v
  114.     end --if model:IsA
  115.     if not model.PrimaryPart then
  116.         for _, v in pairs(currentitem:GetChildren()) do
  117.             giveprimarypart(v, model)
  118.         end
  119.     end
  120. end
  121.    
  122.    
  123.    
  124.    
  125.  
  126.  
  127. function changemeshesformodel(thing, newmodel) --thing is the object/model whose children we are checking;  newmodel is the new model that we are cloning everything into;  
  128.    
  129.    
  130.    
  131.     if thing:IsA('BasePart') and (thing.Name ~= transparentname or ignoretransparentitems == false) then
  132.         local themesh
  133.        
  134.         --I am doing this for loop because the part could have multiple meshes; if a part has multiple meshes, it uses the most recent mesh, and the most recent mesh is the last one to be iterated through in "in pairs"
  135.         for _, v in pairs(thing:GetChildren()) do
  136.             if v and v:IsA("DataModelMesh") then
  137.                 themesh = v
  138.             end --if v and v:IsA('DataModelMesh')
  139.         end --for _, v in pairs
  140.        
  141.        
  142.         if not themesh then
  143.             local copy = thing:Clone()
  144.             copy:ClearAllChildren()
  145.             copy.Anchored = true
  146.             copy.CanCollide = false
  147.             copy.Transparency = 1  
  148.             copy.Name = thing.Name 
  149.             copy.Parent = newmodel
  150.         elseif themesh.ClassName == "BlockMesh" then
  151.             local newpart = Instance.new("Part")
  152.             newpart.Size = thing.Size * themesh.Scale
  153.             newpart.CFrame = thing.CFrame * CFrame.new(themesh.Offset)
  154.             newpart.Name = thing.Name
  155.             newpart.Anchored = true
  156.             newpart.CanCollide = false
  157.             newpart.Transparency = 1
  158.             newpart.Parent = newmodel
  159.         elseif themesh.ClassName == "CylinderMesh" then
  160.             local newpart = Instance.new("Part")
  161.             newpart.Shape = Enum.PartType.Cylinder
  162.            
  163.             local sizex = thing.Size.Y * themesh.Scale.Y----these don't match; that's on purpose
  164.             local sizey = thing.Size.X * themesh.Scale.X----these don't match; that's on purpose, as the sizing for a cylinder part and the sizing for a normal part with a cylinder mesh is different
  165.             local sizez = thing.Size.Z * themesh.Scale.Z
  166.            
  167.             newpart.Size = Vector3.new(sizex, sizey, sizez)
  168.             newpart.CFrame = thing.CFrame * CFrame.new(themesh.Offset) * CFrame.Angles(0, 0, math.pi / 2)
  169.             newpart.Anchored = true
  170.             newpart.CanCollide = false
  171.             newpart.Transparency = 1
  172.             newpart.Name = thing.Name
  173.             newpart.Parent = newmodel
  174.         elseif themesh.ClassName ==  "SpecialMesh" then
  175.             if themesh.MeshType == Enum.MeshType.Brick or themesh.MeshType == Enum.MeshType.Torso then
  176.                 local newpart = Instance.new("Part")
  177.                 newpart.Size = thing.Size * themesh.Scale
  178.                 newpart.CFrame = thing.CFrame * CFrame.new(themesh.Offset)
  179.                 newpart.Name = thing.Name
  180.                 newpart.Anchored = true
  181.                 newpart.CanCollide = false
  182.                 newpart.Transparency = 1
  183.                 newpart.Parent = newmodel
  184.             elseif themesh.MeshType == Enum.MeshType.Cylinder then
  185.                 local newpart = Instance.new("Part")
  186.                 newpart.Shape = Enum.PartType.Cylinder
  187.                 newpart.Size = thing.Size * themesh.Scale
  188.                 newpart.CFrame = thing.CFrame * CFrame.new(themesh.Offset)
  189.                 newpart.Anchored = true
  190.                 newpart.CanCollide = false
  191.                 newpart.Transparency = 1
  192.                 newpart.Name = thing.Name
  193.                 newpart.Parent = newmodel
  194.    
  195.             elseif themesh.MeshType == Enum.MeshType.FileMesh then
  196.                 local idnumber = string.match(themesh.MeshId, '%d+$') --gets all the numbers at the end of the meshid (the asset id)
  197.                 if idnumber == nil or (string.match(themesh.MeshId, 'rbxasset') and not string.match(themesh.MeshId, 'rbxassetid')) then
  198.                     idnumber =  themesh.MeshId --if code gets here, then mesh id is not an actual asset number (it's somehting like rbxasset://fonts/slingshot.mesh)
  199.                 end
  200.                 local newpart = game.ServerStorage.meshpartsforscanner:FindFirstChild(idnumber)
  201.                 if newpart then
  202.                     newpart = newpart:Clone()
  203.                     newpart.Size = newpart.Size * themesh.Scale
  204.                     newpart.CFrame = thing.CFrame * CFrame.new(themesh.Offset)
  205.                     newpart.Anchored = true
  206.                     newpart.CanCollide = false
  207.                     newpart.Transparency = 1
  208.                     newpart.Name = thing.Name
  209.                     newpart.Parent = newmodel
  210.                 else
  211.                     newpart = Instance.new('Part')
  212.                     newpart.Size = Vector3.new(.5, .5, .5)
  213.                     newpart.CFrame = scanlocation
  214.                     newpart.Anchored = true
  215.                     newpart.CanCollide = false
  216.                     newpart.Transparency = 1
  217.                     newpart.Name = thing.Name
  218.                     newpart.Parent = newmodel
  219.                    
  220.                     if not makedotinfo[newmodel] then
  221.                         preparetable(newmodel)
  222.                     end
  223.                     makedotinfo[newmodel].message = 'Some or all of this model was not scanned properly'
  224.                 end
  225.                
  226.                
  227.                
  228.            
  229.             elseif themesh.MeshType == Enum.MeshType.Head then
  230.                 local newpart = script.Parent.Parent.Parent.storage.meshparthead:Clone()
  231.                
  232.                 local sizex
  233.                 local sizey = thing.Size.Y * themesh.Scale.Y----these don't match; that's on purpose, as the sizing for a cylinder part and the sizing for a normal part with a cylinder mesh is different
  234.                 local sizez
  235.                 if thing.Size.X < thing.Size.Z or thing.Size.X == thing.Size.Z then
  236.                     sizex = thing.Size.X * themesh.Scale.X
  237.                     sizez = thing.Size.X * themesh.Scale.X
  238.                 elseif thing.Size.Z < thing.Size.X then
  239.                     sizex = thing.Size.Z * themesh.Scale.Z
  240.                     sizez = thing.Size.Z * themesh.Scale.Z
  241.                 else
  242.                     local scale
  243.                     if themesh.Scale.X < themesh.Scale.Z then
  244.                         scale = themesh.Scale.X
  245.                     elseif themesh.Scale.Z < themesh.Scale.X then
  246.                         scale = themesh.Scale.Z
  247.                     else
  248.                         scale = themesh.Scale.X
  249.                     end
  250.                     sizex = thing.Size.X * scale
  251.                     sizez = thing.Size.X * scale
  252.                 end
  253.                 newpart.Size = Vector3.new(sizex, sizey, sizez)
  254.                 newpart.CFrame = thing.CFrame * CFrame.new(themesh.Offset)
  255.                 newpart.Name = thing.Name
  256.                 newpart.Anchored = true
  257.                 newpart.CanCollide = false
  258.                 newpart.Transparency = 1
  259.                 newpart.Parent = newmodel
  260.             elseif themesh.MeshType == Enum.MeshType.Sphere then
  261.                 local newpart = script.Parent.Parent.Parent.storage.meshpartball:Clone()
  262.                 newpart.Size = thing.Size * themesh.Scale
  263.                 newpart.CFrame = thing.CFrame * CFrame.new(themesh.Offset)
  264.                 newpart.Name = thing.Name
  265.                 newpart.Anchored = true
  266.                 newpart.CanCollide = false
  267.                 newpart.Transparency = 1
  268.                 newpart.Parent = newmodel
  269.             --elseif themesh.MeshType == Enum.MeshType.Torso then  --this is paired with meshtype==brick
  270.                
  271.             elseif themesh.MeshType == Enum.MeshType.Wedge then
  272.                 local newpart = Instance.new('WedgePart')
  273.                 newpart.Size = thing.Size * themesh.Scale
  274.                 newpart.CFrame = thing.CFrame * CFrame.new(themesh.Offset)
  275.                 newpart.Name = thing.Name
  276.                 newpart.Anchored = true
  277.                 newpart.CanCollide = false
  278.                 newpart.Transparency = 1
  279.                 newpart.Parent = newmodel
  280.             end --if themesh.MeshType
  281.         end --if not themesh
  282.            
  283.     end --if thing:IsA('BasePart')
  284.            
  285.     for _, v in pairs(thing:GetChildren()) do
  286.         changemeshesformodel(v, newmodel)
  287.     end
  288.            
  289.            
  290. end
  291.  
  292. --this is not meant for scanning individual objects in a model
  293. function changemeshesforpart(thing) --thing is the object whose children we are checking; it is expected that this 'thing' has no children of type 'BasePart' (blocks)
  294.    
  295.     --note: the new brick will be returned with an unmodified position, and if no meshes were found in the brick, a clone of the original brick will be returned
  296.    
  297.     if thing:IsA('BasePart') then --if it's not a basepart, then it doesn't matter if there is a mesh child. We will just continue looking through its children, as one of the children could be a basepart
  298.         local themesh
  299.        
  300.         --I am doing this for loop because the part could have multiple meshes; if a part has multiple meshes, it uses the most recent mesh, and the most recent mesh is the last one to be iterated through in "in pairs"
  301.         for _, v in pairs(thing:GetChildren()) do
  302.             if v and v:IsA("DataModelMesh") then
  303.                 themesh = v
  304.             end --if v and v:IsA('DataModelMesh')
  305.         end --for _, v in pairs
  306.        
  307.        
  308.         if not themesh then
  309.             local newpart = thing:Clone()
  310.             newpart.Name = thing.Name
  311.             newpart:ClearAllChildren()
  312.             newpart.Anchored = true
  313.             newpart.CanCollide = false
  314.             newpart.Transparency = 1
  315.             newpart.Parent = game.Workspace
  316.             return newpart
  317.         elseif themesh.ClassName == "BlockMesh" then
  318.             local newpart = Instance.new("Part")
  319.             newpart.Size = thing.Size * themesh.Scale
  320.             newpart.CFrame = scanlocation
  321.             newpart.Name = thing.Name
  322.             newpart.Anchored = true
  323.             newpart.CanCollide = false
  324.             newpart.Transparency = 1
  325.             newpart.Parent = game.Workspace
  326.             return newpart
  327.         elseif themesh.ClassName == "CylinderMesh" then
  328.             local newpart = Instance.new("Part")
  329.             newpart.Shape = Enum.PartType.Cylinder
  330.            
  331.             local sizex = thing.Size.Y * themesh.Scale.Y----these don't match; that's on purpose
  332.             local sizey = thing.Size.X * themesh.Scale.X----these don't match; that's on purpose, as the sizing for a cylinder part and the sizing for a normal part with a cylinder mesh is different
  333.             local sizez = thing.Size.Z * themesh.Scale.Z
  334.            
  335.             newpart.Size = Vector3.new(sizex, sizey, sizez)
  336.             newpart.CFrame = scanlocation
  337.             newpart.Anchored = true
  338.             newpart.CanCollide = false
  339.             newpart.Transparency = 1
  340.             newpart.Name = thing.Name
  341.             newpart.Parent = game.Workspace
  342.             return newpart
  343.         elseif themesh.ClassName ==  "SpecialMesh" then
  344.             if themesh.MeshType == Enum.MeshType.Brick or themesh.MeshType == Enum.MeshType.Torso then
  345.                 local newpart = Instance.new("Part")
  346.                 newpart.Size = thing.Size * themesh.Scale
  347.                 newpart.CFrame = scanlocation
  348.                 newpart.Name = thing.Name
  349.                 newpart.Anchored = true
  350.                 newpart.CanCollide = false
  351.                 newpart.Transparency = 1
  352.                 newpart.Parent = game.Workspace
  353.                 return newpart
  354.             elseif themesh.MeshType == Enum.MeshType.Cylinder then
  355.                 local newpart = Instance.new("Part")
  356.                 newpart.Shape = Enum.PartType.Cylinder
  357.                 newpart.Size = thing.Size * themesh.Scale
  358.                 newpart.CFrame = scanlocation
  359.                 newpart.Anchored = true
  360.                 newpart.CanCollide = false
  361.                 newpart.Transparency = 1
  362.                 newpart.Name = thing.Name
  363.                 newpart.Parent = game.Workspace
  364.                 return newpart
  365.    
  366.             elseif themesh.MeshType == Enum.MeshType.FileMesh then
  367.                 local idnumber = string.match(themesh.MeshId, '%d+$') --gets all the numbers at the end of the meshid (the asset id)
  368.                 if idnumber == nil or (string.match(themesh.MeshId, 'rbxasset') and not string.match(themesh.MeshId, 'rbxassetid')) then
  369.                     idnumber =  themesh.MeshId --if code gets here, then mesh id is not an actual asset number (it's somehting like rbxasset://fonts/slingshot.mesh)
  370.                 end
  371.                 local newpart = game.ServerStorage.meshpartsforscanner:FindFirstChild(idnumber)
  372.                 if newpart then
  373.                     newpart = newpart:Clone()
  374.                     newpart.Size = newpart.Size * themesh.Scale
  375.                     newpart.CFrame = scanlocation
  376.                     newpart.Anchored = true
  377.                     newpart.CanCollide = false
  378.                     newpart.Transparency = 1
  379.                     newpart.Name = thing.Name
  380.                     newpart.Parent = game.Workspace
  381.                     return newpart
  382.                 else
  383.                     newpart = Instance.new('Part')
  384.                     newpart.Size = Vector3.new(.5, .5, .5)
  385.                     newpart.CFrame = scanlocation
  386.                     newpart.Anchored = true
  387.                     newpart.CanCollide = false
  388.                     newpart.Transparency = 1
  389.                     newpart.Name = thing.Name
  390.                     newpart.Parent = game.Workspace
  391.                     if not makedotinfo[newpart] then
  392.                         preparetable(newpart)
  393.                     end
  394.                     makedotinfo[newpart].message = 'This mesh could not be scanned'
  395.                    
  396.                     return newpart
  397.                 end
  398.             elseif themesh.MeshType == Enum.MeshType.Head then
  399.                 local newpart = script.Parent.Parent.Parent.storage.meshparthead:Clone()
  400.                
  401.                 local sizex
  402.                 local sizey = thing.Size.Y * themesh.Scale.Y----these don't match; that's on purpose, as the sizing for a cylinder part and the sizing for a normal part with a cylinder mesh is different
  403.                 local sizez
  404.                 if thing.Size.X < thing.Size.Z or thing.Size.X == thing.Size.Z then
  405.                     sizex = thing.Size.X * themesh.Scale.X
  406.                     sizez = thing.Size.X * themesh.Scale.X
  407.                 elseif thing.Size.Z < thing.Size.X then
  408.                     sizex = thing.Size.Z * themesh.Scale.Z
  409.                     sizez = thing.Size.Z * themesh.Scale.Z
  410.                 else
  411.                     local scale
  412.                     if themesh.Scale.X < themesh.Scale.Z then
  413.                         scale = themesh.Scale.X
  414.                     elseif themesh.Scale.Z < themesh.Scale.X then
  415.                         scale = themesh.Scale.Z
  416.                     else
  417.                         scale = themesh.Scale.X
  418.                     end
  419.                     sizex = thing.Size.X * scale
  420.                     sizez = thing.Size.X * scale
  421.                 end
  422.                 newpart.Size = Vector3.new(sizex, sizey, sizez)
  423.                 newpart.CFrame = scanlocation
  424.                 newpart.Name = thing.Name
  425.                 newpart.Anchored = true
  426.                 newpart.CanCollide = false
  427.                 newpart.Transparency = 1
  428.                 newpart.Parent = game.Workspace
  429.                 return newpart
  430.             elseif themesh.MeshType == Enum.MeshType.Sphere then
  431.                 local newpart = script.Parent.Parent.Parent.storage.meshpartball:Clone()
  432.                 newpart.Size = thing.Size * themesh.Scale
  433.                 newpart.CFrame = scanlocation
  434.                 newpart.Name = thing.Name
  435.                 newpart.Anchored = true
  436.                 newpart.CanCollide = false
  437.                 newpart.Transparency = 1
  438.                 newpart.Parent = game.Workspace
  439.                 return newpart
  440.             --elseif themesh.MeshType == Enum.MeshType.Torso then  --this is paired with meshtype==brick
  441.                
  442.             elseif themesh.MeshType == Enum.MeshType.Wedge then
  443.                 local newpart = Instance.new('WedgePart')
  444.                 newpart.Size = thing.Size * themesh.Scale
  445.                 newpart.CFrame = scanlocation
  446.                 newpart.Name = thing.Name
  447.                 newpart.Anchored = true
  448.                 newpart.CanCollide = false
  449.                 newpart.Transparency = 1
  450.                 newpart.Parent = game.Workspace
  451.                 return newpart
  452.             end --if themesh.MeshType
  453.         end --if not themesh
  454.            
  455.     end --if thing:IsA('BasePart')
  456.            
  457. end
  458.        
  459. --thing will be a part or model
  460. function preparetable(thing) --this is used to prepare the table "makedotinfo" used in the function makedot; if we didn't do it here and did it function makedot, it would check the table several times
  461.     makedotinfo[thing] = {}
  462.     local holder = script.Parent.holder:Clone()
  463.     holder.Parent = script.Parent.SurfaceGui.scanimages
  464.     makedotinfo[thing].holder = holder
  465. end
  466.  
  467. function makedot(x, y, distance, depth, thing)
  468.     local x = (x * dotsize) - dotsize
  469.     local y = (y * dotsize) - dotsize
  470.     local dot = script.Parent.dot:Clone()
  471.     local brightnesslimit = 200 --this + 15 is the brightest the gui will be allowed to go
  472.     local brightnessmodifier = (depth - (depth * .1)) / brightnesslimit
  473.     local thecolor = distance / brightnessmodifier
  474.     thecolor = thecolor + 15
  475.    
  476.     if thecolor < brightnesslimit then
  477.         dot.BackgroundColor3 = Color3.new(thecolor/255, thecolor/255, thecolor/255)
  478.     else
  479.         dot.BackgroundColor3 = Color3.new(brightnesslimit/255, brightnesslimit/255, brightnesslimit/255)
  480.     end
  481.    
  482.     dot.Position = UDim2.new(0, x, 0, y)
  483.     dot.Parent = makedotinfo[thing].holder
  484. end
  485.  
  486. function findlargestfaceformodel(model, cframe) --cframe is the CFrame of the model
  487.     local largestface
  488.     local x, y, z
  489.     local c1, c2, c3, c4 --coordinate 1, 2, 3, 4
  490.     local v1, v2, v3 --vertice length 1, 2, 3
  491.     local toparea, leftarea, backarea --area of top face, left face, and back face
  492.     local size = model:GetExtentsSize()
  493.     local position = cframe.Position
  494.     x = position.X - (size.X / 2)
  495.     y = (size.Y / 2) + position.Y
  496.     z = position.Z - (size.Z / 2)
  497.     c1 = Vector3.new(x, y, z) --top left corner  (face of brick that is seen from a top down perspective and while brick has no rotation, also the corner made by the front-top-leftside faces)
  498.     c2 = c1 + Vector3.new(0, 0, size.Z) --going over +Z part size from c1
  499.     c3 = c2 - Vector3.new(0, size.Y, 0) --going over -Y part size from c2
  500.     c4 = c3 + Vector3.new(size.X, 0, 0) --going over +X part size from c3
  501.     v1 = (c1 - c2).magnitude
  502.     v2 = (c2 - c3).magnitude
  503.     v3 = (c3 - c4).magnitude
  504.     leftarea = v1 * v2 --note that left and right area are same, top area and bottom area are same, etc
  505.     backarea = v2 * v3
  506.     toparea = v3 * v1
  507.     if leftarea > backarea and leftarea > toparea then
  508.         largestface = "left"
  509.     elseif backarea > leftarea and backarea > toparea then
  510.         largestface = "back"
  511.     elseif toparea > leftarea and toparea > backarea then
  512.         largestface = "top"
  513.     elseif leftarea > backarea or leftarea > toparea then --if code gets here, it means two or more sizes could be the same
  514.         largestface = "left"
  515.     elseif backarea > leftarea or backarea > toparea then
  516.         largestface = "back"
  517.     elseif toparea > leftarea or toparea > backarea then
  518.         largestface = "top"
  519.     else --if code gets here, that means object is perfectly cube shaped
  520.         largestface = "left"
  521.     end
  522.     return largestface
  523. end
  524.  
  525. function findlargestface(part) --not used for models, parts only ; use findlargestfaceformodel for models
  526.     local largestface
  527.     local x, y, z
  528.     local c1, c2, c3, c4 --coordinate 1, 2, 3, 4
  529.     local v1, v2, v3 --vertice length 1, 2, 3
  530.     local toparea, leftarea, backarea --area of top face, left face, and back face
  531.     x = part.Position.X - (part.Size.X / 2)
  532.     y = (part.Size.Y / 2) + part.Position.Y
  533.     z = part.Position.Z - (part.Size.Z / 2)
  534.     c1 = Vector3.new(x, y, z) --top left corner  (face of brick that is seen from a top down perspective and while brick has no rotation, also the corner made by the front-top-leftside faces)
  535.     c2 = c1 + Vector3.new(0, 0, part.Size.Z) --going over +Z part size from c1
  536.     c3 = c2 - Vector3.new(0, part.Size.Y, 0) --going over -Y part size from c2
  537.     c4 = c3 + Vector3.new(part.Size.X, 0, 0) --going over +X part size from c3
  538.     v1 = (c1 - c2).magnitude
  539.     v2 = (c2 - c3).magnitude
  540.     v3 = (c3 - c4).magnitude
  541.     leftarea = v1 * v2 --note that left and right area are same, top area and bottom area are same, etc
  542.     backarea = v2 * v3
  543.     toparea = v3 * v1
  544.     if leftarea > backarea and leftarea > toparea then
  545.         largestface = "left"
  546.     elseif backarea > leftarea and backarea > toparea then
  547.         largestface = "back"
  548.     elseif toparea > leftarea and toparea > backarea then
  549.         largestface = "top"
  550.     elseif leftarea > backarea or leftarea > toparea then --if code gets here, it means two or more sizes could be the same
  551.         largestface = "left"
  552.     elseif backarea > leftarea or backarea > toparea then
  553.         largestface = "back"
  554.     elseif toparea > leftarea or toparea > backarea then
  555.         largestface = "top"
  556.     else --if code gets here, that means object is perfectly cube shaped
  557.         largestface = "left"
  558.     end
  559.     return largestface
  560. end
  561.  
  562.                                    
  563. function castray(x, y, z, guix, guiy, depth, part) --REMEMBER: the 3D Z is equal to the gui Y                          
  564.     local startpoint = Vector3.new(x, y, z)
  565.     local direction = Vector3.new(0, -1, 0) --this direction is straight down
  566.     local ray = Ray.new(startpoint, direction * depth)
  567.     local part, pos = game.Workspace:FindPartOnRayWithWhitelist(ray, {part})
  568.     local distance
  569.     --game.Workspace.indicate1.Position = startpoint
  570.     --game.Workspace.indicate2.CFrame = CFrame.new(startpoint +  ( (depth + (raycaststartdistance * 2) ) * direction ) )
  571.     if part then
  572.         distance = ( (pos-startpoint).magnitude ) - raycaststartdistance
  573.         makedot(guix, guiy, distance, depth, part)
  574.     end
  575. end
  576.  
  577. function castrayformodel(startpoint, endpoint, guix, guiy, model, modelcframe, depth) --REMEMBER: the 3D Z is equal to the gui Y
  578.     local modelcframe, _ = model:GetBoundingBox()                              
  579.     local startpoint = modelcframe:toWorldSpace(CFrame.new(startpoint)).Position
  580.     local endpoint = modelcframe:toWorldSpace(CFrame.new(endpoint)).Position
  581.    
  582.    
  583.    
  584.     local direction = (endpoint - startpoint).unit --this direction is straight down
  585.     local ray = Ray.new(startpoint, direction * depth)
  586.     local part, pos = game.Workspace:FindPartOnRayWithWhitelist(ray, {model})
  587.     local distance
  588.     if part then
  589.         distance = ( (pos-startpoint).magnitude ) - raycaststartdistance
  590.         makedot(guix, guiy, distance, depth, model)
  591.     end
  592.    
  593. end
  594.  
  595.                                             --\/ originalpart could be a tool, model, etc, not just a part
  596. function doscanforpart(part, itemowner, originalpart) --when this is used, it is expected that 'part' is a basepart and 'part' has no basepart children and 'part' has no meshes in it (use changemeshesforpart function to take care of this)
  597.                            
  598.  
  599.     part.Anchored = true
  600.     part.CanCollide = false
  601.     part.Transparency = 1
  602.     part.CFrame = scanlocation
  603.     part.Parent = game.Workspace
  604.     local largestface = findlargestface(part)
  605.     local leftpos, toppos, frontpos, xsize, zsize
  606.     local depth
  607.    
  608.    
  609.     --NOTE: leftpos, toppos, and frontpos don't represent the actual front, left, and top faces of the brick; the top face of the brick is whatever face of the brick is pointing up after we rotate the brick
  610.                     --and so on with the other two faces
  611.                     --AND these variables represent the one dimensional (only x, y, or z) position of that face; example, top face position may be something like 10 (as in Y = 10)
  612.     if largestface == "top" then
  613.         leftpos = part.Position.X - (part.Size.X / 2)
  614.         toppos = (part.Size.Y / 2) + part.Position.Y
  615.         frontpos = part.Position.Z - (part.Size.Z / 2)
  616.         xsize = part.Size.X
  617.         zsize = part.Size.Z
  618.         depth = (part.Size.Y) + (raycaststartdistance * 2)
  619.     elseif largestface == "left" then
  620.         part.CFrame = scanlocation * CFrame.Angles(0, 0, -math.pi / 2)
  621.         leftpos = part.Position.X - (part.Size.Y / 2)
  622.         toppos = (part.Size.X / 2) + part.Position.Y
  623.         frontpos = part.Position.Z - (part.Size.Z / 2)
  624.         xsize = part.Size.Y
  625.         zsize = part.Size.Z
  626.         depth = (part.Size.X) + (raycaststartdistance * 2)
  627.     elseif largestface == "back" then
  628.         --NOTE: here, we are actually going to look at the front of the brick (which is opposite the back) but that's fine, front or back will work
  629.         part.CFrame = scanlocation * CFrame.Angles(math.pi / 2, 0, 0)
  630.         leftpos = part.Position.X - (part.Size.X / 2)
  631.         toppos = (part.Size.Z / 2) + part.Position.Y
  632.         frontpos = part.Position.Z - (part.Size.Y / 2)
  633.         xsize = part.Size.X
  634.         zsize = part.Size.Y
  635.         depth = (part.Size.Z) + (raycaststartdistance * 2)
  636.     end
  637.     local increment = increment
  638.     if xsize * zsize <= 10 then
  639.         increment = increment / 2
  640.     end
  641.     if not makedotinfo[part] then
  642.         preparetable(part)
  643.     end
  644.    
  645.     local startposx = leftpos
  646.     local startposy = toppos + raycaststartdistance
  647.     local startposz = frontpos
  648.     local guix = 0
  649.     local guiy = 0
  650.     local xpos = 0
  651.     local zpos = 0
  652.    
  653.     for i = 0, zsize / increment do
  654.         guiy = guiy + 1
  655.         guix = 0
  656.    
  657.         for j = 0, xsize / increment do
  658.             guix = guix + 1
  659.             local addtox = j * increment
  660.             local addtoz = i * increment
  661.             castray(startposx + addtox, startposy, startposz + addtoz, guix, guiy, depth, part)
  662.         end
  663.     end
  664.    
  665.     local dotholder = makedotinfo[part].holder
  666.     generalinfoarray[dotholder] = {}
  667.    
  668.     local message = makedotinfo[part].message
  669.     if message then
  670.         generalinfoarray[dotholder].message = message
  671.         if part.Name == transparentname then
  672.             generalinfoarray[dotholder].message = generalinfoarray[dotholder].message .. '\nNote that this part is transparent'
  673.         end
  674.     elseif part.Name == transparentname then
  675.         generalinfoarray[dotholder].message = 'Note that this part is transparent'
  676.     end
  677.    
  678.     generalinfoarray[dotholder].itemowner = itemowner
  679.     generalinfoarray[dotholder].scannedthing = originalpart
  680.     makedotinfo[part] = nil
  681.    
  682.    
  683.    
  684. end
  685.  
  686.  
  687.  
  688. function anchorandhidechildren(thing)
  689.     if thing and thing:IsA("BasePart") then
  690.         thing.Anchored = true
  691.         thing.Transparency = 1
  692.         thing.CanCollide = false
  693.     end
  694.     for _, v in pairs(thing:GetChildren()) do
  695.         anchorandhidechildren(v)
  696.     end
  697. end
  698.  
  699.  
  700.  
  701. function doscanformodel(model, itemowner, originalmodel) --when this is used, it is expected that 'model' is a model, there is at least one basepart in the model, and none of the baseparts are affected by meshes (use changemeshesformodel for this)
  702.                        
  703.    
  704.    
  705.    
  706.     anchorandhidechildren(model)
  707.     giveprimarypart(model, model)
  708.     model:SetPrimaryPartCFrame(scanlocation)
  709.     model.PrimaryPart = nil
  710.     model.Parent =  game.Workspace
  711.    
  712.     if not makedotinfo[model] then
  713.         preparetable(model)
  714.     end
  715.                                            
  716.     local modelcframe, size = model:GetBoundingBox()
  717.                                            
  718.    
  719.     --model:SetPrimaryPartCFrame( scanlocation * (modelcframe - modelcframe.p) )
  720.     --model.Parent = game.Workspace
  721.    
  722.     local largestface = findlargestfaceformodel(model, modelcframe)
  723.     local leftpos, toppos, frontpos, xsize, zsize
  724.     local position = modelcframe.p
  725.     local startposx, startposy, startposz --where the first raycasts will begin
  726.     local firstdirection, seconddirection --used for scanning the model up to down left to right
  727.     local extradistance --this is used so the raycast doesn't start right against the brick; see the variable "raycaststartdistance" at top of page; this will be a Vector3
  728.    
  729.    
  730.    
  731.     --NOTE: leftpos, toppos, and frontpos don't represent the actual front, left, and top faces of the brick; the top face of the brick is whatever face of the brick is pointing up after we rotate the brick
  732.                     --and so on with the other two faces
  733.                     --AND these variables represent the one dimensional (only x, y, or z) position of that face; example, top face position may be something like 10 (as in Y = 10)
  734.     if largestface == "top" then
  735.         startposx = size.X / -2
  736.         startposy = size.Y / 2
  737.         startposz = size.Z / -2
  738.         firstdirection = Vector3.new(0, 0, 1)
  739.         seconddirection = Vector3.new(1, 0, 0)
  740.         extradistance  = Vector3.new(0, 1, 0) * raycaststartdistance
  741.     elseif largestface == "left" then
  742.         startposx = size.X / -2
  743.         startposy = size.Y / 2
  744.         startposz = size.Z / -2
  745.         firstdirection = Vector3.new(0, -1, 0)
  746.         seconddirection = Vector3.new(0, 0, 1)
  747.         extradistance  = Vector3.new(-1, 0, 0) * raycaststartdistance
  748.     elseif largestface == "back" then
  749.         startposx = size.X / -2
  750.         startposy = size.Y / 2
  751.         startposz = size.Z / 2
  752.         firstdirection = Vector3.new(0, -1, 0)
  753.         seconddirection = Vector3.new(1, 0, 0)
  754.         extradistance  = Vector3.new(0, 0, 1) * raycaststartdistance
  755.     end
  756.    
  757.    
  758.     local guix = 0
  759.     local guiy = 0
  760.     local size1 = (size * firstdirection).magnitude --size1 and size2 is getting the first and second size we need (as in the X, Y, or Z size of the model)
  761.     local size2 = (size * seconddirection).magnitude      --example of how this works    ( (3, 4, 7) * (1, 0, 0) ).magnitude = 3
  762.     local depth = (extradistance.unit * size).magnitude --this is getting the size of the brick/model that the ray is going through; if we are raycasting into the top side of the brick, then depth would be Size.Y
  763.     local increment = increment
  764.     if size1 * size2 <= 10 then
  765.         increment = increment / 2
  766.     end
  767.     local startpos = Vector3.new(startposx, startposy, startposz)
  768.    
  769.     for i = 0, size1 / increment do
  770.         wait()
  771.         guiy = guiy + 1
  772.         guix = 0
  773.         for j = 0, size2 / increment do
  774.             guix = guix + 1
  775.             local addtostartpos1 = i * increment * firstdirection--this variable is a Vector3
  776.             local addtostartpos2 = j * increment * seconddirection--this variable is a Vector3
  777.             local raycastfromhere = startpos + addtostartpos1 + addtostartpos2 + extradistance
  778.             local raycasttohere = raycastfromhere - ( (size * extradistance.unit) + (extradistance * 2) )
  779.             castrayformodel(raycastfromhere, raycasttohere, guix, guiy, model, modelcframe, depth)
  780.             --raycastfromhere: start position of ray cast
  781.             --raycasttohere: end position of ray cast
  782.             --guix: x position of where on the gui a dot will be made (won't represent exact location, as this number will be multiplied and stuff)
  783.             --guiy: y position of where on the gui a dot will be made (won't represent exact location, as this number will be multiplied and stuff)
  784.             --model: the model
  785.             --modelcframe: the cframe of the model
  786.             --depth: depth is getting the size of the brick/model that the ray is going through; if we are raycasting into the top side of the brick, then depth would be Size.Y
  787.                 --go up about 22 lines to see this variable or search script for "local depth ="
  788.         end
  789.            
  790.     end
  791.    
  792.     local dotholder = makedotinfo[model].holder
  793.     generalinfoarray[dotholder] = {}
  794.    
  795.     local message = makedotinfo[model].message
  796.     if message then
  797.         generalinfoarray[dotholder].message = message
  798.     end
  799.     generalinfoarray[dotholder].itemowner = itemowner
  800.     generalinfoarray[dotholder].scannedthing = originalmodel
  801.     makedotinfo[model] = nil
  802.    
  803. end
  804.    
  805.    
  806.    
  807. function modifymeshpartsize(part)
  808.     local minarea = 4
  809.     local largestface = findlargestface(part)
  810.     if largestface == 'left' then --Z and Y
  811.         local area = part.Size.Z * part.Size.Y
  812.         if area < minarea then
  813.             part.Size = part.Size * (minarea / area)
  814.         end
  815.     elseif largestface == 'back' then --x and y
  816.         local area = part.Size.X * part.Size.Y
  817.         if area < minarea then
  818.             part.Size = part.Size * (minarea / area)
  819.         end
  820.     else --top  z and x
  821.         local area = part.Size.Z * part.Size.X
  822.         if area < minarea then
  823.             part.Size = part.Size * (minarea / area)
  824.         end
  825.     end
  826. end
  827.    
  828.    
  829. function getnumoftangiblechildren(item)
  830.     local num = 0
  831.     for _, v in pairs(item:GetDescendants()) do
  832.         if v:IsA('BasePart') then-- and (v.Transparency < .95 or ignoretransparentitems == false) then
  833.             num = num + 1
  834.         end
  835.     end
  836.     return num
  837. end
  838.  
  839.  
  840. function checkformeshchildren(item) --checks to see if item or any descendants of item are a mesh
  841.     if item:IsA('DataModelMesh') then
  842.         return true
  843.     end
  844.     for _, v in pairs(item:GetDescendants()) do
  845.         if v:IsA('DataModelMesh') then
  846.             return true
  847.         end
  848.     end
  849. end
  850.  
  851. function checkfortransparentchildren(item) --checks to see if item or any descendant of item are transparent
  852.     if item and item:IsA('BasePart') and item.Name == transparentname > .95 then
  853.         return true
  854.     end
  855.     for _, v in pairs(item:GetDescendants()) do
  856.         if v and v:IsA('BasePart') and v.Name == transparentname then
  857.             return true
  858.         end
  859.     end
  860. end
  861.  
  862.  
  863. function doscanforthing(oldthing)
  864.     local itemowner
  865.     local thing
  866.     if oldthing.Parent.ClassName == 'Model' then
  867.         local playerwhoownsitem = game.Players:GetPlayerFromCharacter(oldthing.Parent)
  868.         if playerwhoownsitem then
  869.             itemowner = playerwhoownsitem.Backpack
  870.         else
  871.             itemowner = oldthing.Parent
  872.         end
  873.     else
  874.         itemowner = oldthing.Parent
  875.     end
  876.    
  877.     thing = oldthing:Clone()
  878.    
  879.     if thing and thing:IsA('BasePart') and thing.Transparency > .95 and ignoretransparentitems == true then
  880.         thing.Name = transparentname
  881.     end
  882.     if ignoretransparentitems == true then
  883.         for _, v in pairs(thing:GetDescendants()) do
  884.             if v and v:IsA('BasePart') and v.Transparency > .95 then
  885.                 v.Name = transparentname
  886.             end
  887.         end
  888.     end
  889.  
  890.     local num = getnumoftangiblechildren(thing)
  891.     print(num)
  892.    
  893.     if num == 0 then
  894.         if thing:IsA('BasePart') then
  895.             if checkformeshchildren(thing) then
  896.                 local newthing = changemeshesforpart(thing)
  897.                 thing:Destroy()
  898.                 thing = newthing
  899.                 newthing = nil
  900.                 doscanforpart(thing, itemowner, oldthing)
  901.                 thing:Destroy()
  902.             else
  903.                 doscanforpart(thing, itemowner, oldthing)
  904.                 thing:Destroy()
  905.             end
  906.         else
  907. --          script.Parent.SurfaceGui.interface.message.Text = 'nothing physical to scan'
  908. --          script.Parent.SurfaceGui.interface.message.Visible = true
  909. --          wait(2)
  910. --          script.Parent.SurfaceGui.interface.message.Text = ''
  911. --          script.Parent.SurfaceGui.interface.message.Visible = false
  912.         end
  913.     elseif num == 1 then
  914.         print('==1')
  915.         if thing:IsA('BasePart') then
  916.             local model = Instance.new('Model')
  917.             thing.Parent = model
  918.            
  919.             if checkformeshchildren(model) or (checkfortransparentchildren(thing) and ignoretransparentitems == true) then
  920.                 local newmodel = Instance.new('Model')
  921.                 changemeshesformodel(model, newmodel)
  922.                 model:Destroy()
  923.                 doscanformodel(newmodel, itemowner, oldthing)
  924.                 newmodel:Destroy()
  925.             else
  926.                 doscanformodel(model, itemowner, oldthing)
  927.                 model:Destroy()
  928.             end
  929.         else
  930.             for _, v in pairs(thing:GetDescendants()) do
  931.                 if v:IsA('BasePart') then
  932.                     if checkformeshchildren(v) then
  933.                         local newpart = changemeshesforpart(v)
  934.                         doscanforpart(newpart, itemowner, oldthing)
  935.                         thing:Destroy()
  936.                         newpart:Destroy()
  937.                     else
  938.                         doscanforpart(v, itemowner, oldthing)
  939.                         thing:Destroy()
  940.                     end
  941.                     break
  942.                 end
  943.             end
  944.         end
  945.        
  946.     elseif num > 1 then
  947.         if thing.ClassName == 'Model' then
  948.             if checkformeshchildren(thing) or (checkfortransparentchildren(thing) and ignoretransparentitems == true) then
  949.                 local newmodel = Instance.new('Model')
  950.                 changemeshesformodel(thing, newmodel)
  951.                 thing:Destroy()
  952.                 doscanformodel(newmodel, itemowner, oldthing)
  953.                 newmodel:Destroy()
  954.             else
  955.                 doscanformodel(thing, itemowner, oldthing)
  956.                 thing:Destroy()
  957.             end
  958.         else
  959.             local model = Instance.new('Model')
  960.             thing.Parent = model
  961.            
  962.             if checkformeshchildren(model) or (checkfortransparentchildren(thing) and ignoretransparentitems == true) then
  963.                 local newmodel = Instance.new('Model')
  964.                 changemeshesformodel(model, newmodel)
  965.                 model:Destroy()
  966.                 doscanformodel(newmodel, itemowner, oldthing)
  967.                 newmodel:Destroy()
  968.             else
  969.                 doscanformodel(model, itemowner, oldthing)
  970.                 model:Destroy()
  971.             end
  972.         end
  973.            
  974.     end
  975. end
  976.  
  977. function makescannerrotate()
  978.     hinge.TargetAngle = hinge.TargetAngle * -1
  979.     wait(1)
  980.     hinge.AngularSpeed = .2
  981.     wait(1)
  982.     hinge.AngularSpeed = 1.6
  983. end
  984.  
  985.  
  986. --game.Workspace.testevent.OnServerEvent:Connect(function(player, arg)
  987. --  print('got it')
  988. --  local newmodel = Instance.new('Model', workspace)
  989. --  changemeshesformodel(arg.Parent, newmodel)
  990. --  newmodel.PrimaryPart = newmodel.Part
  991. --  newmodel:SetPrimaryPartCFrame(CFrame.new(game.Workspace.imalex4.Head.Position + Vector3.new(0, 6, 0))) 
  992. --  for _, v in pairs(newmodel:GetChildren()) do
  993. --      v.Transparency = 0
  994. --  end
  995. --end)
  996.  
  997. --game.Workspace.testevent.OnServerEvent:Connect(function(player, arg)
  998. --  print('got it')
  999. -- 
  1000. --  local newpart = changemeshesforpart(arg)
  1001. --  newpart.Position = game.Workspace.imalex4.Head.Position + Vector3.new(0, 3, 0)
  1002. --  newpart.Transparency = 0
  1003. --  newpart.Anchored = true
  1004. --end)
  1005.  
  1006.  
  1007.  
  1008.  
  1009. script.Parent.Parent.RemoteEvent.OnServerEvent:Connect(function(player, args)
  1010.     if player and player.Character and player.Character.Parent and player.Character.Humanoid.Health > 0 and (player.Character.Head.Position - script.Parent.Position).magnitude <= clickdistance then
  1011.        
  1012.        
  1013.         ----//////////// if you only want certain players to be able to use the body scanner, modify the line below
  1014.         if player then
  1015.             if args == 'directthru' then
  1016.                 if not debounces[args] then
  1017.                     debounces[args] = true
  1018.                     script.Parent.Parent.Parent.simplescreen1.SurfaceGui.TextLabel.Text = 'GO THRU'
  1019.                     script.Parent.Parent.Parent.simplescreen2.SurfaceGui.TextLabel.Text = 'GO THRU'
  1020.                     script.Parent.Parent.Parent.simplescreen1.SurfaceGui.TextLabel.TextColor3 = Color3.new(0, 255, 0)
  1021.                     script.Parent.Parent.Parent.simplescreen2.SurfaceGui.TextLabel.TextColor3 = Color3.new(0, 255, 0)
  1022.                     script.Parent.Parent.Parent.simplescreen1.Sound:Play()
  1023.                     wait(1.9)
  1024.                     script.Parent.Parent.Parent.simplescreen1.SurfaceGui.TextLabel.Text = '-WAIT-'
  1025.                     script.Parent.Parent.Parent.simplescreen2.SurfaceGui.TextLabel.Text = '-WAIT-'
  1026.                     script.Parent.Parent.Parent.simplescreen1.SurfaceGui.TextLabel.TextColor3 = Color3.new(255, 0, 0)
  1027.                     script.Parent.Parent.Parent.simplescreen2.SurfaceGui.TextLabel.TextColor3 = Color3.new(255, 0, 0)
  1028.                     debounces[args] = false
  1029.                 else
  1030.                     script.Parent.Parent.Parent.simplescreen1.Sound:Play()
  1031.                 end
  1032.             elseif args == 'scan' then
  1033.                 if not debounces[args] and not debounces['previousimage'] and not debounces['nextimage'] and not debounces['doscan'] then
  1034.                     debounces[args] = true
  1035.                     debounces['doscan'] = true
  1036.                     debounces['previousimage'] = true
  1037.                     debounces['nextimage'] = true
  1038.                    
  1039.                     for _, v in pairs(gui.scanimages:GetChildren()) do
  1040.                         v:Destroy()
  1041.                         wait()
  1042.                     end
  1043.                     scanimagesindex = 0
  1044.                     interface.message.Text = ''
  1045.                     interface.scannumber.Text = ''
  1046.                     interface.message.Visible = false
  1047.                     interface.take.Text = 'Confiscate'
  1048.                    
  1049.                     debounces['doscan'] = false
  1050.                     debounces['previousimage'] = false
  1051.                     debounces['nextimage'] = false
  1052.                     debounces[args] = false
  1053.                 end
  1054.                
  1055.                 if not debounces[args] then
  1056.                     debounces[args] = true
  1057.                    
  1058.                     numofscanimages = 0
  1059.                     numofpeopleinscanner = 0
  1060.                     interface.scannumber.Text = ''
  1061.                     interface.message.Text = 'Scanning in progress'
  1062.                     interface.message.Visible = true
  1063.                     makescannerrotate()
  1064.                     timeofscanstart = tick()
  1065.                    
  1066.                    
  1067.                     for _, v in pairs(peopleinscanner) do
  1068.                         numofpeopleinscanner = numofpeopleinscanner + 1
  1069.                         --#peopleinscanner doesn't work here
  1070.                     end
  1071.                    
  1072.                     if numofpeopleinscanner == 0 or numofpeopleinscanner > 1 then
  1073.                         wait(1.8 - (tick() - timeofscanstart) )
  1074.                         interface.message.Text = 'no one in scanner or multiple people in scanner'
  1075.                         interface.message.Visible = true
  1076.                         wait(2)
  1077.                         interface.message.Visible = false
  1078.                         interface.message.Text = ''
  1079.                     else --numofpeopleinscanner == 1
  1080.                         debounces['previousimage'] = true
  1081.                         debounces['nextimage'] = true
  1082.                         debounces['clear'] = true
  1083.                         scanimagesindex = 0
  1084.                        
  1085.                         makedotinfo = {}
  1086.                         generalinfoarray = {}
  1087.                         for _, v in pairs(gui.scanimages:GetChildren()) do
  1088.                             v:Destroy()
  1089.                             wait()
  1090.                         end
  1091.                        
  1092.                         local character
  1093.                         for i, v in pairs(peopleinscanner) do
  1094.                             character = i --this is correct, character is not v; peopleinscanner is a map array
  1095.                             --at this point in the code, there should only be one person in the array
  1096.                         end
  1097.                         local player = game.Players:GetPlayerFromCharacter(character)
  1098.                        
  1099.                         if not player then
  1100.                             for _, v in pairs(character:GetChildren()) do
  1101.                                 if v and v:IsA('BackpackItem') then
  1102.                                     doscanforthing(v)
  1103.                                 end
  1104.                             end
  1105.                         else
  1106.                             for _, v in pairs(player.Backpack:GetChildren()) do
  1107.                                 if v then
  1108.                                     doscanforthing(v)
  1109.                                 end
  1110.                             end
  1111.                             for _, v in pairs(character:GetChildren()) do
  1112.                                 if v and v:IsA('BackpackItem') then
  1113.                                     doscanforthing(v)
  1114.                                 end
  1115.                             end
  1116.                         end
  1117.                        
  1118.                         scanimages = gui.scanimages:GetChildren()
  1119.                        
  1120.                         for _, v in pairs(scanimages) do
  1121.                             numofscanimages = numofscanimages + 1
  1122.                         end
  1123.                        
  1124.                         wait(1.8 - (tick() - timeofscanstart) )
  1125.                        
  1126.                         if numofscanimages == 0 then
  1127.                             interface.message.Text = 'This person has no items'
  1128.                             interface.message.Visible = true
  1129.                             wait(1.5)
  1130.                         else
  1131.                             if numofscanimages > 1 then
  1132.                                 interface.scannumber.Text = '1 of ' .. numofscanimages
  1133.                             end
  1134.                             scanimages[1].Visible = true
  1135.                             scanimagesindex = 1
  1136.                         end
  1137.                        
  1138.                         local message = generalinfoarray[ scanimages[scanimagesindex] ].message
  1139.                         if message then
  1140.                             interface.message.Text = message
  1141.                             interface.message.Visible = true
  1142.                         else
  1143.                             interface.message.Visible = false
  1144.                             interface.message.Text = ''
  1145.                         end
  1146.                        
  1147.                         debounces['clear'] = false
  1148.                         debounces['previousimage'] = false
  1149.                         debounces['nextimage'] = false
  1150.                        
  1151.                        
  1152.                     end
  1153.                    
  1154.                     debounces[args] = false
  1155.                 end
  1156.                
  1157.             elseif args == 'previousimage' then
  1158.                 if not debounces[args] and scanimagesindex ~= 0 then
  1159.                     debounces[args] = true
  1160.                     debounces['doscan'] = true
  1161.                     if scanimagesindex > 1 then
  1162.                         interface.message.Visible = false
  1163.                         interface.message.Text = ''
  1164.                        
  1165.                         scanimages[scanimagesindex].Visible = false
  1166.                         scanimagesindex = scanimagesindex - 1
  1167.                         scanimages[scanimagesindex].Visible = true
  1168.                         local message = generalinfoarray[ scanimages[scanimagesindex] ].message
  1169.                         if message then
  1170.                             interface.message.Text = message
  1171.                             interface.message.Visible = true
  1172.                         end
  1173.                         interface.scannumber.Text = scanimagesindex .. ' of ' .. numofscanimages
  1174.                         if generalinfoarray[ scanimages[scanimagesindex] ].currentitemholder then
  1175.                             interface.take.Text = 'Return Item'
  1176.                         else
  1177.                             interface.take.Text = 'Confiscate'
  1178.                         end
  1179.                     end
  1180.                     debounces['doscan'] = false
  1181.                     debounces[args] = false
  1182.                 end
  1183.                
  1184.             elseif args == 'nextimage' then
  1185.                 if not debounces[args] and scanimagesindex ~= 0 then
  1186.                     debounces[args] = true
  1187.                     debounces['doscan'] = true
  1188.                     if scanimagesindex < numofscanimages then
  1189.                         interface.message.Visible = false
  1190.                         interface.message.Text = ''
  1191.                        
  1192.                         scanimages[scanimagesindex].Visible = false
  1193.                         scanimagesindex = scanimagesindex + 1
  1194.                         scanimages[scanimagesindex].Visible = true
  1195.                         local message = generalinfoarray[ scanimages[scanimagesindex] ].message
  1196.                         if message then
  1197.                             interface.message.Text = message
  1198.                             interface.message.Visible = true
  1199.                         end
  1200.                         interface.scannumber.Text = scanimagesindex .. ' of ' .. numofscanimages
  1201.                         if generalinfoarray[ scanimages[scanimagesindex] ].currentitemholder then
  1202.                             interface.take.Text = 'Return Item'
  1203.                         else
  1204.                             interface.take.Text = 'Confiscate'
  1205.                         end
  1206.                     end
  1207.                     debounces['doscan'] = false
  1208.                     debounces[args] = false
  1209.                 end
  1210.                
  1211.             elseif args == 'clear' then
  1212.                 if not debounces[args] and not debounces['previousimage'] and not debounces['nextimage'] and not debounces['doscan'] then
  1213.                     debounces[args] = true
  1214.                     debounces['doscan'] = true
  1215.                     debounces['previousimage'] = true
  1216.                     debounces['nextimage'] = true
  1217.                    
  1218.                     for _, v in pairs(gui.scanimages:GetChildren()) do
  1219.                         v:Destroy()
  1220.                         wait()
  1221.                     end
  1222.                     scanimagesindex = 0
  1223.                     interface.message.Text = ''
  1224.                     interface.scannumber.Text = ''
  1225.                     interface.message.Visible = false
  1226.                     interface.take.Text = 'Confiscate'
  1227.                    
  1228.                     debounces['doscan'] = false
  1229.                     debounces['previousimage'] = false
  1230.                     debounces['nextimage'] = false
  1231.                     debounces[args] = false
  1232.                 end
  1233.             elseif args == 'takeorreturn' then
  1234.                
  1235.                 if not debounces[args] then
  1236.                     debounces[args] = true
  1237.                     local currentscanimage = scanimages[scanimagesindex]
  1238.                     if generalinfoarray[currentscanimage].currentitemholder and generalinfoarray[currentscanimage].currentitemholder.Parent == player and generalinfoarray[currentscanimage].itemowner then
  1239.                         generalinfoarray[currentscanimage].scannedthing.Parent = generalinfoarray[currentscanimage].itemowner
  1240.                         generalinfoarray[currentscanimage].currentitemholder = nil
  1241.                         interface.take.Text = 'Confiscate'
  1242.                     elseif generalinfoarray[currentscanimage].itemowner and not generalinfoarray[currentscanimage].currentitemholder then
  1243.                         generalinfoarray[currentscanimage].scannedthing.Parent = player.Backpack
  1244.                         generalinfoarray[currentscanimage].currentitemholder = player.Backpack
  1245.                         interface.take.Text = 'Return Item'
  1246.                     end
  1247.                     debounces[args] = false
  1248.                 end
  1249.            
  1250.             end --if args ==
  1251.            
  1252.         end
  1253.        
  1254.     end
  1255. end)
  1256.  
  1257. script.Parent.Parent.Parent.touchpart.Touched:Connect(function(part)
  1258.     if part and part.Name == 'Head' and part.Parent and part.Parent:FindFirstChild('Humanoid') and not peopleinscanner[part.Parent] then
  1259.         peopleinscanner[part.Parent] = true
  1260.     end
  1261. end)
  1262.  
  1263. while true do
  1264.     wait(1)
  1265.     for i, v in pairs(peopleinscanner) do --NOTE look at i, not v; v will always just be true or nil, as this table is a map
  1266.         if not i or not i.Parent or not i:FindFirstChild('Head') or ( (i.Head.Position - script.Parent.Parent.Parent.touchpart.Position).magnitude ) > 3 then
  1267.             print('gone')
  1268.             peopleinscanner[i] = nil
  1269.         end
  1270.     end
  1271. end
  1272.  
  1273. --doscanforthing(game.Workspace.p1)
  1274. --doscanforthing(game.Workspace.testmodel)
  1275.  
  1276.  
  1277.  
Advertisement
Add Comment
Please, Sign In to add comment