Mudanças entre as edições de "Módulo:BossSkills"
Ir para navegação
Ir para pesquisar
(Criou página com '--[[ Módulo:BossSkills — Gera HTML de habilidades para bosses (Weekly/World). Uso via predefinição (recomendado): {{BossSkills|module=Boss.Gedatsu|lang=pt}} Uso diret...') |
m |
||
| (Uma revisão intermediária pelo mesmo usuário não está sendo mostrada) | |||
| Linha 11: | Linha 11: | ||
Parâmetros: | Parâmetros: | ||
|module= (obrigatório) Nome do módulo do boss (ex: Boss.Gedatsu) | |module= (obrigatório) Nome do módulo do boss (ex: Boss.Gedatsu) | ||
|lang= (opcional) Idioma: pt, en, es, pl. Padrão: pt | |lang= (opcional) Idioma: pt, en, es, pl. Padrão: pt | ||
O módulo do boss (ex: Módulo:Boss.Gedatsu) deve retornar: | O módulo do boss (ex: Módulo:Boss.Gedatsu) deve retornar: | ||
{ | { | ||
order = { "Skill1", "Skill2" }, | order = { "Skill1", "Skill2" }, | ||
skills = { | skills = { | ||
["Skill1"] = { | ["Skill1"] = { | ||
icon = "Skill1-Icon.png", | icon = "Skill1-Icon.png", | ||
cooldown = "10s", | 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", | video = "Skill1-Video.mp4", | ||
desc = { pt = "...", en = "..." }, | desc = { pt = "...", en = "...", pl = "..." }, | ||
}, | }, | ||
}, | }, | ||
| Linha 35: | Linha 32: | ||
local function trim(s) | local function trim(s) | ||
return (tostring(s or ""):gsub("^%s+", ""):gsub("%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 | end | ||
| Linha 78: | Linha 101: | ||
return "<!-- BossSkills: módulo '" .. moduleName .. "' sem order/skills -->" | return "<!-- BossSkills: módulo '" .. moduleName .. "' sem order/skills -->" | ||
end | end | ||
-- Idioma (pt padrão) | -- Idioma (pt padrão) | ||
local | local lang = normalizeLang(args.lang or "pt") | ||
local html = mw.html.create('div') | local html = mw.html.create('div') | ||
local box = html:tag('div'):addClass('boss-box') | local box = html:tag('div'):addClass('boss-box') | ||
:attr('data-lang', lang) | :attr('data-lang', lang) | ||
-- Skills container | -- Skills container | ||
| Linha 123: | Linha 127: | ||
local sk = data.skills[skillName] | local sk = data.skills[skillName] | ||
if type(sk) == "table" then | if type(sk) == "table" then | ||
idx | idx = idx + 1 | ||
local icon | local icon = trim(sk.icon or "") | ||
local | local video = trim(sk.video or "") | ||
local | |||
-- 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 | -- Descrição i18n | ||
local | local descPack = pickI18nValue(sk.desc) | ||
local iconEl = iconBar:tag('div') | local iconEl = iconBar:tag('div') | ||
:addClass('boss-skill-icon') | :addClass('boss-skill-icon') | ||
:attr('data-index', idx) | :attr('data-index', idx) | ||
:attr('data- | :attr('data-name-pt', namePack.pt) | ||
:attr('data-cd', cd) | :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', video ~= "" and fileURL(video) or "") | ||
:attr('data-video-file', video) | :attr('data-video-file', video) | ||
:attr('data-desc-pt', | :attr('data-desc-pt', descPack.pt) | ||
:attr('data-desc-en', | :attr('data-desc-en', descPack.en) | ||
:attr('data-desc-es', | :attr('data-desc-es', descPack.es) | ||
:attr('data-desc-pl', | :attr('data-desc-pl', descPack.pl) | ||
if idx == 1 then | if idx == 1 then | ||
Edição atual tal como às 22h25min de 17 de março de 2026
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