Модуль:Крафт: различия между версиями
Внешний вид
Spark108 (обсуждение | вклад) Новая страница: «---------------------------------------------------------------------------------- --- Модуль для создания таблиц с рецептами для крафта. --- ВНИМАНИЕ: Изменения на этом модуле отразятся на большом количестве статей! ---------------------------------------------------------------------------------- local p = {} --- Интернационализация...» |
Spark108 (обсуждение | вклад) м 1 версия импортирована |
(нет различий)
|
Текущая версия от 10:40, 26 марта 2025
Для документации этого модуля может быть создана страница Модуль:Крафт/doc
----------------------------------------------------------------------------------
--- Модуль для создания таблиц с рецептами для крафта.
--- ВНИМАНИЕ: Изменения на этом модуле отразятся на большом количестве статей!
----------------------------------------------------------------------------------
local p = {}
--- Интернационализация и локализация
local i18n = {
-- Зависимости
moduleArgs = [[Модуль:ProcessArgs]],
moduleSlot = [[Модуль:Инвентарный слот]],
moduleRecipe = [[Модуль:Таблица рецептов]],
jsonMergeRules = [[Модуль:Крафт/Правила группировки.json]],
-- Параметры процесса
type = "крафт",
typeGenitive = "крафта",
-- Форматы категорий
categoryRecipeType = "[[Категория:Рецепты/$1]]",
-- В оригинале название следующей категории имеет формат «Recipe using
-- <предмет>». Прямо переводится эта конструкция как «Рецепт, использующий
-- <предмет>». При этом название предмета должно было быть в винительном
-- падеже, но на данный момент быстро склонять название предметов в имени-
-- тельном падеже с помощью модулей не представляется возможным. Поэтому в
-- качестве перевода используется близкая по смыслу конструкция, не тре-
-- бующая склонения.
categoryIngredientUsage = "[[Категория:$1 как ингредиент для крафта]]",
-- В отличие от англоязычной версии модуля, преобразования для категорий
-- выведены в отдельную функцию. Здесь соответствующие строки не указываются
}
--- Внутренние глобальные данные модуля
local title = mw.title.getCurrentTitle()
-- Зависимости
local slot = require(i18n.moduleSlot)
local recipeTable = require(i18n.moduleRecipe).table
-- Аргументы, задающие ячейки
local cArgVals = {'A1', 'B1', 'C1', 'A2', 'B2', 'C2', 'A3', 'B3', 'C3'}
p.cArgVals = cArgVals
--- Служебные функции
-- Автоматически раскладывает бесформенный рецепт, определяемый нумерованными
-- параметрами
local function arrangeShapelessRecipe(args)
if args[1] then
args["бесформенный"] = 1
if args[7] then
args.A1 = args[1]
args.B1 = args[2]
args.C1 = args[3]
args.A2 = args[4]
args.B2 = args[5]
args.C2 = args[6]
if args[8] then
-- ◼◼◼ ◼◼◼
-- ◼◼◼ или ◼◼◼
-- ◼◼◼ ◼◼◻
args.A3 = args[7]
args.B3 = args[8]
args.C3 = args[9]
if args[9] then
-- Если все слоты равны, то рецепт явно не бесформенный
local identical = true
for i = 1, 8 do
if args[i] ~= args[i + 1] then
identical = false
break
end
end
if identical then
args["бесформенный"] = nil
end
end
else
-- ◼◼◼
-- ◼◼◼
-- ◻◼◻
args.B3 = args[7]
end
elseif args[2] then
args.A2 = args[1]
args.B2 = args[2]
if args[5] then
-- ◻◻◻ ◻◻◻
-- ◼◼◼ или ◼◼◼
-- ◼◼◼ ◼◼◻
args.C2 = args[3]
args.A3 = args[4]
args.B3 = args[5]
args.C3 = args[6]
elseif args[4] then
-- ◻◻◻
-- ◼◼◻
-- ◼◼◻
args.A3 = args[3]
args.B3 = args[4]
else
-- ◻◻◻ ◻◻◻
-- ◼◼◻ или ◼◼◻
-- ◻◼◻ ◻◻◻
args.B3 = args[3]
end
else
-- ◻◻◻
-- ◻◼◻
-- ◻◻◻
-- Рецепт из одного ингредиента по определению не может быть
-- бесформенным
args.B2 = args[1]
args["бесформенный"] = nil
end
for i = 1, 9 do
args[i] = nil
end
end
end
-- Следующая функция добавляет категории использования. Именно с их помощью
-- работает модуль «Использование для крафта».
-- Некоторые варианты ингредиентов описываются на общей статье, некоторые -
-- на раздельных. За разрешение таких случаев отвечает специальный JSON-файл.
-- Обязательно вносите или запрашивайте изменения туда в случае слияния
-- или разбиения статей!
local mergeRules = mw.loadJsonData(i18n.jsonMergeRules)
local prefixesMatch = slot.i18n.prefixesMatch
local function addUsageCategories(ingredientSets, categories)
-- Уже обработанные ингредиенты на всякий случай кэшируются
local usedNames = {}
local function addName(name)
if not usedNames[name] then
local cat = i18n.categoryIngredientUsage:gsub("%$1", name)
table.insert(categories, cat)
usedNames[name] = true
end
end
local function addNames(names)
if names[1] then
for _, name in ipairs(names) do
addName(name)
end
else
addName(names)
end
end
-- Обрабатываем все наборы ингредиентов
for _, ingredientSet in ipairs(ingredientSets) do
for _, ingredient in ipairs(ingredientSet) do
local name = ingredient.name
if not ingredient.mod and not usedNames[name] then
-- Сначала попытаемся прямо заменить то или иное название статьи
local directReplace = mergeRules["прямая замена"][name]
if directReplace then
addNames(directReplace)
else
-- Теперь приступаем к обработке по шаблонам замены
local replaced = false
for _, patternReplace in ipairs(mergeRules["замена по шаблону"]) do
if mw.ustring.find(name, patternReplace[1]) then
addNames(patternReplace[2])
replaced = true
break
end
end
if not replaced then
-- Если шаблон не найден, то делается общая обработка
-- Убираем типовые прилагательные
for _, prefixMatch in pairs(prefixesMatch) do
if mw.ustring.find(name, prefixMatch .. " ") then
name = mw.ustring.gsub(name, prefixMatch .. " ", "")
break
end
end
-- Убираем специфические прилагательные для медных блоков
if mw.ustring.find(name, "медн[ыао][йяе]") then
name = mw.ustring.gsub(name, "^[Нн]евощён[ыао][йяе] ", "")
name = mw.ustring.gsub(name, "^[Вв]ощён[ыао][йяе] ", "")
name = mw.ustring.gsub(name, "^[Пп]отемневш[иае][йяе] ", "")
name = mw.ustring.gsub(name, "^[Сс]остаренн[ыао][йяе] ", "")
name = mw.ustring.gsub(name, "^[Оо]кисленн[ыао][йяе] ", "")
end
-- Обработка строк вида "А или Б"
local orA, orB = mw.ustring.match(name, "(.-) или (.+)")
if orA then
addName(orA)
addName(orB)
else
addName(name)
end
end
end
end
end
end
end
--- Основная функция
--- Строительство таблицы крафта
function p.table(f)
-- Принимаем аргументы
local args = f
if f == mw.getCurrentFrame() then
args = require('Модуль:ProcessArgs').merge(true)
else
f = mw.getCurrentFrame()
end
-- Автоматически раскладываем бесформенный рецепт
arrangeShapelessRecipe(args)
-- Строим таблицу и получаем списки ингредиентов
local out, ingredientSets = recipeTable(args, {
["функция интерфейса"] = 'craftingTable',
["тип"] = i18n.type,
["типа"] = i18n.typeGenitive,
["аргументы ингредиентов"] = cArgVals,
["аргументы выхода"] = {'Выход'},
})
if args["некат"] == "1" or args["игнорировать"] == "1" or title.namespace ~= 0 or title.isSubpage then
return out
else
-- Простановка категорий. Она автоматически отключена вне пространства статей, а
-- также на подстраницах (в т. ч. для модификаций). Для модов ещё не реализована
-- адекватная поддержка механизма «Использование для крафта» — это предполагается
-- сделать после переписывания модуля на базе Semantic MediaWiki.
local categories = {}
-- Тип рецепта
if args["тип"] then
local cat = i18n.categoryRecipeType:gsub("%$1", mw.text.trim(args["тип"]))
table.insert(categories, cat)
end
-- Использование ингредиентов
addUsageCategories(ingredientSets, categories)
return out, table.concat(categories, "")
end
end
return p