From 833968208f56d5f046309d3401d23777366e92b4 Mon Sep 17 00:00:00 2001 From: rawoil Date: Mon, 5 Jul 2021 19:33:36 +0800 Subject: [PATCH] add rbag --- rBag/core.lua | 884 ++++++++++++++++++++++++++++++++++++++++ rBag/functions.lua | 19 + rBag/init.lua | 62 +++ rBag/libs/SortBags.lua | 539 ++++++++++++++++++++++++ rBag/rBag.toc | 12 + rBag/setup.lua | 13 + rButtonTemplate/core.lua | 3 +- rButtonTemplate_Zork/theme.lua | 34 +- 8 files changed, 1545 insertions(+), 21 deletions(-) create mode 100644 rBag/core.lua create mode 100644 rBag/functions.lua create mode 100644 rBag/init.lua create mode 100644 rBag/libs/SortBags.lua create mode 100644 rBag/rBag.toc create mode 100644 rBag/setup.lua 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 -- 1.7.9.5