Mudanças entre as edições de "Módulo:Gb"

De Wiki Gla
Ir para navegação Ir para pesquisar
 
(44 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
Linha 1: Linha 1:
-- Módulo:BossDisplay (responsivo)
local p = {}
local p = {}


-- === Utilidades ===
function p.bossInfo(frame)
    local args = frame:getParent().args


local function trim(s)
    local function g(k, default)
    if type(s) ~= "string" then
        return mw.text.trim(args[k] or "") ~= "" and args[k] or default
        return s
     end
     end
    return mw.text.trim(s)
end


local function split_list(s)
    local img        = g("img",        "Placeholder.png")
     -- Tenta primeiro por ';' (recomendado quando usar vírgula decimal).
    local nome      = g("nome",      "Nome do Boss")
     if s:find(";") then
    local frase      = g("frase",      "Frase ou lema do boss.")
         local t = {}
    local hp        = g("hp",        "???")
         for part in mw.text.gsplit(s, ";", true) do
    local exp        = g("exp",        "???")
            table.insert(t, part)
    local nivel      = g("nivel",      "???")
         end
    local necessario = g("necessario",    "-")
         return t
    local comum      = g("comum",      "")
     end
    local semiraro  = g("semiraro",  "")
     -- Caso não haja ';', separa por ',' (útil se números usam ponto decimal).
    local raro      = g("raro",      "")
     local t = {}
    local muitoRaro  = g("muitoraro",  "")
     for part in mw.text.gsplit(s, ",", true) do
 
        table.insert(t, part)
    ----------------------------------------------------
     end
    -- CSS responsivo embutido
    return t
    ----------------------------------------------------
end
    local css = [[
 
]]
 
 
    local html = mw.html.create()
 
    html:wikitext(css)
 
    local box = html:tag("div")
    :addClass("boss-container")
    :css{
        background = "#18181b",
        ["border-radius"] = "12px",
        padding = "30px",
        color = "#fff",
        width = "100%",
        margin = "auto",
        ["font-family"] = "Verdana,sans-serif",
        ["box-sizing"] = "border-box"
    }
 
     ----------------------------------------------------
    -- Cabeçalho
    ----------------------------------------------------
    box:tag("div")
        :css{ ["font-size"] = "1.5em", ["font-weight"] = "bold", ["margin-bottom"] = "10px" }
        :wikitext("Bosses")
 
    local var = box:tag("div")
        :css("margin-bottom", "24px")
 
    var:tag("span")
        :css{
            ["background-color"] = "#232329",
            ["border-radius"] = "7px 0 0 7px",
            padding = "7px 20px",
            ["font-size"] = "1em",
            color = "#cbcdd7",
            ["font-weight"] = "600"
        }
        :wikitext("Mecanica Elite")
 
     var:tag("span")
         :css{
            ["background-color"] = "#19171c",
            ["border-radius"] = "0 7px 7px 0",
            padding = "7px 20px",
            ["font-size"] = "1em",
            color = "#fff",
            ["font-weight"] = "600",
            border = "2px solid #c7a047",
            ["border-left"] = "0"
        }
        :wikitext("Mecanica Hard")
 
    ----------------------------------------------------
    -- Corpo principal (responsivo)
    ----------------------------------------------------
    local main = box:tag("div")
        :addClass("boss-main")
        :css{
            display = "flex",
            gap = "20px",
            ["align-items"] = "center",
            ["justify-content"] = "space-between",
            ["flex-wrap"] = "wrap"
        }
 
    main:tag("div")
        :addClass("boss-img-box")
        :css{ ["flex"] = "none" }
         :wikitext(string.format("[[Arquivo:%s|90px]]", img))
 
    local textBox = main:tag("div")
        :css{ ["flex"] = "1", ["min-width"] = "200px" }
 
    textBox:tag("div")
        :css{ ["font-size"] = "1.2em", ["font-weight"] = "bold", color = "#e82b2b" }
        :wikitext(nome)
 
    textBox:tag("div")
         :css{ ["font-size"] = "95%", color = "#eaa85d", ["font-style"] = "italic" }
         :wikitext(string.format('"%s"', frase))
 
    ----------------------------------------------------
     -- Stats
    ----------------------------------------------------
     local stats = main:tag("div")
        :addClass("boss-stats")
        :css{
            display = "flex",
            ["flex-direction"] = "column",
            ["align-items"] = "flex-end",
            gap = "6px",
            ["min-width"] = "160px"
        }
 
    local statBox = stats:tag("div")
        :css{
            ["background-color"] = "#222126",
            ["border-radius"] = "8px",
            padding = "12px 20px",
            ["min-width"] = "170px"
        }
 
     local sline = statBox:tag("div")
        :css{
            display = "flex",
            ["align-items"] = "center",
            ["justify-content"] = "center",
            gap = "16px",
            ["flex-wrap"] = "wrap"
        }
 
     sline:wikitext(string.format('<span style="color:#fb3d3d;font-weight:bold;font-size:1.15em;">&#x2764;&#xFE0F; %s</span>', hp))
    sline:wikitext(string.format('<span style="color:#ffe568;font-weight:bold;font-size:1.08em;">&#x1F4B0; %s</span>', exp))
    sline:wikitext(string.format('<span style="color:#6ca8fb;font-weight:bold;font-size:1.04em;">&#x2694;&#xFE0F; %s</span>', nivel))
 
     stats:tag("div")
        :css{
            ["margin-top"] = "5px",
            ["font-size"] = "90%",
            color = "#cfccff",
            ["text-align"] = "right"
        }
        :wikitext(string.format(
            "<b>Necessario:</b> %s &nbsp;&nbsp; ",
            necessario, forte, reflete
        ))


local function parse_number(token)
     ----------------------------------------------------
     if type(token) ~= "string" then
        return nil
    end
    token = trim(token)
    if token == "" then
        return nil
    end


     -- Remove espaços
     -- Espaço livre para conteúdo customizável do editor
    token = token:gsub("%s+", "")


     -- Heurística pt-BR:
     ----------------------------------------------------
    -- 1) Se tiver vírgula e ponto, assume '.' como milhar e ',' como decimal
    --   Ex.: "1.234,56" -> "1234.56"
    if token:find(",") and token:find("%.") then
        token = token:gsub("%.", "") -- tira milhares
        token = token:gsub(",", ".") -- vírgula -> ponto decimal
        -- 2) Se só tiver vírgula, assume vírgula decimal
    elseif token:find(",") then
        token = token:gsub(",", ".")
        -- 3) Se só tiver ponto, deixa como está (ponto decimal)
    end


     local n = tonumber(token)
     local conteudo = box:tag("div")
    return n
end


local function collect_numbers(frame)
        :addClass("boss-custom-content")
    local args = frame:getParent() and frame:getParent().args or frame.args
    local nums = {}


    -- 1) Lista em 'valores='
         :css{
    local lista = args.valores or args.lista
    if lista and trim(lista) ~= "" then
         for _, part in ipairs(split_list(lista)) do
            local n = parse_number(part)
            if n then
                table.insert(nums, n)
            end
        end
    end


    -- 2) Parâmetros posicionais 1,2,3,...
            ["margin-top"] = "28px",
    local i = 1
    while true do
        local v = args[i]
        if v == nil then
            break
        end
        v = trim(v)
        if v and v ~= "" then
            -- Pode ser lista dentro do posicional
            local parts = split_list(v)
            for _, part in ipairs(parts) do
                local n = parse_number(part)
                if n then
                    table.insert(nums, n)
                end
            end
        end
        i = i + 1
    end


    return nums
            background = "#232329",
end


local function round(n, casas)
            ["border-radius"] = "10px",
    if not casas or casas == "" then
        return n
    end
    casas = tonumber(casas) or 0
    local mult = 10 ^ casas
    if n >= 0 then
        return math.floor(n * mult + 0.5) / mult
    else
        return math.ceil(n * mult - 0.5) / mult
    end
end


local function format_number(n, casas, formato)
             padding = "18px",
    n = round(n, casas)
    if formato == "pt" then
        -- Formata com vírgula decimal e ponto de milhar
        local s = string.format("%." .. tostring(tonumber(casas) or 0) .. "f", n)
        -- s usa ponto decimal; converter para pt-BR
        local inteiro, frac = s:match("^(-?%d+)%.(%d+)$")
        if not inteiro then
             inteiro = s
            frac = nil
        end
        -- insere pontos nos milhares
        local k
        local sign = ""
        if inteiro:sub(1, 1) == "-" then
            sign = "-"
            inteiro = inteiro:sub(2)
        end
        while true do
            inteiro, k = inteiro:gsub("^(-?%d+)(%d%d%d)", "%1.%2")
            if k == 0 then
                break
            end
        end
        if frac then
            return sign .. inteiro .. "," .. frac
        else
            return sign .. inteiro
        end
    else
        -- "en" ou padrão: ponto decimal, sem milhar
        local casasN = tonumber(casas) or 0
        return string.format("%." .. tostring(casasN) .. "f", n)
    end
end


local function compute(nums, op)
             ["min-height"] = "40px"
    if #nums == 0 then
        return nil
    end
    if op == "soma" or op == "sum" then
        local s = 0
        for _, v in ipairs(nums) do
             s = s + v
        end
        return s
    elseif op == "media" or op == "média" or op == "avg" then
        local s = 0
        for _, v in ipairs(nums) do
            s = s + v
        end
        return s / #nums
    elseif op == "min" or op == "mín" then
        local m = nums[1]
        for i = 2, #nums do
            if nums[i] < m then
                m = nums[i]
            end
        end
        return m
    elseif op == "max" then
        local m = nums[1]
        for i = 2, #nums do
            if nums[i] > m then
                m = nums[i]
            end
        end
        return m
    elseif op == "contar" or op == "count" then
        return #nums
    else
        -- padrão: soma
        local s = 0
        for _, v in ipairs(nums) do
            s = s + v
        end
        return s
    end
end


-- === Interface pública ===
        }


function p.calc(frame)
        :wikitext(g("conteudo", "")) -- permite o uso de |conteudo= na predefinição
    local args = frame:getParent() and frame:getParent().args or frame.args


    local op = (args.op or args.operacao or args.operacao or "soma"):lower()
    local casas = args.casas or args.decimais or 2
    local formato = (args.formato or args.locale or "pt"):lower() -- "pt" ou "en"


    local nums = collect_numbers(frame)
    local result = compute(nums, op)


    if result == nil then
        return "—" -- sem dados
    end


     return format_number(result, casas, formato)
     return tostring(html)end
end


return p
return p

Edição atual tal como às 18h27min de 5 de dezembro de 2025

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

-- Módulo:BossDisplay (responsivo)

local p = {}

function p.bossInfo(frame)
    local args = frame:getParent().args

    local function g(k, default)
        return mw.text.trim(args[k] or "") ~= "" and args[k] or default
    end

    local img        = g("img",        "Placeholder.png")
    local nome       = g("nome",       "Nome do Boss")
    local frase      = g("frase",      "Frase ou lema do boss.")
    local hp         = g("hp",         "???")
    local exp        = g("exp",        "???")
    local nivel      = g("nivel",      "???")
    local necessario = g("necessario",     "-")
    local comum      = g("comum",      "")
    local semiraro   = g("semiraro",   "")
    local raro       = g("raro",       "")
    local muitoRaro  = g("muitoraro",  "")

    ----------------------------------------------------
    -- CSS responsivo embutido
    ----------------------------------------------------
    local css = [[

]]


    local html = mw.html.create()

    html:wikitext(css)

    local box = html:tag("div")
    :addClass("boss-container")
    :css{
        background = "#18181b",
        ["border-radius"] = "12px",
        padding = "30px",
        color = "#fff",
        width = "100%",
        margin = "auto",
        ["font-family"] = "Verdana,sans-serif",
        ["box-sizing"] = "border-box"
    }

    ----------------------------------------------------
    -- Cabeçalho
    ----------------------------------------------------
    box:tag("div")
        :css{ ["font-size"] = "1.5em", ["font-weight"] = "bold", ["margin-bottom"] = "10px" }
        :wikitext("Bosses")

    local var = box:tag("div")
        :css("margin-bottom", "24px")

    var:tag("span")
        :css{
            ["background-color"] = "#232329",
            ["border-radius"] = "7px 0 0 7px",
            padding = "7px 20px",
            ["font-size"] = "1em",
            color = "#cbcdd7",
            ["font-weight"] = "600"
        }
        :wikitext("Mecanica Elite")

    var:tag("span")
        :css{
            ["background-color"] = "#19171c",
            ["border-radius"] = "0 7px 7px 0",
            padding = "7px 20px",
            ["font-size"] = "1em",
            color = "#fff",
            ["font-weight"] = "600",
            border = "2px solid #c7a047",
            ["border-left"] = "0"
        }
        :wikitext("Mecanica Hard")

    ----------------------------------------------------
    -- Corpo principal (responsivo)
    ----------------------------------------------------
    local main = box:tag("div")
        :addClass("boss-main")
        :css{
            display = "flex",
            gap = "20px",
            ["align-items"] = "center",
            ["justify-content"] = "space-between",
            ["flex-wrap"] = "wrap"
        }

    main:tag("div")
        :addClass("boss-img-box")
        :css{ ["flex"] = "none" }
        :wikitext(string.format("[[Arquivo:%s|90px]]", img))

    local textBox = main:tag("div")
        :css{ ["flex"] = "1", ["min-width"] = "200px" }

    textBox:tag("div")
        :css{ ["font-size"] = "1.2em", ["font-weight"] = "bold", color = "#e82b2b" }
        :wikitext(nome)

    textBox:tag("div")
        :css{ ["font-size"] = "95%", color = "#eaa85d", ["font-style"] = "italic" }
        :wikitext(string.format('"%s"', frase))

    ----------------------------------------------------
    -- Stats
    ----------------------------------------------------
    local stats = main:tag("div")
        :addClass("boss-stats")
        :css{
            display = "flex",
            ["flex-direction"] = "column",
            ["align-items"] = "flex-end",
            gap = "6px",
            ["min-width"] = "160px"
        }

    local statBox = stats:tag("div")
        :css{
            ["background-color"] = "#222126",
            ["border-radius"] = "8px",
            padding = "12px 20px",
            ["min-width"] = "170px"
        }

    local sline = statBox:tag("div")
        :css{
            display = "flex",
            ["align-items"] = "center",
            ["justify-content"] = "center",
            gap = "16px",
            ["flex-wrap"] = "wrap"
        }

    sline:wikitext(string.format('<span style="color:#fb3d3d;font-weight:bold;font-size:1.15em;">&#x2764;&#xFE0F; %s</span>', hp))
    sline:wikitext(string.format('<span style="color:#ffe568;font-weight:bold;font-size:1.08em;">&#x1F4B0; %s</span>', exp))
    sline:wikitext(string.format('<span style="color:#6ca8fb;font-weight:bold;font-size:1.04em;">&#x2694;&#xFE0F; %s</span>', nivel))

    stats:tag("div")
        :css{
            ["margin-top"] = "5px",
            ["font-size"] = "90%",
            color = "#cfccff",
            ["text-align"] = "right"
        }
        :wikitext(string.format(
            "<b>Necessario:</b> %s &nbsp;&nbsp; ",
            necessario, forte, reflete
        ))

    ----------------------------------------------------

    -- Espaço livre para conteúdo customizável do editor

    ----------------------------------------------------

    local conteudo = box:tag("div")

        :addClass("boss-custom-content")

        :css{

            ["margin-top"] = "28px",

            background = "#232329",

            ["border-radius"] = "10px",

            padding = "18px",

            ["min-height"] = "40px"

        }

        :wikitext(g("conteudo", ""))  -- permite o uso de |conteudo= na predefinição




    return tostring(html)end

return p