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

мНет описания правки
Нет описания правки
 
(не показано 28 промежуточных версий этого же участника)
Строка 1: Строка 1:
local p = {}
local p = {}
local JsonPaths = require('Module:JsonPaths')


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


    local function isArray(t)
path = mw.text.trim(tostring(path))
        local count = 0
path = path:gsub("^/Textures/?", "")
        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
return path
        if #t1 ~= #t2 then return false end
end
        for i = 1, #t1 do
 
            if not deepEqual(t1[i], t2[i]) then
local function buildEntryKey(entry)
                return false
local parts = {}
            end
 
        end
if entry.sprite then
        return true
table.insert(parts, "sprite=" .. normalizeSpritePath(entry.sprite))
    end
end


    for k, v in pairs(t1) do
if entry.layers and type(entry.layers) == "table" then
        if t2[k] == nil or not deepEqual(v, t2[k]) then
local layers = {}
            return false
        end
    end


    for k, v in pairs(t2) do
for _, layer in ipairs(entry.layers) do
        if t1[k] == nil or not deepEqual(v, t1[k]) then
local layerParts = {}
            return false
        end
    end


    return true
for k, v in pairs(layer) do
layerParts[#layerParts+1] = k .. "=" .. tostring(v)
end
 
table.sort(layerParts)
table.insert(layers, table.concat(layerParts, ","))
end
 
table.sort(layers)
table.insert(parts, "layers=" .. table.concat(layers, "|"))
end
 
return table.concat(parts, ";")
end
end


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


local function getSpritePath(entry)
local function getSpriteStates(entry)
    local iconField = getInsensitiveKey(entry, "Icon")
local result = {}
    local spriteField = getInsensitiveKey(entry, "Sprite")
 
   
if entry.layers and type(entry.layers) == "table" then
    if iconField and iconField.sprite then
for _, layer in ipairs(entry.layers) do
        return iconField.sprite
if layer.visible ~= false then
    elseif spriteField and spriteField.sprite then
table.insert(result, {
        return spriteField.sprite
state = tostring(layer.state or entry.state or ""),
    elseif spriteField and spriteField.layers then
sprite = normalizeSpritePath(layer.sprite or entry.sprite)
        for _, layer in pairs(spriteField.layers) do
})
            if layer.sprite then
end
                return layer.sprite
end
            end
elseif entry.state and entry.sprite then
        end
table.insert(result, {
    end
state = tostring(entry.state or ""),
    return nil
sprite = normalizeSpritePath(entry.sprite)
})
end
 
return (#result > 0) and result or nil
end
 
local function getPrefix(id, project)
if project ~= "" and JsonPaths.has(id, project) then
return project .. ":"
end
return ""
end
 
local function splitCsv(value)
local result = {}
 
if value == nil then
return nil
end
 
value = mw.text.trim(tostring(value))
if value == "" then
return nil
end
 
for part in mw.text.gsplit(value, ",", true) do
local item = mw.text.trim(part)
if item ~= "" then
table.insert(result, item)
end
end
 
return (#result > 0) and result or nil
end
 
local function buildSet(value)
local list = splitCsv(value)
if not list then
return nil
end
 
local set = {}
for _, item in ipairs(list) do
set[item] = true
end
 
return set
end
 
local function getParents(entry)
if not entry then
return nil
end
 
if type(entry.parents) == "table" then
return entry.parents
end
 
if type(entry.parents) == "string" then
return splitCsv(entry.parents)
end
 
return nil
end
 
local function hasAnyParent(parents, set)
if not parents or not set then
return false
end
 
for _, parent in ipairs(parents) do
if set[parent] then
return true
end
end
 
return false
end
 
local function shouldIncludeEntry(entry, whitelistSet, blacklistSet)
local parents = getParents(entry)
 
if whitelistSet then
if not hasAnyParent(parents, whitelistSet) then
return false
end
end
 
if blacklistSet and hasAnyParent(parents, blacklistSet) then
return false
end
 
return true
end
end


local function getSpriteState(entry)
local function filterSpriteData(spriteData, prototypeData, whitelistSet, blacklistSet)
    local iconBlock = getInsensitiveKey(entry, "Icon")
local result = {}
    if iconBlock and iconBlock.state then
 
        return iconBlock.state
for id, entry in pairs(spriteData) do
    end
local protoEntry = prototypeData and prototypeData[id] or entry
   
 
    local spriteBlock = getInsensitiveKey(entry, "Sprite")
if shouldIncludeEntry(protoEntry, whitelistSet, blacklistSet) then
    if spriteBlock then
result[id] = entry
        if spriteBlock.state then
end
            return spriteBlock.state
end
        elseif spriteBlock.layers then
            for _, layer in pairs(spriteBlock.layers) do
                if layer.state then
                    return layer.state
                end
            end
        end
    end


    return nil
return result
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 key = buildEntryKey(entry)
        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
spriteGroups[key] = spriteGroups[key] or {}
            table.insert(spriteGroups, {entry})
table.insert(spriteGroups[key], { id = id, entry = entry })
        end
end
    end


    local result = {}
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")
for _, group in pairs(spriteGroups) do
if #group > 1 then
local idLinks = {}
for _, obj in ipairs(group) do
local id = obj.id
local prefix = getPrefix(id, project)
table.insert(idLinks, "[[:Файл:" .. prefix .. id .. ".png]]")
end
local firstId = group[1].id
local prefix = getPrefix(firstId, project)
table.insert(result, mw.getCurrentFrame():preprocess(
"{{Entity Sprite/Repeat|спрайты=" .. table.concat(idLinks, " ") ..
"|перенаправление=" .. prefix .. firstId ..
"|id=" .. firstId ..
"}}"
))
end
end
 
return table.concat(result, "\n")
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
 
local prefix = getPrefix(id, project)


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


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


    return nil
return mw.getCurrentFrame():preprocess(
"{{Entity Sprite/Image|файл=" .. prefix .. id ..
"|id=" .. id ..
"|путь=" .. baseUrl .. spritePath ..
"|state=" .. 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 json = frame.args.json or "sprite_entity.json"
 
local project = JsonPaths.project()
local baseUrl = JsonPaths.git() .. "/Resources/Textures/"
 
local dataPage = JsonPaths.get(json)
local prototypesPage = JsonPaths.get("entity prototypes.json")
 
local spriteData = mw.loadData(dataPage)
local prototypeData = mw.loadData(prototypesPage)
 
if not spriteData or type(spriteData) ~= "table" then
return "Ошибка загрузки JSON: " .. dataPage
end
 
if not prototypeData or type(prototypeData) ~= "table" then
return "Ошибка загрузки JSON: " .. prototypesPage
end
 
local whitelistSet = buildSet(frame.args.whitelistParent)
local blacklistSet = buildSet(frame.args.blacklistParent)
 
local filteredData = filterSpriteData(spriteData, prototypeData, whitelistSet, blacklistSet)
 
if action == "repeat" then
return generateRepeatTemplate(filteredData, project)
 
elseif action == "image" then
local result = {}


    local dataPage
for id, entry in pairs(filteredData) do
    if mode == "item" then
local t = generateTemplate(id, entry, baseUrl, project)
        dataPage = "Модуль:IanComradeBot/prototypes/entity sprite/item.json/data"
if t then
    elseif mode == "structure" then
table.insert(result, t)
        dataPage = "Модуль:IanComradeBot/prototypes/entity sprite/structure.json/data"
end
    elseif mode == "mob" then
end
        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)
return table.concat(result, "\n")
    if not spriteData or type(spriteData) ~= "table" then
end
        return "Ошибка: Невозможно загрузить данные из JSON (" .. dataPage .. ")."
    end


    if action == "repeat" then
return nil
        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
end


return p
return p