缺氧 wiki 编辑团队提示:注册账号并登录后体验更佳,且可通过参数设置定制优化您的浏览体验!

该站点为镜像站点,如果你想帮助这个由玩家志愿编辑的 wiki 站点,请前往原站点参与编辑,
同时欢迎加入编辑讨论群 851803695 与其他编辑者一起参与建设!

全站通知:

模块:食物信息框

来自缺氧WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

用于模板:Template:食物信息框。 视图模块:Module:信息框/食物。 数据模块:Module:Data/Food



-- 食物信息框
local p = {}
local fstr = mw.ustring.format

local utils = require("Module:Utils")
local k0 = utils.K0
local po = require([[Module:Po]]).po
local i18ncr = require([[Module:I18n]]).loadMessages([[Module:I18n/Items]])
local infobox = require([[Module:信息框/食物]])
local getArgs = require("Module:Dev/Arguments").getArgs
local fDataPath = [[Module:Data/Food]]
local fData = mw.loadData(fDataPath)
local exception = {
    ["BEAN"] = "BEANPLANTSEED"
}
local arrow = '➠'
local cross = '×'

function p._main(foodData, foodCode)
    local out = {}
    local cat = {
        "[[Category:食物]]"
    }
    out["ID"] = fstr("<code>%s</code>", foodData.Id)
    out["名称"] = po(foodCode)
    out["图片"] = fstr("%s.png", out["名称"])
    out["图片说明"] = po(foodCode:sub(1, -6) .. ".DESC")
    if foodData.CaloriesPerUnit ~= nil and foodData.CaloriesPerUnit > 0 then
        out["能量"] = fstr("%s 千卡/单位", foodData.CaloriesPerUnit / 1000)
        table.insert(cat, "[[Category:可食用物]]")
    else
        table.insert(cat, "[[Category:烹饪原料]]")
    end
    if foodData.CanRot then
        out["是否会腐烂"] = "✔"
        if foodData.StaleTime ~= nil then
            -- out["变质时间"] = utils.float2str(foodData.StaleTime / 600) .. " 周期"
        end
        if foodData.SpoilTime ~= nil then
            out["腐烂时间"] = utils.float2str(foodData.SpoilTime / 600) .. " 周期"
        end

        if foodData.RotTemperature ~= nil then
            out["冷藏温度"] = utils.float2str(foodData.RotTemperature + k0) .. " °C"
        end
        if foodData.PreserveTemperature ~= nil then
            out["深度冷冻温度"] = utils.float2str(foodData.PreserveTemperature + k0) .. " °C"
        end
    else
        out["是否会腐烂"] = "✖"
    end
    if foodData.Quality ~= nil then
        if foodData.Quality <= 6 and foodData.Quality >= -1 then
            out["食物品质"] = fstr("{{食物品质|%s}}", foodData.Quality)
        end
        if foodData.qualityOfLife ~= nil and foodData.qualityOfLife ~= 0 then
            out["士气加成"] = utils.float2str(foodData.qualityOfLife, nil, true)
        end
    end
    if foodData.primaryElement ~= nil then
        out["元素"] = fstr("{{物品|%s}}", utils.getEntry(foodData.primaryElement.Name))
        out["质量"] = utils.kg2str(foodData.primaryElement.Mass)
        -- out["初始温度"] = utils.float2str(foodData.primaryElement.InternalTemperature + k0) .. " °C"
    end
    if foodData.recipes then
        local function categorize(recipes)
            local categories = {}
            for _, recipe in ipairs(recipes) do
                local order = recipe.results[1].amount

                if not categories[order] then
                    categories[order] = {}
                end

                table.insert(categories[order], recipe)
            end

            return categories
        end

        local recipeGroups = categorize(foodData.recipes)
        local sortedKeys = {}
        local sortedGroups = {}
        for key, group in pairs(recipeGroups) do
            table.insert(sortedKeys, key)
            local sortedGroup = {
                time = nil,
                fabricator = nil,
                ingredients = {},
                results = {}
            }
            local ingredientKeys = {}
            for key, recipe in pairs(group) do
                -- 简化处理:一种食物的所有配方均经“同一”制作建筑制作,且所需时间一致
                if not sortedGroup.time then
                    sortedGroup.time = recipe.time
                elseif sortedGroup.time ~= recipe.time then
                    error("配方制作时间不一致。")
                end
                if recipe.fabricators[2] then
                    error("不支持复数制作建筑的配方,或制作建筑不可用。")
                else
                    if not sortedGroup.fabricator then
                        sortedGroup.fabricator = recipe.fabricators[1]
                    elseif sortedGroup.fabricator ~= recipe.fabricators[1] then
                        error("配方制作建筑不一致。")
                    end
                end
                table.insert(ingredientKeys, {
                    order = recipe.ingredients[1].name,
                    key = key
                })
                for i, result in ipairs(recipe.results) do
                    if not sortedGroup.results[i] then
                        sortedGroup.results[i] = recipe.results[i]
                    elseif sortedGroup.results[i].name ~= recipe.results[i].name or sortedGroup.results[i].amount ~=
                        recipe.results[i].amount then
                        error("配方结果异常。")
                    end
                end
            end
            table.sort(ingredientKeys, function(a, b)
                return a.order < b.order
            end)
            for _, v in ipairs(ingredientKeys) do
                for i, _ in ipairs(group[v.key].ingredients) do
                    if not sortedGroup.ingredients[i] then
                        sortedGroup.ingredients[i] = {}
                    end
                    table.insert(sortedGroup.ingredients[i], group[v.key].ingredients[i])
                end
            end
            sortedGroups[key] = sortedGroup
        end

        local sortedKeyOrders = {}
        for k in pairs(sortedKeys) do
            table.insert(sortedKeyOrders, k)
        end

        table.sort(sortedKeyOrders, function(a, b)
            return sortedKeys[a] > sortedKeys[b]
        end)

        local equations = {}
        for _, order in ipairs(sortedKeyOrders) do
            local key = sortedKeys[order]
            if not out["制作时间"] then
                out["制作时间"] = sortedGroups[key].time
            elseif out["制作时间"] ~= sortedGroups[key].time then
                error("配方制作时间不一致。")
            end
            if not out["制作建筑"] then
                out["制作建筑"] = sortedGroups[key].fabricator
            elseif out["制作建筑"] ~= sortedGroups[key].fabricator then
                error("配方制作建筑不一致。")
            end
            local equation = ""
            local equationIngredients = {}
            local equationInAmount = {}
            for i, ingredientSet in ipairs(sortedGroups[key].ingredients) do
                if not equationIngredients[i] then
                    equationIngredients[i] = {}
                end
                for _, ingredient in ipairs(ingredientSet) do
                    table.insert(equationIngredients[i], ingredient.name)
                    if not equationInAmount[i] then
                        equationInAmount[i] = ingredient.amount
                    elseif equationInAmount[i] ~= ingredient.amount then
                        error("配方原料输入异常。")
                    end
                end
            end
            for i, set in ipairs(equationIngredients) do
                local names = {}
                for _, v in ipairs(set) do
                    -- mw.logObject(utils.getEntry(v))
                    local name = ''
                    local name = fstr("{{物品|%s}}", utils.getEntry(v))
                    table.insert(names, name)
                end
                equation = equation .. table.concat(names, "/") .. cross .. equationInAmount[i] .. "<br>"
            end
            local equationResults = {}
            local equationReAmount = {}
            for i, result in ipairs(sortedGroups[key].results) do
                if not equationResults[i] then
                    equationResults[i] = {}
                end
                table.insert(equationResults[i], result.name)
                if not equationReAmount[i] then
                    equationReAmount[i] = result.amount
                elseif equationReAmount[i] ~= result.amount then
                    error("配方输出异常。")
                end
            end
            -- mw.logObject(equationResults)
            equation = equation .. "<div style='text-align:right'>" .. arrow
            for i, set in ipairs(equationResults) do
                local names = {}
                for _, result in ipairs(set) do
                    local name = fstr("{{物品|%s}}", utils.getEntry(result))
                    table.insert(names, name)
                end
                equation = equation .. table.concat(names, "/") .. cross .. equationReAmount[i] .. "<br>"
            end
            equation = equation .. "</div>"
            -- mw.log(equation)
            table.insert(equations, equation)
        end
        out["制作时间"] = out["制作时间"] .. " 秒"
        out["制作建筑"] = fstr("{{物品|%s}}", utils.getEntry(out["制作建筑"]))
        out["配方"] = "<div class='infobox-recipe'>" .. table.concat(equations, "") .. "</div>"
    end
    if foodData.Effects then
        local effects = {}
        for _, effect in pairs(foodData.Effects) do
            local efCode = "STRINGS.DUPLICANTS.MODIFIERS." .. effect:upper()
            table.insert(effects, fstr("<abbr title='{{Po|%s.TOOLTIP}}'>{{Po|%s.NAME}}<abbr>", efCode, efCode))
        end
        out["效果"] = table.concat(effects, "<br>")
    end
    return out, table.concat(cat, "")
end

-- test by: = p.main(require("Module:debug").frame({},{debug=1, pagename="烤肉串"}))
-- test by: = p.main(require("Module:debug").frame({},{debug=1, pagename="冰霜汉堡"}))
-- test by: = p.main(require("Module:debug").frame({},{debug=1, pagename="小吃豆"}))
-- test by: = p.main(require("Module:debug").frame({},{debug=1, pagename="生蛋"}))
-- test by: = p.main(require("Module:debug").frame({},{debug=1, pagename="烤海鲜"}))
-- test by: = p.main(require("Module:debug").frame({},{debug=1, "Burger"}))
-- test by: = p.main(require("Module:debug").frame({},{debug=1, "BeanPlantSeed"}))

function p.main(frame)
    local args = getArgs(frame)
    local infos = {}
    local foods = {}
    local pageCats = {}

    if args[1] ~= nil then
        for _, foodId in ipairs(args) do
            local _, _, foodCode = utils.getEntry(foodId)
            if foodCode == nil then
                return {
                    ["名称"] = fstr("找不到食物 '%s',请使用参数1或检查 [[%s]]。", foodId, fDataPath)
                }
            end
            table.insert(foods, {
                id = foodId,
                code = foodCode
            })
        end
    else
        local foodCode = i18ncr:msgRev({
            key = args.pagename,
            args = {
                prefix = "STRINGS.ITEMS.FOOD."
            }
        } or "")
        if foodCode == nil then
            return {
                ["名称"] = fstr("找不到食物 '%s',请使用参数1或检查 [[%s]]。", args.pagename, fDataPath)
            }
        end
        local foodId = foodCode:match("([%u_]+).NAME$")
        table.insert(foods, {
            id = foodId,
            code = foodCode
        })
    end

    for _, food in pairs(foods) do
        if exception[food.id] then
            food.id = exception[food.id]
            local _
            _, _, food.code = utils.getEntry(food.id)
        end
        for k, v in pairs(fData) do
            if k:upper() == food.id:upper() then
                local curr, cat = p._main(v, food.code)
                table.insert(infos, {
                    label = curr["名称"],
                    data = curr
                })
                if args.nocat then
                    cat = ""
                end
                table.insert(pageCats, cat)
            end
        end
    end

    if args.debug then
        mw.logObject(infos)
    end
    local infoboxTitle = #infos > 1 and args.pagename or infos[1].label
    return infobox.main(infoboxTitle, infos) .. table.concat(pageCats, "")
end

return p