Module:UI

-- -- Taken from: https://minecraft.gamepedia.com/Module:UI local multiRequire = require('Module:MultiRequire') local getArgs = require('Module:Arguments').getArgs local slot = require( Module:Inventory slot ).slot local tooltips = mw.loadData('Module:Inventory slot/Aliases') local parseFrameText = require( Module:Inventory slot ).parseFrameText local rarityAliases = require('Module:RarityTier/Aliases') local table, string, lu, uiText, uiColors = multiRequire('Module:Table', 'Module:String', 'Module:LibraryUtil', 'Module:UIText', 'Module:UIText/Data') local formatUIText = uiText._main

local addSlot = function( args, item, prefix, class, default ) local none, nostacksize prefix = prefix or '' if #prefix == 0 then none = 'none' nostacksize = ((item ==  or nil) and ) or (args and args[item] and args[item]:gsub( '[,%d]',  ) or ) end return slot{ nostacksize or args[item], mod = args.Mod, link = none or args[prefix .. 'link'], title = none or args[prefix .. 'title'], class = class, default = default, parsed = args.parsed, forcenum = args.forcenum } end

local p = {}

-- Crafting table function p.craftingTable( f ) local args = f	if f == mw.getCurrentFrame then args = f:getParent.args else f = mw.getCurrentFrame end local body = mw.html.create( 'span' ):addClass( 'mcui mcui-Crafting_Table pixel-image' ) -- CUSTOM: changing grid to use since wikia mobile doesn't support CSS local input = body:tag( 'table' ):addClass( 'mcui-input' ) for num = 1, 3 do		local row = input:tag( 'tr' ):addClass( 'mcui-row' ) for _, letter in ipairs{ 'A', 'B', 'C' } do		   local td = row:tag( 'td' ) td:wikitext( addSlot( args, letter .. num, 'I' ) ) end end 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( args, '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 return tostring( mw.html.create( 'div' ):node( body ) ) end

-- Furnace function p.furnace( f ) local args = f	if f == mw.getCurrentFrame then args = f:getParent.args else f = mw.getCurrentFrame end 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( f ) local args = f	if f == mw.getCurrentFrame then args = f:getParent.args else f = mw.getCurrentFrame end 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

-- Stonecutter function p.stonecutter( f ) local args = f	if f == mw.getCurrentFrame then args = f:getParent.args else f = mw.getCurrentFrame end local body = mw.html.create( 'span' ):addClass( 'mcui mcui-Stonecutter pixel-image' ) local input = body:tag( 'span' ):addClass( 'mcui-input' ) input:wikitext( addSlot( args, 'Input', 'I' ) ) local arrow = body:tag( 'span' ):addClass( 'mcui-stonecutterArrow' ) if (args.arrow or ) ~=  then arrow:css(			'background-image',			''		) end arrow:wikitext( addSlot( args, 'Output', '', 'invslot-plain mcui-stonecutterSprite' ) ) body :tag( 'span' ) :addClass( 'mcui-output' ) :wikitext( addSlot( args, 'Output', 'O', 'invslot-large' ) ) return tostring( mw.html.create( 'div' ):node( body ) ) end

-- Loom function p.loom( f ) local args = f	if f == mw.getCurrentFrame then args = f:getParent.args else f = mw.getCurrentFrame end local body = mw.html.create( 'span' ):addClass( 'mcui mcui-Loom pixel-image' ) local tapestry = body:tag( 'span' ):addClass( 'mcui-tapestry' ) if args.Banner and #args.Banner>0 then tapestry:wikitext( addSlot( args, 'Banner', 'B', 'mcui-inputBanner' ) ) end if args.Dye and #args.Dye>0 then tapestry:wikitext( addSlot( args, 'Dye', 'D', 'mcui-inputDye' ) ) end if args.Pattern and #args.Pattern>0 then tapestry:wikitext( addSlot( args, 'Pattern', 'P', 'mcui-inputPattern' ) ) end tapestry:tag( 'span' ):tag( 'br' ):done local arrow = body:tag( 'span' ):addClass( 'mcui-loomArrow' ) if args.arrow or  ~=  then arrow:css(			'background-image',			''		) end local sprite = args.Sprite local bannerSprite if sprite and #sprite>0 then local animate = require( Module:AnimateSprite ).animate bannerSprite = animate{ args.Sprite, sheet = 'SlotSprite' }	else bannerSprite = ' ' end arrow :tag( 'span' ) :addClass( 'mcui-bannerSprite' ) :wikitext( bannerSprite ) body :tag( 'span' ) :addClass( 'mcui-output' ) :wikitext( addSlot( args, 'Output', 'O', 'invslot-large' ) ) return tostring( mw.html.create( 'div' ):node( body ) ) end

-- Grindstone function p.grindstone( f ) local args = f	if f == mw.getCurrentFrame then args = f:getParent.args else f = mw.getCurrentFrame end local body = mw.html.create( 'span' ):addClass( 'mcui mcui-Grindstone pixel-image' ) local grindstone = body:tag( 'span' ):addClass( 'mcui-grindstone' ) grindstone:wikitext( addSlot( args, 'Input1', 'I1', 'mcui-input1' ) ) grindstone:wikitext( addSlot( args, 'Input2', 'I2', 'mcui-input2' ) ) local arrow = body:tag( 'span' ):addClass( 'mcui-arrow' ) if args.arrow or  ~=  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

-- 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: Collection UI -- -- Creates a main collection UI for a given item - function p.collectionUI(frame) return p._collectionUI(table.deepCopy(getArgs(frame))) end

- -- _collectionUI Helper functions - local rarityReplace = mw.clone(rarityAliases) for k, v in pairs(rarityReplace) do	rarityReplace[k] = '' end

local function replaceRarity(s) return s and s:gsub(s, rarityReplace) end

local function specialCaseColors(s) local matches = { ['[Mm]inion'] = 'blue', ['[Uu]pgrade'] = 'green', }

for k, v in pairs(matches) do		if s:match(k) then return uiColors.conversions[v] end end end

local function isUpgrade(s) return not not s:match('[Uu]pgrade') end local function parseCollectionData(slots, rewards, collection) local total = 0 local rows = 1 for y, v in ipairs(rewards) do		total = total+1 if y > 27 then break; end local x = 3 if y/9 >= 1 then x = x+rows-1 end if y%9 == 0 and y/9 >= 1 then rows = rows+1 end y = y%9 y = y == 0 and 9 or y		slots[x] = slots[x] or {} slots[x][y] = { total == 1 and "Yellow Stained Glass Pane,"..total or 'Red Stained Glass Pane,'..total, link='none', title=table.concat{ '&e', collection, ' ', string._toRoman(total) }, class=v._goto and 'goto-'..v._goto, text=formatUIText(string.dedent			\n&7Progress: &e0&6%%			&f%s &e0&6/&e%s&7			%s:			%s			&eClick to view rewards!			):format(				('-'):rep(20),				string._formatShortNum(string._toNumber(v.amount)),				#v > 1 and '&7Rewards' or '&7Reward',				table.concat(table.map(v, function(val)					local s = val[1]					local isUpgrade = isUpgrade(s)					return table.concat{ 						val.rarity..s, 						isUpgrade and ' ' or ' &r', 						val.type or (s:match('[Mm]inion') and 'Recipes') or (isUpgrade and '' or'Recipe'),					}				end), '/')			) }	end end

local function parseTextList(s) local rewards = {} local count = 0

for i, v in ipairs(string.split(s, '\n')) do		local _type v = string.methods(v):_trim if v:getValue ~= '' then if v:charAt(1) == "*" then if v:charAt(2) == "*" then _type = 'item' else _type = 'amount' end end if _type == 'amount' then local amount, _goto = unpack(string.split(v:sub(2), "%s*,%s*")) count = count+1 rewards[count] = {} rewards[count].amount = amount rewards[count]._goto = _goto and _goto:gsub('goto%-', '') elseif _type == 'item' then local item, type, rarity = unpack(string.split(v:sub(3), '%s*,%s*')) item = item or v:sub(3) rarity = (rarity and rarity ~= "") and uiText.getRarityColor(rarity) local tooltip = tooltips[item] local split = string.split(tooltip and tooltip.text or '', '[\n\\]') local tooltipRarity = split[#split > 1 and #split-1 or 1] tooltipRarity = tooltipRarity and (tooltipRarity:match('^&([a-z0-9])&l') or tooltipRarity:match('&([a-z0-9])&l%w*$'))

table.push(rewards[count], { 					item, 					rarity = '&'..(tooltipRarity or rarity or specialCaseColors(item) or 'f')..'&l',					type=(type and type ~= "") and string.ucfirst(recipeAliases[type:lower] or type)				}) end end end return rewards end

local recipeAliases = { ['r'] = 'recipe', ['recipe'] = 'recipe', ['recipes'] = 'recipes', ['rs'] = 'recipes', ['rec'] = 'recipe', ['recs'] = 'recipes', ['recip'] = 'recipe', ['recips'] = 'recipes', ['res'] = 'recipes', ['re'] = 'recipe', ['up'] = 'upgrade', ['upg'] = 'upgrade', ['u'] = 'upgrade', ['upgr'] = 'upgrade', ['upgra'] = 'upgrade', ['upgrad'] = 'upgrade', ['upgrade'] = 'upgrade', } - -- function: _collectionUI(args: table|frame) -- -- Invoked by. - function p._collectionUI(args) checkType(1, args, { 'table' }) assertTrue(args[1], 'No collection specified', 2) assertTrue(args[2], 'No collection rewards specified', 2) local slots = {} local collection = args[1] and args[1]:gsub('[Ee][Nn][Cc][Hh][Aa]?[Nn]?[Tt]?[Ee]?[Dd]? ?', ):gsub('[Bb][Ll][Oo][Cc][Kk] ?[Oo]?[Ff]? ?', ) local title = mw.title.getCurrentTitle local wt = mw.html.create('table') :attr{ class="mcui mcui-Crafting_Table pixel-image" } :css{ ['margin'] = '0 auto'; ['display'] = 'table'; }		:tag('tr') :css{ ['position'] = 'absolute'; ['top'] = '2px'; }			:tag('td') :attr{ colspan=9 } :css{ ['font-family'] = 'minecraft'; ['color'] = '#2B2D2F'; ['font-size'] = '16px'; }				:wikitext(collection and collection..' Collection' or title.rootText) :done :done

for x = 1, 6, 1 do		slots[x] = {} for y = 1, 9, 1 do			if x == 1 and y == 5 then slots[x][y] = { args.title or collection, link='none', title='&a'..collection..' Collection', text=formatUIText(string.dedent					&7View all your %s Collection 					&7progress and rewards!					&7Total Collected: &e0					:format(collection)) }			elseif x == 6 and y == 4 then slots[x][y] = { 'Go Back', text=args['goback'] and '&7To '..args['goback'], link=args['goback'] and args['goback']:gsub('%s*[Cc]ollection', ''), class=args['return_id'] and 'goto'..args['return_id']:gsub('goto%-',''), }			elseif x == 6 and y == 5 then slots[x][y] = { 'Close' } else slots[x][y] = { 'Blank' } end end end parseCollectionData(slots, parseTextList(args[2]), collection) for x, xValue in ipairs(slots) do		local row = wt:tag('tr') :addClass('mcui-row') :css{ ['margin-top'] = x == 1 and '24px' or nil }		for y, yValue in ipairs(xValue) do			row:tag('td') :wikitext(slot(yValue)) :done end row:done end return args['id'] and tostring(mw.html.create('div')			:node(wt)			:attr{ id=args['id'] and 'ui-'..args['id']:gsub('ui%-', ''), class=args['id'] and "sbw-ui-tab-content" } 		:done) or tostring(wt) end

return p