Module:GameData: Difference between revisions

From the Dyson Sphere Program Wiki
(Add vein and gas giant support, and use local variables)
(Show fractionator percentage instead of time, possibly add infobox recipes?)
Line 50: Line 50:
table.insert(output, '=== Buildings ===')
table.insert(output, '=== Buildings ===')
table.insert(output, tableRecipes(item, buildings, nil, nil, frame))
table.insert(output, tableRecipes(item, buildings, nil, nil, frame))
end
return table.concat(output, '\n')
end
function funcs.itemRecipes(frame)
return itemRecipesForName(frame:getParent().args[1], frame)
end
function funcs.itemRecipesDirect(frame)
return itemRecipesForName(frame.args[1], frame)
end
function itemRecipesForName(name, frame)
local item = itemByName(name)
local output = {}
for _, r in pairs(recipesMakingByID(item.ID)) do
table.insert(output, itemRecipe(r, frame))
end
local vein = veinMakingByID(item.ID)
if vein then
table.insert(output, veinRecipe(item, vein, frame))
end
for _, giant in pairs(deduplicateGiants(gasGiantsMakingByID(item.ID))) do
table.insert(output, gasGiantRecipe(giant, frame))
end
end
return table.concat(output, '\n')
return table.concat(output, '\n')
Line 57: Line 80:
local result = {}
local result = {}
for _, recipe in pairs(recipes) do
for _, recipe in pairs(recipes) do
local itemdata = {}
itemdata.CraftTime = string.format('%s s', tostring(recipe.TimeSpend/60))
for i, itemid in ipairs(recipe.Results) do
itemdata[string.format('Out%d', i)] = titleCase(itemByID(itemid).Name)
itemdata[string.format('Out%dQty', i)] = tostring(recipe.ResultCounts[i])
end
for i, itemid in ipairs(recipe.Items) do
itemdata[string.format('In%d', i)] = titleCase(itemByID(itemid).Name)
itemdata[string.format('In%dQty', i)] = tostring(recipe.ItemCounts[i])
end
local data = {
local data = {
Building = titleCase(machines[recipe.Type]),
Building = titleCase(machines[recipe.Type]),
Recipe = frame:expandTemplate{title='ItemRecipe', args=itemdata},
Recipe = itemRecipe(recipe, frame)
}
}
if recipe.Handcraft then
if recipe.Handcraft then
Line 87: Line 100:
local miner = itemByName(machines.Mine)
local miner = itemByName(machines.Mine)
local minerTech = technologyForRecipeID(recipesMakingByID(miner.ID)[1].ID)
local minerTech = technologyForRecipeID(recipesMakingByID(miner.ID)[1].ID)
local vname = string.gsub(vein.Name, '%sVeins$', ' Vein')
local idata = {
In1 = titleCase(vname),
In1Qty = '1',
Out1 = titleCase(item.Name),
Out1Qty = '1',
CraftTime = '2 s',
}
local vrecipe = frame:expandTemplate{title='ItemRecipe', args=idata}
local veindata = {
local veindata = {
Building = titleCase(miner.Name),
Building = titleCase(miner.Name),
Replicator = 'Mine',
Replicator = 'Mine',
Technology = titleCase(minerTech.Name),
Technology = titleCase(minerTech.Name),
Recipe = vrecipe,
Recipe = veinRecipe(item, vein, frame),
}
}
table.insert(result, '| ' .. frame:expandTemplate{title='ProductionChain', args=veindata})
table.insert(result, '| ' .. frame:expandTemplate{title='ProductionChain', args=veindata})
Line 108: Line 112:
local collectorTech = technologyForRecipeID(recipesMakingByID(collector.ID)[1].ID)
local collectorTech = technologyForRecipeID(recipesMakingByID(collector.ID)[1].ID)
for _, giant in pairs(gas) do
for _, giant in pairs(gas) do
itemrecipe = {
local gasdata = {
CraftTime = '?',
In1 = titleCase(giant.DisplayName),
In1Qty = '',
}
for i, productID in ipairs(giant.GasItems) do
product = itemByID(productID)
itemrecipe[string.format('Out%d', i)] = titleCase(product.Name)
itemrecipe[string.format('Out%dQty', i)] = '1'
end
gasdata = {
Building = titleCase(collector.Name),
Building = titleCase(collector.Name),
Replicator = 'Mine',
Replicator = 'Mine',
Technology = titleCase(collectorTech.Name),
Technology = titleCase(collectorTech.Name),
Recipe = frame:expandTemplate{title='ItemRecipe', args=itemrecipe}
Recipe = gasGiantRecipe(giant, frame)
}
}
table.insert(result, '| ' .. frame:expandTemplate{title='ProductionChain', args=gasdata})
table.insert(result, '| ' .. frame:expandTemplate{title='ProductionChain', args=gasdata})
Line 129: Line 123:
local prefix = frame:expandTemplate{title='ProductionChainTable/head', args={}}
local prefix = frame:expandTemplate{title='ProductionChainTable/head', args={}}
return string.format('%s\n%s\n|}', prefix, table.concat(result, '\n|-\n'))
return string.format('%s\n%s\n|}', prefix, table.concat(result, '\n|-\n'))
end
function itemRecipe(recipe, frame)
if recipe.Type == 'Fractionate' then
return fractionateRecipe(recipe, frame)
end
local rdata = {
CraftTime = string.format('%s s', tostring(recipe.TimeSpend/60)),
}
for i, itemid in ipairs(recipe.Results) do
rdata[string.format('Out%d', i)] = titleCase(itemByID(itemid).Name)
rdata[string.format('Out%dQty', i)] = tostring(recipe.ResultCounts[i])
end
for i, itemid in ipairs(recipe.Items) do
rdata[string.format('In%d', i)] = titleCase(itemByID(itemid).Name)
rdata[string.format('In%dQty', i)] = tostring(recipe.ItemCounts[i])
end
return frame:expandTemplate{title='ItemRecipe', args=rdata}
end
function fractionateRecipe(recipe, frame)
local ratio = 100 * recipe.ResultCounts[1] / recipe.ItemCounts[1]
local rdata = {
CraftTime = tostring(ratio) .. '%',
}
for i, itemid in ipairs(recipe.Results) do
rdata[string.format('Out%d', i)] = titleCase(itemByID(itemid).Name)
rdata[string.format('Out%dQty', i)] = '1'
end
for i, itemid in ipairs(recipe.Items) do
rdata[string.format('In%d', i)] = titleCase(itemByID(itemid).Name)
rdata[string.format('In%dQty', i)] = '1'
end
return frame:expandTemplate{title='ItemRecipe', args=rdata}
end
function veinRecipe(item, vein, frame)
local vname = string.gsub(vein.Name, '%sVeins$', ' Vein')
local idata = {
In1 = titleCase(vname),
In1Qty = '1',
Out1 = titleCase(item.Name),
Out1Qty = '1',
CraftTime = '2 s',
}
return frame:expandTemplate{title='ItemRecipe', args=idata}
end
function gasGiantRecipe(gas, frame)
local gdata = {
CraftTime = '?',
In1 = titleCase(gas.DisplayName),
In1Qty = '',
}
for i, productID in ipairs(gas.GasItems) do
local product = itemByID(productID)
gdata[string.format('Out%d', i)] = titleCase(product.Name)
gdata[string.format('Out%dQty', i)] = '1'
end
return frame:expandTemplate{title='ItemRecipe', args=gdata}
end
end



Revision as of 18:34, 27 April 2024

Source data for this module is stored at Module:GameData/protosets.json

Exported Functions

Each function in this module is exported twice: one as-is for use in templates, and once with a Direct suffix for use directly on pages using {{#invoke|GameData|functionDirect|...}}.

recipesMaking

Arguments: Item Name

Print recipes making an item, given by name. This produces a full table with headers.

Example invocation:

{{#invoke:GameData|recipesMakingDirect|Sulfuric Acid}}
Recipe Building Replicator? Technology
Icon Sulfuric Acid.png
4
6 s
Icon Refined Oil.png
6
Icon Stone.png
8
Icon Water.png
4
Icon Chemical Plant.pngIcon Quantum Chemical Plant.png
Tech Basic Chemical Engineering.png

recipesUsing

Arguments: Item Name

Print recipes using an item as an ingredient. Output is separated into two full tables: recipes which create components, and recipes which create buildings. This is selected by the CanBuild property of the produced items.

Example invocation:

{{#invoke:GameData|recipesUsingDirect|Copper Ingot}}

Components

Recipe Building Replicator? Technology
Icon Microcrystalline Component.png
1
2 s
Icon High-Purity Silicon.png
2
Icon Copper Ingot.png
1
Icon Assembling Machine Mk.I.pngIcon Assembling Machine Mk.II.pngIcon Assembling Machine Mk.III.pngIcon Re-composing Assembler.png
Tech Semiconductor Material.png
Icon Magnetic Coil.png
2
1 s
Icon Magnet.png
2
Icon Copper Ingot.png
1
Icon Assembling Machine Mk.I.pngIcon Assembling Machine Mk.II.pngIcon Assembling Machine Mk.III.pngIcon Re-composing Assembler.png N/A
Icon Particle Container.png
1
4 s
Icon Electromagnetic Turbine.png
2
Icon Copper Ingot.png
2
Icon Graphene.png
2
Icon Assembling Machine Mk.I.pngIcon Assembling Machine Mk.II.pngIcon Assembling Machine Mk.III.pngIcon Re-composing Assembler.png
Tech Magnetic Particle Trap.png
Icon Thruster.png
1
4 s
Icon Steel.png
2
Icon Copper Ingot.png
3
Icon Assembling Machine Mk.I.pngIcon Assembling Machine Mk.II.pngIcon Assembling Machine Mk.III.pngIcon Re-composing Assembler.png
Tech Thruster.png
Icon Circuit Board.png
2
1 s
Icon Iron Ingot.png
2
Icon Copper Ingot.png
1
Icon Assembling Machine Mk.I.pngIcon Assembling Machine Mk.II.pngIcon Assembling Machine Mk.III.pngIcon Re-composing Assembler.png N/A
Icon Particle Container.png
1
4 s
Icon Unipolar Magnet.png
10
Icon Copper Ingot.png
2
Icon Assembling Machine Mk.I.pngIcon Assembling Machine Mk.II.pngIcon Assembling Machine Mk.III.pngIcon Re-composing Assembler.png
Tech Magnetic Particle Trap.png
Icon Shell Set.png
1
1.5 s
Icon Copper Ingot.png
9
Icon Combustible Unit.png
2
Icon Assembling Machine Mk.I.pngIcon Assembling Machine Mk.II.pngIcon Assembling Machine Mk.III.pngIcon Re-composing Assembler.png
Tech Implosion Cannon.png
Icon Engine.png
1
3 s
Icon Magnetic Coil.png
1
Icon Copper Ingot.png
2
Icon Assembling Machine Mk.I.pngIcon Assembling Machine Mk.II.pngIcon Assembling Machine Mk.III.pngIcon Re-composing Assembler.png
Tech Engine.png
Icon Missile Set.png
1
2 s
Icon Copper Ingot.png
6
Icon Circuit Board.png
3
Icon Combustible Unit.png
2
Icon Engine.png
1
Icon Assembling Machine Mk.I.pngIcon Assembling Machine Mk.II.pngIcon Assembling Machine Mk.III.pngIcon Re-composing Assembler.png
Tech Missile Turret.png
Icon Magnum Ammo Box.png
1
1 s
Icon Copper Ingot.png
3
Icon Assembling Machine Mk.I.pngIcon Assembling Machine Mk.II.pngIcon Assembling Machine Mk.III.pngIcon Re-composing Assembler.png
Tech Weapon System.png

Buildings

Recipe Building Replicator? Technology
Icon Solar Panel.png
1
6 s
Icon Copper Ingot.png
10
Icon High-Purity Silicon.png
10
Icon Circuit Board.png
5
Icon Assembling Machine Mk.I.pngIcon Assembling Machine Mk.II.pngIcon Assembling Machine Mk.III.pngIcon Re-composing Assembler.png
Tech Solar Collection.png
Icon Jammer Tower.png
1
5 s
Icon Copper Ingot.png
12
Icon Plasma Exciter.png
9
Icon Diamond.png
6
Icon Processor.png
3
Icon Assembling Machine Mk.I.pngIcon Assembling Machine Mk.II.pngIcon Assembling Machine Mk.III.pngIcon Re-composing Assembler.png
Tech Jammer Tower.png
Icon Geothermal Power Station.png
1
6 s
Icon Steel.png
15
Icon Copper Ingot.png
20
Icon Photon Combiner.png
4
Icon Super-Magnetic Ring.png
1
Icon Assembling Machine Mk.I.pngIcon Assembling Machine Mk.II.pngIcon Assembling Machine Mk.III.pngIcon Re-composing Assembler.png
Tech Geothermal Extraction.png

itemRecipes

Arguments: Item Name

Print recipes making an item. This does not produce a full table, and is intended for use in ItemInfo boxes such as at Graphene/ItemInfo.

itemField

Arguments: Item Name, Field Name

Print a field from an item, with the field to print as an argument. You can look at Module:GameData/protosets.json and scroll down or search (Ctrl+F) to the ItemProtoSet to browse fields.

Example invocation:

{{#invoke:GameData|itemFieldDirect|Magnetic Coil|Description}}

Script error: The function "itemFieldDirect" does not exist.

{{#invoke:GameData|itemFieldDirect|Hydrogen|StackSize}}

Script error: The function "itemFieldDirect" does not exist.


local funcs = {}
local protosets = mw.loadJsonData('Module:GameData/protosets.json')
local machines = {
	Smelt='Smelter',
	Assemble='Assembling Machine',
	Refine='Oil Refinery',
	Chemical='Chemical Plant',
	Exchange='Energy Exchanger',
	Particle='Miniature Particle Collider',
	PhotonStore='Ray Receiver',
	Fractionate='Fractionator',
	Research='Matrix Lab',
	Mine='Mining Machine',
	Gas='Orbital Collector',
}

function funcs.recipesMaking(frame)
	return recipesMakingName(frame:getParent().args[1], frame)
end

function funcs.recipesMakingDirect(frame)
	return recipesMakingName(frame.args[1], frame)
end

function recipesMakingName(name, frame)
	local item = itemByName(name)
	local recipes = recipesMakingByID(item.ID)
	local vein = veinMakingByID(item.ID)
	local gas = deduplicateGiants(gasGiantsMakingByID(item.ID))
	return tableRecipes(item, recipes, vein, gas, frame)
end

function funcs.recipesUsing(frame)
	return recipesUsingName(frame:getParent().args[1], frame)
end

function funcs.recipesUsingDirect(frame)
	return recipesUsingName(frame.args[1], frame)
end

function recipesUsingName(name, frame)
	local output = {}
	local item = itemByName(name)
	local components, buildings = recipesUsingByID(item.ID)
	if next(components) then
		table.insert(output, '=== Components ===')
		table.insert(output, tableRecipes(item, components, nil, nil, frame))
	end
	if next(buildings) then
		table.insert(output, '=== Buildings ===')
		table.insert(output, tableRecipes(item, buildings, nil, nil, frame))
	end
	return table.concat(output, '\n')
end

function funcs.itemRecipes(frame)
	return itemRecipesForName(frame:getParent().args[1], frame)
end
function funcs.itemRecipesDirect(frame)
	return itemRecipesForName(frame.args[1], frame)
end

function itemRecipesForName(name, frame)
	local item = itemByName(name)
	local output = {}
	for _, r in pairs(recipesMakingByID(item.ID)) do
		table.insert(output, itemRecipe(r, frame))
	end
	local vein = veinMakingByID(item.ID)
	if vein then
		table.insert(output, veinRecipe(item, vein, frame))
	end
	for _, giant in pairs(deduplicateGiants(gasGiantsMakingByID(item.ID))) do
		table.insert(output, gasGiantRecipe(giant, frame))
	end
	return table.concat(output, '\n')
end

function tableRecipes(item, recipes, vein, gas, frame)
	local result = {}
	for _, recipe in pairs(recipes) do
		local data = {
			Building = titleCase(machines[recipe.Type]),
			Recipe = itemRecipe(recipe, frame)
		}
		if recipe.Handcraft then
			data.Replicator = 'Yes'
		else
			data.Replicator = 'No'
		end
		local tech = technologyForRecipeID(recipe.ID)
		if tech ~= nil then
			data.Technology = titleCase(tech.Name)
		else
			data.Technology = ''
		end
		table.insert(result, '| ' .. frame:expandTemplate{title='ProductionChain', args=data})
	end
	if vein then
		local miner = itemByName(machines.Mine)
		local minerTech = technologyForRecipeID(recipesMakingByID(miner.ID)[1].ID)
		local veindata = {
			Building = titleCase(miner.Name),
			Replicator = 'Mine',
			Technology = titleCase(minerTech.Name),
			Recipe = veinRecipe(item, vein, frame),
		}
		table.insert(result, '| ' .. frame:expandTemplate{title='ProductionChain', args=veindata})
	end
	if gas then
		local collector = itemByName(machines.Gas)
		local collectorTech = technologyForRecipeID(recipesMakingByID(collector.ID)[1].ID)
		for _, giant in pairs(gas) do
			local gasdata = {
				Building = titleCase(collector.Name),
				Replicator = 'Mine',
				Technology = titleCase(collectorTech.Name),
				Recipe = gasGiantRecipe(giant, frame)
			}
			table.insert(result, '| ' .. frame:expandTemplate{title='ProductionChain', args=gasdata})
		end
	end
	local prefix = frame:expandTemplate{title='ProductionChainTable/head', args={}}
	return string.format('%s\n%s\n|}', prefix, table.concat(result, '\n|-\n'))
end

function itemRecipe(recipe, frame)
	if recipe.Type == 'Fractionate' then
		return fractionateRecipe(recipe, frame)
	end
	local rdata = {
		CraftTime = string.format('%s s', tostring(recipe.TimeSpend/60)),
	}
	for i, itemid in ipairs(recipe.Results) do
		rdata[string.format('Out%d', i)] = titleCase(itemByID(itemid).Name)
		rdata[string.format('Out%dQty', i)] = tostring(recipe.ResultCounts[i])
	end
	for i, itemid in ipairs(recipe.Items) do
		rdata[string.format('In%d', i)] = titleCase(itemByID(itemid).Name)
		rdata[string.format('In%dQty', i)] = tostring(recipe.ItemCounts[i])
	end
	return frame:expandTemplate{title='ItemRecipe', args=rdata}
end

function fractionateRecipe(recipe, frame)
	local ratio = 100 * recipe.ResultCounts[1] / recipe.ItemCounts[1]
	local rdata = {
		CraftTime = tostring(ratio) .. '%',
	}
	for i, itemid in ipairs(recipe.Results) do
		rdata[string.format('Out%d', i)] = titleCase(itemByID(itemid).Name)
		rdata[string.format('Out%dQty', i)] = '1'
	end
	for i, itemid in ipairs(recipe.Items) do
		rdata[string.format('In%d', i)] = titleCase(itemByID(itemid).Name)
		rdata[string.format('In%dQty', i)] = '1'
	end
	return frame:expandTemplate{title='ItemRecipe', args=rdata}
end

function veinRecipe(item, vein, frame)
	local vname = string.gsub(vein.Name, '%sVeins$', ' Vein')
	local idata = {
		In1 = titleCase(vname),
		In1Qty = '1',
		Out1 = titleCase(item.Name),
		Out1Qty = '1',
		CraftTime = '2 s',
	}
	return frame:expandTemplate{title='ItemRecipe', args=idata}
end

function gasGiantRecipe(gas, frame)
	local gdata = {
		CraftTime = '?',
		In1 = titleCase(gas.DisplayName),
		In1Qty = '',
	}
	for i, productID in ipairs(gas.GasItems) do
		local product = itemByID(productID)
		gdata[string.format('Out%d', i)] = titleCase(product.Name)
		gdata[string.format('Out%dQty', i)] = '1'
	end
	return frame:expandTemplate{title='ItemRecipe', args=gdata}
end

function itemByName(name)
	local lame = string.lower(name)
	for _, item in pairs(protosets.ItemProtoSet.dataArray) do
		if string.lower(item.Name) == lame then
			return item
		end
	end
	error('No item named ' .. name)
end
function itemByID(id)
	for _, item in pairs(protosets.ItemProtoSet.dataArray) do
		if item.ID == id then
			return item
		end
	end
	error('No item with ID ' .. id)
end

function recipesMakingByID(id)
	local result = {}
	for _, recipe in pairs(protosets.RecipeProtoSet.dataArray) do
		for _, itemid in pairs(recipe.Results) do
			if itemid == id then
				table.insert(result, recipe)
				break
			end
		end
	end
	return result
end
function recipesUsingByID(id)
	local components = {}
	local buildings = {}
	for _, recipe in pairs(protosets.RecipeProtoSet.dataArray) do
		for _, itemid in pairs(recipe.Items) do
			if itemid == id then
				if itemByID(recipe.Results[1]).CanBuild then
					table.insert(buildings, recipe)
				else
					table.insert(components, recipe)
				end
				break
			end
		end
	end
	return components, buildings
end

function technologyForRecipeID(id)
	for _, tech in pairs(protosets.TechProtoSet.dataArray) do
		for _, recipeid in pairs(tech.UnlockRecipes) do
			if recipeid == id then
				return tech
			end
		end
	end
	return nil
end

function veinMakingByID(id)
	for _, vein in pairs(protosets.VeinProtoSet.dataArray) do
		if vein.MiningItem == id then
			return vein
		end
	end
	return nil
end

function gasGiantsMakingByID(id)
	local giants = {}
	for _, planet in pairs(protosets.ThemeProtoSet.dataArray) do
		for _, item in pairs(planet.GasItems) do
			if item == id then
				table.insert(giants, planet)
				break
			end
		end
	end
	return giants
end

function deduplicateGiants(giants)
	local dedup = {}
	for _, planet in pairs(giants) do
		new = true
		for _, exist in pairs(dedup) do
			if string.lower(planet.DisplayName) == string.lower(exist.DisplayName) then
				new = false
				break
			end
		end
		if new then table.insert(dedup, planet) end
	end
	return dedup
end

function titleCase(str)
	local start = string.gsub(str, '^%l', string.upper)
	local title = string.gsub(start, '[-%s]%l', string.upper)
	return title
end

return funcs
🍪 We use cookies to keep session information to provide you a better experience.