<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.roatpkz.com/index.php?action=history&amp;feed=atom&amp;title=Module%3AUses_facility_list</id>
	<title>Module:Uses facility list - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.roatpkz.com/index.php?action=history&amp;feed=atom&amp;title=Module%3AUses_facility_list"/>
	<link rel="alternate" type="text/html" href="https://wiki.roatpkz.com/index.php?title=Module:Uses_facility_list&amp;action=history"/>
	<updated>2026-05-02T02:08:15Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.roatpkz.com/index.php?title=Module:Uses_facility_list&amp;diff=4243&amp;oldid=prev</id>
		<title>Hefner: 1 revision imported</title>
		<link rel="alternate" type="text/html" href="https://wiki.roatpkz.com/index.php?title=Module:Uses_facility_list&amp;diff=4243&amp;oldid=prev"/>
		<updated>2024-03-30T22:33:07Z</updated>

		<summary type="html">&lt;p&gt;1 revision imported&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 22:33, 30 March 2024&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;en&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(No difference)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Hefner</name></author>
	</entry>
	<entry>
		<id>https://wiki.roatpkz.com/index.php?title=Module:Uses_facility_list&amp;diff=4242&amp;oldid=prev</id>
		<title>Wilderness&gt;Fjara: rename output header to product, better filtering for multi-facility stuff and cut out to function a check for both tables/strings containing the same value</title>
		<link rel="alternate" type="text/html" href="https://wiki.roatpkz.com/index.php?title=Module:Uses_facility_list&amp;diff=4242&amp;oldid=prev"/>
		<updated>2022-09-07T19:59:29Z</updated>

		<summary type="html">&lt;p&gt;rename output header to product, better filtering for multi-facility stuff and cut out to function a check for both tables/strings containing the same value&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;local p = {}&lt;br /&gt;
&lt;br /&gt;
local commas = require(&amp;#039;Module:Addcommas&amp;#039;)&lt;br /&gt;
local skillPic = require(&amp;#039;Module:SCP&amp;#039;)._main&lt;br /&gt;
local yesNo = require(&amp;#039;Module:Yesno&amp;#039;)&lt;br /&gt;
local lang = mw.getContentLanguage()&lt;br /&gt;
local trim = mw.text.trim&lt;br /&gt;
local split = mw.text.split&lt;br /&gt;
local jsonDecode = mw.text.jsonDecode&lt;br /&gt;
&lt;br /&gt;
function buildRow(recipe, facility)&lt;br /&gt;
	local ret = mw.html.create(&amp;#039;tr&amp;#039;)&lt;br /&gt;
	&lt;br /&gt;
	-- Outputs&lt;br /&gt;
	ret:tag(&amp;#039;td&amp;#039;):wikitext(recipe.output.image)&lt;br /&gt;
	ret:tag(&amp;#039;td&amp;#039;):attr(&amp;#039;data-sort-value&amp;#039;, recipe.output.name):wikitext(commas._add(recipe.output.quantity) .. &amp;#039; × [[&amp;#039; .. recipe.output.name .. &amp;#039;]]&amp;#039; .. (recipe.output.subtxt ~= nil and &amp;#039;&amp;lt;br/&amp;gt;&amp;lt;small&amp;gt;(&amp;#039; .. recipe.output.subtxt .. &amp;#039;)&amp;lt;/small&amp;gt;&amp;#039; or &amp;#039;&amp;#039;))&lt;br /&gt;
&lt;br /&gt;
	-- Members&lt;br /&gt;
	if(yesNo(recipe.members)) then&lt;br /&gt;
		ret:tag(&amp;#039;td&amp;#039;):wikitext(&amp;quot;[[File:Member icon.png|center|link=Members]]&amp;quot;)&lt;br /&gt;
	elseif(not yesNo(recipe.members)) then&lt;br /&gt;
		ret:tag(&amp;#039;td&amp;#039;):wikitext(&amp;quot;[[File:Free-to-play icon.png|center|link=Free-to-play]]&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	--Facility&lt;br /&gt;
	local facilityList = mw.html.create(&amp;#039;ul&amp;#039;):addClass(&amp;#039;products-materials&amp;#039;)&lt;br /&gt;
	local facilitySortValue = nil&lt;br /&gt;
	local facilities = split(recipe.facilities, &amp;quot;,&amp;quot;)&lt;br /&gt;
	for i, facil in ipairs(facilities) do&lt;br /&gt;
		facilityList:tag(&amp;#039;li&amp;#039;):attr(&amp;#039;data-sort-value&amp;#039;, i == 1 and facil or &amp;#039;&amp;#039;):wikitext(facil) -- For highlighting _all_ facilities --- :addClass(&amp;#039;production-selected&amp;#039;)&lt;br /&gt;
	end&lt;br /&gt;
	ret:tag(&amp;#039;td&amp;#039;):addClass(&amp;#039;plainlist&amp;#039;):node(facilityList)&lt;br /&gt;
	&lt;br /&gt;
	-- Skills (level)&lt;br /&gt;
	-- Skills (xp)&lt;br /&gt;
	local skillList = mw.html.create(&amp;#039;ul&amp;#039;):addClass(&amp;#039;skills-list&amp;#039;)&lt;br /&gt;
	local xpList = mw.html.create(&amp;#039;ul&amp;#039;):addClass(&amp;#039;skills-list&amp;#039;)&lt;br /&gt;
	&lt;br /&gt;
	if(#recipe.skills == 0) then&lt;br /&gt;
		skillList:tag(&amp;#039;li&amp;#039;):wikitext(&amp;#039;None&amp;#039;)&lt;br /&gt;
		xpList:tag(&amp;#039;li&amp;#039;):wikitext(&amp;#039;None&amp;#039;)&lt;br /&gt;
		ret:tag(&amp;#039;td&amp;#039;):addClass(&amp;#039;table-na plainlist&amp;#039;):node(skillList)&lt;br /&gt;
		ret:tag(&amp;#039;td&amp;#039;):addClass(&amp;#039;table-na plainlist&amp;#039;):node(xpList)&lt;br /&gt;
	else&lt;br /&gt;
		for i, skill in ipairs(recipe.skills) do&lt;br /&gt;
			skillList:tag(&amp;#039;li&amp;#039;):attr(&amp;#039;data-sort-value&amp;#039;, i == 1 and skill.level or &amp;#039;&amp;#039;):wikitext(skillPic(lang:ucfirst(skill.name), skill.level))&lt;br /&gt;
			xpList:tag(&amp;#039;li&amp;#039;):attr(&amp;#039;data-sort-value&amp;#039;, i == 1 and skill.experience or &amp;#039;&amp;#039;):wikitext(commas._strip(skill.experience) ~= nil and skillPic(lang:ucfirst(skill.name), skill.experience) or skill.experience)&lt;br /&gt;
		end&lt;br /&gt;
		ret:tag(&amp;#039;td&amp;#039;):addClass(&amp;#039;plainlist&amp;#039;):node(skillList)&lt;br /&gt;
		ret:tag(&amp;#039;td&amp;#039;):addClass(&amp;#039;plainlist&amp;#039;):node(xpList)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Inputs&lt;br /&gt;
	local matList = mw.html.create(&amp;#039;ul&amp;#039;)&lt;br /&gt;
	local materialSortValue = nil&lt;br /&gt;
	for _, mat in ipairs(recipe.materials) do&lt;br /&gt;
		local quantity = string.gsub(mat.quantity, &amp;#039;%-&amp;#039;, &amp;#039;–&amp;#039;)&lt;br /&gt;
		if(materialSortValue == nil) then&lt;br /&gt;
			materialSortValue = quantity&lt;br /&gt;
		end&lt;br /&gt;
		matList:tag(&amp;#039;li&amp;#039;):wikitext(string.format(&amp;#039;%s × [[%s]]&amp;#039;, commas._add(quantity), mat.name))&lt;br /&gt;
	end&lt;br /&gt;
	ret:tag(&amp;#039;td&amp;#039;):addClass(&amp;#039;plainlist&amp;#039;):attr(&amp;#039;data-sort-value&amp;#039;, materialSortValue):node(matList)&lt;br /&gt;
	&lt;br /&gt;
	return ret&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function createHeader()&lt;br /&gt;
	local header = mw.html.create(&amp;#039;table&amp;#039;):addClass(&amp;#039;wikitable sortable products-list align-center-1 align-left-2 align-center-3&amp;#039;):done()&lt;br /&gt;
		header:tag(&amp;#039;tr&amp;#039;):tag(&amp;#039;th&amp;#039;):attr(&amp;#039;colspan&amp;#039;, &amp;#039;2&amp;#039;):wikitext(&amp;#039;Product&amp;#039;):done()&lt;br /&gt;
			:tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;Members&amp;#039;):done()&lt;br /&gt;
			:tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;Facility&amp;#039;):done()&lt;br /&gt;
			:tag(&amp;#039;th&amp;#039;):attr(&amp;#039;data-sort-type&amp;#039;, &amp;#039;number&amp;#039;):wikitext(&amp;#039;Skills&amp;#039;):done()&lt;br /&gt;
			:tag(&amp;#039;th&amp;#039;):attr(&amp;#039;data-sort-type&amp;#039;, &amp;#039;number&amp;#039;):wikitext(&amp;#039;XP&amp;#039;):done()&lt;br /&gt;
			:tag(&amp;#039;th&amp;#039;):wikitext(&amp;#039;Materials&amp;#039;):done()&lt;br /&gt;
	return header&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- If both variables contain the same element as part of a list (or single string)&lt;br /&gt;
function bothContain(argOne, argTwo)&lt;br /&gt;
	if(argOne == nil) or (argOne == &amp;#039;&amp;#039;) or (argTwo == nil) or (argTwo == &amp;#039;&amp;#039;) then&lt;br /&gt;
		return false&lt;br /&gt;
	elseif((type(argOne) == &amp;#039;string&amp;#039;) and (string.find(argOne, &amp;#039;,&amp;#039;) == nil)) and ((type(argTwo) == &amp;#039;string&amp;#039;) and (string.find(argTwo, &amp;#039;,&amp;#039;) == nil)) then&lt;br /&gt;
		return trim(argOne) == trim(argTwo)&lt;br /&gt;
	else&lt;br /&gt;
		if(type(argOne) == &amp;#039;string&amp;#039;) then&lt;br /&gt;
			argOne = split(argOne, &amp;quot;%s*,%s*&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
		if(type(argTwo) == &amp;#039;string&amp;#039;) then&lt;br /&gt;
			argTwo = split(argTwo, &amp;quot;%s*,%s*&amp;quot;)&lt;br /&gt;
		end&lt;br /&gt;
		for i, v in ipairs(argOne) do&lt;br /&gt;
			for j, w in ipairs(argTwo) do&lt;br /&gt;
				if(trim(w) == trim(v)) then&lt;br /&gt;
					return true&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p.loadData(facilities, limit, offset)&lt;br /&gt;
	local query = {&lt;br /&gt;
		&amp;#039;[[Uses facility::&amp;#039;.. table.concat(facilities, &amp;#039;||&amp;#039;) ..&amp;#039;]]&amp;#039;,&lt;br /&gt;
		&amp;#039;[[Production JSON::+]]&amp;#039;,&lt;br /&gt;
		&amp;#039;?=#-&amp;#039;,&lt;br /&gt;
		&amp;#039;?Production JSON = json&amp;#039;,&lt;br /&gt;
		limit = limit or 500,&lt;br /&gt;
		offset = offset or 0,&lt;br /&gt;
	}&lt;br /&gt;
	local t1 = os.clock()&lt;br /&gt;
	local smwData = mw.smw.ask(query)&lt;br /&gt;
	local t2 = os.clock()&lt;br /&gt;
&lt;br /&gt;
	if(smwData == nil) then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	mw.log(string.format(&amp;#039;SMW: entries %d, time elapsed: %.3f ms.&amp;#039;, #smwData, (t2 - t1) * 1000))&lt;br /&gt;
&lt;br /&gt;
	data = {}&lt;br /&gt;
	for i, v in ipairs(smwData) do&lt;br /&gt;
		if type(v[&amp;#039;json&amp;#039;]) == &amp;#039;string&amp;#039; then&lt;br /&gt;
			table.insert(data, jsonDecode(v[&amp;#039;json&amp;#039;]))&lt;br /&gt;
		elseif type(v[&amp;#039;json&amp;#039;]) == &amp;#039;table&amp;#039; then&lt;br /&gt;
			for _, w in ipairs(v[&amp;#039;json&amp;#039;]) do&lt;br /&gt;
				table.insert(data, jsonDecode(w))&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- Remove recipes that do not use at least one of the input facilities&lt;br /&gt;
	-- Iterate in reverse so pops do not interrupt iteration&lt;br /&gt;
	for i = #data, 1, -1 do&lt;br /&gt;
		if(not bothContain(facilities, data[i].facilities)) then&lt;br /&gt;
			table.remove(data, i)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	-- Sort table values by order of facility input&lt;br /&gt;
	if((#facilities == 1) or (#data == 1)) then&lt;br /&gt;
		return data&lt;br /&gt;
	else&lt;br /&gt;
		local ret = {}&lt;br /&gt;
		-- This tracks the current position of where inserts should occur&lt;br /&gt;
		local facilityCountOffset = {}&lt;br /&gt;
		for i = 1, #facilities, 1 do&lt;br /&gt;
			table.insert(facilityCountOffset, 0)&lt;br /&gt;
		end&lt;br /&gt;
		for i, recipe in ipairs(data) do&lt;br /&gt;
			local pos = 0&lt;br /&gt;
			for j, facil in ipairs(facilities) do&lt;br /&gt;
				pos = pos + facilityCountOffset[j]&lt;br /&gt;
				if(bothContain(recipe.facilities, facil)) then&lt;br /&gt;
					table.insert(ret, pos + 1, recipe)&lt;br /&gt;
					facilityCountOffset[j] = facilityCountOffset[j] + 1&lt;br /&gt;
					break&lt;br /&gt;
				end&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		return ret&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
function p._main(args)&lt;br /&gt;
	local facility = args ~= nil and args[1] or mw.title.getCurrentTitle().text&lt;br /&gt;
&lt;br /&gt;
	local facilities = {}&lt;br /&gt;
	if(string.find(facility, &amp;#039;,&amp;#039;) == nil) then&lt;br /&gt;
		table.insert(facilities, trim(facility))&lt;br /&gt;
	else&lt;br /&gt;
		for _, facil in ipairs(split(facility, &amp;quot;,&amp;quot;)) do&lt;br /&gt;
			table.insert(facilities, trim(facil))&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	data = p.loadData(facilities, args.limit, args.offset)&lt;br /&gt;
	&lt;br /&gt;
	if(data == nil) then&lt;br /&gt;
		return &amp;#039;Failed to find products using that facility - ensure it is spelled correctly. (ERR: no results from SMW)[[Category:Empty drop lists]]&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local ret = createHeader()&lt;br /&gt;
	for _, recipe in ipairs(data) do&lt;br /&gt;
		ret:node(buildRow(recipe, facilities))&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	return tostring(ret)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
--[[ DEBUG&lt;br /&gt;
= p._main({&amp;#039;Anvil&amp;#039;})&lt;br /&gt;
= p._main({&amp;#039;Crafting table 1, Crafting table 2&amp;#039;})&lt;br /&gt;
--]]&lt;br /&gt;
&lt;br /&gt;
function p.main(frame)&lt;br /&gt;
	--mw.logObject(frame)&lt;br /&gt;
	local args = frame:getParent().args&lt;br /&gt;
	return p._main(args)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Wilderness&gt;Fjara</name></author>
	</entry>
</feed>