-- Originally designed and coded by Maya (U:MJH) -- Special thanks to U:空识珈蓝 for styling supports and bug fixes ♡ local getArgs = require("Module:Arguments").getArgs local cards = require("Module:FGOCards").tableToCards local palettes = { Quick = { grid = '#01460A', cellLight = 'rgba(10,123,28,.75)', cellDark = 'rgba(6,90,21,.2)', backTop = '#0A7B1C', backBottom = '#065A15', textBorder = '#6DCF2D' }, Arts = { grid = '#121F5D', cellLight = 'rgba(37,56,152,.75)', cellDark = 'rgba(24,36,108,.2)', backTop = '#2A35A2', backBottom = '#18246C', textBorder = '#2C9FEE' }, Buster = { grid = '#590F0C', cellLight = 'rgba(155,47,31,.75)', cellDark = 'rgba(83,24,16,.2)', backTop = '#7A120C', backBottom = '#A71E16', textBorder = '#FD2F08' }, Extra = { grid = '#515151', cellLight = 'rgba(216,224,233,.75)', cellDark = 'rgba(160,176,193,.2)', backTop = '#F1F1F9', backBottom = '#656D7D', textBorder = '#FFFFFF' } } local getAllRoundShadow = function (color, width) local wp = width .. 'px ' local wn = (-width) .. 'px ' return wp .. '0 0 ' .. color .. ',' .. wn .. '0 0 ' .. color .. ',0 ' .. wp .. '0 ' .. color .. ',0 ' .. wn .. '0 ' .. color .. ',' .. wp .. wp .. '0 ' .. color .. ',' .. wn .. wn .. '0 ' .. color .. ',' .. wp .. wn .. '0 ' .. color .. ',' .. wn .. wp .. '0 ' .. color .. ',' end local getCardBoxStyle = function (palette) return 'border:2px solid #CCC;border-image:linear-gradient(#FFF390, #BC854D) 1;' .. 'background:repeating-linear-gradient(45deg,' .. palette.grid .. ' 0 1px, rgba(0,0,0,0) 1px 15px),' .. 'repeating-linear-gradient(-45deg,' .. palette.grid .. ' 0 1px, rgba(0,0,0,0) 1px 15px),' .. 'repeating-linear-gradient(45deg,' .. palette.cellLight .. ' 0 15px,' .. palette.cellDark .. ' 15px 30px),' .. 'repeating-linear-gradient(-45deg,'.. palette.cellLight .. ' 0 15px,' .. palette.cellDark .. ' 15px 30px),' .. 'linear-gradient(' .. palette.backTop .. ',' .. palette.backBottom .. ');' end local getGradientShade = function (str, overallStyle, shadeStyle, gradStyle, paddingTop) return '<div style="position:relative;width:100%;color:transparent;' .. overallStyle .. '">' .. str .. '<div style="position:absolute;left:0px;top:' .. (paddingTop or 0) .. 'px;width:100%;' .. shadeStyle .. '">' .. str .. '</div>' .. '<div style="position:absolute;left:0px;top:' .. (paddingTop or 0) .. 'px;width:100%;"><span style="' .. gradStyle .. '">' .. str .. '</span></div></div>' end local getNPNameBox = function (args) local palette = palettes[args['卡色']] local shadeStyle = 'color:gold;text-shadow:' .. getAllRoundShadow('#000', 1) .. getAllRoundShadow(palette.textBorder, 2) .. '3px 3px 3px black,-3px -3px 3px black;' local gradientStyle = 'background:linear-gradient(#FCF7A1 0% 50%,#AE7C3C 70% 100%);' .. '-webkit-background-clip:text;box-decoration-break:clone;-webkit-box-decoration-break:clone;color:transparent;' local nameContent = getGradientShade(args['国服上标'] or '', 'padding-top:10px;', shadeStyle, gradientStyle, 10) .. getGradientShade(args['中文名'] or '', 'font-size:125%;padding-bottom:15px;', shadeStyle, gradientStyle, 0) return '<div class="nomobile" style="font-size:20px;line-height:2em;' .. getCardBoxStyle(palette, '') .. '">' .. nameContent .. '</div>' .. '<div class="mobileonly" style="line-height:2em;' .. getCardBoxStyle(palette, '') .. '">' .. nameContent .. '</div>' end local getNPJaEnCell = function (args) local npJa = '-{<span style="font-size:80%">' .. (args['日服上标'] and args['日服上标'] .. '</span><br>' or '</span>') .. (args['日文名'] or '') .. '}-' if (args['英文名']) then return 'style="padding:0;"|' .. '<div style="width:100%;background:#CCC;><div class="Tabs" data-text-background-color="#F8F9FA" data-label-padding="0" data-text-padding="0.2em 0.4em" ' .. 'data-label-border-color="transparent" data-text-border-color="transparent" data-label-background-color="#F8F9FA" data-label-color="transparent">' .. '<div class="Tab"><div class="TabLabelText" style="line-height:2em;font-size:14px;width:50%;box-sizing:border-box;">日文</div>' .. '<div class="TabContentText" lang="ja">' .. npJa .. '</div></div>' .. '<div class="Tab"><div class="TabLabelText" style="line-height:2em;font-size:14px;width:50%;box-sizing:border-box;">英文</div>' .. '<div class="TabContentText">' .. args['英文名'] .. '</div></div></div></div>' else return '|' .. npJa end end local NPSteps = { 4, 6, 7 } local getSkillValue = function (s) if mw.ustring.sub(s, 1, 4) == 'val:' then return nil, mw.ustring.sub(s, 5, -1) end local n = tonumber(s) if n then return n end local ssub = mw.ustring.sub(s, 1, -2) n = tonumber(ssub) if n then return n, mw.ustring.sub(s, -1, -1) end if s == '∅' or s == '∅' then return nil, '∅' end end local getRoundValue = function (s) if mw.ustring.sub(s, 1, 6) == 'round:' then return mw.ustring.sub(s, 7, -1) end end local roundTo = function (n, to) if not tonumber(to) then return n end local mult = 10 ^ to return math.floor(n * mult + 0.5) / mult end local examineCondition = function (s) local retobj = {} if mw.ustring.match(s, '宝具升级') then retobj.NP = true end if mw.ustring.match(s, 'Over Charge') then retobj.OC = true end if retobj.NP and retobj.OC then error('同一效果只能受宝具升级和Over Charge之一影响,请拆分效果描述') end return retobj end local packSkillArgs = function (args, startIdx) local retobj = {} local addingobj = nil -- Pack forargs local funcTrick = args['funcTrick'] local funcTrickTbl = {} mw.ustring.gsub(funcTrick, '([^;]*);', function (s) table.insert(funcTrickTbl, s) end) for i = 1, #funcTrickTbl do addingobj = { name = args['效果' .. funcTrickTbl[i]] } for j = 1, 5 do if args['数值' .. funcTrickTbl[i] .. j] then local val, suffix = getSkillValue(args['数值' .. funcTrickTbl[i] .. j]) if val or suffix then table.insert(addingobj, { val = val, suffix = suffix }) end end end table.insert(retobj, addingobj) end -- Pack fornumargs addingobj = nil i = startIdx while args[i] do if args[i] ~= '' then local val, suffix = getSkillValue(args[i]) if not val and not suffix then local round = getRoundValue(args[i]) if round then addingobj.round = round else if addingobj then table.insert(retobj, addingobj) end addingobj = {} addingobj.name = args[i] end else table.insert(addingobj, { val = val, suffix = suffix }) end end i = i + 1 end if addingobj then table.insert(retobj, addingobj) end return retobj end local expandSkillArg = function (skillArg) if #skillArg == 5 then return skillArg end if #skillArg == 1 then return skillArg end if #skillArg == 0 then skillArg[1] = { suffix = '∅' } return skillArg end if #skillArg ~= 2 then error('宝具数值参数数量有误。应为0个、1个、2个或5个,实为' .. #skillArg .. '个') end if skillArg[1].suffix ~= skillArg[2].suffix then error('宝具数值参数单位不匹配,其一为' .. skillArg[1].suffix .. ',另一为' .. skillArg[2].suffix) end local skillCond = examineCondition(skillArg.name) skillArg[5] = skillArg[2] local skillDiff = (skillArg[2].val - skillArg[1].val) / 8 if skillCond.NP then for i = 1, 3 do skillArg[i+1] = { val = roundTo(skillArg[1].val + skillDiff * NPSteps[i], skillArg.round), suffix = skillArg[1].suffix } end elseif skillCond.OC then for i = 1, 3 do skillArg[i+1] = { val = roundTo(skillArg[1].val + skillDiff * 2 * i, skillArg.round), suffix = skillArg[1].suffix } end else error('不随宝具升级和Over Charge提升的宝具效果不应使用数值延拓') end return skillArg end local formatSkillArg = function (val, suffix) if not val then return suffix else return val .. (suffix or '') end end local generateTable = function (args, skillArgs) local rank = args['阶级'] or "" local type = args['种类'] or "" local color = args['卡色'] or "Extra" local iconspan = 2 + 2 * #skillArgs local iconstr = cards({color}, 80) .. '<br>' .. rank .. '<br>' .. type local retstr = '{| class="wikitable" style="text-align:center;line-height:1.75em;display:table;max-width:100%;' .. [[-ms-text-size-adjust:none;-webkit-text-size-adjust:none;" ! rowspan="]] .. iconspan .. '" style="width:160px;max-width:20%" class="nomobile" |' .. iconstr .. [[ ! rowspan="2" class="mobileonly" |]] .. iconstr .. [[ ! colspan="5" style="width:640px;max-width:100%;padding:0;" |]] .. getNPNameBox(args) .. [[ |- | colspan="5" lang="ja" ]] .. getNPJaEnCell(args) for i = 1, #skillArgs do retstr = retstr .. [[ |- ! colspan="5" |]] .. skillArgs[i].name .. [[ |-]] if #(skillArgs[i]) > 1 then for j = 1, #(skillArgs[i]) do retstr = retstr .. [[ | style="width:128px;max-width:16%" |]] .. formatSkillArg(skillArgs[i][j].val, skillArgs[i][j].suffix) end else retstr = retstr .. [[ | colspan="5" |]] .. formatSkillArg(skillArgs[i][1].val, skillArgs[i][1].suffix) end end retstr = retstr .. [[ |}]] return retstr end local FGONoblePhantasm = { main = function (frame) local args = getArgs(frame, { removeBlanks = false }) local skillArgs = packSkillArgs(args, 1) for i = 1, #skillArgs do skillArgs[i] = expandSkillArg(skillArgs[i]) end return generateTable(args, skillArgs) end } return FGONoblePhantasm