Module:Breaking time: Difference between revisions

From Create: Minecraft Mod Wiki
Jump to navigation Jump to search
Create: Minecraft Mod Wiki>Joker876
No edit summary
Create: Minecraft Mod Wiki>Joker876
No edit summary
Line 1: Line 1:
local p = {}
local p = {}
local displayItem = require( [[Module:Item]] ).item
local mcWikiLink = require( [[Module:Link]] ).mcWikiLink


local breakingTimeHeader;
local breakingTimeHeader;
Line 8: Line 11:
     return breakingTimeHeader
     return breakingTimeHeader
end
end
 
function ucfirst(s)
function p.row( f )
if s == nil then s = "" end
return s:gsub("(%w)([%w']*)", function(a,b) return string.upper(a)..b end)
end
function p.breaking( f )
local args = require( [[Module:ProcessArgs]] ).norm()
local args = require( [[Module:ProcessArgs]] ).norm()
local sprite = require( [[Module:Sprite]] )
local rows = {}
local tableParts = {}
local categories = {}
local horizontal
local materials = {
if args.horizontal or args[1]:match( ';' ) then
any = {grade=0,speed=1,display={nolink=true,item='Default',img='Blank'}},
horizontal = true
wooden = {grade=1,speed=2,display={nolink=true,item='Wooden',img='Oak Planks'}},
end
stone = {grade=2,speed=4,display={nolink=true,item='Stone',img='Cobblestone'}},
local showTool = true
iron = {grade=3,speed=6,display={nolink=true,item='Iron',img='Iron Ingot'}},
local showShears = true
diamond = {grade=4,speed=8,display={nolink=true,item='Diamond'}},
local showSword = true
        netherite = {grade=5,speed=9,display={nolink=true,item='Netherite',img='Netherite Ingot'}},
local header, sortable, simple
golden = {grade=1,speed=12,display={nolink=true,item='Golden',img='Gold Ingot'}},
if horizontal then
}
if args.hidetool or horizontal and ( not args[2] or args[2]:lower() == 'any' or args[2]:lower() == 'none' ) then
local tools = {
showTool = false
pickaxe=2,
    breakingTimeHeader = '[[Breaking]] time'
axe=2,
end
sword=2,
if args.hideshears or horizontal and not args.shears then
shovel=2,
showShears = false
shears=1,
end
bucket=1,
if args.hidesword or horizontal and not args.sword then
}
showSword = false
end
sortable = not horizontal and args.sort
if sortable then
end
simple = args.simple
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', 'Netherite', '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 = { 'Oak Planks' },
Stone = { 'BlockSprite', 'cobblestone' },
Iron = { 'ItemSprite', 'iron-ingot' },
Diamond = { 'ItemSprite', 'diamond' },
Netherite = { 'ItemSprite', 'netherite-ingot' },
Golden = { 'ItemSprite', 'gold-ingot' },
Shears = { 'ItemSprite', 'shears' },
Sword = { 'ItemSprite', 'wooden-sword' }
}
for _, tool in ipairs( toolColumns ) do
if toolSprites[tool] then
local image, spriteCat = sprite.sprite{
data = 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' )
end
table.insert( tableParts, header )
end
local hardness = require( [[Module:Block value]] ).value
local hardness = args[1] or args.hardness or args.h
local requiredGrade = args[2] or args.material or args.mat or args.grade
local tool1 = args[3] or args.tool or args.tool1 or args.t or args.t1
local tool2 = args[4] or  args.tool2 or args.t2
local function fillCells( cellsTable, text, num )
if not hardness then return '<strong><font color="red">Missing argument #1 (hardness)</font></strong>' end
for i = 1, num do
if (not requiredGrade or not materials[requiredGrade]) and tools[tool1] == 2 then return '<strong><font color="red">Missing argument #2 (required material)</font></strong>' end
table.insert( cellsTable, text )
if not tool1 then return '<strong><font color="red">Missing argument #3 (tool)</font></strong>' end
end
end
local materialGrade = {
Any = 0,
Wooden = 1, Wood = 1,
Golden = 1,
Stone = 2,
Iron = 3,
Diamond = 4,
        Netherite = 5,
None = 6
}
local materialSpeed = {
None = 1,
Any = 1,
Wooden = 2, Wood = 2,
Stone = 4,
Iron = 6,
Diamond = 8,
        Netherite = 9,
Golden = 12
}
local numberMaterials = 6
local function insertBlock( blockArgs )
hardness = tonumber(hardness)
local cells = {}
requiredGrade = requiredGrade:lower()
local blocks = mw.text.split( blockArgs[1], '%s*,%s*' )
tool1 = tool1:lower()
local hardnessVal = tonumber( hardness{ blocks[1], type = 'hardness' } )
if tool2 then tool2 = tool2:lower() end
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 = {
data = 'BlockSprite',
block,
text = blockText,
link = link,
id = id
}
if items[i] == '1' or not items[i] and items[1] == '1' then
blockSpriteArgs.data = 'ItemSprite'
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 fullToolName = ( (not isMaterialSpecified) and 'Wooden ' or '' ) .. toolName
local image, spriteCat = sprite.sprite{
data = 'ItemSprite',
fullToolName,
title = toolName,
link = tool
}
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 have a minimum breaking time of 1 game tick (0.05 seconds)
num = 0.05
else -- And they must be broken in multiples of 1 game tick (0.05 seconds)
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', 'Netherite', '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 table = mw.html.create('table')
local blocksArgs = {}
:tag('tr')
for _, arg in ipairs{ 1, 'note', 'sprite', 'link', 'item', 'drop', 2, 3, 'shears', 'sword' } do
:tag('th'):wikitext('Hardness'):done()
if args[arg] then
:tag('td'):wikitext(hardness):attr{colspan=tool2 and 2 or 1}:done()
local col = 0
:done()
for colVal in mw.text.gsplit( args[arg], '%s*;%s*' ) do
if tool2 then
col = col + 1
table:tag('tr')
if colVal ~= '' then
:tag('th'):wikitext('Tool'):done()
if not blocksArgs[col] then
:tag('td'):wikitext(table.concat{
blocksArgs[col] = {}
'[[File:', tools[tool1] == 2 and ucfirst(requiredGrade) or '', ' ', ucfirst(tool1), '.png|21px|link=w:c:minecraft:', ucfirst(tool1), ']]'
end
}):done()
:tag('td'):wikitext(table.concat{
blocksArgs[col][arg] = colVal
'[[File:', tools[tool2] == 2 and ucfirst(requiredGrade) or '', ' ', ucfirst(tool2), '.png|21px|link=w:c:minecraft:', ucfirst(tool2), ']]'
end
}):done()
end
:done()
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
else
insertBlock( args )
table:tag('tr')
for _, row in ipairs( tableParts ) do
:tag('th'):wikitext('Tool'):done()
table.insert( rows, row )
:tag('td'):wikitext(table.concat{
'[[File:', tools[tool1] == 2 and ucfirst(requiredGrade) or '', ' ', ucfirst(tool1), '.png|21px|link=w:c:minecraft:', ucfirst(tool1), ']]'
}):done()
:done()
end
table:tag('tr')
:tag('th')
:wikitext(mcWikiLink('Breaking')..' time' .. f:preprocess( '<ref group="FN" name="breakingtimenote">Times are for unenchanted tools as wielded by players with no status effects, measured in seconds. For more information, see '..mcWikiLink('Breaking#Speed', 'Breaking § Speed')..'.</ref>' ))
:attr{colspan=tool2 and 3 or 2}
:done()
:done()
for k,v in pairs(materials) do
local reqGradeNum = materials[requiredGrade].grade
local calc = v.speed
calc = calc / hardness
local wasDividedBy30 = false
if v.grade >= reqGradeNum then
calc = calc / 30
wasDividedBy30 = true
else
calc = calc / 100
end
end
end
calc = 1 / calc
table.insert( rows, '' )
calc = math.ceil(calc)
calc = calc / 20
local note = ''
if args.foot or horizontal then
note = f:preprocess( '<references group="FN"/>' )
if args.foot == '2' then
if tool2 then
table.insert( rows, header )
table:tag('tr')
:tag('th'):wikitext(displayItem(v.display)):done()
:tag('td'):wikitext(calc):addClass((v.grade >= reqGradeNum) and 'green' or 'red'):done()
:tag('td'):wikitext(wasDividedBy30 and calc*0.3 or calc):addClass((v.grade >= reqGradeNum) and 'green' or 'red'):done()
:done()
else
table:tag('tr')
:tag('th'):wikitext(displayItem(v.display)):done()
:tag('td'):wikitext(calc):addClass((v.grade >= reqGradeNum) and 'green' or 'red'):done()
:done()
end
end
table.insert( rows, '|}' )
end
end
return tostring(table)
return table.concat( rows, '\n|-\n' ) .. note .. table.concat( categories )
end
end
return p
return p

Revision as of 19:52, 1 May 2021

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

local p = {}

local displayItem = require( [[Module:Item]] ).item
local mcWikiLink = require( [[Module:Link]] ).mcWikiLink

local breakingTimeHeader;
local function getBreakingTimeHeader( f )
    if breakingTimeHeader == nil then
        breakingTimeHeader = '[[Breaking]] time' .. f:preprocess( '<ref group="FN" name="breakingtimenote">Times are for unenchanted tools as wielded by players with no status effects, measured in seconds. For more information, see [[Breaking#Speed|Breaking § Speed]].</ref>' )
    end
    return breakingTimeHeader
end
function ucfirst(s)
	if s == nil then s = "" end
	return s:gsub("(%w)([%w']*)", function(a,b) return string.upper(a)..b end)
end
function p.breaking( f )
	local args = require( [[Module:ProcessArgs]] ).norm()
	
	local materials = {
		any = {grade=0,speed=1,display={nolink=true,item='Default',img='Blank'}},
		wooden = {grade=1,speed=2,display={nolink=true,item='Wooden',img='Oak Planks'}},
		stone = {grade=2,speed=4,display={nolink=true,item='Stone',img='Cobblestone'}},
		iron = {grade=3,speed=6,display={nolink=true,item='Iron',img='Iron Ingot'}},
		diamond = {grade=4,speed=8,display={nolink=true,item='Diamond'}},
        netherite = {grade=5,speed=9,display={nolink=true,item='Netherite',img='Netherite Ingot'}},
		golden = {grade=1,speed=12,display={nolink=true,item='Golden',img='Gold Ingot'}},
	}
	local tools = {
		pickaxe=2,
		axe=2,
		sword=2,
		shovel=2,
		shears=1,
		bucket=1,
	}
	
	local hardness = args[1] or args.hardness or args.h
	local requiredGrade = args[2] or args.material or args.mat or args.grade
	local tool1 = args[3] or args.tool or args.tool1 or args.t or args.t1
	local tool2 = args[4] or  args.tool2 or args.t2
	
	if not hardness then return '<strong><font color="red">Missing argument #1 (hardness)</font></strong>' end
	if (not requiredGrade or not materials[requiredGrade]) and tools[tool1] == 2 then return '<strong><font color="red">Missing argument #2 (required material)</font></strong>' end
	if not tool1 then return '<strong><font color="red">Missing argument #3 (tool)</font></strong>' end
	
	hardness = tonumber(hardness)
	requiredGrade = requiredGrade:lower()
	tool1 = tool1:lower()
	if tool2 then tool2 = tool2:lower() end
	
	local table = mw.html.create('table')
		:tag('tr')
			:tag('th'):wikitext('Hardness'):done()
			:tag('td'):wikitext(hardness):attr{colspan=tool2 and 2 or 1}:done()
		:done()
	if tool2 then
		table:tag('tr')
			:tag('th'):wikitext('Tool'):done()
			:tag('td'):wikitext(table.concat{
				'[[File:', tools[tool1] == 2 and ucfirst(requiredGrade) or '', ' ', ucfirst(tool1), '.png|21px|link=w:c:minecraft:', ucfirst(tool1), ']]'
			}):done()
			:tag('td'):wikitext(table.concat{
				'[[File:', tools[tool2] == 2 and ucfirst(requiredGrade) or '', ' ', ucfirst(tool2), '.png|21px|link=w:c:minecraft:', ucfirst(tool2), ']]'
			}):done()
		:done()
	else
		table:tag('tr')
			:tag('th'):wikitext('Tool'):done()
			:tag('td'):wikitext(table.concat{
				'[[File:', tools[tool1] == 2 and ucfirst(requiredGrade) or '', ' ', ucfirst(tool1), '.png|21px|link=w:c:minecraft:', ucfirst(tool1), ']]'
			}):done()
		:done()
	end
	table:tag('tr')
		:tag('th')
			:wikitext(mcWikiLink('Breaking')..' time' .. f:preprocess( '<ref group="FN" name="breakingtimenote">Times are for unenchanted tools as wielded by players with no status effects, measured in seconds. For more information, see '..mcWikiLink('Breaking#Speed', 'Breaking § Speed')..'.</ref>' ))
			:attr{colspan=tool2 and 3 or 2}
			:done()
	:done()
	for k,v in pairs(materials) do
		local reqGradeNum = materials[requiredGrade].grade
		local calc = v.speed
		calc = calc / hardness
		local wasDividedBy30 = false
		if v.grade >= reqGradeNum then 
			calc = calc / 30
			wasDividedBy30 = true
		else 
			calc = calc / 100
		end
		calc = 1 / calc
		calc = math.ceil(calc)
		calc = calc / 20
		
		if tool2 then
			table:tag('tr')
				:tag('th'):wikitext(displayItem(v.display)):done()
				:tag('td'):wikitext(calc):addClass((v.grade >= reqGradeNum) and 'green' or 'red'):done()
				:tag('td'):wikitext(wasDividedBy30 and calc*0.3 or calc):addClass((v.grade >= reqGradeNum) and 'green' or 'red'):done()
			:done()
		else
			table:tag('tr')
				:tag('th'):wikitext(displayItem(v.display)):done()
				:tag('td'):wikitext(calc):addClass((v.grade >= reqGradeNum) and 'green' or 'red'):done()
			:done()
		end
	end
	return tostring(table)
end
return p