Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 51 additions & 28 deletions DataStore_Containers/DataStore_Containers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ local function Log2(n)
return log(n) / log(2)
end

-- Bag types are saved as Log2(item family) + this offset, so that they occupy 16 to 26 in the
-- 5 bits (0 to 31) reserved for them. See ScanBag for why the range starts there.
local BAG_TYPE_OFFSET = 16

-- *** Scanning functions ***
local function EmptyContainer(bagID)
local bag = GetContainer(bagID)
Expand Down Expand Up @@ -146,9 +150,16 @@ local function ScanBagSlotsInfo()
for bagID = 0, COMMON_NUM_BAG_SLOTS, 1 do -- 5 Slots to include Reagent Bag
local bag = GetContainer(bagID)
local info = bag.info or 0

numSlots = numSlots + bit64:GetBits(info, 3, 7) -- bits 3-9 : bag size
freeSlots = freeSlots + bit64:GetBits(info, 10, 7) -- bits 10-16 : number of free slots in this bag

-- A profession bag only takes what it was made for, so counting its slots here said a
-- character could carry more than they can : a hunter with a full quiver read as having
-- sixteen slots of room, a warlock's soul pouch added twenty. The bag type is saved
-- now, so the two kinds can be told apart. Each bag is still listed with its size and
-- its type in the tooltip, only these totals change.
if bit64:GetBits(info, 17, 5) == 0 then
numSlots = numSlots + bit64:GetBits(info, 3, 7) -- bits 3-9 : bag size
freeSlots = freeSlots + bit64:GetBits(info, 10, 7) -- bits 10-16 : number of free slots in this bag
end
end

char.bagInfo = numSlots -- bits 0-9 : num bag slots
Expand All @@ -169,9 +180,13 @@ local function ScanBankSlotsInfo()
-- Retail : 6 to 11, MoP : 6 to 12
for bagID = COMMON_NUM_BAG_SLOTS + 1, COMMON_NUM_BAG_SLOTS + (NUM_BANKBAGSLOTS or 6) do -- 6 to 12
local bag = GetContainer(bagID)

numSlots = numSlots + bit64:GetBits(bag.info, 3, 7) -- bits 3-9 : bag size
freeSlots = freeSlots + bit64:GetBits(bag.info, 10, 7) -- bits 10-16 : number of free slots in this bag
local info = bag.info or 0 -- a bank bag slot that was never filled has none

-- same as the bags : a herb bag in the bank is not room for anything else
if bit64:GetBits(info, 17, 5) == 0 then
numSlots = numSlots + bit64:GetBits(info, 3, 7) -- bits 3-9 : bag size
freeSlots = freeSlots + bit64:GetBits(info, 10, 7) -- bits 10-16 : number of free slots in this bag
end
end

local numPurchasedSlots = isRetail
Expand Down Expand Up @@ -199,9 +214,15 @@ local function ScanBag(bagID)
-- https://wowpedia.fandom.com/wiki/ItemFamily
-- bag type will be 1024 for a mining bag for instance, it's just bit 11 in the item family (2^bit-1)
-- we'll just save 10 using the Log2

-- .. shifted by BAG_TYPE_OFFSET, for two reasons:
-- - 0 must keep meaning "no specific type", but a quiver (family 1) would also save a 0
-- - earlier versions saved the plain Log2 (0 to 10) while bagTypeStrings was keyed on the
-- item family itself, so those keys never matched. Staying clear of that range means
-- data saved by an earlier version reads as "no type" (what it already displayed)
-- instead of picking up a wrong label, until that character is scanned again.

if bagType and bagType > 0 then
bagType = Log2(bagType)
bagType = Log2(bagType) + BAG_TYPE_OFFSET
end

bag.info = (rarity or 0) -- bits 0-2 : rarity
Expand Down Expand Up @@ -354,17 +375,18 @@ if interfaceVersion >= 110200 then
end

if isRetail then
-- keys are what ScanBag saves : the bit index of the item family, offset by BAG_TYPE_OFFSET
bagTypeStrings = {
-- [1] = "Quiver",
-- [2] = "Ammo Pouch",
[4] = C_Item.GetItemSubClassInfo(Enum.ItemClass.Container, 1), -- "Soul Bag",
[8] = C_Item.GetItemSubClassInfo(Enum.ItemClass.Container, 7), -- "Leatherworking Bag",
[16] = C_Item.GetItemSubClassInfo(Enum.ItemClass.Container, 8), -- "Inscription Bag",
[32] = C_Item.GetItemSubClassInfo(Enum.ItemClass.Container, 2), -- "Herb Bag"
[64] = C_Item.GetItemSubClassInfo(Enum.ItemClass.Container, 3), -- "Enchanting Bag",
[128] = C_Item.GetItemSubClassInfo(Enum.ItemClass.Container, 4), -- "Engineering Bag",
[512] = C_Item.GetItemSubClassInfo(Enum.ItemClass.Container, 5), -- "Gem Bag",
[1024] = C_Item.GetItemSubClassInfo(Enum.ItemClass.Container, 6), -- "Mining Bag",
-- [BAG_TYPE_OFFSET + 0] = "Quiver", -- family 1
-- [BAG_TYPE_OFFSET + 1] = "Ammo Pouch", -- family 2
[BAG_TYPE_OFFSET + 2] = C_Item.GetItemSubClassInfo(Enum.ItemClass.Container, 1), -- "Soul Bag", family 4
[BAG_TYPE_OFFSET + 3] = C_Item.GetItemSubClassInfo(Enum.ItemClass.Container, 7), -- "Leatherworking Bag", family 8
[BAG_TYPE_OFFSET + 4] = C_Item.GetItemSubClassInfo(Enum.ItemClass.Container, 8), -- "Inscription Bag", family 16
[BAG_TYPE_OFFSET + 5] = C_Item.GetItemSubClassInfo(Enum.ItemClass.Container, 2), -- "Herb Bag" family 32
[BAG_TYPE_OFFSET + 6] = C_Item.GetItemSubClassInfo(Enum.ItemClass.Container, 3), -- "Enchanting Bag", family 64
[BAG_TYPE_OFFSET + 7] = C_Item.GetItemSubClassInfo(Enum.ItemClass.Container, 4), -- "Engineering Bag", family 128
[BAG_TYPE_OFFSET + 9] = C_Item.GetItemSubClassInfo(Enum.ItemClass.Container, 5), -- "Gem Bag", family 512
[BAG_TYPE_OFFSET + 10] = C_Item.GetItemSubClassInfo(Enum.ItemClass.Container, 6), -- "Mining Bag", family 1024
}

-- CharacterBankTab_x : 6 to 11, AccountBankTab_x : 12 to 16
Expand All @@ -373,17 +395,18 @@ if isRetail then
-- end

else
-- keys are what ScanBag saves : the bit index of the item family, offset by BAG_TYPE_OFFSET
bagTypeStrings = {
[1] = "Quiver",
[2] = "Ammo Pouch",
[4] = C_Item.GetItemSubClassInfo(LE_ITEM_CLASS_CONTAINER or Enum.ItemClass.Container, 1), -- "Soul Bag",
[8] = C_Item.GetItemSubClassInfo(LE_ITEM_CLASS_CONTAINER or Enum.ItemClass.Container, 7), -- "Leatherworking Bag",
[16] = C_Item.GetItemSubClassInfo(LE_ITEM_CLASS_CONTAINER or Enum.ItemClass.Container, 8), -- "Inscription Bag",
[32] = C_Item.GetItemSubClassInfo(LE_ITEM_CLASS_CONTAINER or Enum.ItemClass.Container, 2), -- "Herb Bag"
[64] = C_Item.GetItemSubClassInfo(LE_ITEM_CLASS_CONTAINER or Enum.ItemClass.Container, 3), -- "Enchanting Bag",
[128] = C_Item.GetItemSubClassInfo(LE_ITEM_CLASS_CONTAINER or Enum.ItemClass.Container, 4), -- "Engineering Bag",
[512] = C_Item.GetItemSubClassInfo(LE_ITEM_CLASS_CONTAINER or Enum.ItemClass.Container, 5), -- "Gem Bag",
[1024] = C_Item.GetItemSubClassInfo(LE_ITEM_CLASS_CONTAINER or Enum.ItemClass.Container, 6), -- "Mining Bag",
[BAG_TYPE_OFFSET + 0] = "Quiver", -- family 1
[BAG_TYPE_OFFSET + 1] = "Ammo Pouch", -- family 2
[BAG_TYPE_OFFSET + 2] = C_Item.GetItemSubClassInfo(LE_ITEM_CLASS_CONTAINER or Enum.ItemClass.Container, 1), -- "Soul Bag", family 4
[BAG_TYPE_OFFSET + 3] = C_Item.GetItemSubClassInfo(LE_ITEM_CLASS_CONTAINER or Enum.ItemClass.Container, 7), -- "Leatherworking Bag", family 8
[BAG_TYPE_OFFSET + 4] = C_Item.GetItemSubClassInfo(LE_ITEM_CLASS_CONTAINER or Enum.ItemClass.Container, 8), -- "Inscription Bag", family 16
[BAG_TYPE_OFFSET + 5] = C_Item.GetItemSubClassInfo(LE_ITEM_CLASS_CONTAINER or Enum.ItemClass.Container, 2), -- "Herb Bag" family 32
[BAG_TYPE_OFFSET + 6] = C_Item.GetItemSubClassInfo(LE_ITEM_CLASS_CONTAINER or Enum.ItemClass.Container, 3), -- "Enchanting Bag", family 64
[BAG_TYPE_OFFSET + 7] = C_Item.GetItemSubClassInfo(LE_ITEM_CLASS_CONTAINER or Enum.ItemClass.Container, 4), -- "Engineering Bag", family 128
[BAG_TYPE_OFFSET + 9] = C_Item.GetItemSubClassInfo(LE_ITEM_CLASS_CONTAINER or Enum.ItemClass.Container, 5), -- "Gem Bag", family 512
[BAG_TYPE_OFFSET + 10] = C_Item.GetItemSubClassInfo(LE_ITEM_CLASS_CONTAINER or Enum.ItemClass.Container, 6), -- "Mining Bag", family 1024
}
end

Expand Down