Mo' Creatures Wiki
Advertisement
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

This module implements {{breaking row}}

Dependencies


local p = {}

local breakingTimeHeader;
local function getBreakingTimeHeader( f )
    if breakingTimeHeader == nil then
        breakingTimeHeader = 'Breaking time (sec)' .. f:preprocess( '<ref group="FN" name="breakingtimenote">Times are for unenchanted tools as used by players with no status effects, measured in seconds. For more information, see Breaking Speed.</ref>' )
    end
    return breakingTimeHeader
end

function p.row( f )
	local args = require( [[Module:ProcessArgs]] ).norm()
	local sprite = require( [[Module:SpriteFile]] )
	
	local function getDplVar( var )
		local val = f:callParserFunction( '#dplvar', 'breaking ' .. var )
		if val == '' then
			val = false
		end
		return val
	end
	local dplVars = {}
	local function setDplVar( var, val )
		table.insert( dplVars, 'breaking ' .. var )
		table.insert( dplVars, val or '1' )
	end
		
	local rows = {}
	local tableParts = {}
	local categories = {}
	
	local horizontal
	if args.horizontal or args[1]:match( ';' ) then
		horizontal = true
	end
	local showTool = true
	local showShears = true
	local showSword = true
	local header, sortable, simple
	if horizontal or not getDplVar( 'header' ) then
		if args.hidetool or horizontal and ( not args[2] or args[2]:lower() == 'any' or args[2]:lower() == 'none' ) then
			showTool = false
			setDplVar( 'hidetool' )
    		breakingTimeHeader = 'Breaking time (secs)'
		end
		if args.hideshears or horizontal and not args.shears then
			showShears = false
			setDplVar( 'hideshears' )
		end
		if args.hidesword or horizontal and not args.sword then
			showSword = false
			setDplVar( 'hidesword' )
		end
		
		sortable = not horizontal and args.sort
		if sortable then
			setDplVar( 'sortable' )
		end
		simple = args.simple
		if simple and not horizontal then
			setDplVar( 'simple' )
		end
		
		local tableClasses = { 'wikitable' }
		if sortable then
			table.insert( tableClasses, 'sortable' )
		end
		table.insert( rows, ' {| class="' .. table.concat( tableClasses, ' ' ) .. '" style="text-align:center"' )
		
		local sortType = ''
		if sortable then
			sortType = 'data-sort-type="number"'
		end
		local rowspan = ''
		if not horizontal then
			rowspan = 'rowspan="2" '
		end
		header = {
			'! ' .. rowspan .. ' | Block'
		}
		
		if not simple then
			table.insert( header, '! ' .. rowspan .. sortType .. ' | Hardness' )
			if showTool then
				table.insert( header, '! ' .. rowspan .. ' | Tool' )
			end
		end
		
		local toolColumns = {}
		if showTool then
			toolColumns = { 'Wooden', 'Stone', 'Iron', 'Diamond', 'Golden'}
		end
		table.insert( toolColumns, 1, 'Default' )
		
		if not simple then
			if showShears then
				table.insert( toolColumns, 'Shears' )
			end
			if showSword then
				table.insert( toolColumns, 'Sword' )
			end
		end
		
		if not horizontal then
			table.insert( header, '! colspan="' .. #toolColumns .. '" |' .. getBreakingTimeHeader( f ) )
			table.insert( header, '|-' )
		end
		
		local toolSprites = {
			Wooden = { 'Icon', 'oak-planks' },
			Stone = { 'Icon', 'cobblestone' },
			Iron = { 'Icon', 'iron-ingot' },
			Diamond = { 'Icon', 'diamond' },
			Golden = { 'Icon', 'gold-ingot' },
			Shears = { 'Icon', 'shears' },
			Sword = { 'Icon', 'wooden-sword' }
		}
		for _, tool in ipairs( toolColumns ) do
			if toolSprites[tool] then
				local image, spriteCat = sprite.sprite{
					name = toolSprites[tool][1],
					toolSprites[tool][2],
					text = tool
				}
				table.insert( header, '! style="text-align:left" ' .. sortType .. ' | ' .. image )
				table.insert( categories, spriteCat )
			else
				table.insert( header, '! ' .. sortType .. ' | ' .. tool )
			end
		end
		
		if not horizontal then
			header = table.concat( header, '\n' )
			setDplVar( 'header', header )
		end
		table.insert( tableParts, header )
	else
		showTool = not getDplVar( 'hidetool' )
		showShears = not getDplVar( 'hideshears' )
		showSword = not getDplVar( 'hidesword' )
		sortable = getDplVar( 'sortable' )
		simple = getDplVar( 'simple' )
	end
	
	local hardness = require( [[Module:Block value]] ).value
	
	local function fillCells( cellsTable, text, num )
		for i = 1, num do
			table.insert( cellsTable, text )
		end
	end
	local materialGrade = {
		Any = 0,
		Wooden = 1, Wood = 1,
		Golden = 1,
		Stone = 2,
		Iron = 3,
		Diamond = 4,
		None = 5
	}
	local materialSpeed = {
		None = 1,
		Any = 1,
		Wooden = 2, Wood = 2,
		Stone = 4,
		Iron = 6,
		Diamond = 8,
		Golden = 12
	}
	local numberMaterials = 6
	
	local function insertBlock( blockArgs )
		local cells = {}
		local blocks = mw.text.split( blockArgs[1], '%s*,%s*' )
		local hardnessVal = tonumber( hardness{ blocks[1], type = 'hardness' } )
		if not hardnessVal then
			hardnessVal = '?'
			local title = mw.title.getCurrentTitle()
			if title.namespace == 0 and not title.isSubpage then
				table.insert(categories, '[[Category:Missing hardness]]')
			end
		end
		local unbreakable
		if hardnessVal == -1 or blockArgs.liquid then
			unbreakable = true
		end
		
		local blockSprites = {}
		local links = mw.text.split( blockArgs.link or '', '%s*,%s*' )
		local ids = mw.text.split( blockArgs.sprite or '', '%s*,%s*' )
		local items = mw.text.split( blockArgs.item or '', '%s*,%s*' )
		for i, block in ipairs( blocks ) do
			local link
			if not links[i] and links[1] ~= '' then
				link = links[1]
			elseif links[i] ~= '' then
				link = links[i]
			end
			local id
			if not ids[i] and ids[1] ~= '' then
				id = ids[1]
			elseif ids[i] ~= '' then
				id = ids[i]
			end
			local blockText
			if args.textTrim then
				blockText = block:gsub( args.textTrim .. '$', '' )
			else
				blockText = block
			end
			local blockSpriteArgs = {
				name = 'Icon',
				block,
				text = blockText,
				link = link,
				id = id
			}
			if items[i] == '1' or not items[i] and items[1] == '1' then
				blockSpriteArgs.data = 'Icon'
			end
			
			local image, spriteCat = sprite.link( blockSpriteArgs )
			table.insert( blockSprites, image )
			table.insert( categories, spriteCat )
		end
		table.insert( cells,
			'! style="text-align:left" | ' .. table.concat( blockSprites, '<br>' ) .. ( blockArgs.note or '' )
		)
		
		local tool = mw.text.trim( simple and 'Tool' or blockArgs[2] or 'Any' ):gsub( '^%l', string.upper )
		local material = mw.text.trim( simple and blockArgs[2] or blockArgs[3] or 'Any' ):gsub( '^%l', string.upper )
		if tool == 'None' then
			material = tool
		end
		if not simple then
			local hardnessText = hardnessVal
			if hardnessVal == -1 then
				hardnessText = ( sortable and 'data-sort-value="999" | ' or '' ) .. '∞'
			end
			table.insert( cells, '|' .. hardnessText )
			
			if showTool then
				local toolCell = '—'
				if tool ~= 'Any' and tool ~= 'None' then
					if material == 'Wood' then
						material = 'Wooden'
					end
					local isMaterialSpecified = (material ~= 'Any') and (material ~= 'None')
					local toolName = ( isMaterialSpecified and material .. ' ' or '' ) .. tool
					local toolSpriteName = toolName .. ( (isMaterialSpecified) and '' or ' Required' )
					local image, spriteCat = sprite.sprite{
						name = isMaterialSpecified and 'Icon' or 'Invicon',
						toolSpriteName,
						title = toolName,
						link = tool,
						keepcase = not isMaterialSpecified -- SlotSprite has case sensitive names
					}
					toolCell = ( sortable and 'data-sort-value="' .. toolName .. '" |' or '' ) .. image
					table.insert( categories, spriteCat )
				end
				table.insert( cells, '|' .. toolCell )
			end
		end
		
		local choices = {}
		local function getChoice( choice, text )
			if not choices[choice] then
				choices[choice] = f:expandTemplate{ title = 'Table Choice', args = { choice, '' } }
			end
			return choices[choice] .. text
		end
		
		local function processTime( num )
			-- the number passed in has been multiplied by 100
			if num < 5 then		    -- Blocks with a breaking time of exactly 1 game tick (0.05 seconds) are not instant mined (no delay after each block broken)
				num = "''0.05''"    -- Blocks have a minimum breaking time of 1 game tick
			else					-- And they must be broken in multiples of 1 game tick
				num = math.ceil( num / 5 ) / 20
			end
			return num
		end
		
		if hardnessVal == '?' then
			fillCells( cells, '|?', numberMaterials + 1 )
		else
			if unbreakable then
				table.insert( cells, '| ' .. ( sortable and 'data-sort-value="999" ' or '' ) .. getChoice( 'no', '∞' ) )
				if showTool then
					fillCells( cells, '|—', numberMaterials )
				end
			else
				local drop = 'yes'
				local forceDrop = false
				if blockArgs.drop == '0' then
					drop = 'partial'
				elseif blockArgs.drop == '1' then
					forceDrop = 'yes'
				end
				local requiredLevel = unbreakable and 999 or materialGrade[material]
				local function insertMaterialCell( material )
					local shouldDrop = drop
					if materialGrade[material] < requiredLevel then
						shouldDrop = 'no'
					end
					-- prevent float number precision loss, multiply by 100 and divide it in processTime function
					local breakTime = processTime( hardnessVal * (shouldDrop == 'no' and 500 or 150) / materialSpeed[material] )
					table.insert( cells, '|' .. getChoice( forceDrop or shouldDrop, breakTime ) )
				end
				
				if not showTool or tool == 'Any' or tool == 'None' then
					insertMaterialCell( 'Any' )
					if showTool then
						fillCells( cells, '|—', numberMaterials )
					end
				else
					for _, material in ipairs{ 'Any', 'Wooden', 'Stone', 'Iron', 'Diamond', 'Golden' } do
						insertMaterialCell( material )
					end
				end
			end
		end
		
		if not simple and ( showShears or showSword ) then
			local tools = {}
			if showShears then
				table.insert( tools, 'Shears' )
			end
			if showSword then
				table.insert( tools, 'Sword' )
			end
			if hardnessVal == '?' then
				fillCells( cells, '|?', #tools )
			else
				local toolSpeed = {
					Shears = 1,
					Sword = 1.5
				}
				if blocks[1] == 'Wool' then
					toolSpeed.Shears = 5
				elseif blocks[1] == 'Leaves' then
					toolSpeed.Shears = 15
				elseif blocks[1] == 'Cobweb' then
					toolSpeed.Sword = 15
					toolSpeed.Shears = 15
				elseif blocks[1] =='Bamboo' then
					toolSpeed.Sword = 5000
				end
				
				for _, tool in ipairs( tools ) do
					local toolDrop = blockArgs[mw.ustring.lower( tool )]
					if not toolDrop then
						table.insert( cells, '|—' )
					else
						local willDrop = 'yes'
						if toolDrop == '0' then
							willDrop = 'partial'
						end
						-- prevent float number precision loss, multiply by 100 and divide it in processTime function
						local breakTime = processTime( hardnessVal * 150 / toolSpeed[tool] )
						table.insert( cells, '|' .. getChoice( willDrop, breakTime ) )
					end
				end
			end
		end
		
		if not horizontal then
			cells = table.concat( cells, '\n' )
		end
		table.insert( tableParts, cells )
	end
	
	if horizontal then
		local blocksArgs = {}
		for _, arg in ipairs{ 1, 'note', 'sprite', 'link', 'item', 'drop', 2, 3, 'shears', 'sword' } do
			if args[arg] then
				local col = 0
				for colVal in mw.text.gsplit( args[arg], '%s*;%s*' ) do
					col = col + 1
					if colVal ~= '' then
						if not blocksArgs[col] then
							blocksArgs[col] = {}
						end
						
						blocksArgs[col][arg] = colVal
					end
				end
			end
		end
		for _, block in ipairs( blocksArgs ) do
			insertBlock( block )
		end
		
		local columns = #tableParts
		for row = 1, #tableParts[1] do
			local cells = {}
			for col = 1, columns do
				table.insert( cells, tableParts[col][row] )
			end
			table.insert( rows, table.concat( cells, '\n' ) )
		end
		
		-- Insert breaking time header after block row when simple, or after tool or hardness row when not
		table.insert( rows, simple and 3 or showTool and 5 or 4, '! colspan="' .. columns + 1 .. '" |' .. getBreakingTimeHeader( f ) )
	else
		insertBlock( args )
		for _, row in ipairs( tableParts ) do
			table.insert( rows, row )
		end
	end
	table.insert( rows, '' )
	
	local note = ''
	if args.foot or horizontal then
		note = f:preprocess( '<references group="FN"/>' )
		
		if args.foot == '2' then
			table.insert( rows, header or getDplVar( 'header' ) )
		end
		table.insert( rows, '|}' )
		
		if not horizontal then
			f:callParserFunction( '#dplvar:set',
				'breaking header', '',
				'breaking hidetool', '',
				'breaking hideshears', '',
				'breaking hidesword', '',
				'breaking simple', '',
				'breaking sortable', ''
			)
		end
	elseif #dplVars > 0 then
		f:callParserFunction( '#dplvar:set', dplVars )
	end
	
	return table.concat( rows, '\n|-\n' ) .. note .. table.concat( categories )
end
return p
Advertisement