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

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


-- Módulo:CalculadoraTier
local p = {}
-- Calculadora de custos para evolução de tiers/estrelas
 
-- Compatível com MediaWiki + Scribunto
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 p = {}


-- \u26a0\ufe0f EDITÁVEL: Tabela de custos padrão
    local html = mw.html.create()
-- Defina aqui os custos para cada estrela alcançada (1..5) em cada tier,
 
-- e o custo para subir de um tier para o próximo.
    html:wikitext(css)
local COSTS = {
 
  tiers = {"bronze", "prata", "ouro", "diamante"},
    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")


  -- Custo para alcançar CADA estrela (ex.: STAR[1] = custo para ir de 0 -> 1 estrela)
    var:tag("span")
  star = {
        :css{
    bronze = {
            ["background-color"] = "#19171c",
      [1] = { berry = 100, frag = 1 },
            ["border-radius"] = "0 7px 7px 0",
      [2] = { berry = 200, frag = 1 },
            padding = "7px 20px",
      [3] = { berry = 300, frag = 2 },
            ["font-size"] = "1em",
      [4] = { berry = 450, frag = 2 },
            color = "#fff",
      [5] = { berry = 600, frag = 3 },
            ["font-weight"] = "600",
    },
            border = "2px solid #c7a047",
    prata = {
            ["border-left"] = "0"
      [1] = { berry = 200, frag = 1 },
        }
      [2] = { berry = 300, frag = 2 },
        :wikitext("Mecanica Hard")
      [3] = { berry = 450, frag = 2 },
      [4] = { berry = 650, frag = 3 },
      [5] = { berry = 900, frag = 4 },
    },
    ouro = {
      [1] = { berry = 400, frag = 2 },
      [2] = { berry = 600, frag = 2 },
      [3] = { berry = 900, frag = 3 },
      [4] = { berry = 1300, frag = 4 },
      [5] = { berry = 1800, frag = 5 },
    },
    diamante = {
      [1] = { berry = 800, frag = 3 },
      [2] = { berry = 1200, frag = 4 },
      [3] = { berry = 1700, frag = 5 },
      [4] = { berry = 2300, frag = 6 },
      [5] = { berry = 3000, frag = 8 },
    },
  },


  -- Custo de mudar de tier (ex.: BRONZE -> PRATA). Não altera estrelas (reinicia para 0).
    ----------------------------------------------------
  tierUp = {
    -- Corpo principal (responsivo)
     bronze  = { berry = 2000, frag = 5 },  -- custo para BRONZE -> PRATA
     ----------------------------------------------------
    prata    = { berry = 6000, frag = 10 }, -- custo para PRATA -> OURO
     local main = box:tag("div")
     ouro    = { berry = 15000, frag = 20 },-- custo para OURO -> DIAMANTE
        :addClass("boss-main")
    diamante = nil,                         -- não há próximo tier
        :css{
  },
            display = "flex",
}
            gap = "20px",
            ["align-items"] = "center",
            ["justify-content"] = "space-between",
            ["flex-wrap"] = "wrap"
        }


-- Normaliza texto (case-insensitive, acentos ignorados simples)
    main:tag("div")
local function norm(s)
        :addClass("boss-img-box")
  if type(s) ~= 'string' then return nil end
        :css{ ["flex"] = "none" }
  s = mw.ustring.lower(s)
        :wikitext(string.format("[[Arquivo:%s|90px]]", img))
  s = s:gsub("á", "a"):gsub("â", "a"):gsub("ã", "a")
      :gsub("é", "e"):gsub("ê", "e")
      :gsub("í", "i")
      :gsub("ó", "o"):gsub("ô", "o")
      :gsub("ú", "u")
  return s
end


local function tierIndex(name)
    local textBox = main:tag("div")
  local n = norm(name)
        :css{ ["flex"] = "1", ["min-width"] = "200px" }
  for i, t in ipairs(COSTS.tiers) do
    if n == t then return i end
  end
  return nil
end


local function getTierName(idx)
    textBox:tag("div")
  return COSTS.tiers[idx]
        :css{ ["font-size"] = "1.2em", ["font-weight"] = "bold", color = "#e82b2b" }
end
        :wikitext(nome)


-- Soma custos (protege nil)
    textBox:tag("div")
local function addCost(a, b)
        :css{ ["font-size"] = "95%", color = "#eaa85d", ["font-style"] = "italic" }
  a = a or { berry = 0, frag = 0 }
        :wikitext(string.format('"%s"', frase))
  b = b or { berry = 0, frag = 0 }
  return { berry = (a.berry or 0) + (b.berry or 0), frag = (a.frag or 0) + (b.frag or 0) }
end


-- Obtém custo para subir 1 estrela dentro do tier
    ----------------------------------------------------
local function starCost(tierName, starTo)
    -- Stats
  local t = COSTS.star[tierName]
    ----------------------------------------------------
  return t and t[starTo] or { berry = 0, frag = 0 }
    local stats = main:tag("div")
end
        :addClass("boss-stats")
        :css{
            display = "flex",
            ["flex-direction"] = "column",
            ["align-items"] = "flex-end",
            gap = "6px",
            ["min-width"] = "160px"
        }


-- Obtém custo para subir de tier
    local statBox = stats:tag("div")
local function tierUpCost(tierName)
        :css{
  local c = COSTS.tierUp[tierName]
            ["background-color"] = "#222126",
  return c or { berry = 0, frag = 0 }
            ["border-radius"] = "8px",
end
            padding = "12px 20px",
            ["min-width"] = "170px"
        }


-- Caminho de evolução do estado (tierIdx, star) até (tierIdx2, star2)
    local sline = statBox:tag("div")
local function computePath(ti, si, tf, sf)
        :css{
  local steps = {}
            display = "flex",
  local total = { berry = 0, frag = 0 }
            ["align-items"] = "center",
            ["justify-content"] = "center",
            gap = "16px",
            ["flex-wrap"] = "wrap"
        }


  local iTier, iStar = ti, si
    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))


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


  while (iTier < tf) or (iTier == tf and iStar < sf) do
     ----------------------------------------------------
     if iStar < 5 and (iTier < tf or (iTier == tf and iStar < sf)) then
      -- subir estrela dentro do tier atual
      local tierName = getTierName(iTier)
      local toStar = iStar + 1
      local c = starCost(tierName, toStar)
      push({ tipo = "estrela", tier = tierName, de = iStar, para = toStar, custo = c })
      iStar = toStar
    else
      -- já está com 5 estrelas -> tentar subir de tier
      if iTier >= #COSTS.tiers then
        -- não há próximo tier, evitar loop
        break
      end
      local fromTier = getTierName(iTier)
      local c = tierUpCost(fromTier)
      push({ tipo = "tier", de = fromTier, para = getTierName(iTier + 1), custo = c })
      iTier = iTier + 1
      iStar = 0 -- ao subir de tier, reinicia estrelas
    end
  end


  return steps, total
    -- Espaço livre para conteúdo customizável do editor
end


-- Renderização em wikitext/HTML
    ----------------------------------------------------
local function render(steps, total, opts)
  local h = mw.html.create('div'):addClass('calc-tier')


  if opts.titulo then
     local conteudo = box:tag("div")
     h:tag('h3'):wikitext(opts.titulo)
  end


  if opts.mostrarTabela ~= false then
        :addClass("boss-custom-content")
    local tbl = h:tag('table'):addClass('wikitable'):css('width', '100%')
    local thead = tbl:tag('tr')
    thead:tag('th'):wikitext('Passo')
    thead:tag('th'):wikitext('Ação')
    thead:tag('th'):wikitext('Custo (Berry)')
    thead:tag('th'):wikitext('Custo (Fragmentos)')


    for i, st in ipairs(steps) do
         :css{
      local tr = tbl:tag('tr')
      tr:tag('td'):wikitext(i)
      if st.tipo == 'estrela' then
        tr:tag('td'):wikitext(string.format('Tier **%s**: %d → %d estrelas', st.tier, st.de, st.para))
      else
         tr:tag('td'):wikitext(string.format('Subir de **%s** → **%s**', st.de, st.para))
      end
      tr:tag('td'):wikitext(st.custo.berry or 0)
      tr:tag('td'):wikitext(st.custo.frag or 0)
    end
  end


  local box = h:tag('div'):addClass('calc-tier-total'):css('margin-top','8px')
            ["margin-top"] = "28px",
  box:wikitext(string.format("'''Total:''' %d Berry • %d Fragmentos", total.berry or 0, total.frag or 0))


  return tostring(h)
            background = "#232329",
end


local function parseInt(v, default)
            ["border-radius"] = "10px",
  local n = tonumber(v)
  if not n then return default end
  n = math.floor(n)
  return n
end


-- Entrada pública via #invoke
            padding = "18px",
function p.calcular(frame)
  local args = frame:getParent() and frame:getParent().args or frame.args


  local inicioTier = args.inicio_tier or args.de_tier or args.tier_inicial
            ["min-height"] = "40px"
  local fimTier    = args.fim_tier    or args.ate_tier or args.tier_final
  local inicioEst  = parseInt(args.inicio_estrela or args.de_estrela or args.estrelas_iniciais or 0, 0)
  local fimEst    = parseInt(args.fim_estrela    or args.ate_estrela  or args.estrelas_finais  or 0, 0)


  -- Opções
        }
  local titulo = args.titulo
  local mostrarTabela = (tostring(args.mostrar_tabela or 'sim') ~= 'nao')


  if not inicioTier or not fimTier then
        :wikitext(g("conteudo", ""))  -- permite o uso de |conteudo= na predefinição
    return "Erro: defina 'inicio_tier' e 'fim_tier'."
  end


  local ti = tierIndex(inicioTier)
  local tf = tierIndex(fimTier)
  if not ti or not tf then
    return "Erro: tier inválido. Use: bronze, prata, ouro, diamante."
  end


  -- Sanitiza limites de estrela (0..5)
  if inicioEst < 0 then inicioEst = 0 end
  if inicioEst > 5 then inicioEst = 5 end
  if fimEst < 0 then fimEst = 0 end
  if fimEst > 5 then fimEst = 5 end


  -- Se o tier inicial já é maior que o final, invertido
  if (ti > tf) or (ti == tf and inicioEst > fimEst) then
    return "Erro: o alvo precisa ser maior que o estado inicial."
  end


  local steps, total = computePath(ti, inicioEst, tf, fimEst)
    return tostring(html)end
  return render(steps, total, { titulo = titulo, mostrarTabela = mostrarTabela })
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