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

Нет описания правки
Нет описания правки
 
(не показано 12 промежуточных версий этого же участника)
Строка 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 buildEntryKey(entry)
local parts = {}
if entry.sprite then
table.insert(parts, "sprite=" .. normalizeSpritePath(entry.sprite))
end
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
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


local function getSpritePath(entry)
local function getSpritePath(entry)
    return entry.sprite
return normalizeSpritePath(entry.sprite)
end
end


local function getSpriteStates(entry)
local function getSpriteStates(entry)
    local result = {}
local result = {}


    if entry.layers and entry.sprite then
if entry.layers and type(entry.layers) == "table" then
        for _, layer in ipairs(entry.layers) do
for _, layer in ipairs(entry.layers) do
            if layer.visible ~= false then
if layer.visible ~= false then
                table.insert(result, {
table.insert(result, {
                    state = tostring(layer.state or entry.state or ""),
state = tostring(layer.state or entry.state or ""),
                    sprite = entry.sprite
sprite = normalizeSpritePath(layer.sprite or entry.sprite)
                })
})
            end
end
        end
end
    elseif entry.state and entry.sprite then
elseif entry.state and entry.sprite then
        table.insert(result, {
table.insert(result, {
            state = tostring(entry.state or ""),  
state = tostring(entry.state or ""),
            sprite = entry.sprite
sprite = normalizeSpritePath(entry.sprite)
        })
})
    end
end


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


local function getPrefix(id, project)
local function getPrefix(id, project)
    if project ~= "" and JsonPaths.has(id, project) then
if project ~= "" and JsonPaths.has(id, project) then
        return project .. ":"
return project .. ":"
    end
end
    return ""
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
end


local MAX_CHECKS = 100
local function getParents(entry)
local checkCount = 0
if not entry then
return nil
end


local function fileExists(name)
if type(entry.parents) == "table" then
    if checkCount >= MAX_CHECKS then
return entry.parents
        return false
end
    end


    checkCount = checkCount + 1
if type(entry.parents) == "string" then
return splitCsv(entry.parents)
end


    local title = mw.title.new(name, "File")
return nil
    return title and title.exists
end
end


local function generateRepeatTemplate(data, project)
local function hasAnyParent(parents, set)
    local spriteGroups = {}
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


    for id, entry in pairs(data) do
local function filterSpriteData(spriteData, prototypeData, whitelistSet, blacklistSet)
        local found = false
local result = {}


        for _, group in pairs(spriteGroups) do
for id, entry in pairs(spriteData) do
            local g = group[1]
local protoEntry = prototypeData and prototypeData[id] or entry


            if entry.sprite == g.entry.sprite and entry.state == g.entry.state then
if shouldIncludeEntry(protoEntry, whitelistSet, blacklistSet) then
                table.insert(group, { id = id, entry = entry })
result[id] = entry
                found = true
end
                break
end
            end
        end


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


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


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


            for _, obj in pairs(group) do
spriteGroups[key] = spriteGroups[key] or {}
                local id = obj.id
table.insert(spriteGroups[key], { id = id, entry = entry })
                local prefix = getPrefix(id, project)
end


                table.insert(idLinks, "[[:Файл:" .. prefix .. id .. ".png]]")
local result = {}
            end


            table.insert(result, mw.getCurrentFrame():preprocess(
for _, group in pairs(spriteGroups) do
                "{{Entity Sprite/Repeat|" ..
if #group > 1 then
                table.concat(idLinks, " ") ..
local idLinks = {}
                "|" .. group[1].id ..
                "}}"
for _, obj in ipairs(group) do
            ))
local id = obj.id
        end
local prefix = getPrefix(id, project)
    end
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")
return table.concat(result, "\n")
end
end


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


    local prefix = getPrefix(id, project)
local prefix = getPrefix(id, project)


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


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


    return mw.getCurrentFrame():preprocess(
return mw.getCurrentFrame():preprocess(
        "{{Песочница/Pok|файл=" .. prefix .. id ..
"{{Entity Sprite/Image|файл=" .. prefix .. id ..
        "|id=" .. id ..
"|id=" .. id ..
        "|путь=" .. baseUrl .. spritePath ..
"|путь=" .. 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 "entity_sprite.json"
local json = frame.args.json or "sprite_entity.json"
    local checkFile = frame.args.checkFile or ""
    if checkFile == "" then checkFile = false end
   
    local project = JsonPaths.project()
    local baseUrl = JsonPaths.git() .. "/Resources/Textures/"
    local dataPage = JsonPaths.get(json)
    local spriteData = mw.loadData(dataPage)


    if not spriteData or type(spriteData) ~= "table" then
local project = JsonPaths.project()
        return "Ошибка загрузки JSON: " .. dataPage
local baseUrl = JsonPaths.git() .. "/Resources/Textures/"
    end


    if action == "repeat" then
local dataPage = JsonPaths.get(json)
        return generateRepeatTemplate(spriteData, project)
local prototypesPage = JsonPaths.get("entity prototypes.json")


    elseif action == "image" then
local spriteData = mw.loadData(dataPage)
        local result = {}
local prototypeData = mw.loadData(prototypesPage)


        for id, entry in pairs(spriteData) do
if not spriteData or type(spriteData) ~= "table" then
            local prefix = getPrefix(id, project)
return "Ошибка загрузки JSON: " .. dataPage
end


local skip = false
if not prototypeData or type(prototypeData) ~= "table" then
return "Ошибка загрузки JSON: " .. prototypesPage
if checkFile then
end
    local fileName = prefix .. id .. ".png"
 
    if fileExists(fileName) then
local whitelistSet = buildSet(frame.args.whitelistParent)
        skip = true
local blacklistSet = buildSet(frame.args.blacklistParent)
    end
 
end
local filteredData = filterSpriteData(spriteData, prototypeData, whitelistSet, blacklistSet)
 
if not skip then
if action == "repeat" then
    local t = generateTemplate(id, entry, baseUrl, project)
return generateRepeatTemplate(filteredData, project)
    if t then
 
        table.insert(result, t)
elseif action == "image" then
    end
local result = {}
 
for id, entry in pairs(filteredData) do
local t = generateTemplate(id, entry, baseUrl, project)
if t then
table.insert(result, t)
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