Module:UI

-- -- Taken from: https://minecraft.gamepedia.com/Module:UI local getArgs = require('Module:Arguments').getArgs local loader = require('Module:Loader')

local string, table, _, uiText, yesno, inventorySlot, crafting, Interface = loader.require('String', 'Table', 'LibraryUtil', 'UIText', 'Yesno', 'Inventory slot', 'Crafting', 'UI/Core') local rarityAliases = loader.loadData('RarityTier/Aliases')

local aliasesCache = require('Module:Cache').slotAliasesCache

local slot = inventorySlot.slot local parseFrameText = inventorySlot.parseFrameText local formatUIText = uiText._main local curTitle = mw.title.getCurrentTitle

local p = {}

local addSlot = crafting.addSlot

-- Crafting table function p.craftingTable( frame ) local args = getArgs(frame) local body = mw.html.create('span'):addClass('mcui mcui-Crafting_Table pixel-image') local recipe = crafting.parseRecipe(args) local grid = crafting._craftingGrid(recipe) body:node(grid) local arrow = body:tag('span'):addClass('mcui-arrow'):tag('br'):done if args.arrow or  ~=  then arrow:css(			'background-image',			''		) end body:tag('span') :addClass('mcui-output') :wikitext(addSlot(recipe, 'Output', 'O', 'invslot-large')) local shapeless = args.shapeless or '' local fixed = args.fixed or '' if shapeless ~=  or fixed ~=  then local icon = body:tag('span') :addClass('mcui-icons') :tag('span') :tag('br') :done if shapeless ~= '' then icon:addClass('mcui-shapeless') :attr('title',					'This recipe is shapeless, the inputs may be placed in any arrangement in the crafting grid.'				) elseif fixed ~= '' then local notFixed = args.notfixed or '' local exceptFixed = '' if notFixed ~= '' then exceptFixed = '; except for ' .. notFixed .. ', which can go anywhere' end icon:addClass('mcui-fixed') :attr('title',					'This recipe is fixed, the input arrangement may not be moved or mirrored in the crafting grid' .. exceptFixed .. '.'				) end end if curTitle.namespace == 0 and (args.A1 or args.A2 or args.A3 or args.B1 or args.B2 or args.B3 or args.C1 or args.C2 or args.C3) then return tostring(mw.html.create('div'):node(body)) .. ''	end return tostring(mw.html.create('div'):node(body)) end

-- Crafting UI function p.craftingUI( frame ) local args = getArgs(frame) local ui = Interface({		args.title or 'Craft Item',		id = args.id,		return_text = args.return_text or args.goback,		return_link = args.return_link,		return_id = args.return_id or args.return_to,		hide = args.hide,	}) ui:setSlot(3, 6, {		'Crafting Table',		link = 'none',		title = '&aCrafting Table',		text = '&7Craft this recipe by using/&7a crafting table.',	}) for num = 1, 3 do		for i, lt in ipairs{ 'A', 'B', 'C' } do			if yesno(args.custom) then ui:setSlot(num + 1, i + 1, args[lt .. num], true) else ui:setSlot(num + 1, i + 1, {					args[lt .. num],					link = args[lt .. '_link' .. num] or args[lt .. num .. '_link'],					text = args[lt .. '_text' .. num] or args[lt .. num .. '_text'],					class = args[lt .. '_class' .. num] or args[lt .. num .. '_class'],					title = args[lt .. '_title' .. num] or args[lt .. num .. '_title'],				}) end end end if yesno(args.custom) then ui:setSlot(3, 8, args.Output, true) else ui:setSlot(3, 8, {			args.Output,			link = args.Output_link,			text = args.Output_text,			class = args.Output_class,			title = args.Output_title,		}) end return tostring(ui) end

-- Collection Recipe UI -- Outdated. The goback message should be something like -- "Go back to Coal IV Rewards" function p.collectionRecipe( frame ) local args = getArgs(frame) local topText = args.title or (args.Output or curTitle.text):gsub('^(.-)[;,](.+)$', '$1') topText = topText .. (args.title and '' or ' Recipe') local back = '&7 to ' .. (args.return_text or args.goback or args[1] or curTitle.text) .. ' Collection' return p.craftingUI(table.merge(args, { title = topText, goback = back, hide = yesno(args.hide, true), })) end

-- Furnace function p.furnace( frame ) local args = getArgs(frame) local body = mw.html.create('span'):addClass('mcui mcui-Furnace pixel-image') local input = body:tag('span'):addClass('mcui-input') input:wikitext(addSlot(args, 'Input', 'I')) local fuel = input:tag('span'):addClass('mcui-fuel'):tag('br'):done local fuelImg = args.FuelUsage or '' local burning = args.Input or  ~=  and args.Fuel or  ~=  if not burning then fuel:addClass('mcui-inactive') if fuelImg ~= '' then fuelImg = fuelImg .. ' (in-active)' end end if fuelImg ~= '' then fuel:css(			'background-image',			''		) end input:wikitext(addSlot(args, 'Fuel', 'F')) local arrow = body:tag('span'):addClass('mcui-arrow'):tag('br'):done local arrowImg = args.Progress or '' if not burning or (args.Output or ) ==  then arrow:addClass('mcui-inactive') if arrowImg ~= '' then arrowImg = arrowImg .. ' (in-active)' end end if arrowImg ~= '' then arrow:css(			'background-image',			''		) end body :tag('span') :addClass('mcui-output') :wikitext(addSlot(args, 'Output', 'O', 'invslot-large')) return tostring(mw.html.create('div'):node(body)) end

-- Brewing Stand function p.brewingStand( frame ) local args = getArgs(frame) local body = mw.html.create('span'):addClass('mcui mcui-Brewing_Stand pixel-image') local input = body:tag('span'):addClass('mcui-input') input:tag('span'):addClass('mcui-bubbling'):tag('br') input:wikitext(addSlot(args, 'Input', 'I')) input:tag('span'):addClass('mcui-arrow'):tag('br') if (args.Input or ) ==  or		((args.Output1 or ) ==  and (args.Output2 or ) ==  and (args.Output3 or ) == ) then input:addClass('mcui-inactive') end body:tag('span'):addClass('mcui-paths'):tag('br') local output = body:tag('span'):addClass('mcui-output') for i = 1, 3 do output:wikitext(addSlot(args, 'Output' .. i, 'O' .. i, 'mcui-output' .. i)) end return tostring(mw.html.create('div'):node(body)) end

-- Melody function p.noteSequence(f) local args = getArgs(f) local sequence = args[1] return p._noteSequence(sequence) end

function p._noteSequence(sequence) local function simpleSlot(frames) frames = parseFrameText(frames, nil, false, {aliases = '', default = nil}) local function simpleMakeItem(name) return mw.html.create('span'):addClass('invslot-item invslot-item-image'):wikitext(''):done end local body = mw.html.create('span'):addClass('invslot animated') local activeFrame = 1 for i, frame in ipairs(frames) do			local item if frame[1] then item = body:tag('span'):addClass('animated-subframe') local subActiveFrame = 1 --FC-frame.randomise and random(#frame) or 1 for sI, sFrame in ipairs(frame) do					local sItem = simpleMakeItem(sFrame.name) item:node(sItem) if sI == subActiveFrame then sItem:addClass('animated-active') else sItem:addClass('hidden') end end else item = simpleMakeItem(frame.name) body:node(item) end if i == activeFrame and animated then item:addClass('animated-active') elseif animated then item:addClass('hidden') end end return mw.getCurrentFrame:preprocess(tostring(body)) end local colors = { 'Red', 'Yellow', 'Lime', 'Green', 'Purple', 'Blue', 'Light_Blue' }	local slots = {} for x = 1, 7, 1 do		slots[x] = {} for y = 1, 6, 1 do			if y == 5 then slots[x][y] = sequence:gsub('[' .. x .. ']', 'Block_of_Quartz;') else slots[x][y] = sequence:gsub('[' .. x .. ']', colors[x] .. '_Wool;') end if y == 5 then slots[x][y] = slots[x][y]:gsub('[%d%s]', colors[x] .. '_Stained_Clay;') else slots[x][y] = slots[x][y]:gsub('[%d%s]', colors[x] .. '_Stained_Glass_Pane;') end if y == 5 then for z = 1, y, 1 do slots[x][y] = colors[x] .. '_Stained_Clay;' .. slots[x][y] end for z = 1, 12-y, 1 do slots[x][y] = slots[x][y] .. colors[x] .. '_Stained_Clay;' end else for z = 1, y, 1 do slots[x][y] = colors[x] .. '_Stained_Glass_Pane;' .. slots[x][y] end for z = 1, 12-y, 1 do slots[x][y] = slots[x][y] .. colors[x] .. '_Stained_Glass_Pane;' end end slots[x][y] = slots[x][y]:gsub('[_]', ' ') end end local table = mw.html.create('table'):addClass('mcui mcui-Crafting_Table pixel-image'):css({margin = '0 auto', display = 'table', cursor = 'not-allowed'}) for y = 1, 6, 1 do		local row = table:tag('tr'):addClass('mcui-row') row:tag('td'):wikitext(simpleSlot('Gray Stained Glass Pane')):done for x = 1, 7, 1 do			row:tag('td'):wikitext(simpleSlot(slots[x][y])):done end row:tag('td'):wikitext(simpleSlot('Gray Stained Glass Pane')):done row:done end table:done return tostring(table) end

- -- Template: UIPage -- -- Imports (transclude) another UI page with custom options on its first UI. - function p.uipage(frame) local args = getArgs(frame) local page = args.page or args[1] return frame:preprocess(p._uipage(page, args)) end

function p._uipage(page, args) local function injectParamsBoolean(callStr, args) for param, value in pairs(args) do			if value then value = tostring(yesno(value)) callStr, n = callStr:gsub('|%s*' .. param .. '%s*=.-%f[|}]','|' .. param .. '=' .. value .. '\n') if n == 0 then callStr = callStr:sub(0,callStr:len-2) .. '|' .. param .. '=' .. value .. '}}' end end end return callStr end local function injectParamsString(callStr, args) for param, value in pairs(args) do			if value then callStr, n = callStr:gsub('|%s*' .. param .. '%s*=.-%f[|}]','|' .. param .. '=' .. value .. '\n') if n == 0 then callStr = callStr:sub(0,callStr:len-2) .. '|' .. param .. '=' .. value .. '}}' end end end return callStr end local return_id = args.return_id local extPageTitle = mw.title.new(page, 0) if not extPageTitle.exists then error('Specified page does not exist, page: ' .. page) end local extPageContent = extPageTitle:getContent local ls = string.matchAll(extPageContent,'%b{}') local finalStr = '' local firstUI = true if ls.n < 1 then return '' end for i = 1, ls.n, 1 do		local callStr = ls[i][1] local x, y = callStr:find('{{UI|') local x1, y1, subpage, subparams = callStr:find('{{UIPage|(.-)%f[|}](.-)}}') if x == 1 then if firstUI then -- first UI on page, apply all the custom settings to this UI				callStr = injectParamsBoolean(callStr, {					hide = yesno(args.hide,true),					fill = args.fill, 					rows = args.rows,					cols = args.cols,					noarrow = args.noarrow,					noclose = args.noclose,				}) callStr = injectParamsString(callStr, {					id = args.id,					goback = (args.return_text or args.goback),					goback_link = args.goback_link,					return_id = args.return_id,					arrow = (args.arrow or args.arrow_),					close_ = (args.close or args.close_),				}) firstUI = false end finalStr = finalStr .. callStr elseif x1 == 1 then subparams = subparams and subparams:gsub('^[|%s]*(.-)[|%s]*$','%1') or '' local subargs = {} for _, param in ipairs(string.split(subparams,'|')) do				if param:match('=') then param = string.split(param, '=') subargs[param[1]] = param[2] else -- no positional arguments for UIPage at the moment end end finalStr = finalStr .. p._uipage(subpage, subargs) end end return finalStr end

- -- Template: UI -- -- Creates a UI. - function p.ui(frame) local args = getArgs(frame, { removeBlanks = false }) local ui = Interface(args[1], args.id, {		text = (args.return_text or args.goback_text or args['return'] or args.goback),		link = (args.return_link or args.goback_link),		id = (args.return_id or args.goback_id),	}, yesno(args.hide, false), args.fill, args.rows, args.cols, args.noarrow, args.noclose, (args.arrow or args.arrow_), (args.close or args.close_)) local x, y, rowCount = 1, 1, 1 local maxRows, maxCols = tonumber(args.rows) or 6, tonumber(args.cols) or 9 local fill = yesno(args.fill, true) local defaultnolink = yesno((args['defaultnolink'] or args['dnl']), false) local function decodeCommas(...) local t = { ... }		for i, v in ipairs(t) do			t[i] = t[i]:gsub('\255', ',') end return unpack(t) end local function setSlot(v, x, y)		local isCustom = v:match('(.-)') v = v:gsub('\\,', '\255') local val, id, title, text = decodeCommas(string.unpackedSplit(v, '%s*,%s*')) local _val = val local val, num = val:match('^%s*(.+)%s*[;]%s*(%d+)%s*$') val = val or _val local link_specify if not id or id == '' then id = nil else local _id = id			id, link_specify = id:match('^%s*(.+)%s*[;]%s*(.+)%s*$') id = id or _id end -- [IMPORTANT] Transform newlines into `/` if text and text:match('\n') then text = text:gsub('\n', '/') end ui:setSlot(x, y, isCustom and v or {			val .. (num and ', ' .. num or ),			class = (id and id ~= 'none') and 'goto-' .. id:gsub('^goto%-', ),			link = (id and id ~= 'none') and 'none' or (link_specify or (defaultnolink and 'none' or'')),			title = title,			text = text,		}, isCustom) end for i, v in ipairs(args) do		if i > 1 then if x > 6 then break; end if v:match('^%-$') then for y2 = y, maxCols do					if fill then ui:setBlankSlot(x, y2) else ui:setSlot(x, y2, '') end end x = x+1 y = 1 elseif y > maxCols then y = 1 x = x+1 else setSlot(v, x, y)				y = y+1 end end end for k, v in pairs(args) do		local k = tostring(k) if k:match('^%d+%s*,%s*%d+$') then local x, y = k:match('^(%d+)%s*,%s*(%d+)$') setSlot(v, tonumber(x), tonumber(y)) elseif k:match('^row%s*([1-6])%s*$') then local x = k:match('^row%s*([1-6])$') local endParams = v:match('%s*;%s*([%d%s,]-)%s*$') v = v:gsub('%s*;%s*([%d%s,]-)%s*$', '') endParams = endParams and string.split(endParams, '%s*,%s*') or {1, maxCols} if #endParams > 2 then for dummy, y in pairs(endParams) do					setSlot(v:gsub('%$n', y):gsub('\\%$n', '$n'), tonumber(x), tonumber(y)) end else for y = tonumber(endParams[1] or 1), tonumber(endParams[2] or maxCols), 1 do					setSlot(v:gsub('%$n', y):gsub('\\%$n', '$n'), tonumber(x), tonumber(y)) end end elseif k:match('^colu?m?n?%s*([1-9])%s*$') then local y = k:match('^colu?m?n?%s*([1-9])%s*$') local endParams = v:match('%s*;%s*([%d%s,]-)%s*$') v = v:gsub('%s*;%s*([%d%s,]-)%s*$', '') endParams = endParams and string.split(endParams, '%s*,%s*') or {1, maxRows} if #endParams > 2 then for dummy, x in pairs(endParams) do					setSlot(v:gsub('%$n', x):gsub('\\%$n', '$n'), tonumber(x), tonumber(y)) end else for x = tonumber(endParams[1] or 1), tonumber(endParams[2] or maxRows), 1 do					setSlot(v:gsub('%$n', x):gsub('\\%$n', '$n'), tonumber(x), tonumber(y)) end end end end return tostring(ui) end

function p.forgingTable( frame ) local args = getArgs(frame) local body = mw.html.create('span'):addClass('mcui mcui-Forging_Table pixel-image') -- CUSTOM: changing grid to use since wikia mobile doesn't support CSS local input = body:tag('table'):addClass('mcui-input') local row = input:tag('tr'):addClass('mcui-row') for num = 1, 6 do		if args[num] then local td = row:tag('td') td:wikitext(addSlot(args, num, 'I')) end end local arrow = body:tag('span'):addClass('mcui-arrow') :tag('span'):addClass('mcui-text mcui-overarrow-text'):wikitext(args.Time):done :tag('br') :done if args.arrow or  ~=  then arrow:css({			['background-image'] = '',			['margin-top'] = '0px'		}) end body :tag('span') :addClass('mcui-output') :wikitext(addSlot(args, 'Output', 'O', 'invslot-large')) return tostring(mw.html.create('div'):node(body)) end

p.createBlankUI = Interface p.slot = slot return p