缺氧 wiki 编辑团队提示:注册账号并登录后体验更佳,且可通过参数设置定制优化您的浏览体验!
该站点为镜像站点,如果你想帮助这个由玩家志愿编辑的 wiki 站点,请前往原站点参与编辑,
同时欢迎加入编辑讨论群 851803695 与其他编辑者一起参与建设!
全站通知:
模块:建筑信息框
刷
历
编
跳到导航
跳到搜索
-- Module:建筑信息框
local p = {}
local utils = require([[Module:Utils]])
local rcputils = require([[Module:Utils/Recipes]]).infobox
local po = require([[Module:Po]]).po
local getArgs = require('Module:Dev/Arguments').getArgs
local fstr = mw.ustring.format -- shortcut for formattig a string
local infobox = require([[Module:信息框/建筑]])
local i18ndc = require([[Module:I18n]]).loadMessages([[Module:i18n/Codex]])
local i18nde = require([[Module:I18n]]).loadMessages([[Module:i18n/Elements]])
local i18ndi = require([[Module:I18n]]).loadMessages([[Module:i18n/Items]])
local i18ndr = require([[Module:I18n]]).loadMessages([[Module:i18n/Research]])
local i18ndu = require([[Module:I18n]]).loadMessages([[Module:i18n/Ui]])
local i18ndm = require([[Module:I18n]]).loadMessages([[Module:i18n/Misc]])
local i18ndb = require([[Module:I18n]]).loadMessages([[Module:i18n/Buildings]])
local _c = function(...) return i18ndc:msg(...) end
local _e = function(...) return i18nde:msg(...) end
local _i = function(...) return i18ndi:msg(...) end
local _r = function(...) return i18ndr:msg(...) end
local _u = function(...) return i18ndu:msg(...) end
local _m = function(...) return i18ndm:msg(...) end
local _b = function(...) return i18ndb:msg(...) end
local buData = mw.loadData([[Module:Data/Buildings]])
local mModifier = require([[Module:Data/MaterialModifier]])
local k0 = utils.K0
local epsilon = 1e-7
local ROTATIONS = {
[0] = "不可旋转",
[1] = "90度旋转",
[2] = "360度旋转",
[3] = "水平翻转",
[4] = "垂直翻转"
}
local function effectCode(id) return fstr("STRINGS.BUILDINGS.PREFABS.%s.EFFECT", string.upper(id)) end
local function descCode(id) return fstr("STRINGS.BUILDINGS.PREFABS.%s.DESC", string.upper(id)) end
local function isDefaultT(s, t) return ("<" .. s .. ">") == t end
local function cleanLoc(str) return (string.gsub(str,"<br/>","")) end
-- return {buCode}
local function getBuCode(pagename)
local buCode = i18ndb:msgRev({
key = pagename,
args = {
prefix = "STRINGS.BUILDINGS.PREFABS."
}
} or "")
if buCode == nil or isDefaultT(pagename, buCode) then
error(fstr("找不到建筑物 '%s',请使用参数1或检查 [[%s]]。",pagename, [[Module:Data/Buildings]]))
else
return buCode
end
return nil
end
local function getItemLink(items, sep)
-- 返回物品短链
local links = {}
local shortcut = {
["BuildingFiber"] = "BasicFabric", -- 纤维 => 芦苇纤维
["BuildingWood"] = "Wood", -- 木材(分类) => 木材
}
for item in items:gmatch("[^%&]+") do
item = shortcut[item] or item
local locStr, isCat = utils.getEntry(item)
locStr = cleanLoc(locStr)
local link = isCat and fstr("[[:category:%s|%s]]", locStr, locStr) or fstr("[[%s]]", locStr)
table.insert(links, link)
end
return table.concat(links, sep or "/")
end
local function logicMsg(s)
local ret = _u(s)
if isDefaultT(s, ret) then
ret = _b(s)
end
return ret
end
function p._main(bu, buCode, args)
local out = {}
local pageCats = {}
local elemData = nil
out["ID"] = fstr("<code>%s</code>", bu.id)
out["名称"] = _b(buCode)
out["图片"] = args.img or fstr("%s.png", out["名称"])
out["图片说明"] = _b(descCode(bu.id))
out["图片说明"] = not isDefaultT(descCode(bu.id), out["图片说明"]) and out["图片说明"] or nil
out["描述"] = _b(effectCode(bu.id))
out["描述"] = not isDefaultT(effectCode(bu.id), out["描述"]) and out["描述"] or nil
out['弃用'] = bu.Deprecated ~= nil and bu.Deprecated == true and "已弃用" or nil
out["尺寸"] = fstr("宽 %s 高 %s", bu.WidthInCells, bu.HeightInCells)
out["旋转"] = bu.PermittedRotations and ROTATIONS[bu.PermittedRotations] or "不可旋转"
out["淹没"] = bu.Floodable and "淹没时无法运作" or "淹没时可正常工作"
out["掩埋"] = bu.Entombable and "掩埋时无法运作" or "掩埋时可正常工作"
out["基础建造时间"] = bu.ConstructionTime and fstr("%d 秒", bu.ConstructionTime) or nil
out['建筑血量'] = bu.Invincible == true and "无敌" or utils.float2str(bu.HitPoints)
out['可被蓄意破坏'] = bu.Breakable == true and bu.Invincible == false and "✔" or "✖"
out['导热系数'] = bu.ThermalConductivity ~= nil and utils.float2str(bu.ThermalConductivity) or nil
out['火箭限制'] = bu.rocketUsageRestrictionDef ~= nil and "✔" or nil
out['电力'] = {}
if bu.GeneratorWattageRating and bu.GeneratorWattageRating > 0 then
local power = fstr("发电 %d 瓦", utils.float2str(bu.GeneratorWattageRating))
table.insert(out['电力'], power)
end
if bu.EnergyConsumptionWhenActive and bu.EnergyConsumptionWhenActive > 0 then
local power = fstr("消耗 %d 瓦", utils.float2str(bu.EnergyConsumptionWhenActive))
table.insert(out['电力'], power)
end
out['电力'] = #out["电力"] ~= 0 and table.concat(out["电力"], "<br/>") or nil
local heatGenerate = 0
heatGenerate = heatGenerate + ( bu.ExhaustKilowattsWhenActive or 0 )
heatGenerate = heatGenerate + ( bu.SelfHeatKilowattsWhenActive or 0 )
if math.abs(heatGenerate) > 0.5 then
out["产热"] = fstr("%d 千复制热/秒",
utils.float2str(heatGenerate, nil, true))
elseif heatGenerate ~= 0 then
out["产热"] = fstr("%d 复制热/秒",
utils.float2str(heatGenerate * 1000, nil, true))
end
if bu.battery ~= nil then
out['电力容量'] = fstr("%s 千焦", utils.float2str(bu.battery.capacity/1000))
out['电力泄露'] = fstr("%s 焦/[[周期]]", utils.float2str(bu.battery.joulesLostPerSecond*600))
end
if bu.tech ~= nil then
local tech = _r("STRINGS.RESEARCH.TECHS."..bu.tech:upper()..".NAME")
tech = cleanLoc(tech)
out["科技"] = fstr("[[技术/%s|%s]]", tech, tech)
end
if bu.category ~= nil then
out["类别"] = cleanLoc(_u(bu.category))
if bu.subCategory ~= nil then
out["类别"] = fstr("%s > %s", out["类别"], cleanLoc(_u(bu.subCategory)))
table.insert(pageCats, fstr("[[category:%s]]", cleanLoc(_u(bu.subCategory))))
end
end
if bu.roomRequireTags ~= nil then
--- 房间需求类型
out['类型'] = {}
for _, tag in ipairs(bu.roomRequireTags) do
local tagName = cleanLoc(po("STRINGS.ROOMS.CRITERIA."..tag:upper()..".NAME"))
table.insert(out['类型'],fstr(
"[[category:%s]]",
tagName
))
table.insert(pageCats, fstr("[[category:%s]]", tagName))
end
out['类型'] = #out["类型"] ~= 0 and table.concat(out["类型"], " ") or nil
end
if bu.effects ~= nil then
local function getAttributeDesc(attribute)
if attribute.formatter == nil then
return utils.float2str(attribute.Value)
end
local unitClass = attribute.formatter['unitClass']
local deltaTimeSlice = attribute.formatter['DeltaTimeSlice']
local plusChar = attribute['IsMultiplier'] == true and "x" or true
local timeSlice = deltaTimeSlice == "PerCycle" and 600 or 1
if unitClass == "Percent" then
return fstr("%s%%", utils.float2str(attribute.Value * timeSlice * 100, nil, plusChar))
elseif unitClass == "SimpleFloat" then
return utils.float2str(attribute.Value * timeSlice, 2, plusChar)
elseif unitClass == "SimpleInteger" then
return utils.float2str(attribute.Value * timeSlice, nil, plusChar)
else
return utils.float2str(attribute.Value * timeSlice, nil, plusChar)
end
end
out['使用效果'] = {}
for _, effect in ipairs(bu.effects) do
table.insert(out['使用效果'],fstr(
"%s(%s周期):",
po("STRINGS.DUPLICANTS.MODIFIERS."..effect.Id:upper()..".NAME"),
utils.float2str(effect.duration/600)
))
if effect.SelfModifiers ~= nil then
for _, attribute in ipairs(effect.SelfModifiers) do
table.insert(out['使用效果'],fstr(
"* %s: %s",
po("STRINGS.DUPLICANTS.ATTRIBUTES."..attribute.AttributeId:upper()..".NAME"),
getAttributeDesc(attribute)
))
end
end
end
out['使用效果'] = #out["使用效果"] ~= 0 and table.concat(out["使用效果"], "\n") or nil
end
if bu.roomTracker ~= nil and bu.roomTracker.requiredRoomName ~= nil then
out['房间类型'] = fstr("[[%s]]",cleanLoc(po(bu.roomTracker.requiredRoomName)))
end
-- out['操作'] = bu.AlwaysOperational == true and "复制人操作" or "无人值守"
if bu.requiredGrantSkill == true then
local skill = po(bu.requiredGrantSkill)
local skillredir = {
["高级研究"] = "高级研究(技能)",
["应用科学研究"] = "应用科学研究(技能)"
}
if skillredir[skill] ~= nil then
out['操作'] = fstr("%s(技能:[[%s|%s]])", out['操作'], cleanLoc(skillredir[skill]), cleanLoc(skill))
else
out['操作'] = fstr("%s(技能:[[%s]])", out['操作'], cleanLoc(skill))
end
end
out["建筑材料"] = {}
for _, ingredient in ipairs(bu.ingredients) do
local material = ingredient.name
if material == "BuildingFiber" then
table.insert(out["建筑材料"], fstr("%s %s 单位", getItemLink(material), tostring(ingredient.amount)))
else
table.insert(out["建筑材料"], fstr("%s %s", getItemLink(material), utils.kg2str(ingredient.amount)))
end
end
out["建筑材料"] = #out["建筑材料"] > 0 and table.concat(out["建筑材料"], "<br />") or nil
if bu.Overheatable == true then
out["过热"] = utils.float2str(bu.OverheatTemperature + k0) .. "°C"
if out['过热'] ~= nil then
local perMat = {}
local elemRead = {}
-- 读取元素数据
if elemData == nil then
elemData = mw.loadData([[Module:Data/Elements]])
end
-- 添加元素过热加成
local function addEle(elem)
local eId = elem.elementId
if elemRead[eId] == nil then
local mod = mModifier[eId] and mModifier[eId].overheatMod ~= nil and mModifier[eId].overheatMod or 0
table.insert(perMat, {
elem.localizationID,
elem.buildMenuSort,
utils.float2str(bu.OverheatTemperature + mod + k0),
mod
})
elemRead[eId] = true
end
end
local tagPrefix = "STRINGS.ELEMENTS."
for i, ingredient in ipairs(bu.ingredients) do
local m = ingredient.name
local name, isCate , msgctxt, cate = utils.getEntry(m)
if isCate or msgctxt:sub(1, #tagPrefix) ~= tagPrefix then
-- 获取标签下所有的元素
for _, elem in pairs(elemData) do
if elem.state == "Solid" and elem.isDisabled ~= true then
if elem.materialCategory ~= nil and elem.materialCategory:upper() == m:upper() then
addEle(elem)
elseif elem.tags ~= nil then
for _, t in ipairs(elem.tags) do
if t:upper() == m:upper() then
addEle(elem)
end
end
end
end
end
else
-- 元素
if mModifier[m] and mModifier[m].overheatMod then
local elem = elemData[m]
if elem ~= nil then
addEle(elem)
end
end
end
end
-- 组装过热加成
if #perMat > 0 then
table.sort(perMat, function(a, b) return a[2] < b[2] end) -- 排序
out['各材料过热'] = {}
for _, mat in ipairs(perMat) do
local info = fstr(
"{{物品|%s}}<div></div><div>:</div><div style='text-align: right'>%s°C</div><div style='text-align: right'>(%+d°C)</div>",
_e(mat[1]), mat[3], mat[4])
table.insert(out['各材料过热'], info)
end
out['各材料过热'] = #out["各材料过热"] ~= 0 and table.concat(out["各材料过热"], "\n") or nil
end
end
else
out["过热"] = "✖"
end
if bu.BaseDecor and bu.BaseDecor ~= 0 and bu.BaseDecorRadius then
out["装饰"] = fstr("%s(范围:%s 格)", tostring(bu.BaseDecor), tostring(bu.BaseDecorRadius))
if out['装饰'] ~= nil then
local perMat = {}
local elemRead = {}
-- 读取元素数据
if elemData == nil then
elemData = mw.loadData([[Module:Data/Elements]])
end
-- 添加元素装饰加成
local function addEle(elem)
local eId = elem.elementId
if elemRead[eId] == nil then
local mod = mModifier[eId] and mModifier[eId].decor ~= nil and mModifier[eId].decor or 0
table.insert(perMat, {
elem.localizationID,
elem.buildMenuSort,
utils.float2str(bu.BaseDecor + math.abs(bu.BaseDecor) * mod, nil, true),
mod * 100
})
elemRead[eId] = true
end
end
local tagPrefix = "STRINGS.ELEMENTS."
for i, ingredient in ipairs(bu.ingredients) do
local m = ingredient.name
local name, isCate , msgctxt, cate = utils.getEntry(m)
if isCate or msgctxt:sub(1, #tagPrefix) ~= tagPrefix then
-- 获取标签下所有的元素
for _, elem in pairs(elemData) do
if elem.state == "Solid" and elem.isDisabled ~= true then
if elem.materialCategory ~= nil and elem.materialCategory:upper() == m:upper() then
addEle(elem)
elseif elem.tags ~= nil then
for _, t in ipairs(elem.tags) do
if t:upper() == m:upper() then
addEle(elem)
end
end
end
end
end
else
-- 元素
if mModifier[m] and mModifier[m].decor then
local elem = elemData[m]
if elem ~= nil then
addEle(elem)
end
end
end
end
-- 组装装饰加成
if #perMat > 0 then
table.sort(perMat, function(a, b) return a[2] < b[2] end) -- 排序
out['各材料装饰'] = {}
for _, mat in ipairs(perMat) do
local info = fstr(
"{{物品|%s}}<div></div><div>:</div><div style='text-align: right'>%s</div><div style='text-align: right'>(%+d%%)</div>",
_e(mat[1]), mat[3], mat[4])
table.insert(out['各材料装饰'], info)
end
out['各材料装饰'] = #out["各材料装饰"] ~= 0 and table.concat(out["各材料装饰"], "\n") or nil
end
end
end
if bu.storage ~= nil then
if bu.storage.showInUI == true then
out['机械臂运送'] = bu.storage.useGunForDelivery == true and "✔" or "✖"
if bu.storage.storageFilters ~= nil and #bu.storage.storageFilters > 0 then
out['允许清空库存'] = bu.storage.allowItemRemoval == true and "✔" or "✖"
out['库存容量'] = utils.kg2str(bu.storage.capacityKg)
out['库存'] = {}
for _, tag in ipairs(bu.storage.storageFilters) do
local name = utils.getEntry(tag)
if name ~= nil then
table.insert(out['库存'], fstr("{{物品|%s}}}", name))
end
end
end
else
out['机械臂运送'] = bu.storage.useGunForDelivery == true and "✔" or nil
end
end
if bu.LogicInputPorts ~= nil then
out['自动化输入'] = {}
for _, logicPort in ipairs(bu.LogicInputPorts) do
table.insert(out['自动化输入'], fstr(logicMsg(logicPort.description)))
table.insert(out['自动化输入'], fstr(
"[[File:自动化输入绿色.png|16px|link=|alt=自动化输入绿色信号]] %s",
logicMsg(logicPort.activeDescription)
))
table.insert(out['自动化输入'], fstr(
"[[File:自动化输入红色.png|16px|link=|alt=自动化输入红色信号]] %s",
logicMsg(logicPort.inactiveDescription)
))
end
out["自动化输入"] = #out["自动化输入"] > 0 and table.concat(out["自动化输入"], "<br/>") or nil
end
if bu.LogicOutputPorts ~= nil then
out['自动化输出'] = {}
for _, logicPort in ipairs(bu.LogicOutputPorts) do
table.insert(out['自动化输出'], fstr(logicMsg(logicPort.description)))
table.insert(out['自动化输出'], fstr(
"[[File:自动化输出绿色.png|16px|link=|alt=自动化输出绿色信号]] %s",
logicMsg(logicPort.activeDescription)
))
table.insert(out['自动化输出'], fstr(
"[[File:自动化输出红色.png|16px|link=|alt=自动化输出红色信号]] %s",
logicMsg(logicPort.inactiveDescription)
))
end
out["自动化输出"] = #out["自动化输出"] > 0 and table.concat(out["自动化输出"], "<br />") or nil
end
-- 眼冒金星火箭舱块
if bu.rocketModule ~= nil then
out["舱块负担"] = bu.rocketModule.burden
out["引擎功率"] = bu.rocketModule.enginePower > 0 and bu.rocketModule.enginePower or nil
if bu.rocketEngineCluster ~= nil then
out["最大高度"] = bu.rocketEngineCluster.maxHeight
if bu.rocketEngineCluster.requireOxidizer ~= nil then
out["需要氧化剂"] = bu.rocketEngineCluster.requireOxidizer and "是" or "否"
end
-- 燃料
if bu.rocketEngineCluster.fuelTag ~= nil then
local fuelTag = fstr("{{物品|%s}}", utils.getEntry(bu.rocketEngineCluster.fuelTag))
-- global::CraftModuleInterface.FuelPerHex.get()
if fuelTag == "HighEnergyParticle" then
out["燃料"] = fstr("%s:%s单位/格", fuelTag, utils.float2str(bu.rocketModule.fuelKilogramPerDistance * 600))
else
out["燃料"] = fstr("%s:%s/格", fuelTag, utils.kg2str(bu.rocketModule.fuelKilogramPerDistance * 600))
end
end
-- 废气
if bu.rocketEngineCluster.exhaustElement ~= nil then
out["废气"] = fstr(
"%s:%s/秒\n(最高 %s°C)",
fstr("{{物品|%s}}", utils.getEntry(bu.rocketEngineCluster.exhaustElement)),
utils.kg2str(bu.rocketEngineCluster.exhaustEmitRate),
utils.float2str(bu.rocketEngineCluster.exhaustTemperature + k0)
)
end
end
elseif bu.rocketEngine ~= nil then
if bu.rocketEngine.requireOxidizer ~= nil then
out["需要氧化剂"] = bu.rocketEngine.requireOxidizer and "是" or "否"
end
-- 燃料
if bu.rocketEngine.fuelTag ~= nil then
out["燃料"] = fstr("{{物品|%s}}", utils.getEntry(bu.rocketEngine.fuelTag))
end
-- 废气
if bu.rocketEngine.exhaustElement ~= nil then
out["废气"] = fstr(
"%s:%s/秒\n(最高 %s°C)",
fstr("{{物品|%s}}", utils.getEntry(bu.rocketEngine.exhaustElement)),
utils.kg2str(bu.rocketEngine.exhaustEmitRate),
utils.float2str(bu.rocketEngine.exhaustTemperature + k0)
)
end
end
-- 配方
if bu.recipes then
out["配方"] = rcputils(bu.recipes)
end
-- 添加页面分类
if bu.category ~= nil then
if utils.startswith(bu.category, "STRINGS.UI.BUILDCATEGORIES.") then
table.insert(pageCats, fstr("[[category:%s建筑]]", cleanLoc(_u(bu.category))))
elseif utils.startswith(bu.category, "STRINGS.UI.") then
table.insert(pageCats, fstr("[[category:%s]]", cleanLoc(_u(bu.category))))
else
table.insert(pageCats, fstr("[[category:%s]]", cleanLoc(_m(bu.category))))
end
end
if (args.namespace or args.nocat) then pageCats = {} end
if (args.debug) then mw.logObject(out) end
return out, pageCats
end
-- test by: = p.main(require("Module:debug").frame({},{debug=1, "AirConditioner"}))
-- test by: = p.main(require("Module:debug").frame({},{debug=1, "Tile"}))
-- 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, 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, 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({},{
pagename='虚拟天象仪'
}))
]]
-- test by: = p.main(require("Module:debug").frame({},{debug=1, pagename="辐射粒子引擎"}))
-- test by: = p.main(require("Module:debug").frame({},{debug=1, "KeroseneEngineCluster" ,pagename="辐射粒子引擎"}))
-- test by: = p.main(require("Module:debug").frame({},{debug=1, "SteamEngineCluster"}))
-- test by: = p.main(require("Module:debug").frame({},{debug=1, multipage="PropSurfaceSatellite1,PropSurfaceSatellite2,PropSurfaceSatellite3"}))
--[[ test by:
= p.main(require("Module:debug").frame({},{
main,
debug=1,
multipage=,
}))
]]
function p.main(frame)
local args = getArgs(frame)
local builds = {}
if args.debug then mw.logObject(args, "args") end
if args[1] ~= nil or args.multipage ~= nil then
local pagename_array = {}
pagename_array = args[1] ~= nil and {args[1]} or nil
if pagename_array == nil then
pagename_array = args.multipage ~= nil and mw.text.split(args.multipage, ",") or {}
end
for _, buId in ipairs(pagename_array) do
local _, _, buCode = utils.getEntry(buId)
if buCode ~= nil then
-- 使用id
table.insert(builds, {
id = buId,
code = buCode
})
else
-- 使用pagename
buCode = getBuCode(buId)
local mId = buCode:match("([%u%d]+).NAME$")
table.insert(builds, {
id = mId,
code = buCode
})
end
end
else
local buCode = getBuCode(args.pagename)
local buId = buCode:match("([%u%d]+).NAME$")
table.insert(builds, {
id = buId,
code = buCode
})
end
-- 组装信息
local pageCats = {}
local infos = {}
for _, building in ipairs(builds) do
for k, v in pairs(buData) do
if k:upper() == building.id:upper() then
local curr, cats = p._main(v, building.code, args)
table.insert(infos, {
label = curr['名称'],
data = curr
})
if cats ~= nil then
for _, c in ipairs(cats) do
if c ~= nil then
table.insert(pageCats, c)
end
end
end
end
end
end
if args.debug then mw.logObject(infos, "infos") end
if args.debug then mw.logObject(pageCats, "pageCats") end
local infoboxTitle = #infos == 1 and infos[1].label or args.pagename
return infobox.main(infoboxTitle, infos) .. table.concat(pageCats, "")
end
return p