Module:Stat Factors Table

From RimWorld Wiki
Jump to navigation Jump to search

This module is designed to create tables for the different in-game stat factors. Currently:

This module returns the rows used in said table. It accepts 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%

{{Stat Factors Table|Medical Surgery Success Chance|l0=0.10|l1=0.20|l2=0.30|l3=0.40|l4=0.50|l5=0.60|l6=0.70|l7=0.75|l8=0.80|l9=0.85|l10=0.90|l11=0.92|l12=0.94|l13=0.96|l14=0.98|l15=1.00|l16=1.02|l17=1.04|l18=1.06|l19=1.08|l20=1.10}}

Special case[edit]

The Template:Deep Drilling Speed Table calls the following function:

{{#invoke:Stat Factors Table|Table_DDS|{{#show:Deep Drilling Speed|?Skill Base Factor}}|{{#show:Deep Drilling Speed|?Skill Bonus Factor}}|{{#show:Deep Drilling Speed|?Manipulation Importance}} }}

This calls the following values from the Deep Drilling Speed page:

  • Skill Base factor
  • Skill Bonus Factor
  • Manipulation Importance

To create the following table:

Mining Skill Level Deep Drilling Speed
(Real time at 1x speed)
100% Manipulation 125% Manipulation 150% Manipulation
0 4%
(97.22 min)
5%
(77.78 min)
6%
(64.81 min)
1 16%
(24.31 min)
20%
(19.44 min)
24%
(16.20 min)
2 28%
(13.89 min)
35%
(11.11 min)
42%
(9.26 min)
3 40%
(9.72 min)
50%
(7.78 min)
60%
(6.48 min)
4 52%
(7.48 min)
65%
(5.98 min)
78%
(4.99 min)
5 64%
(6.08 min)
80%
(4.86 min)
96%
(4.05 min)
6 76%
(5.12 min)
95%
(4.09 min)
114%
(3.41 min)
7 88%
(4.42 min)
110%
(3.54 min)
132%
(2.95 min)
8 100%
(3.89 min)
125%
(3.11 min)
150%
(2.59 min)
9 112%
(3.47 min)
140%
(2.78 min)
168%
(2.31 min)
10 124%
(3.14 min)
155%
(2.51 min)
186%
(2.09 min)
11 136%
(2.86 min)
170%
(2.29 min)
204%
(1.91 min)
12 148%
(2.63 min)
185%
(2.10 min)
222%
(1.75 min)
13 160%
(2.43 min)
200%
(1.94 min)
240%
(1.62 min)
14 172%
(2.26 min)
215%
(1.81 min)
258%
(1.51 min)
15 184%
(2.11 min)
230%
(1.69 min)
276%
(1.41 min)
16 196%
(1.98 min)
245%
(1.59 min)
294%
(1.32 min)
17 208%
(1.87 min)
260%
(1.50 min)
312%
(1.25 min)
18 220%
(1.77 min)
275%
(1.41 min)
330%
(1.18 min)
19 232%
(1.68 min)
290%
(1.34 min)
348%
(1.12 min)
20 244%
(1.59 min)
305%
(1.28 min)
366%
(1.06 min)

--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