Newer
Older
rpg / v2 / apps / game / src / data / lighting.ts
/**
 * Освещение и атмосфера областей (перенос v1 locations.ts lighting/atmosphere
 * 1:1): ambient-тон (день/ночь/закат) + точечные источники по флагам и времени
 * суток. Радиусы — в юнитах v1 (на границе конвертируются: 1 юнит = 3 вокселя).
 * Позиции `at` — тайлы v1; `tiles` — свет на каждом тайле заданного id.
 */

import { FLAGS } from './ids';

/** Источник света: точка в тайлах или все тайлы заданного id; радиус в юнитах. */
export interface LightSourceDef {
    id: string;
    /** Центр источника в тайлах (центр ромба v1: +0.5). */
    at?: { x: number; y: number };
    /** Альтернатива: свет на каждом тайле этого id (позиции из раскладки). */
    tiles?: number[];
    /** Радиус в юнитах (по умолчанию 3). */
    radius?: number;
    /** Цвет свечения (по умолчанию 0xf2b45a — тёплый F1). */
    color?: number;
    /** Яркость (по умолчанию 0.9). */
    intensity?: number;
    /** Амплитуда мерцания 0..1 (по умолчанию 0 — ровный). */
    flicker?: number;
    /** Источник активен только при наличии (whenFlag) / отсутствии (notFlag) флага. */
    whenFlag?: string;
    notFlag?: string;
    /** Ночной источник: горит при факторе ночи ≥ 0.5 (вечер/ночь по часам). */
    whenNight?: boolean;
}

/** Освещение области: дневной/ночной ambient + статические источники. */
export interface LightingDef {
    /** Тон области днём (тёмный интерьер гасит hemisphere и солнце). */
    ambient?: number;
    /** Ночной ambient (кривая суток); нет — ночь не меняет тон. */
    nightAmbient?: number;
    /** Закатный тон (золотой час); нет — движковый DEFAULT_DUSK_COLOR. */
    duskColor?: number;
    sources?: LightSourceDef[];
}

/** Тайлы раскладки v1 (TILES из data/map.ts v1). */
const T = { BELLFLOWER: 5 } as const;

/** Освещение областей по id (области без записи — без своего освещения). */
export const LIGHTING: Record<string, LightingDef> = {
    // Солнечный выжженный день: тёплый почти-белый. Вечером — золотой час
    // и синяя ночь: прорези колокольчиков несут свет.
    meadows: {
        ambient: 0xf7f4ea,
        nightAmbient: 0x3e4658,
        sources: [
            {
                id: 'bells',
                tiles: [T.BELLFLOWER],
                color: 0xf2cd68,
                radius: 1.0,
                intensity: 0.65,
                flicker: 0.15,
                whenNight: true,
            },
        ],
    },
    // Светлый день у прудов; ночью — глухая синева.
    ponds: { ambient: 0xf2f0e8, nightAmbient: 0x444c60 },
    // Светлый тёплый день деревни; вечером — окна трёх домов; после звонка —
    // холодный отсвет от башни.
    zvenets: {
        ambient: 0xf5f2ea,
        nightAmbient: 0x454c62,
        sources: [
            // Окна — на теле дома; днём не горят, зажигаются вечером.
            { id: 'window_elder', at: { x: 12.5, y: 11.5 }, radius: 1.2, intensity: 0.65, flicker: 0.1, whenNight: true },
            { id: 'window_north', at: { x: 36.5, y: 9.5 }, radius: 1.2, intensity: 0.65, flicker: 0.1, whenNight: true },
            { id: 'window_shop', at: { x: 42.5, y: 18.5 }, radius: 1.2, intensity: 0.65, flicker: 0.1, whenNight: true },
            {
                id: 'tower_resonance',
                at: { x: 28, y: 14 },
                color: 0x4a737f,
                radius: 2.5,
                intensity: 0.6,
                flicker: 0.25,
                whenFlag: FLAGS.rang_tower,
            },
        ],
    },
    rust_grove: { ambient: 0xe9e6da, nightAmbient: 0x39405a },
    old_siding: { ambient: 0xe4e2d8, nightAmbient: 0x343a50 },
    // Под землёй темно; единственный свет — холодное тление устья печи.
    machine_hall: {
        ambient: 0x3e4252,
        sources: [
            {
                id: 'machine_mouth',
                at: { x: 12.5, y: 1.5 },
                color: 0x4a737f,
                radius: 3.5,
                intensity: 0.55,
                flicker: 0.3,
            },
        ],
    },
    // Тёмный холодный интерьер; очаг: тлеет, пока квест не закрыт,
    // после — горит ровнее и ярче.
    house_elder: {
        ambient: 0x54586a,
        sources: [
            { id: 'hearth_low', at: { x: 8.5, y: 0.5 }, radius: 4, intensity: 0.75, flicker: 0.35, notFlag: FLAGS.quest_bells_done },
            { id: 'hearth_high', at: { x: 8.5, y: 0.5 }, radius: 5, intensity: 1.05, flicker: 0.2, whenFlag: FLAGS.quest_bells_done },
        ],
    },
    // Полутёмная лавка: лампа над прилавком.
    shop: {
        ambient: 0x5a5e70,
        sources: [{ id: 'counter_lamp', at: { x: 5.5, y: 3.5 }, radius: 3, intensity: 0.7, flicker: 0.05 }],
    },
};

/** Атмосферные частицы области (v1 atmosphere; fog прудов — вне скоупа v2). */
export type Atmosphere = 'ash' | 'fog' | 'none';

/** Атмосфера по id: пепел на улицах, интерьеры — чистые. */
export const ATMOSPHERE: Record<string, Atmosphere> = {
    meadows: 'ash',
    ponds: 'fog',
    zvenets: 'ash',
    rust_grove: 'ash',
    old_siding: 'ash',
    machine_hall: 'none',
    house_elder: 'none',
    shop: 'none',
};

/** Профиль воздушных частиц области: листопад рощи, пыль разъезда. */
export type AirFxProfile = 'leaves' | 'dust';

/** Воздух по id: где что летает сверх пепла/дымки. */
export const AIRFX: Record<string, AirFxProfile> = {
    rust_grove: 'leaves',
    old_siding: 'dust',
};