此处为全站公告,通常对读者进行申明或对该WIKI某些规则进行公告,请在确认后修改本通告。本WIKI编辑权限开放,欢迎收藏起来防止迷路,也希望有爱的小伙伴和我们一起编辑哟~

全站通知:

模块:Potential

来自星塔旅人WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

此模块的文档可以在模块:Potential/doc创建

local p = {}

    local function formatSkillDesc(desc)
        if not desc then return "" end
        desc = tostring(desc)
        desc = desc:gsub("\\u000b", "<br>")
        desc = desc:gsub(string.char(11), "<br>")
        desc = desc:gsub("##([^#]+)#%d+#", "%1")
        desc = desc:gsub("<color=(#?[%w]+)>(.-)</color>", '<span style="color:%1;">%2</span>')
        return desc
    end

    local function formatParamValue(v)
        if v == nil then return "" end
        local num = tonumber(v)
        if not num then
            return tostring(v)
        end
        if num > 10000 then
            local p = num / 10000
            local s = string.format("%.2f", p)
            s = s:gsub("%.00$", ""):gsub("(%..-)0+$", "%1")
            return s .. "%"
        end
        if math.floor(num) == num then
            return tostring(math.floor(num))
        else
            return tostring(num)
        end
    end

        local function canonicalize_key(k)
            if not k then return "" end
            local s = tostring(k):lower()
            s = s:gsub("%W+", "")
            local prefix, digits = s:match("^(%a+)(%d*)$")
            if prefix then
                if digits ~= "" then
                    local n = tonumber(digits)
                    if n then digits = tostring(n) end
                    return prefix .. digits
                else
                    return prefix
                end
            end
            return s
        end

        local function findKey(tbl, key)
            if not tbl then return nil, nil end
            local target = canonicalize_key(key)
            for k, v in pairs(tbl) do
                if canonicalize_key(k) == target then
                    return k, v
                end
            end
            return nil, nil
        end

        local function getField(tbl, key)
            if not tbl then return nil end
            local _, v = findKey(tbl, key)
            return v
        end

function p.main(frame)
    local args = frame.args
    local char = args[1]
    local PotentialType = args[2]


    local IdTitle = mw.title.new('Mediawiki:Char.json')
    local itemcontent = IdTitle and IdTitle:getContent() or nil
    local IdData = mw.text.jsonDecode(itemcontent)
    local id = tostring(IdData[char])
    if not id then
        return "角色不存在"
    end

    local title = mw.title.new('Mediawiki:char/' .. id .. '.json')
    local content = title and title:getContent() or nil
    local data = mw.text.jsonDecode(content or '{}')

    local function parsePotential(pt)
        if not pt then return nil end
        local s = tostring(pt)
        s = s:gsub("%s+", "")
        s = s:lower()
        if s == "潜能1" or s == "1" or s == "build1" then return 1 end
        if s == "潜能2" or s == "2" or s == "build2" then return 2 end
        if s == "潜能3" or s == "3" or s == "build3" then return 3 end
        if s == "潜能4" or s == "4" or s == "build4" then return 4 end
        if s == "潜能5" or s == "5" or s == "build5" then return 5 end
        if s == "潜能6" or s == "6" or s == "build6" then return 6 end
        if s == "潜能7" or s == "7" or s == "build7" then return 7 end
        if s == "潜能8" or s == "8" or s == "build8" then return 8 end
        if s == "潜能9" or s == "9" or s == "build9" then return 9 end
        if s == "潜能10" or s == "10" or s == "build10" then return 10 end
        if s == "潜能11" or s == "11" or s == "build11" then return 11 end
        if s == "潜能12" or s == "12" or s == "build12" then return 12 end
        if s == "潜能13" or s == "13" or s == "build13" then return 13 end
        if s == "潜能14" or s == "14" or s == "build14" then return 14 end
        if s == "潜能15" or s == "15" or s == "build15" then return 15 end
        if s == "潜能16" or s == "16" or s == "build16" then return 16 end
        if s == "潜能17" or s == "17" or s == "build17" then return 17 end
        if s == "潜能18" or s == "18" or s == "build18" then return 18 end
        if s == "潜能19" or s == "19" or s == "build19" then return 19 end
        if s == "潜能20" or s == "20" or s == "build20" then return 20 end
        if s == "潜能21" or s == "21" or s == "build21" then return 21 end
        if s == "潜能22" or s == "22" or s == "build22" then return 22 end
        if s == "潜能23" or s == "23" or s == "build23" then return 23 end
        if s == "潜能24" or s == "24" or s == "build24" then return 24 end
        if s == "潜能25" or s == "25" or s == "build25" then return 25 end
        if s == "潜能26" or s == "26" or s == "build26" then return 26 end
        if s == "潜能27" or s == "27" or s == "build27" then return 27 end
        if s == "潜能28" or s == "28" or s == "build28" then return 28 end
        if s == "潜能29" or s == "29" or s == "build29" then return 29 end
         return nil
     end

    if not data or not data.Potential then
        return "无潜能数据"
    end

    local ptypeClean = tostring(PotentialType or ""):gsub("%s+", "")
    if ptypeClean == "主控描述1" then
        local ms = getField(data.Potential, "MainSkill")
        local v = getField(ms, "Build1_Desc") or getField(ms, "Build1Desc")
        return formatSkillDesc(v)
    elseif ptypeClean == "主控描述2" then
        local ms = getField(data.Potential, "MainSkill")
        local v = getField(ms, "Build2_Desc") or getField(ms, "Build2Desc")
        return formatSkillDesc(v)
    elseif ptypeClean == "援护描述1" then
        local ss = getField(data.Potential, "SupportSkill")
        local v = getField(ss, "Build1_Desc") or getField(ss, "Build1Desc")
        return formatSkillDesc(v)
    elseif ptypeClean == "援护描述2" then
        local ss = getField(data.Potential, "SupportSkill")
        local v = getField(ss, "Build2_Desc") or getField(ss, "Build2Desc")
        return formatSkillDesc(v)
    end

    local pIndex = parsePotential(PotentialType)
    if not pIndex then
        return ""
    end

    local mainSkill = getField(data.Potential, "MainSkill")
    local build = getField(mainSkill, "Build1")
    local build2 = getField(mainSkill, "Build2")
    local build3 = getField(mainSkill, "Build3")
    local common = getField(data.Potential, "CommonSkill")
    local support = getField(data.Potential, "SupportSkill")
    local supportBuild1 = getField(support, "Build1")
    local supportBuild2 = getField(support, "Build2")
    local supportBuild3 = getField(support, "Build3")

    local targetBuild = build
    local baseIndex = pIndex
    if pIndex >= 6 and pIndex <= 10 then
        if not build2 then
            return "无 Build2 数据"
        end
        targetBuild = build2
        baseIndex = pIndex - 5
    elseif pIndex >= 11 and pIndex <= 13 then
        if not build3 then
            return "无 Build3 数据"
        end
        targetBuild = build3
        baseIndex = pIndex - 8
    elseif pIndex >= 14 and pIndex <= 16 then
        if not common then
            return "无 CommonSkill 数据"
        end
        targetBuild = common
        baseIndex = pIndex - 10
    elseif pIndex >= 17 and pIndex <= 21 then
        if not supportBuild1 then
            return "无 SupportSkill Build1 数据"
        end
        targetBuild = supportBuild1
        baseIndex = pIndex - 16
    elseif pIndex >= 22 and pIndex <= 26 then
        if not supportBuild2 then
            return "无 SupportSkill Build2 数据"
        end
        targetBuild = supportBuild2
        baseIndex = pIndex - 21
    elseif pIndex >= 27 and pIndex <= 29 then
        if not supportBuild3 then
            return "无 SupportSkill Build3 数据"
        end
        targetBuild = supportBuild3
        baseIndex = pIndex - 24
    end

    local skill = nil
    if pIndex >= 14 and pIndex <= 16 then
        if pIndex == 14 then
            skill = getField(common, "Skill01")
        elseif pIndex == 15 then
            skill = getField(common, "Skill02")
        else
            skill = getField(common, "Skill03")
        end
    else
        if baseIndex == 1 then
            skill = getField(targetBuild, "Skill01")
        elseif baseIndex == 2 then
            skill = getField(targetBuild, "Skill02")
        elseif baseIndex == 3 then
            for k, v in pairs(targetBuild or {}) do
                if type(k) == "string" then
                    local ck = canonicalize_key(k)
                    if ck:match("^skill%d+") then
                        if type(v) == "table" then
                            local rareVal = tonumber(getField(v, "rare") or getField(v, "Rare") or getField(v, "rarity") or v.rare)
                            if rareVal == 2 then
                                skill = v
                                break
                            end
                        end
                    end
                end
            end
            if not skill then
                skill = getField(targetBuild, "Skill03") or getField(targetBuild, "Skill3")
            end
        elseif baseIndex == 4 or baseIndex == 5 then
            local candidates = {}
            for k, v in pairs(targetBuild or {}) do
                if type(k) == "string" then
                    local ck = canonicalize_key(k)
                    if ck:match("^skill%d+") then
                        if type(v) == "table" then
                            local rareVal = tonumber(getField(v, "rare") or getField(v, "Rare") or getField(v, "rarity") or v.rare)
                            if rareVal == 3 then
                                table.insert(candidates, v)
                            end
                        end
                    end
                end
            end
            if #candidates == 0 then
                local f1 = getField(targetBuild, "Skill04") or getField(targetBuild, "Skill4")
                local f2 = getField(targetBuild, "Skill05") or getField(targetBuild, "Skill5")
                if f1 then table.insert(candidates, f1) end
                if f2 then table.insert(candidates, f2) end
            end
            if baseIndex == 4 then
                skill = candidates[1]
            else
                skill = candidates[2]
            end
        end
    end

    if not skill then
        local buildName = "Unknown"
        if targetBuild == build then buildName = "Build1"
        elseif targetBuild == build2 then buildName = "Build2"
        elseif targetBuild == build3 then buildName = "Build3"
        elseif targetBuild == common then buildName = "CommonSkill"
        elseif targetBuild == supportBuild1 then buildName = "SupportSkill Build1"
        elseif targetBuild == supportBuild2 then buildName = "SupportSkill Build2"
        elseif targetBuild == supportBuild3 then buildName = "SupportSkill Build3" end
        return "无 " .. buildName .. " 中的 skill0" .. tostring(baseIndex) .. " 数据"
    end
    local name = getField(skill, "name") or getField(skill, "Name") or ""
    local descTemplate = getField(skill, "desc") or getField(skill, "Desc") or ""
    local iconPath = getField(skill, "icon") or getField(skill, "Icon") or ""
    local iconFile = iconPath:match("([^/\\]+)$") or iconPath
    if iconFile ~= "" and not iconFile:match("%.") then
        iconFile = iconFile .. ".png"
    end

    local maxLv = 1
    for k, v in pairs(skill or {}) do
        local ck = canonicalize_key(k)
        local pn = ck:match("^param(%d+)$")
        if pn then
            if type(v) == "table" then
                maxLv = math.max(maxLv, #v)
            else
                maxLv = math.max(maxLv, 1)
            end
        end
    end

    local layoutIndex = baseIndex
    if pIndex >= 14 and pIndex <= 16 then
        layoutIndex = 4
    end

    local showOnlyLv1 = (layoutIndex >= 3 and layoutIndex <= 5 and maxLv == 1)

    local descs = {}
    for lv = 1, maxLv do
        local d = descTemplate

        d = d:gsub("&Param(%d+)&([^&<]*)", function(paramNumStr, afterText)
            local paramKey = "Param" .. paramNumStr
            local val = getField(skill, paramKey)
            if not val then
                return "&Param" .. paramNumStr .. "&" .. (afterText or "")
            end

            local value
            if type(val) == "table" then
                if #val >= lv then
                    value = val[lv]
                else
                    value = val[#val]
                end
            else
                value = val
            end

            if value == nil then
                return "&Param" .. paramNumStr .. "&" .. (afterText or "")
            end

            local num = tonumber(value)
            if num then
                local hasSeconds = (afterText or ""):match("^秒")
                if num > 10000 then
                    local p = num / 10000
                    if hasSeconds then
                        return string.format("%g", p) .. (afterText or "")
                    else
                        return string.format("%g%%", p) .. (afterText or "")
                    end
                else
                    if math.floor(num) == num then
                        return tostring(math.floor(num)) .. (afterText or "")
                    else
                        local s = tostring(num)
                        s = s:gsub("(%..-)0+$", "%1")
                        s = s:gsub("%.0+$", "")
                        return s .. (afterText or "")
                    end
                end
            else
                return tostring(value) .. (afterText or "")
            end
        end)

        d = formatSkillDesc(d)
        descs[#descs + 1] = d
    end

    local htmlParts = {}
    local containerClass = "sora_sora_Potential_SkillCard_ex"
    local bgFile = "潜能_bg_6.png"
    local pinkHtml = '<div class="sora_sora_Potential_SkillCard_pink"><div class="sora_sora_Potential_SkillCard_pinkImg">[[file:潜能_bg_6.1.png|link=]]</div>' .. '[[file:' .. iconFile .. '|link=|class=SkillCard_pink_icon]]' .. '</div>'

    if layoutIndex == 3 then
        containerClass = "sora_sora_Potential_SkillCard"
        bgFile = "潜能_bg_5.png"
        pinkHtml = '<div class="sora_sora_Potential_SkillCard_pink" style="z-index:2;">[[file:' .. iconFile .. '|link=|class=SkillCard_pink_icon]]</div>'
    elseif layoutIndex == 4 or layoutIndex == 5 then
        containerClass = "sora_sora_Potential_SkillCard"
        bgFile = "潜能_bg_4.png"
        pinkHtml = '<div class="sora_sora_Potential_SkillCard_pink" style="z-index:2;">[[file:' .. iconFile .. '|link=|class=SkillCard_pink_icon]]</div>'
    end

    showOnlyLv1 = (layoutIndex >= 3 and layoutIndex <= 5 and maxLv == 1)

    htmlParts[#htmlParts + 1] = '<div class="' .. containerClass .. '">'
    htmlParts[#htmlParts + 1] = '<div class="sora_sora_Potential_SkillCard_pinkBg">[[file:' .. bgFile .. '|link=]]</div>'
    htmlParts[#htmlParts + 1] = pinkHtml
    htmlParts[#htmlParts + 1] = '<div class="sora_sora_Potential_SkillCard_txt">'
    htmlParts[#htmlParts + 1] = '<div class="sora_sora_Potential_SkillCard_name">' .. name .. '</div>'

    if showOnlyLv1 then
        htmlParts[#htmlParts + 1] = '<div class="sora_sora_Potential_SkillCard_lv">等级1</div>'
        htmlParts[#htmlParts + 1] = '<div class="sora_sora_Potential_SkillCard_desc" data-lv="1">' .. (descs[1] or "") .. '</div>'
    else
        for lv = 1, #descs do
            local lvTxt = string.format('<div class="sora_sora_Potential_SkillCard_lv">等级%d</div>', lv)
            local style = ""
            if lv > 1 then style = ' style="display:none"' end
            local descDiv = string.format('<div class="sora_sora_Potential_SkillCard_desc" data-lv="%d"%s>%s</div>', lv, style, descs[lv] or "")
            if lv == 1 then
                htmlParts[#htmlParts + 1] = lvTxt
            else
                htmlParts[#htmlParts + 1] = string.format('<div class="sora_sora_Potential_SkillCard_lv" data-lv="%d"%s>等级%d</div>', lv, style, lv)
            end
            htmlParts[#htmlParts + 1] = descDiv
        end
    end

    htmlParts[#htmlParts + 1] = '</div></div>'

    return table.concat(htmlParts, "")
end

return p