1
0

fix: close California play and asset acceptance gaps

This commit is contained in:
2026-08-11 22:49:37 -07:00
parent d4859b33c6
commit dd18c6775d
12 changed files with 267 additions and 126 deletions
+10 -2
View File
@@ -72,7 +72,7 @@ export interface VehicleControllerState extends GeographicPoint {
routeId: string;
mode: VehicleControlMode;
direction: 1 | -1;
/** Distance from the route's declared start, wrapped to its total length. */
/** Distance from the route's declared start. A restored endpoint may equal route length. */
distanceM: number;
progress: number;
/** Signed offset from route centre; positive is to the driver's right. */
@@ -212,6 +212,9 @@ export class VehicleController {
this.pack = pack;
this.options = resolveOptions(options);
this.path = buildRoutePath(pack, this.options.routeId);
if (options.initialDistanceM === undefined && this.options.direction === -1) {
this.options.initialDistanceM = this.path.lengthM;
}
const sample = sampleRoute(this.path, this.options.initialDistanceM, this.options.direction);
const point = offsetPoint(sample, 0);
this.current = {
@@ -257,7 +260,12 @@ export class VehicleController {
/** Restore the configured spawn state and clear pending fractional time. */
reset(): void {
this.accumulator = 0;
const distanceM = wrap(this.options.initialDistanceM, this.path.lengthM);
const wrappedDistanceM = wrap(this.options.initialDistanceM, this.path.lengthM);
const distanceM = wrappedDistanceM === 0 &&
this.options.initialDistanceM > 0 &&
this.options.initialDistanceM <= this.path.lengthM
? this.path.lengthM
: wrappedDistanceM;
const lateralOffsetM = clamp(
this.options.initialLateralOffsetM,
-this.options.guardrailOffsetM,
+8 -1
View File
@@ -116,7 +116,14 @@ function wrap(value: number, modulus: number): number {
}
export function sampleRoute(path: RoutePath, distanceM: number, direction: 1 | -1 = 1): RouteSample {
const travelled = wrap(distanceM, path.lengthM);
const wrapped = wrap(distanceM, path.lengthM);
// Preserve the authored endpoint when a caller deliberately samples an
// exact positive route length. Simulation steps store their already-wrapped
// zero and still loop normally; restored journey progress=1 must remain at
// San Francisco instead of teleporting to Los Angeles before play resumes.
const travelled = wrapped === 0 && distanceM > 0 && distanceM <= path.lengthM
? path.lengthM
: wrapped;
const leg = path.legs.find((candidate) => travelled <= candidate.endM) ?? path.legs.at(-1);
if (!leg) throw new Error(`transport: route "${path.route.id}" has no legs`);
const t = Math.max(0, Math.min(1, (travelled - leg.startM) / leg.lengthM));