feat(repair): per-node scan voicelines, refroidisseur diagnostic gates scanning -> repairing
The ebike refroidisseur diagnostic line used to fire on the 'repairing' step via EbikeRepairNarrator, AFTER the scan sequence had already raced through every part on a fixed timer. Visually the red broken-part highlight appeared and disappeared before the player ever heard which part was actually broken. Now the scan sequence itself can carry per-node voice lines via a new optional config field on each broken part. When the scan lands on a part that has a voice line: - the audio is played immediately (with its subtitle); - the red broken-part highlight is on screen the entire time (existing cumulative highlight behaviour from RepairScanSequence); - the next-part advance is gated on the audio's event; - a 15s ceiling fallback (and per-part fallback when manifest is missing) keeps the flow from stalling if the audio never resolves. Cancel paths (component unmount, mission switch, debug rewind) pause the audio, clear the subtitle, and drop both the listener and the fallback timer to avoid leaks or double-advances. Changes: - types/repairMission: new optional . - data/repairMissions: ebike refroidisseur broken part now declares . - RepairScanSequence: per-part effect now branches on . Default per-part timer is preserved for parts without an audio line (incl. all pylon/farm broken parts and ebike's non-diagnostic parts). - EbikeRepairNarrator: drop the 'repairing' entry from the step -> dialogue map (the diagnostic now plays earlier, during scanning). 'fragmented' (scan hint) and 'done' (repaired voiceover) are unchanged. End result: player hears 'le refroidisseur a laché...' exactly while the red sphere is pulsing on the cooling node, and the case opens for the repairing step the moment the line ends.
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import {
|
||||
EBIKE_DIAGNOSTIC_DIALOGUE_ID,
|
||||
EBIKE_REPAIRED_DIALOGUE_ID,
|
||||
EBIKE_SCAN_HINT_DIALOGUE_ID,
|
||||
} from "@/data/ebike/ebikeConfig";
|
||||
@@ -13,9 +12,15 @@ import { playDialogueById } from "@/utils/dialogues/playDialogue";
|
||||
/**
|
||||
* Plays narrator cues during the ebike repair game:
|
||||
* - `fragmented` -> "Alors? Pas magnifique ça?... ces galets vont scanner..."
|
||||
* - `repairing` -> "Parfait! C'est le refroidisseur qui a lâché..."
|
||||
* - `done` -> "Eeeet voilà! Il fonctionne comme une horloge!..."
|
||||
*
|
||||
* The `narrateur_refroidisseur_diagnostic` line is no longer played
|
||||
* here on the `repairing` step. It is now triggered by the scan
|
||||
* sequence itself when it lands on the refroidisseur node (configured
|
||||
* via `RepairMissionPartConfig.voiceLineId` on the broken part). That
|
||||
* keeps the audio synchronized with the red broken-part highlight and
|
||||
* gates the `scanning -> repairing` transition on the audio's `ended`.
|
||||
*
|
||||
* Each cue is one-shot per mission run; the played-set resets when the
|
||||
* mission state rolls back to `waiting` so debug-panel replays still
|
||||
* trigger the narration.
|
||||
@@ -27,7 +32,6 @@ import { playDialogueById } from "@/utils/dialogues/playDialogue";
|
||||
*/
|
||||
const STEP_TO_DIALOGUE_ID: Partial<Record<MissionStep, string>> = {
|
||||
fragmented: EBIKE_SCAN_HINT_DIALOGUE_ID,
|
||||
repairing: EBIKE_DIAGNOSTIC_DIALOGUE_ID,
|
||||
done: EBIKE_REPAIRED_DIALOGUE_ID,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user