/**
* Состояние игры «Пепельных луга»: флаги сюжета и числовые вары.
* Реализует DialogueState движка (диалоги и квест-стадии пишут прямо сюда);
* данные сериализуемы (toData/fromData) — автосейв подхватит в треке сейвов.
* Ключи — только из реестров data/ids.ts.
*/
import type { DialogueState } from '@rpg/engine';
export type VarValue = number | string | boolean;
/** Данные для сейва: какие флаги подняты + значения варов. */
export interface GameStateData {
flags: string[];
vars: Record<string, VarValue>;
}
export class GameState implements DialogueState {
private readonly flags = new Set<string>();
private readonly vars = new Map<string, VarValue>();
hasFlag(flag: string): boolean {
return this.flags.has(flag);
}
setFlag(flag: string): void {
this.flags.add(flag);
}
clearFlag(flag: string): void {
this.flags.delete(flag);
}
getVar(key: string): VarValue | undefined {
return this.vars.get(key);
}
setVar(key: string, value: VarValue): void {
this.vars.set(key, value);
}
/** Числовой вар (для прогресса N/M); нет/не число — 0. */
getNumber(key: string): number {
const v = this.vars.get(key);
return typeof v === 'number' ? v : 0;
}
toData(): GameStateData {
return { flags: [...this.flags], vars: Object.fromEntries(this.vars) };
}
/** Заменить состояние (загрузка сейва); пусто — новая игра. */
fromData(data: GameStateData | null): void {
this.flags.clear();
this.vars.clear();
if (!data) return;
for (const f of data.flags) this.flags.add(f);
for (const [k, v] of Object.entries(data.vars)) this.vars.set(k, v);
}
}