TradeSkillMaster/LibTSM/Util/Money.lua

178 lines
6.5 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. --
-- ------------------------------------------------------------------------------ --
--- Money Functions
-- @module Money
local _, TSM = ...
local Money = TSM.Init("Util.Money")
local String = TSM.Include("Util.String")
local private = {
textMoneyParts = {},
}
local GOLD_ICON = "|TInterface\\MoneyFrame\\UI-GoldIcon:0|t"
local SILVER_ICON = "|TInterface\\MoneyFrame\\UI-SilverIcon:0|t"
local COPPER_ICON = "|TInterface\\MoneyFrame\\UI-CopperIcon:0|t"
local GOLD_ICON_DISABLED = "|TInterface\\MoneyFrame\\UI-GoldIcon:0:0:0:0:1:1:0:1:0:1:100:100:100|t"
local SILVER_ICON_DISABLED = "|TInterface\\MoneyFrame\\UI-SilverIcon:0:0:0:0:1:1:0:1:0:1:100:100:100|t"
local COPPER_ICON_DISABLED = "|TInterface\\MoneyFrame\\UI-CopperIcon:0:0:0:0:1:1:0:1:0:1:100:100:100|t"
local GOLD_TEXT = "|cffffd70ag|r"
local SILVER_TEXT = "|cffc7c7cfs|r"
local COPPER_TEXT = "|cffeda55fc|r"
local GOLD_TEXT_DISABLED = "|cff5d5222g|r"
local SILVER_TEXT_DISABLED = "|cff464646s|r"
local COPPER_TEXT_DISABLED = "|cff402d22c|r"
-- ============================================================================
-- Module Functions
-- ============================================================================
--- Converts a numeric money value (in copper) to a string for display in the UI.
-- Supported options:
--
-- * OPT\_ICON Use texture icons instead of g/s/c letters
-- * OPT\_TRIM Remove any non-significant 0 valued denominations (i.e. "1g" instead of "1g 0s 0c")
-- * OPT\_83\_NO\_COPPER Remove the copper value entirely if we're patch 8.3
-- * OPT\_DISABLE Uses a muted color from the denomination text (not allowed with "OPT\_ICON" or "OPT\_NO\_COLOR")
-- @tparam number value The money value to be converted in copper (100 copper per silver, 100 silver per gold)
-- @tparam[opt] string color A color prefix to use for the numbers in the result (i.e. "|cff00ff00" for red)
-- @param[opt] ... One or more options to modify the format of the result
-- @return The string representation of the specified money value
function Money.ToString(value, color, ...)
value = tonumber(value)
if not value then
return
end
assert(not color or strmatch(color, "^\124cff[0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]$"))
-- parse the options
local isIcon, trim, disabled, noCopper = false, false, false, false
for i = 1, select('#', ...) do
local opt = select(i, ...)
if opt == nil then
-- pass
elseif opt == "OPT_ICON" then
isIcon = true
elseif opt == "OPT_TRIM" then
trim = true
elseif opt == "OPT_DISABLE" then
disabled = true
elseif opt == "OPT_83_NO_COPPER" then
noCopper = not TSM.IsWowClassic()
else
error("Invalid option: "..tostring(opt))
end
end
local isNegative = value < 0
value = abs(value)
local gold = floor(value / COPPER_PER_GOLD)
local silver = floor((value % COPPER_PER_GOLD) / COPPER_PER_SILVER)
local copper = floor(value % COPPER_PER_SILVER)
assert(not noCopper or copper == 0)
local goldText, silverText, copperText = nil, nil, nil
if isIcon then
if disabled then
goldText, silverText, copperText = GOLD_ICON_DISABLED, SILVER_ICON_DISABLED, COPPER_ICON_DISABLED
else
goldText, silverText, copperText = GOLD_ICON, SILVER_ICON, COPPER_ICON
end
else
if disabled then
goldText, silverText, copperText = GOLD_TEXT_DISABLED, SILVER_TEXT_DISABLED, COPPER_TEXT_DISABLED
else
goldText, silverText, copperText = GOLD_TEXT, SILVER_TEXT, COPPER_TEXT
end
end
if value == 0 then
return private.FormatNumber(0, true, color)..(noCopper and silverText or copperText)
end
wipe(private.textMoneyParts)
-- add gold
if gold > 0 then
private.InsertMoneyPart(gold, color, goldText)
end
-- add silver
if silver > 0 or (not trim and gold > 0) then
private.InsertMoneyPart(silver, color, silverText)
end
-- add copper
if copper > 0 or (not trim and not noCopper and (gold + silver) > 0) then
private.InsertMoneyPart(copper, color, copperText)
end
local text = table.concat(private.textMoneyParts, " ")
if isNegative then
return (color and (color.."-|r") or "-")..text
else
return text
end
end
--- Converts a string money value to a number value (in copper).
-- The value passed to this function can contain colored text, but must use g/s/c for the denominations and not icons.
-- @tparam string value The money value to be converted as a string
-- @treturn string The numeric representation of the specified money value
function Money.FromString(value)
-- remove any colors
value = gsub(gsub(strtrim(value), "\124c([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])", ""), "\124r", "")
-- remove any separators
value = gsub(value, String.Escape(LARGE_NUMBER_SEPERATOR), "")
-- extract gold/silver/copper values
local gold = tonumber(strmatch(value, "([0-9]+)g"))
local silver = tonumber(strmatch(value, "([0-9]+)s"))
local copper = tonumber(strmatch(value, "([0-9]+)c"))
if not gold and not silver and not copper then return end
-- test that there are no extra characters (other than spaces)
value = gsub(value, "[0-9]+g", "", 1)
value = gsub(value, "[0-9]+s", "", 1)
value = gsub(value, "[0-9]+c", "", 1)
if strtrim(value) ~= "" then return end
return ((gold or 0) * COPPER_PER_GOLD) + ((silver or 0) * COPPER_PER_SILVER) + (copper or 0)
end
--- Returns the colored gold indicator text
-- @treturn string The colored gold indicator text
function Money.GetGoldText()
return GOLD_TEXT
end
-- ============================================================================
-- Helper Functions
-- ============================================================================
function private.InsertMoneyPart(value, color, text)
tinsert(private.textMoneyParts, private.FormatNumber(value, #private.textMoneyParts == 0, color)..text)
end
function private.FormatNumber(num, isMostSignificant, color)
if num < 10 and not isMostSignificant then
num = "0"..num
elseif isMostSignificant and num >= 1000 then
num = tostring(num)
local result = ""
for i = 4, #num, 3 do
result = LARGE_NUMBER_SEPERATOR..strsub(num, -(i - 1), -(i - 3))..result
end
result = strsub(num, 1, (#num % 3 == 0) and 3 or (#num % 3))..result
num = result
end
if color then
return color..num.."|r"
else
return num
end
end