Module:Rates/Sandbox: Difference between revisions
From Ephinea PSO Wiki
mNo edit summary |
mNo edit summary |
||
Line 1: | Line 1: | ||
-- <nowiki> | |||
-- | |||
-- Formats drop rates and calculates two rates multiplied together (usually DAR and RDR) | |||
-- | |||
local p = {} | local p = {} | ||
-- Every DAR/RDR fraction between 1/2 and 1/1 | |||
local wholeFractions = | |||
{ | |||
[0.9] = "9/10", | |||
[0.88] = "22/25", | |||
[0.875] = "7/8", | |||
[0.85] = "17/20", | |||
[0.7] = "7/10", | |||
[0.8] = "4/5", | |||
[0.6] = "3/5", | |||
[0.5625] = "9/16", | |||
[0.55] = "9/20", | |||
[0.50625] = "81/160", | |||
[0.5] = "1/2" | |||
} | |||
-- | |||
-- Rate calculation accessed through #invoke | |||
-- | |||
-- @param frame {table} | |||
-- @return {number} | |||
-- | |||
function p.calcRate(frame) | |||
-- Separate the two numbers passed in as strings | |||
local mult = {} | |||
mult[1] = frame.args[1] | |||
mult[2] = frame.args[2] | |||
-- Initialize numbers for string conversion | |||
local frac = {} | |||
frac[1] = {} | |||
frac[2] = {} | |||
-- If either number is a fraction, split it up into numerator and denominator | |||
-- Thanks, Ender! | |||
for i=1,2,1 do | |||
for number in string.gmatch(mult[i], '([^/]+)') do | |||
table.insert(frac[i], number) | |||
end | |||
-- If either number wasn't a fraction, fill 1 in for its denominator | |||
if frac[i][2] == nil then | |||
frac[i][2] = 1 | |||
end | |||
end | |||
-- These probably don't need to be redefined, but I'm still super new to Lua so I'll come back to it later xd | |||
local num1 = frac[1][1] | |||
local den1 = frac[1][2] | |||
local num2 = frac[2][1] | |||
local den2 = frac[2][2] | |||
return (num1/den1)*(num2/den2) | |||
end | |||
-- | |||
-- Number formatting. Pass in a number in either fraction, decimal, or whole format and convert it. | |||
-- | |||
-- @param rate {string} | |||
-- @param fmt {string} -- "f" for fraction, "p" for percent, "n" for both fraction and percent used in the Note template | |||
-- @param digits {number} -- optional | |||
-- @return {string} | |||
-- | |||
local function fmtRate(rate, fmt, digits) | |||
local out = "" | |||
-- Don't want nil comparisons or whatever | |||
if digits == nil then | |||
digits = 0 | |||
end | |||
local frac = {} | |||
-- If either number is a fraction, split it up into numerator and denominator | |||
-- Thanks, Ender! | |||
for number in string.gmatch(rate, '([^/]+)') do | |||
table.insert(frac, number) | |||
end | |||
-- If either number wasn't a fraction, fill 1 in for its denominator | |||
if frac[2] == nil then | |||
frac[2] = 1 | |||
end | |||
local num = frac[1] | |||
local den = frac[2] | |||
-- Turn rate into a number! | |||
rate = num / den | |||
if fmt == "f" then | |||
if wholeFractions[rate] == nil then | |||
-- Set maximum number of decimal places | |||
if rate < 10 then | |||
-- Displays with two places between 1.01 ~ 9.99 | |||
digits = math.max(digits, 2) | |||
elseif rate < 100 then | |||
-- Displays with one place between 10.1 ~ 99.9 | |||
digits = math.max(digits, 1) | |||
else | |||
-- Otherwise just displays the whole number at 100+ | |||
digits = math.max(digits, 0) | |||
end | |||
-- Even if we're displaying one or more decimal places, cut zeroes off | |||
out = out .. string.format("%s", string.format("1/%." .. digits .. "f", 1/rate)):gsub("%.?0+$", "") | |||
else | |||
out = out .. wholeFractions[rate] | |||
end | |||
return out | |||
elseif fmt == "p" then | |||
-- Display up to five decimal places. Cut zeroes off | |||
rate = string.format("%s%%", string.format("%f", string.format("%.5f", rate*100)):gsub("%.?0+$", "")) | |||
out = out .. rate | |||
return out | |||
end | |||
end | |||
-- | |||
-- Rate display accessed through #invoke | |||
-- | |||
-- @param frame {table} | |||
-- @return {string} | |||
-- | |||
function p.displayRate(frame) | function p.displayRate(frame) | ||
local rate = frame.args[1] | -- Separate the rate (number passed in as string) from the format (string) and digits (string). digits parameter is optional | ||
local fmt = frame.args[2] | |||
local digits = frame.args[3] | |||
local rate = {} | |||
for i=3,#frame,1 do | |||
rate[i] = frame.args[i] | |||
end | |||
local out = "" | |||
if fmt == "f" then | |||
-- Fraction | |||
out = out .. fmtRate(rate[1], "f", digits) | |||
elseif fmt == "p" then | |||
-- Percentage | |||
out = out .. fmtRate(rate[1], "p") | |||
elseif fmt == "n" then | |||
-- Fraction with hover text showing first two input rates as Fraction (Percentage) | |||
local span = mw.html.create("span") | |||
span | |||
:addClass("more_info") | |||
:wikitext("%s %s", rate[1], rate2) | |||
--:attr("title", string.format("Drop Rate: %s (%s)
Rare Rate: %s (%s)", fmtRate(rate[1], "f", 2), fmtRate(rate[1], "p"), fmtRate(rate[2], "f", 2), fmtRate(rate[2], "p"))) | |||
:css("border-bottom", "1px dotted") | |||
--:wikitext(string.format("%s", fmtRate(p.calcRate(rate[1], rate[2])))) | |||
--out = out .. fmtRate(rate, "f", 2) .. " (" .. fmtRate(rate, "p") .. ")" | |||
end | |||
return out | |||
end | end | ||
return p | return p | ||
-- </nowiki> |
Revision as of 08:55, 6 May 2023
Documentation for this module may be created at Module:Rates/Sandbox/doc
-- <nowiki> -- -- Formats drop rates and calculates two rates multiplied together (usually DAR and RDR) -- local p = {} -- Every DAR/RDR fraction between 1/2 and 1/1 local wholeFractions = { [0.9] = "9/10", [0.88] = "22/25", [0.875] = "7/8", [0.85] = "17/20", [0.7] = "7/10", [0.8] = "4/5", [0.6] = "3/5", [0.5625] = "9/16", [0.55] = "9/20", [0.50625] = "81/160", [0.5] = "1/2" } -- -- Rate calculation accessed through #invoke -- -- @param frame {table} -- @return {number} -- function p.calcRate(frame) -- Separate the two numbers passed in as strings local mult = {} mult[1] = frame.args[1] mult[2] = frame.args[2] -- Initialize numbers for string conversion local frac = {} frac[1] = {} frac[2] = {} -- If either number is a fraction, split it up into numerator and denominator -- Thanks, Ender! for i=1,2,1 do for number in string.gmatch(mult[i], '([^/]+)') do table.insert(frac[i], number) end -- If either number wasn't a fraction, fill 1 in for its denominator if frac[i][2] == nil then frac[i][2] = 1 end end -- These probably don't need to be redefined, but I'm still super new to Lua so I'll come back to it later xd local num1 = frac[1][1] local den1 = frac[1][2] local num2 = frac[2][1] local den2 = frac[2][2] return (num1/den1)*(num2/den2) end -- -- Number formatting. Pass in a number in either fraction, decimal, or whole format and convert it. -- -- @param rate {string} -- @param fmt {string} -- "f" for fraction, "p" for percent, "n" for both fraction and percent used in the Note template -- @param digits {number} -- optional -- @return {string} -- local function fmtRate(rate, fmt, digits) local out = "" -- Don't want nil comparisons or whatever if digits == nil then digits = 0 end local frac = {} -- If either number is a fraction, split it up into numerator and denominator -- Thanks, Ender! for number in string.gmatch(rate, '([^/]+)') do table.insert(frac, number) end -- If either number wasn't a fraction, fill 1 in for its denominator if frac[2] == nil then frac[2] = 1 end local num = frac[1] local den = frac[2] -- Turn rate into a number! rate = num / den if fmt == "f" then if wholeFractions[rate] == nil then -- Set maximum number of decimal places if rate < 10 then -- Displays with two places between 1.01 ~ 9.99 digits = math.max(digits, 2) elseif rate < 100 then -- Displays with one place between 10.1 ~ 99.9 digits = math.max(digits, 1) else -- Otherwise just displays the whole number at 100+ digits = math.max(digits, 0) end -- Even if we're displaying one or more decimal places, cut zeroes off out = out .. string.format("%s", string.format("1/%." .. digits .. "f", 1/rate)):gsub("%.?0+$", "") else out = out .. wholeFractions[rate] end return out elseif fmt == "p" then -- Display up to five decimal places. Cut zeroes off rate = string.format("%s%%", string.format("%f", string.format("%.5f", rate*100)):gsub("%.?0+$", "")) out = out .. rate return out end end -- -- Rate display accessed through #invoke -- -- @param frame {table} -- @return {string} -- function p.displayRate(frame) -- Separate the rate (number passed in as string) from the format (string) and digits (string). digits parameter is optional local fmt = frame.args[2] local digits = frame.args[3] local rate = {} for i=3,#frame,1 do rate[i] = frame.args[i] end local out = "" if fmt == "f" then -- Fraction out = out .. fmtRate(rate[1], "f", digits) elseif fmt == "p" then -- Percentage out = out .. fmtRate(rate[1], "p") elseif fmt == "n" then -- Fraction with hover text showing first two input rates as Fraction (Percentage) local span = mw.html.create("span") span :addClass("more_info") :wikitext("%s %s", rate[1], rate2) --:attr("title", string.format("Drop Rate: %s (%s)
Rare Rate: %s (%s)", fmtRate(rate[1], "f", 2), fmtRate(rate[1], "p"), fmtRate(rate[2], "f", 2), fmtRate(rate[2], "p"))) :css("border-bottom", "1px dotted") --:wikitext(string.format("%s", fmtRate(p.calcRate(rate[1], rate[2])))) --out = out .. fmtRate(rate, "f", 2) .. " (" .. fmtRate(rate, "p") .. ")" end return out end return p -- </nowiki>