local N={}N.OpenClose=nil N.IsOpen=false N.StateChanged=Instance.new("\066\105\110\100\097\098\108\101\069\118\101\110\116")N.ModuleName="\066\097\099\107\112\097\099\107"N.KeepVRTopbarOpen=true N.VRIsExclusive=true N.VRClosesNonExclusive=true local k=55 local z=Enum.FontSize.Size14 local L=6.5 local l=.6 local K=Color3.new(.12156862745098,.12156862745098,.12156862745098)local w=1 local s=100 local M=Color3.new(.176471,.176471,.176471)local O=.4 local j=Color3.new(1,.772549,.309804)local X=0 local b=.6 local Z=Color3.new(.411765,.619608,1)local I=6 local i=16 local H=-25 local V="\114\098\120\097\115\115\101\116\058\047\047\116\101\120\116\117\114\101\115\047\117\105\047\084\111\112\066\097\114\047\105\110\118\101\110\116\111\114\121\079\110\046\112\110\103"local q="\114\098\120\097\115\115\101\116\058\047\047\116\101\120\116\117\114\101\115\047\117\105\047\084\111\112\066\097\114\047\105\110\118\101\110\116\111\114\121\079\102\102\046\112\110\103"local c={Enum.KeyCode.Backquote,Enum.KeyCode.DPadUp}local x=script.Icon local f=10 local g=6 local p=4 local U=1024 local B=-30 local m=4 local T=3 local G=2 local A=25 local D=40 local d=4 local u=125 local t="\083\101\097\114\099\104"local S=0 local J=Color3.new(0,0,0)local P=.7 local r=.5 local o=function()local N=Instance.new("\083\099\114\101\101\110\071\117\105",game.Players.LocalPlayer.PlayerGui)local k=Instance.new("\070\114\097\109\101",N)k.BackgroundTransparency=1 k.Size=UDim2.new(1,0,1,0)local z=k.AbsoluteSize N:Destroy()return z end local Y=Enum.KeyCode.Zero.Value local W=Enum.KeyCode.Backspace.Value local R={[Enum.UserInputType.Gamepad1]=true;[Enum.UserInputType.Gamepad2]=true;[Enum.UserInputType.Gamepad3]=true,[Enum.UserInputType.Gamepad4]=true;[Enum.UserInputType.Gamepad5]=true;[Enum.UserInputType.Gamepad6]=true;[Enum.UserInputType.Gamepad7]=true,[Enum.UserInputType.Gamepad8]=true}local C=game:GetService("\085\115\101\114\073\110\112\117\116\083\101\114\118\105\099\101")local y=game:GetService("\080\108\097\121\101\114\115")local h=game:GetService("\082\101\112\108\105\099\097\116\101\100\083\116\111\114\097\103\101")local v=game:GetService("\083\116\097\114\116\101\114\071\117\105")local F=game:GetService("\071\117\105\083\101\114\118\105\099\101")local a=y.LocalPlayer.PlayerGui local n=h:FindFirstChild("\084\111\112\098\097\114\080\108\117\115\082\101\102\101\114\101\110\099\101")local E=true if n then x=n.Value end local Q=Instance.new("\083\099\114\101\101\110\071\117\105",a)Q.DisplayOrder=120 Q.IgnoreGuiInset=true Q.ResetOnSpawn=false Q.Name="\066\097\099\107\112\097\099\107\071\117\105"local e=true local Nd=game:GetService("\067\111\110\116\101\120\116\065\099\116\105\111\110\083\101\114\118\105\099\101")local kd=game:GetService("\082\117\110\083\101\114\118\105\099\101")local zd=game:GetService("\086\082\083\101\114\118\105\099\101")local Ld=require(script.Utility)local ld=require(script.GameTranslator)local Kd=require(x.Themes)local wd=require(x)local sd=true local Md=true local Od=true local jd=F:IsTenFootInterface()if jd then k=100 z=Enum.FontSize.Size24 end local Xd=false local bd=C.TouchEnabled and(o()).X<U local Zd=y.LocalPlayer local Id=nil local id=nil local Hd=nil local Vd=nil local qd=nil local cd=nil local xd=nil local fd=nil local gd=nil local pd=Zd.Character or Zd.CharacterAdded:Wait()local Ud=pd:FindFirstChildOfClass("\072\117\109\097\110\111\105\100")local Bd=Zd:WaitForChild("\066\097\099\107\112\097\099\107")local md=wd.new()md:setImage(q,"\100\101\115\101\108\101\099\116\101\100")md:setImage(V,"\115\101\108\101\099\116\101\100")md:setTheme(Kd.BlueGradient)md:bindToggleKey(c[1],c[2])md:setName("\073\110\118\101\110\116\111\114\121\073\099\111\110")md:setImageYScale(1.12)md:setOrder(-5)md.deselectWhenOtherIconSelected=false local Td={}local Gd=nil local Ad={}local Dd={}local dd={}local ud=0 local td=false local Sd=false local Jd=false local Pd=false local rd={}local od={}local Yd=false local Wd=0 local Rd=zd.VREnabled local Cd=Rd and g or bd and p or f local yd=Rd and T or bd and G or m local hd=nil local vd=nil local function Fd(N)return N and(md.enabled and(E and zd.VREnabled))end local function ad()if hd and Fd(true)then hd:ForceShowForSeconds(2)end end local function nd(N,k)local L=Instance.new(N)L.Name=k L.BackgroundColor3=Color3.new(0,0,0)L.BackgroundTransparency=1 L.BorderColor3=Color3.new(0,0,0)L.BorderSizePixel=0 L.Size=UDim2.new(1,0,1,0)if N:match("\084\101\120\116")then L.TextColor3=Color3.new(1,1,1)L.Text=""L.Font=Enum.Font.SourceSans L.FontSize=z L.TextWrapped=true if N=="\084\101\120\116\066\117\116\116\111\110"then L.Font=Enum.Font.SourceSansSemibold L.BorderSizePixel=1 end end return L end local function Ed()for N=1,Cd,1 do local k=Td[N]if not k.Tool then return k end end return nil end local function Qd()for N=Cd+1,#Td,1 do local k=Td[N]if k and k.Tool then return false end end return true end local function ed()return C.VREnabled end local function NQ()local N=Hd.Visible local k=N and Cd or ud local z=0 local L=k>=1 for L=1,Cd,1 do local l=Td[L]if l.Tool or N then z=z+1 l:Readjust(z,k)l.Frame.Visible=true else l.Frame.Visible=false end end end local function kQ()local N=math.floor(qd.AbsoluteSize.X/(k+L))local z=math.ceil((#cd:GetChildren()-1)/N)local l=z*(k+L)+L qd.CanvasSize=UDim2.new(0,0,0,l)end local function zQ()for N=Cd+1,#Td,1 do local k=Td[N]k.Frame.LayoutOrder=k.Index k.Frame.Visible=k.Tool~=nil end kQ()end local function LQ()id.Size=UDim2.new(0,(L+Cd*(k+L))+120,0,(L+k)+L)id.Position=UDim2.new(.5,-id.Size.X.Offset/2,1,-id.Size.Y.Offset)Hd.Size=UDim2.new(0,id.Size.X.Offset,0,(id.Size.Y.Offset*yd+A)+(Rd and 2*D or 0))Hd.Position=UDim2.new(.5,-Hd.Size.X.Offset/2,1,id.Position.Y.Offset-Hd.Size.Y.Offset)local N=Instance.new("\085\073\067\111\114\110\101\114")N.CornerRadius=UDim.new(.015,0)N.Parent=Hd qd.Size=UDim2.new(1,qd.ScrollBarThickness+1,1,-A-(Rd and 2*D or 0))qd.Position=UDim2.new(0,0,0,A+(Rd and D or 0))NQ()zQ()end local function lQ(N,k,z)return math.min(k,math.max(N,z))end local function KQ(N,k,z)local L=N.AbsolutePosition local l=N.AbsoluteSize return k>L.X and(k<=L.X+l.X and(z>L.Y and z<=L.Y+l.Y))end local function wQ(N,k)local z=N.AbsolutePosition+N.AbsoluteSize/2 return(z-k).magnitude end local function sQ()if Ud then Ud:UnequipTools()end end local function MQ(N)sQ()N.Parent=pd end local function OQ(N)return N and N.Parent==pd end local function jQ(N,z)z=z or#Td+1 local l={}l.Tool=nil l.Index=z l.Frame=nil local w=nil local s=nil local V=nil local q=nil local c=nil local x=nil local f=nil local g=nil local p=nil local U=nil local B=nil local m=nil local function T()if zd.VREnabled and hd then local N=hd.transparency local k=b local z=(N+k)-N*k q.BackgroundTransparency=z q.TextTransparency=z if x then x.ImageTransparency=Hd.Visible and 0 or N end if p then for N,k in pairs(p:GetChildren())do k.BackgroundTransparency=z end end q.SelectionImageObject=U else q.SelectionImageObject=nil q.BackgroundTransparency=q.Draggable and O or b end q.BackgroundColor3=q.Draggable and M or K if q:FindFirstChild("\069\113\117\105\112\112\101\100")then q.BackgroundColor3=Color3.fromRGB(105,105,105)end end function l.Readjust(l,N,z)local K=id.Size.X.Offset/2 local w=L+k local s=z/2+.5 local M=N-s q.Position=UDim2.new(0,(K-k/2)+w*M,0,L)end function l.Fill(k,N)if not N then return k:Clear()end k.Tool=N local function z()if Md then local k=N.TextureId x.Image=k if k~=""then f.Visible=false end f.Text=N.Name if B and N:IsA("\084\111\111\108")then B.Text=N.ToolTip local k=B.TextBounds.X+I B.Size=UDim2.new(0,k,0,i)B.Position=UDim2.new(.5,-k/2,0,H)end else w=N.Name s=nil local k=N.TextureId x.Image=k x.AnchorPoint=Vector2.new(.5,.5)x.Position=UDim2.fromScale(.5,.5)if k~=""then f.Text=w else f.Text=""end if B and N:IsA("\084\111\111\108")then s=ld:TranslateGameText(N,N.ToolTip)B.Text=N.ToolTip local k=B.TextBounds.X+I B.Size=UDim2.new(0,k,0,i)B.Position=UDim2.new(.5,-k/2,0,H)end end end z()if g then g:disconnect()g=nil end g=N.Changed:connect(function(N)if N=="\084\101\120\116\117\114\101\073\100"or N=="\078\097\109\101"or N=="\084\111\111\108\084\105\112"then z()end end)local L=k.Index<=Cd local l=Hd.Visible if(not L or l)and not C.VREnabled then q.Draggable=true end k:UpdateEquipView()if L then ud=ud+1 if Sd then if ud>=1 and not Xd then Xd=true Nd:BindAction("\082\066\088\072\111\116\098\097\114\069\113\117\105\112",changeToolFunc,false,Enum.KeyCode.ButtonL1,Enum.KeyCode.ButtonR1)end end end Ad[N]=k Gd=Ed()end function l.Clear(N)if not N.Tool then return end if g then g:disconnect()g=nil end x.Image=""f.Text=""if B then B.Text=""B.Visible=false end q.Draggable=false N:UpdateEquipView(true)if N.Index<=Cd then ud=ud-1 if ud<1 then Xd=false Nd:UnbindAction("\082\066\088\072\111\116\098\097\114\069\113\117\105\112")end end Ad[N.Tool]=nil N.Tool=nil Gd=Ed()end function l.UpdateEquipView(k,N)if not N and OQ(k.Tool)then vd=l if not p then p=nd("\070\114\097\109\101","\069\113\117\105\112\112\101\100")p.ZIndex=q.ZIndex local N=script.Cover:Clone()N.Parent=p local k=X local z={{k,1,0;0},{1-2*k,k;k;0},{k,1,1-k;0},{1-2*k,k,k;1-k}}for N,k in pairs(z)do local z=nd("\070\114\097\109\101","\069\100\103\101")z.BackgroundTransparency=1 z.BackgroundColor3=j z.Size=UDim2.new(k[1],0,k[2],0)z.Position=UDim2.new(k[3],0,k[4],0)z.ZIndex=p.ZIndex z.Parent=p end end p.Parent=q else if p then p.Parent=nil end end T()if not N and OQ(k.Tool)then q.BackgroundColor3=Color3.fromRGB(105,105,105)else q.BackgroundColor3=Color3.fromRGB(31,31,31)end end function l.IsEquipped(N)return OQ(N.Tool)end function l.Delete(N)q:Destroy()table.remove(Td,N.Index)local k=#Td for N=N.Index,k,1 do Td[N]:SlideBack()end kQ()end function l.Swap(k,N)local z,L=k.Tool,N.Tool k:Clear()if L then N:Clear()k:Fill(L)end if z then N:Fill(z)else N:Clear()end end function l.SlideBack(N)N.Index=N.Index-1 q.Name=N.Index q.LayoutOrder=N.Index end function l.TurnNumber(k,N)if m then m.Visible=N end end function l.SetClickability(k,N)if k.Tool then if C.VREnabled then q.Draggable=false else q.Draggable=not N end T()end end function l.CheckTerms(k,N)local z=0 local function L(N,k)local L,l=(N:lower()):gsub(k,"")z=z+l end local l=k.Tool if l then for N in pairs(N)do if Md then L(f.Text,N)if l:IsA("\084\111\111\108")then local k=B and B.Text or""L(k,N)end else L(w,N)if l:IsA("\084\111\111\108")then L(s,N)end end end end return z end function l.Select(N)local k=l.Tool if k then if OQ(k)then sQ()elseif k.Parent==Bd then MQ(k)end end end q=nd("\084\101\120\116\066\117\116\116\111\110",z)q.BackgroundColor3=K q.BorderColor3=Z q.Text=""q.AutoButtonColor=false q.BorderSizePixel=0 q.Size=UDim2.new(0,k,0,k)q.Active=true q.Draggable=false q.BackgroundTransparency=b q.MouseButton1Click:connect(function()changeSlot(l)end)local G=Instance.new("\085\073\067\111\114\110\101\114")G.CornerRadius=UDim.new(1,0)G.Parent=q local A=Instance.new("\085\073\083\116\114\111\107\101")A.Transparency=.9 A.Thickness=2 A.Parent=q l.Frame=q do local N=nd("\070\114\097\109\101","\083\101\108\101\099\116\105\111\110\079\098\106\101\099\116\067\108\105\112\112\101\114")N.Visible=false N.Parent=q U=nd("\073\109\097\103\101\076\097\098\101\108","\083\101\108\101\099\116\111\114")U.Size=UDim2.new(1,0,1,0)U.Image="\114\098\120\097\115\115\101\116\058\047\047\116\101\120\116\117\114\101\115\047\117\105\047\075\101\121\098\111\097\114\100\047\107\101\121\095\115\101\108\101\099\116\105\111\110\095\057\115\108\105\099\101\046\112\110\103"U.ScaleType=Enum.ScaleType.Slice U.SliceCenter=Rect.new(12,12,52,52)U.Parent=N end x=nd("\073\109\097\103\101\076\097\098\101\108","\073\099\111\110")x.AnchorPoint=Vector2.new(.5,.5)x.Size=UDim2.new(1,0,1,0)x.Position=UDim2.new(.5,0,.5,0)x.Parent=q f=nd("\084\101\120\116\076\097\098\101\108","\084\111\111\108\078\097\109\101")f.AnchorPoint=Vector2.new(.5,.5)f.Size=UDim2.new(.9,0,1,0)f.Position=UDim2.new(.5,0,.5,0)f.Font=Enum.Font.JosefinSans f.Parent=q l.Frame.LayoutOrder=l.Index if z<=Cd then B=nd("\084\101\120\116\076\097\098\101\108","\084\111\111\108\084\105\112")B.ZIndex=2 B.TextWrapped=false B.TextYAlignment=Enum.TextYAlignment.Top B.BackgroundColor3=Color3.new(.4,.4,.4)B.BackgroundTransparency=1 B.Font=Enum.Font.Oswald B.Visible=false B.Parent=q q.MouseEnter:connect(function()if B.Text~=""then B.Visible=true end end)q.MouseLeave:connect(function()B.Visible=false end)function l.MoveToInventory(N)if l.Index<=Cd then local k=l.Tool N:Clear()local z=jQ(cd)z:Fill(k)if OQ(k)then sQ()end if Pd then z.Frame.Visible=false z.Parent=Hd end end end if z<10 or z==Cd then local N=z<10 and z or 0 m=nd("\084\101\120\116\076\097\098\101\108","\078\117\109\098\101\114")m.Text=N m.TextScaled=true m.Position=UDim2.new(.325,0,.75,0)m.Font=Enum.Font.GothamMedium m.Size=UDim2.new(.4,0,.2,0)m.Visible=false m.Parent=q Dd[Y+N]=l.Select end end do local N=q.Position local k=0 local z=nil q.DragBegin:connect(function(k)dd[q]=true N=k q.BorderSizePixel=2 md:lock()q.ZIndex=2 x.ZIndex=2 f.ZIndex=2 if Od then q.Parent.ZIndex=2 end if m then m.ZIndex=2 end if p then p.ZIndex=2 for N,k in pairs(p:GetChildren())do if not k:IsA("\085\073\067\111\114\110\101\114")then k.ZIndex=2 end end end z=q.Parent if z==cd then local N=q.AbsolutePosition local k=UDim2.new(0,q.AbsolutePosition.X-Hd.AbsolutePosition.X,0,q.AbsolutePosition.Y-Hd.AbsolutePosition.Y)q.Parent=Hd q.Position=k c=nd("\070\114\097\109\101","\070\097\107\101\083\108\111\116")c.LayoutOrder=q.LayoutOrder local z=Instance.new("\085\073\067\111\114\110\101\114")z.CornerRadius=UDim.new(.07,0)z.Parent=c c.Size=q.Size c.BackgroundTransparency=1 c.Parent=cd end end)q.DragStopped:connect(function(L,K)if c then c:Destroy()end local w=tick()q.Position=N q.Parent=z q.BorderSizePixel=0 md:unlock()q.ZIndex=1 x.ZIndex=1 f.ZIndex=1 if Od then z.ZIndex=1 end if m then m.ZIndex=1 end if p then p.ZIndex=1 for N,k in pairs(p:GetChildren())do if not k:IsA("\085\073\067\111\114\110\101\114")then k.ZIndex=1 end end end dd[q]=nil if not l.Tool then return end if KQ(Hd,L,K)then if l.Index<=Cd then l:MoveToInventory()end if l.Index>Cd and w-k<r then if Gd then local N=l.Tool l:Clear()Gd:Fill(N)l:Delete()end w=0 end elseif KQ(id,L,K)then local N={math.huge;nil}for k=1,Cd,1 do local z=Td[k]local l=wQ(z.Frame,Vector2.new(L,K))if l<N[1]then N={l;z}end end local k=N[2]if k~=l then l:Swap(k)if l.Index>Cd then local N=l.Tool if not N then l:Delete()else if OQ(N)then sQ()end if Pd then l.Frame.Visible=false l.Frame.Parent=Hd end end end end else if l.Index<=Cd then l:MoveToInventory()end end k=w end)end q.Parent=N Td[z]=l if z>Cd then kQ()if Hd.Visible and not Pd then local N=qd.CanvasSize.Y.Offset-qd.AbsoluteSize.Y qd.CanvasPosition=Vector2.new(0,math.max(0,N))end end return l end local function XQ(N)if not N:IsA("\084\111\111\108")then if N:IsA("\072\117\109\097\110\111\105\100")and N.Parent==pd then Ud=N end return end local k=N if k.Parent==pd then ad()Wd=tick()end if not td and(k.Parent==pd and not Ad[k])then local N=Zd:FindFirstChild("\083\116\097\114\116\101\114\071\101\097\114")if N then if N:FindFirstChild(k.Name)then td=true local N=Gd or jQ(cd)for N=N.Index,1,-1 do local z=Td[N]local L=N-1 if L>0 then local N=Td[L]N:Swap(z)else z:Fill(k)end end for N,z in pairs(pd:GetChildren())do if z:IsA("\084\111\111\108")and z~=k then z.Parent=Bd end end NQ()return end end end local z=Ad[k]if z then z:UpdateEquipView()else z=Gd or jQ(cd)z:Fill(k)if z.Index<=Cd and not Hd.Visible then NQ()end end end local function bQ(N)if not N:IsA("\084\111\111\108")then return end local k=N ad()Wd=tick()local z=k.Parent if z==pd or z==Bd then return end local L=Ad[k]if L then L:Clear()if L.Index>Cd then L:Delete()elseif not Hd.Visible then NQ()end end end local function ZQ(N)for N=#Td,1,-1 do local k=Td[N]if k.Tool then k:Clear()end if N>Cd then k:Delete()end end for N,k in pairs(od)do k:Disconnect()end od={}pd=N table.insert(od,N.ChildRemoved:Connect(bQ))table.insert(od,N.ChildAdded:Connect(XQ))for N,k in pairs(N:GetChildren())do XQ(k)end Bd=Zd:WaitForChild("\066\097\099\107\112\097\099\107")table.insert(od,Bd.ChildRemoved:Connect(bQ))table.insert(od,Bd.ChildAdded:Connect(XQ))for N,k in pairs(Bd:GetChildren())do XQ(k)end NQ()end local function IQ(N,k)if N.UserInputType==Enum.UserInputType.Keyboard and(not Jd and(Sd or N.KeyCode.Value==W))then local z=Dd[N.KeyCode.Value]if z then z(k)end end local z=N.UserInputType if not k then if z==Enum.UserInputType.MouseButton1 or z==Enum.UserInputType.Touch then if Hd.Visible then md:deselect()end end end end local function iQ(N)if N=="\075\101\121\098\111\097\114\100\069\110\097\098\108\101\100"or N=="\086\082\069\110\097\098\108\101\100"then local N=C.KeyboardEnabled and not C.VREnabled for k=1,Cd,1 do Td[k]:TurnNumber(N)end end end local HQ=nil local VQ=nil local qQ=.06 local cQ=function() end local xQ=Vector2.new(0,0)local fQ=false function unbindAllGamepadEquipActions()Nd:UnbindAction("\082\066\088\066\097\099\107\112\097\099\107\072\097\115\071\097\109\101\112\097\100\070\111\099\117\115")Nd:UnbindAction("\082\066\088\067\108\111\115\101\073\110\118\101\110\116\111\114\121")end local function gQ(N,k)for z=1,Cd,1 do local L=Td[z]if L and(L.Frame and(k or L.Tool))then L.Frame.Visible=N end end end local function pQ(N)local k=1 if N.UserInputState==Enum.UserInputState.End then k=-1 end if N.KeyCode==Enum.KeyCode.Thumbstick1 then local k=N.Position.magnitude if k>.98 then local z=Vector2.new(N.Position.x/k,-N.Position.y/k)xQ=z else xQ=Vector2.new(0,0)end elseif N.KeyCode==Enum.KeyCode.DPadLeft then xQ=Vector2.new(xQ.x-1*k,xQ.y)elseif N.KeyCode==Enum.KeyCode.DPadRight then xQ=Vector2.new(xQ.x+1*k,xQ.y)elseif N.KeyCode==Enum.KeyCode.DPadUp then xQ=Vector2.new(xQ.x,xQ.y-1*k)elseif N.KeyCode==Enum.KeyCode.DPadDown then xQ=Vector2.new(xQ.x,xQ.y+1*k)else xQ=Vector2.new(0,0)end return xQ end local UQ=function(N,k,z)local L=pQ(z)if L==Vector2.new(0,0)then return end local l=math.atan2(L.y,L.x)-math.atan2(-1,0)if l<0 then l=l+math.pi*2 end local K=math.pi*.25 local w=l/K+1 w=math.floor(w+.5)if w>Cd then w=1 end if w>0 then local N=Td[w]if N and(N.Tool and not N:IsEquipped())then N:Select()end else sQ()end end changeToolFunc=function(N,k,z)if k~=Enum.UserInputState.Begin then return end if HQ then if HQ.KeyCode==Enum.KeyCode.ButtonR1 and z.KeyCode==Enum.KeyCode.ButtonL1 or HQ.KeyCode==Enum.KeyCode.ButtonL1 and z.KeyCode==Enum.KeyCode.ButtonR1 then if tick()-VQ<=qQ then sQ()HQ=z VQ=tick()return end end end HQ=z VQ=tick()delay(qQ,function()if HQ~=z then return end local N=0 if z.KeyCode==Enum.KeyCode.ButtonL1 then N=-1 else N=1 end for k=1,Cd,1 do local z=Td[k]if z:IsEquipped()then local z=N+k local L=false if z>Cd then z=1 L=true elseif z<1 then z=Cd L=true end local l=z while not Td[z].Tool do z=z+N if z==l then return end if z>Cd then z=1 L=true elseif z<1 then z=Cd L=true end end if L then sQ()vd=nil else Td[z]:Select()end return end end if vd and vd.Tool then vd:Select()return end local k=N==-1 and Cd or 1 local L=N==-1 and 1 or Cd for N=k,L,N do if Td[N].Tool then Td[N]:Select()return end end end)end function getGamepadSwapSlot()for N=1,#Td,1 do if Td[N].Frame.BorderSizePixel>0 then return Td[N]end end end function changeSlot(N)local k=not zd.VREnabled or Hd.Visible if N.Frame==F.SelectedObject and k then local k=getGamepadSwapSlot()if k then k.Frame.BorderSizePixel=0 if k~=N then N:Swap(k)Vd.SelectionImageObject.Visible=false if N.Index>Cd and not N.Tool then if F.SelectedObject==N.Frame then F.SelectedObject=k.Frame end N:Delete()end if k.Index>Cd and not k.Tool then if F.SelectedObject==k.Frame then F.SelectedObject=N.Frame end k:Delete()end end else local k=N.Frame.Size local z=N.Frame.Position N.Frame:TweenSizeAndPosition(k+UDim2.new(0,10,0,10),z-UDim2.new(0,5,0,5),Enum.EasingDirection.Out,Enum.EasingStyle.Quad,.1,true,function()N.Frame:TweenSizeAndPosition(k,z,Enum.EasingDirection.In,Enum.EasingStyle.Quad,.1,true)end)N.Frame.BorderSizePixel=3 Vd.SelectionImageObject.Visible=true end else N:Select()Vd.SelectionImageObject.Visible=false end end function vrMoveSlotToInventory()if not zd.VREnabled then return end local N=getGamepadSwapSlot()if N and N.Tool then N.Frame.BorderSizePixel=0 N:MoveToInventory()Vd.SelectionImageObject.Visible=false end end function enableGamepadInventoryControl()local N=function(N,k,z)if k~=Enum.UserInputState.Begin then return end local L=getGamepadSwapSlot()if L then local N=getGamepadSwapSlot()if N then N.Frame.BorderSizePixel=0 return end elseif Hd.Visible then md:deselect()end end Nd:BindAction("\082\066\088\066\097\099\107\112\097\099\107\072\097\115\071\097\109\101\112\097\100\070\111\099\117\115",cQ,false,Enum.UserInputType.Gamepad1)Nd:BindAction("\082\066\088\067\108\111\115\101\073\110\118\101\110\116\111\114\121",N,false,Enum.KeyCode.ButtonB,Enum.KeyCode.ButtonStart)if not ed()then F.SelectedObject=id:FindFirstChild("\049")end end function disableGamepadInventoryControl()unbindAllGamepadEquipActions()for N=1,Cd,1 do local k=Td[N]if k and k.Frame then k.Frame.BorderSizePixel=0 end end if F.SelectedObject and F.SelectedObject:IsDescendantOf(Id)then F.SelectedObject=nil end end local function BQ()if Sd and not Xd then Xd=true Nd:BindAction("\082\066\088\072\111\116\098\097\114\069\113\117\105\112",changeToolFunc,false,Enum.KeyCode.ButtonL1,Enum.KeyCode.ButtonR1)end end local function mQ()disableGamepadInventoryControl()Xd=false Nd:UnbindAction("\082\066\088\072\111\116\098\097\114\069\113\117\105\112")end function gamepadDisconnected()Yd=false disableGamepadInventoryControl()end function gamepadConnected()Yd=true F:AddSelectionParent("\082\066\088\066\097\099\107\112\097\099\107\083\101\108\101\099\116\105\111\110",Id)if ud>=1 then BQ()end if Hd.Visible then enableGamepadInventoryControl()end end local function TQ(N)N=N and v:GetCore("\084\111\112\098\097\114\069\110\097\098\108\101\100")md:setEnabled(N and not F.MenuIsOpen)Sd=N Id.Visible=N for k,z in pairs(rd)do if N then else end end if N then if ud>=1 then BQ()end else mQ()end end local function GQ(N,k)local z=nd("\073\109\097\103\101\066\117\116\116\111\110",N)z.Size=UDim2.new(0,40,0,40)z.Image="\114\098\120\097\115\115\101\116\058\047\047\116\101\120\116\117\114\101\115\047\117\105\047\075\101\121\098\111\097\114\100\047\099\108\111\115\101\095\098\117\116\116\111\110\095\098\097\099\107\103\114\111\117\110\100\046\112\110\103"local L=nd("\073\109\097\103\101\076\097\098\101\108","\073\099\111\110")L.Size=UDim2.new(.5,0,.5,0)L.Position=UDim2.new(.25,0,.25,0)L.Image=k L.Parent=z local l=nd("\073\109\097\103\101\076\097\098\101\108","\083\101\108\101\099\116\105\111\110")l.Size=UDim2.new(.9,0,.9,0)l.Position=UDim2.new(.05,0,.05,0)l.Image="\114\098\120\097\115\115\101\116\058\047\047\116\101\120\116\117\114\101\115\047\117\105\047\075\101\121\098\111\097\114\100\047\099\108\111\115\101\095\098\117\116\116\111\110\095\115\101\108\101\099\116\105\111\110\046\112\110\103"z.SelectionImageObject=l return z,L,l end


local BackpackScript = {}
BackpackScript.OpenClose = nil -- Function to toggle open/close
BackpackScript.IsOpen = false
BackpackScript.StateChanged = Instance.new("BindableEvent") -- Fires after any open/close, passes IsNowOpen

BackpackScript.ModuleName = "Backpack"
BackpackScript.KeepVRTopbarOpen = true
BackpackScript.VRIsExclusive = true
BackpackScript.VRClosesNonExclusive = true

local ICON_SIZE = 55
local FONT_SIZE = Enum.FontSize.Size14
local ICON_BUFFER = 6.5

local BACKGROUND_FADE = 0.6
local BACKGROUND_COLOR = Color3.new(31/255, 31/255, 31/255)

local VR_FADE_TIME = 1
local VR_PANEL_RESOLUTION = 100

local SLOT_DRAGGABLE_COLOR = Color3.new(0.176471, 0.176471, 0.176471)
local SLOT_DRAGGABLE_TRANSPARENCY = 0.4
local SLOT_EQUIP_COLOR = Color3.new(1, 0.772549, 0.309804)
local SLOT_EQUIP_THICKNESS = 0 -- Relative
local SLOT_FADE_LOCKED = 0.6 -- Locked means undraggable
local SLOT_BORDER_COLOR = Color3.new(0.411765, 0.619608, 1) -- Appears when dragging

local TOOLTIP_BUFFER = 6
local TOOLTIP_HEIGHT = 16
local TOOLTIP_OFFSET = -25 -- From top

local ARROW_IMAGE_OPEN = 'rbxasset://textures/ui/TopBar/inventoryOn.png'
local ARROW_IMAGE_CLOSE = 'rbxasset://textures/ui/TopBar/inventoryOff.png'
local ARROW_HOTKEY = {Enum.KeyCode.Backquote, Enum.KeyCode.DPadUp} --TODO: Hookup '~' too?
local ICON_MODULE = script.Icon

local HOTBAR_SLOTS_FULL = 10
local HOTBAR_SLOTS_VR = 6
local HOTBAR_SLOTS_MINI = 4
local HOTBAR_SLOTS_WIDTH_CUTOFF = 1024 -- Anything smaller is MINI
local HOTBAR_OFFSET_FROMBOTTOM = -30 -- Offset to make room for the Health GUI

local INVENTORY_ROWS_FULL = 4
local INVENTORY_ROWS_VR = 3
local INVENTORY_ROWS_MINI = 2
local INVENTORY_HEADER_SIZE = 25
local INVENTORY_ARROWS_BUFFER_VR = 40

local SEARCH_BUFFER = 4
local SEARCH_WIDTH = 125
local SEARCH_TEXT = "Search"

local SEARCH_TEXT_OFFSET_FROMLEFT = 0
local SEARCH_BACKGROUND_COLOR = Color3.new(0, 0, 0)
local SEARCH_BACKGROUND_FADE = 0.7

local DOUBLE_CLICK_TIME = 0.5
local GetScreenResolution = function ()
	local I = Instance.new("ScreenGui", game.Players.LocalPlayer.PlayerGui)
	local Frame = Instance.new("Frame", I)
	Frame.BackgroundTransparency = 1
	Frame.Size = UDim2.new(1,0,1,0)
	local AbsoluteSize = Frame.AbsoluteSize
	I:Destroy()
	return AbsoluteSize
end
local ZERO_KEY_VALUE = Enum.KeyCode.Zero.Value
local DROP_HOTKEY_VALUE = Enum.KeyCode.Backspace.Value

local GAMEPAD_INPUT_TYPES =
	{
		[Enum.UserInputType.Gamepad1] = true;
		[Enum.UserInputType.Gamepad2] = true;
		[Enum.UserInputType.Gamepad3] = true;
		[Enum.UserInputType.Gamepad4] = true;
		[Enum.UserInputType.Gamepad5] = true;
		[Enum.UserInputType.Gamepad6] = true;
		[Enum.UserInputType.Gamepad7] = true;
		[Enum.UserInputType.Gamepad8] = true;
	}

local UserInputService = game:GetService('UserInputService')
local PlayersService = game:GetService('Players')
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local StarterGui = game:GetService('StarterGui')
local GuiService = game:GetService('GuiService')
local CoreGui = PlayersService.LocalPlayer.PlayerGui

local TopbarPlusReference = ReplicatedStorage:FindFirstChild("TopbarPlusReference")
local BackpackEnabled = true

if TopbarPlusReference then
	ICON_MODULE = TopbarPlusReference.Value
end

local RobloxGui = Instance.new("ScreenGui", CoreGui)
RobloxGui.DisplayOrder = 120
RobloxGui.IgnoreGuiInset = true
RobloxGui.ResetOnSpawn = false
RobloxGui.Name = "BackpackGui"

local CanHover = true

local ContextActionService = game:GetService("ContextActionService")
local RunService = game:GetService('RunService')
local VRService = game:GetService('VRService')
local Utility = require(script.Utility)
local GameTranslator = require(script.GameTranslator)
local Themes = require(ICON_MODULE.Themes)
local Icon = require(ICON_MODULE)

local FFlagBackpackScriptUseFormatByKey = true
local FFlagCoreScriptTranslateGameText2 = true
local FFlagRobloxGuiSiblingZindexs = true
local IsTenFootInterface = GuiService:IsTenFootInterface()

if IsTenFootInterface then
	ICON_SIZE = 100
	FONT_SIZE = Enum.FontSize.Size24
end

local GamepadActionsBound = false

local IS_PHONE = UserInputService.TouchEnabled and GetScreenResolution().X < HOTBAR_SLOTS_WIDTH_CUTOFF

local Player = PlayersService.LocalPlayer

local MainFrame = nil
local HotbarFrame = nil
local InventoryFrame = nil
local VRInventorySelector = nil
local ScrollingFrame = nil
local UIGridFrame = nil
local UIGridLayout = nil
local ScrollUpInventoryButton = nil
local ScrollDownInventoryButton = nil

local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:FindFirstChildOfClass("Humanoid")
local Backpack = Player:WaitForChild("Backpack")

local InventoryIcon = Icon.new()
InventoryIcon:setImage(ARROW_IMAGE_CLOSE, "deselected")
InventoryIcon:setImage(ARROW_IMAGE_OPEN, "selected")
InventoryIcon:setTheme(Themes.BlueGradient)
InventoryIcon:bindToggleKey(ARROW_HOTKEY[1], ARROW_HOTKEY[2])
InventoryIcon:setName("InventoryIcon")
InventoryIcon:setImageYScale(1.12)
InventoryIcon:setOrder(-5)
InventoryIcon.deselectWhenOtherIconSelected = false

local Slots = {} -- List of all Slots by index
local LowestEmptySlot = nil
local SlotsByTool = {} -- Map of Tools to their assigned Slots
local HotkeyFns = {} -- Map of KeyCode values to their assigned behaviors
local Dragging = {} -- Only used to check if anything is being dragged, to disable other input
local FullHotbarSlots = 0 -- Now being used to also determine whether or not LB and RB on the gamepad are enabled.
local StarterToolFound = false -- Special handling is required for the gear currently equipped on the site
local WholeThingEnabled = false
local TextBoxFocused = false -- ANY TextBox, not just the search box
local ViewingSearchResults = false -- If the results of a search are currently being viewed
local HotkeyStrings = {} -- Used for eating/releasing hotkeys
local CharConns = {} -- Holds character Connections to be cleared later
local GamepadEnabled = false -- determines if our gui needs to be gamepad friendly
local TimeOfLastToolChange = 0

local IsVR = VRService.VREnabled -- Are we currently using a VR device?
local NumberOfHotbarSlots = IsVR and HOTBAR_SLOTS_VR or (IS_PHONE and HOTBAR_SLOTS_MINI or HOTBAR_SLOTS_FULL) -- Number of slots shown at the bottom
local NumberOfInventoryRows = IsVR and INVENTORY_ROWS_VR or (IS_PHONE and INVENTORY_ROWS_MINI or INVENTORY_ROWS_FULL) -- How many rows in the popped-up inventory
local BackpackPanel = nil
local lastEquippedSlot = nil

local function EvaluateBackpackPanelVisibility(enabled)
	return enabled and InventoryIcon.enabled and BackpackEnabled and VRService.VREnabled
end

local function ShowVRBackpackPopup()
	if BackpackPanel and EvaluateBackpackPanelVisibility(true) then
		BackpackPanel:ForceShowForSeconds(2)
	end
end

local function NewGui(className, objectName)
	local newGui = Instance.new(className)
	newGui.Name = objectName
	newGui.BackgroundColor3 = Color3.new(0, 0, 0)
	newGui.BackgroundTransparency = 1
	newGui.BorderColor3 = Color3.new(0, 0, 0)
	newGui.BorderSizePixel = 0
	newGui.Size = UDim2.new(1, 0, 1, 0)
	if className:match('Text') then
		newGui.TextColor3 = Color3.new(1, 1, 1)
		newGui.Text = ''
		newGui.Font = Enum.Font.SourceSans
		newGui.FontSize = FONT_SIZE
		newGui.TextWrapped = true
		if className == 'TextButton' then
			newGui.Font = Enum.Font.SourceSansSemibold
			newGui.BorderSizePixel = 1
		end
	end
	return newGui
end

local function FindLowestEmpty()
	for i = 1, NumberOfHotbarSlots do
		local slot = Slots[i]
		if not slot.Tool then
			return slot
		end
	end
	return nil
end

local function isInventoryEmpty()
	for i = NumberOfHotbarSlots + 1, #Slots do
		local slot = Slots[i]
		if slot and slot.Tool then
			return false
		end
	end
	return true
end

local function UseGazeSelection()
	return UserInputService.VREnabled
end

local function AdjustHotbarFrames()
	local inventoryOpen = InventoryFrame.Visible -- (Show all)
	local visualTotal = (inventoryOpen) and NumberOfHotbarSlots or FullHotbarSlots
	local visualIndex = 0
	local hotbarIsVisible = (visualTotal >= 1)

	for i = 1, NumberOfHotbarSlots do
		local slot = Slots[i]
		if slot.Tool or inventoryOpen then
			visualIndex = visualIndex + 1
			slot:Readjust(visualIndex, visualTotal)
			slot.Frame.Visible = true
		else
			slot.Frame.Visible = false
		end
	end
end

local function UpdateScrollingFrameCanvasSize()
	local countX = math.floor(ScrollingFrame.AbsoluteSize.X/(ICON_SIZE + ICON_BUFFER))
	local maxRow = math.ceil((#UIGridFrame:GetChildren() - 1)/countX)
	local canvasSizeY = maxRow*(ICON_SIZE + ICON_BUFFER) + ICON_BUFFER
	ScrollingFrame.CanvasSize = UDim2.new(0, 0, 0, canvasSizeY)
end

local function AdjustInventoryFrames()
	for i = NumberOfHotbarSlots + 1, #Slots do
		local slot = Slots[i]
		slot.Frame.LayoutOrder = slot.Index
		slot.Frame.Visible = (slot.Tool ~= nil)
	end
	UpdateScrollingFrameCanvasSize()
end

local function UpdateBackpackLayout()
	HotbarFrame.Size = UDim2.new(0, ICON_BUFFER + (NumberOfHotbarSlots * (ICON_SIZE + ICON_BUFFER)) + 120, 0, ICON_BUFFER + ICON_SIZE + ICON_BUFFER)
	HotbarFrame.Position = UDim2.new(0.5, -HotbarFrame.Size.X.Offset / 2, 1, -HotbarFrame.Size.Y.Offset)
	InventoryFrame.Size = UDim2.new(0, HotbarFrame.Size.X.Offset, 0, (HotbarFrame.Size.Y.Offset * NumberOfInventoryRows) + INVENTORY_HEADER_SIZE + (IsVR and 2*INVENTORY_ARROWS_BUFFER_VR or 0))
	InventoryFrame.Position = UDim2.new(0.5, -InventoryFrame.Size.X.Offset / 2, 1, HotbarFrame.Position.Y.Offset - InventoryFrame.Size.Y.Offset)
	
	local uic = Instance.new("UICorner")
	uic.CornerRadius = UDim.new(0.015, 0)
	uic.Parent = InventoryFrame
	
	ScrollingFrame.Size = UDim2.new(1, ScrollingFrame.ScrollBarThickness + 1, 1, -INVENTORY_HEADER_SIZE - (IsVR and 2*INVENTORY_ARROWS_BUFFER_VR or 0))
	ScrollingFrame.Position = UDim2.new(0, 0, 0, INVENTORY_HEADER_SIZE + (IsVR and INVENTORY_ARROWS_BUFFER_VR or 0))
	AdjustHotbarFrames()
	AdjustInventoryFrames()
end

local function Clamp(low, high, num)
	return math.min(high, math.max(low, num))
end

local function CheckBounds(guiObject, x, y)
	local pos = guiObject.AbsolutePosition
	local size = guiObject.AbsoluteSize
	return (x > pos.X and x <= pos.X + size.X and y > pos.Y and y <= pos.Y + size.Y)
end

local function GetOffset(guiObject, point)
	local centerPoint = guiObject.AbsolutePosition + (guiObject.AbsoluteSize / 2)
	return (centerPoint - point).magnitude
end

local function UnequipAllTools() --NOTE: HopperBin
	if Humanoid then
		Humanoid:UnequipTools()
	end
end

local function EquipNewTool(tool) --NOTE: HopperBin
	UnequipAllTools()
	--Humanoid:EquipTool(tool) --NOTE: This would also unequip current Tool
	tool.Parent = Character --TODO: Switch back to above line after EquipTool is fixed!
end

local function IsEquipped(tool)
	return tool and tool.Parent == Character --NOTE: HopperBin
end

local function MakeSlot(parent, index)
	index = index or (#Slots + 1)

	-- Slot Definition --

	local slot = {}
	slot.Tool = nil
	slot.Index = index
	slot.Frame = nil

	local LocalizedName = nil --remove with FFlagCoreScriptTranslateGameText2
	local LocalizedToolTip = nil --remove with FFlagCoreScriptTranslateGameText2

	local SlotFrameParent = nil
	local SlotFrame = nil
	local FakeSlotFrame = nil
	local ToolIcon = nil
	local ToolName = nil
	local ToolChangeConn = nil
	local HighlightFrame = nil
	local SelectionObj = nil

	--NOTE: The following are only defined for Hotbar Slots
	local ToolTip = nil
	local SlotNumber = nil

	-- Slot Functions --

	local function UpdateSlotFading()
		if VRService.VREnabled and BackpackPanel then
			local panelTransparency = BackpackPanel.transparency
			local slotTransparency = SLOT_FADE_LOCKED

			-- This equation multiplies the two transparencies together.
			local finalTransparency = panelTransparency + slotTransparency - panelTransparency * slotTransparency

			SlotFrame.BackgroundTransparency = finalTransparency
			SlotFrame.TextTransparency = finalTransparency
			if ToolIcon then
				ToolIcon.ImageTransparency = InventoryFrame.Visible and 0 or panelTransparency
			end
			if HighlightFrame then
				for _, child in pairs(HighlightFrame:GetChildren()) do
					child.BackgroundTransparency = finalTransparency
				end
			end

			SlotFrame.SelectionImageObject = SelectionObj
		else
			SlotFrame.SelectionImageObject = nil
			SlotFrame.BackgroundTransparency = (SlotFrame.Draggable) and SLOT_DRAGGABLE_TRANSPARENCY or SLOT_FADE_LOCKED
		end
		SlotFrame.BackgroundColor3 = (SlotFrame.Draggable) and SLOT_DRAGGABLE_COLOR or BACKGROUND_COLOR
		if SlotFrame:FindFirstChild("Equipped") then
			SlotFrame.BackgroundColor3 = Color3.fromRGB(105, 105, 105)
		end
	end

	function slot:Readjust(visualIndex, visualTotal) --NOTE: Only used for Hotbar slots
		local centered = HotbarFrame.Size.X.Offset / 2
		local sizePlus = ICON_BUFFER + ICON_SIZE
		local midpointish = (visualTotal / 2) + 0.5
		local factor = visualIndex - midpointish
		SlotFrame.Position = UDim2.new(0, centered - (ICON_SIZE / 2) + (sizePlus * factor), 0, ICON_BUFFER)
	end

	function slot:Fill(tool)
		if not tool then
			return self:Clear()
		end

		self.Tool = tool

		local function assignToolData()
			if FFlagCoreScriptTranslateGameText2 then
				local icon = tool.TextureId
				ToolIcon.Image = icon

				if icon ~= "" then
					ToolName.Visible = false
				end

				ToolName.Text = tool.Name

				if ToolTip and tool:IsA('Tool') then --NOTE: HopperBin
					ToolTip.Text = tool.ToolTip
					local width = ToolTip.TextBounds.X + TOOLTIP_BUFFER
					ToolTip.Size = UDim2.new(0, width, 0, TOOLTIP_HEIGHT)
					ToolTip.Position = UDim2.new(0.5, -width / 2, 0, TOOLTIP_OFFSET)
				end
			else
				LocalizedName = tool.Name
				LocalizedToolTip = nil

				local icon = tool.TextureId
				ToolIcon.Image = icon
				ToolIcon.AnchorPoint = Vector2.new(0.5,0.5)
				ToolIcon.Position = UDim2.fromScale(0.5, 0.5)
				if icon ~= '' then
					ToolName.Text = LocalizedName
				else
					ToolName.Text = ""
				end -- (Only show name if no icon)
				if ToolTip and tool:IsA('Tool') then --NOTE: HopperBin
					LocalizedToolTip = GameTranslator:TranslateGameText(tool, tool.ToolTip)
					ToolTip.Text = tool.ToolTip
					local width = ToolTip.TextBounds.X + TOOLTIP_BUFFER
					ToolTip.Size = UDim2.new(0, width, 0, TOOLTIP_HEIGHT)
					ToolTip.Position = UDim2.new(0.5, -width / 2, 0, TOOLTIP_OFFSET)
				end
			end
		end
		assignToolData()

		if ToolChangeConn then
			ToolChangeConn:disconnect()
			ToolChangeConn = nil
		end

		ToolChangeConn = tool.Changed:connect(function(property)
			if property == 'TextureId' or property == 'Name' or property == 'ToolTip' then
				assignToolData()
			end
		end)

		local hotbarSlot = (self.Index <= NumberOfHotbarSlots)
		local inventoryOpen = InventoryFrame.Visible

		if (not hotbarSlot or inventoryOpen) and not UserInputService.VREnabled then
			SlotFrame.Draggable = true
		end

		self:UpdateEquipView()

		if hotbarSlot then
			FullHotbarSlots = FullHotbarSlots + 1
			-- If using a controller, determine whether or not we can enable BindCoreAction("RBXHotbarEquip", etc)
			if WholeThingEnabled then
				if FullHotbarSlots >= 1 and not GamepadActionsBound then
					-- Player added first item to a hotbar slot, enable BindCoreAction
					GamepadActionsBound = true
					ContextActionService:BindAction("RBXHotbarEquip", changeToolFunc, false, Enum.KeyCode.ButtonL1, Enum.KeyCode.ButtonR1)
				end
			end
		end

		SlotsByTool[tool] = self
		LowestEmptySlot = FindLowestEmpty()
	end

	function slot:Clear()
		if not self.Tool then return end

		if ToolChangeConn then
			ToolChangeConn:disconnect()
			ToolChangeConn = nil
		end

		ToolIcon.Image = ''
		ToolName.Text = ''
		if ToolTip then
			ToolTip.Text = ''
			ToolTip.Visible = false
		end
		SlotFrame.Draggable = false

		self:UpdateEquipView(true) -- Show as unequipped

		if self.Index <= NumberOfHotbarSlots then
			FullHotbarSlots = FullHotbarSlots - 1
			if FullHotbarSlots < 1 then
				-- Player removed last item from hotbar; UnbindCoreAction("RBXHotbarEquip"), allowing the developer to use LB and RB.
				GamepadActionsBound = false
				ContextActionService:UnbindAction("RBXHotbarEquip")
			end
		end

		SlotsByTool[self.Tool] = nil
		self.Tool = nil
		LowestEmptySlot = FindLowestEmpty()
	end

	function slot:UpdateEquipView(unequippedOverride)
		if not unequippedOverride and IsEquipped(self.Tool) then -- Equipped
			lastEquippedSlot = slot
			if not HighlightFrame then
				HighlightFrame = NewGui('Frame', 'Equipped')
				HighlightFrame.ZIndex = SlotFrame.ZIndex
				local ring = script.Cover:Clone()
				ring.Parent = HighlightFrame
				
				
				local t = SLOT_EQUIP_THICKNESS
				local dataTable = { -- Relative sizes and positions
					{t,       1, 0,     0},
					{1 - 2*t, t, t,     0},
					{t,       1, 1 - t, 0},
					{1 - 2*t, t, t,     1 - t},
				}
				for _, data in pairs(dataTable) do
					local edgeFrame = NewGui("Frame", "Edge")
					edgeFrame.BackgroundTransparency = 1
					edgeFrame.BackgroundColor3 = SLOT_EQUIP_COLOR
					edgeFrame.Size = UDim2.new(data[1], 0, data[2], 0)
					edgeFrame.Position = UDim2.new(data[3], 0, data[4], 0)
					edgeFrame.ZIndex = HighlightFrame.ZIndex
					
					edgeFrame.Parent = HighlightFrame
				end
			end
			HighlightFrame.Parent = SlotFrame
		else -- In the Backpack
			if HighlightFrame then
				HighlightFrame.Parent = nil
			end
		end
		UpdateSlotFading()
		if not unequippedOverride and IsEquipped(self.Tool) then
			SlotFrame.BackgroundColor3 = Color3.fromRGB(105, 105, 105)
		else
			SlotFrame.BackgroundColor3 = Color3.fromRGB(31,31,31)
		end
	end

	function slot:IsEquipped()
		return IsEquipped(self.Tool)
	end

	function slot:Delete()
		SlotFrame:Destroy() --NOTE: Also clears connections
		table.remove(Slots, self.Index)
		local newSize = #Slots

		-- Now adjust the rest (both visually and representationally)
		for i = self.Index, newSize do
			Slots[i]:SlideBack()
		end

		UpdateScrollingFrameCanvasSize()
	end

	function slot:Swap(targetSlot) --NOTE: This slot (self) must not be empty!
		local myTool, otherTool = self.Tool, targetSlot.Tool
		self:Clear()
		if otherTool then -- (Target slot might be empty)
			targetSlot:Clear()
			self:Fill(otherTool)
		end
		if myTool then
			targetSlot:Fill(myTool)
		else
			targetSlot:Clear()
		end
	end

	function slot:SlideBack() -- For inventory slot shifting
		self.Index = self.Index - 1
		SlotFrame.Name = self.Index
		SlotFrame.LayoutOrder = self.Index
	end

	function slot:TurnNumber(on)
		if SlotNumber then
			SlotNumber.Visible = on
		end
	end

	function slot:SetClickability(on) -- (Happens on open/close arrow)
		if self.Tool then
			if UserInputService.VREnabled then
				SlotFrame.Draggable = false
			else
				SlotFrame.Draggable = not on
			end
			UpdateSlotFading()
		end
	end

	function slot:CheckTerms(terms)
		local hits = 0
		local function checkEm(str, term)
			local _, n = str:lower():gsub(term, '')
			hits = hits + n
		end
		local tool = self.Tool
		if tool then
			for term in pairs(terms) do
				if FFlagCoreScriptTranslateGameText2 then
					checkEm(ToolName.Text, term)
					if tool:IsA('Tool') then --NOTE: HopperBin
						local toolTipText = ToolTip and ToolTip.Text or ""
						checkEm(toolTipText, term)
					end
				else
					checkEm(LocalizedName, term)
					if tool:IsA('Tool') then --NOTE: HopperBin
						checkEm(LocalizedToolTip, term)
					end
				end
			end
		end
		return hits
	end

	-- Slot select logic, activated by clicking or pressing hotkey
	function slot:Select()
		local tool = slot.Tool
		if tool then
			if IsEquipped(tool) then --NOTE: HopperBin
				UnequipAllTools()
			elseif tool.Parent == Backpack then
				EquipNewTool(tool)
			end
		end
	end

	-- Slot Init Logic --

	SlotFrame = NewGui('TextButton', index)
	SlotFrame.BackgroundColor3 = BACKGROUND_COLOR
	SlotFrame.BorderColor3 = SLOT_BORDER_COLOR
	SlotFrame.Text = ""
	SlotFrame.AutoButtonColor = false
	SlotFrame.BorderSizePixel = 0
	SlotFrame.Size = UDim2.new(0, ICON_SIZE, 0, ICON_SIZE)
	SlotFrame.Active = true
	SlotFrame.Draggable = false
	SlotFrame.BackgroundTransparency = SLOT_FADE_LOCKED
	SlotFrame.MouseButton1Click:connect(function() changeSlot(slot) end)
	
	local slotFrameUIC = Instance.new("UICorner")
	slotFrameUIC.CornerRadius = UDim.new(1, 0)
	slotFrameUIC.Parent = SlotFrame
	
	local slotFrameStroke = Instance.new("UIStroke")
	slotFrameStroke.Transparency = 0.9
	slotFrameStroke.Thickness = 2
	slotFrameStroke.Parent = SlotFrame
	
	slot.Frame = SlotFrame
	
	do
		local selectionObjectClipper = NewGui('Frame', 'SelectionObjectClipper')
		selectionObjectClipper.Visible = false
		selectionObjectClipper.Parent = SlotFrame

		SelectionObj = NewGui('ImageLabel', 'Selector')
		SelectionObj.Size = UDim2.new(1, 0, 1, 0)
		SelectionObj.Image = "rbxasset://textures/ui/Keyboard/key_selection_9slice.png"
		SelectionObj.ScaleType = Enum.ScaleType.Slice
		SelectionObj.SliceCenter = Rect.new(12,12,52,52)
		SelectionObj.Parent = selectionObjectClipper
	end


	ToolIcon = NewGui('ImageLabel', 'Icon')
	ToolIcon.AnchorPoint = Vector2.new(0.5, 0.5)
	ToolIcon.Size = UDim2.new(1, 0, 1, 0)
	ToolIcon.Position = UDim2.new(0.5, 0, 0.5, 0)
	ToolIcon.Parent = SlotFrame

	ToolName = NewGui('TextLabel', 'ToolName')
	ToolName.AnchorPoint = Vector2.new(0.5, 0.5)
	ToolName.Size = UDim2.new(0.9, 0, 1, 0)
	ToolName.Position = UDim2.new(0.5, 0, 0.5, 0)
	ToolName.Font = Enum.Font.JosefinSans
	ToolName.Parent = SlotFrame

	slot.Frame.LayoutOrder = slot.Index

	if index <= NumberOfHotbarSlots then -- Hotbar-Specific Slot Stuff
		-- ToolTip stuff
		ToolTip = NewGui('TextLabel', 'ToolTip')
		ToolTip.ZIndex = 2
		ToolTip.TextWrapped = false
		ToolTip.TextYAlignment = Enum.TextYAlignment.Top
		ToolTip.BackgroundColor3 = Color3.new(0.4, 0.4, 0.4)
		ToolTip.BackgroundTransparency = 1
		ToolTip.Font = Enum.Font.Oswald
		ToolTip.Visible = false
		ToolTip.Parent = SlotFrame
		SlotFrame.MouseEnter:connect(function()
			if ToolTip.Text ~= '' then
				ToolTip.Visible = true
			end
		end)
		SlotFrame.MouseLeave:connect(function() ToolTip.Visible = false end)

		function slot:MoveToInventory()
			if slot.Index <= NumberOfHotbarSlots then -- From a Hotbar slot
				local tool = slot.Tool
				self:Clear() --NOTE: Order matters here
				local newSlot = MakeSlot(UIGridFrame)
				newSlot:Fill(tool)
				if IsEquipped(tool) then -- Also unequip it --NOTE: HopperBin
					UnequipAllTools()
				end
				-- Also hide the inventory slot if we're showing results right now
				if ViewingSearchResults then
					newSlot.Frame.Visible = false
					newSlot.Parent = InventoryFrame
				end
			end
		end

		-- Show label and assign hotkeys for 1-9 and 0 (zero is always last slot when > 10 total)
		if index < 10 or index == NumberOfHotbarSlots then -- NOTE: Hardcoded on purpose!
			local slotNum = (index < 10) and index or 0
			SlotNumber = NewGui('TextLabel', 'Number')
			SlotNumber.Text = slotNum
			SlotNumber.TextScaled = true
			SlotNumber.Position = UDim2.new(0.325,0,0.75,0)
			SlotNumber.Font = Enum.Font.GothamMedium
			SlotNumber.Size = UDim2.new(0.4, 0, 0.2, 0)
			SlotNumber.Visible = false
			SlotNumber.Parent = SlotFrame
			HotkeyFns[ZERO_KEY_VALUE + slotNum] = slot.Select
		end
	end

	do -- Dragging Logic
		local startPoint = SlotFrame.Position
		local lastUpTime = 0
		local startParent = nil

		SlotFrame.DragBegin:connect(function(dragPoint)
			Dragging[SlotFrame] = true
			startPoint = dragPoint

			SlotFrame.BorderSizePixel = 2
			InventoryIcon:lock()

			-- Raise above other slots
			SlotFrame.ZIndex = 2
			ToolIcon.ZIndex = 2
			ToolName.ZIndex = 2
			if FFlagRobloxGuiSiblingZindexs then
				SlotFrame.Parent.ZIndex = 2
			end
			if SlotNumber then
				SlotNumber.ZIndex = 2
			end
			if HighlightFrame then
				HighlightFrame.ZIndex = 2
				for _, child in pairs(HighlightFrame:GetChildren()) do
					if not child:IsA("UICorner") then
						child.ZIndex = 2
					end
				end
			end

			-- Circumvent the ScrollingFrame's ClipsDescendants property
			startParent = SlotFrame.Parent
			if startParent == UIGridFrame then
				local oldAbsolutPos = SlotFrame.AbsolutePosition
				local newPosition = UDim2.new(0, SlotFrame.AbsolutePosition.X - InventoryFrame.AbsolutePosition.X, 0, SlotFrame.AbsolutePosition.Y - InventoryFrame.AbsolutePosition.Y)
				SlotFrame.Parent = InventoryFrame
				SlotFrame.Position = newPosition

				FakeSlotFrame = NewGui('Frame', 'FakeSlot')
				FakeSlotFrame.LayoutOrder = SlotFrame.LayoutOrder
				local UIC = Instance.new("UICorner")
				UIC.CornerRadius = UDim.new(0.07, 0)
				UIC.Parent = FakeSlotFrame
				FakeSlotFrame.Size = SlotFrame.Size
				FakeSlotFrame.BackgroundTransparency = 1
				FakeSlotFrame.Parent = UIGridFrame
			end
		end)

		SlotFrame.DragStopped:connect(function(x, y)
			if FakeSlotFrame then
				FakeSlotFrame:Destroy()
			end

			local now = tick()
			SlotFrame.Position = startPoint
			SlotFrame.Parent = startParent

			SlotFrame.BorderSizePixel = 0
			InventoryIcon:unlock()

			-- Restore height
			SlotFrame.ZIndex = 1
			ToolIcon.ZIndex = 1
			ToolName.ZIndex = 1
			if FFlagRobloxGuiSiblingZindexs then
				startParent.ZIndex = 1
			end
			if SlotNumber then
				SlotNumber.ZIndex = 1
			end
			if HighlightFrame then
				HighlightFrame.ZIndex = 1
				for _, child in pairs(HighlightFrame:GetChildren()) do
					if not child:IsA("UICorner") then
						child.ZIndex = 1
					end
				end
			end

			Dragging[SlotFrame] = nil

			-- Make sure the tool wasn't dropped
			if not slot.Tool then
				return
			end

			-- Check where we were dropped
			if CheckBounds(InventoryFrame, x, y) then
				if slot.Index <= NumberOfHotbarSlots then
					slot:MoveToInventory()
				end
				-- Check for double clicking on an inventory slot, to move into empty hotbar slot
				if slot.Index > NumberOfHotbarSlots and now - lastUpTime < DOUBLE_CLICK_TIME then
					if LowestEmptySlot then
						local myTool = slot.Tool
						slot:Clear()
						LowestEmptySlot:Fill(myTool)
						slot:Delete()
					end
					now = 0 -- Resets the timer
				end
			elseif CheckBounds(HotbarFrame, x, y) then
				local closest = {math.huge, nil}
				for i = 1, NumberOfHotbarSlots do
					local otherSlot = Slots[i]
					local offset = GetOffset(otherSlot.Frame, Vector2.new(x, y))
					if offset < closest[1] then
						closest = {offset, otherSlot}
					end
				end
				local closestSlot = closest[2]
				if closestSlot ~= slot then
					slot:Swap(closestSlot)
					if slot.Index > NumberOfHotbarSlots then
						local tool = slot.Tool
						if not tool then -- Clean up after ourselves if we're an inventory slot that's now empty
							slot:Delete()
						else -- Moved inventory slot to hotbar slot, and gained a tool that needs to be unequipped
							if IsEquipped(tool) then --NOTE: HopperBin
								UnequipAllTools()
							end
							-- Also hide the inventory slot if we're showing results right now
							if ViewingSearchResults then
								slot.Frame.Visible = false
								slot.Frame.Parent = InventoryFrame
							end
						end
					end
				end
			else
				-- local tool = slot.Tool
				-- if tool.CanBeDropped then --TODO: HopperBins
				-- tool.Parent = workspace
				-- --TODO: Move away from character
				-- end
				if slot.Index <= NumberOfHotbarSlots then
					slot:MoveToInventory() --NOTE: Temporary
				end
			end

			lastUpTime = now
		end)
	end

	-- All ready!
	SlotFrame.Parent = parent
	Slots[index] = slot

	if index > NumberOfHotbarSlots then
		UpdateScrollingFrameCanvasSize()
		-- Scroll to new inventory slot, if we're open and not viewing search results
		if InventoryFrame.Visible and not ViewingSearchResults then
			local offset = ScrollingFrame.CanvasSize.Y.Offset - ScrollingFrame.AbsoluteSize.Y
			ScrollingFrame.CanvasPosition = Vector2.new(0, math.max(0, offset))
		end
	end

	return slot
end

local function OnChildAdded(child) -- To Character or Backpack
	if not child:IsA('Tool') then --NOTE: HopperBin
		if child:IsA('Humanoid') and child.Parent == Character then
			Humanoid = child
		end
		return
	end
	local tool = child

	if tool.Parent == Character then
		ShowVRBackpackPopup()
		TimeOfLastToolChange = tick()
	end

	--TODO: Optimize / refactor / do something else
	if not StarterToolFound and tool.Parent == Character and not SlotsByTool[tool] then
		local starterGear = Player:FindFirstChild('StarterGear')
		if starterGear then
			if starterGear:FindFirstChild(tool.Name) then
				StarterToolFound = true
				local slot = LowestEmptySlot or MakeSlot(UIGridFrame)
				for i = slot.Index, 1, -1 do
					local curr = Slots[i] -- An empty slot, because above
					local pIndex = i - 1
					if pIndex > 0 then
						local prev = Slots[pIndex] -- Guaranteed to be full, because above
						prev:Swap(curr)
					else
						curr:Fill(tool)
					end
				end
				-- Have to manually unequip a possibly equipped tool
				for _, child in pairs(Character:GetChildren()) do
					if child:IsA('Tool') and child ~= tool then
						child.Parent = Backpack
					end
				end
				AdjustHotbarFrames()
				return -- We're done here
			end
		end
	end

	-- The tool is either moving or new
	local slot = SlotsByTool[tool]
	if slot then
		slot:UpdateEquipView()
	else -- New! Put into lowest hotbar slot or new inventory slot
		slot = LowestEmptySlot or MakeSlot(UIGridFrame)
		slot:Fill(tool)
		if slot.Index <= NumberOfHotbarSlots and not InventoryFrame.Visible then
			AdjustHotbarFrames()
		end
	end
end

local function OnChildRemoved(child) -- From Character or Backpack
	if not child:IsA('Tool') then --NOTE: HopperBin
		return
	end
	local tool = child

	ShowVRBackpackPopup()
	TimeOfLastToolChange = tick()

	-- Ignore this event if we're just moving between the two
	local newParent = tool.Parent
	if newParent == Character or newParent == Backpack then
		return
	end

	local slot = SlotsByTool[tool]
	if slot then
		slot:Clear()
		if slot.Index > NumberOfHotbarSlots then -- Inventory slot
			slot:Delete()
		elseif not InventoryFrame.Visible then
			AdjustHotbarFrames()
		end
	end
end

local function OnCharacterAdded(character)
	-- First, clean up any old slots
	for i = #Slots, 1, -1 do
		local slot = Slots[i]
		if slot.Tool then
			slot:Clear()
		end
		if i > NumberOfHotbarSlots then
			slot:Delete()
		end
	end

	-- And any old Connections
	for _, conn in pairs(CharConns) do
		conn:Disconnect()
	end
	CharConns = {}

	-- Hook up the new character
	Character = character
	table.insert(CharConns, character.ChildRemoved:Connect(OnChildRemoved))
	table.insert(CharConns, character.ChildAdded:Connect(OnChildAdded))
	for _, child in pairs(character:GetChildren()) do
		OnChildAdded(child)
	end
	--NOTE: Humanoid is set inside OnChildAdded

	-- And the new backpack, when it gets here
	Backpack = Player:WaitForChild('Backpack')
	table.insert(CharConns, Backpack.ChildRemoved:Connect(OnChildRemoved))
	table.insert(CharConns, Backpack.ChildAdded:Connect(OnChildAdded))
	for _, child in pairs(Backpack:GetChildren()) do
		OnChildAdded(child)
	end
	
	AdjustHotbarFrames()
end

local function OnInputBegan(input, isProcessed)
	-- Pass through keyboard hotkeys when not typing into a TextBox and not disabled (except for the Drop key)
	if input.UserInputType == Enum.UserInputType.Keyboard and not TextBoxFocused and (WholeThingEnabled or input.KeyCode.Value == DROP_HOTKEY_VALUE) then
		local hotkeyBehavior = HotkeyFns[input.KeyCode.Value]
		if hotkeyBehavior then
			hotkeyBehavior(isProcessed)
		end
	end

	local inputType = input.UserInputType
	if not isProcessed then
		if inputType == Enum.UserInputType.MouseButton1 or inputType == Enum.UserInputType.Touch then
			if InventoryFrame.Visible then
				InventoryIcon:deselect()
			end
		end
	end
end

local function OnUISChanged(property)
	if property == 'KeyboardEnabled' or property == "VREnabled" then
		local on = UserInputService.KeyboardEnabled and not UserInputService.VREnabled
		for i = 1, NumberOfHotbarSlots do
			Slots[i]:TurnNumber(on)
		end
	end
end

local lastChangeToolInputObject = nil
local lastChangeToolInputTime = nil
local maxEquipDeltaTime = 0.06
local noOpFunc = function() end
local selectDirection = Vector2.new(0,0)
local hotbarVisible = false

function unbindAllGamepadEquipActions()
	ContextActionService:UnbindAction("RBXBackpackHasGamepadFocus")
	ContextActionService:UnbindAction("RBXCloseInventory")
end

local function setHotbarVisibility(visible, isInventoryScreen)
	for i = 1, NumberOfHotbarSlots do
		local hotbarSlot = Slots[i]
		if hotbarSlot and hotbarSlot.Frame and (isInventoryScreen or hotbarSlot.Tool) then
			hotbarSlot.Frame.Visible = visible
		end
	end
end

local function getInputDirection(inputObject)
	local buttonModifier = 1
	if inputObject.UserInputState == Enum.UserInputState.End then
		buttonModifier = -1
	end

	if inputObject.KeyCode == Enum.KeyCode.Thumbstick1 then

		local magnitude = inputObject.Position.magnitude

		if magnitude > 0.98 then
			local normalizedVector = Vector2.new(inputObject.Position.x / magnitude, -inputObject.Position.y / magnitude)
			selectDirection =  normalizedVector
		else
			selectDirection = Vector2.new(0,0)
		end
	elseif inputObject.KeyCode == Enum.KeyCode.DPadLeft then
		selectDirection = Vector2.new(selectDirection.x - 1 * buttonModifier, selectDirection.y)
	elseif inputObject.KeyCode == Enum.KeyCode.DPadRight then
		selectDirection = Vector2.new(selectDirection.x + 1 * buttonModifier, selectDirection.y)
	elseif inputObject.KeyCode == Enum.KeyCode.DPadUp then
		selectDirection = Vector2.new(selectDirection.x, selectDirection.y - 1 * buttonModifier)
	elseif inputObject.KeyCode == Enum.KeyCode.DPadDown then
		selectDirection = Vector2.new(selectDirection.x, selectDirection.y + 1 * buttonModifier)
	else
		selectDirection = Vector2.new(0,0)
	end

	return selectDirection
end

local selectToolExperiment = function(actionName, inputState, inputObject)
	local inputDirection = getInputDirection(inputObject)

	if inputDirection == Vector2.new(0,0) then
		return
	end

	local angle = math.atan2(inputDirection.y, inputDirection.x) - math.atan2(-1, 0)
	if angle < 0 then
		angle = angle + (math.pi * 2)
	end

	local quarterPi = (math.pi * 0.25)

	local index = (angle/quarterPi) + 1
	index = math.floor(index + 0.5) -- round index to whole number
	if index > NumberOfHotbarSlots then
		index = 1
	end

	if index > 0 then
		local selectedSlot = Slots[index]
		if selectedSlot and selectedSlot.Tool and not selectedSlot:IsEquipped() then
			selectedSlot:Select()
		end
	else
		UnequipAllTools()
	end
end

changeToolFunc = function(actionName, inputState, inputObject)
	if inputState ~= Enum.UserInputState.Begin then return end

	if lastChangeToolInputObject then
		if (lastChangeToolInputObject.KeyCode == Enum.KeyCode.ButtonR1 and
			inputObject.KeyCode == Enum.KeyCode.ButtonL1) or
			(lastChangeToolInputObject.KeyCode == Enum.KeyCode.ButtonL1 and
				inputObject.KeyCode == Enum.KeyCode.ButtonR1) then
			if (tick() - lastChangeToolInputTime) <= maxEquipDeltaTime then
				UnequipAllTools()
				lastChangeToolInputObject = inputObject
				lastChangeToolInputTime = tick()
				return
			end
		end
	end

	lastChangeToolInputObject = inputObject
	lastChangeToolInputTime = tick()

	delay(maxEquipDeltaTime, function()
		if lastChangeToolInputObject ~= inputObject then return end

		local moveDirection = 0
		if (inputObject.KeyCode == Enum.KeyCode.ButtonL1) then
			moveDirection = -1
		else
			moveDirection = 1
		end

		for i = 1, NumberOfHotbarSlots do
			local hotbarSlot = Slots[i]
			if hotbarSlot:IsEquipped() then

				local newSlotPosition = moveDirection + i
				local hitEdge = false
				if newSlotPosition > NumberOfHotbarSlots then
					newSlotPosition = 1
					hitEdge = true
				elseif newSlotPosition < 1 then
					newSlotPosition = NumberOfHotbarSlots
					hitEdge = true
				end

				local origNewSlotPos = newSlotPosition
				while not Slots[newSlotPosition].Tool do
					newSlotPosition = newSlotPosition + moveDirection
					if newSlotPosition == origNewSlotPos then return end

					if newSlotPosition > NumberOfHotbarSlots then
						newSlotPosition = 1
						hitEdge = true
					elseif newSlotPosition < 1 then
						newSlotPosition = NumberOfHotbarSlots
						hitEdge = true
					end
				end

				if hitEdge then
					UnequipAllTools()
					lastEquippedSlot = nil
				else
					Slots[newSlotPosition]:Select()
				end
				return
			end
		end

		if lastEquippedSlot and lastEquippedSlot.Tool then
			lastEquippedSlot:Select()
			return
		end

		local startIndex = moveDirection == -1 and NumberOfHotbarSlots or 1
		local endIndex = moveDirection == -1 and 1 or NumberOfHotbarSlots
		for i = startIndex, endIndex, moveDirection do
			if Slots[i].Tool then
				Slots[i]:Select()
				return
			end
		end
	end)
end

function getGamepadSwapSlot()
	for i = 1, #Slots do
		if Slots[i].Frame.BorderSizePixel > 0 then
			return Slots[i]
		end
	end
end

function changeSlot(slot)
	local swapInVr = not VRService.VREnabled or InventoryFrame.Visible

	if slot.Frame == GuiService.SelectedObject and swapInVr then
		local currentlySelectedSlot = getGamepadSwapSlot()

		if currentlySelectedSlot then
			currentlySelectedSlot.Frame.BorderSizePixel = 0
			if currentlySelectedSlot ~= slot then
				slot:Swap(currentlySelectedSlot)
				VRInventorySelector.SelectionImageObject.Visible = false

				if slot.Index > NumberOfHotbarSlots and not slot.Tool then
					if GuiService.SelectedObject == slot.Frame then
						GuiService.SelectedObject = currentlySelectedSlot.Frame
					end
					slot:Delete()
				end

				if currentlySelectedSlot.Index > NumberOfHotbarSlots and not currentlySelectedSlot.Tool then
					if GuiService.SelectedObject == currentlySelectedSlot.Frame then
						GuiService.SelectedObject = slot.Frame
					end
					currentlySelectedSlot:Delete()
				end
			end
		else
			local startSize = slot.Frame.Size
			local startPosition = slot.Frame.Position
			slot.Frame:TweenSizeAndPosition(startSize + UDim2.new(0, 10, 0, 10), startPosition - UDim2.new(0, 5, 0, 5), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, .1, true, function() slot.Frame:TweenSizeAndPosition(startSize, startPosition, Enum.EasingDirection.In, Enum.EasingStyle.Quad, .1, true) end)
			slot.Frame.BorderSizePixel = 3
			VRInventorySelector.SelectionImageObject.Visible = true
		end
	else
		slot:Select()
		VRInventorySelector.SelectionImageObject.Visible = false
	end
end

function vrMoveSlotToInventory()
	if not VRService.VREnabled then
		return
	end

	local currentlySelectedSlot = getGamepadSwapSlot()
	if currentlySelectedSlot and currentlySelectedSlot.Tool then
		currentlySelectedSlot.Frame.BorderSizePixel = 0
		currentlySelectedSlot:MoveToInventory()
		VRInventorySelector.SelectionImageObject.Visible = false
	end
end

function enableGamepadInventoryControl()
	local goBackOneLevel = function(actionName, inputState, inputObject)
		if inputState ~= Enum.UserInputState.Begin then return end

		local selectedSlot = getGamepadSwapSlot()
		if selectedSlot then
			local selectedSlot = getGamepadSwapSlot()
			if selectedSlot then
				selectedSlot.Frame.BorderSizePixel = 0
				return
			end
		elseif InventoryFrame.Visible then
			InventoryIcon:deselect()
		end
	end

	ContextActionService:BindAction("RBXBackpackHasGamepadFocus", noOpFunc, false, Enum.UserInputType.Gamepad1)
	ContextActionService:BindAction("RBXCloseInventory", goBackOneLevel, false, Enum.KeyCode.ButtonB, Enum.KeyCode.ButtonStart)

	-- Gaze select will automatically select the object for us!
	if not UseGazeSelection() then
		GuiService.SelectedObject = HotbarFrame:FindFirstChild("1")
	end
end


function disableGamepadInventoryControl()
	unbindAllGamepadEquipActions()

	for i = 1, NumberOfHotbarSlots do
		local hotbarSlot = Slots[i]
		if hotbarSlot and hotbarSlot.Frame then
			hotbarSlot.Frame.BorderSizePixel = 0
		end
	end

	if GuiService.SelectedObject and GuiService.SelectedObject:IsDescendantOf(MainFrame) then
		GuiService.SelectedObject = nil
	end
end


local function bindBackpackHotbarAction()
	if WholeThingEnabled and not GamepadActionsBound then
		GamepadActionsBound = true
		ContextActionService:BindAction("RBXHotbarEquip", changeToolFunc, false, Enum.KeyCode.ButtonL1, Enum.KeyCode.ButtonR1)
	end
end

local function unbindBackpackHotbarAction()
	disableGamepadInventoryControl()
	GamepadActionsBound = false
	ContextActionService:UnbindAction("RBXHotbarEquip")
end

function gamepadDisconnected()
	GamepadEnabled = false
	disableGamepadInventoryControl()
end

function gamepadConnected()
	GamepadEnabled = true
	GuiService:AddSelectionParent("RBXBackpackSelection", MainFrame)

	if FullHotbarSlots >= 1 then
		bindBackpackHotbarAction()
	end

	if InventoryFrame.Visible then
		enableGamepadInventoryControl()
	end
end

local function OnIconChanged(enabled)
	-- Check for enabling/disabling the whole thing
	enabled = enabled and StarterGui:GetCore("TopbarEnabled")
	InventoryIcon:setEnabled(enabled and not GuiService.MenuIsOpen)
	WholeThingEnabled = enabled
	MainFrame.Visible = enabled

	-- Eat/Release hotkeys (Doesn't affect UserInputService)
	for _, keyString in pairs(HotkeyStrings) do
		if enabled then
			--GuiService:AddKey(keyString)
		else
			--GuiService:RemoveKey(keyString)
		end
	end

	if enabled then
		if FullHotbarSlots >=1 then
			bindBackpackHotbarAction()
		end
	else
		unbindBackpackHotbarAction()
	end
end


local function MakeVRRoundButton(name, image)
	local newButton = NewGui('ImageButton', name)
	newButton.Size = UDim2.new(0, 40, 0, 40)
	newButton.Image = "rbxasset://textures/ui/Keyboard/close_button_background.png";

	local buttonIcon = NewGui('ImageLabel', 'Icon')
	buttonIcon.Size = UDim2.new(0.5,0,0.5,0);
	buttonIcon.Position = UDim2.new(0.25,0,0.25,0);
	buttonIcon.Image = image;
	buttonIcon.Parent = newButton;

	local buttonSelectionObject = NewGui('ImageLabel', 'Selection')
	buttonSelectionObject.Size = UDim2.new(0.9,0,0.9,0);
	buttonSelectionObject.Position = UDim2.new(0.05,0,0.05,0);
	buttonSelectionObject.Image = "rbxasset://textures/ui/Keyboard/close_button_selection.png";
	newButton.SelectionImageObject = buttonSelectionObject

	return newButton, buttonIcon, buttonSelectionObject
end

