Module:Stonecutting: Difference between revisions

From I-Pixelmon
Jump to navigation Jump to search
No edit summary
No edit summary
Line 89: Line 89:
end
end


-- attach TemplateStyles (base rules) ----------------------------
------------------------------------------------------------------------
    local styleBase = frame:extensionTag(
--  Dynamically adjust animation timing to the number of frames
        'templatestyles', '', { src = 'Template:Stonecutting/styles.css' }
------------------------------------------------------------------------
    )
local dur = count * 4          -- seconds (4 s per recipe)
    outer:wikitext(styleBase)
local pct = 100 / count        -- % slice per recipe


    ------------------------------------------------------------------
local cssCode = {}            -- build a single string
    --  Dynamically adjust animation timing to the number of frames
    ------------------------------------------------------------------
    local dur = count * 4            -- seconds, 4 s per recipe
    local pct = 100 / count          -- % slice per recipe


    local css = mw.html.create('style'):attr('type', 'text/css')
-- main animation rule
table.insert(cssCode,
  string.format(
    '.stonecutting-carousel .sc-frame{animation:sc-cycle %ds steps(1) infinite;}',
    dur
  )
)


    -- main animation rule with variable duration
-- per-frame delays
    css
for i = 1, count do
      :wikitext(string.format(
  table.insert(cssCode,
        '.stonecutting-carousel .sc-frame{animation:sc-cycle %ds steps(1) infinite;}',
    string.format(
        dur
      '.stonecutting-carousel .sc-frame:nth-child(%d){animation-delay:%ds;}',
      ))
      i, (i - 1) * 4
    )
  )
end


    -- per-frame delays
-- key-frames (visible for its slice, hidden otherwise)
    for i = 1, count do
table.insert(cssCode,
        css:wikitext(string.format(
  string.format('@keyframes sc-cycle{0%%{opacity:1;} %.2f%%{opacity:1;} %.2f%%{opacity:0;} 100%%{opacity:0;}}',
          '.stonecutting-carousel .sc-frame:nth-child(%d){animation-delay:%ds;}',
                pct, pct + 0.01)
          i, (i - 1) * 4
)
        ))
    end


    -- keyframes: visible for its whole slice, invisible otherwise
cssCode = table.concat(cssCode)
    css:wikitext('@keyframes sc-cycle{')
    css:wikitext(string.format('0%%{opacity:1;} %.2f%%{opacity:1;}', pct))
    css:wikitext(string.format('%.2f%%{opacity:0;} 100%%{opacity:0;}', pct + 0.01))
    css:wikitext('}')


    outer:wikitext(tostring(css))
-- inject as a TemplateStyles tag
local styleDyn = frame:extensionTag(
  'templatestyles',
  cssCode,
  { lang = 'css' }              -- inline stylesheet
)
outer:wikitext(styleDyn)


    return tostring(outer)
end
end


return p
return p

Revision as of 21:58, 13 June 2025

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

------------------------------------------------------------
--  Stone-cutter recipe carousel
--  Usage 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 getArgs = require('Module:Arguments').getArgs

------------------------------------------------------------------------
-- tiny helper that turns {label,image,link} → [[File:...]] or text
------------------------------------------------------------------------
local function slotImage(label, image, link)
	if not label or label == '' then return '' end
	local file = image ~= '' and image or ('Grid_' .. label .. '.png')
	local alt  = label
	local linkTarget = link ~= '' and link or label
	return string.format(
		'[[File:%s|32px|class=pixelated|link=%s|alt=%s]]',
		file, linkTarget, alt
	)
end

------------------------------------------------------------------------
-- build a single frame (= one output variant)
------------------------------------------------------------------------
local function buildFrame(args, idx)
	local inputL , inputI , inputLink  = args.input     or args[1]            ,
	                                     args['input-image']  or '',
	                                     args['input-link']   or ''
	local outL   = args['output'..idx] or args[idx+1]   or ''
	local outI   = args['output'..idx..'-image'] or ''
	local outLink= args['output'..idx..'-link']  or ''

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

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

	-- input slot (left, 48 × 48 px area)
	local inp = html:tag('div'):addClass('sc-slot'):css{left='11px', top='50px'}
	inp:wikitext(slotImage(inputL, inputI, inputLink))

    -- Stonecutting Type (middle)
	local out = html:tag('div'):addClass('sc-slot'):css{left='56.5px', top='23px'}
	out:wikitext(slotImage(outL, outI, outLink))

	-- output slot (right)
	local out = html:tag('div'):addClass('sc-slot'):css{left='127px', top='50px'}
	out:wikitext(slotImage(outL, outI, outLink))

	return tostring(html)
end

------------------------------------------------------------------------
-- main entry
------------------------------------------------------------------------
function p.carousel(frame)
	local args = getArgs(frame, {removeBlanks = false})

	-- count outputs (ignore blanks and whitespace-only params)
    local count = 0
    while true do
        local raw = args['output' .. (count + 1)] or args[count + 2]
        if not raw then break end                       -- truly missing
        if mw.text.trim(tostring(raw)) == '' then break end  -- empty / spaces
        count = count + 1
    end
	if count == 0 then
		return "<span style='color:red'>Stonecutting: no outputs supplied</span>"
	end

	-- build 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))
	end

	------------------------------------------------------------------------
--  Dynamically adjust animation timing to the number of frames
------------------------------------------------------------------------
local dur = count * 4          -- seconds (4 s per recipe)
local pct = 100 / count        -- % slice per recipe

local cssCode = {}             -- build a single string

-- main animation rule
table.insert(cssCode,
  string.format(
    '.stonecutting-carousel .sc-frame{animation:sc-cycle %ds steps(1) infinite;}',
    dur
  )
)

-- per-frame delays
for i = 1, count do
  table.insert(cssCode,
    string.format(
      '.stonecutting-carousel .sc-frame:nth-child(%d){animation-delay:%ds;}',
      i, (i - 1) * 4
    )
  )
end

-- key-frames (visible for its slice, hidden otherwise)
table.insert(cssCode,
  string.format('@keyframes sc-cycle{0%%{opacity:1;} %.2f%%{opacity:1;} %.2f%%{opacity:0;} 100%%{opacity:0;}}',
                pct, pct + 0.01)
)

cssCode = table.concat(cssCode)

-- inject as a TemplateStyles tag
local styleDyn = frame:extensionTag(
  'templatestyles',
  cssCode,
  { lang = 'css' }              -- inline stylesheet
)
outer:wikitext(styleDyn)

end

return p