forked from phenom/healer-man
33 lines
1.5 KiB
TypeScript
33 lines
1.5 KiB
TypeScript
import { useRapier } from "@react-three/rapier";
|
|
import { useEffect, useMemo } from "react";
|
|
import { combatNavigationGraph } from "../game/combatSpatial";
|
|
import { createMobPursuit } from "../game/mobPursuit";
|
|
import { registerDungeonRuntimeReset } from "../game/dungeonRuntimeReset";
|
|
import { hasDungeonLineOfSight } from "./dungeonLineOfSight";
|
|
import { createPartyDirectSegmentValidator, createPartyRecoveryPointValidator, createPartyRouteSegmentValidator } from "./partyTraversal";
|
|
|
|
/** Uses terrain only; actors remain non-blocking and the graph is loaded only once. */
|
|
export function useMobNavigation() {
|
|
const { rapier, world } = useRapier();
|
|
const navigator = useMemo(() => {
|
|
let graph = combatNavigationGraph();
|
|
let landing = createPartyRecoveryPointValidator(rapier, world, graph);
|
|
return createMobPursuit({
|
|
graph: combatNavigationGraph,
|
|
hasLineOfSight: (from, to) => hasDungeonLineOfSight(rapier, world, from, to),
|
|
directAllowed: createPartyDirectSegmentValidator(rapier, world),
|
|
routeAllowed: createPartyRouteSegmentValidator(rapier, world),
|
|
validateLanding: (point, anchor) => {
|
|
const currentGraph = combatNavigationGraph();
|
|
if (graph !== currentGraph) {
|
|
graph = currentGraph;
|
|
landing = createPartyRecoveryPointValidator(rapier, world, graph);
|
|
}
|
|
return landing(point, anchor);
|
|
},
|
|
});
|
|
}, [rapier, world]);
|
|
useEffect(() => registerDungeonRuntimeReset(navigator.clear), [navigator]);
|
|
return navigator;
|
|
}
|