fix: scene clear race, path editor anchors, avatar cover, team color crash

Clear scene now patches traps/tokens/npcTokens atomically and updateScene merges against a fresh scene snapshot. Align NPC path-editor previews on token center, default new paths to fixed facing, size avatars by natural aspect for cover, and read team color synchronously from the picker.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Ivan Fontosh
2026-08-29 15:30:28 +08:00
parent 028c1be059
commit 0a9168b320
10 changed files with 189 additions and 95 deletions
+25
View File
@@ -2,8 +2,10 @@ import assert from 'node:assert/strict';
import test from 'node:test';
import {
createEmptyTokenPath,
findNearestAheadDistance,
normalizeTokenPath,
normalizeTokenPathFacingMode,
reverseTokenPathPoints,
rotateTokenPathByCwSteps,
sampleTokenPathAtProgress,
@@ -12,6 +14,29 @@ import {
TOKEN_PATH_MIN_POINT_DIST,
} from './tokenPath';
void test('createEmptyTokenPath defaults to fixed facing (no auto-rotate)', () => {
const empty = createEmptyTokenPath();
assert.equal(empty.facingMode, 'fixed');
assert.equal(empty.fixedRotationDeg, 0);
});
void test('normalizeTokenPathFacingMode: missing → fixed; explicit tangent kept', () => {
assert.equal(normalizeTokenPathFacingMode(undefined), 'fixed');
assert.equal(normalizeTokenPathFacingMode('fixed'), 'fixed');
assert.equal(normalizeTokenPathFacingMode('tangentSmooth'), 'tangentSmooth');
});
void test('normalizeTokenPath defaults facingMode to fixed when omitted', () => {
const p = normalizeTokenPath({
points: [
{ nx: 0.1, ny: 0.1 },
{ nx: 0.5, ny: 0.1 },
],
});
assert.ok(p);
assert.equal(p!.facingMode, 'fixed');
});
void test('tryAppendPathPoint rejects double-click distance', () => {
const a = tryAppendPathPoint([], { nx: 0.1, ny: 0.1 });
assert.ok(a);
+2 -2
View File
@@ -56,13 +56,13 @@ export function createEmptyTokenPath(): TokenPath {
durationSec: DEFAULT_TOKEN_PATH_DURATION_SEC,
startMode: 'onEnter',
delaySec: DEFAULT_TOKEN_PATH_DELAY_SEC,
facingMode: 'tangentSmooth',
facingMode: 'fixed',
fixedRotationDeg: 0,
};
}
export function normalizeTokenPathFacingMode(raw: unknown): TokenPathFacingMode {
return raw === 'fixed' ? 'fixed' : 'tangentSmooth';
return raw === 'tangentSmooth' ? 'tangentSmooth' : 'fixed';
}
export function normalizeTokenPathLoopMode(raw: unknown, closed: boolean): TokenPathLoopMode {