mirror of
https://github.com/xmanrui/OpenClaw-bot-review.git
synced 2026-07-27 22:25:52 +00:00
- Add layout editor with floor/wall paint, erase, furniture place/move/rotate/delete tools - Add editor state management (undo/redo, selection, drag, ghost preview) - Add EditorToolbar and EditActionBar UI components - Add layout persistence API (GET/POST to ~/.openclaw/pixel-office/layout.json) - Add notification sound system (Web Audio API ascending chime on agent completion) - Add sub-agent visualization via session JSONL parsing - Fix agent activity API to read from agents.list config and correct session paths - Add agent name labels above character sprites in canvas renderer - Add i18n translations for editor features (zh/en)
75 lines
2.8 KiB
TypeScript
75 lines
2.8 KiB
TypeScript
/**
|
||
* Floor tile pattern storage and caching.
|
||
*
|
||
* Stores 7 grayscale floor patterns loaded from floors.png.
|
||
* Uses shared colorize module for HSL tinting (Photoshop-style Colorize).
|
||
* Caches colorized SpriteData by (pattern, h, s, b, c) key.
|
||
*/
|
||
|
||
import type { SpriteData, FloorColor } from './types'
|
||
import { getColorizedSprite, clearColorizeCache } from './colorize'
|
||
import { TILE_SIZE, FALLBACK_FLOOR_COLOR } from './constants'
|
||
|
||
/** Default solid gray 16×16 tile used when floors.png is not loaded */
|
||
const DEFAULT_FLOOR_SPRITE: SpriteData = Array.from(
|
||
{ length: TILE_SIZE },
|
||
() => Array(TILE_SIZE).fill(FALLBACK_FLOOR_COLOR) as string[],
|
||
)
|
||
|
||
/** Module-level storage for floor tile sprites (set once on load) */
|
||
let floorSprites: SpriteData[] = []
|
||
|
||
/** Wall color constant */
|
||
export const WALL_COLOR = '#3A3A5C'
|
||
|
||
/** Set floor tile sprites (called once when extension sends floorTilesLoaded) */
|
||
export function setFloorSprites(sprites: SpriteData[]): void {
|
||
floorSprites = sprites
|
||
clearColorizeCache()
|
||
}
|
||
|
||
/** Get the raw (grayscale) floor sprite for a pattern index (1-7 -> array index 0-6).
|
||
* Falls back to the default solid gray tile when floors.png is not loaded. */
|
||
export function getFloorSprite(patternIndex: number): SpriteData | null {
|
||
const idx = patternIndex - 1
|
||
if (idx < 0) return null
|
||
if (idx < floorSprites.length) return floorSprites[idx]
|
||
// No PNG sprites loaded — return default solid tile for any valid pattern index
|
||
if (floorSprites.length === 0 && patternIndex >= 1) return DEFAULT_FLOOR_SPRITE
|
||
return null
|
||
}
|
||
|
||
/** Check if floor sprites are available (always true — falls back to default solid tile) */
|
||
export function hasFloorSprites(): boolean {
|
||
return true
|
||
}
|
||
|
||
/** Get count of available floor patterns (at least 1 for the default solid tile) */
|
||
export function getFloorPatternCount(): number {
|
||
return floorSprites.length > 0 ? floorSprites.length : 1
|
||
}
|
||
|
||
/** Get all floor sprites (for preview rendering, falls back to default solid tile) */
|
||
export function getAllFloorSprites(): SpriteData[] {
|
||
return floorSprites.length > 0 ? floorSprites : [DEFAULT_FLOOR_SPRITE]
|
||
}
|
||
|
||
/**
|
||
* Get a colorized version of a floor sprite.
|
||
* Uses Photoshop-style Colorize: grayscale -> HSL with given hue/saturation,
|
||
* then brightness/contrast adjustment.
|
||
*/
|
||
export function getColorizedFloorSprite(patternIndex: number, color: FloorColor): SpriteData {
|
||
const key = `floor-${patternIndex}-${color.h}-${color.s}-${color.b}-${color.c}`
|
||
|
||
const base = getFloorSprite(patternIndex)
|
||
if (!base) {
|
||
// Return a 16x16 magenta error tile
|
||
const err: SpriteData = Array.from({ length: 16 }, () => Array(16).fill('#FF00FF'))
|
||
return err
|
||
}
|
||
|
||
// Floor tiles are always colorized (grayscale patterns need Photoshop-style Colorize)
|
||
return getColorizedSprite(key, base, { ...color, colorize: true })
|
||
}
|