├── CoreScripts
├── BackpackScripts
│ ├── BackpackBuilder.lua
│ ├── BackpackGear.lua
│ ├── BackpackManager.lua
│ ├── BackpackResizer.lua
│ └── LoadoutScript.lua
├── BuildToolsScripts
│ ├── BuildToolManager.lua
│ └── BuildToolsScript.lua
├── ChatScript.lua
├── ContextActionTouch.lua
├── DialogScripts.rbxm
├── HealthScript.lua
├── MainBotChatScript.lua
├── NotificationScript.lua
├── PlaceConsoleScript.lua
├── PlayerListScript.lua
├── PopupScript.lua
├── PurchasePromptScript.lua
├── RBXStatusBuffsGUIScript.lua
├── Sections.lua
├── Settings.lua
├── SubMenuBuilder.lua
├── SurfaceMenuMover.lua
├── ToolTip.lua
├── TouchControls.lua
└── fastlog.lua
├── Libraries
├── LibraryRegistration
│ ├── Gametest2LibraryRegistration.lua
│ ├── GametestLibraryRegistration.lua
│ ├── LibraryRegistration.lua
│ └── SitetestLibraryRegistration.lua
├── RBXStatus.lua
├── RbxGear.lua
├── RbxGui.lua
├── RbxStamper.lua
└── RbxUtility.lua
├── README.md
├── StarterScript.lua
└── newHumanoidHealthRegen.rbxm
/CoreScripts/BackpackScripts/BackpackGear.lua:
--------------------------------------------------------------------------------
1 | -- A couple of necessary functions
2 | local function waitForChild(instance, name)
3 | assert(instance)
4 | assert(name)
5 | while not instance:FindFirstChild(name) do
6 | print('Waiting for ...', instance, name)
7 | instance.ChildAdded:wait()
8 | end
9 | return instance:FindFirstChild(name)
10 | end
11 | local function waitForProperty(instance, property)
12 | assert(instance)
13 | assert(property)
14 | while not instance[property] do
15 | instance.Changed:wait()
16 | end
17 | end
18 |
19 | local function IsTouchDevice()
20 | return Game:GetService('UserInputService').TouchEnabled
21 | end
22 |
23 |
24 | waitForChild(game,"Players")
25 | waitForProperty(game.Players,"LocalPlayer")
26 | local player = game.Players.LocalPlayer
27 |
28 | local RbxGui, msg = LoadLibrary("RbxGui")
29 | if not RbxGui then print("could not find RbxGui!") return end
30 |
31 | --- Begin Locals
32 | local StaticTabName = "gear"
33 |
34 | local backpack = script.Parent
35 | local screen = script.Parent.Parent
36 |
37 | local backpackItems = {}
38 | local buttons = {}
39 |
40 | local debounce = false
41 | local browsingMenu = false
42 |
43 | local mouseEnterCons = {}
44 | local mouseClickCons = {}
45 |
46 | local characterChildAddedCon = nil
47 | local characterChildRemovedCon = nil
48 | local backpackAddCon = nil
49 |
50 | local playerBackpack = waitForChild(player,"Backpack")
51 |
52 | waitForChild(backpack,"Tabs")
53 |
54 | waitForChild(backpack,"Gear")
55 | local gearPreview = waitForChild(backpack.Gear,"GearPreview")
56 |
57 | local scroller = waitForChild(backpack.Gear,"GearGridScrollingArea")
58 |
59 | local currentLoadout = waitForChild(backpack.Parent,"CurrentLoadout")
60 |
61 | local grid = waitForChild(backpack.Gear,"GearGrid")
62 | local gearButton = waitForChild(grid,"GearButton")
63 |
64 | local swapSlot = waitForChild(script.Parent,"SwapSlot")
65 |
66 | local backpackManager = waitForChild(script.Parent,"CoreScripts/BackpackScripts/BackpackManager")
67 | local backpackOpenEvent = waitForChild(backpackManager,"BackpackOpenEvent")
68 | local backpackCloseEvent = waitForChild(backpackManager,"BackpackCloseEvent")
69 | local tabClickedEvent = waitForChild(backpackManager,"TabClickedEvent")
70 | local resizeEvent = waitForChild(backpackManager,"ResizeEvent")
71 | local searchRequestedEvent = waitForChild(backpackManager,"SearchRequestedEvent")
72 | local tellBackpackReadyFunc = waitForChild(backpackManager,"BackpackReady")
73 |
74 | -- creating scroll bar early as to make sure items get placed correctly
75 | local scrollFrame, scrollUp, scrollDown, recalculateScroll = RbxGui.CreateScrollingFrame(nil, "grid", Vector2.new(6, 6))
76 |
77 | scrollFrame.Position = UDim2.new(0,0,0,30)
78 | scrollFrame.Size = UDim2.new(1,0,1,-30)
79 | scrollFrame.Parent = backpack.Gear.GearGrid
80 |
81 | local scrollBar = Instance.new("Frame")
82 | scrollBar.Name = "ScrollBar"
83 | scrollBar.BackgroundTransparency = 0.9
84 | scrollBar.BackgroundColor3 = Color3.new(1,1,1)
85 | scrollBar.BorderSizePixel = 0
86 | scrollBar.Size = UDim2.new(0, 17, 1, -36)
87 | scrollBar.Position = UDim2.new(0,0,0,18)
88 | scrollBar.Parent = scroller
89 |
90 | scrollDown.Position = UDim2.new(0,0,1,-17)
91 |
92 | scrollUp.Parent = scroller
93 | scrollDown.Parent = scroller
94 |
95 | local scrollFrameLoadout, scrollUpLoadout, scrollDownLoadout, recalculateScrollLoadout = RbxGui.CreateScrollingFrame()
96 |
97 | scrollFrameLoadout.Position = UDim2.new(0,0,0,0)
98 | scrollFrameLoadout.Size = UDim2.new(1,0,1,0)
99 | scrollFrameLoadout.Parent = backpack.Gear.GearLoadouts.LoadoutsList
100 |
101 | local LoadoutButton = Instance.new("TextButton")
102 | LoadoutButton.RobloxLocked = true
103 | LoadoutButton.Name = "LoadoutButton"
104 | LoadoutButton.Font = Enum.Font.ArialBold
105 | LoadoutButton.FontSize = Enum.FontSize.Size14
106 | LoadoutButton.Position = UDim2.new(0,0,0,0)
107 | LoadoutButton.Size = UDim2.new(1,0,0,32)
108 | LoadoutButton.Style = Enum.ButtonStyle.RobloxButton
109 | LoadoutButton.Text = "Loadout #1"
110 | LoadoutButton.TextColor3 = Color3.new(1,1,1)
111 | LoadoutButton.Parent = scrollFrameLoadout
112 |
113 | local LoadoutButtonTwo = LoadoutButton:clone()
114 | LoadoutButtonTwo.Text = "Loadout #2"
115 | LoadoutButtonTwo.Parent = scrollFrameLoadout
116 |
117 | local LoadoutButtonThree = LoadoutButton:clone()
118 | LoadoutButtonThree.Text = "Loadout #3"
119 | LoadoutButtonThree.Parent = scrollFrameLoadout
120 |
121 | local LoadoutButtonFour = LoadoutButton:clone()
122 | LoadoutButtonFour.Text = "Loadout #4"
123 | LoadoutButtonFour.Parent = scrollFrameLoadout
124 |
125 | local scrollBarLoadout = Instance.new("Frame")
126 | scrollBarLoadout.Name = "ScrollBarLoadout"
127 | scrollBarLoadout.BackgroundTransparency = 0.9
128 | scrollBarLoadout.BackgroundColor3 = Color3.new(1,1,1)
129 | scrollBarLoadout.BorderSizePixel = 0
130 | scrollBarLoadout.Size = UDim2.new(0, 17, 1, -36)
131 | scrollBarLoadout.Position = UDim2.new(0,0,0,18)
132 | scrollBarLoadout.Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea
133 |
134 | scrollDownLoadout.Position = UDim2.new(0,0,1,-17)
135 |
136 | scrollUpLoadout.Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea
137 | scrollDownLoadout.Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea
138 |
139 |
140 | -- Begin Functions
141 | function removeFromMap(map,object)
142 | for i = 1, #map do
143 | if map[i] == object then
144 | table.remove(map,i)
145 | break
146 | end
147 | end
148 | end
149 |
150 | function robloxLock(instance)
151 | instance.RobloxLocked = true
152 | children = instance:GetChildren()
153 | if children then
154 | for i, child in ipairs(children) do
155 | robloxLock(child)
156 | end
157 | end
158 | end
159 |
160 | function resize()
161 | local size = 0
162 | if gearPreview.AbsoluteSize.Y > gearPreview.AbsoluteSize.X then
163 | size = gearPreview.AbsoluteSize.X * 0.75
164 | else
165 | size = gearPreview.AbsoluteSize.Y * 0.75
166 | end
167 |
168 | waitForChild(gearPreview,"GearImage")
169 | gearPreview.GearImage.Size = UDim2.new(0,size,0,size)
170 | gearPreview.GearImage.Position = UDim2.new(0,gearPreview.AbsoluteSize.X/2 - size/2,0.75,-size)
171 |
172 | resizeGrid()
173 | end
174 |
175 | function addToGrid(child)
176 | if not child:IsA("Tool") then
177 | if not child:IsA("HopperBin") then
178 | return
179 | end
180 | end
181 | if child:FindFirstChild("RobloxBuildTool") then return end
182 |
183 | for i,v in pairs(backpackItems) do -- check to see if we already have this gear registered
184 | if v == child then return end
185 | end
186 |
187 | table.insert(backpackItems,child)
188 |
189 | local changeCon = child.Changed:connect(function(prop)
190 | if prop == "Name" then
191 | if buttons[child] then
192 | if buttons[child].Image == "" then
193 | buttons[child].GearText.Text = child.Name
194 | end
195 | end
196 | end
197 | end)
198 | local ancestryCon = nil
199 | ancestryCon = child.AncestryChanged:connect(function(theChild,theParent)
200 | local thisObject = nil
201 | for k,v in pairs(backpackItems) do
202 | if v == child then
203 | thisObject = v
204 | break
205 | end
206 | end
207 |
208 | waitForProperty(player,"Character")
209 | waitForChild(player,"Backpack")
210 | if (child.Parent ~= player.Backpack and child.Parent ~= player.Character) then
211 | if ancestryCon then ancestryCon:disconnect() end
212 | if changeCon then changeCon:disconnect() end
213 |
214 | for k,v in pairs(backpackItems) do
215 | if v == thisObject then
216 | if mouseEnterCons[buttons[v]] then mouseEnterCons[buttons[v]]:disconnect() end
217 | if mouseClickCons[buttons[v]] then mouseClickCons[buttons[v]]:disconnect() end
218 | buttons[v].Parent = nil
219 | buttons[v] = nil
220 | break
221 | end
222 | end
223 |
224 | removeFromMap(backpackItems,thisObject)
225 |
226 | resizeGrid()
227 | else
228 | resizeGrid()
229 | end
230 | updateGridActive()
231 | end)
232 | resizeGrid()
233 | end
234 |
235 | function buttonClick(button)
236 | if button:FindFirstChild("UnequipContextMenu") and not button.Active then
237 | button.UnequipContextMenu.Visible = true
238 | browsingMenu = true
239 | end
240 | end
241 |
242 | function previewGear(button)
243 | if not browsingMenu then
244 | gearPreview.Visible = false
245 | gearPreview.GearImage.Image = button.Image
246 | gearPreview.GearStats.GearName.Text = button.GearReference.Value.Name
247 | end
248 | end
249 |
250 | function findEmptySlot()
251 | local smallestNum = nil
252 | local loadout = currentLoadout:GetChildren()
253 | for i = 1, #loadout do
254 | if loadout[i]:IsA("Frame") and #loadout[i]:GetChildren() <= 0 then
255 | local frameNum = tonumber(string.sub(loadout[i].Name,5))
256 | if frameNum == 0 then frameNum = 10 end
257 | if not smallestNum or (smallestNum > frameNum) then
258 | smallestNum = frameNum
259 | end
260 | end
261 | end
262 | if smallestNum == 10 then smallestNum = 0 end
263 | return smallestNum
264 | end
265 |
266 | function checkForSwap(button,x,y)
267 | local loadoutChildren = currentLoadout:GetChildren()
268 | for i = 1, #loadoutChildren do
269 | if loadoutChildren[i]:IsA("Frame") and string.find(loadoutChildren[i].Name,"Slot") then
270 | if x >= loadoutChildren[i].AbsolutePosition.x and x <= (loadoutChildren[i].AbsolutePosition.x + loadoutChildren[i].AbsoluteSize.x) then
271 | if y >= loadoutChildren[i].AbsolutePosition.y and y <= (loadoutChildren[i].AbsolutePosition.y + loadoutChildren[i].AbsoluteSize.y) then
272 | local slot = tonumber(string.sub(loadoutChildren[i].Name,5))
273 | swapGearSlot(slot,button)
274 | return true
275 | end
276 | end
277 | end
278 | end
279 | return false
280 | end
281 |
282 | function resizeGrid()
283 | for k,v in pairs(backpackItems) do
284 | if not v:FindFirstChild("RobloxBuildTool") then
285 | if not buttons[v] then
286 | local buttonClone = gearButton:clone()
287 | buttonClone.Parent = grid.ScrollingFrame
288 | buttonClone.Visible = true
289 | buttonClone.Image = v.TextureId
290 | if buttonClone.Image == "" then
291 | buttonClone.GearText.Text = v.Name
292 | end
293 |
294 | buttonClone.GearReference.Value = v
295 | buttonClone.Draggable = true
296 | buttons[v] = buttonClone
297 |
298 |
299 | if not IsTouchDevice() then
300 | local unequipMenu = getGearContextMenu()
301 |
302 |
303 | unequipMenu.Visible = false
304 | unequipMenu.Parent = buttonClone
305 | end
306 |
307 | local beginPos = nil
308 | buttonClone.DragBegin:connect(function(value)
309 | waitForChild(buttonClone, 'Background')
310 | buttonClone['Background'].ZIndex = 10
311 | buttonClone.ZIndex = 10
312 | beginPos = value
313 | end)
314 | buttonClone.DragStopped:connect(function(x,y)
315 | waitForChild(buttonClone, 'Background')
316 | buttonClone['Background'].ZIndex = 1.0
317 | buttonClone.ZIndex = 2
318 | if beginPos ~= buttonClone.Position then
319 | if not checkForSwap(buttonClone,x,y) then
320 | buttonClone:TweenPosition(beginPos,Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.5, true)
321 | buttonClone.Draggable = false
322 | delay(0.5,function()
323 | buttonClone.Draggable = true
324 | end)
325 | else
326 | buttonClone.Position = beginPos
327 | end
328 | end
329 | end)
330 | local clickTime = tick()
331 | mouseEnterCons[buttonClone] = buttonClone.MouseEnter:connect(function() previewGear(buttonClone) end)
332 | mouseClickCons[buttonClone] = buttonClone.MouseButton1Click:connect(function()
333 | local newClickTime = tick()
334 | if buttonClone.Active and (newClickTime - clickTime) < 0.5 then
335 | local slot = findEmptySlot()
336 | if slot then
337 | buttonClone.ZIndex = 1
338 | swapGearSlot(slot,buttonClone)
339 | end
340 | else
341 | buttonClick(buttonClone)
342 | end
343 | clickTime = newClickTime
344 | end)
345 | end
346 | end
347 | end
348 | recalculateScroll()
349 | end
350 |
351 | function showPartialGrid(subset)
352 | for k,v in pairs(buttons) do
353 | v.Parent = nil
354 | end
355 | if subset then
356 | for k,v in pairs(subset) do
357 | v.Parent = grid.ScrollingFrame
358 | end
359 | end
360 | recalculateScroll()
361 | end
362 |
363 | function showEntireGrid()
364 | for k,v in pairs(buttons) do
365 | v.Parent = grid.ScrollingFrame
366 | end
367 | recalculateScroll()
368 | end
369 |
370 | function inLoadout(gear)
371 | local children = currentLoadout:GetChildren()
372 | for i = 1, #children do
373 | if children[i]:IsA("Frame") then
374 | local button = children[i]:GetChildren()
375 | if #button > 0 then
376 | if button[1].GearReference.Value and button[1].GearReference.Value == gear then
377 | return true
378 | end
379 | end
380 | end
381 | end
382 | return false
383 | end
384 |
385 | function updateGridActive()
386 | for k,v in pairs(backpackItems) do
387 | if buttons[v] then
388 | local gear = nil
389 | local gearRef = buttons[v]:FindFirstChild("GearReference")
390 |
391 | if gearRef then gear = gearRef.Value end
392 |
393 | if not gear then
394 | buttons[v].Active = false
395 | elseif inLoadout(gear) then
396 | buttons[v].Active = false
397 | else
398 | buttons[v].Active = true
399 | end
400 | end
401 | end
402 | end
403 |
404 | function centerGear(loadoutChildren)
405 | local gearButtons = {}
406 | local lastSlotAdd = nil
407 | for i = 1, #loadoutChildren do
408 | if loadoutChildren[i]:IsA("Frame") and #loadoutChildren[i]:GetChildren() > 0 then
409 | if loadoutChildren[i].Name == "Slot0" then
410 | lastSlotAdd = loadoutChildren[i]
411 | else
412 | table.insert(gearButtons, loadoutChildren[i])
413 | end
414 | end
415 | end
416 | if lastSlotAdd then table.insert(gearButtons,lastSlotAdd) end
417 |
418 | local startPos = ( 1 - (#gearButtons * 0.1) ) / 2
419 | for i = 1, #gearButtons do
420 | gearButtons[i]:TweenPosition(UDim2.new(startPos + ((i - 1) * 0.1),0,0,0), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.25, true)
421 | end
422 | end
423 |
424 | function tabClickHandler(tabName)
425 | if tabName == StaticTabName then
426 | backpackOpenHandler(tabName)
427 | else
428 | backpackCloseHandler(tabName)
429 | end
430 | end
431 |
432 | function backpackOpenHandler(currentTab)
433 | if currentTab and currentTab ~= StaticTabName then
434 | backpack.Gear.Visible = false
435 | return
436 | end
437 |
438 | backpack.Gear.Visible = true
439 | updateGridActive()
440 |
441 | resizeGrid()
442 | resize()
443 | tellBackpackReadyFunc:Invoke()
444 | end
445 |
446 | function backpackCloseHandler(currentTab)
447 | if currentTab and currentTab ~= StaticTabName then
448 | backpack.Gear.Visible = false
449 | return
450 | end
451 |
452 | backpack.Gear.Visible = false
453 |
454 | resizeGrid()
455 | resize()
456 | tellBackpackReadyFunc:Invoke()
457 | end
458 |
459 | function loadoutCheck(child, selectState)
460 | if not child:IsA("ImageButton") then return end
461 | for k,v in pairs(backpackItems) do
462 | if buttons[v] then
463 | if child:FindFirstChild("GearReference") and buttons[v]:FindFirstChild("GearReference") then
464 | if buttons[v].GearReference.Value == child.GearReference.Value then
465 | buttons[v].Active = selectState
466 | break
467 | end
468 | end
469 | end
470 | end
471 | end
472 |
473 | function clearPreview()
474 | gearPreview.GearImage.Image = ""
475 | gearPreview.GearStats.GearName.Text = ""
476 | end
477 |
478 | function removeAllEquippedGear(physGear)
479 | local stuff = player.Character:GetChildren()
480 | for i = 1, #stuff do
481 | if ( stuff[i]:IsA("Tool") or stuff[i]:IsA("HopperBin") ) and stuff[i] ~= physGear then
482 | stuff[i].Parent = playerBackpack
483 | end
484 | end
485 | end
486 |
487 | function equipGear(physGear)
488 | removeAllEquippedGear(physGear)
489 | physGear.Parent = player.Character
490 | updateGridActive()
491 | end
492 |
493 | function unequipGear(physGear)
494 | physGear.Parent = playerBackpack
495 | updateGridActive()
496 | end
497 |
498 | function highlight(button)
499 | button.TextColor3 = Color3.new(0,0,0)
500 | button.BackgroundColor3 = Color3.new(0.8,0.8,0.8)
501 | end
502 | function clearHighlight(button)
503 | button.TextColor3 = Color3.new(1,1,1)
504 | button.BackgroundColor3 = Color3.new(0,0,0)
505 | end
506 |
507 | function swapGearSlot(slot,gearButton)
508 | if not swapSlot.Value then -- signal loadout to swap a gear out
509 | swapSlot.Slot.Value = slot
510 | swapSlot.GearButton.Value = gearButton
511 | swapSlot.Value = true
512 | updateGridActive()
513 | end
514 | end
515 |
516 |
517 | local UnequipGearMenuClick = function(element, menu)
518 | if type(element.Action) ~= "number" then return end
519 | local num = element.Action
520 | if num == 1 then -- remove from loadout
521 | unequipGear(menu.Parent.GearReference.Value)
522 | local inventoryButton = menu.Parent
523 | local gearToUnequip = inventoryButton.GearReference.Value
524 | local loadoutChildren = currentLoadout:GetChildren()
525 | local slot = -1
526 | for i = 1, #loadoutChildren do
527 | if loadoutChildren[i]:IsA("Frame") then
528 | local button = loadoutChildren[i]:GetChildren()
529 | if button[1] and button[1].GearReference.Value == gearToUnequip then
530 | slot = button[1].SlotNumber.Text
531 | break
532 | end
533 | end
534 | end
535 | swapGearSlot(slot,nil)
536 | end
537 | end
538 |
539 | function setupCharacterConnections()
540 |
541 | if backpackAddCon then backpackAddCon:disconnect() end
542 | backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded:connect(function(child) addToGrid(child) end)
543 |
544 | -- make sure we get all the children
545 | local backpackChildren = game.Players.LocalPlayer.Backpack:GetChildren()
546 | for i = 1, #backpackChildren do
547 | addToGrid(backpackChildren[i])
548 | end
549 |
550 | if characterChildAddedCon then characterChildAddedCon:disconnect() end
551 | characterChildAddedCon =
552 | game.Players.LocalPlayer.Character.ChildAdded:connect(function(child)
553 | addToGrid(child)
554 | updateGridActive()
555 | end)
556 |
557 | if characterChildRemovedCon then characterChildRemovedCon:disconnect() end
558 | characterChildRemovedCon =
559 | game.Players.LocalPlayer.Character.ChildRemoved:connect(function(child)
560 | updateGridActive()
561 | end)
562 |
563 | wait()
564 | centerGear(currentLoadout:GetChildren())
565 | end
566 |
567 | function removeCharacterConnections()
568 | if characterChildAddedCon then characterChildAddedCon:disconnect() end
569 | if characterChildRemovedCon then characterChildRemovedCon:disconnect() end
570 | if backpackAddCon then backpackAddCon:disconnect() end
571 | end
572 |
573 | function trim(s)
574 | return (s:gsub("^%s*(.-)%s*$", "%1"))
575 | end
576 |
577 | function filterGear(terms)
578 | local filteredGear = {}
579 | for k,v in pairs(backpackItems) do
580 | if buttons[v] then
581 | local gearString = string.lower(buttons[v].GearReference.Value.Name)
582 | gearString = trim(gearString)
583 | for i = 1, #terms do
584 | if string.match(gearString,terms[i]) then
585 | table.insert(filteredGear,buttons[v])
586 | break
587 | end
588 | end
589 | end
590 | end
591 |
592 | return filteredGear
593 | end
594 | function splitByWhitespace(text)
595 | if type(text) ~= "string" then return nil end
596 |
597 | local terms = {}
598 | for token in string.gmatch(text, "[^%s]+") do
599 | if string.len(token) > 0 then
600 | table.insert(terms,token)
601 | end
602 | end
603 | return terms
604 | end
605 | function showSearchGear(searchTerms)
606 | if not backpack.Gear.Visible then return end -- currently not active tab
607 |
608 | local searchTermTable = splitByWhitespace(searchTerms)
609 | if searchTermTable and (#searchTermTable > 0) then
610 | currSearchTerms = searchTermTable
611 | else
612 | currSearchTerms = nil
613 | end
614 |
615 | if searchTermTable == nil then
616 | showEntireGrid()
617 | return
618 | end
619 |
620 | local filteredButtons = filterGear(currSearchTerms)
621 | showPartialGrid(filteredButtons)
622 | end
623 |
624 | function nukeBackpack()
625 | while #buttons > 0 do
626 | table.remove(buttons)
627 | end
628 | buttons = {}
629 | while #backpackItems > 0 do
630 | table.remove(backpackItems)
631 | end
632 | backpackItems = {}
633 | local scrollingFrameChildren = grid.ScrollingFrame:GetChildren()
634 | for i = 1, #scrollingFrameChildren do
635 | scrollingFrameChildren[i]:remove()
636 | end
637 | end
638 |
639 | function getGearContextMenu()
640 | local gearContextMenu = Instance.new("Frame")
641 | gearContextMenu.Active = true
642 | gearContextMenu.Name = "UnequipContextMenu"
643 | gearContextMenu.Size = UDim2.new(0,115,0,70)
644 | gearContextMenu.Position = UDim2.new(0,-16,0,-16)
645 | gearContextMenu.BackgroundTransparency = 1
646 | gearContextMenu.Visible = false
647 |
648 | local gearContextMenuButton = Instance.new("TextButton")
649 | gearContextMenuButton.Name = "UnequipContextMenuButton"
650 | gearContextMenuButton.Text = ""
651 | gearContextMenuButton.Style = Enum.ButtonStyle.RobloxButtonDefault
652 | gearContextMenuButton.ZIndex = 8
653 | gearContextMenuButton.Size = UDim2.new(1, 0, 1, -20)
654 | gearContextMenuButton.Visible = true
655 | gearContextMenuButton.Parent = gearContextMenu
656 |
657 | local elementHeight = 12
658 |
659 | local contextMenuElements = {}
660 | local contextMenuElementsName = {"Remove Hotkey"}
661 |
662 | for i = 1, #contextMenuElementsName do
663 | local element = {}
664 | element.Type = "Button"
665 | element.Text = contextMenuElementsName[i]
666 | element.Action = i
667 | element.DoIt = UnequipGearMenuClick
668 | table.insert(contextMenuElements,element)
669 | end
670 |
671 | for i, contextElement in ipairs(contextMenuElements) do
672 | local element = contextElement
673 | if element.Type == "Button" then
674 | local button = Instance.new("TextButton")
675 | button.Name = "UnequipContextButton" .. i
676 | button.BackgroundColor3 = Color3.new(0,0,0)
677 | button.BorderSizePixel = 0
678 | button.TextXAlignment = Enum.TextXAlignment.Left
679 | button.Text = " " .. contextElement.Text
680 | button.Font = Enum.Font.Arial
681 | button.FontSize = Enum.FontSize.Size14
682 | button.Size = UDim2.new(1, 8, 0, elementHeight)
683 | button.Position = UDim2.new(0,0,0,elementHeight * i)
684 | button.TextColor3 = Color3.new(1,1,1)
685 | button.ZIndex = 9
686 | button.Parent = gearContextMenuButton
687 |
688 | if not IsTouchDevice() then
689 |
690 | button.MouseButton1Click:connect(function()
691 | if button.Active and not gearContextMenu.Parent.Active then
692 | local success, result = pcall(function() element.DoIt(element, gearContextMenu) end)
693 | browsingMenu = false
694 | gearContextMenu.Visible = false
695 | clearHighlight(button)
696 | clearPreview()
697 | end
698 | end)
699 |
700 | button.MouseEnter:connect(function()
701 | if button.Active and gearContextMenu.Parent.Active then
702 | highlight(button)
703 | end
704 | end)
705 | button.MouseLeave:connect(function()
706 | if button.Active and gearContextMenu.Parent.Active then
707 | clearHighlight(button)
708 | end
709 | end)
710 | end
711 |
712 | contextElement.Button = button
713 | contextElement.Element = button
714 | elseif element.Type == "Label" then
715 | local frame = Instance.new("Frame")
716 | frame.Name = "ContextLabel" .. i
717 | frame.BackgroundTransparency = 1
718 | frame.Size = UDim2.new(1, 8, 0, elementHeight)
719 |
720 | local label = Instance.new("TextLabel")
721 | label.Name = "Text1"
722 | label.BackgroundTransparency = 1
723 | label.BackgroundColor3 = Color3.new(1,1,1)
724 | label.BorderSizePixel = 0
725 | label.TextXAlignment = Enum.TextXAlignment.Left
726 | label.Font = Enum.Font.ArialBold
727 | label.FontSize = Enum.FontSize.Size14
728 | label.Position = UDim2.new(0.0, 0, 0, 0)
729 | label.Size = UDim2.new(0.5, 0, 1, 0)
730 | label.TextColor3 = Color3.new(1,1,1)
731 | label.ZIndex = 9
732 | label.Parent = frame
733 | element.Label1 = label
734 |
735 | if element.GetText2 then
736 | label = Instance.new("TextLabel")
737 | label.Name = "Text2"
738 | label.BackgroundTransparency = 1
739 | label.BackgroundColor3 = Color3.new(1,1,1)
740 | label.BorderSizePixel = 0
741 | label.TextXAlignment = Enum.TextXAlignment.Right
742 | label.Font = Enum.Font.Arial
743 | label.FontSize = Enum.FontSize.Size14
744 | label.Position = UDim2.new(0.5, 0, 0, 0)
745 | label.Size = UDim2.new(0.5, 0, 1, 0)
746 | label.TextColor3 = Color3.new(1,1,1)
747 | label.ZIndex = 9
748 | label.Parent = frame
749 | element.Label2 = label
750 | end
751 | frame.Parent = gearContextMenuButton
752 | element.Label = frame
753 | element.Element = frame
754 | end
755 | end
756 |
757 | gearContextMenu.ZIndex = 4
758 | gearContextMenu.MouseLeave:connect(function()
759 | browsingMenu = false
760 | gearContextMenu.Visible = false
761 | clearPreview()
762 | end)
763 | robloxLock(gearContextMenu)
764 |
765 | return gearContextMenu
766 | end
767 |
768 | function coreGuiChanged(coreGuiType,enabled)
769 | if coreGuiType == Enum.CoreGuiType.Backpack or coreGuiType == Enum.CoreGuiType.All then
770 | if not enabled then
771 | backpack.Gear.Visible = false
772 | end
773 | end
774 | end
775 |
776 |
777 | local backpackChildren = player.Backpack:GetChildren()
778 | for i = 1, #backpackChildren do
779 | addToGrid(backpackChildren[i])
780 | end
781 |
782 | ------------------------- Start Lifelong Connections -----------------------
783 |
784 |
785 | resizeEvent.Event:connect(function(absSize)
786 | if debounce then return end
787 |
788 | debounce = true
789 | wait()
790 | resize()
791 | resizeGrid()
792 | debounce = false
793 | end)
794 |
795 | currentLoadout.ChildAdded:connect(function(child) loadoutCheck(child, false) end)
796 | currentLoadout.ChildRemoved:connect(function(child) loadoutCheck(child, true) end)
797 |
798 | currentLoadout.DescendantAdded:connect(function(descendant)
799 | if not backpack.Visible and ( descendant:IsA("ImageButton") or descendant:IsA("TextButton") ) then
800 | centerGear(currentLoadout:GetChildren())
801 | end
802 | end)
803 | currentLoadout.DescendantRemoving:connect(function(descendant)
804 | if not backpack.Visible and ( descendant:IsA("ImageButton") or descendant:IsA("TextButton") ) then
805 | wait()
806 | centerGear(currentLoadout:GetChildren())
807 | end
808 | end)
809 |
810 | grid.MouseEnter:connect(function() clearPreview() end)
811 | grid.MouseLeave:connect(function() clearPreview() end)
812 |
813 | player.CharacterRemoving:connect(function()
814 | removeCharacterConnections()
815 | nukeBackpack()
816 | end)
817 | player.CharacterAdded:connect(function() setupCharacterConnections() end)
818 |
819 | player.ChildAdded:connect(function(child)
820 | if child:IsA("Backpack") then
821 | playerBackpack = child
822 | if backpackAddCon then backpackAddCon:disconnect() end
823 | backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded:connect(function(child) addToGrid(child) end)
824 | end
825 | end)
826 |
827 | swapSlot.Changed:connect(function()
828 | if not swapSlot.Value then
829 | updateGridActive()
830 | end
831 | end)
832 |
833 | local loadoutChildren = currentLoadout:GetChildren()
834 | for i = 1, #loadoutChildren do
835 | if loadoutChildren[i]:IsA("Frame") and string.find(loadoutChildren[i].Name,"Slot") then
836 | loadoutChildren[i].ChildRemoved:connect(function()
837 | updateGridActive()
838 | end)
839 | loadoutChildren[i].ChildAdded:connect(function()
840 | updateGridActive()
841 | end)
842 | end
843 | end
844 | ------------------------- End Lifelong Connections -----------------------
845 |
846 | coreGuiChanged(Enum.CoreGuiType.Backpack, Game.StarterGui:GetCoreGuiEnabled(Enum.CoreGuiType.Backpack))
847 | Game.StarterGui.CoreGuiChangedSignal:connect(coreGuiChanged)
848 |
849 | resize()
850 | resizeGrid()
851 |
852 | -- make sure any items in the loadout are accounted for in inventory
853 | local loadoutChildren = currentLoadout:GetChildren()
854 | for i = 1, #loadoutChildren do
855 | loadoutCheck(loadoutChildren[i], false)
856 | end
857 | if not backpack.Visible then centerGear(currentLoadout:GetChildren()) end
858 |
859 | -- make sure that inventory is listening to gear reparenting
860 | if characterChildAddedCon == nil and game.Players.LocalPlayer["Character"] then
861 | setupCharacterConnections()
862 | end
863 | if not backpackAddCon then
864 | backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded:connect(function(child) addToGrid(child) end)
865 | end
866 |
867 | backpackOpenEvent.Event:connect(backpackOpenHandler)
868 | backpackCloseEvent.Event:connect(backpackCloseHandler)
869 | tabClickedEvent.Event:connect(tabClickHandler)
870 | searchRequestedEvent.Event:connect(showSearchGear)
871 |
872 | recalculateScrollLoadout()
--------------------------------------------------------------------------------
/CoreScripts/BackpackScripts/BackpackManager.lua:
--------------------------------------------------------------------------------
1 | -- This script manages context switches in the backpack (Gear to Wardrobe, etc.) and player state changes. Also manages global functions across different tabs (currently only search)
2 | if game.CoreGui.Version < 7 then return end -- peace out if we aren't using the right client
3 |
4 | -- basic functions
5 | local function waitForChild(instance, name)
6 | while not instance:FindFirstChild(name) do
7 | instance.ChildAdded:wait()
8 | end
9 | return instance:FindFirstChild(name)
10 | end
11 | local function waitForProperty(instance, property)
12 | while not instance[property] do
13 | instance.Changed:wait()
14 | end
15 | end
16 |
17 | -- don't do anything if we are in an empty game
18 | waitForChild(game,"Players")
19 | if #game.Players:GetChildren() < 1 then
20 | game.Players.ChildAdded:wait()
21 | end
22 | -- make sure everything is loaded in before we do anything
23 | -- get our local player
24 | waitForProperty(game.Players,"LocalPlayer")
25 | local player = game.Players.LocalPlayer
26 |
27 |
28 |
29 | ------------------------ Locals ------------------------------
30 | local backpack = script.Parent
31 | waitForChild(backpack,"Gear")
32 |
33 | local screen = script.Parent.Parent
34 | assert(screen:IsA("ScreenGui"))
35 |
36 | waitForChild(backpack, "Tabs")
37 | waitForChild(backpack.Tabs, "CloseButton")
38 | local closeButton = backpack.Tabs.CloseButton
39 |
40 | waitForChild(backpack.Tabs, "InventoryButton")
41 | local inventoryButton = backpack.Tabs.InventoryButton
42 | if game.CoreGui.Version >= 8 then
43 | waitForChild(backpack.Tabs, "WardrobeButton")
44 | local wardrobeButton = backpack.Tabs.WardrobeButton
45 | end
46 | waitForChild(backpack.Parent,"ControlFrame")
47 | local backpackButton = waitForChild(backpack.Parent.ControlFrame,"BackpackButton")
48 | local currentTab = "gear"
49 |
50 | local searchFrame = waitForChild(backpack,"SearchFrame")
51 | waitForChild(backpack.SearchFrame,"SearchBoxFrame")
52 | local searchBox = waitForChild(backpack.SearchFrame.SearchBoxFrame,"SearchBox")
53 | local searchButton = waitForChild(backpack.SearchFrame,"SearchButton")
54 | local resetButton = waitForChild(backpack.SearchFrame,"ResetButton")
55 |
56 | local robloxGui = waitForChild(Game.CoreGui, 'RobloxGui')
57 | local currentLoadout = waitForChild(robloxGui, 'CurrentLoadout')
58 | local loadoutBackground = waitForChild(currentLoadout, 'Background')
59 |
60 | local canToggle = true
61 | local readyForNextEvent = true
62 | local backpackIsOpen = false
63 | local active = true
64 | local disabledByDeveloper = false
65 |
66 | local humanoidDiedCon = nil
67 |
68 | local backpackButtonPos
69 |
70 | local guiTweenSpeed = 0.25 -- how quickly we open/close the backpack
71 |
72 | local searchDefaultText = "Search..."
73 | local tilde = "~"
74 | local backquote = "`"
75 |
76 | local backpackSize = UDim2.new(0, 600, 0, 400)
77 |
78 | if robloxGui.AbsoluteSize.Y <= 320 then
79 | backpackSize = UDim2.new(0, 200, 0, 140)
80 | end
81 |
82 |
83 | ------------------------ End Locals ---------------------------
84 |
85 |
86 | ---------------------------------------- Public Event Setup ----------------------------------------
87 |
88 | function createPublicEvent(eventName)
89 | assert(eventName, "eventName is nil")
90 | assert(tostring(eventName),"eventName is not a string")
91 |
92 | local newEvent = Instance.new("BindableEvent")
93 | newEvent.Name = tostring(eventName)
94 | newEvent.Parent = script
95 |
96 | return newEvent
97 | end
98 |
99 | function createPublicFunction(funcName, invokeFunc)
100 | assert(funcName, "funcName is nil")
101 | assert(tostring(funcName), "funcName is not a string")
102 | assert(invokeFunc, "invokeFunc is nil")
103 | assert(type(invokeFunc) == "function", "invokeFunc should be of type 'function'")
104 |
105 | local newFunction = Instance.new("BindableFunction")
106 | newFunction.Name = tostring(funcName)
107 | newFunction.OnInvoke = invokeFunc
108 | newFunction.Parent = script
109 |
110 | return newFunction
111 | end
112 |
113 | -- Events
114 | local resizeEvent = createPublicEvent("ResizeEvent")
115 | local backpackOpenEvent = createPublicEvent("BackpackOpenEvent")
116 | local backpackCloseEvent = createPublicEvent("BackpackCloseEvent")
117 | local tabClickedEvent = createPublicEvent("TabClickedEvent")
118 | local searchRequestedEvent = createPublicEvent("SearchRequestedEvent")
119 | ---------------------------------------- End Public Event Setup ----------------------------------------
120 |
121 |
122 |
123 | --------------------------- Internal Functions ----------------------------------------
124 |
125 | function deactivateBackpack()
126 | backpack.Visible = false
127 | active = false
128 | end
129 |
130 | function activateBackpack()
131 | initHumanoidDiedConnections()
132 | active = true
133 | backpack.Visible = backpackIsOpen
134 | if backpackIsOpen then
135 | toggleBackpack()
136 | end
137 | end
138 |
139 | function initHumanoidDiedConnections()
140 | if humanoidDiedCon then
141 | humanoidDiedCon:disconnect()
142 | end
143 | waitForProperty(game.Players.LocalPlayer,"Character")
144 | waitForChild(game.Players.LocalPlayer.Character,"Humanoid")
145 | humanoidDiedCon = game.Players.LocalPlayer.Character.Humanoid.Died:connect(deactivateBackpack)
146 | end
147 |
148 | local hideBackpack = function()
149 | backpackIsOpen = false
150 | readyForNextEvent = false
151 | backpackButton.Selected = false
152 | resetSearch()
153 | backpackCloseEvent:Fire(currentTab)
154 | backpack.Tabs.Visible = false
155 | searchFrame.Visible = false
156 | backpack:TweenSizeAndPosition(UDim2.new(0, backpackSize.X.Offset,0, 0), UDim2.new(0.5, -backpackSize.X.Offset/2, 1, -85), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, guiTweenSpeed, true,
157 | function()
158 | game.GuiService:RemoveCenterDialog(backpack)
159 | backpack.Visible = false
160 | backpackButton.Selected = false
161 | end)
162 | delay(guiTweenSpeed,function()
163 | game.GuiService:RemoveCenterDialog(backpack)
164 | backpack.Visible = false
165 | backpackButton.Selected = false
166 | readyForNextEvent = true
167 | canToggle = true
168 | end)
169 | end
170 |
171 | function showBackpack()
172 | game.GuiService:AddCenterDialog(backpack, Enum.CenterDialogType.PlayerInitiatedDialog,
173 | function()
174 | backpack.Visible = true
175 | backpackButton.Selected = true
176 | end,
177 | function()
178 | backpack.Visible = false
179 | backpackButton.Selected = false
180 | end)
181 | backpack.Visible = true
182 | backpackButton.Selected = true
183 | backpack:TweenSizeAndPosition(backpackSize, UDim2.new(0.5, -backpackSize.X.Offset/2, 1, -backpackSize.Y.Offset - 88), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, guiTweenSpeed, true)
184 | delay(guiTweenSpeed,function()
185 | backpack.Tabs.Visible = false
186 | searchFrame.Visible = true
187 | backpackOpenEvent:Fire(currentTab)
188 | canToggle = true
189 | readyForNextEvent = true
190 | backpackButton.Image = 'http://www.roblox.com/asset/?id=97644093'
191 | backpackButton.Position = UDim2.new(0.5, -60, 1, -backpackSize.Y.Offset - 103)
192 | end)
193 | end
194 |
195 | function toggleBackpack()
196 | if not game.Players.LocalPlayer then return end
197 | if not game.Players.LocalPlayer["Character"] then return end
198 | if not canToggle then return end
199 | if not readyForNextEvent then return end
200 | readyForNextEvent = false
201 | canToggle = false
202 |
203 | backpackIsOpen = not backpackIsOpen
204 |
205 | if backpackIsOpen then
206 | loadoutBackground.Image = 'http://www.roblox.com/asset/?id=97623721'
207 | loadoutBackground.Position = UDim2.new(-0.03, 0, -0.17, 0)
208 | loadoutBackground.Size = UDim2.new(1.05, 0, 1.25, 0)
209 | loadoutBackground.ZIndex = 2.0
210 | loadoutBackground.Visible = true
211 | showBackpack()
212 | else
213 | backpackButton.Position = UDim2.new(0.5, -60, 1, -44)
214 | loadoutBackground.Visible = false
215 | backpackButton.Selected = false
216 | backpackButton.Image = "http://www.roblox.com/asset/?id=97617958"
217 | loadoutBackground.Image = 'http://www.roblox.com/asset/?id=96536002'
218 | loadoutBackground.Position = UDim2.new(-0.1, 0, -0.1, 0)
219 | loadoutBackground.Size = UDim2.new(1.2, 0, 1.2, 0)
220 | hideBackpack()
221 |
222 |
223 | local clChildren = currentLoadout:GetChildren()
224 | for i = 1, #clChildren do
225 | if clChildren[i] and clChildren[i]:IsA('Frame') then
226 | local frame = clChildren[i]
227 | if #frame:GetChildren() > 0 then
228 | backpackButton.Position = UDim2.new(0.5, -60, 1, -108)
229 | backpackButton.Visible = true
230 | loadoutBackground.Visible = true
231 | if frame:GetChildren()[1]:IsA('ImageButton') then
232 | local imgButton = frame:GetChildren()[1]
233 | imgButton.Active = true
234 | imgButton.Draggable = false
235 | end
236 | end
237 | end
238 | end
239 |
240 | end
241 | end
242 |
243 | function closeBackpack()
244 | if backpackIsOpen then
245 | toggleBackpack()
246 | end
247 | end
248 |
249 | function setSelected(tab)
250 | assert(tab)
251 | assert(tab:IsA("TextButton"))
252 |
253 | tab.BackgroundColor3 = Color3.new(1,1,1)
254 | tab.TextColor3 = Color3.new(0,0,0)
255 | tab.Selected = true
256 | tab.ZIndex = 3
257 | end
258 |
259 | function setUnselected(tab)
260 | assert(tab)
261 | assert(tab:IsA("TextButton"))
262 |
263 | tab.BackgroundColor3 = Color3.new(0,0,0)
264 | tab.TextColor3 = Color3.new(1,1,1)
265 | tab.Selected = false
266 | tab.ZIndex = 1
267 | end
268 |
269 | function updateTabGui(selectedTab)
270 | assert(selectedTab)
271 |
272 | if selectedTab == "gear" then
273 | setSelected(inventoryButton)
274 | setUnselected(wardrobeButton)
275 | elseif selectedTab == "wardrobe" then
276 | setSelected(wardrobeButton)
277 | setUnselected(inventoryButton)
278 | end
279 | end
280 |
281 | function mouseLeaveTab(button)
282 | assert(button)
283 | assert(button:IsA("TextButton"))
284 |
285 | if button.Selected then return end
286 |
287 | button.BackgroundColor3 = Color3.new(0,0,0)
288 | end
289 |
290 | function mouseOverTab(button)
291 | assert(button)
292 | assert(button:IsA("TextButton"))
293 |
294 | if button.Selected then return end
295 |
296 | button.BackgroundColor3 = Color3.new(39/255,39/255,39/255)
297 | end
298 |
299 | function newTabClicked(tabName)
300 | assert(tabName)
301 | tabName = string.lower(tabName)
302 | currentTab = tabName
303 |
304 | updateTabGui(tabName)
305 | tabClickedEvent:Fire(tabName)
306 | resetSearch()
307 | end
308 |
309 | function trim(s)
310 | return (s:gsub("^%s*(.-)%s*$", "%1"))
311 | end
312 |
313 | function splitByWhitespace(text)
314 | if type(text) ~= "string" then return nil end
315 |
316 | local terms = {}
317 | for token in string.gmatch(text, "[^%s]+") do
318 | if string.len(token) > 0 then
319 | table.insert(terms,token)
320 | end
321 | end
322 | return terms
323 | end
324 |
325 | function resetSearchBoxGui()
326 | resetButton.Visible = false
327 | searchBox.Text = searchDefaultText
328 | end
329 |
330 | function doSearch()
331 | local searchText = searchBox.Text
332 | if searchText == "" then
333 | resetSearch()
334 | return
335 | end
336 | searchText = trim(searchText)
337 | resetButton.Visible = true
338 | termTable = splitByWhitespace(searchText)
339 | searchRequestedEvent:Fire(searchText) -- todo: replace this with termtable when table passing is possible
340 | end
341 |
342 | function resetSearch()
343 | resetSearchBoxGui()
344 | searchRequestedEvent:Fire()
345 | end
346 |
347 | local backpackReady = function()
348 | readyForNextEvent = true
349 | end
350 |
351 | function coreGuiChanged(coreGuiType,enabled)
352 | if coreGuiType == Enum.CoreGuiType.Backpack or coreGuiType == Enum.CoreGuiType.All then
353 | active = enabled
354 | disabledByDeveloper = not enabled
355 |
356 | if disabledByDeveloper then
357 | game:GetService("GuiService"):RemoveKey(tilde)
358 | game:GetService("GuiService"):RemoveKey(backquote)
359 | else
360 | game:GetService("GuiService"):AddKey(tilde)
361 | game:GetService("GuiService"):AddKey(backquote)
362 | end
363 |
364 | resetSearch()
365 | searchFrame.Visible = enabled and backpackIsOpen
366 |
367 | currentLoadout.Visible = enabled
368 | backpack.Visible = enabled
369 | backpackButton.Visible = enabled
370 | end
371 | end
372 |
373 | --------------------------- End Internal Functions -------------------------------------
374 |
375 |
376 | ------------------------------ Public Functions Setup -------------------------------------
377 | createPublicFunction("CloseBackpack", hideBackpack)
378 | createPublicFunction("BackpackReady", backpackReady)
379 | ------------------------------ End Public Functions Setup ---------------------------------
380 |
381 |
382 | ------------------------ Connections/Script Main -------------------------------------------
383 |
384 | coreGuiChanged(Enum.CoreGuiType.Backpack, Game.StarterGui:GetCoreGuiEnabled(Enum.CoreGuiType.Backpack))
385 | Game.StarterGui.CoreGuiChangedSignal:connect(coreGuiChanged)
386 |
387 | inventoryButton.MouseButton1Click:connect(function() newTabClicked("gear") end)
388 | inventoryButton.MouseEnter:connect(function() mouseOverTab(inventoryButton) end)
389 | inventoryButton.MouseLeave:connect(function() mouseLeaveTab(inventoryButton) end)
390 |
391 | if game.CoreGui.Version >= 8 then
392 | wardrobeButton.MouseButton1Click:connect(function() newTabClicked("wardrobe") end)
393 | wardrobeButton.MouseEnter:connect(function() mouseOverTab(wardrobeButton) end)
394 | wardrobeButton.MouseLeave:connect(function() mouseLeaveTab(wardrobeButton) end)
395 | end
396 |
397 | closeButton.MouseButton1Click:connect(closeBackpack)
398 |
399 | screen.Changed:connect(function(prop)
400 | if prop == "AbsoluteSize" then
401 | resizeEvent:Fire(screen.AbsoluteSize)
402 | end
403 | end)
404 |
405 | -- GuiService key setup
406 | game:GetService("GuiService"):AddKey(tilde)
407 | game:GetService("GuiService"):AddKey(backquote)
408 | game:GetService("GuiService").KeyPressed:connect(function(key)
409 | if not active or disabledByDeveloper then return end
410 | if key == tilde or key == backquote then
411 | toggleBackpack()
412 | end
413 | end)
414 | backpackButton.MouseButton1Click:connect(function()
415 | if not active or disabledByDeveloper then return end
416 | toggleBackpack()
417 | end)
418 |
419 | if game.Players.LocalPlayer["Character"] then
420 | activateBackpack()
421 | end
422 |
423 | game.Players.LocalPlayer.CharacterAdded:connect(activateBackpack)
424 |
425 | -- search functions
426 | searchBox.FocusLost:connect(function(enterPressed)
427 | if enterPressed or searchBox.Text ~= "" then
428 | doSearch()
429 | elseif searchBox.Text == "" then
430 | resetSearch()
431 | end
432 | end)
433 | searchButton.MouseButton1Click:connect(doSearch)
434 | resetButton.MouseButton1Click:connect(resetSearch)
435 |
436 | if searchFrame and robloxGui.AbsoluteSize.Y <= 320 then
437 | searchFrame.RobloxLocked = false
438 | searchFrame:Destroy()
439 | end
--------------------------------------------------------------------------------
/CoreScripts/BackpackScripts/BackpackResizer.lua:
--------------------------------------------------------------------------------
1 | if game.CoreGui.Version < 3 then return end -- peace out if we aren't using the right client
2 |
3 | -- A couple of necessary functions
4 | local function waitForChild(instance, name)
5 | while not instance:FindFirstChild(name) do
6 | instance.ChildAdded:wait()
7 | end
8 | end
9 | local function waitForProperty(instance, property)
10 | while not instance[property] do
11 | instance.Changed:wait()
12 | end
13 | end
14 |
15 | waitForChild(game,"Players")
16 | waitForProperty(game.Players,"LocalPlayer")
17 | local player = game.Players.LocalPlayer
18 |
19 | local RbxGui,msg = LoadLibrary("RbxGui")
20 | if not RbxGui then print("could not find RbxGui!") return end
21 |
22 | --- Begin Locals
23 | waitForChild(game,"Players")
24 |
25 | -- don't do anything if we are in an empty game
26 | if #game.Players:GetChildren() < 1 then
27 | game.Players.ChildAdded:wait()
28 | end
29 |
30 | local tilde = "~"
31 | local backquote = "`"
32 | game:GetService("GuiService"):AddKey(tilde) -- register our keys
33 | game:GetService("GuiService"):AddKey(backquote)
34 |
35 | local player = game.Players.LocalPlayer
36 |
37 | local backpack = script.Parent
38 | local screen = script.Parent.Parent
39 | local closeButton = backpack.Tabs.CloseButton
40 |
41 | local openCloseDebounce = false
42 |
43 | local backpackItems = {}
44 |
45 | local buttons = {}
46 |
47 | local debounce = false
48 |
49 | local guiTweenSpeed = 1
50 |
51 | local backpackOldStateVisible = false
52 | local browsingMenu = false
53 |
54 | local mouseEnterCons = {}
55 | local mouseClickCons = {}
56 |
57 | local characterChildAddedCon = nil
58 | local characterChildRemovedCon = nil
59 | local backpackAddCon = nil
60 | local humanoidDiedCon = nil
61 | local backpackButtonClickCon = nil
62 | local guiServiceKeyPressCon = nil
63 |
64 | waitForChild(player,"Backpack")
65 | local playerBackpack = player.Backpack
66 |
67 | waitForChild(backpack,"Gear")
68 | waitForChild(backpack.Gear,"GearPreview")
69 | local gearPreview = backpack.Gear.GearPreview
70 |
71 | waitForChild(backpack.Gear,"GearGridScrollingArea")
72 | local scroller = backpack.Gear.GearGridScrollingArea
73 |
74 | waitForChild(backpack.Parent,"CurrentLoadout")
75 | local currentLoadout = backpack.Parent.CurrentLoadout
76 |
77 | waitForChild(backpack.Parent,"ControlFrame")
78 | waitForChild(backpack.Parent.ControlFrame,"BackpackButton")
79 | local backpackButton = backpack.Parent.ControlFrame.BackpackButton
80 |
81 | waitForChild(backpack.Gear,"GearGrid")
82 | waitForChild(backpack.Gear.GearGrid,"GearButton")
83 | local gearButton = backpack.Gear.GearGrid.GearButton
84 | local grid = backpack.Gear.GearGrid
85 |
86 | waitForChild(backpack.Gear.GearGrid,"SearchFrame")
87 | waitForChild(backpack.Gear.GearGrid.SearchFrame,"SearchBoxFrame")
88 | waitForChild(backpack.Gear.GearGrid.SearchFrame.SearchBoxFrame,"SearchBox")
89 | local searchBox = backpack.Gear.GearGrid.SearchFrame.SearchBoxFrame.SearchBox
90 |
91 | waitForChild(backpack.Gear.GearGrid.SearchFrame,"SearchButton")
92 | local searchButton = backpack.Gear.GearGrid.SearchFrame.SearchButton
93 |
94 | waitForChild(backpack.Gear.GearGrid,"ResetFrame")
95 | local resetFrame = backpack.Gear.GearGrid.ResetFrame
96 |
97 | waitForChild(backpack.Gear.GearGrid.ResetFrame,"ResetButtonBorder")
98 | local resetButton = backpack.Gear.GearGrid.ResetFrame.ResetButtonBorder
99 |
100 | waitForChild(script.Parent,"SwapSlot")
101 | local swapSlot = script.Parent.SwapSlot
102 |
103 |
104 | -- creating scroll bar early as to make sure items get placed correctly
105 | local scrollFrame, scrollUp, scrollDown, recalculateScroll = RbxGui.CreateScrollingFrame(nil, "grid", Vector2.new(4, 4))
106 |
107 | scrollFrame.Position = UDim2.new(0,0,0,30)
108 | scrollFrame.Size = UDim2.new(1,0,1,-30)
109 | scrollFrame.Parent = backpack.Gear.GearGrid
110 |
111 | local scrollBar = Instance.new("Frame")
112 | scrollBar.Name = "ScrollBar"
113 | scrollBar.BackgroundTransparency = 0.9
114 | scrollBar.BackgroundColor3 = Color3.new(1,1,1)
115 | scrollBar.BorderSizePixel = 0
116 | scrollBar.Size = UDim2.new(0, 17, 1, -36)
117 | scrollBar.Position = UDim2.new(0,0,0,18)
118 | scrollBar.Parent = scroller
119 |
120 | scrollDown.Position = UDim2.new(0,0,1,-17)
121 |
122 | scrollUp.Parent = scroller
123 | scrollDown.Parent = scroller
124 |
125 | local scrollFrameLoadout, scrollUpLoadout, scrollDownLoadout, recalculateScrollLoadout = RbxGui.CreateScrollingFrame()
126 |
127 | scrollFrameLoadout.Position = UDim2.new(0,0,0,0)
128 | scrollFrameLoadout.Size = UDim2.new(1,0,1,0)
129 | scrollFrameLoadout.Parent = backpack.Gear.GearLoadouts.LoadoutsList
130 |
131 | local LoadoutButton = Instance.new("TextButton")
132 | LoadoutButton.RobloxLocked = true
133 | LoadoutButton.Name = "LoadoutButton"
134 | LoadoutButton.Font = Enum.Font.ArialBold
135 | LoadoutButton.FontSize = Enum.FontSize.Size14
136 | LoadoutButton.Position = UDim2.new(0,0,0,0)
137 | LoadoutButton.Size = UDim2.new(1,0,0,32)
138 | LoadoutButton.Style = Enum.ButtonStyle.RobloxButton
139 | LoadoutButton.Text = "Loadout #1"
140 | LoadoutButton.TextColor3 = Color3.new(1,1,1)
141 | LoadoutButton.Parent = scrollFrameLoadout
142 |
143 | local LoadoutButtonTwo = LoadoutButton:clone()
144 | LoadoutButtonTwo.Text = "Loadout #2"
145 | LoadoutButtonTwo.Parent = scrollFrameLoadout
146 |
147 | local LoadoutButtonThree = LoadoutButton:clone()
148 | LoadoutButtonThree.Text = "Loadout #3"
149 | LoadoutButtonThree.Parent = scrollFrameLoadout
150 |
151 | local LoadoutButtonFour = LoadoutButton:clone()
152 | LoadoutButtonFour.Text = "Loadout #4"
153 | LoadoutButtonFour.Parent = scrollFrameLoadout
154 |
155 | local scrollBarLoadout = Instance.new("Frame")
156 | scrollBarLoadout.Name = "ScrollBarLoadout"
157 | scrollBarLoadout.BackgroundTransparency = 0.9
158 | scrollBarLoadout.BackgroundColor3 = Color3.new(1,1,1)
159 | scrollBarLoadout.BorderSizePixel = 0
160 | scrollBarLoadout.Size = UDim2.new(0, 17, 1, -36)
161 | scrollBarLoadout.Position = UDim2.new(0,0,0,18)
162 | scrollBarLoadout.Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea
163 |
164 | scrollDownLoadout.Position = UDim2.new(0,0,1,-17)
165 |
166 | scrollUpLoadout.Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea
167 | scrollDownLoadout.Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea
168 |
169 |
170 | -- Begin Functions
171 | function removeFromMap(map,object)
172 | for i = 1, #map do
173 | if map[i] == object then
174 | table.remove(map,i)
175 | break
176 | end
177 | end
178 | end
179 |
180 | function robloxLock(instance)
181 | instance.RobloxLocked = true
182 | children = instance:GetChildren()
183 | if children then
184 | for i, child in ipairs(children) do
185 | robloxLock(child)
186 | end
187 | end
188 | end
189 |
190 | function resize()
191 | local size = 0
192 | if gearPreview.AbsoluteSize.Y > gearPreview.AbsoluteSize.X then
193 | size = gearPreview.AbsoluteSize.X * 0.75
194 | else
195 | size = gearPreview.AbsoluteSize.Y * 0.75
196 | end
197 |
198 | gearPreview.GearImage.Size = UDim2.new(0,size,0,size)
199 | gearPreview.GearImage.Position = UDim2.new(0,gearPreview.AbsoluteSize.X/2 - size/2,0.75,-size)
200 |
201 | resizeGrid()
202 | end
203 |
204 | function addToGrid(child)
205 | if not child:IsA("Tool") then
206 | if not child:IsA("HopperBin") then
207 | return
208 | end
209 | end
210 | if child:FindFirstChild("RobloxBuildTool") then return end
211 |
212 | for i,v in pairs(backpackItems) do -- check to see if we already have this gear registered
213 | if v == child then return end
214 | end
215 |
216 | table.insert(backpackItems,child)
217 |
218 | local changeCon = child.Changed:connect(function(prop)
219 | if prop == "Name" then
220 | if buttons[child] then
221 | if buttons[child].Image == "" then
222 | buttons[child].GearText.Text = child.Name
223 | end
224 | end
225 | end
226 | end)
227 | local ancestryCon = nil
228 | ancestryCon = child.AncestryChanged:connect(function(theChild,theParent)
229 | local thisObject = nil
230 | for k,v in pairs(backpackItems) do
231 | if v == child then
232 | thisObject = v
233 | break
234 | end
235 | end
236 |
237 | waitForProperty(player,"Character")
238 | waitForChild(player,"Backpack")
239 | if (child.Parent ~= player.Backpack and child.Parent ~= player.Character) then
240 | if ancestryCon then ancestryCon:disconnect() end
241 | if changeCon then changeCon:disconnect() end
242 |
243 | for k,v in pairs(backpackItems) do
244 | if v == thisObject then
245 | if mouseEnterCons[buttons[v]] then mouseEnterCons[buttons[v]]:disconnect() end
246 | if mouseClickCons[buttons[v]] then mouseClickCons[buttons[v]]:disconnect() end
247 | buttons[v].Parent = nil
248 | buttons[v] = nil
249 | break
250 | end
251 | end
252 |
253 | removeFromMap(backpackItems,thisObject)
254 |
255 | resizeGrid()
256 | else
257 | resizeGrid()
258 | end
259 | updateGridActive()
260 | end)
261 | resizeGrid()
262 | end
263 |
264 | function buttonClick(button)
265 | if button:FindFirstChild("UnequipContextMenu") and not button.Active then
266 | button.UnequipContextMenu.Visible = true
267 | browsingMenu = true
268 | end
269 | end
270 |
271 | function previewGear(button)
272 | if not browsingMenu then
273 | gearPreview.GearImage.Image = button.Image
274 | gearPreview.GearStats.GearName.Text = button.GearReference.Value.Name
275 | end
276 | end
277 |
278 | function findEmptySlot()
279 | local smallestNum = nil
280 | local loadout = currentLoadout:GetChildren()
281 | for i = 1, #loadout do
282 | if loadout[i]:IsA("Frame") and #loadout[i]:GetChildren() <= 0 then
283 | local frameNum = tonumber(string.sub(loadout[i].Name,5))
284 | if frameNum == 0 then frameNum = 10 end
285 | if not smallestNum or (smallestNum > frameNum) then
286 | smallestNum = frameNum
287 | end
288 | end
289 | end
290 | if smallestNum == 10 then smallestNum = 0 end
291 | return smallestNum
292 | end
293 |
294 | function checkForSwap(button,x,y)
295 | local loadoutChildren = currentLoadout:GetChildren()
296 | for i = 1, #loadoutChildren do
297 | if loadoutChildren[i]:IsA("Frame") and string.find(loadoutChildren[i].Name,"Slot") then
298 | if x >= loadoutChildren[i].AbsolutePosition.x and x <= (loadoutChildren[i].AbsolutePosition.x + loadoutChildren[i].AbsoluteSize.x) then
299 | if y >= loadoutChildren[i].AbsolutePosition.y and y <= (loadoutChildren[i].AbsolutePosition.y + loadoutChildren[i].AbsoluteSize.y) then
300 | local slot = tonumber(string.sub(loadoutChildren[i].Name,5))
301 | swapGearSlot(slot,button)
302 | return true
303 | end
304 | end
305 | end
306 | end
307 | return false
308 | end
309 |
310 | function resizeGrid()
311 | for k,v in pairs(backpackItems) do
312 | if not v:FindFirstChild("RobloxBuildTool") then
313 | if not buttons[v] then
314 | local buttonClone = gearButton:clone()
315 | buttonClone.Parent = grid.ScrollingFrame
316 | buttonClone.Visible = true
317 | buttonClone.Image = v.TextureId
318 | if buttonClone.Image == "" then
319 | buttonClone.GearText.Text = v.Name
320 | end
321 |
322 | buttonClone.GearReference.Value = v
323 | buttonClone.Draggable = true
324 | buttons[v] = buttonClone
325 |
326 | local unequipMenu = getGearContextMenu()
327 |
328 | unequipMenu.Visible = false
329 | unequipMenu.Parent = buttonClone
330 |
331 | local beginPos = nil
332 | buttonClone.DragBegin:connect(function(value)
333 | buttonClone.ZIndex = 9
334 | beginPos = value
335 | end)
336 | buttonClone.DragStopped:connect(function(x,y)
337 | buttonClone.ZIndex = 1
338 | if beginPos ~= buttonClone.Position then
339 | if not checkForSwap(buttonClone,x,y) then
340 | buttonClone:TweenPosition(beginPos,Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.5, true)
341 | buttonClone.Draggable = false
342 | delay(0.5,function()
343 | buttonClone.Draggable = true
344 | end)
345 | else
346 | buttonClone.Position = beginPos
347 | end
348 | end
349 | end)
350 | local clickTime = tick()
351 | mouseEnterCons[buttonClone] = buttonClone.MouseEnter:connect(function() previewGear(buttonClone) end)
352 | mouseClickCons[buttonClone] = buttonClone.MouseButton1Click:connect(function()
353 | local newClickTime = tick()
354 | if buttonClone.Active and (newClickTime - clickTime) < 0.5 then
355 | local slot = findEmptySlot()
356 | if slot then
357 | buttonClone.ZIndex = 1
358 | swapGearSlot(slot,buttonClone)
359 | end
360 | else
361 | buttonClick(buttonClone)
362 | end
363 | clickTime = newClickTime
364 | end)
365 | end
366 | end
367 | end
368 | recalculateScroll()
369 | end
370 |
371 | function showPartialGrid(subset)
372 |
373 | resetFrame.Visible = true
374 |
375 | for k,v in pairs(buttons) do
376 | v.Parent = nil
377 | end
378 | for k,v in pairs(subset) do
379 | v.Parent = grid.ScrollingFrame
380 | end
381 | recalculateScroll()
382 | end
383 |
384 | function showEntireGrid()
385 | resetFrame.Visible = false
386 |
387 | for k,v in pairs(buttons) do
388 | v.Parent = grid.ScrollingFrame
389 | end
390 | recalculateScroll()
391 | end
392 |
393 | function inLoadout(gear)
394 | local children = currentLoadout:GetChildren()
395 | for i = 1, #children do
396 | if children[i]:IsA("Frame") then
397 | local button = children[i]:GetChildren()
398 | if #button > 0 then
399 | if button[1].GearReference.Value and button[1].GearReference.Value == gear then
400 | return true
401 | end
402 | end
403 | end
404 | end
405 | return false
406 | end
407 |
408 | function updateGridActive()
409 | for k,v in pairs(backpackItems) do
410 | if buttons[v] then
411 | local gear = nil
412 | local gearRef = buttons[v]:FindFirstChild("GearReference")
413 |
414 | if gearRef then gear = gearRef.Value end
415 |
416 | if not gear then
417 | buttons[v].Active = false
418 | elseif inLoadout(gear) then
419 | buttons[v].Active = false
420 | else
421 | buttons[v].Active = true
422 | end
423 | end
424 | end
425 | end
426 |
427 | function centerGear(loadoutChildren)
428 | local gearButtons = {}
429 | local lastSlotAdd = nil
430 | for i = 1, #loadoutChildren do
431 | if loadoutChildren[i]:IsA("Frame") and #loadoutChildren[i]:GetChildren() > 0 then
432 | if loadoutChildren[i].Name == "Slot0" then
433 | lastSlotAdd = loadoutChildren[i]
434 | else
435 | table.insert(gearButtons, loadoutChildren[i])
436 | end
437 | end
438 | end
439 | if lastSlotAdd then table.insert(gearButtons,lastSlotAdd) end
440 |
441 | local startPos = ( 1 - (#gearButtons * 0.1) ) / 2
442 | for i = 1, #gearButtons do
443 | gearButtons[i]:TweenPosition(UDim2.new(startPos + ((i - 1) * 0.1),0,0,0), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.25, true)
444 | end
445 | end
446 |
447 | function spreadOutGear(loadoutChildren)
448 | for i = 1, #loadoutChildren do
449 | if loadoutChildren[i]:IsA("Frame") then
450 | local slot = tonumber(string.sub(loadoutChildren[i].Name,5))
451 | if slot == 0 then slot = 10 end
452 | loadoutChildren[i]:TweenPosition(UDim2.new((slot - 1)/10,0,0,0), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.25, true)
453 | end
454 | end
455 | end
456 |
457 | function openCloseBackpack(close)
458 | if openCloseDebounce then return end
459 | openCloseDebounce = true
460 |
461 | local visible = not backpack.Visible
462 | if visible and not close then
463 | updateGridActive()
464 | local centerDialogSupported, msg = pcall(function() game.GuiService:AddCenterDialog(backpack, Enum.CenterDialogType.PlayerInitiatedDialog,
465 | function()
466 | backpack.Visible = true
467 | loadoutChildren = currentLoadout:GetChildren()
468 | for i = 1, #loadoutChildren do
469 | if loadoutChildren[i]:IsA("Frame") then
470 | loadoutChildren[i].BackgroundTransparency = 0.5
471 | end
472 | end
473 | spreadOutGear(loadoutChildren)
474 | end,
475 | function()
476 | backpack.Visible = false
477 | end)
478 | end)
479 | backpackButton.Selected = true
480 | backpack:TweenSizeAndPosition(UDim2.new(0.55, 0, 0.6, 0),UDim2.new(0.225, 0, 0.2, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, guiTweenSpeed/2, true)
481 | delay(guiTweenSpeed/2 + 0.01,
482 | function()
483 | local children = backpack:GetChildren()
484 | for i = 1, #children do
485 | if children[i]:IsA("Frame") then
486 | children[i].Visible = true
487 | end
488 | end
489 | resizeGrid()
490 | resize()
491 | openCloseDebounce = false
492 | end)
493 | else
494 | backpackButton.Selected = false
495 | local children = backpack:GetChildren()
496 | for i = 1, #children do
497 | if children[i]:IsA("Frame") then
498 | children[i].Visible = false
499 | end
500 | end
501 | loadoutChildren = currentLoadout:GetChildren()
502 | for i = 1, #loadoutChildren do
503 | if loadoutChildren[i]:IsA("Frame") then
504 | loadoutChildren[i].BackgroundTransparency = 1
505 | end
506 | end
507 | centerGear(loadoutChildren)
508 |
509 | backpack:TweenSizeAndPosition(UDim2.new(0,0,0,0),UDim2.new(0.5,0,0.5,0), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, guiTweenSpeed/2, true)
510 | delay(guiTweenSpeed/2 + 0.01,
511 | function()
512 | backpack.Visible = visible
513 | resizeGrid()
514 | resize()
515 | pcall(function() game.GuiService:RemoveCenterDialog(backpack) end)
516 | openCloseDebounce = false
517 | end)
518 | end
519 | end
520 |
521 | function loadoutCheck(child, selectState)
522 | if not child:IsA("ImageButton") then return end
523 | for k,v in pairs(backpackItems) do
524 | if buttons[v] then
525 | if child:FindFirstChild("GearReference") and buttons[v]:FindFirstChild("GearReference") then
526 | if buttons[v].GearReference.Value == child.GearReference.Value then
527 | buttons[v].Active = selectState
528 | break
529 | end
530 | end
531 | end
532 | end
533 | end
534 |
535 | function clearPreview()
536 | gearPreview.GearImage.Image = ""
537 | gearPreview.GearStats.GearName.Text = ""
538 | end
539 |
540 | function removeAllEquippedGear(physGear)
541 | local stuff = player.Character:GetChildren()
542 | for i = 1, #stuff do
543 | if ( stuff[i]:IsA("Tool") or stuff[i]:IsA("HopperBin") ) and stuff[i] ~= physGear then
544 | stuff[i].Parent = playerBackpack
545 | end
546 | end
547 | end
548 |
549 | function equipGear(physGear)
550 | removeAllEquippedGear(physGear)
551 | physGear.Parent = player.Character
552 | updateGridActive()
553 | end
554 |
555 | function unequipGear(physGear)
556 | physGear.Parent = playerBackpack
557 | updateGridActive()
558 | end
559 |
560 | function highlight(button)
561 | button.TextColor3 = Color3.new(0,0,0)
562 | button.BackgroundColor3 = Color3.new(0.8,0.8,0.8)
563 | end
564 | function clearHighlight(button)
565 | button.TextColor3 = Color3.new(1,1,1)
566 | button.BackgroundColor3 = Color3.new(0,0,0)
567 | end
568 |
569 | function swapGearSlot(slot,gearButton)
570 | if not swapSlot.Value then -- signal loadout to swap a gear out
571 | swapSlot.Slot.Value = slot
572 | swapSlot.GearButton.Value = gearButton
573 | swapSlot.Value = true
574 | updateGridActive()
575 | end
576 | end
577 |
578 |
579 | local UnequipGearMenuClick = function(element, menu)
580 | if type(element.Action) ~= "number" then return end
581 | local num = element.Action
582 | if num == 1 then -- remove from loadout
583 | unequipGear(menu.Parent.GearReference.Value)
584 | local inventoryButton = menu.Parent
585 | local gearToUnequip = inventoryButton.GearReference.Value
586 | local loadoutChildren = currentLoadout:GetChildren()
587 | local slot = -1
588 | for i = 1, #loadoutChildren do
589 | if loadoutChildren[i]:IsA("Frame") then
590 | local button = loadoutChildren[i]:GetChildren()
591 | if button[1] and button[1].GearReference.Value == gearToUnequip then
592 | slot = button[1].SlotNumber.Text
593 | break
594 | end
595 | end
596 | end
597 | swapGearSlot(slot,nil)
598 | end
599 | end
600 |
601 | -- these next two functions are used to stop any use of backpack while the player is dead (can cause issues)
602 | function activateBackpack()
603 | backpack.Visible = backpackOldStateVisible
604 |
605 | loadoutChildren = currentLoadout:GetChildren()
606 | for i = 1, #loadoutChildren do
607 | if loadoutChildren[i]:IsA("Frame") then
608 | loadoutChildren[i].BackgroundTransparency = 1
609 | end
610 | end
611 |
612 | backpackButtonClickCon = backpackButton.MouseButton1Click:connect(function() openCloseBackpack() end)
613 | guiServiceKeyPressCon = game:GetService("GuiService").KeyPressed:connect(function(key)
614 | if key == tilde or key == backquote then
615 | openCloseBackpack()
616 | end
617 | end)
618 | end
619 | function deactivateBackpack()
620 | if backpackButtonClickCon then backpackButtonClickCon:disconnect() end
621 | if guiServiceKeyPressCon then guiServiceKeyPressCon:disconnect() end
622 |
623 | backpackOldStateVisible = backpack.Visible
624 | backpack.Visible = false
625 | openCloseBackpack(true)
626 | end
627 |
628 | function setupCharacterConnections()
629 |
630 | if backpackAddCon then backpackAddCon:disconnect() end
631 | backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded:connect(function(child) addToGrid(child) end)
632 |
633 | -- make sure we get all the children
634 | local backpackChildren = game.Players.LocalPlayer.Backpack:GetChildren()
635 | for i = 1, #backpackChildren do
636 | addToGrid(backpackChildren[i])
637 | end
638 |
639 | if characterChildAddedCon then characterChildAddedCon:disconnect() end
640 | characterChildAddedCon =
641 | game.Players.LocalPlayer.Character.ChildAdded:connect(function(child)
642 | addToGrid(child)
643 | updateGridActive()
644 | end)
645 |
646 | if characterChildRemovedCon then characterChildRemovedCon:disconnect() end
647 | characterChildRemovedCon =
648 | game.Players.LocalPlayer.Character.ChildRemoved:connect(function(child)
649 | updateGridActive()
650 | end)
651 |
652 |
653 | if humanoidDiedCon then humanoidDiedCon:disconnect() end
654 | local localPlayer = game.Players.LocalPlayer
655 | waitForProperty(localPlayer,"Character")
656 | waitForChild(localPlayer.Character,"Humanoid")
657 | humanoidDiedCon = game.Players.LocalPlayer.Character.Humanoid.Died:connect(function() deactivateBackpack() end)
658 |
659 | activateBackpack()
660 |
661 | wait()
662 | centerGear(currentLoadout:GetChildren())
663 | end
664 |
665 | function removeCharacterConnections()
666 | if characterChildAddedCon then characterChildAddedCon:disconnect() end
667 | if characterChildRemovedCon then characterChildRemovedCon:disconnect() end
668 | if backpackAddCon then backpackAddCon:disconnect() end
669 | end
670 |
671 | function trim(s)
672 | return (s:gsub("^%s*(.-)%s*$", "%1"))
673 | end
674 |
675 | function splitByWhiteSpace(text)
676 | if type(text) ~= "string" then return nil end
677 |
678 | local terms = {}
679 | for token in string.gmatch(text, "[^%s]+") do
680 | if string.len(token) > 2 then
681 | table.insert(terms,token)
682 | end
683 | end
684 | return terms
685 | end
686 |
687 | function filterGear(searchTerm)
688 | string.lower(searchTerm)
689 | searchTerm = trim(searchTerm)
690 | if string.len(searchTerm) < 2 then return nil end
691 | local terms = splitByWhiteSpace(searchTerm)
692 |
693 | local filteredGear = {}
694 | for k,v in pairs(backpackItems) do
695 | if buttons[v] then
696 | local gearString = string.lower(buttons[v].GearReference.Value.Name)
697 | gearString = trim(gearString)
698 | for i = 1, #terms do
699 | if string.match(gearString,terms[i]) then
700 | table.insert(filteredGear,buttons[v])
701 | break
702 | end
703 | end
704 | end
705 | end
706 |
707 | return filteredGear
708 | end
709 |
710 |
711 | function showSearchGear()
712 | local searchText = searchBox.Text
713 | searchBox.Text = "Search..."
714 | local filteredButtons = filterGear(searchText)
715 | if filteredButtons and #filteredButtons > 0 then
716 | showPartialGrid(filteredButtons)
717 | else
718 | showEntireGrid()
719 | end
720 | end
721 |
722 | function nukeBackpack()
723 | while #buttons > 0 do
724 | table.remove(buttons)
725 | end
726 | buttons = {}
727 | while #backpackItems > 0 do
728 | table.remove(backpackItems)
729 | end
730 | backpackItems = {}
731 | local scrollingFrameChildren = grid.ScrollingFrame:GetChildren()
732 | for i = 1, #scrollingFrameChildren do
733 | scrollingFrameChildren[i]:remove()
734 | end
735 | end
736 |
737 | function getGearContextMenu()
738 | local gearContextMenu = Instance.new("Frame")
739 | gearContextMenu.Active = true
740 | gearContextMenu.Name = "UnequipContextMenu"
741 | gearContextMenu.Size = UDim2.new(0,115,0,70)
742 | gearContextMenu.Position = UDim2.new(0,-16,0,-16)
743 | gearContextMenu.BackgroundTransparency = 1
744 | gearContextMenu.Visible = false
745 |
746 | local gearContextMenuButton = Instance.new("TextButton")
747 | gearContextMenuButton.Name = "UnequipContextMenuButton"
748 | gearContextMenuButton.Text = ""
749 | gearContextMenuButton.Style = Enum.ButtonStyle.RobloxButtonDefault
750 | gearContextMenuButton.ZIndex = 8
751 | gearContextMenuButton.Size = UDim2.new(1, 0, 1, -20)
752 | gearContextMenuButton.Visible = true
753 | gearContextMenuButton.Parent = gearContextMenu
754 |
755 | local elementHeight = 12
756 |
757 | local contextMenuElements = {}
758 | local contextMenuElementsName = {"Remove Hotkey"}
759 |
760 | for i = 1, #contextMenuElementsName do
761 | local element = {}
762 | element.Type = "Button"
763 | element.Text = contextMenuElementsName[i]
764 | element.Action = i
765 | element.DoIt = UnequipGearMenuClick
766 | table.insert(contextMenuElements,element)
767 | end
768 |
769 | for i, contextElement in ipairs(contextMenuElements) do
770 | local element = contextElement
771 | if element.Type == "Button" then
772 | local button = Instance.new("TextButton")
773 | button.Name = "UnequipContextButton" .. i
774 | button.BackgroundColor3 = Color3.new(0,0,0)
775 | button.BorderSizePixel = 0
776 | button.TextXAlignment = Enum.TextXAlignment.Left
777 | button.Text = " " .. contextElement.Text
778 | button.Font = Enum.Font.Arial
779 | button.FontSize = Enum.FontSize.Size14
780 | button.Size = UDim2.new(1, 8, 0, elementHeight)
781 | button.Position = UDim2.new(0,0,0,elementHeight * i)
782 | button.TextColor3 = Color3.new(1,1,1)
783 | button.ZIndex = 9
784 | button.Parent = gearContextMenuButton
785 |
786 | button.MouseButton1Click:connect(function()
787 | if button.Active and not gearContextMenu.Parent.Active then
788 | local success, result = pcall(function() element.DoIt(element, gearContextMenu) end)
789 | browsingMenu = false
790 | gearContextMenu.Visible = false
791 | clearHighlight(button)
792 | clearPreview()
793 | end
794 | end)
795 |
796 | button.MouseEnter:connect(function()
797 | if button.Active and gearContextMenu.Parent.Active then
798 | highlight(button)
799 | end
800 | end)
801 | button.MouseLeave:connect(function()
802 | if button.Active and gearContextMenu.Parent.Active then
803 | clearHighlight(button)
804 | end
805 | end)
806 |
807 | contextElement.Button = button
808 | contextElement.Element = button
809 | elseif element.Type == "Label" then
810 | local frame = Instance.new("Frame")
811 | frame.Name = "ContextLabel" .. i
812 | frame.BackgroundTransparency = 1
813 | frame.Size = UDim2.new(1, 8, 0, elementHeight)
814 |
815 | local label = Instance.new("TextLabel")
816 | label.Name = "Text1"
817 | label.BackgroundTransparency = 1
818 | label.BackgroundColor3 = Color3.new(1,1,1)
819 | label.BorderSizePixel = 0
820 | label.TextXAlignment = Enum.TextXAlignment.Left
821 | label.Font = Enum.Font.ArialBold
822 | label.FontSize = Enum.FontSize.Size14
823 | label.Position = UDim2.new(0.0, 0, 0, 0)
824 | label.Size = UDim2.new(0.5, 0, 1, 0)
825 | label.TextColor3 = Color3.new(1,1,1)
826 | label.ZIndex = 9
827 | label.Parent = frame
828 | element.Label1 = label
829 |
830 | if element.GetText2 then
831 | label = Instance.new("TextLabel")
832 | label.Name = "Text2"
833 | label.BackgroundTransparency = 1
834 | label.BackgroundColor3 = Color3.new(1,1,1)
835 | label.BorderSizePixel = 0
836 | label.TextXAlignment = Enum.TextXAlignment.Right
837 | label.Font = Enum.Font.Arial
838 | label.FontSize = Enum.FontSize.Size14
839 | label.Position = UDim2.new(0.5, 0, 0, 0)
840 | label.Size = UDim2.new(0.5, 0, 1, 0)
841 | label.TextColor3 = Color3.new(1,1,1)
842 | label.ZIndex = 9
843 | label.Parent = frame
844 | element.Label2 = label
845 | end
846 | frame.Parent = gearContextMenuButton
847 | element.Label = frame
848 | element.Element = frame
849 | end
850 | end
851 |
852 | gearContextMenu.ZIndex = 4
853 | gearContextMenu.MouseLeave:connect(function()
854 | browsingMenu = false
855 | gearContextMenu.Visible = false
856 | clearPreview()
857 | end)
858 | robloxLock(gearContextMenu)
859 |
860 | return gearContextMenu
861 | end
862 |
863 | local backpackChildren = player.Backpack:GetChildren()
864 | for i = 1, #backpackChildren do
865 | addToGrid(backpackChildren[i])
866 | end
867 |
868 | ------------------------- Start Lifelong Connections -----------------------
869 | screen.Changed:connect(function(prop)
870 | if prop == "AbsoluteSize" then
871 | if debounce then return end
872 | debounce = true
873 | wait()
874 | resize()
875 | resizeGrid()
876 | debounce = false
877 | end
878 | end)
879 |
880 | currentLoadout.ChildAdded:connect(function(child) loadoutCheck(child, false) end)
881 | currentLoadout.ChildRemoved:connect(function(child) loadoutCheck(child, true) end)
882 |
883 | currentLoadout.DescendantAdded:connect(function(descendant)
884 | if not backpack.Visible and ( descendant:IsA("ImageButton") or descendant:IsA("TextButton") ) then
885 | centerGear(currentLoadout:GetChildren())
886 | end
887 | end)
888 | currentLoadout.DescendantRemoving:connect(function(descendant)
889 | if not backpack.Visible and ( descendant:IsA("ImageButton") or descendant:IsA("TextButton") ) then
890 | wait()
891 | centerGear(currentLoadout:GetChildren())
892 | end
893 | end)
894 |
895 | grid.MouseEnter:connect(function() clearPreview() end)
896 | grid.MouseLeave:connect(function() clearPreview() end)
897 |
898 | player.CharacterRemoving:connect(function()
899 | removeCharacterConnections()
900 | nukeBackpack()
901 | end)
902 | player.CharacterAdded:connect(function() setupCharacterConnections() end)
903 |
904 | player.ChildAdded:connect(function(child)
905 | if child:IsA("Backpack") then
906 | playerBackpack = child
907 | if backpackAddCon then backpackAddCon:disconnect() end
908 | backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded:connect(function(child) addToGrid(child) end)
909 | end
910 | end)
911 |
912 | swapSlot.Changed:connect(function()
913 | if not swapSlot.Value then
914 | updateGridActive()
915 | end
916 | end)
917 |
918 | searchBox.FocusLost:connect(function(enterPressed)
919 | if enterPressed then
920 | showSearchGear()
921 | end
922 | end)
923 |
924 | local loadoutChildren = currentLoadout:GetChildren()
925 | for i = 1, #loadoutChildren do
926 | if loadoutChildren[i]:IsA("Frame") and string.find(loadoutChildren[i].Name,"Slot") then
927 | loadoutChildren[i].ChildRemoved:connect(function()
928 | updateGridActive()
929 | end)
930 | loadoutChildren[i].ChildAdded:connect(function()
931 | updateGridActive()
932 | end)
933 | end
934 | end
935 |
936 | closeButton.Modal = true
937 | closeButton.MouseButton1Click:connect(function() openCloseBackpack() end)
938 |
939 | searchButton.MouseButton1Click:connect(function() showSearchGear() end)
940 | resetButton.MouseButton1Click:connect(function() showEntireGrid() end)
941 | ------------------------- End Lifelong Connections -----------------------
942 |
943 | resize()
944 | resizeGrid()
945 |
946 | -- make sure any items in the loadout are accounted for in inventory
947 | local loadoutChildren = currentLoadout:GetChildren()
948 | for i = 1, #loadoutChildren do
949 | loadoutCheck(loadoutChildren[i], false)
950 | end
951 | if not backpack.Visible then centerGear(currentLoadout:GetChildren()) end
952 |
953 | -- make sure that inventory is listening to gear reparenting
954 | if characterChildAddedCon == nil and game.Players.LocalPlayer["Character"] then
955 | setupCharacterConnections()
956 | end
957 | if not backpackAddCon then
958 | backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded:connect(function(child) addToGrid(child) end)
959 | end
960 |
961 | -- flip it on if we are good
962 | if game.CoreGui.Version >= 3 then
963 | backpackButton.Visible = true
964 | end
965 |
966 | recalculateScrollLoadout()
967 |
968 |
969 |
--------------------------------------------------------------------------------
/CoreScripts/BuildToolsScripts/BuildToolManager.lua:
--------------------------------------------------------------------------------
1 | -- Responsible for giving out tools in personal servers
2 |
3 | -- first, lets see if buildTools have already been created
4 | -- create the object in lighting (TODO: move to some sort of "container" object when we have one)
5 | local toolsArray = game.Lighting:FindFirstChild("BuildToolsModel")
6 | local ownerArray = game.Lighting:FindFirstChild("OwnerToolsModel")
7 | local hasBuildTools = false
8 |
9 | function getIds(idTable, assetTable)
10 | for i = 1, #idTable do
11 | local model = game:GetService("InsertService"):LoadAsset(idTable[i])
12 | if model then
13 | local children = model:GetChildren()
14 | for i = 1, #children do
15 | if children[i]:IsA("Tool") then
16 | table.insert(assetTable,children[i])
17 | end
18 | end
19 | end
20 | end
21 | end
22 |
23 | function storeInLighting(modelName, assetTable)
24 | local model = Instance.new("Model")
25 | model.Archivable = false
26 | model.Name = modelName
27 |
28 | for i = 1, #assetTable do
29 | assetTable[i].Parent = model
30 | end
31 |
32 | if not game.Lighting:FindFirstChild(modelName) then -- no one beat us to it, we get to insert
33 | model.Parent = game.Lighting
34 | end
35 | end
36 |
37 | if not toolsArray then -- no one has made build tools yet, we get to!
38 | local buildToolIds = {}
39 | local ownerToolIds = {}
40 |
41 | table.insert(buildToolIds,73089166) -- PartSelectionTool
42 | table.insert(buildToolIds,73089190) -- DeleteTool
43 | table.insert(buildToolIds,73089204) -- CloneTool
44 | table.insert(buildToolIds,73089214) -- RotateTool
45 | table.insert(buildToolIds,73089229) -- RecentPartTool
46 | table.insert(buildToolIds,73089239) -- ConfigTool
47 | table.insert(buildToolIds,73089259) -- WiringTool
48 | table.insert(buildToolIds,58921588) -- ClassicTool
49 |
50 | table.insert(ownerToolIds, 65347268)
51 |
52 | -- next, create array of our tools
53 | local buildTools = {}
54 | local ownerTools = {}
55 |
56 | getIds(buildToolIds, buildTools)
57 | getIds(ownerToolIds, ownerTools)
58 |
59 | storeInLighting("BuildToolsModel",buildTools)
60 | storeInLighting("OwnerToolsModel",ownerTools)
61 |
62 | toolsArray = game.Lighting:FindFirstChild("BuildToolsModel")
63 | ownerArray = game.Lighting:FindFirstChild("OwnerToolsModel")
64 | end
65 |
66 | local localBuildTools = {}
67 |
68 | function giveBuildTools()
69 | if not hasBuildTools then
70 | hasBuildTools = true
71 | local theTools = toolsArray:GetChildren()
72 | for i = 1, #theTools do
73 | local toolClone = theTools[i]:clone()
74 | if toolClone then
75 | toolClone.Parent = game.Players.LocalPlayer.Backpack
76 | table.insert(localBuildTools,toolClone)
77 | end
78 | end
79 | end
80 | end
81 |
82 | function giveOwnerTools()
83 | local theOwnerTools = ownerArray:GetChildren()
84 | for i = 1, #theOwnerTools do
85 | local ownerToolClone = theOwnerTools[i]:clone()
86 | if ownerToolClone then
87 | ownerToolClone.Parent = game.Players.LocalPlayer.Backpack
88 | table.insert(localBuildTools,ownerToolClone)
89 | end
90 | end
91 | end
92 |
93 | function removeBuildTools()
94 | if hasBuildTools then
95 | hasBuildTools = false
96 | for i = 1, #localBuildTools do
97 | localBuildTools[i].Parent = nil
98 | end
99 | localBuildTools = {}
100 | end
101 | end
102 |
103 | if game.Players.LocalPlayer.HasBuildTools then
104 | giveBuildTools()
105 | end
106 | if game.Players.LocalPlayer.PersonalServerRank >= 255 then
107 | giveOwnerTools()
108 | end
109 |
110 | local debounce = false
111 | game.Players.LocalPlayer.Changed:connect(function(prop)
112 | if prop == "HasBuildTools" then
113 | while debounce do
114 | wait(0.5)
115 | end
116 |
117 | debounce = true
118 |
119 | if game.Players.LocalPlayer.HasBuildTools then
120 | giveBuildTools()
121 | else
122 | removeBuildTools()
123 | end
124 |
125 | if game.Players.LocalPlayer.PersonalServerRank >= 255 then
126 | giveOwnerTools()
127 | end
128 |
129 | debounce = false
130 | elseif prop == "PersonalServerRank" then
131 | if game.Players.LocalPlayer.PersonalServerRank >= 255 then
132 | giveOwnerTools()
133 | elseif game.Players.LocalPlayer.PersonalServerRank <= 0 then
134 | game.Players.LocalPlayer:Remove() -- you're banned, goodbye!
135 | end
136 | end
137 | end)
138 |
139 | game.Players.LocalPlayer.CharacterAdded:connect(function()
140 | hasBuildTools = false
141 | if game.Players.LocalPlayer.HasBuildTools then
142 | giveBuildTools()
143 | end
144 | if game.Players.LocalPlayer.PersonalServerRank >= 255 then
145 | giveOwnerTools()
146 | end
147 | end)
--------------------------------------------------------------------------------
/CoreScripts/BuildToolsScripts/BuildToolsScript.lua:
--------------------------------------------------------------------------------
1 | -- This script is responsible for loading in all build tools for build mode
2 |
3 | -- Script Globals
4 | local buildTools = {}
5 | local currentTools = {}
6 |
7 | local DeleteToolID = 73089190
8 | local PartSelectionID = 73089166
9 | local CloneToolID = 73089204
10 | local RecentPartToolID = 73089229
11 | local RotateToolID = 73089214
12 | local ConfigToolID = 73089239
13 | local WiringToolID = 73089259
14 | local classicToolID = 58921588
15 |
16 | local player = nil
17 | local backpack = nil
18 |
19 | -- Basic Functions
20 | local function waitForProperty(instance, name)
21 | while not instance[name] do
22 | instance.Changed:wait()
23 | end
24 | end
25 |
26 | local function waitForChild(instance, name)
27 | while not instance:FindFirstChild(name) do
28 | instance.ChildAdded:wait()
29 | end
30 | end
31 |
32 | waitForProperty(game.Players,"LocalPlayer")
33 | waitForProperty(game.Players.LocalPlayer,"userId")
34 |
35 | -- we aren't in a true build mode session, don't give build tools and delete this script
36 | if game.Players.LocalPlayer.userId < 1 then
37 | script:Destroy()
38 | return -- this is probably not necessesary, doing it just in case
39 | end
40 |
41 | -- Functions
42 | function getLatestPlayer()
43 | waitForProperty(game.Players,"LocalPlayer")
44 | player = game.Players.LocalPlayer
45 | waitForChild(player,"Backpack")
46 | backpack = player.Backpack
47 | end
48 |
49 | function waitForCharacterLoad()
50 |
51 | local startTick = tick()
52 |
53 | local playerLoaded = false
54 |
55 | local success = pcall(function() playerLoaded = player.AppearanceDidLoad end) --TODO: remove pcall once this in client on prod
56 | if not success then return false end
57 |
58 | while not playerLoaded do
59 | player.Changed:wait()
60 | playerLoaded = player.AppearanceDidLoad
61 | end
62 |
63 | return true
64 | end
65 |
66 | function showBuildToolsTutorial()
67 | local tutorialKey = "BuildToolsTutorial"
68 | if UserSettings().GameSettings:GetTutorialState(tutorialKey) == true then return end --already have shown tutorial
69 |
70 | local RbxGui = LoadLibrary("RbxGui")
71 |
72 | local frame, showTutorial, dismissTutorial, gotoPage = RbxGui.CreateTutorial("Build", tutorialKey, false)
73 | local firstPage = RbxGui.CreateImageTutorialPage(" ", "http://www.roblox.com/asset/?id=59162193", 359, 296, function() dismissTutorial() end, true)
74 |
75 | RbxGui.AddTutorialPage(frame, firstPage)
76 | frame.Parent = game:GetService("CoreGui"):FindFirstChild("RobloxGui")
77 |
78 | game:GetService("GuiService"):AddCenterDialog(frame, Enum.CenterDialogType.UnsolicitedDialog,
79 | --showFunction
80 | function()
81 | frame.Visible = true
82 | showTutorial()
83 | end,
84 | --hideFunction
85 | function()
86 | frame.Visible = false
87 | end
88 | )
89 |
90 | wait(1)
91 | showTutorial()
92 | end
93 |
94 | function clearLoadout()
95 | currentTools = {}
96 |
97 | local backpackChildren = game.Players.LocalPlayer.Backpack:GetChildren()
98 | for i = 1, #backpackChildren do
99 | if backpackChildren[i]:IsA("Tool") or backpackChildren[i]:IsA("HopperBin") then
100 | table.insert(currentTools,backpackChildren[i])
101 | end
102 | end
103 |
104 | if game.Players.LocalPlayer["Character"] then
105 | local characterChildren = game.Players.LocalPlayer.Character:GetChildren()
106 | for i = 1, #characterChildren do
107 | if characterChildren[i]:IsA("Tool") or characterChildren[i]:IsA("HopperBin") then
108 | table.insert(currentTools,characterChildren[i])
109 | end
110 | end
111 | end
112 |
113 | for i = 1, #currentTools do
114 | currentTools[i].Parent = nil
115 | end
116 | end
117 |
118 | function giveToolsBack()
119 | for i = 1, #currentTools do
120 | currentTools[i].Parent = game.Players.LocalPlayer.Backpack
121 | end
122 | end
123 |
124 | function backpackHasTool(tool)
125 | local backpackChildren = backpack:GetChildren()
126 | for i = 1, #backpackChildren do
127 | if backpackChildren[i] == tool then
128 | return true
129 | end
130 | end
131 | return false
132 | end
133 |
134 | function getToolAssetID(assetID)
135 | local newTool = game:GetService("InsertService"):LoadAsset(assetID)
136 | local toolChildren = newTool:GetChildren()
137 | for i = 1, #toolChildren do
138 | if toolChildren[i]:IsA("Tool") then
139 | return toolChildren[i]
140 | end
141 | end
142 | return nil
143 | end
144 |
145 | -- remove legacy identifiers
146 | -- todo: determine if we still need this
147 | function removeBuildToolTag(tool)
148 | if tool:FindFirstChild("RobloxBuildTool") then
149 | tool.RobloxBuildTool:Destroy()
150 | end
151 | end
152 |
153 | function giveAssetId(assetID,toolName)
154 | local theTool = getToolAssetID(assetID,toolName)
155 | if theTool and not backpackHasTool(theTool) then
156 | removeBuildToolTag(theTool)
157 | theTool.Parent = backpack
158 | table.insert(buildTools,theTool)
159 | end
160 | end
161 |
162 | function loadBuildTools()
163 | giveAssetId(PartSelectionID)
164 | giveAssetId(DeleteToolID)
165 | giveAssetId(CloneToolID)
166 | giveAssetId(RotateToolID)
167 | giveAssetId(RecentPartToolID)
168 | giveAssetId(WiringToolID)
169 | giveAssetId(ConfigToolID)
170 |
171 | -- deprecated tools
172 | giveAssetId(classicToolID)
173 | end
174 |
175 | function givePlayerBuildTools()
176 | getLatestPlayer()
177 |
178 | clearLoadout()
179 |
180 | loadBuildTools()
181 |
182 | giveToolsBack()
183 | end
184 |
185 | function takePlayerBuildTools()
186 | for k,v in ipairs(buildTools) do
187 | v.Parent = nil
188 | end
189 | buildTools = {}
190 | end
191 |
192 |
193 | -- Script start
194 | getLatestPlayer()
195 | waitForCharacterLoad()
196 | givePlayerBuildTools()
197 |
198 | -- If player dies, we make sure to give them build tools again
199 | player.CharacterAdded:connect(function()
200 | takePlayerBuildTools()
201 | givePlayerBuildTools()
202 | end)
203 |
204 | showBuildToolsTutorial()
205 |
--------------------------------------------------------------------------------
/CoreScripts/ContextActionTouch.lua:
--------------------------------------------------------------------------------
1 | -- ContextActionTouch.lua
2 | -- Copyright ROBLOX 2014, created by Ben Tkacheff
3 | -- this script controls ui and firing of lua functions that are bound in ContextActionService for touch inputs
4 | -- Essentially a user can bind a lua function to a key code, input type (mousebutton1 etc.) and this
5 |
6 | -- Variables
7 | local contextActionService = Game:GetService("ContextActionService")
8 | local isTouchDevice = Game:GetService("UserInputService").TouchEnabled
9 | local functionTable = {}
10 | local buttonVector = {}
11 | local buttonScreenGui = nil
12 | local buttonFrame = nil
13 |
14 | local ContextDownImage = "http://www.roblox.com/asset/?id=97166756"
15 | local ContextUpImage = "http://www.roblox.com/asset/?id=97166444"
16 |
17 | local oldTouches = {}
18 |
19 | local buttonPositionTable = {
20 | [1] = UDim2.new(0,123,0,70),
21 | [2] = UDim2.new(0,30,0,60),
22 | [3] = UDim2.new(0,180,0,160),
23 | [4] = UDim2.new(0,85,0,-25),
24 | [5] = UDim2.new(0,185,0,-25),
25 | [6] = UDim2.new(0,185,0,260),
26 | [7] = UDim2.new(0,216,0,65)
27 | }
28 | local maxButtons = #buttonPositionTable
29 |
30 | -- Preload images
31 | Game:GetService("ContentProvider"):Preload(ContextDownImage)
32 | Game:GetService("ContentProvider"):Preload(ContextUpImage)
33 |
34 | while not Game.Players do
35 | wait()
36 | end
37 |
38 | while not Game.Players.LocalPlayer do
39 | wait()
40 | end
41 |
42 | function createContextActionGui()
43 | if not buttonScreenGui and isTouchDevice then
44 | buttonScreenGui = Instance.new("ScreenGui")
45 | buttonScreenGui.Name = "ContextActionGui"
46 |
47 | buttonFrame = Instance.new("Frame")
48 | buttonFrame.BackgroundTransparency = 1
49 | buttonFrame.Size = UDim2.new(0.3,0,0.5,0)
50 | buttonFrame.Position = UDim2.new(0.7,0,0.5,0)
51 | buttonFrame.Name = "ContextButtonFrame"
52 | buttonFrame.Parent = buttonScreenGui
53 | end
54 | end
55 |
56 | -- functions
57 | function setButtonSizeAndPosition(object)
58 | local buttonSize = 55
59 | local xOffset = 10
60 | local yOffset = 95
61 |
62 | -- todo: better way to determine mobile sized screens
63 | local onSmallScreen = (game.CoreGui.RobloxGui.AbsoluteSize.X < 600)
64 | if not onSmallScreen then
65 | buttonSize = 85
66 | xOffset = 40
67 | end
68 |
69 | object.Size = UDim2.new(0,buttonSize,0,buttonSize)
70 | end
71 |
72 | function contextButtonDown(button, inputObject, actionName)
73 | if inputObject.UserInputType == Enum.UserInputType.Touch then
74 | button.Image = ContextDownImage
75 | contextActionService:CallFunction(actionName, Enum.UserInputState.Begin, inputObject)
76 | end
77 | end
78 |
79 | function contextButtonMoved(button, inputObject, actionName)
80 | if inputObject.UserInputType == Enum.UserInputType.Touch then
81 | button.Image = ContextDownImage
82 | contextActionService:CallFunction(actionName, Enum.UserInputState.Change, inputObject)
83 | end
84 | end
85 |
86 | function contextButtonUp(button, inputObject, actionName)
87 | button.Image = ContextUpImage
88 | if inputObject.UserInputType == Enum.UserInputType.Touch and inputObject.UserInputState == Enum.UserInputState.End then
89 | contextActionService:CallFunction(actionName, Enum.UserInputState.End, inputObject)
90 | end
91 | end
92 |
93 | function isSmallScreenDevice()
94 | return Game:GetService("GuiService"):GetScreenResolution().y <= 320
95 | end
96 |
97 |
98 | function createNewButton(actionName, functionInfoTable)
99 | local contextButton = Instance.new("ImageButton")
100 | contextButton.Name = "ContextActionButton"
101 | contextButton.BackgroundTransparency = 1
102 | contextButton.Size = UDim2.new(0,90,0,90)
103 | contextButton.Active = true
104 | if isSmallScreenDevice() then
105 | contextButton.Size = UDim2.new(0,70,0,70)
106 | end
107 | contextButton.Image = ContextUpImage
108 | contextButton.Parent = buttonFrame
109 |
110 | local currentButtonTouch = nil
111 |
112 | Game:GetService("UserInputService").InputEnded:connect(function ( inputObject )
113 | oldTouches[inputObject] = nil
114 | end)
115 | contextButton.InputBegan:connect(function(inputObject)
116 | if oldTouches[inputObject] then return end
117 |
118 | if inputObject.UserInputState == Enum.UserInputState.Begin and currentButtonTouch == nil then
119 | currentButtonTouch = inputObject
120 | contextButtonDown(contextButton, inputObject, actionName)
121 | end
122 | end)
123 | contextButton.InputChanged:connect(function(inputObject)
124 | if oldTouches[inputObject] then return end
125 | if currentButtonTouch ~= inputObject then return end
126 |
127 | contextButtonMoved(contextButton, inputObject, actionName)
128 | end)
129 | contextButton.InputEnded:connect(function(inputObject)
130 | if oldTouches[inputObject] then return end
131 | if currentButtonTouch ~= inputObject then return end
132 |
133 | currentButtonTouch = nil
134 | oldTouches[inputObject] = true
135 | contextButtonUp(contextButton, inputObject, actionName)
136 | end)
137 |
138 | local actionIcon = Instance.new("ImageLabel")
139 | actionIcon.Name = "ActionIcon"
140 | actionIcon.Position = UDim2.new(0.175, 0, 0.175, 0)
141 | actionIcon.Size = UDim2.new(0.65, 0, 0.65, 0)
142 | actionIcon.BackgroundTransparency = 1
143 | if functionInfoTable["image"] and type(functionInfoTable["image"]) == "string" then
144 | actionIcon.Image = functionInfoTable["image"]
145 | end
146 | actionIcon.Parent = contextButton
147 |
148 | local actionTitle = Instance.new("TextLabel")
149 | actionTitle.Name = "ActionTitle"
150 | actionTitle.Size = UDim2.new(1,0,1,0)
151 | actionTitle.BackgroundTransparency = 1
152 | actionTitle.Font = Enum.Font.SourceSansBold
153 | actionTitle.TextColor3 = Color3.new(1,1,1)
154 | actionTitle.TextStrokeTransparency = 0
155 | actionTitle.FontSize = Enum.FontSize.Size18
156 | actionTitle.TextWrapped = true
157 | actionTitle.Text = ""
158 | if functionInfoTable["title"] and type(functionInfoTable["title"]) == "string" then
159 | actionTitle.Text = functionInfoTable["title"]
160 | end
161 | actionTitle.Parent = contextButton
162 |
163 | return contextButton
164 | end
165 |
166 | function createButton( actionName, functionInfoTable )
167 | local button = createNewButton(actionName, functionInfoTable)
168 |
169 | local position = nil
170 | for i = 1,#buttonVector do
171 | if buttonVector[i] == "empty" then
172 | position = i
173 | break
174 | end
175 | end
176 |
177 | if not position then
178 | position = #buttonVector + 1
179 | end
180 |
181 | if position > maxButtons then
182 | return -- todo: let user know we have too many buttons already?
183 | end
184 |
185 | buttonVector[position] = button
186 | functionTable[actionName]["button"] = button
187 |
188 | button.Position = buttonPositionTable[position]
189 | button.Parent = buttonFrame
190 |
191 | if buttonScreenGui and buttonScreenGui.Parent == nil then
192 | buttonScreenGui.Parent = Game.Players.LocalPlayer.PlayerGui
193 | end
194 | end
195 |
196 | function removeAction(actionName)
197 | if not functionTable[actionName] then return end
198 |
199 | local actionButton = functionTable[actionName]["button"]
200 |
201 | if actionButton then
202 | actionButton.Parent = nil
203 |
204 | for i = 1,#buttonVector do
205 | if buttonVector[i] == actionButton then
206 | buttonVector[i] = "empty"
207 | break
208 | end
209 | end
210 |
211 | actionButton:Destroy()
212 | end
213 |
214 | functionTable[actionName] = nil
215 | end
216 |
217 | function addAction(actionName,createTouchButton,functionInfoTable)
218 | if functionTable[actionName] then
219 | removeAction(actionName)
220 | end
221 | functionTable[actionName] = {functionInfoTable}
222 | if createTouchButton and isTouchDevice then
223 | createContextActionGui()
224 | createButton(actionName, functionInfoTable)
225 | end
226 | end
227 |
228 | -- Connections
229 | contextActionService.BoundActionChanged:connect( function(actionName, changeName, changeTable)
230 | if functionTable[actionName] and changeTable then
231 | local button = functionTable[actionName]["button"]
232 | if button then
233 | if changeName == "image" then
234 | button.ActionIcon.Image = changeTable[changeName]
235 | elseif changeName == "title" then
236 | button.ActionTitle.Text = changeTable[changeName]
237 | elseif changeName == "description" then
238 | -- todo: add description to menu
239 | elseif changeName == "position" then
240 | button.Position = changeTable[changeName]
241 | end
242 | end
243 | end
244 | end)
245 |
246 | contextActionService.BoundActionAdded:connect( function(actionName, createTouchButton, functionInfoTable)
247 | addAction(actionName, createTouchButton, functionInfoTable)
248 | end)
249 |
250 | contextActionService.BoundActionRemoved:connect( function(actionName, functionInfoTable)
251 | removeAction(actionName)
252 | end)
253 |
254 | contextActionService.GetActionButtonEvent:connect( function(actionName)
255 | if functionTable[actionName] then
256 | contextActionService:FireActionButtonFoundSignal(actionName, functionTable[actionName]["button"])
257 | end
258 | end)
259 |
260 | -- make sure any bound data before we setup connections is handled
261 | local boundActions = contextActionService:GetAllBoundActionInfo()
262 | for actionName, actionData in pairs(boundActions) do
263 | addAction(actionName,actionData["createTouchButton"],actionData)
264 | end
265 |
--------------------------------------------------------------------------------
/CoreScripts/DialogScripts.rbxm:
--------------------------------------------------------------------------------
1 |
2 | null
3 | nil
4 | -
5 |
6 | true
7 |
8 | ReenableDialogScript
9 | wait(5)
10 | local dialog = script.Parent
11 | if dialog:IsA("Dialog") then
12 | dialog.InUse = false
13 | end
14 | script:Remove()
15 |
16 | true
17 |
18 |
19 | -
20 |
21 | true
22 |
23 | TimeoutScript
24 | wait(15)
25 | local dialog = script.Parent
26 | if dialog:IsA("Dialog") then
27 | dialog.InUse = false
28 | end
29 | script:Remove()
30 |
31 | true
32 |
33 |
34 |
--------------------------------------------------------------------------------
/CoreScripts/HealthScript.lua:
--------------------------------------------------------------------------------
1 | --[[
2 | This script controls the gui the player sees in regards to his or her health.
3 | Can be turned with Game.StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Health,false)
4 | Copyright ROBLOX 2014. Written by Ben Tkacheff.
5 | --]]
6 |
7 | ---------------------------------------------------------------------
8 | -- Initialize/Variables
9 | while not Game do
10 | wait(1/60)
11 | end
12 | while not Game.Players do
13 | wait(1/60)
14 | end
15 |
16 | local useCoreHealthBar = false
17 | local success = pcall(function() useCoreHealthBar = Game.Players:GetUseCoreScriptHealthBar() end)
18 | if not success or not useCoreHealthBar then
19 | return
20 | end
21 |
22 | local currentHumanoid = nil
23 |
24 | local HealthGui = nil
25 | local lastHealth = 100
26 | local HealthPercentageForOverlay = 5
27 | local maxBarTweenTime = 0.3
28 |
29 | local guiEnabled = false
30 | local healthChangedConnection = nil
31 | local humanoidDiedConnection = nil
32 | local characterAddedConnection = nil
33 |
34 | local greenBarImage = "http://www.roblox.com/asset/?id=35238053"
35 | local redBarImage = "http://www.roblox.com/asset/?id=35238036"
36 | local hurtOverlayImage = "http://www.roblox.com/asset/?id=34854607"
37 |
38 | Game:GetService("ContentProvider"):Preload(greenBarImage)
39 | Game:GetService("ContentProvider"):Preload(redBarImage)
40 | Game:GetService("ContentProvider"):Preload(hurtOverlayImage)
41 |
42 |
43 | while not Game.Players.LocalPlayer do
44 | wait(1/60)
45 | end
46 |
47 | ---------------------------------------------------------------------
48 | -- Functions
49 |
50 | function CreateGui()
51 | if HealthGui then
52 | HealthGui.Parent = Game.CoreGui.RobloxGui
53 | return
54 | end
55 |
56 | HealthGui = Instance.new("Frame")
57 | HealthGui.Name = "HealthGui"
58 | HealthGui.BackgroundTransparency = 1
59 | HealthGui.Size = UDim2.new(1,0,1,0)
60 |
61 | local hurtOverlay = Instance.new("ImageLabel")
62 | hurtOverlay.Name = "HurtOverlay"
63 | hurtOverlay.BackgroundTransparency = 1
64 | hurtOverlay.Image = hurtOverlayImage
65 | hurtOverlay.Position = UDim2.new(-10,0,-10,0)
66 | hurtOverlay.Size = UDim2.new(20,0,20,0)
67 | hurtOverlay.Visible = false
68 | hurtOverlay.Parent = HealthGui
69 |
70 | local healthFrame = Instance.new("Frame")
71 | healthFrame.Name = "HealthFrame"
72 | healthFrame.BackgroundColor3 = Color3.new(0,0,0)
73 | healthFrame.BorderColor3 = Color3.new(0,0,0)
74 | healthFrame.Position = UDim2.new(0.5,-85,1,-22)
75 | healthFrame.Size = UDim2.new(0,170,0,18)
76 | healthFrame.Parent = HealthGui
77 |
78 | local healthBar = Instance.new("ImageLabel")
79 | healthBar.Name = "HealthBar"
80 | healthBar.BackgroundTransparency = 1
81 | healthBar.Image = greenBarImage
82 | healthBar.Size = UDim2.new(1,0,1,0)
83 | healthBar.Parent = healthFrame
84 |
85 | local healthLabel = Instance.new("TextLabel")
86 | healthLabel.Name = "HealthLabel"
87 |
88 | healthLabel.Text = "Health " -- gives room at end of health bar
89 | healthLabel.Font = Enum.Font.SourceSansBold
90 | healthLabel.FontSize = Enum.FontSize.Size14
91 | healthLabel.TextColor3 = Color3.new(1,1,1)
92 | healthLabel.TextStrokeTransparency = 0
93 | healthLabel.TextXAlignment = Enum.TextXAlignment.Right
94 |
95 | healthLabel.BackgroundTransparency = 1
96 | healthLabel.Size = UDim2.new(1,0,1,0)
97 | healthLabel.Parent = healthFrame
98 |
99 | HealthGui.Parent = Game.CoreGui.RobloxGui
100 | end
101 |
102 | function UpdateGui(health)
103 | if not HealthGui then return end
104 |
105 | local healthFrame = HealthGui:FindFirstChild("HealthFrame")
106 | if not healthFrame then return end
107 |
108 | local healthBar = healthFrame:FindFirstChild("HealthBar")
109 | if not healthBar then return end
110 |
111 | -- If more than 1/4 health, bar = green. Else, bar = red.
112 | if (health/currentHumanoid.MaxHealth) > 0.25 then
113 | healthBar.Image = greenBarImage
114 | else
115 | healthBar.Image = redBarImage
116 | end
117 |
118 | local width = (health / currentHumanoid.MaxHealth)
119 | width = math.max(math.min(width,1),0) -- make sure width is between 0 and 1
120 |
121 | local healthDelta = lastHealth - health
122 | lastHealth = health
123 |
124 | local percentOfTotalHealth = math.abs(healthDelta/currentHumanoid.MaxHealth)
125 | percentOfTotalHealth = math.max(math.min(percentOfTotalHealth,1),0) -- make sure percentOfTotalHealth is between 0 and 1
126 |
127 | local newHealthSize = UDim2.new(width,0,1,0)
128 |
129 | healthBar:TweenSize(newHealthSize, Enum.EasingDirection.InOut, Enum.EasingStyle.Linear, percentOfTotalHealth * maxBarTweenTime, true)
130 |
131 | local thresholdForHurtOverlay = currentHumanoid.MaxHealth * (HealthPercentageForOverlay/100)
132 |
133 | if healthDelta >= thresholdForHurtOverlay then
134 | AnimateHurtOverlay()
135 | end
136 | end
137 |
138 | function AnimateHurtOverlay()
139 | if not HealthGui then return end
140 |
141 | local overlay = HealthGui:FindFirstChild("HurtOverlay")
142 | if not overlay then return end
143 |
144 | -- stop any tweens on overlay
145 | overlay:TweenSizeAndPosition(UDim2.new(20, 0, 20, 0), UDim2.new(-10, 0, -10, 0),Enum.EasingDirection.Out,Enum.EasingStyle.Linear,0,true,function()
146 |
147 | -- show the gui
148 | overlay.Size = UDim2.new(1,0,1,0)
149 | overlay.Position = UDim2.new(0,0,0,0)
150 | overlay.Visible = true
151 |
152 | -- now tween the hide
153 | overlay:TweenSizeAndPosition(UDim2.new(20, 0, 20, 0) ,UDim2.new(-10, 0, -10, 0),Enum.EasingDirection.Out,Enum.EasingStyle.Quad,10,false,function()
154 | overlay.Visible = false
155 | end)
156 | end)
157 |
158 | end
159 |
160 | function humanoidDied()
161 | UpdateGui(0)
162 | end
163 |
164 | function disconnectPlayerConnections()
165 | humanoidDiedConnection:disconnect()
166 | healthChangedConnection:disconnect()
167 | characterAddedConnection:disconnect()
168 | end
169 |
170 | function newPlayerCharacter()
171 | disconnectPlayerConnections()
172 | startGui()
173 | end
174 |
175 | function startGui()
176 | local character = Game.Players.LocalPlayer.Character
177 |
178 | while (character == nil) do
179 | character = Game.Players.LocalPlayer.Character
180 | wait(1/30)
181 | end
182 |
183 | currentHumanoid = character:WaitForChild("Humanoid")
184 | if currentHumanoid then
185 | CreateGui()
186 | healthChangedConnection = currentHumanoid.HealthChanged:connect(UpdateGui)
187 | humanoidDiedConnection = currentHumanoid.Died:connect(humanoidDied)
188 | end
189 |
190 | UpdateGui(currentHumanoid.Health)
191 |
192 | characterAddedConnection = Game.Players.LocalPlayer.CharacterAdded:connect(newPlayerCharacter)
193 | end
194 |
195 |
196 |
197 | ---------------------------------------------------------------------
198 | -- Start Script
199 |
200 | if Game.StarterGui:GetCoreGuiEnabled(Enum.CoreGuiType.Health) then
201 | guiEnabled = true
202 | startGui()
203 | end
204 |
205 | Game.StarterGui.CoreGuiChangedSignal:connect(function(coreGuiType,enabled)
206 |
207 | if guiEnabled and not enabled then
208 | if HealthGui then
209 | HealthGui.Parent = nil
210 | end
211 | disconnectPlayerConnections()
212 | elseif not guiEnabled and enabled then
213 | startGui()
214 | end
215 |
216 | guiEnabled = enabled
217 |
218 | end)
219 |
--------------------------------------------------------------------------------
/CoreScripts/MainBotChatScript.lua:
--------------------------------------------------------------------------------
1 | function waitForProperty(instance, name)
2 | while not instance[name] do
3 | instance.Changed:wait()
4 | end
5 | end
6 |
7 | function waitForChild(instance, name)
8 | while not instance:FindFirstChild(name) do
9 | instance.ChildAdded:wait()
10 | end
11 | end
12 |
13 |
14 | local mainFrame
15 | local choices = {}
16 | local lastChoice
17 | local choiceMap = {}
18 | local currentConversationDialog
19 | local currentConversationPartner
20 | local currentAbortDialogScript
21 |
22 | local tooFarAwayMessage = "You are too far away to chat!"
23 | local tooFarAwaySize = 300
24 | local characterWanderedOffMessage = "Chat ended because you walked away"
25 | local characterWanderedOffSize = 350
26 | local conversationTimedOut = "Chat ended because you didn't reply"
27 | local conversationTimedOutSize = 350
28 |
29 | local player
30 | local screenGui
31 | local chatNotificationGui
32 | local messageDialog
33 | local timeoutScript
34 | local reenableDialogScript
35 | local dialogMap = {}
36 | local dialogConnections = {}
37 |
38 | local gui = nil
39 | waitForChild(game,"CoreGui")
40 | waitForChild(game.CoreGui,"RobloxGui")
41 | if game.CoreGui.RobloxGui:FindFirstChild("ControlFrame") then
42 | gui = game.CoreGui.RobloxGui.ControlFrame
43 | else
44 | gui = game.CoreGui.RobloxGui
45 | end
46 |
47 | function currentTone()
48 | if currentConversationDialog then
49 | return currentConversationDialog.Tone
50 | else
51 | return Enum.DialogTone.Neutral
52 | end
53 | end
54 |
55 |
56 | function createChatNotificationGui()
57 | chatNotificationGui = Instance.new("BillboardGui")
58 | chatNotificationGui.Name = "ChatNotificationGui"
59 | chatNotificationGui.ExtentsOffset = Vector3.new(0,1,0)
60 | chatNotificationGui.Size = UDim2.new(4, 0, 5.42857122, 0)
61 | chatNotificationGui.SizeOffset = Vector2.new(0,0)
62 | chatNotificationGui.StudsOffset = Vector3.new(0.4, 4.3, 0)
63 | chatNotificationGui.Enabled = true
64 | chatNotificationGui.RobloxLocked = true
65 | chatNotificationGui.Active = true
66 |
67 | local image = Instance.new("ImageLabel")
68 | image.Name = "Image"
69 | image.Active = false
70 | image.BackgroundTransparency = 1
71 | image.Position = UDim2.new(0,0,0,0)
72 | image.Size = UDim2.new(1.0,0,1.0,0)
73 | image.Image = ""
74 | image.RobloxLocked = true
75 | image.Parent = chatNotificationGui
76 |
77 |
78 | local button = Instance.new("ImageButton")
79 | button.Name = "Button"
80 | button.AutoButtonColor = false
81 | button.Position = UDim2.new(0.0879999995, 0, 0.0529999994, 0)
82 | button.Size = UDim2.new(0.829999983, 0, 0.460000008, 0)
83 | button.Image = ""
84 | button.BackgroundTransparency = 1
85 | button.RobloxLocked = true
86 | button.Parent = image
87 | end
88 |
89 | function getChatColor(tone)
90 | if tone == Enum.DialogTone.Neutral then
91 | return Enum.ChatColor.Blue
92 | elseif tone == Enum.DialogTone.Friendly then
93 | return Enum.ChatColor.Green
94 | elseif tone == Enum.DialogTone.Enemy then
95 | return Enum.ChatColor.Red
96 | end
97 | end
98 |
99 | function styleChoices(tone)
100 | for i, obj in pairs(choices) do
101 | resetColor(obj, tone)
102 | end
103 | resetColor(lastChoice, tone)
104 | end
105 |
106 | function styleMainFrame(tone)
107 | if tone == Enum.DialogTone.Neutral then
108 | mainFrame.Style = Enum.FrameStyle.ChatBlue
109 | mainFrame.Tail.Image = "rbxasset://textures/chatBubble_botBlue_tailRight.png"
110 | elseif tone == Enum.DialogTone.Friendly then
111 | mainFrame.Style = Enum.FrameStyle.ChatGreen
112 | mainFrame.Tail.Image = "rbxasset://textures/chatBubble_botGreen_tailRight.png"
113 | elseif tone == Enum.DialogTone.Enemy then
114 | mainFrame.Style = Enum.FrameStyle.ChatRed
115 | mainFrame.Tail.Image = "rbxasset://textures/chatBubble_botRed_tailRight.png"
116 | end
117 |
118 | styleChoices(tone)
119 | end
120 | function setChatNotificationTone(gui, purpose, tone)
121 | if tone == Enum.DialogTone.Neutral then
122 | gui.Image.Image = "rbxasset://textures/chatBubble_botBlue_notify_bkg.png"
123 | elseif tone == Enum.DialogTone.Friendly then
124 | gui.Image.Image = "rbxasset://textures/chatBubble_botGreen_notify_bkg.png"
125 | elseif tone == Enum.DialogTone.Enemy then
126 | gui.Image.Image = "rbxasset://textures/chatBubble_botRed_notify_bkg.png"
127 | end
128 | if purpose == Enum.DialogPurpose.Quest then
129 | gui.Image.Button.Image = "rbxasset://textures/chatBubble_bot_notify_bang.png"
130 | elseif purpose == Enum.DialogPurpose.Help then
131 | gui.Image.Button.Image = "rbxasset://textures/chatBubble_bot_notify_question.png"
132 | elseif purpose == Enum.DialogPurpose.Shop then
133 | gui.Image.Button.Image = "rbxasset://textures/chatBubble_bot_notify_money.png"
134 | end
135 | end
136 |
137 | function createMessageDialog()
138 | messageDialog = Instance.new("Frame");
139 | messageDialog.Name = "DialogScriptMessage"
140 | messageDialog.Style = Enum.FrameStyle.RobloxRound
141 | messageDialog.Visible = false
142 |
143 | local text = Instance.new("TextLabel")
144 | text.Name = "Text"
145 | text.Position = UDim2.new(0,0,0,-1)
146 | text.Size = UDim2.new(1,0,1,0)
147 | text.FontSize = Enum.FontSize.Size14
148 | text.BackgroundTransparency = 1
149 | text.TextColor3 = Color3.new(1,1,1)
150 | text.RobloxLocked = true
151 | text.Parent = messageDialog
152 | end
153 |
154 | function showMessage(msg, size)
155 | messageDialog.Text.Text = msg
156 | messageDialog.Size = UDim2.new(0,size,0,40)
157 | messageDialog.Position = UDim2.new(0.5, -size/2, 0.5, -40)
158 | messageDialog.Visible = true
159 | wait(2)
160 | messageDialog.Visible = false
161 | end
162 |
163 | function variableDelay(str)
164 | local length = math.min(string.len(str), 100)
165 | wait(0.75 + ((length/75) * 1.5))
166 | end
167 |
168 | function resetColor(frame, tone)
169 | if tone == Enum.DialogTone.Neutral then
170 | frame.BackgroundColor3 = Color3.new(0/255, 0/255, 179/255)
171 | frame.Number.TextColor3 = Color3.new(45/255, 142/255, 245/255)
172 | elseif tone == Enum.DialogTone.Friendly then
173 | frame.BackgroundColor3 = Color3.new(0/255, 77/255, 0/255)
174 | frame.Number.TextColor3 = Color3.new(0/255, 190/255, 0/255)
175 | elseif tone == Enum.DialogTone.Enemy then
176 | frame.BackgroundColor3 = Color3.new(140/255, 0/255, 0/255)
177 | frame.Number.TextColor3 = Color3.new(255/255,88/255, 79/255)
178 | end
179 | end
180 |
181 | function highlightColor(frame, tone)
182 | if tone == Enum.DialogTone.Neutral then
183 | frame.BackgroundColor3 = Color3.new(2/255, 108/255, 255/255)
184 | frame.Number.TextColor3 = Color3.new(1, 1, 1)
185 | elseif tone == Enum.DialogTone.Friendly then
186 | frame.BackgroundColor3 = Color3.new(0/255, 128/255, 0/255)
187 | frame.Number.TextColor3 = Color3.new(1, 1, 1)
188 | elseif tone == Enum.DialogTone.Enemy then
189 | frame.BackgroundColor3 = Color3.new(204/255, 0/255, 0/255)
190 | frame.Number.TextColor3 = Color3.new(1, 1, 1)
191 | end
192 | end
193 |
194 | function wanderDialog()
195 | print("Wander")
196 | mainFrame.Visible = false
197 | endDialog()
198 | showMessage(characterWanderedOffMessage, characterWanderedOffSize)
199 | end
200 |
201 | function timeoutDialog()
202 | print("Timeout")
203 | mainFrame.Visible = false
204 | endDialog()
205 | showMessage(conversationTimedOut, conversationTimedOutSize)
206 | end
207 | function normalEndDialog()
208 | print("Done")
209 | endDialog()
210 | end
211 |
212 | function endDialog()
213 | if currentAbortDialogScript then
214 | currentAbortDialogScript:Remove()
215 | currentAbortDialogScript = nil
216 | end
217 |
218 | local dialog = currentConversationDialog
219 | currentConversationDialog = nil
220 | if dialog and dialog.InUse then
221 | local reenableScript = reenableDialogScript:Clone()
222 | reenableScript.archivable = false
223 | reenableScript.Disabled = false
224 | reenableScript.Parent = dialog
225 | end
226 |
227 | for dialog, gui in pairs(dialogMap) do
228 | if dialog and gui then
229 | gui.Enabled = not dialog.InUse
230 | end
231 | end
232 |
233 | currentConversationPartner = nil
234 | end
235 |
236 | function sanitizeMessage(msg)
237 | if string.len(msg) == 0 then
238 | return "..."
239 | else
240 | return msg
241 | end
242 | end
243 |
244 | function selectChoice(choice)
245 | renewKillswitch(currentConversationDialog)
246 |
247 | --First hide the Gui
248 | mainFrame.Visible = false
249 | if choice == lastChoice then
250 | game.Chat:Chat(game.Players.LocalPlayer.Character, "Goodbye!", getChatColor(currentTone()))
251 |
252 | normalEndDialog()
253 | else
254 | local dialogChoice = choiceMap[choice]
255 |
256 | game.Chat:Chat(game.Players.LocalPlayer.Character, sanitizeMessage(dialogChoice.UserDialog), getChatColor(currentTone()))
257 | wait(1)
258 | currentConversationDialog:SignalDialogChoiceSelected(player, dialogChoice)
259 | game.Chat:Chat(currentConversationPartner, sanitizeMessage(dialogChoice.ResponseDialog), getChatColor(currentTone()))
260 |
261 | variableDelay(dialogChoice.ResponseDialog)
262 | presentDialogChoices(currentConversationPartner, dialogChoice:GetChildren())
263 | end
264 | end
265 |
266 | function newChoice(numberText)
267 | local frame = Instance.new("TextButton")
268 | frame.BackgroundColor3 = Color3.new(0/255, 0/255, 179/255)
269 | frame.AutoButtonColor = false
270 | frame.BorderSizePixel = 0
271 | frame.Text = ""
272 | frame.MouseEnter:connect(function() highlightColor(frame, currentTone()) end)
273 | frame.MouseLeave:connect(function() resetColor(frame, currentTone()) end)
274 | frame.MouseButton1Click:connect(function() selectChoice(frame) end)
275 | frame.RobloxLocked = true
276 |
277 | local number = Instance.new("TextLabel")
278 | number.Name = "Number"
279 | number.TextColor3 = Color3.new(127/255, 212/255, 255/255)
280 | number.Text = numberText
281 | number.FontSize = Enum.FontSize.Size14
282 | number.BackgroundTransparency = 1
283 | number.Position = UDim2.new(0,4,0,2)
284 | number.Size = UDim2.new(0,20,0,24)
285 | number.TextXAlignment = Enum.TextXAlignment.Left
286 | number.TextYAlignment = Enum.TextYAlignment.Top
287 | number.RobloxLocked = true
288 | number.Parent = frame
289 |
290 | local prompt = Instance.new("TextLabel")
291 | prompt.Name = "UserPrompt"
292 | prompt.BackgroundTransparency = 1
293 | prompt.TextColor3 = Color3.new(1,1,1)
294 | prompt.FontSize = Enum.FontSize.Size14
295 | prompt.Position = UDim2.new(0,28, 0, 2)
296 | prompt.Size = UDim2.new(1,-32, 1, -4)
297 | prompt.TextXAlignment = Enum.TextXAlignment.Left
298 | prompt.TextYAlignment = Enum.TextYAlignment.Top
299 | prompt.TextWrap = true
300 | prompt.RobloxLocked = true
301 | prompt.Parent = frame
302 |
303 | return frame
304 | end
305 | function initialize(parent)
306 | choices[1] = newChoice("1)")
307 | choices[2] = newChoice("2)")
308 | choices[3] = newChoice("3)")
309 | choices[4] = newChoice("4)")
310 |
311 | lastChoice = newChoice("5)")
312 | lastChoice.UserPrompt.Text = "Goodbye!"
313 | lastChoice.Size = UDim2.new(1,0,0,28)
314 |
315 | mainFrame = Instance.new("Frame")
316 | mainFrame.Name = "UserDialogArea"
317 | mainFrame.Size = UDim2.new(0, 350, 0, 200)
318 | mainFrame.Style = Enum.FrameStyle.ChatBlue
319 | mainFrame.Visible = false
320 |
321 | imageLabel = Instance.new("ImageLabel")
322 | imageLabel.Name = "Tail"
323 | imageLabel.Size = UDim2.new(0,62,0,53)
324 | imageLabel.Position = UDim2.new(1,8,0.25)
325 | imageLabel.Image = "rbxasset://textures/chatBubble_botBlue_tailRight.png"
326 | imageLabel.BackgroundTransparency = 1
327 | imageLabel.RobloxLocked = true
328 | imageLabel.Parent = mainFrame
329 |
330 | for n, obj in pairs(choices) do
331 | obj.RobloxLocked = true
332 | obj.Parent = mainFrame
333 | end
334 | lastChoice.RobloxLocked = true
335 | lastChoice.Parent = mainFrame
336 |
337 | mainFrame.RobloxLocked = true
338 | mainFrame.Parent = parent
339 | end
340 |
341 | function presentDialogChoices(talkingPart, dialogChoices)
342 | if not currentConversationDialog then
343 | return
344 | end
345 |
346 | currentConversationPartner = talkingPart
347 | sortedDialogChoices = {}
348 | for n, obj in pairs(dialogChoices) do
349 | if obj:IsA("DialogChoice") then
350 | table.insert(sortedDialogChoices, obj)
351 | end
352 | end
353 | table.sort(sortedDialogChoices, function(a,b) return a.Name < b.Name end)
354 |
355 | if #sortedDialogChoices == 0 then
356 | normalEndDialog()
357 | return
358 | end
359 |
360 | local pos = 1
361 | local yPosition = 0
362 | choiceMap = {}
363 | for n, obj in pairs(choices) do
364 | obj.Visible = false
365 | end
366 |
367 | for n, obj in pairs(sortedDialogChoices) do
368 | if pos <= #choices then
369 | --3 lines is the maximum, set it to that temporarily
370 | choices[pos].Size = UDim2.new(1, 0, 0, 24*3)
371 | choices[pos].UserPrompt.Text = obj.UserDialog
372 | local height = math.ceil(choices[pos].UserPrompt.TextBounds.Y/24)*24
373 |
374 | choices[pos].Position = UDim2.new(0, 0, 0, yPosition)
375 | choices[pos].Size = UDim2.new(1, 0, 0, height)
376 | choices[pos].Visible = true
377 |
378 | choiceMap[choices[pos]] = obj
379 |
380 | yPosition = yPosition + height
381 | pos = pos + 1
382 | end
383 | end
384 |
385 | lastChoice.Position = UDim2.new(0,0,0,yPosition)
386 | lastChoice.Number.Text = pos .. ")"
387 |
388 | mainFrame.Size = UDim2.new(0, 350, 0, yPosition+24+32)
389 | mainFrame.Position = UDim2.new(0,20,0.0, -mainFrame.Size.Y.Offset-20)
390 | styleMainFrame(currentTone())
391 | mainFrame.Visible = true
392 | end
393 |
394 | function doDialog(dialog)
395 | while not Instance.Lock(dialog, player) do
396 | wait()
397 | end
398 |
399 | if dialog.InUse then
400 | Instance.Unlock(dialog)
401 | return
402 | else
403 | dialog.InUse = true
404 | Instance.Unlock(dialog)
405 | end
406 |
407 | currentConversationDialog = dialog
408 | game.Chat:Chat(dialog.Parent, dialog.InitialPrompt, getChatColor(dialog.Tone))
409 | variableDelay(dialog.InitialPrompt)
410 |
411 | presentDialogChoices(dialog.Parent, dialog:GetChildren())
412 | end
413 |
414 | function renewKillswitch(dialog)
415 | if currentAbortDialogScript then
416 | currentAbortDialogScript:Remove()
417 | currentAbortDialogScript = nil
418 | end
419 |
420 | currentAbortDialogScript = timeoutScript:Clone()
421 | currentAbortDialogScript.archivable = false
422 | currentAbortDialogScript.Disabled = false
423 | currentAbortDialogScript.Parent = dialog
424 | end
425 |
426 | function checkForLeaveArea()
427 | while currentConversationDialog do
428 | if currentConversationDialog.Parent and (player:DistanceFromCharacter(currentConversationDialog.Parent.Position) >= currentConversationDialog.ConversationDistance) then
429 | wanderDialog()
430 | end
431 | wait(1)
432 | end
433 | end
434 |
435 | function startDialog(dialog)
436 | if dialog.Parent and dialog.Parent:IsA("BasePart") then
437 | if player:DistanceFromCharacter(dialog.Parent.Position) >= dialog.ConversationDistance then
438 | showMessage(tooFarAwayMessage, tooFarAwaySize)
439 | return
440 | end
441 |
442 | for dialog, gui in pairs(dialogMap) do
443 | if dialog and gui then
444 | gui.Enabled = false
445 | end
446 | end
447 |
448 | renewKillswitch(dialog)
449 |
450 | delay(1, checkForLeaveArea)
451 | doDialog(dialog)
452 | end
453 | end
454 |
455 | function removeDialog(dialog)
456 | if dialogMap[dialog] then
457 | dialogMap[dialog]:Remove()
458 | dialogMap[dialog] = nil
459 | end
460 | if dialogConnections[dialog] then
461 | dialogConnections[dialog]:disconnect()
462 | dialogConnections[dialog] = nil
463 | end
464 | end
465 |
466 | function addDialog(dialog)
467 | if dialog.Parent then
468 | if dialog.Parent:IsA("BasePart") then
469 | local chatGui = chatNotificationGui:clone()
470 | chatGui.Enabled = not dialog.InUse
471 | chatGui.Adornee = dialog.Parent
472 | chatGui.RobloxLocked = true
473 | chatGui.Parent = game.CoreGui
474 | chatGui.Image.Button.MouseButton1Click:connect(function() startDialog(dialog) end)
475 | setChatNotificationTone(chatGui, dialog.Purpose, dialog.Tone)
476 |
477 | dialogMap[dialog] = chatGui
478 |
479 | dialogConnections[dialog] = dialog.Changed:connect(function(prop)
480 | if prop == "Parent" and dialog.Parent then
481 | --This handles the reparenting case, seperate from removal case
482 | removeDialog(dialog)
483 | addDialog(dialog)
484 | elseif prop == "InUse" then
485 | chatGui.Enabled = not currentConversationDialog and not dialog.InUse
486 | if dialog == currentConversationDialog then
487 | timeoutDialog()
488 | end
489 | elseif prop == "Tone" or prop == "Purpose" then
490 | setChatNotificationTone(chatGui, dialog.Purpose, dialog.Tone)
491 | end
492 | end)
493 | else -- still need to listen to parent changes even if current parent is not a BasePart
494 | dialogConnections[dialog] = dialog.Changed:connect(function(prop)
495 | if prop == "Parent" and dialog.Parent then
496 | --This handles the reparenting case, seperate from removal case
497 | removeDialog(dialog)
498 | addDialog(dialog)
499 | end
500 | end)
501 | end
502 | end
503 | end
504 |
505 | function fetchScripts()
506 | local model = game:GetService("InsertService"):LoadAsset(39226062)
507 | if type(model) == "string" then -- load failed, lets try again
508 | wait(0.1)
509 | model = game:GetService("InsertService"):LoadAsset(39226062)
510 | end
511 | if type(model) == "string" then -- not going to work, lets bail
512 | return
513 | end
514 |
515 | waitForChild(model,"TimeoutScript")
516 | timeoutScript = model.TimeoutScript
517 | waitForChild(model,"ReenableDialogScript")
518 | reenableDialogScript = model.ReenableDialogScript
519 | end
520 |
521 | function onLoad()
522 | waitForProperty(game.Players, "LocalPlayer")
523 | player = game.Players.LocalPlayer
524 | waitForProperty(player, "Character")
525 |
526 | --print("Fetching Scripts")
527 | fetchScripts()
528 |
529 | --print("Creating Guis")
530 | createChatNotificationGui()
531 |
532 | --print("Creating MessageDialog")
533 | createMessageDialog()
534 | messageDialog.RobloxLocked = true
535 | messageDialog.Parent = gui
536 |
537 | --print("Waiting for BottomLeftControl")
538 | waitForChild(gui, "BottomLeftControl")
539 |
540 | --print("Initializing Frame")
541 | local frame = Instance.new("Frame")
542 | frame.Name = "DialogFrame"
543 | frame.Position = UDim2.new(0,0,0,0)
544 | frame.Size = UDim2.new(0,0,0,0)
545 | frame.BackgroundTransparency = 1
546 | frame.RobloxLocked = true
547 | frame.Parent = gui.BottomLeftControl
548 | initialize(frame)
549 |
550 | --print("Adding Dialogs")
551 | game.CollectionService.ItemAdded:connect(function(obj) if obj:IsA("Dialog") then addDialog(obj) end end)
552 | game.CollectionService.ItemRemoved:connect(function(obj) if obj:IsA("Dialog") then removeDialog(obj) end end)
553 | for i, obj in pairs(game.CollectionService:GetCollection("Dialog")) do
554 | if obj:IsA("Dialog") then
555 | addDialog(obj)
556 | end
557 | end
558 | end
559 |
560 | onLoad()
--------------------------------------------------------------------------------
/CoreScripts/NotificationScript.lua:
--------------------------------------------------------------------------------
1 | function waitForProperty(instance, property)
2 | while not instance[property] do
3 | instance.Changed:wait()
4 | end
5 | end
6 | function waitForChild(instance, name)
7 | while not instance:FindFirstChild(name) do
8 | instance.ChildAdded:wait()
9 | end
10 | end
11 |
12 | waitForProperty(game.Players,"LocalPlayer")
13 | waitForChild(script.Parent,"Popup")
14 | waitForChild(script.Parent.Popup,"AcceptButton")
15 | script.Parent.Popup.AcceptButton.Modal = true
16 |
17 | local localPlayer = game.Players.LocalPlayer
18 | local teleportUI = nil
19 |
20 | local acceptedTeleport = Instance.new("IntValue")
21 |
22 | local friendRequestBlacklist = {}
23 |
24 | local teleportEnabled = true
25 |
26 | local makePopupInvisible = function()
27 | if script.Parent.Popup then script.Parent.Popup.Visible = false end
28 | end
29 |
30 | function makeFriend(fromPlayer,toPlayer)
31 |
32 | local popup = script.Parent:FindFirstChild("Popup")
33 | if popup == nil then return end -- there is no popup!
34 | if popup.Visible then return end -- currently popping something, abort!
35 | if friendRequestBlacklist[fromPlayer] then return end -- previously cancelled friend request, we don't want it!
36 |
37 | popup.PopupText.Text = "Accept Friend Request from " .. tostring(fromPlayer.Name) .. "?"
38 | popup.PopupImage.Image = "http://www.roblox.com/thumbs/avatar.ashx?userId="..tostring(fromPlayer.userId).."&x=352&y=352"
39 |
40 | showTwoButtons()
41 | popup.Visible = true
42 | popup.AcceptButton.Text = "Accept"
43 | popup.DeclineButton.Text = "Decline"
44 | popup:TweenSize(UDim2.new(0,330,0,350),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true)
45 |
46 | local yesCon, noCon
47 |
48 | yesCon = popup.AcceptButton.MouseButton1Click:connect(function()
49 | popup.Visible = false
50 | toPlayer:RequestFriendship(fromPlayer)
51 | if yesCon then yesCon:disconnect() end
52 | if noCon then noCon:disconnect() end
53 | popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
54 | end)
55 |
56 | noCon = popup.DeclineButton.MouseButton1Click:connect(function()
57 | popup.Visible = false
58 | toPlayer:RevokeFriendship(fromPlayer)
59 | friendRequestBlacklist[fromPlayer] = true
60 | print("pop up blacklist")
61 | if yesCon then yesCon:disconnect() end
62 | if noCon then noCon:disconnect() end
63 | popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
64 | end)
65 | end
66 |
67 |
68 | game.Players.FriendRequestEvent:connect(function(fromPlayer,toPlayer,event)
69 |
70 | -- if this doesn't involve me, then do nothing
71 | if fromPlayer ~= localPlayer and toPlayer ~= localPlayer then return end
72 |
73 | if fromPlayer == localPlayer then
74 | if event == Enum.FriendRequestEvent.Accept then
75 | game:GetService("GuiService"):SendNotification("You are Friends",
76 | "With " .. toPlayer.Name .. "!",
77 | "http://www.roblox.com/thumbs/avatar.ashx?userId="..tostring(toPlayer.userId).."&x=48&y=48",
78 | 5,
79 | function()
80 |
81 | end)
82 | end
83 | elseif toPlayer == localPlayer then
84 | if event == Enum.FriendRequestEvent.Issue then
85 | if friendRequestBlacklist[fromPlayer] then return end -- previously cancelled friend request, we don't want it!
86 | game:GetService("GuiService"):SendNotification("Friend Request",
87 | "From " .. fromPlayer.Name,
88 | "http://www.roblox.com/thumbs/avatar.ashx?userId="..tostring(fromPlayer.userId).."&x=48&y=48",
89 | 8,
90 | function()
91 | makeFriend(fromPlayer,toPlayer)
92 | end)
93 | elseif event == Enum.FriendRequestEvent.Accept then
94 | game:GetService("GuiService"):SendNotification("You are Friends",
95 | "With " .. fromPlayer.Name .. "!",
96 | "http://www.roblox.com/thumbs/avatar.ashx?userId="..tostring(fromPlayer.userId).."&x=48&y=48",
97 | 5,
98 | function()
99 |
100 | end)
101 | end
102 | end
103 | end)
104 |
105 | function showOneButton()
106 | local popup = script.Parent:FindFirstChild("Popup")
107 | if popup then
108 | popup.OKButton.Visible = true
109 | popup.DeclineButton.Visible = false
110 | popup.AcceptButton.Visible = false
111 | end
112 | end
113 |
114 | function showTwoButtons()
115 | local popup = script.Parent:FindFirstChild("Popup")
116 | if popup then
117 | popup.OKButton.Visible = false
118 | popup.DeclineButton.Visible = true
119 | popup.AcceptButton.Visible = true
120 | end
121 | end
122 |
123 | function onTeleport(teleportState, placeId, spawnName)
124 | if game:GetService("TeleportService").CustomizedTeleportUI == false then
125 | if teleportState == Enum.TeleportState.Started then
126 | showTeleportUI("Teleport started...", 0)
127 | elseif teleportState == Enum.TeleportState.WaitingForServer then
128 | showTeleportUI("Requesting server...", 0)
129 | elseif teleportState == Enum.TeleportState.InProgress then
130 | showTeleportUI("Teleporting...", 0)
131 | elseif teleportState == Enum.TeleportState.Failed then
132 | showTeleportUI("Teleport failed. Insufficient privileges or target place does not exist.", 3)
133 | end
134 | end
135 | end
136 |
137 | function showTeleportUI(message, timer)
138 | if teleportUI ~= nil then
139 | teleportUI:Remove()
140 | end
141 | waitForChild(localPlayer, "PlayerGui")
142 | teleportUI = Instance.new("Message", localPlayer.PlayerGui)
143 | teleportUI.Text = message
144 | if timer > 0 then
145 | wait(timer)
146 | teleportUI:Remove()
147 | end
148 | end
149 |
150 | if teleportEnabled then
151 |
152 | localPlayer.OnTeleport:connect(onTeleport)
153 |
154 | game:GetService("TeleportService").ErrorCallback = function(message)
155 | local popup = script.Parent:FindFirstChild("Popup")
156 | showOneButton()
157 | popup.PopupText.Text = message
158 | local clickCon
159 | clickCon = popup.OKButton.MouseButton1Click:connect(function()
160 | game:GetService("TeleportService"):TeleportCancel()
161 | if clickCon then clickCon:disconnect() end
162 | game.GuiService:RemoveCenterDialog(script.Parent:FindFirstChild("Popup"))
163 | popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
164 | end)
165 | game.GuiService:AddCenterDialog(script.Parent:FindFirstChild("Popup"), Enum.CenterDialogType.QuitDialog,
166 | --ShowFunction
167 | function()
168 | showOneButton()
169 | script.Parent:FindFirstChild("Popup").Visible = true
170 | popup:TweenSize(UDim2.new(0,330,0,350),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true)
171 | end,
172 | --HideFunction
173 | function()
174 | popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
175 | end)
176 |
177 | end
178 | game:GetService("TeleportService").ConfirmationCallback = function(message, placeId, spawnName)
179 | local popup = script.Parent:FindFirstChild("Popup")
180 | popup.PopupText.Text = message
181 | popup.PopupImage.Image = ""
182 |
183 | local yesCon, noCon
184 |
185 | local function killCons()
186 | if yesCon then yesCon:disconnect() end
187 | if noCon then noCon:disconnect() end
188 | game.GuiService:RemoveCenterDialog(script.Parent:FindFirstChild("Popup"))
189 | popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
190 | end
191 |
192 | yesCon = popup.AcceptButton.MouseButton1Click:connect(function()
193 | killCons()
194 | local success, err = pcall(function() game:GetService("TeleportService"):TeleportImpl(placeId,spawnName) end)
195 | if not success then
196 | showOneButton()
197 | popup.PopupText.Text = err
198 | local clickCon
199 | clickCon = popup.OKButton.MouseButton1Click:connect(function()
200 | if clickCon then clickCon:disconnect() end
201 | game.GuiService:RemoveCenterDialog(script.Parent:FindFirstChild("Popup"))
202 | popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
203 | end)
204 | game.GuiService:AddCenterDialog(script.Parent:FindFirstChild("Popup"), Enum.CenterDialogType.QuitDialog,
205 | --ShowFunction
206 | function()
207 | showOneButton()
208 | script.Parent:FindFirstChild("Popup").Visible = true
209 | popup:TweenSize(UDim2.new(0,330,0,350),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true)
210 | end,
211 | --HideFunction
212 | function()
213 | popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
214 | end)
215 | end
216 | end)
217 |
218 | noCon = popup.DeclineButton.MouseButton1Click:connect(function()
219 | killCons()
220 | local success = pcall(function() game:GetService("TeleportService"):TeleportCancel() end)
221 | end)
222 |
223 | local centerDialogSuccess = pcall(function() game.GuiService:AddCenterDialog(script.Parent:FindFirstChild("Popup"), Enum.CenterDialogType.QuitDialog,
224 | --ShowFunction
225 | function()
226 | showTwoButtons()
227 | popup.AcceptButton.Text = "Leave"
228 | popup.DeclineButton.Text = "Stay"
229 | script.Parent:FindFirstChild("Popup").Visible = true
230 | popup:TweenSize(UDim2.new(0,330,0,350),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true)
231 | end,
232 | --HideFunction
233 | function()
234 | popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
235 | end)
236 | end)
237 |
238 | if centerDialogSuccess == false then
239 | script.Parent:FindFirstChild("Popup").Visible = true
240 | popup.AcceptButton.Text = "Leave"
241 | popup.DeclineButton.Text = "Stay"
242 | popup:TweenSize(UDim2.new(0,330,0,350),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true)
243 | end
244 | return true
245 |
246 | end
247 | end
248 |
249 | game:GetService("MarketplaceService").ClientLuaDialogRequested:connect(function(message, accept, decline)
250 | local popup = script.Parent:FindFirstChild("Popup")
251 | popup.PopupText.Text = message
252 | popup.PopupImage.Image = ""
253 |
254 | local yesCon, noCon
255 |
256 | local function killCons()
257 | if yesCon then yesCon:disconnect() end
258 | if noCon then noCon:disconnect() end
259 | game.GuiService:RemoveCenterDialog(script.Parent:FindFirstChild("Popup"))
260 | popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
261 | end
262 |
263 | yesCon = popup.AcceptButton.MouseButton1Click:connect(function()
264 | killCons()
265 | game:GetService("MarketplaceService"):SignalServerLuaDialogClosed(true);
266 | end)
267 |
268 | noCon = popup.DeclineButton.MouseButton1Click:connect(function()
269 | killCons()
270 | game:GetService("MarketplaceService"):SignalServerLuaDialogClosed(false);
271 | end)
272 |
273 | local centerDialogSuccess = pcall(function() game.GuiService:AddCenterDialog(script.Parent:FindFirstChild("Popup"), Enum.CenterDialogType.QuitDialog,
274 | function()
275 | showTwoButtons()
276 | popup.AcceptButton.Text = accept
277 | popup.DeclineButton.Text = decline
278 | script.Parent:FindFirstChild("Popup").Visible = true
279 | popup:TweenSize(UDim2.new(0,330,0,350),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true)
280 | end,
281 | function()
282 | popup:TweenSize(UDim2.new(0,0,0,0),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true,makePopupInvisible())
283 | end)
284 | end)
285 |
286 | if centerDialogSuccess == false then
287 | script.Parent:FindFirstChild("Popup").Visible = true
288 | popup.AcceptButton.Text = accept
289 | popup.DeclineButton.Text = decline
290 | popup:TweenSize(UDim2.new(0,330,0,350),Enum.EasingDirection.Out,Enum.EasingStyle.Quart,1,true)
291 | end
292 |
293 | return true
294 |
295 | end)
--------------------------------------------------------------------------------
/CoreScripts/PlaceConsoleScript.lua:
--------------------------------------------------------------------------------
1 | -- a couple neccessary functions
2 | local function waitForChild(instance, name)
3 | while not instance:FindFirstChild(name) do
4 | instance.ChildAdded:wait()
5 | end
6 | end
7 | local function waitForProperty(instance, prop)
8 | while not instance[prop] do
9 | instance.Changed:wait()
10 | end
11 | end
12 |
13 |
14 |
15 |
16 | function securityCheck()
17 | local allowedUserIds = {--[[game.CreatorId,]]7210880}
18 |
19 | local canUsePanel = false
20 | local localUserId = game.Players.LocalPlayer.userId
21 | for i = 1, #allowedUserIds do
22 | if localUserId == allowedUserIds[i] then
23 | canUsePanel = true
24 | break
25 | end
26 | end
27 |
28 | if not canUsePanel then
29 | script:remove()
30 | end
31 | end
32 |
33 |
34 |
35 | function createGui()
36 | local adminStatsFrame = Instance.new("Frame")
37 | adminStatsFrame.RobloxLocked = true
38 | adminStatsFrame.Name = "AdminStatsFrame"
39 | adminStatsFrame.Active = true
40 | adminStatsFrame.Draggable = true
41 | adminStatsFrame.Position = UDim2.new(0.2,20,0,0)
42 | adminStatsFrame.Size = UDim2.new(0.6,-40,1,0)
43 | adminStatsFrame.Style = Enum.FrameStyle.RobloxRound
44 | adminStatsFrame.Parent = script.Parent
45 |
46 | -- AdminStatsFrame Children
47 | local adminStatsTextLabel = Instance.new("TextLabel")
48 | adminStatsTextLabel.RobloxLocked = true
49 | adminStatsTextLabel.Name = "AdminStatsTextLabel"
50 | adminStatsTextLabel.BackgroundTransparency = 1
51 | adminStatsTextLabel.Font = Enum.Font.ArialBold
52 | adminStatsTextLabel.FontSize = Enum.FontSize.Size24
53 | adminStatsTextLabel.Size = UDim2.new(1,0,0,24)
54 | adminStatsTextLabel.Text = "Place Console"
55 | adminStatsTextLabel.TextColor3 = Color3.new(1,1,1)
56 | adminStatsTextLabel.TextYAlignment = Enum.TextYAlignment.Center
57 | adminStatsTextLabel.Parent = adminStatsFrame
58 |
59 | local errorPanel = Instance.new("Frame")
60 | errorPanel.RobloxLocked = true
61 | errorPanel.Name = "ErrorPanel"
62 | errorPanel.Position = UDim2.new(0,0,0.5,0)
63 | errorPanel.Size = UDim2.new(1,0,0.5,0)
64 | errorPanel.Style = Enum.FrameStyle.RobloxRound
65 | errorPanel.Parent = adminStatsFrame
66 |
67 | -- ErrorPanel Children
68 | local textPanel = Instance.new("Frame")
69 | textPanel.RobloxLocked = true
70 | textPanel.Name = "TextPanel"
71 | textPanel.Position = UDim2.new(0,0,0,18)
72 | textPanel.Size = UDim2.new(1,0,1,-18)
73 | textPanel.BackgroundTransparency = 1
74 | textPanel.Parent = errorPanel
75 |
76 | local errorPanelTextLabel = Instance.new("TextLabel")
77 | errorPanelTextLabel.RobloxLocked = true
78 | errorPanelTextLabel.Name = "ErrorPanelTextLabel"
79 | errorPanelTextLabel.Font = Enum.Font.ArialBold
80 | errorPanelTextLabel.FontSize = Enum.FontSize.Size18
81 | errorPanelTextLabel.Size = UDim2.new(1,0,0,18)
82 | errorPanelTextLabel.BackgroundTransparency = 1
83 | errorPanelTextLabel.TextColor3 = Color3.new(1,1,1)
84 | errorPanelTextLabel.Text = "Lua Errors"
85 | errorPanelTextLabel.Parent = errorPanel
86 |
87 | local sampleError = Instance.new("TextLabel")
88 | sampleError.RobloxLocked = true
89 | sampleError.Name = "SampleError"
90 | sampleError.Font = Enum.Font.Arial
91 | sampleError.FontSize = Enum.FontSize.Size12
92 | sampleError.Size = UDim2.new(1,0,0,12)
93 | sampleError.BackgroundTransparency = 0.5
94 | sampleError.TextColor3 = Color3.new(1,1,1)
95 | sampleError.Text = "Thu May 19 12:37:09 2011 - Players.Player.Backpack.StamperTool.GuiScript:1199: attempt to index field '?' (a nil value)"
96 | sampleError.TextWrap = true
97 | sampleError.TextXAlignment = Enum.TextXAlignment.Left
98 | sampleError.TextYAlignment = Enum.TextYAlignment.Top
99 | sampleError.Visible = false
100 | sampleError.Parent = errorPanel
101 |
102 | local playerStatsFrame = Instance.new("Frame")
103 | playerStatsFrame.RobloxLocked = true
104 | playerStatsFrame.Name = "PlayerStatsFrame"
105 | playerStatsFrame.BackgroundTransparency = 1
106 | playerStatsFrame.Position = UDim2.new(0,0,0,24)
107 | playerStatsFrame.Size = UDim2.new(0,200,0,100)
108 | playerStatsFrame.Style = Enum.FrameStyle.RobloxRound
109 | playerStatsFrame.Parent = adminStatsFrame
110 |
111 | local playerStatsTextInfo = Instance.new("TextLabel")
112 | playerStatsTextInfo.Name = "PlayerStatsTextInfo"
113 | playerStatsTextInfo.BackgroundTransparency = 1
114 | playerStatsTextInfo.Font = Enum.Font.ArialBold
115 | playerStatsTextInfo.FontSize = Enum.FontSize.Size14
116 | playerStatsTextInfo.Size = UDim2.new(1,0,1,0)
117 | playerStatsTextInfo.Text = ""
118 | playerStatsTextInfo.TextColor3 = Color3.new(1,1,1)
119 | playerStatsTextInfo.TextYAlignment = Enum.TextYAlignment.Top
120 |
121 | local smallFrame = Instance.new("Frame")
122 | smallFrame.BackgroundTransparency = 1
123 | smallFrame.Size = UDim2.new(1,0,0,14)
124 |
125 | -- PlayerStatsFrame Children
126 | local avgPlayerTimeFrame = smallFrame:clone()
127 | avgPlayerTimeFrame.RobloxLocked = true
128 | avgPlayerTimeFrame.Name = "AvgPlayerTimeFrame"
129 | avgPlayerTimeFrame.Position = UDim2.new(0,0,0,46)
130 | local newTextInfo = playerStatsTextInfo:clone()
131 | newTextInfo.RobloxLocked = true
132 | newTextInfo.Text = "Avg. Play Time: 0"
133 | newTextInfo.Parent = avgPlayerTimeFrame
134 | avgPlayerTimeFrame.Parent = playerStatsFrame
135 |
136 | local joinFrame = smallFrame:clone()
137 | joinFrame.RobloxLocked = true
138 | joinFrame.Name = "JoinFrame"
139 | joinFrame.Position = UDim2.new(0,0,0,18)
140 | local newTextInfo = playerStatsTextInfo:clone()
141 | newTextInfo.RobloxLocked = true
142 | newTextInfo.Text = "# of Joins: 0"
143 | newTextInfo.Parent = joinFrame
144 | joinFrame.Parent = playerStatsFrame
145 |
146 | local leaveFrame = smallFrame:clone()
147 | leaveFrame.RobloxLocked = true
148 | leaveFrame.Name = "LeaveFrame"
149 | leaveFrame.Position = UDim2.new(0,0,0,32)
150 | local newTextInfo = playerStatsTextInfo:clone()
151 | newTextInfo.RobloxLocked = true
152 | newTextInfo.Text = "# of Leaves: 0"
153 | newTextInfo.Parent = leaveFrame
154 | leaveFrame.Parent = playerStatsFrame
155 |
156 | local uniqueVisitorsFrame = smallFrame:clone()
157 | uniqueVisitorsFrame.RobloxLocked = true
158 | uniqueVisitorsFrame.Name = "UniqueVisitorsFrame"
159 | uniqueVisitorsFrame.Position = UDim2.new(0,0,0,60)
160 | local newTextInfo = playerStatsTextInfo:clone()
161 | newTextInfo.RobloxLocked = true
162 | newTextInfo.Text = "# of Unique Visits: 0"
163 | newTextInfo.Parent = uniqueVisitorsFrame
164 | uniqueVisitorsFrame.Parent = playerStatsFrame
165 |
166 | local textHeader = playerStatsTextInfo:clone()
167 | textHeader.Name = "PlayerStatsTextLabel"
168 | textHeader.RobloxLocked = true
169 | textHeader.FontSize = Enum.FontSize.Size18
170 | textHeader.Size = UDim2.new(1,0,0,18)
171 | textHeader.Text = "Player Stats"
172 | textHeader.TextYAlignment = Enum.TextYAlignment.Center
173 | textHeader.Parent = playerStatsFrame
174 |
175 | -- Script Stats Frame
176 | local scriptStatsFrame = playerStatsFrame:clone()
177 | scriptStatsFrame.RobloxLocked = true
178 | scriptStatsFrame.Name = "ScriptStatsFrame"
179 | scriptStatsFrame.Position = UDim2.new(0,0,0,126)
180 | scriptStatsFrame.PlayerStatsTextLabel.Name = "ScriptStatsTextLabel"
181 | scriptStatsFrame.ScriptStatsTextLabel.Text = "Lua Stats"
182 | scriptStatsFrame.JoinFrame.Name = "ScriptErrorsFrame"
183 | scriptStatsFrame.ScriptErrorsFrame.PlayerStatsTextInfo.Name = "ScriptErrorsTextInfo"
184 | scriptStatsFrame.ScriptErrorsFrame.ScriptErrorsTextInfo.Text = "# of Lua Errors: 0"
185 | scriptStatsFrame.LeaveFrame.Name = "ScriptWarningFrame"
186 | scriptStatsFrame.ScriptWarningFrame.PlayerStatsTextInfo.Name = "ScriptWarningTextInfo"
187 | scriptStatsFrame.ScriptWarningFrame.ScriptWarningTextInfo.Text = "# of Lua Warnings: 0"
188 | scriptStatsFrame.AvgPlayerTimeFrame.Name = "ScriptsRunningFrame"
189 | scriptStatsFrame.ScriptsRunningFrame.PlayerStatsTextInfo.Name = "ScriptsRunningInfo"
190 | scriptStatsFrame.ScriptsRunningFrame.ScriptsRunningInfo.Text = "# Scripts Running: 0"
191 | scriptStatsFrame.UniqueVisitorsFrame:remove()
192 | scriptStatsFrame.Parent = adminStatsFrame
193 |
194 |
195 | -- UptimeFrame
196 | local upTimeFrame = Instance.new("Frame")
197 | upTimeFrame.RobloxLocked = true
198 | upTimeFrame.Name = "UptimeFrame"
199 | upTimeFrame.BackgroundTransparency = 1
200 | upTimeFrame.Position = UDim2.new(1,-200,0,24)
201 | upTimeFrame.Size = UDim2.new(0,200,0,100)
202 | upTimeFrame.Style = Enum.FrameStyle.RobloxRound
203 | upTimeFrame.Parent = adminStatsFrame
204 |
205 | -- UptimeFrame Children
206 | local secondsUpTimeTextInfo = Instance.new("TextLabel")
207 | secondsUpTimeTextInfo.RobloxLocked = true
208 | secondsUpTimeTextInfo.Name = "SecondsUptimeTextInfo"
209 | secondsUpTimeTextInfo.Font = Enum.Font.ArialBold
210 | secondsUpTimeTextInfo.FontSize = Enum.FontSize.Size14
211 | secondsUpTimeTextInfo.Position = UDim2.new(0,0,0.5,18)
212 | secondsUpTimeTextInfo.Size = UDim2.new(1,0,0.5,-18)
213 | secondsUpTimeTextInfo.Text = "0 Total Seconds"
214 | secondsUpTimeTextInfo.BackgroundTransparency = 1
215 | secondsUpTimeTextInfo.TextColor3 = Color3.new(1,1,1)
216 | secondsUpTimeTextInfo.TextYAlignment = Enum.TextYAlignment.Top
217 | secondsUpTimeTextInfo.Parent = upTimeFrame
218 |
219 | local uptimeTextInfo = secondsUpTimeTextInfo:clone()
220 | uptimeTextInfo.RobloxLocked = true
221 | uptimeTextInfo.Name = "UptimeTextInfo"
222 | uptimeTextInfo.Position = UDim2.new(0,0,0,18)
223 | uptimeTextInfo.Size = UDim2.new(1,0,0.5,0)
224 | uptimeTextInfo.TextWrap = true
225 | uptimeTextInfo.Text = "0 Days, 0 Hours, 0 Minutes, 0 Seconds"
226 | uptimeTextInfo.Parent = upTimeFrame
227 |
228 | local upTimeTextLabel = uptimeTextInfo:clone()
229 | upTimeTextLabel.RobloxLocked = true
230 | upTimeTextLabel.Name = "UptimeTextLabel"
231 | upTimeTextLabel.FontSize = Enum.FontSize.Size18
232 | upTimeTextLabel.Size = UDim2.new(1,0,0,18)
233 | upTimeTextLabel.Position = UDim2.new(0,0,0,0)
234 | upTimeTextLabel.Text = "Instance Uptime"
235 | upTimeTextLabel.TextYAlignment = Enum.TextYAlignment.Center
236 | upTimeTextLabel.Parent = upTimeFrame
237 | end
238 |
239 |
240 |
241 | -- functions
242 | function initLocals()
243 | -- Top Gui Layer
244 | adminGui = script.Parent
245 | adminFrame = adminGui.AdminStatsFrame
246 |
247 | -- Second Gui Layer
248 | upTimeFrame = adminFrame.UptimeFrame
249 | errorFrame = adminFrame.ErrorPanel
250 | playerStatsFrame = adminFrame.PlayerStatsFrame
251 | scriptStatsFrame = adminFrame.ScriptStatsFrame
252 |
253 | -- UptimeFrame Children
254 | upTimeFormattedText = upTimeFrame.UptimeTextInfo
255 | upTimeSecondsText = upTimeFrame.SecondsUptimeTextInfo
256 |
257 | -- PlayerStatsFrame Children
258 | avgPlayTimeText = playerStatsFrame.AvgPlayerTimeFrame.PlayerStatsTextInfo
259 | joinText = playerStatsFrame.JoinFrame.PlayerStatsTextInfo
260 | leaveText = playerStatsFrame.LeaveFrame.PlayerStatsTextInfo
261 | uniqueVisitorText = playerStatsFrame.UniqueVisitorsFrame.PlayerStatsTextInfo
262 |
263 |
264 | uniqueUserIds = {}
265 | playTimes = {}
266 |
267 | avgPlayTime = 0
268 | placeVisits = 0
269 | placeLeaves = 0
270 | end
271 |
272 | function updateUptime()
273 | local currentTime = game.Workspace.DistributedGameTime
274 |
275 | upTimeSecondsText.Text = tostring(math.floor(currentTime)) .. " Total Seconds"
276 |
277 | local days = math.floor(currentTime/86400)
278 | currentTime = currentTime - (days * 86400)
279 |
280 | local hours = math.floor(currentTime/3600)
281 | currentTime = currentTime - (hours * 3600)
282 |
283 | local minutes = math.floor(currentTime/60)
284 | currentTime = currentTime - (minutes * 60)
285 |
286 | currentTime = math.floor(currentTime)
287 |
288 | upTimeFormattedText.Text = tostring(days) .. " Days, " .. tostring(hours) .. " Hours, " .. tostring(minutes) .. " Minutes, " .. tostring(currentTime) .. (" Seconds")
289 | end
290 |
291 |
292 | function playerJoined(addedPlayer)
293 | placeVisits = placeVisits + 1
294 | joinText.Text = "# of Joins: " .. tostring(placeVisits)
295 | if uniqueUserIds[addedPlayer] == nil then
296 | uniqueUserIds[addedPlayer] = addedPlayer.userId
297 | uniqueVisitorText.Text = "#of Unique Visits: " .. tostring(#uniqueUserIds)
298 | end
299 |
300 | playTimes[addedPlayer] = game.Workspace.DistributedGameTime
301 | end
302 |
303 | function recalculateAvgPlayTime(removedPlayer)
304 | if playTimes[removedPlayer] then
305 | local playerPlayTime = game.Workspace.DistributedGameTime - playTimes[removedPlayer]
306 | avgPlayTime = ( ((placesLeaves - 1)/placeLeaves) * avgPlayTime ) + ( (1/placeLeaves) * playerPlayTime )
307 | avgPlayTimeText.Text = "Avg. Play Time: " .. tostring(math.floor(avgPlayTime))
308 | end
309 | end
310 |
311 | function playerLeft(removedPlayer)
312 | placeLeaves = placeLeaves + 1
313 | leaveText.Text = "# of Leaves: " .. tostring(placeLeaves)
314 |
315 | recalculateAvgPlayTime(removedPlayer)
316 | end
317 |
318 |
319 | function uptimeLoop()
320 | while true do
321 | updateUptime()
322 | wait(1)
323 | end
324 | end
325 |
326 | function playerAddedFunction(player)
327 | if player == game.Players.LocalPlayer then
328 | securityCheck()
329 | createGui()
330 | initLocals()
331 | adminFrame.Visible = true
332 | uptimeLoop()
333 | end
334 | playerJoined(addedPlayer)
335 | end
336 |
337 | -- Script Start
338 |
339 | -- Check to see if we already have players
340 | local playersChildren = game.Players:GetChildren()
341 | for i = 1, #playersChildren do
342 | if playersChildren[i]:IsA("Player") then
343 | playerAddedFunction(playersChildren[i])
344 | end
345 | end
346 |
347 | -- Listen for players now
348 | game.Players.PlayerAdded:connect(function(addedPlayer) playerAddedFunction(addedPlayer) end)
349 | game.Players.PlayerRemoving:connect(function(removedPlayer) playerLeft(removedPlayer) end)
--------------------------------------------------------------------------------
/CoreScripts/PopupScript.lua:
--------------------------------------------------------------------------------
1 | --build our gui
2 |
3 | local popupFrame = Instance.new("Frame")
4 | popupFrame.Position = UDim2.new(0.5,-165,0.5,-175)
5 | popupFrame.Size = UDim2.new(0,330,0,350)
6 | popupFrame.Style = Enum.FrameStyle.RobloxRound
7 | popupFrame.ZIndex = 4
8 | popupFrame.Name = "Popup"
9 | popupFrame.Visible = false
10 | popupFrame.Parent = script.Parent
11 |
12 | local darken = popupFrame:clone()
13 | darken.Size = UDim2.new(1,16,1,16)
14 | darken.Position = UDim2.new(0,-8,0,-8)
15 | darken.Name = "Darken"
16 | darken.ZIndex = 1
17 | darken.Parent = popupFrame
18 |
19 | local acceptButton = Instance.new("TextButton")
20 | acceptButton.Position = UDim2.new(0,20,0,270)
21 | acceptButton.Size = UDim2.new(0,100,0,50)
22 | acceptButton.Font = Enum.Font.ArialBold
23 | acceptButton.FontSize = Enum.FontSize.Size24
24 | acceptButton.Style = Enum.ButtonStyle.RobloxButton
25 | acceptButton.TextColor3 = Color3.new(248/255,248/255,248/255)
26 | acceptButton.Text = "Yes"
27 | acceptButton.ZIndex = 5
28 | acceptButton.Name = "AcceptButton"
29 | acceptButton.Parent = popupFrame
30 |
31 | local declineButton = acceptButton:clone()
32 | declineButton.Position = UDim2.new(1,-120,0,270)
33 | declineButton.Text = "No"
34 | declineButton.Name = "DeclineButton"
35 | declineButton.Parent = popupFrame
36 |
37 | local okButton = acceptButton:clone()
38 | okButton.Name = "OKButton"
39 | okButton.Text = "OK"
40 | okButton.Position = UDim2.new(0.5,-50,0,270)
41 | okButton.Visible = false
42 | okButton.Parent = popupFrame
43 |
44 | local popupImage = Instance.new("ImageLabel")
45 | popupImage.BackgroundTransparency = 1
46 | popupImage.Position = UDim2.new(0.5,-140,0,0)
47 | popupImage.Size = UDim2.new(0,280,0,280)
48 | popupImage.ZIndex = 3
49 | popupImage.Name = "PopupImage"
50 | popupImage.Parent = popupFrame
51 |
52 | local backing = Instance.new("ImageLabel")
53 | backing.BackgroundTransparency = 1
54 | backing.Size = UDim2.new(1,0,1,0)
55 | backing.Image = "http://www.roblox.com/asset/?id=47574181"
56 | backing.Name = "Backing"
57 | backing.ZIndex = 2
58 | backing.Parent = popupImage
59 |
60 | local popupText = Instance.new("TextLabel")
61 | popupText.Name = "PopupText"
62 | popupText.Size = UDim2.new(1,0,0.8,0)
63 | popupText.Font = Enum.Font.ArialBold
64 | popupText.FontSize = Enum.FontSize.Size36
65 | popupText.BackgroundTransparency = 1
66 | popupText.Text = "Hello I'm a popup"
67 | popupText.TextColor3 = Color3.new(248/255,248/255,248/255)
68 | popupText.TextWrap = true
69 | popupText.ZIndex = 5
70 | popupText.Parent = popupFrame
71 |
72 | script:remove()
--------------------------------------------------------------------------------
/CoreScripts/RBXStatusBuffsGUIScript.lua:
--------------------------------------------------------------------------------
1 | local vChar = script.Parent
2 | local vPlayer = game.Players:GetPlayerFromCharacter(vChar)
3 | playerGui = vPlayer.PlayerGui
4 |
5 | local config = vChar:FindFirstChild("PlayerStats")
6 | while config == nil do
7 | config = vChar:FindFirstChild("PlayerStats")
8 | wait()
9 | end
10 |
11 | buffGui = Instance.new("ScreenGui")
12 | buffGui.Parent = playerGui
13 | buffGui.Name = "BuffGUI"
14 |
15 | tray = Instance.new("Frame")
16 | tray.BackgroundTransparency = 1.0
17 | tray.Parent = buffGui
18 | tray.Name = "Tray"
19 | tray.Position = UDim2.new(0.40, 0.0, 0.95, 0.0)
20 | tray.Size = UDim2.new(0.0, 300.0, 0.0, 30.0)
21 | tray.BorderColor3 = Color3.new(0, 0, 0)
22 | tray.Visible = true
23 |
24 | local iceLabel = Instance.new("ImageLabel")
25 | iceLabel.Name = "Ice"
26 | iceLabel.Size = UDim2.new(0.1, 0.0, 0.8, 0.0)
27 | iceLabel.BackgroundTransparency = 1.0
28 | iceLabel.Image = "http://www.roblox.com/asset/?id=47522829"
29 | iceLabel.Visible = true
30 |
31 | local poisonLabel = Instance.new("ImageLabel")
32 | poisonLabel.Name = "Poison"
33 | poisonLabel.Size = UDim2.new(0.1, 0.0, 0.8, 0.0)
34 | poisonLabel.BackgroundTransparency = 1.0
35 | poisonLabel.Image = "http://www.roblox.com/asset/?id=47525343"
36 | poisonLabel.Visible = true
37 |
38 | local fireLabel = Instance.new("ImageLabel")
39 | fireLabel.Name = "Fire"
40 | fireLabel.Size = UDim2.new(0.1, 0.0, 0.8, 0.0)
41 | fireLabel.BackgroundTransparency = 1.0
42 | fireLabel.Image = "http://www.roblox.com/asset/?id=47522853"
43 | fireLabel.Visible = true
44 |
45 | local stunLabel = Instance.new("ImageLabel")
46 | stunLabel.Name = "Stun"
47 | stunLabel.Size = UDim2.new(0.1, 0.0, 0.8, 0.0)
48 | stunLabel.BackgroundTransparency = 1.0
49 | stunLabel.Image = "http://www.roblox.com/asset/?id= 47522868"
50 | stunLabel.Visible = true
51 |
52 | -- The table that contains the list of all the status buff images
53 | local labels = {poisonLabel, iceLabel, fireLabel, stunLabel}
54 |
55 | -- Contains the list of active Labels to draw them
56 | local activeLabels = {}
57 |
58 | -- Copies the necessary labels
59 | local buffsGuiTable = {
60 | ["Speed"] = function ()
61 | end,
62 | ["MaxHealth"] = function ()
63 | end,
64 | ["Poison"] = function ()
65 | table.insert(activeLabels, labels[1])
66 | end,
67 | ["Ice"] = function()
68 | table.insert(activeLabels, labels[2])
69 | end,
70 | ["Fire"] = function()
71 | table.insert(activeLabels, labels[3])
72 | end,
73 | ["Stun"] = function()
74 | table.insert(activeLabels, labels[4])
75 | end
76 | }
77 |
78 | function statusBuffGui()
79 | activeLabels = {}
80 | for a = 1, #labels do
81 | labels[a].Active = false
82 | labels[a].Visible = false
83 | end
84 | activeBuffs = config:GetChildren()
85 | print(#buffsGuiTable)
86 | print(#activeBuffs)
87 | if #activeBuffs > 2 then
88 | for i = 1, #activeBuffs do
89 | print(activeBuffs[i].Name)
90 | buffsGuiTable[activeBuffs[i].Name]()
91 | end
92 | print(#activeLabels)
93 | if #activeLabels > 0 then
94 | count = 0
95 | parity = 1
96 | median = 0.45
97 | if #activeLabels%2 == 0 then median = .5 end
98 | for j = 1, #activeLabels do
99 | activeLabels[j].Position = UDim2.new(median + parity*count, 0.0, 0.0, 0.0)
100 | if j%2 == 1 then count = count + .1 end
101 | parity = parity * -1
102 | activeLabels[j].Parent = tray
103 | activeLabels.Active = true
104 | end
105 | end
106 | end
107 | end
108 |
109 | -- Blinking Labels
110 |
111 | function blinkGui()
112 | while true do
113 | for n = 1, #activeLabels do
114 | activeLabels[n].Visible = not activeLabels[n].Visible
115 | end
116 | wait(0.5)
117 | end
118 | end
119 |
120 | blink = coroutine.create(blinkGui)
121 | coroutine.resume(blink)
122 |
123 | -- Event Listeners
124 | config.ChildAdded:connect(statusBuffGui)
125 | config.ChildRemoved:connect(statusBuffGui)
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
--------------------------------------------------------------------------------
/CoreScripts/Sections.lua:
--------------------------------------------------------------------------------
1 | settings().FastLogSettings:SetGroupEnable("Network", 1, true)
2 | settings().FastLogSettings:SetGroupEnable("MegaClusterNetwork", 1, true)
3 | settings().FastLogSettings:SetGroupEnable("MegaClusterNetworkInit", 1, true)
--------------------------------------------------------------------------------
/CoreScripts/SubMenuBuilder.lua:
--------------------------------------------------------------------------------
1 | -- creates the in-game gui sub menus for property tools
2 | -- written 9/27/2010 by Ben (jeditkacheff)
3 |
4 | local gui = script.Parent
5 | if gui:FindFirstChild("ControlFrame") then
6 | gui = gui:FindFirstChild("ControlFrame")
7 | end
8 |
9 | local currentlySelectedButton = nil
10 |
11 | local localAssetBase = "rbxasset://textures/ui/"
12 |
13 | local selectedButton = Instance.new("ObjectValue")
14 | selectedButton.RobloxLocked = true
15 | selectedButton.Name = "SelectedButton"
16 | selectedButton.Parent = gui.BuildTools
17 |
18 | local closeButton = Instance.new("ImageButton")
19 | closeButton.Name = "CloseButton"
20 | closeButton.RobloxLocked = true
21 | closeButton.BackgroundTransparency = 1
22 | closeButton.Image = localAssetBase .. "CloseButton.png"
23 | closeButton.ZIndex = 2
24 | closeButton.Size = UDim2.new(0.2,0,0.05,0)
25 | closeButton.AutoButtonColor = false
26 | closeButton.Position = UDim2.new(0.75,0,0.01,0)
27 |
28 |
29 |
30 | function setUpCloseButtonState(button)
31 |
32 | button.MouseEnter:connect(function()
33 | button.Image = localAssetBase .. "CloseButton_dn.png"
34 | end)
35 | button.MouseLeave:connect(function()
36 | button.Image = localAssetBase .. "CloseButton.png"
37 | end)
38 | button.MouseButton1Click:connect(function()
39 | button.ClosedState.Value = true
40 | button.Image = localAssetBase .. "CloseButton.png"
41 | end)
42 |
43 | end
44 |
45 | -- nice selection animation
46 | function fadeInButton(button)
47 |
48 | if currentlySelectedButton ~= nil then
49 | currentlySelectedButton.Selected = false
50 | currentlySelectedButton.ZIndex = 2
51 | currentlySelectedButton.Frame.BackgroundTransparency = 1
52 | end
53 |
54 | local speed = 0.1
55 | button.ZIndex = 3
56 | while button.Frame.BackgroundTransparency > 0 do
57 | button.Frame.BackgroundTransparency = button.Frame.BackgroundTransparency - speed
58 | wait()
59 | end
60 | button.Selected = true
61 |
62 | currentlySelectedButton = button
63 | selectedButton.Value = currentlySelectedButton
64 | end
65 |
66 | ------------------------------- create the color selection sub menu -----------------------------------
67 |
68 | local paintMenu = Instance.new("ImageLabel")
69 | local paintTool = gui.BuildTools.Frame.PropertyTools.PaintTool
70 | paintMenu.Name = "PaintMenu"
71 | paintMenu.RobloxLocked = true
72 | paintMenu.Parent = paintTool
73 | paintMenu.Position = UDim2.new(-2.7,0,-3,0)
74 | paintMenu.Size = UDim2.new(2.5,0,10,0)
75 | paintMenu.BackgroundTransparency = 1
76 | paintMenu.ZIndex = 2
77 | paintMenu.Image = localAssetBase .. "PaintMenu.png"
78 |
79 | local paintColorButton = Instance.new("ImageButton")
80 | paintColorButton.RobloxLocked = true
81 | paintColorButton.BorderSizePixel = 0
82 | paintColorButton.ZIndex = 2
83 | paintColorButton.Size = UDim2.new(0.200000003, 0,0.0500000007, 0)
84 |
85 | local selection = Instance.new("Frame")
86 | selection.RobloxLocked = true
87 | selection.BorderSizePixel = 0
88 | selection.BackgroundColor3 = Color3.new(1,1,1)
89 | selection.BackgroundTransparency = 1
90 | selection.ZIndex = 2
91 | selection.Size = UDim2.new(1.1,0,1.1,0)
92 | selection.Position = UDim2.new(-0.05,0,-0.05,0)
93 | selection.Parent = paintColorButton
94 |
95 | local header = 0.08
96 | local spacing = 18
97 |
98 | local count = 1
99 |
100 | function findNextColor()
101 | colorName = tostring(BrickColor.new(count))
102 | while colorName == "Medium stone grey" do
103 | count = count + 1
104 | colorName = tostring(BrickColor.new(count))
105 | end
106 | return count
107 | end
108 |
109 | for i = 0,15 do
110 | for j = 1, 4 do
111 | newButton = paintColorButton:clone()
112 | newButton.RobloxLocked = true
113 | newButton.BackgroundColor3 = BrickColor.new(findNextColor()).Color
114 | newButton.Name = tostring(BrickColor.new(count))
115 | count = count + 1
116 | if j == 1 then newButton.Position = UDim2.new(0.08,0,i/spacing + header,0)
117 | elseif j == 2 then newButton.Position = UDim2.new(0.29,0,i/spacing + header,0)
118 | elseif j == 3 then newButton.Position = UDim2.new(0.5,0,i/spacing + header,0)
119 | elseif j == 4 then newButton.Position = UDim2.new(0.71,0,i/spacing + header,0) end
120 | newButton.Parent = paintMenu
121 | end
122 | end
123 |
124 | local paintButtons = paintMenu:GetChildren()
125 | for i = 1, #paintButtons do
126 | paintButtons[i].MouseButton1Click:connect(function()
127 | fadeInButton(paintButtons[i])
128 | end)
129 | end
130 |
131 | local paintCloseButton = closeButton:clone()
132 | paintCloseButton.RobloxLocked = true
133 | paintCloseButton.Parent = paintMenu
134 |
135 | local closedState = Instance.new("BoolValue")
136 | closedState.RobloxLocked = true
137 | closedState.Name = "ClosedState"
138 | closedState.Parent = paintCloseButton
139 |
140 | setUpCloseButtonState(paintCloseButton)
141 |
142 | ------------------------------- create the material selection sub menu -----------------------------------
143 |
144 | local materialMenu = Instance.new("ImageLabel")
145 | local materialTool = gui.BuildTools.Frame.PropertyTools.MaterialSelector
146 | materialMenu.RobloxLocked = true
147 | materialMenu.Name = "MaterialMenu"
148 | materialMenu.Position = UDim2.new(-4,0,-3,0)
149 | materialMenu.Size = UDim2.new(2.5,0,6.5,0)
150 | materialMenu.BackgroundTransparency = 1
151 | materialMenu.ZIndex = 2
152 | materialMenu.Image = localAssetBase .. "MaterialMenu.png"
153 | materialMenu.Parent = materialTool
154 |
155 | local textures = {"Plastic","Wood","Slate","CorrodedMetal","Ice","Grass","Foil","DiamondPlate","Concrete"}
156 |
157 | local materialButtons = {}
158 |
159 | local materialButton = Instance.new("ImageButton")
160 | materialButton.RobloxLocked = true
161 | materialButton.BackgroundTransparency = 1
162 | materialButton.Size = UDim2.new(0.400000003, 0,0.16, 0)
163 | materialButton.ZIndex = 2
164 |
165 | selection.Parent = materialButton
166 |
167 | local current = 1
168 | function getTextureAndName(button)
169 |
170 | if current > #textures then
171 | button:remove()
172 | return false
173 | end
174 | button.Image = localAssetBase .. textures[current] .. ".png"
175 | button.Name = textures[current]
176 | current = current + 1
177 | return true
178 |
179 | end
180 |
181 | local ySpacing = 0.10
182 | local xSpacing = 0.07
183 | for i = 1,5 do
184 | for j = 1,2 do
185 | local button = materialButton:clone()
186 | button.RobloxLocked = true
187 | button.Position = UDim2.new((j -1)/2.2 + xSpacing,0,ySpacing + (i - 1)/5.5,0)
188 | if getTextureAndName(button) then button.Parent = materialMenu else button:remove() end
189 | table.insert(materialButtons,button)
190 | end
191 | end
192 |
193 |
194 | for i = 1, #materialButtons do
195 | materialButtons[i].MouseButton1Click:connect(function()
196 | fadeInButton(materialButtons[i])
197 | end)
198 | end
199 |
200 | local materialCloseButton = closeButton:clone()
201 | materialCloseButton.RobloxLocked = true
202 | materialCloseButton.Size = UDim2.new(0.2,0,0.08,0)
203 | materialCloseButton.Parent = materialMenu
204 |
205 | local closedState = Instance.new("BoolValue")
206 | closedState.RobloxLocked = true
207 | closedState.Name = "ClosedState"
208 | closedState.Parent = materialCloseButton
209 |
210 | setUpCloseButtonState(materialCloseButton)
211 |
212 |
213 | ------------------------------- create the surface selection sub menu -----------------------------------
214 |
215 | local surfaceMenu = Instance.new("ImageLabel")
216 | local surfaceTool = gui.BuildTools.Frame.PropertyTools.InputSelector
217 | surfaceMenu.RobloxLocked = true
218 | surfaceMenu.Name = "SurfaceMenu"
219 | surfaceMenu.Position = UDim2.new(-2.6,0,-4,0)
220 | surfaceMenu.Size = UDim2.new(2.5,0,5.5,0)
221 | surfaceMenu.BackgroundTransparency = 1
222 | surfaceMenu.ZIndex = 2
223 | surfaceMenu.Image = localAssetBase .. "SurfaceMenu.png"
224 | surfaceMenu.Parent = surfaceTool
225 |
226 | textures = {"Smooth", "Studs", "Inlets", "Universal", "Glue", "Weld", "Hinge", "Motor"}
227 | current = 1
228 |
229 | local surfaceButtons = {}
230 |
231 | local surfaceButton = Instance.new("ImageButton")
232 | surfaceButton.RobloxLocked = true
233 | surfaceButton.BackgroundTransparency = 1
234 | surfaceButton.Size = UDim2.new(0.400000003, 0,0.19, 0)
235 | surfaceButton.ZIndex = 2
236 |
237 | selection.Parent = surfaceButton
238 |
239 | local ySpacing = 0.14
240 | local xSpacing = 0.07
241 | for i = 1,4 do
242 | for j = 1,2 do
243 | local button = surfaceButton:clone()
244 | button.RobloxLocked = true
245 | button.Position = UDim2.new((j -1)/2.2 + xSpacing,0,ySpacing + (i - 1)/4.6,0)
246 | getTextureAndName(button)
247 | button.Parent = surfaceMenu
248 | table.insert(surfaceButtons,button)
249 | end
250 | end
251 |
252 | for i = 1, #surfaceButtons do
253 | surfaceButtons[i].MouseButton1Click:connect(function()
254 | fadeInButton(surfaceButtons[i])
255 | end)
256 | end
257 |
258 | local surfaceMenuCloseButton = closeButton:clone()
259 | surfaceMenuCloseButton.RobloxLocked = true
260 | surfaceMenuCloseButton.Size = UDim2.new(0.2,0,0.09,0)
261 | surfaceMenuCloseButton.Parent = surfaceMenu
262 |
263 | local closedState = Instance.new("BoolValue")
264 | closedState.RobloxLocked = true
265 | closedState.Name = "ClosedState"
266 | closedState.Parent = surfaceMenuCloseButton
267 |
268 | setUpCloseButtonState(surfaceMenuCloseButton)
269 |
270 | if game.CoreGui.Version >= 2 then
271 | local function setupTweenTransition(button, menu, outXScale, inXScale)
272 | button.Changed:connect(
273 | function(property)
274 | if property ~= "Selected" then
275 | return
276 | end
277 | if button.Selected then
278 | menu:TweenPosition(UDim2.new(inXScale, menu.Position.X.Offset, menu.Position.Y.Scale, menu.Position.Y.Offset),
279 | Enum.EasingDirection.Out, Enum.EasingStyle.Quart, 1, true)
280 | else
281 | menu:TweenPosition(UDim2.new(outXScale, menu.Position.X.Offset, menu.Position.Y.Scale, menu.Position.Y.Offset),
282 | Enum.EasingDirection.In, Enum.EasingStyle.Quart, 0.5, true)
283 | end
284 | end)
285 | end
286 |
287 | setupTweenTransition(paintTool, paintMenu, -2.7, 2.6)
288 | setupTweenTransition(surfaceTool, surfaceMenu, -2.6, 2.6)
289 | setupTweenTransition(materialTool, materialMenu, -4, 1.4)
290 | end
291 |
--------------------------------------------------------------------------------
/CoreScripts/SurfaceMenuMover.lua:
--------------------------------------------------------------------------------
1 | -- this script is responsible for moving the surface menu in and out when selected/deselected
2 |
3 | local button = script.Parent
4 | local activated = false
5 |
6 | function waitForChild(instance, name)
7 | while not instance:FindFirstChild(name) do
8 | instance.ChildAdded:wait()
9 | end
10 | end
11 |
12 | waitForChild(script.Parent,"SurfaceMenu")
13 | local menu = script.Parent:FindFirstChild("SurfaceMenu")
14 |
15 | local speed = 0.35
16 | local moving = false
17 |
18 | button.Changed:connect(function(property)
19 |
20 | if property ~= "Selected" then return end
21 | if moving then return end
22 | moving = true
23 | activated = button.Selected
24 | if activated then
25 | while menu.Position.X.Scale < 2.6 do
26 | menu.Position = UDim2.new(menu.Position.X.Scale + speed,menu.Position.X.Offset,menu.Position.Y.Scale,menu.Position.Y.Offset)
27 | wait()
28 | end
29 | else
30 | while menu.Position.X.Scale > -2.6 do
31 | menu.Position = UDim2.new(menu.Position.X.Scale - speed,menu.Position.X.Offset,menu.Position.Y.Scale,menu.Position.Y.Offset)
32 | wait()
33 | end
34 | end
35 |
36 | moving = false end)
--------------------------------------------------------------------------------
/CoreScripts/ToolTip.lua:
--------------------------------------------------------------------------------
1 | local controlFrame = script.Parent:FindFirstChild("ControlFrame")
2 |
3 | if not controlFrame then return end
4 |
5 | local topLeftControl = controlFrame:FindFirstChild("TopLeftControl")
6 | local bottomLeftControl = controlFrame:FindFirstChild("BottomLeftControl")
7 | local bottomRightControl = controlFrame:FindFirstChild("BottomRightControl")
8 |
9 |
10 | local frameTip = Instance.new("TextLabel")
11 | frameTip.Name = "ToolTip"
12 | frameTip.Text = ""
13 | frameTip.Font = Enum.Font.ArialBold
14 | frameTip.FontSize = Enum.FontSize.Size12
15 | frameTip.TextColor3 = Color3.new(1,1,1)
16 | frameTip.BorderSizePixel = 0
17 | frameTip.ZIndex = 10
18 | frameTip.Size = UDim2.new(2,0,1,0)
19 | frameTip.Position = UDim2.new(1,0,0,0)
20 | frameTip.BackgroundColor3 = Color3.new(0,0,0)
21 | frameTip.BackgroundTransparency = 1
22 | frameTip.TextTransparency = 1
23 | frameTip.TextWrap = true
24 |
25 | local inside = Instance.new("BoolValue")
26 | inside.Name = "inside"
27 | inside.Value = false
28 | inside.Parent = frameTip
29 |
30 | function setUpListeners(frameToListen)
31 | local fadeSpeed = 0.1
32 | frameToListen.Parent.MouseEnter:connect(function()
33 | if frameToListen:FindFirstChild("inside") then
34 | frameToListen.inside.Value = true
35 | wait(1.2)
36 | if frameToListen.inside.Value then
37 | while frameToListen.inside.Value and frameToListen.BackgroundTransparency > 0 do
38 | frameToListen.BackgroundTransparency = frameToListen.BackgroundTransparency - fadeSpeed
39 | frameToListen.TextTransparency = frameToListen.TextTransparency - fadeSpeed
40 | wait()
41 | end
42 | end
43 | end
44 | end)
45 | function killTip(killFrame)
46 | killFrame.inside.Value = false
47 | killFrame.BackgroundTransparency = 1
48 | killFrame.TextTransparency = 1
49 | end
50 | frameToListen.Parent.MouseLeave:connect(function() killTip(frameToListen) end)
51 | frameToListen.Parent.MouseButton1Click:connect(function() killTip(frameToListen) end)
52 | end
53 |
54 | function createSettingsButtonTip(parent)
55 | if parent == nil then
56 | parent = bottomLeftControl:FindFirstChild("SettingsButton")
57 | end
58 |
59 | local toolTip = frameTip:clone()
60 | toolTip.RobloxLocked = true
61 | toolTip.Text = "Settings/Leave Game"
62 | toolTip.Position = UDim2.new(0,0,0,-18)
63 | toolTip.Size = UDim2.new(0,120,0,20)
64 | toolTip.Parent = parent
65 | setUpListeners(toolTip)
66 | end
67 |
68 | wait(5) -- make sure we are loaded in, won't need tool tips for first 5 seconds anyway
69 |
70 | ---------------- set up Bottom Left Tool Tips -------------------------
71 |
72 | local bottomLeftChildren = bottomLeftControl:GetChildren()
73 | local hasSettingsTip = false
74 |
75 | for i = 1, #bottomLeftChildren do
76 |
77 | if bottomLeftChildren[i].Name == "Exit" then
78 | local exitTip = frameTip:clone()
79 | exitTip.RobloxLocked = true
80 | exitTip.Text = "Leave Place"
81 | exitTip.Position = UDim2.new(0,0,-1,0)
82 | exitTip.Size = UDim2.new(1,0,1,0)
83 | exitTip.Parent = bottomLeftChildren[i]
84 | setUpListeners(exitTip)
85 | elseif bottomLeftChildren[i].Name == "SettingsButton" then
86 | hasSettingsTip = true
87 | createSettingsButtonTip(bottomLeftChildren[i])
88 | end
89 | end
90 |
91 | ---------------- set up Bottom Right Tool Tips -------------------------
92 |
93 | local bottomRightChildren = bottomRightControl:GetChildren()
94 |
95 | for i = 1, #bottomRightChildren do
96 | if bottomRightChildren[i].Name:find("Camera") ~= nil then
97 | local cameraTip = frameTip:clone()
98 | cameraTip.RobloxLocked = true
99 | cameraTip.Text = "Camera View"
100 | if bottomRightChildren[i].Name:find("Zoom") then
101 | cameraTip.Position = UDim2.new(-1,0,-1.5)
102 | else
103 | cameraTip.Position = UDim2.new(0,0,-1.5,0)
104 | end
105 | cameraTip.Size = UDim2.new(2,0,1.25,0)
106 | cameraTip.Parent = bottomRightChildren[i]
107 | setUpListeners(cameraTip)
108 | end
109 | end
110 |
--------------------------------------------------------------------------------
/CoreScripts/TouchControls.lua:
--------------------------------------------------------------------------------
1 | -- This is responsible for all touch controls we show (as of this writing, only on iOS)
2 | -- this includes character move thumbsticks, and buttons for jump, use of items, camera, etc.
3 | -- Written by Ben Tkacheff, Copyright Roblox 2013
4 |
5 | -- obligatory stuff to make sure we don't access nil data
6 | while not Game do
7 | wait()
8 | end
9 | while not Game:FindFirstChild("Players") do
10 | wait()
11 | end
12 | while not Game.Players.LocalPlayer do
13 | wait()
14 | end
15 | while not Game:FindFirstChild("CoreGui") do
16 | wait()
17 | end
18 | while not Game.CoreGui:FindFirstChild("RobloxGui") do
19 | wait()
20 | end
21 |
22 | local userInputService = Game:GetService("UserInputService")
23 | local success = pcall(function() userInputService:IsLuaTouchControls() end)
24 | if not success then
25 | script:Destroy()
26 | end
27 |
28 | ----------------------------------------------------------------------------
29 | ----------------------------------------------------------------------------
30 | -- Variables
31 | local screenResolution = Game:GetService("GuiService"):GetScreenResolution()
32 | function isSmallScreenDevice()
33 | return screenResolution.y <= 320
34 | end
35 |
36 | local localPlayer = Game.Players.LocalPlayer
37 | local thumbstickInactiveAlpha = 0.3
38 | local thumbstickSize = 120
39 | if isSmallScreenDevice() then
40 | thumbstickSize = 70
41 | end
42 |
43 | local touchControlsSheet = "rbxasset://textures/ui/TouchControlsSheet.png"
44 | local ThumbstickDeadZone = 5
45 | local ThumbstickMaxPercentGive = 0.92
46 | local thumbstickTouches = {}
47 |
48 | local jumpButtonSize = 90
49 | if isSmallScreenDevice() then
50 | jumpButtonSize = 70
51 | end
52 | local oldJumpTouches = {}
53 | local currentJumpTouch = nil
54 |
55 | local CameraRotateSensitivity = 0.007
56 | local CameraRotateDeadZone = CameraRotateSensitivity * 16
57 | local CameraZoomSensitivity = 0.03
58 | local PinchZoomDelay = 0.2
59 | local cameraTouch = nil
60 |
61 |
62 | -- make sure all of our images are good to go
63 | Game:GetService("ContentProvider"):Preload(touchControlsSheet)
64 |
65 | ----------------------------------------------------------------------------
66 | ----------------------------------------------------------------------------
67 | -- Functions
68 |
69 | function DistanceBetweenTwoPoints(point1, point2)
70 | local dx = point2.x - point1.x
71 | local dy = point2.y - point1.y
72 | return math.sqrt( (dx*dx) + (dy*dy) )
73 | end
74 |
75 | function transformFromCenterToTopLeft(pointToTranslate, guiObject)
76 | return UDim2.new(0,pointToTranslate.x - guiObject.AbsoluteSize.x/2,0,pointToTranslate.y - guiObject.AbsoluteSize.y/2)
77 | end
78 |
79 | function rotatePointAboutLocation(pointToRotate, pointToRotateAbout, radians)
80 | local sinAnglePercent = math.sin(radians)
81 | local cosAnglePercent = math.cos(radians)
82 |
83 | local transformedPoint = pointToRotate
84 |
85 | -- translate point back to origin:
86 | transformedPoint = Vector2.new(transformedPoint.x - pointToRotateAbout.x, transformedPoint.y - pointToRotateAbout.y)
87 |
88 | -- rotate point
89 | local xNew = transformedPoint.x * cosAnglePercent - transformedPoint.y * sinAnglePercent
90 | local yNew = transformedPoint.x * sinAnglePercent + transformedPoint.y * cosAnglePercent
91 |
92 | -- translate point back:
93 | transformedPoint = Vector2.new(xNew + pointToRotateAbout.x, yNew + pointToRotateAbout.y)
94 |
95 | return transformedPoint
96 | end
97 |
98 | function dotProduct(v1,v2)
99 | return ((v1.x*v2.x) + (v1.y*v2.y))
100 | end
101 |
102 | function stationaryThumbstickTouchMove(thumbstickFrame, thumbstickOuter, touchLocation)
103 | local thumbstickOuterCenterPosition = Vector2.new(thumbstickOuter.Position.X.Offset + thumbstickOuter.AbsoluteSize.x/2, thumbstickOuter.Position.Y.Offset + thumbstickOuter.AbsoluteSize.y/2)
104 | local centerDiff = DistanceBetweenTwoPoints(touchLocation, thumbstickOuterCenterPosition)
105 |
106 | -- thumbstick is moving outside our region, need to cap its distance
107 | if centerDiff > (thumbstickSize/2) then
108 | local thumbVector = Vector2.new(touchLocation.x - thumbstickOuterCenterPosition.x,touchLocation.y - thumbstickOuterCenterPosition.y);
109 | local normal = thumbVector.unit
110 | if normal.x == math.nan or normal.x == math.inf then
111 | normal = Vector2.new(0,normal.y)
112 | end
113 | if normal.y == math.nan or normal.y == math.inf then
114 | normal = Vector2.new(normal.x,0)
115 | end
116 |
117 | local newThumbstickInnerPosition = thumbstickOuterCenterPosition + (normal * (thumbstickSize/2))
118 | thumbstickFrame.Position = transformFromCenterToTopLeft(newThumbstickInnerPosition, thumbstickFrame)
119 | else
120 | thumbstickFrame.Position = transformFromCenterToTopLeft(touchLocation,thumbstickFrame)
121 | end
122 |
123 | return Vector2.new(thumbstickFrame.Position.X.Offset - thumbstickOuter.Position.X.Offset,thumbstickFrame.Position.Y.Offset - thumbstickOuter.Position.Y.Offset)
124 | end
125 |
126 | function followThumbstickTouchMove(thumbstickFrame, thumbstickOuter, touchLocation)
127 | local thumbstickOuterCenter = Vector2.new(thumbstickOuter.Position.X.Offset + thumbstickOuter.AbsoluteSize.x/2, thumbstickOuter.Position.Y.Offset + thumbstickOuter.AbsoluteSize.y/2)
128 |
129 | -- thumbstick is moving outside our region, need to position outer thumbstick texture carefully (to make look and feel like actual joystick controller)
130 | if DistanceBetweenTwoPoints(touchLocation, thumbstickOuterCenter) > thumbstickSize/2 then
131 | local thumbstickInnerCenter = Vector2.new(thumbstickFrame.Position.X.Offset + thumbstickFrame.AbsoluteSize.x/2, thumbstickFrame.Position.Y.Offset + thumbstickFrame.AbsoluteSize.y/2)
132 | local movementVectorUnit = Vector2.new(touchLocation.x - thumbstickInnerCenter.x, touchLocation.y - thumbstickInnerCenter.y).unit
133 |
134 | local outerToInnerVectorCurrent = Vector2.new(thumbstickInnerCenter.x - thumbstickOuterCenter.x, thumbstickInnerCenter.y - thumbstickOuterCenter.y)
135 | local outerToInnerVectorCurrentUnit = outerToInnerVectorCurrent.unit
136 | local movementVector = Vector2.new(touchLocation.x - thumbstickInnerCenter.x, touchLocation.y - thumbstickInnerCenter.y)
137 |
138 | -- First, find the angle between the new thumbstick movement vector,
139 | -- and the vector between thumbstick inner and thumbstick outer.
140 | -- We will use this to pivot thumbstick outer around thumbstick inner, gives a nice joystick feel
141 | local crossOuterToInnerWithMovement = (outerToInnerVectorCurrentUnit.x * movementVectorUnit.y) - (outerToInnerVectorCurrentUnit.y * movementVectorUnit.x)
142 | local angle = math.atan2(crossOuterToInnerWithMovement, dotProduct(outerToInnerVectorCurrentUnit, movementVectorUnit))
143 | local anglePercent = angle * math.min( (movementVector.magnitude)/(outerToInnerVectorCurrent.magnitude), 1.0);
144 |
145 | -- If angle is significant, rotate about the inner thumbsticks current center
146 | if math.abs(anglePercent) > 0.00001 then
147 | local outerThumbCenter = rotatePointAboutLocation(thumbstickOuterCenter, thumbstickInnerCenter, anglePercent)
148 | thumbstickOuter.Position = transformFromCenterToTopLeft(Vector2.new(outerThumbCenter.x,outerThumbCenter.y), thumbstickOuter)
149 | end
150 |
151 | -- now just translate outer thumbstick to make sure it stays nears inner thumbstick
152 | thumbstickOuter.Position = UDim2.new(0,thumbstickOuter.Position.X.Offset+movementVector.x,0,thumbstickOuter.Position.Y.Offset+movementVector.y)
153 | end
154 |
155 | thumbstickFrame.Position = transformFromCenterToTopLeft(touchLocation,thumbstickFrame)
156 |
157 | -- a bit of error checking to make sure thumbsticks stay close to eachother
158 | thumbstickFramePosition = Vector2.new(thumbstickFrame.Position.X.Offset,thumbstickFrame.Position.Y.Offset)
159 | thumbstickOuterPosition = Vector2.new(thumbstickOuter.Position.X.Offset,thumbstickOuter.Position.Y.Offset)
160 | if DistanceBetweenTwoPoints(thumbstickFramePosition, thumbstickOuterPosition) > thumbstickSize/2 then
161 | local vectorWithLength = (thumbstickOuterPosition - thumbstickFramePosition).unit * thumbstickSize/2
162 | thumbstickOuter.Position = UDim2.new(0,thumbstickFramePosition.x + vectorWithLength.x,0,thumbstickFramePosition.y + vectorWithLength.y)
163 | end
164 |
165 | return Vector2.new(thumbstickFrame.Position.X.Offset - thumbstickOuter.Position.X.Offset,thumbstickFrame.Position.Y.Offset - thumbstickOuter.Position.Y.Offset)
166 | end
167 |
168 | function movementOutsideDeadZone(movementVector)
169 | return ( (math.abs(movementVector.x) > ThumbstickDeadZone) or (math.abs(movementVector.y) > ThumbstickDeadZone) )
170 | end
171 |
172 | function constructThumbstick(defaultThumbstickPos, updateFunction, stationaryThumbstick)
173 | local thumbstickFrame = Instance.new("Frame")
174 | thumbstickFrame.Name = "ThumbstickFrame"
175 | thumbstickFrame.Active = true
176 | thumbstickFrame.Size = UDim2.new(0,thumbstickSize,0,thumbstickSize)
177 | thumbstickFrame.Position = defaultThumbstickPos
178 | thumbstickFrame.BackgroundTransparency = 1
179 |
180 | local outerThumbstick = Instance.new("ImageLabel")
181 | outerThumbstick.Name = "OuterThumbstick"
182 | outerThumbstick.Image = touchControlsSheet
183 | outerThumbstick.ImageRectOffset = Vector2.new(0,0)
184 | outerThumbstick.ImageRectSize = Vector2.new(220,220)
185 | outerThumbstick.BackgroundTransparency = 1
186 | outerThumbstick.Size = UDim2.new(0,thumbstickSize,0,thumbstickSize)
187 | outerThumbstick.Position = defaultThumbstickPos
188 | outerThumbstick.Parent = Game.CoreGui.RobloxGui
189 |
190 | local innerThumbstick = Instance.new("ImageLabel")
191 | innerThumbstick.Name = "InnerThumbstick"
192 | innerThumbstick.Image = touchControlsSheet
193 | innerThumbstick.ImageRectOffset = Vector2.new(220,0)
194 | innerThumbstick.ImageRectSize = Vector2.new(111,111)
195 | innerThumbstick.BackgroundTransparency = 1
196 | innerThumbstick.Size = UDim2.new(0,thumbstickSize/2,0,thumbstickSize/2)
197 | innerThumbstick.Position = UDim2.new(0, thumbstickFrame.Size.X.Offset/2 - thumbstickSize/4, 0, thumbstickFrame.Size.Y.Offset/2 - thumbstickSize/4)
198 | innerThumbstick.Parent = thumbstickFrame
199 | innerThumbstick.ZIndex = 2
200 |
201 | local thumbstickTouch = nil
202 | local userInputServiceTouchMovedCon = nil
203 | local userInputSeviceTouchEndedCon = nil
204 |
205 | local startInputTracking = function(inputObject)
206 | if thumbstickTouch then return end
207 | if inputObject == cameraTouch then return end
208 | if inputObject == currentJumpTouch then return end
209 | if inputObject.UserInputType ~= Enum.UserInputType.Touch then return end
210 |
211 | thumbstickTouch = inputObject
212 | table.insert(thumbstickTouches,thumbstickTouch)
213 |
214 | thumbstickFrame.Position = transformFromCenterToTopLeft(thumbstickTouch.Position,thumbstickFrame)
215 | outerThumbstick.Position = thumbstickFrame.Position
216 |
217 | userInputServiceTouchMovedCon = userInputService.TouchMoved:connect(function(movedInput)
218 | if movedInput == thumbstickTouch then
219 | local movementVector = nil
220 | if stationaryThumbstick then
221 | movementVector = stationaryThumbstickTouchMove(thumbstickFrame,outerThumbstick,Vector2.new(movedInput.Position.x,movedInput.Position.y))
222 | else
223 | movementVector = followThumbstickTouchMove(thumbstickFrame,outerThumbstick,Vector2.new(movedInput.Position.x,movedInput.Position.y))
224 | end
225 |
226 | if updateFunction then
227 | updateFunction(movementVector,outerThumbstick.Size.X.Offset/2)
228 | end
229 | end
230 | end)
231 | userInputSeviceTouchEndedCon = userInputService.TouchEnded:connect(function(endedInput)
232 | if endedInput == thumbstickTouch then
233 | if updateFunction then
234 | updateFunction(Vector2.new(0,0),1)
235 | end
236 |
237 | userInputSeviceTouchEndedCon:disconnect()
238 | userInputServiceTouchMovedCon:disconnect()
239 |
240 | thumbstickFrame.Position = defaultThumbstickPos
241 | outerThumbstick.Position = defaultThumbstickPos
242 |
243 | for i, object in pairs(thumbstickTouches) do
244 | if object == thumbstickTouch then
245 | table.remove(thumbstickTouches,i)
246 | break
247 | end
248 | end
249 | thumbstickTouch = nil
250 | end
251 | end)
252 | end
253 |
254 | userInputService.Changed:connect(function(prop)
255 | if prop == "ModalEnabled" then
256 | thumbstickFrame.Visible = not userInputService.ModalEnabled
257 | outerThumbstick.Visible = not userInputService.ModalEnabled
258 | end
259 | end)
260 |
261 | thumbstickFrame.InputBegan:connect(startInputTracking)
262 | return thumbstickFrame
263 | end
264 |
265 | function setupCharacterMovement( parentFrame )
266 | local lastMovementVector, lastMaxMovement = nil
267 | local moveCharacterFunc = localPlayer.MoveCharacter
268 | local moveCharacterFunction = function ( movementVector, maxMovement )
269 | if localPlayer then
270 | if movementOutsideDeadZone(movementVector) then
271 | lastMovementVector = movementVector
272 | lastMaxMovement = maxMovement
273 | -- sometimes rounding error will not allow us to go max speed at some
274 | -- thumbstick angles, fix this with a bit of fudging near 100% throttle
275 | if movementVector.magnitude/maxMovement > ThumbstickMaxPercentGive then
276 | maxMovement = movementVector.magnitude - 1
277 | end
278 | moveCharacterFunc(localPlayer, movementVector, maxMovement)
279 | else
280 | lastMovementVector = Vector2.new(0,0)
281 | lastMaxMovement = 1
282 | moveCharacterFunc(localPlayer, lastMovementVector, lastMaxMovement)
283 | end
284 | end
285 | end
286 |
287 | local thumbstickPos = UDim2.new(0,thumbstickSize/2,1,-thumbstickSize*1.75)
288 | if isSmallScreenDevice() then
289 | thumbstickPos = UDim2.new(0,(thumbstickSize/2) - 10,1,-thumbstickSize - 20)
290 | end
291 | local characterThumbstick = constructThumbstick(thumbstickPos, moveCharacterFunction, false)
292 | characterThumbstick.Name = "CharacterThumbstick"
293 | characterThumbstick.Parent = parentFrame
294 |
295 | local refreshCharacterMovement = function()
296 | if localPlayer and moveCharacterFunc and lastMovementVector and lastMaxMovement then
297 | moveCharacterFunc(localPlayer, lastMovementVector, lastMaxMovement)
298 | end
299 | end
300 | return refreshCharacterMovement
301 | end
302 |
303 |
304 | function setupJumpButton( parentFrame )
305 | local jumpButton = Instance.new("ImageButton")
306 | jumpButton.Name = "JumpButton"
307 | jumpButton.BackgroundTransparency = 1
308 | jumpButton.Image = touchControlsSheet
309 | jumpButton.ImageRectOffset = Vector2.new(176,222)
310 | jumpButton.ImageRectSize = Vector2.new(174,174)
311 | jumpButton.Size = UDim2.new(0,jumpButtonSize,0,jumpButtonSize)
312 | if isSmallScreenDevice() then
313 | jumpButton.Position = UDim2.new(1, -(jumpButtonSize*2.25), 1, -jumpButtonSize - 20)
314 | else
315 | jumpButton.Position = UDim2.new(1, -(jumpButtonSize*2.75), 1, -jumpButtonSize - 120)
316 | end
317 |
318 | local playerJumpFunc = localPlayer.JumpCharacter
319 |
320 | local doJumpLoop = function ()
321 | while currentJumpTouch do
322 | if localPlayer then
323 | playerJumpFunc(localPlayer)
324 | end
325 | wait(1/60)
326 | end
327 | end
328 |
329 | jumpButton.InputBegan:connect(function(inputObject)
330 | if inputObject.UserInputType ~= Enum.UserInputType.Touch then return end
331 | if currentJumpTouch then return end
332 | if inputObject == cameraTouch then return end
333 | for i, touch in pairs(oldJumpTouches) do
334 | if touch == inputObject then
335 | return
336 | end
337 | end
338 |
339 | currentJumpTouch = inputObject
340 | jumpButton.ImageRectOffset = Vector2.new(0,222)
341 | jumpButton.ImageRectSize = Vector2.new(174,174)
342 | doJumpLoop()
343 | end)
344 | jumpButton.InputEnded:connect(function (inputObject)
345 | if inputObject.UserInputType ~= Enum.UserInputType.Touch then return end
346 |
347 | jumpButton.ImageRectOffset = Vector2.new(176,222)
348 | jumpButton.ImageRectSize = Vector2.new(174,174)
349 |
350 | if inputObject == currentJumpTouch then
351 | table.insert(oldJumpTouches,currentJumpTouch)
352 | currentJumpTouch = nil
353 | end
354 | end)
355 | userInputService.InputEnded:connect(function ( globalInputObject )
356 | for i, touch in pairs(oldJumpTouches) do
357 | if touch == globalInputObject then
358 | table.remove(oldJumpTouches,i)
359 | break
360 | end
361 | end
362 | end)
363 |
364 | userInputService.Changed:connect(function(prop)
365 | if prop == "ModalEnabled" then
366 | jumpButton.Visible = not userInputService.ModalEnabled
367 | end
368 | end)
369 |
370 | jumpButton.Parent = parentFrame
371 | end
372 |
373 | function isTouchUsedByJumpButton( touch )
374 | if touch == currentJumpTouch then return true end
375 | for i, touchToCompare in pairs(oldJumpTouches) do
376 | if touch == touchToCompare then
377 | return true
378 | end
379 | end
380 |
381 | return false
382 | end
383 |
384 | function isTouchUsedByThumbstick(touch)
385 | for i, touchToCompare in pairs(thumbstickTouches) do
386 | if touch == touchToCompare then
387 | return true
388 | end
389 | end
390 |
391 | return false
392 | end
393 |
394 | function setupCameraControl(parentFrame, refreshCharacterMoveFunc)
395 | local lastPos = nil
396 | local hasRotatedCamera = false
397 | local rotateCameraFunc = userInputService.RotateCamera
398 |
399 | local pinchTime = -1
400 | local shouldPinch = false
401 | local lastPinchScale = nil
402 | local zoomCameraFunc = userInputService.ZoomCamera
403 | local pinchTouches = {}
404 | local pinchFrame = nil
405 |
406 | local resetCameraRotateState = function()
407 | cameraTouch = nil
408 | hasRotatedCamera = false
409 | lastPos = nil
410 | end
411 |
412 | local resetPinchState = function ()
413 | pinchTouches = {}
414 | lastPinchScale = nil
415 | shouldPinch = false
416 | pinchFrame:Destroy()
417 | pinchFrame = nil
418 | end
419 |
420 | local startPinch = function(firstTouch, secondTouch)
421 | -- track pinching in new frame
422 | if pinchFrame then pinchFrame:Destroy() end -- make sure we didn't track in any mud
423 | pinchFrame = Instance.new("Frame")
424 | pinchFrame.Name = "PinchFrame"
425 | pinchFrame.BackgroundTransparency = 1
426 | pinchFrame.Parent = parentFrame
427 | pinchFrame.Size = UDim2.new(1,0,1,0)
428 |
429 | pinchFrame.InputChanged:connect(function(inputObject)
430 | if not shouldPinch then
431 | resetPinchState()
432 | return
433 | end
434 | resetCameraRotateState()
435 |
436 | if lastPinchScale == nil then -- first pinch move, just set up scale
437 | if inputObject == firstTouch then
438 | lastPinchScale = (inputObject.Position - secondTouch.Position).magnitude
439 | firstTouch = inputObject
440 | elseif inputObject == secondTouch then
441 | lastPinchScale = (inputObject.Position - firstTouch.Position).magnitude
442 | secondTouch = inputObject
443 | end
444 | else -- we are now actually pinching, do comparison to last pinch size
445 | local newPinchDistance = 0
446 | if inputObject == firstTouch then
447 | newPinchDistance = (inputObject.Position - secondTouch.Position).magnitude
448 | firstTouch = inputObject
449 | elseif inputObject == secondTouch then
450 | newPinchDistance = (inputObject.Position - firstTouch.Position).magnitude
451 | secondTouch = inputObject
452 | end
453 | if newPinchDistance ~= 0 then
454 | local pinchDiff = newPinchDistance - lastPinchScale
455 | if pinchDiff ~= 0 then
456 | zoomCameraFunc(userInputService, (pinchDiff * CameraZoomSensitivity))
457 | end
458 | lastPinchScale = newPinchDistance
459 | end
460 | end
461 | end)
462 | pinchFrame.InputEnded:connect(function(inputObject) -- pinch is over, destroy all
463 | if inputObject == firstTouch or inputObject == secondTouch then
464 | resetPinchState()
465 | end
466 | end)
467 | end
468 |
469 | local pinchGestureReceivedTouch = function(inputObject)
470 | if #pinchTouches < 1 then
471 | table.insert(pinchTouches,inputObject)
472 | pinchTime = tick()
473 | shouldPinch = false
474 | elseif #pinchTouches == 1 then
475 | shouldPinch = ( (tick() - pinchTime) <= PinchZoomDelay )
476 |
477 | if shouldPinch then
478 | table.insert(pinchTouches,inputObject)
479 | startPinch(pinchTouches[1], pinchTouches[2])
480 | else -- shouldn't ever get here, but just in case
481 | pinchTouches = {}
482 | end
483 | end
484 | end
485 |
486 | parentFrame.InputBegan:connect(function (inputObject)
487 | if inputObject.UserInputType ~= Enum.UserInputType.Touch then return end
488 | if isTouchUsedByJumpButton(inputObject) then return end
489 |
490 | local usedByThumbstick = isTouchUsedByThumbstick(inputObject)
491 | if not usedByThumbstick then
492 | pinchGestureReceivedTouch(inputObject)
493 | end
494 |
495 | if cameraTouch == nil and not usedByThumbstick then
496 | cameraTouch = inputObject
497 | lastPos = Vector2.new(cameraTouch.Position.x,cameraTouch.Position.y)
498 | lastTick = tick()
499 | end
500 | end)
501 | userInputService.InputChanged:connect(function (inputObject)
502 | if inputObject.UserInputType ~= Enum.UserInputType.Touch then return end
503 | if cameraTouch ~= inputObject then return end
504 |
505 | local newPos = Vector2.new(cameraTouch.Position.x,cameraTouch.Position.y)
506 | local touchDiff = (lastPos - newPos) * CameraRotateSensitivity
507 |
508 | -- first time rotating outside deadzone, just setup for next changed event
509 | if not hasRotatedCamera and (touchDiff.magnitude > CameraRotateDeadZone) then
510 | hasRotatedCamera = true
511 | lastPos = newPos
512 | end
513 |
514 | -- fire everytime after we have rotated out of deadzone
515 | if hasRotatedCamera and (lastPos ~= newPos) then
516 | rotateCameraFunc(userInputService, touchDiff)
517 | refreshCharacterMoveFunc()
518 | lastPos = newPos
519 | end
520 | end)
521 | userInputService.InputEnded:connect(function (inputObject)
522 | if cameraTouch == inputObject or cameraTouch == nil then
523 | resetCameraRotateState()
524 | end
525 |
526 | for i, touch in pairs(pinchTouches) do
527 | if touch == inputObject then
528 | table.remove(pinchTouches,i)
529 | end
530 | end
531 | end)
532 | end
533 |
534 | function setupTouchControls()
535 | local touchControlFrame = Instance.new("Frame")
536 | touchControlFrame.Name = "TouchControlFrame"
537 | touchControlFrame.Size = UDim2.new(1,0,1,0)
538 | touchControlFrame.BackgroundTransparency = 1
539 | touchControlFrame.Parent = Game.CoreGui.RobloxGui
540 |
541 | local refreshCharacterMoveFunc = setupCharacterMovement(touchControlFrame)
542 | setupJumpButton(touchControlFrame)
543 | setupCameraControl(touchControlFrame, refreshCharacterMoveFunc)
544 |
545 | userInputService.ProcessedEvent:connect(function(inputObject, processed)
546 | if not processed then return end
547 |
548 | -- kill camera pan if the touch is used by some user controls
549 | if inputObject == cameraTouch and inputObject.UserInputState == Enum.UserInputState.Begin then
550 | cameraTouch = nil
551 | end
552 | end)
553 | end
554 |
555 |
556 | ----------------------------------------------------------------------------
557 | ----------------------------------------------------------------------------
558 | -- Start of Script
559 |
560 | if userInputService:IsLuaTouchControls() then
561 | setupTouchControls()
562 | else
563 | script:Destroy()
564 | end
--------------------------------------------------------------------------------
/CoreScripts/fastlog.lua:
--------------------------------------------------------------------------------
1 | settings().FastLogSettings.ViewRbxBase = true
2 | settings().FastLogSettings.DeviceLost = true
3 | settings().FastLogSettings.Network = true
4 | settings().FastLogSettings.RenderBreakdown = true
5 |
--------------------------------------------------------------------------------
/Libraries/LibraryRegistration/Gametest2LibraryRegistration.lua:
--------------------------------------------------------------------------------
1 | -- Library Registration Script
2 | -- This script is used to register RbxLua libraries on game servers, so game scripts have
3 | -- access to all of the libraries (otherwise only local scripts do)
4 |
5 | local deepakTestingPlace = 3569749
6 | local sc = game:GetService("ScriptContext")
7 | local tries = 0
8 |
9 | while not sc and tries < 3 do
10 | tries = tries + 1
11 | sc = game:GetService("ScriptContext")
12 | wait(0.2)
13 | end
14 |
15 | if sc then
16 | sc:RegisterLibrary("Libraries/RbxGui", "45284430")
17 | sc:RegisterLibrary("Libraries/RbxGear", "45374389")
18 | if game.PlaceId == deepakTestingPlace then
19 | sc:RegisterLibrary("Libraries/RbxStatus", "52177566")
20 | end
21 | sc:RegisterLibrary("Libraries/RbxUtility", "60595411")
22 | sc:RegisterLibrary("Libraries/RbxStamper", "70353313")
23 | sc:LibraryRegistrationComplete()
24 | else
25 | print("failed to find script context, libraries did not load")
26 | end
27 |
--------------------------------------------------------------------------------
/Libraries/LibraryRegistration/GametestLibraryRegistration.lua:
--------------------------------------------------------------------------------
1 | -- Library Registration Script
2 | -- This script is used to register RbxLua libraries on game servers, so game scripts have
3 | -- access to all of the libraries (otherwise only local scripts do)
4 |
5 | local deepakTestingPlace = 3569749
6 | local sc = game:GetService("ScriptContext")
7 | local tries = 0
8 |
9 | while not sc and tries < 3 do
10 | tries = tries + 1
11 | sc = game:GetService("ScriptContext")
12 | wait(0.2)
13 | end
14 |
15 | if sc then
16 | sc:RegisterLibrary("RbxGui", "45284430")
17 | sc:RegisterLibrary("RbxGear", "45374389")
18 | if game.PlaceId == deepakTestingPlace then
19 | sc:RegisterLibrary("RbxStatus", "52177566")
20 | end
21 | sc:RegisterLibrary("RbxUtility", "60595411")
22 | sc:RegisterLibrary("RbxStamper","129667429")
23 | sc:LibraryRegistrationComplete()
24 | else
25 | print("failed to find libraries")
26 | end
27 |
--------------------------------------------------------------------------------
/Libraries/LibraryRegistration/LibraryRegistration.lua:
--------------------------------------------------------------------------------
1 | -- Library Registration Script
2 | -- This script is used to register RbxLua libraries on game servers, so game scripts have
3 | -- access to all of the libraries (otherwise only local scripts do)
4 |
5 | local deepakTestingPlace = 3569749
6 | local sc = game:GetService("ScriptContext")
7 | local tries = 0
8 |
9 | while not sc and tries < 3 do
10 | tries = tries + 1
11 | sc = game:GetService("ScriptContext")
12 | wait(0.2)
13 | end
14 |
15 | if sc then
16 | sc:RegisterLibrary("Libraries/RbxGui", "45284430")
17 | sc:RegisterLibrary("Libraries/RbxGear", "45374389")
18 | if game.PlaceId == deepakTestingPlace then
19 | sc:RegisterLibrary("Libraries/RbxStatus", "52177566")
20 | end
21 | sc:RegisterLibrary("Libraries/RbxUtility", "60595411")
22 | sc:RegisterLibrary("Libraries/RbxStamper", "73157242")
23 | sc:LibraryRegistrationComplete()
24 | else
25 | print("failed to find script context, libraries did not load")
26 | end
27 |
--------------------------------------------------------------------------------
/Libraries/LibraryRegistration/SitetestLibraryRegistration.lua:
--------------------------------------------------------------------------------
1 | -- Library Registration Script
2 | -- This script is used to register RbxLua libraries on game servers, so game scripts have
3 | -- access to all of the libraries (otherwise only local scripts do)
4 |
5 | local sc = game:GetService("ScriptContext")
6 | local tries = 0
7 |
8 | while not sc and tries < 3 do
9 | tries = tries + 1
10 | sc = game:GetService("ScriptContext")
11 | wait(0.2)
12 | end
13 |
14 | if sc then
15 | sc:RegisterLibrary("RbxGui", 45284430)
16 | sc:RegisterLibrary("RbxGear", 45374389)
17 | sc:RegisterLibrary("RbxUtility", 91376477)
18 | sc:LibraryRegistrationComplete()
19 | else
20 | print("failed to find libraries")
21 | end
22 |
--------------------------------------------------------------------------------
/Libraries/RBXStatus.lua:
--------------------------------------------------------------------------------
1 | -- Global Status Buff Script --
2 | -- This will be a part of a humanoid
3 | -- Everytime a humanoid gets hit, this script will be invoked
4 | -- If the damage is from a previous older gear we just query the takeDamage C++ function
5 | -- If its from some of the newer ones with status buffs, we look them up in our table and use that to determine what we need to do
6 |
7 |
8 | -- [[ The status debuffs currently are
9 |
10 | -- OVER TIME EFFECTS
11 |
12 | -- Poison
13 | -- Fire
14 | -- Ice, also slows
15 | -- Heal
16 | -- Plague
17 |
18 |
19 | -- For fire, ice etc we could apply the texture to nearby parts to showcase as if its spreading
20 |
21 | -- INSTANT EFFECTS
22 |
23 | -- Stun, 10-20% chance to stun
24 | -- Confusion
25 | -- Invisibilty, there will be fading in and fading out
26 | -- Silence, can't use gears
27 | -- Blind/Miss
28 |
29 |
30 | -- TODO, AOE EFFECTS (these will propagate from the wielder) ]]
31 |
32 | -- Return this table for accessing the library
33 | local t = {}
34 |
35 | -- Wait for a particular child to show up
36 | function waitForChild(instance, name)
37 | while not instance:FindFirstChild(name) do
38 | instance.ChildAdded:wait()
39 | end
40 | end
41 |
42 | local damageGuiWidth = 5.0
43 | local damageGuiHeight = 5.0
44 |
45 | local myPlayer = script.Parent
46 | local myName = script.Parent.Name
47 | local myHumanoid = myPlayer:FindFirstChild("Humanoid")
48 |
49 |
50 | local charConfig = nil
51 |
52 | -- gear effects
53 | local poison = 0
54 | local physical = 0
55 | local heal = 0
56 | local regen = 0
57 | local piercing = 0
58 | local poisonTime = 10 -- duration of a poisoning (default 10)
59 | local corruption = 0 -- amount poison worsens
60 |
61 | local iceDOT = 0
62 | local iceDuration = 0
63 | local iceSlow = 0
64 |
65 | local stunDuration = 0
66 |
67 | -- armor/character effects [will be reloaded upon characters config folder changing]
68 |
69 | local existingIceDuration = 0
70 |
71 | local fireDOT = 0
72 | local fireDuration = 0
73 | local existingFireDuration = 0
74 |
75 | local armor = 0
76 | local poisonArmor = 0
77 | local existingPoison = 0
78 | local existingCorruption = 0
79 |
80 | local existingStunDuration = 0
81 |
82 |
83 | -- Create Lookup Tables
84 | local charPropType = {
85 | ["Armor"] = function(x)
86 | print("ARMOR ", x)
87 | armor = x
88 | end,
89 | ["Poison Resistance"] = function(x)
90 | print("POISON RESISTANCE ", x)
91 | poisonArmor = x
92 | end,
93 | ["Poison"] = function(x)
94 | existingPoison = x.X
95 | existingCorruption = x.Z
96 | end,
97 | ["Ice"] = function(x)
98 | existingIceDuration = x.Y
99 | end,
100 | ["Fire"] = function(x)
101 | existingFireDuration = x.Y
102 | end,
103 | ["Stun"] = function(x)
104 | -- Tentative value, usually we should allow to override stun duration and have a long cool down or a chance effect
105 | existingStunDuration = x
106 | end
107 | }
108 |
109 |
110 | -- Damage Type Table
111 | local damageType = {
112 | ["Damage"] = function(x)
113 | --print("DAMAGE ", x)
114 | physical = x
115 | end,
116 | ["Poison"] = function(x)
117 | print("POISONED", x)
118 | poison = x
119 | --poisonTime = x.Y
120 | --corruption = x.Z
121 | end,
122 | ["Heal"] = function(x)
123 | print("HEALED", x)
124 | heal = x
125 | end,
126 | ["Regen"] = function(x)
127 | print("REGEN", x)
128 | regen = x
129 | end,
130 | ["Piercing"] = function(x)
131 | print("PIERCING", x)
132 | piercing = x
133 | end,
134 | ["Poison Time"] = function(x)
135 | print("POISON TIME", x)
136 | poisonTime = x
137 | end,
138 | ["Corruption"] = function(x)
139 | print("CORRUPTION", x)
140 | corruption = x
141 | end,
142 | -- Code Change Feb 25th
143 | ["Ice"] = function(x)
144 | --print("Ice")
145 | iceDOT = x.X
146 | iceDuration = x.Y
147 | iceSlow = x.Z
148 | end,
149 | ["Fire"] = function(x)
150 | fireDOT = x.X
151 | fireDuration = x.Y
152 | end,
153 | ["Stun"] = function(x)
154 | stunDuration = x
155 | end
156 | --
157 | }
158 |
159 | function updateCharProperties()
160 | -- reset all char properties first to 0
161 | armor = 0
162 | poisonArmor = 0
163 | existingPoison = 0
164 | existingCorruption = 0
165 | --iceDOT = 0
166 | --iceDuration = 0
167 | --iceSlow = 0
168 |
169 | --print("Updating Char Properties")
170 | charProperties = charConfig:GetChildren()
171 | --print(iceDOT," ", iceDuration," ", iceSlow)
172 | for i = 1, #charProperties do
173 | if charPropType[charProperties[i].Name] then -- can get rid of this check to improve speed at cost of safety
174 | charPropType[charProperties[i].Name](charProperties[i].Value)
175 | end
176 | end
177 | end
178 |
179 |
180 | function applyRandomizationTo(property)
181 | if (math.random() > property.Y) then
182 | return property.X
183 | else
184 | return property.Z
185 | end
186 | end
187 |
188 | function eval(property)
189 | if type(property) == "number" then return property
190 | else return applyRandomizationTo(property) end
191 | end
192 |
193 |
194 | t.ComputeStatusEffects = function (gearConfig, charConfig, vChar)
195 | -- all gear effects need to be set to 0 initially
196 | poison = 0
197 | physical = 0
198 | heal = 0
199 | --iceDOT = 0
200 | iceDuration = 0
201 | --iceSlow = 0
202 | regen = 0
203 | piercing = 0
204 | poisonTime = 10 -- default is to poison someone for 10 seconds
205 |
206 | gearProperties = gearConfig:GetChildren()
207 | for i = 1, #gearProperties do
208 | if not (gearProperties[i].Name == "Damage") then
209 | damageType[gearProperties[i].Name](gearProperties[i].Value)
210 | print(gearProperties[i].Name)
211 | else
212 | damageType[gearProperties[i].Name](eval(gearProperties[i].Value))
213 | end
214 | end
215 |
216 | -- apply randomization to armors that need it
217 | -- (doing this here [with eval] allows us to change armor variables only when necessary)
218 | --poi = math.max(existingPoison, math.max(poison - eval(poisonArmor), 0))
219 | dmg = math.max(physical - math.max(eval(armor) - piercing, 0), 0) - heal
220 | poi = math.max(poison - eval(poisonArmor), 0)
221 | cor = math.max(existingCorruption, corruption)
222 |
223 | -- Feb 25th Change
224 | iceDamage = iceDOT
225 | --
226 |
227 | -- Populate the tags in the Players Config!
228 | myHumanoid:takeDamage(dmg)
229 | print(myHumanoid.Health)
230 | if charConfig ~= nil then
231 | --if poi > 0 then -- if poison damage taken, make sure we give 'em a poisoned status
232 | if poi > 0 and poi >= existingPoison then -- must at least tie previous poison strength to change the poison tag
233 | poisonTag = charConfig:FindFirstChild("Poison")
234 | if poisonTag == nil then
235 | poisonTag = Instance.new("Vector3Value")
236 | poisonTag.Name = "Poison"
237 | poisonTag.Parent = charConfig
238 | end
239 | poisonTag.Value = Vector3.new(poi, poisonTime, cor)
240 | end
241 |
242 | -- Feb 25th Change
243 | if iceDuration > 0 and existingIceDuration <= 0 then
244 | iceTag = charConfig:FindFirstChild("Ice")
245 | if iceTag == nil then
246 | iceTag = Instance.new("Vector3Value")
247 | iceTag.Name = "Ice"
248 | iceTag.Parent = charConfig
249 | end
250 | iceTag.Value = Vector3.new(iceDOT, iceDuration, iceSlow)
251 | end
252 | print(fireDuration, existingFireDuration)
253 | if fireDuration > 0 and existingFireDuration <= 0 then
254 | fireTag = charConfig:FindFirstChild("Fire")
255 | if fireTag == nil then
256 | fireTag = Instance.new("Vector3Value")
257 | fireTag.Name = "Fire"
258 | fireTag.Parent = charConfig
259 | end
260 | fireTag.Value = Vector3.new(fireDOT, fireDuration, 0.0)
261 | end
262 |
263 | if stunDuration > 0 and existingStunDuration <= 0 then
264 | stunTag = charConfig:FindFirstChild("Stun")
265 | if stunTag == nil then
266 | stunTag = Instance.new("NumberValue")
267 | stunTag.Name = "Stun"
268 | stunTag.Parent = charConfig
269 | end
270 | stunTag.Value = stunDuration
271 | end
272 | end
273 | vPlayer = game.Players:GetPlayerFromCharacter(script.Parent)
274 | if vPlayer then
275 | dmgGui = vPlayer.PlayerGui:FindFirstChild("DamageGui")
276 | if dmgGui ~= nil then
277 | dmgChildren = dmgGui:GetChildren()
278 | for i = 1, #dmgChildren do
279 | if dmgChildren[i].TextTransparency < .35 then
280 | dmgChildren[i].Text = tostring(tonumber(dmgChildren[i].Text) + dmg)
281 | return
282 | end
283 | end
284 | end
285 | local guiCoRoutine = coroutine.create(statusGui)
286 | coroutine.resume(guiCoRoutine, vPlayer, dmg, poi)
287 | print("CREATING GUI")
288 | end
289 | end
290 |
291 | -- GUI STUFF --
292 |
293 | function statusGui(vPlayer, guiDmg, guiPoi)
294 | local damageGui = vPlayer.PlayerGui:FindFirstChild("DamageGui")
295 | if damageGui == nil then
296 | damageGui = Instance.new("BillboardGui")
297 | damageGui.Name = "DamageGui"
298 | print("BB GUI CREATED")
299 | damageGui.Parent = vPlayer.PlayerGui
300 | damageGui.Adornee = script.Parent:FindFirstChild("Head")
301 | damageGui.Active = true
302 | damageGui.size = UDim2.new(damageGuiWidth, 0.0, damageGuiHeight, 0.0)
303 | damageGui.StudsOffset = Vector3.new(0.0, 2.0, 0.0)
304 | end
305 | local textLabel = Instance.new("TextLabel")
306 | print("TEXT LABEL CREATED")
307 | textLabel.Text = tostring(guiDmg)
308 | textLabel.size = UDim2.new(1.0, 0.0, 1.0, 0.0)
309 | textLabel.Active = true
310 | textLabel.FontSize = 6
311 | textLabel.BackgroundTransparency = 1
312 | textLabel.TextColor3 = Color3.new(1, 0, 0)
313 | textLabel.Parent = damageGui
314 |
315 | for t = 1, 10 do
316 | wait(.1)
317 | textLabel.TextTransparency = t/10
318 | textLabel.Position = UDim2.new(0, 0, 0, -t*5)
319 | textLabel.FontSize = 6-t*.6
320 | end
321 | textLabel:remove()
322 | end
323 |
324 | return t
325 |
326 |
327 |
328 | -- Hook-up stuff to listeners here and do any other initialization
329 | --[[while true do
330 | waitForChild(script.Parent, "PlayerStats")
331 | charConfig = script.Parent:FindFirstChild("PlayerStats")
332 |
333 | if charConfig then
334 | updateCharProperties()
335 | charConfig.Changed:connect(updateCharProperties)
336 | charConfig.ChildAdded:connect(function (newChild) newChild.Changed:connect(updateCharProperties) updateCharProperties() end)
337 | --charConfig.Desc
338 | break
339 | end
340 | end]]
341 |
342 |
--------------------------------------------------------------------------------
/Libraries/RbxGear.lua:
--------------------------------------------------------------------------------
1 | local t = {}
2 |
3 | t.Foo =
4 | function()
5 | print("foo")
6 | end
7 |
8 | t.Bar =
9 | function()
10 | print("bar")
11 | end
12 |
13 | t.Help =
14 | function(funcNameOrFunc)
15 | --input argument can be a string or a function. Should return a description (of arguments and expected side effects)
16 | if funcNameOrFunc == "Foo" or funcNameOrFunc == t.Foo then
17 | return "Function Foo. Arguments: None. Side effect: prints foo"
18 | elseif funcNameOrFunc == "Bar" or funcNameOrFunc == t.Bar then
19 | return "Function Bar. Arguments: None. Side effect: prints bar"
20 | end
21 | end
22 |
23 | return t
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Core-Scripts
2 | ============
3 |
4 | All of ROBLOX's Core Scripts. These control in-game UI among other things.
5 |
--------------------------------------------------------------------------------
/StarterScript.lua:
--------------------------------------------------------------------------------
1 | -- Creates all neccessary scripts for the gui on initial load, everything except build tools
2 | -- Created by Ben T. 10/29/10
3 | -- Please note that these are loaded in a specific order to diminish errors/perceived load time by user
4 | local scriptContext = game:GetService("ScriptContext")
5 | local touchEnabled = false
6 | pcall(function() touchEnabled = game:GetService("UserInputService").TouchEnabled end)
7 |
8 | -- library registration
9 | scriptContext:AddCoreScript(60595695, scriptContext,"/Libraries/LibraryRegistration/LibraryRegistration")
10 |
11 | local function waitForChild(instance, name)
12 | while not instance:FindFirstChild(name) do
13 | instance.ChildAdded:wait()
14 | end
15 | end
16 | local function waitForProperty(instance, property)
17 | while not instance[property] do
18 | instance.Changed:wait()
19 | end
20 | end
21 |
22 | -- Responsible for tracking logging items
23 | local scriptContext = game:GetService("ScriptContext")
24 | scriptContext:AddCoreScript(59002209, scriptContext, "CoreScripts/Sections")
25 |
26 | waitForChild(game:GetService("CoreGui"),"RobloxGui")
27 | local screenGui = game:GetService("CoreGui"):FindFirstChild("RobloxGui")
28 |
29 | if not touchEnabled then
30 | -- ToolTipper (creates tool tips for gui)
31 | scriptContext:AddCoreScript(36868950,screenGui,"CoreScripts/ToolTip")
32 | -- SettingsScript
33 | scriptContext:AddCoreScript(46295863,screenGui,"CoreScripts/Settings")
34 | else
35 | scriptContext:AddCoreScript(70377157,screenGui,"CoreScripts/TouchControls")
36 | end
37 |
38 | -- MainBotChatScript
39 | scriptContext:AddCoreScript(39250920,screenGui,"CoreScripts/MainBotChatScript")
40 |
41 | -- Popup Script
42 | scriptContext:AddCoreScript(48488451,screenGui,"CoreScripts/PopupScript")
43 | -- Friend Notification Script (probably can use this script to expand out to other notifications)
44 | scriptContext:AddCoreScript(48488398,screenGui,"CoreScripts/NotificationScript")
45 | -- Chat script
46 | scriptContext:AddCoreScript(97188756, screenGui, "CoreScripts/ChatScript")
47 | -- Purchase Prompt Script
48 | scriptContext:AddCoreScript(107893730, screenGui, "CoreScripts/PurchasePromptScript")
49 | -- Health Script
50 | scriptContext:AddCoreScript(0, screenGui, "CoreScripts/HealthScript")
51 |
52 | if not touchEnabled then
53 | -- New Player List
54 | scriptContext:AddCoreScript(48488235,screenGui,"CoreScripts/PlayerListScript")
55 | elseif screenGui.AbsoluteSize.Y > 600 then
56 | -- New Player List
57 | scriptContext:AddCoreScript(48488235,screenGui,"CoreScripts/PlayerListScript")
58 | else
59 | delay(5, function()
60 | if screenGui.AbsoluteSize.Y >= 600 then
61 | -- New Player List
62 | scriptContext:AddCoreScript(48488235,screenGui,"CoreScripts/PlayerListScript")
63 | end
64 | end)
65 | end
66 |
67 | if game.CoreGui.Version >= 3 then
68 | -- Backpack Builder, creates most of the backpack gui
69 | scriptContext:AddCoreScript(53878047,screenGui,"CoreScripts/BackpackScripts/BackpackBuilder")
70 |
71 | waitForChild(screenGui,"CurrentLoadout")
72 | waitForChild(screenGui,"Backpack")
73 | local Backpack = screenGui.Backpack
74 |
75 | -- Manager handles all big backpack state changes, other scripts subscribe to this and do things accordingly
76 | if game.CoreGui.Version >= 7 then
77 | scriptContext:AddCoreScript(89449093,Backpack,"CoreScripts/BackpackScripts/BackpackManager")
78 | end
79 |
80 | -- Backpack Gear (handles all backpack gear tab stuff)
81 | game:GetService("ScriptContext"):AddCoreScript(89449008,Backpack,"CoreScripts/BackpackScripts/BackpackGear")
82 | -- Loadout Script, used for gear hotkeys
83 | scriptContext:AddCoreScript(53878057,screenGui.CurrentLoadout,"CoreScripts/BackpackScripts/LoadoutScript")
84 | if game.CoreGui.Version >= 8 then
85 | -- Wardrobe script handles all character dressing operations
86 | scriptContext:AddCoreScript(-1,Backpack,"CoreScripts/BackpackScripts/BackpackWardrobe")
87 | end
88 | end
89 |
90 |
91 | if touchEnabled then -- touch devices don't use same control frame
92 | -- only used for touch device button generation
93 | scriptContext:AddCoreScript(53878047,screenGui,"CoreScripts/ContextActionTouch")
94 |
95 | waitForChild(screenGui, 'ControlFrame')
96 | waitForChild(screenGui.ControlFrame, 'BottomLeftControl')
97 | screenGui.ControlFrame.BottomLeftControl.Visible = false
98 |
99 | waitForChild(screenGui.ControlFrame, 'TopLeftControl')
100 | screenGui.ControlFrame.TopLeftControl.Visible = false
101 | end
--------------------------------------------------------------------------------
/newHumanoidHealthRegen.rbxm:
--------------------------------------------------------------------------------
1 |
2 | null
3 | nil
4 | -
5 |
6 | false
7 |
8 | Health
9 | --Responsible for regening a player's humanoid's health
10 |
11 | -- declarations
12 | local Figure = script.Parent
13 | local Head = Figure:WaitForChild("Head")
14 | local Humanoid = Figure:WaitForChild("Humanoid")
15 | local regening = false
16 |
17 | -- regeneration
18 | function regenHealth()
19 | if regening then return end
20 | regening = true
21 |
22 | while Humanoid.Health < Humanoid.MaxHealth do
23 | local s = wait(1)
24 | local health = Humanoid.Health
25 | if health > 0 and health < Humanoid.MaxHealth then
26 | local newHealthDelta = 0.01 * s * Humanoid.MaxHealth
27 | health = health + newHealthDelta
28 | Humanoid.Health = math.min(health,Humanoid.MaxHealth)
29 | end
30 | end
31 |
32 | if Humanoid.Health > Humanoid.MaxHealth then
33 | Humanoid.Health = Humanoid.MaxHealth
34 | end
35 |
36 | regening = false
37 | end
38 |
39 | Humanoid.HealthChanged:connect(regenHealth)
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------