Zerotorescue@80
|
1 local addon = select(2, ...);
|
Zerotorescue@84
|
2 local mod = addon:NewModule("Scanner", "AceEvent-3.0", "AceTimer-3.0");
|
Zerotorescue@80
|
3
|
Zerotorescue@80
|
4 addon.Locations = {
|
Zerotorescue@80
|
5 Bag = 0,
|
Zerotorescue@80
|
6 Bank = 1,
|
Zerotorescue@80
|
7 Guild = 2,
|
Zerotorescue@80
|
8 };
|
Zerotorescue@80
|
9
|
Zerotorescue@80
|
10 local Mover, paused;
|
Zerotorescue@80
|
11 local itemCache = {};
|
Zerotorescue@80
|
12
|
Zerotorescue@80
|
13 function mod:ClearCache()
|
Zerotorescue@80
|
14 table.wipe(itemCache);
|
Zerotorescue@80
|
15 end
|
Zerotorescue@80
|
16
|
Zerotorescue@80
|
17 function mod:CacheLocation(location, remember)
|
Zerotorescue@89
|
18 -- Reset cache just in case it was filled
|
Zerotorescue@89
|
19 self:ClearCache();
|
Zerotorescue@89
|
20
|
Zerotorescue@80
|
21 if location == addon.Locations.Bag or location == addon.Locations.Bank then
|
Zerotorescue@80
|
22 local start, stop;
|
Zerotorescue@80
|
23 if location == addon.Locations.Bag then
|
Zerotorescue@80
|
24 start = 0;
|
Zerotorescue@80
|
25 stop = NUM_BAG_SLOTS;
|
Zerotorescue@80
|
26 else
|
Zerotorescue@80
|
27 -- If we requested the bank then we don't want the bag info
|
Zerotorescue@80
|
28 start = ( NUM_BAG_SLOTS + 1 );
|
Zerotorescue@80
|
29 stop = ( NUM_BAG_SLOTS + NUM_BANKBAGSLOTS );
|
Zerotorescue@80
|
30 end
|
Zerotorescue@80
|
31
|
Zerotorescue@80
|
32 -- Go through all our bags, including the backpack
|
Zerotorescue@81
|
33 for i = start, ((location == addon.Locations.Bag and stop) or (location == addon.Locations.Bank and (stop + 1))) do -- if scanning bags stop at normal bag slot, if scanning bank, stop one later to allow BANK_CONTAINER to be scanned too
|
Zerotorescue@80
|
34 -- Scan the default 100 slots whenever we're at a non-existing index
|
Zerotorescue@80
|
35 local bagId = (i == (stop + 1) and BANK_CONTAINER) or i;
|
Zerotorescue@80
|
36 local slotId = GetContainerNumSlots(bagId);
|
Zerotorescue@80
|
37
|
Zerotorescue@80
|
38 while slotId ~= 0 do
|
Zerotorescue@80
|
39 -- A not equal-comparison should be quicker than a larger than-comparison
|
Zerotorescue@80
|
40
|
Zerotorescue@80
|
41 local itemId = GetContainerItemID(bagId, slotId);
|
Zerotorescue@80
|
42 local itemCount = itemId and select(2, GetContainerItemInfo(bagId, slotId));
|
Zerotorescue@80
|
43
|
Zerotorescue@80
|
44 if itemId and itemCount and itemCount > 0 then
|
Zerotorescue@80
|
45 local itemMove;
|
Zerotorescue@80
|
46 if not itemCache[itemId] then
|
Zerotorescue@80
|
47 -- If this is the first time we see this item, make a new object
|
Zerotorescue@81
|
48 itemMove = addon.ContainerItem:New();
|
Zerotorescue@81
|
49 itemCache[itemId] = itemMove;
|
Zerotorescue@80
|
50 else
|
Zerotorescue@80
|
51 -- If we had this item in another slot too
|
Zerotorescue@80
|
52 itemMove = itemCache[itemId];
|
Zerotorescue@80
|
53 end
|
Zerotorescue@80
|
54
|
Zerotorescue@81
|
55 itemMove:AddLocation(bagId, slotId, itemCount);
|
Zerotorescue@80
|
56 end
|
Zerotorescue@80
|
57
|
Zerotorescue@80
|
58 -- Continue scanning a different slot
|
Zerotorescue@80
|
59 slotId = (slotId - 1);
|
Zerotorescue@80
|
60 end
|
Zerotorescue@80
|
61 end
|
Zerotorescue@80
|
62 elseif location == addon.Locations.Guild then
|
Zerotorescue@84
|
63 for tabId = 1, GetNumGuildBankTabs() do
|
Zerotorescue@84
|
64 local isViewable = select(3, GetGuildBankTabInfo(tabId));
|
Zerotorescue@80
|
65
|
Zerotorescue@84
|
66 if isViewable == 1 then
|
Zerotorescue@84
|
67 local slotId = (MAX_GUILDBANK_SLOTS_PER_TAB or 98); -- start by scanning the last slot
|
Zerotorescue@80
|
68
|
Zerotorescue@84
|
69 while slotId ~= 0 do
|
Zerotorescue@84
|
70 -- A not equal-comparison should be quicker than a larger than-comparison
|
Zerotorescue@84
|
71
|
Zerotorescue@84
|
72 local itemLink = GetGuildBankItemLink(tabId, slotId);
|
Zerotorescue@84
|
73 local itemId = itemLink and addon:GetItemID(itemLink);
|
Zerotorescue@84
|
74 local itemCount = itemLink and select(2, GetGuildBankItemInfo(tabId, slotId));
|
Zerotorescue@84
|
75
|
Zerotorescue@84
|
76 if itemLink and itemId and itemCount and itemCount > 0 then
|
Zerotorescue@84
|
77 -- If there is actually an item in this slot
|
Zerotorescue@84
|
78 local itemMove;
|
Zerotorescue@84
|
79 if not itemCache[itemId] then
|
Zerotorescue@84
|
80 -- If this is the first time we see this item, make a new object
|
Zerotorescue@84
|
81 itemMove = addon.ContainerItem:New();
|
Zerotorescue@84
|
82 itemCache[itemId] = itemMove;
|
Zerotorescue@84
|
83 else
|
Zerotorescue@84
|
84 -- If we had this item in another slot too
|
Zerotorescue@84
|
85 itemMove = itemCache[itemId];
|
Zerotorescue@84
|
86 end
|
Zerotorescue@84
|
87
|
Zerotorescue@84
|
88 itemMove:AddLocation(tabId, slotId, itemCount);
|
Zerotorescue@84
|
89 end
|
Zerotorescue@84
|
90
|
Zerotorescue@84
|
91 -- Continue scanning a different slot
|
Zerotorescue@84
|
92 slotId = (slotId - 1);
|
Zerotorescue@80
|
93 end
|
Zerotorescue@80
|
94 end
|
Zerotorescue@80
|
95 end
|
Zerotorescue@80
|
96 else
|
Zerotorescue@82
|
97 error("Invalid location provided for CacheLocation. Must be Bank or Guild.");
|
Zerotorescue@80
|
98 end
|
Zerotorescue@80
|
99
|
Zerotorescue@80
|
100 if not remember then
|
Zerotorescue@80
|
101 -- Copy the table as clearing the cache wipes it empty (and tables are passed by reference)
|
Zerotorescue@80
|
102 local cacheCopy = CopyTable(itemCache);
|
Zerotorescue@80
|
103
|
Zerotorescue@80
|
104 self:ClearCache();
|
Zerotorescue@80
|
105
|
Zerotorescue@80
|
106 return cacheCopy;
|
Zerotorescue@80
|
107 end
|
Zerotorescue@80
|
108 end
|
Zerotorescue@80
|
109
|
Zerotorescue@80
|
110 function mod:Scan(location)
|
Zerotorescue@80
|
111 -- We might pause the scanning when we invoke moves ourself
|
Zerotorescue@80
|
112 if paused then
|
Zerotorescue@80
|
113 return;
|
Zerotorescue@80
|
114 end
|
Zerotorescue@80
|
115
|
Zerotorescue@80
|
116 local playerName = UnitName("player");
|
Zerotorescue@80
|
117
|
Zerotorescue@80
|
118 self:CacheLocation(location, true);
|
Zerotorescue@80
|
119
|
Zerotorescue@80
|
120 -- Go through all groups
|
Zerotorescue@80
|
121 for groupName, values in pairs(addon.db.profile.groups) do
|
Zerotorescue@80
|
122 local trackAt = addon:GetOptionByKey(groupName, "trackAtCharacters");
|
Zerotorescue@84
|
123 local localItemData = addon:GetOptionByKey(groupName, "localItemData");
|
Zerotorescue@80
|
124
|
Zerotorescue@82
|
125 if values.items and trackAt[playerName] and addon:GetOptionByKey(groupName, "autoRefill") and (location ~= addon.Locations.Bank or not localItemData or not localItemData["Bank"]) then
|
Zerotorescue@80
|
126 -- Is this character interested in this data?
|
Zerotorescue@80
|
127
|
Zerotorescue@80
|
128 local minLocalStock = addon:GetOptionByKey(groupName, "minLocalStock");
|
Zerotorescue@80
|
129
|
Zerotorescue@80
|
130 -- Go through all items
|
Zerotorescue@80
|
131 for itemId, _ in pairs(values.items) do
|
Zerotorescue@80
|
132
|
Zerotorescue@81
|
133 -- Check if we have enough items local (but only do so if this location also has enough available)
|
Zerotorescue@81
|
134 local missingItems = itemCache[itemId] and (minLocalStock - addon:GetLocalItemCount(itemId, groupName));
|
Zerotorescue@80
|
135
|
Zerotorescue@81
|
136 if itemCache[itemId] and missingItems > 0 then
|
Zerotorescue@80
|
137 -- Check how many are available
|
Zerotorescue@81
|
138 local availableItems = ((itemCache[itemId] and itemCache[itemId].totalCount) or 0);
|
Zerotorescue@80
|
139
|
Zerotorescue@80
|
140 if availableItems > 0 then
|
Zerotorescue@80
|
141 print("Insufficient " .. select(2, GetItemInfo(itemId)) .. " but this location has " .. availableItems .. " (moving " .. missingItems .. ")");
|
Zerotorescue@80
|
142
|
Zerotorescue@80
|
143 Mover:AddMove(itemId, missingItems);
|
Zerotorescue@80
|
144 else
|
Zerotorescue@81
|
145 print("Insufficient " .. IdToItemLink(itemId));
|
Zerotorescue@80
|
146 end
|
Zerotorescue@80
|
147 end
|
Zerotorescue@80
|
148 end
|
Zerotorescue@80
|
149 end
|
Zerotorescue@80
|
150 end
|
Zerotorescue@80
|
151
|
Zerotorescue@80
|
152 self:ClearCache();
|
Zerotorescue@80
|
153
|
Zerotorescue@81
|
154 if Mover:HasMoves() then
|
Zerotorescue@81
|
155 StaticPopupDialogs["InventoriumRefill"] = {
|
Zerotorescue@81
|
156 text = "There are items that can be refilled from this location, do you wish to proceed?",
|
Zerotorescue@81
|
157 button1 = YES,
|
Zerotorescue@81
|
158 button2 = NO,
|
Zerotorescue@81
|
159 OnAccept = function()
|
Zerotorescue@81
|
160 mod:Pause();
|
Zerotorescue@81
|
161 Mover:BeginMove(location, self.Unpause);
|
Zerotorescue@81
|
162 end,
|
Zerotorescue@81
|
163 timeout = 0,
|
Zerotorescue@81
|
164 whileDead = 1,
|
Zerotorescue@81
|
165 hideOnEscape = 1,
|
Zerotorescue@82
|
166 exclusive = 1,
|
Zerotorescue@81
|
167 };
|
Zerotorescue@81
|
168 StaticPopup_Show("InventoriumRefill");
|
Zerotorescue@81
|
169 end
|
Zerotorescue@81
|
170 end
|
Zerotorescue@81
|
171
|
Zerotorescue@84
|
172
|
Zerotorescue@84
|
173
|
Zerotorescue@84
|
174 -- Events
|
Zerotorescue@84
|
175
|
Zerotorescue@84
|
176 -- Player bank
|
Zerotorescue@84
|
177
|
Zerotorescue@84
|
178 function mod:BANKFRAME_OPENED()
|
Zerotorescue@84
|
179 addon:Debug("Scanner:BANKFRAME_OPENED");
|
Zerotorescue@84
|
180
|
Zerotorescue@84
|
181 mod:RegisterEvent("BANKFRAME_CLOSED");
|
Zerotorescue@84
|
182
|
Zerotorescue@84
|
183 -- Scan once when the bank is opened, but no need to scan after
|
Zerotorescue@84
|
184 mod:Scan(addon.Locations.Bank);
|
Zerotorescue@84
|
185 end
|
Zerotorescue@84
|
186
|
Zerotorescue@84
|
187 function mod:BANKFRAME_CLOSED()
|
Zerotorescue@81
|
188 addon:Debug("Scanner:BANKFRAME_CLOSED");
|
Zerotorescue@81
|
189
|
Zerotorescue@89
|
190 self:ClearCache();
|
Zerotorescue@89
|
191
|
Zerotorescue@81
|
192 mod:UnregisterEvent("BANKFRAME_CLOSED");
|
Zerotorescue@81
|
193
|
Zerotorescue@81
|
194 StaticPopup_Hide("InventoriumRefill");
|
Zerotorescue@80
|
195 end
|
Zerotorescue@80
|
196
|
Zerotorescue@84
|
197 -- Guild bank
|
Zerotorescue@84
|
198
|
Zerotorescue@84
|
199 local tmrScanGuild, scanned;
|
Zerotorescue@84
|
200 function mod:GUILDBANKBAGSLOTS_CHANGED()
|
Zerotorescue@84
|
201 -- This event is spammed the first time the guild bank is opened
|
Zerotorescue@84
|
202 if not scanned then
|
Zerotorescue@84
|
203 self:CancelTimer(tmrScanGuild, true); -- silent
|
Zerotorescue@84
|
204 tmrScanGuild = self:ScheduleTimer("DoScanGuild", 1);
|
Zerotorescue@84
|
205 end
|
Zerotorescue@80
|
206 end
|
Zerotorescue@80
|
207
|
Zerotorescue@84
|
208 function mod:DoScanGuild()
|
Zerotorescue@84
|
209 if not scanned then
|
Zerotorescue@89
|
210 addon:Debug("Scanner:DoScanGuild");
|
Zerotorescue@84
|
211
|
Zerotorescue@84
|
212 scanned = true;
|
Zerotorescue@84
|
213
|
Zerotorescue@84
|
214 self:Scan(addon.Locations.Guild);
|
Zerotorescue@84
|
215 end
|
Zerotorescue@84
|
216 end
|
Zerotorescue@80
|
217
|
Zerotorescue@84
|
218 function mod:GUILDBANKFRAME_CLOSED()
|
Zerotorescue@81
|
219 addon:Debug("Scanner:GUILDBANKFRAME_CLOSED");
|
Zerotorescue@81
|
220
|
Zerotorescue@84
|
221 scanned = nil;
|
Zerotorescue@89
|
222 self:ClearCache();
|
Zerotorescue@81
|
223
|
Zerotorescue@84
|
224 self:UnregisterEvent("GUILDBANKFRAME_CLOSED");
|
Zerotorescue@84
|
225 self:UnregisterEvent("GUILDBANKBAGSLOTS_CHANGED");
|
Zerotorescue@84
|
226
|
Zerotorescue@84
|
227 self:CancelTimer(tmrScanGuild, true); -- silent
|
Zerotorescue@80
|
228
|
Zerotorescue@81
|
229 StaticPopup_Hide("InventoriumRefill");
|
Zerotorescue@80
|
230 end
|
Zerotorescue@80
|
231
|
Zerotorescue@84
|
232 function mod:GUILDBANKFRAME_OPENED()
|
Zerotorescue@81
|
233 addon:Debug("Scanner:GUILDBANKFRAME_OPENED");
|
Zerotorescue@81
|
234
|
Zerotorescue@84
|
235 scanned = nil;
|
Zerotorescue@80
|
236
|
Zerotorescue@84
|
237 -- Get the contents for every tab into our cache
|
Zerotorescue@84
|
238 for tabId = 1, GetNumGuildBankTabs() do
|
Zerotorescue@84
|
239 local isViewable = select(3, GetGuildBankTabInfo(tabId));
|
Zerotorescue@84
|
240 if isViewable == 1 then
|
Zerotorescue@84
|
241 QueryGuildBankTab(tabId);
|
Zerotorescue@84
|
242 end
|
Zerotorescue@84
|
243 end
|
Zerotorescue@84
|
244
|
Zerotorescue@84
|
245 self:RegisterEvent("GUILDBANKFRAME_CLOSED");
|
Zerotorescue@84
|
246 self:RegisterEvent("GUILDBANKBAGSLOTS_CHANGED");
|
Zerotorescue@80
|
247 end
|
Zerotorescue@80
|
248
|
Zerotorescue@80
|
249 function mod:OnEnable()
|
Zerotorescue@80
|
250 -- Scan once when the bankframe is opened
|
Zerotorescue@84
|
251 self:RegisterEvent("BANKFRAME_OPENED");
|
Zerotorescue@84
|
252 self:RegisterEvent("GUILDBANKFRAME_OPENED");
|
Zerotorescue@80
|
253
|
Zerotorescue@80
|
254 Mover = addon:GetModule("Mover");
|
Zerotorescue@80
|
255 end
|
Zerotorescue@80
|
256
|
Zerotorescue@80
|
257 function mod:OnDisable()
|
Zerotorescue@80
|
258 Mover = nil;
|
Zerotorescue@80
|
259
|
Zerotorescue@80
|
260 -- Bank
|
Zerotorescue@84
|
261 self:UnregisterEvent("BANKFRAME_OPENED");
|
Zerotorescue@80
|
262
|
Zerotorescue@80
|
263 -- Guild
|
Zerotorescue@84
|
264 self:GUILDBANKFRAME_CLOSED();
|
Zerotorescue@84
|
265 self:UnregisterEvent("GUILDBANKFRAME_OPENED");
|
Zerotorescue@80
|
266 end
|
Zerotorescue@80
|
267
|
Zerotorescue@80
|
268 function mod:Pause()
|
Zerotorescue@80
|
269 paused = true;
|
Zerotorescue@80
|
270 end
|
Zerotorescue@80
|
271
|
Zerotorescue@80
|
272 function mod:Unpause()
|
Zerotorescue@80
|
273 paused = nil;
|
Zerotorescue@80
|
274 end
|