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

Версия от 07:47, 4 августа 2020

-- Экспортируемые функции
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
	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 '21110000'
	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["Ресурс2"] = args["Ресурс2"] or args["Топливо"] or args["топливо"]
	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 = (270 - output_size - input_size - arrow_width) / 2	
	if (input_rows + fluid_input_rows) > 3 or (output_rows + fluid_output_rows) > 3 then
		h_size = 150
	else
		h_size = 128
	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
	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
		v_margin_output = (h_size - 36 * (output_rows + max_fluid_rows)) / 2
	else
		v_margin_input = (h_size - 36 * (input_rows + fluid_input_rows + input_pic)) / (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;'):format(v_margin_input))
		if fluid_input_cols > input_cols then
			item_input:cssText(('margin-left:%spx;'):format((fluid_input_cols - input_cols) * 36))
		end
		
		local param_arg = args["Параметр"]
		for i = 1, input_rows * input_cols do
			local resource_n = args["Ресурс" .. i]
			if resource_n ~= 'none' then
				if 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], class1)
			end
			
			if (input_pic == 1 and i <= input_cols) then
				item_input:wikitext(fuelImg .. '<br>')
			end
		end
		
	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')
			:cssText('text-align:right;')
		if input_pic ~= 1 then
			fluid_input:cssText(('margin-top:%spx;'):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], '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], 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], '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