Mudanças entre as edições de "Módulo:Item"

De Wiki Gla
Ir para navegação Ir para pesquisar
m
m
 
(4 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
Linha 6: Linha 6:
local DEFAULT_FRAME_SIZE = 32
local DEFAULT_FRAME_SIZE = 32


-- Categorias alinhadas ao jogo (ItemDB / editor). Sem duplicata coin/currency nem gem_currency.
local CATEGORY_LABELS = {
local CATEGORY_LABELS = {
     general_item    = { en = "General Item", pt = "Item Geral" },
     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" },
     head            = { en = "Head", pt = "Cabeça" },
     body            = { en = "Body", pt = "Corpo" },
     body            = { en = "Body", pt = "Corpo" },
     legs            = { en = "Legs", pt = "Perna" },
     legs            = { en = "Legs", pt = "Perna" },
    weapon          = { en = "Weapon", pt = "Arma" },
     accessory      = { en = "Accessory", pt = "Acessório" },
     accessory      = { en = "Accessory", pt = "Acessório" },
     emblem          = { en = "Emblem", pt = "Emblema" },
     emblem          = { en = "Emblem", pt = "Emblema" },
     ship_style      = { en = "Ship Style", pt = "Estilo de Navio" },
     ship_style      = { en = "Ship Style", pt = "Estilo de navio" },
     costume        = { en = "Costume", pt = "Traje" },
     costume        = { en = "Costume", pt = "Traje" },
     navigation      = { en = "Navigation", pt = "Navegação" },
     navigation      = { en = "Navigation", pt = "Navegação" },
     consumable      = { en = "Consumable", pt = "Consumível" },
     consumable      = { en = "Consumable", pt = "Consumível" },
    profile_icon    = { en = "Profile Icon", pt = "Ícone de Perfil" },
     gem            = { en = "Gem", pt = "Gema" },
     gem            = { en = "Gem", pt = "Gema" },
    den_den_mushi  = { en = "Den Den Mushi", pt = "Den Den Mushi" },
     crystal        = { en = "Crystal", pt = "Cristal" },
     crystal        = { en = "Crystal", pt = "Cristal" },
     awakening_stone = { en = "Awakening Stone", pt = "Pedra do Despertar" },
     awakening_stone = { en = "Awakening Stone", pt = "Pedra do Despertar" },
     headstone      = { en = "Headstone", pt = "Lápide" },
     headstone      = { en = "Headstone", pt = "Lápide" },
     coin            = { en = "Coin", pt = "Moeda" },
     den_den_mushi  = { en = "Den Den Mushi", pt = "Den Den Mushi" },
}
}


Linha 89: Linha 91:
     lang = lang or DEFAULT_LANG
     lang = lang or DEFAULT_LANG
     return entry[lang] or entry[DEFAULT_LANG] or entry[FALLBACK_LANG] or nil
     return entry[lang] or entry[DEFAULT_LANG] or entry[FALLBACK_LANG] 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 = lang or DEFAULT_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
end


Linha 102: Linha 145:
     local value    = Item.getValue(item)
     local value    = Item.getValue(item)
     local level    = Item.getLevel(item)
     local level    = Item.getLevel(item)
    if not image then return "" end


     local w, h = Item.getSpriteSize(item)
     local w, h     = Item.getSpriteSize(item)


     local wrapper = mw.html.create("span")
     local wrapper = mw.html.create("div")
         :addClass("item-wrapper")
         :addClass("item-wrapper")
         :css("width", w .. "px")
         :css("width", w .. "px")
         :css("height", h .. "px")
         :css("height", h .. "px")


     wrapper:tag("span")
     if item.category == "special_item" then
        :wikitext(string.format("[[Arquivo:%s|%dx%dpx|link=]]", image, w, h))
        wrapper:addClass("item-wrapper-special")
    end
 
    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
     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.category == "coin" and image:lower():find("berries")
         local isBerries = item.category == "currency" and image
            and image:lower():find("berries")
         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 124: Linha 178:


     if options.showTooltip ~= false then
     if options.showTooltip ~= false then
         local tip  = wrapper:tag("span"):addClass("item-tooltip")
        -- div (não span): descrições em wikitext podem virar <p>/blocos; span+bloco
         local body = tip:tag("span"):addClass("item-tooltip-body")
        -- 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("span"):addClass("item-tooltip-name"):wikitext(nome)
         body:tag("div"):addClass("item-tooltip-name"):wikitext(nome)


         if catLabel then
         if catLabel then
             body:tag("span"):addClass("item-tooltip-cat"):wikitext(catLabel)
             body:tag("div"):addClass("item-tooltip-cat"):wikitext(catLabel)
         end
         end


         local hasExtra = desc or value or level
         local passive1 = getPassiveLine(item, "passive1", lang)
         if hasExtra then
        local passive2 = getPassiveLine(item, "passive2", lang)
             body:tag("span"):addClass("item-tooltip-sep")
        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
         end


         if desc then
         if level then
             body:tag("span"):addClass("item-tooltip-desc"):wikitext(desc)
            local lvlFull = (lang == "pt") and ("Nível: " .. tostring(level))
                or ("Level: " .. tostring(level))
             body:tag("div"):addClass("item-tooltip-level"):wikitext(lvlFull)
         end
         end


         if value or level then
         if showPassives then
             local footer = body:tag("span"):addClass("item-tooltip-footer")
             local passWrap = body:tag("div"):addClass("item-tooltip-passives")
             if value then
             if passive1 then
                 local valLabel = (lang == "pt") and "Valor: " or "Value: "
                 local row = passWrap:tag("div"):addClass("item-tooltip-passive-row")
                 footer:tag("span"):addClass("item-tooltip-val")
                row:tag("span"):addClass("item-tooltip-passive-badge"):wikitext("1")
                    :wikitext(valLabel .. formatDots(value))
                 row:tag("span"):addClass("item-tooltip-passive-text"):wikitext(passive1)
             end
             end
             if level then
             if passive2 then
                 local lvlLabel = (lang == "pt") and "Nv. " or "Lv. "
                 local row = passWrap:tag("div"):addClass("item-tooltip-passive-row")
                 footer:tag("span"):addClass("item-tooltip-lvl")
                row:tag("span"):addClass("item-tooltip-passive-badge"):wikitext("2")
                    :wikitext(lvlLabel .. tostring(level))
                 row:tag("span"):addClass("item-tooltip-passive-text"):wikitext(passive2)
             end
             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
         end


         tip:tag("span"):addClass("item-tooltip-arrow")
         tip:tag("div"):addClass("item-tooltip-arrow")
     end
     end



Edição atual tal como às 23h07min de 8 de abril 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 = "en"
local FALLBACK_LANG = "pt"
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 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

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 = lang or DEFAULT_LANG
    return item.names[lang]
        or item.names[DEFAULT_LANG]
        or item.names[FALLBACK_LANG]
        or item.image or ""
end

function Item.getDesc(item, lang)
    if not item or not item.desc then return nil end
    lang = lang or DEFAULT_LANG
    return item.desc[lang]
        or item.desc[DEFAULT_LANG]
        or item.desc[FALLBACK_LANG]
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 = lang or DEFAULT_LANG
    return entry[lang] or entry[DEFAULT_LANG] or entry[FALLBACK_LANG] 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 = lang or DEFAULT_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 = lang or DEFAULT_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 item.category == "special_item" then
        wrapper:addClass("item-wrapper-special")
    end

    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 = item.category == "currency" and image
            and image:lower():find("berries")
        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("1")
                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("2")
                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 = lang or DEFAULT_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