Module:Campeao
Appearance
Documentation for this module may be created at Module:Campeao/doc
-- Renderizador das fichas de Campeao do Champion's Path.
--
-- A pagina de cada Campeao deve conter uma linha e nada mais:
-- {{Campeao|Tyranitar}}
--
-- Todo o layout vive aqui. Se for preciso duplicar marcacao entre dois
-- Campeoes, o erro esta neste modulo, nao na pagina.
local p = {}
local dados = mw.loadData('Module:Campeao/dados')
local PLACEHOLDER = 'ArquivoExemplo.png'
-- Formata 1000000 como "1.000.000"
local function numero(n)
local s = tostring(n)
local r = s:reverse():gsub('(%d%d%d)', '%1.'):reverse()
return (r:gsub('^%.', ''))
end
-- Chip de item: icone, contador e tooltip. Enquanto nao houver sprite, cai
-- no placeholder, entao a ficha ja fica montada e so troca a imagem depois.
local function chip(nomeItem, qtd)
local arquivo = 'Item ' .. nomeItem:gsub('[%(%):]', ''):gsub('%s+', ' ') .. '.png'
local existe = mw.title.new('File:' .. arquivo)
local usar = (existe and existe.fileExists) and arquivo or PLACEHOLDER
local w = mw.html.create('span'):addClass('cp-item')
w:tag('span'):addClass('cp-item-icon')
:wikitext('[[File:' .. usar .. '|40px|link=|alt=' .. nomeItem .. ']]')
if qtd and qtd ~= '' then
w:tag('span'):addClass('cp-item-qty'):wikitext(qtd)
end
local tip = w:tag('span'):addClass('cp-tip')
tip:tag('span'):addClass('cp-tip-name'):wikitext(nomeItem)
if qtd and qtd ~= '' then
tip:tag('span'):addClass('cp-tip-qty'):wikitext('Quantidade: ' .. qtd)
end
return w
end
local function stat(rotulo, valor)
local d = mw.html.create('div'):addClass('cp-stat')
d:tag('span'):addClass('cp-stat-label'):wikitext(rotulo)
d:tag('span'):addClass('cp-stat-value'):wikitext(valor)
return d
end
local function painel(titulo, modificador)
local s = mw.html.create('div'):addClass('cp-panel')
if modificador then s:addClass('cp-panel--' .. modificador) end
-- div, nao h3: um heading de verdade faria o MediaWiki criar secao e
-- indice automatico dentro do painel, alem de reestruturar o HTML.
s:tag('div'):addClass('cp-panel-title'):wikitext(titulo)
return s
end
-- Recompensas de uma dificuldade: EXP em destaque e os itens como chips.
local function recompensas(c, dif)
local box = mw.html.create('div'):addClass('cp-rewards'):attr('data-dif', dif:lower())
local exp = (dif == 'Hard') and c.expHard or c.expNormal
if exp then
box:tag('div'):addClass('cp-rewards-label'):wikitext('Experiência')
local linha = box:tag('div'):addClass('cp-rewards-row')
linha:tag('span'):addClass('cp-exp'):wikitext(numero(exp) .. ' EXP')
end
box:tag('div'):addClass('cp-rewards-label'):wikitext('Itens possíveis')
local linha = box:tag('div'):addClass('cp-rewards-row')
for _, r in ipairs(dados.loot[dif] or {}) do
linha:node(chip(r.item, r.qtd))
end
if c.megaStone and c.megaStone ~= '' then
linha:node(chip(c.megaStone, '1'))
end
box:tag('div'):addClass('cp-rewards-hint')
:wikitext('Passe o mouse sobre um item para ver o nome.')
return box
end
local function requisitos(c, dif)
local box = mw.html.create('div'):addClass('cp-req'):attr('data-dif', dif:lower())
local ul = box:tag('ul')
ul:tag('li'):wikitext("Nível '''" .. ((dif == 'Hard') and '425' or '350') .. "''' ou superior.")
ul:tag('li'):wikitext("Equipe de '''exatamente 3 jogadores'''.")
ul:tag('li'):wikitext("'''1 Pokémon''' por jogador, sem troca durante a batalha.")
ul:tag('li'):wikitext("'''1 Champion's Ticket''' para entrar.")
ul:tag('li'):wikitext('Acesso liberado com o ' .. (c.aceTrainer or '') .. '.')
if dif == 'Hard' then
ul:tag('li'):wikitext("O Campeão enfrentado é a versão '''Shiny'''.")
end
return box
end
local function conquistas(dif)
local box = mw.html.create('div'):addClass('cp-ach'):attr('data-dif', dif:lower())
local ul = box:tag('ul'):addClass('cp-ach-list')
local chave = (dif == 'Hard') and 'hard' or 'normal'
for _, a in ipairs(dados.conquistas or {}) do
if a[chave] then ul:tag('li'):wikitext(a.desc) end
end
return box
end
function p.ficha(frame)
local chave = frame.args[1] or frame.args.campeao or ''
chave = mw.text.trim(chave)
local c = dados.campeoes[chave]
if not c then
return '<span class="error">Campeão desconhecido: ' .. mw.text.nowiki(chave)
.. '. Cadastre-o em [[Module:Campeao/dados]].</span>'
end
local difs = { 'Normal' }
if c.hard then table.insert(difs, 'Hard') end
local raiz = mw.html.create('div'):addClass('cp-boss'):attr('data-tema', 'claro')
-- Alternador de tema. O JS em MediaWiki:Common.js troca data-tema e guarda
-- a preferencia; sem JS o botao some e a ficha fica no tema claro.
raiz:tag('span'):addClass('cp-tema'):attr('role', 'button'):attr('tabindex', '0')
:attr('data-cp-tema', '1'):css('display', 'none'):wikitext('Modo escuro')
-- Cabecalho
local head = raiz:tag('div'):addClass('cp-head')
local arte = (c.arte and c.arte ~= '') and c.arte or PLACEHOLDER
head:tag('div'):addClass('cp-art')
:wikitext('[[File:' .. arte .. '|200px|link=|alt=' .. c.nome .. ']]')
local info = head:tag('div'):addClass('cp-head-info')
info:tag('div'):addClass('cp-title'):wikitext(c.nome)
info:tag('span'):addClass('cp-badge'):wikitext("Campeão das Expedições")
info:tag('p'):addClass('cp-desc'):wikitext(
'Campeão da Expedition do ' .. c.expedition ..
', enfrentado no [[Champion\'s Path]] em uma arena que representa o seu habitat natural.')
local stats = info:tag('div'):addClass('cp-stats')
stats:node(stat('Expedition', c.expedition))
stats:node(stat('Ace Trainer', c.aceTrainer))
stats:node(stat('Jogadores', '3'))
stats:node(stat('Tempo alvo', c.tempoAlvo .. ' min'))
-- Abas de dificuldade
local abas = raiz:tag('div'):addClass('cp-tabs')
for i, dif in ipairs(difs) do
local b = abas:tag('span'):addClass('cp-tab'):attr('data-dif', dif:lower())
:attr('role', 'button'):attr('tabindex', '0'):wikitext(dif)
if i == 1 then b:addClass('is-active') end
end
-- Paineis lado a lado
local split = raiz:tag('div'):addClass('cp-split')
local pReq = painel('Requisitos')
local pRec = painel('Recompensas', 'rewards')
for i, dif in ipairs(difs) do
local r1, r2 = requisitos(c, dif), recompensas(c, dif)
if i > 1 then r1:addClass('is-hidden'); r2:addClass('is-hidden') end
pReq:node(r1)
pRec:node(r2)
end
split:node(pReq)
split:node(pRec)
-- Habilidades: seletor em cima, detalhe da escolhida embaixo.
local pHab = painel('Habilidades', 'skills')
local temAlguma = false
for i, dif in ipairs(difs) do
local lista = c.habilidades and c.habilidades[dif:lower()] or {}
-- lista[1] em vez de #lista: mw.loadData guarda os valores no metatable,
-- entao o operador # devolve zero mesmo com a tabela cheia.
if lista[1] then
temAlguma = true
local grupo = pHab:tag('div'):addClass('cp-skills'):attr('data-dif', dif:lower())
if i > 1 then grupo:addClass('is-hidden') end
local barra = grupo:tag('div'):addClass('cp-skill-bar')
for n, h in ipairs(lista) do
local b = barra:tag('span'):addClass('cp-skill-pick')
:attr('data-skill', tostring(n)):attr('role', 'button')
:attr('tabindex', '0'):wikitext(h.nome)
if n == 1 then b:addClass('is-active') end
end
for n, h in ipairs(lista) do
local det = grupo:tag('div'):addClass('cp-skill-detail')
:attr('data-skill', tostring(n))
if n > 1 then det:addClass('is-hidden') end
det:tag('div'):addClass('cp-skill-name'):wikitext(h.nome)
local meta = det:tag('div'):addClass('cp-skill-meta')
meta:tag('span'):wikitext(h.tipo)
if h.elemento and h.elemento ~= '' then
meta:tag('span'):wikitext(h.elemento)
end
-- Alcance, recarga e dano ficam de fora: sao numeros internos do
-- servidor, nao informacao que ajuda quem esta jogando.
if h.chance and h.chance < 100 then
meta:tag('span'):wikitext('Chance ' .. h.chance .. '%')
end
if h.nevermiss then
meta:tag('span'):addClass('cp-skill-flag'):wikitext('Não erra')
end
if h.desc and h.desc ~= '' then
det:tag('div'):addClass('cp-skill-desc'):wikitext(h.desc)
else
det:tag('div'):addClass('cp-skill-desc cp-empty')
:wikitext('Descrição ainda não documentada.')
end
if h.video and h.video ~= '' then
-- .mp4 e .webm nao podem ser <video> direto no wikitext: o
-- sanitizador do MediaWiki remove a tag. Por isso o Widget.
-- GIF e PNG continuam como imagem normal.
local caixa = det:tag('div'):addClass('cp-skill-video')
if h.video:lower():match('%\.mp4$') or h.video:lower():match('%\.webm$') then
caixa:wikitext('{{#widget:Video|url={{filepath:' .. h.video .. '}}|width=480}}')
else
caixa:wikitext('[[File:' .. h.video .. '|center|480px|link=]]')
end
else
det:tag('div'):addClass('cp-skill-video cp-empty')
:wikitext('Vídeo desta habilidade ainda não gravado.')
end
end
end
end
if not temAlguma then
pHab:tag('div'):addClass('cp-empty')
:wikitext('O moveset deste Campeão ainda não foi cadastrado.')
end
raiz:node(pHab)
-- Conquistas
local pCon = painel('Conquistas', 'ach')
for i, dif in ipairs(difs) do
local bloco = conquistas(dif)
if i > 1 then bloco:addClass('is-hidden') end
pCon:node(bloco)
end
raiz:node(pCon)
local tip = raiz:tag('div'):addClass('cp-tip-bar')
tip:tag('span'):addClass('cp-tip-tag'):wikitext('Dica')
tip:tag('span'):wikitext('Não há Potions nem Revives nesta sala: sobreviver às mecânicas vale mais do que causar dano.')
return frame:extensionTag{ name = 'templatestyles', args = { src = 'Campeao/styles.css' } }
.. tostring(raiz)
end
return p