Mudanças entre as edições de "Módulo:Info"
Ir para navegação
Ir para pesquisar
m |
|||
| Linha 111: | Linha 111: | ||
local COLOR = { | local COLOR = { | ||
debuff = "#ff5252", | debuff = "#ff5252", | ||
atk = "ff9000", | atk = "#ff9000", | ||
def = "#006cfe", | def = "#006cfe", | ||
ms = "#43a047", | ms = "#43a047", | ||
Edição das 22h52min de 12 de outubro de 2025
A documentação para este módulo pode ser criada em Módulo:Info/doc
-- Módulo:Info — resolve metadados e skills (com Subskill e cores inline)
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 ok, data = pcall(function()
return require("Módulo:" .. charName)
end)
if ok and type(data) == "table" then
return data
end
charName = charName:gsub(" ", "_")
ok, data = pcall(function()
return require("Módulo:" .. charName)
end)
if ok and type(data) == "table" then
return data
end
return nil
end
-- Separa uma sequência de {} (JSONs colados) em uma tabela de chunks
local function collectJsonObjects(s)
s = tostring(s or "")
local out = {}
for chunk in s:gmatch("%b{}") do
table.insert(out, chunk)
end
return out
end
--------------------------------------------------------------------------------
-- I18N: rótulos de atributos + "Nível"
--------------------------------------------------------------------------------
local I18N = {
pt = {
level = "Nível",
power = "Poder",
power_pvp = "Poder PvP",
energy = "Energia",
energy_cost = "Energia",
energy_gain = "Energia",
cooldown = "Recarga"
},
en = {
level = "Level",
power = "Power",
power_pvp = "Power PvP",
energy = "Energy",
energy_cost = "Energy",
energy_gain = "Energy",
cooldown = "Cooldown"
},
es = {
level = "Nivel",
power = "Poder",
power_pvp = "Poder PvP",
energy = "Energía",
energy_cost = "Energía",
energy_gain = "Energía",
cooldown = "Enfriamiento"
},
pl = {
level = "Poziom",
power = "Moc",
power_pvp = "Moc PvP",
energy = "Energia",
energy_cost = "Energia",
energy_gain = "Energia",
cooldown = "Odnawianie"
}
}
local function resolveCharFromFrames(frame, a)
a = a or {}
if frame and frame.getParent then
local parent = frame:getParent()
if parent and parent.args then
if parent.args.nome and trim(parent.args.nome) ~= "" then
return trim(parent.args.nome)
end
for k, v in pairs(parent.args) do
if type(k) == "string" and k:match("^class") and trim(v) ~= "" then
return trim(v)
end
end
end
end
if a.nome and trim(a.nome) ~= "" then
return trim(a.nome)
end
if a.char and trim(a.char) ~= "" then
return trim(a.char)
end
local title = mw.title.getCurrentTitle()
return title and trim(title.text) or ""
end
-- mapa de cores (inline!)
local COLOR = {
debuff = "#ff5252",
atk = "#ff9000",
def = "#006cfe",
ms = "#43a047",
hp = "#42a5f5",
sec = "#ffcc00"
}
-- substitui {{atk:}}, {{def:}}, {{ms:}}, {{hp:}}, {{sec:}}, {{debuff:}} por <span style="color:#hex">…</span>
local function colorize(txt)
if not txt or txt == "" then
return ""
end
return (tostring(txt):gsub("{{%s*(%a+)%s*:%s*([^}]+)%s*}}", function(tag, inner)
tag = tag:lower()
local hex = COLOR[tag]
if not hex then
return "{{" .. tag .. ":" .. inner .. "}}"
end
return string.format('<span style="color:%s;">%s</span>', hex, trim(inner))
end))
end
-- ===== API =====
-- Tier textual (i18n)
function p.getTier(frame)
local a = safeArgs(frame)
local char = trim(frame.args[1] or a.nome)
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())
if data.tier_i18n and data.tier_i18n[lang] then
return data.tier_i18n[lang]
end
return trim(data.tier or "")
end
-- Tags textuais (i18n)
function p.getTags(frame)
local a = safeArgs(frame)
local char = trim(frame.args[1] or a.nome)
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 trim(tags or "")
end
return trim(table.concat(tags, " / "))
end
-- Skill (com M)
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 name, desc_i18n = nil, {}
if 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 "")
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)
end
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 "",
name = name,
noback = (trim(a.noback or "") == "yes" or trim(a.noback or "") == "true") and true or nil
}
if chosen ~= "" then
obj.desc = chosen
end
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
-- empacota subskills vindas via |subs= (cada {{Subskill}} vira um objeto JSON)
do
local subsPacked = a.subs or ""
local subsArr = {}
for _, chunk in ipairs(collectJsonObjects(subsPacked)) do
local ok, sk = pcall(mw.text.jsonDecode, chunk)
if ok and type(sk) == "table" then
table.insert(subsArr, sk)
end
end
-- se não vier via |subs=, tenta obter do módulo (suborder/subskills)
if #subsArr == 0 and a.M and tonumber(a.M) then
local m = tonumber(a.M)
local order = (data and data.order) or {}
local key = order[m] or ""
local sk = (data and data.skills and data.skills[key]) or {}
local suborder = type(sk) == "table" and sk.suborder or nil
local subskills = type(sk) == "table" and sk.subskills or nil
if type(suborder) == "table" and type(subskills) == "table" then
for _, n in ipairs(suborder) do
local sub = subskills[n]
if type(sub) == "table" then
local subObj = {
n = n,
name = n,
icon = sub.icon or "",
level = sub.level or "",
video = sub.video or "",
energy = sub.energy,
powerpve = sub.powerpve,
powerpvp = sub.powerpvp,
cooldown = sub.cooldown,
desc_i18n = sub.desc,
descPt = sub.desc and sub.desc.pt or nil,
descEn = sub.desc and sub.desc.en or nil,
descEs = sub.desc and sub.desc.es or nil,
descPl = sub.desc and sub.desc.pl or nil
}
-- nested subs do módulo (sub.suborder/sub.subskills)
if type(sub.suborder) == "table" and type(sub.subskills) == "table" then
local nested = {}
for _, nn in ipairs(sub.suborder) do
local s2 = sub.subskills[nn]
if type(s2) == "table" then
table.insert(nested, {
n = nn,
name = nn,
icon = s2.icon or "",
level = s2.level or "",
video = s2.video or "",
energy = s2.energy,
powerpve = s2.powerpve,
powerpvp = s2.powerpvp,
cooldown = s2.cooldown,
desc_i18n = s2.desc,
descPt = s2.desc and s2.desc.pt or nil,
descEn = s2.desc and s2.desc.en or nil,
descEs = s2.desc and s2.desc.es or nil,
descPl = s2.desc and s2.desc.pl or nil
})
end
end
if #nested > 0 then subObj.subs = nested end
end
table.insert(subsArr, subObj)
end
end
end
end
if #subsArr > 0 then
obj.subs = subsArr
end
-- suborder do módulo (se existir pra esta skill M)
if a.M and tonumber(a.M) then
local m = tonumber(a.M)
local order = (data and data.order) or {}
local key = order[m] or ""
local sk = (data and data.skills and data.skills[key]) or {}
if type(sk) == "table" and type(sk.suborder) == "table" then
obj.suborder = sk.suborder
end
end
end
return mw.text.jsonEncode(obj)
end
-- Emote (sem M)
function p.emote(frame)
local a = safeArgs(frame)
local obj = {
name = "Emote",
desc = "",
icon = (trim(a.icon or "") ~= "" and a.icon or "Nada.png"),
level = (trim(a.level or "") ~= "" and a.level or "NIVEL"),
video = a.video or ""
}
return mw.text.jsonEncode(obj)
end
-- Subskill (nome n EXATO do suborder; agrega desc_i18n do módulo + atributos locais)
function p.subskill(frame)
local a = safeArgs(frame)
local lang = trim((a.lang or (frame:getParent() and frame:getParent().args.lang) or "pt"):lower())
local n = trim(a.n or "")
if n == "" then
return mw.text.jsonEncode({})
end
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 desc_i18n = {}
for _, key in ipairs(data.order or {}) do
local sk = (data.skills or {})[key]
if type(sk) == "table" and type(sk.subskills) == "table" then
local sub = sk.subskills[n]
if sub then
local langs = { "pt", "en", "es", "pl" }
for _, code in ipairs(langs) do
local d = sub.desc and sub.desc[code]
if d and trim(d) ~= "" then
desc_i18n[code] = colorize(d)
end
end
break
end
end
end
local function nz(v)
v = v or "";
return (trim(v) ~= "" and v or nil)
end
local obj = {
name = n,
icon = (trim(a.icon or "") ~= "" and a.icon or "Nada.png"),
level = (trim(a.level or "") ~= "" and a.level or "NIVEL"),
video = a.video or "",
energy = nz(a.energy),
powerpve = nz(a.powerpve),
powerpvp = nz(a.powerpvp),
cooldown = nz(a.cooldown),
back = (trim(a.back or "") == "yes" or trim(a.back or "") == "true") and true or nil
}
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
-- Nested subs support: allow |subs= inside a subskill
do
local subsPacked = a.subs or ""
local subsArr = {}
for _, chunk in ipairs(collectJsonObjects(subsPacked)) do
local ok, sub = pcall(mw.text.jsonDecode, chunk)
if ok and type(sub) == "table" then
table.insert(subsArr, sub)
end
end
if #subsArr > 0 then
obj.subs = subsArr
end
end
return mw.text.jsonEncode(obj)
end
-- Weapon (com WM, sem subskills)
function p.weapon(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 name, desc_i18n = nil, {}
-- Se vier WM, busca no módulo (data.weapon.order[WM] -> data.weapon.skills[key])
if a.WM and trim(a.WM) ~= "" then
local wm = tonumber(a.WM) or 0
local weaponData = data.weapon or {}
local order = weaponData.order or {}
local key = order[wm] or ""
local wk = (weaponData.skills or {})[key] or {}
name = trim(wk.name or key or "")
if type(wk.desc) == "table" then
local langs = { "pt", "en", "es", "pl" }
for _, code in ipairs(langs) do
local d = wk.desc[code]
if d and trim(d) ~= "" then
desc_i18n[code] = colorize(d)
end
end
elseif wk.desc and trim(wk.desc) ~= "" then
desc_i18n["pt"] = colorize(wk.desc)
end
else
-- Sem WM: permite setar name e desc pelos args
name = trim(a.name or "")
if trim(a.desc_pt or "") ~= "" then desc_i18n["pt"] = colorize(a.desc_pt) end
if trim(a.desc_en or "") ~= "" then desc_i18n["en"] = colorize(a.desc_en) end
if trim(a.desc_es or "") ~= "" then desc_i18n["es"] = colorize(a.desc_es) end
if trim(a.desc_pl or "") ~= "" then desc_i18n["pl"] = colorize(a.desc_pl) end
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 "",
name = name
}
if chosen ~= "" then
obj.desc = chosen
end
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
-- Armas NÃO têm subskills: não empacotar subs/suborder
return mw.text.jsonEncode(obj)
end
-- Gambis: expandir tier/tags via token "tierNome", "tagsNome"
function p.expandTier(frame)
local token = trim(frame.args[1] or "")
local nome = trim(frame.args[2] or (frame:getParent() and frame:getParent().args.nome) or "")
if token == "" then
return ""
end
if token:lower():sub(1, 4) ~= "tier" then
return token
end
local char = nome ~= "" and nome or token:match("^tier(.+)$") or ""
if char == "" then
local title = mw.title.getCurrentTitle()
char = title and trim(title.text) or ""
end
local data = requireCharacterModule(char) or {}
local lang = trim((frame.args.lang or "pt"):lower())
if data.tier_i18n and data.tier_i18n[lang] then
return data.tier_i18n[lang]
end
return trim(data.tier or "")
end
function p.expandTags(frame)
local token = trim(frame.args[1] or "")
local nome = trim(frame.args[2] or (frame:getParent() and frame:getParent().args.nome) or "")
if token == "" then
return ""
end
if token:lower():sub(1, 4) ~= "tags" then
return token
end
local char = nome ~= "" and nome or token:match("^tags(.+)$") or ""
if char == "" then
local title = mw.title.getCurrentTitle()
char = title and trim(title.text) or ""
end
local data = requireCharacterModule(char) or {}
local arr = (data.tags_i18n and data.tags_i18n.pt) or data.tags
if type(arr) == "table" then
return table.concat(arr, " / ")
end
return trim(arr or "")
end
return p