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

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


local fileExistsCache = {}
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


Строка 11: Строка 48:
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
Строка 23: Строка 60:
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
Строка 37: Строка 74:
end
end


local function fileExists(name)
local function splitCsv(value)
if fileExistsCache[name] ~= nil then
local result = {}
return fileExistsCache[name]
 
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
end


local title = mw.title.new(name, "File")
return nil
local exists = title and title.exists or false
fileExistsCache[name] = exists
return 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


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


for _, group in pairs(spriteGroups) do
local function shouldIncludeEntry(entry, whitelistSet, blacklistSet)
local g = group[1]
local parents = getParents(entry)


if entry.sprite == g.entry.sprite and entry.state == g.entry.state then
if whitelistSet then
table.insert(group, { id = id, entry = entry })
if not hasAnyParent(parents, whitelistSet) then
found = true
return false
break
end
end
end
end
if blacklistSet and hasAnyParent(parents, blacklistSet) then
return false
end
return true
end


if not found then
local function filterSpriteData(spriteData, prototypeData, whitelistSet, blacklistSet)
table.insert(spriteGroups, {
local result = {}
{ id = id, entry = entry }
 
})
for id, entry in pairs(spriteData) do
local protoEntry = prototypeData and prototypeData[id] or entry
 
if shouldIncludeEntry(protoEntry, whitelistSet, blacklistSet) then
result[id] = entry
end
end
end
return result
end
local function generateRepeatTemplate(data, project)
local spriteGroups = {}
for id, entry in pairs(data) do
local key = buildEntryKey(entry)
spriteGroups[key] = spriteGroups[key] or {}
table.insert(spriteGroups[key], { id = id, entry = entry })
end
end


local result = {}
local result = {}
local frame = mw.getCurrentFrame()


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 _, obj in pairs(group) do
for _, obj in ipairs(group) do
local id = obj.id
local id = obj.id
local prefix = getPrefix(id, project)
local prefix = getPrefix(id, project)
table.insert(idLinks, "[[:Файл:" .. prefix .. id .. ".png]]")
table.insert(idLinks, "[[:Файл:" .. prefix .. id .. ".png]]")
end
end
 
table.insert(result, frame:preprocess(
local firstId = group[1].id
"{{Entity Sprite/Repeat|" ..
local prefix = getPrefix(firstId, project)
table.concat(idLinks, " ") ..
"|" .. group[1].id ..
table.insert(result, mw.getCurrentFrame():preprocess(
"{{Entity Sprite/Repeat|спрайты=" .. table.concat(idLinks, " ") ..
"|перенаправление=" .. prefix .. firstId ..
"|id=" .. firstId ..
"}}"
"}}"
))
))
Строка 110: Строка 222:
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"
table.insert(links, "[" .. url .. " " .. item.state .. "]")
end
end
end
stateStr = table.concat(links, ", ")
stateStr = table.concat(links, ", ")
Строка 128: Строка 242:
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 "sprite_entity.json"
local checkFile = frame.args.checkFile or ""
if checkFile == "" then
checkFile = false
end


local project = JsonPaths.project()
local project = JsonPaths.project()
local baseUrl = JsonPaths.git() .. "/Resources/Textures/"
local baseUrl = JsonPaths.git() .. "/Resources/Textures/"
local dataPage = JsonPaths.get(json)
local dataPage = JsonPaths.get(json)
local prototypesPage = JsonPaths.get("entity prototypes.json")
local spriteData = mw.loadData(dataPage)
local spriteData = mw.loadData(dataPage)
local prototypeData = mw.loadData(prototypesPage)


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 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
if action == "repeat" then
return generateRepeatTemplate(spriteData, project)
return generateRepeatTemplate(filteredData, project)


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


for id, entry in pairs(spriteData) do
for id, entry in pairs(filteredData) do
local prefix = getPrefix(id, project)
local t = generateTemplate(id, entry, baseUrl, project)
 
if t then
local skip = false
table.insert(result, t)
if checkFile then
local fileName = prefix .. id .. ".png"
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