ESOUI

ESOUI (https://www.esoui.com/forums/index.php)
-   General Authoring Discussion (https://www.esoui.com/forums/forumdisplay.php?f=174)
-   -   Duplication of items between bank and ESO+ bank (https://www.esoui.com/forums/showthread.php?t=10778)

vsrs_au 01/05/24 06:50 PM

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?

Dolgubon 01/05/24 08:56 PM

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.

vsrs_au 01/05/24 10:33 PM

Quote:

Originally Posted by Dolgubon (Post 49158)
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,
...
                }


DakJaniels 01/05/24 11:30 PM

Quote:

Originally Posted by vsrs_au (Post 49161)
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

Dolgubon 01/06/24 12:20 AM

Quote:

Originally Posted by vsrs_au (Post 49161)
Thanks for the reply, much appreciated.

Quote:

Originally Posted by vsrs_au (Post 49161)

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.

vsrs_au 01/06/24 03:11 AM

Quote:

Originally Posted by Dolgubon (Post 49163)

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.

Baertram 01/06/24 04:51 AM

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.

vsrs_au 01/06/24 06:23 AM

Quote:

Originally Posted by Baertram (Post 49165)
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.

Baertram 01/06/24 08:26 AM

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)!


All times are GMT -6. The time now is 02:27 AM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2014 - 2022 MMOUI