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

Материал из Space Station 14 Вики
мНет описания правки
Нет описания правки
 
(не показаны 34 промежуточные версии этого же участника)
Строка 1: Строка 1:
-- Загрузка данных
local JsonPaths = require('Module:JsonPaths')
local spriteData = mw.loadData(JsonPaths.get("prototype/sprite.json"))
local p = {}
local p = {}


-- Загрузка данных
local function normalizeSpritePath(path)
local function loadData(filePath)
if path == nil then
    local page = mw.title.new(filePath)
return nil
    local content = page and page:getContent()
end
    return content and mw.text.jsonDecode(content) or nil
 
path = mw.text.trim(tostring(path))
path = path:gsub("^/Textures/?", "")
 
return path
end
end


-- Проверка равенства двух таблиц
-- Функция получения таблицы данных
local function deepEqual(t1, t2)
local function getIdTable()
    if t1 == t2 then return true end
if type(spriteData) == "table" and type(spriteData.id) == "table" then
    if type(t1) ~= "table" or type(t2) ~= "table" then return false end
return spriteData.id
end
return nil
end


    -- Если это массивы, проверяем их содержимое без учета порядка
-- Функция для получения таблицы данных
    local function isArray(t)
function p.getData()
        for _, v in pairs(t) do
return getIdTable() or {}
            if type(v) == "nil" then return false end
end
        end
        return true
    end


    if isArray(t1) and isArray(t2) then
-- Функция получения пути спрайта:
        if #t1 ~= #t2 then return false end
-- 1) сначала entry.sprite
        local matched = {}
-- 2) потом первый layers[*].sprite
        for _, v1 in pairs(t1) do
local function getSpritePath(entry)
            local found = false
if not entry then
            for _, v2 in pairs(t2) do
return nil
                if not matched[v2] and deepEqual(v1, v2) then
end
                    matched[v2] = true
                    found = true
                    break
                end
            end
            if not found then return false end
        end
        return true
    end


    -- Если это таблицы, проверяем их содержимое
if entry.sprite then
    for k, v in pairs(t1) do
return normalizeSpritePath(entry.sprite)
        if not deepEqual(v, t2[k]) then
end
            return false
        end
    end


    for k, v in pairs(t2) do
if type(entry.layers) == "table" then
        if not deepEqual(v, t1[k]) then
for _, layer in ipairs(entry.layers) do
            return false
if layer and layer.sprite then
        end
return normalizeSpritePath(layer.sprite)
    end
end
end
end


    return true
return nil
end
end


-- Получение пути спрайта
-- Проверка visible
local function getSpritePath(entry)
local function isLayerVisible(layer)
    if entry.Sprite and entry.Sprite.sprite then
if not layer then
        return entry.Sprite.sprite
return false
    elseif entry.Icon and entry.Icon.sprite then
end
        return entry.Icon.sprite
return layer.visible ~= false
    elseif entry.Sprite and entry.Sprite.layers then
        for _, layer in pairs(entry.Sprite.layers) do
            if layer.sprite then
                return layer.sprite
            end
        end
    end
    return nil
end
end


-- Генерация шаблона repeat
-- Функция получения списка состояний с учётом переопределяющего sprite в слое
local function generateRepeatTemplate(data)
local function getSpriteStates(entry)
    local spriteGroups = {}
local result = {}
local spritePath = getSpritePath(entry)
 
if entry and type(entry.layers) == "table" then
for _, layer in ipairs(entry.layers) do
if isLayerVisible(layer) and layer.state then
table.insert(result, {
state = tostring(layer.state),
sprite = normalizeSpritePath(layer.sprite or spritePath)
})
end
end
elseif entry and entry.state and spritePath then
table.insert(result, {
state = tostring(entry.state),
sprite = spritePath
})
end


    for _, entry in pairs(data) do
if #result == 0 and spritePath then
        local found = false
table.insert(result, {
        for _, group in pairs(spriteGroups) do
state = "icon",
            if deepEqual(entry.Sprite, group[1].Sprite) and
sprite = spritePath
              deepEqual(entry.EntityStorageVisuals, group[1].EntityStorageVisuals) and
})
              deepEqual(entry.Icon, group[1].Icon) then
end
                table.insert(group, entry)
                found = true
                break
            end
        end


        if not found then
return (#result > 0) and result or nil
            table.insert(spriteGroups, {entry})
end
        end
    end


    local result = {}
-- Функция генерации шаблона по записи (mode: image, path, state)
    for _, group in pairs(spriteGroups) do
function p.main(frame)
        if #group > 1 then
local mode = frame.args[1]
            local idLinks = {}
local id = frame.args[2]
            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")
if not mode or not id then
end
return "Ошибка: отсутствует режим или ID"
end


-- Обновляем основную функцию
local data = getIdTable()
local function generateTemplate(entry, param, secondaryParam, data)
if not data then
    local spritePath = getSpritePath(entry)
return "Ошибка: неверный формат JSON"
    if not entry.id or not spritePath then
end
        return nil
    end


    if param == "image" then
if mode == "image" or mode == "state" then
        if secondaryParam then
local entry = data[id]
            if tostring(entry.id) == tostring(secondaryParam) then
if not entry then
                return spritePath
return "Ошибка: ID не найден"
            end
end
            return nil
        else
            return mw.getCurrentFrame():preprocess("{{Entity Sprite/Image|" .. entry.id .. "|" .. spritePath .. "}}")
        end
    elseif param == "path" then
        return mw.getCurrentFrame():preprocess("{{Entity Sprite/Path|" .. entry.id .. "|" .. spritePath .. "}}")
    end


    return nil
if mode == "image" then
end
local sprite = getSpritePath(entry)
return sprite or "Ошибка: спрайт не найден"
elseif mode == "state" then
local states = getSpriteStates(entry)
if not states then
return ""
end


-- Генерация шаблона по умолчанию
local baseUrl = JsonPaths.git() .. "/Resources/Textures/"
local function generateDefaultTemplate(data, params)
local links = {}
    local id = params.Id
    local description = params.Description or ""
    local servers = params.Servers or ""
    local source = params.Source or ""
    local tags = params.Tags or ""


    local spritePath = nil
for _, item in ipairs(states) do
    local path = params.Path
local spritePath = item.sprite
local stateName = item.state


    local entry = nil
if spritePath then
    if id and id ~= "" then
local url = baseUrl .. normalizeSpritePath(spritePath) .. "/" .. stateName .. ".png"
        for _, item in pairs(data) do
table.insert(links, "[" .. url .. " " .. stateName .. "]")
            if tostring(item.id) == tostring(id) then
else
                entry = item
table.insert(links, stateName .. " Error: sprite not found")
                break
end
            end
end
        end
    end


    if entry then
return "(state: " .. table.concat(links, ", ") .. ")"
        spritePath = getSpritePath(entry)
end
        if not spritePath then
end
            return ""
        end
    end
   
    if not path or path == "" then
        path = "Resources/Textures/" .. (spritePath or "")
    end


    return mw.getCurrentFrame():preprocess(
if mode == "path" then
        "{{Файл\n" ..
local targetPath = normalizeSpritePath(id)
        "|Описание = " .. description .. "\n" ..
        "|Id      = " .. id .. "\n" ..
        "|Сервера  = " .. servers .. "\n" ..
        "|Источник = " .. source .. "\n" ..
        "|Путь    = " .. path .. "\n" ..
        "|Теги    = " .. tags .. "\n" ..
        "}}\n"
    )
end


function p.main(frame)
for entityId, entry in pairs(data) do
    local param = frame.args[1]
if getSpritePath(entry) == targetPath then
    local secondaryParam = frame.args[2]
return entityId
end
end


    local data = loadData('User:IanComradeBot/prototypes/entity sprite.json')
return "Ошибка: путь не найден"
    if not data or type(data) ~= 'table' then
end
        return 'Ошибка: Невозможно загрузить данные из JSON.'
    end


    if param == "repeat" then
return "Ошибка: неизвестный режим"
        return generateRepeatTemplate(data)
    elseif param == "path" and secondaryParam then
        for _, entry in ipairs(data) do
            local template = generateTemplate(entry, param, secondaryParam, data)
            if template then
                return template
            end
        end
        return nil
    elseif param == "image" or param == "path" then
        local result = {}
        for _, entry in pairs(data) do
            local template = generateTemplate(entry, param, secondaryParam, data)
            if template then
                table.insert(result, template)
            end
        end
        return table.concat(result, "\n")
    else
        return generateDefaultTemplate(data, frame.args)
    end
end
end


return p
return p

Текущая версия от 04:35, 23 марта 2026

Шаблон:Entity Sprite


-- Загрузка данных
local JsonPaths = require('Module:JsonPaths')
local spriteData = mw.loadData(JsonPaths.get("prototype/sprite.json"))

local p = {}

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 getIdTable()
	if type(spriteData) == "table" and type(spriteData.id) == "table" then
		return spriteData.id
	end
	return nil
end

-- Функция для получения таблицы данных
function p.getData()
	return getIdTable() or {}
end

-- Функция получения пути спрайта:
-- 1) сначала entry.sprite
-- 2) потом первый layers[*].sprite
local function getSpritePath(entry)
	if not entry then
		return nil
	end

	if entry.sprite then
		return normalizeSpritePath(entry.sprite)
	end

	if type(entry.layers) == "table" then
		for _, layer in ipairs(entry.layers) do
			if layer and layer.sprite then
				return normalizeSpritePath(layer.sprite)
			end
		end
	end

	return nil
end

-- Проверка visible
local function isLayerVisible(layer)
	if not layer then
		return false
	end
	return layer.visible ~= false
end

-- Функция получения списка состояний с учётом переопределяющего sprite в слое
local function getSpriteStates(entry)
	local result = {}
	local spritePath = getSpritePath(entry)

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

	if #result == 0 and spritePath then
		table.insert(result, {
			state = "icon",
			sprite = spritePath
		})
	end

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

-- Функция генерации шаблона по записи (mode: image, path, state)
function p.main(frame)
	local mode = frame.args[1]
	local id = frame.args[2]

	if not mode or not id then
		return "Ошибка: отсутствует режим или ID"
	end

	local data = getIdTable()
	if not data then
		return "Ошибка: неверный формат JSON"
	end

	if mode == "image" or mode == "state" then
		local entry = data[id]
		if not entry then
			return "Ошибка: ID не найден"
		end

		if mode == "image" then
			local sprite = getSpritePath(entry)
			return sprite or "Ошибка: спрайт не найден"
		elseif mode == "state" then
			local states = getSpriteStates(entry)
			if not states then
				return ""
			end

			local baseUrl = JsonPaths.git() .. "/Resources/Textures/"
			local links = {}

			for _, item in ipairs(states) do
				local spritePath = item.sprite
				local stateName = item.state

				if spritePath then
					local url = baseUrl .. normalizeSpritePath(spritePath) .. "/" .. stateName .. ".png"
					table.insert(links, "[" .. url .. " " .. stateName .. "]")
				else
					table.insert(links, stateName .. " Error: sprite not found")
				end
			end

			return "(state: " .. table.concat(links, ", ") .. ")"
		end
	end

	if mode == "path" then
		local targetPath = normalizeSpritePath(id)

		for entityId, entry in pairs(data) do
			if getSpritePath(entry) == targetPath then
				return entityId
			end
		end

		return "Ошибка: путь не найден"
	end

	return "Ошибка: неизвестный режим"
end

return p