Модуль:TableOfRecipes: различия между версиями

Материал из МК14 | Space Station 14 Wiki
(п 10)
(Попытка 11 блять)
Строка 82: Строка 82:
     local anchor = string.gsub(ingredientId, " ", "_")  -- Заменяем пробелы на подчеркивания
     local anchor = string.gsub(ingredientId, " ", "_")  -- Заменяем пробелы на подчеркивания
     if isIngredientCookable(ingredientId) then
     if isIngredientCookable(ingredientId) then
         return frame:preprocess(string.format('{{#tag:a|%s|href="#%s"}}', ingredientName, anchor))
         return string.format('[[#%s|%s]]', anchor, ingredientName)
     else
     else
         return ingredientName
         return ingredientName

Версия от 23:56, 8 марта 2025

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

local p = {}

-- Кэш для хранения данных о рецептах
local recipeCache = nil

-- Кэш для хранения данных о химических веществах
local chemCache = nil

-- Функция для загрузки данных о рецептах из JSON-файла
local function loadRecipes()
    if recipeCache then
        return recipeCache
    end
    
    local success, data = pcall(function()
        return mw.text.jsonDecode(mw.title.new("User:CapybaraBot/mealrecipes_prototypes.json"):getContent())
    end)
    
    if success then
        recipeCache = data
        return data
    else
        mw.log("Ошибка при загрузке JSON (mealrecipes_prototypes.json): " .. data)
        return {}
    end
end

-- Функция для загрузки данных о химических веществах из JSON-файла
local function loadChemPrototypes()
    if chemCache then
        return chemCache
    end
    
    local success, data = pcall(function()
        return mw.text.jsonDecode(mw.title.new("User:CapybaraBot/chem_prototypes.json"):getContent())
    end)
    
    if success then
        chemCache = data
        return data
    else
        mw.log("Ошибка при загрузке JSON (chem_prototypes.json): " .. data)
        return {}
    end
end

-- Функция для перевода ID с использованием Module:Entity Lookup (для твердых веществ)
local function translateID(frame, id)
    local translatedName = frame:callParserFunction{ name = '#invoke', args = { 'Entity_Lookup', 'getname', id } }
    if translatedName then
        return string.format("%s [[Файл:%s.png|link=|32пкс]]", translatedName, id)
    else
        return id  -- Если перевод не найден, возвращаем исходный ID
    end
end

-- Функция для перевода реагента (жидкого вещества) из chem_prototypes.json
local function translateReagent(reagentId)
    local chemData = loadChemPrototypes()
    if chemData[reagentId] and chemData[reagentId].name then
        return chemData[reagentId].name
    else
        return reagentId  -- Если перевод не найден, возвращаем исходный ID
    end
end

-- Функция для проверки, можно ли приготовить ингредиент
local function isIngredientCookable(ingredientId)
    local recipes = loadRecipes()
    for _, recipeGroup in pairs(recipes) do
        for _, recipe in pairs(recipeGroup) do
            if recipe.result == ingredientId then
                return true
            end
        end
    end
    return false
end

-- Функция для создания ссылки на рецепт, если ингредиент можно приготовить
local function createIngredientLink(frame, ingredientId, ingredientName)
    local anchor = string.gsub(ingredientId, " ", "_")  -- Заменяем пробелы на подчеркивания
    if isIngredientCookable(ingredientId) then
        return string.format('[[#%s|%s]]', anchor, ingredientName)
    else
        return ingredientName
    end
end

-- Основная функция для генерации таблицы с рецептами
p.fillRecipeTable = function(frame)
    local args = frame.args
    local recipeType = args.recipeType or "microwaveRecipes"  -- Тип рецептов по умолчанию
    local templateName = args.template or "RecipeRow"  -- Шаблон по умолчанию

    local out = ""
    
    -- Загрузка данных о рецептах
    local recipes = loadRecipes()
    
    if not recipes or not recipes[recipeType] then
        return "Ошибка: данные о рецептах не загружены или тип рецептов не найден."
    end
    
    -- Создаем таблицу для сортировки
    local sortedRecipes = {}
    for recipeId, recipe in pairs(recipes[recipeType]) do
        table.insert(sortedRecipes, { id = recipeId, data = recipe })
    end

    -- Сортировка рецептов с учетом перевода
    if recipeType == "grindableRecipes" then
        table.sort(sortedRecipes, function(a, b)
            local aName = translateID(frame, a.data.input or "")
            local bName = translateID(frame, b.data.input or "")
            return aName < bName
        end)
    else
        table.sort(sortedRecipes, function(a, b)
            local aName = translateID(frame, a.data.result or "")
            local bName = translateID(frame, b.data.result or "")
            return aName < bName
        end)
    end

    -- Перебираем отсортированные рецепты
    for _, recipeData in ipairs(sortedRecipes) do
        local recipe = recipeData.data
        local templateArgs = {}

        -- Обработка для microwaveRecipes
        if recipeType == "microwaveRecipes" then
            -- Переводим результат
            local result = translateID(frame, recipe.result) or "Нет результата"
            
            -- Формируем список ингредиентов (solids)
            local solidsList = {}
            if recipe.solids and type(recipe.solids) == "table" then
                for solidId, amount in pairs(recipe.solids) do
                    local ingredientName = translateID(frame, solidId)
                    ingredientName = createIngredientLink(frame, solidId, ingredientName)
                    table.insert(solidsList, string.format("%s (%d)", ingredientName, amount))
                end
            end
            
            -- Формируем список реагентов (reagents)
            local reagentsList = {}
            if recipe.reagents and type(recipe.reagents) == "table" then
                for reagentId, amount in pairs(recipe.reagents) do
                    local reagentName = translateReagent(reagentId)
                    table.insert(reagentsList, string.format("%s (%d)", reagentName, amount))
                end
            end
            
            -- Формируем аргументы для шаблона
            templateArgs = {
                result = result,
                solids = table.concat(solidsList, ", ") or "Нет ингредиентов",
                reagents = table.concat(reagentsList, ", ") or "Нет реагентов",
                time = recipe.time or "Нет данных"
            }

        -- Обработка для sliceableRecipes
        elseif recipeType == "sliceableRecipes" then
            local input = translateID(frame, recipe.input) or "Нет входного элемента"
            input = createIngredientLink(frame, recipe.input, input)
            local result = translateID(frame, recipe.result) or "Нет результата"
            local count = recipe.count or "Нет данных"

            templateArgs = {
                input = input,
                result = result,
                count = count
            }

        -- Обработка для grindableRecipes
        elseif recipeType == "grindableRecipes" then
            local input = translateID(frame, recipe.input) or "Нет входного элемента"
            input = createIngredientLink(frame, recipe.input, input)
            local resultList = {}

            if recipe.result and type(recipe.result) == "table" then
                for reagentId, amount in pairs(recipe.result) do
                    local reagentName = translateReagent(reagentId)
                    table.insert(resultList, string.format("%s (%d)", reagentName, amount))
                end
            end

            templateArgs = {
                input = input,
                result = table.concat(resultList, ", ") or "Нет результата"
            }

        -- Обработка для heatableRecipes
        elseif recipeType == "heatableRecipes" then
            local input = translateID(frame, recipe.input) or "Нет входного элемента"
            input = createIngredientLink(frame, recipe.input, input)
            local result = translateID(frame, recipe.result) or "Нет результата"
            local minTemp = recipe.minTemp or "Нет данных"

            templateArgs = {
                input = input,
                result = result,
                minTemp = minTemp
            }

        -- Обработка для toolmadeRecipes
        elseif recipeType == "toolmadeRecipes" then
            local input = translateID(frame, recipe.input) or "Нет входного элемента"
            input = createIngredientLink(frame, recipe.input, input)
            local result = translateID(frame, recipe.result) or "Нет результата"
            local tool = translateID(frame, recipe.tool) or "Нет инструмента"

            templateArgs = {
                input = input,
                result = result,
                tool = tool
            }
        end

        -- Добавляем якорь для строки таблицы
        out = out .. string.format('|- id="%s"\n', recipe.id)

        -- Генерация строки таблицы с использованием шаблона
        out = out .. frame:expandTemplate{ title = templateName, args = templateArgs } .. "\n"
    end
    
    return out
end

return p