Mudanças entre as edições de "Módulo:Item"
Ir para navegação
Ir para pesquisar
m |
m |
||
| (2 revisões intermediárias pelo mesmo usuário não estão sendo mostradas) | |||
| Linha 2: | Linha 2: | ||
local ItemDB = require("Módulo:ItemDB") | local ItemDB = require("Módulo:ItemDB") | ||
local DEFAULT_LANG = " | local DEFAULT_LANG = "pt-br" | ||
local FALLBACK_LANG = " | local FALLBACK_LANG = "en" | ||
local DEFAULT_FRAME_SIZE = 32 | local DEFAULT_FRAME_SIZE = 32 | ||
| Linha 28: | Linha 28: | ||
den_den_mushi = { en = "Den Den Mushi", pt = "Den Den Mushi" }, | den_den_mushi = { en = "Den Den Mushi", pt = "Den Den Mushi" }, | ||
} | } | ||
local function normalizeLang(lang) | |||
local lg = mw.ustring.lower(mw.text.trim(tostring(lang or DEFAULT_LANG))) | |||
lg = lg:gsub("_", "-") | |||
if lg == "" then return "pt" end | |||
if lg == "pt" or lg == "pt-br" then return "pt" end | |||
if lg == "en" or lg == "en-us" or lg == "en-gb" then return "en" end | |||
return lg | |||
end | |||
local function formatDots(n) | local function formatDots(n) | ||
| Linha 38: | Linha 47: | ||
end | end | ||
return table.concat(parts, ".") | return table.concat(parts, ".") | ||
end | |||
local function normalizeForMatch(s) | |||
if not s then return "" end | |||
return mw.ustring.lower(mw.text.trim(tostring(s))) | |||
end | |||
local function isBerriesItem(item) | |||
if not item then return false end | |||
local image = normalizeForMatch(item.image) | |||
if image ~= "" and image:find("berr", 1, true) then | |||
return true | |||
end | |||
local namePt = item.names and normalizeForMatch(item.names.pt) or "" | |||
local nameEn = item.names and normalizeForMatch(item.names.en) or "" | |||
if namePt:find("berr", 1, true) or nameEn:find("berr", 1, true) then | |||
return true | |||
end | |||
if item.aliases and type(item.aliases) == "table" then | |||
for _, alias in ipairs(item.aliases) do | |||
local norm = normalizeForMatch(alias) | |||
if norm:find("berr", 1, true) then | |||
return true | |||
end | |||
end | |||
end | |||
return item.category == "currency" | |||
end | end | ||
| Linha 47: | Linha 87: | ||
function Item.getName(item, lang) | function Item.getName(item, lang) | ||
if not item or not item.names then return "" end | if not item or not item.names then return "" end | ||
lang = lang | lang = normalizeLang(lang) | ||
return item.names[lang] | return item.names[lang] | ||
or item.names[FALLBACK_LANG] | or item.names[FALLBACK_LANG] | ||
or item.names.pt | |||
or item.image or "" | or item.image or "" | ||
end | end | ||
| Linha 56: | Linha 96: | ||
function Item.getDesc(item, lang) | function Item.getDesc(item, lang) | ||
if not item or not item.desc then return nil end | if not item or not item.desc then return nil end | ||
lang = lang | lang = normalizeLang(lang) | ||
return item.desc[lang] | return item.desc[lang] | ||
or item.desc[FALLBACK_LANG] | or item.desc[FALLBACK_LANG] | ||
or item.desc.pt | |||
end | end | ||
| Linha 89: | Linha 129: | ||
local entry = CATEGORY_LABELS[item.category] | local entry = CATEGORY_LABELS[item.category] | ||
if not entry then return nil end | if not entry then return nil end | ||
lang = lang | lang = normalizeLang(lang) | ||
return entry[lang] or entry[ | return entry[lang] or entry[FALLBACK_LANG] or entry.pt or nil | ||
end | end | ||
| Linha 96: | Linha 136: | ||
if not item or not item[key] or type(item[key]) ~= "table" then return nil end | if not item or not item[key] or type(item[key]) ~= "table" then return nil end | ||
local p = item[key] | local p = item[key] | ||
lang = lang | lang = normalizeLang(lang) | ||
local function pick(lg) | local function pick(lg) | ||
local t = p[lg] | local t = p[lg] | ||
| Linha 103: | Linha 143: | ||
end | end | ||
return pick(lang) or pick(DEFAULT_LANG) or pick(FALLBACK_LANG) | return pick(lang) or pick(DEFAULT_LANG) or pick(FALLBACK_LANG) | ||
end | |||
--[[ | |||
Passivas no tooltip: definidas aqui (Módulo:Item), não no Widget:Item. | |||
Widget:Item só carrega CSS/JS do hover. Atualizar a lógica = editar ESTE módulo na wiki. | |||
ItemDB precisa de passive1 (e opcionalmente passive2) com pt/en. | |||
equipment_special = true é o fluxo oficial do editor; se a flag faltar mas houver | |||
texto em passive1/2, ainda exibimos (ItemDB antigo / cópia incompleta). | |||
]] | |||
local function shouldShowPassiveBlock(item, passive1, passive2) | |||
if not (passive1 or passive2) then | |||
return false | |||
end | |||
local f = item and item.equipment_special | |||
if f == false then | |||
return false | |||
end | |||
if f == true or f == 1 then | |||
return true | |||
end | |||
if type(f) == "string" then | |||
local s = mw.ustring.lower(mw.text.trim(f)) | |||
if s == "true" or s == "1" then | |||
return true | |||
end | |||
end | |||
-- flag ausente (nil): ainda há texto de passiva → mostrar | |||
return f == nil | |||
end | end | ||
function Item.renderOne(item, qty, lang, options) | function Item.renderOne(item, qty, lang, options) | ||
options = options or {} | options = options or {} | ||
lang = lang | lang = normalizeLang(lang) | ||
if not item then return "" end | if not item then return "" end | ||
| Linha 123: | Linha 192: | ||
:css("width", w .. "px") | :css("width", w .. "px") | ||
:css("height", h .. "px") | :css("height", h .. "px") | ||
if image and mw.text.trim(image) ~= "" then | if image and mw.text.trim(image) ~= "" then | ||
| Linha 140: | Linha 205: | ||
if qty and options.showCount ~= false then | if qty and options.showCount ~= false then | ||
local countSpan = wrapper:tag("span"):addClass("item-count") | local countSpan = wrapper:tag("span"):addClass("item-count") | ||
local isBerries = item | local isBerries = isBerriesItem(item) | ||
if not isBerries then | if not isBerries then | ||
countSpan:tag("span"):addClass("item-count-x"):wikitext("x") | countSpan:tag("span"):addClass("item-count-x"):wikitext("x") | ||
| Linha 162: | Linha 226: | ||
local passive1 = getPassiveLine(item, "passive1", lang) | local passive1 = getPassiveLine(item, "passive1", lang) | ||
local passive2 = getPassiveLine(item, "passive2", lang) | local passive2 = getPassiveLine(item, "passive2", lang) | ||
local showPassives = item | local showPassives = shouldShowPassiveBlock(item, passive1, passive2) | ||
local hasDetails = level or showPassives or (desc and not showPassives) or value | local hasDetails = level or showPassives or (desc and not showPassives) or value | ||
if hasDetails then | if hasDetails then | ||
| Linha 178: | Linha 242: | ||
if passive1 then | if passive1 then | ||
local row = passWrap:tag("div"):addClass("item-tooltip-passive-row") | local row = passWrap:tag("div"):addClass("item-tooltip-passive-row") | ||
row:tag("span"):addClass("item-tooltip-passive-badge"):wikitext(" | row:tag("span"):addClass("item-tooltip-passive-badge"):wikitext("2") | ||
row:tag("span"):addClass("item-tooltip-passive-text"):wikitext(passive1) | row:tag("span"):addClass("item-tooltip-passive-text"):wikitext(passive1) | ||
end | end | ||
if passive2 then | if passive2 then | ||
local row = passWrap:tag("div"):addClass("item-tooltip-passive-row") | local row = passWrap:tag("div"):addClass("item-tooltip-passive-row") | ||
row:tag("span"):addClass("item-tooltip-passive-badge"):wikitext(" | row:tag("span"):addClass("item-tooltip-passive-badge"):wikitext("5") | ||
row:tag("span"):addClass("item-tooltip-passive-text"):wikitext(passive2) | row:tag("span"):addClass("item-tooltip-passive-text"):wikitext(passive2) | ||
end | end | ||
| Linha 192: | Linha 256: | ||
if value then | if value then | ||
local footer = body:tag("div"):addClass("item-tooltip-footer") | local footer = body:tag("div"):addClass("item-tooltip-footer") | ||
footer:tag("span"):addClass("item-tooltip-val") | footer:tag("span"):addClass("item-tooltip-val") | ||
:wikitext( | :wikitext("$" .. formatDots(value)) | ||
end | end | ||
| Linha 205: | Linha 268: | ||
function Item.renderLine(itemList, lang, options) | function Item.renderLine(itemList, lang, options) | ||
options = options or {} | options = options or {} | ||
lang = lang | lang = normalizeLang(lang) | ||
if not itemList or #itemList == 0 then return "" end | if not itemList or #itemList == 0 then return "" end | ||
Edição atual tal como às 14h32min de 19 de maio de 2026
A documentação para este módulo pode ser criada em Módulo:Item/doc
local Item = {}
local ItemDB = require("Módulo:ItemDB")
local DEFAULT_LANG = "pt-br"
local FALLBACK_LANG = "en"
local DEFAULT_FRAME_SIZE = 32
-- Categorias alinhadas ao jogo (ItemDB / editor). Sem duplicata coin/currency nem gem_currency.
local CATEGORY_LABELS = {
general_item = { en = "General Item", pt = "Item geral" },
special_item = { en = "Special Item", pt = "Item especial" },
currency = { en = "Currency", pt = "Moeda" },
cosmetic = { en = "Cosmetic", pt = "Cosmético" },
weapon = { en = "Weapon", pt = "Arma" },
head = { en = "Head", pt = "Cabeça" },
body = { en = "Body", pt = "Corpo" },
legs = { en = "Legs", pt = "Perna" },
accessory = { en = "Accessory", pt = "Acessório" },
emblem = { en = "Emblem", pt = "Emblema" },
ship_style = { en = "Ship Style", pt = "Estilo de navio" },
costume = { en = "Costume", pt = "Traje" },
navigation = { en = "Navigation", pt = "Navegação" },
consumable = { en = "Consumable", pt = "Consumível" },
gem = { en = "Gem", pt = "Gema" },
crystal = { en = "Crystal", pt = "Cristal" },
awakening_stone = { en = "Awakening Stone", pt = "Pedra do Despertar" },
headstone = { en = "Headstone", pt = "Lápide" },
den_den_mushi = { en = "Den Den Mushi", pt = "Den Den Mushi" },
}
local function normalizeLang(lang)
local lg = mw.ustring.lower(mw.text.trim(tostring(lang or DEFAULT_LANG)))
lg = lg:gsub("_", "-")
if lg == "" then return "pt" end
if lg == "pt" or lg == "pt-br" then return "pt" end
if lg == "en" or lg == "en-us" or lg == "en-gb" then return "en" end
return lg
end
local function formatDots(n)
local s = tostring(n)
local pos = #s % 3
if pos == 0 then pos = 3 end
local parts = { s:sub(1, pos) }
for i = pos + 1, #s, 3 do
parts[#parts + 1] = s:sub(i, i + 2)
end
return table.concat(parts, ".")
end
local function normalizeForMatch(s)
if not s then return "" end
return mw.ustring.lower(mw.text.trim(tostring(s)))
end
local function isBerriesItem(item)
if not item then return false end
local image = normalizeForMatch(item.image)
if image ~= "" and image:find("berr", 1, true) then
return true
end
local namePt = item.names and normalizeForMatch(item.names.pt) or ""
local nameEn = item.names and normalizeForMatch(item.names.en) or ""
if namePt:find("berr", 1, true) or nameEn:find("berr", 1, true) then
return true
end
if item.aliases and type(item.aliases) == "table" then
for _, alias in ipairs(item.aliases) do
local norm = normalizeForMatch(alias)
if norm:find("berr", 1, true) then
return true
end
end
end
return item.category == "currency"
end
function Item.resolve(query)
if not query or query == "" then return nil end
return ItemDB.get(query)
end
function Item.getName(item, lang)
if not item or not item.names then return "" end
lang = normalizeLang(lang)
return item.names[lang]
or item.names[FALLBACK_LANG]
or item.names.pt
or item.image or ""
end
function Item.getDesc(item, lang)
if not item or not item.desc then return nil end
lang = normalizeLang(lang)
return item.desc[lang]
or item.desc[FALLBACK_LANG]
or item.desc.pt
end
function Item.getValue(item)
if not item then return nil end
return item.value
end
function Item.getLevel(item)
if not item then return nil end
return item.level
end
function Item.getImage(item)
if not item then return nil end
return item.image
end
function Item.getSpriteSize(item)
if item and item.sprite then
return item.sprite.frameWidth or DEFAULT_FRAME_SIZE,
item.sprite.frameHeight or DEFAULT_FRAME_SIZE
end
return DEFAULT_FRAME_SIZE, DEFAULT_FRAME_SIZE
end
function Item.getCategoryLabel(item, lang)
if not item or not item.category then return nil end
local entry = CATEGORY_LABELS[item.category]
if not entry then return nil end
lang = normalizeLang(lang)
return entry[lang] or entry[FALLBACK_LANG] or entry.pt or nil
end
local function getPassiveLine(item, key, lang)
if not item or not item[key] or type(item[key]) ~= "table" then return nil end
local p = item[key]
lang = normalizeLang(lang)
local function pick(lg)
local t = p[lg]
if t and mw.text.trim(tostring(t)) ~= "" then return mw.text.trim(tostring(t)) end
return nil
end
return pick(lang) or pick(DEFAULT_LANG) or pick(FALLBACK_LANG)
end
--[[
Passivas no tooltip: definidas aqui (Módulo:Item), não no Widget:Item.
Widget:Item só carrega CSS/JS do hover. Atualizar a lógica = editar ESTE módulo na wiki.
ItemDB precisa de passive1 (e opcionalmente passive2) com pt/en.
equipment_special = true é o fluxo oficial do editor; se a flag faltar mas houver
texto em passive1/2, ainda exibimos (ItemDB antigo / cópia incompleta).
]]
local function shouldShowPassiveBlock(item, passive1, passive2)
if not (passive1 or passive2) then
return false
end
local f = item and item.equipment_special
if f == false then
return false
end
if f == true or f == 1 then
return true
end
if type(f) == "string" then
local s = mw.ustring.lower(mw.text.trim(f))
if s == "true" or s == "1" then
return true
end
end
-- flag ausente (nil): ainda há texto de passiva → mostrar
return f == nil
end
function Item.renderOne(item, qty, lang, options)
options = options or {}
lang = normalizeLang(lang)
if not item then return "" end
local nome = Item.getName(item, lang)
local desc = Item.getDesc(item, lang)
local image = Item.getImage(item)
local catLabel = Item.getCategoryLabel(item, lang)
local value = Item.getValue(item)
local level = Item.getLevel(item)
local w, h = Item.getSpriteSize(item)
local wrapper = mw.html.create("div")
:addClass("item-wrapper")
:css("width", w .. "px")
:css("height", h .. "px")
if image and mw.text.trim(image) ~= "" then
wrapper:tag("span")
:wikitext(string.format("[[Arquivo:%s|%dx%dpx|link=]]", image, w, h))
else
wrapper:tag("span")
:addClass("item-icon-placeholder")
:attr("title", nome)
:wikitext("")
end
if qty and options.showCount ~= false then
local countSpan = wrapper:tag("span"):addClass("item-count")
local isBerries = isBerriesItem(item)
if not isBerries then
countSpan:tag("span"):addClass("item-count-x"):wikitext("x")
end
countSpan:wikitext(tostring(qty))
end
if options.showTooltip ~= false then
-- div (não span): descrições em wikitext podem virar <p>/blocos; span+bloco
-- quebra o DOM e os próximos .item-wrapper acabam dentro do tooltip.
local tip = wrapper:tag("div"):addClass("item-tooltip")
local body = tip:tag("div"):addClass("item-tooltip-body")
body:tag("div"):addClass("item-tooltip-name"):wikitext(nome)
if catLabel then
body:tag("div"):addClass("item-tooltip-cat"):wikitext(catLabel)
end
local passive1 = getPassiveLine(item, "passive1", lang)
local passive2 = getPassiveLine(item, "passive2", lang)
local showPassives = shouldShowPassiveBlock(item, passive1, passive2)
local hasDetails = level or showPassives or (desc and not showPassives) or value
if hasDetails then
body:tag("div"):addClass("item-tooltip-sep")
end
if level then
local lvlFull = (lang == "pt") and ("Nível: " .. tostring(level))
or ("Level: " .. tostring(level))
body:tag("div"):addClass("item-tooltip-level"):wikitext(lvlFull)
end
if showPassives then
local passWrap = body:tag("div"):addClass("item-tooltip-passives")
if passive1 then
local row = passWrap:tag("div"):addClass("item-tooltip-passive-row")
row:tag("span"):addClass("item-tooltip-passive-badge"):wikitext("2")
row:tag("span"):addClass("item-tooltip-passive-text"):wikitext(passive1)
end
if passive2 then
local row = passWrap:tag("div"):addClass("item-tooltip-passive-row")
row:tag("span"):addClass("item-tooltip-passive-badge"):wikitext("5")
row:tag("span"):addClass("item-tooltip-passive-text"):wikitext(passive2)
end
elseif desc then
body:tag("div"):addClass("item-tooltip-desc"):wikitext(desc)
end
if value then
local footer = body:tag("div"):addClass("item-tooltip-footer")
footer:tag("span"):addClass("item-tooltip-val")
:wikitext("$" .. formatDots(value))
end
tip:tag("div"):addClass("item-tooltip-arrow")
end
return tostring(wrapper)
end
function Item.renderLine(itemList, lang, options)
options = options or {}
lang = normalizeLang(lang)
if not itemList or #itemList == 0 then return "" end
local container = mw.html.create("div")
:addClass("reward-items")
for _, entry in ipairs(itemList) do
container:wikitext(Item.renderOne(entry.item, entry.qty, lang, options))
end
return tostring(container)
end
return Item