diff --git a/TradeSkillMaster/TradeSkillMaster.lua b/TradeSkillMaster/TradeSkillMaster.lua index 56a4684..b160331 100644 --- a/TradeSkillMaster/TradeSkillMaster.lua +++ b/TradeSkillMaster/TradeSkillMaster.lua @@ -738,6 +738,9 @@ function TSMAPI:GetItemPrices(itemLink) -- Use TSM:GetCustomPrice to get smartAvgBuy price prices.smartAvgBuy = TSM:GetCustomPrice("smartAvgBuy", itemString) or 0 + -- Use TSM:GetCustomPrice to get lastBuy price + prices.lastBuy = TSM:GetCustomPrice("lastBuy", itemString) or 0 + -- Use TSM:GetCustomPrice to get avgSell price prices.avgSell = TSM:GetCustomPrice("avgSell", itemString) or 0 diff --git a/TradeSkillMaster/TradeSkillMaster.toc b/TradeSkillMaster/TradeSkillMaster.toc index b95eba2..910d7ab 100644 --- a/TradeSkillMaster/TradeSkillMaster.toc +++ b/TradeSkillMaster/TradeSkillMaster.toc @@ -2,7 +2,7 @@ ## Title: |cff00fe00TradeSkillMaster: Revived|r ## Notes: Core addon for the TradeSkillMaster suite, revived for Wrath of the Lich King. Does nothing without modules installed. ## Author: Sapu94, Bart39, Gnomezilla [Warmane-Icecrown(A)], BlueAo [Warmane], andrew6180, Yoshiyuka, DimaSheiko, and other contributors... -## Version: 2.3.27 +## Version: 2.3.29 ## SavedVariables: TradeSkillMasterAppDB, AscensionTSMDB ## OptionalDeps: AccurateTime, Ace3, LibDataBroker-1.1, LibDBIcon-1.0, LibExtraTip, TipHelper, LibParse, LibCompress, LibGraph-2.0, SharedMedia, TheUndermineJournal, TheUndermineJournalGE ## X-Embeds: AccurateTime, Ace3, LibDataBroker-1.1, LibDBIcon-1.0, LibExtraTip, TipHelper, LibParse, LibCompress, LibGraph-2.0 diff --git a/TradeSkillMaster_AuctionDB/TradeSkillMaster_AuctionDB.toc b/TradeSkillMaster_AuctionDB/TradeSkillMaster_AuctionDB.toc index aa9b995..811245a 100644 --- a/TradeSkillMaster_AuctionDB/TradeSkillMaster_AuctionDB.toc +++ b/TradeSkillMaster_AuctionDB/TradeSkillMaster_AuctionDB.toc @@ -2,10 +2,10 @@ ## Title: |cff00ff00TradeSkillMaster_AuctionDB|r ## Notes: Stores auction house data and calculates market prices. ## Author: Sapu94, Bart39 -## Version: 2.3.27 +## Version: 2.3.29 ## SavedVariables: AscensionTSM_AuctionDB ## Dependency: TradeSkillMaster -## X-Curse-Packaged-Version: 2.3.27 +## X-Curse-Packaged-Version: 2.3.29 ## X-Curse-Project-Name: TradeSkillMaster_AuctionDB ## X-Curse-Project-ID: tradeskillmaster_auctiondb ## X-Curse-Repository-ID: wow/tradeskillmaster_auctiondb/mainline diff --git a/TradeSkillMaster_Crafting/Modules/CraftingGUI.lua b/TradeSkillMaster_Crafting/Modules/CraftingGUI.lua index 0a6f9c5..645cc16 100644 --- a/TradeSkillMaster_Crafting/Modules/CraftingGUI.lua +++ b/TradeSkillMaster_Crafting/Modules/CraftingGUI.lua @@ -2834,7 +2834,7 @@ function GUI:UpdateGathering() if task.taskType == L["Search for Mats"] then availQty = taskQuantity end - if task.taskType == L["Mail Items"] then + if task.taskType == L["Mail Items"] or task.taskType == L["Collect Mail"] then availQty = min(need, taskQuantity) elseif not crafter == UnitName("player") then availQty = min(need, taskQuantity) - (playerBags[itemString] or 0) @@ -2878,16 +2878,18 @@ function GUI:UpdateGathering() TSM.db.realm.gathering.availableMats = CopyTable(availableMats) GUI.gatheringFrame.gatherButton:SetText(L["Gather Items"]) - if next(stData) then - GUI.gatheringFrame.gatherButton:Enable() - if private.currentTask == L["Visit Vendor"] then - GUI.gatheringFrame.gatherButton:SetText(L["Buy Vendor Items"]) - elseif private.currentTask == L["Mail Items"] then - GUI.gatheringFrame.gatherButton:SetText(L["Mail Items"]) + if next(stData) then + GUI.gatheringFrame.gatherButton:Enable() + if private.currentTask == L["Visit Vendor"] then + GUI.gatheringFrame.gatherButton:SetText(L["Buy Vendor Items"]) + elseif private.currentTask == L["Mail Items"] then + GUI.gatheringFrame.gatherButton:SetText(L["Mail Items"]) + elseif private.currentTask == L["Collect Mail"] then + GUI.gatheringFrame.gatherButton:SetText(L["Collect Mail"]) + end + else + GUI.gatheringFrame.gatherButton:Disable() end - else - GUI.gatheringFrame.gatherButton:Disable() - end sort(stData, function(a, b) return a.name < b.name end) GUI.gatheringFrame.availableST:SetData(stData) @@ -2919,7 +2921,12 @@ function GUI:GatheringEventHandler(event) GUI.gatheringFrame.gatherButton:Disable() elseif event == "MAIL_SHOW" then private.currentSource = UnitName("player") - private.currentTask = L["Mail Items"] + local crafter = TSM.db.realm.gathering.crafter + if crafter and crafter == UnitName("player") then + private.currentTask = L["Collect Mail"] + else + private.currentTask = L["Mail Items"] + end elseif event == "MAIL_CLOSED" then private.currentSource = nil private.currentTask = nil diff --git a/TradeSkillMaster_Crafting/Modules/Gather.lua b/TradeSkillMaster_Crafting/Modules/Gather.lua index 6f603f0..64e0ccd 100644 --- a/TradeSkillMaster_Crafting/Modules/Gather.lua +++ b/TradeSkillMaster_Crafting/Modules/Gather.lua @@ -36,6 +36,8 @@ function Gather:gatherItems(source, task) Gather:BuyFromMerchant(items) elseif source == UnitName("player") and (task == L["Visit Bank"] or task == L["Visit Guild Bank"]) then Gather:GatherBank(items) + elseif source == UnitName("player") and task == L["Collect Mail"] then + TSMAPI:ModuleAPI("Mailing", "collectItems", items, Gather.PrintMsg) elseif source == UnitName("player") and task == L["Mail Items"] then Gather:MailItems(items) elseif source == L["Auction House"] then @@ -185,4 +187,4 @@ function Gather:ShoppingSearch(itemString, need, ignoreMaxQty) TSMAPI:ModuleAPI("Shopping", "runSearch", TSMAPI:GetSafeItemInfo(itemString) .. "/exact/x" .. need, ShoppingCallback) end end -end \ No newline at end of file +end diff --git a/TradeSkillMaster_Mailing/Modules/Inbox.lua b/TradeSkillMaster_Mailing/Modules/Inbox.lua index 321b29f..f19b70f 100644 --- a/TradeSkillMaster_Mailing/Modules/Inbox.lua +++ b/TradeSkillMaster_Mailing/Modules/Inbox.lua @@ -436,6 +436,102 @@ function private:StartAutoLooting(mode) private:AutoLoot() end +local function CanLootItem(itemString, quantity) + if not itemString or not quantity then return false end + local maxStack = select(8, TSMAPI:GetSafeItemInfo(itemString)) + local hasPartial = false + local hasEmpty = false + local totalFreeSlots = 0 + + for bag = 0, NUM_BAG_SLOTS do + if TSMAPI:ItemWillGoInBag(itemString, bag) then + totalFreeSlots = totalFreeSlots + (GetContainerNumFreeSlots(bag) or 0) + for slot = 1, GetContainerNumSlots(bag) do + local iLink = GetContainerItemLink(bag, slot) + if iLink then + if TSMAPI:GetItemString(iLink) == itemString and maxStack then + local stackSize = select(2, GetContainerItemInfo(bag, slot)) + if stackSize and (maxStack - stackSize) >= quantity then + hasPartial = true + end + end + else + hasEmpty = true + end + end + end + end + + if hasPartial then + return true + end + if not hasEmpty then + return false + end + if TSM.db.global.keepMailSpace and TSM.db.global.keepMailSpace > 0 then + return (totalFreeSlots - 1) >= TSM.db.global.keepMailSpace + end + return true +end + +local function HasFittableStack(itemString, needed) + if not itemString or not needed or needed <= 0 then return false end + for i = 1, GetInboxNumItems() do + local _, _, _, _, _, cod, _, hasItem = GetInboxHeaderInfo(i) + if hasItem and hasItem > 0 and (not cod or cod == 0) then + for j = 1, hasItem do + local itemLink = GetInboxItemLink(i, j) + if itemLink and TSMAPI:GetItemString(itemLink) == itemString then + local quantity = select(3, GetInboxItem(i, j)) or 0 + if quantity > 0 and quantity <= needed then + return true + end + end + end + end + end + return false +end + +function Inbox:CollectItems(items, callback) + if not items or not next(items) then return end + if not MailFrame or not MailFrame:IsShown() then return end + + local remaining = CopyTable(items) + local collected = false + for i = GetInboxNumItems(), 1, -1 do + local _, _, _, _, _, cod, _, hasItem = GetInboxHeaderInfo(i) + if hasItem and hasItem > 0 and (not cod or cod == 0) then + for j = hasItem, 1, -1 do + local itemLink = GetInboxItemLink(i, j) + local itemString = itemLink and TSMAPI:GetItemString(itemLink) + local need = itemString and remaining[itemString] + if need and need > 0 then + local quantity = select(3, GetInboxItem(i, j)) or 0 + if quantity > 0 and (quantity <= need or not HasFittableStack(itemString, need)) then + if CanLootItem(itemString, quantity) then + TakeInboxItem(i, j) + remaining[itemString] = max(need - quantity, 0) + collected = true + elseif callback then + callback(L["Cannot finish auto looting, inventory is full or too many unique items."]) + return + end + end + end + end + end + end + + -- Keep looting as new mail indexes shift, while preserving 1 free slot. + if collected then + TSMAPI:CreateTimeDelay("craftingGatherMailLoop", 0.4, function() + Inbox:CollectItems(remaining, callback) + end) + end + +end + function private:AutoLoot() TSMAPI:CancelFrame("mailSkipDelay") diff --git a/TradeSkillMaster_Mailing/TradeSkillMaster_Mailing.lua b/TradeSkillMaster_Mailing/TradeSkillMaster_Mailing.lua index a38b8b1..6f7b5b3 100644 --- a/TradeSkillMaster_Mailing/TradeSkillMaster_Mailing.lua +++ b/TradeSkillMaster_Mailing/TradeSkillMaster_Mailing.lua @@ -62,6 +62,7 @@ function TSM:RegisterModule() TSM.operations = {maxOperations=12, callbackOptions="Options:Load", callbackInfo="GetOperationInfo"} TSM.moduleAPIs = { {key="mailItems", callback="AutoMail:SendItems"}, + {key="collectItems", callback="Inbox:CollectItems"}, } TSMAPI:NewModule(TSM) @@ -89,4 +90,4 @@ function TSM:GetOperationInfo(operationName) else return format(L["Mailing all to %s."], operation.target) end -end \ No newline at end of file +end