95 lines
3.7 KiB
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
|