Skip to content

Instantly share code, notes, and snippets.

@Lockeid
Created August 23, 2010 18:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Lockeid/546036 to your computer and use it in GitHub Desktop.
Save Lockeid/546036 to your computer and use it in GitHub Desktop.
--[[
Advanced users:
If you like, you can embed the cargBags2-framework in your Implementation,
serving as your personal bag-addon. This enables you to remove
unneeded core-plugins/mixins, but could be more complicated.
Class: Implementation
Serves as the core for your cargBags layout.
Attributes:
.contByID - indexed table of all containers
.contByName - containers by name, but the preferred way is to use :GetContainer(name)
.buttons - bagSlot-indexed table of all buttons - see cargBags/base/core.lua @ cargBags:ToBagSlot(bagID, slotID)
Functions:
container = :GetContainer(name) - fetches a container by its name (wrapper for .contByName)
Container = :GetContainerClass(name) - fetches a Container class by name or the default one (basis for all Containers)
Button = :GetItemButtonClass() - fetches the ItemButton class (basis for all ItemButtons)
:SetDefaultItemButtonClass(name) - you only need this if you have multiple ItemButton-classes
:RegisterBlizzard() - Overwrite Blizzard functions for toggling bags
:RegisterCallback(event, key, func) - The preferred way to handle events for plugins, they will be called func(key)
:GetButton(bagID, slotID) - Gets a button from the storage
:AtBank() - Returns whether the bank data is available
item = :GetItemInfo(bagID, slotID) - Fetches all available information for one item into a table
Callbacks:
:OnInit(...) - called when the implementation is opened the first time, spawn your bags here
:OnOpen() - called when it is shown
:OnClose() - called when it is hidden
:OnBankOpened() - called when the user visits a bank, good for toggling bank frame
:OnBankClosed() - called when the user finished visiting the bank
]]
local Gnomed = cargBags:NewImplementation("Gnomed")
Gnomed:RegisterBlizzard()
local function Init()
cargBags_Gnomed.Frames = {
["bank"] = {},
["bag"] = {},
["All"] = {},
["mp"] = {
["bag"] = cB_Gnomed_Bag,
["bank"] = cB_Gnomed_Bank,
};
};
end
local L = {}
L.Weapon, L.Armor, L.Container, L.Consumables, L.Glyph, L.Trades, L.Projectile, L.Quiver, L.Recipe, L.Gem, L.Misc, L.Quest = GetAuctionItemClasses()
-- Now let's set the points
-- Hide if the main bag is hidden
function HideIfMain(frame, type)
if not cargBags_Gnomed.Frames.mp[type]:IsShown() then
frame:Hide()
end
end
-- optionsTable
local frameStacks = {
["bag"] = {
frames = {},
firstPos = { "RIGHT", UIParent, "RIGHT", -65, -100 },
nextPos = { "BOTTOM", "TOP", 0, 15 },
nextColPos = { "BOTTOMRIGHT", "BOTTOMLEFT", -15, 0 },
},
["bank"] = {
frames = {},
firstPos = {"LEFT",UIParent,"LEFT", 15, -100},
nextPos = { "BOTTOM", "TOP", 0, 15 },
},
}
-- This anchors one frame in its stack
local function stackAnchorSingle(frame)
local stack = frame.stack
local frames = stack.frames
local height = frame:GetHeight() / frame:GetEffectiveScale()
local uiHeight = UIParent:GetHeight() / UIParent:GetEffectiveScale()
frame:ClearAllPoints()
local searchBeginning
for i=frame.stackPos-1, 1, -1 do
local prev = frames[i]
if(prev:IsShown()) then
if(frame.beginsCol) then
-- This frame begins a new column, anchor next to it!
local a,b,c,d = unpack(stack.nextColPos)
frame.beginsRow = true
return frame:SetPoint(a, frames[1], b,c,d)
else
-- Just place on column
local a,b,c,d = unpack(stack.nextPos)
return frame:SetPoint(a, prev, b,c,d)
end
end
end
-- No previous frame found? Be the first then!
frame:SetPoint(unpack(stack.firstPos))
end
-- This anchors a frame and the following ones
local function stackAnchorFrame(frame,type)
HideIfMain(frame, type)
stackAnchorSingle(frame)
for i= frame.stackPos+1, #frame.stack.frames do
stackAnchorSingle(frame.stack.frames[i])
end
end
-- Anchors all frames in the stack
function stackAnchorAll(stackName)
for i,frame in ipairs(frameStacks[stackName].frames) do
stackAnchorSingle(frame, stackName)
end
end
-- Adds a frame to the stack
function addToStack(frame, stackName)
local stack = frameStacks[stackName]
table.insert(stack.frames, frame)
frame.stack = stack
frame.stackPos = #stack.frames
end
local function PlaceFrame(frame, parent, type)
HideIfMain(frame, type)
addToStack(frame, type)
frame:SetScript("OnShow", function(self) stackAnchorFrame(self,type) end)
frame:SetScript("OnHide", function(self) stackAnchorFrame(self,type) end)
end
local function Call(frame,parent,type)
tinsert(cargBags_Gnomed.Frames[type], frame)
tinsert(cargBags_Gnomed.Frames.All, frame)
PlaceFrame(frame, parent, type)
end
function Gnomed:InitFilters()
local INVERTED = -1 -- with inverted filters (using -1), everything goes into this bag when the filter returns false
-- Blizzard Equipement manager part
-- This table will hold information about all items which are part of a set:
local item2setEM = {}
-- This function will extract the item set data, so it can be
-- efficiently checked in the filter later:
local function cacheSetsEM()
for k in pairs(item2setEM) do item2setEM[k] = nil end
for k = 1, GetNumEquipmentSets() do
local sName = GetEquipmentSetInfo(k)
local set = GetEquipmentSetItemIDs(sName)
for _,item in next, set do
-- "item" is simply the item ID here:
if item then item2setEM[item] = true end
end
end
--~ cargBags:UpdateBags()
end
-- This creates an invisible frame to hold the required event handlers:
local EQ_Event = CreateFrame("Frame")
EQ_Event:RegisterEvent("PLAYER_LOGIN")
EQ_Event:RegisterEvent("EQUIPMENT_SETS_CHANGED")
EQ_Event:SetScript("OnEvent", cacheSetsEM)
local OF = IsAddOnLoaded('Outfitter')
local item2setOF = {}
local pLevel = UnitLevel("player")
-- Outfitter doesn't use item strings or links to identify items by default,
-- so this is the function to create an item string:
local function createItemString(i) return "item:"..i.Code..":"..i.EnchantCode..":"..i.JewelCode1..":"..i.JewelCode2..":"..i.JewelCode3..":"..i.JewelCode4..":"..i.SubCode..":"..i.UniqueID..":"..pLevel end
local function cacheSetsOF()
for k in pairs(item2setOF) do item2setOF[k] = nil end
-- Outfitter grants access to sets via categories,
-- so there are two loops here:
for _,id in ipairs(Outfitter_GetCategoryOrder()) do
local OFsets = Outfitter_GetOutfitsByCategoryID(id)
for _,vSet in pairs(OFsets) do
for _,item in pairs(vSet.Items) do
-- "item" is a table here, and since I don't want to save
-- the whole table, I'll create an itemstring out of it:
if item then item2setOF[createItemString(item)] = true end
end
end
end
--~ cargBags:UpdateBags()
end
if OF then
-- Outfitter supports the needed callbacks by itself:
Outfitter_RegisterOutfitEvent("ADD_OUTFIT", cacheSetsOF)
Outfitter_RegisterOutfitEvent("DELETE_OUTFIT", cacheSetsOF)
Outfitter_RegisterOutfitEvent("EDIT_OUTFIT", cacheSetsOF)
if Outfitter:IsInitialized() then
cacheSetsOF()
else
Outfitter_RegisterOutfitEvent('OUTFITTER_INIT', cacheSetsOF)
end
end
local IR = IsAddOnLoaded('ItemRack')
local item2setIR = {}
local function cacheSetsIR()
for k in pairs(item2setIR) do item2setIR[k] = nil end
local IRsets = ItemRackUser.Sets
for i in next, IRsets do
-- Some internal sets and queues start with one of these
-- characters, so let's exclude them:
if not string.find(i, "^~") then
for _,item in pairs(IRsets[i].equip) do
-- "item" is a custom itemstring here:
if item then item2setIR[item] = true end
end
end
end
end
if IR then
cacheSetsIR()
-- ItemRack doesn't support any callbacks by itself, so we're going to
-- hook into the functions we need manually:
local function ItemRackOpt_CreateHooks()
-- Those are the actual hooks for adding, updating and deleting sets:
local IRsaveSet = ItemRackOpt.SaveSet
function ItemRackOpt.SaveSet(...) IRsaveSet(...); cacheSetsIR(); cargBags:UpdateBags() end
local IRdeleteSet = ItemRackOpt.DeleteSet
function ItemRackOpt.DeleteSet(...) IRdeleteSet(...); cacheSetsIR(); cargBags:UpdateBags() end
end
-- Amusingly, ItemRack puts its set updating functions into a
-- load-on-demand module, so we need to hook into the LoD-function first:
local IRtoggleOpts = ItemRack.ToggleOptions
function ItemRack.ToggleOptions(...) IRtoggleOpts(...) ItemRackOpt_CreateHooks() end
end
--------------------
--General filters
--------------------
-- Bag filter
local onlyBags = function(item) return item.bagID >= 0 and item.bagID <= 4 end
--Keyring filter
local onlyKeyring = function(item) return item.bagID == -2 end
-- Bank filter
local onlyBank = function(item) return item.bagID == -1 or item.bagID >= 5 and item.bagID <= 11 end
----------------
-- Bag filters
----------------
--[[
-- Stuff filter
self.onlyArmor = function(item) return item.type and item.type == L.Armor end -- for stuff
self.onlyWeapon = function(item) return item.type and item.type == L.Weapon end
self.onlyStuff = function(item) return item.type and (item.type == L.Armor or item.type == L.Weapon) end
-- Hide unused slots
local hideEmpty = function(item) return item.texture ~= nil end -- for keyring, stuff, quest, consumable
-- Quest items filter
self.onlyQuest = function(item) return item.type and item.type == L.Quest end
-- Consumables filter
self.onlyConsumables = function(item) return item.type and item.type == L.Consumables end
-- Trade goods filter
self.onlyTradeGoods = function(item) return item.type and item.type == L.Trades end
-- Gem filter
self.onlyGems = function(item) return item.type and item.type == L.Gem end
-- Glyphs
self.onlyGlyphs = function(item) return item.type and item.type == L.Glyph end
-- Projectiles
self.onlyPJ = function(item) return item.type and item.type == L.Projectile end
-- Custom
--~ self.onlyCustom = function (item) end
-- Filters filters :)
local nothing = function(item) return end
-- Blizzard filter
local fItemSets = function(item)
if not item.link then return false end
-- Check ItemRack sets:
if item2setIR[string.match(item.link,"item:(.+):%-?%d+")] then return true end
-- Check Outfitter sets:
local _,_,itemStr = string.find(item.link, "^|c%x+|H(.+)|h%[.*%]")
if item2setOF[itemStr] then return true end
-- Check Equipment Manager sets:
local _,itemID = strsplit(":", itemStr)
if item2setEM[tonumber(itemID)] then return true end
return false
end
-----------------
-- Bank filters
-----------------
-- Stuff
self.onlyBankArmor = function(item) return self.onlyBank(item) and self.onlyArmor(item) end
self.onlyBankWeapons = function(item) return self.onlyBank(item) and self.onlyWeapon(item) end
self.onlyBankStuff = function(item) return self.onlyBank(item) and self.onlyStuff(item) end
-- Consumables
self.onlyBankConsumables = function(item) return self.onlyBank(item) and self.onlyConsumables(item) end
-- Trade Goods
self.onlyBankTG = function(item) return self.onlyBank(item) and self.onlyTradeGoods(item) end
-- Quest
self.onlyBankQuest = function(item) return self.onlyBank(item) and self.onlyQuest(item) end--]]
end
function Gnomed:InitBags()
self.Frames = {
["bank"] = {},
["bag"] = {},
["All"] = {},
["mp"] = {
["bag"] = cB_Gnomed_Bag,
["bank"] = cB_Gnomed_Bank,
};
};
local Cont = Gnomed:GetContainerClass()
local db = cargBags_Gnomed.Config
local f = {}
-- Bank frame and bank bags
--[[
f.bankStuff = Cont:New("Stuff", {Columns = db.BankColumns, Scale = db.DefaultScale, Bags = "bankframe+bank"})
f.bankStuff:SetFilter(self.onlyBankStuff, true)
f.bankStuff:SetFilter(self.hideEmpty)
f.bankQuest = Cont:New("Bank Quest", {Columns = db.BankColumns, Scale = db.DefaultScale, Bags = "bankframe+bank"})
f.bankQuest:SetFilter(self.onlyBankQuest, true)
f.bankQuest:SetFilter(self.hideEmpty, true)
f.bankConso = Cont:New("Bank Consumables", {Columns = db.BankColumns, Scale = db.DefaultScale, Bags = "bankframe+bank"})
f.bankConso:SetFilter(self.onlyBankConsumables, true)
f.bankConso:SetFilter(self.hideEmpty, true)
f.bankTGoods = Cont:New("Bank Trade Goods", {Columns = db.BankColumns, Scale = db.DefaultScale, Bags = "bankframe+bank"})
f.bankTGoods:SetFilter(self.onlyBankTG, true)
f.bankTGoods:SetFilter(self.hideEmpty, true) --]]
f.bank = Cont:New("Bank", {Columns = db.BankColumns, Scale = db.DefaultScale, Bags = "bankframe+bank"})
f.bank:SetFilter(onlyBank, true)
-- Stuff frames
--[[
f.equipment = Cont:New("Equipment", {Columns = db.DefaultColumns, Scale = db.DefaultScale, Bags = "backpack+bags"})
f.equipment:SetFilter(self.fItemSets,true)
f.equipment:SetFilter(self.hideEmpty, true)
f.stuff = Cont:New("Stuff", {Columns = db.DefaultColumns, Scale = db.DefaultScale, Bags = "backpack+bags"})
f.stuff:SetFilter(self.onlyStuff , true)
f.stuff:SetFilter(self.hideEmpty, true)
-- Quest frame
f.quest = Cont:New("Quest", {Columns = db.DefaultColumns, Scale = db.DefaultScale, Bags = "backpack+bags"})
f.quest:SetFilter(self.onlyQuest, true)
f.quest:SetFilter(self.hideEmpty, true)
-- Consumable
f.consumables = Cont:New("Consumables", {Columns = db.DefaultColumns, Scale = db.DefaultScale, Bags = "backpack+bags"})
f.consumables:SetFilter(self.onlyConsumables, true)
f.consumables:SetFilter(self.hideEmpty, true)
-- Trade goods
f.tgoods = Cont:New("Trade Goods", {Columns = db.DefaultColumns, Scale = db.DefaultScale, Bags = "backpack+bags"})
f.tgoods:SetFilter(self.onlyTradeGoods, true)
f.tgoods:SetFilter(self.hideEmpty, true)
-- Glyphs
f.gl = Cont:New("Glyphs", {Columns = db.DefaultColumns, Scale = db.DefaultScale, Bags = "backpack+bags"})
f.gl:SetFilter(self.onlyGlyphs, true)
f.gl:SetFilter(self.hideEmpty, true)
-- Gems
f.gems = Cont:New("Gems", {Columns = db.DefaultColumns, Scale = db.DefaultScale, Bags = "backpack+bags"})
f.gems:SetFilter(self.onlyGems, true)
f.gems:SetFilter(self.hideEmpty, true) --]]
-- Bagpack and bags
f.main = Cont:New("Bag", {Columns = db.DefaultColumns, Scale = db.DefaultScale, Bags = "backpack+bags"})
f.main:SetFilter(onlyBags, true)
Gnomed.main = f.main
-- Keyring
f.key = Cont:New("Keyring", {Columns = db.KeyringColumns, Scale = db.KeyringScale, Bags = "backpack+bags"})
f.key:SetFilter(onlyKeyring, true)
--f.key:SetFilter(Gnomed.hideEmpty, true)
Gnomed.Frames.All = f
end
function Gnomed:InitPoint()
-- Bags
frames = self.Frames.All
Call(frames.main, UIParent,"bag")
Call(frames.consumables, frames.main,"bag")
Call(frames.tgoods, frames.consumables,"bag")
Call(frames.gl, frames.tgoods,"bag", "BOTTOM")
Call(frames.gems, frames.gl,"bag", "BOTTOM")
Call(frames.equipment, frames.main,"bag")
Call(frames.stuff, frames.equipment,"bag")
Call(frames.quest, frames.stuff,"bag")
Call(frames.key, frames.quest,"bag")
-- Bank
frames.bank:SetPoint("LEFT", 15, -80)
Call(frames.bankStuff, frames.bank, "bank", "BOTTOM", frames.bank, "TOP", 0, 15)
Call(frames.bankQuest, frames.bankStuff, "bank", "BOTTOM", frames.bankStuff, "TOP", 0, 15)
Call(frames.bankConso, frames.bankQuest, "bank", "BOTTOM", frames.bankQuest, "TOP", 0, 15)
Call(frames.bankTGoods, frames.bankConso, "bank", "BOTTOM", frames.bankConso, "TOP", 0, 15)
end
function Gnomed:OnInit()
Gnomed:InitFilters()
Gnomed:InitBags()
Gnomed:InitPoint()
end
-- Showing/Hiding funcs
function ToggleCargBags(forceopen)
if(main:IsShown() and not forceopen) then CloseCargBags() else OpenCargBags() end
end
-- Opening / Closing Functions
function Gnomed:OnOpen()
Gnomed.main:Show()
--~ stackAnchorAll("bag")
for _, f in pairs(cargBags_Gnomed.Frames.bag) do
f:Show()
self.key:Hide()
CollapseEmpty(f)
end
end
function Gnomed:OnClose()
Gnomed.main:Hide()
for _, f in pairs(cargBags_Gnomed.Frames.bag) do
f:Hide()
end
end
-- To toggle containers when entering / leaving a bank
function Gnomed:OnBankOpened()
self.main:Show()
self.bank:Show()
for _, f in pairs(cargBags_Gnomed.Frames.All) do
f:Show()
self.key:Hide()
CollapseEmpty(f)
end
end
function Gnomed:OnBankClosed()
self.bank:Hide()
for _, f in pairs(cargBags_Gnomed.Frames.bank) do
f:Hide()
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment