Moduł:Breaking row

Wersja z dnia 19:02, 27 paź 2025 autorstwa MetroKopUA (dyskusja | edycje)
(różn.) ← poprzednia wersja | przejdź do aktualnej wersji (różn.) | następna wersja → (różn.)
[ utwórz | historia | odśwież ]Dokumentacja
W tym module nie ma dokumentacji. Jeśli wiesz jak używać tego modułu, proszę, podaj odpowiednie informacje.
local p = {}
local polish = mw.language.new('pl')

local breakingTimeHeader;
local function getBreakingTimeHeader( f )
	if breakingTimeHeader == nil then
		breakingTimeHeader = 'Czas wydobycia (sekundy)' .. f:preprocess( '<ref group="FN" name="breakingtimenote">Czasy nie biorą pod uwagę [[Zaklinanie|zaklęć]], [[efekt]]ów i innych czynników, jak np. zanurzenie w wodzie.</ref>' )
	end
	return breakingTimeHeader
end


function p.row( f )
	local args = require( [[Moduł:ProcessArgs]] ).norm()
	
	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 showOptions = false
	
	local horizontal
	if args['horyzontalny'] 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() == 'dowolny' or args[2]:lower() == 'brak' ) then
			showTool = false
			setDplVar( 'hidetool' )
    		breakingTimeHeader = 'Czas wydobycia (sekundy)'
		end
		if args.hideshears or horizontal and not args['nożyce'] then
			showShears = false
			setDplVar( 'hideshears' )
		end
		if args.hidesword or horizontal and not args['miecz'] 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; margin: 0;"' )
		
		local sortType = ''
		if sortable then
			sortType = 'data-sort-type="number"'
		end
		local rowspan = ''
		if not horizontal then
			rowspan = 'rowspan="2" '
		end
		header = {
			'! ' .. rowspan .. ' | Blok'
		}
		
		if not simple then
			table.insert( header, '! ' .. rowspan .. sortType .. ' | Twardość' )
			if showTool then
				table.insert( header, '! ' .. rowspan .. ' | Narzędzie' )
			end
		end
		
		local toolColumns = {}
		if showTool then
			toolColumns = { 'Drewniany', 'Kamienny', 'Miedziany', 'Żelazny', 'Diamentowy', 'Netherytowy', 'Złoty'}
		end
		table.insert( toolColumns, 1, 'Domyślne' )
		
		if not simple then
			if showShears then
				table.insert( toolColumns, 'Nożyce' )
			end
			if showSword then
				table.insert( toolColumns, 'Miecz' )
			end
		end
		
		if not horizontal then
			table.insert( header, '! colspan="' .. #toolColumns .. '" |' .. getBreakingTimeHeader( f ) )
			table.insert( header, '|-' )
		end
		
		local toolSprites = {
			['Drewniany'] = { 'Block', 'dębowe-deski' },
			['Kamienny'] = { 'Block', 'bruk' },
			['Miedziany'] = { 'Item', 'sztabka-miedzi' },
			['Żelazny'] = { 'Item', 'sztabka-żelaza' },
			['Diamentowy'] = { 'Item', 'diament' },
			['Netherytowy'] = { 'Item', 'sztabka-netherytu' },
			['Złoty'] = { 'Item', 'sztabka-złota' },
			['Nożyce'] = { 'Item', 'nożyce' },
			['Miecz'] = { 'Item', 'drewniany-miecz' }
		}
		for _, tool in ipairs( toolColumns ) do
			if toolSprites[tool] then
				local image = f:expandTemplate({title = toolSprites[tool][1]..'Sprite', args = {['1']=toolSprites[tool][2]}}).. ' ' .. 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( [[Moduł: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,
		Copper = 2,
		Iron = 3,
		Diamond = 4,
        Netherite = 5,
		None = 6,
		['Dowolny'] = 0,
		['Drewniany'] = 1, ['Drewniana'] = 1,
		['Złoty'] = 1, ['Złota'] = 1,
		['Kamienny'] = 2, ['Kamienna'] = 2,
		['Miedziany'] = 2, ['Miedziana'] = 2,
		['Żelazny'] = 3, ['Żelazna'] = 3,
		['Diamentowy'] = 4, ['Diamentowa'] = 4,
        ['Netherytowy'] = 5, ['Netherytowa'] = 5,
		['Brak'] = 6
	}
	local materialSpeed = {
		None = 1,
		Any = 1,
		Wooden = 2, Wood = 2,
		Stone = 4,
		Copper = 5,
		Iron = 6,
		Diamond = 8,
        Netherite = 9,
		Golden = 12,
		['Dowolny'] = 1,
		['Drewniany'] = 2, ['Drewnianf'] = 2,
		['Złoty'] = 12, ['Złota'] = 12,
		['Kamienny'] = 4, ['Kamienna'] = 4,
		['Miedziany'] = 5, ['Miedziana'] = 5,
		['Żelazny'] = 6, ['Żelazna'] = 6,
		['Diamentowy'] = 8, ['Diamentowa'] = 8,
        ['Netherytowy'] = 9, ['Netherytowa'] = 9,
		['Brak'] = 1
	}
	local numberMaterials = 6
	
	local function insertBlock( blockArgs, horizontal )
		local cells = {}
		local blocks = mw.text.split( blockArgs[1], '%s*,%s*' )
		local hardnessVal = tonumber( hardness{ blocks[1], type = 'Twardość' } )
		if not hardnessVal then
			hardnessVal = '?'
			local title = mw.title.getCurrentTitle()
			if title.namespace == 0 and not title.isSubpage then
				table.insert(categories, '[[Kategoria:Brakująca twardość]]')
			end
		end
		local unbreakable
		if hardnessVal == -1 or blockArgs.liquid then
			unbreakable = true
		elseif hardnessVal ~= 0 then
			showOptions = 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
			
			if (link == nil or link == '') and horizontal then
				link = 'brak'
			end
			
			local image = f:expandTemplate({title='BlockLink', args = {['1']=block,text=blockText,['2']=link,id=id}})
			table.insert( blockSprites, image )
		end
		table.insert( cells,
			'!' .. (horizontal and '' or ' style="text-align:left" | ') .. table.concat( blockSprites, '<br>' ) .. ( blockArgs.note or '' )
		)
		
		local tool = mw.text.trim( simple and 'Narzędzie' or blockArgs[2] or 'Dowolny' ):gsub( '^%l', string.upper )
		local material = mw.text.trim( simple and blockArgs[2] or blockArgs[3] or 'Dowolny' ):gsub( '^%l', string.upper )
		if tool == 'Brak' then
			material = tool
		end
		if not simple then
			local hardnessText = hardnessVal
			if hardnessVal == -1 then
				hardnessText = ( sortable and 'data-sort-value="9999" | ' or '' ) .. "&#45;1 (infinite)"
			end
			table.insert( cells, '|' .. hardnessText )
			
			if showTool then
				local toolCell = '—'
				if tool ~= 'Dowolny' and tool ~= 'Brak' then
					if material == 'Wood' then
						material = 'Wooden'
					end
					local isMaterialSpecified = (material ~= 'Dowolny') and (material ~= 'Brak')
					local toolName = polish:lc(( isMaterialSpecified and material .. '-' or '' ) .. tool)
					local toolSpriteName = ( (isMaterialSpecified) and '' or '' ) .. toolName
					local image = f:expandTemplate({title='ItemSprite', args = {['1']=toolSpriteName,title=toolName,link=tool,keepcase = not isMaterialSpecified}})
					
					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 = 'Tc', args = { choice, '' } }
			end
			return choices[choice] .. text
		end
		
		local function processTime( actualHardness, baseSpeed, tool )
			-- the number passed in has been multiplied by 100
			local num = actualHardness / baseSpeed
			if num <= 5 then	   -- Blocks with a breaking time <= 1 game tick (0.05 seconds) are 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="9999" ' or '' ) .. getChoice( 'nie', '∞' ) )
				if showTool then
					fillCells( cells, '|—', numberMaterials )
				end
			else
				local drop = 'tak'
				local forceDrop = false
				if blockArgs['łupy'] == '0' then
					drop = 'częściowo'
				elseif blockArgs['łupy'] == '1' then
					forceDrop = 'tak'
				end
				
				local requiredLevel = unbreakable and 999 or materialGrade[material]
				local function insertMaterialCell( material )
					local shouldDrop = drop
					if materialGrade[material] < requiredLevel then
						shouldDrop = 'nie'
					end
					-- prevent float number precision loss, multiply by 100 and divide it in processTime function
					local breakTime = processTime( hardnessVal * (shouldDrop == 'nie' and 500 or 150), materialSpeed[material], 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', 'Copper', '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, 'Nożyce' )
			end
			if showSword then
				table.insert( tools, 'Miecz' )
			end
			if hardnessVal == '?' then
				fillCells( cells, '|?', #tools )
			else
				local toolSpeed = {
					['Nożyce'] = 1,
					['Miecz'] = 1.5
				}
				if blocks[1] == 'Wełna' then
					toolSpeed['Nożyce'] = 5
				elseif blocks[1] == 'Liście' then
					toolSpeed['Nożyce'] = 15
				elseif blocks[1] == 'Pajęczyna' then
					toolSpeed['Miecz'] = 15
					toolSpeed['Nożyce'] = 15
				elseif blocks[1] == 'Bambus' or blocks[1] == 'Pęd bambusu' then
					toolSpeed['Miecz'] = 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 = 'tak'
						if toolDrop == '0' then
							willDrop = 'częściowo'
						end
						-- prevent float number precision loss, multiply by 100 and divide it in processTime function
						local breakTime = processTime( hardnessVal * 150, toolSpeed[tool], 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', 'łupy', 2, 3, 'nożyce', 'miecz' } 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, true )
		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, false )
		for _, row in ipairs( tableParts ) do
			table.insert( rows, row )
		end
		table.insert( rows, '' )
	end
	
	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
	
	local result = table.concat( rows, '\n|-\n' )
	return result .. note .. table.concat( categories )
end
return p