363 lines
11 KiB
Lua
Raw Normal View History

2020-11-13 14:13:12 -05:00
-- ------------------------------------------------------------------------------ --
-- TradeSkillMaster --
-- https://tradeskillmaster.com --
-- All Rights Reserved - Detailed license information included with addon. --
-- ------------------------------------------------------------------------------ --
local _, TSM = ...
local Groups = TSM.UI.MailingUI:NewPackage("Other")
local L = TSM.Include("Locale").GetTable()
local FSM = TSM.Include("Util.FSM")
local Event = TSM.Include("Util.Event")
local Money = TSM.Include("Util.Money")
local String = TSM.Include("Util.String")
local ItemInfo = TSM.Include("Service.ItemInfo")
local BagTracking = TSM.Include("Service.BagTracking")
local PlayerInfo = TSM.Include("Service.PlayerInfo")
local UIElements = TSM.Include("UI.UIElements")
local private = {
frame = nil,
fsm = nil,
}
local PLAYER_NAME = UnitName("player")
local PLAYER_NAME_REALM = string.gsub(PLAYER_NAME.."-"..GetRealmName(), "%s+", "")
-- ============================================================================
-- Module Functions
-- ============================================================================
function Groups.OnInitialize()
private.FSMCreate()
TSM.UI.MailingUI.RegisterTopLevelPage(OTHER, private.GetOtherFrame)
end
-- ============================================================================
-- Other UI
-- ============================================================================
function private.GetOtherFrame()
TSM.UI.AnalyticsRecordPathChange("mailing", "other")
local frame = UIElements.New("Frame", "other")
:SetLayout("VERTICAL")
:SetPadding(10)
:SetBackgroundColor("PRIMARY_BG")
:AddChild(UIElements.New("Text", "enchant")
:SetHeight(24)
:SetFont("BODY_BODY1_BOLD")
:SetText(L["Mail Disenchantables"])
)
:AddChild(UIElements.New("Text", "enchantDesc")
:SetHeight(20)
:SetMargin(0, 0, 4, 0)
:SetFont("BODY_BODY2")
:SetText(L["Quickly mail all excess disenchantable items to a character"])
)
:AddChild(UIElements.New("Text", "enchantRecipient")
:SetHeight(15)
:SetMargin(0, 0, 12, 0)
:SetFont("BODY_BODY2")
:SetText(L["Recipient"])
)
:AddChild(UIElements.New("Frame", "enchantHeader")
:SetLayout("HORIZONTAL")
:SetHeight(24)
:SetMargin(0, 0, 8, 0)
:AddChild(UIElements.New("Input", "recipient")
:SetMargin(0, 8, 0, 0)
:SetAutoComplete(PlayerInfo.GetConnectedAlts())
:SetClearButtonEnabled(true)
:SetValue(TSM.db.factionrealm.internalData.mailDisenchantablesChar)
:SetScript("OnValueChanged", private.EchantRecipientOnValueChanged)
)
:AddChild(UIElements.New("ActionButton", "send")
:SetSize(186, 24)
:SetDisabled(true)
:SetText(L["Send Disenchantables"])
:SetScript("OnClick", private.EnchantSendBtnOnClick)
)
)
:AddChild(UIElements.New("Text", "gold")
:SetHeight(24)
:SetMargin(0, 0, 24, 0)
:SetFont("BODY_BODY1_BOLD")
:SetText(L["Send Excess Gold to Banker"])
)
:AddChild(UIElements.New("Text", "goldDesc")
:SetHeight(18)
:SetMargin(0, 0, 4, 0)
:SetFont("BODY_BODY2")
:SetText(L["Quickly mail all excess gold (limited to a certain amount) to a character"])
)
:AddChild(UIElements.New("Frame", "goldTextHeader")
:SetLayout("HORIZONTAL")
:SetHeight(13)
:SetMargin(0, 0, 12, 0)
:AddChild(UIElements.New("Text", "recipient")
:SetMargin(0, 8, 0, 0)
:SetFont("BODY_BODY2")
:SetText(L["Recipient"])
)
:AddChild(UIElements.New("Text", "limit")
:SetWidth(128)
:SetMargin(0, 8, 0, 0)
:SetFont("BODY_BODY2")
:SetText(L["Limit"])
)
:AddChild(UIElements.New("Spacer", "spacer")
:SetWidth(106)
)
)
:AddChild(UIElements.New("Frame", "goldHeader")
:SetLayout("HORIZONTAL")
:SetHeight(24)
:SetMargin(0, 0, 4, 0)
:AddChild(UIElements.New("Input", "recipient")
:SetMargin(0, 8, 0, 0)
:SetAutoComplete(PlayerInfo.GetConnectedAlts())
:SetClearButtonEnabled(true)
:SetValue(TSM.db.factionrealm.internalData.mailExcessGoldChar)
:SetScript("OnValueChanged", private.GoldRecipientOnValueChanged)
)
:AddChild(UIElements.New("Input", "limit")
:SetSize(128, 24)
:SetMargin(0, 8, 0, 0)
:SetBackgroundColor("PRIMARY_BG_ALT")
:SetJustifyH("RIGHT")
:SetValidateFunc(private.LimitValidateFunc)
:SetValue(Money.ToString(TSM.db.factionrealm.internalData.mailExcessGoldLimit, nil, "OPT_TRIM"))
:SetScript("OnValueChanged", private.LimitOnValueChanged)
)
:AddChild(UIElements.New("ActionButton", "send")
:SetSize(106, 24)
:SetDisabled(true)
:SetText(L["Send Gold"])
:SetScript("OnClick", private.GoldSendBtnOnClick)
)
)
:AddChild(UIElements.New("Spacer", "spacer")
)
:SetScript("OnUpdate", private.FrameOnUpdate)
:SetScript("OnHide", private.FrameOnHide)
private.frame = frame
return frame
end
-- ============================================================================
-- Local Script Handlers
-- ============================================================================
function private.FrameOnUpdate(frame)
frame:SetScript("OnUpdate", nil)
private.UpdateEnchantButton()
private.UpdateGoldButton()
private.fsm:ProcessEvent("EV_FRAME_SHOW", frame)
end
function private.FrameOnHide(frame)
private.fsm:ProcessEvent("EV_FRAME_HIDE")
end
function private.EchantRecipientOnValueChanged(input)
local value = input:GetValue()
if value == TSM.db.factionrealm.internalData.mailDisenchantablesChar then
return
end
TSM.db.factionrealm.internalData.mailDisenchantablesChar = value
private.UpdateEnchantButton()
end
function private.EnchantSendBtnOnClick(button)
local items = {}
local query = BagTracking.CreateQueryBags()
:OrderBy("slotId", true)
:Select("itemString", "quantity")
:Equal("isBoP", false)
:Equal("isBoA", false)
for _, itemString, quantity in query:Iterator() do
if ItemInfo.IsDisenchantable(itemString) and not ItemInfo.IsSoulbound(itemString) then
local quality = ItemInfo.GetQuality(itemString)
if quality <= TSM.db.global.mailingOptions.deMaxQuality then
items[itemString] = (items[itemString] or 0) + quantity
end
end
end
query:Release()
private.fsm:ProcessEvent("EV_BUTTON_CLICKED", TSM.db.factionrealm.internalData.mailDisenchantablesChar, 0, items)
end
function private.GoldRecipientOnValueChanged(input)
local value = input:GetValue()
if value == TSM.db.factionrealm.internalData.mailExcessGoldChar then
return
end
TSM.db.factionrealm.internalData.mailExcessGoldChar = value
private.UpdateGoldButton()
end
function private.GoldSendBtnOnClick(button)
local money = private.GetSendMoney()
private.fsm:ProcessEvent("EV_BUTTON_CLICKED", TSM.db.factionrealm.internalData.mailExcessGoldChar, money)
end
function private.ConvertLimitValue(value)
value = gsub(value, String.Escape(LARGE_NUMBER_SEPERATOR), "")
value = tonumber(value) or Money.FromString(value)
if not value then
return nil
end
return value > 0 and value <= MAXIMUM_BID_PRICE and value or nil
end
function private.LimitValidateFunc(_, value)
return private.ConvertLimitValue(value) and true or false
end
function private.LimitOnValueChanged(input)
local value = private.ConvertLimitValue(input:GetValue())
assert(value)
if value == TSM.db.factionrealm.internalData.mailExcessGoldLimit then
return
end
TSM.db.factionrealm.internalData.mailExcessGoldLimit = value
private.UpdateGoldButton()
end
-- ============================================================================
-- Private Helper Functions
-- ============================================================================
function private.GetSendMoney()
local money = GetMoney() - 30 - TSM.db.factionrealm.internalData.mailExcessGoldLimit
if money < 0 then
money = 0
end
return money
end
function private.UpdateEnchantButton()
local recipient = TSM.db.factionrealm.internalData.mailDisenchantablesChar
local enchantButton = private.frame:GetElement("enchantHeader.send")
if recipient == "" or recipient == PLAYER_NAME or recipient == PLAYER_NAME_REALM then
enchantButton:SetDisabled(true)
:Draw()
return
else
enchantButton:SetDisabled(false)
:Draw()
end
end
function private.UpdateGoldButton()
local recipient = TSM.db.factionrealm.internalData.mailExcessGoldChar
local goldButton = private.frame:GetElement("goldHeader.send")
if recipient == "" or recipient == PLAYER_NAME or recipient == PLAYER_NAME_REALM then
goldButton:SetDisabled(true)
:Draw()
return
end
if private.GetSendMoney() > 0 then
goldButton:SetDisabled(false)
else
goldButton:SetDisabled(true)
end
goldButton:Draw()
end
-- ============================================================================
-- FSM
-- ============================================================================
function private.FSMCreate()
Event.Register("PLAYER_MONEY", function()
private.fsm:ProcessEvent("EV_PLAYER_MONEY_UPDATE")
end)
local fsmContext = {
frame = nil,
sending = false
}
local function UpdateEnchant(context)
context.frame:GetElement("enchantHeader.send"):SetText(context.sending and L["Sending..."] or L["Send Disenchantables"])
:SetPressed(context.sending)
:Draw()
end
local function UpdateGold(context)
private.UpdateGoldButton()
context.frame:GetElement("goldHeader.send"):SetText(context.sending and L["Sending..."] or L["Send Gold"])
:SetPressed(context.sending)
:Draw()
end
private.fsm = FSM.New("MAILING_GROUPS")
:AddState(FSM.NewState("ST_HIDDEN")
:SetOnEnter(function(context)
context.frame = nil
end)
:AddTransition("ST_SHOWN")
:AddTransition("ST_HIDDEN")
:AddEventTransition("EV_FRAME_SHOW", "ST_SHOWN")
)
:AddState(FSM.NewState("ST_SHOWN")
:SetOnEnter(function(context, frame)
if not context.frame then
context.frame = frame
end
end)
:AddTransition("ST_HIDDEN")
:AddTransition("ST_SENDING_START")
:AddEvent("EV_PLAYER_MONEY_UPDATE", function(context)
UpdateGold(context)
end)
:AddEventTransition("EV_BUTTON_CLICKED", "ST_SENDING_START")
)
:AddState(FSM.NewState("ST_SENDING_START")
:SetOnEnter(function(context, recipient, money, items)
context.sending = true
if money > 0 then
TSM.Mailing.Send.StartSending(private.FSMOthersCallback, recipient, "TSM Mailing: Excess Gold", "", money)
UpdateGold(context)
elseif items then
TSM.Mailing.Send.StartSending(private.FSMOthersCallback, recipient, "TSM Mailing: Disenchantables", "", money, items)
UpdateEnchant(context)
end
end)
:SetOnExit(function(context)
context.sending = false
UpdateEnchant(context)
UpdateGold(context)
end)
:AddTransition("ST_SHOWN")
:AddTransition("ST_HIDDEN")
:AddEventTransition("EV_SENDING_DONE", "ST_SHOWN")
)
:AddDefaultEventTransition("EV_FRAME_HIDE", "ST_HIDDEN")
:Init("ST_HIDDEN", fsmContext)
end
function private.FSMOthersCallback()
private.fsm:ProcessEvent("EV_SENDING_DONE")
end