Module:RecipeDetails: Difference between revisions
From IdleOn MMO Wiki
Kiokurashi (talk | contribs) mNo edit summary |
Kiokurashi (talk | contribs) mNo edit summary |
||
Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
local cargo = mw.ext.cargo | local cargo = mw.ext.cargo | ||
local function appendTable(tableA, tableB) | |||
local aLen = #tableA | |||
for n=1, #tableB do | |||
tableA[aLen+n] = tableB[n] | |||
end | |||
return tableA | |||
end | |||
local function fuseBaseIngredients(oldTable, newTable) | |||
local newItem | |||
for n=1, #newTable do -- For each item in the new table | |||
newItem = true -- Initialize newItem boolean | |||
for o=1, #oldTable do -- Check each item in the old table | |||
if oldTable[o].Item == newTable[n].Item then -- If the there is a match | |||
-- Add value, set boolean to false, and break loop. | |||
oldTable[o].Amount = oldTable[o].Amount + newTable[n].Amount | |||
newItem = false | |||
break | |||
end | |||
end | |||
if newItem == true then oldTable[#oldTable+1] = newTable[n].Amount end -- If it is a new item then add new item. | |||
end | |||
return oldTable | |||
end | |||
local function sortByKey(key) | |||
return function(a, b) | |||
return a[key] < b[key] | |||
end | |||
end | |||
-- Takes a list of items and an optional iterator for indentation. | -- Takes a list of items and an optional iterator for indentation. | ||
local function RecipeBreakdownRecursive(items, i) | local function RecipeBreakdownRecursive(items, i) | ||
local indent = i or 1 -- Used to set padding later. | local indent = i or 1 -- Used to set padding later. | ||
local fullTableStruct = { --[[ inserted as ( | local fullTableStruct = { --[[ inserted as (padding, item, amount) ]] } | ||
for n = 1, #items do | local tuple = {} | ||
local reciItems = {} | |||
local baseIngredients = { --[[ insereted as (name, amount) ]] } | |||
for n = 1, #items do | |||
tuple = {Padding = indent, Item = items[n].item, Amount = items[n].amount} | |||
-- Insert item into fullTableStruct. | -- Insert item into fullTableStruct. | ||
fullTableStruct[#fullTableStruct+1] = tuple | |||
-- Query smithing table for the recipe and retrieve the ingeredients | -- Query smithing table for the recipe and retrieve the ingeredients | ||
reciItems = getReecipeItems(items[n].item, items[n].amount) or {} | |||
-- If previous line's result is not nil then recursively call this function and increment i. | -- If previous line's result is not nil then recursively call this function and increment i. | ||
if #reciItems == 0 then | |||
-- If item has value in baseingredients then increase, otherwise set to the value. | |||
baseIngredients = fuseBaseIngredients(baseIngredients, {Item = items[n].item, Amount = items[n].amount}) | |||
else | |||
-- If reciItems is not nil then recursively call this function and increment i. | |||
local retTable = RecipeBreakdownRecursive(reciItems, indent + 1) | |||
fullTableStruct = appendTable(fullTableStruct, retTable[1]) | |||
baseIngredients = fuseBaseIngredients(baseIngredients, retTable[2]) | |||
end | |||
end | end | ||
return fullTableStruct | return {fullTableStruct, baseIngredients} | ||
end | end | ||
local function RecipeBreakdownFormatter(fullTable) | local function RecipeBreakdownFormatter(fullTable) | ||
local | local results = {} | ||
local Row = [==[<tr><td style="padding-left:%spx">{{CraftReq|%s}}</td><td>{{Numdisplay|%s}}</td></tr>]==] | local Row = [==[<tr><td style="padding-left:%spx">{{CraftReq|%s}}</td><td>{{Numdisplay|%s}}</td></tr>]==] | ||
-- Format output rows. | |||
local padding = 0 | |||
for n=1, #fullTable do | |||
-- Index is 6 for the first tier, and 20n+5 for the rest. | -- Index is 6 for the first tier, and 20n+5 for the rest. | ||
if fullTable[n].Padding > 1 then padding = fullTable[n].Padding * 20 + 5 else padding = 6 end | |||
results[n] = string.format(Row, padding, fullTable[n].Item, fullTable[n].Amount) | |||
end | |||
-- Concatenate strings together. | -- Concatenate strings together. | ||
return | return table.concat(results, "") | ||
end | end | ||
local function RecipeTotalsFormatter( | local function RecipeTotalsFormatter(baseIngTable) | ||
local result = | local result = {} | ||
local sortedTable = {} | |||
local Row = [==[<tr><td style="text-align:right">{{CraftReq|%s}}</td><td>{{Numdisplay|%s}}</td></tr>]==] | local Row = [==[<tr><td style="text-align:right">{{CraftReq|%s}}</td><td>{{Numdisplay|%s}}</td></tr>]==] | ||
-- Sort list | -- Sort list | ||
sortedTable = table.sort(baseIngTable, sortByKey("Item")) | |||
-- Format output rows. | -- Format output rows. | ||
for n=1, #sortedTable do | |||
result[n] = string.format(Row, sortedTable.Item, sortedTable.Amount) | |||
end | |||
return result | return table.concat(result, "") | ||
end | end | ||
-- Query smithing table for the recipe and retrieve the ingeredients | -- Query smithing table for the recipe and retrieve the ingeredients | ||
local function getReecipeItems( item ) | local function getReecipeItems( item, multi ) | ||
local multiplier = multi or 1 | |||
local ingredients = {} | local ingredients = {} | ||
-- Query | -- Query | ||
Line 50: | Line 107: | ||
if results['Resource'..n] == nil or results['Resource'..n] == '' then break end -- If an empty cell is encountered, stop processing items. | if results['Resource'..n] == nil or results['Resource'..n] == '' then break end -- If an empty cell is encountered, stop processing items. | ||
tuple.item = results['Resource'..n] | tuple.item = results['Resource'..n] | ||
tuple.amount = results['Quantity'..n] | tuple.amount = tonumber(results['Quantity'..n]) * multiplier | ||
ingredients[n] = tuple | ingredients[n] = tuple | ||
end | end | ||
Line 61: | Line 118: | ||
local item = frame.args[1] | local item = frame.args[1] | ||
local items = getRecipeItems(item) | local items = getRecipeItems(item) | ||
local | local doubleTable = RecipeBreakdownRecursive(items) | ||
local fullTableStruct = doubleTable[1] | |||
local baseIngredients = doubleTable[2] | |||
-- build the data. | -- build the data. | ||
local breakdown = RecipeBreakdownFormatter(fullTableStruct) | local breakdown = RecipeBreakdownFormatter(fullTableStruct) | ||
local totals = RecipeTotalsFormatter( | local totals = RecipeTotalsFormatter(baseIngredients) | ||
-- Declare the Cargo Table: item, breakdown, totals. | -- Declare the Cargo Table: item, breakdown, totals. | ||
Line 87: | Line 146: | ||
local item = frame.args[1] | local item = frame.args[1] | ||
-- Query ' | -- Query 'DetailedRecipes' table for the recipe and retrieve the outputs | ||
local tables = 'DetailedRecipes' | local tables = 'DetailedRecipes' | ||
local fields = 'Breakdown, Totals' | local fields = 'Breakdown, Totals' |
Revision as of 18:51, 26 March 2024
Documentation for this module may be created at Module:RecipeDetails/doc
local p = {}
local cargo = mw.ext.cargo
local function appendTable(tableA, tableB)
local aLen = #tableA
for n=1, #tableB do
tableA[aLen+n] = tableB[n]
end
return tableA
end
local function fuseBaseIngredients(oldTable, newTable)
local newItem
for n=1, #newTable do -- For each item in the new table
newItem = true -- Initialize newItem boolean
for o=1, #oldTable do -- Check each item in the old table
if oldTable[o].Item == newTable[n].Item then -- If the there is a match
-- Add value, set boolean to false, and break loop.
oldTable[o].Amount = oldTable[o].Amount + newTable[n].Amount
newItem = false
break
end
end
if newItem == true then oldTable[#oldTable+1] = newTable[n].Amount end -- If it is a new item then add new item.
end
return oldTable
end
local function sortByKey(key)
return function(a, b)
return a[key] < b[key]
end
end
-- Takes a list of items and an optional iterator for indentation.
local function RecipeBreakdownRecursive(items, i)
local indent = i or 1 -- Used to set padding later.
local fullTableStruct = { --[[ inserted as (padding, item, amount) ]] }
local tuple = {}
local reciItems = {}
local baseIngredients = { --[[ insereted as (name, amount) ]] }
for n = 1, #items do
tuple = {Padding = indent, Item = items[n].item, Amount = items[n].amount}
-- Insert item into fullTableStruct.
fullTableStruct[#fullTableStruct+1] = tuple
-- Query smithing table for the recipe and retrieve the ingeredients
reciItems = getReecipeItems(items[n].item, items[n].amount) or {}
-- If previous line's result is not nil then recursively call this function and increment i.
if #reciItems == 0 then
-- If item has value in baseingredients then increase, otherwise set to the value.
baseIngredients = fuseBaseIngredients(baseIngredients, {Item = items[n].item, Amount = items[n].amount})
else
-- If reciItems is not nil then recursively call this function and increment i.
local retTable = RecipeBreakdownRecursive(reciItems, indent + 1)
fullTableStruct = appendTable(fullTableStruct, retTable[1])
baseIngredients = fuseBaseIngredients(baseIngredients, retTable[2])
end
end
return {fullTableStruct, baseIngredients}
end
local function RecipeBreakdownFormatter(fullTable)
local results = {}
local Row = [==[<tr><td style="padding-left:%spx">{{CraftReq|%s}}</td><td>{{Numdisplay|%s}}</td></tr>]==]
-- Format output rows.
local padding = 0
for n=1, #fullTable do
-- Index is 6 for the first tier, and 20n+5 for the rest.
if fullTable[n].Padding > 1 then padding = fullTable[n].Padding * 20 + 5 else padding = 6 end
results[n] = string.format(Row, padding, fullTable[n].Item, fullTable[n].Amount)
end
-- Concatenate strings together.
return table.concat(results, "")
end
local function RecipeTotalsFormatter(baseIngTable)
local result = {}
local sortedTable = {}
local Row = [==[<tr><td style="text-align:right">{{CraftReq|%s}}</td><td>{{Numdisplay|%s}}</td></tr>]==]
-- Sort list
sortedTable = table.sort(baseIngTable, sortByKey("Item"))
-- Format output rows.
for n=1, #sortedTable do
result[n] = string.format(Row, sortedTable.Item, sortedTable.Amount)
end
return table.concat(result, "")
end
-- Query smithing table for the recipe and retrieve the ingeredients
local function getReecipeItems( item, multi )
local multiplier = multi or 1
local ingredients = {}
-- Query
local args = {
where = 'AnvilCraft.Item="'.. item ..'"',
orderBy = 'AnvilCraft.Item'
}
local results = cargo.query('AnvilCraft', 'Resource1, Quantity1, Resource2, Quantity2, Resource3, Quantity3, Resource4, Quantity4', args )
if #results == 0 then return 0 end -- if no results, exit with 0
local tuple = {}
for n=1, 4 do
if results['Resource'..n] == nil or results['Resource'..n] == '' then break end -- If an empty cell is encountered, stop processing items.
tuple.item = results['Resource'..n]
tuple.amount = tonumber(results['Quantity'..n]) * multiplier
ingredients[n] = tuple
end
-- Return table of items and values.
return ingredients
end
function p.Builder( frame )
local item = frame.args[1]
local items = getRecipeItems(item)
local doubleTable = RecipeBreakdownRecursive(items)
local fullTableStruct = doubleTable[1]
local baseIngredients = doubleTable[2]
-- build the data.
local breakdown = RecipeBreakdownFormatter(fullTableStruct)
local totals = RecipeTotalsFormatter(baseIngredients)
-- Declare the Cargo Table: item, breakdown, totals.
local cargoTable = 'DetailedRecipes'
local args = {
Item = 'String',
Breakdown = 'Wikitext',
Totals = 'Wikitext' }
local results = cargo.declare( cargoTable, args )
-- Store it in the Cargo Table: item, breakdown, totals.
local args = {
Item = item,
Breakdown = breakdown,
Totals = totals }
local results = cargo.store( cargoTable, args )
end
function p.Main( frame )
local item = frame.args[1]
-- Query 'DetailedRecipes' table for the recipe and retrieve the outputs
local tables = 'DetailedRecipes'
local fields = 'Breakdown, Totals'
local args = {
where = 'Item = "' .. item .. '"'
}
local results = cargo.query( tables, fields, args )
if #results == 0 then return end
-- return table data for item
return string.format("{{Detrecipe/tab|reci=%s|tot=%s}}", results.Breakdown, results.Totals)
end
return p