Module:Grind/autocalc

From Fallen London Wiki

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

local p = {}

local common = require('Module:Grind/common')
local util = require('Module:Grind/util')
local GRON = require('Module:Grind/GRON')
local fml = require('Module:Grind/fml')

-- == Autocalculator utilities ==

local function row_mainstat(name)
	return {name, name, '100', 'int', '0-500'}
end

local function row_advstat(name)
	return {name, name, '0', 'int', '0-20'}
end

local function row_menace(name)
	local defaults = {
		Wounds = '0.33',
		Scandal = '0.33',
		Suspicion = '0.33',
		Nightmares = '0.33'
	}
	return {'Menace:' .. name, name, defaults[name] or '0', 'float', '0-'}
end

local function row_material(name)
	return {'Material:' .. name, name, '0.2', 'float', '0-'}
end

local function row_boolean(name, title)
	return {name, title, '0', 'toggleswitch', '1,0'}
end

local function row_buttonselect(name, title, default, options)
	return {name, title, default, 'buttonselect', options}
end

local function row_select(name, title, default, options)
	return {name, title, default, 'select', options}
end

local function row_string(name, title)
	return {name, title, '', 'string'}
end

local function row_number(name, title)
	return {name, title, '0', 'float'}
end

local function genlist(list, prefix)
	prefix = prefix or ''
	local s = ''
	for i, item in ipairs(list) do
		if i > 1 then
			s = s .. ','
		end
		s = s .. prefix .. item
	end
	return s
end

local list = {
	mainstats = genlist(common.mainstats),
	advstats = genlist(common.advstats),
	menaces = genlist(common.menaces, 'Menace:')
}

-- Builds HTML calculator configuration.
-- See [[MediaWiki:Common.js/calc.js]].
function p.buildcalc(grind, title, id, template, resources, entries)
	local form = 'form-' .. id
	local result = 'result-' .. id
	local s = '<pre class="jcConfig">\n'
	s = s .. 'template = GrindAnalyse\n'
	s = s .. 'name = ' .. title .. '\n'
	s = s .. 'form = ' .. form .. '\n'
	s = s .. 'result = ' .. result .. '\n'
	s = s .. 'param = 1||' .. grind .. '|hidden\n'
	
	if template ~= nil then
		s = s .. 'param = Template||' .. template .. '|hidden\n'
	end
	
	table.insert(resources, 'Nothing')
	if #resources > 1 then
		s = s .. 'param = Resource|Optimise for:||select|'
		for i, resource in ipairs(resources) do
			if i > 1 then
				s = s .. ';'
			end
			s = s .. resource
		end
		s = s .. '\n'
	elseif #resources == 1 then
		local resource = resources[1]
		s = s .. 'param = Resource|Optimise for:|' .. resource .. '|fixed\n'
	end
	
	s = s .. 'param = RPA||per action|hidden\n'
	
	for _, entry in ipairs(entries) do
		s = s .. 'param = '
		for i, field in ipairs(entry) do
			if i > 1 then
				s = s .. '|'
			end
			s = s .. field
		end
		s = s .. '\n'
	end
	
	s = s .. '</pre>'
	s = s .. '<div id="' .. form .. '">Loading...</div>'
	s = s .. '<div id="' .. result .. '"></div>'
	return s
end

-- Generates a list of calculator input entries.
function p.generate(gron, extras, materials)
	local inputs = GRON.inputs(gron)
	local qualities = GRON.qualities(gron)
	local outputs = GRON.outputs(gron)
	
	local mainstats = {}
	local advstats = {}
	local menaces = {}
	local binary = {}
	local unknown = {}
	
	for quality, category in pairs(qualities) do
		if quality == 'Luck' then
			-- skip this one
		elseif category == 'mainstat' then
			mainstats[quality] = true
		elseif category == 'advstat' then
			advstats[quality] = true
		elseif category == 'binary' then
			binary[quality] = true
		elseif category == 'unknown' then
			unknown[quality] = true
		end
	end
	for _, v in pairs(extras) do
		if v:sub(1, 6) == 'Input:' then
			local i = v:sub(7)
			local itype
			i, itype = util.normalise_input(i)
			inputs[i] = itype
		else
			local vtype
			v, vtype = util.normalise_input(v)
			local category = common.identify(v)
			if category == 'mainstat' then
				mainstats[v] = true
			elseif category == 'advstat' then
				advstats[v] = true
			elseif category == 'unknown' then
				if vtype == 'boolean' then
					binary[v:sub(1, -9)] = true
				else
					unknown[v] = true
				end
			end
		end
	end
	for quality, _ in pairs(outputs) do
		if common.identify(quality) == 'menace' then
			menaces[quality] = true
		end
	end
	local entries = {}
	if next(mainstats) ~= nil then
		table.insert(entries, {'maingroup', 'Main stats', '', 'group', list.mainstats})
		for quality, _ in pairs(mainstats) do
			table.insert(entries, row_mainstat(quality))
		end
	end
	if next(advstats) ~= nil then
		table.insert(entries, {'advgroup', 'Advanced skills', '', 'group', list.advstats})
		for quality, _ in pairs(advstats) do
			table.insert(entries, row_advstat(quality))
		end
	end
	if next(menaces) ~= nil then
		table.insert(entries, {'menacegroup', 'Menace costs (in actions per point)', '', 'group', list.menaces})
		for quality, _ in pairs(menaces) do
			table.insert(entries, row_menace(quality))
		end
	end
	if next(materials) ~= nil then
		local materials_set = {}
		for _, quality in pairs(materials) do
			materials_set[quality] = true
		end
		local material_list = {}
		for quality, _ in pairs(materials_set) do
			table.insert(material_list, quality)
		end
		table.insert(entries, {
			'materialgroup', 'Material costs (in actions per point)', '', 'group',
			genlist(material_list, 'Material:')
		})
		for quality, _ in pairs(materials_set) do
			table.insert(entries, row_material(quality))
		end
	end
	if next(binary) ~= nil then
		for quality, _ in pairs(binary) do
			table.insert(entries, row_boolean(quality, quality))
		end
	end
	if next(unknown) ~= nil then
		for quality, _ in pairs(unknown) do
			if common.misc[quality] ~= nil then
				local row_config = common.misc[quality]
				table.insert(entries, {
					quality,
					row_config['title'] or quality,
					row_config['default'],
					row_config['class'],
					row_config['ranges']
				})
			else
				table.insert(entries, row_number(quality, quality))
			end
		end
	end
	if next(inputs) ~= nil then
		local input_list = {}
		for quality, itype in pairs(inputs) do
			table.insert(input_list, quality .. util.input_suffix(itype))
		end
		table.insert(entries, {'inputgroup', 'Inputs', '', 'group', genlist(input_list, 'Input:')})
		for quality, itype in pairs(inputs) do
			local q = 'Input:' .. quality .. util.input_suffix(itype)
			if itype == 'gron' then
				table.insert(entries, row_string(q, quality .. ' (GRON)'))
			elseif itype == 'boolean' then
				table.insert(entries, row_boolean(q, quality))
			elseif itype == 'number' then
				table.insert(entries, row_number(q, quality))
			elseif itype == 'string' then
				table.insert(entries, row_string(q, quality))
			else
				table.insert(entries, row_string(q, quality))
			end
		end
	end
	return entries
end

return p