Merge pull request #8 from AssemblerManiac/master

manavortex [02-12-18 - 16:45]
Merge pull request #8 from AssemblerManiac/master

Count tracking solved
Filename
IIfA/IIfABackpack.lua
IIfA/IIfADataCollection.lua
IIfA/IIfAEvents.lua
diff --git a/IIfA/IIfABackpack.lua b/IIfA/IIfABackpack.lua
index 9134916..d9fb2da 100644
--- a/IIfA/IIfABackpack.lua
+++ b/IIfA/IIfABackpack.lua
@@ -104,15 +104,15 @@ end
 local function DoesInventoryMatchList(locationName, location)
 	local bagId 	= location.bagID
 	local filter 	= IIfA.InventoryListFilter
-
+
 	local function isHouse()
 		return IIfA:GetTrackingWithHouseNames()[locationName]
 	end
-
+
 	local function isOneOf(value, comp1, comp2, comp3, comp4, comp5, comp6)
-		return nil ~= value and (value == comp6) or (value == comp5) or (value == comp4) or (value == comp3) or (value == comp2) or value == comp1
+		return nil ~= value and (value == comp6) or (value == comp5) or (value == comp4) or (value == comp3) or (value == comp2) or value == comp1
 	end
-
+
 --	if locationName == "attributes" then return false end
 	if (filter == "All") then
 		return true
@@ -130,11 +130,11 @@ local function DoesInventoryMatchList(locationName, location)
 		return isOneOf(bagId, BAG_BANK, BAG_SUBSCRIBER_BANK, BAG_BACKPACK, BAG_WORN)

 	elseif(filter == "Bank and Current Character") then
-		return isOneOf(bagId, BAG_BANK, BAG_SUBSCRIBER_BANK, BAG_BACKPACK, BAG_WORN)
+		return isOneOf(bagId, BAG_BANK, BAG_SUBSCRIBER_BANK, BAG_BACKPACK, BAG_WORN)
 			and locationName == IIfA.currentCharacterId
-
+
 	elseif(filter == "Bank and other characters") then
-		return isOneOf(bagId, BAG_BANK, BAG_SUBSCRIBER_BANK, BAG_BACKPACK, BAG_WORN)
+		return isOneOf(bagId, BAG_BANK, BAG_SUBSCRIBER_BANK, BAG_BACKPACK, BAG_WORN)
 			and locationName ~= IIfA.currentCharacterId

 	elseif(filter == "Bank Only") then
@@ -142,16 +142,16 @@ local function DoesInventoryMatchList(locationName, location)

 	elseif(filter == "Craft Bag") then
 		return (bagId == BAG_VIRTUAL)
-
+
 	elseif(filter == "Housing Storage") then
-		return nil ~= GetCollectibleForHouseBankBag and GetCollectibleForHouseBankBag(bagId) > 0
-
+		return nil ~= GetCollectibleForHouseBankBag and GetCollectibleForHouseBankBag(bagId) > 0
+
 	elseif(filter == "All Houses") then
 		return IIfA.data.collectHouseData[bagId]
-
+
 	elseif(nil ~= IIfA:GetTrackingWithHouseNames()[filter]) then
 		return (bagId == IIfA:GetHouseIdFromName(filter))
-
+
 	else --Not a preset, must be a specific guildbank or character
 		if isOneOf(bagId, BAG_BACKPACK, BAG_WORN) then
 			-- it's a character name, convert to Id, check that against location Name in the dbv3 table
@@ -167,7 +167,7 @@ local function matchCurrentInventory(locationName)
 --	if locationName == "attributes" then return false end
 	local accountInventoryList = IIfA:GetAccountInventoryList()

-	for i, inventoryName in ipairs(accountInventoryList) do
+	for i, inventoryName in pairs(accountInventoryList) do
 		if inventoryName == locationName then return true end
 	end

@@ -189,7 +189,7 @@ local function getQualityDict()
 		qualityDictionary[getColoredString(ITEM_QUALITY_MAGIC,  "Magic")] 			= ITEM_QUALITY_MAGIC
 		qualityDictionary[getColoredString(ITEM_QUALITY_ARCANE, "Arcane")] 			= ITEM_QUALITY_ARCANE
 		qualityDictionary[getColoredString(ITEM_QUALITY_ARTIFACT, "Artifact")] 		= ITEM_QUALITY_ARTIFACT
-		qualityDictionary[getColoredString(ITEM_QUALITY_LEGENDARY, "Legendary")] 	= ITEM_QUALITY_LEGENDARY
+		qualityDictionary[getColoredString(ITEM_QUALITY_LEGENDARY, "Legendary")] 	= ITEM_QUALITY_LEGENDARY
 	end
 	return qualityDictionary
 end
@@ -201,7 +201,7 @@ local function matchFilter(itemName, itemLink)

 	local searchFilter = IIfA.searchFilter
 	-- 17-7-30 AM - moved lowercasing to when it's created, one less call to lowercase for every item
-
+
     local name = string.lower(itemName) or ""

 	-- text filter takes precedence
@@ -399,7 +399,7 @@ function IIfA:UpdateScrollDataLinesData()
 	IIFA_GUI_ListHolder.dataLines = dataLines
 	sort(IIFA_GUI_ListHolder.dataLines)
 	IIFA_GUI_ListHolder.dataOffset = 0
-
+
 end


@@ -463,9 +463,9 @@ function IIfA:UpdateInventoryScroll()
 end

 function IIfA:RefreshInventoryScroll()
-
+
 	-- p("RefreshInventoryScroll")
-
+
 	IIfA:UpdateScrollDataLinesData()
 	IIfA:UpdateInventoryScroll()
 end
@@ -564,7 +564,7 @@ function IIfA:GetCharacterList()
 	for i=1, GetNumCharacters() do
 		local charName, _, _, _, _, _, _, _ = GetCharacterInfo(i)
 		charName = charName:sub(1, charName:find("%^") - 1)
-		if (nil == charInventories[charName]) then
+		if (nil == charInventories[charName]) then
 			table.insert(charInventories, charName)
 		end
 	end
@@ -573,15 +573,15 @@ end

 function IIfA:GetAccountInventoryList()
 	local accountInventories = IIfA.dropdownBankNames
-
+

 -- get character names, will present in same order as character selection screen
 	for idx, charName in ipairs(IIfA:GetCharacterList()) do
-		if (nil == accountInventories[charName]) then
+		if (nil == accountInventories[charName]) then
 			table.insert(accountInventories, charName)
 		end
 	end
-
+
 -- banks are same as toons, same order as player normally sees them
 	if IIfA.data.bCollectGuildBankData then
 		for i = 1, GetNumGuilds() do
@@ -592,20 +592,20 @@ function IIfA:GetAccountInventoryList()
 			if IIfA.data.guildBanks == nil then
 				IIfA.data.guildBanks = {}
 			end
-
+
 			if IIfA.data.guildBanks[guildName] ~= nil then
 				table.insert(accountInventories, guildName)
 			end
 		end
 	end
-
+
 	if IIfA.data.b_collectHouses then
 		table.insert(accountInventories, "All Houses")
 		for idx, houseName in pairs(IIfA:GetTrackedHouseNames()) do
 			table.insert(accountInventories, houseName)
 		end
 	end
-
+
 	return accountInventories
 end

@@ -662,27 +662,27 @@ function IIfA:QueryAccountInventory(itemLink)
 				locationName = IIfA.CharIdToName[locationName]
 			end
 			if locationName ~= nil then
-
+
 				for x, QILocation in pairs(queryItem.locations) do
 					if (QILocation.name == locationName)then
 						QILocation.itemsFound = QILocation.itemsFound + location.itemCount
 						AlreadySavedLoc = true
 					end
 				end
-
+
 				if nil ~= location.itemCount then
 					if (not AlreadySavedLoc) and (location.itemCount > 0) then
 						newLocation = {}
 						newLocation.name = locationName
-
+
 						if locationName == location.bagID then -- location is a collectible
 							newLocation.name = GetCollectibleNickname(locationName)
 							if newLocation.name == "" then newLocation.name = GetCollectibleName(locationName) end
 						end
-
+
 						newLocation.itemsFound = location.itemCount
 						newLocation.worn = location.bagID == BAG_WORN
-
+
 						table.insert(queryItem.locations, newLocation)
 					end
 				end
@@ -753,7 +753,7 @@ function IIfA:SetupBackpack()
 		table.insert(validChoices, getColoredString(ITEM_QUALITY_ARTIFACT, "Artifact"))
 		table.insert(validChoices, getColoredString(ITEM_QUALITY_LEGENDARY, "Legendary"))

-		local comboBox = IIFA_GUI_Header_Dropdown_Quality.comboBox
+		local comboBox = IIFA_GUI_Header_Dropdown_Quality.comboBox

 		function OnItemSelect(_, choiceText, choice)
 			IIfA:SetInventoryListFilterQuality(getQualityDict()[choiceText])
@@ -763,7 +763,7 @@ function IIfA:SetupBackpack()
 		comboBox:SetSortsItems(false)

 		for i = 1, #validChoices do
-			entry = comboBox:CreateItemEntry(validChoices[i], OnItemSelect)
+			entry = comboBox:CreateItemEntry(validChoices[i], OnItemSelect)
 			comboBox:AddItem(entry)
 			if getQualityDict()[validChoices[i]] == IIfA:GetInventoryListFilterQuality() then
 				comboBox:SetSelectedItem(validChoices[i])
@@ -776,7 +776,7 @@ function IIfA:SetupBackpack()
 	IIfA.InventoryListFilter = IIfA.data.in2DefaultInventoryFrameView
 	IIfA:CreateInventoryScroll()
 	createInventoryDropdown()
-	createInventoryDropdownQuality()
+	createInventoryDropdownQuality()
 	IIfA:GuiOnSort(true)
 end

diff --git a/IIfA/IIfADataCollection.lua b/IIfA/IIfADataCollection.lua
index f8b90e8..65b8084 100644
--- a/IIfA/IIfADataCollection.lua
+++ b/IIfA/IIfADataCollection.lua
@@ -2,7 +2,7 @@ local IIfA 			= IIfA
 local EMPTY_STRING 	= ""

 local task 			= LibStub("LibAsync"):Create("IIfA_DataCollection")
-IIfA.task			= task
+IIfA.task			= task

 local function p(...) IIfA:DebugOut(...) end

@@ -36,14 +36,14 @@ function IIfA:DeleteGuildData(name)
 	end
 end

-function IIfA:CollectGuildBank()
+function IIfA:CollectGuildBank()

 	-- add roomba support
-	if Roomba and Roomba.WorkInProgress and Roomba.WorkInProgress() then
+	if Roomba and Roomba.WorkInProgress and Roomba.WorkInProgress() then
 		CALLBACK_MANAGER:FireCallbacks("Roomba-EndStacking", function() IIfA:CollectGuildBank() end)
 		return
 	end
-
+
 	local curGB = GetSelectedGuildBankId()

 	if not IIfA.data.bCollectGuildBankData or curGB == nil then
@@ -68,7 +68,7 @@ function IIfA:CollectGuildBank()
 		IIfA.data.guildBanks[curGuild] = {}
 		IIfA.data.guildBanks[curGuild].bCollectData = true		-- default to true just so it's here and ok
 	end
-
+
 	-- call with libAsync to avoid lags
 	task:Call(function()
 		local guildData = IIfA.data.guildBanks[curGuild]
@@ -88,19 +88,19 @@ end

 local function scanBags()
 	local playerName = GetUnitName('player')
-
+
 	IIfA.data.accountCharacters 			= IIfA.data.accountCharacters or {}
 	IIfA.data.accountCharacters[playerName] = IIfA.data.accountCharacters[playerName] or {}
-
+
 	IIfA:ClearLocationData(IIfA.currentCharacterId)
-
-	if not IIfA:IsCharacterEquipIgnored(playerName) then
+
+	if not IIfA:IsCharacterEquipIgnored(playerName) then
 		-- call with libAsync to avoid lags
 		task:Call(function()
 			grabBagContent(BAG_WORN)
 		end)
-	end
-	if not IIfA:IsCharacterInventoryIgnored(playerName) then
+	end
+	if not IIfA:IsCharacterInventoryIgnored(playerName) then
 		-- call with libAsync to avoid lags
 		task:Call(function()
 			grabBagContent(BAG_BACKPACK)
@@ -117,11 +117,11 @@ local function tryScanHouseBank()
 	local bagId = GetBankingBag()
 	if not bagId then return end
 	local collectibleId = GetCollectibleForHouseBankBag(bagId)
-
+
 	if IsCollectibleUnlocked(collectibleId) then
-
+
 		IIfA:DebugOut(zo_strformat("tryScanHouseBank(<<1>>)", collectibleId))
-
+
 		local collectibleName = GetCollectibleNickname(collectibleId)
 		if collectibleName == EMPTY_STRING then collectibleName = GetCollectibleName(collectibleId) end
 		-- call with libAsync to avoid lags
@@ -131,7 +131,7 @@ local function tryScanHouseBank()
 			grabBagContent(bagId, true)
 		end)
 	end
-
+
 	return true
 end

@@ -144,9 +144,9 @@ function IIfA:ScanBank()
 	end):Then(function()
 		grabBagContent(BAG_BANK)
 	end)
-
+
 	local slotId = nil
-	if HasCraftBagAccess() then
+	if HasCraftBagAccess() then
 		task:Call(function()
 			grabBagContent(BAG_SUBSCRIBER_BANK)
 		end):Then(function()
@@ -159,30 +159,22 @@ function IIfA:ScanBank()
 			end
 		end)
 	end
-
-end

-function IIfA:UpdateBSI(bagId, slotId, locationId)
-	if locationId then
-		IIfA:MakeBSI()
-	elseif  nil ~= bagId and  nil ~= slotId and nil ~= IIfA.BagSlotInfo[bagId] then
-		IIfA.BagSlotInfo[bagId][slotId] = GetItemLink(bagId, slotId)
-	end
 end


 -- only grabs the content of bagpack and worn on the first login - hence we set the function to insta-return below.
 function IIfA:OnFirstInventoryOpen()
-
+
 	if IIfA.BagsScanned then return end
 	IIfA.BagsScanned = true
-
+
 	scanBags()
 	-- call with libAsync to avoid lags
 	task:Call(function()
-
+
 	end):Then(function()
-		IIfA:ScanBank()
+		IIfA:ScanBank()
 	end)
 end

@@ -299,10 +291,10 @@ Data collection notes:
 --]]

 function IIfA:RescanHouse(houseCollectibleId)
-
+
 	houseCollectibleId = houseCollectibleId or GetCollectibleIdForHouse(GetCurrentZoneHouseId())
 	if not houseCollectibleId then return end
-
+
 	if not IIfA:GetTrackedBags()[houseCollectibleId] then return end

 	--- stuff them all into an array
@@ -312,16 +304,16 @@ function IIfA:RescanHouse(houseCollectibleId)
 			furnitureId = GetNextPlacedHousingFurnitureId(furnitureId)
 			if(not furnitureId) then return ret end
 			local itemLink = GetPlacedFurnitureLink(furnitureId, LINK_STYLE_BRACKETS)
-			if not ret[itemLink] then
+			if not ret[itemLink] then
 				ret[itemLink] = 1
 			else
 				ret[itemLink] = ret[itemLink] +1
 			end
-		end
+		end
 	end
-
+
 	-- call with libAsync to avoid lags
-	task:Call(function()
+	task:Call(function()
 		-- clear and re-create, faster than conditionally updating
 		IIfA:ClearLocationData(houseCollectibleId)
 	end):Then(function()
@@ -329,17 +321,17 @@ function IIfA:RescanHouse(houseCollectibleId)
 			IIfA:AddFurnitureItem(itemLink, itemCount, houseCollectibleId, true)
 		end
 	end)
-
+
 end

 -- try to read item link from bag/slot - if that's an empty string, we try to read it from BSI
 local function getItemLink(bagId, slotId)
 	if nil == bagId or nil == slotId then return end
 	local itemLink = GetItemLink(bagId, slotId, LINK_STYLE_BRACKETS)
-	if itemLink ~= "" then
+	if itemLink ~= "" then
 		-- got an item link, save it to the BSI for reverse lookups
 		IIfA:SaveBagSlotIndex(bagId, slotId, itemLink)
-		return itemLink
+		return itemLink
 	end
 	if nil == IIfA.BagSlotInfo[bagId] then return end
 	return IIfA.BagSlotInfo[bagId][slotId]
@@ -355,7 +347,7 @@ end

 -- returns the item's db key, we only save under the item link if we need to save level information etc, else we use the ID
 local function getItemKey(itemLink, usedInCraftingType, itemType)
-
+
 	-- crafting materials get saved by ID
 	if usedInCraftingType ~= CRAFTING_TYPE_INVALID and
 	   itemType ~= ITEMTYPE_GLYPH_ARMOR and
@@ -363,7 +355,7 @@ local function getItemKey(itemLink, usedInCraftingType, itemType)
 	   itemType ~= ITEMTYPE_GLYPH_WEAPON then
 	   return IIfA:GetItemID(itemLink)
 	end
-	-- raw materials
+	-- raw materials
 	itemType = itemType or GetItemLinkItemType(itemLink)
 	if  itemType == ITEMTYPE_STYLE_MATERIAL or
 		itemType == ITEMTYPE_ARMOR_TRAIT or
@@ -378,20 +370,21 @@ local function getItemKey(itemLink, usedInCraftingType, itemType)
 end

 local function getItemCount(bagId, slotId, itemLink)
-
+
 	local stackCountBackpack, stackCountBank, stackCountCraftBag, itemCount
 	-- first try to read item count from bag/slot
-	_, itemCount =  GetItemInfo(bagId, slotId)
+	_, itemCount =  GetItemInfo(bagId, slotId)
 	if 0 < itemCount then return itemCount end
-
+
 	-- try to find it by item link - only works for bag_backpack / bank / virtual
-	stackCountBackpack, stackCountBank, stackCountCraftBag = GetItemLinkStacks(itemLink)
+	stackCountBackpack, stackCountBank, stackCountCraftBag = GetItemLinkStacks(itemLink)
 	if 		bagId == BAG_BACKPACK 	and 0 < stackCountBackpack 	then return stackCountBackpack
 	elseif 	bagId == BAG_BANK 		and 0 < stackCountBank 		then return stackCountBank
-	elseif 	bagId == BAG_VIRTUAL 	and 0 < stackCountCraftBag 	then return  stackCountCraftBag end
-
-	-- return 1 if no slot size was found - in that case it's an equip item
-	return 1
+	elseif 	bagId == BAG_VIRTUAL 	and 0 < stackCountCraftBag 	then return stackCountCraftBag
+	elseif  bagId == BAG_WORN then return itemCount end
+
+	-- return 0 if no item count was found, possibly an out of date index to a house container that no longer exists
+	return 0
 end

 local function getLocation(location, bagId)
@@ -422,41 +415,41 @@ end

 function IIfA:EvalBagItem(bagId, slotId, fromXfer, itemCount, itemLink, itemName, locationID)
 	if not IIfA.trackedBags[bagId] then return end
-
+
 	IIfA.database = IIfA.database or {}
 	local DBv3 = IIfA.database

 	-- item link is either passed as arg or we need to read it from the BSI
 	itemLink = itemLink or getItemLink(bagId, slotId)
-
+
 	-- return if we don't have any item to track
 	if nil == itemLink or #itemLink == 0 then return end
-
+
 	-- item nams is either passed or we get it from bag/slot or item link
-	itemName = itemName or getItemName(bagId, slotId, itemLink) or EMPTY_STRING
-
+	itemName = itemName or getItemName(bagId, slotId, itemLink) or EMPTY_STRING
+
 	-- item count is either passed or we have to get it from bag/slot ID or item link
-	itemCount = itemCount or getItemCount(bagId, slotId, itemLink)
-
+	itemCount = itemCount or getItemCount(bagId, slotId, itemLink)
+
 	-- get item key from crafting type
 	local usedInCraftingType, itemType = GetItemCraftingInfo(bagId, slotId)
-
-
+
+
 	local qty, itemQuality
 	_, qty, _, _, _, _, _, itemQuality = GetItemInfo(bagId, slotId)
-
-	if 0 == qty and itemLink then
+
+	if 0 == qty and itemLink then
 		itemQuality			= GetItemLinkQuality(itemLink)
 		usedInCraftingType 	= GetItemLinkCraftingSkillType(itemLink)
 		itemType 			= GetItemLinkItemType(itemLink)
 	end
-
+
 	itemKey = getItemKey(itemLink, usedInCraftingType, itemType)
-
+
 	itemFilterType = GetItemFilterTypeInfo(bagId, slotId) or 0
 	DBitem = DBv3[itemKey]
 	location = locationID or getLocation(location, bagId) or EMPTY_STRING
-
+
 	if(DBitem) then
 		DBitemlocation = DBitem.locations[location]
 		if DBitemlocation then
@@ -490,11 +483,11 @@ function IIfA:EvalBagItem(bagId, slotId, fromXfer, itemCount, itemLink, itemName
 	end

 	return DBv3[itemKey], itemKey
-
+
 end

 function IIfA:ValidateItemCounts(bagID, slotId, dbItem, itemKey, itemLinkOverride, override)
-
+
 	local itemCount
 	local itemLink, itemLinkCheck
 	if zo_strlen(itemKey) < 10 then
@@ -505,32 +498,30 @@ function IIfA:ValidateItemCounts(bagID, slotId, dbItem, itemKey, itemLinkOverrid
 	IIfA:DebugOut(zo_strformat("ValidateItemCounts: <<1>> in bag <<2>>/<<3>>", itemLink, bagID, slotId))

 	for locName, data in pairs(dbItem.locations) do
-		if (data.bagID == BAG_GUILDBANK and locName == GetGuildName(GetSelectedGuildBankId())) or
+		if (data.bagID == BAG_GUILDBANK and locName == GetGuildName(GetSelectedGuildBankId())) or
 		-- we're looking at the right guild bank
 			data.bagID == BAG_VIRTUAL or
 			data.bagID == BAG_BANK or
-			data.bagID == BAG_SUBSCRIBER_BANK or
+			data.bagID == BAG_SUBSCRIBER_BANK or
 			nil ~= GetCollectibleForHouseBankBag and nil ~= GetCollectibleForHouseBankBag(data.bagID) or -- is housing bank, manaeeee
 		   ((data.bagID == BAG_BACKPACK or data.bagID == BAG_WORN) and locName == GetCurrentCharacterId()) then
-
+
 			itemLinkCheck = GetItemLink(data.bagID, data.bagSlot, LINK_STYLE_BRACKETS)
 			if itemLinkCheck == nil then
 				itemLinkCheck = (override and itemLinkOverride) or EMPTY_STRING
 			end
 			if itemLinkCheck ~= itemLink then
 				if bagID ~= data.bagID and slotId ~= data.bagSlot then
-				-- it's no longer the same item, or it's not there at all
+				-- it's no longer the same item, or it's not there at all
 					IIfA.database[itemKey].locations[locName] = nil
 				end
 			-- item link is valid, just make sure we have our count right
 			elseif bagId == data.bagID then
 					_, data.itemCount = GetItemInfo(bagID, slotId)
-
-			end
+
+			end
 		end
-	end
-	-- mana: Do we need this here? It should already happen in Eval. Need to check when brain working.
-	IIfA:UpdateBSI(bagID, slotId)
+	end
 end


@@ -542,9 +533,10 @@ function IIfA:CollectAll()
 	local location = EMPTY_STRING
 	local BagList = IIfA:GetTrackedBags() -- 20.1. mana: Iterating over a list now

-	for bagId, tracked in pairs(BagList) do
+
+	for bagId, tracked in pairs(BagList) do		-- do NOT use ipairs, it's non-linear list (holes in the # sequence)
 		-- call with libAsync to avoid lags
-		task:Call(function()
+		task:Call(function()
 			bagItems = GetBagSize(bagId)
 			if(bagId == BAG_WORN)then	--location for BAG_BACKPACK and BAG_WORN is the same so only reset once
 				IIfA:ClearLocationData(IIfA.currentCharacterId)
@@ -573,7 +565,7 @@ function IIfA:CollectAll()
 					end
 				end
 			end
-
+
 		end)
 	end

@@ -581,16 +573,12 @@ function IIfA:CollectAll()
 	IIfA:ClearUnowned()
 end

-function IIfA:TrySaveBagInfo()
-
-end

 function IIfA:ClearUnowned()
 -- 2015-3-7 Assembler Maniac - new code added to go through full inventory list, remove any un-owned items
-	local DBv3 = IIfA.database
 	local n, ItemLink, DBItem
 	local ItemOwner, ItemData
-	for ItemLink, DBItem in pairs(DBv3) do
+	for ItemLink, DBItem in pairs(IIfA.database) do
 		n = 0
 		for ItemOwner, ItemData in pairs(DBItem.locations) do
 			n = n + 1
@@ -598,16 +586,18 @@ function IIfA:ClearUnowned()
 				if ItemData.bagID == BAG_BACKPACK or ItemData.bagID == BAG_WORN then
 					if IIfA.CharIdToName[ItemOwner] == nil then
 						DBItem[ItemOwner] = nil
+						n = n - 1
 	  				end
 				elseif ItemData.bagID == BAG_GUILDBANK then
 					if IIfA.data.guildBanks[ItemOwner] == nil then
 						DBItem[ItemOwner] = nil
+						n = n - 1
 					end
 				end
 			end
 		end
 		if (n == 0) then
-			DBv3[ItemLink] = nil
+			IIfA.database[ItemLink] = nil
 		end
 	end
 -- 2015-3-7 end of addition
@@ -621,9 +611,9 @@ function IIfA:ClearLocationData(location)
 	local itemName, itemData

 	if(DBv3)then
-
+
 		IIfA:DebugOut(zo_strformat("IIfA:ClearLocationData(<<1>>)", location))
-
+
 		for itemName, itemData in pairs(DBv3) do
 			itemLocation = itemData.locations[location]
 			if (itemLocation) then
diff --git a/IIfA/IIfAEvents.lua b/IIfA/IIfAEvents.lua
index 0aa3ec9..6f7e489 100644
--- a/IIfA/IIfAEvents.lua
+++ b/IIfA/IIfAEvents.lua
@@ -15,7 +15,7 @@ end

 -- used by an event function
 function IIfA:InventorySlotUpdate(eventCode, bagId, slotId, isNewItem, itemSoundCategory, inventoryUpdateReason, qty)
-
+
 	if isNewItem then
 		isNewItem = "True"
 	else
@@ -23,14 +23,20 @@ function IIfA:InventorySlotUpdate(eventCode, bagId, slotId, isNewItem, itemSound
 	end

 	local itemLink = GetItemLink(bagId, slotId, LINK_STYLE_BRACKETS) or ""
-	if #itemLink == 0 then itemLink = (nil ~= IIfA.BagSlotInfo[bagId] and IIfA.BagSlotInfo[bagId][slotId]) end
-
-	IIfA:DebugOut("Inv Slot Upd <<1>> - bag/slot <<2>>/<<3>> x<<4>>, new: <<6>>",
+	if #itemLink == 0 and IIfA.BagSlotInfo[bagId] ~= nil and IIfA.BagSlotInfo[bagId][slotId] then
+		itemLink = IIfA.BagSlotInfo[bagId][slotId]
+	elseif #itemLink > 0 and IIfA.BagSlotInfo[bagId] == nil then
+		IIfA.BagSlotInfo[bagId][slotId] = itemLink
+	elseif #itemLink > 0 and IIfA.BagSlotInfo[bagId][slotId] == nil then
+		IIfA.BagSlotInfo[bagId][slotId] = itemLink
+	end
+
+	IIfA:DebugOut("Inv Slot Upd <<1>> - bag/slot <<2>>/<<3>> x<<4>>, new: <<6>>",
 		itemLink, bagId, slotId, qty, inventoryUpdateReason, tostring(isNewItem))
-
+
 	-- (bagId, slotNum, fromXfer, itemCount, itemLink, itemName, locationID)
 	local dbItem, itemKey = self:EvalBagItem(bagId, slotId, not isNewItem, qty, itemLink)
-
+
 end


@@ -40,28 +46,29 @@ end

 local function IIfA_ScanHouse(eventCode, oldMode, newMode)
 	if newMode == "showing" or newMode == "shown" then return end
-	-- are we listening?
+	-- are we listening?
 	if not IIfA:GetCollectingHouseData() then return end
 	local collectibleId = GetCollectibleIdForHouse(GetCurrentZoneHouseId())
 	IIfA:DebugOut(zo_strformat("Housing editor mode is now <<2>> - calling IIfA:RescanHouse(<<1>>)", collectibleId, newMode))
 	IIfA:RescanHouse(collectibleId)
 end

-local function IIfA_HouseEntered(eventCode)
+local function IIfA_HouseEntered(eventCode)
 	if not IsOwnerOfCurrentHouse() then return end
-
-	-- are we listening?
+
+	-- are we listening?
 	if not IIfA:GetCollectingHouseData() then return end
-
-	-- is the house registered?
-	local houseCollectibleId = GetCollectibleIdForHouse(GetCurrentZoneHouseId())
-
+
+	-- is the house registered?
+	local houseCollectibleId = GetCollectibleIdForHouse(GetCurrentZoneHouseId())
+
 	if nil == IIfA.data.collectHouseData[houseCollectibleId] then
-		IIfA:SetTrackingForHouse(houseCollectibleId, true)
+		IIfA:SetTrackingForHouse(houseCollectibleId, true)
 	end
-
+
 	IIfA:RescanHouse(houseCollectibleId)
 end
+
 local function IIfA_EventProc(...)
 	--d(...)
 	local l = {...}
@@ -128,8 +135,8 @@ function IIfA:RegisterForEvents()
 -- not helpful, no link at all on this callback
 --	SHARED_INVENTORY:RegisterCallback("SlotRemoved", IIfA_EventDump)
 --	SHARED_INVENTORY:RegisterCallback("SingleSlotInventoryUpdate", IIfA_EventDump)
-
-
+
+
 	-- Events for data collection
 	em:RegisterForEvent("IIFA_ALPUSH", 		EVENT_ACTION_LAYER_PUSHED, 	function() IIfA:ActionLayerInventoryUpdate() end)
 	em:RegisterForEvent("IIFA_BANK_OPEN",	EVENT_OPEN_BANK, 			function() IIfA:ScanBank() end)
@@ -149,13 +156,13 @@ function IIfA:RegisterForEvents()
 	em:RegisterForEvent("IIFA_GUILDBANK_ITEM_REMOVED", 	EVENT_GUILD_BANK_ITEM_REMOVED, 	function(...) IIfA:GuildBankAddRemove(...) end)

 	-- Housing
-	em:RegisterForEvent("IIFA_HOUSING_PLAYER_INFO_CHANGED", EVENT_PLAYER_ACTIVATED, 			IIfA_HouseEntered)
+	em:RegisterForEvent("IIFA_HOUSING_PLAYER_INFO_CHANGED", EVENT_PLAYER_ACTIVATED, 			IIfA_HouseEntered)
 	em:RegisterForEvent("IIfA_HOUSE_MANAGER_MODE_CHANGED", 	EVENT_HOUSING_EDITOR_MODE_CHANGED, 	IIfA_ScanHouse)

 	em:RegisterForEvent("IIFA_GuildJoin",  EVENT_GUILD_SELF_JOINED_GUILD, 	function() IIfA:CreateOptionsMenu() end)
 	em:RegisterForEvent("IIFA_GuildLeave", EVENT_GUILD_SELF_LEFT_GUILD, 	function() IIfA:CreateOptionsMenu() end)

-	--    ZO_QuickSlot:RegisterForEvent(EVENT_ABILITY_COOLDOWN_UPDATED, IIfA_EventDump)
+	--    ZO_QuickSlot:RegisterForEvent(EVENT_ABILITY_COOLDOWN_UPDATED, IIfA_EventDump)
 	ZO_PreHook('ZO_InventorySlot_ShowContextMenu', function(rowControl) IIfA:ProcessRightClick(rowControl) end)
 end