annotate Modules/Mover.lua @ 89:a12d22ef3f39

AceSerializer has been enabled again as it?s used when exporting/importing groups. All other unused libraries are now really removed. Adjusted debug function to format only when a debug channel is available. Fixed moving from guild banks, checking if items are locked is different then with banks. Now unregistering the item locking event so it doesn?t continue to try to move every time an item is switched after the automated cycle has finished. (geeezus, this description is a total overkill) Fixed item queueing. Queue all when there?s a group without any items inside no longer crashes. Removing cached container data after closing a container.
author Zerotorescue
date Fri, 07 Jan 2011 22:19:03 +0100
parents f1c035694545
children 31493364b163
rev   line source
Zerotorescue@80 1 local addon = select(2, ...);
Zerotorescue@80 2 local mod = addon:NewModule("Mover", "AceEvent-3.0", "AceTimer-3.0");
Zerotorescue@80 3
Zerotorescue@80 4 local Scanner;
Zerotorescue@80 5 local queuedMoves = {}; -- table storing all queued moves before BeginMove is called
Zerotorescue@80 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 #)
Zerotorescue@81 7 local movesSource;
Zerotorescue@80 8
Zerotorescue@80 9 function mod:AddMove(itemId, amount)
Zerotorescue@80 10 table.insert(queuedMoves, {
Zerotorescue@80 11 id = itemId,
Zerotorescue@80 12 num = amount,
Zerotorescue@80 13 });
Zerotorescue@80 14 end
Zerotorescue@80 15
Zerotorescue@81 16 function mod:HasMoves()
Zerotorescue@81 17 return (#queuedMoves ~= 0);
Zerotorescue@81 18 end
Zerotorescue@81 19
Zerotorescue@84 20 if not table.reverse then
Zerotorescue@84 21 table.reverse = function(orig)
Zerotorescue@84 22 local temp = {};
Zerotorescue@84 23 local origLength = #orig;
Zerotorescue@84 24 for i = 1, origLength do
Zerotorescue@84 25 temp[(origLength - i + 1)] = orig[i];
Zerotorescue@84 26 end
Zerotorescue@84 27
Zerotorescue@84 28 -- -- Update the original table (can't do orig = temp as that would change the reference-link instead of the original table)
Zerotorescue@84 29 -- for i, v in pairs(temp) do
Zerotorescue@84 30 -- orig[i] = v;
Zerotorescue@84 31 -- end
Zerotorescue@84 32 return temp; -- for speed we choose to do a return instead
Zerotorescue@84 33 end
Zerotorescue@84 34 end
Zerotorescue@84 35
Zerotorescue@80 36 function mod:BeginMove(location, onFinish)
Zerotorescue@81 37 addon:Debug("BeginMove");
Zerotorescue@80 38
Zerotorescue@80 39 -- Find the outgoing moves
Zerotorescue@80 40 -- 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
Zerotorescue@80 41
Zerotorescue@80 42 -- Get a list of items in the source container
Zerotorescue@80 43 local sourceContents = Scanner:CacheLocation(location, false);
Zerotorescue@80 44
Zerotorescue@80 45 local outgoingMoves = {};
Zerotorescue@80 46
Zerotorescue@89 47 addon:Debug("%d moves were queued.", #queuedMoves);
Zerotorescue@82 48
Zerotorescue@81 49 for _, singleMove in pairs(queuedMoves) do
Zerotorescue@80 50 local sourceItem = sourceContents[singleMove.id];
Zerotorescue@80 51 if not sourceItem then
Zerotorescue@80 52 print("Can't move " .. IdToItemLink(singleMove.id) .. ", non-existant in source");
Zerotorescue@80 53 else
Zerotorescue@82 54 -- We want to move the smallest stacks first to keep stuff pretty (and minimize space usage, splitting a stack takes 2 slots, moving something only 1)
Zerotorescue@80 55 table.sort(sourceItem.locations, function(a, b)
Zerotorescue@81 56 return a.count < b.count;
Zerotorescue@80 57 end);
Zerotorescue@80 58
Zerotorescue@81 59 for _, itemLocation in pairs(sourceItem.locations) do
Zerotorescue@80 60 -- if this location has more items than we need, only move what we need, otherwise move everything in this stack
Zerotorescue@80 61 local movingNum = ((itemLocation.count > singleMove.num and singleMove.num) or itemLocation.count);
Zerotorescue@80 62
Zerotorescue@80 63 table.insert(outgoingMoves, {
Zerotorescue@80 64 itemId = singleMove.id,
Zerotorescue@82 65 num = movingNum,
Zerotorescue@80 66 container = itemLocation.container,
Zerotorescue@80 67 slot = itemLocation.slot,
Zerotorescue@80 68 });
Zerotorescue@80 69
Zerotorescue@80 70 singleMove.num = (singleMove.num - movingNum);
Zerotorescue@80 71
Zerotorescue@80 72 if singleMove.num == 0 then
Zerotorescue@80 73 -- If we have prepared everything we wanted, go to the next queued move
Zerotorescue@81 74 break; -- stop the locations-loop
Zerotorescue@80 75 end
Zerotorescue@80 76 end
Zerotorescue@80 77 end
Zerotorescue@80 78 end
Zerotorescue@82 79
Zerotorescue@89 80 addon:Debug("%d outgoing moves are possible.", #outgoingMoves);
Zerotorescue@80 81
Zerotorescue@80 82 -- No longer needed
Zerotorescue@80 83 table.wipe(queuedMoves);
Zerotorescue@80 84
Zerotorescue@80 85 -- Process every single outgoing move and find fitting targets
Zerotorescue@80 86
Zerotorescue@80 87 -- Get a list of items already in the target container
Zerotorescue@80 88 local targetContents = Scanner:CacheLocation(addon.Locations.Bag, false);
Zerotorescue@80 89
Zerotorescue@80 90 -- Find all empty slots
Zerotorescue@80 91
Zerotorescue@80 92 local emptySlots = {};
Zerotorescue@80 93
Zerotorescue@80 94 local start = 0;
Zerotorescue@80 95 local stop = NUM_BAG_SLOTS;
Zerotorescue@80 96
Zerotorescue@80 97 -- Go through all our bags, including the backpack
Zerotorescue@80 98 for bagId = start, stop do
Zerotorescue@80 99 -- Go through all our slots
Zerotorescue@80 100 for slotId = 1, GetContainerNumSlots(bagId) do
Zerotorescue@82 101 local itemId = GetContainerItemID(bagId, slotId); -- we're scanning our local bags here, so no need to get messy with guild bank support
Zerotorescue@80 102
Zerotorescue@80 103 if not itemId then
Zerotorescue@80 104 table.insert(emptySlots, {
Zerotorescue@81 105 container = bagId,
Zerotorescue@81 106 slot = slotId,
Zerotorescue@80 107 });
Zerotorescue@80 108 end
Zerotorescue@80 109 end
Zerotorescue@80 110 end
Zerotorescue@82 111
Zerotorescue@89 112 addon:Debug("%d empty slots are available.", #emptySlots);
Zerotorescue@80 113
Zerotorescue@81 114 -- Remember where we're moving from
Zerotorescue@81 115 movesSource = location;
Zerotorescue@81 116
Zerotorescue@84 117 local backup = 0;
Zerotorescue@84 118
Zerotorescue@80 119 while #outgoingMoves ~= 0 do
Zerotorescue@80 120 -- A not equal-comparison should be quicker than a larger/smaller than-comparison
Zerotorescue@80 121
Zerotorescue@81 122 for _, outgoingMove in pairs(outgoingMoves) do
Zerotorescue@80 123 -- itemId will be set to nil when this outgoing move was processed - sanity check
Zerotorescue@80 124 if outgoingMove.itemId then
Zerotorescue@80 125 local targetItem = targetContents[outgoingMove.itemId];
Zerotorescue@80 126
Zerotorescue@80 127 if not targetItem then
Zerotorescue@80 128 -- grab an empty slot
Zerotorescue@80 129 -- make new instance of ItemMove
Zerotorescue@80 130 -- populate targetContents with it so future moves of this item can be put on top of it if this isn't a full stack
Zerotorescue@80 131
Zerotorescue@80 132 local firstAvailableSlot = emptySlots[1];
Zerotorescue@80 133
Zerotorescue@80 134 if not firstAvailableSlot then
Zerotorescue@80 135 print("Bags are full. Skipping " .. IdToItemLink(outgoingMove.itemId) .. ".");
Zerotorescue@80 136
Zerotorescue@82 137 outgoingMove.itemId = nil; -- remove this record from the outgoingMoves-table
Zerotorescue@80 138 else
Zerotorescue@80 139 table.insert(combinedMoves, {
Zerotorescue@82 140 itemId = outgoingMove.itemId,
Zerotorescue@82 141 num = outgoingMove.num,
Zerotorescue@80 142 sourceContainer = outgoingMove.container,
Zerotorescue@80 143 sourceSlot = outgoingMove.slot,
Zerotorescue@80 144 targetContainer = firstAvailableSlot.container,
Zerotorescue@80 145 targetSlot = firstAvailableSlot.slot,
Zerotorescue@80 146 });
Zerotorescue@80 147
Zerotorescue@80 148 -- We filled an empty slot so the target contents now has one more item,
Zerotorescue@80 149 -- make a new instance of the ItemMove class so any additional items with this id can be stacked on top of it
Zerotorescue@81 150 local itemMove = addon.ContainerItem:New();
Zerotorescue@82 151 itemMove:AddLocation(firstAvailableSlot.container, firstAvailableSlot.slot, outgoingMove.num);
Zerotorescue@80 152 targetContents[outgoingMove.itemId] = itemMove;
Zerotorescue@80 153
Zerotorescue@81 154 table.remove(emptySlots, 1); -- no longer empty
Zerotorescue@80 155
Zerotorescue@82 156 outgoingMove.num = 0; -- nothing remaining - sanity check
Zerotorescue@80 157 outgoingMove.itemId = nil; -- remove this record from the outgoingMoves-table
Zerotorescue@80 158 end
Zerotorescue@80 159 else
Zerotorescue@80 160 -- Find the maximum stack size for this item
Zerotorescue@80 161 local itemStackCount = select(8, GetItemInfo(outgoingMove.itemId));
Zerotorescue@80 162
Zerotorescue@80 163 -- We want to move to the largest stacks first to keep stuff pretty
Zerotorescue@80 164 table.sort(targetItem.locations, function(a, b)
Zerotorescue@81 165 return a.count > b.count;
Zerotorescue@80 166 end);
Zerotorescue@80 167
Zerotorescue@81 168 for _, itemLocation in pairs(targetItem.locations) do
Zerotorescue@82 169 if itemLocation.count < itemStackCount and outgoingMove.num > 0 then
Zerotorescue@80 170 -- Check if this stack isn't already full (and we still need to move this item)
Zerotorescue@80 171
Zerotorescue@80 172 local remainingSpace = (itemStackCount - itemLocation.count);
Zerotorescue@84 173 if remainingSpace >= outgoingMove.num then
Zerotorescue@80 174 -- Enough room to move this entire stack
Zerotorescue@80 175 -- Deposit this item and then forget this outgoing move as everything in it was processed
Zerotorescue@80 176
Zerotorescue@80 177 table.insert(combinedMoves, {
Zerotorescue@82 178 itemId = outgoingMove.itemId,
Zerotorescue@82 179 num = outgoingMove.num,
Zerotorescue@80 180 sourceContainer = outgoingMove.container,
Zerotorescue@80 181 sourceSlot = outgoingMove.slot,
Zerotorescue@80 182 targetContainer = itemLocation.container,
Zerotorescue@80 183 targetSlot = itemLocation.slot,
Zerotorescue@80 184 });
Zerotorescue@80 185
Zerotorescue@82 186 itemLocation.count = (itemLocation.count + outgoingMove.num);
Zerotorescue@84 187 outgoingMove.num = 0; -- nothing remaining
Zerotorescue@80 188 outgoingMove.itemId = nil; -- remove this record from the outgoingMoves-table
Zerotorescue@80 189 break; -- stop the locations-loop
Zerotorescue@80 190 else
Zerotorescue@80 191 -- Deposit this item but don't remove the outgoing move as there are some items left to move
Zerotorescue@80 192
Zerotorescue@80 193 table.insert(combinedMoves, {
Zerotorescue@82 194 itemId = outgoingMove.itemId,
Zerotorescue@82 195 num = outgoingMove.num,
Zerotorescue@80 196 sourceContainer = outgoingMove.container,
Zerotorescue@80 197 sourceSlot = outgoingMove.slot,
Zerotorescue@80 198 targetContainer = itemLocation.container,
Zerotorescue@80 199 targetSlot = itemLocation.slot,
Zerotorescue@80 200 });
Zerotorescue@80 201
Zerotorescue@80 202 -- The target will be full when we complete, but the source will still have remaining items left to be moved
Zerotorescue@80 203 itemLocation.count = itemStackCount;
Zerotorescue@82 204 outgoingMove.num = (outgoingMove.num - remainingSpace);
Zerotorescue@80 205 end
Zerotorescue@80 206 end
Zerotorescue@80 207 end
Zerotorescue@80 208
Zerotorescue@82 209 if outgoingMove.num > 0 then
Zerotorescue@80 210 -- We went through all matching items and checked their stack sizes if we could move this there, no room available
Zerotorescue@80 211 -- So forget about the target item (even though it may just have full locations, these are useless anyway) and the next loop move it onto an empty slot
Zerotorescue@84 212 targetContents[outgoingMove.itemId] = nil;
Zerotorescue@80 213 end
Zerotorescue@80 214 end
Zerotorescue@80 215 end
Zerotorescue@80 216 end
Zerotorescue@80 217
Zerotorescue@80 218 -- Loop through the array to find items that should be removed, start with the last element or the loop would break
Zerotorescue@80 219 local numOutgoingMoves = #outgoingMoves; -- since LUA-tables start at an index of 1, this is actually an existing index (outgoingMoves[#outgoingMoves] would return a value)
Zerotorescue@80 220 while numOutgoingMoves ~= 0 do
Zerotorescue@80 221 -- A not equal-comparison should be quicker than a larger/smaller than-comparison
Zerotorescue@80 222
Zerotorescue@80 223 -- Check if the item id is nil, this is set to nil when this outgoing move has been processed
Zerotorescue@84 224 if not outgoingMoves[numOutgoingMoves].itemId or outgoingMoves[numOutgoingMoves].num == 0 then
Zerotorescue@80 225 -- Remove this element from the array
Zerotorescue@80 226 table.remove(outgoingMoves, numOutgoingMoves);
Zerotorescue@80 227 end
Zerotorescue@80 228
Zerotorescue@80 229 -- Proceed with the next element (or previous considering we're going from last to first)
Zerotorescue@80 230 numOutgoingMoves = (numOutgoingMoves - 1);
Zerotorescue@80 231 end
Zerotorescue@84 232
Zerotorescue@89 233 addon:Debug("%d moves remaining.", #outgoingMoves);
Zerotorescue@84 234
Zerotorescue@84 235 backup = (backup + 1);
Zerotorescue@84 236 if backup > 1000 then
Zerotorescue@84 237 dump(nil, outgoingMoves);
Zerotorescue@84 238 table.wipe(outgoingMoves);
Zerotorescue@84 239 self:Abort("mover crashed", "Error preparing moves, hit an endless loop");
Zerotorescue@84 240 onFinish();
Zerotorescue@84 241 return;
Zerotorescue@84 242 end
Zerotorescue@80 243 end
Zerotorescue@84 244
Zerotorescue@84 245 -- 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
Zerotorescue@84 246 combinedMoves = table.reverse(combinedMoves);
Zerotorescue@82 247
Zerotorescue@89 248 addon:Debug("%d moves should be possible.", #combinedMoves);
Zerotorescue@80 249
Zerotorescue@80 250 -- No longer needed
Zerotorescue@80 251 table.wipe(emptySlots);
Zerotorescue@80 252
Zerotorescue@81 253 self:ProcessMove();
Zerotorescue@80 254
Zerotorescue@82 255 -- Even though we aren't completely done yet, allow requeueing
Zerotorescue@81 256 onFinish();
Zerotorescue@80 257 end
Zerotorescue@80 258
Zerotorescue@81 259 function mod:ProcessMove()
Zerotorescue@81 260 addon:Debug("ProcessMove");
Zerotorescue@81 261
Zerotorescue@81 262 if #combinedMoves == 0 then
Zerotorescue@81 263 print("Nothing to move.");
Zerotorescue@81 264
Zerotorescue@81 265 self:Abort();
Zerotorescue@81 266
Zerotorescue@81 267 return;
Zerotorescue@81 268 end
Zerotorescue@81 269
Zerotorescue@88 270 --self:RegisterEvent("BAG_UPDATE");
Zerotorescue@88 271 self:RegisterEvent("ITEM_LOCK_CHANGED");
Zerotorescue@81 272 self:RegisterEvent("UI_ERROR_MESSAGE");
Zerotorescue@81 273
Zerotorescue@80 274 -- combinedMoves now has all moves in it (source -> target)
Zerotorescue@80 275 -- go through list, move everything inside it
Zerotorescue@81 276 -- add source and target to lists, if either is already in this list, skip the move
Zerotorescue@81 277 -- repeat every few seconds until we're completely done
Zerotorescue@80 278
Zerotorescue@80 279 local sourceLocationsLocked = {};
Zerotorescue@80 280 local targetLocationsLocked = {};
Zerotorescue@80 281
Zerotorescue@84 282 local _GetContainerItemId = GetContainerItemID;
Zerotorescue@82 283 if movesSource == addon.Locations.Guild then
Zerotorescue@84 284 _GetContainerItemId = function(tabId, slotId) return addon:GetItemID(GetGuildBankItemLink(tabId, slotId)); end;
Zerotorescue@82 285 end
Zerotorescue@89 286 local _GetContainerItemInfo = GetContainerItemInfo;
Zerotorescue@89 287 if movesSource == addon.Locations.Guild then
Zerotorescue@89 288 _GetContainerItemInfo = GetGuildBankItemInfo;
Zerotorescue@89 289 end
Zerotorescue@82 290
Zerotorescue@82 291 local combinedMovesOriginalLength = #combinedMoves;
Zerotorescue@82 292 local numCurrentMove = combinedMovesOriginalLength;
Zerotorescue@80 293 while numCurrentMove ~= 0 do
Zerotorescue@80 294 local move = combinedMoves[numCurrentMove];
Zerotorescue@80 295
Zerotorescue@89 296 local isSourceLocked = ((sourceLocationsLocked[move.sourceContainer] and sourceLocationsLocked[move.sourceContainer][move.sourceSlot]) or select(3, _GetContainerItemInfo(move.sourceContainer, move.sourceSlot)));
Zerotorescue@89 297 local isTargetLocked = ((targetLocationsLocked[move.targetContainer] and targetLocationsLocked[move.targetContainer][move.targetSlot]) or select(3, GetContainerItemInfo(move.targetContainer, move.targetSlot)));
Zerotorescue@88 298
Zerotorescue@89 299 if move and not isSourceLocked and not isTargetLocked then
Zerotorescue@80 300
Zerotorescue@84 301 print(("Moving %dx%s."):format(move.num, IdToItemLink(move.itemId)));
Zerotorescue@80 302
Zerotorescue@89 303 addon:Debug("Moving %dx%s from (%d,%d) to (%d,%d)", move.num, IdToItemLink(move.itemId), move.sourceContainer, move.sourceSlot, move.targetContainer, move.targetSlot);
Zerotorescue@81 304
Zerotorescue@84 305 if _GetContainerItemId(move.sourceContainer, move.sourceSlot) ~= move.itemId then
Zerotorescue@81 306 self:Abort("source changed", "Source (" .. move.sourceContainer .. "," .. move.sourceSlot .. ") is not " .. IdToItemLink(move.itemId));
Zerotorescue@81 307 return;
Zerotorescue@81 308 end
Zerotorescue@81 309
Zerotorescue@80 310 -- Pickup stack
Zerotorescue@81 311 if movesSource == addon.Locations.Bank then
Zerotorescue@81 312 SplitContainerItem(move.sourceContainer, move.sourceSlot, move.num);
Zerotorescue@81 313 elseif movesSource == addon.Locations.Guild then
Zerotorescue@81 314 SplitGuildBankItem(move.sourceContainer, move.sourceSlot, move.num);
Zerotorescue@81 315 end
Zerotorescue@80 316
Zerotorescue@80 317 -- Remember we picked this item up and thus it is now locked
Zerotorescue@80 318 if not sourceLocationsLocked[move.sourceContainer] then
Zerotorescue@80 319 sourceLocationsLocked[move.sourceContainer] = {};
Zerotorescue@80 320 end
Zerotorescue@80 321 sourceLocationsLocked[move.sourceContainer][move.sourceSlot] = true;
Zerotorescue@80 322
Zerotorescue@81 323 if movesSource == addon.Locations.Guild or CursorHasItem() then -- CursorHasItem is always false if source is a guild tab
Zerotorescue@84 324 -- We are moving into our local bags, so the below must check normal
Zerotorescue@84 325 local targetItemId = GetContainerItemID(move.targetContainer, move.targetSlot);
Zerotorescue@84 326 if targetItemId and targetItemId ~= move.itemId then
Zerotorescue@81 327 self:Abort("target changed", "Target (" .. move.targetContainer .. "," .. move.targetSlot .. ") is not " .. IdToItemLink(move.itemId) .. " nor empty");
Zerotorescue@81 328 return;
Zerotorescue@81 329 end
Zerotorescue@81 330
Zerotorescue@82 331 -- And drop it (this is always a local bag so no need to do any guild-checks)
Zerotorescue@80 332 PickupContainerItem(move.targetContainer, move.targetSlot);
Zerotorescue@80 333
Zerotorescue@80 334 -- Remember we dropped an item here and thus this is now locked
Zerotorescue@81 335 if not targetLocationsLocked[move.targetContainer] then
Zerotorescue@81 336 targetLocationsLocked[move.targetContainer] = {};
Zerotorescue@80 337 end
Zerotorescue@81 338 targetLocationsLocked[move.targetContainer][move.targetSlot] = true;
Zerotorescue@80 339
Zerotorescue@80 340 -- This move was processed
Zerotorescue@80 341 table.remove(combinedMoves, numCurrentMove);
Zerotorescue@81 342 else
Zerotorescue@81 343 self:Abort("item disappeared from mouse", "Couldn't move " .. IdToItemLink(move.itemId) .. ", CursorHasItem() is false");
Zerotorescue@81 344 return;
Zerotorescue@80 345 end
Zerotorescue@80 346 end
Zerotorescue@80 347
Zerotorescue@80 348 -- Proceed with the next element (or previous considering we're going from last to first)
Zerotorescue@80 349 numCurrentMove = (numCurrentMove - 1);
Zerotorescue@80 350 end
Zerotorescue@81 351
Zerotorescue@89 352 addon:Debug("%d moves processed. %d moves remaining.", (combinedMovesOriginalLength - #combinedMoves), #combinedMoves);
Zerotorescue@82 353
Zerotorescue@81 354 if #combinedMoves == 0 then
Zerotorescue@81 355 print("Finished.");
Zerotorescue@81 356
Zerotorescue@81 357 self:Abort();
Zerotorescue@81 358
Zerotorescue@81 359 return;
Zerotorescue@81 360 end
Zerotorescue@80 361 end
Zerotorescue@80 362
Zerotorescue@80 363 local tmrProcessNext;
Zerotorescue@88 364 function mod:ITEM_LOCK_CHANGED()
Zerotorescue@81 365 self:CancelTimer(tmrProcessNext, true); -- silent
Zerotorescue@89 366 tmrProcessNext = self:ScheduleTimer("ProcessMove", .5);
Zerotorescue@80 367 end
Zerotorescue@80 368
Zerotorescue@81 369 function IdToItemLink(itemId)
Zerotorescue@81 370 local itemLink = select(2, GetItemInfo(itemId));
Zerotorescue@81 371 itemLink = itemLink or "Unknown (" .. itemId .. ")";
Zerotorescue@81 372 return itemLink;
Zerotorescue@81 373 end
Zerotorescue@81 374
Zerotorescue@81 375 function mod:UI_ERROR_MESSAGE(e, errorMessage)
Zerotorescue@81 376 if errorMessage == ERR_SPLIT_FAILED then
Zerotorescue@81 377 self:Abort("splitting failed", "Splitting failed.");
Zerotorescue@80 378 end
Zerotorescue@80 379 end
Zerotorescue@80 380
Zerotorescue@81 381 function mod:Abort(simple, debugMsg)
Zerotorescue@81 382 if debugMsg then
Zerotorescue@89 383 addon:Debug("Aborting:%s", debugMsg);
Zerotorescue@81 384 end
Zerotorescue@81 385 if simple then
Zerotorescue@81 386 print("|cffff0000Aborting: " .. simple .. ".|r");
Zerotorescue@81 387 end
Zerotorescue@81 388 table.wipe(combinedMoves);
Zerotorescue@81 389 movesSource = nil;
Zerotorescue@80 390
Zerotorescue@81 391 -- Stop timer
Zerotorescue@89 392 self:UnregisterEvent("ITEM_LOCK_CHANGED");
Zerotorescue@81 393 self:CancelTimer(tmrProcessNext, true); -- silent
Zerotorescue@80 394
Zerotorescue@81 395 self:UnregisterEvent("UI_ERROR_MESSAGE");
Zerotorescue@80 396 end
Zerotorescue@80 397
Zerotorescue@80 398 function mod:OnEnable()
Zerotorescue@80 399 Scanner = addon:GetModule("Scanner");
Zerotorescue@80 400 end
Zerotorescue@80 401
Zerotorescue@80 402 function mod:OnDisable()
Zerotorescue@80 403 Scanner = nil;
Zerotorescue@81 404
Zerotorescue@81 405 self:Abort();
Zerotorescue@80 406 end