feat(scene): keep map tokens with preview rotation

When previewRotationDeg changes, remap non-player, NPC and trap
markers (plus live session token overrides) so they stay on the art.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Ivan Fontosh
2026-08-11 12:29:20 +08:00
parent 7362a36fe5
commit 46bec1a86a
11 changed files with 312 additions and 1 deletions
@@ -1,4 +1,5 @@
import type { SceneTokensSessionEvent, SceneTokensSessionState } from '../../shared/types';
import { rotateMapNormPointByCwSteps } from '../../shared/types/scenePreviewRotation';
function emptyState(): SceneTokensSessionState {
return {
@@ -23,6 +24,26 @@ export class SceneTokensSessionStore {
return this.state;
}
/** Rotate session position overrides with the scene preview (CSS rotate steps). */
rotateMapCwSteps(steps: number): SceneTokensSessionState {
const n = ((steps % 4) + 4) % 4;
if (n === 0) return this.state;
const ids = Object.keys(this.state.byPlacementId);
if (ids.length === 0) return this.state;
const byPlacementId: SceneTokensSessionState['byPlacementId'] = {};
for (const id of ids) {
const prev = this.state.byPlacementId[id];
if (!prev) continue;
const next = rotateMapNormPointByCwSteps(prev.nx, prev.ny, n);
byPlacementId[id] = { nx: next.nx, ny: next.ny };
}
this.state = {
revision: this.state.revision + 1,
byPlacementId,
};
return this.state;
}
dispatch(event: SceneTokensSessionEvent): SceneTokensSessionState {
switch (event.kind) {
case 'clear':