|
|
| (не показано 96 промежуточных версий этого же участника) |
| Строка 1: |
Строка 1: |
| local p = {} | | local p = {} |
|
| |
|
| -----------------------------------------------------------
| |
| -- Загрузка данных | | -- Загрузка данных |
| -----------------------------------------------------------
| | local chemData = mw.loadData("Модуль:IanComradeBot/chem prototypes.json/data") |
| local latheData = mw.loadData("Модуль:IanComradeBot/prototypes/lathe.json/data") | | local seedsData = mw.loadData("Модуль:IanComradeBot/prototypes/seeds.json/data") |
| local recipeData = mw.loadData("Модуль:IanComradeBot/prototypes/lathe/recipes.json/data")
| |
| local recipePackData = mw.loadData("Модуль:IanComradeBot/prototypes/lathe/recipe pack.json/data") | |
| local researchData = mw.loadData("Модуль:IanComradeBot/prototypes/research.json/data")
| |
| local materialData = mw.loadData("Модуль:IanComradeBot/prototypes/materials.json/data")
| |
| local chemData = mw.loadData("Модуль:IanComradeBot/chem prototypes.json/data")
| |
|
| |
|
| -----------------------------------------------------------
| | local function kelvinToCelsius(k) |
| -- Вспомогательные функции
| | return k - 273.15 |
| -----------------------------------------------------------
| |
| local function sortRecipesByPriority(recipes) | |
| table.sort(recipes, function(a, b) | |
| local priority = { Static = 1, EMAG = 3 }
| |
| local aPriority = priority[a.discipline] or 2
| |
| local bPriority = priority[b.discipline] or 2
| |
| | |
| if a.isEmag ~= b.isEmag then
| |
| return not a.isEmag
| |
| end
| |
| | |
| if aPriority == bPriority then
| |
| if a.tier == b.tier then
| |
| return a.discipline < b.discipline
| |
| end
| |
| return a.tier < b.tier
| |
| end
| |
| | |
| return aPriority < bPriority
| |
| end)
| |
| end | | end |
|
| |
|
| local function getRecipeDetails(recipeId) | | local function findSeedById(id, data) |
| for _, recipe in ipairs(recipeData) do | | for _, seed in ipairs(data) do |
| if recipe.id == recipeId then | | if seed.id == id then |
| return recipe | | return seed |
| end | | end |
| end | | end |
| Строка 44: |
Строка 18: |
| end | | end |
|
| |
|
| local function findInResearch(recipeId) | | local function formatCharacteristics(seed) |
| for _, research in ipairs(researchData) do | | local parts = { |
| if research and research.recipeUnlocks then | | ("[[Гидропоника#Потенция|Потенция]]: %s"):format(seed.potency or 1), |
| for _, unlock in ipairs(research.recipeUnlocks) do
| | ("[[Гидропоника#Урожайность|Урожайность]]: %s"):format(seed.yield), |
| if unlock == recipeId then
| | ("[[Гидропоника#Срок жизни|Срок жизни]]: %s"):format(seed.lifespan), |
| return {
| | ("[[Гидропоника#Созревание|Созревание]]: %s"):format(seed.maturation), |
| name = research.name,
| | ("[[Гидропоника#Производство|Производство]]: %s"):format(seed.production), |
| tier = research.tier,
| | ("[[Гидропоника#Стадии роста|Стадии роста]]: %s"):format(seed.growthStages or 6), |
| discipline = research.discipline
| | } |
| }
| | return table.concat(parts, '<br>') |
| end
| |
| end
| |
| end
| |
| end
| |
| return nil | |
| end | | end |
|
| |
|
| local function getRecipePackDetails(packId) | | local function formatConditions(seed) |
| for _, pack in ipairs(recipePackData) do | | local parts = { |
| if pack.id == packId then | | ("[[Гидропоника#Потребление воды|Вода]]: %s"):format(seed.waterConsumption or 0.5), |
| return pack
| | ("[[Гидропоника#Потребление нутриентов|Удобрение]]: %s"):format(seed.nutrientConsumption or 0.75), |
| end | | ("[[Гидропоника#Оптимальная температура|Темп.]]: %.2f°C"):format(kelvinToCelsius(seed.idealHeat or 293)), |
| end | | } |
| return nil | | return table.concat(parts, '<br>') |
| end | | end |
|
| |
|
| -----------------------------------------------------------
| | local function formatHarvestType(seed) |
| -- Функция для сбора рецептов из станка | | return seed.harvestRepeat and "[[Гидропоника#Тип урожая|" .. tostring(seed.harvestRepeat) .. "]]" or "-" |
| -----------------------------------------------------------
| | end |
| local function getLatheRecipes(lathe) | | local function formatHarvestType(seed) |
| local recipes = {} | | local harvestRepeat = seed.harvestRepeat |
| local chemMapping = {} | | if harvestRepeat == "Repeat" then |
| for id, chem in pairs(chemData) do | | return "[[Гидропоника#Тип урожая|Многолетнее]]" |
| chemMapping[id] = chem.name | | elseif harvestRepeat == "SelfHarvest" then |
| | return "[[Гидропоника#Тип урожая|Самосбор]]" |
| | else |
| | return "[[Гидропоника#Тип урожая|Однолетнее]]" |
| end | | end |
| | end |
|
| |
|
| -- Вспомогательная функция для обработки одного рецепта
| | local function formatChemicals(seed) |
| local function processRecipe(recipeId, defaultDiscipline, isEmag)
| | if not seed.chemicals then return "-" end |
| local recipe = getRecipeDetails(recipeId)
| | local list = {} |
| if recipe then
| | for chemId, vals in pairs(seed.chemicals) do |
| if recipe.result then
| | local entry = chemData[chemId] |
| local info = {
| | local chemName = entry and entry.name or chemId |
| id = recipe.id,
| | table.insert(list, string.format( |
| result = recipe.result,
| | "<li>[[Химия#chem_%s|%s]] (мин: %s, макс: %s, дел: %s)</li>", |
| completetime = recipe.completetime,
| | chemId, chemName, vals.Min or 0, vals.Max or 0, vals.PotencyDivisor or 1 |
| 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
| |
| | |
| -- Обработка рецептов для lathe.Lathe (старый и новый формат)
| |
| if lathe.Lathe then
| |
| if lathe.Lathe.staticRecipes then
| |
| for _, recipeId in ipairs(lathe.Lathe.staticRecipes) do
| |
| processRecipe(recipeId, "Static", false)
| |
| end | |
| end
| |
| if lathe.Lathe.dynamicRecipes then
| |
| 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 |
| | return "<ul>" .. table.concat(list) .. "</ul>" |
| | end |
|
| |
|
| if lathe.EmagLatheRecipes then
| | local function formatMutations(seed, data) |
| if lathe.EmagLatheRecipes.emagStaticRecipes then
| | if not seed.mutationPrototypes then return "-" end |
| for _, recipeId in ipairs(lathe.EmagLatheRecipes.emagStaticRecipes) do
| | local list = {} |
| processRecipe(recipeId, "Static", true)
| | for _, mu in ipairs(seed.mutationPrototypes) do |
| end
| | local target = findSeedById(mu, data) |
| end
| | if target and target.productPrototypes then |
| if lathe.EmagLatheRecipes.emagDynamicRecipes then
| | for _, prod in ipairs(target.productPrototypes) do |
| for _, recipeId in ipairs(lathe.EmagLatheRecipes.emagDynamicRecipes) do
| | table.insert(list, ("<li>{{Предмет|%s|link=Гидропоника#{{#invoke:Entity Lookup|getname|%s}}}}</li>"):format(prod, prod)) |
| processRecipe(recipeId, "Dynamic", true)
| |
| end
| |
| 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
| |
| if lathe.EmagLatheRecipes.emagDynamicPacks then | |
| for _, packId in ipairs(lathe.EmagLatheRecipes.emagDynamicPacks) 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", true)
| |
| end
| |
| end
| |
| end | | end |
| end | | end |
| end | | end |
| | | return "<ul>" .. table.concat(list) .. "</ul>" |
| sortRecipesByPriority(recipes) | |
| return recipes
| |
| end | | end |
|
| |
|
| -----------------------------------------------------------
| | local function generateHeader() |
| -- Общие таблицы для форматирования вывода
| | return [[ |
| ----------------------------------------------------------- | | {| id="BOTANY" class="wikitable sortable mw-collapsible" style="width:100%;" |
| local disciplineMapping = {
| | ! rowspan="2" style="width:10%;" | Плод |
| Arsenal = "Арсенал",
| | ! rowspan="2" class="unsortable" style="width:5%;" | Семена |
| Industrial = "Промышленность",
| | ! rowspan="2" class="unsortable" style="width:5%;" | Растение |
| Experimental = "Экспериментальное",
| | ! colspan="3" class="unsortable" style="width:30%;" id="no-highlight" | Характеристики |
| CivilianServices = "Обслуживание персонала"
| | ! rowspan="2" class="unsortable" style="width:30%;" | Содержит вещества |
| }
| | ! rowspan="2" style="width:20%;" | Мутации |
| local tierColors = {
| | |- |
| [1] = "#54d554",
| | ! style="width:10%;" class="unsortable" | Рост |
| [2] = "#ed9000",
| | ! style="width:10%;" class="unsortable" | Условия |
| [3] = "#d72a2a"
| | ! style="width:5%;" class="unsortable" | Тип сбора |
| }
| | ]] |
| 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 | | end |
|
| |
|
| -----------------------------------------------------------
| | local function generateFooter() |
| -- Функция для формирования строки рецепта
| | return "|}" |
| -----------------------------------------------------------
| |
| local function formatRecipe(recipe, timeMultiplier, materialUseMultiplier, itemMode) | |
| local out = "" | |
| local scaledTime = recipe.completetime * timeMultiplier
| |
| out = out .. '{{Шаблон:Prototypes/Машина/Станок|product=' .. recipe.result
| |
| if itemMode then
| |
| out = out .. '|no-product=1'
| |
| end
| |
| 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
| |
| 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
| |
| | |
| out = out .. '}}'
| |
| return out
| |
| end
| |
| | |
| -----------------------------------------------------------
| |
| -- Функция для поиска и вывода рецептов по ID станка
| |
| -----------------------------------------------------------
| |
| function p.lathe(frame)
| |
| local latheId = frame.args[1] or ""
| |
| if latheId == "" then
| |
| return '<div style="color:red;">Не указан ID станка.</div>'
| |
| end
| |
| | |
| local lathe = nil
| |
| for _, data in ipairs(latheData) do
| |
| if data.id == latheId then
| |
| lathe = data
| |
| break
| |
| end
| |
| end
| |
| | |
| if not lathe then
| |
| 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
| |
| out = out .. formatRecipe(recipe, timeMultiplier, materialUseMultiplier)
| |
| end
| |
| | |
| return mw.getCurrentFrame():preprocess(out)
| |
| end | | end |
|
| |
|
| -----------------------------------------------------------
| | function p.table(frame) |
| -- Функция для поиска и вывода рецептов по ID предмета
| | local data = mw.loadData("Модуль:IanComradeBot/prototypes/seeds.json/data") |
| -----------------------------------------------------------
| | local rows = {} |
| function p.item(frame) | |
| local itemId = frame.args[1] or "" | |
| if itemId == "" then
| |
| return '<div style="color:red;">Не указан ID предмета.</div>'
| |
| end | |
|
| |
|
| local out = '{| class="wikitable"' .. "\n! Станок ID\n! Рецепт\n" | | for _, seed in ipairs(data) do |
| local foundAny = false
| | local prodId = seed.productPrototypes[1] |
| | local seedId = seed.packetPrototype |
| | local seedName = string.format('{{#invoke:Entity Lookup|getname|%s}}', seedId) |
|
| |
|
| for _, lathe in ipairs(latheData) do
| | local anchor = string.format('{{anchor|%s}}', seedName) |
| local recipes = getLatheRecipes(lathe) | | local fruitImg = string.format( |
| local materialUseMultiplier = (lathe.Lathe and lathe.Lathe.materialUseMultiplier) or 1 | | '{{Предмет|%s|size=64px|vertical=1|imageTooltip=1|link=%s}}', |
| local timeMultiplier = (lathe.Lathe and lathe.Lathe.timeMultiplier) or 1 | | prodId, seedName |
| | ) |
| | local seedImg = string.format( |
| | '{{Предмет|%s|size=64px|vertical=1|imageTooltip=1|l=|link=%s}}', |
| | seedId, seedName |
| | ) |
| | local plantImg = string.format( |
| | '{{Предмет|%s-harvest|size=64px|l=|link=%s}}', |
| | seedId, seedName |
| | ) |
|
| |
|
| for _, recipe in ipairs(recipes) do | | local colGrowth = formatCharacteristics(seed) |
| if recipe.id == itemId or recipe.result == itemId then
| | local colConditions = formatConditions(seed) |
| foundAny = true
| | local colHarvest = formatHarvestType(seed) |
| out = out .. '|-' .. "\n"
| | local colChemicals = formatChemicals(seed) |
| out = out .. '| [[File:' .. lathe.id .. '.png|32x32px|link=]] [[{{#invoke:Entity Lookup|getname|' .. lathe.id .. '}}|{{#invoke:Entity Lookup|getname|' .. lathe.id .. '}}]]' .. "\n"
| | local colMutations = formatMutations(seed, data) |
| out = out .. '| ' .. formatRecipe(recipe, timeMultiplier, materialUseMultiplier, true) .. "\n"
| |
| end
| |
| end
| |
| end
| |
|
| |
|
| if not foundAny then
| | local row = frame:preprocess(string.format( |
| return '<div style="color:red;">Рецепт для предмета с ID "' .. itemId .. '" не найден во всех станках.</div>' | | [[|- |
| | ! %s |
| | ! %s |
| | ! %s |
| | | %s |
| | | %s |
| | | %s |
| | | %s |
| | | %s ]], |
| | fruitImg, seedImg, plantImg, |
| | colGrowth, colConditions, colHarvest, |
| | colChemicals, colMutations |
| | )) |
| | table.insert(rows, row) |
| end | | end |
|
| |
|
| out = out .. '|}' | | return generateHeader() .. table.concat(rows, '\n') .. '\n' .. generateFooter() |
| return mw.getCurrentFrame():preprocess(out)
| |
| end | | end |
|
| |
|
| -----------------------------------------------------------
| | function p.main(frame) |
| -- Функция для поиска и вывода рецептов по ID материала
| | local args = frame.args |
| -----------------------------------------------------------
| | local id = args[1] |
| function p.material(frame) | | local mode = mw.text.trim(args[2] or ""):lower() |
| local materialId = frame.args[1] or "" | | local seed = findSeedById(id, seedsData) |
| if materialId == "" then | | if not seed then return "" end |
| return '<div style="color:red;">Не указан ID материала.</div>'
| |
| end | |
| | |
| local out = '{| class="wikitable"' .. "\n! Станок\n! Рецепт\n" | |
| local foundAny = false
| |
|
| |
|
| for _, lathe in ipairs(latheData) do | | if mode == "growth" then |
| local recipes = getLatheRecipes(lathe)
| | return formatCharacteristics(seed) |
| local materialUseMultiplier = (lathe.Lathe and lathe.Lathe.materialUseMultiplier) or 1 | | elseif mode == "conditions" then |
| local timeMultiplier = (lathe.Lathe and lathe.Lathe.timeMultiplier) or 1
| | return formatConditions(seed) |
| local matchingRecipes = {}
| | elseif mode == "harvest" then |
| | | return formatHarvestType(seed) |
| for _, recipe in ipairs(recipes) do | | elseif mode == "chemicals" then |
| if recipe.materials then
| | return formatChemicals(seed) |
| for matId, _ in pairs(recipe.materials) do
| | elseif mode == "mutations" then |
| if matId == materialId then
| | return formatMutations(seed, seedsData) |
| table.insert(matchingRecipes, recipe)
| | else |
| break
| | return "" |
| end
| |
| end
| |
| end
| |
| end | |
| | |
| if #matchingRecipes > 0 then
| |
| foundAny = true
| |
| local rowspan = #matchingRecipes
| |
| for i, recipe in ipairs(matchingRecipes) do
| |
| out = out .. '|-\n'
| |
| if i == 1 then
| |
| out = out .. string.format('| rowspan="%d"|[[File:%s.png|32x32px|link=]] [[{{#invoke:Entity Lookup|getname|%s}}|{{#invoke:Entity Lookup|getname|%s}}]]\n', rowspan, lathe.id, lathe.id, lathe.id)
| |
| end
| |
| out = out .. '| ' .. formatRecipe(recipe, timeMultiplier, materialUseMultiplier, false) .. "\n"
| |
| end
| |
| end
| |
| end | |
| | |
| if not foundAny then
| |
| return '<div style="color:red;">Для материала с ID "' .. materialId .. '" рецептов не найдено во всех станках.</div>' | |
| end | | end |
|
| |
| out = out .. '|}'
| |
| return mw.getCurrentFrame():preprocess(out)
| |
| end | | end |
|
| |
|
| return p | | return p |