Module:Stat Factors Table
This module is meant to be used by Template:Stat Factors Table Row, which in turn is meant to be used alogside Template:Stat Factors Table.
This module returns the rows used in said table. It accept 8 inputs: skillBase, skillBonus, statMin, statMax, capImportance, capLimit, resultCols, LV, Ln
Any value not given is assumed 0. There are exceptions for the default values of Stat Maximum (99999999) and statMin (0), both of which are defined on Template:Stat Factors Table.
This can probably be further improved. Regardless, this represents a 71% improvement over the ParserFunctions method.
Examples:
{{Stat Factors Table}}
on the Butchery Efficiency page would produce:
| Cooking Skill Level | Butchery Efficiency | ||
|---|---|---|---|
| 100% Manipulation | 125% Manipulation | 150% Manipulation | |
| 0 | 75% | 91.88% | 108.75% |
| 1 | 77.5% | 94.94% | 112.38% |
| 2 | 80% | 98% | 116% |
| 3 | 82.5% | 101.06% | 119.63% |
| 4 | 85% | 104.13% | 123.25% |
| 5 | 87.5% | 107.19% | 126.88% |
| 6 | 90% | 110.25% | 130.5% |
| 7 | 92.5% | 113.31% | 134.13% |
| 8 | 95% | 116.38% | 137.75% |
| 9 | 97.5% | 119.44% | 141.38% |
| 10 | 100% | 122.5% | 145% |
| 11 | 102.5% | 125.56% | 148.63% |
| 12 | 105% | 128.63% | 150% |
| 13 | 107.5% | 131.69% | 150% |
| 14 | 110% | 134.75% | 150% |
| 15 | 112.5% | 137.81% | 150% |
| 16 | 115% | 140.88% | 150% |
| 17 | 117.5% | 143.94% | 150% |
| 18 | 120% | 147% | 150% |
| 19 | 122.5% | 150% | 150% |
| 20 | 125% | 150% | 150% |
{{Stat Factors Table|Foraged Food Amount}}
on any page would produce:
| Plants Skill Level | Foraged Food Amount | ||
|---|---|---|---|
| 100% Sight | 125% Sight | 150% Sight | |
| 0 | 0% | 0% | 0% |
| 1 | 9% | 11.03% | 13.05% |
| 2 | 18% | 22.05% | 26.1% |
| 3 | 27% | 33.08% | 39.15% |
| 4 | 36% | 44.1% | 52.2% |
| 5 | 45% | 55.13% | 65.25% |
| 6 | 54% | 66.15% | 78.3% |
| 7 | 63% | 77.18% | 91.35% |
| 8 | 72% | 88.2% | 104.4% |
| 9 | 81% | 99.23% | 117.45% |
| 10 | 90% | 110.25% | 130.5% |
| 11 | 99% | 121.28% | 143.55% |
| 12 | 108% | 132.3% | 156.6% |
| 13 | 117% | 143.33% | 169.65% |
| 14 | 126% | 154.35% | 182.7% |
| 15 | 135% | 165.38% | 195.75% |
| 16 | 144% | 176.4% | 208.8% |
| 17 | 153% | 187.43% | 221.85% |
| 18 | 162% | 198.45% | 234.9% |
| 19 | 171% | 209.48% | 247.95% |
| 20 | 180% | 220.5% | 261% |
Example when limit is 100%:
{{Stat Factors Table|Arrest Success Chance}}
it produces:
| Social Skill Level | Arrest Success Chance |
|---|---|
| 0 | 60% |
| 1 | 67.5% |
| 2 | 75% |
| 3 | 82.5% |
| 4 | 90% |
| 5 | 97.5% |
| 6 | 100% |
| 7 | 100% |
| 8 | 100% |
| 9 | 100% |
| 10 | 100% |
| 11 | 100% |
| 12 | 100% |
| 13 | 100% |
| 14 | 100% |
| 15 | 100% |
| 16 | 100% |
| 17 | 100% |
| 18 | 100% |
| 19 | 100% |
| 20 | 100% |
Example when limit is >100% but <125%: Note: Research Speed is not an appropriate use of the template, as it relies equally on two different capacities, however, at the time of writing no compatible example of an inter-column limit exists:
{{Stat Factors Table|Research Speed }}
on any page would produce:
| Intellectual Skill Level | Research Speed | |
|---|---|---|
| 100% Manipulation | 110%+ Manipulation | |
| 0 | 10% | 10% |
| 1 | 19.5% | 20.48% |
| 2 | 31% | 32.55% |
| 3 | 42.5% | 44.63% |
| 4 | 54% | 56.7% |
| 5 | 65.5% | 68.78% |
| 6 | 77% | 80.85% |
| 7 | 88.5% | 92.93% |
| 8 | 100% | 105% |
| 9 | 111.5% | 117.08% |
| 10 | 123% | 129.15% |
| 11 | 134.5% | 141.23% |
| 12 | 146% | 153.3% |
| 13 | 157.5% | 165.38% |
| 14 | 169% | 177.45% |
| 15 | 180.5% | 189.53% |
| 16 | 192% | 201.6% |
| 17 | 203.5% | 213.68% |
| 18 | 215% | 225.75% |
| 19 | 226.5% | 237.83% |
| 20 | 238% | 249.9% |
Example when skills have to be specifically defined:
{{Stat Factors Table|Plant Harvest Yield|l0=0.60|l1=0.70|l2=0.75|l3=0.80|l4=0.85|l5=0.90|l6=0.95|l7=0.98|l8=1.00|l9=1.01|l10=1.02|l11=1.03|l12=1.04|l13=1.05|l14=1.06|l15=1.07|l16=1.08|l17=1.09|l18=1.10|l19=1.12|l20=1.13}}
it produces:
| Plants Skill Level | Plant Harvest Yield | ||
|---|---|---|---|
| 100% Manipulation | 125% Manipulation | 150% Manipulation | |
| 0 | 60% | 64.5% | 69% |
| 1 | 70% | 75.25% | 80.5% |
| 2 | 75% | 80.63% | 86.25% |
| 3 | 80% | 86% | 92% |
| 4 | 85% | 91.38% | 97.75% |
| 5 | 90% | 96.75% | 103.5% |
| 6 | 95% | 102.13% | 109.25% |
| 7 | 98% | 105.35% | 112.7% |
| 8 | 100% | 107.5% | 115% |
| 9 | 101% | 108.58% | 116.15% |
| 10 | 102% | 109.65% | 117.3% |
| 11 | 103% | 110.73% | 118.45% |
| 12 | 104% | 111.8% | 119.6% |
| 13 | 105% | 112.88% | 120.75% |
| 14 | 106% | 113.95% | 121.9% |
| 15 | 107% | 115.03% | 123.05% |
| 16 | 108% | 116.1% | 124.2% |
| 17 | 109% | 117.18% | 125.35% |
| 18 | 110% | 118.25% | 126.5% |
| 19 | 112% | 120.4% | 128.8% |
| 20 | 113% | 121.48% | 129.95% |
| Medical Skill Level | Medical Surgery Success Chance | ||
|---|---|---|---|
| 100% Manipulation | 125% Manipulation | 150% Manipulation | |
| 0 | 10% | 12.5% | 15% |
| 1 | 20% | 25% | 30% |
| 2 | 30% | 37.5% | 45% |
| 3 | 40% | 50% | 60% |
| 4 | 50% | 62.5% | 75% |
| 5 | 60% | 75% | 90% |
| 6 | 70% | 87.5% | 105% |
| 7 | 75% | 93.75% | 112.5% |
| 8 | 80% | 100% | 120% |
| 9 | 85% | 106.25% | 127.5% |
| 10 | 90% | 112.5% | 135% |
| 11 | 92% | 115% | 138% |
| 12 | 94% | 117.5% | 141% |
| 13 | 96% | 120% | 144% |
| 14 | 98% | 122.5% | 147% |
| 15 | 100% | 125% | 150% |
| 16 | 102% | 127.5% | 153% |
| 17 | 104% | 130% | 156% |
| 18 | 106% | 132.5% | 159% |
| 19 | 108% | 135% | 162% |
| 20 | 110% | 137.5% | 165% |
--local getArgs -- lazily initialized
local getArgs = require('Module:Arguments').getArgs
local p = {}
local wrap = {} -- Holds wrapper functions that process arguments from #invoke. These act as intemediary between functions meant for #invoke and functions meant for Lua.
local function unpackNumberArgs(args)
-- Returns an unpacked list of arguments specified with numerical keys.
local ret = {}
for k, v in pairs(args) do
if type(k) == 'number' then
table.insert(ret, v)
end
end
return unpack(ret)
end
--Stat Factors Table Row
function wrap.TableRow(args)
return p._TableRow(unpackNumberArgs(args))
end
function p._TableRow(skillBase, skillBonus, statMin, statMax, capImportance, capLimit, resultCols, LV, Ln)
--Remove local if these variables are to be used somewhere else.
local argumentos={skillBase,skillBonus,statMin,statMax,capImportance,capLimit,resultCols,LV,Ln}
for i = 1,8 do --This should prevent errors if a number is not defined.
if type(argumentos[i])~='number' then
if i == 6 then -- In case capLimit is not correctly set.
argumentos[6]=1000
else
argumentos[i]=0
end
else
argumentos[i]=tonumber(argumentos[i])
end
end
-- This was giving issues. This also means that the list "argumentos" may be redundant now. Adress later, as I don't undertand on a first pass what was failing.
-- skillBase,skillBonus,statMin,statMax,capImportance,capLimit,resultCols,LV,Ln = argumentos[1],argumentos[2],argumentos[3],argumentos[4],argumentos[5],argumentos[6],argumentos[7],argumentos[8]
-- Do note that statMin, statMax are handled by "Template:Stat Factors Table" (including defaults)
if tonumber(Ln)==nil then --Sanitizes input and allows for Ln=0.
factor = skillBase + (tonumber(skillBonus) or 0) * LV
else
factor = tonumber(Ln)
end
local Pval = math.min(math.max(factor,statMin),statMax)
R_Pval = tostring(math.floor(Pval*10000+0.5)/100).."%" -- This formats the number as a 2 digit percent value, rounded up.
-- R_Pval = string.format("%.2f", Pval*100).."%" -- While Easier to parse, this has the issue of forcing 2 decimals for all numbers.
if tonumber(resultCols)>1 then
Pval = factor * ( 1 + capImportance * math.min(capLimit-1, 0.25))
Pval = math.min(math.max(Pval,statMin),statMax)
R_Sval="<td>"..tostring(math.floor(Pval*10000+0.5)/100).."% </td>"
else
R_Sval=""
end
if tonumber(resultCols)>2 then
Pval = factor * ( 1 + capImportance * math.min(capLimit-1, 0.5))
Pval = math.min(math.max(Pval,statMin),statMax)
R_Tval="<td>"..tostring(math.floor(Pval*10000+0.5)/100).."% </td>"
else
R_Tval=""
end
return "|-\r\n!"..LV.."\r\n|"..R_Pval..R_Sval..R_Tval
-- There are more efficient ways, but this works.
end
-- Deep Drill Speed custom version. Includes Time in minutes (at x1 speed)
function wrap.Table_DDS(frame) --The normal unpacking is giving me issues, so this is a potential if ugly work around.
-- return p._Table_DDS(unpackNumberArgs(args))
local args = getArgs(frame)
return p._Table_DDS(tonumber(args[1]),tonumber(args[2]),tonumber(args[3]))
end
function p._Table_DDS(skillBase, skillBonus, capImportance)
--statMin=0 so omitted, skill uncapped so statMax omitted.
local argumentos={skillBase, skillBonus, capImportance}
for i = 1,3 do --This should prevent errors if a number is not defined.
if type(argumentos[i])~='number' then
argumentos[i]=0
end
end
skillBase,skillBonus,capImportance = argumentos[1],argumentos[2],argumentos[3]
-- If needed, the Header can be moved outside
local Header = '{| class = "mw-collapsible wikitable" width="180" style="text-align: center;"\r\n' -- May just call it from outside.
Header = Header..'! rowspan=2 | Mining Skill Level'..'\r\n'
Header = Header..'! colspan=3 | Deep Drilling Speed<br/>(Real time at 1x speed)'..'\r\n'
Header = Header..'|-\r\n'
Header = Header..'! 100% Manipulation !! 125% Manipulation !! 150% Manipulation'..'\r\n'
local line, cuerpo = "", ""
local factor = 0
local val1, val2, val3 = 0,0,0
local time1, time2, time3 = 0,0,0
for i = 0, 20 do --This creates the table itself.
line = "|-\r\n!"..i.."\r\n|" --Just for order
factor = skillBase + tonumber(skillBonus) * i
val1 = math.max(factor, 0)
time1 = 14000/(val1*3600) -- This is time in minutes. Because factor is a percentage, I need to multiply this by 100 to compensate.
-- This formats the number as a percent value with X decimals, rounded up. Change to %.0f for no decimals.
R_Pval= string.format("%.0f", val1*100).."% <br/>"..string.format("(%.2f min)", time1)
val2 = factor * ( 1 + capImportance * 0.25)
val2 = math.max(val2, 0)
time2 = 14000/(val2*3600)
R_Sval= string.format("<td>%.0f", val2*100).."% <br/>"..string.format("(%.2f min)", time2).."</td>"
val3 = factor * ( 1 + capImportance * 0.5)
val3 = math.max(val3, 0)
time3 = 14000/(val3*3600)
R_Tval= string.format("<td>%.0f", val3*100).."% <br/>"..string.format("(%.2f min)", time3).."</td>"
cuerpo = cuerpo..line..R_Pval..R_Sval..R_Tval.."\r\n"
end
return Header..cuerpo.."|}" --This should be the entire table. I may be a space short.
end
--[[
Wrapper function that does basic argument processing. This ensures that all functions from #invoke can use either the current
frame or the parent frame, and it also trims whitespace for all arguments and removes blank arguments.
]]
local mt = { __index = function(t, k)
return function(frame)
if not getArgs then
getArgs = require('Module:Arguments').getArgs
end
return wrap[k](getArgs(frame)) -- Argument processing is left to Module:Arguments. Whitespace is trimmed and blank arguments are removed.
end
end }
return setmetatable(p, mt)
-- END OF MODULE