View Single Post
08/30/15, 09:14 PM   #2
Ayantir
 
Ayantir's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2014
Posts: 1,019
That's how I do in Roomba to stack in stackable bags, it does exactly the same feature as the function :
Little bit modified for the exemple!


Lua Code:
  1. -- Called when user click on the keybind / press the key.
  2.    
  3. local bagToScan = SHARED_INVENTORY:GenerateFullSlotData(nil, bagId)
  4. Roomba.scanInStackableBag(bagToScan)
  5. if NonContiguousCount(Roomba.duplicates) > 0 then Roomba.restackStackableBag(bagId, duplicateList) end
  6.  
  7. -- Scan in a stackable bag
  8. function Roomba.scanInStackableBag(bagToScan)
  9.  
  10.     Roomba.lookUp = {}
  11.     Roomba.duplicates = {}
  12.     local duplitemp = {}
  13.    
  14.     -- We only need to store slots with items
  15.     for index, slot in pairs(bagToScan) do
  16.        
  17.         -- Stack at max?
  18.         local stack, maxStack = GetSlotStackSize(slot.bagId, slot.slotIndex)
  19.        
  20.         -- Stack is not at max
  21.         if stack ~= maxStack then
  22.            
  23.             -- itemId
  24.             local itemInstanceId = slot.itemInstanceId
  25.            
  26.             -- We already find this item before
  27.             if Roomba.lookUp[itemInstanceId] then
  28.                 -- Already marked as duplicate?
  29.                 if not duplitemp[itemInstanceId] then
  30.                     -- Duplicate
  31.                     duplitemp[itemInstanceId] = Roomba.lookUp[itemInstanceId]
  32.                 end
  33.             else
  34.                 -- New item found
  35.                 Roomba.lookUp[itemInstanceId] = {}
  36.             end
  37.            
  38.             -- Now group all items by id
  39.             table.insert(Roomba.lookUp[itemInstanceId], {slot = slot.slotIndex, stack = stack, texture = slot.iconFile, name = slot.name, itemInstanceId = slot.itemInstanceId})
  40.            
  41.         end
  42.        
  43.     end
  44.    
  45.     local i = 1
  46.     for _, data in pairs(duplitemp) do
  47.         Roomba.duplicates[i] = data
  48.         i = i + 1
  49.     end
  50.  
  51. end
  52.  
  53. -- duplicateList is Roomba.duplicates
  54. function Roomba.restackStackableBag(bagId, duplicateList)
  55.  
  56.     local restartAfter = false
  57.     local itemIndex = 0
  58.     local indexItemsDuplicated, dataItems = next(duplicateList)
  59.     local result = {}
  60.    
  61.     -- Loop for item X/Y/Z
  62.     while indexItemsDuplicated do
  63.        
  64.         local index = 1
  65.         local itemInfo = dataItems[index]
  66.         local baseSlot = nil
  67.         local lastMoveWasSingleStack = false
  68.         local lastMoveWasMultiStack = false
  69.         result[indexItemsDuplicated] = {}
  70.        
  71.         -- Loop for item X and slots 1/2/3/y
  72.         while itemInfo do
  73.            
  74.             -- 1st loop : we go in
  75.             if baseSlot == nil then
  76.                 -- Our actual stack / Our max size
  77.                 baseSlot = itemInfo
  78.                 baseSlot.actualStack, baseSlot.maxStack = GetSlotStackSize(bagId, itemInfo.slot)
  79.             else
  80.                
  81.                 local qty
  82.                 -- If stacking, will we get 1 or 2 stacks ?
  83.                 itemInfo.maxStack = baseSlot.maxStack
  84.                
  85.                 if (baseSlot.actualStack + itemInfo.stack) <= baseSlot.maxStack then
  86.                    
  87.                     -- Only 1 stack, we can merge stacks
  88.                     qty = itemInfo.stack
  89.                    
  90.                     -- Merging
  91.                     if IsProtectedFunction("RequestMoveItem") then
  92.                         CallSecureProtected("RequestMoveItem", bagId, itemInfo.slot, bagId, baseSlot.slot, qty)
  93.                     else
  94.                         RequestMoveItem(bagId, itemInfo.slot, bagId, baseSlot.slot, qty)
  95.                     end
  96.                    
  97.                     -- Update values baseSlot can still be used in next loop
  98.                     baseSlot.actualStack = baseSlot.actualStack + itemInfo.stack
  99.                     baseSlot.stack = baseSlot.actualStack
  100.                    
  101.                     if lastMoveWasMultiStack == true then
  102.                         result[indexItemsDuplicated][#result[indexItemsDuplicated]] = baseSlot
  103.                         lastMoveWasSingleStack = true
  104.                         lastMoveWasMultiStack = false
  105.                     elseif lastMoveWasSingleStack == true then
  106.                         result[indexItemsDuplicated][#result[indexItemsDuplicated]] = baseSlot
  107.                         lastMoveWasMultiStack = false
  108.                     else
  109.                         table.insert(result[indexItemsDuplicated], baseSlot)
  110.                         lastMoveWasSingleStack = true
  111.                         lastMoveWasMultiStack = false
  112.                     end
  113.                    
  114.                 else
  115.                    
  116.                     -- It won't fit, just move the qty to match maxStack, no need to rescan because slots don't move, only stacks.
  117.                     qty = baseSlot.maxStack - baseSlot.actualStack
  118.                    
  119.                     -- Merging
  120.                     if IsProtectedFunction("RequestMoveItem") then
  121.                         CallSecureProtected("RequestMoveItem", bagId, itemInfo.slot, bagId, baseSlot.slot, qty)
  122.                     else
  123.                         RequestMoveItem(bagId, itemInfo.slot, bagId, baseSlot.slot, qty)
  124.                     end
  125.                    
  126.                     if lastMoveWasMultiStack == true then
  127.                         result[indexItemsDuplicated][#result[indexItemsDuplicated]].stack = baseSlot.maxStack
  128.                         result[indexItemsDuplicated][#result[indexItemsDuplicated]].actualStack = baseSlot.maxStack
  129.                         table.insert(result[indexItemsDuplicated], itemInfo)
  130.                         result[indexItemsDuplicated][#result[indexItemsDuplicated]].stack = itemInfo.stack - qty
  131.                         result[indexItemsDuplicated][#result[indexItemsDuplicated]].actualStack = itemInfo.stack - qty
  132.                         lastMoveWasSingleStack = false
  133.                     elseif lastMoveWasSingleStack == true then
  134.                         result[indexItemsDuplicated][#result[indexItemsDuplicated]].stack = baseSlot.maxStack
  135.                         result[indexItemsDuplicated][#result[indexItemsDuplicated]].actualStack = baseSlot.maxStack
  136.                         table.insert(result[indexItemsDuplicated], itemInfo)
  137.                         result[indexItemsDuplicated][#result[indexItemsDuplicated]].stack = itemInfo.stack - qty
  138.                         result[indexItemsDuplicated][#result[indexItemsDuplicated]].actualStack = itemInfo.stack - qty
  139.                         lastMoveWasSingleStack = false
  140.                         lastMoveWasMultiStack = true
  141.                     else
  142.                         table.insert(result[indexItemsDuplicated], baseSlot)
  143.                         result[indexItemsDuplicated][#result[indexItemsDuplicated]].stack = baseSlot.maxStack
  144.                         result[indexItemsDuplicated][#result[indexItemsDuplicated]].actualStack = baseSlot.maxStack
  145.                         table.insert(result[indexItemsDuplicated], itemInfo)
  146.                         result[indexItemsDuplicated][#result[indexItemsDuplicated]].stack = itemInfo.stack - qty
  147.                         result[indexItemsDuplicated][#result[indexItemsDuplicated]].actualStack = itemInfo.stack - qty
  148.                         lastMoveWasSingleStack = false
  149.                         lastMoveWasMultiStack = true
  150.                     end
  151.                    
  152.                     -- Baseslot is now at max, we cannot use it anymore
  153.                     baseSlot = itemInfo
  154.                     baseSlot.actualStack = itemInfo.stack - qty
  155.                    
  156.                 end
  157.                
  158.             end
  159.            
  160.             index = index + 1
  161.             itemInfo = dataItems[index]
  162.        
  163.         end
  164.        
  165.         itemIndex = itemIndex + 1
  166.         indexItemsDuplicated, dataItems = next(duplicateList, itemIndex)
  167.        
  168.     end
  169.    
  170.     -- Rescan to permit the user press the keybind again. Because Bank got a lag, we need to call Roomba.onBankReady() and its zo_callLater to avoid having our restacking job still unknown
  171.     if bagId == BAG_BANK then
  172.         Roomba.onBankReady()
  173.     -- Only on restacking bag
  174.     elseif bagId == BAG_BACKPACK then
  175.         Roomba.onSceneStateChange(SCENE_HIDDEN, SCENE_SHOWING)
  176.     end
  177.    
  178. end

Last edited by Ayantir : 08/30/15 at 09:19 PM.
  Reply With Quote