Модуль:Песочница/Pok: различия между версиями

Материал из Space Station 14 Вики
мНет описания правки
мНет описания правки
Строка 108: Строка 108:


     local results = {}
     local results = {}
    -- Поиск в startingGear (gearData)
for _, gear in pairs(gearData) do
    for gearId, gear in pairs(gearData) do
    local currentGearId = gear.id or "Unknown"
        if gear.equipment then
    if gear.equipment then
            for slot, equipId in pairs(gear.equipment) do
        for slot, equipId in pairs(gear.equipment) do
                if equipId == targetId and (not slotFilter or slot == slotFilter) then
            if equipId == targetId and (not slotFilter or slot == slotFilter) then
                    -- Ищем в jobData, где startingGear равен gearId
                local foundJob = nil
                    local foundJob = nil
                for jobId, job in pairs(jobData) do
                    for jobId, job in pairs(jobData) do
                    if job.startingGear == currentGearId then
                        if job.startingGear == gearId then
                        foundJob = jobId
                            foundJob = jobId
                        break
                            break
                    end
                        end
                end
                    end
                if foundJob then
                    if foundJob then
                    table.insert(results, "Job: " .. foundJob .. " (слот: " .. slot .. ")")
                        table.insert(results, "Job: " .. foundJob .. " (слот: " .. slot .. ")")
                else
                    else
                    table.insert(results, "Gear: " .. currentGearId .. " (слот: " .. slot .. ")")
                        table.insert(results, "Gear: " .. gearId .. " (слот: " .. slot .. ")")
                end
                    end
            end
                end
        end
            end
    end
        end
end
    end


     -- Поиск в loadout (loadoutData)
     -- Поиск в loadout (loadoutData)

Версия от 18:38, 20 февраля 2025

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

local p = {}

---------------------------------------------------------------------
-- Загрузка данных из разных модулей
---------------------------------------------------------------------
local itemData           = mw.loadData("Модуль:IanComradeBot/prototypes/fills/Item.json/data")
local tableData          = mw.loadData("Модуль:IanComradeBot/prototypes/table.json/data")
local gearData           = mw.loadData("Модуль:IanComradeBot/startingGear.json/data")
local jobData            = mw.loadData("Модуль:IanComradeBot/job.json/data")
local gearRoleLoadout    = mw.loadData("Модуль:IanComradeBot/roleLoadout.json/data")
local loadoutData        = mw.loadData("Модуль:IanComradeBot/loadout.json/data")
local loadoutGroupData   = mw.loadData("Модуль:IanComradeBot/loadoutGroup.json/data")
local cargoData          = mw.loadData("Модуль:IanComradeBot/prototypes/сargo.json/base")
local latheData          = mw.loadData("Модуль:IanComradeBot/prototypes/lathe.json/data")
local recipeData         = mw.loadData("Модуль:IanComradeBot/prototypes/lathe/recipes.json/data")
local researchData       = mw.loadData("Модуль:IanComradeBot/prototypes/research.json/data")
local materialData       = mw.loadData("Модуль:IanComradeBot/prototypes/materials.json/data")
local chemDataLathe      = mw.loadData("Модуль:IanComradeBot/chem prototypes.json/data")

---------------------------------------------------------------------
-- Функции для обратного поиска
---------------------------------------------------------------------

-- Функция для рекурсивного поиска id предмета в произвольной структуре таблицы.
local function searchItemInStructure(struct, targetId)
    if type(struct) ~= "table" then
        return false
    end
    if struct.id and struct.id == targetId then
        return true
    end
    for _, v in pairs(struct) do
        if type(v) == "table" then
            if searchItemInStructure(v, targetId) then
                return true
            end
        end
    end
    return false
end

---------------------------------------------------------------------
-- Обратный поиск по содержимому (reverseContained)
-- По заданному id предмета ищем таблицы, в которых он встречается,
-- а затем в itemData ищем хранилища, где используются найденные таблицы.
---------------------------------------------------------------------
function p.reverseContained(frame)
    local targetId = frame.args[2]
    if not targetId or targetId == "" then
        return "Ошибка: не указан id предмета для обратного поиска."
    end

    local matchingTables = {}
    -- Перебираем все записи таблиц
    for tableId, tblEntry in pairs(tableData) do
        if type(tblEntry) == "table" then
            if searchItemInStructure(tblEntry, targetId) then
                table.insert(matchingTables, tableId)
            end
        end
    end

    if #matchingTables == 0 then
        return "Таблица, содержащая предмет с id " .. targetId .. ", не найдена."
    end

    local matchingStorages = {}
    -- Ищем в itemData хранилища, в которых используется найденная таблица
    for storageId, storage in pairs(itemData) do
        if type(storage) == "table" and storage.EntityTableContainerFill and storage.EntityTableContainerFill.containers then
            local containers = storage.EntityTableContainerFill.containers
            if containers.entity_storage and containers.entity_storage.tableId then
                for _, tblId in ipairs(matchingTables) do
                    if containers.entity_storage.tableId == tblId then
                        table.insert(matchingStorages, storageId)
                    end
                end
            end
            if containers.storagebase and containers.storagebase.tableId then
                for _, tblId in ipairs(matchingTables) do
                    if containers.storagebase.tableId == tblId then
                        table.insert(matchingStorages, storageId)
                    end
                end
            end
        end
    end

    if #matchingStorages == 0 then
        return "Хранилище, вызывающее найденные таблицы, не найдено."
    end

    return "Найденные хранилища: " .. table.concat(matchingStorages, ", ")
end

---------------------------------------------------------------------
-- Обратный поиск для экипировки (reverseEquipment)
-- По заданному id оборудования ищем, в каких наборах экипировки
-- оно используется, и, если найдено в startingGear, ищем в jobData
-- по параметру startingGear, выводя id соответствующего job.
---------------------------------------------------------------------
function p.reverseEquipment(frame)
    local targetId = frame.args[2]
    local slotFilter = frame.args[3]  -- если указан, фильтруем по конкретному слоту
    if not targetId or targetId == "" then
        return "Ошибка: не указан id оборудования для обратного поиска."
    end

    local results = {}
	for _, gear in pairs(gearData) do
	    local currentGearId = gear.id or "Unknown"
	    if gear.equipment then
	        for slot, equipId in pairs(gear.equipment) do
	            if equipId == targetId and (not slotFilter or slot == slotFilter) then
	                local foundJob = nil
	                for jobId, job in pairs(jobData) do
	                    if job.startingGear == currentGearId then
	                        foundJob = jobId
	                        break
	                    end
	                end
	                if foundJob then
	                    table.insert(results, "Job: " .. foundJob .. " (слот: " .. slot .. ")")
	                else
	                    table.insert(results, "Gear: " .. currentGearId .. " (слот: " .. slot .. ")")
	                end
	            end
	        end
	    end
	end

    -- Поиск в loadout (loadoutData)
    for loadoutId, loadout in pairs(loadoutData) do
        if loadout.equipment then
            for slot, equipId in pairs(loadout.equipment) do
                if equipId == targetId and (not slotFilter or slot == slotFilter) then
                    table.insert(results, "Loadout: " .. loadoutId .. " (слот: " .. slot .. ")")
                end
            end
        end
    end

    if #results == 0 then
        return "Оборудование с id " .. targetId .. " не найдено в наборах экипировки."
    end

    return "Найдено использование оборудования: " .. table.concat(results, "; ")
end

---------------------------------------------------------------------
-- Обратный поиск для груза (cargo) (reverseCargo)
-- Всегда осуществляется поиск по полю product.
---------------------------------------------------------------------
function p.reverseCargo(frame)
    local searchValue = frame.args[2]
    if not searchValue or searchValue == "" then
        return "Ошибка: не указано значение для поиска в режиме cargo."
    end

    local foundIds = {}
    for _, entry in ipairs(cargoData) do
        if entry.product == searchValue then
            table.insert(foundIds, entry.id)
        end
    end

    if #foundIds == 0 then
        return "Запись для product со значением '" .. searchValue .. "' не найдена."
    end

    return "Найденные записи cargo: " .. table.concat(foundIds, ", ")
end

---------------------------------------------------------------------
-- Обратный поиск для станков (lathe) (reverseLathe)
-- По заданному результату рецепта ищем рецепты станков и возвращаем id станка, который его производит.
---------------------------------------------------------------------
local function getRecipeById(recipeId)
    for _, recipe in ipairs(recipeData) do
        if recipe.id == recipeId then
            return recipe
        end
    end
    return nil
end

function p.reverseLathe(frame)
    local targetResult = frame.args[2]
    if not targetResult or targetResult == "" then
        return "Ошибка: не указан результат рецепта для обратного поиска."
    end

    local matchingLathes = {}
    -- Вспомогательная функция для проверки набора рецептов
    local function checkRecipes(recipeIds)
        for _, recipeId in ipairs(recipeIds or {}) do
            local recipe = getRecipeById(recipeId)
            if recipe and recipe.result == targetResult then
                return true
            end
        end
        return false
    end

    for _, lathe in ipairs(latheData) do
        local found = false
        if lathe.Lathe then
            if checkRecipes(lathe.Lathe.staticRecipes) or checkRecipes(lathe.Lathe.dynamicRecipes) then
                found = true
            end
        end
        if not found and lathe.EmagLatheRecipes then
            if checkRecipes(lathe.EmagLatheRecipes.emagStaticRecipes) or checkRecipes(lathe.EmagLatheRecipes.emagDynamicRecipes) then
                found = true
            end
        end
        if found and lathe.id then
            table.insert(matchingLathes, lathe.id)
        end
    end

    if #matchingLathes == 0 then
        return "Станок, производящий '" .. targetResult .. "', не найден."
    end

    return "Найденные станки: " .. table.concat(matchingLathes, ", ")
end

---------------------------------------------------------------------
-- Основная функция модуля
-- Принимает первым аргументом режим обратного поиска:
-- reverseContained, reverseEquipment, reverseCargo, reverseLathe.
-- Второй (и последующие) аргументы передаются соответствующим функциям.
---------------------------------------------------------------------
function p.main(frame)
    local mode = frame.args[1]
    if not mode or mode == "" then
        return "Ошибка: не указан режим обратного поиска. Доступные режимы: reverseContained, reverseEquipment, reverseCargo, reverseLathe."
    end

    if mode == "reverseContained" then
        return p.reverseContained(frame)
    elseif mode == "reverseEquipment" then
        return p.reverseEquipment(frame)
    elseif mode == "reverseCargo" then
        return p.reverseCargo(frame)
    elseif mode == "reverseLathe" then
        return p.reverseLathe(frame)
    else
        return "Неизвестный режим: " .. mode .. ". Доступные режимы: reverseContained, reverseEquipment, reverseCargo, reverseLathe."
    end
end

return p