Модуль:Entity Sprite: различия между версиями

мНет описания правки
Нет описания правки
 
(не показаны 43 промежуточные версии этого же участника)
Строка 1: Строка 1:
local dataModule = mw.loadData("Модуль:Entity Sprite/data")
-- Загрузка данных
if type(dataModule) ~= "table" then
local JsonPaths = require('Module:JsonPaths')
    return "Ошибка: Невозможно загрузить данные."
local spriteData = mw.loadData(JsonPaths.get("prototype/sprite.json"))
end


local p = {}
local p = {}


p.data = dataModule.data
local function normalizeSpritePath(path)
if path == nil then
return nil
end
 
path = mw.text.trim(tostring(path))
path = path:gsub("^/Textures/?", "")
 
return path
end


-- Проверка равенства двух таблиц
-- Функция получения таблицы данных
local function deepEqual(t1, t2)
local function getIdTable()
    if t1 == t2 then return true end
if type(spriteData) == "table" and type(spriteData.id) == "table" then
    if type(t1) ~= "table" or type(t2) ~= "table" then return false end
return spriteData.id
end
return nil
end


    -- Если это массивы, проверяем их содержимое без учета порядка
-- Функция для получения таблицы данных
    local function isArray(t)
function p.getData()
        local i = 0
return getIdTable() or {}
        for _ in pairs(t) do
end
            i = i + 1
            if t[i] == nil then return false end
        end
        return true
    end


    if isArray(t1) and isArray(t2) then
-- Функция получения пути спрайта:
        if #t1 ~= #t2 then return false end
-- 1) сначала entry.sprite
        local matched = {}
-- 2) потом первый layers[*].sprite
        for _, v1 in ipairs(t1) do
local function getSpritePath(entry)
            local found = false
if not entry then
            for j, v2 in ipairs(t2) do
return nil
                if not matched[j] and deepEqual(v1, v2) then
end
                    matched[j] = true
                    found = true
                    break
                end
            end
            if not found then return false end
        end
        return true
    end


    -- Если это таблицы, проверяем их содержимое
if entry.sprite then
    for k, v in pairs(t1) do
return normalizeSpritePath(entry.sprite)
        if t2[k] == nil or not deepEqual(v, t2[k]) then
end
            return false
        end
    end


    for k, v in pairs(t2) do
if type(entry.layers) == "table" then
        if t1[k] == nil then
for _, layer in ipairs(entry.layers) do
            return false
if layer and layer.sprite then
        end
return normalizeSpritePath(layer.sprite)
    end
end
end
end


    return true
return nil
end
end


-- Получение пути спрайта
-- Проверка visible
local function getSpritePath(entry)
local function isLayerVisible(layer)
    if entry.Sprite and entry.Sprite.sprite then
if not layer then
        return entry.Sprite.sprite
return false
    elseif entry.Icon and entry.Icon.sprite then
end
        return entry.Icon.sprite
return layer.visible ~= false
    elseif entry.Sprite and entry.Sprite.layers then
        for _, layer in ipairs(entry.Sprite.layers) do
            if layer.sprite then
                return layer.sprite
            end
        end
    end
    return nil
end
end


-- Генерация шаблона repeat с оптимизированным вызовом preprocess (один раз в конце)
-- Функция получения списка состояний с учётом переопределяющего sprite в слое
local function generateRepeatTemplate(data)
local function getSpriteStates(entry)
    local spriteGroups = {}
local result = {}
local spritePath = getSpritePath(entry)


    for _, entry in ipairs(data) do
if entry and type(entry.layers) == "table" then
        local found = false
for _, layer in ipairs(entry.layers) do
        for key, group in pairs(spriteGroups) do
if isLayerVisible(layer) and layer.state then
            if deepEqual(entry.Sprite, group[1].Sprite) and
table.insert(result, {
              deepEqual(entry.EntityStorageVisuals, group[1].EntityStorageVisuals) and
state = tostring(layer.state),
              deepEqual(entry.Icon, group[1].Icon) then
sprite = normalizeSpritePath(layer.sprite or spritePath)
                table.insert(group, entry)
})
                found = true
end
                break
end
            end
elseif entry and entry.state and spritePath then
        end
table.insert(result, {
state = tostring(entry.state),
sprite = spritePath
})
end


        if not found then
if #result == 0 and spritePath then
            spriteGroups[entry.id] = {entry}
table.insert(result, {
        end
state = "icon",
    end
sprite = spritePath
})
end


    local result = {}
return (#result > 0) and result or nil
    for _, group in pairs(spriteGroups) do
end
        if #group > 1 then
            local idLinks = {}
            for _, entry in ipairs(group) do
                table.insert(idLinks, "[[:Файл:" .. entry.id .. ".png]]")
            end
            local firstId = group[1].id
            table.insert(result, "{{Entity Sprite/Repeat|" .. table.concat(idLinks, " ") .. "|" .. firstId .. "}}")
        end
    end


    return mw.getCurrentFrame():preprocess(table.concat(result, "\n"))
-- Функция генерации шаблона по записи (mode: image, path, state)
end
function p.main(frame)
local mode = frame.args[1]
local id = frame.args[2]


-- Создаём индекс для путей
if not mode or not id then
local function createSpritePathIndex(data)
return "Ошибка: отсутствует режим или ID"
    local index = {}
end
    for _, entry in ipairs(data) do
        local spritePath = getSpritePath(entry)
        if spritePath then
            index[spritePath] = entry.id
        end
    end
    return index
end


local function generateTemplate(entry, param, secondaryParam, data, spritePathIndex)
local data = getIdTable()
    local spritePath = getSpritePath(entry)
if not data then
    if not entry.id or not spritePath then
return "Ошибка: неверный формат JSON"
        return nil
end
    end


    if param == "image" then
if mode == "image" or mode == "state" then
        if secondaryParam then
local entry = data[id]
            if tostring(entry.id) == tostring(secondaryParam) then
if not entry then
                return spritePath
return "Ошибка: ID не найден"
            end
end
            return nil
        else
            return mw.getCurrentFrame():preprocess("{{Entity Sprite/Image|" .. entry.id .. "|" .. spritePath .. "}}")
        end
    elseif param == "path" then
        if secondaryParam then
            local id = spritePathIndex[secondaryParam]
            if id then
                return id
            end
            return nil
        else
            return mw.getCurrentFrame():preprocess("{{Entity Sprite/Path|" .. entry.id .. "|" .. spritePath .. "}}")
        end
    end


    return nil
if mode == "image" then
end
local sprite = getSpritePath(entry)
return sprite or "Ошибка: спрайт не найден"
elseif mode == "state" then
local states = getSpriteStates(entry)
if not states then
return ""
end


-- Генерация шаблона по умолчанию
local baseUrl = JsonPaths.git() .. "/Resources/Textures/"
local function generateDefaultTemplate(data, params)
local links = {}
    local id = params.Id
    local description = params.Description or ""
    local servers = params.Servers or ""
    local source = params.Source or ""
    local tags = params.Tags or ""


    local spritePath = nil
for _, item in ipairs(states) do
    local path = params.Path
local spritePath = item.sprite
local stateName = item.state


    -- Поиск записи с указанным ID
if spritePath then
    local entry = nil
local url = baseUrl .. normalizeSpritePath(spritePath) .. "/" .. stateName .. ".png"
    if id and id ~= "" then
table.insert(links, "[" .. url .. " " .. stateName .. "]")
        for _, item in ipairs(data) do
else
            if tostring(item.id) == tostring(id) then
table.insert(links, stateName .. " Error: sprite not found")
                entry = item
end
                break
end
            end
        end
    end


    -- Если запись не найдена, ничего не выводим
return "(state: " .. table.concat(links, ", ") .. ")"
    if entry then
end
        spritePath = getSpritePath(entry)
end
        if not spritePath then
            return ""
        end
    end
   
    -- Если Path не указан, подставляем путь из User:IanComradeBot/prototypes/entity sprite.json
    if not path or path == "" then
        path = "Resources/Textures/" .. (spritePath or "")
    end


    -- Формирование шаблона
if mode == "path" then
    return mw.getCurrentFrame():preprocess(
local targetPath = normalizeSpritePath(id)
        "{{Файл\n" ..
        "|Описание = " .. description .. "\n" ..
        "|Id      = " .. id .. "\n" ..
        "|Сервера  = " .. servers .. "\n" ..
        "|Источник = " .. source .. "\n" ..
        "|Путь    = " .. path .. "\n" ..
        "|Теги    = " .. tags .. "\n" ..
        "}}\n"
    )
end


function p.main(frame)
for entityId, entry in pairs(data) do
    local param = frame.args[1]
if getSpritePath(entry) == targetPath then
    local secondaryParam = frame.args[2]
return entityId
end
end


    -- Индекс путей
return "Ошибка: путь не найден"
    local spritePathIndex = createSpritePathIndex(data)
end


    if param == "repeat" then
return "Ошибка: неизвестный режим"
        return generateRepeatTemplate(data)
    elseif param == "path" and secondaryParam then
        for _, entry in ipairs(data) do
            local template = generateTemplate(entry, param, secondaryParam, data, spritePathIndex)
            if template then
                return template
            end
        end
        return nil
    elseif param == "image" and secondaryParam then
        for _, entry in ipairs(p.data) do
            if tostring(entry.id) == tostring(secondaryParam) then
                return getSpritePath(entry) or "Ошибка: Спрайт не найден."
            end
        end
        return "Ошибка: ID не найден."
    elseif param == "image" or param == "path" then
        local result = {}
        for _, entry in ipairs(data) do
            local template = generateTemplate(entry, param, secondaryParam, data, spritePathIndex)
            if template then
                table.insert(result, template)
            end
        end
        return table.concat(result, "\n")
    else
        -- Если нет режима, генерируем шаблон по умолчанию
        return generateDefaultTemplate(data, frame.args)
    end
end
end


return p
return p