Module:Sprite

From Tensura Wiki
Jump to navigation Jump to search

Template:Documentation header This module implements {{sprite}}. It should generally be invoked directly on template pages, rather than using the sprite template.

Parent arguments are automatically merged with directly passed arguments (the latter overwriting the former) and all arguments are normalised to trim whitespace and set empty arguments to nil.

Dependencies

See also

Minecraft
Minecraft (legacy)
Minecraft Dungeons
Minecraft Legends
Minecraft Story Mode
A Minecraft Movie
Other

local p = {}
local CurrentFrame = mw.getCurrentFrame()
local aliases = require('Module:Inventory slot/Aliases') -- Import the aliases table

function p.base(f)
    local args = f
    if f == CurrentFrame then
        args = require('Module:ProcessArgs').merge(true)
    else
        f = CurrentFrame
    end

    local data = args.data and mw.loadData('Module:' .. args.data) or {}
    local settings = data.settings

    -- Default settings
    local default = {
        scale = 1,
        sheetsize = 256,
        size = 16,
        pos = 1,
        align = 'text-top'
    }

    local defaultStyle = mw.clone(default)
    if settings then
        for k, v in pairs(settings) do
            default[k] = v
        end
    end

    local function setting(arg)
        return args[arg] or default[arg]
    end

    local sprite = mw.html.create('span'):addClass('sprite')
    local styles = {}

    if not setting('nourl') and setting('url') then
        styles[#styles + 1] = 'background-image:' .. (setting('url').url or setting('url'))
    end
    if setting('stylesheet') then
        sprite:addClass(setting('classname') or mw.ustring.lower(setting('name'):gsub(' ', '-')) .. '-sprite')
    elseif not setting('url') then
        styles[#styles + 1] = 'background-image:' .. p.getUrl(setting('image') or setting('name') .. 'Sprite.png').url
    end

    local class = setting('class')
    if class then
        sprite:addClass(class)
    end

    local width = setting('width') or setting('size')
    local height = setting('height') or setting('size')
    local sheetWidth = setting('sheetsize')
    local tiles = sheetWidth / width
    local pos = setting('pos') - 1
    local scale = setting('scale')
    local autoScale = setting('autoscale')

    if pos then
        local left = pos % tiles * width * scale
        local top = math.floor(pos / tiles) * height * scale
        styles[#styles + 1] = 'background-position:-' .. left .. 'px -' .. top .. 'px'
    end

    if not autoScale and scale ~= defaultStyle.scale then
        styles[#styles + 1] = 'background-size:' .. sheetWidth * scale .. 'px auto'
    end
    if height ~= defaultStyle.size or width ~= defaultStyle.size or (not autoScale and scale ~= defaultStyle.scale) then
        styles[#styles + 1] = 'height:' .. height * scale .. 'px'
        styles[#styles + 1] = 'width:' .. width * scale .. 'px'
    end

    local align = setting('align')
    if align ~= defaultStyle.align then
        styles[#styles + 1] = 'vertical-align:' .. align
    end
    styles[#styles + 1] = setting('css')

    sprite:cssText(table.concat(styles, ';'))

    local text = setting('text')
    local root
    local spriteText
    if text then
        if not args['wrap'] then
            root = mw.html.create('span'):addClass('nowrap')
        end
        spriteText = mw.html.create('span'):addClass('sprite-text'):wikitext(text)
    end

    local title = setting('title')
    if title then
        (root or sprite):attr('title', title)
    end

    if not root then
        root = mw.html.create('')
    end
    root:node(sprite)
    if spriteText then
        root:node(spriteText)
    end

    local link = setting('link') or ''
    if link ~= '' and mw.ustring.lower(link) ~= 'none' then
        if link:find('//') then
            return '[' .. link .. ' ' .. tostring(root) .. ']'
        end

        local linkPrefix = setting('linkprefix') or ''
        return '[[' .. linkPrefix .. link .. '|' .. tostring(root) .. ']]'
    end

    return tostring(root)
end

function p.sprite(f)
    local args = f
    if f == CurrentFrame then
        args = require('Module:ProcessArgs').merge(true)
    else
        f = CurrentFrame
    end

    local data = args.data and mw.loadData('Module:' .. args.data) or {}
    local id = mw.text.trim(tostring(args[1] or ''))

    -- Check for aliases
    local alias = aliases[args[1] or '']
    if alias then
        args.title = alias.title
        args.link = alias.link
        args.name = alias.name
        args.pos = nil -- Optional: reset position if not using sprite sheets
    else
        local idData = data.ids and (data.ids[id] or data.ids[mw.ustring.lower(id):gsub('[%s%+]', '-')])
        if idData then
            args.pos = idData.pos
        end
    end

    return p.base(args)
end

function p.link(f)
    local args = f
    if f == CurrentFrame then
        args = require('Module:ProcessArgs').merge(true)
    end

    -- Check for aliases
    local alias = aliases[args[1] or '']
    if alias then
        args.link = alias.link
        args.text = alias.title
        args.name = alias.name
    else
        local link = args[1]
        if args[1] and not args.id then
            link = args[1]:match('^(.-)%+') or args[1]
        end
        args.link = args.link or link
        args.text = args.text or args[2] or link
    end

    return p.sprite(args)
end

function p.getUrl(image, query, classname)
    local f = CurrentFrame
    local t = {
        url = f:expandTemplate{
            title = 'FileUrl',
            args = { image, query = query }
        },
    }
    if classname and classname ~= '' then
        t.style = f:expandTemplate{
            title = 'FileUrlStyle',
            args = { classname, image, query = query }
        }
    end
    return t
end

return p