缺氧 Wiki

缺氧 wiki 编辑团队提示:注册账号并登录后浏览体验更佳 —— 官方免广告首页除外  •  启用小工具换源显示图片  •  通过参数设置定制化您的浏览体验

缺氧 Wiki 正在进行分叉讨论,欢迎参与!

如果你想帮助这个由玩家志愿编辑的 wiki 站点,欢迎加群 851803695 与其他编辑者一起参与建设!同时也欢迎加入缺氧 QQ 频道参与讨论~

了解更多

缺氧 Wiki
Advertisement

此模块的文档可以在Module:小行星信息框/doc创建

-- 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 getArgs = require('Dev:Arguments').getArgs
local infobox = require([[Module:信息框/小行星]])
local gData = require([[Module:Data/Geysers]])
local worldsDataBASE = mw.loadData([[Module:Data/Worldgen/Worlds]])
local worldsDataDLC1 = mw.loadData([[Module:Data/Worldgen/Worlds/Expansion1]])
local clustersDLC1 = mw.loadData([[Module:Data/Worldgen/Clusters/Expansion1]])
local i18ndw = require([[Module:I18n]]).loadMessages([[Module:i18n/Worlds]])

local seasonNames = {
    MeteorShowers = "[[流星雨]]",
    RegolithMoonMeteorShowers = "[[流星雨]](浮土)",
    GassyMooteorShowers = "[[流星雨]]([[释气海牛|海牛]])"
}

local GeyserGenericRepr = "随机[[间歇泉]]"

-- TUNING.FIXEDTRAITS.SUNLIGHT
local DEFAULT_SPACED_OUT_SUNLIGHT = 40000
local sunlightLevels = {
    sunlightNone = 0,
    sunlightVeryVeryLow = DEFAULT_SPACED_OUT_SUNLIGHT * 0.25,
    sunlightVeryLow = DEFAULT_SPACED_OUT_SUNLIGHT * 0.5,
    sunlightLow = DEFAULT_SPACED_OUT_SUNLIGHT * 0.75,
    sunlightMedLow = DEFAULT_SPACED_OUT_SUNLIGHT * 0.875,
    sunlightMed = DEFAULT_SPACED_OUT_SUNLIGHT,
    sunlightMedHigh = DEFAULT_SPACED_OUT_SUNLIGHT * 1.25,
    sunlightHigh = DEFAULT_SPACED_OUT_SUNLIGHT * 1.5,
    sunlightVeryHigh = DEFAULT_SPACED_OUT_SUNLIGHT * 2,
    sunlightVeryVeryHigh = DEFAULT_SPACED_OUT_SUNLIGHT * 2.5,
    sunlightVeryVeryVeryHigh = DEFAULT_SPACED_OUT_SUNLIGHT * 3,
    default = DEFAULT_SPACED_OUT_SUNLIGHT * 2 -- DEFAULT_VALUE = VERY_HIGH
}

-- TUNING.FIXEDTRAITS.COSMICRADIATION
local BASELINE = 250
local cosmicRadiationLevels = {
    cosmicRadiationNone = 0,
    cosmicRadiationVeryVeryLow = BASELINE * 0.25,
    cosmicRadiationVeryLow = BASELINE * 0.5,
    cosmicRadiationLow = BASELINE * 0.75,
    cosmicRadiationMedLow = BASELINE * 0.875,
    cosmicRadiationMed = BASELINE,
    cosmicRadiationMedHigh = BASELINE * 1.25,
    cosmicRadiationHigh = BASELINE * 1.5,
    cosmicRadiationVeryHigh = BASELINE * 2,
    cosmicRadiationVeryVeryHigh = BASELINE * 3,
    default = BASELINE -- DEFAULT_VALUE = MED
}

local function subworldName(path)
    local subworld = path:match("subworlds/(%w+)/")
    return fstr("STRINGS.SUBWORLDS.%s.NAME", subworld:upper())
end

-- test by: = p.getTemplate("expansion1::poi/radioactive/uranium_fields_liquid_co2_geyser_b")
-- test by: = p.getTemplate("poi/jungle/geyser_steam")
-- test by: = p.getTemplate("geysers/generic")
function p.getTemplate(path)
    local out = path
    local dlc1Prefix = "expansion1::"
    local dlc1 = utils.startswith(path, dlc1Prefix)
    if dlc1 then out = path:sub(#dlc1Prefix + 1) end
    local splited = mw.text.split(out, '/', true)
    local capName = splited[1]:sub(1, 1):upper() .. splited[1]:sub(2)
    out = mw.loadData("Module:Data/Templates/" .. capName ..
                          (dlc1 and "/Expansion1" or ""))

    splited[#splited] = splited[#splited] .. ".yaml"
    for i = 2, #splited do
        if out == nil then return nil end
        out = out[splited[i]]
    end
    return out
end

function p.getGeyserId(template)
    local prefix = "GeyserGeneric_"
    if template.otherEntities == nil then return nil end
    for _, e in ipairs(template.otherEntities) do
        if e.id == "GeyserGeneric" then return e.id end
        if utils.startswith(e.id, prefix) then
            return e.id:sub(#prefix + 1)
        end
    end
    return nil
end

function p.getInfo(worldId)
    local worldFile = utils.endswith(worldId, ".yaml") and worldId or worldId ..
                          ".yaml"
    local wData = worldsDataDLC1[worldFile]
    local isBase = false
    if wData == nil then
        wData = worldsDataBASE[worldFile]
        isBase = true
    end

    local out = {}
    local pageCats = {}

    if wData == nil then
        out["名称"] =
            "找不到小行星,请检查[[module:小行星信息框]]。<br/>" ..
                "args[1]=" .. tostring(worldId)
        return out
    end

    out["小行星代码"] = table.concat(utils.camel2Array(worldId), "<wbr>") -- in case that the id is too long
    out["小行星代码"] = fstr("-{<code>%s</code>}-", out["小行星代码"]) -- disable language conversion
    out["名称"] = po(wData.name)
    out["图片"] = fstr("%s.png", out["名称"])
    out["图片说明"] = po(wData.description)
    out["大小"] = fstr("%s x %s 格", wData.worldsize.X, wData.worldsize.Y)

    if not isBase then
        out["出现星群"] = {}
        for _, cData in pairs(clustersDLC1) do
            for _, worldInCluster in ipairs(cData.worldPlacements) do
                -- only consider dlc1 worlds
                local worldIdWithPrefix = "expansion1::worlds/" .. worldId
                if worldIdWithPrefix == worldInCluster.world then
                    table.insert(out["出现星群"], cData)
                end
            end
        end
        table.sort(out["出现星群"], function(a, b)
            if a.clusterCategory ~= b.clusterCategory then
                return a.clusterCategory < b.clusterCategory
            else
                return a.menuOrder < b.menuOrder
            end
        end)
        local list = utils.map(out["出现星群"], function(cData)
            return fstr("\n*[[%s]]", po(cData.name))
        end)
        out["出现星群"] = table.concat(list, "")
        if out["出现星群"] == "" then out["出现星群"] = "无" end
    end

    if wData.seasons then
        out["天气"] = {}
        for _, s in ipairs(wData.seasons) do
            table.insert(out["天气"], seasonNames[s])
        end
        out["天气"] = table.concat(out["天气"], " {{*}} ")
    end

    out["星球特质"] = "无"
    if wData.worldTraitRules then
        local min = wData.worldTraitRules[1] and wData.worldTraitRules[1].min
        local max = wData.worldTraitRules[1] and wData.worldTraitRules[1].max
        if min and max then
            if (min == max) then
                out["星球特质"] = fstr("%s 个", min)
            else
                out["星球特质"] = fstr("%s - %s 个", min, max)
            end
        end
    end

    if wData.subworldFiles then
        local subworldSet = {}
        local subworlds = {}
        for _, sf in ipairs(wData.subworldFiles) do
            subworldSet[subworldName(sf.name)] = true
        end
        for name, _ in pairs(subworldSet) do
            table.insert(subworlds, name)
        end
        table.sort(subworlds)
        subworlds = utils.map(subworlds, function(code)
            return fstr("\n*[[%s生态]]", po(code))
        end)
        out["生态"] = table.concat(subworlds, "")
    end

    if isBase then
        out["最大光照"] = 80000
    elseif wData.fixedTraits then
        out["最大光照"] = sunlightLevels.default
        out["辐射强度"] = cosmicRadiationLevels.default
        for _, trait in ipairs(wData.fixedTraits) do
            out["最大光照"] = sunlightLevels[trait] and
                                      math.floor(sunlightLevels[trait] + 0.5) or
                                      out["最大光照"]
            out["辐射强度"] = cosmicRadiationLevels[trait] and
                                      math.floor(
                                          cosmicRadiationLevels[trait] + 0.5) or
                                      out["辐射强度"]
        end
    end

    local gGroups = {}
    out["间歇泉"] = "无"
    if wData.worldTemplateRules then
        for _, rule in ipairs(wData.worldTemplateRules) do
            local geyserIds = {}
            local geyserIdNum = {}	-- 该规则下各种间歇泉的重复数
            local ruleTimes = rule.times or 1
            for _, name in ipairs(rule.names) do
                local id = p.getGeyserId(p.getTemplate(name))
                if id ~= nil then
                	if not geyserIdNum[id] then
                    	geyserIdNum[id] = 1
                    	table.insert(geyserIds, id)
                    else
                    	geyserIdNum[id] = geyserIdNum[id] + 1
                	end
                end
            end
            table.sort(geyserIds)

            if #geyserIds ~= 0 then
                local group = {}
                group.id = table.concat(geyserIds)
                group.geysers = utils.map(geyserIds, function(id)
                    return gData[id] or {id = id}
                end)
                for _, g in ipairs(group.geysers) do	-- 在间歇泉数据中添加重复数信息
                	g.num = geyserIdNum[g.id]
                end
                group.minNum = 0
                group.maxNum = 0

                if rule.listRule == "GuaranteeAll" then
                    for _, g in ipairs(group.geysers) do
                        if gGroups[g.id] ~= nil then
                            gGroups[g.id].minNum =
                                gGroups[g.id].minNum + 1 * ruleTimes * geyserIdNum[g.id]
                            gGroups[g.id].maxNum =
                                gGroups[g.id].maxNum + 1 * ruleTimes * geyserIdNum[g.id]
                        else
                            gGroups[g.id] = {
                                geysers = {g},
                                minNum = 1 * ruleTimes * geyserIdNum[g.id],
                                maxNum = 1 * ruleTimes * geyserIdNum[g.id]
                            }
                        end
                    end
                else
                    if rule.listRule == "GuaranteeSome" then
                        group.minNum = rule.someCount
                        group.maxNum = rule.someCount
                    elseif rule.listRule == "GuaranteeSomeTryMore" then
                        group.minNum = rule.someCount
                        group.maxNum = rule.someCount + rule.moreCount
                    elseif rule.listRule == "GuaranteeOne" then
                        group.minNum = 1
                        group.maxNum = 1
                    elseif rule.listRule == "TryAll" then	-- 不使用间歇泉种类计数,累加全体重复数
                    	group.maxNum = 0
                        for _, n in pairs(geyserIdNum) do
                        	group.maxNum = group.maxNum + n
                        end
                    elseif rule.listRule == "TrySome" then
                        group.maxNum = rule.someCount
                    elseif rule.listRule == "TryOne" then
                        group.maxNum = 1
                    end
                    group.minNum = group.minNum * ruleTimes
                    group.maxNum = group.maxNum * ruleTimes

                    if gGroups[group.id] ~= nil then
                        gGroups[group.id].minNum =
                            gGroups[group.id].minNum + group.minNum
                        gGroups[group.id].maxNum =
                            gGroups[group.id].maxNum + group.maxNum
                    else
                        gGroups[group.id] = group
                    end
                end
            end
        end
        local gGroupIds = {}
        for gId, _ in pairs(gGroups) do table.insert(gGroupIds, gId) end
        table.sort(gGroupIds)

        local geyserText = {}
        for _, gId in ipairs(gGroupIds) do
            local currGroup = gGroups[gId]
            local gNames = utils.map(currGroup.geysers, function(g)
                if g.id == "GeyserGeneric" then
                    return GeyserGenericRepr
                end
                if g.num ~= 1 then
                	return g.page and fstr("[[%s]](%d)", g.page, g.num) or g.id
                end
                return g.page and fstr("[[%s]]", g.page) or g.id
            end)
            local rangeText = tostring(currGroup.minNum)
            if currGroup.minNum ~= currGroup.maxNum then
                rangeText = rangeText .. " - " .. tostring(currGroup.maxNum)
            end
            table.insert(geyserText,
                         fstr("<div>%s</div><div>%s</div>",
                              table.concat(gNames, "<wbr>{{*}}"), rangeText))
        end
        out["间歇泉"] = table.concat(geyserText)
    end

    table.insert(pageCats, "[[Category:小行星]]")
    return out, pageCats
end

--[=[ test by:
= p.main(require("Module:debug").frame({},{
    pagename = "倒置小行星",
    "MiniFlippedStart",
    ["标题 MiniFlippedStart"] = "开局",
    "MiniFlippedWarp",
    ["标题 MiniFlippedWarp"] = "传送",
    "MiniFlipped",
    ["标题 MiniFlipped"] = "基础",
    debug=1,
}))
]=]
--[=[ test by:
= p.main(require("Module:debug").frame({},{
    pagename = "放射性沼泽小行星",
    "MediumRadioactiveVanillaWarpPlanet",
    debug=1,
}))
]=]
--[=[ test by:
= p.main(require("Module:debug").frame({},{
    pagename = "辐照森林小行星",
    "SmallRadioactiveLandingSite",
    debug=1,
}))
]=]
--[=[ test by:
= p.main(require("Module:debug").frame({},{
    pagename = "砂土小行星",
    "TerraMoonlet",
    debug=1,
}))
]=]
-- test by: =p.main(require("Module:debug").frame({},{"Badlands", debug=1}))
function p.main(frame)
    local sections = {}
    local args = getArgs(frame)

    local pageCatsSet = {}
    for _, worldId in ipairs(args) do
        local info, cats = p.getInfo(worldId)
        if args.debug then mw.logObject(info, "info") end
        table.insert(sections,
                     {data = info, label = args[fstr("标题 %s", worldId)]})
        for _, cat in ipairs(cats) do pageCatsSet[cat] = true end
    end

    local pageCats = {}
    for cat, _ in pairs(pageCatsSet) do table.insert(pageCats, cat) end
    table.sort(pageCats)

    local title = args.pagename
    if args.debug then
        mw.logObject(infobox.main(title, sections, true), "Infobox")
        mw.logObject(pageCats, "pageCats")
        return
    end

    if (args.namespace or args.nocat) then pageCats = {} end
    return infobox.main(title, sections) .. table.concat(pageCats, "")
end
return p
Advertisement