add: repair fragmentation and scan flow
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import { useCallback, useEffect, useRef } from "react";
|
||||
import { REPAIR_FRAGMENTATION_FIST_HOLD_SECONDS } from "@/data/gameplay/repairGameConfig";
|
||||
import { INTERACT_KEY } from "@/data/input/keybindings";
|
||||
import { useBothFistsHold } from "@/hooks/handTracking/useBothFistsHold";
|
||||
|
||||
interface UseRepairFragmentationInputOptions {
|
||||
enabled: boolean;
|
||||
onFragment: () => void;
|
||||
}
|
||||
|
||||
export function useRepairFragmentationInput({
|
||||
enabled,
|
||||
onFragment,
|
||||
}: UseRepairFragmentationInputOptions): void {
|
||||
const completedRef = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (enabled) return;
|
||||
|
||||
completedRef.current = false;
|
||||
}, [enabled]);
|
||||
|
||||
const fragment = useCallback(() => {
|
||||
if (!enabled) return;
|
||||
if (completedRef.current) return;
|
||||
|
||||
completedRef.current = true;
|
||||
onFragment();
|
||||
}, [enabled, onFragment]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!enabled) return undefined;
|
||||
|
||||
const handleKeyDown = (event: KeyboardEvent): void => {
|
||||
if (event.key.toLowerCase() !== INTERACT_KEY) return;
|
||||
|
||||
event.preventDefault();
|
||||
fragment();
|
||||
};
|
||||
|
||||
window.addEventListener("keydown", handleKeyDown);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("keydown", handleKeyDown);
|
||||
};
|
||||
}, [enabled, fragment]);
|
||||
|
||||
useBothFistsHold({
|
||||
enabled,
|
||||
holdSeconds: REPAIR_FRAGMENTATION_FIST_HOLD_SECONDS,
|
||||
onComplete: fragment,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useFrame } from "@react-three/fiber";
|
||||
import { useHandTrackingSnapshot } from "@/hooks/handTracking/useHandTrackingSnapshot";
|
||||
|
||||
interface UseBothFistsHoldOptions {
|
||||
enabled: boolean;
|
||||
holdSeconds: number;
|
||||
onComplete: () => void;
|
||||
}
|
||||
|
||||
export function useBothFistsHold({
|
||||
enabled,
|
||||
holdSeconds,
|
||||
onComplete,
|
||||
}: UseBothFistsHoldOptions): void {
|
||||
const { hands } = useHandTrackingSnapshot();
|
||||
const elapsedRef = useRef(0);
|
||||
const completedRef = useRef(false);
|
||||
const onCompleteRef = useRef(onComplete);
|
||||
|
||||
useEffect(() => {
|
||||
onCompleteRef.current = onComplete;
|
||||
}, [onComplete]);
|
||||
|
||||
useEffect(() => {
|
||||
if (enabled) return;
|
||||
|
||||
elapsedRef.current = 0;
|
||||
completedRef.current = false;
|
||||
}, [enabled]);
|
||||
|
||||
useFrame((_, delta) => {
|
||||
if (!enabled) return;
|
||||
if (completedRef.current) return;
|
||||
|
||||
const fistCount = hands.filter((hand) => hand.isFist).length;
|
||||
if (fistCount < 2) {
|
||||
elapsedRef.current = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
elapsedRef.current += delta;
|
||||
if (elapsedRef.current < holdSeconds) return;
|
||||
|
||||
completedRef.current = true;
|
||||
onCompleteRef.current();
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user