该模块作为碧蓝航线系列条目的重要模块,编辑请尽量使用原生编辑页面,并且保存前请务必预览Template:碧蓝航线的显示情况。
逻辑代码位于本页面。
数据位于模块:碧蓝航线Ships/Data。
目前数据由脚本自动更新,有编辑组专人负责。
local module = {} local data = mw.loadData("Module:碧蓝航线Ships/Data") local temp_data = { -- Temporary data, please remove after being applied ["企业·META"] = { type = 7, rarity = 14, }, ["高雄·META"] = { type = 7, rarity = 14, code = "獒·META", }, ["约克城·META"] = { type = 7, rarity = 14, }, ["好人理查德·META"] = { type = 7, rarity = 14, }, } -- Override in the main module, avoid manual modification to the data module. local override_data = { } local color = { [0] = "999", [1] = "999", [2] = "33f", [3] = "c3c", [4] = "c90", [5] = "f39", [6] = "963", [7] = "d79", -- META, +10 as baseline [13] = "410881", [14] = "800000", } local alias = { ["比睿"] = "比叡", ["小比睿"] = "小比叡", ["北安普顿"] = "北安普敦", ["凑阿库娅"] = "湊阿库娅", ["㭴野"] = "樫野" } local map_items = { ["耐久"] = 1, ["炮击"] = 2, ["雷击"] = 3, ["防空"] = 4, ["航空"] = 5, ["装填"] = 6, ["射程"] = 7, ["命中"] = 8, ["机动"] = 9, ["航速"] = 10, ["幸运"] = 11, ["反潜"] = 12 } local tech_type = { [1] = "耐久", [2] = "炮击", [3] = "雷击", [4] = "防空", [5] = "航空", [6] = "装填", [7] = "装甲", [8] = "命中", [9] = "机动", [10] = "航速", [11] = "幸运", [12] = "反潜" } local map_type = { [1] = "驱逐", [2] = "轻巡", [3] = "重巡", [4] = "战巡", [5] = "战列", [6] = "轻航", [7] = "航母", [8] = "潜艇", [9] = "航巡", [10] = "航战", [11] = "雷巡", [12] = "维修", [13] = "重炮", [17] = "潜母", [18] = "超巡", [19] = "运输", [20] = "导驱-先锋", [21] = "导驱-主力" ,[22] = "风帆S", [23] = "风帆V",[24] = "风帆M"} local map_level = { [1] = "普通【N】", [2] = "稀有【R】", [3] = "精锐【SR】", [4] = "超稀有【SSR】", [5] = "海上传奇【UR】", [6] = "最高方案【PR】", [7] = "决战方案【DR】", [13] = "META-精锐", [14] = "META-超稀有" } local map_notrans = { [7] = true, [11] = true } local map_armor = { [1] = "轻型", [2] = "中型", [3] = "重型" } local map_nation = { [1] = '白鹰联邦', [2] = '皇家海军', [3] = '重樱群岛', [4] = '铁血公国', [5] = '东煌', [6] = '撒丁帝国', [7] = '北方联合', [8] = '自由鸢尾', [9] = '维希教廷', [96] = '飓风', [97] = 'META', [98] = '无阵营', [99] = '塞壬', [101] = '海王星', [102] = '哔哩哔哩', [103] = '传颂之物', [104] = 'KizunaAI', [105] = 'Hololive', [106] = '维纳斯假期', [107] = '偶像大师', [108] = 'SSSS', [109] = 'Atelier Ryza', [110] = '闪乱神乐' } function get_data(...) for _, ship_id in ipairs({ ... }) do value = data[ship_id] or temp_data[ship_id] if value then if override_data[ship_id] then retn = {} for key, val in pairs(value) do retn[key] = override_data[ship_id][key] or val end return retn end return value end end return data.null end module.get_data = get_data -- 碧蓝航线colors模板 function module.colors(frame) local parent = frame:getParent() if parent and parent:getTitle() == "Template:碧蓝航线colors" then frame = parent end local arg_name = mw.text.trim(frame.args[1] or "null") return color[get_data(arg_name, alias[arg_name]).rarity] end function module.innerlevel(arg_name) local plus = 0 if mw.ustring.find(arg_name, "[^%a]?改$") then plus = 1 arg_name = mw.ustring.gsub(arg_name, "[^%a]?改$", "") end return get_data(arg_name, alias[arg_name]).rarity + plus end -- 碧蓝航线稀有度模板 function module.level(frame) local parent = frame:getParent() if parent and parent:getTitle() == "Template:碧蓝航线稀有度" then frame = parent end local arg_name = mw.text.trim(frame.args[1] or "null") return module.innerlevel(arg_name) end -- 碧蓝航线links模板 function module.links(frame) local i = 1 local ret = "" local parent = frame:getParent() if parent and parent:getTitle() == "Template:碧蓝航线links" then frame = parent end local outerprefix = frame.args["outerprefix"] or "" local outersuffix = frame.args["outersuffix"] or "" local css = frame.args["css"] local nocolor = frame.args["nocolor"] == "no" local nocheck = frame.args["nocheck"] == "1" local name, link, plus while (frame.args[i]) do name = mw.text.trim(frame.args[i]) plus = mw.ustring.find(name, "[^%a]?改$") and 1 or 0 link = plus == 1 and mw.ustring.gsub(name, "[^%a]?改$", "") or name name = mw.ustring.gsub(name, "%([^μ]+%)", "") local item = get_data(link, alias[link]) if item.type == 0 and (not nocheck) then ret = ret .. frame:preprocess("{{#ifeq:{{NAMESPACENUMBER}}|2||[[Category:碧蓝航线未知的模板参数]][[Category:碧蓝航线未知的模板参数/" .. name .. "]]}}") link = "碧蓝航线" else link = "碧蓝航线:" .. link end if plus == 0 and item.code then name = name .. "(" .. item.code .. ")" end if i > 1 then ret = ret .. " • " end if nocolor then ret = ret .. outerprefix .. "[[" .. link .. "|" .. name .. "]]" .. outersuffix else ret = ret .. outerprefix .. "[[" .. link .. '|<span style="color:#' .. color[item.rarity + plus] .. (css and (";" .. css) or "") .. '">' .. name .. "</span>]]" if plus == 0 and item.attrs and item.attrs[3] then ret = ret .. '<sup style="color:#' .. color[item.rarity + 1] .. '">改</sup>' end ret = ret .. outersuffix end i = i + 1 end return ret end function args_err(info) return '<div class="error">参数错误:' .. info .. '</div>' end -- 碧蓝航线舰船性能模板 function module.property(frame) local parent = frame:getParent() if parent and parent:getTitle() == "Template:碧蓝航线舰船性能" then frame = parent end local arg_name = frame.args[1] or "" arg_name = mw.text.trim(arg_name) local info = get_data(arg_name, alias[arg_name]) if not info or not info.attrs then return args_err("1") end info = info.attrs local arg_type = frame.args["type"] or "0" arg_type = tonumber(arg_type) local arg_item = frame.args["item"] or "1" if map_items[arg_item] then arg_item = map_items[arg_item] else arg_item = tonumber(arg_item) end if not arg_item or arg_item < 1 or arg_item > 12 then return args_err("item") end local arg_check = frame.args["check"] or "" if arg_type == 1 or map_notrans[arg_item] then local arg_index = frame.args["index"] or "1" arg_index = tonumber(arg_index) if info[arg_index] then return info[arg_index][arg_item] else return args_err("index") end else local retn, matches = {}, {} local last, needChk = nil, false for num in mw.ustring.gmatch(arg_check, "%d+") do table.insert(matches, num) end for index, item in ipairs(info) do if matches[index] and tonumber(matches[index]) ~= item[arg_item] then needChk = true end if not last or last ~= item[arg_item] then last = item[arg_item] if index == 3 then table.insert(retn, frame:expandTemplate { title = "Color", args = { "orange", item[arg_item] } } .. ( needChk and "[[Category:碧蓝航线数据需要检查]][[Category:碧蓝航线数据需要检查/" .. frame.args["item"] .. "]]" or "")) else table.insert(retn, item[arg_item]) end end end return table.concat(retn, "→") end end function module.check(frame) local arg_name = mw.text.trim(frame.args[1] or "null") local info = get_data(arg_name, alias[arg_name]) if not info or not info.attrs then return "" end return arg_name end -- 碧蓝航线文件拼音模板 function module.filename(frame) local parent = frame:getParent() if parent and parent:getTitle() == "Template:碧蓝航线文件拼音" then frame = parent end local special = 0 local arg_name = mw.text.trim(frame.args[1] or "null") if mw.ustring.find(arg_name, "[^%a]?改$") then special = 3 arg_name = mw.ustring.gsub(arg_name, "[^%a]?改$", "") end local info = get_data(arg_name, alias[arg_name]) if arg_name == "null" or not info then return end if info.picname then return info.picname .. (special == 3 and "_g" or "") end local name_cut, filename = arg_name, nil if mw.ustring.sub(arg_name, 1, 1) == "小" then special = 1 name_cut = mw.ustring.sub(name_cut, 2, -1) elseif mw.ustring.find(arg_name, "%(μ兵装%)") then special = 2 name_cut = mw.ustring.gsub(name_cut, "%(μ兵装%)", "") elseif mw.ustring.find(arg_name, "META") then special = 4 name_cut = mw.ustring.gsub(name_cut, "·META", "") end info = get_data(name_cut, alias[name_cut]) if info and info.picname then filename = info.picname else -- Should not fall into this inefficient code path filename = frame:expandTemplate { title = "拼音生成", args = { name_cut, strip = 1 } } end if special == 1 then filename = filename .. "_younv" elseif special == 2 then filename = filename .. "_idol" elseif special == 4 then filename = filename .. "_alter" elseif special == 3 then filename = filename .. "_g" end return filename end -- 碧蓝航线人物背景模板 function module.skin_bg(frame) local ship_name = mw.text.trim(frame.args[1]) local skin_file = mw.text.trim(frame.args[2]) local skin_name = mw.text.trim(frame.args[3]) local info = get_data(ship_name, alias[ship_name]) if info.skin_bg then local index = mw.ustring.match(skin_file, '[_ ](%d+)') if index and info.skin_bg[index - 1] then return 'BLHX_skin_bg_' .. info.skin_bg[index - 1] .. '.png' end end if mw.ustring.find(skin_name, '誓[约約]') then local map_postfix = { [3] = '_jp', [5] = '_cn' } return 'BLHX_bg_church' .. (map_postfix[info.nation] or '') .. '.png' end return 'BLHX稀有度背景' .. (info.rarity + (mw.ustring.find(skin_name, '改造') and 1 or 0)) .. '.png' end function warp_link(title) return "[[" .. title .. "]]" end -- 碧蓝航线角色条目人物数据模板部分数据导入 local processInfo = { cv1 = function(cv1, args) -- Manual or noLink if not args or args.noLink then return cv1 end return warp_link(cv1) end, type = function(type) type = tonumber(type) return map_type[type] or args_err("3") end, rarity = function(rarity) rarity = tonumber(rarity) return map_level[rarity] or args_err("3") end, armor = function(armor) armor = tonumber(armor) return map_armor[armor] or args_err("3") end, nation = function(nation) nation = tonumber(nation) return map_nation[nation] or args_err("3") end, radar = function(radar, args, frame) local manual = false if args == false then args = frame.args manual = true end if not args.color2 then return args_err("color2") end if not args.color3 then return args_err("color3") end local tab_html = { '<div class="Tabs blue" data-label-side="top" data-text-padding="0" data-auto-width="yes" data-label-background-color="' .. args.color2 .. '"><div class="Tab"><div class="TabLabelText">作战性能</div><div class="TabContentText">', [3] = '</div></div>', [4] = '</div>', } local RADAR_MAP = { "炮击", "雷击", "航空", "机动", "防空", "耐久" } for radar_index = 1, 2 do local cur_radar = radar[radar_index] if not manual and not cur_radar then if radar_index == 2 then mw.log("无改造数据,已跳过雷达图生成……") break else return args_err("无雷达图信息") end end local radar_args = { color = args["color" .. radar_index + 1], } for k, arg in ipairs(RADAR_MAP) do radar_args[arg .. "值"] = manual and args[(radar_index == 2 and "改造" or "") .. arg .. "值"] or cur_radar[k] end radar_html = frame:expandTemplate { title = "碧蓝航线雷达图", args = radar_args } if radar_index == 1 then tab_html[2] = radar_html else table.insert(tab_html, 4, '<div class="Tab"><div class="TabLabelText">改造性能</div><div class="TabContentText">' .. radar_html .. "</div></div>") end end mw.logObject(tab_html) return table.concat(tab_html) end, } processInfo.cv2 = processInfo.cv1 function module.getInfo(frame) local attr = mw.text.trim(frame.args[1] or "") if attr == "" then return args_err("1") end local arg_name = mw.text.trim(frame.args[2] or "null") local info = get_data(arg_name, alias[arg_name]) local processFunc = processInfo[attr] or function(v) return v end if not info or not info[attr] then return processFunc(mw.text.trim(frame.args[3] or ""), false, frame) end return processFunc(info[attr], frame.args, frame) end -- 碧蓝航线角色条目人物数据模板科技点数据导入 function module.get_tech(frame) local arg_name = mw.text.trim(frame.args[1] or "null") local tech_pts = get_data(arg_name, alias[arg_name]).tech_pts if not tech_pts then return '' end local arg_type = mw.text.trim(frame.args[2]) local map_temp = { get = 1, upgrade = 2, level = 3 } tech_pts = tech_pts[map_temp[arg_type]] local output = {} if arg_type == 'get' or arg_type == 'level' then table.insert(output, tech_pts[1]) for _, type in ipairs(tech_pts[2]) do table.insert(output, '{{碧蓝航线标签|' .. map_type[type] .. '}}{{space|2}}' .. tech_type[tech_pts[3]] .. '+' .. tech_pts[4]) end return frame:preprocess(table.concat(output, '{{space|4}}')) else return tech_pts end end return module