Files
OctoAuctionator/zcUtils.lua

858 lines
15 KiB
Lua

-- Zirco's utilities
-- This module should contain no globals as it is intended to be "linked" in to each of Zirco's addons
local addonName, addonTable = "Auctionator", AtrNS;
local zc = {};
addonTable.zc = zc;
-----------------------------------------
function zc.RGBtoHEX (r,g,b)
local hex = "";
return string.format ("%02x%02x%02x", r * 255, g * 255, b * 255);
end
-----------------------------------------
function zc.EnableDisable (elem, b)
if (b) then
elem:Enable();
else
elem:Disable();
end
end
-----------------------------------------
function zc.ShowHide (elem, b)
if (b) then
elem:Show();
else
elem:Hide();
end
end
-----------------------------------------
function zc.SetTextIf (elem, b, t1, t2)
if (b) then
elem:SetText(t1);
else
elem:SetText(t2);
end
end
-----------------------------------------
function zc.Val (val, ifNilVal)
if (val == nil) then
return ifNilVal;
end
return val;
end
-----------------------------------------
function zc.Min (a, b)
if (a == nil) then
return b;
end
if (b == nil) then
return a;
end
return math.min (tonumber (a), tonumber (b));
end
-----------------------------------------
function zc.Max (a, b)
if (a == nil) then
return b;
end
if (b == nil) then
return a;
end
return math.max (tonumber (a), tonumber (b));
end
-----------------------------------------
function zc.If (b, x, y)
if (b ~= nil and b ~= false) then
return x;
end
return y;
end
-----------------------------------------
function zc.PrintKeysSorted (t)
local ta = {};
for a,v in pairs (t) do
table.insert (ta, a);
end
table.sort (ta, function (a,b) return (string.lower(a) < string.lower(b)); end);
for x = 1, getn(ta) do
zc.msg_pink (x.." "..ta[x]);
end
end
-----------------------------------------
function zc.UTF8_Truncate (s, newlen)
if (string.len (s) <= newlen) then
return s;
end
local x, c;
for x = newlen, 1, -1 do
c = string.byte (s, x+1);
if (c ~= nil and (c < 128 or c >= 192)) then -- the next byte starts a character, so cut here
return string.sub (s, 1, x);
end
end
return string.sub (s, 1, newlen);
end
-----------------------------------------
function zc.GetArrayElemOrFirst (a, x)
if (a and getn(a) > 0) then
if (x == nil or x < 1 or x > getn(a)) then
x = 1;
end
return a[x];
end
return nil;
end
-----------------------------------------
function zc.GetArrayElemOrNil (a, x)
if (a and getn(a) > 0) then
if (x == nil or x < 1 or x > getn(a)) then
return nil;
end
return a[x];
end
return nil;
end
-----------------------------------------
function zc.padstring (s, n, c)
while (string.len (s) < n) do
s = c..s;
end
return s;
end
-----------------------------------------
local encTable = {"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",
"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z",
"0","1","2","3","4","5","6","7","8","9",
"-", "_" };
local decTable;
-----------------------------------------
local function BuildDecTable()
if (decTable == nil) then
decTable = {};
local i;
for i = 1,64 do
decTable[encTable[i]] = i-1;
end
end
end
-----------------------------------------
function zc.enc64 (n)
if (n == 0) then
return encTable[1];
end
local k = n;
local result = "";
while k > 0 do
local x = mod (k, 64);
result = encTable[x+1]..result;
k = floor (k / 64);
end
return result;
end
-----------------------------------------
function zc.dec64 (s)
if (s == nil or s == "") then
return 0;
end
BuildDecTable();
local result = 0;
local len = string.len (s);
local x;
for x = 1, len do
result = result * 64;
result = result + decTable[string.sub(s,x,x)];
end
return result;
end
-----------------------------------------
function ZF (s)
BuildDecTable();
local s2 = "";
local n;
for n = 1, string.len(s) do
local c = string.sub(s, n,n);
local x = decTable[c];
if (x == nil) then
s2 = s2..c;
else
if (x < 32) then x = x + 32;
else x = x - 32;
end;
s2 = s2..encTable[x+1];
end
end
return s2;
end
-----------------------------------------
function zc.words(str)
local t = {}
local function helper(word) table.insert(t, word) return "" end
local rest = string.gsub (str, "%w+", helper);
if (not string.find (rest, "%S")) then
if (getn(t) == 1) then return t[1]; end;
if (getn(t) == 2) then return t[1],t[2]; end;
if (getn(t) == 3) then return t[1],t[2],t[3]; end;
if (getn(t) == 4) then return t[1],t[2],t[3],t[4]; end;
if (getn(t) == 5) then return t[1],t[2],t[3],t[4],t[5]; end;
return t;
end
end
-----------------------------------------
local gDeferredCalls = {};
-----------------------------------------
function zc.AddDeferredCall (seconds, funcname, param1, param2, tag) -- tag is optional. if present used to overwrite prior call with same tag
local now = time();
local cfdEntry = {};
cfdEntry.funcname = funcname;
cfdEntry.param1 = param1;
cfdEntry.param2 = param2;
cfdEntry.when = now + seconds;
cfdEntry.tag = "";
if (tag) then
cfdEntry.tag = tag;
for i = 1, getn(gDeferredCalls) do
if (gDeferredCalls[i].tag == tag) then
gDeferredCalls[i] = cfdEntry; -- overwrite
return;
end
end
end
table.insert (gDeferredCalls, cfdEntry);
end
-----------------------------------------
function zc.CheckDeferredCall ()
local now = time();
local i;
for i = 1, getn(gDeferredCalls) do
if (gDeferredCalls[i].when < now) then
local fcn = getglobal(gDeferredCalls[i].funcname);
local p1 = gDeferredCalls[i].param1;
local p2 = gDeferredCalls[i].param2;
table.remove (gDeferredCalls, i);
if (type(fcn) == 'function') then
fcn(p1, p2);
end
return; -- only do one
end
end
end
-----------------------------------------
function zc.periodic (elem, name, period, elapsed)
local t = elem[name] or 0;
t = t + elapsed;
if (t > period) then
elem[name] = 0;
return true;
end
elem[name] = t;
return false;
end
-----------------------------------------
function zc.tableIsEmpty (t)
local n, v;
for n, v in pairs (t) do
return false;
end
return true;
end
-----------------------------------------
function zc.PrintTable (t, indent)
if (not indent) then
indent = 0;
end
local x
local padding = "";
for x = 1,indent do
padding = padding.." ";
end
zc.msg ("-------");
for n, v in pairs (t) do
if (type(v) == "table") then
zc.msg (padding..n, "TABLE");
zc.PrintTable(v, indent+1);
elseif (type(v) == "userdata") then
zc.msg (padding..n, "userdata");
else
zc.msg (padding..n, v);
end
end
end
-----------------------------------------
function zc.ItemIDfromLink (itemLink)
if (itemLink == nil) then
return 0,0,0;
end
-- 1.12 item strings are item:id:enchant:suffix:unique
local found, _, itemString = string.find(itemLink, "^|c%x+|H(.+)|h%[.*%]")
if (itemString == nil) then
found, _, itemString = string.find (itemLink, "(item:[%-%d:]+)");
end
if (itemString == nil) then
return 0,0,0;
end
local _, itemId, _, suffixId, uniqueId = Atr_strsplit (":", itemString)
return itemId, suffixId or 0, uniqueId or 0;
end
-----------------------------------------
function zc.BoolToString (b)
if (b) then
return "true";
end
return "false";
end
-----------------------------------------
function zc.BoolToNum (b)
if (b) then
return 1;
end
return 0;
end
-----------------------------------------
function zc.NumToBool (n)
if (n == 0) then
return false;
end
return true;
end
-----------------------------------------
function zc.pluralizeIf (word, count)
if (count and count == 1) then
return word;
else
return zc.pluralize(word);
end
end
-----------------------------------------
function zc.pluralize (word)
return word.."s";
end
-----------------------------------------
function zc.round (v)
return math.floor (v + 0.5);
end
-----------------------------------------
function zc.msg_red (...) zc.msg_color (1, 0, 0, unpack(arg)); end
function zc.msg_pink (...) zc.msg_color (1, .6, .6, unpack(arg)); end
function zc.msg_yellow (...) zc.msg_color (1, 1, 0, unpack(arg)); end
-----------------------------------------
function zc.msg_color (r, g, b, ...)
local options = {};
options.r = r;
options.g = g;
options.b = b;
zc.msg_ex (options, unpack(arg));
end
-----------------------------------------
function zc.msg_str (...)
local options = {};
options.str = true;
return zc.msg_ex (options, unpack(arg));
end
-----------------------------------------
function zc.msg_atr (...)
zc.msg_yellow ("|cff00ffff<Auctionator>|r", unpack(arg));
end
-----------------------------------------
function zc.HSV2RGB (h, s, v)
local r, g, b;
local hi = mod (math.floor(h/60), 6);
local f = h/60 - math.floor(h/60);
local p = v * (1-s);
local q = v * (1-(f*s));
local t = v * (1-((1-f)*s));
if (hi == 0) then return v, t, p; end
if (hi == 1) then return q, v, p; end
if (hi == 2) then return p, v, t; end
if (hi == 3) then return p, q, v; end
if (hi == 4) then return t, p, v; end
if (hi == 5) then return v, p, q; end
return
end
-----------------------------------------
function zc.md (...)
-- developer trace output: disabled in the 1.12 port
end
-----------------------------------------
function zc.msg (...)
local options = {};
zc.msg_ex (options, unpack(arg));
end
-----------------------------------------
function zc.msg_ex (options, ...)
if (not DEFAULT_CHAT_FRAME) then
return;
end
local msg = "";
local i;
local m;
for i = 1, arg.n do
local v = arg[i];
if (type(v) == "boolean") then m = zc.BoolToString(v);
elseif (type(v) == "table") then m = "<table>";
elseif (v == nil) then m = "<nil>";
else m = v;
end
msg = msg.." "..m;
end
if (options.str) then
return msg;
end
if (options.r ~= nil) then
DEFAULT_CHAT_FRAME:AddMessage (msg, options.r, options.g, options.b);
else
DEFAULT_CHAT_FRAME:AddMessage (msg);
end
end
-----------------------------------------
function zc.val2gsc (v)
local rv = zc.round(v)
local g = math.floor (rv/10000);
rv = rv - g*10000;
local s = math.floor (rv/100);
rv = rv - s*100;
local c = rv;
return g, s, c
end
-----------------------------------------
function zc.priceToString (val)
local gold, silver, copper = zc.val2gsc(val);
local st = "";
if (gold ~= 0) then
st = gold.."g ";
end
if (st ~= "") then
st = st..format("%02is ", silver);
elseif (silver ~= 0) then
st = st..silver.."s ";
end
if (st ~= "") then
st = st..format("%02ic", copper);
elseif (copper ~= 0) then
st = st..copper.."c";
end
return st;
end
-----------------------------------------
local goldicon = "|cffffd100g|r"
local silvericon = "|cffc7c7cfs|r"
local coppericon = "|cffeda55fc|r"
-----------------------------------------
function zc.priceToMoneyString (val, noZeroCoppers)
local gold, silver, copper = zc.val2gsc(val);
local st = "";
if (gold ~= 0) then
st = gold..goldicon.." ";
end
if (st ~= "") then
st = st..format("%02i%s ", silver, silvericon);
elseif (silver ~= 0) then
st = st..silver..silvericon.." ";
end
if (noZeroCoppers and copper == 0) then
return st;
end
if (st ~= "") then
st = st..format("%02i%s", copper, coppericon);
elseif (copper ~= 0) then
st = st..copper..coppericon;
end
return st;
end
-----------------------------------------
function zc.StringSame (s1, s2)
if (s1 == nil and s2 == nil) then
return true;
end
if (s1 == nil or s2 == nil) then
return false;
end
if (s1 == s2) then -- maybe will fix german umlaut problem?
return true;
end
return (string.lower (s1) == string.lower (s2));
end
-----------------------------------------
function zc.StringContains (s, sub)
if (sub == nil or sub == "") then
return false;
end
local start, stop = string.find (string.lower(s), string.lower(sub), 1, true);
return (start ~= nil);
end
-----------------------------------------
function zc.StringEndsWith (s, sub)
if (sub == nil or sub == "") then
return false;
end
local i = string.len(s) - string.len(sub);
if (i < 0) then
return false;
end
local sEnd = string.sub (s, i+1);
return (string.lower (sEnd) == string.lower (sub));
end
-----------------------------------------
function zc.StringStartsWith (s, sub)
if (s == nil or sub == nil or sub == "") then
return false;
end
local sublen = string.len (sub);
if (string.len (s) < sublen) then
return false;
end
return (string.lower (string.sub(s, 1, sublen)) == string.lower(sub));
end
-----------------------------------------
function zc.CopyDeep (src)
local result = {};
for n, v in pairs (src) do
if (type(v) == "table") then
result[n] = zc.CopyDeep(v);
else
result[n] = v;
end
end
return result;
end
-----------------------------------------
function zc.printableLink (link)
if (link == nil) then
return "nil";
end
local printable = gsub(link, "\124", "\124\124");
return printable;
end
-----------------------------------------
function zc.printmem ()
local cmem = math.floor(collectgarbage ("count"))
UpdateAddOnMemoryUsage();
local mem = GetAddOnMemoryUsage("OctoAuctionator");
zc.msg_atr (math.floor(mem).." KB (total LUA: "..cmem.." KB)");
end
-----------------------------------------
function zc.printstack (options)
return {}; -- needs debugstack(), which the 1.12 client does not have
end
-----------------------------------------
function zc.tallyAdd (ttable, value)
if (ttable[value]) then
ttable[value] = ttable[value] + 1;
else
ttable[value] = 1;
end
end
-----------------------------------------
function zc.tallyPrint (ttable, options)
local sortedTable = {};
local total = 0;
local n = 1;
for value,count in pairs(ttable) do
sortedTable[n] = {};
sortedTable[n].value = value;
sortedTable[n].count = count;
total = total + count;
n = n + 1;
end
if (options.sortByValue and options.sortDesc) then table.sort (sortedTable, function(x,y) return x.value > y.value; end);
elseif (options.sortByValue and not options.sortDesc) then table.sort (sortedTable, function(x,y) return x.value < y.value; end);
elseif (options.sortDesc) then table.sort (sortedTable, function(x,y) return x.count > y.count; end);
else table.sort (sortedTable, function(x,y) return x.count < y.count; end);
end
for n = 1, getn(sortedTable) do
if (not options.printCount or n < options.printCount) then
zc.msg_pink (sortedTable[n].count.." "..sortedTable[n].value);
end
end
zc.msg_yellow ("Total: "..total);
end