模块:Ship Specs
来自星际公民宇宙百科
此模块的文档可以在模块:Ship Specs/doc创建
local p = {}
local itemNames = {
["name_format"] = "[[%s|%s]]",
["manufacturer"] = "制造商",
["focus"] = "定位",
["description"] = "描述",
["production_status"] = "生产状态",
["length"] = "长",
["beam"] = "宽",
["height"] = "高",
["mass"] = "空重",
["cargo_capacity"] = "载货量",
["max_crew"] = "船员上限",
["max_power_plant_size"] = "能源装置尺寸上限",
["max_shield_size"] = "护盾尺寸上限",
["max_primary_thruster"] = "主推进器上限",
["max_maneuvering_thruster"] = "机动推进器上限",
["max_retro_thruster"] = "制动推进器上限",
["type"] = "类型",
["size_count"] = "尺寸/数量",
["length_unit_format"] = "%d M",
["mass_unit_format"] = "%d KG",
["cargo_unit_format"] = "%d SCU",
["crew_unit_format"] = "%d 人",
["size_unit_format"] = "S%d",
["factory_propulsion"] = "原厂推进设备",
["propulsion_specs_format"] = "S%d x%d",
["propulsion_factory_format"] = "%s(S%d) x%d",
["propulsion:Primary"] = "主推进器",
["propulsion:Maneuvering"] = "机动推进器",
["propulsion:Retro"] = "制动推进器",
["factory_ordnance"] = "原厂武器设备",
["ordnance_class_format"] = "%s类武器",
["ordnance_specs_format"] = "S%d x%d",
["ordnance_factory_format"] = "%s(S%d) x%d",
["factory_modular"] = "原厂模块设备",
["modular_specs_format"] = "S%d x%d",
["modular_factory_format"] = "%s(S%d) x%d",
["modular:Shield"] = "护盾",
["modular:Power Plant"] = "能源装置",
["modular:Additional"] = "附加装备",
["factory_avionics"] = "原厂航电设备",
["avionics_specs_format"] = "S%d x%d",
["avionics_factory_format"] = "%s(S%d) x%d",
["official_page_format"] = "[%s %s - 官方页面]",
}
local optionsToken = "8wBrvOMe1bWj"
local function isEnabled( options , name )
if (options ~= nil) and (name ~= nil) then
local value = options[name]
return value == true or value == "true" or value == 1
end
end
local function pairsByKeys( t, f )
local a = {}
for n in pairs(t) do table.insert(a, n) end
table.sort(a, f)
local i = 0 -- iterator variable
local iter = function() -- iterator function
i = i + 1
if a[i] == nil then return nil
else return a[i], t[a[i]]
end
end
return iter
end
local function getPropulsionOrder( type )
if type == "Primary" then
return 1
elseif type == "Maneuvering" then
return 2
elseif type == "Retro" then
return 3
else
return math.huge
end
end
local function propulsionOrderByType( p1, p2 )
return getPropulsionOrder(p1) < getPropulsionOrder(p2)
end
local function createInternalLink( text )
return "[[" .. text .. "]]"
end
local function defualtWhenNil( value, defaultValue )
if value then
return value
else
return defaultValue
end
end
local function anyInTable( table )
if table then
for k,v in pairs(table) do
return true
end
else
return false
end
end
local function countInTable( table, key, num)
if table[key] then
table[key] = table[key] + num
else
table[key] = num
end
end
local function ensureSubTable( table, key )
local subTable
if table[key] then
subTable = table[key]
else
subTable = {}
table[key] = subTable
end
return subTable
end
local function shipTableRows( shipSpecsList , options)
local rows = {}
for shipIndex, shipSpecs in ipairs(shipSpecsList) do
--mw.log(string.format("shipIndex:%d", shipIndex))
for shipSpecs_key, shipSpecs_value in pairs(shipSpecs) do
--mw.log(string.format("shipSpecs_key:%s", shipSpecs_key))
local row = ensureSubTable(rows, shipSpecs_key)
if (shipSpecs_key == "propulsion") or (shipSpecs_key == "ordnance") or (shipSpecs_key == "modular") or (shipSpecs_key == "avionics") then
for ss_p_item_name, ss_p_item in pairs(shipSpecs_value) do
if ss_p_item then
local ss_p_item_type
if shipSpecs_key == "ordnance" then
ss_p_item_type = ss_p_item["class"]
else
ss_p_item_type = ss_p_item["type"]
end
local ss_p_item_max_size = tonumber(ss_p_item["max_size"])
local ss_p_item_count = tonumber(ss_p_item["count"])
if not ss_p_item_count then
ss_p_item_count = 1
end
if ss_p_item_type and ss_p_item_max_size and (ss_p_item_max_size > 0) and (ss_p_item_count > 0) then
local row_p = ensureSubTable(row, ss_p_item_type)
local row_p_ship = ensureSubTable(row_p, shipIndex)
local row_p_ship_specs = ensureSubTable(row_p_ship, "specs")
local row_p_ship_factory = ensureSubTable(row_p_ship, "factory")
countInTable(row_p_ship_specs, ss_p_item_max_size, ss_p_item_count)
local ss_p_item_components = ss_p_item["components"]
if ss_p_item_components then
for ss_p_item_component_index, ss_p_item_component in ipairs(ss_p_item_components) do
table.insert(row_p_ship_factory, { ["name"] = ss_p_item_component.name, ["size"] = ss_p_item_component.size, ["count"] = ss_p_item_component.count})
end
end
end
end
end
else
row[shipIndex] = shipSpecs_value
end
end
end
return rows
end
local function createShipTable(shipTableRows, shipCount, options)
local table_col_num = (2 * shipCount) + 1
local h_table = mw.html.create("table"):addClass("ship-specs-table")
local nameRow = shipTableRows["name"]
local nameEnRow = shipTableRows["name_en"]
if nameRow then
local h_tr = h_table:tag("tr"):addClass("sps-name")
if shipCount > 1 then
h_tr:tag("td")
end
for i=1, shipCount do
local h_td
if shipCount > 1 then
h_td = h_tr:tag("td"):attr({ colspan="2" })
else
h_td = h_tr:tag("td"):attr({ colspan="3" })
end
local name = nameRow[i]
local nameEn = nameEnRow[i]
if name then
h_td:wikitext(string.format(itemNames["name_format"], nameEn, name))
end
end
end
local imageRow = shipTableRows["image"]
if imageRow then
local h_tr = h_table:tag("tr"):addClass("sps-image")
if shipCount > 1 then
h_tr:tag("td")
end
for i=1, shipCount do
local h_td
if shipCount > 1 then
h_td = h_tr:tag("td"):attr({ colspan="2" })
else
h_td = h_tr:tag("td"):attr({ colspan="3" })
end
local image = imageRow[i]
if image then
h_td:wikitext(image)
end
end
end
local manufacturerRow = shipTableRows["manufacturer"]
if manufacturerRow then
local h_tr = h_table:tag("tr"):addClass("sps-base")
h_tr:tag("td"):addClass("sps-title"):wikitext(createInternalLink(itemNames["manufacturer"]))
for i=1,shipCount do
local h_td = h_tr:tag("td"):addClass("sps-cell"):attr({ colspan="2" })
local manufacturer = manufacturerRow[i]
if manufacturer then
h_td:wikitext(createInternalLink(manufacturer))
end
end
end
local descriptionRow = shipTableRows["description"]
if descriptionRow and isEnabled(options, "show-description") then
local h_tr = h_table:tag("tr"):addClass("sps-base")
h_tr:tag("td"):addClass("sps-title"):wikitext(itemNames["description"])
for i=1,shipCount do
local h_td = h_tr:tag("td"):addClass("sps-cell"):attr({ colspan="2" })
local description = descriptionRow[i]
if description then
h_td:wikitext(description)
end
end
end
local focusRow = shipTableRows["focus"]
if focusRow then
local h_tr = h_table:tag("tr"):addClass("sps-base")
h_tr:tag("td"):addClass("sps-title"):wikitext(createInternalLink(itemNames["focus"]))
for i=1,shipCount do
local h_td = h_tr:tag("td"):addClass("sps-cell"):attr({ colspan="2" })
local focus = focusRow[i]
if focus then
h_td:wikitext(focus)
end
end
end
local productionStatusRow = shipTableRows["production_status"]
local productionNoteRow = shipTableRows["production_note"]
if productionStatusRow then
local h_tr = h_table:tag("tr"):addClass("sps-base")
h_tr:tag("td"):addClass("sps-title"):wikitext(createInternalLink(itemNames["production_status"]))
for i=1,shipCount do
local productionStatus = productionStatusRow[i]
local productionNote
if productionNoteRow then
productionNote = productionNoteRow[i]
end
local h_td = h_tr:tag("td"):addClass("sps-cell"):attr({ colspan="2" })
if productionStatus then
h_td:wikitext(productionStatus)
if productionNote then
h_td:wikitext("<br />")
end
end
if productionNote then
h_td:wikitext(productionNote)
end
end
end
local lengthRow = shipTableRows["length"]
if lengthRow then
local h_tr = h_table:tag("tr"):addClass("sps-measurement")
h_tr:tag("td"):addClass("sps-title"):wikitext(itemNames["length"])
for i=1,shipCount do
local h_td = h_tr:tag("td"):addClass("sps-cell"):attr({ colspan="2" })
local length = lengthRow[i]
if length then
h_td:wikitext(string.format(itemNames["length_unit_format"], length))
end
end
end
local beamRow = shipTableRows["beam"]
if beamRow then
local h_tr = h_table:tag("tr"):addClass("sps-measurement")
h_tr:tag("td"):addClass("sps-title"):wikitext(itemNames["beam"])
for i=1,shipCount do
local h_td = h_tr:tag("td"):addClass("sps-cell"):attr({ colspan="2" })
local beam = beamRow[i]
if beam then
h_td:wikitext(string.format(itemNames["length_unit_format"], beam))
end
end
end
local heightRow = shipTableRows["height"]
if heightRow then
local h_tr = h_table:tag("tr"):addClass("sps-measurement")
h_tr:tag("td"):addClass("sps-title"):wikitext(itemNames["height"])
for i=1,shipCount do
local h_td = h_tr:tag("td"):addClass("sps-cell"):attr({ colspan="2" })
local height = heightRow[i]
if height then
h_td:wikitext(string.format(itemNames["length_unit_format"], height))
end
end
end
local massRow = shipTableRows["mass"]
if massRow then
local h_tr = h_table:tag("tr"):addClass("sps-measurement")
h_tr:tag("td"):addClass("sps-title"):wikitext(createInternalLink(itemNames["mass"]))
for i=1,shipCount do
local h_td = h_tr:tag("td"):addClass("sps-cell"):attr({ colspan="2" })
local mass = massRow[i]
if mass then
h_td:wikitext(string.format(itemNames["mass_unit_format"], mass))
end
end
end
local cargo_capacity_row = shipTableRows["cargo_capacity"]
if cargo_capacity_row then
local h_tr = h_table:tag("tr"):addClass("sps-structural")
h_tr:tag("td"):addClass("sps-title"):wikitext(createInternalLink(itemNames["cargo_capacity"]))
for i=1,shipCount do
local h_td = h_tr:tag("td"):addClass("sps-cell"):attr({ colspan="2" })
local cargo_capacity = cargo_capacity_row[i]
if cargo_capacity then
h_td:wikitext(string.format(itemNames["cargo_unit_format"], cargo_capacity))
end
end
end
local max_crew_row = shipTableRows["max_crew"]
if max_crew_row then
local h_tr = h_table:tag("tr"):addClass("sps-structural")
h_tr:tag("td"):addClass("sps-title"):wikitext(itemNames["max_crew"])
for i=1,shipCount do
local h_td = h_tr:tag("td"):addClass("sps-cell"):attr({ colspan="2" })
local max_crew = max_crew_row[i]
if max_crew then
h_td:wikitext(string.format(itemNames["crew_unit_format"], max_crew))
end
end
end
local max_power_plant_size_row = shipTableRows["max_power_plant_size"]
if max_power_plant_size_row then
local h_tr = h_table:tag("tr"):addClass("sps-structural")
h_tr:tag("td"):addClass("sps-title"):wikitext(itemNames["max_power_plant_size"])
for i=1,shipCount do
local h_td = h_tr:tag("td"):addClass("sps-cell"):attr({ colspan="2" })
local max_power_plant_size = max_power_plant_size_row[i]
if max_power_plant_size then
h_td:wikitext(string.format(itemNames["size_unit_format"], max_power_plant_size))
end
end
end
local max_shield_size_row = shipTableRows["max_shield_size"]
if max_shield_size_row then
local h_tr = h_table:tag("tr"):addClass("sps-structural")
h_tr:tag("td"):addClass("sps-title"):wikitext(itemNames["max_shield_size"])
for i=1,shipCount do
local h_td = h_tr:tag("td"):addClass("sps-cell"):attr({ colspan="2" })
local max_shield_size = max_shield_size_row[i]
if max_shield_size then
h_td:wikitext(string.format(itemNames["size_unit_format"], max_shield_size))
end
end
end
local propulsion_row = shipTableRows["propulsion"]
if anyInTable(propulsion_row) then
local h_tr = h_table:tag("tr"):addClass("sps-propulsion-title")
h_tr:tag("td"):addClass("sps-title"):wikitext(itemNames["type"])
for shipIndex=1,shipCount do
h_tr:tag("td"):addClass("sps-cell-h1"):wikitext(itemNames["size_count"])
h_tr:tag("td"):addClass("sps-cell-h2"):wikitext(itemNames["factory_propulsion"])
end
for p_type, p_row in pairsByKeys(propulsion_row, propulsionOrderByType) do
h_tr = h_table:tag("tr"):addClass("sps-propulsion")
h_tr:tag("td"):addClass("sps-title"):wikitext(createInternalLink(defualtWhenNil(itemNames["propulsion:" .. p_type], p_type)))
for shipIndex=1,shipCount do
local h_td_specs = h_tr:tag("td"):addClass("sps-cell-h1")
local h_td_factory = h_tr:tag("td"):addClass("sps-cell-h2")
local p_row_ship = p_row[shipIndex]
if p_row_ship then
local p_row_ship_specs = p_row_ship["specs"]
if p_row_ship_specs then
for specs_size, specs_count in pairs(p_row_ship_specs) do
h_td_specs:wikitext(string.format(itemNames["propulsion_specs_format"], specs_size, specs_count))
h_td_specs:wikitext("<br />")
end
end
local p_row_ship_factory = p_row_ship["factory"]
if p_row_ship_factory then
for factory_component_index, factory_component in ipairs(p_row_ship_factory) do
h_td_factory:wikitext(string.format(itemNames["propulsion_factory_format"], factory_component.name, factory_component.size, factory_component.count))
h_td_factory:wikitext("<br />")
end
end
end
end
end
end
local ordnance_row = shipTableRows["ordnance"]
if anyInTable(ordnance_row) then
local h_tr = h_table:tag("tr"):addClass("sps-ordnance-title")
h_tr:tag("td"):addClass("sps-title"):wikitext(itemNames["type"])
for shipIndex=1,shipCount do
h_tr:tag("td"):addClass("sps-cell-h1"):wikitext(itemNames["size_count"])
h_tr:tag("td"):addClass("sps-cell-h2"):wikitext(itemNames["factory_ordnance"])
end
for p_class, p_row in pairsByKeys(ordnance_row) do
h_tr = h_table:tag("tr"):addClass("sps-ordnance")
h_tr:tag("td"):addClass("sps-title"):wikitext(createInternalLink(string.format(itemNames["ordnance_class_format"], p_class)))
for shipIndex=1,shipCount do
local h_td_specs = h_tr:tag("td"):addClass("sps-cell-h1")
local h_td_factory = h_tr:tag("td"):addClass("sps-cell-h2")
local p_row_ship = p_row[shipIndex]
if p_row_ship then
local p_row_ship_specs = p_row_ship["specs"]
if p_row_ship_specs then
for specs_size, specs_count in pairs(p_row_ship_specs) do
h_td_specs:wikitext(string.format(itemNames["ordnance_specs_format"], specs_size, specs_count))
h_td_specs:wikitext("<br />")
end
end
local p_row_ship_factory = p_row_ship["factory"]
if p_row_ship_factory then
for factory_component_index, factory_component in ipairs(p_row_ship_factory) do
h_td_factory:wikitext(string.format(itemNames["ordnance_factory_format"], factory_component.name, factory_component.size, factory_component.count))
h_td_factory:wikitext("<br />")
end
end
end
end
end
end
local modular_row = shipTableRows["modular"]
if anyInTable(modular_row) then
local h_tr = h_table:tag("tr"):addClass("sps-modular-title")
h_tr:tag("td"):addClass("sps-title"):wikitext(itemNames["type"])
for shipIndex=1,shipCount do
h_tr:tag("td"):addClass("sps-cell-h1"):wikitext(itemNames["size_count"])
h_tr:tag("td"):addClass("sps-cell-h2"):wikitext(itemNames["factory_modular"])
end
for p_type, p_row in pairs(modular_row) do
h_tr = h_table:tag("tr"):addClass("sps-modular")
h_tr:tag("td"):addClass("sps-title"):wikitext(createInternalLink(defualtWhenNil(itemNames["modular:" .. p_type], p_type)))
for shipIndex=1,shipCount do
local h_td_specs = h_tr:tag("td"):addClass("sps-cell-h1")
local h_td_factory = h_tr:tag("td"):addClass("sps-cell-h2")
local p_row_ship = p_row[shipIndex]
if p_row_ship then
local p_row_ship_specs = p_row_ship["specs"]
if p_row_ship_specs then
for specs_size, specs_count in pairs(p_row_ship_specs) do
h_td_specs:wikitext(string.format(itemNames["modular_specs_format"], specs_size, specs_count))
h_td_specs:wikitext("<br />")
end
end
local p_row_ship_factory = p_row_ship["factory"]
if p_row_ship_factory then
for factory_component_index, factory_component in ipairs(p_row_ship_factory) do
h_td_factory:wikitext(string.format(itemNames["modular_factory_format"], factory_component.name, factory_component.size, factory_component.count))
h_td_factory:wikitext("<br />")
end
end
end
end
end
end
local avionics_row = shipTableRows["avionics"]
if anyInTable(avionics_row) then
local h_tr = h_table:tag("tr"):addClass("sps-avionics-title")
h_tr:tag("td"):addClass("sps-title"):wikitext(itemNames["type"])
for shipIndex=1,shipCount do
h_tr:tag("td"):addClass("sps-cell-h1"):wikitext(itemNames["size_count"])
h_tr:tag("td"):addClass("sps-cell-h2"):wikitext(itemNames["factory_avionics"])
end
for p_type, p_row in pairs(avionics_row) do
h_tr = h_table:tag("tr"):addClass("sps-avionics")
h_tr:tag("td"):addClass("sps-title"):wikitext(createInternalLink(defualtWhenNil(itemNames["avionics:" .. p_type], p_type)))
for shipIndex=1,shipCount do
local h_td_specs = h_tr:tag("td"):addClass("sps-cell-h1")
local h_td_factory = h_tr:tag("td"):addClass("sps-cell-h2")
local p_row_ship = p_row[shipIndex]
if p_row_ship then
local p_row_ship_specs = p_row_ship["specs"]
if p_row_ship_specs then
for specs_size, specs_count in pairs(p_row_ship_specs) do
h_td_specs:wikitext(string.format(itemNames["avionics_specs_format"], specs_size, specs_count))
h_td_specs:wikitext("<br />")
end
end
local p_row_ship_factory = p_row_ship["factory"]
if p_row_ship_factory then
for factory_component_index, factory_component in ipairs(p_row_ship_factory) do
h_td_factory:wikitext(string.format(itemNames["avionics_factory_format"], factory_component.name, factory_component.size, factory_component.count))
h_td_factory:wikitext("<br />")
end
end
end
end
end
end
local urlRow = shipTableRows["url"]
if urlRow then
local h_tr = h_table:tag("tr"):addClass("sps-url")
if shipCount > 1 then
h_tr:tag("td")
end
for i=1, shipCount do
local h_td
if shipCount > 1 then
h_td = h_tr:tag("td"):attr({ colspan="2" })
else
h_td = h_tr:tag("td"):attr({ colspan="3" })
end
local url = urlRow[i]
if url then
local name
if nameEnRow and nameEnRow[i] then
name = nameEnRow[i]
elseif nameRow and nameRow[i] then
name = nameRow[i]
else
name = "Unkonwn"
end
h_td:wikitext(string.format(itemNames["official_page_format"], url, name))
end
end
end
return tostring(h_table)
end
function p.shipTable( frame )
local options = {}
local specsList = {}
for name, arg in pairs(frame.args) do
local status, result = pcall(mw.text.jsonDecode, arg)
if status and result then
if result["id"] and result["name"] then --'{ "id":"1", "name":"Ship Name" }'
table.insert(specsList, result)
elseif result[optionsToken] then --'{ "optionsToken":"", "arg1":"abc", "arg2":"def" }'
options = result
else
mw.log(string.format("frame.args[%s] is an unknown json object.", name))
end
else
mw.log(string.format("frame.args[%s] is an unknown object.", name))
end
end
local specsListCount = table.getn(specsList)
if specsListCount > 0 then
--mw.log(mw.logObject(specsList))
local rows = shipTableRows(specsList, options)
--mw.log(mw.logObject(rows))
return createShipTable(rows, specsListCount, options)
end
end
function p.options( frame )
local options = {}
local optionsArgs = {}
for name, arg in pairs(frame.args) do
table.insert(optionsArgs, arg)
end
for index = 1, table.getn(optionsArgs) do
if (index % 2) == 0 then
options[optionsArgs[index - 1]] = optionsArgs[index]
end
end
options[optionsToken] = true
return mw.text.jsonEncode(options)
end
return p