Módulo:Info
Ir para navegação
Ir para pesquisar
A documentação para este módulo pode ser criada em Módulo:Info/doc
-- Módulo:Info — resolve metadados e skills (robusto/corrigido + gambiarra expandTier/expandTags)
local p = {}
-- ===== util =====
local function trim(s)
return (tostring(s or ""):gsub("^%s+", ""):gsub("%s+$", ""))
end
local function safeArgs(node)
return (node and node.args) or {}
end
local function requireCharacterModule(charName)
charName = trim(charName)
if charName == "" then
return nil
end
local title = mw.title.new("Módulo:" .. charName .. " — dados do personagem")
if title and title.exists then
local ok, mod = pcall(require, title.prefixedText)
if ok then return mod end
end
-- fallback: tentar Módulo:Nome sem “— dados do personagem”
local title2 = mw.title.new("Módulo:" .. charName)
if title2 and title2.exists then
local ok, mod = pcall(require, title2.prefixedText)
if ok then return mod end
end
return {}
end
local function colorize(txt)
if not txt or txt == "" then return "" end
local s = tostring(txt)
-- marcações {{debuff:60}} {{atk:}} {{def:}} {{ms:}} {{hp:}} {{sec:3 segundos}}
s = s:gsub("{{(%w+)%:([^\n}]-)}}", function(kind, val)
kind = kind:lower()
local map = {
debuff = "#ff5252",
atk = "#ffcc00",
def = "#64b5f6",
ms = "#43a047",
hp = "#42a5f5",
sec = "#aaaaaa",
}
local col = map[kind] or "#cccccc"
return string.format("<span style='color:%s;'>%s</span>", col, trim(val))
end)
return s
end
local function resolveCharFromFrames(frame, a)
-- tenta descobrir o nome do personagem a partir do parent frame ou título da página
local parent = frame:getParent()
if parent and parent.args and trim(parent.args.nome or "") ~= "" then
return trim(parent.args.nome)
end
-- Se vier via |char= também aceita
if a and trim(a.char or "") ~= "" then
return trim(a.char)
end
-- fallback: título atual
local title = mw.title.getCurrentTitle()
return title and trim(title.text) or ""
end
-- paleta para marcadores
local COLOR = {
debuff = "#ff5252",
atk = "#ffcc00",
def = "#64b5f6",
ms = "#43a047",
hp = "#42a5f5",
sec = "#aaaaaa",
}
-- ====== Tier/Tags expanders (mantidos) ======
function p.getTier(frame)
local a = safeArgs(frame)
local char = trim(a.char or (frame:getParent() and frame:getParent().args.nome) or "")
if char == "" then char = resolveCharFromFrames(frame, a) end
local data = requireCharacterModule(char) or {}
local lang = trim(a.lang or (frame:getParent() and frame:getParent().args.lang) or "pt"):lower()
local tier = (data.tier_i18n and data.tier_i18n[lang]) or data.tier or ""
return trim(tier)
end
function p.getTags(frame)
local a = safeArgs(frame)
local char = trim(a.char or (frame:getParent() and frame:getParent().args.nome) or "")
if char == "" then char = resolveCharFromFrames(frame, a) end
local data = requireCharacterModule(char) or {}
local lang = trim(a.lang or (frame:getParent() and frame:getParent().args.lang) or "pt"):lower()
local tags = (data.tags_i18n and data.tags_i18n[lang]) or data.tags or {}
if type(tags) == "table" then
return table.concat(tags, " / ")
end
return trim(tags or "")
end
-- ===== Skill / Subskill =====
local function parseMSmart(aM, aS, aParentM)
-- retorna (isSub, parentM, sIndex, mInt)
local M = trim(aM or "")
if M ~= "" and M:find("%.") then
local p, s = M:match("^(%d+)%.(%d+)$")
if p and s then
return true, tonumber(p) or 0, tonumber(s) or 1, tonumber(p) or 0
end
end
local s = tonumber(aS or "") or nil
local pm = tonumber(aParentM or "") or nil
if s and pm then
return true, pm, s, pm
end
return false, nil, nil, tonumber(M) or 0
end
function p.skill(frame)
local a = safeArgs(frame)
local lang = trim((a.lang or (frame:getParent() and frame:getParent().args.lang) or "pt"):lower())
local char = trim(a.char or (frame:getParent() and frame:getParent().args.nome) or "")
if char == "" then
char = resolveCharFromFrames(frame, a)
end
local data = requireCharacterModule(char) or {}
local isSub, parentM, sIndex, mInt = parseMSmart(a.M, a.S, a.parentM)
local name, desc_i18n = nil, {}
-- PRINCIPAL (M inteiro)
if not isSub and a.M and trim(a.M) ~= "" then
local m = tonumber(a.M) or 0
local order = data.order or {}
local key = order[m] or ""
local sk = (data.skills or {})[key] or {}
name = trim(sk.name or key or "")
-- monta tabela de descrições por idioma (já colorizadas)
if type(sk.desc) == "table" then
local langs = {"pt", "en", "es", "pl"}
for _, code in ipairs(langs) do
local d = sk.desc[code]
if d and trim(d) ~= "" then
desc_i18n[code] = colorize(d)
end
end
elseif sk.desc and trim(sk.desc) ~= "" then
desc_i18n["pt"] = colorize(sk.desc) -- fallback: único texto vira pt
end
-- NOVO: se a principal tiver suborder, exporta pro front
if type(sk.suborder) == "table" and #sk.suborder > 0 then
_SUBS = sk.suborder
_M_INDEX = m
_PARENT_KEY = key
end
end
-- SUBSKILL (por M decimal ou S+parentM)
if isSub then
local order = data.order or {}
local parentKey = order[parentM or 0] or ""
local parentSk = (data.skills or {})[parentKey] or {}
-- lista de filhas: suborder ou fallback por parent=name
local subs = {}
if type(parentSk.suborder) == "table" then
subs = parentSk.suborder
else
for k, v in pairs(data.skills or {}) do
if type(v) == "table" and v.parent == parentKey then
table.insert(subs, k)
end
end
table.sort(subs)
end
local childKey = subs[sIndex or 1] or ""
local sk = (data.skills or {})[childKey] or {}
name = trim(sk.name or childKey or "")
if type(sk.desc) == "table" then
for _, code in ipairs({"pt","en","es","pl"}) do
local d = sk.desc[code]
if d and trim(d) ~= "" then
desc_i18n[code] = colorize(d)
end
end
elseif sk.desc and trim(sk.desc) ~= "" then
desc_i18n["pt"] = colorize(sk.desc)
end
_IS_SUB = true
_PARENT_M = parentM
_PARENT_NAME = parentKey
end
local function nz(v)
v = v or ""
return (trim(v) ~= "" and v or nil)
end
local chosen = desc_i18n[lang] or desc_i18n["pt"] or ""
local obj = {
icon = (trim(a.icon or "") ~= "" and a.icon or "Nada.png"),
level = (trim(a.level or "") ~= "" and a.level or "NIVEL"),
energy = nz(a.energy),
powerpve = nz(a.powerpve),
powerpvp = nz(a.powerpvp),
cooldown = nz(a.cooldown),
video = a.video or ""
}
if name and name ~= "" then
obj.name = name
end
if chosen and chosen ~= "" then
obj.desc = chosen
end
-- inclui as variantes para o Character expor como data-desc-*
if next(desc_i18n) ~= nil then
obj.desc_i18n = desc_i18n
obj.descPt = desc_i18n.pt
obj.descEn = desc_i18n.en
obj.descEs = desc_i18n.es
obj.descPl = desc_i18n.pl
end
-- NOVO: metadados hierárquicos
if _IS_SUB then
obj.type = "sub"
obj.parentM = _PARENT_M
obj.parentName = _PARENT_NAME
else
if _M_INDEX then obj.m = _M_INDEX end
if _SUBS and type(_SUBS) == "table" and #_SUBS > 0 then
obj.subs_names = _SUBS
end
end
return mw.text.jsonEncode(obj)
end
-- Skill (emote: sem M)
function p.emote(frame)
local a = safeArgs(frame)
local obj = {
icon = (trim(a.icon or "") ~= "" and a.icon or "Nada.png"),
video = a.video or ""
}
return mw.text.jsonEncode(obj)
end
-- ======= Gambis helpers para Tier/Tags no cabeçalho =======
function p.expandTier(frame)
local a = safeArgs(frame)
local nome = trim(a.nome or (frame:getParent() and frame:getParent().args.nome) or "")
if nome == "" then
nome = resolveCharFromFrames(frame, a)
end
local data = requireCharacterModule(nome) or {}
local lang = trim(a.lang or (frame:getParent() and frame:getParent().args.lang) or "pt"):lower()
local tier = (data.tier_i18n and data.tier_i18n[lang]) or data.tier or ""
return trim(tier)
end
function p.expandTags(frame)
local a = safeArgs(frame)
local nome = trim(a.nome or (frame:getParent() and frame:getParent().args.nome) or "")
if nome == "" then
nome = resolveCharFromFrames(frame, a)
end
local data = requireCharacterModule(nome) or {}
local lang = trim(a.lang or (frame:getParent() and frame:getParent().args.lang) or "pt"):lower()
local arr = (data.tags_i18n and data.tags_i18n[lang]) or data.tags
if type(arr) == "table" then
return table.concat(arr, " / ")
end
return trim(arr or "")
end
return p