Thread Tools Display Modes
01/05/24, 06:50 PM   #1
vsrs_au
Join Date: Dec 2022
Posts: 18
Duplication of items between bank and ESO+ bank

I wrote an addon to (among other things) count the items in the account's bank, using the 2 bag type codes defined in the ESOUI API, i.e. BAG_BANK and BAG_SUBSCRIBER_BANK. The problem is that my code is finding various instances of the same items appearing in both shared inventories. My (partial) code is below:
Code:
function InventoryDump.DumpInventory(bagType)
	local iUsed = GetNumBagUsedSlots(bagType)
	local iTotal = GetBagSize(bagType)
	if bagType == BAG_VIRTUAL then
		CHAT_SYSTEM:AddMessage("InventoryDump:     used=" .. iUsed)
	else
		CHAT_SYSTEM:AddMessage("InventoryDump:     used=" .. iUsed .. "/" .. iTotal)
	end

	for _, data in pairs(SHARED_INVENTORY.bagCache[bagType]) do
		if data ~= nil then
			local itemLink = GetItemLink(bagType, data.slotIndex)
			local invCount, bankCount, cbCount = GetItemLinkStacks(itemLink)
			local count = 0
			if bagType == BAG_BANK or bagType == BAG_SUBSCRIBER_BANK then
				count = bankCount
			elseif bagType == BAG_VIRTUAL then
				count = cbCount
			elseif bagType == BAG_BACKPACK then
				count = invCount
			end
			InventoryDump.DumpItem(bagType, count, itemName)
		end
	end

	CHAT_SYSTEM:AddMessage("InventoryDump: inventory dumped.")
end
If I call the function first for BAG_BANK and then for BAG_SUBSCRIBER_BANK, the message output to the chat window correctly shows the used and used+free for the 2 shared inventories, e.g. at the moment it will show
Code:
InventoryDump:    used=165/240
InventoryDump:    used=58/240
When I use the bank UI in the game, it shows I have 223 items out of 480. So the overall counts seem to be correct. But when I examine the item names and counts written to the SavedVariables file, I find that some items are appearing in both these shared inventories (with the same stack count), and others only appear in 1 of these shared inventories. Does anyone know why?

Last edited by vsrs_au : 01/05/24 at 08:55 PM.
  Reply With Quote
01/05/24, 08:56 PM   #2
Dolgubon
 
Dolgubon's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2016
Posts: 409
BAG_BANK and BAG_SUBSCRIBER_BANK are two different bags. This isn't just a number or funny quirk, it has actual consequences in how the underlying game behaves.They are completely separate, and just display as combined when viewed in the game UI.
So if you ask for the first empty slot in the BAG_BANK and it's full, you'll get nil even if sub bank has space. Or if you stack items in the bank, it won't stack an item in the bag_bank with one in the bag_subscriber_bank even if they are stackable (See https://www.esoui.com/downloads/info...nkStacker.html for a fix )
If you go through your bank, for items that appear in both lists, you'll probably see separate stacks of both items - and doing Y to stack the bank won't change that.

House storage could actually theoretically work similarly - all items in storage are available for withdrawal when you're inside a house. An addon could be made that shows you all 360 slots whenever you interact with any house storage item.


I haven't tested it, but it might even be possible to put in items above the bank 'limit' if your ESO+ lapses and you had most of your items in the sub bank.
  Reply With Quote
01/05/24, 10:33 PM   #3
vsrs_au
Join Date: Dec 2022
Posts: 18
Originally Posted by Dolgubon View Post
BAG_BANK and BAG_SUBSCRIBER_BANK are two different bags. This isn't just a number or funny quirk, it has actual consequences in how the underlying game behaves.They are completely separate, and just display as combined when viewed in the game UI.
So if you ask for the first empty slot in the BAG_BANK and it's full, you'll get nil even if sub bank has space. Or if you stack items in the bank, it won't stack an item in the bag_bank with one in the bag_subscriber_bank even if they are stackable (See https://www.esoui.com/downloads/info...nkStacker.html for a fix )
If you go through your bank, for items that appear in both lists, you'll probably see separate stacks of both items - and doing Y to stack the bank won't change that.

House storage could actually theoretically work similarly - all items in storage are available for withdrawal when you're inside a house. An addon could be made that shows you all 360 slots whenever you interact with any house storage item.


I haven't tested it, but it might even be possible to put in items above the bank 'limit' if your ESO+ lapses and you had most of your items in the sub bank.
Thanks for the reply, much appreciated.

However, this doesn't explain how I have the same item showing in both bags, e.g. in the bank UI in game, the item "Revelry Pie" shows with a stack of 60, then in my SavedVariables file, I have the same item showing in BAG_BANK and in BAG_SUBSCRIBER_BANK, and both have a count of 60, i.e. there's only 1 stack of 60 and it shows in both bags. It looks like GetItemLinkStacks() is returning the same value for that item for both bags, which doesn't make sense to me.

If it's any help, my DumpItem function is as follows:
Code:
function InventoryDump.DumpItem(bagType, count, itemName)
	if bagType == BAG_BANK then
		InventoryDump.savedVariablesAccountWide.Bank[itemName] = count
	elseif bagType == BAG_SUBSCRIBER_BANK then
		InventoryDump.savedVariablesAccountWide.ESOBank[itemName] = count
	elseif bagType == BAG_VIRTUAL then
		InventoryDump.savedVariablesAccountWide.CraftBag[itemName] = count
	elseif bagType == BAG_BACKPACK then
		InventoryDump.savedVariablesPerChar.Backpack[itemName] = count
	end
end
I then have the following in SavedVariables file:
Code:
InventoryAccountWide =
{
    ["EU Megaserver"] = 
    {
        ["@vsrs_au"] = 
        {
            ["$AccountWide"] = 
            {
                ["version"] = 1,
                ["ESOBank"] = 
                {
...
                    ["Revelry Pie"] = 60,
...
                }
                ["Bank"] = 
                {
...
                    ["Revelry Pie"] = 60,
...
                }

Last edited by vsrs_au : 01/05/24 at 10:49 PM.
  Reply With Quote
01/05/24, 11:30 PM   #4
DakJaniels
AddOn Author - Click to view addons
Join Date: Mar 2021
Posts: 31
Originally Posted by vsrs_au View Post
Thanks for the reply, much appreciated.

However, this doesn't explain how I have the same item showing in both bags, e.g. in the bank UI in game, the item "Revelry Pie" shows with a stack of 60, then in my SavedVariables file, I have the same item showing in BAG_BANK and in BAG_SUBSCRIBER_BANK, and both have a count of 60, i.e. there's only 1 stack of 60 and it shows in both bags. It looks like GetItemLinkStacks() is returning the same value for that item for both bags, which doesn't make sense to me.

If it's any help, my DumpItem function is as follows:
Code:
function InventoryDump.DumpItem(bagType, count, itemName)
	if bagType == BAG_BANK then
		InventoryDump.savedVariablesAccountWide.Bank[itemName] = count
	elseif bagType == BAG_SUBSCRIBER_BANK then
		InventoryDump.savedVariablesAccountWide.ESOBank[itemName] = count
	elseif bagType == BAG_VIRTUAL then
		InventoryDump.savedVariablesAccountWide.CraftBag[itemName] = count
	elseif bagType == BAG_BACKPACK then
		InventoryDump.savedVariablesPerChar.Backpack[itemName] = count
	end
end
I then have the following in SavedVariables file:
Code:
InventoryAccountWide =
{
    ["EU Megaserver"] = 
    {
        ["@vsrs_au"] = 
        {
            ["$AccountWide"] = 
            {
                ["version"] = 1,
                ["ESOBank"] = 
                {
...
                    ["Revelry Pie"] = 60,
...
                }
                ["Bank"] = 
                {
...
                    ["Revelry Pie"] = 60,
...
                }
Probably need to implement using
Lua Code:
  1. --- @param bagId Bag
  2. --- @param slotIndex integer
  3. --- @return id64|nil id
  4. function GetItemUniqueId(bagId, slotIndex) end

That way you get that uniqueId
  Reply With Quote
01/06/24, 12:20 AM   #5
Dolgubon
 
Dolgubon's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2016
Posts: 409
Originally Posted by vsrs_au View Post
Thanks for the reply, much appreciated.
Originally Posted by vsrs_au View Post

However, this doesn't explain how I have the same item showing in both bags, e.g. in the bank UI in game, the item "Revelry Pie" shows with a stack of 60, then in my SavedVariables file, I have the same item showing in BAG_BANK and in BAG_SUBSCRIBER_BANK, and both have a count of 60, i.e. there's only 1 stack of 60 and it shows in both bags. It looks like GetItemLinkStacks() is returning the same value for that item for both bags, which doesn't make sense to me.

If it's any help, my DumpItem function is as follows:
Code:
function InventoryDump.DumpItem(bagType, count, itemName)
    if bagType == BAG_BANK then
        InventoryDump.savedVariablesAccountWide.Bank[itemName] = count
    elseif bagType == BAG_SUBSCRIBER_BANK then
        InventoryDump.savedVariablesAccountWide.ESOBank[itemName] = count
    elseif bagType == BAG_VIRTUAL then
        InventoryDump.savedVariablesAccountWide.CraftBag[itemName] = count
    elseif bagType == BAG_BACKPACK then
        InventoryDump.savedVariablesPerChar.Backpack[itemName] = count
    end
end
I then have the following in SavedVariables file:
Code:
InventoryAccountWide =
{
    ["EU Megaserver"] = 
    {
        ["@vsrs_au"] = 
        {
            ["$AccountWide"] = 
            {
                ["version"] = 1,
                ["ESOBank"] = 
                {
...
                    ["Revelry Pie"] = 60,
...
                }
                ["Bank"] = 
                {
...
                    ["Revelry Pie"] = 60,
...
                }


The issue here is down to how you are 'counting' the items.
Consider this: If you have two full stacks of say, lockpicks, what would be listed in the saved vars? Or even just two partial stacks of them? Note that when you look at the number of items indicator in a tooltip, it does not differentiate between bank and sub bank.
You could either count them better, or change the table structure so you don't get duplicate entries (or make a cache but that's overkill)
Changing the sv to not differentiate between the bank and sub bank would mean that it would just re-save the same value in the spot for the key, so you'd have one revelry pie amount in the combined bank.
Counting them better would keep the separate entries, so you'd have two entries that add up to the combined total.
However, whichever one you choose, you probably want to re-consider using the item name to save the items. For example, if you have a potion of health, say tripots for tanking and single effect potions for writs and looted potions, then you'd only keep the last item stack size. For example, if you encounter tripots first, you'll save essence of health = 100, then you get to single effect potion and save essence of health = 45 over the existing tripot value of 100. https://wiki.esoui.com/GetSlotStackSize
As far as I'm aware, there isn't really a great way of programmatically designing the table keys to work around this problem. Item IDs are great for many items, but some items share the same item ID despite being different (for example, the aforementioned potions)
Item Link is possible, but many same items do not share the same item link. For example, a tempering alloy in a bank would usually have a different item ID than a tempering alloy in a craft bag.
Unique Item ID I'm pretty sure also does not really work too well, also being too discriminatory for most purposes, but you could experiment with it to see if it works for you.

The best way really is to go a more decision based way. Craft materials use item ID, potions use the level and effect IDs, gear uses the initial portion of the item link or unique ID, etc. Experiment with different item links and keys to find out what works best for you.
  Reply With Quote
01/06/24, 03:11 AM   #6
vsrs_au
Join Date: Dec 2022
Posts: 18
Originally Posted by Dolgubon View Post

The issue here is down to how you are 'counting' the items.
Consider this: If you have two full stacks of say, lockpicks, what would be listed in the saved vars? Or even just two partial stacks of them? Note that when you look at the number of items indicator in a tooltip, it does not differentiate between bank and sub bank.
You could either count them better, or change the table structure so you don't get duplicate entries (or make a cache but that's overkill)
Changing the sv to not differentiate between the bank and sub bank would mean that it would just re-save the same value in the spot for the key, so you'd have one revelry pie amount in the combined bank.
Counting them better would keep the separate entries, so you'd have two entries that add up to the combined total.
However, whichever one you choose, you probably want to re-consider using the item name to save the items. For example, if you have a potion of health, say tripots for tanking and single effect potions for writs and looted potions, then you'd only keep the last item stack size. For example, if you encounter tripots first, you'll save essence of health = 100, then you get to single effect potion and save essence of health = 45 over the existing tripot value of 100. https://wiki.esoui.com/GetSlotStackSize
As far as I'm aware, there isn't really a great way of programmatically designing the table keys to work around this problem. Item IDs are great for many items, but some items share the same item ID despite being different (for example, the aforementioned potions)
Item Link is possible, but many same items do not share the same item link. For example, a tempering alloy in a bank would usually have a different item ID than a tempering alloy in a craft bag.
Unique Item ID I'm pretty sure also does not really work too well, also being too discriminatory for most purposes, but you could experiment with it to see if it works for you.

The best way really is to go a more decision based way. Craft materials use item ID, potions use the level and effect IDs, gear uses the initial portion of the item link or unique ID, etc. Experiment with different item links and keys to find out what works best for you.
Thanks! That's a very detailed and useful answer, and I'll look into improving how I save the inventory counts.

[off-topic] Thanks for the Lazy Writ Crafter addon, by the way, I use it and it's great.
  Reply With Quote
01/06/24, 04:51 AM   #7
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,989
Why do you use getitemlink functions in that loop at all?
You already loop the bag cache so just use the data in the slots there! It should already contain all the info as data table.

Last edited by Baertram : 01/06/24 at 04:54 AM.
  Reply With Quote
01/06/24, 06:23 AM   #8
vsrs_au
Join Date: Dec 2022
Posts: 18
Originally Posted by Baertram View Post
Why do you use getitemlink functions in that loop at all?
You already loop the bag cache so just use the data in the slots there! It should already contain all the info as data table.
I did it that way because I'm unfamiliar with the ESOUI API and didn't realise there was a better way.
  Reply With Quote
01/06/24, 08:26 AM   #9
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,989
The bag cache is the cached data of the bags, containing the slots (which is the same data as the inventorySlots shown in the scrolllist as you press i basically).

So your loop here
for _, data in pairs(SHARED_INVENTORY.bagCache[bagType]) do
got the data and data.slotIndex etc. but also data.stackCount, data.name and all the other vanilla data should be in there that the GetBag* and GetItemLink* functions would return if you pass in the bagId, slotIndex and/or itemLink.

Only "special data" maybe missing.
I recommand to use an addon like merTorchbug and make your loope data global via e.g.
InventoryDump._debugData = data

That way you can use /tbug or /tb (or /zgoo if you use ZGOO addon) InventoryDump and inspect your global variable InventoryDump and then click on _debugData and inspect what is given already.


oh btw,to get the most actual bag cache you need to run this function once before you start to loop the bagCache:
SHARED_INVENTORY:GetOrCreateBagCache(bagId)
So for your needs you'd have to run

SHARED_INVENTORY:GetOrCreateBagCache(BAG_BACKPACK)
SHARED_INVENTORY:GetOrCreateBagCache(BAG_BANK)
SHARED_INVENTORY:GetOrCreateBagCache(BAG_SUBSCRIBER_BANK)
SHARED_INVENTORY:GetOrCreateBagCache(BAG_VIRTUAL)

Hint: As Dolgubon already said the slotIndex in the BAG_VIRTUAL is the actual data.itemId or GetItemId(bagId, slotIndex)!

Last edited by Baertram : 01/06/24 at 08:31 AM.
  Reply With Quote

ESOUI » Developer Discussions » General Authoring Discussion » Duplication of items between bank and ESO+ bank


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off