You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
4.5 KiB
130 lines
4.5 KiB
-- ------------------------------------------------------------------------------ --
|
|
-- TradeSkillMaster --
|
|
-- https://tradeskillmaster.com --
|
|
-- All Rights Reserved - Detailed license information included with addon. --
|
|
-- ------------------------------------------------------------------------------ --
|
|
|
|
local TSM = select(2, ...) ---@type TSM
|
|
local InventoryInfo = TSM.Init("Service.InventoryInfo") ---@class Service.InventoryInfo
|
|
local Environment = TSM.Include("Environment")
|
|
local Container = TSM.Include("Util.Container")
|
|
local Event = TSM.Include("Util.Event")
|
|
local SlotId = TSM.Include("Util.SlotId")
|
|
local Table = TSM.Include("Util.Table")
|
|
local ItemInfo = TSM.Include("Service.ItemInfo")
|
|
local TooltipScanning = TSM.Include("Service.TooltipScanning")
|
|
local private = {
|
|
slotIdLocked = {},
|
|
slotIdSoulboundCached = {},
|
|
slotIdIsBoP = {},
|
|
slotIdIsBoA = {},
|
|
}
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
-- Module Loading
|
|
-- ============================================================================
|
|
|
|
InventoryInfo:OnModuleLoad(function()
|
|
Event.Register("ITEM_LOCKED", private.ItemLockedHandler)
|
|
Event.Register("ITEM_UNLOCKED", private.ItemUnlockedHandler)
|
|
Event.Register("BAG_UPDATE", private.BagUpdateHandler)
|
|
Event.Register("PLAYERBANKSLOTS_CHANGED", private.BankSlotChangedHandler)
|
|
if Environment.HasFeature(Environment.FEATURES.REAGENT_BANK) then
|
|
Event.Register("PLAYERREAGENTBANKSLOTS_CHANGED", private.ReagentBankSlotChangedHandler)
|
|
end
|
|
end)
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
-- Module Functions
|
|
-- ============================================================================
|
|
|
|
--- Check if an item will go in a bag.
|
|
-- @tparam string link The item
|
|
-- @tparam number bag The bag index
|
|
-- @treturn boolean Whether or not the item will go in the bag
|
|
function InventoryInfo.ItemWillGoInBag(link, bag)
|
|
if not link or not bag then
|
|
return
|
|
end
|
|
if bag == BACKPACK_CONTAINER or bag == BANK_CONTAINER then
|
|
return true
|
|
elseif bag == REAGENTBANK_CONTAINER then
|
|
return IsReagentBankUnlocked() and ItemInfo.IsCraftingReagent(link)
|
|
end
|
|
local itemFamily = GetItemFamily(link) or 0
|
|
if ItemInfo.GetClassId(link) == Enum.ItemClass.Container then
|
|
-- bags report their family as what can go inside them, not what they can go inside
|
|
itemFamily = 0
|
|
end
|
|
local _, bagFamily = Container.GetNumFreeSlots(bag)
|
|
if not bagFamily then
|
|
return
|
|
end
|
|
return bagFamily == 0 or bit.band(itemFamily, bagFamily) > 0
|
|
end
|
|
|
|
function InventoryInfo.IsBagSlotLocked(bag, slot)
|
|
return private.slotIdLocked[SlotId.Join(bag, slot)]
|
|
end
|
|
|
|
function InventoryInfo.IsSoulbound(bag, slot)
|
|
local slotId = SlotId.Join(bag, slot)
|
|
if private.slotIdSoulboundCached[slotId] then
|
|
return private.slotIdIsBoP[slotId], private.slotIdIsBoA[slotId]
|
|
end
|
|
local scanned, isBOP, isBOA = TooltipScanning.IsSoulbound(bag, slot)
|
|
if scanned then
|
|
private.slotIdSoulboundCached[slotId] = true
|
|
private.slotIdIsBoP[slotId] = isBOP
|
|
private.slotIdIsBoA[slotId] = isBOA
|
|
end
|
|
return isBOP, isBOA
|
|
end
|
|
|
|
|
|
|
|
-- ============================================================================
|
|
-- Private Helper Functions
|
|
-- ============================================================================
|
|
|
|
function private.ItemLockedHandler(_, bag, slot)
|
|
if not slot then
|
|
return
|
|
end
|
|
private.slotIdLocked[SlotId.Join(bag, slot)] = true
|
|
end
|
|
|
|
function private.ItemUnlockedHandler(_, bag, slot)
|
|
if not slot then
|
|
return
|
|
end
|
|
private.slotIdLocked[SlotId.Join(bag, slot)] = nil
|
|
end
|
|
|
|
function private.BagUpdateHandler(_, bag)
|
|
-- clear the soulbound cache for everything in this bag
|
|
Table.Filter(private.slotIdSoulboundCached, private.SlotIdSoulboundCachedFilter, bag)
|
|
end
|
|
|
|
function private.BankSlotChangedHandler(_, slot)
|
|
if slot <= NUM_BANKGENERIC_SLOTS then
|
|
-- one of the slots of the primary bank container changed, so just clear the cache for this slot
|
|
private.slotIdSoulboundCached[SlotId.Join(BANK_CONTAINER, slot)] = nil
|
|
else
|
|
-- one of the extra bank bags changed, so clear the cache for the entire bag
|
|
Table.Filter(private.slotIdSoulboundCached, private.SlotIdSoulboundCachedFilter, slot - NUM_BANKGENERIC_SLOTS)
|
|
end
|
|
end
|
|
|
|
function private.SlotIdSoulboundCachedFilter(slotId, _, bag)
|
|
return SlotId.Split(slotId) == bag
|
|
end
|
|
|
|
function private.ReagentBankSlotChangedHandler(_, slot)
|
|
-- clear the soulbound cache for this slot
|
|
private.slotIdSoulboundCached[SlotId.Join(REAGENTBANK_CONTAINER, slot)] = nil
|
|
end
|
|
|