Module:CraftingTable: Difference between revisions

From Pixelrus
Jump to navigation Jump to search
(Created page with "-- Module:CraftingTable – animated crafting-grid slots local p = {} local getArgs = require('Module:Arguments').getArgs ---------------------------------------------------------------------- -- helper : 32-px inventory-slot image ---------------------------------------------------------------------- local function slotImage(label, image, link) if not label or label == '' then return '' end local file = (image ~= '' and image) or ('Grid_' .. label .. '.png')...")
 
No edit summary
Line 1: Line 1:
-- Module:CraftingTable – animated crafting-grid slots
-- Module:CraftingTable – animated crafting-grid slots
local p       = {}
local p       = {}
local getArgs = require('Module:Arguments').getArgs
local getArgs = require('Module:Arguments').getArgs


----------------------------------------------------------------------
----------------------------------------------------------------------
-- helper : 32-px inventory-slot image
-- helper : render a 32-px inventory-slot image
----------------------------------------------------------------------
----------------------------------------------------------------------
local function slotImage(label, image, link)
local function slotImage(label, image, link)
if not label or label == '' then return '' end
if not label or label == '' then return '' end
local file = (image ~= '' and image) or ('Grid_' .. label .. '.png')
local file = (image ~= '' and image) or ('Grid_' .. label .. '.png')
local tgt   = (link  ~= '' and link ) or ('Special:MyLanguage/' .. label)
local tgt = (link  ~= '' and link ) or ('Special:MyLanguage/' .. label)
return string.format(
return string.format(
'[[File:%s|32px|class=pixelated|link=%s|alt=%s]]',
'[[File:%s|32px|class=pixelated|link=%s|alt=%s]]',
file, tgt, label
file, tgt, label
)
)
end
----------------------------------------------------------------------
-- collect *all* numbered args for a slot  (A1, A1-2, A1-3, …)
----------------------------------------------------------------------
local function collectItems(args, base)
local items = {}
for key, val in pairs(args) do
if mw.ustring.match(key, '^' .. base .. '$') or
  mw.ustring.match(key, '^' .. base .. '%-%d+$') then
local label = val
if label and label ~= '' then
local image = args[key .. '-image'] or ''
local link  = args[key .. '-link']  or ''
table.insert(items, {label = label, image = image, link = link})
end
end
end
table.sort(items, function(a, b) return a.label < b.label end) -- deterministic order
return items
end
end


Line 22: Line 42:
local args = getArgs(frame, {removeBlanks = false})
local args = getArgs(frame, {removeBlanks = false})


-- slot coordinates (input 3×3 + output)
-- slot coordinates (input 3×3 + output)
local slots = {
local slots = {
A1 = {left='14px',  top='14px'}, A2 = {left='14px',  top='50px'},
A1 = {left=14,  top=14}, A2 = {left=14,  top=50}, A3 = {left=14,  top=86},
A3 = {left='14px',  top='86px'}, B1 = {left='50px',  top='14px'},
B1 = {left=50,  top=14}, B2 = {left=50,  top=50}, B3 = {left=50,  top=86},
B2 = {left='50px',  top='50px'}, B3 = {left='50px',  top='86px'},
C1 = {left=86,  top=14}, C2 = {left=86,  top=50}, C3 = {left=86,  top=86},
C1 = {left='86px',  top='14px'}, C2 = {left='86px',  top='50px'},
Output = {left=202, top=50},
C3 = {left='86px',  top='86px'}, Output = {left='202px', top='50px'},
}
}


-- outer <div> collects everything
-- outer container (the template already provides a relative parent)
local root = mw.html.create()
local root = mw.html.create()


------------------------------------------------------------------
-- helper to collect *all* numbered parameters for one slot
------------------------------------------------------------------
local function collectItems(base)
local out = {}
local idx = 1
while true do
local lblKey = (idx == 1) and base or (base .. '-' .. idx)
local label  = args[lblKey]
if not label or label == '' then break end    -- finished
local imgKey = lblKey .. '-image'
local lnkKey = lblKey .. '-link'
table.insert(out, {
label = label,
image = args[imgKey] or '',
link  = args[lnkKey] or '',
})
idx = idx + 1
end
return out
end
-- build every slot that has at least one item
for slot, pos in pairs(slots) do
for slot, pos in pairs(slots) do
local items = collectItems(slot)
local items = collectItems(args, slot)
if #items > 0 then
if #items > 0 then
-- wrapper positioned at correct GUI coords
local holder = root:tag('div')
local holder = root:tag('div')
:css('position','absolute')
:css('position', 'absolute')
:css('left', pos.left):css('top', pos.top)
:css('left', pos.left .. 'px'):css('top', pos.top .. 'px')
:css('width','32px'):css('height','32px')
:css('width', '32px'):css('height', '32px')


if #items == 1 then
if #items == 1 then
-- static single image
holder:wikitext(slotImage(items[1].label, items[1].image, items[1].link))
holder:wikitext(slotImage(items[1].label, items[1].image, items[1].link))
else
else
-- multiple frames → animation
for i, it in ipairs(items) do
for i, itm in ipairs(items) do
holder:tag('div')
holder:tag('div')
:addClass('slot-frame')
:addClass('slot-frame')
:css('animation-duration', (#items * 4) .. 's')
:css('animation-duration', (#items * 4) .. 's')
:css('animation-delay', ((i - 1) * 4) .. 's')
:css('animation-delay', ((i - 1) * 4) .. 's')
:wikitext(slotImage(itm.label, itm.image, itm.link))
:wikitext(slotImage(it.label, it.image, it.link))
end
end
end
end
Line 85: Line 78:
if args.shapeless and args.shapeless ~= '' then
if args.shapeless and args.shapeless ~= '' then
root:tag('div')
root:tag('div')
:css('position','absolute')
:css{position='absolute', left='135px', top='96px',
:css('left','135px'):css('top','96px')
    width='19px', height='15px'}
:css('width','19px'):css('height','15px')
:wikitext('{{tt|[[File:Shapeless.png|link=]]|This recipe is shapeless; the ingredients may be placed in any arrangement in the crafting grid.}}')
:wikitext('{{tt|[[File:Shapeless.png|link=]]|This recipe is shapeless; the ingredients may be placed in any arrangement in the crafting grid.}}')
end
end
Line 94: Line 86:
if args.OA and args.OA ~= '' then
if args.OA and args.OA ~= '' then
root:tag('div')
root:tag('div')
:css('position','absolute')
:css{position='absolute', left='201px', top='71px',
:css('left','201px'):css('top','71px')
    width='64px', height='24px', overflow='hidden'}
:css('width','64px'):css('height','24px')
:css('overflow','hidden')
:wikitext(string.format('{{GridText|white|%s}}', args.OA))
:wikitext(string.format('{{GridText|white|%s}}', args.OA))
end
end

Revision as of 22:55, 15 June 2025

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

-- Module:CraftingTable – animated crafting-grid slots
local p       = {}
local getArgs = require('Module:Arguments').getArgs

----------------------------------------------------------------------
-- helper : render a 32-px inventory-slot image
----------------------------------------------------------------------
local function slotImage(label, image, link)
	if not label or label == '' then return '' end
	local file = (image ~= '' and image) or ('Grid_' .. label .. '.png')
	local tgt  = (link  ~= '' and link ) or ('Special:MyLanguage/' .. label)
	return string.format(
		'[[File:%s|32px|class=pixelated|link=%s|alt=%s]]',
		file, tgt, label
	)
end

----------------------------------------------------------------------
-- collect *all* numbered args for a slot  (A1, A1-2, A1-3, …)
----------------------------------------------------------------------
local function collectItems(args, base)
	local items = {}
	for key, val in pairs(args) do
		if mw.ustring.match(key, '^' .. base .. '$') or
		   mw.ustring.match(key, '^' .. base .. '%-%d+$') then
			local label = val
			if label and label ~= '' then
				local image = args[key .. '-image'] or ''
				local link  = args[key .. '-link']  or ''
				table.insert(items, {label = label, image = image, link = link})
			end
		end
	end
	table.sort(items, function(a, b) return a.label < b.label end) -- deterministic order
	return items
end

----------------------------------------------------------------------
-- public entry – {{#invoke:CraftingTable|grid|…}}
----------------------------------------------------------------------
function p.grid(frame)
	local args = getArgs(frame, {removeBlanks = false})

	-- slot coordinates (input 3×3 + output)
	local slots = {
		A1 = {left=14,  top=14},  A2 = {left=14,  top=50},  A3 = {left=14,  top=86},
		B1 = {left=50,  top=14},  B2 = {left=50,  top=50},  B3 = {left=50,  top=86},
		C1 = {left=86,  top=14},  C2 = {left=86,  top=50},  C3 = {left=86,  top=86},
		Output = {left=202, top=50},
	}

	-- outer container (the template already provides a relative parent)
	local root = mw.html.create()

	for slot, pos in pairs(slots) do
		local items = collectItems(args, slot)
		if #items > 0 then
			local holder = root:tag('div')
				:css('position', 'absolute')
				:css('left', pos.left .. 'px'):css('top', pos.top .. 'px')
				:css('width', '32px'):css('height', '32px')

			if #items == 1 then
				holder:wikitext(slotImage(items[1].label, items[1].image, items[1].link))
			else
				for i, it in ipairs(items) do
					holder:tag('div')
						:addClass('slot-frame')
						:css('animation-duration', (#items * 4) .. 's')
						:css('animation-delay', ((i - 1) * 4) .. 's')
						:wikitext(slotImage(it.label, it.image, it.link))
				end
			end
		end
	end

	-- shapeless icon
	if args.shapeless and args.shapeless ~= '' then
		root:tag('div')
			:css{position='absolute', left='135px', top='96px',
			     width='19px', height='15px'}
			:wikitext('{{tt|[[File:Shapeless.png|link=]]|This recipe is shapeless; the ingredients may be placed in any arrangement in the crafting grid.}}')
	end

	-- output-amount overlay
	if args.OA and args.OA ~= '' then
		root:tag('div')
			:css{position='absolute', left='201px', top='71px',
			     width='64px', height='24px', overflow='hidden'}
			:wikitext(string.format('{{GridText|white|%s}}', args.OA))
	end

	return tostring(root)
end

return p