forked from phenom/healer-man
34 lines
2.1 KiB
TypeScript
34 lines
2.1 KiB
TypeScript
import { findNearestPartyNavigationSurface, type PartyNavigationGraph } from "./partyNavigation";
|
|
import { emptyPartyRouteState, nextPartyRouteRecoveryWaypoint, nextPartyRouteWaypoint, partyRouteNeedsPlanning, planPartyRoute, type PartyRouteOptions, type PartyRouteState } from "./partyPathing";
|
|
import type { PartyWorldPosition } from "./partyRuntimeRegistry";
|
|
|
|
export const PARTY_REJOIN_DISTANCE = 3;
|
|
|
|
/** Returning resurrected members target the player, not a distant boss or leader. */
|
|
export function partyRejoinMovement(
|
|
id: string, current: PartyWorldPosition, player: PartyWorldPosition, nowMs: number,
|
|
graph: PartyNavigationGraph | null, route: PartyRouteState,
|
|
options: Pick<PartyRouteOptions, "directSegmentAllowed" | "routeSegmentAllowed">,
|
|
) {
|
|
const reachedPlayer = (point: PartyWorldPosition) => Math.hypot(
|
|
point[0] - player[0], point[1] - player[1], point[2] - player[2],
|
|
) <= PARTY_REJOIN_DISTANCE && Boolean(options.directSegmentAllowed?.(point, player));
|
|
if (reachedPlayer(current)) return { rejoined: true, route: emptyPartyRouteState(), waypoint: null, blocked: false };
|
|
if (options.directSegmentAllowed?.(current, player)) {
|
|
return { rejoined: false, route: emptyPartyRouteState(), waypoint: player, blocked: false };
|
|
}
|
|
const destination = graph ? findNearestPartyNavigationSurface(graph, player, 5)?.position ?? player : player;
|
|
const goalKey = `member:${id}|resurrection-rejoin`;
|
|
if (partyRouteNeedsPlanning(route, goalKey, current, destination, nowMs, { replanIntervalMs: 350, blockedRetryMs: 800 })) {
|
|
route = planPartyRoute(graph, goalKey, current, destination, nowMs, {
|
|
...options, maxOriginSnapDistance: 6, maxDestinationSnapDistance: 5,
|
|
localFinishDistance: PARTY_REJOIN_DISTANCE,
|
|
destinationReached: reachedPlayer,
|
|
});
|
|
}
|
|
const waypoint: [number, number, number] = [0, 0, 0];
|
|
const hasWaypoint = nextPartyRouteWaypoint(route, current, waypoint)
|
|
|| nextPartyRouteRecoveryWaypoint(route, current, waypoint, options.directSegmentAllowed ?? (() => false));
|
|
return { rejoined: false, route, waypoint: hasWaypoint ? waypoint : null, blocked: route.blocked && !hasWaypoint };
|
|
}
|