Модуль реализует шаблон
local p = {} local breakingTimeHeader; local function getBreakingTimeHeader( f ) if breakingTimeHeader == nil then breakingTimeHeader = 'Время [[Добывание|разрушения]]' .. f:preprocess( '<ref group="FN" name="breakingtimenote">Время для незачарованных инструментов, используемых игроком без наложенных эффектов, в секундах. Для большей информации см. [[Добывание#Скорость|Добывание § Скорость]].</ref>' ) end return breakingTimeHeader end function p.row( f ) local args = require( [[Модуль:ProcessArgs]] ).norm() local sprite = require( [[Модуль:Спрайт]] ) 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 args[1] = args[1] or '' -- чтобы не переделывать весь модуль, ранее считавший, что тут строка -- Подставляет название страницы, если параметр args[1] не указан. if (args[1] == '') or (args[1] == nil) then args[1] = mw.title.getCurrentTitle().text args["встолбик"] = 1 end if args["встолбик"] 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["скрытьинструмент"] or horizontal and ( not args[2] or args[2]:lower() == 'any' or args[2]:lower() == 'none' ) then showTool = false setDplVar( 'hidetool' ) breakingTimeHeader = 'Время [[Добывание|разрушения]]' end if args["скрытьножницы"] or horizontal and not args["ножницы"] then showShears = false setDplVar( 'hideshears' ) end if args["скрытьмеч"] or horizontal and not args["меч"] then showSword = false setDplVar( 'hidesword' ) end sortable = not horizontal and args["сортировка"] if sortable then setDplVar( 'sortable' ) end simple = args["простой"] 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 .. ' | Блок' } if not simple then table.insert( header, '! ' .. rowspan .. sortType .. ' | Прочность' ) if showTool then table.insert( header, '! ' .. rowspan .. ' | Инструмент' ) end end local toolColumns = {} if showTool then local firstTool = mw.text.trim( simple and 'Инструмент' or args[2] or 'Любой' ):gsub( '^%l', string.upper ) firstTool = mw.text.split( firstTool, ';' )[1] if firstTool == 'Кирка' or firstTool == 'Лопата' or firstTool == 'Мотыга' then toolColumns = { 'Деревянная', 'Каменная', 'Железная', 'Алмазная', 'Незеритовая', 'Золотая' } else toolColumns = { 'Деревянный', 'Каменный', 'Железный', 'Алмазный', 'Незеритовый', 'Золотой' } end end table.insert( toolColumns, 1, 'По умолчанию' ) if not simple then if showShears then table.insert( toolColumns, 'Ножницы' ) end if showSword then table.insert( toolColumns, 'Меч' ) end end if not horizontal then table.insert( header, '! colspan="' .. #toolColumns .. '" |' .. getBreakingTimeHeader( f ) ) table.insert( header, '|-' ) end local toolSprites = { ["Деревянный"] = {'Спрайт/Блок', 'дубовые-доски' }, ["Деревянная"] = {'Спрайт/Блок', 'дубовые-доски' }, ["Каменный"] = { 'Спрайт/Блок', 'булыжник' }, ["Каменная"] = { 'Спрайт/Блок', 'булыжник' }, ["Железный"] = { 'Спрайт/Предмет', 'железный-слиток' }, ["Железная"] = { 'Спрайт/Предмет', 'железный-слиток' }, ["Алмазный"] = { 'Спрайт/Предмет', 'алмаз' }, ["Алмазная"] = { 'Спрайт/Предмет', 'алмаз' }, ["Незеритовый"] = { 'Спрайт/Предмет', 'незеритовый-слиток' }, ["Незеритовая"] = { 'Спрайт/Предмет', 'незеритовый-слиток' }, ["Золотой"] = { 'Спрайт/Предмет', 'золотой-слиток' }, ["Золотая"] = { 'Спрайт/Предмет', 'золотой-слиток' }, ["Ножницы"] = { 'Спрайт/Предмет', 'ножницы' }, ["Меч"] = { 'Спрайт/Предмет', 'деревянный-меч' } } for _, tool in ipairs( toolColumns ) do if toolSprites[tool] then local image, spriteCat = sprite.sprite{ ["данные"] = toolSprites[tool][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( [[Модуль:Значения блоков]] ).value local function fillCells( cellsTable, text, num ) for i = 1, num do table.insert( cellsTable, text ) end end local materialGrade = { ["Любой"] = 0, ["Любая"] = 0, ["Деревянный"] = 1, ["Деревянная"] = 1, ["Золотой"] = 1, ["Золотая"] = 1, ["Каменный"] = 2, ["Каменная"] = 2, ["Железный"] = 3, ["Железная"] = 3, ["Алмазный"] = 4, ["Алмазная"] = 4, ["Незеритовый"] = 5, ["Незеритовая"] = 5, ["Нет"] = 6 } local materialSpeed = { ["Нет"] = 1, ["Любой"] = 1, ["Любая"] = 1, ["Деревянный"] = 2, ["Деревянная"] = 2, ["Каменный"] = 4, ["Каменная"] = 4, ["Железный"] = 6, ["Железная"] = 6, ["Алмазный"] = 8, ["Алмазная"] = 8, ["Незеритовый"] = 9, ["Незеритовая"] = 9, ["Золотой"] = 12, ["Золотая"] = 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], ["тип"] = 'прочности' } ) if not hardnessVal then hardnessVal = '?' local title = mw.title.getCurrentTitle() if title.namespace == 0 and not title.isSubpage then table.insert(categories, '[[Категория:Отсутствующие значения прочности]]') end end local unbreakable if hardnessVal == -1 or blockArgs.liquid then unbreakable = true end local blockSprites = {} local links = mw.text.split( blockArgs["ссылка"] or '', '%s*,%s*' ) local ids = mw.text.split( blockArgs["спрайт"] or '', '%s*,%s*' ) local items = mw.text.split( blockArgs["предмет"] 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["сократить"] then blockText = block:gsub( args["сократить"] .. '$', '' ) else blockText = block end local blockSpriteArgs = { ["данные"] = 'Спрайт/Блок', block, ["текст"] = blockText, ["ссылка"] = link, ["ID"] = id } if items[i] == '1' or not items[i] and items[1] == '1' then blockSpriteArgs["данные"] = 'Спрайт/Предмет' 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["прим"] or '' ) ) local tool = mw.text.trim( simple and 'Инструмент' or blockArgs[2] or 'Любой' ):gsub( '^%l', string.upper ) local material = mw.text.trim( simple and blockArgs[2] or blockArgs[3] or 'Любой' ):gsub( '^%l', string.upper ) if tool == 'Нет' 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 ~= 'Любой' and tool ~= 'Нет' then local isMaterialSpecified = (material ~= 'Любой') and (material ~= 'Нет') local toolName = ( isMaterialSpecified and material .. ' ' or '' ) .. tool if toolName == 'Топор' then wooden = 'Деревянный ' else wooden = 'Деревянная ' end local fullToolName = ( (not isMaterialSpecified) and wooden or '' ) .. toolName local image, spriteCat = sprite.sprite{ ["данные"] = 'Спрайт/Предмет', fullToolName, ["назв"] = toolName, ["ссылка"] = 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 = 'Таблица выбора', args = { choice, ''} } end return choices[choice] .. text end local function processTime( num ) -- переданное число было умножено на 100 if num <= 5 then -- Минимальные временные затраты на разрушение блока равны 1 игровому такту (0,05 секунды) num = 0.05 else -- Блоки должны быть разрушены кратно 1 игровому такту (0,05 секунды) 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 = 'да' local forceDrop = false if blockArgs["дроп"] == '0' then drop = 'частично' elseif blockArgs["дроп"] == '1' then forceDrop = 'да' end local requiredLevel = unbreakable and 999 or materialGrade[material] local function insertMaterialCell( material ) local shouldDrop = drop if materialGrade[material] < requiredLevel then shouldDrop = 'нет' end -- предотвращение потери точности числа с плавающей запятой: умножить его на 100 и разделить в функции "processTime" local breakTime = processTime( hardnessVal * (shouldDrop == 'нет' and 500 or 150) / materialSpeed[material] ) if breakTime == 0.05 then shouldDrop = "запланировано" end table.insert( cells, '|' .. getChoice( forceDrop or shouldDrop, breakTime ) ) end if not showTool or tool == 'Любой' or tool == 'Нет' then insertMaterialCell( 'Любой' ) if showTool then fillCells( cells, '|—', numberMaterials ) end else for _, material in ipairs{ 'Любой', 'Деревянный', 'Каменный', 'Железный', 'Алмазный', 'Незеритовый', 'Золотой' } do insertMaterialCell( material ) end end end end if not simple and ( showShears or showSword ) then local tools = {} if showShears then table.insert( tools, 'Ножницы' ) end if showSword then table.insert( tools, 'Меч' ) end if hardnessVal == '?' then fillCells( cells, '|?', #tools ) else local toolSpeed = { ["Ножницы"] = 1, ["Меч"] = 1.5 } if blocks[1] == 'Шерсть' then toolSpeed["Ножницы"] = 5 elseif blocks[1] == 'Листва' then toolSpeed["Ножницы"] = 15 elseif blocks[1] == 'Паутина' then toolSpeed["Меч"] = 15 toolSpeed["Ножницы"] = 15 elseif blocks[1] == 'Бамбук' then toolSpeed["Меч"] = 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 = 'да' if toolDrop == '0' then willDrop = 'частично' end -- предотвращение потери точности числа с плавающей запятой: умножить его на 100 и разделить в функции "processTime" local breakTime = processTime( hardnessVal * 150 / toolSpeed[tool] ) if breakTime == 0.05 then willDrop = "запланировано" end 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, 'прим', 'спрайт', 'ссылка', 'предмет', 'дроп', 2, 3, 'ножницы', 'меч' } 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 -- Вставка заголовка времени разрушения после строки блока при "simple", или после строки инструмента или твердости, если "simple" не используется 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["подвал"] or horizontal then note = f:preprocess( '<references group="FN"/>' ) if args["подвал"] == '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