Mudanças entre as edições de "Módulo:I.Skills"
Ir para navegação
Ir para pesquisar
m |
m |
||
| Linha 79: | Linha 79: | ||
local sub = subskills[subName] | local sub = subskills[subName] | ||
if type(sub) == "table" then | if type(sub) == "table" then | ||
-- | -- NOVO SISTEMA: Herança explícita | ||
-- inherit_from: DE qual skill herdar (obrigatório para herdar) | |||
-- inherit_fields: O QUE herdar (array de campos, obrigatório para herdar) | |||
-- Se não especificar ambos, não herda nada (mais seguro) | |||
-- | local inheritFrom = sub.inherit_from -- DE qual skill herdar | ||
-- | local inheritFields = sub.inherit_fields or {} -- O QUE herdar (array) | ||
-- | |||
local | -- Converte inheritFields para set para busca rápida | ||
if type( | local inheritFieldsSet = {} | ||
if type(inheritFields) == "table" then | |||
for _, field in ipairs( | for _, field in ipairs(inheritFields) do | ||
if type(field) == "string" then | if type(field) == "string" then | ||
inheritFieldsSet[field] = true | |||
end | end | ||
end | end | ||
end | end | ||
-- | -- Busca skill principal para herdar | ||
local | local parentSkill = nil | ||
if inheritFrom and parentSkills and type(parentSkills) == "table" then | |||
parentSkill = parentSkills[inheritFrom] | |||
end | end | ||
-- | -- Função auxiliar: verifica se um campo DEVE ser herdado | ||
-- Só herda se inherit_from E inherit_fields estiverem definidos E o campo estiver na lista | |||
local function shouldInheritField(fieldName) | |||
local parentSkill | if not inheritFrom or not parentSkill then | ||
return false -- Sem inherit_from ou parentSkill, não herda | |||
end | |||
return inheritFieldsSet[fieldName] == true -- Só herda se estiver em inherit_fields | |||
end | end | ||
-- Valida flags: deve ser uma tabela com pelo menos um elemento, senão nil | -- Valida flags: deve ser uma tabela com pelo menos um elemento, senão nil | ||
-- Flags herdam se | -- Flags herdam apenas se "flags" estiver em inherit_fields | ||
local subFlags = (sub.flags ~= nil) and sub.flags or | local subFlags = (sub.flags ~= nil) and sub.flags or | ||
( | (shouldInheritField("flags") and parentSkill and parentSkill.flags) | ||
local validSubFlags = (type(subFlags) == "table" and #subFlags > 0) and subFlags or nil | local validSubFlags = (type(subFlags) == "table" and #subFlags > 0) and subFlags or nil | ||
-- Cria o objeto da subskill, herdando campos | -- Cria o objeto da subskill, herdando apenas campos explicitamente listados em inherit_fields | ||
local subObj = { | local subObj = { | ||
name = subName, | name = subName, | ||
n = subName, | n = subName, | ||
-- Herda icon se | -- Herda icon apenas se "icon" estiver em inherit_fields | ||
icon = sub.icon or ( | icon = sub.icon or (shouldInheritField("icon") and parentSkill and parentSkill.icon) or "", | ||
-- Herda level se | -- Herda level apenas se "level" estiver em inherit_fields | ||
level = sub.level or ( | level = sub.level or (shouldInheritField("level") and parentSkill and parentSkill.level) or "", | ||
-- Herda energy se | -- Herda energy apenas se "energy" estiver em inherit_fields | ||
energy = (sub.energy ~= nil) and sub.energy or | energy = (sub.energy ~= nil) and sub.energy or | ||
( | (shouldInheritField("energy") and parentSkill and parentSkill.energy), | ||
-- Herda powerpve se | -- Herda powerpve apenas se "powerpve" estiver em inherit_fields | ||
powerpve = (sub.powerpve ~= nil) and sub.powerpve or | powerpve = (sub.powerpve ~= nil) and sub.powerpve or | ||
( | (shouldInheritField("powerpve") and parentSkill and parentSkill.powerpve), | ||
-- Herda powerpvp se | -- Herda powerpvp apenas se "powerpvp" estiver em inherit_fields | ||
powerpvp = (sub.powerpvp ~= nil) and sub.powerpvp or | powerpvp = (sub.powerpvp ~= nil) and sub.powerpvp or | ||
( | (shouldInheritField("powerpvp") and parentSkill and parentSkill.powerpvp), | ||
-- Herda cooldown se | -- Herda cooldown apenas se "cooldown" estiver em inherit_fields | ||
cooldown = (sub.cooldown ~= nil) and sub.cooldown or | cooldown = (sub.cooldown ~= nil) and sub.cooldown or | ||
( | (shouldInheritField("cooldown") and parentSkill and parentSkill.cooldown), | ||
-- Video sempre vem da subskill (nunca herda) | -- Video sempre vem da subskill (nunca herda) | ||
video = sub.video or "", | video = sub.video or "", | ||
-- Descrição: | -- Descrição: será processada depois, herda apenas se "desc" estiver em inherit_fields | ||
desc_i18n = nil, -- Será definido depois | |||
desc_i18n = nil, -- Será definido depois | -- Flags: herda apenas se "flags" estiver em inherit_fields | ||
-- Flags: se flags | |||
flags = validSubFlags, | flags = validSubFlags, | ||
-- Herda weapon se | -- Herda weapon apenas se "weapon" estiver em inherit_fields | ||
weapon = (sub.weapon and processWeapon(sub.weapon)) or | weapon = (sub.weapon and processWeapon(sub.weapon)) or | ||
( | (shouldInheritField("weapon") and parentSkill and processWeapon(parentSkill.weapon)), | ||
-- Herda back se | -- Herda back apenas se "back" estiver em inherit_fields | ||
back = (sub.back ~= nil) and sub.back or ( | back = (sub.back ~= nil) and sub.back or | ||
-- Inclui | (shouldInheritField("back") and parentSkill and parentSkill.back), | ||
-- Inclui campos de herança para o frontend | |||
inherit_from = inheritFrom, | |||
inherit_fields = inheritFields | |||
} | } | ||
-- | -- Processa descrição: herda apenas se "desc" estiver em inherit_fields | ||
if sub.desc ~= nil then | |||
-- Sempre processa descrição da subskill se existir (prioridade máxima) | |||
local processedDesc = processDesc(sub.desc) | |||
if processedDesc then | |||
subObj.desc_i18n = processedDesc | |||
else | else | ||
-- Se | -- Se processDesc retornou nil, tenta processar novamente | ||
subObj.desc_i18n = processDesc(sub.desc) or {} | |||
subObj.desc_i18n = | |||
end | end | ||
-- | elseif shouldInheritField("desc") and parentSkill and parentSkill.desc then | ||
-- Herda descrição apenas se "desc" estiver em inherit_fields | |||
if | local processedDesc = processDesc(parentSkill.desc) | ||
subObj.desc_i18n = | if processedDesc then | ||
subObj.desc_i18n = processedDesc | |||
end | end | ||
else | else | ||
-- Se não tem desc na subskill e não pode herdar, desc_i18n é nil | |||
subObj.desc_i18n = nil | |||
end | end | ||
Edição das 01h53min de 4 de janeiro de 2026
A documentação para este módulo pode ser criada em Módulo:I.Skills/doc
-- Módulo:I.Skills — skill(), skin() com suporte nativo a subskills recursivas
local p = {}
local utils = require("Módulo:I.Utils")
local trim = utils.trim
local colorize = utils.colorize
-- Fallback se colorize não existir
if not colorize or type(colorize) ~= "function" then
colorize = function(txt)
if not txt or txt == "" then
return ""
end
-- Versão simplificada sem colorização
return tostring(txt)
end
end
local cUtils = require("Módulo:C.Utils")
local requireCharModule = cUtils.requireCharModule
-- Processa descrição (desc table → desc_i18n)
local function processDesc(desc)
if not desc then return nil end
if type(desc) == "string" then
return { pt = colorize(desc) }
end
if type(desc) == "table" then
local desc_i18n = {}
for code, text in pairs(desc) do
if type(text) == "string" and text ~= "" then
desc_i18n[code] = colorize(text)
end
end
return next(desc_i18n) and desc_i18n or nil
end
return nil
end
-- Processa weapon (aplica colorize nas descrições)
local function processWeapon(weapon)
if not weapon or type(weapon) ~= "table" then
return weapon
end
local processed = {}
-- Copia todos os campos do weapon
for k, v in pairs(weapon) do
processed[k] = v
end
-- Processa descrição do weapon (se existir)
if weapon.desc then
processed.desc_i18n = processDesc(weapon.desc)
-- Remove desc se desc_i18n foi criado (para evitar duplicação)
if processed.desc_i18n then
processed.desc = nil
end
end
-- Se o weapon processado estiver vazio (sem campos), retorna nil
-- Isso evita que weapons vazios {} sejam considerados válidos
if next(processed) == nil then
return nil
end
return processed
end
-- Processa subskills recursivamente (suporte ilimitado a níveis)
-- parentSkills: tabela de skills principais para herança automática
local function processSubskills(subskills, suborder, parentSkills)
if not subskills or not suborder or type(subskills) ~= "table" or type(suborder) ~= "table" then
return nil
end
local arr = {}
for _, subName in ipairs(suborder) do
local sub = subskills[subName]
if type(sub) == "table" then
-- NOVO SISTEMA: Herança explícita
-- inherit_from: DE qual skill herdar (obrigatório para herdar)
-- inherit_fields: O QUE herdar (array de campos, obrigatório para herdar)
-- Se não especificar ambos, não herda nada (mais seguro)
local inheritFrom = sub.inherit_from -- DE qual skill herdar
local inheritFields = sub.inherit_fields or {} -- O QUE herdar (array)
-- Converte inheritFields para set para busca rápida
local inheritFieldsSet = {}
if type(inheritFields) == "table" then
for _, field in ipairs(inheritFields) do
if type(field) == "string" then
inheritFieldsSet[field] = true
end
end
end
-- Busca skill principal para herdar
local parentSkill = nil
if inheritFrom and parentSkills and type(parentSkills) == "table" then
parentSkill = parentSkills[inheritFrom]
end
-- Função auxiliar: verifica se um campo DEVE ser herdado
-- Só herda se inherit_from E inherit_fields estiverem definidos E o campo estiver na lista
local function shouldInheritField(fieldName)
if not inheritFrom or not parentSkill then
return false -- Sem inherit_from ou parentSkill, não herda
end
return inheritFieldsSet[fieldName] == true -- Só herda se estiver em inherit_fields
end
-- Valida flags: deve ser uma tabela com pelo menos um elemento, senão nil
-- Flags herdam apenas se "flags" estiver em inherit_fields
local subFlags = (sub.flags ~= nil) and sub.flags or
(shouldInheritField("flags") and parentSkill and parentSkill.flags)
local validSubFlags = (type(subFlags) == "table" and #subFlags > 0) and subFlags or nil
-- Cria o objeto da subskill, herdando apenas campos explicitamente listados em inherit_fields
local subObj = {
name = subName,
n = subName,
-- Herda icon apenas se "icon" estiver em inherit_fields
icon = sub.icon or (shouldInheritField("icon") and parentSkill and parentSkill.icon) or "",
-- Herda level apenas se "level" estiver em inherit_fields
level = sub.level or (shouldInheritField("level") and parentSkill and parentSkill.level) or "",
-- Herda energy apenas se "energy" estiver em inherit_fields
energy = (sub.energy ~= nil) and sub.energy or
(shouldInheritField("energy") and parentSkill and parentSkill.energy),
-- Herda powerpve apenas se "powerpve" estiver em inherit_fields
powerpve = (sub.powerpve ~= nil) and sub.powerpve or
(shouldInheritField("powerpve") and parentSkill and parentSkill.powerpve),
-- Herda powerpvp apenas se "powerpvp" estiver em inherit_fields
powerpvp = (sub.powerpvp ~= nil) and sub.powerpvp or
(shouldInheritField("powerpvp") and parentSkill and parentSkill.powerpvp),
-- Herda cooldown apenas se "cooldown" estiver em inherit_fields
cooldown = (sub.cooldown ~= nil) and sub.cooldown or
(shouldInheritField("cooldown") and parentSkill and parentSkill.cooldown),
-- Video sempre vem da subskill (nunca herda)
video = sub.video or "",
-- Descrição: será processada depois, herda apenas se "desc" estiver em inherit_fields
desc_i18n = nil, -- Será definido depois
-- Flags: herda apenas se "flags" estiver em inherit_fields
flags = validSubFlags,
-- Herda weapon apenas se "weapon" estiver em inherit_fields
weapon = (sub.weapon and processWeapon(sub.weapon)) or
(shouldInheritField("weapon") and parentSkill and processWeapon(parentSkill.weapon)),
-- Herda back apenas se "back" estiver em inherit_fields
back = (sub.back ~= nil) and sub.back or
(shouldInheritField("back") and parentSkill and parentSkill.back),
-- Inclui campos de herança para o frontend
inherit_from = inheritFrom,
inherit_fields = inheritFields
}
-- Processa descrição: herda apenas se "desc" estiver em inherit_fields
if sub.desc ~= nil then
-- Sempre processa descrição da subskill se existir (prioridade máxima)
local processedDesc = processDesc(sub.desc)
if processedDesc then
subObj.desc_i18n = processedDesc
else
-- Se processDesc retornou nil, tenta processar novamente
subObj.desc_i18n = processDesc(sub.desc) or {}
end
elseif shouldInheritField("desc") and parentSkill and parentSkill.desc then
-- Herda descrição apenas se "desc" estiver em inherit_fields
local processedDesc = processDesc(parentSkill.desc)
if processedDesc then
subObj.desc_i18n = processedDesc
end
else
-- Se não tem desc na subskill e não pode herdar, desc_i18n é nil
subObj.desc_i18n = nil
end
-- RECURSÃO NATIVA: processa sub-subskills (e sub-sub-subskills, etc.)
-- Passa parentSkills também para recursão (herança sempre vem das skills principais)
if type(sub.subskills) == "table" and type(sub.suborder) == "table" then
subObj.subs = processSubskills(sub.subskills, sub.suborder, parentSkills)
subObj.suborder = sub.suborder
end
table.insert(arr, subObj)
end
end
return #arr > 0 and arr or nil
end
-- Gera JSON de skills a partir do módulo
function p.skill(frame)
local parent = frame:getParent() or frame
local args = parent.args or {}
local moduleName = trim(args.module or "")
if moduleName == "" then
return "[]"
end
local data = requireCharModule(moduleName) or {}
if not data.order or not data.skills then
return "[]"
end
local skillsArr = {}
-- Se houver forms, obtém a primeira forma disponível (genérico)
local firstForm = nil
local firstFormName = nil
if type(data.forms) == "table" then
-- Pega a primeira forma disponível (ordem não garantida em pairs, mas pega a primeira válida)
for formName, formData in pairs(data.forms) do
if type(formData) == "table" and type(formData.skills) == "table" and type(formData.order) == "table" then
firstForm = formData
firstFormName = formName
break
end
end
end
-- Encontra a skill com form_switch = true (genérico)
local formSwitchSkillName = nil
local nextFixedSkillAfterFormSwitch = nil
if type(data.skills) == "table" then
for skillName, sk in pairs(data.skills) do
if type(sk) == "table" and sk.form_switch == true then
formSwitchSkillName = skillName
break
end
end
-- Encontra a próxima skill fixa depois do form_switch no order
if formSwitchSkillName and type(data.order) == "table" then
local foundFormSwitch = false
for _, skillName in ipairs(data.order) do
if foundFormSwitch then
-- Esta é a próxima skill fixa depois do form_switch
nextFixedSkillAfterFormSwitch = skillName
break
end
if skillName == formSwitchSkillName then
foundFormSwitch = true
end
end
end
end
-- Se houver forms, insere a primeira skill da forma ANTES da skill com form_switch
if firstForm and type(firstForm.skills) == "table" and type(firstForm.order) == "table" and #firstForm.order > 0 then
local firstSkillName = firstForm.order[1]
local formSk = firstForm.skills[firstSkillName]
if type(formSk) == "table" then
-- Valida flags: deve ser uma tabela com pelo menos um elemento, senão nil
local formFlags = nil
if type(formSk.flags) == "table" and #formSk.flags > 0 then
formFlags = formSk.flags
end
local formSkillObj = {
name = firstSkillName,
n = firstSkillName,
icon = (formSk.icon and formSk.icon ~= "") and formSk.icon or "Nada.png",
level = formSk.level or "NIVEL",
energy = formSk.energy,
powerpve = formSk.powerpve,
powerpvp = formSk.powerpvp,
cooldown = formSk.cooldown,
video = formSk.video or "",
desc_i18n = processDesc(formSk.desc),
flags = formFlags,
weapon = processWeapon(formSk.weapon)
}
if type(formSk.subskills) == "table" and type(formSk.suborder) == "table" then
formSkillObj.subs = processSubskills(formSk.subskills, formSk.suborder, data.skills)
formSkillObj.suborder = formSk.suborder
end
table.insert(skillsArr, formSkillObj)
end
end
-- Itera sobre order para manter ordem correta (skills fixas)
local nextFixedSkillIndex = -1
for idx, skillName in ipairs(data.order) do
local sk = data.skills[skillName]
if type(sk) == "table" then
-- Valida flags: deve ser uma tabela com pelo menos um elemento, senão nil
-- Proteção extra: verifica se flags é uma tabela válida e serializável
-- Valida flags: deve ser uma tabela com pelo menos um elemento, senão nil
-- Simplificado: se é uma tabela válida com strings, inclui diretamente
local validFlags = nil
if type(sk.flags) == "table" and #sk.flags > 0 then
-- Verifica se todos os elementos são strings válidas
local allValid = true
for i, flag in ipairs(sk.flags) do
if type(flag) ~= "string" or flag == "" then
allValid = false
break
end
end
if allValid then
validFlags = sk.flags
else
-- Se houver elementos inválidos, cria uma cópia limpa
local cleanFlags = {}
for i, flag in ipairs(sk.flags) do
if type(flag) == "string" and flag ~= "" then
table.insert(cleanFlags, flag)
end
end
if #cleanFlags > 0 then
validFlags = cleanFlags
end
end
end
local skillObj = {
name = skillName,
n = skillName,
icon = (sk.icon and sk.icon ~= "") and sk.icon or "Nada.png",
level = sk.level or "NIVEL",
energy = sk.energy,
powerpve = sk.powerpve,
powerpvp = sk.powerpvp,
cooldown = sk.cooldown,
video = sk.video or "",
desc_i18n = processDesc(sk.desc),
flags = validFlags,
weapon = processWeapon(sk.weapon),
weaponicon = data.weaponicon,
form_switch = sk.form_switch,
form_videos = sk.form_videos -- Vídeos específicos para transições de forma
}
-- Processa subskills recursivamente (suporte nativo ilimitado)
-- Passa data.skills para herança automática quando subskill tem mesmo nome que skill principal
if type(sk.subskills) == "table" and type(sk.suborder) == "table" then
skillObj.subs = processSubskills(sk.subskills, sk.suborder, data.skills)
skillObj.suborder = sk.suborder
end
-- Valida flags antes de inserir no array (proteção extra)
if skillObj.flags and (type(skillObj.flags) ~= "table" or #skillObj.flags == 0) then
skillObj.flags = nil
end
table.insert(skillsArr, skillObj)
-- Se for a skill com form_switch e houver forms, adiciona a terceira skill da forma logo após
if skillName == formSwitchSkillName and firstForm and type(firstForm.skills) == "table" and type(firstForm.order) == "table" and #firstForm.order >= 2 then
local thirdSkillName = firstForm.order[2] -- Segunda na ordem = terceira skill (1, 2, 3)
local formSk = firstForm.skills[thirdSkillName]
if type(formSk) == "table" then
-- Valida flags: deve ser uma tabela com pelo menos um elemento, senão nil
local formFlags3 = nil
if type(formSk.flags) == "table" and #formSk.flags > 0 then
formFlags3 = formSk.flags
end
local formSkillObj = {
name = thirdSkillName,
n = thirdSkillName,
icon = (formSk.icon and formSk.icon ~= "") and formSk.icon or "Nada.png",
level = formSk.level or "NIVEL",
energy = formSk.energy,
powerpve = formSk.powerpve,
powerpvp = formSk.powerpvp,
cooldown = formSk.cooldown,
video = formSk.video or "",
desc_i18n = processDesc(formSk.desc),
flags = formFlags3,
weapon = processWeapon(formSk.weapon)
}
if type(formSk.subskills) == "table" and type(formSk.suborder) == "table" then
formSkillObj.subs = processSubskills(formSk.subskills, formSk.suborder, data.skills)
formSkillObj.suborder = formSk.suborder
end
table.insert(skillsArr, formSkillObj)
end
end
-- Guarda índice da próxima skill fixa depois do form_switch para inserir a quinta skill depois
if skillName == nextFixedSkillAfterFormSwitch then
nextFixedSkillIndex = #skillsArr
end
-- Se for a próxima skill fixa depois do form_switch e houver forms, adiciona a quinta skill da forma logo após
if skillName == nextFixedSkillAfterFormSwitch and firstForm and type(firstForm.skills) == "table" and type(firstForm.order) == "table" and #firstForm.order >= 3 then
local fifthSkillName = firstForm.order[3] -- Terceira na ordem = quinta skill (1, 2, 3)
local formSk = firstForm.skills[fifthSkillName]
if type(formSk) == "table" then
-- Valida flags: deve ser uma tabela com pelo menos um elemento, senão nil
local formFlags5 = nil
if type(formSk.flags) == "table" and #formSk.flags > 0 then
formFlags5 = formSk.flags
end
local formSkillObj = {
name = fifthSkillName,
n = fifthSkillName,
icon = (formSk.icon and formSk.icon ~= "") and formSk.icon or "Nada.png",
level = formSk.level or "NIVEL",
energy = formSk.energy,
powerpve = formSk.powerpve,
powerpvp = formSk.powerpvp,
cooldown = formSk.cooldown,
video = formSk.video or "",
desc_i18n = processDesc(formSk.desc),
flags = formFlags5,
weapon = processWeapon(formSk.weapon)
}
if type(formSk.subskills) == "table" and type(formSk.suborder) == "table" then
formSkillObj.subs = processSubskills(formSk.subskills, formSk.suborder, data.skills)
formSkillObj.suborder = formSk.suborder
end
table.insert(skillsArr, formSkillObj)
end
end
end
end
-- Proteção contra erros no jsonEncode (especialmente para flags)
-- Limpa flags problemáticas ANTES de tentar serializar
-- NOTA: Não remove flags válidas, apenas valida e limpa flags inválidas
for _, skill in ipairs(skillsArr) do
if skill.flags then
if type(skill.flags) ~= "table" or #skill.flags == 0 then
skill.flags = nil
else
-- Limpa flags inválidas (não strings ou vazias)
local cleanFlags = {}
for i, flag in ipairs(skill.flags) do
if type(flag) == "string" and flag ~= "" then
table.insert(cleanFlags, flag)
end
end
if #cleanFlags > 0 then
skill.flags = cleanFlags
else
skill.flags = nil
end
end
end
-- Limpa flags em subskills também
if skill.subs and type(skill.subs) == "table" then
for _, sub in ipairs(skill.subs) do
if sub.flags then
if type(sub.flags) ~= "table" or #sub.flags == 0 then
sub.flags = nil
else
local cleanSubFlags = {}
for i, flag in ipairs(sub.flags) do
if type(flag) == "string" and flag ~= "" then
table.insert(cleanSubFlags, flag)
end
end
if #cleanSubFlags > 0 then
sub.flags = cleanSubFlags
else
sub.flags = nil
end
end
end
end
end
end
local ok, jsonResult = pcall(function()
return mw.text.jsonEncode(skillsArr)
end)
if ok and jsonResult then
return jsonResult
else
-- Última tentativa: remove TODAS as flags
for _, skill in ipairs(skillsArr) do
skill.flags = nil
if skill.subs and type(skill.subs) == "table" then
for _, sub in ipairs(skill.subs) do
sub.flags = nil
end
end
end
return mw.text.jsonEncode(skillsArr)
end
end
-- Gera JSON de forms a partir do módulo
function p.forms(frame)
local parent = frame:getParent() or frame
local args = parent.args or {}
local moduleName = trim(args.module or "")
if moduleName == "" then
return "{}"
end
local data = requireCharModule(moduleName) or {}
if not data.forms or type(data.forms) ~= "table" then
return "{}"
end
local formsData = {}
for formName, formData in pairs(data.forms) do
if type(formData) == "table" and type(formData.skills) == "table" and type(formData.order) == "table" then
local formSkills = {}
for _, skillName in ipairs(formData.order) do
local sk = formData.skills[skillName]
if type(sk) == "table" then
-- Valida flags: deve ser uma tabela com pelo menos um elemento, senão nil
local formSkillFlags = nil
if type(sk.flags) == "table" and #sk.flags > 0 then
formSkillFlags = sk.flags
end
local skillObj = {
name = skillName,
n = skillName,
icon = (sk.icon and sk.icon ~= "") and sk.icon or "Nada.png",
level = sk.level or "NIVEL",
energy = sk.energy,
powerpve = sk.powerpve,
powerpvp = sk.powerpvp,
cooldown = sk.cooldown,
video = sk.video or "",
desc_i18n = processDesc(sk.desc),
flags = formSkillFlags,
weapon = processWeapon(sk.weapon)
}
-- Processa subskills se houver
-- Passa data.skills para herança automática quando subskill tem mesmo nome que skill principal
if type(sk.subskills) == "table" and type(sk.suborder) == "table" then
skillObj.subs = processSubskills(sk.subskills, sk.suborder, data.skills)
skillObj.suborder = sk.suborder
end
table.insert(formSkills, skillObj)
end
end
formsData[formName] = {
order = formData.order,
skills = formSkills
}
end
end
return mw.text.jsonEncode(formsData)
end
-- Gera JSON de skins a partir do módulo
function p.skin(frame)
local parent = frame:getParent() or frame
local args = parent.args or {}
local moduleName = trim(args.module or "")
if moduleName == "" then
return "[]"
end
local data = requireCharModule(moduleName) or {}
if not data.skins or type(data.skins) ~= "table" then
return "[]"
end
-- Processa skins do módulo
local skinsArr = {}
for _, skin in ipairs(data.skins) do
if type(skin) == "table" then
local skinObj = {
name = skin.name or "",
sprite = skin.sprite or "",
tooltip = skin.tooltip or "",
offset_x = skin.offset_x,
tile = skin.tile or "",
tile_x = skin.tile_x,
tile_y = skin.tile_y,
youtube = skin.youtube
}
-- Se tooltip é table, converte para JSON string
if type(skin.tooltip) == "table" then
skinObj.tooltip = mw.text.jsonEncode(skin.tooltip)
end
table.insert(skinsArr, skinObj)
end
end
return mw.text.jsonEncode(skinsArr)
end
return p