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 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
{{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%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%

Example when limit is 100%:

{{Stat Factors Table|Arrest Success Chance}}

it produces:

Social Skill Level CollapseArrest Success Chance
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%

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

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

Medical Skill Level CollapseMedical Surgery Success Chance
100% Manipulation 125% Manipulation 150% Manipulation
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%
0 0%

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