forked from Mirroar/TopFit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathitemlocations.lua
121 lines (103 loc) · 4.51 KB
/
itemlocations.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
--- Code in this file is responsible for keeping track of the player's equippable items,
-- how many he has and where he has them. Only items in bags and equipped on the player interest us.
local addonName, ns = ...
--- This table stores which items are in which inventory slot or bag slot
local equipment = {}
--- This table stores locations that equippable items can be found in, for easy lookups
local equipmentLocations = {}
--- This table stores which items are added or removed over time
local itemCountChanges = {}
local ItemLocations = LibStub('LibItemLocations')
--- Internal function that records the fact that an item is available at a certain location
-- @param itemLink The item's item link
-- @param location The location the item is available at
local function AddEquipLocation(itemLink, location)
if not equipmentLocations[itemLink] then
equipmentLocations[itemLink] = {}
end
tinsert(equipmentLocations[itemLink], location)
itemCountChanges[itemLink] = (itemCountChanges[itemLink] or 0) + 1
end
--- Internal function that records the fact that an item is no longer available at a certain location
-- @param itemLink The item's item link
-- @param location The location the item was available at
local function RemoveEquipLocation(itemLink, location)
for i, equipLocation in ipairs(equipmentLocations[itemLink]) do
if location == equipLocation then
tremove(equipmentLocations[itemLink], i)
break
end
end
itemCountChanges[itemLink] = (itemCountChanges[itemLink] or 0) - 1
end
--- Internal function that updates what item is available in a certain slot
-- @param container The container that needs updating. Either a bag ID or EQUIPMENT_CONTAINER for equipped items
-- @param slot The container's slot that needs updating
-- @param itemLink The item's item link, or nil if no item is currently in the given slot
local function UpdateEquipLocation(container, slot, itemLink)
local location = ItemLocations:GetLocation(container, slot)
if equipment[location] then
-- there was an item previously equipped in this slot
RemoveEquipLocation(equipment[location], location)
equipment[location] = nil
end
-- TODO: we might actually want to include monitoring BoE items
-- by removing the check to ns:CanUseItemBinding and just remove them when calculating
-- careful: this will affect ns.GetNewItems
if itemLink and IsEquippableItem(itemLink) and not ns.Unfit:IsItemUnusable(itemLink) and (container == _G.EQUIPMENT_CONTAINER or ns:CanUseItemBinding(container, slot)) then
AddEquipLocation(itemLink, location)
equipment[location] = itemLink
end
end
--- Update information about available items from equipment.
-- @param slotID Slot number to check, or nil to check all equipment slots
function ns.CheckInventoryItems(slotID)
if not slotID then
for i = INVSLOT_FIRST_EQUIPPED, INVSLOT_LAST_EQUIPPED do
ns.CheckInventoryItems(i)
end
return
end
local itemLink = GetInventoryItemLink('player', slotID)
UpdateEquipLocation(_G.EQUIPMENT_CONTAINER, slotID, itemLink)
end
--- Update information about available items from bags.
-- @param bagID Bag ID to check, or nil to check all bags
function ns.CheckBagItems(bagID)
for bag = 0, NUM_BAG_SLOTS do
if not bagID or bag == bagID then
for slot = 1, GetContainerNumSlots(bag) do
local itemLink = GetContainerItemLink(bag, slot)
UpdateEquipLocation(bag, slot, itemLink)
end
end
end
end
--- Get all locations a given item is available at.
-- @param itemLink The item's item link
-- TODO: actually write an iterator that parses the internal location data into something more usable
function ns.GetItemLocations(itemLink)
if not equipmentLocations[itemLink] then
equipmentLocations[itemLink] = {}
end
return equipmentLocations[itemLink]
end
--- Get the number of times a given item is available to the player
-- @param itemLink The item's item link
function ns.GetItemCount(itemLink)
return #(ns.GetItemLocations(itemLink))
end
--- Mark all current items as known again
function ns.ResetNewItems()
wipe(itemCountChanges)
end
--- Get a list of all equipment items that the player has acquired since the last time ns.ResetNewItems was called
function ns.GetNewItems()
local result = {}
for itemLink, count in pairs(itemCountChanges) do
if count > 0 then
tinsert(result, itemLink)
end
end
return result
end