Module:DocsUtils

From Satisfactory Wiki
Jump to navigation Jump to search


This module is used to load and do common actions with JSON files parsed from the game's Docs.json file, for use in recipe tables and infoboxes: Template:DocsRecipes.json, Template:DocsItems.json and Template:DocsBuildings.json. While they are in the Template namespace, they are not to be used as templates on their own.

The loc variable contains localization strings, which allows this module to be localized without having to change labels throughout.


itemsJSON = mw.loadJsonData('Template:DocsItems.json')
buildingsJSON = mw.loadJsonData('Template:DocsBuildings.json')
recipesJSON = mw.loadJsonData('Template:DocsRecipes.json')

-- Used for localization, used in infoboxes, recipe tables, and other templates if needed.
loc = {
    units = {
        sec = " sec",
        m = " m",
        m2 = "&nbsp;m<sup>2</sup>",
        m3 = "&nbsp;m<sup>3</sup>",
        pmin = " /&nbsp;min",
        mj = "&nbsp;MJ",
        mw = "&nbsp;MW",
        kmh = "&nbsp;km/h"
    },
    numbers = {
        decimalsep = ".",
        thousandsep = ",",
    },
    branches = {
        stable = "Stable",
        experimental = "Experimental",
        ficsmas = "FICSMAS"
    },
    filePage = "File:"
}

-- Get the length of an array, because Lua's built-in length function does not work for JSON data.
-- - T - table
function arrayLength(T)
	local l = 0
	for _ in pairs(T) do l = l+1 end
	return l
end

-- Format a number (thousands separator, decimal separator)
-- - n - number - number to format
function formatNumber(n)
    local integerPart, decimalPart = string.format("%.5f", n):match("([^%.]+)%.?(.*)")
    decimalPart = decimalPart:gsub("0*$", "")
    local returnValue = ((string.reverse(integerPart):gsub("(%d%d%d)", "%1" .. loc.numbers.thousandsep):reverse():gsub("^%s*(.-)%s*$", "%1")) .. (#decimalPart > 0 and loc.numbers.decimalsep .. decimalPart or "")):gsub("^,*(.-),*$", "%1")
    return returnValue
end

-- Retrieve the same parameter from provided stable and experimental items, returns a table with both values
-- - parameter - string - parameter name to retrieve
-- - stableItem - table - stable item to retrieve the parameter from
-- - experimentalItem - table - experimental item to retrieve the parameter from
function getBranchValues(parameter, stableItem, experimentalItem)
    return {stable = stableItem ~= nil and stableItem[parameter] or nil, experimental = experimentalItem ~= nil and experimentalItem[parameter] or nil}
end

-- Format the differences between both branches using {{EA}}/{{EX}} templates
-- - values - table - table with both values
-- - singleBranch - boolean - if true and the value is only in one branch, it will be formatted with {{EA}}/{{EX}}, otherwise it will not
-- - nowiki - boolean - if true, each value is wrapped in <nowiki></nowiki>
function formatBranchDiff(values, singleBranch, nowiki)
    local branchValues = {}
    branchValues.stable = values.stable
    branchValues.experimental = values.experimental
    if (not branchValues.stable or branchValues.stable == 0) and (not branchValues.experimental or branchValues.experimental == 0) then
        return ""
    end

    if type(branchValues.stable) == "number" then
        branchValues.stable = formatNumber(branchValues.stable)
    end
    if type(branchValues.experimental) == "number" then
        branchValues.experimental = formatNumber(branchValues.experimental)
    end

    if nowiki then
        if branchValues.stable then
            branchValues.stable = "<nowiki>" .. branchValues.stable .. "</nowiki>"
        end
        if branchValues.experimental then
            branchValues.experimental = "<nowiki>" .. branchValues.experimental .. "</nowiki>"
        end
    end

    if branchValues.stable == branchValues.experimental then
        return branchValues.stable
    elseif branchValues.stable ~= nil and branchValues.experimental == nil then
        return singleBranch and ("{{EA|" .. branchValues.stable .. "}}") or branchValues.stable
    elseif branchValues.stable == nil and branchValues.experimental ~= nil then
        return singleBranch and ("{{EX|" .. branchValues.experimental .. "}}") or branchValues.experimental
    else
        return "{{EA|" .. branchValues.stable .. "}} ({{EX|" .. branchValues.experimental .. "}})"
    end
end

-- Resolve a className to a name for both branches
-- - className - string - className to resolve
-- - fileJSON - table - JSON file to search in
function getNameFromClassName(className, fileJSON)
    local result = {}
    if fileJSON[className] ~= nil then
        for _, it in pairs(fileJSON[className]) do
            if it.stable then
                result.stable = it.name
            end
            if it.experimental then
                result.experimental = it.name
            end
        end
    end
    return result
end

-- Get object data from a file from the classname for both branches
-- - className - string - className to resolve
-- - fileJSON - table - JSON file to search in
function getObjectFromClassName(className, fileJSON)
    local result = {}
    if fileJSON[className] ~= nil then
        for _, it in pairs(fileJSON[className]) do
            if it.stable then
                result.stable = it
            end
            if it.experimental then
                result.experimental = it
            end
        end
    end
    return result
end

-- Get a link (EA>EX) and name (branchDiff formatted) for a target
-- - target - string - className to resolve
-- - stable - boolean - whether to use stable branch name
-- - experimental - boolean - whether to use experimental branch name
-- - singleBranch - boolean - whether to format the name with {{EA}}/{{EX}} if available only on one branch
function getLinkAndName(target, stable, experimental, singleBranch)
    local targetNames
    local targetLink
    local targetName
    -- resolve item or building name
    targetNames = getNameFromClassName(target, itemsJSON)
    if targetNames.stable == nil and targetNames.stable == nil then
        targetNames = getNameFromClassName(target, buildingsJSON)
    end

    if stable and experimental then
        targetName = formatBranchDiff(targetNames, singleBranch)
    else
        targetName = experimental and targetNames.experimental or targetNames.stable
        targetName = singleBranch and ("{{" .. (experimental and "EX" or "EA") .. "|" .. targetName .. "}}") or targetName
    end

    targetLink = targetNames.stable ~= nil and targetNames.stable or targetNames.experimental
    -- should never occur
    if targetName == nil or targetLink == nil then
        targetName = target
        targetLink = target
    end
    return targetLink, targetName
end

-- Generate an ItemLink for a target
-- - target - string - className to resolve
-- - stable - boolean - whether to use stable branch name
-- - experimental - boolean - whether to use experimental branch name
-- - singleBranch - boolean - whether to format the name with {{EA}}/{{EX}} if available only on one branch
function generateItemLink(className, stable, experimental, singleBranch)
	local itemLink, itemName = getLinkAndName(className, stable, experimental, singleBranch)
	return mw.getCurrentFrame():expandTemplate{title="ItemLink", args={itemLink, itemName}}
end