|
|
| (не показана 241 промежуточная версия этого же участника) |
| Строка 1: |
Строка 1: |
| -- Загрузка данных
| |
| 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 chemData = mw.loadData("Модуль:IanComradeBot/chem prototypes.json/data") -- Функция для загрузки данных химических веществ
| |
|
| |
| local p = {} | | local p = {} |
| | | local getArgs = require('Module:Arguments').getArgs |
| -- Функция для форматирования времени
| |
| 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 '0 сек.'
| |
| end
| |
| end
| |
| | |
| -- Функция для сортировки рецептов
| |
| 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
| |
|
| |
|
| function p.main(frame) | | function p.main(frame) |
| -- Подключение CSS
| | local args = getArgs(frame, { removeBlanks = false }) |
| local cssLink = frame:extensionTag('templatestyles', '', {
| | local name = args[1] or "" |
| src = 'Шаблон:Prototypes/Машина/Станок/styles.css'
| | local attributes = args[2] or "" |
| })
| | if name == "" then |
| | | return "<span class=\"error\">Ошибка: не указано имя файла.</span>" |
| local latheId = frame.args[1] or ""
| | end |
| if latheId == "" then
| | local ext = (args["ext"] or "png"):gsub("^%.", "") |
| return '<div style="color:red;">Не указан ID станка.</div>'
| | local namespace = args["namespace"] or "Файл" |
| end
| | local max = tonumber(args["max"]) or 50 |
| | | local include_base = (args["base"] ~= "no") |
| 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
| |
| | |
| if type(materialData) ~= "table" then
| |
| return '<div style="color:red;">Ошибка: данные о материалах не загружены!</div>'
| |
| end
| |
|
| |
| local materialMapping = {}
| |
| for key, material in pairs(materialData) do
| |
| if type(material) == "table" and material.id then
| |
| materialMapping[material.id] = material.stackEntity or material.id
| |
| else
| |
| mw.log("Ошибка в materialData: " .. tostring(key) .. " -> " .. tostring(material))
| |
| end
| |
| end
| |
| | |
| local chemMapping = {}
| |
| for id, chem in pairs(chemData) do
| |
| chemMapping[id] = chem.name
| |
| end
| |
| | |
| local out = cssLink
| |
| local recipes = {}
| |
| | |
| local function getRecipeDetails(recipeId)
| |
| for _, recipe in ipairs(recipeData) do
| |
| if recipe.id == recipeId then
| |
| return recipe
| |
| end
| |
| end
| |
| return nil
| |
| end
| |
| | |
| local function findInResearch(recipeId)
| |
| for _, research in ipairs(researchData) do
| |
| if research.technology and research.technology.recipeUnlocks then
| |
| for _, unlock in ipairs(research.technology.recipeUnlocks) do
| |
| if unlock == recipeId then
| |
| return {
| |
| name = research.technology.name,
| |
| tier = research.technology.tier,
| |
| discipline = research.technology.discipline
| |
| }
| |
| end
| |
| end
| |
| end
| |
| end
| |
| return nil
| |
| end
| |
| | |
| -- Обработка staticRecipes
| |
| if lathe.Lathe.staticRecipes then
| |
| for _, recipeId in ipairs(lathe.Lathe.staticRecipes) do
| |
| local recipe = getRecipeDetails(recipeId)
| |
| if recipe and recipe.result then
| |
| table.insert(recipes, {
| |
| result = recipe.result,
| |
| completetime = recipe.completetime,
| |
| materials = recipe.materials,
| |
| discipline = "Static",
| |
| tier = 0
| |
| })
| |
| elseif recipe and recipe.resultReagents then
| |
| for reagent, amount in pairs(recipe.resultReagents) do
| |
| local reagentName = chemMapping[reagent] or reagent
| |
| table.insert(recipes, {
| |
| result = reagentName .. "|amount=" .. amount .. "ед.|mode-chem=1",
| |
| completetime = recipe.completetime,
| |
| materials = recipe.materials,
| |
| discipline = "Static",
| |
| tier = 0
| |
| })
| |
| break
| |
| end
| |
| else
| |
| out = out .. '<div style="color:red;">Ошибка: Рецепт с ID "' .. recipeId .. '" не найден или поля result/resultReagents отсутствуют.</div>'
| |
| end
| |
| end
| |
| end
| |
| | |
| -- Обработка dynamicRecipes
| |
| if lathe.Lathe.dynamicRecipes then
| |
| for _, recipeId in ipairs(lathe.Lathe.dynamicRecipes) do
| |
| local recipe = getRecipeDetails(recipeId)
| |
| if recipe then
| |
| local researchInfo = findInResearch(recipeId)
| |
| if researchInfo then
| |
| table.insert(recipes, {
| |
| result = recipe.result,
| |
| completetime = recipe.completetime,
| |
| materials = recipe.materials,
| |
| discipline = researchInfo.discipline,
| |
| tier = researchInfo.tier,
| |
| researchName = researchInfo.name
| |
| })
| |
| end
| |
| end
| |
| end
| |
| end
| |
| | |
| -- Обработка emagStaticRecipes
| |
| if lathe.EmagLatheRecipes and lathe.EmagLatheRecipes.emagStaticRecipes then
| |
| for _, recipeId in ipairs(lathe.EmagLatheRecipes.emagStaticRecipes) do
| |
| local recipe = getRecipeDetails(recipeId)
| |
| if recipe then
| |
| table.insert(recipes, {
| |
| result = recipe.result,
| |
| completetime = recipe.completetime,
| |
| materials = recipe.materials,
| |
| discipline = "Static",
| |
| tier = 0,
| |
| isEmag = true
| |
| })
| |
| end
| |
| end
| |
| end
| |
| | |
| -- Обработка emagDynamicRecipes
| |
| if lathe.EmagLatheRecipes and lathe.EmagLatheRecipes.emagDynamicRecipes then
| |
| for _, recipeId in ipairs(lathe.EmagLatheRecipes.emagDynamicRecipes) do
| |
| local recipe = getRecipeDetails(recipeId)
| |
| if recipe then
| |
| local researchInfo = findInResearch(recipeId)
| |
| if researchInfo then
| |
| table.insert(recipes, {
| |
| result = recipe.result,
| |
| completetime = recipe.completetime,
| |
| materials = recipe.materials,
| |
| discipline = researchInfo.discipline,
| |
| tier = researchInfo.tier,
| |
| researchName = researchInfo.name,
| |
| isEmag = true
| |
| })
| |
| end
| |
| end
| |
| end
| |
| end
| |
| | |
| sortRecipesByPriority(recipes)
| |
| | |
| -- Таблица для перевода названий дисциплин
| |
| local disciplineMapping = {
| |
| Arsenal = "Арсенал",
| |
| Industrial = "Промышленность",
| |
| Experimental = "Экспериментальное",
| |
| CivilianServices = "Обслуживание персонала"
| |
| }
| |
| | |
| -- Таблица для цветов по уровням
| |
| local tierColors = {
| |
| [1] = "#54d554",
| |
| [2] = "#ed9000",
| |
| [3] = "#d72a2a"
| |
| }
| |
| | |
| local materialUseMultiplier = lathe.Lathe.materialUseMultiplier or 1
| |
| local timeMultiplier = lathe.Lathe.timeMultiplier or 1
| |
| | |
| for _, recipe in ipairs(recipes) do
| |
| local scaledTime = format_seconds_to_short_string(recipe.completetime * timeMultiplier)
| |
| out = out .. '{{Шаблон:Prototypes/Машина/Станок|product=' .. recipe.result
| |
| out = out .. '|complete-time=' .. scaledTime
| |
| out = out .. '|materials='
| |
|
| |
|
| if recipe.materials and next(recipe.materials) then
| | local found = {} |
| for material, amount in pairs(recipe.materials) do
| |
| local stackEntity = materialMapping[material] or material
| |
| local scaledAmount = (amount * materialUseMultiplier) / 100
| |
| out = out .. '<b>[[File:' .. stackEntity .. '.png|32x32px|link=]] ' .. scaledAmount .. ' {{#invoke:Entity Lookup|getname|' .. stackEntity .. '}}</b>'
| |
| end
| |
| else
| |
| out = out .. 'Нет данных о материалах'
| |
| end
| |
|
| |
|
| -- Информация об исследовании
| | if include_base then |
| if recipe.discipline ~= "Static" then
| | local t = mw.title.new("Файл:" .. name .. "." .. ext) |
| local tierColor = tierColors[recipe.tier] or "#FFFFFF"
| | if t and t.exists then |
| local disciplineName = disciplineMapping[recipe.discipline] or "Неизвестная дисциплина"
| | table.insert(found, "") |
| | end |
| | end |
|
| |
|
| out = out .. '|info=<div style="font-weight:600;"><span style="margin:8px;">[[File:' .. recipe.discipline .. '.png|16x16px|link=]]</span> [[Руководство по исследованию и разработке|' .. disciplineName
| | for i = 1, max do |
| out = out .. ']], уровень: <span style="color: ' .. tierColor .. '">' .. recipe.tier .. '</span> </div>'
| | local t = mw.title.new("Файл:" .. name .. "-" .. i .. "." .. ext) |
| end
| | if t and t.exists then |
| | table.insert(found, "-" .. i) |
| | end |
| | end |
|
| |
|
| -- Пометка при взломе EMAG
| | if #found == 0 then |
| if recipe.isEmag then
| | return "" |
| out = out .. '|mode-emag=1'
| | end |
| end
| |
|
| |
|
| -- Пометка для исследуемой технологии
| | local before = "[[" .. namespace .. ":" .. name |
| if recipe.discipline ~= "Static" then
| | local after = "." .. ext .. "|" .. attributes .. "]]" |
| out = out .. '|mode-research=1'
| |
| end
| |
|
| |
|
| out = out .. '}}'
| | local parts = {} |
| end
| | table.insert(parts, "<choose before=\"" .. before .. "\" after=\"" .. after .. "\">") |
| | for _, suf in ipairs(found) do |
| | table.insert(parts, "<option>" .. suf .. "</option>") |
| | end |
| | table.insert(parts, "</choose>") |
|
| |
|
| return mw.getCurrentFrame():preprocess(out)
| | return frame:preprocess(table.concat(parts, "\n")) |
| end | | end |
|
| |
|
| return p | | return p |
Для документации этого модуля может быть создана страница Модуль:Песочница/Pok/doc
local p = {}
local getArgs = require('Module:Arguments').getArgs
function p.main(frame)
local args = getArgs(frame, { removeBlanks = false })
local name = args[1] or ""
local attributes = args[2] or ""
if name == "" then
return "<span class=\"error\">Ошибка: не указано имя файла.</span>"
end
local ext = (args["ext"] or "png"):gsub("^%.", "")
local namespace = args["namespace"] or "Файл"
local max = tonumber(args["max"]) or 50
local include_base = (args["base"] ~= "no")
local found = {}
if include_base then
local t = mw.title.new("Файл:" .. name .. "." .. ext)
if t and t.exists then
table.insert(found, "")
end
end
for i = 1, max do
local t = mw.title.new("Файл:" .. name .. "-" .. i .. "." .. ext)
if t and t.exists then
table.insert(found, "-" .. i)
end
end
if #found == 0 then
return ""
end
local before = "[[" .. namespace .. ":" .. name
local after = "." .. ext .. "|" .. attributes .. "]]"
local parts = {}
table.insert(parts, "<choose before=\"" .. before .. "\" after=\"" .. after .. "\">")
for _, suf in ipairs(found) do
table.insert(parts, "<option>" .. suf .. "</option>")
end
table.insert(parts, "</choose>")
return frame:preprocess(table.concat(parts, "\n"))
end
return p