diff --git a/yue/60595411.lua b/yue/60595411.lua new file mode 100644 index 0000000..4a7a035 --- /dev/null +++ b/yue/60595411.lua @@ -0,0 +1,391 @@ +local t = { } +local assert = assert +local Null +Null = function() + return Null +end +local StringBuilder = { + buffer = { } +} +StringBuilder.New = function(self) + local o = setmetatable({ }, self) + self.__index = self + o.buffer = { } + return o +end +StringBuilder.Append = function(self, s) + do + local _obj_0 = self.buffer + _obj_0[#_obj_0 + 1] = s + end +end +StringBuilder.ToString = function(self) + return table.concat(self.buffer) +end +local JsonWriter = { + backslashes = { + ["\b"] = "\\b", + ["\t"] = "\\t", + ["\n"] = "\\n", + ["\f"] = "\\f", + ["\r"] = "\\r", + ['"'] = '\\"', + ["\\"] = "\\\\", + ["/"] = "\\/" + } +} +JsonWriter.New = function(self) + local o = setmetatable({ }, self) + o.writer = StringBuilder:New() + self.__index = self + return o +end +JsonWriter.Append = function(self, s) + return self.writer:Append(s) +end +JsonWriter.ToString = function(self) + return self.writer:ToString() +end +JsonWriter.Write = function(self, o) + local _exp_0 = type(o) + if "nil" == _exp_0 then + return self:WriteNil() + elseif "boolean" == _exp_0 or "number" == _exp_0 then + return self:WriteString(o) + elseif "string" == _exp_0 then + return self:ParseString(o) + elseif "table" == _exp_0 then + return self:WriteTable(o) + elseif "function" == _exp_0 then + return self:WriteFunction(o) + elseif "thread" == _exp_0 or "userdata" == _exp_0 then + return self:WriteError(o) + end +end +JsonWriter.WriteNil = function(self) + return self:Append("null") +end +JsonWriter.WriteString = function(self, o) + return self:Append(tostring(o)) +end +JsonWriter.ParseString = function(self, s) + self:Append('"') + self:Append(string.gsub(s, '[%z%c\\"/]', function(n) + local c = self.backslashes[n] + if c then + return c + end + return string.format("\\u%.4X", string.byte(n)) + end)) + return self:Append('"') +end +JsonWriter.IsArray = function(self, t) + local count = 0 + local isindex + isindex = function(k) + if type(k) == "number" and k > 0 and math.floor(k) == k then + return true + end + return false + end + for k, _ in pairs(t) do + if not isindex(k) then + return false, "{", "}" + else + count = math.max(count, k) + end + end + return true, "[", "]", count +end +JsonWriter.WriteTable = function(self, t) + local ba, st, et, n = self:IsArray(t) + self:Append(st) + if ba then + for i = 1, n do + self:Write(t[i]) + if i < n then + self:Append(",") + end + end + else + local first = true + for k, v in pairs(t) do + if not first then + self:Append(",") + end + first = false + self:ParseString(k) + self:Append(":") + self:Write(v) + end + end + return self:Append(et) +end +JsonWriter.WriteError = function(self, o) + return error(string.format("Encoding of %s unsupported", tostring(o))) +end +JsonWriter.WriteFunction = function(self, o) + if o == Null then + return self:WriteNil() + else + return self:WriteError(o) + end +end +local StringReader = { + s = "", + i = 0 +} +StringReader.New = function(self, s) + local o = setmetatable({ }, self) + self.__index = self + o.s = s or o.s + return o +end +StringReader.Peek = function(self) + local i = self.i + 1 + if i <= #self.s then + return string.sub(self.s, i, i) + end + return nil +end +StringReader.Next = function(self) + self.i = self.i + 1 + if self.i <= #self.s then + return string.sub(self.s, self.i, self.i) + end + return nil +end +StringReader.All = function(self) + return self.s +end +local JsonReader = { + escapes = { + ["t"] = "\t", + ["n"] = "\n", + ["f"] = "\f", + ["r"] = "\r", + ["b"] = "\b" + } +} +JsonReader.New = function(self, s) + local o = setmetatable({ }, self) + o.reader = StringReader:New(s) + self.__index = self + return o +end +JsonReader.Read = function(self) + self:SkipWhiteSpace() + local peek = self:Peek() + if not (peek ~= nil) then + return error(string.format("Nil string: '%s'", self:All())) + elseif peek == "{" then + return self:ReadObject() + elseif peek == "[" then + return self:ReadArray() + elseif peek == '"' then + return self:ReadString() + elseif string.find(peek, "[%+%-%d]") then + return self:ReadNumber() + elseif peek == "t" then + return self:ReadTrue() + elseif peek == "f" then + return self:ReadFalse() + elseif peek == "n" then + return self:ReadNull() + elseif peek == "/" then + self:ReadComment() + return self:Read() + else + return nil + end +end +JsonReader.ReadTrue = function(self) + self:TestReservedWord({ + "t", + "r", + "u", + "e" + }) + return true +end +JsonReader.ReadFalse = function(self) + self:TestReservedWord({ + "f", + "a", + "l", + "s", + "e" + }) + return false +end +JsonReader.ReadNull = function(self) + self:TestReservedWord({ + "n", + "u", + "l", + "l" + }) + return nil +end +JsonReader.TestReservedWord = function(self, t) + for _, v in ipairs(t) do + if self:Next() ~= v then + error(string.format("Error reading '%s': %s", table.concat(t), self:All())) + end + end +end +JsonReader.ReadNumber = function(self) + local result = self:Next() + local peek = self:Peek() + while (peek ~= nil) and string.find(peek, "[%+%-%d%.eE]") do + result = result .. self:Next() + peek = self:Peek() + end + result = tonumber(result) + if not (result ~= nil) then + return error(string.format("Invalid number: '%s'", result)) + else + return result + end +end +JsonReader.ReadString = function(self) + local result = "" + assert(self:Next() == '"') + while self:Peek() ~= '"' do + local ch = self:Next() + if ch == "\\" then + ch = self:Next() + if self.escapes[ch] then + ch = self.escapes[ch] + end + end + result = result .. ch + end + assert(self:Next() == '"') + local fromunicode + fromunicode = function(m) + return string.char(tonumber(m, 16)) + end + return string.gsub(result, "u%x%x(%x%x)", fromunicode) +end +JsonReader.ReadComment = function(self) + assert(self:Next() == "/") + local second = self:Next() + if second == "/" then + return self:ReadSingleLineComment() + elseif second == "*" then + return self:ReadBlockComment() + else + return error(string.format("Invalid comment: %s", self:All())) + end +end +JsonReader.ReadBlockComment = function(self) + local done = false + while not done do + local ch = self:Next() + if ch == "*" and self:Peek() == "/" then + done = true + end + if not done and ch == "/" and self:Peek() == "*" then + error(string.format("Invalid comment: %s, '/*' illegal.", self:All())) + end + end + return self:Next() +end +JsonReader.ReadSingleLineComment = function(self) + local ch = self:Next() + while ch ~= "\r" and ch ~= "\n" do + ch = self:Next() + end +end +JsonReader.ReadArray = function(self) + local result = { } + assert(self:Next() == "[") + local done = false + if self:Peek() == "]" then + done = true + end + while not done do + local item = self:Read() + result[#result + 1] = item + self:SkipWhiteSpace() + if self:Peek() == "]" then + done = true + end + if not done then + local ch = self:Next() + if ch ~= "," then + error(string.format("Invalid array: '%s' due to: '%s'", self:All(), ch)) + end + end + end + assert("]" == self:Next()) + return result +end +JsonReader.ReadObject = function(self) + local result = { } + assert(self:Next() == "{") + local done = false + if self:Peek() == "}" then + done = true + end + while not done do + local key = self:Read() + if type(key) ~= "string" then + error(string.format("Invalid non-string object key: %s", key)) + end + self:SkipWhiteSpace() + local ch = self:Next() + if ch ~= ":" then + error(string.format("Invalid object: '%s' due to: '%s'", self:All(), ch)) + end + self:SkipWhiteSpace() + local val = self:Read() + result[key] = val + self:SkipWhiteSpace() + if self:Peek() == "}" then + done = true + end + if not done then + ch = self:Next() + if ch ~= "," then + error(string.format("Invalid array: '%s' near: '%s'", self:All(), ch)) + end + end + end + assert(self:Next() == "}") + return result +end +JsonReader.SkipWhiteSpace = function(self) + local p = self:Peek() + while (p ~= nil) and string.find(p, "[%s/]") do + if p == "/" then + self:ReadComment() + else + self:Next() + end + p = self:Peek() + end +end +JsonReader.Peek = function(self) + return self.reader:Peek() +end +JsonReader.Next = function(self) + return self.reader:Next() +end +JsonReader.All = function(self) + return self.reader:All() +end +local Encode +Encode = function(o) + local _with_0 = JsonWriter:New() + _with_0:Write(o) + _with_0:ToString() + return _with_0 +end +local Decode +Decode = function(s) + local _with_0 = JsonReader:New(s) + _with_0:Read() + return _with_0 +end diff --git a/yue/60595411.yue b/yue/60595411.yue index e69de29..262403a 100644 --- a/yue/60595411.yue +++ b/yue/60595411.yue @@ -0,0 +1,383 @@ +t = {} + +------------------------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------------------------ +------------------------------------------------JSON Functions Begin---------------------------------------------------- +------------------------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------------------------ + +--JSON Encoder and Parser for Lua 5.1 +-- +--2007 Shaun Brown (http://www.chipmunkav.com) + +assert = assert +Null = -> Null + +StringBuilder = { + buffer: {} +} + +StringBuilder.New ==> + o = <>: @ + @__index = @ + o.buffer = {} + o + + +StringBuilder.Append = (s) => + @buffer[] = s + + +StringBuilder.ToString ==> table.concat @buffer + + +JsonWriter = + backslashes: + ["\b"]: "\\b", + ["\t"]: "\\t", + ["\n"]: "\\n", + ["\f"]: "\\f", + ["\r"]: "\\r", + ['"']: '\\"', + ["\\"]: "\\\\", + ["/"]: "\\/", + +JsonWriter.New ==> + o = <>: @ + o.writer = StringBuilder\New! + @__index = @ + o + + +JsonWriter.Append = (s) => + @writer\Append s + + +JsonWriter.ToString ==> @writer\ToString! + + +JsonWriter.Write = (o) => + switch type o + when "nil" + @\WriteNil! + when "boolean", "number" + @\WriteString o + when "string" + @\ParseString o + when "table" + @\WriteTable o + when "function" + @\WriteFunction o + when "thread", "userdata" + @\WriteError o + +JsonWriter.WriteNil ==> @\Append "null" +JsonWriter.WriteString = (o) => @\Append "#{o}" + + +JsonWriter.ParseString = (s) => + @\Append '"' + @\Append string.gsub s, '[%z%c\\"/]', (n) -> + c = @backslashes[n] + if c + return c + + return string.format "\\u%.4X", string.byte n + + @\Append '"' + + +JsonWriter.IsArray = (t) => + count = 0 + isindex = (k) -> + if type(k) == "number" and + k > 0 and + math.floor(k) == k + + return true + return false + + for k, _ in pairs t + if not isindex k + return false, "{", "}" + else + count = math.max count, k + + + return true, "[", "]", count + + +JsonWriter.WriteTable = (t) => + ba, st, et, n = @\IsArray t + @\Append st + if ba + for i = 1, n + @\Write t[i] + if i < n + @\Append "," + + else + first = true + for k, v in pairs t + if not first + @\Append "," + + first = false + @\ParseString k + @\Append ":" + @\Write v + + + @\Append et + + +JsonWriter.WriteError = (o) => + error string.format "Encoding of %s unsupported", "#{o}" + + +JsonWriter.WriteFunction = (o) => + if o == Null + @\WriteNil! + else + @\WriteError o + + + +StringReader = + s: "", + i: 0, + +StringReader.New = (s) => + o = <>: @ + @__index = @ + o.s = s or o.s + o + + +StringReader.Peek ==> + i = @i + 1 + if i <= #@s + return string.sub @s, i, i + nil + +StringReader.Next ==> + @i = @i + 1 + if @i <= #@s + return string.sub @s, @i, @i + nil + + +StringReader.All ==> @s + + +JsonReader = + escapes: + ["t"]: "\t", + ["n"]: "\n", + ["f"]: "\f", + ["r"]: "\r", + ["b"]: "\b", + +JsonReader.New = (s) => + o = <>: @ + o.reader = StringReader\New s + @__index = @ + o + + +JsonReader.Read ==> + @\SkipWhiteSpace! + peek = @\Peek! + return if not peek? + error string.format "Nil string: '%s'", @\All! + elseif peek == "{" + @\ReadObject! + elseif peek == "[" + @\ReadArray! + elseif peek == '"' + @\ReadString! + elseif string.find peek, "[%+%-%d]" + @\ReadNumber! + elseif peek == "t" + @\ReadTrue! + elseif peek == "f" + @\ReadFalse! + elseif peek == "n" + @\ReadNull! + elseif peek == "/" + @\ReadComment! + @\Read! + else + nil + +JsonReader.ReadTrue ==> + @\TestReservedWord { "t", "r", "u", "e" } + true + +JsonReader.ReadFalse ==> + @\TestReservedWord { "f", "a", "l", "s", "e" } + false + +JsonReader.ReadNull ==> + @\TestReservedWord { "n", "u", "l", "l" } + nil + +JsonReader.TestReservedWord = (t) => + for _, v in ipairs t + if @\Next! ~= v + error string.format "Error reading '%s': %s", table.concat(t), @\All! + + +JsonReader.ReadNumber ==> + result = @\Next! + peek = @\Peek! + while peek? and string.find peek, "[%+%-%d%.eE]" + result ..= @\Next! + peek = @\Peek! + + result = tonumber result + if not result? + error string.format "Invalid number: '%s'", result + else + return result + + + +JsonReader.ReadString ==> + result = "" + assert @\Next! == '"' + while @\Peek! ~= '"' + ch = @\Next! + if ch == "\\" + ch = @\Next! + if @escapes[ch] + ch = @escapes[ch] + + result ..= ch + + assert @\Next! == '"' + fromunicode = (m) -> string.char tonumber m, 16 + + string.gsub result, "u%x%x(%x%x)", fromunicode + + +JsonReader.ReadComment ==> + assert @\Next! == "/" + second = @\Next! + if second == "/" + @\ReadSingleLineComment! + elseif second == "*" + @\ReadBlockComment! + else + error string.format "Invalid comment: %s", @\All! + + +JsonReader.ReadBlockComment ==> + done = false + until done + ch = @\Next! + if ch == "*" and @\Peek! == "/" + done = true + + if not done and ch == "/" and @\Peek! == "*" + error string.format "Invalid comment: %s, '/*' illegal.", @\All! + + + @\Next! + + +JsonReader.ReadSingleLineComment ==> + ch = @\Next! + while ch ~= "\r" and ch ~= "\n" + ch = @\Next! + + +JsonReader.ReadArray ==> + result = {} + assert @\Next! == "[" + done = false + if @\Peek! == "]" + done = true + + until done + item = @\Read! + result[] = item + @\SkipWhiteSpace! + if @\Peek! == "]" + done = true + + if not done + ch = @\Next! + if ch ~= "," + error string.format "Invalid array: '%s' due to: '%s'", @\All!, ch + + + assert "]" == @\Next! + result + + +JsonReader.ReadObject ==> + result = {} + assert @\Next! == "{" + done = false + if @\Peek! == "}" + done = true + + until done + key = @\Read! + if type(key) ~= "string" + error string.format "Invalid non-string object key: %s", key + + @\SkipWhiteSpace! + ch = @\Next! + if ch ~= ":" + error string.format "Invalid object: '%s' due to: '%s'", @\All!, ch + + @\SkipWhiteSpace! + val = @\Read! + result[key] = val + @\SkipWhiteSpace! + if @\Peek! == "}" + done = true + + if not done + ch = @\Next! + if ch ~= "," + error string.format "Invalid array: '%s' near: '%s'", @\All!, ch + + + + assert @\Next! == "}" + result + + +JsonReader.SkipWhiteSpace ==> + p = @\Peek! + while p? and string.find p, "[%s/]" + if p == "/" + @\ReadComment! + else + @\Next! + + p = @\Peek! + + +JsonReader.Peek ==> @reader\Peek! +JsonReader.Next ==> @reader\Next! +JsonReader.All ==> @reader\All! + +Encode = (o) -> + with JsonWriter\New! + \Write o + \ToString! + + +Decode = (s) -> + with JsonReader\New s + \Read! + +-------------------- End JSON Parser ------------------------ + +-- TODO diff --git a/yue/89449008.lua b/yue/89449008.lua new file mode 100644 index 0000000..1be3b70 --- /dev/null +++ b/yue/89449008.lua @@ -0,0 +1,863 @@ +local New +New = function(className, name, props) + if not (props ~= nil) then + props = name + name = nil + end + local obj = New(className) + if name then + obj.Name = name + end + local parent + for k, v in pairs(props) do + if type(k) == "string" then + if k == "Parent" then + parent = v + else + obj[k] = v + end + elseif type(k) == "number" and type(v) == "userdata" then + v.Parent = obj + end + end + obj.Parent = parent + return obj +end +local waitForChild +waitForChild = function(instance, name) + assert(instance) + assert(name) + while not instance:FindFirstChild(name) do + print("Waiting for ...", instance, name) + instance.ChildAdded:wait() + end + return instance:FindFirstChild(name) +end +local waitForProperty +waitForProperty = function(instance, property) + assert(instance) + assert(property) + while not instance[property] do + instance.Changed:wait() + end +end +local IsTouchDevice +IsTouchDevice = function() + local touchEnabled = false +pcall(function() + touchEnabled = Game:GetService("UserInputService").TouchEnabled + end) + return touchEnabled +end +waitForChild(game, "Players") +waitForProperty(game.Players, "LocalPlayer") +local player = game.Players.LocalPlayer +local RbxGui, _ +RbxGui, _ = LoadLibrary("RbxGui") +if not RbxGui then + print("could not find RbxGui!") + return +end +local StaticTabName = "gear" +local backpack = script.Parent +local backpackItems = { } +local buttons = { } +local debounce = false +local browsingMenu = false +local mouseEnterCons = { } +local mouseClickCons = { } +local characterChildAddedCon +local characterChildRemovedCon +local backpackAddCon +local playerBackpack = waitForChild(player, "Backpack") +waitForChild(backpack, "Tabs") +waitForChild(backpack, "Gear") +local gearPreview = waitForChild(backpack.Gear, "GearPreview") +local scroller = waitForChild(backpack.Gear, "GearGridScrollingArea") +local currentLoadout = waitForChild(backpack.Parent, "CurrentLoadout") +local grid = waitForChild(backpack.Gear, "GearGrid") +local gearButton = waitForChild(grid, "GearButton") +local swapSlot = waitForChild(script.Parent, "SwapSlot") +local backpackManager = waitForChild(script.Parent, "CoreScripts/BackpackScripts/BackpackManager") +local backpackOpenEvent = waitForChild(backpackManager, "BackpackOpenEvent") +local backpackCloseEvent = waitForChild(backpackManager, "BackpackCloseEvent") +local tabClickedEvent = waitForChild(backpackManager, "TabClickedEvent") +local resizeEvent = waitForChild(backpackManager, "ResizeEvent") +local searchRequestedEvent = waitForChild(backpackManager, "SearchRequestedEvent") +local tellBackpackReadyFunc = waitForChild(backpackManager, "BackpackReady") +local scrollFrame, scrollUp, scrollDown, recalculateScroll +scrollFrame, scrollUp, scrollDown, recalculateScroll = RbxGui.CreateScrollingFrame(nil, "grid", Vector2.new(6, 6)) +scrollFrame.Position = UDim2.new(0, 0, 0, 30) +scrollFrame.Size = UDim2.new(1, 0, 1, -30) +scrollFrame.Parent = backpack.Gear.GearGrid +local scrollBar = New("Frame", "ScrollBar", { + BackgroundTransparency = 0.9, + BackgroundColor3 = Color3.new(1, 1, 1), + BorderSizePixel = 0, + Size = UDim2.new(0, 17, 1, -36), + Position = UDim2.new(0, 0, 0, 18), + Parent = scroller +}) +scrollDown.Position = UDim2.new(0, 0, 1, -17) +scrollUp.Parent = scroller +scrollDown.Parent = scroller +local scrollFrameLoadout, scrollUpLoadout, scrollDownLoadout, recalculateScrollLoadout +scrollFrameLoadout, scrollUpLoadout, scrollDownLoadout, recalculateScrollLoadout = RbxGui.CreateScrollingFrame() +scrollFrameLoadout.Position = UDim2.new(0, 0, 0, 0) +scrollFrameLoadout.Size = UDim2.new(1, 0, 1, 0) +scrollFrameLoadout.Parent = backpack.Gear.GearLoadouts.LoadoutsList +local LoadoutButton = New("TextButton", "LoadoutButton", { + RobloxLocked = true, + Font = Enum.Font.ArialBold, + FontSize = Enum.FontSize.Size14, + Position = UDim2.new(0, 0, 0, 0), + Size = UDim2.new(1, 0, 0, 32), + Style = Enum.ButtonStyle.RobloxButton, + Text = "Loadout #1", + TextColor3 = Color3.new(1, 1, 1), + Parent = scrollFrameLoadout +}) +do + local _with_0 = LoadoutButton:clone() + _with_0.Text = "Loadout #2" + _with_0.Parent = scrollFrameLoadout +end +do + local _with_0 = LoadoutButton:clone() + _with_0.Text = "Loadout #3" + _with_0.Parent = scrollFrameLoadout +end +do + local _with_0 = LoadoutButton:clone() + _with_0.Text = "Loadout #4" + _with_0.Parent = scrollFrameLoadout +end +New("Frame", "ScrollBarLoadout", { + BackgroundTransparency = 0.9, + BackgroundColor3 = Color3.new(1, 1, 1), + BorderSizePixel = 0, + Size = UDim2.new(0, 17, 1, -36), + Position = UDim2.new(0, 0, 0, 18), + Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea +}) +scrollDownLoadout.Position = UDim2.new(0, 0, 1, -17) +scrollUpLoadout.Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea +scrollDownLoadout.Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea +local removeFromMap +removeFromMap = function(map, object) + for i = 1, #map do + if map[i] == object then + table.remove(map, i) + break + end + end +end +local robloxLock +robloxLock = function(instance) + instance.RobloxLocked = true + local children = instance:GetChildren() + if children then + for _, child in ipairs(children) do + robloxLock(child) + end + end +end +local clearPreview +clearPreview = function() + gearPreview.GearImage.Image = "" + gearPreview.GearStats.GearName.Text = "" +end +local clearHighlight +clearHighlight = function(button) + button.TextColor3 = Color3.new(1, 1, 1) + button.BackgroundColor3 = Color3.new(0, 0, 0) +end +local inLoadout +inLoadout = function(gear) + local children = currentLoadout:GetChildren() + for i = 1, #children do + if children[i]:IsA("Frame") then + local button = children[i]:GetChildren() + if #button > 0 and button[1].GearReference.Value and button[1].GearReference.Value == gear then + return true + end + end + end + return false +end +local updateGridActive +updateGridActive = function() + for _, v in pairs(backpackItems) do + if buttons[v] then + local gear + local gearRef = buttons[v]:FindFirstChild("GearReference") + if gearRef then + gear = gearRef.Value + end + if (not gear) or inLoadout(gear) then + buttons[v].Active = false + else + buttons[v].Active = true + end + end + end +end +local swapGearSlot +swapGearSlot = function(slot, gearButton) + if not swapSlot.Value then + swapSlot.Slot.Value = slot + swapSlot.GearButton.Value = gearButton + swapSlot.Value = true + return updateGridActive() + end +end +local unequipGear +unequipGear = function(physGear) + physGear.Parent = playerBackpack + return updateGridActive() +end +local UnequipGearMenuClick +UnequipGearMenuClick = function(element, menu) + if type(element.Action) ~= "number" then + return + end + local num = element.Action + if num == 1 then + unequipGear(menu.Parent.GearReference.Value) + local inventoryButton = menu.Parent + local gearToUnequip = inventoryButton.GearReference.Value + local loadoutChildren = currentLoadout:GetChildren() + local slot = -1 + for i = 1, #loadoutChildren do + if loadoutChildren[i]:IsA("Frame") then + local button = loadoutChildren[i]:GetChildren() + if button[1] and button[1].GearReference.Value == gearToUnequip then + slot = button[1].SlotNumber.Text + break + end + end + end + return swapGearSlot(slot, nil) + end +end +local highlight +highlight = function(button) + button.TextColor3 = Color3.new(0, 0, 0) + button.BackgroundColor3 = Color3.new(0.8, 0.8, 0.8) +end +local getGearContextMenu +getGearContextMenu = function() + local gearContextMenu = New("Frame", "UnequipContextMenu", { + Active = true, + Size = UDim2.new(0, 115, 0, 70), + Position = UDim2.new(0, -16, 0, -16), + BackgroundTransparency = 1, + Visible = false + }) + local gearContextMenuButton = New("TextButton", "UnequipContextMenuButton", { + Text = "", + Style = Enum.ButtonStyle.RobloxButtonDefault, + ZIndex = 8, + Size = UDim2.new(1, 0, 1, -20), + Visible = true, + Parent = gearContextMenu + }) + local elementHeight = 12 + local contextMenuElements = { } + local contextMenuElementsName = { + "Remove Hotkey" + } + for i = 1, #contextMenuElementsName do + local element = { } + element.Type = "Button" + element.Text = contextMenuElementsName[i] + element.Action = i + element.DoIt = UnequipGearMenuClick + table.insert(contextMenuElements, element) + end + for i, contextElement in ipairs(contextMenuElements) do + local element = contextElement + if element.Type == "Button" then + local button = New("TextButton", "UnequipContextButton" .. tostring(i), { + BackgroundColor3 = Color3.new(0, 0, 0), + BorderSizePixel = 0, + TextXAlignment = Enum.TextXAlignment.Left, + Text = " " .. tostring(contextElement.Text), + Font = Enum.Font.Arial, + FontSize = Enum.FontSize.Size14, + Size = UDim2.new(1, 8, 0, elementHeight), + Position = UDim2.new(0, 0, 0, elementHeight * i), + TextColor3 = Color3.new(1, 1, 1), + ZIndex = 9, + Parent = gearContextMenuButton + }) + if not IsTouchDevice() then + button.MouseButton1Click:connect(function() + if button.Active and not gearContextMenu.Parent.Active then +pcall(function() + return element.DoIt(element, gearContextMenu) + end) + browsingMenu = false + gearContextMenu.Visible = false + clearHighlight(button) + return clearPreview() + end + end) + button.MouseEnter:connect(function() + if button.Active and gearContextMenu.Parent.Active then + return highlight(button) + end + end) + button.MouseLeave:connect(function() + if button.Active and gearContextMenu.Parent.Active then + return clearHighlight(button) + end + end) + end + contextElement.Button = button + contextElement.Element = button + elseif element.Type == "Label" then + local frame = New("Frame", "ContextLabel" .. tostring(i), { + BackgroundTransparency = 1, + Size = UDim2.new(1, 8, 0, elementHeight), + New("TextLabel", "Text1", { + BackgroundTransparency = 1, + BackgroundColor3 = Color3.new(1, 1, 1), + BorderSizePixel = 0, + TextXAlignment = Enum.TextXAlignment.Left, + Font = Enum.Font.ArialBold, + FontSize = Enum.FontSize.Size14, + Position = UDim2.new(0, 0, 0, 0), + Size = UDim2.new(0.5, 0, 1, 0), + TextColor3 = Color3.new(1, 1, 1), + ZIndex = 9 + }) + }) + element.Label1 = frame.Text1 + if element.GetText2 then + element.Label2 = New("TextLabel", "Text2", { + BackgroundTransparency = 1, + BackgroundColor3 = Color3.new(1, 1, 1), + BorderSizePixel = 0, + TextXAlignment = Enum.TextXAlignment.Right, + Font = Enum.Font.Arial, + FontSize = Enum.FontSize.Size14, + Position = UDim2.new(0.5, 0, 0, 0), + Size = UDim2.new(0.5, 0, 1, 0), + TextColor3 = Color3.new(1, 1, 1), + ZIndex = 9, + Parent = frame + }) + end + frame.Parent = gearContextMenuButton + element.Label = frame + element.Element = frame + end + end + gearContextMenu.ZIndex = 4 + gearContextMenu.MouseLeave:connect(function() + browsingMenu = false + gearContextMenu.Visible = false + return clearPreview() + end) + robloxLock(gearContextMenu) + return gearContextMenu +end +local findEmptySlot +findEmptySlot = function() + local smallestNum + local loadout = currentLoadout:GetChildren() + for i = 1, #loadout do + if loadout[i]:IsA("Frame") and #loadout[i]:GetChildren() <= 0 then + local frameNum = tonumber(string.sub(loadout[i].Name, 5)) + if frameNum == 0 then + frameNum = 10 + end + if not smallestNum or (smallestNum > frameNum) then + smallestNum = frameNum + end + end + end + if smallestNum == 10 then + smallestNum = 0 + end + return smallestNum +end +local checkForSwap +checkForSwap = function(button, x, y) + local loadoutChildren = currentLoadout:GetChildren() + for i = 1, #loadoutChildren do + if loadoutChildren[i]:IsA("Frame") and string.find(loadoutChildren[i].Name, "Slot") then + if x >= loadoutChildren[i].AbsolutePosition.x and x <= (loadoutChildren[i].AbsolutePosition.x + loadoutChildren[i].AbsoluteSize.x) then + if y >= loadoutChildren[i].AbsolutePosition.y and y <= (loadoutChildren[i].AbsolutePosition.y + loadoutChildren[i].AbsoluteSize.y) then + local slot = tonumber(string.sub(loadoutChildren[i].Name, 5)) + swapGearSlot(slot, button) + return true + end + end + end + end + return false +end +local previewGear +previewGear = function(button) + if not browsingMenu then + gearPreview.Visible = false + gearPreview.GearImage.Image = button.Image + gearPreview.GearStats.GearName.Text = button.GearReference.Value.Name + end +end +local buttonClick +buttonClick = function(button) + if button:FindFirstChild("UnequipContextMenu" and not button.Active) then + button.UnequipContextMenu.Visible = true + browsingMenu = true + end +end +local resizeGrid +resizeGrid = function() + for _, v in pairs(backpackItems) do + if not v:FindFirstChild("RobloxBuildTool") then + if not buttons[v] then + local buttonClone = gearButton:clone() + buttonClone.Parent = grid.ScrollingFrame + buttonClone.Visible = true + buttonClone.Image = v.TextureId + if buttonClone.Image == "" then + buttonClone.GearText.Text = v.Name + end + buttonClone.GearReference.Value = v + buttonClone.Draggable = true + buttons[v] = buttonClone + if not IsTouchDevice() then + local unequipMenu = getGearContextMenu() + unequipMenu.Visible = false + unequipMenu.Parent = buttonClone + end + local beginPos + buttonClone.DragBegin:connect(function(value) + waitForChild(buttonClone, "Background") + buttonClone["Background"].ZIndex = 10 + buttonClone.ZIndex = 10 + beginPos = value + end) + buttonClone.DragStopped:connect(function(x, y) + waitForChild(buttonClone, "Background") + buttonClone["Background"].ZIndex = 1 + buttonClone.ZIndex = 2 + if beginPos ~= buttonClone.Position then + if not checkForSwap(buttonClone, x, y) then + buttonClone:TweenPosition(beginPos, Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.5, true) + buttonClone.Draggable = false + return delay(0.5, function() + buttonClone.Draggable = true + end) + else + buttonClone.Position = beginPos + end + end + end) + local clickTime = tick() + mouseEnterCons[buttonClone] = buttonClone.MouseEnter:connect(function() + return previewGear(buttonClone) + end) + mouseClickCons[buttonClone] = buttonClone.MouseButton1Click:connect(function() + local newClickTime = tick() + if buttonClone.Active and (newClickTime - clickTime) < 0.5 then + local slot = findEmptySlot() + if slot then + buttonClone.ZIndex = 1 + swapGearSlot(slot, buttonClone) + end + else + buttonClick(buttonClone) + end + clickTime = newClickTime + end) + end + end + end + return recalculateScroll() +end +local resize +resize = function() + local size = 0.75 * (function() + if gearPreview.AbsoluteSize.Y > gearPreview.AbsoluteSize.X then + return gearPreview.AbsoluteSize.X + else + return gearPreview.AbsoluteSize.Y + end + end)() + waitForChild(gearPreview, "GearImage") + gearPreview.GearImage.Size = UDim2.new(0, size, 0, size) + gearPreview.GearImage.Position = UDim2.new(0, gearPreview.AbsoluteSize.X / 2 - size / 2, 0.75, -size) + return resizeGrid() +end +local addToGrid +addToGrid = function(child) + if not child:IsA("Tool") and not child:IsA("HopperBin") then + return + end + if child:FindFirstChild("RobloxBuildTool") then + return + end + for _, v in pairs(backpackItems) do + if v == child then + return + end + end + table.insert(backpackItems, child) + local changeCon = child.Changed:connect(function(prop) + if prop == "Name" and buttons[child] and buttons[child].Image == "" then + buttons[child].GearText.Text = child.Name + end + end) + local ancestryCon = child.AncestryChanged:connect(function(_, _) + local thisObject + for _, v in pairs(backpackItems) do + if v == child then + thisObject = v + break + end + end + waitForProperty(player, "Character") + waitForChild(player, "Backpack") + if child.Parent ~= player.Backpack and child.Parent ~= player.Character then + do + local _obj_0 = ancestryCon + if _obj_0 ~= nil then + _obj_0:disconnect() + end + end + if changeCon ~= nil then + changeCon:disconnect() + end + for _, v in pairs(backpackItems) do + if v == thisObject then + do + local _obj_0 = mouseEnterCons[buttons[v]] + if _obj_0 ~= nil then + _obj_0:disconnect() + end + end + do + local _obj_0 = mouseClickCons[buttons[v]] + if _obj_0 ~= nil then + _obj_0:disconnect() + end + end + buttons[v].Parent = nil + buttons[v] = nil + break + end + end + removeFromMap(backpackItems, thisObject) + resizeGrid() + else + resizeGrid() + end + return updateGridActive() + end) + return resizeGrid() +end +local showPartialGrid +showPartialGrid = function(subset) + for _, v in pairs(buttons) do + v.Parent = nil + end + if subset then + for _, v in pairs(subset) do + v.Parent = grid.ScrollingFrame + end + end + return recalculateScroll() +end +local showEntireGrid +showEntireGrid = function() + for _, v in pairs(buttons) do + v.Parent = grid.ScrollingFrame + end + return recalculateScroll() +end +local centerGear +centerGear = function(loadoutChildren) + local gearButtons = { } + local lastSlotAdd + for i = 1, #loadoutChildren do + if loadoutChildren[i]:IsA("Frame") and #loadoutChildren[i]:GetChildren() > 0 then + if loadoutChildren[i].Name == "Slot0" then + lastSlotAdd = loadoutChildren[i] + else + table.insert(gearButtons, loadoutChildren[i]) + end + end + end + if lastSlotAdd then + table.insert(gearButtons, lastSlotAdd) + end + local startPos = (1 - (#gearButtons * 0.1)) / 2 + for i = 1, #gearButtons do + gearButtons[i]:TweenPosition(UDim2.new(startPos + ((i - 1) * 0.1), 0, 0, 0), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 0.25, true) + end +end +local backpackOpenHandler +backpackOpenHandler = function(currentTab) + if currentTab and currentTab ~= StaticTabName then + backpack.Gear.Visible = false + return + end + backpack.Gear.Visible = true + updateGridActive() + resizeGrid() + resize() + return tellBackpackReadyFunc:Invoke() +end +local backpackCloseHandler +backpackCloseHandler = function(currentTab) + if currentTab and currentTab ~= StaticTabName then + backpack.Gear.Visible = false + return + end + backpack.Gear.Visible = false + resizeGrid() + resize() + return tellBackpackReadyFunc:Invoke() +end +local tabClickHandler +tabClickHandler = function(tabName) + if tabName == StaticTabName then + return backpackOpenHandler(tabName) + else + return backpackCloseHandler(tabName) + end +end +local loadoutCheck +loadoutCheck = function(child, selectState) + if not child:IsA("ImageButton") then + return + end + for _, v in pairs(backpackItems) do + if buttons[v] then + if child:FindFirstChild("GearReference" and buttons[v]:FindFirstChild("GearReference")) then + if buttons[v].GearReference.Value == child.GearReference.Value then + buttons[v].Active = selectState + break + end + end + end + end +end +local setupCharacterConnections +setupCharacterConnections = function() + if backpackAddCon ~= nil then + backpackAddCon:disconnect() + end + backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded:connect(function(child) + return addToGrid(child) + end) + local backpackChildren = game.Players.LocalPlayer.Backpack:GetChildren() + for i = 1, #backpackChildren do + addToGrid(backpackChildren[i]) + end + if characterChildAddedCon ~= nil then + characterChildAddedCon:disconnect() + end + characterChildAddedCon = game.Players.LocalPlayer.Character.ChildAdded:connect(function(child) + addToGrid(child) + return updateGridActive() + end) + if characterChildRemovedCon ~= nil then + characterChildRemovedCon:disconnect() + end + characterChildRemovedCon = game.Players.LocalPlayer.Character.ChildRemoved:connect(function(_) + return updateGridActive() + end) + wait() + return centerGear(currentLoadout:GetChildren()) +end +local removeCharacterConnections +removeCharacterConnections = function() + if characterChildAddedCon ~= nil then + characterChildAddedCon:disconnect() + end + if characterChildRemovedCon ~= nil then + characterChildRemovedCon:disconnect() + end + if backpackAddCon ~= nil then + return backpackAddCon:disconnect() + end + return nil +end +local trim +trim = function(s) + return s:gsub("^%s*(.-)%s*$", "%1") +end +local filterGear +filterGear = function(terms) + local filteredGear = { } + for _, v in pairs(backpackItems) do + if buttons[v] then + local gearString = string.lower(buttons[v].GearReference.Value.Name) + gearString = trim(gearString) + for i = 1, #terms do + if string.match(gearString, terms[i]) then + table.insert(filteredGear, buttons[v]) + break + end + end + end + end + return filteredGear +end +local splitByWhitespace +splitByWhitespace = function(text) + if type(text) ~= "string" then + return + end + local terms = { } + for token in string.gmatch(text, "[^%s]+") do + if string.len(token) > 0 then + table.insert(terms, token) + end + end + return terms +end +local showSearchGear +showSearchGear = function(searchTerms) + if not backpack.Gear.Visible then + return + end + local searchTermTable = splitByWhitespace(searchTerms) + local currSearchTerms + if searchTermTable and (#searchTermTable > 0) then + currSearchTerms = searchTermTable + else + currSearchTerms = nil + end + if not (searchTermTable ~= nil) then + showEntireGrid() + return + end + local filteredButtons = filterGear(currSearchTerms) + return showPartialGrid(filteredButtons) +end +local nukeBackpack +nukeBackpack = function() + while #buttons > 0 do + table.remove(buttons) + end + buttons = { } + while #backpackItems > 0 do + table.remove(backpackItems) + end + backpackItems = { } + local scrollingFrameChildren = grid.ScrollingFrame:GetChildren() + for i = 1, #scrollingFrameChildren do + scrollingFrameChildren[i]:remove() + end +end +local coreGuiChanged +coreGuiChanged = function(coreGuiType, enabled) + if coreGuiType == Enum.CoreGuiType.Backpack or coreGuiType == Enum.CoreGuiType.All then + if not enabled then + backpack.Gear.Visible = false + end + end +end +local backpackChildren = player.Backpack:GetChildren() +for i = 1, #backpackChildren do + addToGrid(backpackChildren[i]) +end +resizeEvent.Event:connect(function(_) + if debounce then + return + end + debounce = true + wait() + resize() + resizeGrid() + debounce = false +end) +currentLoadout.ChildAdded:connect(function(child) + return loadoutCheck(child, false) +end) +currentLoadout.ChildRemoved:connect(function(child) + return loadoutCheck(child, true) +end) +currentLoadout.DescendantAdded:connect(function(descendant) + if not backpack.Visible and (descendant:IsA("ImageButton") or descendant:IsA("TextButton")) then + return centerGear(currentLoadout:GetChildren()) + end +end) +currentLoadout.DescendantRemoving:connect(function(descendant) + if not backpack.Visible and (descendant:IsA("ImageButton") or descendant:IsA("TextButton")) then + wait() + return centerGear(currentLoadout:GetChildren()) + end +end) +grid.MouseEnter:connect(function() + return clearPreview() +end) +grid.MouseLeave:connect(function() + return clearPreview() +end) +player.CharacterRemoving:connect(function() + removeCharacterConnections() + return nukeBackpack() +end) +player.CharacterAdded:connect(function() + return setupCharacterConnections() +end) +player.ChildAdded:connect(function(child) + if child:IsA("Backpack") then + playerBackpack = child + if backpackAddCon ~= nil then + backpackAddCon:disconnect() + end + backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded:connect(function(child) + return addToGrid(child) + end) + end +end) +swapSlot.Changed:connect(function() + if not swapSlot.Value then + return updateGridActive() + end +end) +local loadoutChildren = currentLoadout:GetChildren() +for i = 1, #loadoutChildren do + if loadoutChildren[i]:IsA("Frame") and string.find(loadoutChildren[i].Name, "Slot") then + loadoutChildren[i].ChildRemoved:connect(function() + return updateGridActive() + end) + loadoutChildren[i].ChildAdded:connect(function() + return updateGridActive() + end) + end +end +pcall(function() + coreGuiChanged(Enum.CoreGuiType.Backpack, Game.StarterGui:GetCoreGuiEnabled(Enum.CoreGuiType.Backpack)) + return Game.StarterGui.CoreGuiChangedSignal:connect(coreGuiChanged) +end) +resize() +resizeGrid() +loadoutChildren = currentLoadout:GetChildren() +for i = 1, #loadoutChildren do + loadoutCheck(loadoutChildren[i], false) +end +if not backpack.Visible then + centerGear(currentLoadout:GetChildren()) +end +if not (characterChildAddedCon ~= nil) and game.Players.LocalPlayer["Character"] then + setupCharacterConnections() +end +if not backpackAddCon then + backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded:connect(function(child) + return addToGrid(child) + end) +end +backpackOpenEvent.Event:connect(backpackOpenHandler) +backpackCloseEvent.Event:connect(backpackCloseHandler) +tabClickedEvent.Event:connect(tabClickHandler) +searchRequestedEvent.Event:connect(showSearchGear) +return recalculateScrollLoadout() diff --git a/yue/89449008.yue b/yue/89449008.yue index e69de29..ee2db55 100644 --- a/yue/89449008.yue +++ b/yue/89449008.yue @@ -0,0 +1,826 @@ +-- Heliodex's basic New function (basically a simplified version of melt) +New = (className, name, props) -> + if not props? -- no name was provided + props = name + name = nil + + obj = New className + obj.Name = name if name + local parent + + for k, v in pairs props + if type(k) == "string" + if k == "Parent" + parent = v + else + obj[k] = v + + elseif type(k) == "number" and type(v) == "userdata" + v.Parent = obj + + obj.Parent = parent + obj +-- + +-- A couple of necessary functions +waitForChild = (instance, name) -> + assert instance + assert name + while not instance\FindFirstChild name + print "Waiting for ...", instance, name + instance.ChildAdded\wait! + + instance\FindFirstChild name + +waitForProperty = (instance, property) -> + assert instance + assert property + while not instance[property] + instance.Changed\wait! + + +local IsTouchDevice = -> + touchEnabled = false + try + touchEnabled = Game\GetService"UserInputService".TouchEnabled + touchEnabled + + +waitForChild game, "Players" +waitForProperty game.Players, "LocalPlayer" +player = game.Players.LocalPlayer + +local RbxGui, _ = LoadLibrary "RbxGui" +if not RbxGui + print "could not find RbxGui!" + return + +--- Begin Locals +StaticTabName = "gear" + +backpack = script.Parent + +backpackItems = {} +buttons = {} + +debounce = false +browsingMenu = false + +mouseEnterCons = {} +mouseClickCons = {} + +local characterChildAddedCon +local characterChildRemovedCon +local backpackAddCon + +playerBackpack = waitForChild player, "Backpack" + +waitForChild backpack, "Tabs" + +waitForChild backpack, "Gear" +gearPreview = waitForChild backpack.Gear, "GearPreview" + +scroller = waitForChild backpack.Gear, "GearGridScrollingArea" + +currentLoadout = waitForChild backpack.Parent, "CurrentLoadout" + +grid = waitForChild backpack.Gear, "GearGrid" +gearButton = waitForChild grid, "GearButton" + +swapSlot = waitForChild script.Parent, "SwapSlot" + +backpackManager = waitForChild script.Parent, "CoreScripts/BackpackScripts/BackpackManager" +backpackOpenEvent = waitForChild backpackManager, "BackpackOpenEvent" +backpackCloseEvent = waitForChild backpackManager, "BackpackCloseEvent" +tabClickedEvent = waitForChild backpackManager, "TabClickedEvent" +resizeEvent = waitForChild backpackManager, "ResizeEvent" +searchRequestedEvent = waitForChild backpackManager, "SearchRequestedEvent" +tellBackpackReadyFunc = waitForChild backpackManager, "BackpackReady" + +-- creating scroll bar early as to make sure items get placed correctly +local scrollFrame, scrollUp, scrollDown, recalculateScroll = RbxGui.CreateScrollingFrame nil, "grid", Vector2.new 6, 6 + +scrollFrame.Position = UDim2.new 0, 0, 0, 30 +scrollFrame.Size = UDim2.new 1, 0, 1, -30 +scrollFrame.Parent = backpack.Gear.GearGrid + +scrollBar = New "Frame", "ScrollBar" + BackgroundTransparency: 0.9 + BackgroundColor3: Color3.new 1, 1, 1 + BorderSizePixel: 0 + Size: UDim2.new 0, 17, 1, -36 + Position: UDim2.new 0, 0, 0, 18 + Parent: scroller + +scrollDown.Position = UDim2.new 0, 0, 1, -17 + +scrollUp.Parent = scroller +scrollDown.Parent = scroller + +local scrollFrameLoadout, scrollUpLoadout, scrollDownLoadout, recalculateScrollLoadout = RbxGui.CreateScrollingFrame! + +scrollFrameLoadout.Position = UDim2.new 0, 0, 0, 0 +scrollFrameLoadout.Size = UDim2.new 1, 0, 1, 0 +scrollFrameLoadout.Parent = backpack.Gear.GearLoadouts.LoadoutsList + +LoadoutButton = New "TextButton", "LoadoutButton" + RobloxLocked: true + Font: Enum.Font.ArialBold + FontSize: Enum.FontSize.Size14 + Position: UDim2.new 0, 0, 0, 0 + Size: UDim2.new 1, 0, 0, 32 + Style: Enum.ButtonStyle.RobloxButton + Text: "Loadout #1" + TextColor3: Color3.new 1, 1, 1 + Parent: scrollFrameLoadout + +with LoadoutButton\clone! + .Text = "Loadout #2" + .Parent = scrollFrameLoadout + +with LoadoutButton\clone! + .Text = "Loadout #3" + .Parent = scrollFrameLoadout + +with LoadoutButton\clone! + .Text = "Loadout #4" + .Parent = scrollFrameLoadout + +New "Frame", "ScrollBarLoadout" + BackgroundTransparency: 0.9 + BackgroundColor3: Color3.new 1, 1, 1 + BorderSizePixel: 0 + Size: UDim2.new 0, 17, 1, -36 + Position: UDim2.new 0, 0, 0, 18 + Parent: backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea + +scrollDownLoadout.Position = UDim2.new 0, 0, 1, -17 + +scrollUpLoadout.Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea +scrollDownLoadout.Parent = backpack.Gear.GearLoadouts.GearLoadoutsScrollingArea + +-- Begin Functions +removeFromMap = (map, object) -> + for i = 1, #map + if map[i] == object + table.remove map, i + break + +robloxLock = (instance) -> + instance.RobloxLocked = true + children = instance\GetChildren! + if children + for _, child in ipairs children + robloxLock child + + +clearPreview = -> + gearPreview.GearImage.Image = "" + gearPreview.GearStats.GearName.Text = "" + +clearHighlight = (button) -> + button.TextColor3 = Color3.new 1, 1, 1 + button.BackgroundColor3 = Color3.new 0, 0, 0 + +inLoadout = (gear) -> + children = currentLoadout\GetChildren! + for i = 1, #children + if children[i]\IsA "Frame" + button = children[i]\GetChildren! + if #button > 0 and + button[1].GearReference.Value and + button[1].GearReference.Value == gear + return true + + false + +updateGridActive = -> + for _, v in pairs backpackItems + if buttons[v] + local gear + gearRef = buttons[v]\FindFirstChild "GearReference" + + if gearRef + gear = gearRef.Value + + buttons[v].Active = if (not gear) or inLoadout gear + false + else + true + +swapGearSlot = (slot, gearButton) -> + if not swapSlot.Value -- signal loadout to swap a gear out + swapSlot.Slot.Value = slot + swapSlot.GearButton.Value = gearButton + swapSlot.Value = true + updateGridActive! + +unequipGear = (physGear) -> + physGear.Parent = playerBackpack + updateGridActive! + +UnequipGearMenuClick = (element, menu) -> + return if type(element.Action) ~= "number" + + num = element.Action + if num == 1 -- remove from loadout + unequipGear menu.Parent.GearReference.Value + inventoryButton = menu.Parent + gearToUnequip = inventoryButton.GearReference.Value + loadoutChildren = currentLoadout\GetChildren! + slot = -1 + for i = 1, #loadoutChildren + if loadoutChildren[i]\IsA "Frame" + button = loadoutChildren[i]\GetChildren! + if button[1] and button[1].GearReference.Value == gearToUnequip + slot = button[1].SlotNumber.Text + break + + swapGearSlot slot, nil + + +highlight = (button) -> + button.TextColor3 = Color3.new 0, 0, 0 + button.BackgroundColor3 = Color3.new 0.8, 0.8, 0.8 + +getGearContextMenu = -> + gearContextMenu = New "Frame", "UnequipContextMenu" + Active: true + Size: UDim2.new 0, 115, 0, 70 + Position: UDim2.new 0, -16, 0, -16 + BackgroundTransparency: 1 + Visible: false + + gearContextMenuButton = New "TextButton", "UnequipContextMenuButton" + Text: "" + Style: Enum.ButtonStyle.RobloxButtonDefault + ZIndex: 8 + Size: UDim2.new 1, 0, 1, -20 + Visible: true + Parent: gearContextMenu + + elementHeight = 12 + + contextMenuElements = {} + contextMenuElementsName = { "Remove Hotkey" } + + for i = 1, #contextMenuElementsName + element = {} + element.Type = "Button" + element.Text = contextMenuElementsName[i] + element.Action = i + element.DoIt = UnequipGearMenuClick + table.insert contextMenuElements, element + + + for i, contextElement in ipairs contextMenuElements + element = contextElement + if element.Type == "Button" + button = New "TextButton", "UnequipContextButton#{i}" + BackgroundColor3: Color3.new 0, 0, 0 + BorderSizePixel: 0 + TextXAlignment: Enum.TextXAlignment.Left + Text: " #{contextElement.Text}" + Font: Enum.Font.Arial + FontSize: Enum.FontSize.Size14 + Size: UDim2.new 1, 8, 0, elementHeight + Position: UDim2.new 0, 0, 0, elementHeight * i + TextColor3: Color3.new 1, 1, 1 + ZIndex: 9 + Parent: gearContextMenuButton + + if not IsTouchDevice! + button.MouseButton1Click\connect -> + if button.Active and not gearContextMenu.Parent.Active + try + element.DoIt element, gearContextMenu + + browsingMenu = false + gearContextMenu.Visible = false + clearHighlight button + clearPreview! + + + button.MouseEnter\connect -> + if button.Active and gearContextMenu.Parent.Active + highlight button + + + button.MouseLeave\connect -> + if button.Active and gearContextMenu.Parent.Active + clearHighlight button + + + contextElement.Button = button + contextElement.Element = button + elseif element.Type == "Label" + frame = New "Frame", "ContextLabel#{i}" + BackgroundTransparency: 1 + Size: UDim2.new 1, 8, 0, elementHeight + + * New "TextLabel", "Text1" + BackgroundTransparency: 1 + BackgroundColor3: Color3.new 1, 1, 1 + BorderSizePixel: 0 + TextXAlignment: Enum.TextXAlignment.Left + Font: Enum.Font.ArialBold + FontSize: Enum.FontSize.Size14 + Position: UDim2.new 0, 0, 0, 0 + Size: UDim2.new 0.5, 0, 1, 0 + TextColor3: Color3.new 1, 1, 1 + ZIndex: 9 + + element.Label1 = frame.Text1 + + if element.GetText2 + element.Label2 = New "TextLabel", "Text2" + BackgroundTransparency: 1 + BackgroundColor3: Color3.new 1, 1, 1 + BorderSizePixel: 0 + TextXAlignment: Enum.TextXAlignment.Right + Font: Enum.Font.Arial + FontSize: Enum.FontSize.Size14 + Position: UDim2.new 0.5, 0, 0, 0 + Size: UDim2.new 0.5, 0, 1, 0 + TextColor3: Color3.new 1, 1, 1 + ZIndex: 9 + Parent: frame + + frame.Parent = gearContextMenuButton + element.Label = frame + element.Element = frame + + + gearContextMenu.ZIndex = 4 + gearContextMenu.MouseLeave\connect -> + browsingMenu = false + gearContextMenu.Visible = false + clearPreview! + + robloxLock gearContextMenu + + gearContextMenu + +findEmptySlot = -> + local smallestNum + loadout = currentLoadout\GetChildren! + for i = 1, #loadout + if loadout[i]\IsA"Frame" and #loadout[i]\GetChildren! <= 0 + frameNum = tonumber string.sub loadout[i].Name, 5 + if frameNum == 0 + frameNum = 10 + + if not smallestNum or (smallestNum > frameNum) + smallestNum = frameNum + + if smallestNum == 10 + smallestNum = 0 + + smallestNum + +checkForSwap = (button, x, y) -> + loadoutChildren = currentLoadout\GetChildren! + for i = 1, #loadoutChildren + if loadoutChildren[i]\IsA"Frame" and string.find loadoutChildren[i].Name, "Slot" + if x >= loadoutChildren[i].AbsolutePosition.x and + x <= (loadoutChildren[i].AbsolutePosition.x + loadoutChildren[i].AbsoluteSize.x) + + if y >= loadoutChildren[i].AbsolutePosition.y and + y <= (loadoutChildren[i].AbsolutePosition.y + loadoutChildren[i].AbsoluteSize.y) + + slot = tonumber string.sub loadoutChildren[i].Name, 5 + swapGearSlot slot, button + return true + false + + +previewGear = (button) -> + if not browsingMenu + gearPreview.Visible = false + gearPreview.GearImage.Image = button.Image + gearPreview.GearStats.GearName.Text = button.GearReference.Value.Name + +buttonClick = (button) -> + if button\FindFirstChild "UnequipContextMenu" and not button.Active + button.UnequipContextMenu.Visible = true + browsingMenu = true + +resizeGrid = -> + for _, v in pairs backpackItems + if not v\FindFirstChild "RobloxBuildTool" + if not buttons[v] + buttonClone = gearButton\clone! + + with buttonClone + .Parent = grid.ScrollingFrame + .Visible = true + .Image = v.TextureId + if .Image == "" + .GearText.Text = v.Name + .GearReference.Value = v + .Draggable = true + buttons[v] = buttonClone + + if not IsTouchDevice! + unequipMenu = getGearContextMenu! + + unequipMenu.Visible = false + unequipMenu.Parent = buttonClone + + + local beginPos + buttonClone.DragBegin\connect (value) -> + waitForChild buttonClone, "Background" + buttonClone["Background"].ZIndex = 10 + buttonClone.ZIndex = 10 + beginPos = value + + buttonClone.DragStopped\connect (x, y) -> + waitForChild buttonClone, "Background" + buttonClone["Background"].ZIndex = 1 + buttonClone.ZIndex = 2 + if beginPos ~= buttonClone.Position + if not checkForSwap buttonClone, x, y + buttonClone\TweenPosition( + beginPos, + Enum.EasingDirection.Out, + Enum.EasingStyle.Quad, + 0.5, + true + ) + buttonClone.Draggable = false + delay 0.5, -> + buttonClone.Draggable = true + + else + buttonClone.Position = beginPos + + + + clickTime = tick! + mouseEnterCons[buttonClone] = buttonClone.MouseEnter\connect -> + previewGear buttonClone + + mouseClickCons[buttonClone] = buttonClone.MouseButton1Click\connect -> + newClickTime = tick! + if buttonClone.Active and (newClickTime - clickTime) < 0.5 + slot = findEmptySlot! + if slot + buttonClone.ZIndex = 1 + swapGearSlot slot, buttonClone + + else + buttonClick buttonClone + + clickTime = newClickTime + + recalculateScroll! + +resize = -> + size = 0.75 * if gearPreview.AbsoluteSize.Y > gearPreview.AbsoluteSize.X + gearPreview.AbsoluteSize.X + else + gearPreview.AbsoluteSize.Y + + + waitForChild gearPreview, "GearImage" + gearPreview.GearImage.Size = UDim2.new 0, size, 0, size + gearPreview.GearImage.Position = UDim2.new 0, gearPreview.AbsoluteSize.X / 2 - size / 2, 0.75, -size + + resizeGrid! + + +addToGrid = (child) -> + return if not child\IsA"Tool" and + not child\IsA "HopperBin" + + return if child\FindFirstChild "RobloxBuildTool" + + + for _, v in pairs backpackItems -- check to see if we already have this gear registered + return if v == child + + table.insert backpackItems, child + + changeCon = child.Changed\connect (prop) -> + if prop == "Name" and + buttons[child] and + buttons[child].Image == "" + + buttons[child].GearText.Text = child.Name + + ancestryCon = child.AncestryChanged\connect (_, _) -> + local thisObject + for _, v in pairs backpackItems + if v == child + thisObject = v + break + + waitForProperty player, "Character" + waitForChild player, "Backpack" + if child.Parent ~= player.Backpack and child.Parent ~= player.Character + + ancestryCon?\disconnect! + changeCon?\disconnect! + + for _, v in pairs backpackItems + if v == thisObject + mouseEnterCons[buttons[v]]?\disconnect! + mouseClickCons[buttons[v]]?\disconnect! + + buttons[v].Parent = nil + buttons[v] = nil + break + + removeFromMap backpackItems, thisObject + + resizeGrid! + else + resizeGrid! + updateGridActive! + resizeGrid! + +showPartialGrid = (subset) -> + for _, v in pairs buttons + v.Parent = nil + + if subset + for _, v in pairs subset + v.Parent = grid.ScrollingFrame + + + recalculateScroll! + + +showEntireGrid = -> + for _, v in pairs buttons + v.Parent = grid.ScrollingFrame + + recalculateScroll! + +centerGear = (loadoutChildren) -> + gearButtons = {} + local lastSlotAdd + for i = 1, #loadoutChildren + if loadoutChildren[i]\IsA"Frame" and #loadoutChildren[i]\GetChildren! > 0 + if loadoutChildren[i].Name == "Slot0" + lastSlotAdd = loadoutChildren[i] + else + table.insert gearButtons, loadoutChildren[i] + + if lastSlotAdd + table.insert gearButtons, lastSlotAdd + + + startPos = (1 - (#gearButtons * 0.1)) / 2 + for i = 1, #gearButtons + gearButtons[i]\TweenPosition( + UDim2.new(startPos + ((i - 1) * 0.1), 0, 0, 0), + Enum.EasingDirection.Out, + Enum.EasingStyle.Quad, + 0.25, + true + ) + +backpackOpenHandler = (currentTab) -> + if currentTab and currentTab ~= StaticTabName + backpack.Gear.Visible = false + return + + backpack.Gear.Visible = true + updateGridActive! + + resizeGrid! + resize! + tellBackpackReadyFunc\Invoke! + +backpackCloseHandler = (currentTab) -> + if currentTab and currentTab ~= StaticTabName + backpack.Gear.Visible = false + return + + + backpack.Gear.Visible = false + + resizeGrid! + resize! + tellBackpackReadyFunc\Invoke! + +tabClickHandler = (tabName) -> + if tabName == StaticTabName + backpackOpenHandler tabName + else + backpackCloseHandler tabName + +loadoutCheck = (child, selectState) -> + return if not child\IsA "ImageButton" + + for _, v in pairs backpackItems + if buttons[v] + if child\FindFirstChild "GearReference" and buttons[v]\FindFirstChild "GearReference" + if buttons[v].GearReference.Value == child.GearReference.Value + buttons[v].Active = selectState + break + + +-- removeAllEquippedGear = (physGear) -> +-- stuff = player.Character\GetChildren! +-- for i = 1, #stuff +-- if (stuff[i]\IsA"Tool" or stuff[i]\IsA"HopperBin") and stuff[i] ~= physGear +-- stuff[i].Parent = playerBackpack + +-- equipGear = (physGear) -> +-- removeAllEquippedGear physGear +-- physGear.Parent = player.Character +-- updateGridActive! + +setupCharacterConnections = -> + backpackAddCon?\disconnect! + backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded\connect (child) -> + addToGrid child + + + -- make sure we get all the children + backpackChildren = game.Players.LocalPlayer.Backpack\GetChildren! + for i = 1, #backpackChildren + addToGrid backpackChildren[i] + + + characterChildAddedCon?\disconnect! + characterChildAddedCon = game.Players.LocalPlayer.Character.ChildAdded\connect (child) -> + addToGrid child + updateGridActive! + + characterChildRemovedCon?\disconnect! + characterChildRemovedCon = game.Players.LocalPlayer.Character.ChildRemoved\connect (_) -> + updateGridActive! + + wait! + centerGear currentLoadout\GetChildren! + +removeCharacterConnections = -> + characterChildAddedCon?\disconnect! + characterChildRemovedCon?\disconnect! + backpackAddCon?\disconnect! + +trim = (s) -> s\gsub "^%s*(.-)%s*$", "%1" + +filterGear = (terms) -> + filteredGear = {} + for _, v in pairs backpackItems + if buttons[v] + gearString = string.lower buttons[v].GearReference.Value.Name + gearString = trim gearString + for i = 1, #terms + if string.match gearString, terms[i] + table.insert filteredGear, buttons[v] + break + + filteredGear + +splitByWhitespace = (text) -> + return if type(text) ~= "string" + + terms = {} + for token in string.gmatch text, "[^%s]+" + if string.len(token) > 0 + table.insert terms, token + terms + +showSearchGear = (searchTerms) -> + return if not backpack.Gear.Visible + + -- currently not active tab + + searchTermTable = splitByWhitespace searchTerms + local currSearchTerms + currSearchTerms = if searchTermTable and (#searchTermTable > 0) + searchTermTable + else + nil + + if not searchTermTable? + showEntireGrid! + return + + filteredButtons = filterGear currSearchTerms + showPartialGrid filteredButtons + + +nukeBackpack = -> + while #buttons > 0 + table.remove buttons + + buttons = {} + while #backpackItems > 0 + table.remove backpackItems + + backpackItems = {} + scrollingFrameChildren = grid.ScrollingFrame\GetChildren! + for i = 1, #scrollingFrameChildren + scrollingFrameChildren[i]\remove! + +coreGuiChanged = (coreGuiType, enabled) -> + if coreGuiType == Enum.CoreGuiType.Backpack or coreGuiType == Enum.CoreGuiType.All + if not enabled + backpack.Gear.Visible = false + + + + +backpackChildren = player.Backpack\GetChildren! +for i = 1, #backpackChildren + addToGrid backpackChildren[i] + + +------------------------- Start Lifelong Connections ----------------------- + +resizeEvent.Event\connect (_) -> + return if debounce + + debounce = true + wait! + resize! + resizeGrid! + debounce = false + + +currentLoadout.ChildAdded\connect (child) -> loadoutCheck child, false +currentLoadout.ChildRemoved\connect (child) -> loadoutCheck child, true + + +currentLoadout.DescendantAdded\connect (descendant) -> + if not backpack.Visible and (descendant\IsA"ImageButton" or descendant\IsA "TextButton") + centerGear currentLoadout\GetChildren! + + +currentLoadout.DescendantRemoving\connect (descendant) -> + if not backpack.Visible and (descendant\IsA"ImageButton" or descendant\IsA "TextButton") + wait! + centerGear currentLoadout\GetChildren! + + +grid.MouseEnter\connect -> clearPreview! +grid.MouseLeave\connect -> clearPreview! + + +player.CharacterRemoving\connect -> + removeCharacterConnections! + nukeBackpack! + +player.CharacterAdded\connect -> + setupCharacterConnections! + + +player.ChildAdded\connect (child) -> + if child\IsA "Backpack" + playerBackpack = child + backpackAddCon?\disconnect! + backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded\connect (child) -> + addToGrid child + + +swapSlot.Changed\connect -> + if not swapSlot.Value + updateGridActive! + +loadoutChildren = currentLoadout\GetChildren! +for i = 1, #loadoutChildren + if loadoutChildren[i]\IsA"Frame" and string.find loadoutChildren[i].Name, "Slot" + loadoutChildren[i].ChildRemoved\connect -> updateGridActive! + loadoutChildren[i].ChildAdded\connect -> updateGridActive! + + +------------------------- End Lifelong Connections ----------------------- + +try + coreGuiChanged Enum.CoreGuiType.Backpack, Game.StarterGui\GetCoreGuiEnabled Enum.CoreGuiType.Backpack + Game.StarterGui.CoreGuiChangedSignal\connect coreGuiChanged + + +resize! +resizeGrid! + +-- make sure any items in the loadout are accounted for in inventory +loadoutChildren = currentLoadout\GetChildren! +for i = 1, #loadoutChildren + loadoutCheck loadoutChildren[i], false + +if not backpack.Visible + centerGear currentLoadout\GetChildren! + + +-- make sure that inventory is listening to gear reparenting +if not characterChildAddedCon? and game.Players.LocalPlayer["Character"] + setupCharacterConnections! + +if not backpackAddCon + backpackAddCon = game.Players.LocalPlayer.Backpack.ChildAdded\connect (child) -> + addToGrid child + +backpackOpenEvent.Event\connect backpackOpenHandler +backpackCloseEvent.Event\connect backpackCloseHandler +tabClickedEvent.Event\connect tabClickHandler +searchRequestedEvent.Event\connect showSearchGear + +recalculateScrollLoadout!