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

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

全站通知:

模块:星群信息框

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

用于模板:Template:星群信息框。 视图模块:Module:信息框/星群。 数据模块:Module:Data/Worldgen/Clusters/Expansion1



-- Module:星群信息框
local p = {}
local fstr = mw.ustring.format -- shortcut for formattig a string
local utils = require([[Module:Utils]])
local po = require([[Module:Po]]).po
local i18ndw = require([[Module:I18n]]).loadMessages([[Module:i18n/Clusternames]])
local getArgs = require('Module:Dev/Arguments').getArgs
local infobox = require([[Module:信息框/星群]])
local clustersDataDLC1 = mw.loadData([[Module:Data/Worldgen/Clusters/Expansion1]])
local clustersDataDLC2 = mw.loadData([[Module:Data/Worldgen/Clusters/Dlc2]])
local worldsDataDLC1 = mw.loadData([[Module:Data/Worldgen/Worlds/Expansion1]])
local worldsDataDLC2 = mw.loadData([[Module:Data/Worldgen/Worlds/Dlc2]])
local templatesDataDLC1 = mw.loadData([[Module:Data/Templates/Poi/Expansion1]])

local difficultyCode = {"STRINGS.WORLDS.SURVIVAL_CHANCE.MOSTHOSPITABLE", "STRINGS.WORLDS.SURVIVAL_CHANCE.VERYHIGH",
                        "STRINGS.WORLDS.SURVIVAL_CHANCE.HIGH", "STRINGS.WORLDS.SURVIVAL_CHANCE.NEUTRAL",
                        "STRINGS.WORLDS.SURVIVAL_CHANCE.LOW", "STRINGS.WORLDS.SURVIVAL_CHANCE.VERYLOW",
                        "STRINGS.WORLDS.SURVIVAL_CHANCE.LEASTHOSPITABLE"}
setmetatable(difficultyCode, {
    __call = function(table, key)
        local luaKey = key + 1
        if luaKey < 1 then
            luaKey = 1
        end
        if luaKey > #table then
            luaKey = #table
        end
        return rawget(table, luaKey)
    end
})

local function contains(t, e)
    if t == nil then
        return false
    end
    for _, i in ipairs(t) do
        if i == e then
            return true
        end
    end
    return false
end

-- get a list of feature builds icon to append to the end of worlds' name of a cluster
local FEATURE_BUILDINGS = {"TemporalTearOpener", "WarpConduitReceiver"}
local function get_world_feaatures(worldData, locationType)
    local features = {}
    local featuresSeen = {} -- same feature should only display once
    for _, templateRule in ipairs(worldData.worldTemplateRules) do
        if templateRule.listRule == "GuaranteeAll" then
            for _, tName in ipairs(templateRule.names) do
                local tCode = mw.ustring.match(tName, "^expansion1::poi/(.+)$")
                if tCode ~= nil then
                    local tData = templatesDataDLC1
                    for scope in mw.text.gsplit(tCode .. ".yaml", "/", true) do -- true for plain sep
                        tData = tData[scope]
                    end
                    for _, bu in ipairs(tData.buildings or {}) do
                        local validBu = not contains(featuresSeen, bu.id) and contains(FEATURE_BUILDINGS, bu.id)
                        if validBu then
                            table.insert(featuresSeen, bu.id)
                            local buName = po(utils.getCode("building", bu.id))
                            local icon = mw.getCurrentFrame():expandTemplate{
                                title = "物品",
                                args = {
                                    buName,
                                    notext = 1
                                }
                            }
                            table.insert(features, icon)
                        end
                    end
                end
            end
        end
    end
    return table.concat(features, " ")
end

local function getClusterById(clusterId)
    local clusterFile = utils.endswith(clusterId, ".yaml") and clusterId or clusterId .. ".yaml"
    if clustersDataDLC1[clusterFile] ~= nil then
        local cData = clustersDataDLC1[clusterFile]
        if not contains(cData.forbiddenDlcIds, "EXPANSION1_ID") then
            return cData, "EXPANSION1_ID"
        end
    elseif clustersDataDLC2[clusterFile] ~= nil then
        local cData = clustersDataDLC2[clusterFile]
        if not contains(cData.forbiddenDlcIds, "EXPANSION1_ID") then
            return cData, "DLC2_ID"
        end
    end
    return nil, nil
end

local function getClusterByCode(pagename)
    local clusterCode = i18ndw:msgRev({
        key = pagename,
        args = {
            prefix = "STRINGS.CLUSTER_NAMES."
        }
    } or "")
    for clusterId, cData in pairs(clustersDataDLC1) do
        if (clusterCode == cData.name or po(cData.name) == pagename) and
            not contains(cData.forbiddenDlcIds, "EXPANSION1_ID") then
            return {
                data = cData,
                id = utils.endswith(clusterId, ".yaml") and clusterId:gsub("%.yaml$", "") or clusterId,
                dlc = "EXPANSION1_ID"
            }
        end
    end
    for clusterId, cData in pairs(clustersDataDLC2) do
        if (clusterCode == cData.name or po(cData.name) == pagename) and
            not contains(cData.forbiddenDlcIds, "EXPANSION1_ID") then
            return {
                data = cData,
                id = utils.endswith(clusterId, ".yaml") and clusterId:gsub("%.yaml$", "") or clusterId,
                dlc = "DLC2_ID"
            }
        end
    end
    return nil
end

function p.getInfo(cData, clusterId, dlc)
    local out = {}
    local pageCats = {}

    out["名称"] = po(cData.name)
    out["ID"] = fstr("-{<code>%s</code>}-", clusterId)
    out["图片"] = fstr("%s.png", out["名称"])
    out["图片说明"] = po(cData.description)
    out["存活的可能性"] = po(difficultyCode(cData.difficulty or 0))

    out["初始的小行星"] = {}
    out["临近的小行星"] = {}
    out["遥远的小行星"] = {}
    local locationTypes = {
        StartWorld = out["初始的小行星"],
        InnerCluster = out["临近的小行星"],
        default = out["遥远的小行星"]
    }

    for _, world in ipairs(cData.worldPlacements) do
        local worldId = mw.ustring.match(world.world, "^expansion1::worlds/(.+)$")
        if worldId ~= nil then
            local worldData = worldsDataDLC1[worldId .. ".yaml"]
            if worldData == nil then
                worldData = worldsDataDLC2[worldId .. ".yaml"]
            end
            if worldData ~= nil then
                local worldName = po(worldData.name)
                local worldLocType = world.locationType or 'default'
                local worldRepr = fstr("[[%s]]", worldName) .. ' ' .. get_world_feaatures(worldData, world.locationType)
                table.insert(locationTypes[worldLocType], worldRepr)
            end
        end
    end
    local function toListEntry(s)
        return "\n*" .. s
    end

    out["初始的小行星"] = #out["初始的小行星"] > 0 and table.concat(utils.map(out["初始的小行星"], toListEntry), "") or nil
    out["临近的小行星"] = #out["临近的小行星"] > 0 and table.concat(utils.map(out["临近的小行星"], toListEntry), "") or nil
    out["遥远的小行星"] = #out["遥远的小行星"] > 0 and table.concat(utils.map(out["遥远的小行星"], toListEntry), "") or nil

    local cCatMap = {
        Vanilla = "[[Category:游戏本体星群]]",
        SpacedOutVanillaStyle = "[[Category:经典风格星群]]",
        SpacedOutStyle = "[[Category:眼冒金星风格星群]]",
        Special = "[[Category:实验室风格星群]]",
        [1] = "[[Category:经典风格星群]]",
        [2] = "[[Category:眼冒金星风格星群]]",
        [3] = "[[Category:其他风格星群]]"
    }
    if cData.clusterCategory ~= nil then
        table.insert(pageCats, cCatMap[cData.clusterCategory])
    end

    return out, pageCats
end

-- test by: = p.main(require("Module:debug").frame({},{"VanillaSandstoneCluster", debug=1}))
-- test by: = p.main(require("Module:debug").frame({},{"SandstoneStartCluster", debug=1}))
-- test by: = p.main(require("Module:debug").frame({},{"CeresBaseGameCluster","CeresClassicCluster", debug=1}))
-- test by: = p.main(require("Module:debug").frame({},{pagename = "谷神星群", debug=1}))
-- test by: = p.main(require("Module:debug").frame({},{pagename = "乔木星群", debug=1}))
function p.main(frame)
    local args = getArgs(frame)
    local sections = {}
    local pageCatsSet = {}

    if args[1] ~= nil then
        for _, clusterId in ipairs(args) do
            local cData, dlc = getClusterById(clusterId)
            if cData ~= nil then
                local info, cats = p.getInfo(cData, clusterId, dlc)
                table.insert(sections, {
                    data = info,
                    label = po(cData.name)
                })
            end
        end
    elseif args.pagename ~= nil then
        local cluster = getClusterByCode(args.pagename)
        if cluster ~= nil then
            local info, cats = p.getInfo(cluster.data, cluster.id, cluster.dlc)
            table.insert(sections, {
                data = info,
                label = args.pagename
            })
            for _, cat in ipairs(cats) do
                pageCatsSet[cat] = true
            end
        else
            error(fstr("找不到星群 '%s',请使用参数1或检查 [[%s]]。", args.pagename,
                "[[Module:Data/Worldgen/Clusters]]"))
        end
    else
        error(fstr("找不到星群 '%s',请使用参数1或检查 [[%s]]。", args.pagename,
            "[[Module:Data/Worldgen/Clusters]]"))
    end

    -- 分类
    local pageCats = {}
    if not (args.namespace or args.nocat) then
        for cat, _ in pairs(pageCatsSet) do
            table.insert(pageCats, cat)
        end
        table.sort(pageCats)
    end
    if args.debug then
        mw.logObject(sections, "Infobox")
        mw.logObject(pageCats, "pageCats")
        return
    end
    local infoboxTitle = args.pagename

    return infobox.main(infoboxTitle, sections) .. table.concat(pageCats, "")
end
return p