diff --git a/docs/user/main-feature.md b/docs/user/main-feature.md index 7133196..4325450 100644 --- a/docs/user/main-feature.md +++ b/docs/user/main-feature.md @@ -15,6 +15,8 @@ The current user flow is: 5. Watch the case open or close with sound feedback. 6. Interact with repair module slots to cycle/select repair models. +The production repair flow is now being moved toward reusable mission data for `bike`, `pylone`, and `ferme`. This lets the same future `RepairGame` component read one mission config instead of duplicating per-mission setup. + ## Why It Matters This feature validates the core repair fantasy before a full mission system exists. It tests whether repair objects, physical proximity, model selection, audio feedback, and exploded model visualization can work together in the 3D scene. @@ -38,6 +40,8 @@ Repair module slots are configured from static gameplay data. They render select - `src/data/gameplay/repairCaseConfig.ts` stores repair case model, sound, and animation constants. - `src/data/gameplay/repairGameConfig.ts` stores repair zone and slot positions. - `src/data/gameplay/repairGameModelCatalog.ts` stores selectable repair models. +- `src/data/gameplay/repairMissions.ts` stores reusable repair mission config for `bike`, `pylone`, and `ferme`. +- `src/managers/stores/useGameStore.ts` stores mission progression state and generic mission step helpers. ## Debug Requirements @@ -74,7 +78,8 @@ python -m backend.main ## Current Limitations - It is mounted only in the debug physics scene. -- There is no mission progression system yet. -- There is no central `GameManager` or Zustand store in this branch. +- The production `RepairGame` component is not mounted in the main game scene yet. +- Mission progression exists in Zustand, but the full repair mission flow is still being integrated. +- There is no central `GameManager` in this branch. - Hand tracking is available as debug interaction input, not as final repair gameplay. - The repair-game content is configured statically in `src/data/gameplay/`. diff --git a/src/data/gameplay/repairMissions.ts b/src/data/gameplay/repairMissions.ts new file mode 100644 index 0000000..dd0135c --- /dev/null +++ b/src/data/gameplay/repairMissions.ts @@ -0,0 +1,88 @@ +import type { RepairMissionId } from "@/managers/stores/useGameStore"; +import type { Vector3Scale, Vector3Tuple } from "@/types/three/three"; + +export interface RepairMissionCaseConfig { + position: Vector3Tuple; + rotation: Vector3Tuple; + scale: Vector3Scale; +} + +export interface RepairMissionPartConfig { + id: string; + label: string; + nodeName?: string; + modelPath?: string; +} + +export interface RepairMissionConfig { + id: RepairMissionId; + label: string; + description: string; + modelPath: string; + stageUiPath: string; + interactUiPath: string; + brokenUiPath: string; + case: RepairMissionCaseConfig; + brokenParts: readonly RepairMissionPartConfig[]; + replacementParts: readonly RepairMissionPartConfig[]; +} + +const REPAIR_INTERACT_UI_PATH = "/assets/UI/interagir.webm"; +const REPAIR_BROKEN_UI_PATH = "/assets/UI/cassé.webm"; + +const DEFAULT_REPAIR_CASE = { + position: [0, 0.4, 1.8], + rotation: [0, 0, 0], + scale: 1.5, +} satisfies RepairMissionCaseConfig; + +export const REPAIR_MISSIONS = { + bike: { + id: "bike", + label: "E-bike", + description: + "Repair the damaged cooling module before relaunching the bike", + modelPath: "/models/refroidisseur/model.gltf", + stageUiPath: "/assets/UI/ebike.webm", + interactUiPath: REPAIR_INTERACT_UI_PATH, + brokenUiPath: REPAIR_BROKEN_UI_PATH, + case: DEFAULT_REPAIR_CASE, + brokenParts: [ + { + id: "bike-cooling-core", + label: "Cooling core", + }, + ], + replacementParts: [ + { + id: "bike-cooling-core-replacement", + label: "Replacement cooling core", + modelPath: "/models/refroidisseur/model.gltf", + }, + ], + }, + pylone: { + id: "pylone", + label: "Power pylon", + description: "Generic description", + modelPath: "/models/pylone/model.gltf", + stageUiPath: "/assets/UI/centrale.webm", + interactUiPath: REPAIR_INTERACT_UI_PATH, + brokenUiPath: REPAIR_BROKEN_UI_PATH, + case: DEFAULT_REPAIR_CASE, + brokenParts: [], + replacementParts: [], + }, + ferme: { + id: "ferme", + label: "Vertical farm", + description: "Genreric description", + modelPath: "/models/fermeverticale/model.gltf", + stageUiPath: "/assets/UI/laferme.webm", + interactUiPath: REPAIR_INTERACT_UI_PATH, + brokenUiPath: REPAIR_BROKEN_UI_PATH, + case: DEFAULT_REPAIR_CASE, + brokenParts: [], + replacementParts: [], + }, +} satisfies Record;