Module:ItemBox

From The Deadlock Wiki
Revision as of 18:15, 1 August 2026 by Vergir (talk | contribs) (Use Module:TextFit instead of own implementation)
Jump to navigation Jump to search

Documentation for this module may be created at Module:ItemBox/doc

local p = {}
local ustring = mw.ustring
local textfit = require "Module:TextFit"

-- ============================================================================
--  Name box geometry, in em of .itembox's font-size (1em = 10px at size=1).
--  Mirrors Template:ItemBox/styles.css:
--    .itembox            width: 8em
--    .itembox-name-area  height: 4.5em; padding: 0.5em 0.4em (border-box)
--    .itembox-name       line-height: 1.2; font-size: 1.5em (overridden inline)
--  so the name's content box is 8 - 2*0.4 = 7.2em wide and 4.5 - 2*0.5 = 3.5em
--  tall. Keep these in step with that stylesheet.
--  Glyph widths live in [[Module:TextFit]].
-- ============================================================================
local NAME_W  = 7.2
local NAME_H  = 3.5
local LINE_H  = 1.2
local MAX_EM  = 1.5
local MIN_EM  = 0.8
local SNAP_EM = 0.05   -- keep emitted sizes on a tidy grid

-- Returns the name font size as an em string (scales with the card).
function p.getFontSize(frame)
    local name = ustring.gsub(frame.args[1] or "", "^%s*(.-)%s*$", "%1")
    if name == "" then return string.format("%.2f", MAX_EM) end

    local pct = textfit.fit(name, {
        aspect     = NAME_H / NAME_W,
        lineHeight = LINE_H,
        max        = MAX_EM / NAME_W * 100,
        min        = MIN_EM / NAME_W * 100,
        bold       = true,   -- .itembox-name is font-weight: bold
    })

    -- fit() returns a percentage of the usable width. Convert back to em and
    -- coarsen downward, so a snapped value still fits. The epsilon guards
    -- against binary representation: 1.45 / 0.05 is 28.999999999999996, which
    -- would otherwise floor a whole grid step too low.
    local em = math.floor(pct / 100 * NAME_W / SNAP_EM + 1e-9) * SNAP_EM
    return string.format("%.2f", math.max(em, MIN_EM))
end

-- User for stable per-item texture variety
local function hash(s)
    local h = 5381
    for i = 1, #s do
        h = (h * 33 + s:byte(i)) % 2147483647
    end
    return h
end

function p.variants(frame)
    local h = hash(frame.args[1] or "")
    local icon = (h % 3) + 1
    local wear = (math.floor(h / 3) % 4) + 1
    local tex  = (math.floor(h / 12) % 3) + 1
    return string.format("itembox-icon-v%d itembox-wear-v%d itembox-texture-v%d",
        icon, wear, tex)
end

return p