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

Материал из Space Station 14 Вики
мНет описания правки
Нет описания правки
 
(не показано 97 промежуточных версий этого же участника)
Строка 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
    if content then
 
        content = content:gsub(':null', ':"__null__"')
path = mw.text.trim(tostring(path))
        return mw.text.jsonDecode(content)
path = path:gsub("^/Textures/?", "")
    end
 
    return nil
return path
end
 
local function normalizeState(state)
if state == nil then
return nil
end
 
state = mw.text.trim(tostring(state))
if state == "" then
return nil
end
 
return state
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
end


-- Проверка равенства двух таблиц
-- Функция получения пути спрайта:
local function deepEqual(t1, t2)
-- 1) сначала entry.sprite
    if t1 == t2 then return true end
-- 2) потом первый layers[*].sprite
    if type(t1) ~= "table" or type(t2) ~= "table" then return false end
local function getSpritePath(entry)
if not entry then
return nil
end


    for k, _ in pairs(t1) do
if entry.sprite then
        if t2[k] == nil then
return normalizeSpritePath(entry.sprite)
            return false
end
        end
        if not deepEqual(t1[k], t2[k]) then
            return false
        end
    end


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


    return true
return nil
end
end


-- Генерация шаблона repeat
-- Проверка visible
local function generateRepeatTemplate(data)
local function isLayerVisible(layer)
    local spriteGroups = {}
if not layer then
return false
end
return layer.visible ~= false
end


    for _, entry in ipairs(data) do
-- Функция получения списка состояний с учётом переопределяющего sprite в слое
        local found = false
local function getSpriteStates(entry)
        for key, group in pairs(spriteGroups) do
local result = {}
            if deepEqual(entry.Sprite, group[1].Sprite) and
local spritePath = getSpritePath(entry)
              deepEqual(entry.EntityStorageVisuals, group[1].EntityStorageVisuals) and
              deepEqual(entry.Icon, group[1].Icon) then
                table.insert(group, entry)
                found = true
                break
            end
        end


        if not found then
if entry and type(entry.layers) == "table" then
            spriteGroups[entry.id] = {entry}
for _, layer in ipairs(entry.layers) do
        end
if isLayerVisible(layer) and layer.state then
    end
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


    local result = {}
if #result == 0 and spritePath then
    for _, group in pairs(spriteGroups) do
table.insert(result, {
        if #group > 1 then
state = "icon",
            local idLinks = {}
sprite = spritePath
            for _, entry in ipairs(group) do
})
                table.insert(idLinks, "[[:Файл:" .. entry.id .. ".png]]")
end
            end
            local firstId = group[1].id
            table.insert(result, mw.getCurrentFrame():preprocess("{{Entity Sprite/Repeat|" .. table.concat(idLinks, " ") .. "|" .. firstId .. "}}"))
        end
    end


    return table.concat(result, "\n")
return (#result > 0) and result or nil
end
end


-- Генерация текста для элемента JSON
local function findByPathAndState(data, targetPath, targetState)
local function generateTemplate(entry, param)
for entityId, entry in pairs(data) do
    if not entry.id or not entry.Sprite or not entry.Sprite.sprite then
if getSpritePath(entry) == targetPath then
        return nil
local states = getSpriteStates(entry)
    end
if states then
for _, item in ipairs(states) do
if normalizeState(item.state) == targetState then
return entityId
end
end
end
end
end
 
return nil
end


    if param == "image" then
local function findByPath(data, targetPath)
        return mw.getCurrentFrame():preprocess("{{Entity Sprite/Imege|" .. entry.id .. "|" .. entry.Sprite.sprite .. "}}")
for entityId, entry in pairs(data) do
    elseif param == "path" then
if getSpritePath(entry) == targetPath then
        return mw.getCurrentFrame():preprocess("{{Entity Sprite/Path|" .. entry.id .. "|" .. entry.Sprite.sprite .. "}}")
return entityId
    end
end
end


    return nil
return nil
end
end


-- Генерация шаблона по умолчанию
-- Функция генерации шаблона по записи (mode: image, path, state)
local function generateDefaultTemplate(data, params)
function p.main(frame)
    local id = params.Id
local mode = frame.args[1]
    if not id or id == "" then
local id = frame.args[2]
        return "Ошибка: Не указан ID."
local stateArg = frame.args[3]
    end


    -- Поиск записи с указанным ID
if not mode or not id then
    local entry = nil
return "Ошибка: отсутствует режим или ID"
    for _, item in ipairs(data) do
end
        if tostring(item.id) == tostring(id) then
            entry = item
            break
        end
    end


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


    local description = params.Description or ""
if mode == "image" or mode == "state" then
    local servers = params.Servers or ""
local entry = data[id]
    local source = params.Source or ""
if not entry then
    local path = params.Path
return "Ошибка: ID не найден"
    local tags = params.Tags or ""
end


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


    if not path or path == "" then
local baseUrl = JsonPaths.git() .. "/Resources/Textures/"
        path = "Resources/Textures/" .. entry.Sprite.sprite
local links = {}
    end


    -- Формирование шаблона
for _, item in ipairs(states) do
    return mw.getCurrentFrame():preprocess(
local spritePath = item.sprite
        "{{Файл\n" ..
local stateName = item.state
        "|Описание = " .. description .. "\n" ..
 
        "|Id      = " .. id .. "\n" ..
if spritePath then
        "|Сервера  = " .. servers .. "\n" ..
local url = baseUrl .. normalizeSpritePath(spritePath) .. "/" .. stateName .. ".png"
        "|Источник = " .. source .. "\n" ..
table.insert(links, "[" .. url .. " " .. stateName .. "]")
        "|Путь    = " .. path .. "\n" ..
else
        "|Теги    = " .. tags .. "\n" ..
table.insert(links, stateName .. " Error: sprite not found")
        "}}\n"  
end
    )
end
end
 
return "(state: " .. table.concat(links, ", ") .. ")"
end
end
 
if mode == "path" then
local targetPath = normalizeSpritePath(id)
local targetState = normalizeState(stateArg)


-- Основная функция модуля
if targetState then
function p.main(frame)
local byState = findByPathAndState(data, targetPath, targetState)
    local param = frame.args[1]
if byState then
return JsonPaths.prefixFile(byState)
end
end


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


    if not param then
return "Ошибка: путь не найден"
        -- Генерация шаблона по умолчанию с поиском по ID
end
        return generateDefaultTemplate(data, frame.args)
    end


    -- Логика для других параметров, как "image", "path", "repeat"
return "Ошибка: неизвестный режим"
    if param == "repeat" then
        return generateRepeatTemplate(data)
    else
        local result = {}
        for _, entry in ipairs(data) do
            local template = generateTemplate(entry, param)
            if template then
                table.insert(result, template)
            end
        end
        return table.concat(result)
    end
end
end


return p
return p

Текущая версия от 11:26, 1 апреля 2026

Документация
-- Загрузка данных
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 normalizeState(state)
	if state == nil then
		return nil
	end

	state = mw.text.trim(tostring(state))
	if state == "" then
		return nil
	end

	return state
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

local function findByPathAndState(data, targetPath, targetState)
	for entityId, entry in pairs(data) do
		if getSpritePath(entry) == targetPath then
			local states = getSpriteStates(entry)
			if states then
				for _, item in ipairs(states) do
					if normalizeState(item.state) == targetState then
						return entityId
					end
				end
			end
		end
	end

	return nil
end

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

	return nil
end

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

	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)
		local targetState = normalizeState(stateArg)

		if targetState then
			local byState = findByPathAndState(data, targetPath, targetState)
			if byState then
				return JsonPaths.prefixFile(byState)
			end
		end

		local byPath = findByPath(data, targetPath)
		if byPath then
			return JsonPaths.prefixFile(byPath)
		end

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

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

return p