feat(npcs): show multiple character overlays in session playback

Toggle NPCs independently from the characters window, keep one shared dim/close-all, and scroll descriptions for all selected characters.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Ivan Fontosh
2026-07-21 13:23:19 +08:00
parent f4c0ac1438
commit 1829191410
8 changed files with 538 additions and 121 deletions
+8 -5
View File
@@ -9,11 +9,14 @@ export type NpcsOverlayLayout = {
export type NpcsZoomTool = 'zoomIn' | 'zoomOut' | null;
/** Session-only: какой НПС сейчас показан поверх сцены (только аватар). */
/** Session-only: какие НПС сейчас показаны поверх сцены (только аватары). */
export type NpcsOverlayState = {
revision: number;
activeNpcId: NpcId | null;
layout: NpcsOverlayLayout;
/** Порядок выделения / показа описаний. */
activeNpcIds: NpcId[];
layouts: Record<string, NpcsOverlayLayout>;
/** На кого действует zoom, если клик не попал в конкретный аватар. */
focusNpcId: NpcId | null;
zoomTool: NpcsZoomTool;
};
@@ -27,9 +30,9 @@ export type NpcsOverlayEvent =
| { kind: 'show'; npcId: NpcId }
| { kind: 'hide' }
| { kind: 'toggle'; npcId: NpcId }
| { kind: 'layout.set'; layout: NpcsOverlayLayout }
| { kind: 'layout.set'; npcId: NpcId; layout: NpcsOverlayLayout }
| { kind: 'zoomTool.set'; tool: NpcsZoomTool }
| { kind: 'zoomAt'; nx: number; ny: number };
| { kind: 'zoomAt'; nx: number; ny: number; npcId?: NpcId };
export function clampNpcsLayout(layout: NpcsOverlayLayout): NpcsOverlayLayout {
return {