diff --git a/rBag/core.lua b/rBag/core.lua
new file mode 100644
index 0000000..e5e3f12
--- /dev/null
+++ b/rBag/core.lua
@@ -0,0 +1,884 @@
+local A, L = ...
+
+local Noop = function() end
+local ReplaceBags = 0
+local NeedBagRefresh, NeedBankRefresh
+local LastButtonBag, LastButtonBank
+local Token1, Token2, Token3 = BackpackTokenFrameToken1, BackpackTokenFrameToken2, BackpackTokenFrameToken3
+local NUM_CONTAINER_FRAMES = NUM_CONTAINER_FRAMES
+local NUM_BAG_FRAMES = NUM_BAG_FRAMES
+local ContainerFrame_GetOpenFrame = ContainerFrame_GetOpenFrame
+local OriginalToggleBag = ToggleBag
+local BankFrame = BankFrame
+local BagHelpBox = BagHelpBox
+local ButtonSize, ButtonSpacing, ItemsPerRow
+local Bags = CreateFrame("Frame")
+local QuestColor = {1, 1, 0}
+local Bag_Normal = 1
+local Bag_SoulShard = 2
+local Bag_Profession = 3
+local Bag_Quiver = 4
+local KEYRING_CONTAINER = KEYRING_CONTAINER
+local BAGTYPE_QUIVER = 0x0001 + 0x0002
+local BAGTYPE_SOUL = 0x004
+local BAGTYPE_PROFESSION = 0x0008 + 0x0010 + 0x0020 + 0x0040 + 0x0080 + 0x0200 + 0x0400
+local RAID_CLASS_COLORS = RAID_CLASS_COLORS
+
+local BlizzardBags = {
+ CharacterBag0Slot,
+ CharacterBag1Slot,
+ CharacterBag2Slot,
+ CharacterBag3Slot,
+}
+
+local BagProfessions = {
+ [8] = "Leatherworking",
+ [16] = "Inscription",
+ [32] = "Herb",
+ [64] = "Enchanting",
+ [128] = "Engineering",
+ [512] = "Gem",
+ [1024] = "Mining",
+ [32768] = "Fishing",
+}
+
+local BagSize = {}
+
+function Bags:SetTokensPosition()
+ local Money = ContainerFrame1MoneyFrame
+
+ MAX_WATCHED_TOKENS = 2
+
+ -- Set Position
+ Token1:ClearAllPoints()
+ Token1:SetPoint("LEFT", Money, "RIGHT", 0, -2)
+ Token2:ClearAllPoints()
+ Token2:SetPoint("LEFT", Token1, "RIGHT", 0, 0)
+ Token3:SetParent(L.Hider)
+
+ -- Skin Icons
+ Token1.icon:SetTexCoord(0.1, 0.9, 0.1, 0.9)
+ Token2.icon:SetTexCoord(0.1, 0.9, 0.1, 0.9)
+end
+
+function Bags:GetBagProfessionType(bag)
+ local BagType = select(2, GetContainerNumFreeSlots(bag))
+
+ if BagProfessions[BagType] then
+ return BagProfessions[BagType]
+ end
+end
+
+function Bags:GetBagType(bag)
+ local bagType = select(2, GetContainerNumFreeSlots(bag))
+
+ if bit.band(bagType, BAGTYPE_QUIVER) > 0 then
+ return Bag_Quiver
+ elseif bit.band(bagType, BAGTYPE_SOUL) > 0 then
+ return Bag_SoulShard
+ elseif bit.band(bagType, BAGTYPE_PROFESSION) > 0 then
+ return Bag_Profession
+ end
+
+ return Bag_Normal
+end
+
+function Bags:HideBlizzard()
+ local BankPortraitTexture = _G["BankPortraitTexture"]
+ local BankSlotsFrame = _G["BankSlotsFrame"]
+
+ BankPortraitTexture:Hide()
+
+ BankFrame:EnableMouse(false)
+
+ for i = 1, 12 do
+ local CloseButton = _G["ContainerFrame"..i.."CloseButton"]
+ CloseButton:Hide()
+
+ for k = 1, 7 do
+ local Container = _G["ContainerFrame"..i]
+ select(k, Container:GetRegions()):SetAlpha(0)
+ end
+ end
+
+ -- Hide Bank Frame Textures
+ for i = 1, BankFrame:GetNumRegions() do
+ local Region = select(i, BankFrame:GetRegions())
+
+ Region:SetAlpha(0)
+ end
+
+ -- Hide BankSlotsFrame Textures and Fonts
+ for i = 1, BankSlotsFrame:GetNumRegions() do
+ local Region = select(i, BankSlotsFrame:GetRegions())
+
+ Region:SetAlpha(0)
+ end
+end
+
+function Bags:CreateContainer(storagetype, ...)
+ local Container = CreateFrame("Frame", A .. storagetype, UIParent)
+ Container:SetScale(1)
+ Container:SetWidth(((ButtonSize + ButtonSpacing) * ItemsPerRow) + 22 - ButtonSpacing)
+ Container:SetPoint(...)
+ Container:SetFrameStrata("MEDIUM")
+ Container:SetFrameLevel(1)
+ Container:Hide()
+ L.F.CreateBackdrop(Container)
+ Container:EnableMouse(true)
+
+ if (storagetype == "Bag") then
+ local Sort = CreateFrame("Button", nil, Container)
+ local Keys = CreateFrame("Button", nil, Container)
+
+ Sort:SetSize(16, 16)
+ Sort:SetPoint("TOPRIGHT", Container, "TOPRIGHT", -8, -8)
+ Sort.Text = Sort:CreateFontString(nil, "OVERLAY")
+ Sort.Text:SetFont(L.C.font, 12)
+ Sort.Text:SetJustifyH("LEFT")
+ Sort.Text:SetPoint("CENTER")
+ Sort.Text:SetText("S")
+ Sort:SetScript("OnEnter", GameTooltip_Hide)
+ Sort:SetScript("OnClick", function()
+ if InCombatLockdown() then
+ print("You cannot sort your bag in combat")
+ return
+ end
+ SortBags()
+ end)
+
+ Keys:SetSize(16, 16)
+ Keys:SetPoint("RIGHT", Sort, "LEFT", -5, 0)
+ Keys.Text = Keys:CreateFontString(nil, "OVERLAY")
+ Keys.Text:SetFont(L.C.font, 12)
+ Keys.Text:SetJustifyH("LEFT")
+ Keys.Text:SetPoint("CENTER")
+ Keys.Text:SetText("K")
+ Keys:SetScript("OnEnter", GameTooltip_Hide)
+ Keys:SetScript("OnClick", function()
+ if not IsBagOpen(KEYRING_CONTAINER) then
+ ToggleBag(KEYRING_CONTAINER)
+ else
+ ToggleAllBags()
+ ToggleAllBags()
+ end
+ end)
+
+ Container.SortButton = Sort
+ Container.Keys = Keys
+ else
+ local PurchaseButton = BankFramePurchaseButton
+ local CostText = BankFrameSlotCost
+ local TotalCost = BankFrameDetailMoneyFrame
+ local Purchase = BankFramePurchaseInfo
+ local CloseButton = BankCloseButton
+ local BankBagsContainer = CreateFrame("Frame", nil, Container)
+ local ToggleBags = CreateFrame("Button", nil, Container)
+
+ CostText:ClearAllPoints()
+ CostText:SetPoint("BOTTOMLEFT", 60, 10)
+ TotalCost:ClearAllPoints()
+ TotalCost:SetPoint("LEFT", CostText, "RIGHT", 0, 0)
+ PurchaseButton:ClearAllPoints()
+ PurchaseButton:SetPoint("BOTTOMRIGHT", -10, 10)
+
+ local SortButton = CreateFrame("Button", nil, Container)
+ SortButton:SetSize(16, 16)
+ SortButton:SetPoint("TOPRIGHT", Container, "TOPRIGHT", -8, -8)
+
+ SortButton.Text = SortButton:CreateFontString(nil, "OVERLAY")
+ SortButton.Text:SetFont(L.C.font, 12)
+ SortButton.Text:SetJustifyH("LEFT")
+ SortButton.Text:SetPoint("CENTER")
+ SortButton.Text:SetText("S")
+ SortButton:SetScript("OnClick", BankFrame_AutoSortButtonOnClick)
+
+ ToggleBags:SetSize(16, 16)
+ ToggleBags:SetPoint("RIGHT", SortButton, "LEFT", -5, 0)
+ ToggleBags.Text = ToggleBags:CreateFontString(nil, "OVERLAY")
+ ToggleBags.Text:SetFont(L.C.font, 12)
+ ToggleBags.Text:SetJustifyH("LEFT")
+ ToggleBags.Text:SetPoint("CENTER")
+ ToggleBags.Text:SetText("B")
+ ToggleBags:SetScript("OnEnter", GameTooltip_Hide)
+ ToggleBags:SetScript("OnClick", function(self)
+ local BanksContainer = Bags.Bank.BagsContainer
+
+ if (ReplaceBags == 0) then
+ ReplaceBags = 1
+ BanksContainer:Show()
+ else
+ ReplaceBags = 0
+ BanksContainer:Hide()
+ end
+ end)
+
+ Purchase:ClearAllPoints()
+ Purchase:SetWidth(Container:GetWidth() + 50)
+ Purchase:SetHeight(70)
+ Purchase:SetPoint("TOP", UIParent, "TOP", 0, -8)
+
+ BankBagsContainer:SetSize(Container:GetWidth(), BankSlotsFrame.Bag1:GetHeight() + ButtonSpacing + ButtonSpacing)
+ L.F.CreateBackdrop(BankBagsContainer)
+ BankBagsContainer:SetPoint("BOTTOMLEFT", Container, "TOPLEFT", 0, 3)
+ BankBagsContainer:SetFrameLevel(Container:GetFrameLevel())
+ BankBagsContainer:SetFrameStrata(Container:GetFrameStrata())
+
+ for i = 1, 7 do
+ local Bag = BankSlotsFrame["Bag"..i]
+
+ Bag:SetParent(BankBagsContainer)
+ Bag:SetWidth(ButtonSize)
+ Bag:SetHeight(ButtonSize)
+ Bag:ClearAllPoints()
+
+ if i == 1 then
+ Bag:SetPoint("TOPLEFT", BankBagsContainer, "TOPLEFT", ButtonSpacing, -ButtonSpacing)
+ else
+ Bag:SetPoint("LEFT", BankSlotsFrame["Bag"..i-1], "RIGHT", ButtonSpacing, 0)
+ end
+ end
+
+ BankBagsContainer:SetWidth((ButtonSize * 7) + (ButtonSpacing * (7 + 1)))
+ BankBagsContainer:SetHeight(ButtonSize + (ButtonSpacing * 2))
+ BankBagsContainer:Hide()
+
+ BankFrame:EnableMouse(false)
+
+ Container.BagsContainer = BankBagsContainer
+ Container.SortButton = SortButton
+ Container.ToggleBags = ToggleBags
+ CloseButton:Hide()
+ end
+
+ self[storagetype] = Container
+end
+
+function Bags:SlotUpdate(id, button)
+ if not button then
+ return
+ end
+
+ local _, _, _, Rarity, _, _, ItemLink, _, _, ItemID, IsBound = GetContainerItemInfo(id, button:GetID())
+ local QuestItem = false
+ local IsNewItem = C_NewItems.IsNewItem(id, button:GetID())
+
+ if (button.ItemID == ItemID) then
+ return
+ end
+
+ if button.Quest then
+ button.Quest:Hide()
+ end
+
+ button.ItemID = ItemID
+
+ if ItemLink then
+ local itemName, itemString, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount, itemEquipLoc, itemTexture = GetItemInfo(ItemLink)
+
+ if itemString then
+ if (itemType == TRANSMOG_SOURCE_2) then
+ QuestItem = true
+ end
+ end
+ end
+
+ if L.C.showQuest and QuestItem then
+ button.Backdrop:SetBackdropBorderColor(1, 1, 0)
+ else
+ if Rarity then
+ button.Backdrop:SetBackdropBorderColor(GetItemQualityColor(Rarity))
+ else
+ button.Backdrop:SetBackdropBorderColor(unpack(L.C.backdrop.edgeColor))
+ end
+ end
+
+ if L.C.flashNew and IsNewItem then
+ if not button.Animation then
+ button.Animation = button:CreateAnimationGroup()
+ button.Animation:SetLooping("BOUNCE")
+
+ button.Animation.FadeOut = button.Animation:CreateAnimation("Alpha")
+ button.Animation.FadeOut:SetFromAlpha(1)
+ button.Animation.FadeOut:SetToAlpha(.3)
+ button.Animation.FadeOut:SetDuration(.3)
+ button.Animation.FadeOut:SetSmoothing("IN_OUT")
+ button:HookScript("OnEnter", function(self)
+ local ItemID = self.ItemID
+ local BagID = self:GetID()
+
+ if ItemID and BagID then
+ local IsNewItem = C_NewItems.IsNewItem(self.ItemID, self:GetID())
+
+ if not IsNewItem and button.Animation:IsPlaying() then
+ button.Animation:Stop()
+ end
+ end
+ end)
+ end
+
+ if not button.Animation:IsPlaying() then
+ button.Animation:Play()
+ end
+ end
+
+ if L.C.showItemLevel then
+ if ItemLink then
+ local Level = GetDetailedItemLevelInfo(ItemLink)
+ local _, _, Rarity, _, _, _, _, _, _, _, _, ClassID = GetItemInfo(ItemLink)
+
+ if (ClassID == LE_ITEM_CLASS_ARMOR or ClassID == LE_ITEM_CLASS_WEAPON) and Level > 1 then
+ if not button.ItemLevel then
+ button.ItemLevel = button:CreateFontString(nil, "ARTWORK")
+ button.ItemLevel:SetPoint("TOPRIGHT", 1, -1)
+ button.ItemLevel:SetFont(L.C.font, 12, "OUTLINE")
+ button.ItemLevel:SetJustifyH("RIGHT")
+ end
+
+ button.ItemLevel:SetText(Level)
+
+ if Rarity then
+ button.ItemLevel:SetTextColor(GetItemQualityColor(Rarity))
+ else
+ button.ItemLevel:SetTextColor(1, 1, 1)
+ end
+ else
+ if button.ItemLevel then
+ button.ItemLevel:SetText("")
+ end
+ end
+ else
+ if button.ItemLevel then
+ button.ItemLevel:SetText("")
+ end
+ end
+ end
+end
+
+function Bags:BagUpdate(id)
+ local Size = GetContainerNumSlots(id)
+ local ContainerNumber = IsBagOpen(KEYRING_CONTAINER) and 1 or id + 1
+
+ for Slot = 1, Size do
+ local Button = _G["ContainerFrame"..ContainerNumber.."Item"..Slot]
+
+ if Button then
+ if not Button:IsShown() then
+ Button:Show()
+ end
+
+ local BagType = Bags:GetBagType(id)
+
+ if (BagType ~= 1) and (not Button.IsTypeStatusCreated) then
+ Button.TypeStatus = CreateFrame("StatusBar", nil, Button)
+ Button.TypeStatus:SetPoint("BOTTOMLEFT", 1, 1)
+ Button.TypeStatus:SetPoint("BOTTOMRIGHT", -1, 1)
+ Button.TypeStatus:SetHeight(3)
+ Button.TypeStatus:SetFrameStrata(Button:GetFrameStrata())
+ Button.TypeStatus:SetFrameLevel(Button:GetFrameLevel())
+ Button.TypeStatus:SetStatusBarTexture(L.C.backdrop.bgFile)
+
+ Button.IsTypeStatusCreated = true
+ end
+
+ if BagType == 2 then
+ -- Warlock Soul Shards Slots
+ local color = RAID_CLASS_COLORS["WARLOCK"]
+ Button.TypeStatus:SetStatusBarColor(color.r, color.g, color.b)
+ elseif BagType == 3 then
+ local ProfessionType = Bags:GetBagProfessionType(id)
+
+ if ProfessionType == "Leatherworking" then
+ Button.TypeStatus:SetStatusBarColor(102/255, 51/255, 0/255)
+ elseif ProfessionType == "Inscription" then
+ Button.TypeStatus:SetStatusBarColor(204/255, 204/255, 0/255)
+ elseif ProfessionType == "Herb" then
+ Button.TypeStatus:SetStatusBarColor(0/255, 153/255, 0/255)
+ elseif ProfessionType == "Enchanting" then
+ Button.TypeStatus:SetStatusBarColor(230/255, 25/255, 128/255)
+ elseif ProfessionType == "Engineering" then
+ Button.TypeStatus:SetStatusBarColor(25/255, 230/255, 230/255)
+ elseif ProfessionType == "Gem" then
+ Button.TypeStatus:SetStatusBarColor(232/255, 252/255, 252/255)
+ elseif ProfessionType == "Mining" then
+ Button.TypeStatus:SetStatusBarColor(138/255, 40/255, 40/255)
+ elseif ProfessionType == "Fishing" then
+ Button.TypeStatus:SetStatusBarColor(54/255, 54/255, 226/255)
+ end
+ elseif BagType == 4 then
+ -- Hunter Quiver Slots
+ local color = RAID_CLASS_COLORS["HUNTER"]
+ Button.TypeStatus:SetStatusBarColor(color.r, color.g, color.b)
+ end
+
+ self:SlotUpdate(id, Button)
+ end
+ end
+end
+
+function Bags:UpdateAllBags()
+ -- check if containers changed
+ if not NeedBagRefresh then
+ for i = 1, 5 do
+ local ContainerSize = _G["ContainerFrame"..i].size
+
+ if ContainerSize ~= BagSize[i] then
+ NeedBagRefresh = true
+
+ BagSize[i] = ContainerSize
+ end
+ end
+
+ if (not NeedBagRefresh) then
+ return
+ end
+ end
+
+ -- Refresh layout if a refresh if found
+ local NumRows, LastRowButton, NumButtons, LastButton = 0, ContainerFrame1Item1, 1, ContainerFrame1Item1
+ local FirstButton
+
+ for Bag = 1, 5 do
+ local ID = Bag - 1
+
+ if IsBagOpen(KEYRING_CONTAINER) then
+ ID = -2
+ end
+
+ local Slots = GetContainerNumSlots(ID)
+
+ for Item = Slots, 1, -1 do
+ local Button = _G["ContainerFrame"..Bag.."Item"..Item]
+ local Money = ContainerFrame1MoneyFrame
+
+ if not FirstButton then
+ FirstButton = Button
+ end
+
+ Button:ClearAllPoints()
+ Button:SetWidth(ButtonSize)
+ Button:SetHeight(ButtonSize)
+ Button:SetScale(1)
+
+ Button.newitemglowAnim:Stop()
+ Button.newitemglowAnim.Play = Noop
+
+ Button.flashAnim:Stop()
+ Button.flashAnim.Play = Noop
+
+ if (Button == FirstButton) then
+ Button:SetPoint("TOPLEFT", Bags.Bag, "TOPLEFT", 10, -30)
+ LastRowButton = Button
+ LastButton = Button
+ elseif (NumButtons == ItemsPerRow) then
+ Button:SetPoint("TOPRIGHT", LastRowButton, "TOPRIGHT", 0, -(ButtonSpacing + ButtonSize))
+ Button:SetPoint("BOTTOMLEFT", LastRowButton, "BOTTOMLEFT", 0, -(ButtonSpacing + ButtonSize))
+ LastRowButton = Button
+ NumRows = NumRows + 1
+ NumButtons = 1
+ else
+ Button:SetPoint("TOPRIGHT", LastButton, "TOPRIGHT", (ButtonSpacing + ButtonSize), 0)
+ Button:SetPoint("BOTTOMLEFT", LastButton, "BOTTOMLEFT", (ButtonSpacing + ButtonSize), 0)
+ NumButtons = NumButtons + 1
+ end
+
+ LastButton = Button
+
+ rButtonTemplate:StyleItemButton(Button, rButtonTemplate_Zork_SlotButtonConfig)
+ Button:SetFrameLevel(0)
+ Button.Backdrop:SetFrameLevel(Button:GetFrameLevel())
+
+ if not Money.IsMoved then
+ Money:ClearAllPoints()
+ Money:Show()
+ Money:SetPoint("TOPLEFT", Bags.Bag, "TOPLEFT", 8, -10)
+ Money:SetScale(1)
+ Money.IsMoved = true
+ end
+ end
+
+ Bags:BagUpdate(ID)
+
+ if IsBagOpen(KEYRING_CONTAINER) then
+ break
+ end
+ end
+
+ NeedBagRefresh = false
+
+ self.Bag:SetHeight(((ButtonSize + ButtonSpacing) * (NumRows + 1) + 26 + (ButtonSpacing * 4)) - ButtonSpacing)
+end
+
+function Bags:UpdateAllBankBags()
+ -- check if containers changed
+ for i = 6, 13 do
+ local ContainerSize = _G["ContainerFrame"..i].size
+
+ if ContainerSize ~= BagSize[i] then
+ NeedBankRefresh = true
+
+ BagSize[i] = ContainerSize
+ end
+ end
+
+ if not NeedBankRefresh then
+ return
+ end
+
+ local NumRows, LastRowButton, NumButtons, LastButton = 0, ContainerFrame1Item1, 1, ContainerFrame1Item1
+ local BankFrameMoneyFrame = BankFrameMoneyFrame
+
+ for Bank = 1, 28 do
+ local Button = _G["BankFrameItem"..Bank]
+ local Money = ContainerFrame2MoneyFrame
+
+ Button:ClearAllPoints()
+ Button:SetWidth(ButtonSize)
+ Button:SetHeight(ButtonSize)
+ Button:SetScale(1)
+ Button.IconBorder:SetAlpha(0)
+
+ if (Bank == 1) then
+ Button:SetPoint("TOPLEFT", Bags.Bank, "TOPLEFT", 10, -30)
+ LastRowButton = Button
+ LastButton = Button
+ elseif (NumButtons == ItemsPerRow) then
+ Button:SetPoint("TOPRIGHT", LastRowButton, "TOPRIGHT", 0, -(ButtonSpacing + ButtonSize))
+ Button:SetPoint("BOTTOMLEFT", LastRowButton, "BOTTOMLEFT", 0, -(ButtonSpacing + ButtonSize))
+ LastRowButton = Button
+ NumRows = NumRows + 1
+ NumButtons = 1
+ else
+ Button:SetPoint("TOPRIGHT", LastButton, "TOPRIGHT", (ButtonSpacing + ButtonSize), 0)
+ Button:SetPoint("BOTTOMLEFT", LastButton, "BOTTOMLEFT", (ButtonSpacing + ButtonSize), 0)
+ NumButtons = NumButtons + 1
+ end
+
+ rButtonTemplate:StyleItemButton(Button, rButtonTemplate_Zork_SlotButtonConfig)
+ Button:SetFrameLevel(0)
+ Button.Backdrop:SetFrameLevel(Button:GetFrameLevel())
+ Bags.SlotUpdate(self, -1, Button)
+
+ LastButton = Button
+ end
+
+ BankFrameMoneyFrame:Hide()
+
+ for Bag = 6, 12 do
+ local Slots = GetContainerNumSlots(Bag - 1)
+
+ for Item = Slots, 1, -1 do
+ local Button = _G["ContainerFrame"..Bag.."Item"..Item]
+
+ Button:ClearAllPoints()
+ Button:SetWidth(ButtonSize)
+ Button:SetHeight(ButtonSize)
+ Button:SetScale(1)
+ Button.IconBorder:SetAlpha(0)
+
+ if (NumButtons == ItemsPerRow) then
+ Button:SetPoint("TOPRIGHT", LastRowButton, "TOPRIGHT", 0, -(ButtonSpacing + ButtonSize))
+ Button:SetPoint("BOTTOMLEFT", LastRowButton, "BOTTOMLEFT", 0, -(ButtonSpacing + ButtonSize))
+ LastRowButton = Button
+ NumRows = NumRows + 1
+ NumButtons = 1
+ else
+ Button:SetPoint("TOPRIGHT", LastButton, "TOPRIGHT", (ButtonSpacing+ButtonSize), 0)
+ Button:SetPoint("BOTTOMLEFT", LastButton, "BOTTOMLEFT", (ButtonSpacing+ButtonSize), 0)
+ NumButtons = NumButtons + 1
+ end
+
+ rButtonTemplate:StyleItemButton(Button, rButtonTemplate_Zork_SlotButtonConfig)
+ Button:SetFrameLevel(0)
+ Button.Backdrop:SetFrameLevel(Button:GetFrameLevel())
+ Bags.SlotUpdate(self, Bag - 1, Button)
+
+ LastButton = Button
+ end
+ end
+
+ NeedBankRefresh = false
+
+ Bags.Bank:SetHeight(((ButtonSize + ButtonSpacing) * (NumRows + 1) + 40) - ButtonSpacing)
+end
+
+function Bags:OpenBag(id)
+ if (not CanOpenPanels()) then
+ if (UnitIsDead("player")) then
+ NotWhileDeadError()
+ end
+
+ return
+ end
+
+ local Size = GetContainerNumSlots(id)
+ local OpenFrame = ContainerFrame_GetOpenFrame()
+
+ for i = 1, 40 do
+ local Index = Size - i + 1
+ local Button = _G[OpenFrame:GetName().."Item"..i]
+
+ if Button then
+ if (i > Size) then
+ Button:Hide()
+ else
+ Button:SetID(Index)
+ Button:Show()
+ end
+ end
+ end
+
+ OpenFrame.size = Size
+ OpenFrame:SetID(id)
+ OpenFrame:Show()
+
+ if (id == 4) then
+ Bags:UpdateAllBags()
+ end
+end
+
+function Bags:CloseBag(id)
+ CloseBag(id)
+end
+
+function Bags:OpenAllBags()
+ self:OpenBag(0)
+
+ for i = 1, 4 do
+ self:OpenBag(i)
+ end
+
+ if IsBagOpen(0) then
+ self.Bag:Show()
+
+ if not self.Bag.MoverAdded then
+ --create drag frame
+ rLib:CreateDragFrame(self.Bag, L.dragFrames, -2, true)
+ self.Bag.MoverAdded = true
+ end
+ end
+end
+
+function Bags:OpenAllBankBags()
+ local Bank = BankFrame
+
+ if Bank:IsShown() then
+ self.Bank:Show()
+
+ if not self.Bank.MoverAdded then
+ --create drag frame
+ rLib:CreateDragFrame(self.Bank, L.dragFrames, -2, true)
+ self.Bank.MoverAdded = true
+ end
+
+ for i = 5, 11 do
+ if (not IsBagOpen(i)) then
+ self:OpenBag(i, 1)
+ end
+ end
+ end
+end
+
+function Bags:CloseAllBags()
+ if MerchantFrame:IsVisible() or InboxFrame:IsVisible() then
+ return
+ end
+
+ CloseAllBags()
+
+ if IsBagOpen(KEYRING_CONTAINER) then
+ CloseBag(KEYRING_CONTAINER)
+ end
+
+ PlaySound(SOUNDKIT.IG_BACKPACK_CLOSE)
+end
+
+function Bags:CloseAllBankBags()
+ local Bank = BankFrame
+
+ if (Bank:IsVisible()) then
+ CloseBankBagFrames()
+ CloseBankFrame()
+ end
+end
+
+function Bags:ToggleBags(id, openonly)
+ if id == KEYRING_CONTAINER then
+ if not IsBagOpen(KEYRING_CONTAINER) then
+ CloseAllBags()
+ CloseBankBagFrames()
+ CloseBankFrame()
+
+ NeedBagRefresh = true
+
+ Bags:OpenBag(id)
+ Bags:UpdateAllBags()
+
+ NeedBagRefresh = true
+ else
+ CloseBag(id)
+ end
+ else
+ if (self.Bag:IsShown() and BankFrame:IsShown()) and (not self.Bank:IsShown()) then
+ self:OpenAllBankBags()
+ return
+ end
+
+ if (not openonly) and (self.Bag:IsShown() or self.Bank:IsShown()) then
+ if MerchantFrame:IsVisible() or InboxFrame:IsVisible() then
+ return
+ end
+
+ self:CloseAllBags()
+ self:CloseAllBankBags()
+
+ return
+ end
+
+ if not self.Bag:IsShown() then
+ self:OpenAllBags()
+ end
+
+ if not self.Bank:IsShown() and BankFrame:IsShown() then
+ self:OpenAllBankBags()
+ end
+ end
+end
+
+function Bags:OnEvent(event, ...)
+ if (event == "BAG_UPDATE") then
+ if not IsBagOpen(KEYRING_CONTAINER) then
+ self:BagUpdate(...)
+ else
+ self:BagUpdate(-2)
+ end
+ elseif (event == "MERCHANT_CLOSED" or event == "MAIL_CLOSED") then
+ CloseAllBags()
+ elseif (event == "CURRENCY_DISPLAY_UPDATE") then
+ BackpackTokenFrame_Update()
+ elseif (event == "BAG_CLOSED") then
+ -- This is usually where the client find a bag swap in character or bank slots.
+
+ local Bag = ... + 1
+
+ -- We need to hide buttons from a bag when closing it because they are not parented to the original frame
+ local Container = _G["ContainerFrame"..Bag]
+ local Size = Container.size
+
+ if Size then
+ for i = 1, Size do
+ local Button = _G["ContainerFrame"..Bag.."Item"..i]
+
+ if Button then
+ Button:Hide()
+ end
+ end
+ end
+
+ -- We close to refresh the all in one layout.
+ self:CloseAllBags()
+ self:CloseAllBankBags()
+ elseif (event == "PLAYERBANKSLOTS_CHANGED") then
+ local ID = ...
+ if ID <= 28 then
+ local Button = _G["BankFrameItem"..ID]
+
+ if (Button) then
+ self:SlotUpdate(-1, Button)
+ end
+ end
+ elseif (event == "PLAYERREAGENTBANKSLOTS_CHANGED") then
+ local ID = ...
+ local Button = _G["ReagentBankFrameItem"..ID]
+ if (Button) then
+ self:SlotUpdate(-3, Button)
+ end
+ elseif (event == "BANKFRAME_CLOSED") then
+ local Bank = self.Bank
+ self:CloseAllBags()
+ self:CloseAllBankBags()
+ elseif (event == "BANKFRAME_OPENED") then
+ local Bank = self.Bank
+ Bank:Show()
+ self:UpdateAllBankBags()
+ elseif (event == "SOULBIND_FORGE_INTERACTION_STARTED") then
+ self:OpenAllBags()
+ ItemButtonUtil.OpenAndFilterBags(SoulbindViewer)
+ elseif (event == "SOULBIND_FORGE_INTERACTION_ENDED") then
+ self:CloseAllBags()
+ end
+end
+
+function Bags:Enable()
+ if L.C.sort.sortToBottom then
+ SetSortBagsRightToLeft(false)
+ else
+ SetSortBagsRightToLeft(true)
+ end
+ SetInsertItemsLeftToRight(false)
+
+ -- Bug with mouse click
+ GroupLootContainer:EnableMouse(false)
+
+ ButtonSize = L.C.icon.size
+ ButtonSpacing = L.C.icon.spacing
+ ItemsPerRow = L.C.icon.columns
+
+ local Bag = ContainerFrame1
+ local BankItem1 = BankFrameItem1
+
+ self:CreateContainer("Bag", unpack(L.C.bag.point))
+ self:CreateContainer("Bank", unpack(L.C.bank.point))
+ self:HideBlizzard()
+
+ Bag:SetScript("OnHide", function()
+ self.Bag:Hide()
+ end)
+
+ Bag:HookScript("OnShow", function() -- Cinematic Bug with Bags open.
+ self.Bag:Show()
+ end)
+
+ BankItem1:SetScript("OnHide", function()
+ self.Bank:Hide()
+ end)
+
+ -- Rewrite Blizzard Bags Functions
+ function UpdateContainerFrameAnchors() end
+ function ToggleBag(id) ToggleAllBags(id) end
+ function ToggleBackpack() ToggleAllBags() end
+ function OpenAllBags() ToggleAllBags(1, true) end
+ function OpenBackpack() ToggleAllBags(1, true) end
+ function ToggleAllBags(id, openonly) self:ToggleBags(id, openonly) end
+
+ -- Destroy bubbles help boxes
+ for i = 1, 13 do
+ local HelpBox = _G["ContainerFrame"..i.."ExtraBagSlotsHelpBox"]
+
+ if HelpBox then
+ HelpBox:Hide()
+ HelpBox:SetParent(L.Hider)
+ end
+ end
+
+ OpenAllBagsMatchingContext = function() return 4 end
+
+ -- Register Events for Updates
+ self:RegisterEvent("BAG_UPDATE")
+ self:RegisterEvent("PLAYERBANKSLOTS_CHANGED")
+ self:RegisterEvent("BAG_CLOSED")
+ self:RegisterEvent("BANKFRAME_CLOSED")
+ self:RegisterEvent("BANKFRAME_OPENED")
+ self:RegisterEvent("MERCHANT_CLOSED")
+ self:RegisterEvent("MAIL_CLOSED")
+ self:SetScript("OnEvent", self.OnEvent)
+
+ for i = 1, 13 do
+ _G["ContainerFrame"..i]:EnableMouse(false)
+ end
+
+ ToggleAllBags()
+ ToggleAllBags()
+end
+
+rBag.Bags = Bags
diff --git a/rBag/functions.lua b/rBag/functions.lua
new file mode 100644
index 0000000..2d901ef
--- /dev/null
+++ b/rBag/functions.lua
@@ -0,0 +1,19 @@
+local A, L = ...
+
+local Hider = CreateFrame("Frame", nil, UIParent)
+Hider:Hide()
+L.Hider = Hider
+
+--CreateBackdrop
+local function CreateBackdrop(self,relativeTo)
+ local backdrop = L.C.backdrop
+ local bd = CreateFrame("Frame", nil, self, BackdropTemplateMixin and "BackdropTemplate")
+ bd:SetFrameLevel(self:GetFrameLevel()-1 or 0)
+ bd:SetPoint("TOPLEFT", relativeTo or self, "TOPLEFT", -backdrop.inset, backdrop.inset)
+ bd:SetPoint("BOTTOMRIGHT", relativeTo or self, "BOTTOMRIGHT", backdrop.inset, -backdrop.inset)
+ bd:SetBackdrop(backdrop)
+ bd:SetBackdropColor(unpack(backdrop.bgColor))
+ bd:SetBackdropBorderColor(unpack(backdrop.edgeColor))
+ return bd
+end
+L.F.CreateBackdrop = CreateBackdrop
\ No newline at end of file
diff --git a/rBag/init.lua b/rBag/init.lua
new file mode 100644
index 0000000..ea944c4
--- /dev/null
+++ b/rBag/init.lua
@@ -0,0 +1,62 @@
+local A, L = ...
+
+L.dragFrames = {}
+L.addonName = A
+L.addonColor = "ff1a9fc0"
+L.addonShortcut = "rbag"
+L.F = {}
+
+-----------------------------
+-- rBag Global
+-----------------------------
+
+rBag = {}
+rBag.addonName = A
+
+local mediapath = rLib.mediapath
+
+-----------------------------
+-- Configs
+-----------------------------
+
+local cfg = {}
+
+cfg.icon = {
+ size = 32,
+ spacing = 4,
+ columns = 12,
+}
+
+cfg.sort = {
+ enabled = true,
+ sortToBottom = false,
+}
+
+cfg.font = mediapath .. "expressway.ttf"
+cfg.showQuest = true
+cfg.flashNew = true
+cfg.showItemLevel = true
+
+cfg.backdrop = {
+ bgFile = "Interface\\Buttons\\WHITE8x8",
+ bgColor = {0.08, 0.08, 0.1, 0.92},
+ edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
+ edgeColor = {0.1, 0.1, 0.1, 0.6},
+ tile = false,
+ tileEdge = false,
+ tileSize = 16,
+ edgeSize = 16,
+ inset = 3,
+ insets = {left = 3, right = 3, top = 3, bottom = 3}
+}
+
+cfg.bag = {
+ point = {"BOTTOMRIGHT", UIParent, "BOTTOMRIGHT", -34, 48},
+ extraHeight = 16,
+}
+
+cfg.bank = {
+ point = {"BOTTOMLEFT", UIParent, "BOTTOMLEFT", 34, 48},
+}
+
+L.C = cfg
\ No newline at end of file
diff --git a/rBag/libs/SortBags.lua b/rBag/libs/SortBags.lua
new file mode 100644
index 0000000..654d010
--- /dev/null
+++ b/rBag/libs/SortBags.lua
@@ -0,0 +1,539 @@
+local _G, _M = getfenv(0), {}
+setfenv(1, setmetatable(_M, {__index=_G}))
+
+CreateFrame('GameTooltip', 'SortBagsTooltip', nil, 'GameTooltipTemplate')
+
+BAG_CONTAINERS = {0, 1, 2, 3, 4}
+BANK_BAG_CONTAINERS = {-1, 5, 6, 7, 8, 9, 10, 11}
+
+function _G.SortBags()
+ CONTAINERS = {unpack(BAG_CONTAINERS)}
+ for i = #CONTAINERS, 1, -1 do
+ if GetBagSlotFlag(i - 1, LE_BAG_FILTER_FLAG_IGNORE_CLEANUP) then
+ tremove(CONTAINERS, i)
+ end
+ end
+ Start()
+end
+
+function _G.SortBankBags()
+ CONTAINERS = {unpack(BANK_BAG_CONTAINERS)}
+ for i = #CONTAINERS, 1, -1 do
+ if GetBankBagSlotFlag(i - 1, LE_BAG_FILTER_FLAG_IGNORE_CLEANUP) then
+ tremove(CONTAINERS, i)
+ end
+ end
+ Start()
+end
+
+function _G.GetSortBagsRightToLeft(enabled)
+ return SortBagsRightToLeft
+end
+
+function _G.SetSortBagsRightToLeft(enabled)
+ _G.SortBagsRightToLeft = enabled and 1 or nil
+end
+
+local function set(...)
+ local t = {}
+ local n = select('#', ...)
+ for i = 1, n do
+ t[select(i, ...)] = true
+ end
+ return t
+end
+
+local function arrayToSet(array)
+ local t = {}
+ for i = 1, #array do
+ t[array[i]] = true
+ end
+ return t
+end
+
+local function union(...)
+ local t = {}
+ local n = select('#', ...)
+ for i = 1, n do
+ for k in pairs(select(i, ...)) do
+ t[k] = true
+ end
+ end
+ return t
+end
+
+local SPECIAL = set(5462, 13347, 11511, 38233)
+
+local KEYS = set(9240, 11511, 17191, 13544, 12324, 16309, 12384, 20402)
+
+local TOOLS = set(6218, 6339, 11130, 11145, 16207, 22461, 22462, 22463, 5060, 7005, 12709, 19727, 5956, 2901, 6219, 10498, 9149, 15846, 6256, 6365, 6367, 20815, 20824, 25978)
+
+local CLASSES = {
+ -- soul
+ {
+ containers = {22243, 22244, 21340, 21341, 21342, 21872},
+ items = set(6265),
+ },
+ -- arrow
+ {
+ containers = {2101, 5439, 7278, 11362, 3573, 3605, 7371, 8217, 2662, 19319, 18714, 29143, 29144, 34105, 34100},
+ items = set(2512, 2514, 2515, 3029, 3030, 3031, 3464, 9399, 10579, 11285, 12654, 18042, 19316, 24412, 24417, 28053, 28056, 30319, 30611, 31737, 31949, 32760, 33803, 34581),
+ },
+ -- bullet
+ {
+ containers = {2102, 5441, 7279, 11363, 3574, 3604, 7372, 8218, 2663, 19320, 29118, 34106, 34099},
+ items = set(2516, 2519, 3033, 3465, 4960, 5568, 8067, 8068, 8069, 10512, 10513, 11284, 11630, 13377, 15997, 19317, 23772, 23773, 28060, 28061, 30612, 31735, 32761, 32882, 32883, 34582),
+ },
+ -- ench
+ {
+ containers = {22246, 22248, 22249, 22249, 21858},
+ items = arrayToSet({6218, 6222, 6339, 6342, 6343, 6344, 6345, 6346, 6347, 6348, 6349, 6375, 6376, 6377, 10938, 10939, 10940, 10978, 10998, 11038, 11039, 11081, 11082, 11083, 11084, 11098, 11101, 11130, 11134, 11135, 11137, 11138, 11139, 11145, 11150, 11151, 11152, 11163, 11164, 11165, 11166, 11167, 11168, 11174, 11175, 11176, 11177, 11178, 11202, 11203, 11204, 11205, 11206, 11207, 11208, 11223, 11224, 11225, 11226, 11813, 14343, 14344, 16202, 16203, 16204, 16207, 16214, 16215, 16216, 16217, 16218, 16219, 16220, 16221, 16222, 16223, 16224, 16242, 16243, 16244, 16245, 16246, 16247, 16248, 16249, 16250, 16251, 16252, 16253, 16254, 16255, 17725, 18259, 18260, 19444, 19445, 19446, 19447, 19448, 19449, 20725, 20726, 20727, 20728, 20729, 20730, 20731, 20732, 20733, 20734, 20735, 20736, 20752, 20753, 20754, 20755, 20756, 20757, 20758, 22392, 22445, 22446, 22447, 22448, 22449, 22450, 22461, 22462, 22463, 22530, 22531, 22532, 22533, 22534, 22535, 22536, 22537, 22538, 22539, 22540, 22541, 22542, 22543, 22544, 22545, 22546, 22547, 22548, 22551, 22552, 22553, 22554, 22555, 22556, 22557, 22558, 22559, 22560, 22561, 22562, 22563, 22564, 22565, 24000, 24003, 25848, 25849, 28270, 28271, 28272, 28273, 28274, 28276, 28277, 28279, 28280, 28281, 28282, 33148, 33149, 33150, 33151, 33152, 33153, 33165, 33307, 34872, 35297, 35298, 35299, 35498, 35500, 35756, 186683, 7081, 12810, 7068, 7972, 12808, 7067, 7075, 7076, 7077, 7078, 7080, 7082, 12803}),
+ },
+ -- herb
+ {
+ containers = {22250, 22251, 22252, 38225},
+ items = arrayToSet({765, 785, 1401, 2263, 2447, 2449, 2450, 2452, 2453, 3355, 3356, 3357, 3358, 3369, 3818, 3819, 3820, 3821, 4625, 5013, 5056, 5168, 8831, 8836, 8838, 8839, 8845, 8846, 11018, 11020, 11022, 11024, 11040, 11514, 11951, 11952, 13463, 13464, 13465, 13466, 13467, 13468, 16205, 16208, 17034, 17035, 17036, 17037, 17038, 17760, 18297, 19727, 22094, 22147, 22710, 22785, 22786, 22787, 22788, 22789, 22790, 22791, 22792, 22793, 22794, 22795, 22797, 23329, 23501, 23788, 24245, 24246, 24401, 31300, 32468, 34465, 8153, 10286, 19726}),
+ },
+ -- mining
+ {
+ containers = {29540, 30746},
+ items = arrayToSet({756, 778, 1819, 1893, 1959, 2770, 2771, 2772, 2775, 2776, 2835, 2836, 2838, 2840, 2841, 2842, 2901, 3575, 3576, 3577, 3858, 3859, 3860, 3861, 6037, 7911, 7912, 10620, 11370, 11371, 12359, 12360, 12365, 12655, 17771, 18562, 20723, 22202, 22203, 23424, 23425, 23426, 23427, 23445, 23446, 23447, 23448, 23449, 23573, 32464, 35128, 5956, 24186, 24188, 24190, 24234, 24235, 24242, 24243}),
+ },
+ -- leather
+ {
+ containers = {34482, 34490},
+ items = arrayToSet({783, 2304, 2313, 2318, 2319, 2320, 2321, 2324, 2325, 2406, 2407, 2408, 2409, 2604, 2605, 2934, 3182, 3824, 4096, 4231, 4232, 4233, 4234, 4235, 4236, 4265, 4289, 4291, 4293, 4294, 4295, 4296, 4297, 4298, 4299, 4300, 4301, 4304, 4337, 4340, 4341, 4342, 4461, 5082, 5083, 5116, 5373, 5637, 5784, 5785, 5786, 5787, 5788, 5789, 5972, 5973, 5974, 6260, 6261, 6470, 6471, 6474, 6475, 6476, 6710, 7005, 7070, 7071, 7286, 7287, 7288, 7289, 7290, 7360, 7361, 7362, 7363, 7364, 7392, 7428, 7449, 7450, 7451, 7452, 7453, 7613, 8146, 8150, 8151, 8154, 8165, 8167, 8168, 8169, 8170, 8171, 8172, 8173, 8343, 8368, 8384, 8385, 8386, 8387, 8388, 8389, 8390, 8395, 8397, 8398, 8399, 8400, 8401, 8402, 8403, 8404, 8405, 8406, 8407, 8408, 8409, 10290, 11512, 12607, 12709, 12731, 12753, 13287, 13288, 14341, 14635, 15407, 15408, 15409, 15410, 15412, 15414, 15415, 15416, 15417, 15419, 15420, 15422, 15423, 15564, 15725, 15726, 15727, 15728, 15729, 15730, 15731, 15732, 15733, 15734, 15735, 15737, 15738, 15739, 15740, 15741, 15742, 15743, 15744, 15745, 15746, 15747, 15748, 15749, 15751, 15752, 15753, 15754, 15755, 15756, 15757, 15758, 15759, 15760, 15761, 15762, 15763, 15764, 15765, 15768, 15769, 15770, 15771, 15772, 15773, 15774, 15775, 15776, 15777, 15779, 15781, 17012, 17022, 17023, 17025, 17056, 17722, 17967, 17968, 18239, 18240, 18251, 18252, 18512, 18514, 18515, 18516, 18517, 18518, 18519, 18662, 18731, 18949, 19326, 19327, 19328, 19329, 19330, 19331, 19332, 19333, 19767, 19768, 19769, 19770, 19771, 19772, 19773, 19901, 20253, 20254, 20381, 20382, 20498, 20499, 20500, 20501, 20506, 20507, 20508, 20509, 20510, 20511, 20576, 21548, 21887, 22692, 22694, 22695, 22696, 22697, 22698, 22769, 22770, 22771, 23793, 25649, 25650, 25651, 25652, 25699, 25700, 25707, 25708, 25720, 25721, 25722, 25725, 25726, 25728, 25729, 25730, 25731, 25732, 25733, 25734, 25735, 25736, 25737, 25738, 25739, 25740, 25741, 25742, 25743, 29213, 29214, 29215, 29217, 29218, 29219, 29483, 29485, 29486, 29487, 29488, 29528, 29529, 29530, 29531, 29532, 29533, 29534, 29535, 29536, 29539, 29547, 29548, 29664, 29669, 29672, 29673, 29674, 29675, 29677, 29682, 29684, 29689, 29691, 29693, 29698, 29700, 29701, 29702, 29703, 29704, 29713, 29714, 29717, 29718, 29719, 29720, 29721, 29722, 29723, 29724, 29725, 29726, 29727, 29728, 29729, 29730, 29731, 29732, 29733, 29734, 30183, 30301, 30302, 30303, 30304, 30305, 30306, 30307, 30308, 30444, 31361, 31362, 32428, 32429, 32430, 32431, 32432, 32433, 32434, 32435, 32436, 32470, 32744, 32745, 32746, 32747, 32748, 32749, 32750, 32751, 33124, 33205, 34172, 34173, 34174, 34175, 34200, 34201, 34207, 34218, 34262, 34330, 34491, 34664, 35212, 35213, 35214, 35215, 35216, 35217, 35218, 35219, 35300, 35301, 35302, 35303, 35517, 35519, 35520, 35521, 35523, 35524, 35527, 35528, 35539, 35540, 35541, 35542, 35545, 35546, 35549, 35550, 185848, 185849, 185850, 185851, 185852, 185922, 185923, 185924, 185925, 185926, 187048, 187049, 8153, 7081, 12810, 15846, 19726, 7067, 7075, 7076, 7077, 7078, 7080, 7082, 12803}),
+ },
+ -- gems
+ {
+ containers = {24270, 30747},
+ items = arrayToSet({774, 818, 1206, 1210, 1529, 1705, 3864, 5498, 5500, 5513, 5514, 7909, 7910, 7971, 8007, 8008, 11382, 11754, 12361, 12363, 12364, 12799, 12800, 13926, 18335, 19774, 20815, 20824, 21929, 22044, 22459, 22460, 23077, 23079, 23094, 23095, 23096, 23097, 23098, 23099, 23100, 23101, 23103, 23104, 23105, 23106, 23107, 23108, 23109, 23110, 23111, 23112, 23113, 23114, 23115, 23116, 23117, 23118, 23119, 23120, 23121, 23158, 23234, 23364, 23366, 23436, 23437, 23438, 23439, 23440, 23441, 24027, 24028, 24029, 24030, 24031, 24032, 24033, 24035, 24036, 24037, 24039, 24047, 24048, 24050, 24051, 24052, 24053, 24054, 24055, 24056, 24057, 24058, 24059, 24060, 24061, 24062, 24065, 24066, 24067, 24478, 24479, 25867, 25868, 25890, 25893, 25894, 25895, 25896, 25897, 25898, 25899, 25901, 27679, 27774, 27777, 27785, 27786, 27809, 27811, 27812, 27820, 27863, 27864, 28117, 28118, 28119, 28120, 28122, 28123, 28290, 28360, 28361, 28362, 28363, 28458, 28459, 28460, 28461, 28462, 28463, 28464, 28465, 28466, 28467, 28468, 28469, 28470, 28556, 28557, 28595, 30546, 30547, 30548, 30549, 30550, 30551, 30552, 30553, 30554, 30555, 30556, 30558, 30559, 30560, 30563, 30564, 30565, 30566, 30571, 30572, 30573, 30574, 30575, 30581, 30582, 30583, 30584, 30585, 30586, 30587, 30588, 30589, 30590, 30591, 30592, 30593, 30594, 30598, 30600, 30601, 30602, 30603, 30604, 30605, 30606, 30607, 30608, 31079, 31080, 31116, 31117, 31118, 31860, 31861, 31862, 31863, 31864, 31865, 31866, 31867, 31868, 31869, 32193, 32194, 32195, 32196, 32197, 32198, 32199, 32200, 32201, 32202, 32203, 32204, 32205, 32206, 32207, 32208, 32209, 32210, 32211, 32212, 32213, 32214, 32215, 32216, 32217, 32218, 32219, 32220, 32221, 32222, 32223, 32224, 32225, 32226, 32227, 32228, 32229, 32230, 32231, 32249, 32409, 32410, 32634, 32635, 32636, 32637, 32638, 32639, 32640, 32641, 32735, 32775, 32833, 32836, 33131, 33132, 33133, 33134, 33135, 33137, 33138, 33139, 33140, 33141, 33142, 33143, 33144, 33633, 33782, 34220, 34256, 34831, 35315, 35316, 35318, 35487, 35488, 35489, 35501, 35503, 35707, 35758, 35759, 35760, 35761, 37503, 38545, 38546, 38547, 38548, 38549, 38550, 24186, 24188, 24190, 24234, 24235, 24242, 24243}),
+ },
+ -- engineering
+ {
+ containers = {23774, 23775, 30745},
+ items = arrayToSet({814, 4357, 4358, 4359, 4360, 4361, 4363, 4364, 4365, 4366, 4367, 4368, 4370, 4371, 4373, 4374, 4375, 4376, 4377, 4378, 4380, 4381, 4382, 4384, 4385, 4386, 4387, 4388, 4389, 4390, 4391, 4392, 4393, 4394, 4395, 4396, 4397, 4398, 4399, 4400, 4403, 4404, 4405, 4406, 4407, 4408, 4409, 4410, 4411, 4412, 4413, 4414, 4415, 4416, 4417, 4852, 5507, 6219, 6672, 6712, 6714, 6715, 6716, 7069, 7148, 7189, 7190, 7191, 7192, 7506, 7560, 7561, 7742, 9060, 9061, 9312, 9313, 9318, 10498, 10499, 10500, 10501, 10502, 10503, 10504, 10505, 10506, 10507, 10514, 10518, 10542, 10543, 10545, 10546, 10548, 10558, 10559, 10560, 10561, 10562, 10576, 10577, 10580, 10585, 10586, 10587, 10588, 10601, 10602, 10603, 10604, 10605, 10606, 10607, 10608, 10609, 10645, 10646, 10647, 10648, 10716, 10720, 10721, 10723, 10724, 10725, 10726, 10727, 10790, 10791, 11590, 11827, 11828, 13308, 13309, 13310, 13311, 14639, 15992, 15993, 15994, 15999, 16000, 16005, 16006, 16008, 16009, 16022, 16023, 16040, 16041, 16042, 16043, 16044, 16045, 16046, 16047, 16048, 16049, 16050, 16051, 16052, 16053, 16054, 16055, 16056, 17716, 17720, 18232, 18235, 18283, 18290, 18291, 18292, 18587, 18588, 18594, 18631, 18634, 18636, 18637, 18638, 18639, 18641, 18645, 18647, 18648, 18649, 18650, 18651, 18652, 18653, 18654, 18655, 18656, 18657, 18658, 18660, 18661, 18984, 18986, 19026, 19027, 19998, 19999, 20000, 20001, 20475, 20816, 20834, 21557, 21558, 21559, 21571, 21574, 21576, 21589, 21590, 21592, 21714, 21716, 21718, 21724, 21725, 21726, 21727, 21728, 21729, 21730, 21731, 21732, 21733, 21734, 21735, 21737, 21738, 22728, 22729, 23736, 23737, 23758, 23761, 23762, 23763, 23764, 23765, 23766, 23768, 23769, 23770, 23771, 23781, 23782, 23783, 23784, 23785, 23786, 23787, 23799, 23800, 23802, 23803, 23804, 23805, 23806, 23807, 23808, 23809, 23810, 23811, 23812, 23813, 23814, 23815, 23816, 23817, 23819, 23820, 23821, 23822, 23823, 23824, 23825, 23826, 23827, 23828, 23829, 23831, 23832, 23835, 23836, 23838, 23839, 23840, 23841, 23874, 23882, 23883, 23884, 23887, 23888, 25886, 25887, 30542, 30544, 31666, 32381, 32413, 32423, 32461, 32472, 32473, 32474, 32475, 32476, 32478, 32479, 32480, 32494, 32495, 33092, 33093, 33804, 34060, 34061, 34113, 34114, 34353, 34354, 34355, 34356, 34357, 34467, 34503, 34504, 34626, 34627, 34847, 35181, 35182, 35183, 35184, 35185, 35186, 35187, 35189, 35190, 35191, 35192, 35193, 35194, 35195, 35196, 35197, 35310, 35311, 35485, 35581, 35582, 37567, 15846, 10286, 19726, 7068, 7972, 12808, 7067, 7075, 7076, 7077, 7078, 7080, 7082, 12803, 5956, 22574, 4401, 11825, 11826, 15996, 21277, 23767, 37710}),
+ },
+}
+
+do
+ local f = CreateFrame'Frame'
+ local lastUpdate = 0
+ local function updateHandler()
+ if GetTime() - lastUpdate > 1 then
+ for _, container in pairs(BAG_CONTAINERS) do
+ for position = 1, GetContainerNumSlots(container) do
+ SetScanTooltip(container, position)
+ end
+ end
+ for _, container in pairs(BANK_BAG_CONTAINERS) do
+ for position = 1, GetContainerNumSlots(container) do
+ SetScanTooltip(container, position)
+ end
+ end
+ f:SetScript('OnUpdate', nil)
+ end
+ end
+ f:SetScript('OnEvent', function()
+ lastUpdate = GetTime()
+ f:SetScript('OnUpdate', updateHandler)
+ end)
+ f:RegisterEvent'BAG_UPDATE'
+ f:RegisterEvent'BANKFRAME_OPENED'
+end
+
+local model, itemStacks, itemClasses, itemSortKeys
+
+do
+ local f = CreateFrame'Frame'
+
+ local process = coroutine.create(function() end);
+
+ local suspended
+
+ function Start()
+ process = coroutine.create(function()
+ while not Initialize() do
+ coroutine.yield()
+ end
+ while true do
+ suspended = false
+ if InCombatLockdown() then
+ return
+ end
+ local complete = Sort()
+ if complete then
+ return
+ end
+ Stack()
+ if not suspended then
+ coroutine.yield()
+ end
+ end
+ end)
+ f:Show()
+ end
+
+ f:SetScript('OnUpdate', function(_, arg1)
+ if coroutine.status(process) == 'suspended' then
+ suspended = true
+ coroutine.resume(process)
+ end
+ if coroutine.status(process) == 'dead' then
+ f:Hide()
+ end
+ end)
+end
+
+function LT(a, b)
+ local i = 1
+ while true do
+ if a[i] and b[i] and a[i] ~= b[i] then
+ return a[i] < b[i]
+ elseif not a[i] and b[i] then
+ return true
+ elseif not b[i] then
+ return false
+ end
+ i = i + 1
+ end
+end
+
+function Move(src, dst)
+ local texture, _, srcLocked = GetContainerItemInfo(src.container, src.position)
+ local _, _, dstLocked = GetContainerItemInfo(dst.container, dst.position)
+
+ if texture and not srcLocked and not dstLocked then
+ ClearCursor()
+ PickupContainerItem(src.container, src.position)
+ PickupContainerItem(dst.container, dst.position)
+
+ if src.item == dst.item then
+ local count = min(src.count, itemStacks[dst.item] - dst.count)
+ src.count = src.count - count
+ dst.count = dst.count + count
+ if src.count == 0 then
+ src.item = nil
+ end
+ else
+ src.item, dst.item = dst.item, src.item
+ src.count, dst.count = dst.count, src.count
+ end
+
+ coroutine.yield()
+ return true
+ end
+end
+
+do
+ local patterns = {}
+ for i = 1, 10 do
+ local text = gsub(format(ITEM_SPELL_CHARGES, i), '(-?%d+)(.-)|4([^;]-);', function(numberString, gap, numberForms)
+ local singular, dual, plural
+ _, _, singular, dual, plural = strfind(numberForms, '(.+):(.+):(.+)');
+ if not singular then
+ _, _, singular, plural = strfind(numberForms, '(.+):(.+)')
+ end
+ local i = abs(tonumber(numberString))
+ local numberForm
+ if i == 1 then
+ numberForm = singular
+ elseif i == 2 then
+ numberForm = dual or plural
+ else
+ numberForm = plural
+ end
+ return numberString .. gap .. numberForm
+ end)
+ patterns[text] = i
+ end
+
+ function itemCharges(text)
+ return patterns[text]
+ end
+end
+
+function TooltipInfo(container, position)
+ SetScanTooltip(container, position)
+
+ local charges, usable, soulbound, quest, conjured, mount
+ for i = 1, SortBagsTooltip:NumLines() do
+ local text = getglobal('SortBagsTooltipTextLeft' .. i):GetText()
+
+ local extractedCharges = itemCharges(text)
+ if extractedCharges then
+ charges = extractedCharges
+ elseif strfind(text, '^' .. ITEM_SPELL_TRIGGER_ONUSE) then
+ usable = true
+ elseif text == ITEM_SOULBOUND then
+ soulbound = true
+ elseif text == ITEM_BIND_QUEST then -- TODO retail can maybe use GetItemInfo bind info instead
+ quest = true
+ elseif text == ITEM_CONJURED then
+ conjured = true
+ elseif text == MOUNT then
+ mount = true
+ end
+ end
+
+ return charges or 1, usable, soulbound, quest, conjured, mount
+end
+
+function SetScanTooltip(container, position)
+ SortBagsTooltip:SetOwner(UIParent, 'ANCHOR_NONE')
+ SortBagsTooltip:ClearLines()
+
+ if container == BANK_CONTAINER then
+ SortBagsTooltip:SetInventoryItem('player', BankButtonIDToInvSlotID(position))
+ else
+ SortBagsTooltip:SetBagItem(container, position)
+ end
+end
+
+function Sort()
+ local complete, moved
+ repeat
+ complete, moved = true, false
+ for _, dst in ipairs(model) do
+ if dst.targetItem and (dst.item ~= dst.targetItem or dst.count < dst.targetCount) then
+ complete = false
+
+ local sources, rank = {}, {}
+
+ for _, src in ipairs(model) do
+ if src.item == dst.targetItem
+ and src ~= dst
+ and not (dst.item and src.class and src.class ~= itemClasses[dst.item])
+ and not (src.targetItem and src.item == src.targetItem and src.count <= src.targetCount)
+ then
+ rank[src] = abs(src.count - dst.targetCount + (dst.item == dst.targetItem and dst.count or 0))
+ tinsert(sources, src)
+ end
+ end
+
+ sort(sources, function(a, b) return rank[a] < rank[b] end)
+
+ for _, src in ipairs(sources) do
+ if Move(src, dst) then
+ moved = true
+ break
+ end
+ end
+ end
+ end
+ until complete or not moved
+ return complete
+end
+
+function Stack()
+ for _, src in ipairs(model) do
+ if src.item and src.count < itemStacks[src.item] and src.item ~= src.targetItem then
+ for _, dst in ipairs(model) do
+ if dst ~= src and dst.item and dst.item == src.item and dst.count < itemStacks[dst.item] and dst.item ~= dst.targetItem then
+ if Move(src, dst) then
+ return
+ end
+ end
+ end
+ end
+ end
+end
+
+do
+ local counts
+
+ local function insert(t, v)
+ if SortBagsRightToLeft then
+ tinsert(t, v)
+ else
+ tinsert(t, 1, v)
+ end
+ end
+
+ local function assign(slot, item)
+ if counts[item] > 0 then
+ local count
+ if SortBagsRightToLeft and mod(counts[item], itemStacks[item]) ~= 0 then
+ count = mod(counts[item], itemStacks[item])
+ else
+ count = min(counts[item], itemStacks[item])
+ end
+ slot.targetItem = item
+ slot.targetCount = count
+ counts[item] = counts[item] - count
+ return true
+ end
+ end
+
+ function Initialize()
+ model, counts, itemStacks, itemClasses, itemSortKeys = {}, {}, {}, {}, {}
+
+ for _, container in ipairs(CONTAINERS) do
+ local class = ContainerClass(container)
+ for position = 1, GetContainerNumSlots(container) do
+ local slot = {container=container, position=position, class=class}
+ local item = Item(container, position)
+ if item then
+ local _, count, locked = GetContainerItemInfo(container, position)
+ if locked then
+ return false
+ end
+ slot.item = item
+ slot.count = count
+ counts[item] = (counts[item] or 0) + count
+ end
+ insert(model, slot)
+ end
+ end
+
+ local free = {}
+ for item, count in pairs(counts) do
+ local stacks = ceil(count / itemStacks[item])
+ free[item] = stacks
+ if itemClasses[item] then
+ free[itemClasses[item]] = (free[itemClasses[item]] or 0) + stacks
+ end
+ end
+ for _, slot in ipairs(model) do
+ if slot.class and free[slot.class] then
+ free[slot.class] = free[slot.class] - 1
+ end
+ end
+
+ local items = {}
+ for item in pairs(counts) do
+ tinsert(items, item)
+ end
+ sort(items, function(a, b) return LT(itemSortKeys[a], itemSortKeys[b]) end)
+
+ for _, slot in ipairs(model) do
+ if slot.class then
+ for _, item in ipairs(items) do
+ if itemClasses[item] == slot.class and assign(slot, item) then
+ break
+ end
+ end
+ else
+ for _, item in ipairs(items) do
+ if (not itemClasses[item] or free[itemClasses[item]] > 0) and assign(slot, item) then
+ if itemClasses[item] then
+ free[itemClasses[item]] = free[itemClasses[item]] - 1
+ end
+ break
+ end
+ end
+ end
+ end
+ return true
+ end
+end
+
+function ContainerClass(container)
+ if container ~= 0 and container ~= BANK_CONTAINER then
+ local name = GetBagName(container)
+ if name then
+ for class, info in pairs(CLASSES) do
+ for _, itemID in pairs(info.containers) do
+ if name == GetItemInfo(itemID) then
+ return class
+ end
+ end
+ end
+ end
+ end
+end
+
+function Item(container, position)
+ local link = GetContainerItemLink(container, position)
+ if link then
+ local _, _, itemID, enchantID, suffixID, uniqueID = strfind(link, 'item:(%d+):(%d*):%d*:%d*:%d*:%d*:(%-?%d*):(%-?%d*)')
+ itemID = tonumber(itemID)
+ local itemName, _, quality, _, _, _, _, stack, slot, _, sellPrice, classId, subClassId = GetItemInfo('item:' .. itemID)
+ local charges, usable, soulbound, quest, conjured, mount = TooltipInfo(container, position)
+ local sortKey = {}
+
+ -- hearthstone
+ if itemID == 6948 or itemID == 184871 then
+ tinsert(sortKey, 1)
+
+ -- mounts
+ elseif mount then
+ tinsert(sortKey, 2)
+
+ -- special items
+ elseif SPECIAL[itemID] then
+ tinsert(sortKey, 3)
+
+ -- key items
+ elseif KEYS[itemID] then
+ tinsert(sortKey, 4)
+
+ -- tools
+ elseif TOOLS[itemID] then
+ tinsert(sortKey, 5)
+
+ -- soul shards
+ elseif itemID == 6265 then
+ tinsert(sortKey, 13)
+
+ -- conjured items
+ elseif conjured then
+ tinsert(sortKey, 14)
+
+ -- soulbound items
+ elseif soulbound then
+ tinsert(sortKey, 6)
+
+ -- reagents
+ elseif classId == 9 then
+ tinsert(sortKey, 7)
+
+ -- quest items
+ elseif quest then
+ tinsert(sortKey, 9)
+
+ -- consumables
+ elseif usable and classId ~= 1 and classId ~= 2 and classId ~= 8 or classId == 4 then
+ tinsert(sortKey, 8)
+
+ -- higher quality
+ elseif quality > 1 then
+ tinsert(sortKey, 10)
+
+ -- common quality
+ elseif quality == 1 then
+ tinsert(sortKey, 11)
+ tinsert(sortKey, -sellPrice)
+
+ -- junk
+ elseif quality == 0 then
+ tinsert(sortKey, 12)
+ tinsert(sortKey, sellPrice)
+ end
+
+ tinsert(sortKey, classId)
+ tinsert(sortKey, slot)
+ tinsert(sortKey, subClassId)
+ tinsert(sortKey, -quality)
+ tinsert(sortKey, itemName)
+ tinsert(sortKey, itemID)
+ tinsert(sortKey, (SortBagsRightToLeft and 1 or -1) * charges)
+ tinsert(sortKey, suffixID)
+ tinsert(sortKey, enchantID)
+ tinsert(sortKey, uniqueID)
+
+ local key = format('%s:%s:%s:%s:%s:%s', itemID, enchantID, suffixID, uniqueID, charges, (soulbound and 1 or 0))
+
+ itemStacks[key] = stack
+ itemSortKeys[key] = sortKey
+
+ for class, info in pairs(CLASSES) do
+ if info.items[itemID] then
+ itemClasses[key] = class
+ break
+ end
+ end
+
+ return key
+ end
+end
diff --git a/rBag/rBag.toc b/rBag/rBag.toc
new file mode 100644
index 0000000..f8d5279
--- /dev/null
+++ b/rBag/rBag.toc
@@ -0,0 +1,12 @@
+## Interface: 20501
+## Author: rawoil
+## Title: rBag |cff1a9fc0BCC|r
+## Notes: Inventory enhancements
+## RequiredDeps: rLib, rButtonTemplate_Zork
+
+libs/SortBags.lua
+
+init.lua
+functions.lua
+core.lua
+setup.lua
\ No newline at end of file
diff --git a/rBag/setup.lua b/rBag/setup.lua
new file mode 100644
index 0000000..cbb41b2
--- /dev/null
+++ b/rBag/setup.lua
@@ -0,0 +1,13 @@
+local A, L = ...
+
+local frame = CreateFrame("Frame")
+
+local function OnEvent(event)
+ rBag.Bags:Enable()
+
+ --create slash commands
+ rLib:CreateSlashCmd(L.addonName, L.addonShortcut, L.dragFrames, L.addonColor)
+end
+
+frame:RegisterEvent("PLAYER_LOGIN")
+frame:SetScript("OnEvent", OnEvent)
\ No newline at end of file
diff --git a/rButtonTemplate/core.lua b/rButtonTemplate/core.lua
index 41ce298..df4ffc1 100644
--- a/rButtonTemplate/core.lua
+++ b/rButtonTemplate/core.lua
@@ -164,6 +164,7 @@ local function SetupBackdrop(button,backdrop)
if backdrop.borderColor then
bg:SetBackdropBorderColor(unpack(backdrop.borderColor))
end
+ return bg
end
local function FormatHotkey(hotkey)
@@ -326,7 +327,7 @@ function rButtonTemplate:StyleItemButton(button,cfg)
if button.GetCheckedTexture then checkedTexture = button:GetCheckedTexture() end
--backdrop
- SetupBackdrop(button,cfg.backdrop)
+ button.Backdrop = SetupBackdrop(button,cfg.backdrop)
--textures
SetupTexture(icon,cfg.icon,"SetTexture",icon)
diff --git a/rButtonTemplate_Zork/theme.lua b/rButtonTemplate_Zork/theme.lua
index cfcddc1..add0c7b 100644
--- a/rButtonTemplate_Zork/theme.lua
+++ b/rButtonTemplate_Zork/theme.lua
@@ -160,7 +160,7 @@ local itemButtonConfig = {}
itemButtonConfig.backdrop = copyTable(actionButtonConfig.backdrop)
itemButtonConfig.icon = copyTable(actionButtonConfig.icon)
itemButtonConfig.count = copyTable(actionButtonConfig.count)
-itemButtonConfig.stock = copyTable(actionButtonConfig.name)
+itemButtonConfig.stock = copyTable(actionButtonConfig.hotkey)
itemButtonConfig.stock.alpha = 1
itemButtonConfig.border = copyTable(actionButtonConfig.border)
itemButtonConfig.normalTexture = copyTable(actionButtonConfig.normalTexture)
@@ -171,6 +171,18 @@ for i, button in next, itemButtons do
rButtonTemplate:StyleItemButton(button, itemButtonConfig)
end
+--make item config global for rBag
+rButtonTemplate_Zork_SlotButtonConfig = itemButtonConfig
+rButtonTemplate_Zork_SlotButtonConfig.backdrop.points = {
+ {"TOPLEFT", 0, 0 },
+ {"BOTTOMRIGHT", 0, 0 },
+}
+rButtonTemplate_Zork_SlotButtonConfig.backdrop.edgeSize = 1
+rButtonTemplate_Zork_SlotButtonConfig.backdrop.insets = {left = 0,right = 0,top = 0,bottom = 0}
+rButtonTemplate_Zork_SlotButtonConfig.border.alpha = 0
+rButtonTemplate_Zork_SlotButtonConfig.normalTexture.file = ""
+rButtonTemplate_Zork_SlotButtonConfig.pushedTexture = {file = ""}
+
-----------------------------
-- extraButtonConfig
-----------------------------
@@ -211,22 +223,4 @@ debuffButtonConfig.count.font = { fontExpressway, 12.5, "OUTLINE"}
debuffButtonConfig.duration.font = { fontExpressway, 12.5, "OUTLINE"}
--rButtonTemplate:StyleDebuffButtons
-rButtonTemplate:StyleDebuffButtons(debuffButtonConfig)
-
------------------------------
--- bagButtonConfig
------------------------------
-
-local bagButtonConfig = copyTable(auraButtonConfig)
---change the backdrop a bit
-bagButtonConfig.backdrop.bgFile = "Interface\\Buttons\\WHITE8x8"
-bagButtonConfig.backdrop.edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border"
-bagButtonConfig.backdrop.tileSize = 16
-bagButtonConfig.backdrop.edgeSize = 16
-bagButtonConfig.backdrop.insets = {left=3,right=3,top=3,bottom=3}
-bagButtonConfig.backdrop.backgroundColor = {0.08,0.08,0.1,0.92}
-bagButtonConfig.backdrop.borderColor = {0.1,0.1,0.1,0.6}
-
---rButtonTemplate:StyleAllSlotButtons
--- rButtonTemplate:StyleAllSlotButtons(bagButtonConfig)
-rButtonTemplate_Zork_SlotButtonConfig = bagButtonConfig
\ No newline at end of file
+rButtonTemplate:StyleDebuffButtons(debuffButtonConfig)
\ No newline at end of file