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

Нет описания правки
Нет описания правки
 
(не показано 47 промежуточных версий этого же участника)
Строка 1: Строка 1:
-- Загрузка данных
local JsonPaths = require('Module:JsonPaths')
local spriteData = mw.loadData(JsonPaths.get("component/Sprite.json"))
local p = {}
local p = {}


-- Загружаем данные из модуля
local function normalizeSpritePath(path)
local data = mw.loadData("Модуль:Entity Sprite/data")
if path == nil then
return nil
end
 
path = mw.text.trim(tostring(path))
path = path:gsub("^/Textures/?", "")
 
return path
end
 
local function normalizeState(state)
if state == nil then
return nil
end
 
state = mw.text.trim(tostring(state))
if state == "" then
return nil
end
 
return state
end
 
-- Функция получения таблицы данных
local function getIdTable()
if type(spriteData) == "table" and type(spriteData.id) == "table" then
return spriteData.id
end
return nil
end


-- Проверка равенства двух таблиц
-- Функция для получения таблицы данных
local function deepEqual(t1, t2)
function p.getData()
    if t1 == t2 then return true end
return getIdTable() or {}
    if type(t1) ~= "table" or type(t2) ~= "table" then return false end
   
    -- Если это массивы, проверяем их содержимое без учета порядка
    local function isArray(t)
        local i = 0
        for _ in pairs(t) do
            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
        local matched = {}
        for _, v1 in ipairs(t1) do
            local found = false
            for j, v2 in ipairs(t2) do
                if not matched[j] and deepEqual(v1, v2) then
                    matched[j] = true
                    found = true
                    break
                end
            end
            if not found then return false end
        end
        return true
    end
   
    -- Если это таблицы, проверяем их содержимое
    for k, v in pairs(t1) do
        if t2[k] == nil or not deepEqual(v, t2[k]) then
            return false
        end
    end
    for k, v in pairs(t2) do
        if t1[k] == nil then
            return false
        end
    end
    return true
end
end


-- Получение пути спрайта
-- Функция получения пути спрайта:
-- 1) сначала entry.sprite
-- 2) потом первый layers[*].sprite
local function getSpritePath(entry)
local function getSpritePath(entry)
    if entry.Sprite and entry.Sprite.sprite then
if not entry then
        return entry.Sprite.sprite
return nil
    elseif entry.Icon and entry.Icon.sprite then
end
        return entry.Icon.sprite
 
    elseif entry.Sprite and entry.Sprite.layers then
if entry.sprite then
        for _, layer in ipairs(entry.Sprite.layers) do
return normalizeSpritePath(entry.sprite)
            if layer.sprite then
end
                return layer.sprite
            end
        end
    end
    return nil
end


-- Генерация шаблона repeat
if type(entry.layers) == "table" then
local function generateRepeatTemplate()
for _, layer in ipairs(entry.layers) do
    local spriteGroups = {}
if layer and layer.sprite then
    for _, entry in ipairs(data) do
return normalizeSpritePath(layer.sprite)
        local found = false
end
        for _, group in pairs(spriteGroups) do
end
            if deepEqual(entry.Sprite, group[1].Sprite) and
end
              deepEqual(entry.EntityStorageVisuals, group[1].EntityStorageVisuals) and
              deepEqual(entry.Icon, group[1].Icon) then
                table.insert(group, entry)
                found = true
                break
            end
        end
        if not found then
            spriteGroups[entry.id] = {entry}
        end
    end


    local result = {}
return nil
    for _, group in pairs(spriteGroups) do
        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, mw.getCurrentFrame():preprocess("{{Entity Sprite/Repeat|" .. table.concat(idLinks, " ") .. "|" .. firstId .. "}}"))
        end
    end
    return table.concat(result, "\n")
end
end


-- Создание индекса путей спрайтов
-- Проверка visible
local function createSpritePathIndex()
local function isLayerVisible(layer)
    local index = {}
if not layer then
    for _, entry in ipairs(data) do
return false
        local spritePath = getSpritePath(entry)
end
        if spritePath then
return layer.visible ~= false
            index[spritePath] = entry.id
        end
    end
    return index
end
end


-- Генерация шаблона по параметрам
-- Функция получения списка состояний с учётом переопределяющего sprite в слое
local function generateTemplate(entry, param, secondaryParam, spritePathIndex)
local function getSpriteStates(entry)
    local spritePath = getSpritePath(entry)
local result = {}
    if not entry.id or not spritePath then
local spritePath = getSpritePath(entry)
        return nil
    end


    if param == "image" then
if entry and type(entry.layers) == "table" then
        if secondaryParam and tostring(entry.id) == tostring(secondaryParam) then
for _, layer in ipairs(entry.layers) do
            return spritePath
if isLayerVisible(layer) and layer.state then
        else
table.insert(result, {
            return mw.getCurrentFrame():preprocess("{{Entity Sprite/Image|" .. entry.id .. "|" .. spritePath .. "}}")
state = tostring(layer.state),
        end
sprite = normalizeSpritePath(layer.sprite or spritePath)
    elseif param == "path" then
})
        if secondaryParam then
end
            return spritePathIndex[secondaryParam] or nil
end
        else
elseif entry and entry.state and spritePath then
            return mw.getCurrentFrame():preprocess("{{Entity Sprite/Path|" .. entry.id .. "|" .. spritePath .. "}}")
table.insert(result, {
        end
state = tostring(entry.state),
    end
sprite = spritePath
    return nil
})
end
 
if #result == 0 and spritePath then
table.insert(result, {
state = "icon",
sprite = spritePath
})
end
 
return (#result > 0) and result or nil
end
end


-- Генерация шаблона по умолчанию
local function findByPathAndState(data, targetPath, targetState)
local function generateDefaultTemplate(params)
for entityId, entry in pairs(data) do
    local id = params.Id
if getSpritePath(entry) == targetPath then
    local description = params.Description or ""
local states = getSpriteStates(entry)
    local servers = params.Servers or ""
if states then
    local source = params.Source or ""
for _, item in ipairs(states) do
    local tags = params.Tags or ""
if normalizeState(item.state) == targetState then
    local path = params.Path
return entityId
end
end
end
end
end


    local entry = nil
return nil
    if id and id ~= "" then
end
        for _, item in ipairs(data) do
            if tostring(item.id) == tostring(id) then
                entry = item
                break
            end
        end
    end


    if entry then
local function findByPath(data, targetPath)
        local spritePath = getSpritePath(entry)
for entityId, entry in pairs(data) do
        if not spritePath then
if getSpritePath(entry) == targetPath then
            return ""
return entityId
        end
end
        if not path or path == "" then
end
            path = "Resources/Textures/" .. spritePath
        end
    end


    return mw.getCurrentFrame():preprocess(
return nil
        "{{Файл\n" ..
        "|Описание = " .. description .. "\n" ..
        "|Id      = " .. id .. "\n" ..
        "|Сервера  = " .. servers .. "\n" ..
        "|Источник = " .. source .. "\n" ..
        "|Путь    = " .. (path or "") .. "\n" ..
        "|Теги    = " .. tags .. "\n" ..
        "}}\n"
    )
end
end


-- Функция генерации шаблона по записи (mode: image, path, state)
function p.main(frame)
function p.main(frame)
    local param = frame.args[1]
local mode = frame.args[1]
    local secondaryParam = frame.args[2]
local id = frame.args[2]
    local spritePathIndex = createSpritePathIndex()
local stateArg = frame.args[3]
 
if not mode or not id then
return "Ошибка: отсутствует режим или ID"
end
 
local data = getIdTable()
if not data then
return "Ошибка: неверный формат JSON"
end
 
if mode == "image" or mode == "state" then
local entry = data[id]
if not entry then
return "Ошибка: ID не найден"
end
 
if mode == "image" then
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 links = {}
 
for _, item in ipairs(states) do
local spritePath = item.sprite
local stateName = item.state
 
if spritePath then
local url = baseUrl .. normalizeSpritePath(spritePath) .. "/" .. stateName .. ".png"
table.insert(links, "[" .. url .. " " .. stateName .. "]")
else
table.insert(links, stateName .. " Error: sprite not found")
end
end
 
return "(state: " .. table.concat(links, ", ") .. ")"
end
end
 
if mode == "path" then
local targetPath = normalizeSpritePath(id)
local targetState = normalizeState(stateArg)
 
if targetState then
local byState = findByPathAndState(data, targetPath, targetState)
if byState then
return JsonPaths.prefixFile(byState)
end
end
 
local byPath = findByPath(data, targetPath)
if byPath then
return JsonPaths.prefixFile(byPath)
end
 
return "Ошибка: путь не найден"
end


    if param == "repeat" then
return "Ошибка: неизвестный режим"
        return generateRepeatTemplate()
    elseif param == "path" and secondaryParam then
        for _, entry in ipairs(data) do
            local template = generateTemplate(entry, param, secondaryParam, spritePathIndex)
            if template then
                return template
            end
        end
        return nil
    elseif param == "image" or param == "path" then
        local result = {}
        for _, entry in ipairs(data) do
            local template = generateTemplate(entry, param, secondaryParam, spritePathIndex)
            if template then
                table.insert(result, template)
            end
        end
        return table.concat(result, "\n")
    else
        return generateDefaultTemplate(frame.args)
    end
end
end


return p
return p