init
This commit is contained in:
@@ -0,0 +1,234 @@
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
-- TradeSkillMaster_Mailing --
|
||||
-- http://www.curse.com/addons/wow/tradeskillmaster_mailing --
|
||||
-- --
|
||||
-- A TradeSkillMaster Addon (http://tradeskillmaster.com) --
|
||||
-- All Rights Reserved* - Detailed license information included with addon. --
|
||||
-- ------------------------------------------------------------------------------ --
|
||||
|
||||
local TSM = select(2, ...)
|
||||
local AutoMail = TSM:NewModule("AutoMail", "AceEvent-3.0")
|
||||
local L = LibStub("AceLocale-3.0"):GetLocale("TradeSkillMaster_Mailing") -- loads the localization table
|
||||
|
||||
local private = {}
|
||||
|
||||
|
||||
function AutoMail:OnEnable()
|
||||
AutoMail:RegisterEvent("MAIL_CLOSED", private.StopSending)
|
||||
end
|
||||
|
||||
function AutoMail:SendItems(items, target, callback, codPerItem)
|
||||
if private.isSending or TSMAPI:IsPlayer(target) or not MailFrame:IsVisible() then return end
|
||||
private.isSending = true
|
||||
private.items = items
|
||||
private.target = target
|
||||
private.callback = callback
|
||||
private.codPerItem = codPerItem
|
||||
private.waitingLocations = {}
|
||||
TSMAPI:CreateTimeDelay("mailingSendDelay", 0, private.SendNextMail, TSM.db.global.sendDelay)
|
||||
return true
|
||||
end
|
||||
|
||||
-- returns the number of items currently attached to the mail
|
||||
function private:GetNumPendingAttachments()
|
||||
local totalAttached = 0
|
||||
for i=1, ATTACHMENTS_MAX_SEND do
|
||||
if GetSendMailItem(i) then
|
||||
totalAttached = totalAttached + 1
|
||||
end
|
||||
end
|
||||
|
||||
return totalAttached
|
||||
end
|
||||
|
||||
function private:SendNextMail()
|
||||
for _, info in ipairs(private.waitingLocations) do
|
||||
if not GetContainerItemInfo(info.bag, info.slot) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- send off any pending items
|
||||
private:SendOffMail()
|
||||
|
||||
-- fill the mail with the next batch of items
|
||||
local bagsFull = private:FillMail()
|
||||
if #private.waitingLocations > 0 then return end
|
||||
|
||||
-- check if anything was actually put in the mail to be sent
|
||||
if private:GetNumPendingAttachments() == 0 then
|
||||
-- we're done
|
||||
if bagsFull then
|
||||
TSM:Printf(L["Could not send mail due to not having free bag space available to split a stack of items."])
|
||||
end
|
||||
private:StopSending()
|
||||
return
|
||||
end
|
||||
|
||||
-- send off this mail
|
||||
private:SendOffMail()
|
||||
end
|
||||
|
||||
function private:SendOffMail()
|
||||
local attachments = private:GetNumPendingAttachments()
|
||||
if attachments == 0 or not private.target then return end
|
||||
SendMailNameEditBox:SetText(private.target)
|
||||
SetSendMailMoney(0)
|
||||
if private.codPerItem then
|
||||
local numItems = 0
|
||||
for i=1, ATTACHMENTS_MAX_SEND do
|
||||
local count = select(3, GetSendMailItem(i))
|
||||
numItems = numItems + count
|
||||
end
|
||||
SetSendMailCOD(private.codPerItem*numItems)
|
||||
else
|
||||
SetSendMailCOD(0)
|
||||
end
|
||||
SendMail(private.target, SendMailSubjectEditBox:GetText() or "TSM_Mailing", "")
|
||||
if TSM.db.global.sendMessages then
|
||||
local items = {}
|
||||
for i=1, attachments do
|
||||
local num = select(3, GetSendMailItem(i))
|
||||
local link = GetSendMailItemLink(i)
|
||||
local itemString = TSMAPI:GetItemString(link)
|
||||
if itemString then
|
||||
items[itemString] = items[itemString] or {num=0, link=link}
|
||||
items[itemString].num = items[itemString].num + num
|
||||
end
|
||||
end
|
||||
local temp = {}
|
||||
for itemString, info in pairs(items) do
|
||||
tinsert(temp, format("%sx%d", info.link, info.num))
|
||||
end
|
||||
local msg = ""
|
||||
local cod = GetSendMailCOD()
|
||||
if cod and cod > 0 then
|
||||
msg = format(L["Sent %s to %s with a COD of %s."], table.concat(temp, ", "), private.target, TSMAPI:FormatTextMoney(cod))
|
||||
else
|
||||
msg = format(L["Sent %s to %s."], table.concat(temp, ", "), private.target)
|
||||
end
|
||||
local function DoPrint()
|
||||
if private:GetNumPendingAttachments() > 0 then return end
|
||||
TSMAPI:CancelFrame("sendMailPrintDelay")
|
||||
TSM:Printf(msg)
|
||||
end
|
||||
TSMAPI:CreateTimeDelay("sendMailPrintDelay", 0, DoPrint, 0.1)
|
||||
end
|
||||
end
|
||||
|
||||
-- fills the current mail with items to be sent to the target
|
||||
function private:FillMail()
|
||||
if private:GetNumPendingAttachments() ~= 0 then return end
|
||||
|
||||
local locationInfo = {}
|
||||
for bag, slot, itemString, quantity, locked in TSMAPI:GetBagIterator(true) do
|
||||
if not locked then
|
||||
locationInfo[itemString] = locationInfo[itemString] or {}
|
||||
tinsert(locationInfo[itemString], {bag=bag, slot=slot, quantity=quantity})
|
||||
end
|
||||
end
|
||||
|
||||
local emptySlots = {}
|
||||
for bag=0, NUM_BAG_SLOTS do
|
||||
for slot=1, GetContainerNumSlots(bag) do
|
||||
if not GetContainerItemInfo(bag, slot) then
|
||||
local family = bag == 0 and 0 or GetItemFamily(GetInventoryItemLink("player", ContainerIDToInventoryID(bag)))
|
||||
tinsert(emptySlots, {bag=bag, slot=slot, family=family})
|
||||
end
|
||||
end
|
||||
end
|
||||
private.waitingLocations = {}
|
||||
|
||||
for itemString, quantity in pairs(private.items) do
|
||||
if locationInfo[itemString] and quantity > 0 then
|
||||
-- use stack sizes which match exactly first, followed by the smallest stacks
|
||||
local sameSize = {}
|
||||
for i=#locationInfo[itemString], 1, -1 do
|
||||
if locationInfo[itemString][i].quantity == quantity then
|
||||
tinsert(sameSize, locationInfo[itemString][i])
|
||||
tremove(locationInfo[itemString], i)
|
||||
end
|
||||
end
|
||||
sort(locationInfo[itemString], function(a,b) return a.quantity < b.quantity end)
|
||||
for _, info in ipairs(sameSize) do
|
||||
tinsert(locationInfo[itemString], 1, info)
|
||||
end
|
||||
for _, info in ipairs(locationInfo[itemString]) do
|
||||
if quantity == 0 then break end
|
||||
if quantity >= info.quantity then
|
||||
PickupContainerItem(info.bag, info.slot)
|
||||
quantity = quantity - info.quantity
|
||||
private.items[itemString] = quantity
|
||||
|
||||
ClickSendMailItemButton()
|
||||
if private:GetNumPendingAttachments() == ATTACHMENTS_MAX_SEND then
|
||||
return
|
||||
end
|
||||
else
|
||||
-- sort the empty slots such that we'll use special bags first if possible
|
||||
local family = GetItemFamily(itemString)
|
||||
local splitTarget
|
||||
if family > 0 then
|
||||
local specialBags = {}
|
||||
for bag=1, NUM_BAG_SLOTS do
|
||||
local bagFamily = GetItemFamily(GetInventoryItemLink("player", ContainerIDToInventoryID(bag)))
|
||||
if bagFamily and bagFamily > 0 and bit.band(family, bagFamily) > 0 then
|
||||
specialBags[bag] = true
|
||||
end
|
||||
end
|
||||
sort(emptySlots, function(a, b)
|
||||
if specialBags[a.bag] and specialBags[b.bag] then
|
||||
if a.bag == b.bag then
|
||||
return a.slot < b.slot
|
||||
end
|
||||
return a.bag < b.bag
|
||||
end
|
||||
if a.bag == b.bag then
|
||||
return a.slot < b.slot
|
||||
end
|
||||
if specialBags[a.bag] then return true end
|
||||
if specialBags[b.bag] then return false end
|
||||
return a.bag < b.bag
|
||||
end)
|
||||
else
|
||||
sort(emptySlots, function(a, b)
|
||||
if a.bag == b.bag then
|
||||
return a.slot < b.slot
|
||||
end
|
||||
return a.bag < b.bag
|
||||
end)
|
||||
end
|
||||
for i=1, #emptySlots do
|
||||
if emptySlots[i].family == 0 or bit.band(family, emptySlots[i].family) > 0 then
|
||||
splitTarget = emptySlots[i]
|
||||
tremove(emptySlots, i)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not splitTarget then return true end
|
||||
SplitContainerItem(info.bag, info.slot, quantity)
|
||||
PickupContainerItem(splitTarget.bag, splitTarget.slot)
|
||||
tinsert(private.waitingLocations, splitTarget)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- check if we want to send only one type of item per mail
|
||||
if TSM.db.global.sendItemsIndividually then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- stops sending mail and calls the callback
|
||||
function private:StopSending()
|
||||
if not private.isSending then return end
|
||||
TSMAPI:CancelFrame("mailingSendDelay")
|
||||
private.isSending = nil
|
||||
private.items = nil
|
||||
private.target = nil
|
||||
private.waitingLocations = {}
|
||||
private.callback()
|
||||
end
|
||||
Reference in New Issue
Block a user