Модуль:Prototypes/Хранилище/Предмет: различия между версиями

мНет описания правки
мНет описания правки
Строка 3: Строка 3:
-- Кэш данных
-- Кэш данных
local dataCache = {}
local dataCache = {}
local dataIndexCache = {}
-- Проверка на существование функции
local function safeCall(func, ...)
    if type(func) == "function" then
        return func(...)
    else
        return nil, "Функция не определена."
    end
end


-- Функция processRolls для преобразования диапазона
-- Функция processRolls для преобразования диапазона
local processRolls = function(rolls)
local processRolls = function(rolls)
     if not rolls then return 'Не указан параметр rolls.' end
     local result = {}
 
     if rolls and rolls.range then
     if rolls.range then
        -- Если указан range
         local min, max = rolls.range:match("(%d+),%s*(%d+)")
         local min, max = rolls.range:match("(%d+),%s*(%d+)")
         min, max = tonumber(min), tonumber(max)
         min, max = tonumber(min), tonumber(max)
         if min and max then
         if min and max then
             return string.format('от %d до %d.', min + 1, max + 1)
             result[#result + 1] = string.format('от %d до %d.', min + 1, max + 1)
         else
         else
             return 'Некорректный формат для range.'
             result[#result + 1] = 'Некорректный формат для range.'
         end
         end
     elseif rolls.value then
     elseif rolls and rolls.value then
         return string.format('Будет сгенерировано %d предметов.', rolls.value)
         -- Если указано value
        result[#result + 1] = string.format('Будет сгенерировано %d предметов.', rolls.value)
    else
        result[#result + 1] = 'Не указан параметр rolls.'
     end
     end
 
     return table.concat(result)
     return 'Не указан параметр rolls.'
end
end


Строка 39: Строка 31:
         local content = page:getContent()
         local content = page:getContent()
         dataCache[filePath] = content and mw.text.jsonDecode(content) or nil
         dataCache[filePath] = content and mw.text.jsonDecode(content) or nil
        if dataCache[filePath] then
            dataIndexCache[filePath] = safeCall(buildIndex, dataCache[filePath])
        end
     end
     end
     return dataCache[filePath], dataIndexCache[filePath]
     return dataCache[filePath]
end
end


-- Создание хэш-таблицы для быстрого поиска по ID
-- Создание хэш-таблицы для быстрого поиска по ID
local buildIndex = function(data)
local function buildIndex(data)
     if not data then return {} end
     if not data then return {} end
     local index = {}
     local index = {}
Строка 90: Строка 79:
     local result = {}
     local result = {}
     for _, content in ipairs(contents) do
     for _, content in ipairs(contents) do
         result[#result + 1] = safeCall(formatContent, content)
         result[#result + 1] = formatContent(content)
     end
     end
     return table.concat(result)
     return table.concat(result)
Строка 97: Строка 86:
-- Обработка вложенных таблиц
-- Обработка вложенных таблиц
local processNestedSelectors = function(children)
local processNestedSelectors = function(children)
local handleNestedSelector, handleGroupSelector
     local result = {}
     local result = {}
     for _, child in ipairs(children) do
     for _, child in ipairs(children) do
         if child.id then
         if child.id then
             result[#result + 1] = safeCall(formatContent, child)
             result[#result + 1] = formatContent(child)
         elseif child["!type"] == "NestedSelector" and child.tableId then
         elseif child["!type"] == "NestedSelector" and child.tableId then
             result[#result + 1] = safeCall(handleNestedSelector, child, true)
             result[#result + 1] = handleNestedSelector(child, true)
         elseif child["!type"] == "GroupSelector" then
         elseif child["!type"] == "GroupSelector" then
             result[#result + 1] = safeCall(handleGroupSelector, child)
             result[#result + 1] = handleGroupSelector(child)
         end
         end
     end
     end
Строка 112: Строка 102:
-- Обработка таблиц
-- Обработка таблиц
local getTableOutput = function(tableId)
local getTableOutput = function(tableId)
     local allSelectors, dataIndex = loadData('User:IanComradeBot/prototypes/AllSelector.json')
local handleGroupSelector, processNestedSelectors
     if not allSelectors then return 'Таблица не найдена.' end
     local allSelectors = loadData('User:IanComradeBot/prototypes/AllSelector.json')
     local tableData = findDataById(buildIndex(allSelectors), tableId)


    local tableData = safeCall(findDataById, dataIndex, tableId)
     if not tableData then return 'Таблица не найдена.' end
     if not tableData then return 'Таблица не найдена.' end


     if tableData['!type:GroupSelector'] then
     if tableData['!type:GroupSelector'] then
         return safeCall(handleGroupSelector, tableData['!type:GroupSelector'])
         return handleGroupSelector(tableData['!type:GroupSelector'])
     elseif tableData['!type:AllSelector'] then
     elseif tableData['!type:AllSelector'] then
         return safeCall(processNestedSelectors, tableData['!type:AllSelector'].children)
         return processNestedSelectors(tableData['!type:AllSelector'].children)
     end
     end


Строка 129: Строка 119:
-- Формирование списка содержащихся предметов или таблиц
-- Формирование списка содержащихся предметов или таблиц
local getContainedOutput = function(data, id)
local getContainedOutput = function(data, id)
     local item = safeCall(findDataById, safeCall(buildIndex, data), id)
     local item = findDataById(data, id)
     if not item then return '' end
     if not item then return '' end


Строка 136: Строка 126:
     -- Обработка StorageFill
     -- Обработка StorageFill
     if item.StorageFill and item.StorageFill.contents then
     if item.StorageFill and item.StorageFill.contents then
         result[#result + 1] = safeCall(getContentsOutput, item.StorageFill.contents)
         result[#result + 1] = getContentsOutput(item.StorageFill.contents)


     -- Обработка EntityTableContainerFill
     -- Обработка EntityTableContainerFill
Строка 145: Строка 135:
         if containers.entity_storage then
         if containers.entity_storage then
             if containers.entity_storage.children then
             if containers.entity_storage.children then
                 result[#result + 1] = safeCall(processNestedSelectors, containers.entity_storage.children)
                 result[#result + 1] = processNestedSelectors(containers.entity_storage.children)
             end
             end


             if containers.entity_storage.tableId then
             if containers.entity_storage.tableId then
                 result[#result + 1] = safeCall(getTableOutput, containers.entity_storage.tableId)
                 result[#result + 1] = getTableOutput(containers.entity_storage.tableId)
             end
             end
         end
         end
Строка 155: Строка 145:
         -- Обработка storagebase
         -- Обработка storagebase
         if containers.storagebase and containers.storagebase.tableId then
         if containers.storagebase and containers.storagebase.tableId then
             result[#result + 1] = safeCall(getTableOutput, containers.storagebase.tableId)
             result[#result + 1] = getTableOutput(containers.storagebase.tableId)
         end
         end
     end
     end
Строка 165: Строка 155:
local handleAllSelector = function(allSelector)
local handleAllSelector = function(allSelector)
     if not allSelector.children then return '' end
     if not allSelector.children then return '' end
     return safeCall(processNestedSelectors, allSelector.children)
     return processNestedSelectors(allSelector.children)
end
end


Строка 174: Строка 164:
     local wrapperStart, wrapperEnd = "", ""
     local wrapperStart, wrapperEnd = "", ""


    -- Проверка для контейнера EntityTableContainerFill
     if groupSelector.weight and groupSelector.weight ~= "default" then
     if groupSelector.weight and groupSelector.weight ~= "default" then
         wrapperStart = string.format('<div class="together" id="%s">', groupSelector.weight)
         wrapperStart = string.format('<div class="together" id="%s">', groupSelector.weight)
Строка 184: Строка 175:
     for _, child in ipairs(groupSelector.children) do
     for _, child in ipairs(groupSelector.children) do
         if child["!type"] == "GroupSelector" then
         if child["!type"] == "GroupSelector" then
             result[#result + 1] = safeCall(handleGroupSelector, child)
             result[#result + 1] = handleGroupSelector(child)
         elseif child["!type"] == "AllSelector" then
         elseif child["!type"] == "AllSelector" then
             result[#result + 1] = string.format('<div class="AllSelector">%s</div>', safeCall(handleAllSelector, child))
             result[#result + 1] = string.format('<div class="AllSelector">%s</div>', handleAllSelector(child))
         elseif child.id then
         elseif child.id then
             result[#result + 1] = safeCall(formatContent, child)
             result[#result + 1] = formatContent(child)
         else
         else
             result[#result + 1] = "<div>Ошибка: отсутствует id у элемента.</div>"
             result[#result + 1] = "<div>Ошибка: отсутствует id у элемента.</div>"
Строка 206: Строка 197:
     if wrapped then
     if wrapped then
         if nestedSelector.rolls and nestedSelector.rolls.range then
         if nestedSelector.rolls and nestedSelector.rolls.range then
             classes[#classes + 1] = 'rolls-' .. safeCall(processRolls, nestedSelector.rolls)
             classes[#classes + 1] = 'rolls-' .. processRolls(nestedSelector.rolls)
         end
         end
         if nestedSelector.prob then
         if nestedSelector.prob then
Строка 217: Строка 208:
     end
     end


     result[#result + 1] = safeCall(getTableOutput, nestedSelector.tableId)
     result[#result + 1] = getTableOutput(nestedSelector.tableId)


     if wrapped and #classes > 0 then
     if wrapped and #classes > 0 then
Строка 228: Строка 219:
-- Формирование списка химии
-- Формирование списка химии
local getChemOutput = function(data, id)
local getChemOutput = function(data, id)
     local item = safeCall(findDataById, safeCall(buildIndex, data), id)
     local item = findDataById(data, id)
     if not item or not item.SolutionContainerManager or not item.SolutionContainerManager.solutions then return '' end
     if not item or not item.SolutionContainerManager or not item.SolutionContainerManager.solutions then return '' end


Строка 247: Строка 238:
     if not id then return 'Не указан ID.' end
     if not id then return 'Не указан ID.' end


     local data, dataIndex = loadData('User:IanComradeBot/prototypes/fills/Item.json')
     local data = loadData('User:IanComradeBot/prototypes/fills/Item.json')
    local dataIndex = buildIndex(data)
 
     if not data then return 'Не удалось загрузить данные.' end
     if not data then return 'Не удалось загрузить данные.' end


Строка 259: Строка 252:


         if subMode == 'chem' then
         if subMode == 'chem' then
             return frame:preprocess('{{СollapsibleMenu|' .. safeCall(getChemOutput, dataIndex, id) .. '}}')
             return frame:preprocess('{{СollapsibleMenu|' .. getChemOutput(dataIndex, id) .. '}}')
         elseif subMode == 'contained' then
         elseif subMode == 'contained' then
             return frame:preprocess('{{СollapsibleMenu|' .. safeCall(getContainedOutput, dataIndex, id) .. '}}')
             return frame:preprocess('{{СollapsibleMenu|' .. getContainedOutput(dataIndex, id) .. '}}')
         else
         else
             return 'Неизвестный подрежим для framing: ' .. subMode
             return 'Неизвестный подрежим для framing: ' .. subMode
         end
         end
     elseif mode == 'chem' then
     elseif mode == 'chem' then
         return frame:preprocess(safeCall(getChemOutput, dataIndex, id))
         return frame:preprocess(getChemOutput(dataIndex, id))
     elseif mode == 'contained' then
     elseif mode == 'contained' then
         return frame:preprocess(safeCall(getContainedOutput, dataIndex, id))
         return frame:preprocess(getContainedOutput(dataIndex, id))
     elseif mode == 'rolls' then
     elseif mode == 'rolls' then
         local entity = safeCall(findDataById, dataIndex, id)
         local entity = findDataById(dataIndex, id)
         if not entity then return 'ID не найден в данных.' end
         if not entity then return 'ID не найден в данных.' end
 
         if entity.EntityTableContainerFill then
         if entity.EntityTableContainerFill then
             local containers = entity.EntityTableContainerFill.containers
             local containers = entity.EntityTableContainerFill.containers
             if containers.entity_storage and containers.entity_storage.rolls then
             if containers.entity_storage and containers.entity_storage.rolls then
                 return safeCall(processRolls, containers.entity_storage.rolls)
                 return processRolls(containers.entity_storage.rolls)
             end
             end
         end
         end


         return 'Режим rolls не найден для этого ID.'
         return 'Режим rolls не найден для этого ID.'
    else
    else
         return 'Неизвестный режим: ' .. mode
         return 'Неизвестный режим: ' .. mode
     end
     end