缺氧 wiki 编辑团队提示:注册账号并登录后体验更佳,且可通过参数设置定制优化您的浏览体验!
该站点为镜像站点,如果你想帮助这个由玩家志愿编辑的 wiki 站点,请前往原站点参与编辑,
同时欢迎加入编辑讨论群 851803695 与其他编辑者一起参与建设!
全站通知:
模块:生态信息框
刷
历
编
跳到导航
跳到搜索
-- Module:生态信息框
-- 注意:代码中的 subworld (sw) 才是生态,而 biome 基本指生态所处自然环境(主要是自然砖块元素表)
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('Module:Dev/Arguments').getArgs
local infobox = require([[Module:信息框/生态]])
local i18nds = require([[Module:I18n]]).loadMessages([[Module:I18n/Subworlds]])
local i18nsv = require([[Module:I18n]]).loadMessages([[Module:I18n/SubworldsVariant]])
local gData = require([[Module:Data/Geysers]])
local elData = require([[Module:Data/Elements]])
local subworldsDataBASE = mw.loadData([[Module:Data/Worldgen/Subworlds]])
local subworldsDataDLC1 = mw.loadData([[Module:Data/Worldgen/Subworlds/Expansion1]])
local subworldsDataDLC2 = mw.loadData([[Module:Data/Worldgen/Subworlds/Dlc2]])
local worldsDataBASE = mw.loadData([[Module:Data/Worldgen/Worlds]])
local worldsDataDLC1 = mw.loadData([[Module:Data/Worldgen/Worlds/Expansion1]])
local worldsDataDLC2 = mw.loadData([[Module:Data/Worldgen/Worlds/Dlc2]])
local biomesDataBASE = mw.loadData([[Module:Data/Worldgen/Biomes]])
local biomesDataDLC1 = mw.loadData([[Module:Data/Worldgen/Biomes/Expansion1]])
local biomesDataDLC2 = mw.loadData([[Module:Data/Worldgen/Biomes/Dlc2]])
local tempertures = mw.loadData([[Module:Data/Worldgen/Temperatures]])
local critters = mw.loadData([[Module:Data/Critters]])
local plants = mw.loadData([[Module:Data/Plants]])
-- local plants = mw.loadData([[Module:Sandbox/Data/Plants]])
local DLC1Prefix = "expansion1::"
local DLC2Prefix = "dlc2::"
local GeyserGenericRepr = "随机[[间歇泉]]"
local function set2Seq(s)
local ret = {}
for k, v in pairs(s) do
if v then
table.insert(ret, k)
end
end
table.sort(ret)
return ret
end
local function getWorldListByCode(swNameCode)
local swCode = swNameCode and swNameCode:match("^STRINGS.SUBWORLDS.(%w+).NAME$")
if swCode == nil then
return {}
end
local usedWorlds = {}
local worlds = {}
for _, subworldsData in ipairs({subworldsDataBASE, subworldsDataDLC1, subworldsDataDLC2}) do
for swTypeId, swDatas in pairs(subworldsData) do
if not utils.endswith(swTypeId, ".yaml") and swTypeId:upper() == swCode then
for swFile, swData in pairs(swDatas) do
if usedWorlds[swFile] == nil then
usedWorlds[swFile] = true
table.insert(worlds, {
data = swData,
typeId = swTypeId,
id = utils.endswith(swFile, ".yaml") and swFile:gsub("%.yaml$", "") or swFile,
code = swNameCode
})
end
end
end
end
end
table.sort(worlds, function(a, b)
if a.typeId == b.typeId then
return a.id < b.id
else
return a.typeId < b.typeId
end
end)
return worlds
end
local function worldsData(output, dataset, pattern, subworldId)
for _, wData in pairs(dataset) do
local subworldIdPattern = fstr(pattern, subworldId)
for _, subworldFile in ipairs(wData.subworldFiles) do
if subworldFile.name:find(subworldIdPattern) ~= nil then
table.insert(output, wData)
end
end
end
end
local function getSectionName(swId)
local newName = i18nsv:msg(swId)
if not utils.isDefaultT(swId, newName) then
return newName
end
return swId
end
-- test by: = p.getTemplate("expansion1::poi/radioactive/uranium_fields_liquid_co2_geyser_b")
-- test by: = p.getTemplate("poi/jungle/geyser_steam")
function p.getTemplate(path)
local out = path
local dlc1 = utils.startswith(path, DLC1Prefix)
if dlc1 then
out = path:sub(#DLC1Prefix + 1)
end
local dlc2 = utils.startswith(path, DLC2Prefix)
if dlc2 then
out = path:sub(#DLC2Prefix + 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 (dlc2 and "/Dlc2") 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)
if template == nil then
return nil
end
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.getGeyserGroups(worldTemplateRules)
local gGroups = {}
for _, rule in ipairs(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
return gGroups
end
function p.getInfo(sData, subworldId)
local out = {}
local pageCats = {}
local subworldIdWbr = table.concat(utils.camel2Array(subworldId), "<wbr>") -- in case that the id is too long
out["生态代码"] = fstr("-{<code>%s</code>}-", subworldIdWbr) -- disable language conversion
out["生态类型代码"] = fstr("-{<code>%s</code>}-", sData.zoneType) -- disable language conversion
-- temperatureRange
local temperatureRange = tempertures.add[sData.temperatureRange]
out["温度范围"] = fstr("%.2f°C ~ %.2f°C", temperatureRange.min + utils.K0, temperatureRange.max + utils.K0)
-- biomes(元素、动植物等)
local biomesTagsSet = {}
local biomesTerrainSet = {}
for _, biome in ipairs(sData.biomes) do
for _, tag in ipairs(biome.tags or {}) do
biomesTagsSet[tag] = true
end
local versionPrefix = ""
if (utils.startswith(biome.name, DLC1Prefix)) then
versionPrefix = DLC1Prefix
elseif (utils.startswith(biome.name, DLC2Prefix)) then
versionPrefix = DLC2Prefix
end
local prefix = versionPrefix .. "biomes/"
if utils.startswith(biome.name, prefix) then
local path = mw.text.split(biome.name:sub(#prefix + 1), '/', true)
local biomeFamily = path[1]
local biomeVariant = path[2]
local biomesData = ({
[''] = biomesDataBASE,
[DLC1Prefix] = biomesDataDLC1,
[DLC2Prefix] = biomesDataDLC2
})[versionPrefix]
local bFamilyData = biomesData[biomeFamily .. ".yaml"]
local bData = bFamilyData.TerrainBiomeLookupTable.add[biomeVariant]
for _, entry in ipairs(bData) do
biomesTerrainSet[entry.content] = true
end
else
mw.logObject(biome, "Invalid biome")
end
end
local biomesTags = set2Seq(biomesTagsSet)
local biomesTerrain = set2Seq(biomesTerrainSet)
local biomesElements = {}
for _, eleId in ipairs(biomesTerrain) do
local el = elData[eleId]
if biomesElements[el.state] == nil then
biomesElements[el.state] = {}
end
table.insert(biomesElements[el.state], fstr("{{物品|%s}}", po(el.localizationID)))
end
for state, elements in pairs(biomesElements) do
out[po("STRINGS.MISC.TAGS." .. state:upper())] = table.concat(elements, ' {{*}} ')
end
local entryTags = {}
for _, tag in ipairs(biomesTags) do
local entryTag = tag
if utils.startswith(entryTag, 'med_') then
entryTag = entryTag:sub(5)
end
if utils.startswith(entryTag, 'forestCluster_') then
entryTag = entryTag:sub(15)
mw.log(entryTag)
end
if utils.endswith(entryTag, 'Sparse') then
entryTag = entryTag:sub(1, #entryTag - 6)
end
if utils.endswith(entryTag, 'Dense') then
entryTag = entryTag:sub(1, #entryTag - 5)
end
if utils.endswith(entryTag, 'Large') then
entryTag = entryTag:sub(1, #entryTag - 5)
end
if utils.endswith(entryTag, 'Small') then
entryTag = entryTag:sub(1, #entryTag - 5)
end
local buried = false
if utils.endswith(entryTag, 'Buried') then
entryTag = entryTag:sub(1, #entryTag - 6)
buried = true
end
if entryTag == 'DiverentBeelte' then
entryTag = 'DivergentBeetle'
end
local name, isCat, _, t = utils.getEntry(entryTag)
local missing = name == nil
name = name or entryTag
if critters[entryTag] ~= nil then
t = 'variant'
elseif plants[entryTag] ~= nil then
t = 'plant'
end
local entryTypeName = ({
food = '食物',
creature = '生物',
creature_ = '生物',
family = '小动物',
variant = '小动物',
seed = '种子',
plant = '植物'
})[t or ''] or "其他物品"
if entryTags[entryTypeName] == nil then
entryTags[entryTypeName] = {}
end
local suffix = buried and " (掩埋)" or ""
if missing then
table.insert(entryTags[entryTypeName], name)
elseif isCat then
table.insert(entryTags[entryTypeName], fstr("[[:Category:%s|%s]]%s", name, name, suffix))
else
table.insert(entryTags[entryTypeName], fstr("{{物品|%s}}%s", name, suffix))
end
end
for entryTypeName, entries in pairs(entryTags) do
out[entryTypeName] = table.concat(entries, ' {{*}} ')
end
-- 出现小行星
local usedByWorlds = {}
worldsData(usedByWorlds, worldsDataBASE, "^subworlds/%%w+/%s$", subworldId)
worldsData(usedByWorlds, worldsDataDLC1, "^expansion1::subworlds/%%w+/%s$", subworldId)
worldsData(usedByWorlds, worldsDataDLC2, "^dlc2::subworlds/%%w+/%s$", subworldId)
local usedByWorldsSet = {}
local usedByWorldsList = {}
for _, wData in ipairs(usedByWorlds) do
local nameCode = wData.name
if (usedByWorldsSet[nameCode] == nil) then
usedByWorldsSet[nameCode] = true
table.insert(usedByWorldsList, fstr("\n*[[%s]]", po(nameCode)))
end
end
out["出现小行星"] = table.concat(usedByWorldsList, "")
if out["出现小行星"] == "" then
out["出现小行星"] = "无"
end
-- 间歇泉
if sData.subworldTemplateRules ~= nil then
local gGroups = p.getGeyserGroups(sData.subworldTemplateRules)
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
else
return
fstr("{{*}}{{物品|%s}}", po("STRINGS.CREATURES.SPECIES.GEYSER." .. g.id:upper() .. ".NAME"))
end
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, "<br>"), rangeText))
end
if #geyserText > 0 then
out["间歇泉"] = table.concat(geyserText, "<div><hr /></div><div><hr /></div>")
end
else
out["间歇泉"] =
"<abbr title='但仍可能由地图规则随机生成掩埋的间歇泉'>无本地生成规则</abbr>"
end
table.insert(pageCats, "[[Category:生态]]")
return out, pageCats
end
-- 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 worlds = {}
if args.pagename ~= nil then
local swNamePlain = mw.ustring.match(args.pagename, "^(%w+)生态$")
local swNameCode = i18nds:msgRev({
key = swNamePlain,
args = {
prefix = "STRINGS.SUBWORLDS."
}
} or "")
if swNameCode == nil then
error(fstr("找不到生态 '%s',请使用参数1或检查 [[%s]]。", args.pagename,
"Module:Data/Worldgen/Subworlds"))
end
worlds = getWorldListByCode(swNameCode)
else
error("找不到参数 pagename")
end
local sections = {}
local pageCatsSet = {}
if worlds ~= nil and #worlds > 0 then
local swCode = worlds[1].code
for _, worldData in ipairs(worlds) do
local info, cats = p.getInfo(worldData.data, worldData.id)
info["图片"] = args.pagename .. ".png"
info["图片说明"] = po(swCode:sub(1, -6) .. ".DESC")
table.insert(sections, {
data = info,
label = getSectionName(worldData.id)
})
for _, cat in ipairs(cats) do
pageCatsSet[cat] = true
end
end
else
error(fstr("找不到生态 '%s',请使用参数1或检查 [[%s]]。", args.pagename,
"Module:Data/Worldgen/Subworlds"))
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 title = args.pagename
return tostring(infobox.main(title, sections)) .. table.concat(pageCats, "")
end
return p