annotate Modules/Mover.lua @ 101:6ae44d372360

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