293 lines
10 KiB
Lua
293 lines
10 KiB
Lua
|
-- ------------------------------------------------------------------------------ --
|
||
|
-- 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
|