Module:RecipeDetails: Difference between revisions

From IdleOn MMO Wiki
mNo edit summary
mNo edit summary
Line 1: Line 1:
local p = {}
local p = {}
local cargo = mw.ext.cargo
local cargo = mw.ext.cargo
local allRecipes = mw.loadData("Module:RecipeDetails/data").allRecipes  
--local allRecipes = mw.loadData("Module:RecipeDetails/data").allRecipes  


local function appendTable(tableA, tableB)
local function appendTable(tableA, tableB)
Line 58: Line 58:
return allRecipes
return allRecipes
end
end
-- local allRecipes = _buildRecipeTable()
local allRecipes = _buildRecipeTable()


local function getRecipeItems( inItem, multi )
local function getRecipeItems( inItem, multi )

Revision as of 19:04, 12 April 2024

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

local p = {}
local cargo = mw.ext.cargo
--local allRecipes = mw.loadData("Module:RecipeDetails/data").allRecipes 

local function appendTable(tableA, tableB)
	local a = tableA
	local b = tableB
	local aLen = #a
	for n=1, #b do
		a[aLen+n] = b[n]
	end
	
	return a
end

local function fuseBaseIngredients(oldTable, newTable)
	local old = oldTable
	local new = newTable
	for n=1, #new do -- For each item in the new table
		local newItem = true   -- Initialize newItem boolean
		for o=1, #old do  -- Check each item in the old table
			if old[o].Item == new[n].Item then  -- If the there is a match
				-- Add value, set boolean to false, and break loop.
				old[o].Amount = old[o].Amount + new[n].Amount 
				newItem = false
				break
			end
		end
		if newItem == true then old[#old+1] = new[n] end -- If it is a new item then add new item.
	end
	return old
end

-- Query smithing table for the recipe and retrieve the ingeredients
local function _buildRecipeTable()
	local allRecipes = {}
	-- Query
    local args = {
        orderBy = 'AnvilCraft.Item'
    }
    local recipes = cargo.query('AnvilCraft', 'Item, Resource1, Quantity1, Resource2, Quantity2, Resource3, Quantity3, Resource4, Quantity4', args )
    if #recipes == 0 then return {} end -- if no results, exit with an empty table.
    for r=1, #recipes do
    	local itemRecipe = {}
    	local itemName = recipes[r].Item
    	local recipeArray = {}
	    for n=1, 4 do
	    	if recipes[r]['Resource'..n] == nil or recipes[r]['Resource'..n] == '' then break end -- If an empty cell is encountered, stop processing items.
	    	-- Append item and resource to array.
	    	recipeArray[#recipeArray+1] = recipes[r]['Resource'..n]
	    	recipeArray[#recipeArray+1] = recipes[r]['Quantity'..n]
	    end
	    itemRecipe = recipeArray
	    -- Set item index to name of item.
	    allRecipes[itemName] = itemRecipe
	end
    -- Item = { Recipe = {Item1, Amount1, Item2, Amount2, ...} }
	return allRecipes
end
 local allRecipes = _buildRecipeTable()

local function getRecipeItems( inItem, multi )
	local item = inItem
	local multiplier = multi or 1
	local ingredients = {}

    if allRecipes[item] == nil then return {} end -- if no results, exit with an empty table.
    local recipe = allRecipes[item]
    for n=1, #recipe / 2 do
    	local tuple = {}
    	local i = 1 + ((n-1) * 2) -- Need to go by twos instead of ones.
    	tuple.item = recipe[i]
    	tuple.amount = tonumber(recipe[i+1]) * multiplier
		ingredients[n] = tuple
    end
	
	-- Return table of items and values.
    return ingredients
end

-- Takes a list of items and an optional iterator for indentation.
local function RecipeBreakdownRecursive(inItems, i, inFullTable)
	local fullTableStruct = inFullTable or {}
	local items = inItems
	local indent = i 
	
	for n = 1, #items do
		local 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
		local reciItems = getRecipeItems(items[n].item, items[n].amount)
		-- If previous line's result is not empty then recursively call this function and increment i.
		if #reciItems ~= 0 then
			-- If reciItems is not nil then recursively call this function and increment i.
			local retTable = RecipeBreakdownRecursive(reciItems, indent + 1, fullTableStruct)
		end
	end
	
	return fullTableStruct
end

local function RecipeBreakdownFormatter(inFullTable)
	local fullTable = inFullTable
	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 ParseBaseItemsTable(fullTableStruct)
	local fullList = fullTableStruct
	local baseList = {}
	
	for item=1, #fullList do
		local itemRecipe = getRecipeItems(fullList[item].Item, 1)
		if itemRecipe == {} then
			local addBaseItem = {Item = fullList[item].Item, Amount = fullList[item].Amount}
			baseList = fuseBaseIngredients(baseList, addBaseItem)
		end
	end
	
	return baseList
end

local function RecipeTotalsFormatter(inBaseIngTable)
	local baseIngTable = inBaseIngTable
	local result = {}
	local Row = [==[<tr><td style="text-align:right">{{CraftReq|%s}}</td><td>{{Numdisplay|%s}}</td></tr>]==]
	-- Format output rows.
	for n=1, #baseIngTable do
		result[n] = string.format(Row, baseIngTable[n].Item, baseIngTable[n].Amount)
	end
	
	return table.concat(result, "")
end

local function checkDeepestLevel(inRecipesTable)
	local items = inRecipesTable
	for n=1, #items do 
		local item = items[n].item
		local ret = getRecipeItems(item, 1)
		if #ret >= 1 then 
			return 2 -- If it goes deeper than the first level then return 2.
		end
	end
	return 1 -- If it is not deeper than the first level then return 1.
end

function p.Builder( frame )
	local item = frame.args.Item
	local items = getRecipeItems(item)
	-- Check if deepest level is greater than 1. If it is then continue.
	if checkDeepestLevel(items) > 1 then
		local fullTableStruct = RecipeBreakdownRecursive(items, 1, {})
		local baseIngredients = ParseBaseItemsTable(fullTableStruct)
		local tablehead = [[<table class="wikitable">
							<tr><th style="width:80%;">Item</th><th>Qty</th></tr>]]
		-- build the data.
		local breakdown = tablehead..RecipeBreakdownFormatter(fullTableStruct).."</table>"
		local totals    = tablehead..RecipeTotalsFormatter(baseIngredients).."</table>"
	
		-- Store it in the Cargo Table: item, breakdown, totals.
		frame:callParserFunction{ name = '#cargo_store', args = {"_table=DetailedRecipes", Item = item, Breakdown = breakdown, Totals = totals} }
		-- frame:extensionTag{ name = 'cargo_store', args= {_table = "DetailedRecipes", Item = item, Breakdown = breakdown, Totals = totals} }
		-- frame:expandTemplate{ title = 'DetailedRecipes', args = { Item = item, Breakdown = breakdown, Totals = totals } }
		-- test output
		-- mw.logObject(items, "items")
		return '<br/>Stored data for the item: ' .. item
	end
end

function p.cargo_attach( frame )
	frame:callParserFunction{ name = '#cargo_attach', args = {"_table=DetailedRecipes"} }
	-- frame:extensionTag{ name = 'cargo_attach', args= {_table = "DetailedRecipes"} }
	 mw.logObject(allRecipes)
	return 'Attach script ran. <br/>'
end

function p.Main( frame )
	local item = frame.args.Item
	local tabstr = [[Recipe=%s
	|-|Totals=%s]]
	-- Query 'DetailedRecipes' table for the recipe and retrieve the outputs
	local tables = 'DetailedRecipes'
    local fields = 'Breakdown, Totals'
    local args = {
        where = 'DetailedRecipes.Item="' .. item .. '"',
        orderBy = 'DetailedRecipes.Item'
    }
    local results = cargo.query( tables, fields, args )
    if #results == 0 then return end
--  mw.logObject(results)
	-- return table data for item
	return '<div class="detrecipe">' .. frame:extensionTag( 'tabber', string.format(tabstr, results[1].Breakdown, results[1].Totals)) .. "</div>"
	
--	frame:expandTemplate{ title = 'Detrecipe/tab', args = { reci = results[1].Breakdown, tot = results[1].Totals } }
end

return p