提供從數據列表中自動查找數據並添加格式的各種功能
基本語法: {{#invoke:戰艦少女|功能名|參數1|參數2|...}}
數據儲存在以下幾個文件中:
模塊:戰艦少女:數據(註:此模塊為模塊:戰艦少女:艦娘屬性列表、模塊:戰艦少女:裝備屬性列表和模塊:戰艦少女:台詞的集合,以上3個模塊不再記錄數據)
模塊:戰艦少女:別名 (包括立繪文件名)
其中大部分內容可以用這個程序自動生成
顯示船的名字, 默認高亮加粗並添加連結
可通過第二個參數刪除部分樣式 (c:高亮 , b:加粗 , l:連結)
{{#invoke:戰艦少女|艦娘|列剋星敦(CV-2)}}
{{#invoke:戰艦少女|艦娘|胡德·改|l}}
胡德·改
{{#invoke:戰艦少女|艦娘|列剋星敦(CV-2)·改|cb}}
顯示船的屬性, 對於可成長屬性會顯示成 基本屬性(屬性上限) 的格式
屬性名具體參見模塊:戰艦少女:艦娘屬性列表
{{#invoke:戰艦少女|艦娘屬性|列剋星敦(CV-2)|火力}}
0(35)
{{#invoke:戰艦少女|圖鑑編號|列剋星敦(CV-2)}}
29
重載1: 1個參數
{{#invoke:戰艦少女|稀有度|列剋星敦(CV-2)·改}}
5
重載2: 2個參數 將數字以彩色顯示
{{#invoke:戰艦少女|稀有度|列剋星敦(CV-2)|彩色}}
4
顯示船改前和改後的屬性, 格式為 改前 → 改後
{{#invoke:戰艦少女|改造屬性|列剋星敦(CV-2)|火力}}
0(35) → 0(40)
自動生成所有特定種類艦孃的屬性表格, 具體見 戰艦少女/屬性列表
圖片大小也可以不填(太大了所以不演示了)
{{#invoke:戰艦少女|艦娘立繪|列剋星敦(CV-2)|150px}}
{{#invoke:戰艦少女|大破立繪|列剋星敦(CV-2)|100px}}
{{#invoke:戰艦少女|台詞|<船名>|<台詞種類>|<替換>}}
台詞種類可以是: 自薦, 獲得, 白天1, 白天2, 白天3, 夜間1, 夜間2, 夜間3, 陣型, 攻擊, 夜戰, 中破, 誓約
替換可以省略, 如果不省略則將台詞替換為該內容
{{#invoke:戰艦少女|台詞|列剋星敦(CV-2)·改|獲得}}
休假完畢~海風真是舒爽呢~
{{#invoke:戰艦少女|台詞|列剋星敦(CV-2)·改|獲得|替換成這個}}
替換成這個
{{#invoke:戰艦少女|裝備|BTD-1毀滅者}}
生成裝備數據表格的一行, 詳見戰艦少女/裝備
重載1: 1個參數
{{#invoke:戰艦少女|裝備按鈕|B-25(杜立特隊)}}
轟炸+20
重載2: 2個參數
{{#invoke:戰艦少女|裝備按鈕|巨像|2}}
對空+6
轟炸+7
對潛+3
列出自帶所填寫裝備的所有艦娘:
{{#invoke:戰艦少女|自帶|J國12.7釐米連裝炮}}
吹雪、白雪、初雪、深雪、曉、響、雷、電、綾波、敷波、陽炎、不知火、黑潮、雪風、白露、時雨、村雨、夕立、吹雪·改、白雪·改、初雪·改、深雪·改、曉·改、雷·改、電·改、綾波·改、敷波·改自帶
顯示6個敵艦的連結(不足6個時補空格子), 並自動計算平均航速和制空值
{{#invoke:戰艦少女|敵艦列表|輕母Ξ級III型|輕母Ξ級III型|輕巡Ζ級III型|輕巡Ζ級III型|驅逐Τ級II型}}
local data = mw.loadData("模塊:戰艦少女:特殊數據") local enemies = mw.loadData("模塊:戰艦少女:敵艦屬性列表") local alias = mw.loadData("模塊:戰艦少女:別名") local ships = data.ships local equipts = data.equipts local skills = data.skills local tr = data.tr local equiptDisplay = data.equiptDisplay local byIndex = data.byIndex local p = {} -- Tables -- local shipTypeAbbrName = { CV='航母', CVL='輕母', AV='裝母', BB='戰列', BBV='航戰', BC='戰巡', CA='重巡', CL='輕巡', CLT='雷巡', CAV='航巡', BM='重炮', DD='驅逐', ASDG='導驅', SS='潛艇', SC='炮潛', AP='補給' } local shipTypeFullName = { CV='航空母艦', CVL='輕型航空母艦', BB='戰列艦', BBV='航空戰列艦', BC='戰列巡洋艦', CA='重巡洋艦', CL='輕巡洋艦', CLT='重雷裝巡洋艦', CAV='航空巡洋艦', BM='淺水重炮艦', DD='驅逐艦', ASDG='導彈驅逐艦', SS='潛水艇', SC='重炮潛艇', AP='補給艦' } local color = { 'black', 'green', 'blue', 'purple', 'orange', 'red' } local rangeName = { '無', '短', '中', '長', '超長' } -- 6星字體顏色的調色板, 每行一個顏色(格式{r,g,b}), 從最左到最右均勻分佈, 支持任意種顏色 local palette = { { 0xf3, 0xc7, 0x41 }, { 0xe2, 0x1d, 0x3a }, { 0xbb, 0x44, 0xb8 }, { 0x3c, 0x7a, 0xf7 } } local function rainbow(str, bold) local n = mw.ustring.len(str) local m = #palette - 1 local hasDot = false if mw.ustring.sub(str, n - 1, n - 1) == '·' then hasDot = true str = mw.ustring.gsub(str, '·改', '改') n = n - 1 end local ret = '' local dbg = '' for i = 1,n do local p = i - 0.5 local r = 1 while p * m > n * r do r = r + 1 end local l = r - 1 local pl = n * l / m local pr = n * r / m local wl = (pr - p) / (pr - pl) local wr = (p - pl) / (pr - pl) local cr = math.floor(palette[l + 1][1] * wl + palette[r + 1][1] * wr + 0.5) local cg = math.floor(palette[l + 1][2] * wl + palette[r + 1][2] * wr + 0.5) local cb = math.floor(palette[l + 1][3] * wl + palette[r + 1][3] * wr + 0.5) local color = string.format('#%02x%02x%02x', cr, cg, cb) local ch = mw.ustring.sub(str, i, i) if hasDot and i == n then ch = "·" .. ch end if bold then ch = "'''" .. ch .. "'''" end ret = ret .. "<span style='color:" .. color .. ";'>" .. ch .. "</span>" end return ret end function addColor(str, rarity, bold) if rarity == 6 then return rainbow(str, bold) end if rarity < 1 then rarity = 1 end if bold then str = "'''" .. str .. "'''" end return '<span style="color:' .. color[rarity] .. ';">' .. str .. '</span>' end -- ## Helper functions ## local function formatFloat(x) if x == 0 then return 0 end x = math.floor(x * 100 + 0.5) / 100 return string.format('%.2f', x) end local function getImage(aliasName, index, prefix, size) local ret = prefix .. index .. '.png' if aliasName ~= nil and aliasName ~= '' then ret = aliasName .. '.png' end if size ~= nil then ret = ret .. '|' .. size end return '[[File:' .. ret .. ']]' end local function notContains(str, ch) if str == nil then return true end return string.find(str, ch) == nil end -- ## Ship functions ## local function getBaseName(name) if alias.shipBaseName[name] ~= nil then return alias.shipBaseName[name] end name = string.gsub(name, '·改', '') name = string.gsub(name, '(特殊)', '') if mw.ustring.sub(name, 1, 2) == '航母' then return '敵航空母艦' end if mw.ustring.sub(name, 1, 2) == '輕母' then return '敵輕型航母' end if mw.ustring.sub(name, 1, 2) == '戰列' then return '敵戰列艦' end if mw.ustring.sub(name, 1, 2) == '戰巡' then return '敵戰列巡洋艦' end if mw.ustring.sub(name, 1, 2) == '旗艦' then return '敵航空戰列艦' end if mw.ustring.sub(name, 1, 2) == '重巡' then return '敵重巡洋艦' end if mw.ustring.sub(name, 1, 2) == '雷巡' then return '敵重雷裝巡洋艦' end if mw.ustring.sub(name, 1, 2) == '輕巡' then return '敵輕巡洋艦' end if mw.ustring.sub(name, 1, 2) == '驅逐' then return '敵驅逐艦' end if mw.ustring.sub(name, 1, 2) == '潛艇' then return '潛艇' end if mw.ustring.sub(name, 1, 2) == '補給' then return '敵補給艦' end return name end local function formatShipTitle(shipName, removeStyles, frame) local isBold = notContains(removeStyles, 'b') local hasColor = notContains(removeStyles, 'c') local hasLink = notContains(removeStyles, 'l') local ret = shipName local ship = ships[shipName] if ship == nil then ship = enemies[fixEnemyName(shipName)] end -- backward compatibility if hasColor and ship ~= nil then ret = addColor(ret, ship.rarity, isBold) elseif isBold then ret = "'''" .. ret .. "'''" end if hasLink then ret = '[[戰艦少女:' .. getBaseName(shipName) .. '|' .. ret .. ']]' end return ret end -- Get an attribute of a ship. -- Return in 'BASE(MAX)' format if the attribute can grow with level or strengthen. local function getAttr(shipName, attrName) local ship = ships[shipName] local canGrow = false for i,v in pairs({'火力', '裝甲', '魚雷', '對空', '迴避', '對潛', '索敵'}) do if attrName == v then canGrow = true break end end if canGrow then local base = ship[tr['基礎' .. attrName]] local max_ = ship[tr[attrName .. '上限']] if base == max_ then return base else return base .. '(' .. max_ .. ')' end elseif attrName == '搭載' then return ship.cap1 + ship.cap2 + ship.cap3 + ship.cap4 else local ret = ship[tr[attrName]] if ret == nil then ret = '' end -- some ships lack attributes about modification return ret end end -- Get a list of attributes, splited by '||' (in favor of wiki table). local function getAttrList(shipName, attrNameList) local ret = '' for i,attrName in pairs(attrNameList) do ret = ret .. getAttr(shipName, attrName) .. '||' end return string.sub(ret, 1, -3) end local function getShipNormalImage(shipName, size) return getImage(alias.shipNormalImage[shipName], ships[shipName].index, 'L_NORMAL_', size) end local function getShipBrokenImage(shipName, size) return getImage(alias.shipBrokenImage[shipName], ships[shipName].index, 'L_BROKEN_', size) end local function getShipDialogue(header, shipName, dialogueType, replace) local ret = '|-\n|style="text-align:center"|' .. header .. '||' if replace ~= '' and replace ~= nil then return ret .. replace .. '\n' else if (ships[shipName] == nil) then return '\n警告:錯誤的船名"' .. shipName .. '"\n\n' end local d = ships[shipName][dialogueType] if d == nil or d == '' then return '' else return ret .. ships[shipName][dialogueType] .. '\n' end end end -- ## Equipment functions ## local function formatEquiptListAttr(equiptName, attrName) local equipt = equipts[equiptName] or {} local attr = equipt[tr[attrName]] if attr == nil then attr = 0 end local ret = 'data-sort-value="' .. attr .. '"|' if attrName == '射程' then ret = ret .. rangeName[attr + 1] elseif attrName == '耗鋁' then ret = attr elseif attr == 0 then ret = ret .. '‌' elseif attrName == '對空補正' then ret = ret .. attr .. '%' elseif attr > 0 then ret = ret .. attrName .. '<wbr>+' .. attr else ret = ret .. attrName .. '<wbr>' .. attr end return ret end local function formatEquiptButtonAttr(name, val) if name == '射程' then return name .. ':' .. rangeName[val + 1] .. '<br>' elseif name == '對空補正' then return name .. ':' .. val .. '%<br>' elseif name == '耗鋁' then return '' elseif val > 0 then return name .. '+' .. val .. '<br>' else return name .. val .. '<br>' end end local function getEquiptIcon(equipt, size) return getImage(alias.equiptIcon[equipt.index], equipt.index, 'Equip_L_', size) end local function fixEquiptName(name) name = string.gsub(name, 'Ⅲ', 'III') name = string.gsub(name, 'Ⅵ', 'VI') name = string.gsub(name, '日本', 'J國') name = string.gsub(name, '德國', 'G國') name = string.gsub(name, '英國', 'E國') name = string.gsub(name, '美國', 'U國') name = string.gsub(name, '意大利', 'I國') name = string.gsub(name, '法國', 'F國') name = string.gsub(name, '德國', 'G國') name = string.gsub(name, '蘇聯', 'S國') name = string.gsub(name, '中國', 'C國') local ret = alias.equiptName[name] if ret == nil then ret = name end return ret end local function onShip(equiptName) local ret = '' for i = 1,1300 do local shipName = byIndex[i] if shipName ~= nil then local eq = {ships[shipName].eq1, ships[shipName].eq2, ships[shipName].eq3, ships[shipName].eq4} for k = 1,4 do if eq[k] == equiptName then if i > 1000 and i < 2000 then local shipBaseName = byIndex[i - 1000] ret = ret .. '[[戰艦少女:' .. shipBaseName .. '|' .. shipName .. ']]、' else ret = ret .. '[[戰艦少女:' .. shipName .. '|' .. shipName .. ']]、' end break end end end end ret = string.sub(ret, 1, -4) if ret ~= '' and ret ~= nil then ret = ret .. '自帶' end return ret end -- ## Ship ## p['艦娘'] = function(frame) local shipName = frame.args[1] local removeStyles = frame.args[2] return formatShipTitle(shipName, removeStyles, frame) end p['屬性'] = function(frame) local ship = ships[frame.args[1]] if ship == nil then return '' end local attr = frame.args[2] if ship[attr] == nil then return '' end return ship[attr] end -- {{#invoke:戰艦少女|艦娘屬性|船名|屬性名}} -> 屬性 p['艦娘屬性'] = function(frame) local shipName = frame.args[1] local attrName = frame.args[2] return getAttr(shipName, attrName) end -- {{#invoke:戰艦少女|圖鑑編號|船名}} -> 圖鑑編號 p['圖鑑編號'] = function(frame) return ships[frame.args[1]].index end -- {{#invoke:戰艦少女|稀有度|船名}} -> 稀有度 p['稀有度'] = function(frame) local shipName = frame.args[1] local colorful = frame.args[2] local r = ships[shipName].rarity if colorful then return "<span style='color:" .. color[r] .. ";'>'''" .. r .. "'''</span>" else return r end end -- {{#invoke:戰艦少女|改造屬性|船名|屬性名}} -> "改前屬性 → 改後屬性" p['改造屬性'] = function(frame) local baseShipName = frame.args[1] local attrName = frame.args[2] local modShipName = byIndex[ships[baseShipName].index + 1000] local baseAttr = getAttr(baseShipName, attrName) local modAttr = getAttr(modShipName, attrName) if baseAttr == modAttr then return baseAttr else return baseAttr .. ' → ' .. modAttr end end -- {{#invoke:戰艦少女|艦娘屬性列表|艦種|屬性1,屬性2,...}} p['艦娘屬性列表'] = function(frame) local shipType = frame.args[1] local attrNameList = mw.text.split(frame.args[2], ',', true) -- table title ret = '|-\n!colspan=' .. (#attrNameList + 3) .. '|' .. shipTypeAbbrName[shipType] .. '屬性列表\n' -- table header ret = ret .. '|-\n!圖鑑<br>編號!!頭像!!名稱' for i,attrName in pairs(attrNameList) do ret = ret .. '!!' if mw.ustring.len(attrName) > 2 then -- break long headers into two lines ret = ret .. mw.ustring.sub(attrName, 1, 2) local tmp = mw.ustring.sub(attrName, 3, -1) if tmp ~= '上限' then ret = ret .. '<br>' .. tmp end else ret = ret .. attrName end end ret = ret .. '\n' -- table content for i = 1,1300 do -- keys of table will be sorted as string by default (11>2) local shipName = byIndex[i] if shipName ~= nil and ships[shipName].type == shipType then ret = ret .. '|-\n|' .. i ret = ret .. '||' .. getShipProfile(shipName, '150px') ret = ret .. '||' .. formatShipTitle(shipName) ret = ret .. '||' .. getAttrList(shipName, attrNameList) ..'\n' end end return ret end p['艦娘立繪'] = function(frame) local shipName = frame.args[1] local size = frame.args[2] return getShipNormalImage(shipName, size) end p['大破立繪'] = function(frame) local shipName = frame.args[1] local size = frame.args[2] return getShipBrokenImage(shipName, size) end function getShipProfile(shipName, size) local ret = alias.profile[shipName] if ret == nil then local tmp = ships[shipName] if tmp == nil then return shipName end ret = ships[shipName].index end ret = '[[File:Warship_Girls_icon_' .. ret .. '.png|link=戰艦少女:' .. getBaseName(shipName) if size ~= nil and size ~= '' then ret = ret .. '|' .. size end return ret .. ']]' end p['頭像'] = function(frame) return getShipProfile(frame.args[1], frame.args[2]) end p['台詞'] = function(frame) local shipName = frame.args[1] local dialogue = frame.args[2] local force = frame.args[3] if force ~= nil and force ~= '' then return force end if ships[shipName] == nil then return "none" else return ships[shipName][dialogue] end end function skillDesc(skillName) local desc = skills[skillName] if desc == nil then return '' end desc = desc:gsub('_G%[_', '<span style="color:green;">') desc = desc:gsub('_R%[_', '<span style="color:red;">') desc = desc:gsub('_%]_', '</span>') return desc end p['技能描述'] = function(frame) local shipName = frame.args[1] return skillDesc(ships[shipName].skill) end p['技能描述2'] = function(frame) local shipName = frame.args[1] return skillDesc(ships[shipName].skill2) end -- ## Equipment ## p['裝備'] = function(frame) local name = frame.args[1] name = fixEquiptName(name) local equipt = equipts[name] if (equipt == nil) then return "'''" .. name .. "'''" end local icon = getEquiptIcon(equipt, '25px') local title = addColor(name, equipt.rarity, true) return icon .. '[[戰艦少女/裝備#' .. name .. '|' .. title .. ']]' end -- {{#invoke:戰艦少女|裝備列表行|裝備類型|裝備名|備註}} p['裝備列表行'] = function(frame) local equiptType = frame.args[1] local equiptName = frame.args[2] local remarks = frame.args[3] local onShip = onShip(equiptName) equiptName = fixEquiptName(equiptName) local equipt = equipts[equiptName] or {} local ret = 'id="' .. equiptName .. '"|' ret = ret .. (equipt.index or ' ') .. '||' .. (equipt.index and getEquiptIcon(equipt, '70px') or ' ') ret = ret .. '||' .. (equipt.rarity and addColor(equiptName, equipt.rarity, true) or "'''" .. equiptName .. "'''") for i, attrName in pairs(equiptDisplay[equiptType]) do ret = ret .. '||' .. formatEquiptListAttr(equiptName, attrName) end ret = ret .. '||' if remarks == '' or remarks == nil then ret = ret .. onShip elseif string.find(remarks, '<自帶>') ~= nil then local z = string.find(remarks, '<自帶>') remarks = string.sub(remarks, 1, z-1) .. onShip .. string.sub(remarks, z+8, -1) ret = ret .. remarks else ret = ret .. remarks end return ret end local attrOrder = { '火力', '魚雷', '裝甲', '對空', '轟炸', '索敵', '對潛', '命中', '迴避', '幸運', '射程', '對空補正', '耗鋁' } p['裝備按鈕'] = function(frame) local equiptName = frame.args[1] if frame.args[2] ~= nil then equiptName = ships[frame.args[1]]['eq' .. frame.args[2]] end local equipt = equipts[equiptName] if equipt == nil then return equiptName end btn = getEquiptIcon(equipt, '25px') .. addColor(equiptName, equipt.rarity, true) ctnt = '' for i, attrName in pairs(attrOrder) do local attrVal = equipt[tr[attrName]] if attrVal ~= 0 and attrVal ~= nil then ctnt = ctnt .. formatEquiptButtonAttr(attrName, attrVal) end end if equipt['special'] ~= nil then ctnt = ctnt .. equipt['special'] end return frame:expandTemplate{ title = 'Toggle', args = { button=btn, content=ctnt } } end -- ## Enemies ## function fixEnemyName(name) name = name:gsub('IV', 'Ⅳ') name = name:gsub('V', 'Ⅴ') name = name:gsub('III', 'Ⅲ') name = name:gsub('II', 'Ⅱ') name = name:gsub('I', 'Ⅰ') return name end p['敵艦列表'] = function(frame) local colors = { 'black', 'green', 'blue', 'purple', 'orange', 'red' } local ret = '' local rec = 0 local aa = 0 local speed = { 0, 0, 0 } local n = { 0, 0, 0 } for i = 1,6 do name = frame.args[i] if name == nil then ret = ret .. '||' else name = fixEnemyName(name) ret = ret .. formatShipTitle(name, 'b') .. '||' local ship = enemies[name] rec = rec + ship.rec aa = aa + ship.aa speed[ship.class] = speed[ship.class] + ship.speed n[ship.class] = n[ship.class] + 1 end end local s = 0 if n[1] == 0 and n[2] == 0 then s = speed[3] / n[3] else s = math.min(speed[1] / n[1], speed[2] / n[2]) end return ret .. rec .. '||' .. math.floor(s) .. '||' .. formatFloat(aa) end -- ## Other ## -- {{#invoke:戰艦少女|自帶|裝備名}} p['自帶'] = function(frame) local equiptName = frame.args[1] return onShip(equiptName) end p['彩色'] = function(frame) local str = frame.args[1] local noBold = frame.args[2] return rainbow(str, noBold == nil) end p['debug'] = function() local frame = { } frame.args = { '胡德·改' } return p['技能描述2'](frame) end return p