Модуль:Песочница/Pok: различия между версиями

Материал из Space Station 14 Вики
Нет описания правки
Нет описания правки
Строка 5: Строка 5:
     if t1 == t2 then return true end
     if t1 == t2 then return true end
     if type(t1) ~= "table" or type(t2) ~= "table" then return false 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
     for k, v in pairs(t1) do
         if t2[k] == nil or not deepEqual(v, t2[k]) then
         if not deepEqual(v, t2[k]) then
             return false
             return false
         end
         end
Строка 32: Строка 13:


     for k, v in pairs(t2) do
     for k, v in pairs(t2) do
         if t1[k] == nil or not deepEqual(v, t1[k]) then
         if not deepEqual(v, t1[k]) then
             return false
             return false
         end
         end
Строка 38: Строка 19:


     return true
     return true
end
local function findFieldInsensitive(tbl, fieldName)
    for key, value in pairs(tbl) do
        if type(key) == "string" and mw.ustring.lower(key) == mw.ustring.lower(fieldName) then
            return value
        end
    end
    return nil
end
end


local function getSpritePath(entry)
local function getSpritePath(entry)
     local iconField = findFieldInsensitive(entry, "Icon")
     return entry.sprite
    local spriteField = findFieldInsensitive(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
end


Строка 70: Строка 28:
     local result = {}
     local result = {}


     local function addState(state, sprite)
     if entry.state and entry.sprite then
         table.insert(result, { state = state, sprite = sprite })
         table.insert(result, {
            state = entry.state,
            sprite = entry.sprite
        })
     end
     end


     local spritePath = getSpritePath(entry)
     return (#result > 0) and result or nil
 
end
    local iconBlock = findFieldInsensitive(entry, "Icon")
    local spriteBlock = findFieldInsensitive(entry, "Sprite")


    if iconBlock and iconBlock.state then
local function getTextureBaseUrl(project)
        addState(iconBlock.state, iconBlock.sprite or spritePath)
     if project == "Goob" then
     else
         return "https://github.com/space-syndicate/Goob-Station/blob/master/Resources/Textures/"
        if spriteBlock and spriteBlock.layers then
            for _, layer in ipairs(spriteBlock.layers) do
                if layer.visible ~= false then
                    local stateName = layer.state or (iconBlock and iconBlock.state) or "icon"  
                    local s = layer.sprite or (iconBlock and iconBlock.sprite) or spritePath
                    addState(stateName, s)
                    break
                end
            end
         elseif spriteBlock and spriteBlock.state then
            addState(spriteBlock.state, spriteBlock.sprite or spritePath)
        end
     end
     end


     if spriteBlock and spriteBlock.layers then
     return "https://github.com/space-syndicate/space-station-14/blob/master/Resources/Textures/"
        for _, layer in ipairs(spriteBlock.layers) do
            local alreadyAdded = false
            for _, r in ipairs(result) do
                local layerState = layer.state or "icon"
                if r.state == layerState then
                    alreadyAdded = true
                    break
                end
            end
 
            if not alreadyAdded and layer.visible ~= false then
                local stateName = layer.state or "icon"
                local s = layer.sprite or (iconBlock and iconBlock.sprite) or spritePath
 
                if s then
                    addState(stateName, s)
                end
            end
        end
    end
 
    if #result == 0 and (iconBlock and (iconBlock.sprite or iconBlock.state) or spritePath) then
        local s = (iconBlock and iconBlock.sprite) or spritePath
        addState("icon", s)
    end
 
    return (#result > 0) and result or nil
end
end


local function generateRepeatTemplate(data)
local function generateRepeatTemplate(data, project)
     local spriteGroups = {}
     local spriteGroups = {}


     for _, entry in pairs(data) do
     for id, entry in pairs(data) do
         local found = false
         local found = false
         for _, group in pairs(spriteGroups) do
         for _, group in pairs(spriteGroups) do
             if deepEqual(findFieldInsensitive(entry, "Sprite"), findFieldInsensitive(group[1], "Sprite")) and
             local g = group[1]
              deepEqual(entry.EntityStorageVisuals, group[1].EntityStorageVisuals) and
 
              deepEqual(findFieldInsensitive(entry, "Icon"), findFieldInsensitive(group[1], "Icon")) then
            if entry.sprite == g.sprite and entry.state == g.state then
                 table.insert(group, entry)
                 table.insert(group, { id = id, entry = entry })
                 found = true
                 found = true
                 break
                 break
Строка 142: Строка 63:


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


     local result = {}
     local result = {}
     for _, group in pairs(spriteGroups) do
     for _, group in pairs(spriteGroups) do
         if #group > 1 then
         if #group > 1 then
             local idLinks = {}
             local idLinks = {}
             for _, entry in pairs(group) do
 
                 table.insert(idLinks, "[[:Файл:" .. entry.id .. ".png]]")
             for _, obj in pairs(group) do
                local id = obj.id
                local prefix = (project ~= "" and JsonPaths.has(id)) and (project .. ":") or ""
                 table.insert(idLinks, "[[:Файл:" .. prefix .. id .. ".png]]")
             end
             end
             table.insert(result, mw.getCurrentFrame():preprocess(
             table.insert(result, mw.getCurrentFrame():preprocess(
                 "{{Entity Sprite/Repeat|" .. table.concat(idLinks, " ") .. "|" .. group[1].id .. "}}"
                 "{{Entity Sprite/Repeat|" ..
                table.concat(idLinks, " ") ..
                "|" .. group[1].id ..
                "}}"
             ))
             ))
         end
         end
Строка 162: Строка 93:
end
end


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


     if param == "image" then
     local prefix = (project ~= "" and JsonPaths.has(id)) and (project .. ":") or ""
        local states = getSpriteStates(entry)
 
        local stateStr = ""
    local states = getSpriteStates(entry)
        if states then
    local stateStr = ""
            local baseUrl = "https://github.com/space-syndicate/space-station-14/blob/master/Resources/Textures/"
 
            local links = {}
    if states then
            for _, item in ipairs(states) do
        local links = {}
                local spritePath = item.sprite
        for _, item in ipairs(states) do
                local stateName = item.state
            local url = baseUrl .. item.sprite .. "/" .. item.state .. ".png"
                local url = baseUrl .. spritePath .. "/" .. stateName .. ".png"
            table.insert(links, "[" .. url .. " " .. item.state .. "]")
                table.insert(links, "[" .. url .. " " .. stateName .. "]")
            end
            stateStr = table.concat(links, ", ")
         end
         end
         return mw.getCurrentFrame():preprocess(
         stateStr = table.concat(links, ", ")
            "{{Entity Sprite/Image|" .. entry.id ..
            "|https://github.com/space-syndicate/space-station-14/blob/master/Resources/Textures/" .. spritePath ..
            "|" .. stateStr .. "}}"
        )
     end
     end


     return nil
     return mw.getCurrentFrame():preprocess(
        "{{Entity Sprite/Image|" ..
        prefix .. id ..
        "|" .. baseUrl .. spritePath ..
        "|" .. stateStr ..
        "}}"
    )
end
end


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


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


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


return p
return p

Версия от 22:12, 21 марта 2026

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

local p = {}
local JsonPaths = require('Module:JsonPaths')

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

    for k, v in pairs(t1) do
        if not deepEqual(v, t2[k]) then
            return false
        end
    end

    for k, v in pairs(t2) do
        if not deepEqual(v, t1[k]) then
            return false
        end
    end

    return true
end

local function getSpritePath(entry)
    return entry.sprite
end

local function getSpriteStates(entry)
    local result = {}

    if entry.state and entry.sprite then
        table.insert(result, {
            state = entry.state,
            sprite = entry.sprite
        })
    end

    return (#result > 0) and result or nil
end

local function getTextureBaseUrl(project)
    if project == "Goob" then
        return "https://github.com/space-syndicate/Goob-Station/blob/master/Resources/Textures/"
    end

    return "https://github.com/space-syndicate/space-station-14/blob/master/Resources/Textures/"
end

local function generateRepeatTemplate(data, project)
    local spriteGroups = {}

    for id, entry in pairs(data) do
        local found = false

        for _, group in pairs(spriteGroups) do
            local g = group[1]

            if entry.sprite == g.sprite and entry.state == g.state then
                table.insert(group, { id = id, entry = entry })
                found = true
                break
            end
        end

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

    local result = {}

    for _, group in pairs(spriteGroups) do
        if #group > 1 then
            local idLinks = {}

            for _, obj in pairs(group) do
                local id = obj.id
                local prefix = (project ~= "" and JsonPaths.has(id)) and (project .. ":") or ""
                table.insert(idLinks, "[[:Файл:" .. prefix .. 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(id, entry, baseUrl, project)
    local spritePath = getSpritePath(entry)
    if not id or not spritePath then
        return nil
    end

    local prefix = (project ~= "" and JsonPaths.has(id)) and (project .. ":") or ""

    local states = getSpriteStates(entry)
    local stateStr = ""

    if states then
        local links = {}
        for _, item in ipairs(states) do
            local url = baseUrl .. item.sprite .. "/" .. item.state .. ".png"
            table.insert(links, "[" .. url .. " " .. item.state .. "]")
        end
        stateStr = table.concat(links, ", ")
    end

    return mw.getCurrentFrame():preprocess(
        "{{Entity Sprite/Image|" ..
        prefix .. id ..
        "|" .. baseUrl .. spritePath ..
        "|" .. stateStr ..
        "}}"
    )
end

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

    local project = JsonPaths.project()
    local baseUrl = getTextureBaseUrl(project)

    local dataPage = JsonPaths.get("prototype/sprite.json")
    local spriteData = mw.loadData(dataPage)

    if not spriteData or type(spriteData) ~= "table" then
        return "Ошибка загрузки JSON: " .. dataPage
    end

    if action == "repeat" then
        return generateRepeatTemplate(spriteData, project)

    elseif action == "image" then
        local result = {}

        for id, entry in pairs(spriteData) do
            local t = generateTemplate(id, entry, baseUrl, project)
            if t then
                table.insert(result, t)
            end
        end

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

    return nil
end

return p