Module:CombStatCalc

From Fallen London Wiki

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

local p = {}

--calc and maketable are for [[Combined Equipment Stats Calculator]]
--calc2, maketable2, and processcats are for [[Outfit Planner – Weighted Combination Challenges]]

local attorder = {
	"Watchful",
	"Shadowy",
	"Dangerous",
	"Persuasive",
	"Respectable",
	"Dreaded",
	"Bizarre",
	"Kataleptic Toxicology",
	"Monstrous Anatomy",
	"A Player of Chess",
	"Glasswork",
	"Shapeling Arts",
	"Artisan of the Red Science",
	"Mithridacy",
	"Zeefaring",
	"Neathproofed",
	"Inerrant",
	"Insubstantial"
}

local allcats = {
	"Boon",
	"Hat",
	"Clothing",
	"Adornment",
	"Gloves",
	"Weapon",
	"Boots",
	"Luggage",
	"Companion",
	"Treasure",
	"Destiny",
	"Tools of the Trade",
	"Affiliation",
	"Transport",
	"Home Comfort",
	"Ship",
	"Crew",
	"Spouse",
	"Club",
	"Airship"
}

function maketable(frame, cat, querylist)
	local ret = ""
	local result = mw.smw.getQueryResult( "[[Category:" .. cat .. "]]" .. querylist .. "|?Has effect|limit=1000" )
	if result["meta"]["count"] == 0 then
		return "<center><big><b>No results found.</b></big></center>"
	end
	local sum_list = {}
	local level_list = {}
	local ret = ""
	for n=1,result["meta"]["count"] do
		local name = result["results"][n]["fulltext"]
		if sum_list[name] == nil then sum_list[name] = 0 end
		if level_list[name] == nil then level_list[name] = "" end
		for _,d in ipairs(result["results"][n]["printouts"]["Has effect"]) do
			if string.find(querylist, d["Modifies quality"]["item"][1]["fulltext"], 1, true) then
				sum_list[name] = sum_list[name] + d["Modifies by"]["item"][1]
				level_list[name] = level_list[name] .. d["Modifies quality"]["item"][1]["fulltext"] .. "#" .. d["Modifies by"]["item"][1] .. "|"
			end
		end
	end

	local k = {}
	for n,_ in pairs(sum_list) do
		table.insert(k, n)
	end
	table.sort(k, function(k1, k2) return sum_list[k1] > sum_list[k2] end)
	
	ret = ret .. '<span style="display:none">' .. frame:expandTemplate{title = 'FontFate'} .. '</span>'
	-- The above is to get the needed styles for the Font templates
	ret = ret .. '<table class="article-table"><tr><th>Total</th><th>Item</th>'
	for n,q in ipairs(attorder) do
		if string.find(querylist, q, 0, true) then
			ret = ret .. "<th>" .. frame:expandTemplate{title = 'I',args = {q}} .. "</th>"
		end
	end
	ret = ret .. '</tr>'
	
	local at = -500
	for _,v in ipairs(k) do
		local espan = 0
		if at ~= sum_list[v] then
			at = sum_list[v]
			for _,l in pairs(sum_list) do
				if l == sum_list[v] then espan = espan + 1 end
			end
			ret = ret .. '<tr><td rowspan="' .. espan .. '"><b>' .. (sum_list[v] >= 0 and "+" or "") .. sum_list[v] .. "</b></td><td>[[" .. v .. "]] " .. frame:expandTemplate{title = 'Restrictions',args = {v}} .. "</td>"
		else
			ret = ret .. "<tr><td>[[" .. v .. "]] " .. frame:expandTemplate{title = 'Restrictions',args = {v}} .. "</td>"
		end
		for _,q in ipairs(attorder) do
			if string.find(level_list[v], q, 0, true) then
				local lv = string.match(level_list[v], q .. "#(.-)|")
				ret = ret .. "<td>" .. (tonumber(lv) >= 0 and "+" or "") .. lv .. "</td>"
			end
		end
		ret = ret .. '</tr>'
	end
	ret = ret .. '</table>'
	return ret
end

function p.calc(frame)
	local args = frame.args
	local argsum = 0
	local querylist = ""
	for q,v in pairs(args) do
		if q ~= "cat" and v ~= "0" then
			argsum = argsum + 1
			querylist = querylist .. "[[Has effect::" .. v .. "]]"
		end
	end
	if argsum < 2 then
		return "<center><big><b>Please select at least 2 attributes!</b></big></center>"
	end
	
	local ret = ""
	if args.cat == "All" then
		for i,c in ipairs(allcats) do
			ret = ret .. "<h2>" .. c .. "</h2>" .. maketable(frame, c, querylist)
		end
	else 
		ret = ret .. maketable(frame, args.cat, querylist)
	end
	return ret
end

function processcats(c)
	local ret = ""
	if string.find(c, "Fate", 0, true) then ret = ret .. "<span class=\"tag tag-fate\">'''[[Fate|FATE]]'''</span> " end
	if string.find(c, "SMEN", 0, true) then ret = ret .. "<span class=\"tag tag-smen\">'''[[Seeking Mr Eaten's Name (Guide)|SMEN]]'''</span> " end
	if string.find(c, "Retired", 0, true) then ret = ret .. "<span class=\"tag tag-retired\">'''RETIRED'''</span> " end
	if string.find(c, "Light Fingers", 0, true) then ret = ret .. "[[File:Lightfingers.png|20px|link=Ambition: Light Fingers!|alt=]] [[Ambition: Light Fingers!]] " end
	if string.find(c, "Heart's Desire", 0, true) then ret = ret .. "[[File:Heartsdesire.png|20px|link=Ambition: Heart's Desire!|alt=]] [[Ambition: Heart's Desire!]] " end
	if string.find(c, "Nemesis", 0, true) then ret = ret .. "[[File:Nemesis.png|20px|link=Ambition: Nemesis|alt=]] [[Ambition: Nemesis]] " end
	if string.find(c, "Bag a Legend", 0, true) then ret = ret .. "[[File:Bagalegend.png|20px|link=Ambition: Bag a Legend!|alt=]] [[Ambition: Bag a Legend!]] " end
	if string.find(c, "Hallowmas", 0, true) then ret = ret .. "<span class=\"tag tag-hallowmas\">'''[[Hallowmas|HALLOWMAS]]'''</span> " end
	if string.find(c, "Feast of the Rose", 0, true) then ret = ret .. "<span class=\"tag tag-rose\">'''[[Feast of the Exceptional Rose|FEAST OF THE ROSE]]'''</span> " end
	if string.find(c, "Christmas", 0, true) then ret = ret .. "<span class=\"tag tag-christmas\">'''[[Christmas|CHRISTMAS]]'''</span> " end
	if string.find(c, "Election", 0, true) then ret = ret .. "<span class=\"tag tag-election\">'''[[Election|ELECTION]]'''</span> " end
	if string.find(c, "Clearing-Out", 0, true) then ret = ret .. "<span class=\"tag tag-clearing\">'''[[Mr Chimes' Grand Clearing-Out (historical)|Mr Chimes' Grand Clearing-Out]]'''</span> " end
	if string.find(c, "Prelapsarian Exhibition", 0, true) then ret = ret .. "<span class=\"tag tag-exhibition\">'''[[F.F. Gebrandt's Prelapsarian Exhibition (historical)|F.F. Gebrandt's Prelapsarian Exhibition]]'''</span> " end
	if string.find(c, "Horticultural Show", 0, true) then ret = ret .. "<span class=\"tag tag-horticultural\">'''[[The London Horticultural Show (Guide)|The London Horticultural Show]]'''</span> " end
	if string.find(c, "Summer festival", 0, true) then ret = ret .. "<span class=\"tag tag-summer\">'''[[Summer festivals|SUMMER]]'''</span> " end
	if string.find(c, "Fruits of the Zee", 0, true) then ret = ret .. "<span class=\"tag tag-fruits\">'''[[Fruits of the Zee Festival|FRUITS OF THE ZEE]]'''</span> " end
	if string.find(c, "Whitsun", 0, true) then ret = ret .. "<span class=\"tag tag-whitsun\">'''[[Whitsun|WHITSUN]]'''</span> " end
	if string.find(c, "World Quality", 0, true) then ret = ret .. "<span class=\"tag tag-world\">'''[[World Qualities|WORLD QUALITY]]'''</span> " end
	if string.find(c, "Sunless Sea", 0, true) then ret = ret .. "<span class=\"tag tag-sunless\">'''[[Sunless Sea|SUNLESS SEA]]'''</span> " end
	if string.find(c, "Sunless Skies", 0, true) then ret = ret .. "<span class=\"tag tag-skies\">'''[[Sunless Skies|SUNLESS SKIES]]'''</span> " end
	if string.find(c, "Mask of the Rose", 0, true) then ret = ret .. "<span class=\"tag tag-mask\">'''[[Mask of the Rose: a Fallen London romance|MASK OF THE ROSE]]'''</span> " end
	if string.find(c, "Protégé", 0, true) then ret = ret .. "'''[[The Protégé of a Mysterious Benefactor (Guide)|Protégé Item]]''' " end
	if string.find(c, "Renown", 0, true) then ret = ret .. "'''[[Factions (Guide)#Renown Items|Renown Item]]''' " end
	if string.find(c, "Fallen London Mysteries", 0, true) then ret = ret .. "<span class=\"tag tag-mysteries\">'''MYSTERIES'''</span> " end
	if string.find(c, "Exceptional Friendship", 0, true) then ret = ret .. "<span class=\"tag tag-exceptional\">'''[[Exceptional Friendship|EXCEPTIONAL FRIENDSHIP]]'''</span> " end
	return ret
end

function maketable2(frame, cat, querylist, qws)
	local ret = ""
	local fate = ""
	if frame.args.fate == "0" then fate = "[[Is Fate::false]]" end
	local result = mw.smw.getQueryResult( "[[Equipment status::!ES only]][[Category:" .. cat .. "]]" .. fate .. querylist .. "|?Has effect|limit=1000" )
	if result["meta"]["count"] == 0 then
		return "<center><big><b>No results found.</b></big></center>"
	end
	
	local sum_list = {}
	local level_list = {}
	local ret = ""
	for n=1,result["meta"]["count"] do
		local name = result["results"][n]["fulltext"]
		if sum_list[name] == nil then sum_list[name] = 0 end
		if level_list[name] == nil then level_list[name] = "" end
		for _,d in ipairs(result["results"][n]["printouts"]["Has effect"]) do
			if string.find(querylist, d["Modifies quality"]["item"][1]["fulltext"], 1, true) then
				sum_list[name] = sum_list[name] + d["Modifies by"]["item"][1] * qws[d["Modifies quality"]["item"][1]["fulltext"]]
				level_list[name] = level_list[name] .. d["Modifies quality"]["item"][1]["fulltext"] .. "#" .. d["Modifies by"]["item"][1] .. "|"
			end
		end
	end
	
	local k = {}
	for n,_ in pairs(sum_list) do
		table.insert(k, n)
	end
	table.sort(k, function(k1, k2) return sum_list[k1] > sum_list[k2] end)
	
	ret = ret .. '<span style="display:none">' .. frame:expandTemplate{title = 'FontFate'} .. '</span>'
	-- The above is to get the needed styles for the Font templates
	ret = ret .. '<table class="article-table"><tr><th>Total</th><th>Item</th>'
	for n=1,frame.args.qnum do
		ret = ret .. "<th>" .. frame:expandTemplate{title = 'I',args = {frame.args["q" .. n]}} .. "</th>"
	end
	ret = ret .. '</tr>'
	
	local at = -2000
	local tmax = -2000
	local climit = tonumber(frame.args.climit)
	if climit == 0 then climit = 1000 end
	local c = 0
	for _,v in ipairs(k) do
		if tmax == -2000 then tmax = sum_list[v] end
		local espan = 0
		local icon = ""
		local iconcat_q = mw.smw.ask{'[[' .. v .. ']]', '?Has icon=icon','?Category=cat',mainlabel = '-'}
		if iconcat_q ~= nil then icon = iconcat_q[1]['icon'] end
		icon = string.gsub(icon, '%|frameless%|border%|text%-top%|', '|20px|link=' .. v .. '|alt=')
		local cats = ""
		for _,c in ipairs(iconcat_q[1]['cat']) do
			cats = cats .. c
		end
		cats = processcats(cats)
		if at ~= sum_list[v] and climit > 0 then
			at = sum_list[v]
			for _,l in pairs(sum_list) do
				if l == sum_list[v] then espan = espan + 1 end
			end
			if espan > climit then climit = climit + (espan - climit) end
			ret = ret .. '<tr><td rowspan="' .. espan .. '"><b>' .. (sum_list[v] >= 0 and "+" or "") .. sum_list[v] .. "</b></td><td>" .. icon .. " [[" .. v .. "]] " .. cats .. "</td>"
		else
			ret = ret .. "<tr><td>" .. icon .. " [[" .. v .. "]] " .. cats .. "</td>"
		end
		for n=1,frame.args.qnum do
			ret = ret .. "<td>"
			if string.find(level_list[v], frame.args["q" .. n], 0, true) then
				local lv = string.match(level_list[v], frame.args["q" .. n] .. "#(.-)|")
				ret = ret .. (tonumber(lv) >= 0 and "+" or "") .. lv
			end
			ret = ret .. "</td>"
		end
		ret = ret .. '</tr>'
		c = c + 1
		climit = climit - 1
		if climit == 0 then
			if table.getn(k) ~= c then
				ret = ret .. '<tr><td colspan="' .. 2 + tonumber(frame.args.qnum) .. '">...</td></tr>'
			end
			break
		end
	end
	ret = ret .. "</table>"
	return ret,tmax
end

function p.calc2(frame)
	local args = frame.args
	local qnum = tonumber(args.qnum)
	
	local ql = ""
	for i=1,qnum do
		for n=1,qnum do
			if i ~= n and args["q" .. i] == args["q" .. n] then
				return "<center><big><b>You can't select the same Quality multiple times!</b></big></center>"
			end
		end
	end
	
	local qws = {}
	qws[args.q1] = args.w1
	local querylist = "[[Has effect::" .. args.q1
	for n=2,qnum do
		querylist = querylist .. "||" .. args["q" .. n]
		qws[args["q" .. n]] = tonumber(args["w" .. n])
	end
	querylist = querylist .. "]]"
	
	local ret = ""
	local tmax = 0
	if args.cat == "All" then
		for i,c in ipairs(allcats) do
			if c == "Boon" then
				if args.mood == "1" then
					local t,m = maketable2(frame, c, querylist, qws)
					if m ~= nil then tmax = tmax + m end
					ret = ret .. "<h2>" .. c .. "</h2>" .. t
				end
			else
				local t,m = maketable2(frame, c, querylist, qws)
				if m ~= nil then tmax = tmax + m end
				ret = ret .. "<h2>" .. c .. "</h2>" .. t
			end
		end
		ret = "<h2>Absolute Possible Max</h2><center><big><b>" .. (tmax >= 0 and "+" or "") .. tmax .. "</b></big></center>" .. ret
	else 
		ret = ret .. maketable2(frame, args.cat, querylist, qws)
	end
	return ret
end

return p