refactor(repair): unify exploded model across phases, simplify ebike flow
- RepairGame: lift a single ExplodableModel mounted across fragmented -> done so the model loads once, animates from its real original positions, and never re-instantiates between phases. Eliminates the position/rotation jumps and re-explosion that occurred when each step instantiated its own model. - ExplodableModel: expose splitSpeed prop so the explode/reassemble lerp can be slowed down (REPAIR_FRAGMENT_SPLIT_SPEED = 1.8) for a more deliberate visual where each node is seen leaving its origin. - RepairScanSequence: drop its own ExplodableModel, receive parts from the upstream shared instance. Logs the available part names when broken-part nodes can't be matched so config drift is visible. - RepairReassemblyStep: reduced to the completion particles + a delayed onSettled callback. The collapse animation is now driven by the shared ExplodableModel switching split=false at the reassembling phase. After REPAIR_REASSEMBLY_HOLD_MS (1500ms) the upstream flow auto-advances to done. - RepairEbikeRepairTrigger: new minimal interactable for the ebike repairing step. Replaces the heavier grabbable-parts UX (cercles, ranger pieces) with a single 'Changez le refroidisseur' prompt that advances directly to reassembling. Pylon/farm keep RepairRepairingStep. - RepairCompletionStep: drop the duplicated RepairObjectModel; the shared ExplodableModel renders the repaired model at done. - RepairGame ebike-done: play narrateur_ebikerepare and call completeMission on the audio's ended event (with REPAIR_DONE_DIALOGUE_FALLBACK_MS fallback). Hands off to pylon without a Validate button. - EbikeRepairNarrator: drop the done entry; RepairGame owns it now so the audio's end event can drive the mission completion handoff. - RepairGame: drop the window.ebikeParkedPosition livePosition logic. Ebike movement is disabled during the repair flow so the static zone position is the source of truth, fixing the floating-bike issue observed in TestMap.
This commit is contained in:
@@ -1,8 +1,5 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import {
|
||||
EBIKE_REPAIRED_DIALOGUE_ID,
|
||||
EBIKE_SCAN_HINT_DIALOGUE_ID,
|
||||
} from "@/data/ebike/ebikeConfig";
|
||||
import { EBIKE_SCAN_HINT_DIALOGUE_ID } from "@/data/ebike/ebikeConfig";
|
||||
import { useGameStore } from "@/managers/stores/useGameStore";
|
||||
import { useSubtitleStore } from "@/managers/stores/useSubtitleStore";
|
||||
import type { MissionStep } from "@/types/gameplay/repairMission";
|
||||
@@ -12,14 +9,13 @@ import { playDialogueById } from "@/utils/dialogues/playDialogue";
|
||||
/**
|
||||
* Plays narrator cues during the ebike repair game:
|
||||
* - `fragmented` -> "Alors? Pas magnifique ça?... ces galets vont scanner..."
|
||||
* - `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`.
|
||||
* The `narrateur_refroidisseur_diagnostic` line is triggered by the
|
||||
* scan sequence itself when it lands on the refroidisseur node
|
||||
* (configured via `RepairMissionPartConfig.voiceLineId` on the broken
|
||||
* part). The `narrateur_ebikerepare` line is triggered by RepairGame
|
||||
* directly at the `done` step so its `ended` event can drive the
|
||||
* mission completion handoff.
|
||||
*
|
||||
* 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
|
||||
@@ -32,7 +28,6 @@ import { playDialogueById } from "@/utils/dialogues/playDialogue";
|
||||
*/
|
||||
const STEP_TO_DIALOGUE_ID: Partial<Record<MissionStep, string>> = {
|
||||
fragmented: EBIKE_SCAN_HINT_DIALOGUE_ID,
|
||||
done: EBIKE_REPAIRED_DIALOGUE_ID,
|
||||
};
|
||||
|
||||
function stopAudio(audio: HTMLAudioElement | null): void {
|
||||
|
||||
Reference in New Issue
Block a user