local getArgs = require('Module:Arguments').getArgs
local p = {}
local bg = {smile = 'style="background:#FFC1C1"', pure = 'style="background:#C0FFBB"', cool = 'style="background:#B0E2FF"'}
local tx = {smile = '#d1016a', pure = '#2da55a', cool = '#0f98e3'}
local zeros = {[6] = '0', [5] = '00', [4] = '000', [3] = '.000'}
local function split(str)
return mw.text.split(str, ',', true)
end
local function color(max, attr, text)
if tonumber(text) >= max[attr] then
return "||'''<span style='color:" .. tx[attr] .. "'>" .. text .. "</span>'''"
else
return '||' .. text
end
end
local function zero(frame, text)
local len = #text
if zeros[len] then
return frame:expandTemplate{title = '0', args = {zeros[len]}}
else
return ''
end
end
local function lj(text)
return '<span lang=ja>-{' .. text .. '}-</span>'
end
local function img(frame, file, width)
return frame:callParserFunction('#img', {
frame:callParserFunction('filepath', file),
style = 'width:' .. tostring(width) .. 'px'
})
end
local function updateMax(table, attr, value)
table[attr] = math.max(table[attr], tonumber(value) or 0)
end
local function updateMax3(table, table2, table3, attr, value)
local nv = tonumber(value) or 0
if nv > table[attr] then
table3[attr] = table2[attr]
table2[attr] = table[attr]
table[attr] = nv
elseif nv > table2[attr] then
table3[attr] = table2[attr]
table2[attr] = nv
elseif nv > table3[attr] then
table3[attr] = nv
end
end
local function filename(text)
local ext = '.png'
if text:sub(-4) == '.jpg' then
ext = ''
end
return text .. ext
end
local function cf(frame, args)
local hasDiff = args.diff and args.diff ~= ''
local numIn = 8
if hasDiff then
numIn = 9
end
local output = '{|class="wikitable sortable mw-collapsible mw-collapsed" style="text-align:center"\n|-\n!属性!!class=unsortable|封面!!class=unsortable|歌曲名称!!data-sort-type=number|难度!!data-sort-type=number|Combo'
if hasDiff then
output = output .. '!!data-sort-type=number|等效Combo'
end
output = output .. '!!data-sort-type=number|轮次!!class=unsortable|试听'
local attr
local max = {smile = 0, pure = 0, cool = 0}
local max7 = {smile = 0, pure = 0, cool = 0}
for i, v in ipairs(args) do
local r = i % numIn
if r == 1 and v and v ~= '' then
attr = v:lower()
elseif r == 6 then
updateMax(max, attr, v)
elseif r == 7 and hasDiff then
updateMax(max7, attr, v)
end
end
local song
local stage
for i, v in ipairs(args) do
local r = i % numIn
if r == 1 then
if v and v ~= '' then
attr = v:lower()
end
output = output .. '\n|-\n|' .. frame:expandTemplate{title = 'llsifitem', args = {attr, ''}}
elseif r == 2 then
song = v
output = output .. '||' .. img(frame, args['cover' .. tostring((i - 2) / numIn + 1)] or filename(v), 48)
elseif r == 3 then
if v and v ~= '' then
song = v
end
output = output .. '||' .. bg[attr] .. "|'''[[" .. (args['lk' .. tostring((i - 3) / numIn + 1)] or song) .. '|' .. lj(song) .. "]]'''"
elseif r == 4 then
if v and v ~= '' then
output = output .. '(' .. v .. ')'
end
elseif r == 5 then
output = output .. '||' .. img(frame, 'DIFFICULTY ' .. v .. '.png', 32)
elseif r == 6 then
output = output .. color(max, attr, v)
elseif r == numIn - 1 then
if v and v ~= '' then
stage = v
end
output = output .. '||' .. 'data-sort-value=' .. stage .. '|第' .. stage .. '轮'
elseif r == 7 then
output = output .. color(max7, attr, v) .. zero(frame, v)
elseif r == 0 then
if v and v ~= '' then
output = output .. '||[[File:' .. v .. ']]'
else
output = output .. '||待补充'
end
end
end
output = output .. '\n|}'
return output
end
local function token(frame, args)
local singersplit = split(args.singer or '')
local levelsplit = split(args.level or '')
local combosplit = split(args.combo or '')
local output = '{|class=wikitable style="text-align:center"\n|-\n!封面!!名称!!属性!!演唱者!!难度!!星级!!Combo'
if args.song and args.song ~= '' then
output = output .. '!!试听'
end
local difficulty = split(args.diff or '')
local rowspan = '|rowspan=' .. tostring(#difficulty) .. '|'
local lk = '[[' .. (args.lk or args.nm) .. '|'
output = output .. '\n|-\n' .. rowspan .. lk .. img(frame, args.cover or (args.nm .. '.png') , 176) .. ']]|' .. rowspan .. "'''" .. lj(lk .. args.nm .. ']]') .. "'''|" .. rowspan .. frame:expandTemplate{title = 'llsifitem', args = {args.cl, ''}} .. '|' .. rowspan
if (args.logo and args.logo ~= '') or (args.group and args.group ~= '') then
local group = args.group or ''
if args.disambig and args.disambig ~= '' then
group = group .. '(LoveLive!)'
end
output = output .. '[[' .. (args.singer or group) .. '|' .. img(frame, args.logo or (args.group .. 'logo.png'), 72) .. ']]'
else
for i = 1, #singersplit do
output = output .. "'''" .. frame:expandTemplate{title = 'llcoloredlink', args = {singersplit[i]}} .. "'''<br>"
end
end
output = output .. '\n'
for i = 1, #difficulty do
output = output .. '|'
if difficulty[i] ~= difficulty[i - 1] then
if difficulty[i] == difficulty[i + 1] then
output = output .. 'rowspan=2|'
end
output = output .. img(frame, difficulty[i]:upper() .. '.png', 64) .. '||'
end
output = output .. img(frame, 'DIFFICULTY ' .. (levelsplit[i] or '') .. '.png', 32)
if difficulty[i] ~= difficulty[i - 1] then
output = output .. '||'
if difficulty[i] == difficulty[i + 1] then
output = output .. 'rowspan=2|'
end
output = output .. combosplit[i]
end
if i == 1 and args.song and args.song ~= '' then
output = output .. '|' .. rowspan .. '[[File:' .. args.song .. ']]'
end
output = output .. '\n|-\n'
end
output = output .. '|}'
return output
end
local function building(frame, args, n)
local k = tostring(n)
local file = args['building' .. k]
if not file then
file = 'R' .. (args.round or '') .. ' '
if args.cap and args.cap ~= '' then
file = file .. 'Q'
else
file = file .. 'q'
end
file = file .. 'uest building ' .. frame:callParserFunction('padleft', {k, '2'}) .. '.png'
end
return file
end
local function ch(frame, n)
return '第' .. frame:expandTemplate{title = 'zhnum1', args = {n}} .. '章'
end
local function challenge(frame, args, attr)
return '\n|colspan=2|' .. attr:upper() .. '挑战||' .. img(frame, 'Quest challenge building ' .. attr .. '.png', 64) .. '||' .. (args[attr .. '-unlock'] or ch(frame, args[attr .. '-num'])) .. '目标完成'
end
local function as1(frame, args)
local numIn = 7
local output = "{|class='wikitable mw-collapsible mw-collapsed' style='text-align:center'\n|-\n!colspan=3|章节场景!!解锁条件!!colspan=3|歌曲\n|-\n|'''序章'''||" .. lj(args.prelude or '') .. '||' .. img(frame, building(frame, args, 1), 64) .. '||无||colspan=3|无\n|-\n'
local lastChapter = '序章'
local chapter
local song
for i, v in ipairs(args) do
local r = i % numIn
if r == 1 then
if v and v ~= '' then
chapter = v
else
chapter = ch(frame, (i - 1) / numIn + 1)
end
output = output .. "|-\n|'''" .. chapter .. "'''"
elseif r == 2 then
output = output .. '||' .. lj(v) .. '||' .. img(frame, building(frame, args, (i - 2) / numIn + 2), 64)
elseif r == 3 then
output = output .. '||' .. lastChapter .. '完成'
if v and v ~= '' then
output = output .. '<br>累计pt:' .. v
end
lastChapter = chapter .. '目标'
elseif r == 4 then
output = output .. '||'
if v and v ~= '' then
song = v
output = output .. img(frame, args['cover' .. tostring((i - 4) / numIn + 1)] or filename(v), 48)
else
output = output .. 'colspan=3|无\n|-'
end
elseif r == 5 then
output = output .. '||' .. (bg[v:lower()] or ' ')
elseif r == 6 then
local text = song
if v and v ~= '' then
text = v
end
output = output .. "|'''[[" .. (args['lk' .. tostring((i + 1) / numIn)] or text) .. '|' .. lj(text) .. "]]'''"
elseif r == 0 then
output = output .. '||[[File:' .. v .. ']]\n'
end
end
output = output .. challenge(frame, args, 'smile') .. "||style='background:#EEE0E5' colspan=3 rowspan=4|'''见挑战任务 曲池'''\n|-" .. challenge(frame, args, 'cool') .. '\n|-' .. challenge(frame, args, 'pure') .. '\n|-\n|colspan=2|秘密场景||' .. img(frame, 'Quest basic icon secret.png', 64) .. '||随机产生\n|}'
return output
end
local function other(frame, args)
local type = args.type
local difficulty = split(args.diff or '')
local output = '{|class="wikitable sortable mw-collapsible" style="text-align:center"\n|-\n!rowspan=2|属性!!class=unsortable rowspan=2|封面!!colspan=' .. tostring(#difficulty) .. ' class=unsortable|歌曲'
if type ~= 'rc' then
output = output .. '!!rowspan=2 data-sort-type=number|'
if type == 'sm' then
output = output .. '阶段'
elseif type == 'cm' or type == 'mf' or type == 'as2' then
output = output .. 'EXPERT<br>Combo'
end
end
local numIn
if type == 'rc' then
numIn = 6
elseif type == 'sm' then
numIn = 7
elseif difficulty[#difficulty]:lower() == 'master' then
numIn = 9
else
numIn = 7
end
if numIn and numIn > 7 then
output = output .. '!!rowspan=2 data-sort-type=number|MASTER<br>Combo!!rowspan=2 data-sort-type=number|MASTER<br>等效Combo'
end
output = output .. '!!class=unsortable rowspan=2|试听\n|-\n'
for i, v in ipairs(difficulty) do
output = output .. '!class=unsortable|' .. img(frame, v:upper() .. '.png', 64) .. '\n'
end
local na = frame:expandTemplate{title = 'n/a', args = {''}}
if type == 'rc' then
output = output .. '|-\n|' .. na .. '||' .. img(frame, 'omakase! temp.png', 48) .. '||colspan=' .. tostring(#difficulty) .. " style='background:#EEE0E5'|'''" .. lj('おまかせ!') .. "'''||" .. na
end
local attr
local max6 = {smile = 0, pure = 0, cool = 0}
local max7 = {smile = 0, pure = 0, cool = 0}
local max8 = {smile = 0, pure = 0, cool = 0}
local max26 = {smile = 0, pure = 0, cool = 0}
local max36 = {smile = 0, pure = 0, cool = 0}
local max27 = {smile = 0, pure = 0, cool = 0}
local max37 = {smile = 0, pure = 0, cool = 0}
local max28 = {smile = 0, pure = 0, cool = 0}
local max38 = {smile = 0, pure = 0, cool = 0}
if type == 'mf' then
for i, v in ipairs(args) do
local r = i % numIn
if r == 1 and v and v ~= '' then
attr = v:lower()
elseif r == 6 then
updateMax3(max6, max26, max36, attr, v)
elseif r == 7 then
updateMax3(max7, max27, max37, attr, v)
elseif r == 8 then
updateMax3(max8, max28, max38, attr, v)
end
end
elseif type ~= 'sm' and type ~= 'rc' then
for i, v in ipairs(args) do
local r = i % numIn
if r == 1 and v and v ~= '' then
attr = v:lower()
elseif r == 6 then
updateMax(max6, attr, v)
elseif r == 7 then
updateMax(max7, attr, v)
elseif r == 8 then
updateMax(max8, attr, v)
end
end
end
local song
local diffMin = 0
local diffMax = 0
local stage
for i, v in ipairs(args) do
local r = i % numIn
if r == 1 then
if v and v ~= '' then
attr = v:lower()
end
output = output .. '\n|-\n|' .. frame:expandTemplate{title = 'llsifitem', args = {attr, ''}}
elseif r == 2 then
song = v
output = output .. '||' .. img(frame, args['cover' .. tostring((i - 2) / numIn + 1)] or filename(v), 48)
elseif r == 3 then
diffMin = tonumber(v) or 0
if diffMin > 0 then
output = output .. '||colspan=' .. tostring(diffMin) .. '| '
end
elseif r == 4 then
diffMax = ((tonumber(v) or 0) + #difficulty - 1) % #difficulty + 1
output = output .. '||colspan=' .. tostring(diffMax - diffMin) .. ' ' .. bg[attr] .. '|'
elseif r == 5 then
if v and v ~= '' then
song = v
end
local k = tostring((i - 5) / numIn + 1)
output = output .. "'''[[" .. (args['lk' .. k] or song) .. '|' .. lj(song) .. "]]'''" .. (args['comment' .. k] or '')
if diffMax < #difficulty then
output = output .. '||colspan=' .. tostring(#difficulty - diffMax) .. '| '
end
elseif r == 6 then
if type == 'sm' then
if v and v ~= '' then
stage = v
end
output = output .. '||data-sort-value=' .. stage .. '|'
if stage == '1' then
output = output .. '前期'
elseif args['2stage'] and args['2stage'] ~= '' then
output = output .. '后期'
else
output = output .. '中期'
end
elseif type == 'cm' or type == 'as2' then
output = output .. color(max6, attr, v)
elseif type == 'mf' then
output = output .. color(max36, attr, v)
end
elseif r == 7 then
if type == 'cm' or type == 'as2' then
output = output .. color(max7, attr, v)
elseif type == 'mf' then
output = output .. color(max37, attr, v)
end
elseif r == 8 then
if type == 'cm' or type == 'as2' then
output = output .. color(max8, attr, v)
elseif type == 'mf' then
output = output .. color(max38, attr, v)
end
output = output .. zero(frame, v)
elseif r == 0 then
if v and v ~= '' then
output = output .. '||[[File:' .. v .. ']]'
else
output = output .. '||待补充'
end
end
end
output = output .. '\n|}'
return output
end
function p.main(frame)
local args = getArgs(frame, {removeBlanks = false})
local type = args.type
if type == 'cf' then
return cf(frame, args)
elseif type == 'token' then
return token(frame, args)
elseif type == 'as1' then
return as1(frame, args)
end
return other(frame, args)
end
return p