oma-command/rendering/palette.lua
nosignal 64ce7f0fcb Initial public release
OMA-COMMAND — Missile Command arcade clone in Love2D with Omarchy theme integration.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 18:32:07 +01:00

92 lines
2.9 KiB
Lua

-- Palette auto-detected from the current Omarchy system theme
-- Reads ~/.config/omarchy/current/theme/ghostty.conf on every launch
-- This file is a symlink that always points to the active theme
local Palette = {}
local theme = {}
local function hexToRGB(hex)
hex = hex:gsub("#", "")
return {
tonumber(hex:sub(1,2), 16) / 255,
tonumber(hex:sub(3,4), 16) / 255,
tonumber(hex:sub(5,6), 16) / 255,
}
end
function Palette.loadFromSystem()
-- Omarchy always symlinks the active theme config here
local path = os.getenv("HOME") .. "/.config/omarchy/current/theme/ghostty.conf"
local f = io.open(path, "r")
if not f then
-- Absolute fallback: white-on-black so the game is always playable
theme.bg = {0, 0, 0}
theme.fg = {1, 1, 1}
theme.accent = {1, 1, 1}
for i = 0, 15 do
theme["color" .. i] = {i/15, i/15, i/15}
end
theme.dim = theme.color8
return
end
for line in f:lines() do
local key, val = line:match("^(%S+)%s*=%s*(#%x+)")
if key and val then
if key == "background" then theme.bg = hexToRGB(val)
elseif key == "foreground" then theme.fg = hexToRGB(val)
elseif key == "cursor-color" then theme.accent = hexToRGB(val)
end
end
local idx, hex = line:match("^palette%s*=%s*(%d+)=(#%x+)")
if idx and hex then
theme["color" .. idx] = hexToRGB(hex)
end
end
f:close()
-- Derive dim from color8 (bright black / muted) which all themes provide
theme.dim = theme.color8 or theme.color0 or {0.2, 0.2, 0.2}
-- Safety: ensure all 16 colours exist (some themes might be sparse)
for i = 0, 15 do
if not theme["color" .. i] then
theme["color" .. i] = theme.fg or {1, 1, 1}
end
end
if not theme.bg then theme.bg = {0, 0, 0} end
if not theme.fg then theme.fg = {1, 1, 1} end
if not theme.accent then theme.accent = theme.color12 or theme.fg end
end
-- Vector-style palette mapping for the game
-- Maps the 16 ANSI theme colours into game roles
function Palette.get(wave)
local shift = ((math.ceil(wave / 2) - 1) % 5)
local primary_colors = {theme.color4, theme.color5, theme.color6, theme.color9, theme.color10}
local enemy_colors = {theme.color1, theme.color2, theme.color3, theme.color9, theme.color1}
return {
sky = theme.bg,
ground = primary_colors[shift + 1],
missile = enemy_colors[shift + 1],
abm = theme.color6,
cities = primary_colors[shift + 1],
exp1 = theme.accent,
exp2 = theme.color4,
crosshair = theme.accent,
dim = theme.dim,
bright = theme.accent,
fg = theme.fg,
grid = theme.color0,
glow = theme.color4,
}
end
function Palette.raw()
return theme
end
return Palette