Модуль:Prototypes/Машина/Станок: различия между версиями

Нет описания правки
мНет описания правки
 
(не показаны 54 промежуточные версии этого же участника)
Строка 1: Строка 1:
local p = {}
local p = {}


-- Функция для загрузки данных станков
-----------------------------------------------------------
local function loadLatheData()
-- Загрузка данных
    return mw.text.jsonDecode(mw.title.new("User:IanComradeBot/prototypes/lathe.json"):getContent())
-----------------------------------------------------------
end
local latheData      = mw.loadData("Модуль:IanComradeBot/prototypes/lathe.json/data")
 
local recipeData     = mw.loadData("Модуль:IanComradeBot/prototypes/lathe/recipes.json/data")
-- Функция для загрузки данных рецептов
local recipePackData = mw.loadData("Модуль:IanComradeBot/prototypes/lathe/recipe pack.json/data")
local function loadRecipeData()
local researchData  = mw.loadData("Модуль:IanComradeBot/prototypes/research.json/data")
     return mw.text.jsonDecode(mw.title.new("User:IanComradeBot/prototypes/lathe/recipes.json"):getContent())
local materialData  = mw.loadData("Модуль:IanComradeBot/prototypes/materials.json/data")
end
local chemData      = mw.loadData("Модуль:IanComradeBot/chem prototypes.json/data")
 
-- Функция для загрузки данных исследований
local function loadResearchData()
    return mw.text.jsonDecode(mw.title.new("User:IanComradeBot/prototypes/research.json"):getContent())
end
 
-- Функция для форматирования времени
local function format_seconds_to_short_string(input_seconds)
    local minutes = math.floor(input_seconds / 60)
    local seconds = input_seconds % 60
 
    local minutes_part = minutes > 0 and (minutes .. " мин.") or nil
    local seconds_part = seconds > 0 and (seconds .. " сек.") or nil
 
    if minutes_part and seconds_part then
        return minutes_part .. " " .. seconds_part
    elseif seconds_part then
        return seconds_part
    elseif minutes_part then
        return minutes_part
    else
        return ''
    end
end


-- Функция для сортировки рецептов
-----------------------------------------------------------
-- Вспомогательные функции
-----------------------------------------------------------
local function sortRecipesByPriority(recipes)
local function sortRecipesByPriority(recipes)
     table.sort(recipes, function(a, b)
     table.sort(recipes, function(a, b)
        -- Приоритеты дисциплин
         local priority = { Static = 1, EMAG = 3 }
         local priority = { Static = 1, Unknown = 2, EMAG = 4 }
         local aPriority = priority[a.discipline] or 2
         local aPriority = priority[a.discipline] or 3
         local bPriority = priority[b.discipline] or 2
         local bPriority = priority[b.discipline] or 3


        -- EMAG рецепты всегда в конце
         if a.isEmag ~= b.isEmag then
         if a.isEmag ~= b.isEmag then
             return not a.isEmag
             return not a.isEmag
         end
         end


        -- Если приоритеты совпадают
         if aPriority == bPriority then
         if aPriority == bPriority then
            -- Сравнение по уровню исследования
             if a.tier == b.tier then
             if a.tier == b.tier then
                -- Если уровни совпадают, сортируем по discipline
                 return a.discipline < b.discipline
                 return a.discipline < b.discipline
             end
             end
Строка 58: Строка 31:
         end
         end


        -- Сортируем по приоритету discipline
         return aPriority < bPriority
         return aPriority < bPriority
     end)
     end)
end
end


function p.main(frame)
local function getRecipeDetails(recipeId)
     local latheId = frame.args[1] or ""
     for _, recipe in ipairs(recipeData) do
    if latheId == "" then
        if recipe.id == recipeId then
         return '<div style="color:red;">Не указан ID станка.</div>'
            return recipe
         end
     end
     end
    return nil
end


    local latheData = loadLatheData()
local function findInResearch(recipeId)
     local recipeData = loadRecipeData()
     for _, research in ipairs(researchData) do
    local researchData = loadResearchData()
        if research and research.recipeUnlocks then
 
            for _, unlock in ipairs(research.recipeUnlocks) do
    local lathe = nil
                if unlock == recipeId then
    for _, data in ipairs(latheData) do
                    return {
        if data.id == latheId then
                        name = research.name,
            lathe = data
                        tier = research.tier,
             break
                        discipline = research.discipline
                    }
                end
             end
         end
         end
     end
     end
    return nil
end


     if not lathe then
local function getRecipePackDetails(packId)
         return '<div style="color:red;">Станок с ID "' .. latheId .. '" не найден.</div>'
     for _, pack in ipairs(recipePackData) do
        if pack.id == packId then
            return pack
         end
     end
     end
    return nil
end


    local output = '<h3>Рецепты станка: ' .. latheId .. '</h3>'
-----------------------------------------------------------
 
-- Функция для сбора рецептов из станка
-----------------------------------------------------------
local function getLatheRecipes(lathe)
     local recipes = {}
     local recipes = {}
    local chemMapping = {}
    for id, chem in pairs(chemData) do
        chemMapping[id] = chem.name
    end


     local function getRecipeDetails(recipeId)
    -- Вспомогательная функция для обработки одного рецепта
         for _, recipe in ipairs(recipeData) do
     local function processRecipe(recipeId, defaultDiscipline, isEmag)
             if recipe.id == recipeId then
         local recipe = getRecipeDetails(recipeId)
                 return recipe.latheRecipe
        if recipe then
             if recipe.result then
                local info = {
                    id = recipe.id,
                    result = recipe.result,
                    completetime = recipe.completetime,
                    materials = recipe.materials,
                    discipline = defaultDiscipline,
                    tier = 0,
                    isEmag = isEmag or false
                }
                if defaultDiscipline ~= "Static" then
                    local researchInfo = findInResearch(recipeId)
                    if researchInfo then
                        info.discipline = researchInfo.discipline
                        info.tier = researchInfo.tier
                        info.researchName = researchInfo.name
                    end
                end
                table.insert(recipes, info)
            elseif recipe.resultReagents then
                 for reagent, amount in pairs(recipe.resultReagents) do
                    local reagentName = chemMapping[reagent] or reagent
                    table.insert(recipes, {
                        id = recipe.id,
                        result = reagentName .. "|amount=" .. amount .. "ед.|mode-chem=1",
                        completetime = recipe.completetime,
                        materials = recipe.materials,
                        discipline = defaultDiscipline,
                        tier = 0,
                        isEmag = isEmag or false
                    })
                    break
                end
             end
             end
         end
         end
        return nil
     end
     end


     local function findInResearch(recipeId)
     -- Обработка рецептов для lathe.Lathe (старый и новый формат)
         for _, research in ipairs(researchData) do
    if lathe.Lathe then
             if research.technology and research.technology.recipeUnlocks then
        if lathe.Lathe.staticRecipes then
                for _, unlock in ipairs(research.technology.recipeUnlocks) do
            for _, recipeId in ipairs(lathe.Lathe.staticRecipes) do
                     if unlock == recipeId then
                processRecipe(recipeId, "Static", false)
                         return {
            end
                            name = research.technology.name,
        end
                            tier = research.technology.tier,
         if lathe.Lathe.dynamicRecipes then
                            discipline = research.technology.discipline
            for _, recipeId in ipairs(lathe.Lathe.dynamicRecipes) do
                         }
                processRecipe(recipeId, "Dynamic", false)
             end
        end
        if lathe.Lathe.staticPacks then
            for _, packId in ipairs(lathe.Lathe.staticPacks) do
                local pack = getRecipePackDetails(packId)
                if pack and pack.recipes then
                     local packRecipes = type(pack.recipes) ~= "table" and { pack.recipes } or pack.recipes
                    for _, recipeId in ipairs(packRecipes) do
                         processRecipe(recipeId, "Static", false)
                    end
                end
            end
        end
        if lathe.Lathe.dynamicPacks then
            for _, packId in ipairs(lathe.Lathe.dynamicPacks) do
                local pack = getRecipePackDetails(packId)
                if pack and pack.recipes then
                    local packRecipes = type(pack.recipes) ~= "table" and { pack.recipes } or pack.recipes
                    for _, recipeId in ipairs(packRecipes) do
                         processRecipe(recipeId, "Dynamic", false)
                     end
                     end
                 end
                 end
             end
             end
         end
         end
        return nil
     end
     end


     -- Обработка staticRecipes
     if lathe.EmagLatheRecipes then
    if lathe.Lathe.staticRecipes then
        if lathe.EmagLatheRecipes.emagStaticRecipes then
        for _, recipeId in ipairs(lathe.Lathe.staticRecipes) do
            for _, recipeId in ipairs(lathe.EmagLatheRecipes.emagStaticRecipes) do
            local recipe = getRecipeDetails(recipeId)
                processRecipe(recipeId, "Static", true)
             if recipe then
             end
                 table.insert(recipes, {
        end
                    result = recipe.result,
        if lathe.EmagLatheRecipes.emagDynamicRecipes then
                    completetime = recipe.completetime,
            for _, recipeId in ipairs(lathe.EmagLatheRecipes.emagDynamicRecipes) do
                     materials = recipe.materials,
                 processRecipe(recipeId, "Dynamic", true)
                    discipline = "Static",
            end
                     tier = 0
        end
                 })
        if lathe.EmagLatheRecipes.emagStaticPacks then
            for _, packId in ipairs(lathe.EmagLatheRecipes.emagStaticPacks) do
                local pack = getRecipePackDetails(packId)
                if pack and pack.recipes then
                     local packRecipes = type(pack.recipes) ~= "table" and { pack.recipes } or pack.recipes
                    for _, recipeId in ipairs(packRecipes) do
                        processRecipe(recipeId, "Static", true)
                     end
                 end
             end
             end
         end
         end
    end
        if lathe.EmagLatheRecipes.emagDynamicPacks then
 
            for _, packId in ipairs(lathe.EmagLatheRecipes.emagDynamicPacks) do
    -- Обработка dynamicRecipes
                local pack = getRecipePackDetails(packId)
    if lathe.Lathe.dynamicRecipes then
                if pack and pack.recipes then
        for _, recipeId in ipairs(lathe.Lathe.dynamicRecipes) do
                    local packRecipes = type(pack.recipes) ~= "table" and { pack.recipes } or pack.recipes
            local recipe = getRecipeDetails(recipeId)
                    for _, recipeId in ipairs(packRecipes) do
            if recipe then
                         processRecipe(recipeId, "Dynamic", true)
                local researchInfo = findInResearch(recipeId)
                     end
                if researchInfo then
                    table.insert(recipes, {
                        result = recipe.result,
                        completetime = recipe.completetime,
                        materials = recipe.materials,
                        discipline = researchInfo.discipline,
                        tier = researchInfo.tier,
                        researchName = researchInfo.name
                    })
                else
                    table.insert(recipes, {
                        result = recipe.result,
                         completetime = recipe.completetime,
                        materials = recipe.materials,
                        discipline = "Unknown",
                        tier = 0
                     })
                 end
                 end
             end
             end
Строка 159: Строка 192:
     end
     end


     -- Обработка emagStaticRecipes
     sortRecipesByPriority(recipes)
     if lathe.EmagLatheRecipes and lathe.EmagLatheRecipes.emagStaticRecipes then
    return recipes
        for _, recipeId in ipairs(lathe.EmagLatheRecipes.emagStaticRecipes) do
end
            local recipe = getRecipeDetails(recipeId)
 
            if recipe then
-----------------------------------------------------------
                table.insert(recipes, {
-- Общие таблицы для форматирования вывода
                    result = recipe.result,
-----------------------------------------------------------
                    completetime = recipe.completetime,
local disciplineMapping = {
                    materials = recipe.materials,
    Arsenal = "Арсенал",
                    discipline = "Static",
    Industrial = "Промышленность",
                    tier = 0,
    Experimental = "Экспериментальное",
                    isEmag = true
    CivilianServices = "Обслуживание персонала"
                })
}
            end
local tierColors = {
    [1] = "#54d554",
    [2] = "#ed9000",
     [3] = "#d72a2a"
}
local materialMappingGlobal = {}
for _, material in ipairs(materialData) do
    if material.id then
        materialMappingGlobal[material.id] = material.stackEntity or material.id or material.name
    end
end
 
-----------------------------------------------------------
-- Функция для формирования строки рецепта
-----------------------------------------------------------
local function formatRecipe(recipe, timeMultiplier, materialUseMultiplier)
    local out = ""
    local ct = recipe.completetime or 0
    local scaledTime = ct * timeMultiplier
    out = out .. '{{Шаблон:Prototypes/Машина/Станок/base|product=' .. recipe.result
    out = out .. '|complete-time={{#invoke:Code/Формат/Время|main|seconds|' .. scaledTime .. '}}|materials='
 
    if recipe.materials then
        local materialEntries = {}
        for material, amount in pairs(recipe.materials) do
            local stackEntity = materialMappingGlobal[material] or material
            local scaledAmount = (amount * materialUseMultiplier) / 100
            table.insert(materialEntries, string.format('<b>[[File:%s.png|32x32px|link=]] %g {{#invoke:Entity Lookup|getname|%s}}</b>', stackEntity, scaledAmount, stackEntity))
         end
         end
        out = out .. table.concat(materialEntries)
    else
        out = out .. 'Нет данных о материалах'
    end
    if recipe.discipline ~= "Static" then
        local tierColor = tierColors[recipe.tier] or "#FFFFFF"
        local disciplineName = disciplineMapping[recipe.discipline] or "Неизвестная дисциплина"
        out = out .. '|info=<div style="font-weight:600;"><span style="margin:8px;">[[File:' .. recipe.discipline .. '.png|16x16px|link=]]</span> [[Руководство по исследованию и разработке|' .. disciplineName
        out = out .. ']], уровень: <span style="color: ' .. tierColor .. '">' .. recipe.tier .. '</span> </div>'
    end
    if recipe.isEmag then
        out = out .. '|mode-emag=1'
    end
    if recipe.discipline ~= "Static" then
        out = out .. '|mode-research=1'
     end
     end


     -- Обработка emagDynamicRecipes
     out = out .. '}}'
     if lathe.EmagLatheRecipes and lathe.EmagLatheRecipes.emagDynamicRecipes then
     return out
        for _, recipeId in ipairs(lathe.EmagLatheRecipes.emagDynamicRecipes) do
end
            local recipe = getRecipeDetails(recipeId)
 
            if recipe then
-----------------------------------------------------------
                local researchInfo = findInResearch(recipeId)
-- Функция для поиска и вывода рецептов по ID станка
                if researchInfo then
-----------------------------------------------------------
                    table.insert(recipes, {
function p.lathe(frame)
                        result = recipe.result,
    local latheId = frame.args[1] or ""
                        completetime = recipe.completetime,
    if latheId == "" then
                        materials = recipe.materials,
        return '<div style="color:red;">Не указан ID станка.</div>'
                        discipline = researchInfo.discipline,
    end
                        tier = researchInfo.tier,
 
                        researchName = researchInfo.name,
    local lathe = nil
                        isEmag = true
    for _, data in ipairs(latheData) do
                    })
        if data.id == latheId then
                else
            lathe = data
                    table.insert(recipes, {
             break
                        result = recipe.result,
                        completetime = recipe.completetime,
                        materials = recipe.materials,
                        discipline = "Unknown",
                        tier = 0,
                        isEmag = true
                    })
                end
             end
         end
         end
     end
     end


     -- Сортируем рецепты
     if not lathe then
     sortRecipesByPriority(recipes)
        return '<div style="color:red;">Станок с ID "' .. latheId .. '" не найден.</div>'
     end


     -- Вывод рецептов
     local materialUseMultiplier = (lathe.Lathe and lathe.Lathe.materialUseMultiplier) or 1
    local timeMultiplier = (lathe.Lathe and lathe.Lathe.timeMultiplier) or 1
    local recipes = getLatheRecipes(lathe)
    local out = ""
     for _, recipe in ipairs(recipes) do
     for _, recipe in ipairs(recipes) do
         output = output .. '{{Шаблон:Prototypes/Машина/Станок|product=' .. recipe.result
         out = out .. formatRecipe(recipe, timeMultiplier, materialUseMultiplier)
        output = output .. '|complete-time=' .. format_seconds_to_short_string(recipe.completetime)
    end
        output = output .. '|materials='


        if next(recipe.materials) then
    return mw.getCurrentFrame():preprocess(out)
            for material, amount in pairs(recipe.materials) do
end
                output = output .. '<li>' .. material .. ': ' .. amount .. '</li>'
 
-----------------------------------------------------------
-- Функция для поиска и вывода рецептов по ID предмета
-----------------------------------------------------------
function p.item(frame)
    local itemId = frame.args[1] or ""
    if itemId == "" then
        return '<div style="color:red;">Не указан ID предмета.</div>'
    end
 
    local recipesOutput = ""
    local foundAny = false
 
    for _, lathe in ipairs(latheData) do
        local recipes = getLatheRecipes(lathe)
        local materialUseMultiplier = (lathe.Lathe and lathe.Lathe.materialUseMultiplier) or 1
        local timeMultiplier = (lathe.Lathe and lathe.Lathe.timeMultiplier) or 1
 
        for _, recipe in ipairs(recipes) do
            if recipe.id == itemId or recipe.result == itemId then
                foundAny = true
                local recipeStr = formatRecipe(recipe, timeMultiplier, materialUseMultiplier)
                recipeStr = recipeStr:gsub("}}$", "|method-container=" .. lathe.id .. "}}")
                recipesOutput = recipesOutput .. recipeStr
             end
             end
        else
            output = output .. 'Нет данных о материалах'
         end
         end
    end
    if not foundAny then
        return '<div style="color:red;">Рецепт для предмета с ID "' .. itemId .. '" не найден во всех станках.</div>'
    end


        -- Информация об исследовании
    local out = '<div class="grid-item-compressed">' .. recipesOutput .. '</div>'
        if recipe.discipline ~= "Static" and recipe.discipline ~= "Unknown" then
    return mw.getCurrentFrame():preprocess(out)
            output = output .. '|info=Исследование: ' .. recipe.discipline .. ' - ' .. recipe.researchName
end
            output = output .. ' (Уровень: ' .. recipe.tier .. ')'
 
        end
-----------------------------------------------------------
       
-- Функция для поиска и вывода рецептов по ID материала
        -- Пометка EMAG
-----------------------------------------------------------
        if recipe.isEmag then
function p.material(frame)
             output = output .. '<div>Пометка: EMAG</div>'
    local materialId = frame.args[1] or ""
    if materialId == "" then
        return '<div style="color:red;">Не указан ID материала.</div>'
    end
 
    local recipesOutput = ""
    local foundAny = false
 
    for _, lathe in ipairs(latheData) do
        local recipes = getLatheRecipes(lathe)
        local materialUseMultiplier = (lathe.Lathe and lathe.Lathe.materialUseMultiplier) or 1
        local timeMultiplier = (lathe.Lathe and lathe.Lathe.timeMultiplier) or 1
 
        for _, recipe in ipairs(recipes) do
            if recipe.materials then
                for matId, _ in pairs(recipe.materials) do
                    if matId == materialId then
                        foundAny = true
                        local recipeStr = formatRecipe(recipe, timeMultiplier, materialUseMultiplier)
                        recipeStr = recipeStr:gsub("}}$", "|method-container=" .. lathe.id .. "}}")
                        recipesOutput = recipesOutput .. recipeStr
                        break
                    end
                end
             end
         end
         end
    end


         output = output .. '}}'
    if not foundAny then
         return '<div style="color:red;">Для материала с ID "' .. materialId .. '" рецептов не найдено во всех станках.</div>'
     end
     end


     return mw.getCurrentFrame():preprocess(output)
    local out = '<div class="grid-item-compressed">' .. recipesOutput .. '</div>'
     return mw.getCurrentFrame():preprocess(out)
end
 
-----------------------------------------------------------
-- Функция для универсального вызова из шаблона
-----------------------------------------------------------
function p.main(frame)
    local arguments = require("Модуль:Arguments").getArgs(frame, { unwrap = true })
    local mode = arguments[1] or ""
    local id  = arguments[2] or ""
   
    -- Для обеспечения работы mw.getCurrentFrame(), переиспользуем исходный frame
    local newFrame = {
        args = { id },
        getCurrentFrame = frame.getCurrentFrame or function() return frame end
    }
   
    if mode == "lathe" then
        return p.lathe(newFrame)
    elseif mode == "item" then
        return p.item(newFrame)
    elseif mode == "material" then
        return p.material(newFrame)
    else
        return '<div style="color:red;">Неверный режим вызова: "' .. mode .. '". Используйте "lathe", "item" или "material".</div>'
    end
end
end


return p
return p