Add staggered-start car call-outs and a per-driver done indicator
Staggered-start qualifying heats now announce each car's transponder number in grid order (~3s apart) right after the official start, matching what a track announcer does when releasing cars one at a time; mass/position starts are unaffected. The Timing leaderboard and every overlay variant now also show a green "Done" flag next to a driver's name once their own personal timing window (which already started at their own first crossing) has elapsed, even while the session is still running for other drivers. Also confirmed two things already worked correctly: finals already always start everyone together with the shared countdown/lights/tone sequence, and practice's time-up announcement already says "finish the lap you are on" - only a "2 minutes remaining" cue is genuinely missing from the existing 1min/30s/10s ladder, left as an open question for the user. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@ export const RACE_AUDIO_EVENT_DEFINITIONS = Object.freeze([
|
||||
event("drivers_ready", "start", "high"), event("start_sequence", "start", "high"),
|
||||
event("start_tone", "start", "high", false, "effects/start_beep.wav"),
|
||||
event("false_start", "start", "critical", true, "effects/warning.wav", 1000), event("restart_race", "start", "high"),
|
||||
event("staggered_release", "start", "normal"),
|
||||
event("transponder_pass", "race", "pass", false, "effects/transponder_pass.wav"), event("lap_completed", "race", "pass", false),
|
||||
event("personal_best", "race", "low", true, "effects/personal_best.wav", 1500),
|
||||
event("fastest_lap", "race", "normal", true, "effects/fastest_lap_trophy.wav", 1500),
|
||||
@@ -277,6 +278,18 @@ export function createRaceAudioEngine(options = {}) {
|
||||
await playEffect("start_tone", { force: true });
|
||||
if (cancelled()) return false;
|
||||
callbacks.onTone?.();
|
||||
// Staggered heats don't release every car at once - the session is already live and
|
||||
// recording by this point (each driver's own personal clock starts at their own first
|
||||
// crossing regardless), this is purely the announcer calling cars out in grid order so
|
||||
// marshals know who goes next, ~3s apart.
|
||||
if (session?.startMode === "staggered" && Array.isArray(callbacks.staggerOrder) && callbacks.staggerOrder.length) {
|
||||
for (let index = 0; index < callbacks.staggerOrder.length; index += 1) {
|
||||
if (cancelled()) return false;
|
||||
await trigger("staggered_release", { variables: { tp: callbacks.staggerOrder[index] }, scope: callbacks.staggerOrder[index], logData: { sessionId: session?.id, transponder: callbacks.staggerOrder[index] } }).voiceDone;
|
||||
if (cancelled()) return false;
|
||||
if (index < callbacks.staggerOrder.length - 1) { await wait(3000); if (cancelled()) return false; }
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user