update: show repair movement lock indicator
This commit is contained in:
@@ -2,12 +2,14 @@ import { Crosshair } from "@/components/ui/Crosshair";
|
||||
import { DebugOverlayLayout } from "@/components/ui/debug/DebugOverlayLayout";
|
||||
import { HandTrackingVisualizer } from "@/components/ui/HandTrackingVisualizer";
|
||||
import { InteractPrompt } from "@/components/ui/InteractPrompt";
|
||||
import { RepairMovementLockIndicator } from "@/components/ui/RepairMovementLockIndicator";
|
||||
|
||||
export function GameUI(): React.JSX.Element {
|
||||
return (
|
||||
<>
|
||||
<DebugOverlayLayout />
|
||||
<Crosshair />
|
||||
<RepairMovementLockIndicator />
|
||||
<InteractPrompt />
|
||||
<HandTrackingVisualizer />
|
||||
</>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { useCameraMode } from "@/hooks/debug/useCameraMode";
|
||||
import { useRepairMovementLocked } from "@/hooks/gameplay/useRepairMovementLocked";
|
||||
|
||||
export function RepairMovementLockIndicator(): React.JSX.Element | null {
|
||||
const cameraMode = useCameraMode();
|
||||
const movementLocked = useRepairMovementLocked();
|
||||
|
||||
if (cameraMode !== "player") return null;
|
||||
if (!movementLocked) return null;
|
||||
|
||||
return (
|
||||
<div className="repair-movement-lock-indicator" aria-live="polite">
|
||||
<span
|
||||
className="repair-movement-lock-indicator__dot"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<span>Déplacement verrouillé pendant la réparation</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { useGameStore } from "@/managers/stores/useGameStore";
|
||||
import type { MissionStep } from "@/types/gameplay/repairMission";
|
||||
|
||||
export function useRepairMovementLocked(): boolean {
|
||||
return useGameStore((state) => {
|
||||
switch (state.mainState) {
|
||||
case "bike":
|
||||
return isRepairMovementLocked(state.bike.currentStep);
|
||||
case "pylone":
|
||||
return isRepairMovementLocked(state.pylone.currentStep);
|
||||
case "ferme":
|
||||
return isRepairMovementLocked(state.ferme.currentStep);
|
||||
case "intro":
|
||||
case "outro":
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function isRepairMovementLocked(step: MissionStep): boolean {
|
||||
return (
|
||||
step === "inspected" ||
|
||||
step === "fragmented" ||
|
||||
step === "scanning" ||
|
||||
step === "repairing" ||
|
||||
step === "reassembling"
|
||||
);
|
||||
}
|
||||
@@ -397,6 +397,35 @@ canvas {
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
|
||||
.repair-movement-lock-indicator {
|
||||
position: fixed;
|
||||
top: 22px;
|
||||
left: 50%;
|
||||
z-index: 10;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 9px;
|
||||
padding: 9px 13px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.18);
|
||||
border-radius: 999px;
|
||||
background: rgba(5, 9, 16, 0.72);
|
||||
color: rgba(255, 255, 255, 0.88);
|
||||
font-size: 12px;
|
||||
font-weight: 650;
|
||||
letter-spacing: 0.02em;
|
||||
pointer-events: none;
|
||||
transform: translateX(-50%);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.repair-movement-lock-indicator__dot {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 999px;
|
||||
background: #38bdf8;
|
||||
box-shadow: 0 0 14px rgba(56, 189, 248, 0.86);
|
||||
}
|
||||
|
||||
.scene-loading-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
|
||||
@@ -23,9 +23,8 @@ import {
|
||||
PLAYER_WALK_SPEED,
|
||||
PLAYER_XZ_DAMPING_FACTOR,
|
||||
} from "@/data/player/playerConfig";
|
||||
import { useRepairMovementLocked } from "@/hooks/gameplay/useRepairMovementLocked";
|
||||
import { InteractionManager } from "@/managers/InteractionManager";
|
||||
import { useGameStore } from "@/managers/stores/useGameStore";
|
||||
import type { MissionStep } from "@/types/gameplay/repairMission";
|
||||
import type { Vector3Tuple } from "@/types/three/three";
|
||||
|
||||
type Keys = {
|
||||
@@ -75,32 +74,6 @@ function setMovementKey(keys: Keys, key: string, pressed: boolean): boolean {
|
||||
}
|
||||
}
|
||||
|
||||
function isRepairMovementLocked(step: MissionStep): boolean {
|
||||
return (
|
||||
step === "inspected" ||
|
||||
step === "fragmented" ||
|
||||
step === "scanning" ||
|
||||
step === "repairing" ||
|
||||
step === "reassembling"
|
||||
);
|
||||
}
|
||||
|
||||
function useRepairMovementLocked(): boolean {
|
||||
return useGameStore((state) => {
|
||||
switch (state.mainState) {
|
||||
case "bike":
|
||||
return isRepairMovementLocked(state.bike.currentStep);
|
||||
case "pylone":
|
||||
return isRepairMovementLocked(state.pylone.currentStep);
|
||||
case "ferme":
|
||||
return isRepairMovementLocked(state.ferme.currentStep);
|
||||
case "intro":
|
||||
case "outro":
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function PlayerController({
|
||||
octree,
|
||||
spawnPosition,
|
||||
|
||||
Reference in New Issue
Block a user