Módulo:BossSkills

De Wiki Gla
Ir para navegação Ir para pesquisar

A documentação para este módulo pode ser criada em Módulo:BossSkills/doc

--[[
Módulo:BossSkills — Gera HTML de habilidades para bosses (Weekly/World).

Uso via predefinição (recomendado):
  {{BossSkills|module=Boss.Gedatsu|lang=pt}}

Uso direto (sem predefinição):
  {{#invoke:BossSkills|main|module=Boss.Gedatsu|lang=en}}
  {{#widget:BossSkills}}

Parâmetros:
  |module=      (obrigatório) Nome do módulo do boss (ex: Boss.Gedatsu)
  |lang=        (opcional) Idioma: pt, en, es, pl. Padrão: pt

O módulo do boss (ex: Módulo:Boss.Gedatsu) deve retornar:
  {
    order       = { "Skill1", "Skill2" },
    skills = {
      ["Skill1"] = {
        icon     = "Skill1-Icon.png",
        name_i18n = { pt = "Skill 1", en = "Skill 1", pl = "Umiejętność 1" }, -- opcional
        cooldown = { pt = "10s", en = "10s", pl = "10s" }, -- opcional (aceita string)
        video    = "Skill1-Video.mp4",
        desc     = { pt = "...", en = "...", pl = "..." },
      },
    },
  }
]]

local p = {}

local function trim(s)
    return (tostring(s or ""):gsub("^%s+", ""):gsub("%s+$", ""))
end

local function normalizeLang(raw)
    local code = mw.ustring.lower(trim(raw or "pt")):match("^([a-z][a-z])") or "pt"
    if code == "pt" or code == "en" or code == "es" or code == "pl" then
        return code
    end
    return "pt"
end

local function pickI18nValue(v)
    if type(v) == "table" then
        return {
            pt = trim(v.pt or ""),
            en = trim(v.en or ""),
            es = trim(v.es or ""),
            pl = trim(v.pl or "")
        }
    end
    local single = trim(v or "")
    return {
        pt = single,
        en = "",
        es = "",
        pl = ""
    }
end

local function fileURL(name)
    name = trim(name)
    if name == "" then return "" end
    name = name:gsub("^Arquivo:", ""):gsub("^File:", "")
    local t = mw.title.new("Special:FilePath/" .. name)
    if t then
        local u = t:fullUrl()
        if u and u ~= "" then return u end
    end
    local t2 = mw.title.new("Especial:FilePath/" .. name)
    if t2 then
        local u = t2:fullUrl()
        if u and u ~= "" then return u end
    end
    return ""
end

local function loadBossModule(moduleName)
    local ok, data = pcall(require, "Módulo:" .. moduleName)
    if ok and type(data) == "table" then return data end
    ok, data = pcall(require, "Module:" .. moduleName)
    if ok and type(data) == "table" then return data end
    return nil
end

function p.main(frame)
    local parent = frame:getParent() or frame
    local args = parent.args or {}

    local moduleName = trim(args.module or "")
    if moduleName == "" then
        return "<!-- BossSkills: |module= é obrigatório -->"
    end

    local data = loadBossModule(moduleName)
    if not data then
        return "<!-- BossSkills: módulo '" .. moduleName .. "' não encontrado -->"
    end
    if not data.order or not data.skills then
        return "<!-- BossSkills: módulo '" .. moduleName .. "' sem order/skills -->"
    end

    -- Idioma (pt padrão)
    local lang = normalizeLang(args.lang or "pt")

    local html = mw.html.create('div')
    local box = html:tag('div'):addClass('boss-box')
        :attr('data-lang', lang)

    -- Skills container
    local skillsSection = box:tag('div'):addClass('boss-skills-section')

    -- Barra de ícones
    local iconRail = skillsSection:tag('div'):addClass('boss-rail')
    local scrollWrap = iconRail:tag('div'):addClass('boss-icon-scroll')
    local iconBar = scrollWrap:tag('div'):addClass('boss-icon-bar')

    -- Grid: descrição + vídeo
    local grid = skillsSection:tag('div'):addClass('boss-content-card boss-skills-grid')
    local details = grid:tag('div'):addClass('boss-details')
    local descBox = details:tag('div'):addClass('boss-desc-box')
    grid:tag('div'):addClass('boss-video-container')

    local idx = 0
    for _, skillName in ipairs(data.order) do
        local sk = data.skills[skillName]
        if type(sk) == "table" then
            idx              = idx + 1

            local icon       = trim(sk.icon or "")
            local video      = trim(sk.video or "")

            -- Nome i18n (fallback: chave da skill)
            local namePack   = {
                pt = trim(skillName),
                en = trim(skillName),
                es = trim(skillName),
                pl = trim(skillName)
            }
            local customName = sk.name_i18n or sk.name
            if customName ~= nil then
                local n = pickI18nValue(customName)
                if n.pt ~= "" then namePack.pt = n.pt end
                if n.en ~= "" then namePack.en = n.en end
                if n.es ~= "" then namePack.es = n.es end
                if n.pl ~= "" then namePack.pl = n.pl end
            end

            -- Cooldown i18n (pode ser string ou tabela)
            local cdPack = pickI18nValue(sk.cooldown)

            -- Descrição i18n
            local descPack = pickI18nValue(sk.desc)

            local iconEl = iconBar:tag('div')
                :addClass('boss-skill-icon')
                :attr('data-index', idx)
                :attr('data-name-pt', namePack.pt)
                :attr('data-name-en', namePack.en)
                :attr('data-name-es', namePack.es)
                :attr('data-name-pl', namePack.pl)
                :attr('data-cd-pt', cdPack.pt)
                :attr('data-cd-en', cdPack.en)
                :attr('data-cd-es', cdPack.es)
                :attr('data-cd-pl', cdPack.pl)
                :attr('data-video', video ~= "" and fileURL(video) or "")
                :attr('data-video-file', video)
                :attr('data-desc-pt', descPack.pt)
                :attr('data-desc-en', descPack.en)
                :attr('data-desc-es', descPack.es)
                :attr('data-desc-pl', descPack.pl)

            if idx == 1 then
                iconEl:addClass('active')
            end

            if icon ~= "" then
                iconEl:wikitext(string.format(
                    '[[Arquivo:%s|class=boss-skill-icon-img|link=]]', icon
                ))
            end

            descBox:tag('div'):addClass('boss-skill-desc-slot')
                :attr('data-index', idx)
        end
    end

    return tostring(html)
end

return p