Module:Stonecutting: Difference between revisions

From I-Pixelmon
Jump to navigation Jump to search
No edit summary
No edit summary
 
(19 intermediate revisions by the same user not shown)
Line 1: Line 1:
------------------------------------------------------------
------------------------------------------------------------
--  Stone-cutter recipe carousel
--  Module:Stonecutting – animated stone-cutter carousel
--  Example:
--    {{Stonecutting
--      |input=Stone
--      |input-image=Minecraft-stone.png
--      |input-link=https://minecraft.wiki/w/Stone
--      |output1=Slab
--      |output1-image=Minecraft-stoneslab.png
--      |output1-link=https://minecraft.wiki/w/Slab
--      |output2=Chisel
--      |output2-image=Pixelmon-chisel.png
--      |output2-link=Chisel
--    }}
------------------------------------------------------------
------------------------------------------------------------
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


------------------------------------------------------------------------
------------------------------------------------------------
-- turn {label,image,link} → thumbnail w/ link (32 px)
-- helper: 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 target = ( link ~= '' ) and link or label
local tgt  = (link ~= '' and link ) or 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, target, label
file, tgt, label
)
)
end
end


------------------------------------------------------------------------
------------------------------------------------------------
-- build *one* frame (input + preview + output)
-- build one GUI frame
------------------------------------------------------------------------
------------------------------------------------------------
local function buildFrame( args, idx )
local function buildFrame(args, idx, count)
local inL , inI , inLn = args.input or args[1] or '',
local inL  = args.input                 or args[1] or ''
                          args['input-image'] or '',
local inI  = args['input-image']         or ''
                          args['input-link'] 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 outL  = args['output' .. idx]             or args[idx+1] or ''
local outLn = args[ 'output' .. idx .. '-link' ] or ''
local outI  = args['output' .. idx .. '-image'] or ''
local outLn = args['output' .. idx .. '-link'] or ''
 
local frame = mw.html.create('div'):addClass('sc-frame')
 
if count == 1 then
frame:addClass('sc-static')                      -- no animation
else
-- every frame runs the same 4-second “step” once per full cycle
-- total cycle  = 4 s × #outputs
frame:css('animation-duration', (count * 4) .. 's')
    :css('animation-delay',    (idx - 1) * 4 .. 's')
end


local html = mw.html.create( 'div' ):addClass( 'sc-frame' )
frame:wikitext('[[File:StonecutterGUI.png|180px|link=|alt=]]')
html:wikitext( '[[File:StonecutterGUI.png|180px|link=|alt=]]' )


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


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


-- output (right)
frame:tag('div'):addClass('sc-slot')
html: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})


-- count real outputs (skip blanks / whitespace)
-- how many outputs?
local count = 0
local count = 0
while true do
while (args['output' .. (count+1)] or args[count+2])
local raw = args[ 'output' .. ( count + 1 ) ] or args[ count + 2 ]
      and trim(tostring(args['output' .. (count+1)] or args[count+2])) ~= '' do
if not raw or trim( tostring( raw ) ) == '' then break end
count = count + 1
count = count + 1
end
end
Line 81: Line 75:
end
end


------------------------------------------------------------------
local outer = mw.html.create('div')
-- wrapper
:addClass('stonecutting-carousel')
------------------------------------------------------------------
:css{width='180px', height='131px', position='relative'}
local outer = mw.html.create( 'div' )
:addClass( 'stonecutting-carousel' )
: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, count))
end
end


-- base (static) stylesheet
-- static stylesheet is included once from the template, so nothing here
local base = frame:extensionTag(
return tostring(outer)
'templatestyles', '', { src = 'Template:Stonecutting/styles.css' }
)
outer:wikitext( base )
 
------------------------------------------------------------------
-- dynamic stylesheet (duration / delays)
------------------------------------------------------------------
local dur = count * 4          -- seconds (4 s per recipe)
local pct = 100 / count        -- % slice per recipe
local cssParts = {}
 
table.insert( cssParts,
string.format(
'.stonecutting-carousel .sc-frame{animation:sc-cycle %ds steps(1) infinite;}',
dur
)
)
 
for i = 1, count do
table.insert( cssParts,
string.format(
'.stonecutting-carousel .sc-frame:nth-child(%d){animation-delay:%ds;}',
i, ( i - 1 ) * 4
)
)
end
 
table.insert( cssParts,
string.format(
'@keyframes sc-cycle{0%%{opacity:1;} %.2f%%{opacity:1;} %.2f%%{opacity:0;} 100%%{opacity:0;}}',
pct, pct + 0.01
)
)
 
local dyn = frame:extensionTag(
'templatestyles',
table.concat( cssParts, '' ),
{ lang = 'css' }
)
outer:wikitext( dyn )
 
return tostring( outer )
end
end


return p
return p

Latest revision as of 04:31, 14 June 2025

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

------------------------------------------------------------
--  Module:Stonecutting – animated stone-cutter carousel
------------------------------------------------------------
local p       = {}
local getArgs = require('Module:Arguments').getArgs
local trim    = mw.text.trim

------------------------------------------------------------
-- 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')
	local tgt  = (link  ~= '' and link ) or label
	return string.format(
		'[[File:%s|32px|class=pixelated|link=%s|alt=%s]]',
		file, tgt, label
	)
end

------------------------------------------------------------
-- build one GUI frame
------------------------------------------------------------
local function buildFrame(args, idx, count)
	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 ''

	local frame = mw.html.create('div'):addClass('sc-frame')

	if count == 1 then
		frame:addClass('sc-static')                      -- no animation
	else
		-- every frame runs the same 4-second “step” once per full cycle
		-- total cycle  = 4 s × #outputs
		frame:css('animation-duration', (count * 4) .. 's')
		     :css('animation-delay',    (idx - 1) * 4 .. 's')
	end

	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})

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

	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, count))
	end

	-- static stylesheet is included once from the template, so nothing here
	return tostring(outer)
end

return p