置顶公告:【置顶】关于临时开启评论区所有功能的公告(2022.10.22) | 【置顶】关于本站Widget恢复使用的公告
  • 你好~!欢迎来到萌娘百科镜像站!如需查看或编辑,请联系本站管理员注册账号。
  • 本镜像站和其他萌娘百科的镜像站无关,请注意分别。

Module:FGONoblePhantasm

贴贴♀百科,万娘皆可贴的百科全书!转载请标注来源页面的网页链接,并声明引自贴贴百科。内容不可商用。
跳到导航 跳到搜索
Template-info.svg 模块文档  [创建] [刷新]
-- 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 == '&empty;' 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