diff --git a/src/components/three/gameplay/RepairCompletionStep.tsx b/src/components/three/gameplay/RepairCompletionStep.tsx
index 19aa09d..117d2b1 100644
--- a/src/components/three/gameplay/RepairCompletionStep.tsx
+++ b/src/components/three/gameplay/RepairCompletionStep.tsx
@@ -4,6 +4,7 @@ import { RepairPromptVideo } from "@/components/three/gameplay/RepairPromptVideo
import { RepairMissionCase } from "@/components/three/gameplay/RepairMissionCase";
import { TriggerObject } from "@/components/three/interaction/TriggerObject";
import { REPAIR_CASE_ANIMATION_DURATION } from "@/data/gameplay/repairCaseConfig";
+import { REPAIR_INTERACTION_RADIUS } from "@/data/gameplay/repairGameConfig";
import type { RepairMissionConfig } from "@/data/gameplay/repairMissions";
interface RepairCompletionStepProps {
@@ -42,7 +43,7 @@ export function RepairCompletionStep({
{!isClosingCase ? (
@@ -50,6 +51,7 @@ export function RepairCompletionStep({
position={[0, 1.1, 0]}
colliders="ball"
label={`Valider ${config.label}`}
+ radius={REPAIR_INTERACTION_RADIUS}
onTrigger={() => setIsClosingCase(true)}
>
diff --git a/src/components/three/gameplay/RepairGame.tsx b/src/components/three/gameplay/RepairGame.tsx
index 2da937e..aa4fa5e 100644
--- a/src/components/three/gameplay/RepairGame.tsx
+++ b/src/components/three/gameplay/RepairGame.tsx
@@ -122,7 +122,11 @@ export function RepairGame({
/>
) : null}
{step === "fragmented" ? (
-
+
) : null}
{step === "scanning" ? (
-
+
);
}
diff --git a/src/components/three/gameplay/RepairMissionCase.tsx b/src/components/three/gameplay/RepairMissionCase.tsx
index 3489229..f0e743f 100644
--- a/src/components/three/gameplay/RepairMissionCase.tsx
+++ b/src/components/three/gameplay/RepairMissionCase.tsx
@@ -9,6 +9,7 @@ import {
REPAIR_CASE_FOCUS_SCALE,
REPAIR_CASE_MODEL_PATH,
} from "@/data/gameplay/repairCaseConfig";
+import { REPAIR_INTERACTION_RADIUS } from "@/data/gameplay/repairGameConfig";
import type { RepairMissionConfig } from "@/data/gameplay/repairMissions";
import type { Vector3Tuple } from "@/types/three/three";
@@ -48,6 +49,7 @@ export function RepairMissionCase({
position={casePosition}
colliders="ball"
label={`Ouvrir ${config.label}`}
+ radius={REPAIR_INTERACTION_RADIUS}
onTrigger={onInteract}
>
diff --git a/src/components/three/gameplay/RepairRepairingStep.tsx b/src/components/three/gameplay/RepairRepairingStep.tsx
index 3aba456..dd75395 100644
--- a/src/components/three/gameplay/RepairRepairingStep.tsx
+++ b/src/components/three/gameplay/RepairRepairingStep.tsx
@@ -11,6 +11,7 @@ import {
REPAIR_CASE_PLACEHOLDER_SNAP_DURATION,
REPAIR_CASE_PLACEHOLDER_SNAP_RADIUS,
} from "@/data/gameplay/repairCaseConfig";
+import { REPAIR_INTERACTION_RADIUS } from "@/data/gameplay/repairGameConfig";
import type {
RepairMissionConfig,
RepairMissionPartConfig,
@@ -299,6 +300,7 @@ function RepairInstallTarget({
position={INSTALL_TARGET_POSITION}
colliders="ball"
label={label}
+ radius={REPAIR_INTERACTION_RADIUS}
onTrigger={() => {
if (!isReadyToInstall) {
onBlocked();
diff --git a/src/components/three/gameplay/RepairScanSequence.tsx b/src/components/three/gameplay/RepairScanSequence.tsx
index 65b0b83..c2f99f4 100644
--- a/src/components/three/gameplay/RepairScanSequence.tsx
+++ b/src/components/three/gameplay/RepairScanSequence.tsx
@@ -60,6 +60,7 @@ export function RepairScanSequence({
diff --git a/src/components/three/interaction/InteractableObject.tsx b/src/components/three/interaction/InteractableObject.tsx
index a7bf36e..316d7ae 100644
--- a/src/components/three/interaction/InteractableObject.tsx
+++ b/src/components/three/interaction/InteractableObject.tsx
@@ -19,6 +19,7 @@ import type { Vector3Tuple } from "@/types/three/three";
interface InteractableObjectBaseProps {
label: string;
position: Vector3Tuple;
+ radius?: number;
bodyRef?: RefObject;
onPress: () => void;
children: React.ReactNode;
@@ -64,7 +65,15 @@ function createInteractableHandle(
export function InteractableObject(
props: InteractableObjectProps,
): React.JSX.Element {
- const { kind, label, position, bodyRef, onPress, children } = props;
+ const {
+ kind,
+ label,
+ position,
+ radius = INTERACTION_RADIUS,
+ bodyRef,
+ onPress,
+ children,
+ } = props;
const onRelease = props.kind === "grab" ? props.onRelease : null;
const camera = useThree((state) => state.camera);
const groupRef = useRef(null);
@@ -156,7 +165,7 @@ export function InteractableObject(
camera.getWorldPosition(_cameraPos);
const dist = _cameraPos.distanceTo(_objectPos);
- const isNearby = dist <= INTERACTION_RADIUS;
+ const isNearby = dist <= radius;
manager.setNearby(handle.current, isNearby);
@@ -169,7 +178,7 @@ export function InteractableObject(
camera.getWorldDirection(_cameraDir);
_raycaster.set(_cameraPos, _cameraDir);
- _raycaster.far = INTERACTION_RADIUS;
+ _raycaster.far = radius;
const hits = group ? _raycaster.intersectObject(group, true) : [];
const validHit = hits.find((h) => h.object !== debugSphereRef.current);
@@ -187,7 +196,7 @@ export function InteractableObject(
{
if (soundPath) {
diff --git a/src/data/gameplay/repairGameConfig.ts b/src/data/gameplay/repairGameConfig.ts
index 307dd65..1e28210 100644
--- a/src/data/gameplay/repairGameConfig.ts
+++ b/src/data/gameplay/repairGameConfig.ts
@@ -1,4 +1,5 @@
export const REPAIR_FRAGMENTATION_FIST_HOLD_SECONDS = 1;
export const REPAIR_FRAGMENTATION_SEQUENCE_SECONDS = 4;
+export const REPAIR_INTERACTION_RADIUS = 10;
export const REPAIR_SCAN_PART_SECONDS = 1.2;
export const REPAIR_REASSEMBLY_SECONDS = 1.4;
diff --git a/src/data/gameplay/repairMissions.ts b/src/data/gameplay/repairMissions.ts
index f2c1636..5d05f15 100644
--- a/src/data/gameplay/repairMissions.ts
+++ b/src/data/gameplay/repairMissions.ts
@@ -1,5 +1,9 @@
import type { RepairMissionId } from "@/types/gameplay/repairMission";
-import type { Vector3Scale, Vector3Tuple } from "@/types/three/three";
+import type {
+ ModelTransformProps,
+ Vector3Scale,
+ Vector3Tuple,
+} from "@/types/three/three";
export interface RepairMissionCaseConfig {
position: Vector3Tuple;
@@ -20,6 +24,7 @@ export interface RepairMissionConfig {
label: string;
description: string;
modelPath: string;
+ modelScale?: ModelTransformProps["scale"];
stageUiPath: string;
interactUiPath: string;
brokenUiPath: string;
@@ -40,13 +45,14 @@ const DEFAULT_REPAIR_CASE = {
scale: 1.5,
} satisfies RepairMissionCaseConfig;
-export const REPAIR_MISSIONS = {
+export const REPAIR_MISSIONS: Record = {
bike: {
id: "bike",
label: "E-bike",
description:
"Repair the damaged cooling module before relaunching the bike",
- modelPath: "/models/refroidisseur/model.gltf",
+ modelPath: "/models/ebike/model.gltf",
+ modelScale: 0.25,
stageUiPath: "/assets/UI/ebike.webm",
interactUiPath: REPAIR_INTERACT_UI_PATH,
brokenUiPath: REPAIR_BROKEN_UI_PATH,
@@ -56,7 +62,8 @@ export const REPAIR_MISSIONS = {
{
id: "bike-cooling-core",
label: "Cooling core",
- nodeName: "Cylinder",
+ modelPath: "/models/refroidisseur/model.gltf",
+ nodeName: "refroidisseur",
placeholderName: "placeholder_1",
},
],
@@ -74,7 +81,7 @@ export const REPAIR_MISSIONS = {
{
id: "bike-glove-decoy",
label: "Insulation glove",
- modelPath: "/models/gant/model.gltf",
+ modelPath: "/models/gant_l/model.gltf",
},
],
},
@@ -166,4 +173,4 @@ export const REPAIR_MISSIONS = {
},
],
},
-} satisfies Record;
+};
diff --git a/src/hooks/gameplay/useRepairMovementLocked.ts b/src/hooks/gameplay/useRepairMovementLocked.ts
index 11953ce..c92e611 100644
--- a/src/hooks/gameplay/useRepairMovementLocked.ts
+++ b/src/hooks/gameplay/useRepairMovementLocked.ts
@@ -2,6 +2,8 @@ import { useGameStore } from "@/managers/stores/useGameStore";
import type { MissionStep } from "@/types/gameplay/repairMission";
export function useRepairMovementLocked(): boolean {
+ return false;
+
return useGameStore((state) => {
switch (state.mainState) {
case "bike":