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

Нет описания правки
Нет описания правки
 
(не показано 45 промежуточных версий этого же участника)
Строка 1: Строка 1:
local p = {}
local p = {}
local JsonPaths = require('Module:JsonPaths')
local JsonPaths = require('Module:JsonPaths')
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 normalizeData(data)
if type(data) ~= "table" then
return nil
end
if type(data.id) == "table" then
return data.id
end
return data
end
local function buildEntryKey(entry)
local parts = {}
local function addField(name, value)
if value ~= nil then
table.insert(parts, name .. "=" .. tostring(value))
end
end
addField("sprite", normalizeSpritePath(entry.sprite))
addField("state", entry.state)
addField("scale", entry.scale)
addField("enableOverrideDir", entry.enableOverrideDir)
addField("overrideDir", entry.overrideDir)
if entry.layers and type(entry.layers) == "table" then
local layers = {}
for _, layer in ipairs(entry.layers) do
local layerParts = {}
for k, v in pairs(layer) do
if type(v) ~= "table" then
layerParts[#layerParts + 1] = k .. "=" .. tostring(v)
end
end
table.sort(layerParts)
table.insert(layers, table.concat(layerParts, ","))
end
table.sort(layers)
table.insert(parts, "layers=" .. table.concat(layers, "|"))
end
table.sort(parts)
return table.concat(parts, ";")
end
local function getSpriteStates(entry)
local result = {}
if entry.layers and type(entry.layers) == "table" then
for _, layer in ipairs(entry.layers) do
if layer.visible ~= false and layer.state then
table.insert(result, {
state = tostring(layer.state),
sprite = normalizeSpritePath(layer.sprite or entry.sprite)
})
end
end
elseif entry.state and entry.sprite then
table.insert(result, {
state = tostring(entry.state),
sprite = normalizeSpritePath(entry.sprite)
})
end
return (#result > 0) and result or nil
end


local function getSpritePath(entry)
local function getSpritePath(entry)
    return entry.sprite
if entry.sprite then
return normalizeSpritePath(entry.sprite)
end
 
if entry.layers and type(entry.layers) == "table" then
for _, layer in ipairs(entry.layers) do
if layer.sprite then
return normalizeSpritePath(layer.sprite)
end
end
end
 
return nil
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
end


local function getSpriteStates(entry)
local function buildSet(value)
    local result = {}
local list = splitCsv(value)
if not list then
return nil
end


    if entry.layers and entry.sprite then
local set = {}
        for _, layer in ipairs(entry.layers) do
for _, item in ipairs(list) do
            if layer.visible ~= false then
set[item] = true
                table.insert(result, {
end
                    state = tostring(layer.state or entry.state or ""),
                    sprite = entry.sprite
                })
            end
        end
    elseif entry.state and entry.sprite then
        table.insert(result, {
            state = tostring(entry.state or ""),
            sprite = entry.sprite
        })
    end


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


local function getPrefix(id, project)
local function getParents(parentData, id)
    if project ~= "" and JsonPaths.has(id, project) then
if not parentData or type(parentData) ~= "table" or not id then
        return project .. ":"
return nil
    end
end
    return ""
 
local parents = parentData[id]
if type(parents) ~= "table" then
return nil
end
 
return parents
end
end


local MAX_CHECKS = 100
local function hasAnyParent(parents, set)
local checkCount = 0
if not parents or not set then
return false
end


local function fileExists(name)
for _, parent in ipairs(parents) do
    if checkCount >= MAX_CHECKS then
if set[parent] then
        return false
return true
    end
end
end


    checkCount = checkCount + 1
return false
end


    local title = mw.title.new(name, "File")
local function shouldIncludeEntry(id, whitelistSet, blacklistSet, parentData)
    return title and title.exists
local parents = getParents(parentData, id)
 
if whitelistSet and not hasAnyParent(parents, whitelistSet) then
return false
end
 
if blacklistSet and hasAnyParent(parents, blacklistSet) then
return false
end
 
return true
end
end


local function generateRepeatTemplate(data, project)
local function filterSpriteData(spriteData, parentData, whitelistSet, blacklistSet, project)
    local spriteGroups = {}
local result = {}


    for id, entry in pairs(data) do
for id, entry in pairs(spriteData) do
        local found = false
if shouldIncludeEntry(id, whitelistSet, blacklistSet, parentData) then
if project == "" or JsonPaths.has(id, project) then
result[id] = entry
end
end
end


        for _, group in pairs(spriteGroups) do
return result
            local g = group[1]
end
 
local function buildFileLink(id, project)
return "[[:Файл:" .. JsonPaths.prefixFile(id) .. ".png]]"
end
 
local function buildSpriteUrl(baseUrl, spritePath)
return baseUrl .. spritePath
end
 
local function buildSpritePathLink(baseUrl, spritePath)
local url = buildSpriteUrl(baseUrl, spritePath)
return "[" .. url .. " " .. spritePath .. "]"
end
 
local function buildStateLink(baseUrl, spritePath, state)
local url = buildSpriteUrl(baseUrl, spritePath) .. "/" .. state .. ".png"
return "[" .. url .. " " .. state .. "]"
end


            if entry.sprite == g.entry.sprite and entry.state == g.entry.state then
local function buildSpriteStateLinks(baseUrl, states)
                table.insert(group, { id = id, entry = entry })
if not states or #states == 0 then
                found = true
return ""
                break
end
            end
        end


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


    local result = {}
for _, item in ipairs(states) do
if item.sprite and item.state then
table.insert(links, buildStateLink(baseUrl, item.sprite, item.state))
end
end


    for _, group in pairs(spriteGroups) do
return table.concat(links, ", ")
        if #group > 1 then
end
            local idLinks = {}


            for _, obj in pairs(group) do
local function buildRepeatSpriteValue(baseUrl, entry)
                local id = obj.id
local spritePath = getSpritePath(entry)
                local prefix = getPrefix(id, project)
if not spritePath then
return ""
end


                table.insert(idLinks, "[[:Файл:" .. prefix .. id .. ".png]]")
local pathLink = buildSpritePathLink(baseUrl, spritePath)
            end
local states = getSpriteStates(entry)


            table.insert(result, mw.getCurrentFrame():preprocess(
if states and #states > 0 and states[1].state and states[1].state ~= "" then
                "{{Entity Sprite/Repeat|" ..
return pathLink .. " (" .. buildStateLink(baseUrl, spritePath, states[1].state) .. ")"
                table.concat(idLinks, " ") ..
end
                "|" .. group[1].id ..
                "}}"
            ))
        end
    end


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


local function generateTemplate(id, entry, baseUrl, project)
local function generateRepeatTemplate(data, project, baseUrl)
    local spritePath = getSpritePath(entry)
local spriteGroups = {}
    if not id or not spritePath then
 
        return nil
for id, entry in pairs(data) do
    end
local key = buildEntryKey(entry)
 
spriteGroups[key] = spriteGroups[key] or {}
table.insert(spriteGroups[key], { id = id, entry = entry })
end
 
local result = {}
 
for _, group in pairs(spriteGroups) do
if #group > 1 then
local idLinks = {}
 
for _, obj in ipairs(group) do
table.insert(idLinks, buildFileLink(obj.id, project))
end
 
local firstId = group[1].id
local firstEntry = group[1].entry
local spriteValue = buildRepeatSpriteValue(baseUrl, firstEntry)
 
table.insert(result, mw.getCurrentFrame():preprocess(
"{{Entity Sprite/Repeat|файлы=" .. table.concat(idLinks, " ") ..
"|перенаправление=" .. JsonPaths.prefixFile(firstId) ..
"|id=" .. firstId ..
"|спрайт=" .. spriteValue ..
"}}"
))
end
end


    local prefix = getPrefix(id, project)
return table.concat(result, "\n")
end


    local states = getSpriteStates(entry)
local function generateTemplate(id, entry, baseUrl, project)
    local stateStr = ""
local spritePath = getSpritePath(entry)
if not id or not spritePath then
return nil
end


    if states then
local states = getSpriteStates(entry)
        local links = {}
local stateStr = buildSpriteStateLinks(baseUrl, states)
        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(
return mw.getCurrentFrame():preprocess(
        "{{Песочница/Pok|файл=" .. prefix .. id ..
"{{Entity Sprite/Image|файл=" .. JsonPaths.prefixFile(id) ..
        "|id=" .. id ..
"|id=" .. id ..
        "|путь=" .. baseUrl .. spritePath ..
"|путь=" .. buildSpriteUrl(baseUrl, spritePath) ..
        "|state=" .. stateStr ..
"|state=" .. stateStr ..
        "}}"
"}}"
    )
)
end
end


function p.main(frame)
function p.main(frame)
    local action = frame.args[1]
local action = frame.args[1]
    local json = frame.args.json or "sprite_entity.json"
local json = frame.args.json or "component/Sprite.json"
    local checkFile = frame.args.checkFile or ""
 
    if checkFile == "" then checkFile = false end
local project = JsonPaths.project()
   
local baseUrl = JsonPaths.git() .. "/Resources/Textures/"
    local project = JsonPaths.project()
 
    local baseUrl = JsonPaths.git() .. "/Resources/Textures/"
local dataPage = JsonPaths.get(json)
    local dataPage = JsonPaths.get(json)
local parentPage = JsonPaths.get("entity parent.json")
    local spriteData = mw.loadData(dataPage)
 
local spriteDataRaw = mw.loadData(dataPage)
local parentDataRaw = mw.loadData(parentPage)
 
local spriteData = normalizeData(spriteDataRaw)
local parentData = normalizeData(parentDataRaw)


    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 not parentData or type(parentData) ~= "table" then
        return generateRepeatTemplate(spriteData, project)
return "Ошибка загрузки JSON: " .. parentPage
end


    elseif action == "image" then
local whitelistSet = buildSet(frame.args.whitelistParent)
        local result = {}
local blacklistSet = buildSet(frame.args.blacklistParent)
local filteredData = filterSpriteData(spriteData, parentData, whitelistSet, blacklistSet, project)


        for id, entry in pairs(spriteData) do
if action == "repeat" then
            local prefix = getPrefix(id, project)
return generateRepeatTemplate(filteredData, project, baseUrl)
elseif action == "image" then
local result = {}


local skip = false
for id, entry in pairs(filteredData) do
local t = generateTemplate(id, entry, baseUrl, project)
if checkFile then
if t then
    local fileName = prefix .. id .. ".png"
table.insert(result, t)
    if fileExists(fileName) then
        skip = true
    end
end
if not skip then
    local t = generateTemplate(id, entry, baseUrl, project)
    if t then
        table.insert(result, t)
    end
end
end
        end
end


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


    return nil
return nil
end
end


return p
return p