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

Материал из МК14 | Space Station 14 Wiki
(Попытка 3 + Добавил шаблон для картинок, которые потом добавлю вручную)
(Сделал сортировку и ссылки на доступные рецепты)
Строка 62: Строка 62:
     else
     else
         return reagentId  -- Если перевод не найден, возвращаем исходный ID
         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)
    if isIngredientCookable(ingredientId) then
        return string.format("[[#%s|%s]]", ingredientId, ingredientName)
    else
        return ingredientName
     end
     end
end
end
Строка 80: Строка 102:
     end
     end
      
      
     -- Перебираем все рецепты выбранного типа
     -- Создаем таблицу для сортировки
     for _, recipe in pairs(recipes[recipeType]) do
    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)
            return (a.data.input or "") < (b.data.input or "")
        end)
    else
        table.sort(sortedRecipes, function(a, b)
            return (a.data.result or "") < (b.data.result or "")
        end)
    end
 
    -- Перебираем отсортированные рецепты
    for _, recipeData in ipairs(sortedRecipes) do
        local recipe = recipeData.data
         local templateArgs = {}
         local templateArgs = {}


Строка 94: Строка 134:
                 for solidId, amount in pairs(recipe.solids) do
                 for solidId, amount in pairs(recipe.solids) do
                     local ingredientName = translateID(frame, solidId)
                     local ingredientName = translateID(frame, solidId)
                    ingredientName = createIngredientLink(frame, solidId, ingredientName)
                     table.insert(solidsList, string.format("%s (%d)", ingredientName, amount))
                     table.insert(solidsList, string.format("%s (%d)", ingredientName, amount))
                 end
                 end
Строка 118: Строка 159:
         elseif recipeType == "sliceableRecipes" then
         elseif recipeType == "sliceableRecipes" then
             local input = translateID(frame, recipe.input) or "Нет входного элемента"
             local input = translateID(frame, recipe.input) or "Нет входного элемента"
            input = createIngredientLink(frame, recipe.input, input)
             local result = translateID(frame, recipe.result) or "Нет результата"
             local result = translateID(frame, recipe.result) or "Нет результата"
             local count = recipe.count or "Нет данных"
             local count = recipe.count or "Нет данных"
Строка 130: Строка 172:
         elseif recipeType == "grindableRecipes" then
         elseif recipeType == "grindableRecipes" then
             local input = translateID(frame, recipe.input) or "Нет входного элемента"
             local input = translateID(frame, recipe.input) or "Нет входного элемента"
            input = createIngredientLink(frame, recipe.input, input)
             local resultList = {}
             local resultList = {}


Строка 147: Строка 190:
         elseif recipeType == "heatableRecipes" then
         elseif recipeType == "heatableRecipes" then
             local input = translateID(frame, recipe.input) or "Нет входного элемента"
             local input = translateID(frame, recipe.input) or "Нет входного элемента"
            input = createIngredientLink(frame, recipe.input, input)
             local result = translateID(frame, recipe.result) or "Нет результата"
             local result = translateID(frame, recipe.result) or "Нет результата"
             local minTemp = recipe.minTemp or "Нет данных"
             local minTemp = recipe.minTemp or "Нет данных"
Строка 159: Строка 203:
         elseif recipeType == "toolmadeRecipes" then
         elseif recipeType == "toolmadeRecipes" then
             local input = translateID(frame, recipe.input) or "Нет входного элемента"
             local input = translateID(frame, recipe.input) or "Нет входного элемента"
            input = createIngredientLink(frame, recipe.input, input)
             local result = translateID(frame, recipe.result) or "Нет результата"
             local result = translateID(frame, recipe.result) or "Нет результата"
             local tool = translateID(frame, recipe.tool) or "Нет инструмента"
             local tool = translateID(frame, recipe.tool) or "Нет инструмента"

Версия от 22:48, 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)
    if isIngredientCookable(ingredientId) then
        return string.format("[[#%s|%s]]", ingredientId, 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)
            return (a.data.input or "") < (b.data.input or "")
        end)
    else
        table.sort(sortedRecipes, function(a, b)
            return (a.data.result or "") < (b.data.result or "")
        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 .. frame:expandTemplate{ title = templateName, args = templateArgs }
    end
    
    return out
end

return p