12-14-19, 08:45 AM | #1 |
Inventory Sorting
Hey,
would like to test the idea of sorting items in bag depending on vendor price. Any tips? I think I know a way to loop through inventory, but I do not know how to swap slots in bag. I'm a total newbie to XML/LUA/WoW, but can I for example put all items in a List and sort the list depending on Vendor price, before I put item out in the correct order? Item will swap order in bag while that is being done, so I don't know how that would work either Help or link to APIs that can be helpful is appreciated Last edited by loff93 : 12-14-19 at 08:52 AM. |
|
12-14-19, 02:26 PM | #2 | |
You might want to check out PickupContainerItem().
You'll have to apply the sort in multiple stages since the items will become "locked" once you attempt to swap them. The swapping itself doesn't actually occur until the server responds. When doing each pass, you can keep track which slots you've put into a locked state and work on the others simultaneously. This'll make the overall process quicker as waiting for the server to catch up can consume a lot of time.
__________________
WoWInterface AddOns
Last edited by SDPhantom : 12-14-19 at 02:33 PM. |
||
12-14-19, 03:44 PM | #3 | |
|
||
12-15-19, 05:33 AM | #4 |
Hello again!
I tried a lot of different things. I got some help from people on discord and this is my current result. It doesn't work 100%. I believe the issue is that slots ain't updated if they are moved, so they might try to move even if they are at the correct spot, or trade spot with a item that is at the correct spot. Example of issue: First Slot A updates: Slot A <-> Slot B Then its Slot B's turn Slot B <-> Slot A Any tips on how to sort this better to avoid this kind of behavior? - Couple other issues I haven't done much about: Currently its only for main bag. What if a item swap with another and they merge? Will that break something Code:
local AllItems = {} local waitTable = {} local function PrintAll() -- Debugging only, Ignore this print('------') for i = table.getn(AllItems), 1, -1 do print(AllItems[i].itemName, AllItems[i].itemSellPrice) end print('------') end local function GetAllItemsFromBag(Insert) -- for slot=0, NUM_BAG_SLOTS do for index=1, GetContainerNumSlots(0) do local item = GetContainerItemID(0, index) if(item) then --print(item) local _, _, _, _, _, _, _, _, _, itemID = GetContainerItemInfo(0, index) if(itemID ~= nil) then --print(itemID) local itemName, _, _, _, _, _, _, _, _, _, itemSellPrice = GetItemInfo(itemID) table.insert(Insert, {index = index, itemID = itemID, itemSellPrice = itemSellPrice, itemName = itemName}) end end end -- end end local function SaferSwapItems(bag1, bag2, slot1, slot2) ClearCursor() print(slot1, 'To', slot2) local _, _, locked1 = GetContainerItemInfo(bag1, slot1) local _, _, locked2 = GetContainerItemInfo(bag2, slot2) if(locked1 or locked2) then print(bag1, bag2, slot1, slot2) table.insert(waitTable, {bag1 = bag1, bag2 = bag2, slot1 = slot1, slot2 = slot2}) else --print("Swapping bag", bag1, "slot", slot1, "......for bag", bag2, "slot", slot2) PickupContainerItem(bag1, slot1) PickupContainerItem(bag2, slot2) end end local function SortBag() local bagNr = 0 for i = table.getn(AllItems), 1, -1 do local currentTable = AllItems[i] print(currentTable.itemName , 'CurSlot', currentTable.index ,'TargetSlot', i) SaferSwapItems(0,0, currentTable.index, i) end end local frame = CreateFrame("FRAME", "FooAddonFrame"); local button local ntex local htex local ptex local function ADDON_LOADED() button = CreateFrame("Button", nil, UIParent) button:SetPoint("CENTER") button:SetWidth(100) button:SetHeight(25) button:SetText("Sort") button:SetNormalFontObject("GameFontNormal") ntex = button:CreateTexture() ntex:SetTexture("Interface/Buttons/UI-Panel-Button-Up") ntex:SetTexCoord(0, 0.625, 0, 0.6875) ntex:SetAllPoints() button:SetNormalTexture(ntex) htex = button:CreateTexture() htex:SetTexture("Interface/Buttons/UI-Panel-Button-Highlight") htex:SetTexCoord(0, 0.625, 0, 0.6875) htex:SetAllPoints() button:SetHighlightTexture(htex) ptex = button:CreateTexture() ptex:SetTexture("Interface/Buttons/UI-Panel-Button-Down") ptex:SetTexCoord(0, 0.625, 0, 0.6875) ptex:SetAllPoints() button:SetPushedTexture(ptex) button:SetScript("OnClick", function() AllItems = {} GetAllItemsFromBag(AllItems) table.sort(AllItems, function(i, k) return i.itemSellPrice > k.itemSellPrice end) SortBag() end) end local function ITEM_LOCK_CHANGED(self, event, ...) if table.getn(waitTable) > 0 then local currentTable = waitTable[1] C_Timer.After(0.5, function() SaferSwapItems(currentTable.bag1, currentTable.bag2, currentTable.slot1, currentTable.slot2) end) waitTable = table.remove(waitTable, 1) end end local Events = { ["ADDON_LOADED"] = ADDON_LOADED, ["ITEM_LOCK_CHANGED"] = ITEM_LOCK_CHANGED } local function eventHandler(self, event, ...) if(Events[event]) then Events[event](...) end end frame:RegisterEvent("ADDON_LOADED") frame:RegisterEvent("ITEM_LOCK_CHANGED"); frame:SetScript("OnEvent", eventHandler); |
|
12-15-19, 11:31 PM | #5 | |
ITEM_LOCK_CHANGED fires when the lock state changes. BAG_UPDATE_DELAYED is what fires when items are added/deleted/moved in the bags.
__________________
WoWInterface AddOns
|
||
12-16-19, 08:47 AM | #6 | |
the swapping script is not working correctly thought and I'm not sure how I'm gonna fix this. Example: I have to click multiple times for items to get to the correct spot at times, and sometime it just won't help. I know why this happens, but I don't know how to get around it yet. Trying to think of ways to swap them around, but I'm so new to Lua/WoW it's hard to think of something Will update if I find a solution *UPDATE* This work as far as I can tell. Is it pretty? Not at all Tips to improve is appreciated. Code:
local AllItems = {} local waitTable = {} local function PrintAll() -- Debugging only, Ignore this print('------') for i = table.getn(AllItems), 1, -1 do print(AllItems[i].itemName, AllItems[i].itemSellPrice) end print('------') end local function GetAllItemsFromBag() for bagnr = 0, NUM_BAG_SLOTS do for slotnr=1, GetContainerNumSlots(bagnr) do local item = GetContainerItemID(bagnr, slotnr) if(item) then --print(item) local _, _, _, _, _, _, _, _, _, itemID = GetContainerItemInfo(bagnr, slotnr) --if(itemID ~= nil) then --print(itemID) local itemName, _, _, _, _, _, _, _, _, _, itemSellPrice = GetItemInfo(itemID) table.insert(AllItems, {index = slotnr, itemID = itemID, itemSellPrice = itemSellPrice, itemName = itemName, targetSlot = 0, targetBag = 0}) --print(itemName, index) --end end end end end local function GetSlotNr(bagnr, item) for index=1, GetContainerNumSlots(bagnr) do local _, _, _, _, _, _, _, _, _, itemID = GetContainerItemInfo(bagnr, index) if(item.itemID == itemID) then return index; end end end local function GetBagNr(theItem) for bagnr = 0, NUM_BAG_SLOTS do for slotnr=1, GetContainerNumSlots(bagnr) do local item = GetContainerItemID(bagnr, slotnr) if(item) then local _, _, _, _, _, _, _, _, _, itemID = GetContainerItemInfo(bagnr, slotnr) if(theItem.itemID == itemID) then return bagnr end end end end end local function SaferSwapItems(item) ClearCursor() local bag1 = GetBagNr(item); local bag2 = item.targetBag; local slot1 = GetSlotNr(bag1, item) local slot2 = item.targetSlot if(item.itemID == 11584) then print(bag1, bag2, slot1, slot2) print(item.itemName,': Move From Bag',bag1,'Slot' , slot1, 'To Bag',bag2, 'Slot', slot2) end local _, _, locked1 = GetContainerItemInfo(bag1, slot1) local _, _, locked2 = GetContainerItemInfo(bag2, slot2) if(locked1 or locked2) then table.insert(waitTable, {itemID = item.itemID, itemName = item.itemName, targetSlot = item.targetSlot, targetBag = item.targetBag}) else PickupContainerItem(bag1, slot1) PickupContainerItem(bag2, slot2) end end local function SortBag() local bagNr = 0 for i = 1, table.getn(AllItems) do local currentItem = AllItems[i] SaferSwapItems(currentItem) end end local function GetSlotInBag(index) local currentTotalSlot = 0 for bagnr = 0, NUM_BAG_SLOTS do for slotnr = 1, GetContainerNumSlots(bagnr) do currentTotalSlot = currentTotalSlot + 1 if(index == currentTotalSlot) then return slotnr end end end end local function SetTargetSlot() for i = 1, table.getn(AllItems) do local currentItem = AllItems[i] currentItem.targetSlot = GetSlotInBag(i) print(currentItem.targetSlot) end end local function GetBag(index) local currentTotalSlot = 0 for bagnr = 0, NUM_BAG_SLOTS do for slotnr = 1, GetContainerNumSlots(bagnr) do currentTotalSlot = currentTotalSlot + 1 if(index == currentTotalSlot) then return bagnr end end end end local function SetTargetBag() for i = 1, table.getn(AllItems) do AllItems[i].targetBag = GetBag(i) --print(AllItems[i].itemName,'bag:', AllItems[i].targetBag) end end local function BAG_UPDATE_DELAYED(self, event, ...) if table.getn(waitTable) > 0 then local currentItem = waitTable[1] C_Timer.After(0.2, function() SaferSwapItems(currentItem) end) waitTable = table.remove(waitTable, 1) end end local frame = CreateFrame("FRAME", "FooAddonFrame"); local button local ntex local htex local ptex local function ADDON_LOADED() button = CreateFrame("Button", nil, UIParent) button:SetPoint("CENTER") button:SetWidth(100) button:SetHeight(25) button:SetText("Sort") button:SetNormalFontObject("GameFontNormal") ntex = button:CreateTexture() ntex:SetTexture("Interface/Buttons/UI-Panel-Button-Up") ntex:SetTexCoord(0, 0.625, 0, 0.6875) ntex:SetAllPoints() button:SetNormalTexture(ntex) htex = button:CreateTexture() htex:SetTexture("Interface/Buttons/UI-Panel-Button-Highlight") htex:SetTexCoord(0, 0.625, 0, 0.6875) htex:SetAllPoints() button:SetHighlightTexture(htex) ptex = button:CreateTexture() ptex:SetTexture("Interface/Buttons/UI-Panel-Button-Down") ptex:SetTexCoord(0, 0.625, 0, 0.6875) ptex:SetAllPoints() button:SetPushedTexture(ptex) button:SetScript("OnClick", function() AllItems = {} GetAllItemsFromBag() table.sort(AllItems, function(i, k) return i.itemSellPrice > k.itemSellPrice end) SetTargetBag() SetTargetSlot() --PrintAll() SortBag() end) end local Events = { ["ADDON_LOADED"] = ADDON_LOADED, ["BAG_UPDATE_DELAYED"] = BAG_UPDATE_DELAYED } local function eventHandler(self, event, ...) if(Events[event]) then Events[event](...) end end frame:RegisterEvent("ADDON_LOADED") frame:RegisterEvent("BAG_UPDATE_DELAYED"); frame:SetScript("OnEvent", eventHandler); Everything works, but 1 issue is that if I have multiple of the same items it and calculcate total price of itemcount * sellprice, it doesn't care what stack the orders are in Last edited by loff93 : 12-16-19 at 01:15 PM. |
||
WoWInterface » Developer Discussions » Lua/XML Help » Inventory Sorting |
«
Previous Thread
|
Next Thread
»
|
Display Modes |
Linear Mode |
Switch to Hybrid Mode |
Switch to Threaded Mode |
|
|