├── 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 | --------------------------------------------------------------------------------