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