import type { NpcDef } from './npcs';
import type { EnemyKindId } from './enemies';
import { NPCS } from './npcs';
import type { ItemId } from './items';
/**
* Локации демо-среза. Карты хранятся файлами assets/maps/<id>.map
* (формат rpg-map, RLE) и загружаются через parseMap в BootScene.
*/
export type LocationId = 'meadows' | 'ponds' | 'zvenets';
export interface LocationExit {
/** Тайл-триггер (наступил — переход). */
tile: { x: number; y: number };
to: LocationId;
/** Куда поставить героя в новой локации. */
entry: { x: number; y: number };
}
/** Зона опасности (накат): герой без нужного предмета еле идёт и рискует голосом. */
export interface HazardDef {
name: string;
/** Тайлы низины (свежий пласт пепла). */
tiles: { x: number; y: number }[];
/** Без чего нельзя дышать здесь (по умолчанию — полотно-маска). */
requiresItem?: ItemId;
}
export interface LocationDef {
id: LocationId;
name: string;
/** Музыка локации (кроссфейд при переходе). */
music: string;
/** Стартовый тайл (новая игра / респаун). */
spawn: { x: number; y: number };
npcs: NpcDef[];
enemies: { kind: EnemyKindId; tile: { x: number; y: number } }[];
exits: LocationExit[];
/** Атмосферные частицы: 'ash' — пепел, 'fog' — туман прудов. */
ambience: 'ash' | 'fog';
/** Зоны наката (необязательно). */
hazards?: HazardDef[];
/** Спавны пейзажных оленей (тайлы). */
fauna?: { x: number; y: number }[];
}
export const LOCATIONS: Record<LocationId, LocationDef> = {
meadows: {
id: 'meadows',
name: 'Выжженные луга',
music: 'music/meadows',
spawn: { x: 14, y: 14 },
npcs: [],
enemies: [
{ kind: 'crawler', tile: { x: 8, y: 9 } },
{ kind: 'crawler', tile: { x: 10, y: 7 } },
{ kind: 'spitter', tile: { x: 19, y: 6 } },
{ kind: 'crawler', tile: { x: 22, y: 21 } },
{ kind: 'heavy', tile: { x: 6, y: 22 } }
],
exits: [
// Северо-западный угол: тропа на Серые пруды.
{ tile: { x: 2, y: 2 }, to: 'ponds', entry: { x: 3, y: 3 } },
// Тропа в Звенец (деревня-мастерская).
{ tile: { x: 26, y: 14 }, to: 'zvenets', entry: { x: 3, y: 10 } }
],
ambience: 'ash',
// Безгласные олени у берегов прудов — подходят к звону.
fauna: [
{ x: 9, y: 18 },
{ x: 12, y: 20 }
]
},
ponds: {
id: 'ponds',
name: 'Серые пруды',
music: 'music/ponds',
spawn: { x: 3, y: 3 },
npcs: [],
enemies: [
{ kind: 'crawler', tile: { x: 4, y: 11 } },
{ kind: 'crawler', tile: { x: 9, y: 18 } },
{ kind: 'spitter', tile: { x: 18, y: 10 } },
{ kind: 'spitter', tile: { x: 18, y: 18 } },
{ kind: 'heavy', tile: { x: 13, y: 17 } }
],
exits: [
// Обратно на луга.
{ tile: { x: 2, y: 2 }, to: 'meadows', entry: { x: 3, y: 3 } }
],
ambience: 'fog',
// Свежий накат — низины у берегов: без вощёного полотна здесь не дышать.
hazards: [
{
name: 'Свежий накат',
requiresItem: 'cloth',
tiles: [
{ x: 5, y: 16 },
{ x: 6, y: 17 },
{ x: 7, y: 17 },
{ x: 8, y: 18 },
{ x: 9, y: 18 },
{ x: 10, y: 18 },
{ x: 11, y: 19 },
{ x: 12, y: 19 },
{ x: 13, y: 18 },
{ x: 14, y: 18 },
{ x: 15, y: 17 },
{ x: 4, y: 9 },
{ x: 3, y: 8 },
{ x: 15, y: 6 },
{ x: 16, y: 4 }
]
}
],
// Один олень на северо-западном берегу.
fauna: [{ x: 4, y: 6 }]
},
zvenets: {
id: 'zvenets',
name: 'Звенец',
music: 'music/zvenets',
spawn: { x: 14, y: 10 },
npcs: NPCS,
enemies: [],
exits: [
// Тропа обратно на луга.
{ tile: { x: 2, y: 10 }, to: 'meadows', entry: { x: 25, y: 14 } }
],
ambience: 'ash'
}
};
/** Определение локации по id (с фолбэком на луга для старых сейвов). */
export function locationOf(id: string | null | undefined): LocationDef {
return LOCATIONS[(id as LocationId) ?? 'meadows'] ?? LOCATIONS.meadows;
}