initial commit

This commit is contained in:
Gitea
2020-11-13 14:13:12 -05:00
commit 05df49ff60
368 changed files with 128754 additions and 0 deletions

View File

@@ -0,0 +1,123 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local _, TSM = ...
local Auctioning = TSM.Banking:NewPackage("Auctioning")
local TempTable = TSM.Include("Util.TempTable")
local BagTracking = TSM.Include("Service.BagTracking")
local Inventory = TSM.Include("Service.Inventory")
local private = {}
-- ============================================================================
-- Module Functions
-- ============================================================================
function Auctioning.MoveGroupsToBank(callback, groups)
local items = TempTable.Acquire()
TSM.Banking.Util.PopulateGroupItemsFromBags(items, groups, private.GroupsGetNumToMoveToBank)
TSM.Banking.MoveToBank(items, callback)
TempTable.Release(items)
end
function Auctioning.PostCapToBags(callback, groups)
local items = TempTable.Acquire()
TSM.Banking.Util.PopulateGroupItemsFromOpenBank(items, groups, private.GetNumToMoveToBags)
TSM.Banking.MoveToBag(items, callback)
TempTable.Release(items)
end
function Auctioning.ShortfallToBags(callback, groups)
local items = TempTable.Acquire()
TSM.Banking.Util.PopulateGroupItemsFromOpenBank(items, groups, private.GetNumToMoveToBags, true)
TSM.Banking.MoveToBag(items, callback)
TempTable.Release(items)
end
function Auctioning.MaxExpiresToBank(callback, groups)
local items = TempTable.Acquire()
TSM.Banking.Util.PopulateGroupItemsFromBags(items, groups, private.MaxExpiresGetNumToMoveToBank)
TSM.Banking.MoveToBank(items, callback)
TempTable.Release(items)
end
-- ============================================================================
-- Private Helper Functions
-- ============================================================================
function private.GroupsGetNumToMoveToBank(itemString, numHave)
-- move everything
return numHave
end
function private.GetNumToMoveToBags(itemString, numHave, includeAH)
local totalNumToMove = 0
local numAvailable = numHave
local numInBags = BagTracking.CreateQueryBagsItem(itemString)
:VirtualField("autoBaseItemString", "string", TSM.Groups.TranslateItemString, "itemString")
:Equal("autoBaseItemString", itemString)
:SumAndRelease("quantity") or 0
if includeAH then
numInBags = numInBags + select(3, Inventory.GetPlayerTotals(itemString)) + Inventory.GetMailQuantity(itemString)
end
for _, _, operationSettings in TSM.Operations.GroupOperationIterator("Auctioning", TSM.Groups.GetPathByItem(itemString)) do
local maxExpires = TSM.Auctioning.Util.GetPrice("maxExpires", operationSettings, itemString)
local operationHasExpired = false
if maxExpires and maxExpires > 0 then
local numExpires = TSM.Accounting.Auctions.GetNumExpiresSinceSale(itemString)
if numExpires and numExpires > maxExpires then
operationHasExpired = true
end
end
local postCap = TSM.Auctioning.Util.GetPrice("postCap", operationSettings, itemString)
local stackSize = (TSM.IsWowClassic() and TSM.Auctioning.Util.GetPrice("stackSize", operationSettings, itemString)) or (not TSM.IsWowClassic() and 1)
if not operationHasExpired and postCap and stackSize then
local numNeeded = stackSize * postCap
if numInBags > numNeeded then
-- we can satisfy this operation from the bags
numInBags = numInBags - numNeeded
numNeeded = 0
elseif numInBags > 0 then
-- we can partially satisfy this operation from the bags
numNeeded = numNeeded - numInBags
numInBags = 0
end
local numToMove = min(numAvailable, numNeeded)
if numToMove > 0 then
numAvailable = numAvailable - numToMove
totalNumToMove = totalNumToMove + numToMove
end
end
end
return totalNumToMove
end
function private.MaxExpiresGetNumToMoveToBank(itemString, numHave)
local numToKeepInBags = 0
for _, _, operationSettings in TSM.Operations.GroupOperationIterator("Auctioning", TSM.Groups.GetPathByItem(itemString)) do
local maxExpires = TSM.Auctioning.Util.GetPrice("maxExpires", operationSettings, itemString)
local operationHasExpired = false
if maxExpires and maxExpires > 0 then
local numExpires = TSM.Accounting.Auctions.GetNumExpiresSinceSale(itemString)
if numExpires and numExpires > maxExpires then
operationHasExpired = true
end
end
local postCap = TSM.Auctioning.Util.GetPrice("postCap", operationSettings, itemString)
local stackSize = (TSM.IsWowClassic() and TSM.Auctioning.Util.GetPrice("stackSize", operationSettings, itemString)) or (not TSM.IsWowClassic() and 1)
if not operationHasExpired and postCap and stackSize then
numToKeepInBags = numToKeepInBags + stackSize * postCap
end
end
return max(numHave - numToKeepInBags, 0)
end

View File

@@ -0,0 +1,321 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local _, TSM = ...
local Banking = TSM:NewPackage("Banking")
local Event = TSM.Include("Util.Event")
local TempTable = TSM.Include("Util.TempTable")
local String = TSM.Include("Util.String")
local Log = TSM.Include("Util.Log")
local ItemString = TSM.Include("Util.ItemString")
local Threading = TSM.Include("Service.Threading")
local ItemInfo = TSM.Include("Service.ItemInfo")
local private = {
moveThread = nil,
moveItems = {},
restoreItems = {},
restoreFrame = nil,
callback = nil,
openFrame = nil,
frameCallbacks = {},
}
local MOVE_WAIT_TIMEOUT = 2
-- ============================================================================
-- Module Functions
-- ============================================================================
function Banking.OnInitialize()
private.moveThread = Threading.New("BANKING_MOVE", private.MoveThread)
Event.Register("BANKFRAME_OPENED", private.BankOpened)
Event.Register("BANKFRAME_CLOSED", private.BankClosed)
if not TSM.IsWowClassic() then
Event.Register("GUILDBANKFRAME_OPENED", private.GuildBankOpened)
Event.Register("GUILDBANKFRAME_CLOSED", private.GuildBankClosed)
end
end
function Banking.RegisterFrameCallback(callback)
tinsert(private.frameCallbacks, callback)
end
function Banking.IsGuildBankOpen()
return private.openFrame == "GUILD_BANK"
end
function Banking.IsBankOpen()
return private.openFrame == "BANK"
end
function Banking.MoveToBag(items, callback)
assert(private.openFrame)
local context = Banking.IsGuildBankOpen() and Banking.MoveContext.GetGuildBankToBag() or Banking.MoveContext.GetBankToBag()
private.StartMove(items, context, callback)
end
function Banking.MoveToBank(items, callback)
assert(private.openFrame)
local context = Banking.IsGuildBankOpen() and Banking.MoveContext.GetBagToGuildBank() or Banking.MoveContext.GetBagToBank()
private.StartMove(items, context, callback)
end
function Banking.EmptyBags(callback)
assert(private.openFrame)
local items = TempTable.Acquire()
for _, _, _, itemString, quantity in Banking.Util.BagIterator(false) do
items[itemString] = (items[itemString] or 0) + quantity
end
wipe(private.restoreItems)
private.restoreFrame = private.openFrame
private.callback = callback
local context = Banking.IsGuildBankOpen() and Banking.MoveContext.GetBagToGuildBank() or Banking.MoveContext.GetBagToBank()
private.StartMove(items, context, private.EmptyBagsThreadCallbackWrapper)
TempTable.Release(items)
end
function Banking.RestoreBags(callback)
assert(private.openFrame)
assert(Banking.CanRestoreBags())
private.callback = callback
local context = Banking.IsGuildBankOpen() and Banking.MoveContext.GetGuildBankToBag() or Banking.MoveContext.GetBankToBag()
private.StartMove(private.restoreItems, context, private.RestoreBagsThreadCallbackWrapper)
end
function Banking.CanRestoreBags()
assert(private.openFrame)
return private.openFrame == private.restoreFrame
end
function Banking.PutByFilter(filterStr)
if not private.openFrame then
return
end
local filterItemString = ItemString.Get(filterStr)
filterStr = String.Escape(strlower(filterStr))
local items = TempTable.Acquire()
for _, _, _, itemString, quantity in Banking.Util.BagIterator(false) do
items[itemString] = (items[itemString] or 0) + quantity
end
for itemString in pairs(items) do
if not private.MatchesFilter(itemString, filterStr, filterItemString) then
-- remove this item
items[itemString] = nil
end
end
Banking.MoveToBank(items, private.GetPutCallback)
TempTable.Release(items)
end
function Banking.GetByFilter(filterStr)
if not private.openFrame then
return
end
local filterItemString = ItemString.Get(filterStr)
filterStr = String.Escape(strlower(filterStr))
local items = TempTable.Acquire()
for _, _, _, itemString, quantity in Banking.Util.OpenBankIterator(false) do
items[itemString] = (items[itemString] or 0) + quantity
end
for itemString in pairs(items) do
if not private.MatchesFilter(itemString, filterStr, filterItemString) then
-- remove this item
items[itemString] = nil
end
end
Banking.MoveToBag(items, private.GetPutCallback)
TempTable.Release(items)
end
-- ============================================================================
-- Threads
-- ============================================================================
function private.MoveThread(context, callback)
local numMoves = 0
local emptySlotIds = Threading.AcquireSafeTempTable()
context:GetEmptySlotsThreaded(emptySlotIds)
local slotIds = Threading.AcquireSafeTempTable()
local slotItemString = Threading.AcquireSafeTempTable()
local slotMoveQuantity = Threading.AcquireSafeTempTable()
local slotEndQuantity = Threading.AcquireSafeTempTable()
for itemString, numQueued in pairs(private.moveItems) do
for _, slotId, quantity in context:SlotIdIterator(itemString) do
if numQueued > 0 then
-- find a suitable empty slot
local targetSlotId = context:GetTargetSlotId(itemString, emptySlotIds)
if targetSlotId then
assert(not slotIds[slotId])
slotIds[slotId] = targetSlotId
slotItemString[slotId] = itemString
slotMoveQuantity[slotId] = min(quantity, numQueued)
slotEndQuantity[slotId] = max(quantity - numQueued, 0)
numQueued = numQueued - slotMoveQuantity[slotId]
numMoves = numMoves + 1
else
Log.Err("No target slot")
end
end
end
if numQueued > 0 then
Log.Err("No slots with item (%s)", itemString)
end
end
local numDone = 0
while next(slotIds) do
local movedSlotId = nil
-- do all the pending moves
for slotId, targetSlotId in pairs(slotIds) do
context:MoveSlot(slotId, targetSlotId, slotMoveQuantity[slotId])
Threading.Yield()
if private.openFrame == "GUILD_BANK" then
movedSlotId = slotId
break
end
end
-- wait for at least one to finish or the timeout to elapse
local didMove = false
local timeout = GetTime() + MOVE_WAIT_TIMEOUT
while not didMove and GetTime() < timeout do
-- check which moves are done
for slotId in pairs(slotIds) do
if private.openFrame ~= "GUILD_BANK" or slotId == movedSlotId then
if context:GetSlotQuantity(slotId) <= slotEndQuantity[slotId] then
didMove = true
slotIds[slotId] = nil
numDone = numDone + 1
callback("MOVED", slotItemString[slotId], slotMoveQuantity[slotId])
end
if didMove and slotId == movedSlotId then
break
end
Threading.Yield()
end
end
if didMove then
callback("PROGRESS", numDone / numMoves)
end
Threading.Yield(true)
end
end
if private.openFrame == "GUILD_BANK" then
QueryGuildBankTab(GetCurrentGuildBankTab())
end
Threading.ReleaseSafeTempTable(slotIds)
Threading.ReleaseSafeTempTable(slotItemString)
Threading.ReleaseSafeTempTable(slotMoveQuantity)
Threading.ReleaseSafeTempTable(slotEndQuantity)
Threading.ReleaseSafeTempTable(emptySlotIds)
callback("DONE")
end
-- ============================================================================
-- Private Helper Functions
-- ============================================================================
function private.BankOpened()
if private.openFrame == "BANK" then
return
end
assert(not private.openFrame)
private.openFrame = "BANK"
for _, callback in ipairs(private.frameCallbacks) do
callback(private.openFrame)
end
end
function private.GuildBankOpened()
if private.openFrame == "GUILD_BANK" then
return
end
assert(not private.openFrame)
private.openFrame = "GUILD_BANK"
for _, callback in ipairs(private.frameCallbacks) do
callback(private.openFrame)
end
end
function private.BankClosed()
if not private.openFrame then
return
end
private.openFrame = nil
private.StopMove()
for _, callback in ipairs(private.frameCallbacks) do
callback(private.openFrame)
end
end
function private.GuildBankClosed()
if not private.openFrame then
return
end
private.openFrame = nil
private.StopMove()
for _, callback in ipairs(private.frameCallbacks) do
callback(private.openFrame)
end
end
function private.StartMove(items, context, callback)
private.StopMove()
wipe(private.moveItems)
for itemString, quantity in pairs(items) do
private.moveItems[itemString] = quantity
end
Threading.Start(private.moveThread, context, callback)
end
function private.StopMove()
Threading.Kill(private.moveThread)
end
function private.EmptyBagsThreadCallbackWrapper(event, ...)
if event == "MOVED" then
local itemString, numMoved = ...
private.restoreItems[itemString] = (private.restoreItems[itemString] or 0) + numMoved
elseif event == "DONE" then
if not next(private.restoreItems) then
private.restoreFrame = private.openFrame
end
end
private.callback(event, ...)
end
function private.RestoreBagsThreadCallbackWrapper(event, ...)
if event == "DONE" then
wipe(private.restoreItems)
private.restoreFrame = nil
end
private.callback(event, ...)
end
function private.GetPutCallback(event)
if event == "DONE" then
Log.PrintUser(DONE)
end
end
function private.MatchesFilter(itemString, filterStr, filterItemString)
local name = strlower(ItemInfo.GetName(itemString) or "")
return strmatch(ItemString.GetBase(itemString), filterStr) or strmatch(name, filterStr) or (filterItemString and itemString == filterItemString)
end

View File

@@ -0,0 +1,105 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local _, TSM = ...
local Mailing = TSM.Banking:NewPackage("Mailing")
local TempTable = TSM.Include("Util.TempTable")
local Inventory = TSM.Include("Service.Inventory")
local PlayerInfo = TSM.Include("Service.PlayerInfo")
local private = {}
-- ============================================================================
-- Module Functions
-- ============================================================================
function Mailing.MoveGroupsToBank(callback, groups)
local items = TempTable.Acquire()
TSM.Banking.Util.PopulateGroupItemsFromBags(items, groups, private.GroupsGetNumToMoveToBank)
TSM.Banking.MoveToBank(items, callback)
TempTable.Release(items)
end
function Mailing.NongroupToBank(callback)
local items = TempTable.Acquire()
TSM.Banking.Util.PopulateItemsFromBags(items, private.NongroupGetNumToBank)
TSM.Banking.MoveToBank(items, callback)
TempTable.Release(items)
end
function Mailing.TargetShortfallToBags(callback, groups)
local items = TempTable.Acquire()
TSM.Banking.Util.PopulateGroupItemsFromOpenBank(items, groups, private.TargetShortfallGetNumToBags)
TSM.Banking.MoveToBag(items, callback)
TempTable.Release(items)
end
-- ============================================================================
-- Private Helper Functions
-- ============================================================================
function private.GroupsGetNumToMoveToBank(itemString, numHave)
-- move everything
return numHave
end
function private.NongroupGetNumToBank(itemString, numHave)
local hasOperations = false
for _ in TSM.Operations.GroupOperationIterator("Mailing", TSM.Groups.GetPathByItem(itemString)) do
hasOperations = true
end
return not hasOperations and numHave or 0
end
function private.TargetShortfallGetNumToBags(itemString, numHave)
local totalNumToSend = 0
for _, _, operationSettings in TSM.Operations.GroupOperationIterator("Mailing", TSM.Groups.GetPathByItem(itemString)) do
local numAvailable = numHave - operationSettings.keepQty
local numToSend = 0
if numAvailable > 0 then
if operationSettings.maxQtyEnabled then
if operationSettings.restock then
local targetQty = private.GetTargetQuantity(operationSettings.target, itemString, operationSettings.restockSources)
if PlayerInfo.IsPlayer(operationSettings.target) and targetQty <= operationSettings.maxQty then
numToSend = numAvailable
else
numToSend = min(numAvailable, operationSettings.maxQty - targetQty)
end
if PlayerInfo.IsPlayer(operationSettings.target) then
-- if using restock and target == player ensure that subsequent operations don't take reserved bag inventory
numHave = numHave - max((numAvailable - (targetQty - operationSettings.maxQty)), 0)
end
else
numToSend = min(numAvailable, operationSettings.maxQty)
end
else
numToSend = numAvailable
end
end
totalNumToSend = totalNumToSend + numToSend
numHave = numHave - numToSend
end
return totalNumToSend
end
function private.GetTargetQuantity(player, itemString, sources)
if player then
player = strtrim(strmatch(player, "^[^-]+"))
end
local num = Inventory.GetBagQuantity(itemString, player) + Inventory.GetMailQuantity(itemString, player) + Inventory.GetAuctionQuantity(itemString, player)
if sources then
if sources.guild then
num = num + Inventory.GetGuildQuantity(itemString, PlayerInfo.GetPlayerGuild(player))
end
if sources.bank then
num = num + Inventory.GetBankQuantity(itemString, player) + Inventory.GetReagentBankQuantity(itemString, player)
end
end
return num
end

View File

@@ -0,0 +1,292 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local _, TSM = ...
local MoveContext = TSM.Banking:NewPackage("MoveContext")
local Table = TSM.Include("Util.Table")
local SlotId = TSM.Include("Util.SlotId")
local Threading = TSM.Include("Service.Threading")
local ItemInfo = TSM.Include("Service.ItemInfo")
local InventoryInfo = TSM.Include("Service.InventoryInfo")
local BagTracking = TSM.Include("Service.BagTracking")
local GuildTracking = TSM.Include("Service.GuildTracking")
local private = {
bagToBank = nil,
bankToBag = nil,
bagToGuildBank = nil,
guildBankToBag = nil,
}
-- don't use MAX_GUILDBANK_SLOTS_PER_TAB since it isn't available right away
local GUILD_BANK_TAB_SLOTS = 98
-- ============================================================================
-- BaseMoveContext Class
-- ============================================================================
local BaseMoveContext = TSM.Include("LibTSMClass").DefineClass("BaseMoveContext", nil, "ABSTRACT")
-- ============================================================================
-- BagToBankMoveContext Class
-- ============================================================================
local BagToBankMoveContext = TSM.Include("LibTSMClass").DefineClass("BagToBankMoveContext", BaseMoveContext)
function BagToBankMoveContext.MoveSlot(self, fromSlotId, toSlotId, quantity)
local fromBag, fromSlot = SlotId.Split(fromSlotId)
SplitContainerItem(fromBag, fromSlot, quantity)
if GetCursorInfo() == "item" then
PickupContainerItem(SlotId.Split(toSlotId))
end
ClearCursor()
end
function BagToBankMoveContext.GetSlotQuantity(self, slotId)
return private.BagBankGetSlotQuantity(slotId)
end
function BagToBankMoveContext.SlotIdIterator(self, itemString)
return private.BagSlotIdIterator(itemString)
end
function BagToBankMoveContext.GetEmptySlotsThreaded(self, emptySlotIds)
local sortValue = Threading.AcquireSafeTempTable()
if not TSM.IsWowClassic() then
private.GetEmptySlotsHelper(REAGENTBANK_CONTAINER, emptySlotIds, sortValue)
end
private.GetEmptySlotsHelper(BANK_CONTAINER, emptySlotIds, sortValue)
for bag = NUM_BAG_SLOTS + 1, NUM_BAG_SLOTS + NUM_BANKBAGSLOTS do
private.GetEmptySlotsHelper(bag, emptySlotIds, sortValue)
end
Table.SortWithValueLookup(emptySlotIds, sortValue)
Threading.ReleaseSafeTempTable(sortValue)
end
function BagToBankMoveContext.GetTargetSlotId(self, itemString, emptySlotIds)
return private.BagBankGetTargetSlotId(itemString, emptySlotIds)
end
-- ============================================================================
-- BankToBagMoveContext Class
-- ============================================================================
local BankToBagMoveContext = TSM.Include("LibTSMClass").DefineClass("BankToBagMoveContext", BaseMoveContext)
function BankToBagMoveContext.MoveSlot(self, fromSlotId, toSlotId, quantity)
local fromBag, fromSlot = SlotId.Split(fromSlotId)
SplitContainerItem(fromBag, fromSlot, quantity)
if GetCursorInfo() == "item" then
PickupContainerItem(SlotId.Split(toSlotId))
end
ClearCursor()
end
function BankToBagMoveContext.GetSlotQuantity(self, slotId)
return private.BagBankGetSlotQuantity(slotId)
end
function BankToBagMoveContext.SlotIdIterator(self, itemString)
itemString = TSM.Groups.TranslateItemString(itemString)
return BagTracking.CreateQueryBankItem(itemString)
:VirtualField("autoBaseItemString", "string", TSM.Groups.TranslateItemString, "itemString")
:Equal("autoBaseItemString", itemString)
:Select("slotId", "quantity")
:IteratorAndRelease()
end
function BankToBagMoveContext.GetEmptySlotsThreaded(self, emptySlotIds)
private.BagGetEmptySlotsThreaded(emptySlotIds)
end
function BankToBagMoveContext.GetTargetSlotId(self, itemString, emptySlotIds)
return private.BagBankGetTargetSlotId(itemString, emptySlotIds)
end
-- ============================================================================
-- BagToGuildBankMoveContext Class
-- ============================================================================
local BagToGuildBankMoveContext = TSM.Include("LibTSMClass").DefineClass("BagToGuildBankMoveContext", BaseMoveContext)
function BagToGuildBankMoveContext.MoveSlot(self, fromSlotId, toSlotId, quantity)
local fromBag, fromSlot = SlotId.Split(fromSlotId)
SplitContainerItem(fromBag, fromSlot, quantity)
if GetCursorInfo() == "item" then
PickupGuildBankItem(SlotId.Split(toSlotId))
end
ClearCursor()
end
function BagToGuildBankMoveContext.GetSlotQuantity(self, slotId)
return private.BagBankGetSlotQuantity(slotId)
end
function BagToGuildBankMoveContext.SlotIdIterator(self, itemString)
return private.BagSlotIdIterator(itemString)
end
function BagToGuildBankMoveContext.GetEmptySlotsThreaded(self, emptySlotIds)
local currentTab = GetCurrentGuildBankTab()
local _, _, _, _, numWithdrawals = GetGuildBankTabInfo(currentTab)
if numWithdrawals == -1 or numWithdrawals >= GUILD_BANK_TAB_SLOTS then
for slot = 1, GUILD_BANK_TAB_SLOTS do
if not GetGuildBankItemInfo(currentTab, slot) then
tinsert(emptySlotIds, SlotId.Join(currentTab, slot))
end
end
end
for tab = 1, GetNumGuildBankTabs() do
if tab ~= currentTab then
-- only use tabs which we have at least enough withdrawals to withdraw every slot
_, _, _, _, numWithdrawals = GetGuildBankTabInfo(tab)
if numWithdrawals == -1 or numWithdrawals >= GUILD_BANK_TAB_SLOTS then
for slot = 1, GUILD_BANK_TAB_SLOTS do
if not GetGuildBankItemInfo(tab, slot) then
tinsert(emptySlotIds, SlotId.Join(tab, slot))
end
end
end
end
end
end
function BagToGuildBankMoveContext.GetTargetSlotId(self, itemString, emptySlotIds)
return tremove(emptySlotIds, 1)
end
-- ============================================================================
-- GuildBankToBagMoveContext Class
-- ============================================================================
local GuildBankToBagMoveContext = TSM.Include("LibTSMClass").DefineClass("GuildBankToBagMoveContext", BaseMoveContext)
function GuildBankToBagMoveContext.MoveSlot(self, fromSlotId, toSlotId, quantity)
local fromTab, fromSlot = SlotId.Split(fromSlotId)
SplitGuildBankItem(fromTab, fromSlot, quantity)
if GetCursorInfo() == "item" then
PickupContainerItem(SlotId.Split(toSlotId))
end
ClearCursor()
end
function GuildBankToBagMoveContext.GetSlotQuantity(self, slotId)
local tab, slot = SlotId.Split(slotId)
QueryGuildBankTab(tab)
local _, quantity = GetGuildBankItemInfo(tab, slot)
return quantity or 0
end
function GuildBankToBagMoveContext.SlotIdIterator(self, itemString)
itemString = TSM.Groups.TranslateItemString(itemString)
return GuildTracking.CreateQueryItem(itemString)
:VirtualField("autoBaseItemString", "string", TSM.Groups.TranslateItemString, "itemString")
:Equal("autoBaseItemString", itemString)
:Select("slotId", "quantity")
:IteratorAndRelease()
end
function GuildBankToBagMoveContext.GetEmptySlotsThreaded(self, emptySlotIds)
private.BagGetEmptySlotsThreaded(emptySlotIds)
end
function GuildBankToBagMoveContext.GetTargetSlotId(self, itemString, emptySlotIds)
return private.BagBankGetTargetSlotId(itemString, emptySlotIds)
end
-- ============================================================================
-- Module Functions
-- ============================================================================
function MoveContext.GetBagToBank()
private.bagToBank = private.bagToBank or BagToBankMoveContext()
return private.bagToBank
end
function MoveContext.GetBankToBag()
private.bankToBag = private.bankToBag or BankToBagMoveContext()
return private.bankToBag
end
function MoveContext.GetBagToGuildBank()
private.bagToGuildBank = private.bagToGuildBank or BagToGuildBankMoveContext()
return private.bagToGuildBank
end
function MoveContext.GetGuildBankToBag()
private.guildBankToBag = private.guildBankToBag or GuildBankToBagMoveContext()
return private.guildBankToBag
end
-- ============================================================================
-- Private Helper Functions
-- ============================================================================
function private.BagBankGetSlotQuantity(slotId)
local _, quantity = GetContainerItemInfo(SlotId.Split(slotId))
return quantity or 0
end
function private.BagSlotIdIterator(itemString)
itemString = TSM.Groups.TranslateItemString(itemString)
local query = BagTracking.CreateQueryBagsItem(itemString)
:Select("slotId", "quantity")
:VirtualField("autoBaseItemString", "string", TSM.Groups.TranslateItemString, "itemString")
:Equal("autoBaseItemString", itemString)
if TSM.Banking.IsGuildBankOpen() then
query:Equal("isBoA", false)
query:Equal("isBoP", false)
end
return query:IteratorAndRelease()
end
function private.BagGetEmptySlotsThreaded(emptySlotIds)
local sortValue = Threading.AcquireSafeTempTable()
for bag = BACKPACK_CONTAINER, NUM_BAG_SLOTS do
private.GetEmptySlotsHelper(bag, emptySlotIds, sortValue)
end
Table.SortWithValueLookup(emptySlotIds, sortValue)
Threading.ReleaseSafeTempTable(sortValue)
end
function private.GetEmptySlotsHelper(bag, emptySlotIds, sortValue)
local isSpecial = nil
if bag == REAGENTBANK_CONTAINER then
isSpecial = true
elseif bag == BACKPACK_CONTAINER or bag == BANK_CONTAINER then
isSpecial = false
else
isSpecial = (GetItemFamily(GetInventoryItemLink("player", ContainerIDToInventoryID(bag))) or 0) ~= 0
end
for slot = 1, GetContainerNumSlots(bag) do
if not GetContainerItemInfo(bag, slot) then
local slotId = SlotId.Join(bag, slot)
tinsert(emptySlotIds, slotId)
sortValue[slotId] = slotId + (isSpecial and 0 or 100000)
end
end
end
function private.BagBankGetTargetSlotId(itemString, emptySlotIds)
for i, slotId in ipairs(emptySlotIds) do
local bag = SlotId.Split(slotId)
if InventoryInfo.ItemWillGoInBag(ItemInfo.GetLink(itemString), bag) then
return tremove(emptySlotIds, i)
end
end
end

View File

@@ -0,0 +1,115 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local _, TSM = ...
local Util = TSM.Banking:NewPackage("Util")
local TempTable = TSM.Include("Util.TempTable")
local BagTracking = TSM.Include("Service.BagTracking")
local GuildTracking = TSM.Include("Service.GuildTracking")
local private = {}
-- ============================================================================
-- Module Functions
-- ============================================================================
function Util.BagIterator(autoBaseItems)
local query = BagTracking.CreateQueryBags()
:OrderBy("slotId", true)
if autoBaseItems then
query:VirtualField("autoBaseItemString", "string", TSM.Groups.TranslateItemString, "itemString")
:Select("bag", "slot", "autoBaseItemString", "quantity")
else
query:Select("bag", "slot", "itemString", "quantity")
end
if TSM.Banking.IsGuildBankOpen() then
query:Equal("isBoP", false)
:Equal("isBoA", false)
end
return query:IteratorAndRelease()
end
function Util.OpenBankIterator(autoBaseItems)
if TSM.Banking.IsGuildBankOpen() then
local query = GuildTracking.CreateQuery()
if autoBaseItems then
query:VirtualField("autoBaseItemString", "string", TSM.Groups.TranslateItemString, "itemString")
:Select("tab", "slot", "autoBaseItemString", "quantity")
else
query:Select("tab", "slot", "itemString", "quantity")
end
return query:IteratorAndRelease()
else
local query = BagTracking.CreateQueryBank()
:OrderBy("slotId", true)
if autoBaseItems then
query:VirtualField("autoBaseItemString", "string", TSM.Groups.TranslateItemString, "itemString")
:Select("bag", "slot", "autoBaseItemString", "quantity")
else
query:Select("bag", "slot", "itemString", "quantity")
end
return query:IteratorAndRelease()
end
end
function Util.PopulateGroupItemsFromBags(items, groups, getNumFunc, ...)
local itemQuantity = TempTable.Acquire()
for _, _, _, itemString, quantity in Util.BagIterator(true) do
if private.InGroups(itemString, groups) then
itemQuantity[itemString] = (itemQuantity[itemString] or 0) + quantity
end
end
for itemString, numHave in pairs(itemQuantity) do
local numToMove = getNumFunc(itemString, numHave, ...)
if numToMove > 0 then
items[itemString] = numToMove
end
end
TempTable.Release(itemQuantity)
end
function Util.PopulateGroupItemsFromOpenBank(items, groups, getNumFunc, ...)
local itemQuantity = TempTable.Acquire()
for _, _, _, itemString, quantity in Util.OpenBankIterator(true) do
if private.InGroups(itemString, groups) then
itemQuantity[itemString] = (itemQuantity[itemString] or 0) + quantity
end
end
for itemString, numHave in pairs(itemQuantity) do
local numToMove = getNumFunc(itemString, numHave, ...)
if numToMove > 0 then
items[itemString] = numToMove
end
end
TempTable.Release(itemQuantity)
end
function Util.PopulateItemsFromBags(items, getNumFunc, ...)
local itemQuantity = TempTable.Acquire()
for _, _, _, itemString, quantity in Util.BagIterator(true) do
itemQuantity[itemString] = (itemQuantity[itemString] or 0) + quantity
end
for itemString, numHave in pairs(itemQuantity) do
local numToMove = getNumFunc(itemString, numHave, ...)
if numToMove > 0 then
items[itemString] = numToMove
end
end
TempTable.Release(itemQuantity)
end
-- ============================================================================
-- Private Helper Functions
-- ============================================================================
function private.InGroups(itemString, groups)
local groupPath = TSM.Groups.GetPathByItem(itemString)
-- TODO: support the base group
return groupPath and groupPath ~= TSM.CONST.ROOT_GROUP_PATH and groups[groupPath]
end

View File

@@ -0,0 +1,92 @@
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local _, TSM = ...
local Warehousing = TSM.Banking:NewPackage("Warehousing")
local TempTable = TSM.Include("Util.TempTable")
local Math = TSM.Include("Util.Math")
local BagTracking = TSM.Include("Service.BagTracking")
local private = {}
-- ============================================================================
-- Module Functions
-- ============================================================================
function Warehousing.MoveGroupsToBank(callback, groups)
local items = TempTable.Acquire()
TSM.Banking.Util.PopulateGroupItemsFromBags(items, groups, private.GetNumToMoveToBank)
TSM.Banking.MoveToBank(items, callback)
TempTable.Release(items)
end
function Warehousing.MoveGroupsToBags(callback, groups)
local items = TempTable.Acquire()
TSM.Banking.Util.PopulateGroupItemsFromOpenBank(items, groups, private.GetNumToMoveToBags)
TSM.Banking.MoveToBag(items, callback)
TempTable.Release(items)
end
function Warehousing.RestockBags(callback, groups)
local items = TempTable.Acquire()
TSM.Banking.Util.PopulateGroupItemsFromOpenBank(items, groups, private.GetNumToMoveRestock)
TSM.Banking.MoveToBag(items, callback)
TempTable.Release(items)
end
-- ============================================================================
-- Private Helper Functions
-- ============================================================================
function private.GetNumToMoveToBank(itemString, numToMove)
local _, operationSettings = TSM.Operations.GetFirstOperationByItem("Warehousing", itemString)
if not operationSettings then
return 0
end
if operationSettings.keepBagQuantity ~= 0 then
numToMove = max(numToMove - operationSettings.keepBagQuantity, 0)
end
if operationSettings.moveQuantity ~= 0 then
numToMove = min(numToMove, operationSettings.moveQuantity)
end
return numToMove
end
function private.GetNumToMoveToBags(itemString, numToMove)
local _, operationSettings = TSM.Operations.GetFirstOperationByItem("Warehousing", itemString)
if not operationSettings then
return 0
end
if operationSettings.keepBankQuantity ~= 0 then
numToMove = max(numToMove - operationSettings.keepBankQuantity, 0)
end
if operationSettings.moveQuantity ~= 0 then
numToMove = min(numToMove, operationSettings.moveQuantity)
end
return Math.Floor(numToMove, operationSettings.stackSize ~= 0 and operationSettings.stackSize or 1)
end
function private.GetNumToMoveRestock(itemString, numToMove)
local _, operationSettings = TSM.Operations.GetFirstOperationByItem("Warehousing", itemString)
if not operationSettings then
return 0
end
local numInBags = BagTracking.CreateQueryBagsItem(itemString)
:VirtualField("autoBaseItemString", "string", TSM.Groups.TranslateItemString, "itemString")
:Equal("autoBaseItemString", itemString)
:SumAndRelease("quantity") or 0
if operationSettings.restockQuantity == 0 or numInBags >= operationSettings.restockQuantity then
return 0
end
if operationSettings.restockKeepBankQuantity ~= 0 then
numToMove = max(numToMove - operationSettings.restockKeepBankQuantity, 0)
end
numToMove = min(numToMove, operationSettings.restockQuantity - numInBags)
return Math.Floor(numToMove, operationSettings.restockStackSize ~= 0 and operationSettings.restockStackSize or 1)
end