Module:Item Crafting

From Hero Siege Wiki
Jump to navigation Jump to search

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

local p = {}
local cargo = mw.ext.cargo
local cfg = require('Module:Config')
local func = require('Module:Func')
local item = {}

function p.item_recipe(frame)
	item = mw.text.jsonDecode(frame:callParserFunction("#var", { "itemData" }))
	local output = {}
	local whereResult = p.buildWhereResult(item)
	local recipesResult = cargo.query(
		'Recipe',
		'craftamount1, craftitem1, craftamount2, craftitem2, craftamount3, craftitem3, craftamount4, craftitem4, craftamount5, craftitem5, craftamount6, craftitem6, craftresult1, crafttype',
		{ where = whereResult })
	
	if #recipesResult > 0 then table.insert(output, p.generateResultTable(recipesResult)) end
	return table.concat(output)
end

function p.item_crafting(frame)
	item = mw.text.jsonDecode(frame:callParserFunction("#var", { "itemData" }))
	local output = {}
	
	local whereIngredient = p.buildWhereIngredient(item)
	local recipesIngredient = cargo.query(
		'Recipe',
		'craftamount1, craftitem1, craftamount2, craftitem2, craftamount3, craftitem3, craftamount4, craftitem4, craftamount5, craftitem5, craftamount6, craftitem6, craftresult1, crafttype',
		{where = whereIngredient})
	
		if #recipesIngredient > 0 then table.insert(output, p.generateIngredientTable(recipesIngredient)) end
	return table.concat(output)
	
end

function p.generateResultTable(recipes)
    local output = {}
    local typeHeader = (recipes.crafttype == 'prospect' and 'prospecting' or 'crafting')
    table.insert(output, string.format("\n=== Recipes ===\n"))
    table.insert(output, string.format("<p>%s can be created from the following recipes:", item.Item_Name ))
    table.insert(output, '<table class="wikitable">')
    table.insert(output, '<tr><th>Component</th><th>Amount</th><th>Result</th></tr>')

    for _, recipe in ipairs(recipes) do
        local components = {}
        local totalComponents = 0

        -- Collect all non-empty components
        for i = 1, 6 do
            local craftItem = recipe['craftitem' .. i]
            local craftAmount = recipe['craftamount' .. i]
            if craftItem and craftItem ~= '' and craftAmount and craftAmount ~= '' then
                table.insert(components, {item = craftItem, amount = craftAmount})
                totalComponents = totalComponents + 1
            end
        end

        -- Determine colspan for the final result
        local colspan = totalComponents > 0 and 2 * totalComponents - 1 or 1

        -- Generate rows for the components
        for i, comp in ipairs(components) do
            if i == 1 then
            	local image = cfg.imageFormat(item.Item_Type, item.Item_Name)
                table.insert(output, string.format('<tr><td>[[%s]]</td><td>%s</td><td rowspan="%d">[[File:%s|link=%s|30px]] [[%s]]</td></tr>',
                    comp.item, comp.amount, totalComponents, image, recipe.craftresult1, recipe.craftresult1))
            else
                table.insert(output, string.format('<tr><td>[[%s]]</td><td>%s</td></tr>', comp.item, comp.amount))
            end
        end

        -- If no components, just show the result
        if totalComponents == 0 then
            table.insert(output, string.format('<tr><td colspan="2">None</td><td>%s</td></tr>', recipe.craftresult1 or ''))
        end
    end

    table.insert(output, '</table>')
    return table.concat(output, '\n')
end

function p.generateIngredientTable(recipes)
    local output = {}
    table.insert(output, '\n== Crafting ==\n')
    local typeHeader = (recipes.crafttype == 'prospect' and 'prospecting' or 'crafting')
    table.insert(output, string.format("<p>%s can be used in the following recipes:", item.Item_Name))
    table.insert(output, '<table class="wikitable">')
    table.insert(output, '<tr><th>Component</th><th>Amount</th><th>Result</th></tr>')

    for _, recipe in ipairs(recipes) do
        local components = {}
        local totalComponents = 0

        -- Collect all non-empty components
        for i = 1, 6 do
            local craftItem = recipe['craftitem' .. i]
            local craftAmount = recipe['craftamount' .. i]
            if craftItem and craftItem ~= '' and craftAmount and craftAmount ~= '' then
                table.insert(components, {item = craftItem, amount = craftAmount})
                totalComponents = totalComponents + 1
            end
        end

        -- Determine colspan for the final result
        local colspan = totalComponents > 0 and 2 * totalComponents - 1 or 1

        -- Generate rows for the components
        for i, comp in ipairs(components) do
            if i == 1 then
            	local craftItem = p.fetchItem(recipe.craftresult1)
            	local image = cfg.imageFormat(craftItem.Item_Type, craftItem.Item_Name)
                table.insert(output, string.format('<tr><td>[[%s]]</td><td>%s</td><td rowspan="%d">[[File:%s|link=%s|30px]] [[%s]]</td></tr>',
                    comp.item, comp.amount, totalComponents, image, recipe.craftresult1, recipe.craftresult1))
            else
                table.insert(output, string.format('<tr><td>[[%s]]</td><td>%s</td></tr>', comp.item, comp.amount))
            end
        end

        -- If no components, just show the result
        if totalComponents == 0 then
            table.insert(output, string.format('<tr><td colspan="2">None</td><td>%s</td></tr>', recipe.craftresult1 or ''))
        end
    end

    table.insert(output, '</table>')
    return table.concat(output, '\n')
end

function p.fetchItem(itemName)
	local where = string.format("Item_Name = '%s'", func.encodeName(itemName))
	local item = cargo.query(
		    'items',
		    'Item_Name, Item_Type',
		    { where = where }
		)
	return item[1]
end


function p.buildWhereResult(item)
	if item.Item_Craftable == '1' and item.Item_Restricted_Drop == '1' then
		return string.format("craftresult1 = '%s'", p.encodeName(item.Item_Name))
	--elseif item.Item_Craftable == '1' and item.Item_Restricted_Drop == '0' and item.Item_Tier and item.Item_Tier ~= '' then
		--return string.format("craftresult1 LIKE '%%Random %s%%'", item.Item_Tier)
	--elseif item.Item_Craftable == '1' and item.Item_Restricted_Drop == '0'
	elseif item.Item_Craftable == '1' and item.Item_Restricted_Drop == '0' and (not item.Item_Tier or item.Item_Tier == '') then
		return string.format("craftresult1 = '%s'", p.encodeName(item.Item_Name))
	else
		return string.format("craftresult1 = 'Nothing'")
	end
end

function p.buildWhereIngredient(item)
    local encodedName = p.encodeName(item.Item_Name)
    return string.format("craftitem1 = '%s' OR craftitem2 = '%s' OR craftitem3 = '%s' OR craftitem4 = '%s' OR craftitem5 = '%s' OR craftitem6 = '%s'", encodedName, encodedName, encodedName, encodedName, encodedName, encodedName)
end

function p.decodeHTML(itemName)
    itemName = itemName:gsub("&apos;", "'")
    itemName = itemName:gsub("&#39;", "'")
    itemName = itemName:gsub("&amp;", "&")
    return itemName
end

function p.encodeName(itemName)
	local decoded = p.decodeHTML(itemName)
	local encodedItemName = decoded:gsub("'", "''")
	return encodedItemName
end

return p