Mudanças entre as edições de "Módulo:Gb"
Ir para navegação
Ir para pesquisar
| Linha 1: | Linha 1: | ||
-- Módulo: | -- Módulo:Gb | ||
-- Calculadora de custos para evolução de tiers/estrelas | -- Calculadora de custos para evolução de tiers/estrelas | ||
-- Compatível com MediaWiki + Scribunto | -- Compatível com MediaWiki + Scribunto | ||
Edição das 19h59min de 26 de setembro de 2025
A documentação para este módulo pode ser criada em Módulo:Gb/doc
-- Módulo:Gb
-- Calculadora de custos para evolução de tiers/estrelas
-- Compatível com MediaWiki + Scribunto
local p = {}
-- \u26a0\ufe0f EDITÁVEL: Tabela de custos padrão
-- 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.
local COSTS = {
tiers = {"bronze", "prata", "ouro", "diamante"},
-- Custo para alcançar CADA estrela (ex.: STAR[1] = custo para ir de 0 -> 1 estrela)
star = {
bronze = {
[1] = { berry = 100, frag = 1 },
[2] = { berry = 200, frag = 1 },
[3] = { berry = 300, frag = 2 },
[4] = { berry = 450, frag = 2 },
[5] = { berry = 600, frag = 3 },
},
prata = {
[1] = { berry = 200, frag = 1 },
[2] = { berry = 300, frag = 2 },
[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 = {
bronze = { berry = 2000, frag = 5 }, -- custo para BRONZE -> PRATA
prata = { berry = 6000, frag = 10 }, -- custo para PRATA -> OURO
ouro = { berry = 15000, frag = 20 },-- custo para OURO -> DIAMANTE
diamante = nil, -- não há próximo tier
},
}
-- Normaliza texto (case-insensitive, acentos ignorados simples)
local function norm(s)
if type(s) ~= 'string' then return nil end
s = mw.ustring.lower(s)
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 n = norm(name)
for i, t in ipairs(COSTS.tiers) do
if n == t then return i end
end
return nil
end
local function getTierName(idx)
return COSTS.tiers[idx]
end
-- Soma custos (protege nil)
local function addCost(a, b)
a = a or { berry = 0, frag = 0 }
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)
local t = COSTS.star[tierName]
return t and t[starTo] or { berry = 0, frag = 0 }
end
-- Obtém custo para subir de tier
local function tierUpCost(tierName)
local c = COSTS.tierUp[tierName]
return c or { berry = 0, frag = 0 }
end
-- Caminho de evolução do estado (tierIdx, star) até (tierIdx2, star2)
local function computePath(ti, si, tf, sf)
local steps = {}
local total = { berry = 0, frag = 0 }
local iTier, iStar = ti, si
local function push(step)
table.insert(steps, step)
total = addCost(total, step.custo)
end
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
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
h:tag('h3'):wikitext(opts.titulo)
end
if opts.mostrarTabela ~= false then
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
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')
box:wikitext(string.format("'''Total:''' %d Berry • %d Fragmentos", total.berry or 0, total.frag or 0))
return tostring(h)
end
local function parseInt(v, default)
local n = tonumber(v)
if not n then return default end
n = math.floor(n)
return n
end
-- Entrada pública via #invoke
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
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
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 render(steps, total, { titulo = titulo, mostrarTabela = mostrarTabela })
end
return p