chroma_solstice/level_editor/object_attributes.lua

95 lines
3.7 KiB
Lua

require "libs/TSerial"
local targetFolder = "art"
local reanalyzeCells = true
-- Sprites loaded directly by dedicated entity classes or used as reference art
-- (the palette swatch), not placeable RGB assets. Every other master PNG in a
-- content folder is a colour asset. Keeping this list preserves the exact
-- palette set from when assets were identified by their _r/_g/_b channel files.
local NON_ASSET_SPRITES = {
palette = true,
color_changing_wall = true,
door_locked_w = true,
door_unlocked = true,
player_sad = true,
player_w = true,
switch_pressed = true,
}
function getAllAssets()
local objectnames = {}
local topFolder = "art"
local files = love.filesystem.getDirectoryItems(topFolder)
for _, folder in pairs(files) do
if string.sub(folder, 1, 1) ~= "_" then
-- we ignore directories which are prepended w/ an underscore
if not string.find(folder, "%.") then
objectnames[folder] = {}
-- this is a folder, probably
local newFiles = love.filesystem.getDirectoryItems(topFolder .. "/" .. folder)
for _, fileToAnalyze in pairs(newFiles) do
-- One full-colour master PNG per asset. The draw path tints it
-- per gun (see Entity:draw), so red/green/blue copies are just
-- the same master drawn through gColor[channel]; the channels are
-- split at load time, not stored as separate files.
if fileToAnalyze:find("%.png$") then
local name = fileToAnalyze:sub(1, fileToAnalyze:len() - 4)
-- first folder to define a name wins; skip engine/reference art
if not NON_ASSET_SPRITES[name]
and not (globalAssetProperties[name] and globalAssetProperties[name].directory ~= folder) then
local sprite = topFolder .. "/" .. folder .. "/" .. fileToAnalyze
if not globalAssetProperties[name] then
globalAssetProperties[name] = {}
globalAssetProperties[name].preload = false
end
globalAssetProperties[name].directory = folder
-- all three channels point at the same master image
globalAssetProperties[name].sprites = { red = sprite, green = sprite, blue = sprite }
-- class comes from a <name>.meta sitting next to the art
-- (authoritative); default to immoveable if none exists
local metaPath = topFolder .. "/" .. folder .. "/" .. name .. ".meta"
if love.filesystem.getInfo(metaPath, "file") then
globalAssetProperties[name].class = TSerial.unpack(love.filesystem.read(metaPath)).class
elseif not globalAssetProperties[name].class then
globalAssetProperties[name].class = "immoveable"
end
-- Precompute per-channel occupied-cell shapes once and cache
-- here; entities share this table by reference so collision
-- never rescans pixels at runtime. Keyed per colour because
-- each channel of the master leaves its own gaps.
if reanalyzeCells or not globalAssetProperties[name].cells then
globalAssetProperties[name].cells = getChannelCells(sprite)
end
end
end
end
end
end
end
-- Wired devices intentionally reuse the familiar switch/door artwork. Their
-- white terminal marker is drawn by the entity class, while these synthetic
-- asset records make them available to the ordinary palette and brush.
local function synthetic(name, source, behavior)
local original = globalAssetProperties[source]
if not original then return end
globalAssetProperties[name] = {
directory = original.directory,
sprites = original.sprites,
cells = original.cells,
class = behavior,
preload = false,
synthetic = true,
}
end
synthetic("wired_switch", "switch", "wired_switch")
synthetic("wired_door", "door", "wired_door")
return globalAssetProperties
end