Thread Tools Display Modes
07-08-10, 06:56 AM   #1
Haleth
This Space For Rent
 
Haleth's Avatar
Featured
Join Date: Sep 2008
Posts: 1,173
Number of used bag slots?

Simple question. Is there any way to get the number of used bag slots (the number of bags you are actually using)? I've been looking for this for ages but I can't find it. Currently I have to change this number manually for every char I have and it's a bit annoying.
  Reply With Quote
07-08-10, 07:19 AM   #2
xConStruct
A Chromatic Dragonspawn
 
xConStruct's Avatar
AddOn Author - Click to view addons
Join Date: May 2008
Posts: 199
Hmm, maybe checking against bag size, like:
Code:
local function getBagCount()
    for i=1, 4 do
        if GetContainerNumSlots(i) == 0 then
            return i-1
        end
    end
    return i
end
Just thinking if it is possible to have a free slot between two bags - then this method wouldn't work, but then you'd need to fetch their actual id's and not just the count.

Where do you need it?
__________________
« Website | GitHub »

Oh hai!
  Reply With Quote
07-08-10, 08:34 AM   #3
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
If you want to include the backpack, you'll have to do
Code:
for i = 0, 4 do
Then for each bag, use GetContainerNumSlots(i) - GetContainerFreeSlots(i)
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
07-08-10, 08:55 AM   #4
Haleth
This Space For Rent
 
Haleth's Avatar
Featured
Join Date: Sep 2008
Posts: 1,173
Well I'm trying to define 'NUMBAGS' as the number of bag slots, meaning if NUMBAGS = 1 then I only have the default bagpack, if NUMBAGS = 5 then I have the maximum amount of bags possible.

I've tried what you both said and I came up with this.

Code:
if GetContainerNumSlots(4) == 0 then
	if GetContainerNumSlots(3) == 0 then
		if GetContainerNumSlots(2) == 0 then
			if GetContainerNumSlots(1) == 0 then
				NUMBAGS = 1
			else
				NUMBAGS = 2
			end
		else
			NUMBAGS = 3
		end
	else
		NUMBAGS = 4
	end
else
	NUMBAGS = 5
end
Would this work out properly? It seems to work on one of my chars with the maximum amount of bags, as well as on a char with just the default bag.

Edit: It doesn't seem to work all the time. Strange. When I use it after login, it'll always return 1, when I use it after a reload it works fine. Maybe I need to delay it.

Edit 2: Added a login check now and it seems to work! .. most of the time.

Edit 3: It doesn't work when I log out, switch chars and log back in. It does work when I log out and log back in on the same char... This is so annoying.

Last edited by Haleth : 07-08-10 at 09:20 AM.
  Reply With Quote
07-08-10, 09:37 AM   #5
hairy_palms
A Fallenroot Satyr
AddOn Author - Click to view addons
Join Date: Feb 2010
Posts: 25
just one question. are you firing it from a PLAYER_ENTERING_WORLD or PLAYER_LOGIN event?
  Reply With Quote
07-08-10, 09:38 AM   #6
Haleth
This Space For Rent
 
Haleth's Avatar
Featured
Join Date: Sep 2008
Posts: 1,173
Both actually, to make sure.

Code:
function CheckSlots()
if GetContainerNumSlots(4) == 0 then
	if GetContainerNumSlots(3) == 0 then
		if GetContainerNumSlots(2) == 0 then
			if GetContainerNumSlots(1) == 0 then
				NUMBAGS = 1
			else
				NUMBAGS = 2
			end
		else
			NUMBAGS = 3
		end
	else
		NUMBAGS = 4
	end
else
	NUMBAGS = 5
end
end

local f = CreateFrame("Frame")
f:SetScript("OnEvent", CheckSlots)
f:RegisterEvent("PLAYER_LOGIN")
f:RegisterEvent("PLAYER_ENTERING_WORLD")

CheckSlots()
  Reply With Quote
07-08-10, 10:05 AM   #7
xConStruct
A Chromatic Dragonspawn
 
xConStruct's Avatar
AddOn Author - Click to view addons
Join Date: May 2008
Posts: 199
On login (I don't know in which order), the bags will be loaded separately. They fire a BAG_UPDATE with their bagID as arg1. You probably want to register for this one.

My for-loop should do the same thing you posted but without the nested if's.

local count = getBagCount() -- returns 0 for only backpack.
local count = getBagCount() -- returns 4 for all bags.

If you want to include the backpack in the count, just add a + 1 for each id. Since the backpack is available every time, we don't need to check for it.
__________________
« Website | GitHub »

Oh hai!
  Reply With Quote
07-08-10, 10:20 AM   #8
Haleth
This Space For Rent
 
Haleth's Avatar
Featured
Join Date: Sep 2008
Posts: 1,173
Registering the BAG_UPDATE did indeed do the trick.

Thanks a lot.

Edit: No, it still messes up sometime... I really don't get it now.

Last edited by Haleth : 07-08-10 at 10:28 AM.
  Reply With Quote
07-08-10, 10:47 AM   #9
Xrystal
nUI Maintainer
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 5,892
BAG_UPDATE seems to fire randomly and alot so hard to say when the best time to use it.
Fired when a bags inventory changes. Bag zero, the sixteen slot default backpack, may not fire on login. Upon login (or reloading the console) this event fires even for bank bags. When moving an item in your inventory, this fires multiple times: once each for the source and destination bag. If the bag involved is the default backpack, this event will also fire with a container ID of "-2" (twice if you are moving the item inside the same bag).
If the BAG_UPDATE event doesn't fire for a bag the respective functions won't work for it.
As of 3.0.3, immediately after a PLAYER_ENTERING_WORLD event (initial login or zone change through an instance, ie. any time you see a loading screen), several events of BAG_UPDATE are fired, one for each bag slot you have purchased. All bag data is available during the PLAYER_ENTERING_WORLD event, but this function returns 0 for bags that have not had the BAG_UPDATE function called. This is most likely due to the UI resetting its internal cache sometime between the PLAYER_ENTERING_WORLD event and the first BAG_UPDATE event.
However these seem to be the functions
bagName = GetBagName(bagID) - http://www.wowwiki.com/API_GetBagName
numberOfSlots = GetContainerNumSlots(bagID) - http://www.wowwiki.com/API_GetContainerNumSlots
numberOfFreeSlots, BagType = GetContainerNumFreeSlots(bagID) - http://www.wowwiki.com/API_GetContainerNumFreeSlots

Also bear in mind that VARIABLES_LOADED is the blizz data loading event and sometimes fires after PLAYER_ENTERING_WORLD and may be the event you want to use as a final check for bags in use.

Until 3.0, VARIABLES_LOADED used to fire upon completion of the addon loading process; since 3.0, it is fired in response to CVars, Keybindings and other associated "Blizzard" variables being loaded, and may therefore be delayed until after PLAYER_ENTERING_WORLD. The event may still be useful to override positioning data stored in layout-cache.txt
Perhaps something along the lines of :

Code:
bag_update = {}
bags_in_use = 0
missing_bags = 0
if event == BAG_UPDATE then
   bag_update[arg1] = true
elseif event == VARIABLES_LOADED then
  bags_in_use = 0
  missing_bags = 0
  for i = 0,4 do
    if ( bag_update[i] ) then
      bags_in_use = bags_in_use + 1
    else
     missing_bags = missing_bags + 1
    end
  end
end
This code is untested but in theory may work. Of course all depending on whether all the bag updates trigger before the blizz variables are loaded. Of course BAG_UPDATE triggers everytime the bags are updated and not just at start time so perhaps turn off bagupdate event watching once the blizz variables have loaded once you see that they only get called when the bags actually get updated by yourself.
__________________
  Reply With Quote
07-08-10, 11:21 AM   #10
Haleth
This Space For Rent
 
Haleth's Avatar
Featured
Join Date: Sep 2008
Posts: 1,173
Alright, with that extra check everything seems to work now. I've added a simple check for the bank too and it all seems to be going nice and smooth, but I'll let you know if it still messes up.

This is what it now looks like:

Code:
function CheckSlots()
	if GetContainerNumSlots(4) == 0 then
		if GetContainerNumSlots(3) == 0 then
			if GetContainerNumSlots(2) == 0 then
				if GetContainerNumSlots(1) == 0 then
					NUMBAGS = 1
				else
					NUMBAGS = 2
				end
			else
				NUMBAGS = 3
			end
		else
			NUMBAGS = 4
		end
	else
		NUMBAGS = 5
	end
end

function CheckBankSlots()
	NUMBANKBAGS = GetNumBankSlots() + 1
end

local f = CreateFrame("Frame")
f:SetScript("OnEvent", CheckSlots)
f:RegisterEvent("PLAYER_LOGIN")
f:RegisterEvent("PLAYER_ENTERING_WORLD")
f:RegisterEvent("BAG_UPDATE")
f:RegisterEvent("VARIABLES_LOADED")

local g = CreateFrame("Frame")
g:SetScript("OnEvent", CheckBankSlots)
g:RegisterEvent("PLAYER_LOGIN")
g:RegisterEvent("PLAYER_ENTERING_WORLD")
g:RegisterEvent("BAG_UPDATE")
g:RegisterEvent("VARIABLES_LOADED")

CheckSlots()
Going to do some cleaning up when I see that everything works fine after a while of using it. I don't really need the two frames either.
  Reply With Quote
07-08-10, 01:31 PM   #11
hairy_palms
A Fallenroot Satyr
AddOn Author - Click to view addons
Join Date: Feb 2010
Posts: 25
way to stop it running every single time u update the bags is something like

Code:
if event == "BAG_UPDATE" then
		yourframename:UnRegisterEvent("BAG_UPDATE")
	end
at the end of the loop
  Reply With Quote
07-08-10, 04:32 PM   #12
Vrul
A Scalebane Royal Guard
 
Vrul's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2007
Posts: 404
This is the function I use for that info:
Code:
--[[-----------------------------------------------------------------------------
Find out what the current bag situation is.

ignoreBank	t/f		- Ignore bank bags if true

Returns:
numSlots	#		- Number of bag slots
numEquiped	#		- Number of bag slots that have bags in them
numOpen		#		- Number of bags currently open
-------------------------------------------------------------------------------]]
local function GetNumBags(ignoreBank)
	local numEquiped, numSlots = 0, NUM_BAG_SLOTS + (not ignoreBank and BankFrame:IsShown() and NUM_BANKBAGSLOTS or 0)
	for i = 0, numSlots do
		if GetContainerNumSlots(i) > 0 then
			numEquiped = numEquiped + 1
		end
	end
	return numSlots + 1, numEquiped, #ContainerFrame1.bags - (IsBagOpen(KEYRING_CONTAINER) and 1 or 0)
end

Last edited by Vrul : 07-08-10 at 04:38 PM.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Number of used bag slots?

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