Mercurial > wow > inventory
comparison Mover.lua @ 81:58617c7827fa
Item refilling should now be working. Probably very slow if your bags, bank or guild bank is filled with over 200 unique items or so (needs some real testing, but know that it is a known (possible) issue).
author | Zerotorescue |
---|---|
date | Thu, 06 Jan 2011 01:01:25 +0100 |
parents | c0bf2ddb5288 |
children | f885805da5d6 |
comparison
equal
deleted
inserted
replaced
80:c0bf2ddb5288 | 81:58617c7827fa |
---|---|
2 local mod = addon:NewModule("Mover", "AceEvent-3.0", "AceTimer-3.0"); | 2 local mod = addon:NewModule("Mover", "AceEvent-3.0", "AceTimer-3.0"); |
3 | 3 |
4 local Scanner; | 4 local Scanner; |
5 local queuedMoves = {}; -- table storing all queued moves before BeginMove is called | 5 local queuedMoves = {}; -- table storing all queued moves before BeginMove is called |
6 local combinedMoves = {}; -- table storing all combined moves (with source and target) that is to be processed by the actual mover in the order of the index (1 to #) | 6 local combinedMoves = {}; -- table storing all combined moves (with source and target) that is to be processed by the actual mover in the order of the index (1 to #) |
7 local movesSource; | |
7 | 8 |
8 function mod:AddMove(itemId, amount) | 9 function mod:AddMove(itemId, amount) |
9 table.insert(queuedMoves, { | 10 table.insert(queuedMoves, { |
10 id = itemId, | 11 id = itemId, |
11 num = amount, | 12 num = amount, |
12 }); | 13 }); |
13 end | 14 end |
14 | 15 |
16 function mod:HasMoves() | |
17 return (#queuedMoves ~= 0); | |
18 end | |
19 | |
15 function mod:BeginMove(location, onFinish) | 20 function mod:BeginMove(location, onFinish) |
21 addon:Debug("BeginMove"); | |
16 | 22 |
17 -- Find the outgoing moves | 23 -- Find the outgoing moves |
18 -- We need the source container and slot, find all the requires sources and put them in a list which we go through later to find matching targets | 24 -- We need the source container and slot, find all the requires sources and put them in a list which we go through later to find matching targets |
19 | 25 |
20 -- Get a list of items in the source container | 26 -- Get a list of items in the source container |
21 local sourceContents = Scanner:CacheLocation(location, false); | 27 local sourceContents = Scanner:CacheLocation(location, false); |
22 | 28 |
23 local outgoingMoves = {}; | 29 local outgoingMoves = {}; |
24 | 30 |
25 for singleMove in pairs(queuedMoves) do | 31 for _, singleMove in pairs(queuedMoves) do |
26 local sourceItem = sourceContents[singleMove.id]; | 32 local sourceItem = sourceContents[singleMove.id]; |
27 if not sourceItem then | 33 if not sourceItem then |
28 print("Can't move " .. IdToItemLink(singleMove.id) .. ", non-existant in source"); | 34 print("Can't move " .. IdToItemLink(singleMove.id) .. ", non-existant in source"); |
29 else | 35 else |
30 -- We want to move the smallest stacks first to keep stuff pretty | 36 -- We want to move the smallest stacks first to keep stuff pretty |
31 table.sort(sourceItem.locations, function(a, b) | 37 table.sort(sourceItem.locations, function(a, b) |
32 return a.count > b.count; | 38 return a.count < b.count; |
33 end); | 39 end); |
34 | 40 |
35 for itemLocation in pairs(sourceItem.locations) do | 41 for _, itemLocation in pairs(sourceItem.locations) do |
36 -- if this location has more items than we need, only move what we need, otherwise move everything in this stack | 42 -- if this location has more items than we need, only move what we need, otherwise move everything in this stack |
37 local movingNum = ((itemLocation.count > singleMove.num and singleMove.num) or itemLocation.count); | 43 local movingNum = ((itemLocation.count > singleMove.num and singleMove.num) or itemLocation.count); |
38 | 44 |
39 table.insert(outgoingMoves, { | 45 table.insert(outgoingMoves, { |
40 itemId = singleMove.id, | 46 itemId = singleMove.id, |
45 | 51 |
46 singleMove.num = (singleMove.num - movingNum); | 52 singleMove.num = (singleMove.num - movingNum); |
47 | 53 |
48 if singleMove.num == 0 then | 54 if singleMove.num == 0 then |
49 -- If we have prepared everything we wanted, go to the next queued move | 55 -- If we have prepared everything we wanted, go to the next queued move |
50 break; | 56 break; -- stop the locations-loop |
51 end | 57 end |
52 end | 58 end |
53 end | 59 end |
54 end | 60 end |
55 | 61 |
74 for slotId = 1, GetContainerNumSlots(bagId) do | 80 for slotId = 1, GetContainerNumSlots(bagId) do |
75 local itemId = GetContainerItemID(bagId, slotId); | 81 local itemId = GetContainerItemID(bagId, slotId); |
76 | 82 |
77 if not itemId then | 83 if not itemId then |
78 table.insert(emptySlots, { | 84 table.insert(emptySlots, { |
79 container: bagId, | 85 container = bagId, |
80 slot: slotId, | 86 slot = slotId, |
81 }); | 87 }); |
82 end | 88 end |
83 end | 89 end |
84 end | 90 end |
91 | |
92 -- Remember where we're moving from | |
93 movesSource = location; | |
85 | 94 |
86 while #outgoingMoves ~= 0 do | 95 while #outgoingMoves ~= 0 do |
87 -- A not equal-comparison should be quicker than a larger/smaller than-comparison | 96 -- A not equal-comparison should be quicker than a larger/smaller than-comparison |
88 | 97 |
89 for outgoingMove in pairs(outgoingMoves) do | 98 for _, outgoingMove in pairs(outgoingMoves) do |
90 -- itemId will be set to nil when this outgoing move was processed - sanity check | 99 -- itemId will be set to nil when this outgoing move was processed - sanity check |
91 if outgoingMove.itemId then | 100 if outgoingMove.itemId then |
92 local targetItem = targetContents[outgoingMove.itemId]; | 101 local targetItem = targetContents[outgoingMove.itemId]; |
93 | 102 |
94 if not targetItem then | 103 if not targetItem then |
112 num = outgoingMove.count, | 121 num = outgoingMove.count, |
113 }); | 122 }); |
114 | 123 |
115 -- We filled an empty slot so the target contents now has one more item, | 124 -- We filled an empty slot so the target contents now has one more item, |
116 -- make a new instance of the ItemMove class so any additional items with this id can be stacked on top of it | 125 -- make a new instance of the ItemMove class so any additional items with this id can be stacked on top of it |
117 local itemMove = addon.ItemMove:New(); | 126 local itemMove = addon.ContainerItem:New(); |
118 itemMove.AddLocation(firstAvailableSlot.container, firstAvailableSlot.slot, outgoingMove.count); | 127 itemMove:AddLocation(firstAvailableSlot.container, firstAvailableSlot.slot, outgoingMove.count); |
119 targetContents[outgoingMove.itemId] = itemMove; | 128 targetContents[outgoingMove.itemId] = itemMove; |
120 | 129 |
121 firstAvailableSlot = nil; -- no longer empty | 130 table.remove(emptySlots, 1); -- no longer empty |
122 | 131 |
123 outgoingMove.count = 0; -- nothing remaining - sanity check | 132 outgoingMove.count = 0; -- nothing remaining - sanity check |
124 outgoingMove.itemId = nil; -- remove this record from the outgoingMoves-table | 133 outgoingMove.itemId = nil; -- remove this record from the outgoingMoves-table |
125 end | 134 end |
126 else | 135 else |
127 -- Find the maximum stack size for this item | 136 -- Find the maximum stack size for this item |
128 local itemStackCount = select(8, GetItemInfo(outgoingMove.itemId)); | 137 local itemStackCount = select(8, GetItemInfo(outgoingMove.itemId)); |
129 | 138 |
130 -- We want to move to the largest stacks first to keep stuff pretty | 139 -- We want to move to the largest stacks first to keep stuff pretty |
131 table.sort(targetItem.locations, function(a, b) | 140 table.sort(targetItem.locations, function(a, b) |
132 return a.count < b.count; | 141 return a.count > b.count; |
133 end); | 142 end); |
134 | 143 |
135 for itemLocation in pairs(targetItem.locations) do | 144 for _, itemLocation in pairs(targetItem.locations) do |
136 if itemLocation.count < itemStackCount and outgoingMove.count > 0 then | 145 if itemLocation.count < itemStackCount and outgoingMove.count > 0 then |
137 -- Check if this stack isn't already full (and we still need to move this item) | 146 -- Check if this stack isn't already full (and we still need to move this item) |
138 | 147 |
139 local remainingSpace = (itemStackCount - itemLocation.count); | 148 local remainingSpace = (itemStackCount - itemLocation.count); |
140 if remainingSpace > outgoingMove.count then | 149 if remainingSpace > outgoingMove.count then |
199 end | 208 end |
200 | 209 |
201 -- No longer needed | 210 -- No longer needed |
202 table.wipe(emptySlots); | 211 table.wipe(emptySlots); |
203 | 212 |
204 DoMoveNow(); | 213 self:ProcessMove(); |
205 | 214 |
206 --ProcessMove(); | 215 self:RegisterEvent("BAG_UPDATE"); |
207 | 216 |
208 --mod:RegisterEvent("BAG_UPDATE", BAG_UPDATE); | 217 onFinish(); |
209 | 218 end |
210 --onFinish(); | 219 |
211 end | 220 if not table.reverse then |
212 | 221 -- table.reverse = function(orig) |
213 function DoMoveNow() | 222 -- local temp = CopyTable(orig); |
223 -- local origLength = #temp; | |
224 -- for i = 1, origLength do | |
225 -- orig[(origLength - i + 1)] = temp[i]; | |
226 -- end | |
227 -- end | |
228 table.reverse = function(orig) | |
229 local temp = {}; | |
230 local origLength = #orig; | |
231 for i = 1, origLength do | |
232 temp[(origLength - i + 1)] = orig[i]; | |
233 end | |
234 | |
235 -- -- Update the original table (can't do orig = temp as that would change the reference-link instead of the original table) | |
236 -- for i, v in pairs(temp) do | |
237 -- orig[i] = v; | |
238 -- end | |
239 return temp; -- for speed we choose to do a return instead | |
240 end | |
241 end | |
242 | |
243 function mod:ProcessMove() | |
244 addon:Debug("ProcessMove"); | |
245 | |
246 if #combinedMoves == 0 then | |
247 print("Nothing to move."); | |
248 | |
249 self:Abort(); | |
250 | |
251 return; | |
252 end | |
253 | |
254 self:RegisterEvent("UI_ERROR_MESSAGE"); | |
255 | |
214 -- combinedMoves now has all moves in it (source -> target) | 256 -- combinedMoves now has all moves in it (source -> target) |
215 -- go through list, move everything inside it | 257 -- go through list, move everything inside it |
216 -- add source and target to one single list | 258 -- add source and target to lists, if either is already in this list, skip the move |
217 -- if either is already in this list, skip this move | 259 -- repeat every few seconds until we're completely done |
218 -- repeat every 5 seconds until we're completely done | |
219 | 260 |
220 local sourceLocationsLocked = {}; | 261 local sourceLocationsLocked = {}; |
221 local targetLocationsLocked = {}; | 262 local targetLocationsLocked = {}; |
263 | |
264 -- Reverse table, we need to go through it from last to first because we'll be removing elements, but we don't want the actions to be executed in a different order | |
265 combinedMoves = table.reverse(combinedMoves); | |
222 | 266 |
223 local numCurrentMove = #combinedMoves; | 267 local numCurrentMove = #combinedMoves; |
224 while numCurrentMove ~= 0 do | 268 while numCurrentMove ~= 0 do |
225 local move = combinedMoves[numCurrentMove]; | 269 local move = combinedMoves[numCurrentMove]; |
226 | 270 |
227 -- sourceContainer, sourceSlot, targetContainer, targetSlot, itemId, num | 271 -- sourceContainer, sourceSlot, targetContainer, targetSlot, itemId, num |
228 if (not sourceLocationsLocked[move.sourceContainer] or not sourceLocationsLocked[move.sourceContainer][move.sourceSlot]) and | 272 if move and (not sourceLocationsLocked[move.sourceContainer] or not sourceLocationsLocked[move.sourceContainer][move.sourceSlot]) and |
229 (not targetLocationsLocked[move.targetContainer] or not targetLocationsLocked[move.targetContainer][move.targetSlot]) then | 273 (not targetLocationsLocked[move.targetContainer] or not targetLocationsLocked[move.targetContainer][move.targetSlot]) then |
230 | 274 |
231 print("Moving " .. IdToItemLink(move.itemId)); | 275 print("Moving " .. IdToItemLink(move.itemId)); |
232 | 276 |
277 addon:Debug(("Moving %dx%s from (%d,%d) to (%d,%d)"):format(move.num, IdToItemLink(move.itemId), move.sourceContainer, move.sourceSlot, move.targetContainer, move.targetSlot)); | |
278 | |
279 if GetContainerItemID(move.sourceContainer, move.sourceSlot) ~= move.itemId then | |
280 self:Abort("source changed", "Source (" .. move.sourceContainer .. "," .. move.sourceSlot .. ") is not " .. IdToItemLink(move.itemId)); | |
281 | |
282 return; | |
283 end | |
284 | |
233 -- Pickup stack | 285 -- Pickup stack |
234 SplitGuildBankItem(move.sourceContainer, move.sourceSlot, move.num); | 286 if movesSource == addon.Locations.Bank then |
287 SplitContainerItem(move.sourceContainer, move.sourceSlot, move.num); | |
288 elseif movesSource == addon.Locations.Guild then | |
289 SplitGuildBankItem(move.sourceContainer, move.sourceSlot, move.num); | |
290 end | |
235 | 291 |
236 -- Remember we picked this item up and thus it is now locked | 292 -- Remember we picked this item up and thus it is now locked |
237 if not sourceLocationsLocked[move.sourceContainer] then | 293 if not sourceLocationsLocked[move.sourceContainer] then |
238 sourceLocationsLocked[move.sourceContainer] = {}; | 294 sourceLocationsLocked[move.sourceContainer] = {}; |
239 end | 295 end |
240 sourceLocationsLocked[move.sourceContainer][move.sourceSlot] = true; | 296 sourceLocationsLocked[move.sourceContainer][move.sourceSlot] = true; |
241 | 297 |
242 if CursorHasItem() then | 298 if movesSource == addon.Locations.Guild or CursorHasItem() then -- CursorHasItem is always false if source is a guild tab |
299 if GetContainerItemID(move.targetContainer, move.targetSlot) and GetContainerItemID(move.targetContainer, move.targetSlot) ~= move.itemId then | |
300 self:Abort("target changed", "Target (" .. move.targetContainer .. "," .. move.targetSlot .. ") is not " .. IdToItemLink(move.itemId) .. " nor empty"); | |
301 return; | |
302 end | |
303 | |
243 -- And drop it | 304 -- And drop it |
244 PickupContainerItem(move.targetContainer, move.targetSlot); | 305 PickupContainerItem(move.targetContainer, move.targetSlot); |
245 | 306 |
246 -- Remember we dropped an item here and thus this is now locked | 307 -- Remember we dropped an item here and thus this is now locked |
247 if not sourceLocationsLocked[move.targetContainer] then | 308 if not targetLocationsLocked[move.targetContainer] then |
248 sourceLocationsLocked[move.targetContainer] = {}; | 309 targetLocationsLocked[move.targetContainer] = {}; |
249 end | 310 end |
250 sourceLocationsLocked[move.targetContainer][move.targetSlot] = true; | 311 targetLocationsLocked[move.targetContainer][move.targetSlot] = true; |
251 | 312 |
252 -- This move was processed | 313 -- This move was processed |
253 table.remove(combinedMoves, numCurrentMove); | 314 table.remove(combinedMoves, numCurrentMove); |
315 else | |
316 self:Abort("item disappeared from mouse", "Couldn't move " .. IdToItemLink(move.itemId) .. ", CursorHasItem() is false"); | |
317 return; | |
254 end | 318 end |
255 end | 319 end |
256 | 320 |
257 -- Proceed with the next element (or previous considering we're going from last to first) | 321 -- Proceed with the next element (or previous considering we're going from last to first) |
258 numCurrentMove = (numCurrentMove - 1); | 322 numCurrentMove = (numCurrentMove - 1); |
259 end | 323 end |
324 | |
325 if #combinedMoves == 0 then | |
326 print("Finished."); | |
327 | |
328 self:Abort(); | |
329 | |
330 return; | |
331 end | |
260 end | 332 end |
261 | 333 |
262 local tmrProcessNext; | 334 local tmrProcessNext; |
263 function BAG_UPDATE() | 335 function mod:BAG_UPDATE() |
264 mod:CancelTimer(tmrProcessNext, true); -- silent | 336 self:CancelTimer(tmrProcessNext, true); -- silent |
265 tmrProcessNext = mod:ScheduleTimer(function() | 337 tmrProcessNext = self:ScheduleTimer("ProcessMove", 1); |
266 ProcessMove(); | |
267 end, 2); | |
268 end | |
269 | |
270 function ProcessMove() | |
271 local currentMove = queuedMoves[1]; | |
272 | |
273 if currentMove then | |
274 addon:Debug("Moving " .. currentMove.num .. " of " .. IdToItemLink(currentMove.id)); | |
275 | |
276 local requestedMoves = currentMove.num; | |
277 | |
278 if currentMove.src == addon.Locations.Bank then | |
279 MoveBankItem(currentMove); | |
280 elseif currentMove.src == addon.Locations.Guild then | |
281 MoveGuildItem(currentMove); | |
282 end | |
283 | |
284 if requestedMoves == currentMove.num then | |
285 print("Skipping " .. IdToItemLink(move.id)); | |
286 move.num = 0; | |
287 elseif currentMove.num > 0 then | |
288 -- bags are full | |
289 print("bags are full"); | |
290 end | |
291 | |
292 if currentMove.num == 0 then | |
293 table.remove(queuedMoves, 1); | |
294 end | |
295 end | |
296 end | |
297 | |
298 function MoveGuildItem(move) | |
299 local tabId = GetCurrentGuildBankTab(); | |
300 local slotId = (MAX_GUILDBANK_SLOTS_PER_TAB or 98); -- start by scanning the last slot | |
301 | |
302 if tabId == nil or tabId < 1 then return; end | |
303 | |
304 while slotId ~= 0 do | |
305 -- A not equal-comparison should be quicker than a larger than-comparison | |
306 | |
307 local itemLink = GetGuildBankItemLink(tabId, slotId); | |
308 if itemLink then | |
309 -- If there is actually an item in this slot | |
310 | |
311 local itemId = GetItemId(itemLink); | |
312 | |
313 if itemId and move.id == itemId then | |
314 -- This is one of the items we're looking for | |
315 | |
316 local itemCount = select(2, GetGuildBankItemInfo(tabId, slotId)); | |
317 | |
318 if itemCount and itemCount > 0 then | |
319 -- if the amount we still have to move is more than this stack, move the entire stack, otherwise move the still needed part of the stack | |
320 local moveable = (move.num > itemCount and itemCount) or move.num; | |
321 | |
322 -- Pickup stack | |
323 SplitGuildBankItem(tabId, slotId, moveable); | |
324 | |
325 -- Find an target slot and put it there | |
326 local reallyMoved = DropItem(itemId, moveable); | |
327 if reallyMoved then | |
328 -- Keep track of how many we have moved | |
329 moved = (moved + reallyMoved); | |
330 | |
331 -- Update the required amount of items so it has the remaining num | |
332 move.num = (move.num - reallyMoved); | |
333 | |
334 --if reallyMoved ~= moveable then | |
335 -- -- Scan this slot again because if we moved a 18 stack onto a 16 stack, we'd actually have moved only 4 items and still need to move the remaining 14 (we're capping stacks before using empty slots) | |
336 -- slotId = (slotId + 1); | |
337 --end | |
338 | |
339 --if move.num == 0 then | |
340 -- if no required items are left to move, then stop and tell the caller function how many we moved | |
341 return moved; | |
342 --end | |
343 end | |
344 end | |
345 end | |
346 end | |
347 | |
348 -- Continue scanning a different slot | |
349 slotId = (slotId - 1); | |
350 end | |
351 end | |
352 | |
353 function MoveBankItem(move) | |
354 local start = 0; | |
355 local stop = NUM_BAG_SLOTS; | |
356 | |
357 -- If we requested the bank then we don't want the bag info | |
358 start = ( NUM_BAG_SLOTS + 1 ); | |
359 stop = ( NUM_BAG_SLOTS + NUM_BANKBAGSLOTS ); | |
360 | |
361 -- Scan the default 100 slots | |
362 move.num = (move.num - MoveFromContainter(BANK_CONTAINER, move)); | |
363 | |
364 -- Go through all our bags, including the backpack | |
365 for bagID = start, stop do | |
366 move.num = (move.num - MoveFromContainter(bagID, move)); | |
367 end | |
368 end | |
369 | |
370 -- Go through all slots of this bag and if a match was found, move the items | |
371 function MoveFromContainter(bagID, move) | |
372 -- Keep track of how many we have moved | |
373 local moved = 0; | |
374 | |
375 -- Go through all slots of this bag | |
376 for slot = 1, GetContainerNumSlots(bagID) do | |
377 local itemId = GetContainerItemID(bagID, slot); | |
378 | |
379 if itemId and move.id == itemId then | |
380 -- This is one of the items we're looking for | |
381 | |
382 local itemCount = select(2, GetContainerItemInfo(bagID, slot)); | |
383 | |
384 if itemCount and itemCount > 0 then | |
385 -- if the amount we still have to move is more than this stack, move the entire stack, otherwise move the still needed part of the stack | |
386 local moveable = (move.num > itemCount and itemCount) or move.num; | |
387 | |
388 -- Pickup stack | |
389 SplitContainerItem(bagID, slot, moveable); | |
390 | |
391 addon:Debug("Picked " .. IdToItemLink(itemId) .. " up"); | |
392 | |
393 -- Find an target slot and put it there | |
394 if CursorHasItem() then | |
395 local reallyMoved = DropItem(itemId, moveable); | |
396 | |
397 if reallyMoved then | |
398 addon:Debug("Dropped " .. reallyMoved .. " of " .. IdToItemLink(itemId)); | |
399 | |
400 -- Keep track of how many we have moved | |
401 moved = (moved + reallyMoved); | |
402 | |
403 -- Update the required amount of items so it has the remaining num | |
404 move.num = (move.num - reallyMoved); | |
405 | |
406 --if reallyMoved ~= moveable then | |
407 -- Scan this slot again because if we moved a 18 stack onto a 16 stack, we'd actually have moved only 4 items and still need to move the remaining 14 (we're capping stacks before using empty slots) | |
408 -- slot = (slot - 1); | |
409 --end | |
410 | |
411 --if move.num == 0 then | |
412 -- if no required items are left to move, then stop and tell the caller function how many we moved | |
413 return moved; | |
414 --end | |
415 end | |
416 end | |
417 end | |
418 end | |
419 end | |
420 | |
421 return moved; | |
422 end | |
423 | |
424 | |
425 -- This currently only uses empty slots, it will have to fill stacks in the future | |
426 function DropItem(itemId, amount) | |
427 local start = 0; | |
428 local stop = NUM_BAG_SLOTS; | |
429 | |
430 -- Go through all our bags, including the backpack | |
431 for bagID = start, stop do | |
432 -- Go through all our slots | |
433 for slot = 1, GetContainerNumSlots(bagID) do | |
434 local itemId = GetContainerItemID(bagID, slot); | |
435 | |
436 if not itemId then | |
437 -- If this slot is empty, put the item here | |
438 PickupContainerItem(bagID, slot); | |
439 | |
440 return amount; | |
441 end | |
442 end | |
443 end | |
444 | |
445 return; | |
446 end | 338 end |
447 | 339 |
448 function IdToItemLink(itemId) | 340 function IdToItemLink(itemId) |
449 return select(2, GetItemInfo(itemId)); | 341 local itemLink = select(2, GetItemInfo(itemId)); |
342 itemLink = itemLink or "Unknown (" .. itemId .. ")"; | |
343 return itemLink; | |
344 end | |
345 | |
346 function mod:UI_ERROR_MESSAGE(e, errorMessage) | |
347 if errorMessage == ERR_SPLIT_FAILED then | |
348 self:Abort("splitting failed", "Splitting failed."); | |
349 end | |
350 end | |
351 | |
352 function mod:Abort(simple, debugMsg) | |
353 if debugMsg then | |
354 addon:Debug("Aborting:" .. debugMsg); | |
355 end | |
356 if simple then | |
357 print("|cffff0000Aborting: " .. simple .. ".|r"); | |
358 end | |
359 table.wipe(combinedMoves); | |
360 movesSource = nil; | |
361 | |
362 -- Stop timer | |
363 self:UnregisterEvent("BAG_UPDATE"); | |
364 self:CancelTimer(tmrProcessNext, true); -- silent | |
365 | |
366 self:UnregisterEvent("UI_ERROR_MESSAGE"); | |
450 end | 367 end |
451 | 368 |
452 function mod:OnEnable() | 369 function mod:OnEnable() |
453 Scanner = addon:GetModule("Scanner"); | 370 Scanner = addon:GetModule("Scanner"); |
454 end | 371 end |
455 | 372 |
456 function mod:OnDisable() | 373 function mod:OnDisable() |
457 Scanner = nil; | 374 Scanner = nil; |
458 end | 375 |
376 self:Abort(); | |
377 end |