split narrator srt
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { useEffect } from "react";
|
||||
import { useGameStore } from "@/managers/stores/useGameStore";
|
||||
import { useDialoguePlayback } from "@/hooks/gameplay/useDialoguePlayback";
|
||||
import { ZoneDetection } from "@/components/zone/ZoneDetection";
|
||||
@@ -5,22 +6,109 @@ import { PylonFarmerNPC } from "@/components/gameplay/pylon/PylonFarmerNPC";
|
||||
import { PylonNarratorOutro } from "@/components/gameplay/pylon/PylonNarratorOutro";
|
||||
import { PYLON_APPROACH_ZONE, PYLON_ARRIVED_ZONE } from "@/data/gameplay/zones";
|
||||
import { PYLON_NARRATIVE_DIALOGUES } from "@/data/gameplay/pylonConfig";
|
||||
import { AudioManager } from "@/managers/AudioManager";
|
||||
import { loadDialogueManifest } from "@/utils/dialogues/loadDialogueManifest";
|
||||
import { playDialogueById } from "@/utils/dialogues/playDialogue";
|
||||
|
||||
const PYLON_POWERDOWN_SFX = "/sounds/effect/generateur-powerdown.mp3";
|
||||
const PYLON_POWERUP_SFX = "/sounds/effect/generateur-powerup.mp3";
|
||||
|
||||
export function PylonNarrativeFlow(): React.JSX.Element | null {
|
||||
const mainState = useGameStore((state) => state.mainState);
|
||||
const step = useGameStore((state) => state.pylon.currentStep);
|
||||
const setMissionStep = useGameStore((state) => state.setMissionStep);
|
||||
const setCanMove = useGameStore((state) => state.setCanMove);
|
||||
|
||||
useDialoguePlayback({
|
||||
enabled: mainState === "pylon" && step === "approaching",
|
||||
dialogueId: PYLON_NARRATIVE_DIALOGUES.electricOutage,
|
||||
});
|
||||
// ── approaching : powerdown sfx → then electricOutage dialogue ────────────
|
||||
useEffect(() => {
|
||||
if (mainState !== "pylon" || step !== "approaching") return undefined;
|
||||
|
||||
let isCancelled = false;
|
||||
setCanMove(false);
|
||||
|
||||
void (async () => {
|
||||
// 1. Play the generator powerdown sound effect
|
||||
const sfx = AudioManager.getInstance().playSound(
|
||||
PYLON_POWERDOWN_SFX,
|
||||
1,
|
||||
{ category: "sfx" },
|
||||
);
|
||||
|
||||
// 2. Wait for it to finish (or skip if it can't load)
|
||||
if (sfx) {
|
||||
await new Promise<void>((resolve) => {
|
||||
sfx.addEventListener("ended", () => resolve(), { once: true });
|
||||
sfx.addEventListener("error", () => resolve(), { once: true });
|
||||
});
|
||||
}
|
||||
|
||||
if (isCancelled) return;
|
||||
|
||||
// 3. Play the narrative dialogue
|
||||
const manifest = await loadDialogueManifest();
|
||||
if (isCancelled || !manifest) {
|
||||
setCanMove(true);
|
||||
return;
|
||||
}
|
||||
|
||||
const audio = await playDialogueById(
|
||||
manifest,
|
||||
PYLON_NARRATIVE_DIALOGUES.electricOutage,
|
||||
);
|
||||
|
||||
if (isCancelled || !audio) {
|
||||
setCanMove(true);
|
||||
return;
|
||||
}
|
||||
|
||||
audio.addEventListener(
|
||||
"ended",
|
||||
() => {
|
||||
setCanMove(true);
|
||||
},
|
||||
{ once: true },
|
||||
);
|
||||
})();
|
||||
|
||||
return () => {
|
||||
isCancelled = true;
|
||||
setCanMove(true);
|
||||
};
|
||||
}, [mainState, step, setCanMove]);
|
||||
|
||||
// ── arrived : searchCentral dialogue (unchanged) ──────────────────────────
|
||||
useDialoguePlayback({
|
||||
enabled: mainState === "pylon" && step === "arrived",
|
||||
dialogueId: PYLON_NARRATIVE_DIALOGUES.searchCentral,
|
||||
});
|
||||
|
||||
// ── done : powerup sfx + lighting revert → auto-transition to narrator-outro
|
||||
useEffect(() => {
|
||||
if (mainState !== "pylon" || step !== "done") return undefined;
|
||||
|
||||
const sfx = AudioManager.getInstance().playSound(PYLON_POWERUP_SFX, 1, {
|
||||
category: "sfx",
|
||||
});
|
||||
|
||||
if (sfx) {
|
||||
sfx.addEventListener(
|
||||
"ended",
|
||||
() => setMissionStep("pylon", "narrator-outro"),
|
||||
{ once: true },
|
||||
);
|
||||
sfx.addEventListener(
|
||||
"error",
|
||||
() => setMissionStep("pylon", "narrator-outro"),
|
||||
{ once: true },
|
||||
);
|
||||
} else {
|
||||
// Fallback if the audio can't load
|
||||
setMissionStep("pylon", "narrator-outro");
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}, [mainState, step, setMissionStep]);
|
||||
|
||||
// narrator-outro audio sequence + completeMission are handled in PylonNarratorOutro
|
||||
|
||||
if (mainState !== "pylon") return null;
|
||||
|
||||
Reference in New Issue
Block a user