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

Материал из Space Station 14 Вики
мНет описания правки
мНет описания правки
Строка 50: Строка 50:


local function getSpritePath(entry)
local function getSpritePath(entry)
    local iconField = getInsensitiveKey(entry, "Icon")
     local spriteField = getInsensitiveKey(entry, "Sprite")
     local spriteField = getInsensitiveKey(entry, "Sprite")
     local iconField = getInsensitiveKey(entry, "Icon")
      
 
    if iconField and iconField.sprite then
     if spriteField and spriteField.sprite then
        return iconField.sprite
     elseif spriteField and spriteField.sprite then
         return spriteField.sprite
         return spriteField.sprite
    elseif iconField and iconField.sprite then
        return iconField.sprite
     elseif spriteField and spriteField.layers then
     elseif spriteField and spriteField.layers then
         for _, layer in pairs(spriteField.layers) do
         for _, layer in pairs(spriteField.layers) do
Строка 68: Строка 68:


local function getSpriteState(entry)
local function getSpriteState(entry)
    local iconBlock = getInsensitiveKey(entry, "Icon")
    if iconBlock and iconBlock.state then
        return iconBlock.state
    end
   
     local spriteBlock = getInsensitiveKey(entry, "Sprite")
     local spriteBlock = getInsensitiveKey(entry, "Sprite")
     if spriteBlock then
     if spriteBlock then
Строка 79: Строка 84:
             end
             end
         end
         end
    end
    local iconBlock = getInsensitiveKey(entry, "Icon")
    if iconBlock and iconBlock.state then
        return iconBlock.state
     end
     end



Версия от 15:38, 9 июня 2025

Для документации этого модуля может быть создана страница Модуль:Entity Sprite/all/doc

local p = {}

local function deepEqual(t1, t2)
    if t1 == t2 then return true end
    if type(t1) ~= "table" or type(t2) ~= "table" then return false end

    local function isArray(t)
        local count = 0
        for k in pairs(t) do
            if type(k) ~= "number" then return false end
            count = count + 1
        end
        return count == #t
    end

    if isArray(t1) and isArray(t2) then
        if #t1 ~= #t2 then return false end
        for i = 1, #t1 do
            if not deepEqual(t1[i], t2[i]) 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 or not deepEqual(v, t1[k]) then
            return false
        end
    end

    return true
end

local function getInsensitiveKey(t, target)
    target = target:lower()
    for k, v in pairs(t) do
        if type(k) == "string" and k:lower() == target then
            return v
        end
    end
    return nil
end

local function getSpritePath(entry)
    local iconField = getInsensitiveKey(entry, "Icon")
    local spriteField = getInsensitiveKey(entry, "Sprite")
    
    if iconField and iconField.sprite then
        return iconField.sprite
    elseif spriteField and spriteField.sprite then
        return spriteField.sprite
    elseif spriteField and spriteField.layers then
        for _, layer in pairs(spriteField.layers) do
            if layer.sprite then
                return layer.sprite
            end
        end
    end
    return nil
end

local function getSpriteState(entry)
    local iconBlock = getInsensitiveKey(entry, "Icon")
    if iconBlock and iconBlock.state then
        return iconBlock.state
    end
    
    local spriteBlock = getInsensitiveKey(entry, "Sprite")
    if spriteBlock then
        if spriteBlock.state then
            return spriteBlock.state
        elseif spriteBlock.layers then
            for _, layer in pairs(spriteBlock.layers) do
                if layer.state then
                    return layer.state
                end
            end
        end
    end

    return nil
end

local function generateRepeatTemplate(data)
    local spriteGroups = {}

    for _, entry in pairs(data) do
        local found = false
        for _, group in pairs(spriteGroups) do
            if deepEqual(getInsensitiveKey(entry, "Sprite"), getInsensitiveKey(group[1], "Sprite")) and
               deepEqual(entry.EntityStorageVisuals, group[1].EntityStorageVisuals) and
               deepEqual(getInsensitiveKey(entry, "Icon"), getInsensitiveKey(group[1], "Icon")) then
                table.insert(group, entry)
                found = true
                break
            end
        end

        if not found then
            table.insert(spriteGroups, {entry})
        end
    end

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

    return table.concat(result, "\n")
end

local function generateTemplate(entry, param)
    local spritePath = getSpritePath(entry)
    if not entry.id or not spritePath then
        return nil
    end

    local state = getSpriteState(entry)

    if param == "image" then
        local stateStr = ""
        if state then
            stateStr = " (state: " .. state .. ")"
        end
        return mw.getCurrentFrame():preprocess(
            "{{Entity Sprite/Image|" .. entry.id ..
            "|https://github.com/space-syndicate/space-station-14/blob/master/Resources/Textures/" ..
            spritePath .. stateStr .. "}}"
        )
    end

    return nil
end

function p.main(frame)
    local action = frame.args[1]
    local mode = frame.args[2]

    local dataPage
    if mode == "item" then
        dataPage = "Модуль:IanComradeBot/prototypes/entity sprite/item.json/data"
    elseif mode == "structure" then
        dataPage = "Модуль:IanComradeBot/prototypes/entity sprite/structure.json/data"
    elseif mode == "mob" then
        dataPage = "Модуль:IanComradeBot/prototypes/entity sprite/mob.json/data"
    elseif mode == "other" then
        dataPage = "Модуль:IanComradeBot/prototypes/entity sprite/other.json/data"
    else
        dataPage = "Модуль:IanComradeBot/prototypes/entity sprite.json/data"
    end

    local spriteData = mw.loadData(dataPage)
    if not spriteData or type(spriteData) ~= "table" then
        return "Ошибка: Невозможно загрузить данные из JSON (" .. dataPage .. ")."
    end

    if action == "repeat" then
        return generateRepeatTemplate(spriteData)
    elseif action == "image" or action == "path" then
        local result = {}
        for _, entry in pairs(spriteData) do
            local template = generateTemplate(entry, action)
            if template then
                table.insert(result, template)
            end
        end
        return table.concat(result, "\n")
    else
        return nil
    end
end

return p