Module:Stat Factors Table

From RimWorld Wiki
Jump to navigation Jump to search

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 CollapseButchery 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 CollapseForaged 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 CollapseArrest 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 CollapseResearch 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 CollapsePlant 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 CollapseMedical 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