Перейти к содержанию

Модуль:Интерфейс

Материал из LemonCraft Wiki

Для документации этого модуля может быть создана страница Модуль:Интерфейс/doc

----------------------------------------------------------------------------------------------------
-- Модуль для отображения окон интерфейса (крафта, обжига, варки...) на страницах Minecraft Wiki.
----------------------------------------------------------------------------------------------------

-- Внутренние функции
local slot = require('Модуль:Инвентарный слот').slot
local addSlot = function( args, item, prefix, class, default )
	local none, nostacksize
	prefix = prefix or ''
	if #prefix == 0 then
		none = 'нет'
		nostacksize = ((item == '' or nil) and '') or (args and args[item] and args[item]:gsub( '[,%d]', '' ) or '')
	end
	return slot{
		nostacksize or args[item], ["мод"] = args["мод"] or args["Мод"], ["ссылка"] = none or args[prefix .. 'Ссылка'],
		["назв"] = none or args[prefix .. 'Назв'], ["класс"] = class, ["умолчание"] = default,
		["обработанный"] = args["обработанный"]
	}
end
local templateStyles = require("Модуль:TemplateStyles")

-- Экспортируемые функции
local p = { addSlot = addSlot }

-- Верстак (крафт)
function p.craftingTable( f )
	local args = f
	if f == mw.getCurrentFrame() then
		args = f:getParent().args
	else
		f = mw.getCurrentFrame()
	end
	
	-- Примерная схема интерфейса:
	-- A1 B1 C1      🔀
	-- A2 B2 C2 -> Выход
	-- A3 B3 C3
	
	-- Основной элемент
	local body = mw.html.create('div'):addClass('mcui mcui-Crafting_Table')
	
	-- Контейнер с основным содержимым: ингредиентами, стрелкой и выходом
	local container = body:tag('div'):addClass('mcui-Crafting_Table-container')
	
	-- Вход (ингредиенты)
	local input = container:tag('span'):addClass('mcui-input')
	for num = 1, 3 do
		input:tag('span'):addClass('mcui-row'):wikitext(
			addSlot(args, 'A' .. num, 'A' .. num),
			addSlot(args, 'B' .. num, 'B' .. num),
			addSlot(args, 'C' .. num, 'C' .. num)
		)
	end
	
	-- Стрелка
	local arrow = "Arrow (small)"
	if args["Стрелка"] or '' ~= '' then
		arrow = args["Стрелка"]
		if args["мод"] or args["Мод"] then
			arrow = arrow .. " (" .. args["мод"] or args["Мод"] .. ")"
		end
	end
	container:wikitext("[[Файл:Grid layout " .. arrow .. ".png|class=mcui-arrow|link=|alt=→]]")
	
	-- Слот с результатом
	container:wikitext( addSlot( args, 'Выход', 'В', 'mcui-output invslot-large' ) )
	
	-- Иконки-подсказки для особых форматов рецептов.
	-- Они размещаются по абсолютным координатам и добавляются к body.
	local shapeless = args["бесформенный"] or ''
	local fixed = args["фиксированный"] or ''
	if shapeless ~= '' or fixed ~= '' then
		local class, icon, desc
		if shapeless ~= '' then
			class = "mcui-shapeless"
			icon = "Grid layout Shapeless.png" -- 🔀
			desc = "бесформенный, ресурсы могут располагаться в сетке верстака в любом порядке"
		elseif fixed ~= '' then
			class = "mcui-fixed"
			icon = "Grid layout Fixed.png" -- !
			desc = "фиксированный, его ингредиенты не могут быть перемещены или зеркально отражены"
			if args["нефиксировано"] or '' ~= '' then
				desc = desc .. ", за исключением " .. args["нефиксировано"]
			end
		end
		container:wikitext("[[Файл:" .. icon .. "|class=mcui-icons " .. class .. "|link=|Этот рецепт " .. desc .. ".]]")
	end
	
	-- Обёртка
	local wrapper = mw.html.create("div"):wikitext(templateStyles.load("Верстак/styles.css"))
	return tostring(wrapper:node(body))
end

-- Варочная стойка (варка)
function p.brewingStand( f )
	local args = f
	if f == mw.getCurrentFrame() then
		args = f:getParent().args
	else
		f = mw.getCurrentFrame()
	end
	
	local body = mw.html.create( 'span' ):addClass( 'mcui mcui-Brewing_Stand' )
	local input = body:tag( 'span' ):addClass( 'mcui-input' )
	local inactive = ( args["Ресурс"] or '' ) == '' or
		( ( args["Выход1"] or '' ) == '' and ( args["Выход2"] or '' ) == '' and ( args["Выход3"] or '' ) == '' )

    if not inactive then
        local fuelslot = 'Огненный порошок'
        input:wikitext( slot{ fuelslot } )
    else
        input:wikitext( slot{ ["умолчание"] = 'brewing-blaze-empty' } )
    end

	input:tag( 'span' ):addClass( 'mcui-blaze' ):tag( 'br' )
	input:tag( 'span' ):addClass( 'mcui-bubbling' ):tag( 'br' )
	input:wikitext( addSlot( args, 'Ресурс', 'Р' ) )
	input:tag( 'span' ):addClass( 'mcui-arrow' ):tag( 'br' )
	if inactive
	then
		input:addClass( 'mcui-inactive' )
    end
	
	body:tag( 'span' ):addClass( 'mcui-paths' ):tag( 'br' )
	
	local output = body:tag( 'span' ):addClass( 'mcui-output' )
	for i = 1, 3 do
		output:wikitext( addSlot( args, 'Выход' .. i, 'В' .. i, 'mcui-output' .. i ) )
	end
	
	return tostring( mw.html.create( 'div' ):node( body ) )
end

-- Наковальня (починка, объединение, наложение чар)
-- Используются стили, размещённые в [[Шаблон:Наковальня/styles.css]]
function p.anvil(f)
	-- Аргументы
	local args = f
	if f == mw.getCurrentFrame() then
		args = f:getParent().args
	else
		f = mw.getCurrentFrame()
	end
	local crossed = mw.text.trim(args["недопустимо"] or '')
	local expensive = mw.text.trim(args["дорого"] or '')
	local cost = mw.text.trim(args["Опыт"] or '')
	
	-- Сборка
	local body = mw.html.create("div"):addClass("mcui mcui-Anvil")
	
	-- Заглавие
	local heading = body:tag("div"):addClass("mcui-Anvil-heading")
	
	-- Декоративное изображение молота: [[Файл:Anvil Hammer.png]]
	heading:wikitext("[[Файл:Anvil Hammer.png|60x60px|link=|alt=|class=mcui-Anvil-hammer]]")
	
	-- Поле названия
	local inputbox = heading:tag("span"):addClass("mcui-Anvil-inputbox")
	local title = mw.text.trim(args["назв"] or args["Вход1"] or '')
	if title ~= '' then
		local inputtext = require([[Модуль:Анимация]]).text{title}:gsub('class="animated"', 'class="mcui-Anvil-inputtext animated"')
		inputbox:wikitext(inputtext)
	else
		inputbox:addClass("mcui-inactive"):tag("br")
	end
	
	-- Какая будет стрелка?
	local anvilArrow = "[[Файл:Grid layout Furnace Progress (in-active).png|class=mcui-arrow|link=|alt=→]]"
	if crossed ~= '' or expensive ~= '' then
		-- Скрещённая стрелка (недопустимое сочетание или слишком высокая цена)
		anvilArrow = "[[Файл:Grid layout Anvil crossed.png|class=mcui-arrow|link=|alt=↛]]"
	end
	
	-- Строка со слотами
	body:tag("div"):addClass("mcui-Anvil-slots"):wikitext(
		addSlot(args, "Вход1", "Р1"),                           -- первый вход
		"[[Файл:Anvil Plus.png|class=mcui-plus|link=|alt=+]]",  -- +
		addSlot(args, "Вход2", "Р2"),                           -- второй вход
		anvilArrow,                                             -- →
		addSlot(args, "Выход", "В")                             -- результат
	)
	
	-- Строка стоимости
	if cost ~= '' or expensive ~= '' then
		local costDisplay = body:tag("span"):addClass("mcui-Anvil-cost")
		if expensive ~= '' then
			costDisplay:addClass("mcui-Anvil-cost-expensive")
		end
		
		if cost ~= '' then
			costDisplay:wikitext("Стоимость: " .. cost)
		else -- expensive ~= ''
			costDisplay:wikitext("Слишком дорого!")
		end
	end
	
	-- Обёртка
	local wrapper = mw.html.create("div"):wikitext(templateStyles.load("Наковальня/styles.css"))
	return tostring(wrapper:node(body))
end

-- Камнерез
-- Используются стили, размещённые в [[Шаблон:Камнерез/styles.css]]
function p.stonecutter(f)
	-- Аргументы
	local args = f
	if f == mw.getCurrentFrame() then
		args = f:getParent().args
	else
		f = mw.getCurrentFrame()
	end
	
	-- Сборка
	local body = mw.html.create("span"):addClass("mcui mcui-Stonecutter")
	
	-- Вход
	body:tag("span"):addClass("mcui-input"):wikitext(addSlot(args, "Вход", "Р"))
	
	-- Стрелка
	body:tag("span"):addClass("mcui-arrow"):wikitext(addSlot(args, "Выход", "", "invslot-plain"))
	
	-- Выход
	body:tag("span"):addClass("mcui-output"):wikitext(addSlot(args, "Выход", "В", "invslot-large"))
	
	-- Обёртка
	local wrapper = mw.html.create("div"):wikitext(templateStyles.load("Камнерез/styles.css"))
	return tostring(wrapper:node(body))
end

-- Кузнечный стол
-- Используются стили, размещённые в [[Шаблон:Кузнечный стол/styles.css]]
function p.smithingTable(f)
	-- Аргументы
	local args = f
	if f == mw.getCurrentFrame() then
		args = f:getParent().args
	else
		f = mw.getCurrentFrame()
	end
	
	-- Сборка
	local body = mw.html.create("span"):addClass("mcui mcui-Smithing_Table")
	local container = body:tag("span"):addClass("mcui-Smithing_Table-container")
	
	-- Шапка
	local heading = container:tag("span"):addClass("mcui-Smithing_Table-heading")
	heading:wikitext("[[Файл:Smithing Table Hammer.png|link=|alt=]]")
	heading:tag("span"):addClass("mcui-Smithing_Table-prompt"):wikitext("Улучшение")
	
	-- Содержимое
	local contents = container:tag("span"):addClass("mcui-Smithing_Table-slots")
	
	-- Входы
	contents:tag("span"):addClass("mcui-input"):wikitext(
		addSlot(args, "Вход1", "Р1"),
	    addSlot(args, "Вход2", "Р2"),
	    addSlot(args, "Вход3", "Р3")
	)
	
	-- Стрелка
	contents:wikitext("[[Файл:Grid layout Furnace Progress (in-active).png|class=mcui-arrow|link=|alt=→]]")
	
	-- Выход
	contents:tag("span"):addClass("mcui-output"):wikitext(addSlot(args, "Выход", "В"))
	
	-- Обёртка
	local wrapper = mw.html.create("div"):wikitext(templateStyles.load("Кузнечный стол/styles.css"))
	return tostring(wrapper:node(body))
end

-- Контейнер с возможным текстом-заглавием
function p.container(f)
	-- Аргументы
	local args = f
	if f == mw.getCurrentFrame() then 
		args = require('Модуль:ProcessArgs').merge(true)
	else
		f = mw.getCurrentFrame()
	end
	
	local title = args["заглавие"] or ''
	local body = mw.html.create("div"):addClass("mcui mcui-Container")
	local mod = args["мод"] or args["Мод"]
	
	-- Заглавие
	if title ~= '' then
		body:tag("div"):addClass("mcui-title"):wikitext(title)
	end
	
	-- Содержимое
	local content = body:tag("div"):addClass("mcui-contents")
	
	-- Добавление слотов (с учётом пропусков)
	local last_filled_slot = table.maxn(args)
	local i = 0
	repeat
		local row = content:tag("div"):addClass("mcui-row")
		for j = 1, 9 do
			local arg = args[i + j]
			row:wikitext(arg and slot{arg, ["мод"] = mod} or slot{})
		end
		i = i + 9
	until i >= last_filled_slot
	
	-- Обёртка
	local wrapper = mw.html.create("div")
	wrapper:css{ float = args["расположение"], clear = args["расположение"] }:cssText(args["стиль"])
	return tostring(wrapper:node(body))
end

return p