-- Module:建筑信息框
local p = {}
local utils = require([[Module:Utils]])
local po = require([[Module:Po]]).po
local getArgs = require('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 elData = require([[Module:Data/Elements]])
local mModifier = require([[Module:Data/MaterialModifier]])
local k0 = -273.15
local epsilon = 1e-7
local function addIdx(dt)
local locIdx = {}
for k, v in pairs(dt) do locIdx[v.localizationID] = k end
dt.getByLoc = function(self, loc) return self[locIdx[loc]] end
return dt
end
local dataEl = addIdx(elData)
local function nameCode(id)
return fstr("STRINGS.BUILDINGS.PREFABS.%s.NAME", string.upper(id))
end
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 requireClassCode(id)
return fstr("STRINGS.CODEX.ROOM_REQUIREMENT_CLASS.%s.TITLE", string.upper(id))
end
local function tagCode(t) return "STRINGS.MISC.TAGS." .. string.upper(t) end
local function isDefaultT(s, t) return ("<" .. s .. ">") == t end
-- return {name, isElement}
local function getItem(item)
local ret
if elData[item] ~= nil then
ret = _e(elData[item].localizationID)
if not isDefaultT(elData[item].localizationID, ret) then
return {ret, true}
end
end
if item:upper() == "WOODLOG" then
return {_i("STRINGS.ITEMS.INDUSTRIAL_PRODUCTS.WOOD.NAME"), true}
end
ret = _m(tagCode(item))
if not isDefaultT(tagCode(item), ret) then return {ret, false} end
end
local function getItemLink(item, sep)
if type(item) == 'table' then
local links = {}
for _, i in ipairs(item) do
local l = getItemLink(i)
table.insert(links, l)
end
return table.concat(links, sep or "/")
end
local shortcut = {
["BuildingFiber"] = "BasicFabric" -- 纤维 => 芦苇纤维
}
item = shortcut[item] or item
local locStr, isCat = utils.getEntry(item)
if isCat then
return fstr("[[:category:%s|%s]]", locStr, locStr), isCat
else
return fstr("[[%s]]", locStr), isCat
end
end
-- get data for the requested building
local function getBu(args)
local function getBuByCtxt(name)
for k, v in pairs(buData) do
if string.upper(k) == name then return v end
end
return nil
end
local id = args[1]
local bu
if id ~= nil then
bu = buData[id]
if bu == nil then error(fstr("找不到指定的建筑物")) end
else
local pattern = "STRINGS%.BUILDINGS%.PREFABS%.[^%.]+%.NAME"
local msgctxt = i18ndb:msgRev(args.pagename or "", {pattern = pattern})
if msgctxt == nil then
error(fstr(
"找不到建筑物 '%s',请使用参数1或检查 [[%s]]。",
args.pagename, [[Module:Data/Buildings]]))
end
local name = string.sub(msgctxt, 27, -6)
bu = getBuByCtxt(name)
if bu == nil then
error(fstr(
"'%s' 的建筑物信息未收录,请联系管理员。",
name, [[Module:Data/Buildings]]))
end
end
return bu
end
-- get amount text
local function formatAmount(amount, mat)
local specialUnit = utils.specialUnit[mat]
if specialUnit == nil then return utils.kg2str(amount) end
return specialUnit(amount)
end
-- test by: = p.getInfo({"AirConditioner"})
-- test by: = p.getInfo({"SteamTurbine2", debug=1})
function p.getInfo(args)
local bu = getBu(args)
if type(bu) == "string" then return {["名称"] = bu} end
local out = {}
local id = bu.id
if id == nil then error("建筑信息不完整,请联系管理员") end
local pageCats = {}
out["名称"] = _b(nameCode(id))
out["名称"] = not isDefaultT(nameCode(id), out["名称"]) and
out["名称"] or args.pagename
out["图片"] = out["名称"] .. ".png"
if not bu.gameBase and bu.gameSO then
local soFile = out["名称"] .. "(眼冒金星).png"
local title = mw.title.new("File:" .. soFile)
if title ~= nil and title.exists then out["图片"] = soFile end
end
out["图片"] = args.pagename and (args.pagename .. ".png") or out["图片"]
out["图片说明"] = _b(descCode(id))
out["图片说明"] = not isDefaultT(descCode(id), out["图片说明"]) and
out["图片说明"] or nil
out["描述"] = _b(effectCode(id))
out["描述"] = not isDefaultT(effectCode(id), out["描述"]) and
out["描述"] or nil
out["类别"] = (bu.category == nil or bu.category == "Special") and
"特殊建筑" or _u(bu.category)
if utils.startswith(bu.category, "STRINGS.UI.BUILDCATEGORIES.") then
table.insert(pageCats, fstr("[[category:%s建筑]]", out["类别"]))
else
table.insert(pageCats, fstr("[[category:%s]]", out["类别"]))
end
if bu.research and #(bu.research) ~= 0 then
local researchName = _r(bu.research)
out["科技"] = fstr("[[技术/%s|%s]]", researchName, researchName)
end
out["过热"] = bu.overheat ~= nil and (tonumber(bu.overheat) + k0) or nil
if out["过热"] then -- 各材料过热
local perMat = {}
local matSet = {}
local minorMaterialMod = 0
-- add Element that belongs to a certain category
local function addEle(e)
if matSet[e] == nil then
local temMod = mModifier[e] and mModifier[e].overheatMod ~= nil
and mModifier[e].overheatMod or 0
table.insert(perMat, {
e, out["过热"] + temMod, dataEl[e].buildMenuSort, temMod
})
matSet[e] = true
end
end
for i = 1, 10 do
if bu.materials[i] ~= nil then
local m = bu.materials[i]
local _, _, locId = utils.getEntry(m)
local isEle = mw.text.split(locId, '.', true)[2] == "ELEMENTS"
if not isEle then
for _, e in pairs(mw.loadData([[Module:Data/Elements]])) do
if e.state == "Solid" and e.isDisabled ~= true then
if e.materialCategory ~= nil and
e.materialCategory:upper() == m:upper() then
addEle(e.elementId)
elseif e.tags ~= nil then
for _, t in ipairs(e.tags) do
if t:upper() == m:upper() then
addEle(e.elementId)
end
end
end
end
end
else
if mModifier[m] and mModifier[m].overheatMod then
minorMaterialMod = minorMaterialMod + mModifier[m].overheatMod
end
end
else break end
end
if #perMat > 0 then
table.sort(perMat, function(a, b)
return a[3] < b[3]
end)
for i = 1, #perMat do
perMat[i][2] = perMat[i][2] + minorMaterialMod
perMat[i][4] = perMat[i][4] + minorMaterialMod
end
local function reprOverheat(me)
local name = _e(utils.getCode('element', me[1]))
local exp = mw.getCurrentFrame():expandTemplate{
title = "物品",
args = {name, notext = "1"}
}
return fstr(
"%s[[%s]]<div>:</div><div style='text-align: right'>%d°C</div><div style='text-align: right'>(%+d°C)</div>",
exp, name, me[2], me[4])
end
out["各材料过热"] =
table.concat(utils.map(perMat, reprOverheat), "\n")
end
end
out["淹没"] = bu.floodable and "淹没时无法运作" or
"淹没时可正常工作"
out["掩埋"] = bu.entombable and "掩埋时无法运作" or
"掩埋时可正常工作"
out["尺寸"] = fstr("宽 %s 高 %s", bu.width, bu.height)
out["旋转"] = bu.rotation and
({[1] = "镜像翻转", [2] = "可以旋转"})[bu.rotation] or
"不可旋转"
local buPower = tonumber(bu.power)
out["电力"] = (buPower and math.abs(buPower) > epsilon) and
fstr("%s %d 瓦",
(buPower > 0 and "发电" or "消耗"),
math.abs(buPower)) or nil
out["基础建造时间"] = (bu.constructionTime and bu.category ~= "Special") and
fstr("%d 秒", bu.constructionTime) or nil
out["工业建筑"] = bu.isIndustrialMachinery and "是" or "否"
--- 房间需求类型
local requirementClass = bu.requirementClass or nil
if requirementClass ~= nil then
out["类型"] = ""
for i,_ in ipairs(requirementClass) do
out["类型"] = out["类型"] .. fstr(_c(requireClassCode(requirementClass[i]))) .. "<br/>"
end
end
if bu.baseDecor and bu.baseDecor ~= 0 and bu.baseDecorRadius then
out["装饰"] = fstr("%+d(%d 格范围)", bu.baseDecor,
bu.baseDecorRadius)
end
if out["装饰"] then -- 各材料装饰
local perMat = {}
local matSet = {}
local minorMaterialMod = 0
local function addEle(e)
if matSet[e] == nil then
local temMod = mModifier[e] and mModifier[e].decor ~= nil
and mModifier[e].decor or 0
table.insert(perMat, {
e, bu.baseDecor, dataEl[e].buildMenuSort, temMod
})
matSet[e] = true
end
end
for i = 1, 10 do
if bu.materials[i] ~= nil then
local m = bu.materials[i]
local _, _, locId = utils.getEntry(m)
local isEle = mw.text.split(locId, '.', true)[2] == "ELEMENTS"
if not isEle then
for _, e in pairs(mw.loadData([[Module:Data/Elements]])) do
if e.state == "Solid" and e.isDisabled ~= true then
if e.materialCategory ~= nil and
e.materialCategory:upper() == m:upper() then
addEle(e.elementId)
elseif e.tags ~= nil then
for _, t in ipairs(e.tags) do
if t:upper() == m:upper() then
addEle(e.elementId)
end
end
end
end
end
else
if mModifier[m] and mModifier[m].decor then
minorMaterialMod = minorMaterialMod + mModifier[m].decor
end
end
else break end
end
if #perMat > 0 then
table.sort(perMat, function(a, b)
return a[3] < b[3]
end)
for i = 1, #perMat do
perMat[i][4] = perMat[i][4] + minorMaterialMod
perMat[i][2] = bu.baseDecor + math.abs(bu.baseDecor) * perMat[i][4]
end
local function reprOverheat(me)
local name = _e(utils.getCode('element', me[1]))
local exp = mw.getCurrentFrame():expandTemplate{
title = "物品",
args = {name, notext = "1"}
}
return fstr(
"%s[[%s]]<div>:</div><div style='text-align: right'>%s</div><div style='text-align: right'>(%+d%%)</div>",
exp, name, utils.float2str(me[2], nil, true),
me[4] * 100)
end
out["各材料装饰"] =
table.concat(utils.map(perMat, reprOverheat), "\n")
end
end
if bu.heatGenerate and bu.heatGenerate ~= 0 then
if bu.heatGenerate % 1000 < epsilon then
out["产热"] = fstr(
"%+d [[计量单位#热量(Q)|千复制热]]/秒",
bu.heatGenerate / 1000)
else
out["产热"] = fstr("%+d [[计量单位#热量(Q)|复制热]]/秒",
bu.heatGenerate)
end
end
out["建筑材料"] = {}
for i, _ in ipairs(bu.materials) do
local massRepr = nil
if bu.materials[i] == "BuildingFiber" then
massRepr = bu.materialsMass[i]
else
massRepr = utils.kg2str(bu.materialsMass[i])
end
table.insert(out["建筑材料"],
fstr("%s %s", getItemLink(bu.materials[i]), massRepr))
end
out["建筑材料"] = out["建筑材料"] and
table.concat(out["建筑材料"], "<br />") or nil
out["库存"] = ""
for _, item in ipairs(bu.storage) do
if type(item) == "table" then -- item[1], item[2]
out["库存"] = out["库存"] ..
fstr("%s:%s", getItemLink(item[1]),
formatAmount(item[2], item[1]))
if item[3] ~= nil then
out["库存"] = out["库存"] .. fstr("(%s)", item[3])
end
out["库存"] = out["库存"] .. "<br/>"
elseif type(item) == "string" then
out["库存"] = out["库存"] .. item .. "<br/>"
end
end
out["库存"] = out["库存"] ~= "" and out["库存"] or nil
-- 物质消耗、生产,复制人操作等
local function getInOut(isIn)
local catPrefix = isIn and "消耗" or "生产"
local dataFiled = isIn and "requires" or "effects"
local result = {}
local skillredir = {
["高级研究"] = "高级研究(技能)",
["应用科学研究"] = "应用科学研究(技能)"
}
if isIn and bu.operation then
local opStr = "复制人操作"
if type(bu.operation) == "string" or type(bu.operation) == "table" then
local skills = bu.operation
if type(skills) == "string" then
skills = {skills}
end
local skillNames = {}
for _, s in ipairs(skills) do
if skillredir[po(s)] ~= nil then
table.insert(skillNames,
fstr("[[%s|%s]]", skillredir[po(s)], po(s)))
else
table.insert(skillNames,
fstr("[[%s]]", po(s)))
end
end
opStr = fstr("%s(技能:%s)", opStr,
table.concat(skillNames, ","))
end
table.insert(result, opStr)
end
for _, item in ipairs(bu[dataFiled]) do
if type(item) == "table" then
local mat, amount, notes = item[1], item[2], item[3]
local curr = nil
local locStr, isCate = utils.getEntry(mat)
local link = getItemLink(mat)
if amount ~= nil then
local format = bu.perUse and
("%s:每次" .. catPrefix .. " %s") or
"%s:%s/秒"
curr = fstr(format, link, formatAmount(amount, mat))
table.insert(pageCats,
fstr("[[category:%s%s]]", catPrefix, locStr))
else
curr = link
end
if notes ~= nil then
curr = fstr("%s(%s)", curr, notes)
end
table.insert(result, curr)
elseif type(item) == "string" then
table.insert(result, item)
end
end
return #result > 0 and table.concat(result, "<br/>") or nil
end
out["要求"] = getInOut(true)
out["效果"] = getInOut(false)
if bu.isIndustrialMachinery then
out["工业机械"] = "是"
table.insert(pageCats, "[[category:工业机械]]")
else
out["工业机械"] = "否"
end
-- 自动化
local defaultIn = {
"STRINGS.UI.LOGIC_PORTS.CONTROL_OPERATIONAL",
"STRINGS.UI.LOGIC_PORTS.CONTROL_OPERATIONAL_ACTIVE",
"STRINGS.UI.LOGIC_PORTS.CONTROL_OPERATIONAL_INACTIVE"
}
local defaultInDoor = {
"STRINGS.BUILDINGS.PREFABS.DOOR.LOGIC_OPEN",
"STRINGS.BUILDINGS.PREFABS.DOOR.LOGIC_OPEN_ACTIVE",
"STRINGS.BUILDINGS.PREFABS.DOOR.LOGIC_OPEN_INACTIVE"
}
local defaultInGate = {--门电路输入端
"STRINGS.UI.LOGIC_PORTS.GATE_SINGLE_INPUT_ONE_NAME",
"STRINGS.UI.LOGIC_PORTS.GATE_SINGLE_INPUT_ONE_ACTIVE",
"STRINGS.UI.LOGIC_PORTS.GATE_SINGLE_INPUT_ONE_INACTIVE"
}
local logicType = {"logicIn", "logicOut", "logicReset"}
local logicField = {"自动化输入", "自动化输出", "自动化复位"}
out["工业建筑"] = bu.isIndustrialMachinery and "是" or "否"
local function logicMsg(s)
local ret = _u(s)
if isDefaultT(s, ret) then ret = _b(s) end
return ret
end
-- 在游戏代码 BuildingLoader 中的逻辑(默认为一般耗电建筑添加自动化启禁用输入端口):
-- if (def.RequiresPowerInput && def.AddLogicPowerPort) GeneratedBuildings.RegisterSingleLogicInputPort(go);
local likelyRequiresPowerInput = buPower and -buPower > epsilon -- 猜测 BuildingDef.RequiresPowerInput;负数表示电量消耗
local alpp = bu.addLogicPowerPort == nil and true or bu.addLogicPowerPort
local registerSingleLogicInputPort = false
if likelyRequiresPowerInput and alpp then
registerSingleLogicInputPort = true
end
for i = 1, 3 do
local lt = logicType[i]
local lf = logicField[i]
local ld = bu[lt] -- logic data
if lt == "logicIn" and registerSingleLogicInputPort then
if ld == nil or ld == false then ld = true end
end
if ld then
if ld == true then
if i ~= 1 then
return {
["名称"] = "自动化数据错误,请联系管理员。"
}
end
ld = defaultIn
end
if ld == "door" then
if i ~= 1 then
return {
["名称"] = "自动化数据错误,请联系管理员。"
}
end
ld = defaultInDoor
end
if ld == "gate" then
if i ~= 1 then
return {
["名称"] = "自动化数据错误,请联系管理员。"
}
end
ld = defaultInGate
end
local ldIter = ld
if not ld.multiple then ldIter = {ld} end
out[lf] = {}
for _, logicPort in ipairs(ldIter) do
local tmpStr = ""
tmpStr = tmpStr .. fstr("%s", logicMsg(logicPort[1]))
tmpStr = tmpStr .. "<br/>" ..
fstr(
"[[File:%s绿色.png|16px|link=|alt=%s绿色信号]] %s",
lf, lf, logicMsg(logicPort[2]))
tmpStr = tmpStr .. "<br/>" ..
fstr(
"[[File:%s红色.png|16px|link=|alt=%s红色信号]] %s",
lf, lf, logicMsg(logicPort[3]))
table.insert(out[lf], tmpStr)
end
out[lf] = table.concat(out[lf], "<br/><br/>")
end
end
-- old code below
-- -- 水管, 通风, 运输
-- for _, logi in ipairs({"水管", "通风", "运输"}) do
-- if df[logi] then
-- out[logi] = ""
-- for _, direction in ipairs({"入", "出", "过滤"}) do
-- local toImg = {
-- ["入"] = "输入图标",
-- ["出"] = "输出图标",
-- ["过滤"] = "过滤图标"
-- }
-- if df[logi][direction] then
-- out[logi] = out[logi] .. fstr("[[File:%s.png|16px|link=]]", toImg[direction])
-- if type(df[logi][direction]) == "string" then
-- out[logi] = out[logi] .. fstr(" [[%s]]", df[logi][direction])
-- end
-- out[logi] = out[logi] .. " "
-- end
-- end
-- end
-- end
-- 眼冒金星火箭舱块
if bu.rocketModule ~= nil then
out["引擎功率"] = bu.rocketModule.enginePower
out["舱块负担"] = bu.rocketModule.burden
out["最大高度"] = bu.rocketModule.maxHeight
if bu.rocketModule.requireOxidizer ~= nil then
out["需要氧化剂"] =
bu.rocketModule.requireOxidizer and "是" or "否"
end
if bu.rocketModule.fuelTag ~= nil then
out["燃料"] = getItemLink(bu.rocketModule.fuelTag)
if bu.rocketModule.fuelKilogramPerDistance then
-- global::CraftModuleInterface.FuelPerHex.get()
local amount = bu.rocketModule.fuelKilogramPerDistance * 600
out["燃料"] = fstr("%s:%s/格", out["燃料"], formatAmount(
amount, bu.rocketModule.fuelTag))
end
end
if bu.rocketModule.exhaustElement ~= nil then
out["废气"] = getItemLink(bu.rocketModule.exhaustElement)
if bu.rocketModule.exhaustTemperature ~= nil then
local temp = bu.rocketModule.exhaustTemperature + k0
out["废气"] =
fstr("%s(最高 %s°C)", out["废气"], temp)
end
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({},{
debug=1,
base='CosmicResearchCenter',
so='DLC1CosmicResearchCenter',
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, multi=1, "PropSurfaceSatellite1", "PropSurfaceSatellite2", "PropSurfaceSatellite3"}))
--[[ test by:
= p.main(require("Module:debug").frame({},{
debug=1,
multi=1,
image1="A",
"PropSurfaceSatellite1",
image2="B",
"PropSurfaceSatellite2"
}))
]]
function p.main(frame)
local sections = {}
local args = getArgs(frame)
local pageCats = {}
local pageCatsSet = {}
if args.debug then mw.logObject(args, "args") end
if args.multi then
for idx, bid in ipairs(args) do
if args.debug then mw.logObject(bid, "bid") end
local info, cats = p.getInfo({bid})
if args[fstr('image%d', idx)] then
info['图片'] = fstr('%s.png', args[fstr('image%d', idx)])
end
table.insert(sections, {label = info['名称'], data = info})
for _, c in ipairs(cats) do
if pageCatsSet[c] == nil then
table.insert(pageCats, c)
pageCatsSet[c] = true
end
end
end
elseif args['base'] == nil or args['so'] == nil then
local info = nil
info, pageCats = p.getInfo(args)
table.insert(sections, {data = info})
else
local code2label = {base = '游戏本体', so = '眼冒金星!'}
for _, v in ipairs({'base', 'so'}) do
if args[v] ~= nil then
local info, cats = p.getInfo {
args[v],
namespace = args.namespace,
nocat = args.nocat
}
table.insert(sections, {
label = code2label[v], --
data = info
})
for _, c in ipairs(cats) do
if pageCatsSet[c] == nil then
table.insert(pageCats, c)
pageCatsSet[c] = true
end
end
end
end
end
if args.debug then mw.logObject(sections, "sections") end
local title = sections[1].data['名称']
if #sections > 1 then title = args.pagename end
return infobox.main(title, sections) .. table.concat(pageCats, "")
end
return p
Advertisement
Advertisement