Module:Stonecutting: Difference between revisions

From I-Pixelmon
Jump to navigation Jump to search
No edit summary
No edit summary
Line 1: Line 1:
------------------------------------------------------------
------------------------------------------------------------
--  Module:Stonecutting ·  Stone-cutter recipe carousel
--  Module:Stonecutting – animated stone-cutter carousel
--  • Only dependency: Module:Arguments (bundled with Scribunto)
--  • One static stylesheet (Stonecutting/styles.css) for all pages
------------------------------------------------------------
------------------------------------------------------------
local p      = {}
local p      = {}
local getArgs = require('Module:Arguments').getArgs
local getArgs = require('Module:Arguments').getArgs
local trim    = mw.text.trim
local trim    = mw.text.trim


------------------------------------------------------------------------
------------------------------------------------------------
-- slotImage(label, image, link) → wikitext thumbnail
-- helper: create 32 px inventory slot image link
------------------------------------------------------------------------
------------------------------------------------------------
local function slotImage(label, image, link)
local function slotImage(label, image, link)
if not label or label == '' then
if not label or label == '' then
Line 22: Line 23:
end
end


------------------------------------------------------------------------
------------------------------------------------------------
-- buildFrame(args, idx) → html for one output variant
-- helper: build one GUI frame
------------------------------------------------------------------------
------------------------------------------------------------
local function buildFrame(args, idx)
local function buildFrame(args, idx, totalDur)
local inL   = args.input                  or args[1] or ''
local inL = args.input                  or args[1] or ''
local inI   = args['input-image']        or ''
local inI = args['input-image']        or ''
local inLn = args['input-link']          or ''
local inLn = args['input-link']          or ''


local outL  = args['output' .. idx]            or args[idx + 1] or ''
local outL  = args['output' .. idx]            or args[idx+1] or ''
local outI  = args['output' .. idx .. '-image'] or ''
local outI  = args['output' .. idx .. '-image'] or ''
local outLn = args['output' .. idx .. '-link']  or ''
local outLn = args['output' .. idx .. '-link']  or ''


local html = mw.html.create('div'):addClass('sc-frame')
-- each frame gets its own animation-delay and the shared duration
html:wikitext('[[File:StonecutterGUI.png|180px|link=|alt=]]')
local frame = mw.html.create('div')
frame :addClass('sc-frame')
:css('animation-duration',  totalDur .. 's')
:css('animation-delay',    (idx-1)*4 .. 's')


html:tag('div'):addClass('sc-slot')
frame:wikitext('[[File:StonecutterGUI.png|180px|link=|alt=]]')
    :css{left = '11px',  top = '50px'}
    :wikitext(slotImage(inL, inI, inLn))


html:tag('div'):addClass('sc-slot')
frame:tag('div'):addClass('sc-slot')
    :css{left = '56.5px', top = '23px'}
    :css{left='11px',  top='50px'}
    :wikitext(slotImage(inL,  inI,  inLn))
 
frame:tag('div'):addClass('sc-slot')
    :css{left='56.5px', top='23px'}
    :wikitext(slotImage(outL, outI, outLn))
    :wikitext(slotImage(outL, outI, outLn))


html:tag('div'):addClass('sc-slot')
frame:tag('div'):addClass('sc-slot')
    :css{left = '127px', top = '50px'}
    :css{left='127px', top='50px'}
    :wikitext(slotImage(outL, outI, outLn))
    :wikitext(slotImage(outL, outI, outLn))


return tostring(html)
return tostring(frame)
end
end


------------------------------------------------------------------------
------------------------------------------------------------
-- main entry
-- main entry – {{#invoke:Stonecutting|carousel}}
------------------------------------------------------------------------
------------------------------------------------------------
function p.carousel(frame)
function p.carousel(frame)
local args = getArgs(frame, {removeBlanks = false})
local args = getArgs(frame, {removeBlanks=false})


-- ── How many outputs? ──────────────────────────────────────────
-- count outputs
local count = 0
local count = 0
while true do
while true do
local raw = args['output' .. (count + 1)] or args[count + 2]
local raw = args['output' .. (count+1)] or args[count+2]
if not raw or trim(tostring(raw)) == '' then
if not raw or trim(tostring(raw)) == '' then
break
break
Line 71: Line 77:
end
end


-- ── Outer wrapper ─────────────────────────────────────────────
local totalDur = count * 4 -- seconds (4 s per recipe)
 
-- wrapper
local outer = mw.html.create('div')
local outer = mw.html.create('div')
:addClass('stonecutting-carousel')
:addClass('stonecutting-carousel')
:css{width = '180px', height = '131px', position = 'relative'}
:css{width='180px', height='131px', position='relative'}


for i = 1, count do
for i = 1, count do
outer:wikitext(buildFrame(args, i))
outer:wikitext(buildFrame(args, i, totalDur))
end
end


----------------------------------------------------------------
-- single static stylesheet
-- (1) Static stylesheet – simply link the page
outer:wikitext('<templatestyles src="Stonecutting/styles.css" />')
----------------------------------------------------------------
outer:wikitext(
'<templatestyles src="Stonecutting/styles.css" />'
)
 
----------------------------------------------------------------
-- (2) Dynamic stylesheet  – inline, no attributes
----------------------------------------------------------------
local dur = count * 4          -- seconds: 4 s per recipe
local pct = 100 / count        -- slice in %
local vis = pct - 0.01        -- visible almost the whole slice
 
local css = {}
css[#css+1] = string.format(
'.stonecutting-carousel .sc-frame{animation:sc-cycle %ds steps(1) infinite;}',
dur
)
for i = 1, count do
css[#css+1] = string.format(
'.stonecutting-carousel .sc-frame:nth-child(%d){animation-delay:%ds;}',
i, (i - 1) * 4
)
end
css[#css+1] = string.format(
'@keyframes sc-cycle{0%%{opacity:1;} %.2f%%{opacity:1;} %.2f%%{opacity:0;} 100%%{opacity:0;}}',
vis, pct
)
 
outer:wikitext(
'<templatestyles>' .. table.concat(css) .. '</templatestyles>'
)


return tostring(outer)
return tostring(outer)

Revision as of 02:43, 14 June 2025

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

------------------------------------------------------------
--  Module:Stonecutting – animated stone-cutter carousel
--  • Only dependency: Module:Arguments (bundled with Scribunto)
--  • One static stylesheet (Stonecutting/styles.css) for all pages
------------------------------------------------------------
local p       = {}
local getArgs = require('Module:Arguments').getArgs
local trim    = mw.text.trim

------------------------------------------------------------
-- helper: create 32 px inventory slot image link
------------------------------------------------------------
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 label
	return string.format(
		'[[File:%s|32px|class=pixelated|link=%s|alt=%s]]',
		file, tgt, label
	)
end

------------------------------------------------------------
-- helper: build one GUI frame
------------------------------------------------------------
local function buildFrame(args, idx, totalDur)
	local inL  = args.input                  or args[1] or ''
	local inI  = args['input-image']         or ''
	local inLn = args['input-link']          or ''

	local outL  = args['output' .. idx]             or args[idx+1] or ''
	local outI  = args['output' .. idx .. '-image'] or ''
	local outLn = args['output' .. idx .. '-link']  or ''

	-- each frame gets its own animation-delay and the shared duration
	local frame = mw.html.create('div')
	frame	:addClass('sc-frame')
			:css('animation-duration',  totalDur .. 's')
			:css('animation-delay',     (idx-1)*4 .. 's')

	frame:wikitext('[[File:StonecutterGUI.png|180px|link=|alt=]]')

	frame:tag('div'):addClass('sc-slot')
	    :css{left='11px',  top='50px'}
	    :wikitext(slotImage(inL,  inI,  inLn))

	frame:tag('div'):addClass('sc-slot')
	    :css{left='56.5px', top='23px'}
	    :wikitext(slotImage(outL, outI, outLn))

	frame:tag('div'):addClass('sc-slot')
	    :css{left='127px', top='50px'}
	    :wikitext(slotImage(outL, outI, outLn))

	return tostring(frame)
end

------------------------------------------------------------
-- main entry – {{#invoke:Stonecutting|carousel}}
------------------------------------------------------------
function p.carousel(frame)
	local args = getArgs(frame, {removeBlanks=false})

	-- count outputs
	local count = 0
	while true do
		local raw = args['output' .. (count+1)] or args[count+2]
		if not raw or trim(tostring(raw)) == '' then
			break
		end
		count = count + 1
	end
	if count == 0 then
		return '<span style="color:red">Stonecutting: no outputs supplied</span>'
	end

	local totalDur = count * 4 -- seconds (4 s per recipe)

	-- wrapper
	local outer = mw.html.create('div')
		:addClass('stonecutting-carousel')
		:css{width='180px', height='131px', position='relative'}

	for i = 1, count do
		outer:wikitext(buildFrame(args, i, totalDur))
	end

	-- single static stylesheet
	outer:wikitext('<templatestyles src="Stonecutting/styles.css" />')

	return tostring(outer)
end

return p