Write more corescripts in Yuescript

This commit is contained in:
Lewin Kelly 2023-04-19 23:04:01 +01:00
parent a98951aca6
commit 58df0a7c90
4 changed files with 2463 additions and 0 deletions

391
yue/60595411.lua Normal file
View File

@ -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

View File

@ -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

863
yue/89449008.lua Normal file
View File

@ -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()

View File

@ -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!