Модуль:ТестОбработка

-- Экспортируемые функции local p = {} -- Внутренние функции local h = {} ---- Локальные переменные модуля local slot = require('Модуль:Инвентарный слот').slot local baseSprite = require('Модуль:Спрайт').base -- Параметры машины local versions = { ["GregTech 4"] = 'GregTech 4', ["gt4"] = 'GregTech 4', ["GT4"] = 'GregTech 4', ["GregTech 5"] = 'GregTech 5', ["gt5"] = 'GregTech 5', ["GT5"] = 'GregTech 5', ["GregTech 5 Unofficial"] = 'GregTech 5 Unofficial', ["gt5u"] = 'GregTech 5 Unofficial', ["GT5U"] = 'GregTech 5 Unofficial', ["GregTech 6"] = 'GregTech 6', ["gt6"] = 'GregTech 6', ["GT6"] = 'GregTech 6', ["IndustrialCraft 2"] = 'IndustrialCraft 2', ["ic2"] = 'IndustrialCraft 2', ["IC2"] = 'IndustrialCraft 2', '&4Неизвестна', } ---- Локальные функции модуля -- Быстрее mw.text.trim, но не может обработать юникодные пробелы. function h.fast_trim(str) return (str:gsub("^%s+", ""):gsub("%s+$", "")) end -- Должна быть быстрее mw.text.split. -- Адаптировано отсюда: https://help.gamepedia.com/Extension:Scribunto#mw.text.split_is_very_slow function h.split_on_semi(str) local parts = {} local start_index = 1 local num_parts = 1 local split_start, split_end = str:find(';', start_index, true) while split_start do parts[num_parts] = h.fast_trim(str:sub(start_index, split_start - 1)) start_index = split_end + 1 split_start, split_end = str:find(';', start_index, true) num_parts = num_parts + 1 end parts[num_parts] = h.fast_trim(str:sub(start_index)) return ipairs(parts) end -- Добавление слота function h.addSlot(where, item, mod, Back_ID, class, style) where:wikitext(slot{ item, ["мод"] = mod, ["класс"] = class, ["Фон ИД"] = Back_ID, ["стиль"] = style }) end -- Анимирование текста function h.animate(txt) if not txt:find(';', 1, true) then return txt end local result = {'<span class="animated">'} local index = 2 for _, text in h.split_on_semi(txt) do if text ~= '' then result[index] = '<span>' result[index + 1] = text result[index + 2] = '</span>' index = index + 3 end end result[index] = '</span>' if index > 2 then result[2] = '<span class="active">' end return table.concat( result ) end -- Конструктор текста с подсказкой function h.help_string(HTitle, HText) return mw.html.create('span') :cssText("border-bottom:1px dotted;cursor: help;") :attr('title', HText) :wikitext(HTitle) end function h.splitOnSemi1(arg, format) if not arg then return {} end local result = {} for _, text in h.split_on_semi(arg) do if text ~= '' then table.insert( result, format:format(text) ) end end return result end p.interface = function(f) local args = f if f == mw.getCurrentFrame() then args = f:getParent().args else f = mw.getCurrentFrame() end -- Контейнер интерфейса local body = mw.html.create('div') local recipe = body:tag('span'):addClass('gui-recipe') -------------------------------------- Используемые функции --------------------------------------- -- Конструктор строк потребления local h_size, EStrings local EString = function(EBody_Title, EBody_Help, arg, EBody_Unit) if not arg then return end EStrings = EStrings or body:tag('div'):addClass('gui-energy-lines') h_size = h_size + 22 return EStrings :tag('div') :node(h.help_string(EBody_Title, EBody_Help)) :wikitext(' ', h.animate(arg), ' ', EBody_Unit) end local progress = args["Прогресс"] local machine_list = {} local machine = {} local furnace_like = true local class2 = 'invslot-large' if progress then version = args["Версия"] or mw.ustring.match(progress, ':%s*([a-zA-Zа-яА-ЯёЁ 0-9]+)') or args["Мод"] progress = mw.ustring.match(progress, '([a-zA-Zа-яА-ЯёЁ 0-9]+):') or progress if version then if versions[version] then version = versions[version] machine_list = mw.loadData('Модуль:ТестОбработка/' .. version) machine = machine_list[progress] furnace_like = false class2 = machine["Out_class"] or '' end else version = versions[1] body:wikitext('[[Категория:Страницы с неизвестной версией машин]]') end else machine = { ["Image"] = "[[Файл:Layout_fire.png|link=|36px|class=pixel-image]]", ["Def_args"] = {["Топливо"] = "v:Любое топливо"} } progress = 'Печь' end if furnace_like then machine['fuel_input'] = 1 end local mod = args["Мод"] or machine_list['def_mod'] local back_ids = machine.slot_back or {} -- Предопределённые аргументы for k, v in pairs(machine["Def_args"] or {}) do args[k] = args[k] or v end -- Конфигурация ячеек local byte_zero = ('0'):byte() local machine_code = args["Машина"] or machine[1] or '11110000' local input_rows, input_cols, output_rows, output_cols, fluid_input_rows, fluid_input_cols, fluid_output_rows, fluid_output_cols = machine_code:byte(1, 8) input_rows = input_rows - byte_zero input_cols = input_cols - byte_zero output_rows = output_rows - byte_zero output_cols = output_cols - byte_zero fluid_input_rows = fluid_input_rows - byte_zero fluid_input_cols = fluid_input_cols - byte_zero fluid_output_rows = fluid_output_rows - byte_zero fluid_output_cols = fluid_output_cols - byte_zero -- Определитель стиля local class1 = '' local large = (class2 == 'invslot-large') and 16 or 0 local style = machine_list["Skin"] or 'craft-gui' if machine["Skin"] then style = style .. '-' .. machine["Skin"] class1 = machine["Skin"] .. '_invslot' end -- Иконка реакции local input_pic = 1 local machine_image = machine["Image"] local machine_list_image = machine_list["Image"] local expense_arg = args["Расход"] if (machine_list_image or machine_image) and machine_image ~= 'None' then fuelImg = machine_image or machine_list_image elseif expense_arg then fuelImg = '[[Файл:Grid layout ' ..expense_arg .. ' (' .. version .. ').png|link=]]' else input_pic = 0 end -- Переопределение количества получаемых предметов (1-4) local levelArg = args["Уровень"] if levelArg then output_rows = math.floor(levelArg / 4) + 1 output_cols = levelArg / output_rows end -- Предопределение или конвертация некоторых аргументов args["Шанс1"] = args["Шанс1"] or args["Шанс"] args["Ресурс1"] = args["Ресурс1"] or args["Ресурс"] or args[1] args["Выход1"] = args["Выход1"] or args["Выход"] or args[2] args["Опыт"] = args["Опыт"] or args[3] args["РесурсЖ1"] = args["РесурсЖ1"] or args["РесурсЖ"] args["РЖК1"] = args["РЖК1"] or args["РЖК"] args["РЖТ1"] = args["РЖТ1"] or args["РЖТ"] args["ВыходЖ1"] = args["ВыходЖ1"] or args["ВыходЖ"] args["ВЖК1"] = args["ВЖК1"] or args["ВЖК"] args["ВЖТ1"] = args["ВЖТ1"] or args["ВЖТ"] if args["Выход7"] and progress == 'Просеиватель' and version == 'GregTech 6' then args["Шанс1"] = '0.01' args["Шанс2"] = '01' args["Шанс3"] = '04' args["Шанс4"] = '15' args["Шанс5"] = '20' args["Шанс6"] = '40' args["Шанс7"] = '50' end -- Параметры стрелки прогресса local param = machine_list['Параметры'] or { ['sprite_size'] = 140, ['scale'] = 2, ["default_ID"] = 1, ["arrow_width"] = 28, ["arrow_height"] = 24 } local size = param['arrow_width']-- ширина спрайта в пикселях local v_size = param['arrow_height']-- высота спрайта в пикселях local pos = (machine['arrow_ID'] or param["default_ID"]) - 1 -- положение спрайта в таблице local sheetWidth = param['sprite_size'] -- ширина таблицы спрайта в пикселях local tiles = sheetWidth / size -- количество спрайтов в одной строке local left = pos % tiles * size -- горизонтальная координата спрайта  local top = math.floor(pos / tiles) * v_size -- вертикальная координата спрайта local scale = param['scale'] -- масштаб спрайта (во сколько раз увеличить или уменьшить размер) local arrow_width = (machine['arrow_width'] or size) * scale-- ширина спрайта с учётом масштаба local arrow_height = (machine['arrow_height'] or v_size) * scale-- высота спрайта с учётом масштаба -- Размеры и отступы шаблона input_size = math.max(input_cols, fluid_input_cols) * 36 output_size = math.max(output_cols, fluid_output_cols) * (36 + large) local h_margin = (272 - output_size - input_size - arrow_width) / 2 if (input_rows + fluid_input_rows) > 3 or (output_rows + fluid_output_rows) > 3 then h_size = 152 else h_size = 130 end recipe:cssText(("margin:0 %spx;height:%spx;display:inline-flex;"):format( math.floor(0.75 * h_margin), h_size )) local v_margin_input, v_margin_output local fuel_row = machine['fuel_input'] or 0 if ( fluid_input_rows * fluid_output_rows * input_rows * output_rows ) > 0 then local max_fluid_rows = math.max(fluid_output_rows,fluid_input_rows) v_margin_input = (h_size - 36 * (input_rows + max_fluid_rows)) / 2 - 1 v_margin_output = (h_size - 36 * (output_rows + max_fluid_rows)) / 2 - 1 else v_margin_input = (h_size - 36 * (input_rows + fluid_input_rows + input_pic + fuel_row)) / (3 - 0 ^ input_rows - 0 ^ fluid_input_rows) v_margin_output = (h_size - (36 + large) * (output_rows + fluid_output_rows)) / (3 - 0 ^ output_rows - 0 ^ fluid_output_rows) end ------------------------------------------ Ячейки ресурсов ---------------------------------------- local input = recipe:tag('span'):addClass('gt-input') input:cssText(('width:%spx;'):format(input_size)) if input_rows > 0 then local item_input = input :tag('div') :cssText(('margin-top:%spx;text-align:right;'):format(v_margin_input)) local param_arg = args["Параметр"] for i = 1, input_rows * input_cols do local resource_n = args["Ресурс" .. i] if resource_n and param_arg and resource_n:find('Интегральная схема') then resource_n = resource_n .. "[&7 Параметр: " .. param_arg .. "/]" end h.addSlot(item_input, resource_n, mod, back_ids['in' .. i] or back_ids['in'], class1) if input_pic == 1 and fuel_row == 0 and i == input_rows * input_cols then input:wikitext(fuelImg) end end end if fuel_row > 0 then input:wikitext(fuelImg .. '<br>') fuel = args['Топливо'] or args['топливо'] or args['Ресурс' .. input_rows * input_cols + 1] h.addSlot(input, fuel, mod, back_ids['fuel'], class1) end if progress == 'Режущий механизм' then h.addSlot(input, args['Диск'], mod, nil, 'invslot-plain', 'position:absolute; top:55px; left:116px') end if machine["Mid_input"] then h.addSlot(input, args['РесурсЦ'], mod, back_ids['mid'], '', 'position:absolute; top:96px; left:' .. 6 + h_margin + input_size + (arrow_width - 36) / 2 .. 'px') end -------------------------------------- Ячейки жидких ресурсов ------------------------------------- if fluid_input_rows > 0 then local fluid_input = input :tag('div') if input_pic ~= 1 then fluid_input:cssText(('margin-top:%spx;text-align:right;'):format(v_margin_input)) end for i = 1, fluid_input_rows * fluid_input_cols do local resource_num = args["РесурсЖ" .. i] if resource_num then local fl_quantity = h.splitOnSemi1(args["РЖК" .. i], '/&9 Объём: %s мВ/') local fl_temp = h.splitOnSemi1(args["РЖТ" .. i], '&c Температура: %s К/') local default_quantity = fl_quantity[1] or '' local default_temp = fl_temp[1] or '' local fl_split = {} local c = 0 if fl_quantity[1] or fl_temp[1] then for _, text in h.split_on_semi(resource_num) do if text ~= '' then c = c + 1 text = text .. '[' .. (fl_quantity[c] or default_quantity) .. (fl_temp[c] or default_temp) .. ']' end table.insert( fl_split, text ) end resource_num = table.concat(fl_split, ';') end end h.addSlot(fluid_input, resource_num, mod, back_ids['fl_in' .. i] or back_ids['fl_in'], 'fluid_invslot') end end ---------------------------------------- Стрелка прогресса ---------------------------------------- local arrowtext = '&3' .. progress if machine[2] then arrowtext = arrowtext .. '/&9' .. machine[2] --англ. название end if version then arrowtext = arrowtext .. '//&7Модификация:/' .. version end local arrow = recipe :tag('span') :addClass('minetip') :attr('data-minetip-title','Обработчик:') :attr('data-minetip-text', arrowtext) :cssText(('margin:auto %spx;'):format(math.floor(0.25 * h_margin))) if not furnace_like then arrow:wikitext('[[' .. version .. '/' .. progress .. '|') :tag('span') :addClass('sprite arrow-' .. machine_list["Arrows"]) :cssText(("height:%spx;width:%spx;background-position:-%spx -%spx;background-size:%spx auto;"):format( arrow_height, arrow_width, left * scale, top * scale, sheetWidth * scale )) :done() :wikitext(']]') else if progress ~= 'Печь' and mod then arrow:wikitext('[[Файл:Grid layout ' .. progress .. ' Progress (' .. mod .. ').png|link=' .. mod .. '/' .. progress .. ']]') else arrow:wikitext('[[Файл:Grid_layout_Furnace_Progress.png|link=Печь]]') end arrow:cssText(('width:%spx'):format(arrow_width)) end local modeArg = args["Режим"] if progress == 'Формовщик металла' and modeArg then local mode = recipe :tag('div') :addClass('minetip') :cssText('position:absolute;top:86px;left:113px;') :attr('data-minetip-title', 'Режим: ' .. modeArg) :wikitext('[[Файл:Формовщик металла_(' .. modeArg .. ')_(IndustrialCraft 2).png|link=]]') end ----------------------------------------- Ячейки продуктов ---------------------------------------- local output = recipe :tag('span') :addClass('gt-output') :cssText(('width:%spx;'):format(output_size)) if output_rows > 0 then local item_output = output :tag('div') :cssText(('margin-top:%spx;'):format(v_margin_output)) for i = 1, output_rows * output_cols do local chance_num = args["Шанс" .. i] local output_num = args["Выход" .. i] if chance_num then local pr_chance = h.splitOnSemi1(chance_num, '[&7 Шанс получения: %s%%/]') local default_chance = pr_chance[1] or '' local pr_split = {} local c = 0 for _, text in h.split_on_semi(output_num) do if text ~= '' then c = c + 1 text = text .. (pr_chance[c] or default_chance) end table.insert(pr_split, text) end output_num = table.concat(pr_split, ';') end h.addSlot(item_output, output_num, mod, back_ids['out' .. i] or back_ids['out'], class1 .. ' ' .. class2) end end -- Строка текста под получаемыми ресурсами local arg_t = args["Температура"] local arg_exp = args["Опыт"] if arg_t or arg_exp then local margin_out_2 = output :tag('div') :cssText('margin-top:6px;') if arg_t then margin_out_2 :node(h.help_string(h.animate(arg_t) .. ' К', 'Необходимая температура печи в кельвинах.')) elseif arg_exp then margin_out_2 :cssText('font-family:Minecraft-ru, sans-serif;') :wikitext(baseSprite{ ['изобр'] = 'Сферы_опыта.png', ['выравн'] = 'text-bottom' }) :node(h.help_string(h.animate(arg_exp), 'Дробная часть показывает вероятность получения единицы опыта.')) end end -------------------------------------- Ячейки жидких продуктов ------------------------------------ if fluid_output_rows > 0 then local fluid_output = output :tag('div') :cssText(('margin-top:%spx;text-align:left;'):format(v_margin_output)) for i = 1, fluid_output_rows * fluid_output_cols do local output_num = args["ВыходЖ" .. i] if output_num then local fl_quantity = h.splitOnSemi1(args["ВЖК" .. i], '/&9 Объём: %s мВ/') local fl_temp = h.splitOnSemi1(args["ВЖТ" .. i], '&c Температура: %s К/') local default_quantity = fl_quantity[1] or '' local default_temp = fl_temp[1] or '' local fl_split = {} local c = 0 if fl_quantity[1] or fl_temp[1] then for _, text in h.split_on_semi(output_num) do if text ~= '' then c = c + 1 text = text .. '[' .. (fl_quantity[c] or default_quantity) .. (fl_temp[c] or default_temp) .. ']' end table.insert(fl_split, text) end output_num = table.concat(fl_split, ';') end end h.addSlot(fluid_output, output_num, mod, back_ids['fl_out' .. i] or back_ids['fl_out'], 'fluid_invslot') end end ---------------------------------------- Строки потребления --------------------------------------- local steam_estring = EString ('Пар:' , 'Объём пара, требующийся для проведения операции.' , args["Пар"]) if steam_estring then steam_estring:node(h.help_string('мВ', 'Милливедро (мВ) — единица объёма условно равная 1/1000 части ведра.')) end EString ('Старт:' , 'Энергия, требующаяся на запуск процесса.' , args["Старт"], '[[IndustrialCraft_2|еЭ]]') EString ('Энергия:' , 'Энергия, затрачиваемая на каждую операцию.' , args["Энергия"], '[[IndustrialCraft_2|еЭ]]') EString ('Потребление:' , 'Скорость потребления энергии.' , args["Потребление"], '[[IndustrialCraft_2|еЭ]]/[[Такт|т]]') EString ('Напряжение:' , 'Требуемое для операции напряжение.' , args["Напряжение"], '[[IndustrialCraft_2|еЭ]]/[[Такт|т]]') EString ('Сила тока:' , 'Требуемая для операции сила тока.' , args["Сила тока"]) EString ('Время:' , 'Время, затрачиваемое на операцию.' , args["Время"], 'сек.') --------------------------------------------------------------------------------------------------- if machine_list["Logo"] and not machine["Logo"] then local GTlogo = body :tag('div') :addClass('gt-pic') :addClass('gt-' .. (machine["Skin"] or machine_list["Logo"]) .. '-pic') end if h_size > 140 then body:cssText(('height:%spx'):format(h_size)) end body:addClass('gui-set ' .. style .. ' gui') return tostring(body) end return p 
В данной статье используются материалы из статьи «Модуль:ТестОбработка» с вики-сайта Minecraft Wiki, расположенного на Фэндоме, и они распространяются согласно лицензии Creative Commons Attribution-NonCommercial-ShareAlike 3.0. Авторы статьи.