Difference between revisions of "Module:Thought"

From RimWorld Wiki
Jump to navigation Jump to search
m
m (Very minor edit. I may have to deprecate this: While it works, it has some undesired behaviour due to being LUA. For instance, the long dash (−) is not a valid "minus" sign, making problematic its use (I could replace it on the final result, probably). Also, It may be heavier than the template version (while easier to parse). On the bright side, It did teach me how to make Modules work (the main purpose of writing this), so not a complete loss.)
 
(7 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
--[[
 
--[[
The Preprocessor visited node count was reduced from 969 to 508.
+
This module implements the functions of Template:Thought
 
]]
 
]]
 +
 
local p = {}
 
local p = {}
 
local getArgs = require('Module:Arguments').getArgs
 
local getArgs = require('Module:Arguments').getArgs
--local valores_ingresados={"value", "value2", "value3", "value4", "value5", "value6", "value7", "value8", "value9" }
+
 
 +
--[[ The template argument goes to "main"  
 +
Only this funcion will work when invoked. This is case sensitive.
 +
What it does is obtain the data from the wiki to a fomrat readable by other functions]]
  
 
function p.main(frame)
 
function p.main(frame)
 
local args = getArgs(frame)
 
local args = getArgs(frame)
local desc = tostring(args["desc"])
 
local label = tostring(args["label"])
 
local duration = tonumber(args["duration"])
 
local stack = tonumber(args["stack"])
 
 
local multi = tonumber(args["multi"]) or 1
 
local multi = tonumber(args["multi"]) or 1
-- The advantage of adding values to an empty list rather than defining a list is that no
+
--[[ The advantage of adding values to an empty list rather than defining a list
-- nil values will get into the list. This means that values don't have to be consecutive.
+
with the correct values is that no nil values will get into the list this way.
-- EX: value9 is valid w/o defining value7 and value8.
+
This means that values don't have to be consecutive.
 +
EX: value9 is valid w/o defining value2 to value8.
 +
]]
 
local valores = {}
 
local valores = {}
 
valores[#valores+1]=args["value"]
 
valores[#valores+1]=args["value"]
Line 27: Line 29:
 
valores[#valores+1]=args["value9"]
 
valores[#valores+1]=args["value9"]
 
if tonumber(args["value"]) then
 
if tonumber(args["value"]) then
return p._main(desc, label, duration, stack, multi, valores)
+
return p._main(tostring(args["desc"]), tostring(args["label"]), tonumber(args["duration"]), tonumber(args["stack"]), multi, valores)
 
else
 
else
return "Missing value field."
+
return "<big><b>Missing value. Please, define a numerical value to use.</b></big>"
 
end
 
end
 
end
 
end
 +
 +
--[[
 +
_main function decides the kind of thought this will be and returns the final output
 +
If the are several defines values, then it uses the Thought function
 +
If only value is defined, then:
 +
- If both stack and the multiplier "multi" are 1, it gives a result early.
 +
multi defaults to 1 when not defined (or invalid)
 +
- Otherwise, it calls the stacks function.
 +
]]
  
 
function p._main(desc, label, duration, stack, multi, valores)
 
function p._main(desc, label, duration, stack, multi, valores)
 
local final_string = duration and " [[mood]] for "..duration.." [[Time|days]]" or " [[mood]]"
 
local final_string = duration and " [[mood]] for "..duration.." [[Time|days]]" or " [[mood]]"
 +
local middle_string ='<abbr title="'..desc..'"><i>'..(label:gsub("^%l", string.upper))..'</i></abbr>'
 +
-- middle_string is pure convenience. It makes reading the output easier.
 
-- "valores" is a list of all values given to the function.
 
-- "valores" is a list of all values given to the function.
 
-- This checks if a second value exist
 
-- This checks if a second value exist
 
if valores[2] then
 
if valores[2] then
return p.Thought(valores)..'<abbr title="'..desc..'">'..(label:gsub("^%l", string.upper))..'</abbr>'..final_string
+
return p.Thought(valores)..middle_string..final_string
else --Only one value
+
else --Only initial value defined
 
if stack==1 and multi==1 then
 
if stack==1 and multi==1 then
 +
local value = valores[1]
 
if tonumber(value)>0 then
 
if tonumber(value)>0 then
return '<b><font color="forestgreen">'..value..'</font></b> '..'<abbr title="'..desc..'">'..(label:gsub("^%l", string.upper))..'</abbr>'..final_string
+
return '<b><font color="forestgreen">'..value..'</font></b> '..middle_string..final_string
 
elseif tonumber(value) == 0 then
 
elseif tonumber(value) == 0 then
return '<b>'..value..'</b> '..'<abbr title="'..desc..'">'..(label:gsub("^%l", string.upper))..'</abbr>'..final_string
+
return '<b>'..value..'</b> '..middle_string..final_string
 
else
 
else
return '<b><font color="firebrick">'..value..'</font></b> '..'<abbr title="'..desc..'">'..(label:gsub("^%l", string.upper))..'</abbr>'..final_string
+
return '<b><font color="firebrick">'..value..'</font></b> '..middle_string..final_string
 
end
 
end
 
end
 
end
return p.stacks(stack, multi, valores[1])..'<abbr title="'..desc..'">'..(label:gsub("^%l", string.upper))..'</abbr>'..final_string
+
return p.stacks(stack, multi, valores[1])..middle_string..final_string
 
end
 
end
 
end
 
end
  
 
--[[
 
--[[
This function returns a string if more than 1 value was defined.
+
The "Thought" function returns a string if more than 1 value was defined.
1. It adds all the numbers to a list
+
It iterates through all the values defined (contained on the list "valores")
1.2 Red for negatves, Green otherwise
+
For each element:
2. It concatenates all elements of said lists, wth some extras to make sense.]]
+
1.- If it is a valid number, then it valuates what kind of number it is.
 +
1.2.- If it is, it then decides what color it need. Currently, it returns:
 +
Green for positive, Red for negative, None for 0.
 +
2.- It it is not a valid number, it returns the value bolded and large. The idea is to make the mistake obvious.
 +
3.- Once all values are checked, it concatenates all results, with some extras to make sense.
 +
This last part is what it returns.
 +
]]
  
 
function p.Thought(valores)
 
function p.Thought(valores)
Line 65: Line 85:
 
local vy = ""
 
local vy = ""
 
if tonumber(vx) then -- A number.
 
if tonumber(vx) then -- A number.
if tonumber(vx)<0 then vy='<b><font color="firebrick">'..vx.."</font></b>" else vy='<b><font color="forestgreen">'..vx.."</font></b>" end
+
vy = tonumber(vx)<0 and '<b><font color="firebrick">'..vx.."</font></b>" or tonumber(vx)>0 and '<b><font color="forestgreen">'..vx.."</font></b>" or '<b>0</b>'
 
else
 
else
vy='<b>'..vx.."</b>" --The idea is to prevent a hard to track error
+
vy='<big><b>'..vx.."</b></big>" --The idea is to prevent a hard to track error
 
end
 
end
 
valores_buscados[#valores_buscados+1]=vy
 
valores_buscados[#valores_buscados+1]=vy
Line 75: Line 95:
  
 
--[[
 
--[[
This function return a string for the case that only 1 value was defined.
+
The "stacks" function return a string for the case that only 1 value was defined.
 
1.  If a stack value was defined:
 
1.  If a stack value was defined:
 
1.1 Is stack equal to 1
 
1.1 Is stack equal to 1
Line 84: Line 104:
  
 
Finally, some final code to decide what color to use.
 
Finally, some final code to decide what color to use.
1. Green for positive.
+
1. Green (forestgreen) for positive.
 
2. None for 0.
 
2. None for 0.
3. Red for negatives.
+
3. Red (firebrick) for negatives.
 +
The retuned value is rounded half-down. (Meaning 0.5 -> 0 )
 +
string.format("%.2f", number))
 +
To combat that, I add 0.001 to the number calculated. It should be enough.
 
]]
 
]]
  
Line 97: Line 120:
 
end
 
end
 
else
 
else
text = "Stacking "..stack.." times with a "..multi.." multiplier for maximum of "..tostring(value*( 1 - multi^stack)/(1 - multi))
+
text = "Stacking "..stack.." times with a "..multi.." multiplier for maximum of "..string.format("%.2f", value*( 1 - multi^stack)/(1 - multi) + 0.001)
 
end
 
end
 
else
 
else
Line 103: Line 126:
 
text = "Stacking infinitely"
 
text = "Stacking infinitely"
 
else
 
else
text = "Stacking with a "..multi.." multiplier for maximum of "..tostring(value*( 1 - multi^100)/(1 - multi) )
+
text = "Stacking with a "..multi.." multiplier for maximum of "..string.format("%.2f", value*( 1 - multi^100)/(1 - multi) + 0.001)
 
end
 
end
 
end
 
end
Line 116: Line 139:
 
end
 
end
  
 +
--This last part outputs the actual result. W/O it, it gives an error.
 
return p
 
return p

Latest revision as of 19:04, 26 August 2024

Documentation for this module may be created at Module:Thought/doc

--[[
This module implements the functions of Template:Thought
]]

local p = {}
local getArgs = require('Module:Arguments').getArgs

--[[ The template argument goes to "main" 
Only this funcion will work when invoked. This is case sensitive.
What it does is obtain the data from the wiki to a fomrat readable by other functions]]

function p.main(frame)
	local args = getArgs(frame)
	local multi = tonumber(args["multi"]) or 1
--[[ The advantage of adding values to an empty list rather than defining a list
	with the correct values is that no nil values will get into the list this way.
	This means that values don't have to be consecutive.
	EX: value9 is valid w/o defining value2 to value8.
	]]
	local valores = {}
	valores[#valores+1]=args["value"]
	valores[#valores+1]=args["value2"]
	valores[#valores+1]=args["value3"]
	valores[#valores+1]=args["value4"]
	valores[#valores+1]=args["value5"]
	valores[#valores+1]=args["value6"]
	valores[#valores+1]=args["value7"]
	valores[#valores+1]=args["value8"]
	valores[#valores+1]=args["value9"]
	if tonumber(args["value"]) then
		return p._main(tostring(args["desc"]), tostring(args["label"]), tonumber(args["duration"]), tonumber(args["stack"]), multi, valores)
		else
			return "<big><b>Missing value. Please, define a numerical value to use.</b></big>"
	end
end

--[[
_main function decides the kind of thought this will be and returns the final output
If the are several defines values, then it uses the Thought function
If only value is defined, then:
	- If both stack and the multiplier "multi" are 1, it gives a result early.
		multi defaults to 1 when not defined (or invalid)
	- Otherwise, it calls the stacks function.
]]

function p._main(desc, label, duration, stack, multi, valores)
	local final_string = duration and " [[mood]] for "..duration.." [[Time|days]]" or " [[mood]]"
	local middle_string ='<abbr title="'..desc..'"><i>'..(label:gsub("^%l", string.upper))..'</i></abbr>'
	-- middle_string is pure convenience. It makes reading the output easier.
	-- "valores" is a list of all values given to the function.
	-- This checks if a second value exist
	if valores[2] then
		return p.Thought(valores)..middle_string..final_string
	else --Only initial value defined
		if stack==1 and multi==1 then
			local value = valores[1]
			if tonumber(value)>0 then
				return '<b><font color="forestgreen">'..value..'</font></b> '..middle_string..final_string
			elseif tonumber(value) == 0 then
				return '<b>'..value..'</b> '..middle_string..final_string
			else
				return '<b><font color="firebrick">'..value..'</font></b> '..middle_string..final_string
			end
		end
		return p.stacks(stack, multi, valores[1])..middle_string..final_string
	end
end

--[[
The "Thought" function returns a string if more than 1 value was defined.
It iterates through all the values defined (contained on the list "valores") 
For each element:
1.- If it is a valid number, then it valuates what kind of number it is.
1.2.- If it is, it then decides what color it need. Currently, it returns:
	Green for positive, Red for negative, None for 0.
2.- It it is not a valid number, it returns the value bolded and large. The idea is to make the mistake obvious.
3.- Once all values are checked, it concatenates all results, with some extras to make sense.
This last part is what it returns.
]]

function p.Thought(valores)
	local valores_buscados={}
	for i, j in ipairs(valores) do
		local vx = valores[i]
		local vy = ""
		if tonumber(vx) then -- A number.
			vy = tonumber(vx)<0 and '<b><font color="firebrick">'..vx.."</font></b>" or tonumber(vx)>0 and '<b><font color="forestgreen">'..vx.."</font></b>" or '<b>0</b>'
		else
			vy='<big><b>'..vx.."</b></big>" --The idea is to prevent a hard to track error
		end
		valores_buscados[#valores_buscados+1]=vy
	end
	return "<b>"..table.concat(valores_buscados,"<b>/</b>").."</b> "
end

--[[
The "stacks" function return a string for the case that only 1 value was defined.
1.  If a stack value was defined:
1.1 Is stack equal to 1
1.2 Any other case.
2.  If a stack was not defined, then check the multiplier
2.1 If the multiplier is equal or above one
2.2 If the multiplier is below 1.

Finally, some final code to decide what color to use.
1. Green (forestgreen) for positive.
2. None for 0.
3. Red (firebrick) for negatives.
The retuned value is rounded half-down. (Meaning 0.5 -> 0 )
	string.format("%.2f", number))
To combat that, I add 0.001 to the number calculated. It should be enough.
]]

function p.stacks(stack, multi, value)
	local text=""
	if stack then
		if multi == 1 then
			if stack ~= 1 then 
				text = "Stacking "..stack.." times for a maximum of "..tostring(value*stack)
			end
		else
			text = "Stacking "..stack.." times with a "..multi.." multiplier for maximum of "..string.format("%.2f", value*( 1 - multi^stack)/(1 - multi) + 0.001)
		end
	else
		if multi >= 1 then --I want to avoid the case of really large numbers.
			text = "Stacking infinitely"
		else
			text = "Stacking with a "..multi.." multiplier for maximum of "..string.format("%.2f", value*( 1 - multi^100)/(1 - multi) + 0.001)
		end
	end

	if tonumber(value)>0 then
		return '<abbr title="'..text..'"><b><font color="forestgreen">'..value..'</font></b></abbr> '
	elseif tonumber(value) == 0 then
		return '<abbr title="'..text..'"><b>'..value..'</b></abbr> '
	else
		return '<abbr title="'..text..'"><b><font color="firebrick">'..value..'</font></b></abbr> '
	end
end

--This last part outputs the actual result. W/O it, it gives an error.
return p