Quantcast
Unequip all items - WoWInterface
Thread Tools Display Modes
05-24-22, 10:01 PM   #1
Walkerbo
A Chromatic Dragonspawn
 
Walkerbo's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2010
Posts: 157
Unequip all items

Hi all

I am trying to unequip all items into any empty bag slot.

The problem is that I can unequip all items into my bags or into my backpack but not all into any empty slot in both.

This is the code I am trying to run;
Lua Code:
  1. for k, v in pairs(EquipmentSlots) do
  2.    PickupInventoryItem(v)
  3.    for bag = 0, 4 do
  4.       for slot = 0, GetContainerNumSlots(bag) do
  5.          local itemID = GetContainerItemID(bag, slot)
  6.          if not itemID then
  7.             PutItemInBag(slot)
  8.          end
  9.       end
  10.    end
  11.    if CursorHasItem() then
  12.     PutItemInBackpack()
  13.    end
  14. end

If I have enough bagspace the items move into the bags, but if I do not have enough space the leftover items do not drop into the backpack.

I have tried splitting it into 2 separate chunks runnig one after the other with the same results.

It is the backpack one that seems to break it, it will fill the backpack then say "not enough space" and then stop altogether.

Does anyone have any advice/help for me?

Cheers
__________________
"As someone once told me, frames are just special types of tables, and tables are special types of pointers."
Fizzlemizz
  Reply With Quote
05-24-22, 10:41 PM   #2
Kanegasi
A Molten Giant
 
Kanegasi's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2007
Posts: 615
PutItemInBag wants an InventorySlotId, not a slot in a bag. 20, 21, 22, and 23 are the bag slots. You should also break out of the inner loops once you put the item in a bag.

Lua Code:
  1. local ignore,foundspot={[0]={},[1]={},[2]={},[3]={},[4]={},}
  2. for k, v in pairs(EquipmentSlots) do
  3.    PickupInventoryItem(v)
  4.    foundspot = false
  5.    if CursorHasItem() then
  6.       for bag = 4, 0, -1 do
  7.          for slot = 1, GetContainerNumSlots(bag) do
  8.             if not ignore[bag][slot] and not GetContainerItemID(bag, slot) then
  9.                if bag == 0 then
  10.                   PutItemInBackpack()
  11.                else
  12.                   PutItemInBag(bag+19)
  13.                end
  14.                ignore[bag][slot] = true
  15.                foundspot = true
  16.                break
  17.             end
  18.          end
  19.          if foundspot then
  20.             break
  21.          end
  22.       end
  23.    end
  24. end


Edit: Fizzlemizz makes a good point. Based on your wording, it does look like you would rather fill other bags with the unequipped gear before your backpack. I reversed the bag loop so your backpack is searched last.

Edit2: Added CursorHasItem and an ignore table to keep track of spots filled by the code.

Last edited by Kanegasi : 05-25-22 at 06:58 AM. Reason: slots within a bag start at 1
  Reply With Quote
05-24-22, 11:25 PM   #3
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,500
Bag 0 is the backpack so checking there first for empty slots is probably not what you're looking for.

Code:
for bag = 1, 4 do
Edit:
In a tight loop, the bag inventory doesn't update in time so you the get the "That bag is full" notification which can cause the process to break. Best to wait for the bag update event before processing the next item:
Lua Code:
  1. local LastBag, LastSlot, Remove
  2. local function SaveToBags()
  3.     while Remove do
  4.         PickupInventoryItem(Remove)
  5.         Remove = Remove+1
  6.         if Remove > INVSLOT_LAST_EQUIPPED then
  7.             Remove = nil
  8.             return
  9.         end
  10.         if CursorHasItem() then -- only process picked up items
  11.             local Placed
  12.             for bag = LastBag, 4 do -- bag 0 is the backpack
  13.                 local slots = GetContainerNumSlots(bag)
  14.                 for LastSlot = LastSlot, slots do
  15.                     local itemID = GetContainerItemID(bag, LastSlot)
  16.                     if not itemID then
  17.                         PutItemInBag(bag+19)
  18.                         Placed = true -- so scram
  19.                         break
  20.                     end
  21.                 end
  22.                 if bag > LastBag then
  23.                     LastBag = bag
  24.                     LastSlot = 1
  25.                 end
  26.                 if Placed then break end
  27.             end
  28.             if not Placed then -- no empty slots in bags
  29.                 local GotSpace
  30.                 for i=1, GetContainerNumSlots(0) do -- make sure the backpack isn't full as well
  31.                     if not GetContainerItemID(0, i) then
  32.                         GotSpace = true
  33.                         break
  34.                     end
  35.                 end
  36.                 if not GotSpace then  -- No more slots in backpack to put stuff either
  37.                     print("Not enough backpack space!")
  38.                     Remove = nil
  39.                     return
  40.                 end
  41.                 PutItemInBackpack()
  42.             end
  43.             break
  44.         end
  45.     end
  46. end
  47.  
  48. local f = CreateFrame("Frame")
  49. f:RegisterEvent("BAG_UPDATE")
  50. f:SetScript("OnEvent", function(self, event, ...)
  51.     if event == "BAG_UPDATE" then -- if you are using the handler for more than this event
  52.         if Remove then
  53.             SaveToBags()
  54.             return -- maybe, if you are doing other things with this event as well
  55.         end
  56. --  elseif event == "SOME_EVENT" then
  57.     end
  58. end)
  59.  
  60. SLASH_XXX1 = "/xx"
  61. SlashCmdList.XXX = function()
  62.     LastBag = 1
  63.     LastSlot = 1
  64.     Remove = INVSLOT_FIRST_EQUIPPED
  65.     SaveToBags()
  66. end

Edit: I didn't notice Kanegasi had made changes before doing this...
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 05-25-22 at 10:39 AM. Reason: Previous C_Timer code was a bit iffy
  Reply With Quote
05-26-22, 02:14 AM   #4
Walkerbo
A Chromatic Dragonspawn
 
Walkerbo's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2010
Posts: 157
Hi Kanegasi and Fizzlemizz

Thanks for your answers.

Fizzlemizz, I can see the wait makes a lot of sense, it is something I should have picked up myself

I do have a couple of questions about your solutions.

You both used;
Lua Code:
  1. PutItemInBag(bag+19)
I dont understand where the 19 comes into it?

And Kanegasi you set up a table to record all placed items;
Lua Code:
  1. local ignore={[0]={},[1]={},[2]={},[3]={},[4]={},}
Is it necassary to record where items were placed, or is this just good practise?
__________________
"As someone once told me, frames are just special types of tables, and tables are special types of pointers."
Fizzlemizz
  Reply With Quote
05-26-22, 09:43 AM   #5
Fizzlemizz
I did that?
 
Fizzlemizz's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 1,500
Kanegasi mentioned that PutItemInBag requires a bag id. (InventorySlotId) not a bag number and these start at 20 (bag 1+19 = 20).

Using the table keeps track of where you put the last item instead of using the event method. Checking GetContainerItemID in a tight loop can return nil for a slot that has only just been filled in the previous loop(s) until the system catches up and sends the event which could cause a "Bag is full" message.
__________________
Fizzlemizz
Maintainer of Discord Unit Frames and Discord Art.
Author of FauxMazzle, FauxMazzleHUD and Move Pad Plus.

Last edited by Fizzlemizz : 05-26-22 at 10:44 AM.
  Reply With Quote
05-26-22, 01:40 PM   #6
Kanegasi
A Molten Giant
 
Kanegasi's Avatar
AddOn Author - Click to view addons
Join Date: Apr 2007
Posts: 615
Fizzlemizz, I left this thread open on my phone's browser just after your post, so I didn't catch your edits either lol.

Anyways, to expand on InventorySlotId: https://wowpedia.fandom.com/wiki/InventorySlotId
And PutItemInBag: https://wowpedia.fandom.com/wiki/API_PutItemInBag

Basically, your character's entire "inventory" is actually your equipped items, your equipped bags (where items are saved elsewhere), your 28 base bank slots, and then your equipped bank bags. On retail, this counts all the way to 86. 0 is the old unused ammo slot, 1 is your head, 2 is your neck, 19 is your tabard, 20 is the first bag next to your backback, 21-23 is the next three. I'm honestly not sure what 24-51 is, then 52-79 is your base bank, and finally 80-86 is your bank bags.

Also, Fizzlemizz nailed the table explanation. It's a temporary table that starts off blank every time you use this code and is a quick solution to track slots where your unequipped items get dropped into. The slots may actually not line up depending on how you have new items enter your bags, but it still works in the end because the loop will find the, say for example, four empty slots and the table will treat those spots filled in the eyes of this loop when it dumps four of your pieces in.

Last edited by Kanegasi : 05-26-22 at 01:45 PM.
  Reply With Quote
05-26-22, 04:30 PM   #7
Walkerbo
A Chromatic Dragonspawn
 
Walkerbo's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2010
Posts: 157
Hi Kanegasi and Fizzlemizz

Thanks for the further explainations, I do really appreciate your help.

You two absolutely rock

Cheers
__________________
"As someone once told me, frames are just special types of tables, and tables are special types of pointers."
Fizzlemizz
  Reply With Quote
05-26-22, 06:55 PM   #8
briskman3000
A Warpwood Thunder Caller
 
briskman3000's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2009
Posts: 98
Originally Posted by Kanegasi View Post
I'm honestly not sure what 24-51 is
If I had to guess, they probably have something to do with the old Keyring system. It was dynamically sized with up to 32 slots.

IIRC when the added the 4 extra backpack slots for having an authenticator, they repurposed they keyring system for those slots. Counting up the number of slots in spots 24 - 51 gives you 28, which would be the 28 unassigned numbers you see there.

I'm completely pulling this out of my ass and my be completely wrong, but it all makes sense to me.
__________________
My Addons: Convert Ratings Honor Track
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Unequip all items

Thread Tools
Display Modes

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