Модуль:Entity Sprite/all: различия между версиями
Pok (обсуждение | вклад) мНет описания правки |
Pok (обсуждение | вклад) Нет описания правки |
||
| (не показано 35 промежуточных версий этого же участника) | |||
| Строка 1: | Строка 1: | ||
local p = {} | local p = {} | ||
local JsonPaths = require('Module:JsonPaths') | |||
local function normalizeSpritePath(path) | |||
local function | if path == nil then | ||
return nil | |||
end | |||
path = mw.text.trim(tostring(path)) | |||
path = path:gsub("^/Textures/?", "") | |||
return path | |||
end | end | ||
local function buildEntryKey(entry) | |||
local function | 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 | end | ||
local function getSpritePath(entry) | local function getSpritePath(entry) | ||
return normalizeSpritePath(entry.sprite) | |||
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 then | |||
table.insert(result, { | |||
state = tostring(layer.state or entry.state or ""), | |||
sprite = normalizeSpritePath(layer.sprite or entry.sprite) | |||
}) | |||
end | |||
end | |||
elseif entry.state and entry.sprite then | |||
table.insert(result, { | |||
state = tostring(entry.state or ""), | |||
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 | end | ||
local function buildSet(value) | |||
local function | 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 | end | ||
local function hasAnyParent(parents, set) | |||
local function | 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 | |||
local function filterSpriteData(spriteData, prototypeData, whitelistSet, blacklistSet) | |||
local result = {} | |||
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 | |||
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 | |||
local result = {} | |||
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 | |||
local function generateTemplate(id, entry, baseUrl, project) | |||
local spritePath = getSpritePath(entry) | |||
if not id or not spritePath then | |||
return nil | |||
end | |||
local prefix = getPrefix(id, project) | |||
local states = getSpriteStates(entry) | |||
local stateStr = "" | |||
if states then | |||
local links = {} | |||
for _, item in ipairs(states) do | |||
if item.sprite and item.state then | |||
local url = baseUrl .. item.sprite .. "/" .. item.state .. ".png" | |||
table.insert(links, "[" .. url .. " " .. item.state .. "]") | |||
end | |||
end | |||
stateStr = table.concat(links, ", ") | |||
end | |||
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 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 = {} | |||
for id, entry in pairs(filteredData) 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 | end | ||
return p | return p | ||