Release Healer Man 0.1.37
This commit is contained in:
1 parent
03a4e3f51c
commit
361734bc41
41 files changed
+1714
-110
No files matched your search
@@ -72,10 +72,14 @@ import {
|
||||
type PartyRouteState,
|
||||
} from "../game/partyPathing";
|
||||
import { partyCombatRangeBand } from "../game/partyRuntime";
|
||||
import { partyRejoinMovement } from "../game/partyRejoin";
|
||||
import { useWailingEncounterStore } from "../game/wailingCavernsEncounter";
|
||||
import {
|
||||
clearPartyRuntimeAttackCorridor,
|
||||
consumePartyRuntimeRejoin,
|
||||
finishPartyRuntimeRejoin,
|
||||
getPartyRuntimePosition,
|
||||
partyRuntimeIsRejoining,
|
||||
registerPartyRuntimePosition,
|
||||
updatePartyRuntimeAttackCorridor,
|
||||
updatePartyRuntimePosition,
|
||||
@@ -419,6 +423,7 @@ function PartyActors({
|
||||
: null;
|
||||
const recallPosition = navigationRecall?.position ?? player;
|
||||
party.members.forEach((member, index) => {
|
||||
finishPartyRuntimeRejoin(member.id);
|
||||
const position = positionsRef.current.get(member.id) ?? initialMemberPosition(index);
|
||||
// Attach a recalled squad to the reviewed surface just as initial
|
||||
// spawns do. An exact visual-floor point can sit between Recast stair
|
||||
@@ -518,6 +523,7 @@ function PartyActors({
|
||||
members.forEach((member, index) => {
|
||||
const position = positionsRef.current.get(member.id) ?? initialMemberPosition(index);
|
||||
const slot = spawnSlots[index + 1] ?? spawnSlots[0];
|
||||
finishPartyRuntimeRejoin(member.id);
|
||||
position[0] = slot.footPosition[0];
|
||||
position[1] = slot.footPosition[1];
|
||||
position[2] = slot.footPosition[2];
|
||||
@@ -605,6 +611,29 @@ function PartyActors({
|
||||
appendPartyBreadcrumb(playerTrailRef.current, playerNavigation);
|
||||
const routeNow = clock.elapsedTime * 1_000;
|
||||
const combatNow = Date.now();
|
||||
for (const member of party.members) {
|
||||
if (member.health <= 0) {
|
||||
finishPartyRuntimeRejoin(member.id);
|
||||
continue;
|
||||
}
|
||||
const checkpoint = consumePartyRuntimeRejoin(member.id);
|
||||
if (!checkpoint) continue;
|
||||
const landing = navigationGraph
|
||||
? findNearestPartyNavigationSurface(navigationGraph, checkpoint, 6)?.position ?? checkpoint : checkpoint;
|
||||
const current = positionsRef.current.get(member.id) ?? [...landing];
|
||||
current[0] = landing[0]; current[1] = landing[1]; current[2] = landing[2];
|
||||
positionsRef.current.set(member.id, current);
|
||||
updatePartyRuntimePosition(member.id, current[0], current[1], current[2]);
|
||||
combatRoutesRef.current.delete(member.id);
|
||||
combatAnchorsRef.current.delete(member.id);
|
||||
followerCursorsRef.current.delete(member.id);
|
||||
directFollowMovingRef.current.delete(member.id);
|
||||
stuckProgressRef.current.delete(member.id);
|
||||
updatePartyRuntimeTargetVisibility(member.id, null, false);
|
||||
const animationSignal = animationEventSignalsRef.current.get(member.id);
|
||||
animationRevisionRef.current += 1;
|
||||
if (animationSignal) animationSignal.current = { revision: animationRevisionRef.current, kind: "ability-cancel" };
|
||||
}
|
||||
const playerTrail = playerTrailRef.current.points;
|
||||
const latestPlayerTrailPoint = playerTrail[playerTrail.length - 1];
|
||||
const previousPlayerTrailPoint = playerTrail[playerTrail.length - 2];
|
||||
@@ -639,7 +668,7 @@ function PartyActors({
|
||||
lastLeaderWaypointRef.current = null;
|
||||
}
|
||||
const objective = objectives.find((candidate) => candidate.id === party.objectiveBossId) ?? null;
|
||||
const leaderIndex = party.members.findIndex((member) => member.health > 0);
|
||||
const leaderIndex = party.members.findIndex((member) => member.health > 0 && !partyRuntimeIsRejoining(member.id));
|
||||
const safeDelta = Math.min(delta, 0.05);
|
||||
const desired: MutablePartyWorldPosition = [0, 0, 0];
|
||||
const nextPosition: MutablePartyWorldPosition = [0, 0, 0];
|
||||
@@ -994,7 +1023,8 @@ function PartyActors({
|
||||
}
|
||||
lastHealthRef.current.set(member.id, member.health);
|
||||
if (!actor || !current) continue;
|
||||
const memberTargetId = party.memberTargetIds[member.id] ?? party.activeMobId;
|
||||
const rejoining = partyRuntimeIsRejoining(member.id);
|
||||
const memberTargetId = rejoining ? null : party.memberTargetIds[member.id] ?? party.activeMobId;
|
||||
const memberTargetPosition = memberTargetId ? getMobPosition(memberTargetId) : null;
|
||||
const canSeeActiveTarget = Boolean(
|
||||
memberTargetId
|
||||
@@ -1012,10 +1042,28 @@ function PartyActors({
|
||||
if (member.health <= 0) {
|
||||
const signal = movingSignalsRef.current.get(member.id);
|
||||
if (signal) signal.current = false;
|
||||
} else if (party.command === "stop") {
|
||||
// Holding is represented by retaining the current world-space tuple.
|
||||
} else if (member.activeCast || member.controlledUntil > combatNow) {
|
||||
// Casting and crowd control are intentional immobility, not stuck navigation.
|
||||
} else if (rejoining) {
|
||||
const intent = partyRejoinMovement(member.id, current, playerNavigation, routeNow,
|
||||
navigationGraph, combatRoutesRef.current.get(member.id) ?? emptyPartyRouteState(),
|
||||
{ directSegmentAllowed, routeSegmentAllowed: navigationRouteSegmentAllowed });
|
||||
combatRoutesRef.current.set(member.id, intent.route);
|
||||
if (intent.rejoined) {
|
||||
finishPartyRuntimeRejoin(member.id);
|
||||
combatRoutesRef.current.delete(member.id);
|
||||
followerCursorsRef.current.delete(member.id);
|
||||
} else {
|
||||
movementExpected = true;
|
||||
frameRouteBlocked ||= intent.blocked;
|
||||
if (intent.waypoint) {
|
||||
desired[0] = intent.waypoint[0]; desired[1] = intent.waypoint[1]; desired[2] = intent.waypoint[2];
|
||||
hasDesired = true;
|
||||
faceX = desired[0] - current[0]; faceZ = desired[2] - current[2];
|
||||
}
|
||||
}
|
||||
} else if (party.command === "stop") {
|
||||
// Holding is represented by retaining the current world-space tuple.
|
||||
} else if (index === leaderIndex) {
|
||||
hasDesired = leaderHasWaypoint;
|
||||
movementExpected = leaderMovementExpected;
|
||||
@@ -1254,7 +1302,7 @@ function PartyActors({
|
||||
const movementProfile = movementProfileFor(member.id, index);
|
||||
|
||||
const currentPlanarDistance = planarDistance(current, playerNavigation);
|
||||
if (member.health > 0 && party.command !== "stop" && hasDesired) {
|
||||
if (member.health > 0 && (party.command !== "stop" || rejoining) && hasDesired) {
|
||||
const speed = (currentPlanarDistance > 8 ? PARTY_CATCH_UP_SPEED : PARTY_MOVE_SPEED)
|
||||
* movementProfile.speedMultiplier;
|
||||
const moved = stepPartyPosition(current, desired, speed * safeDelta, nextPosition);
|
||||
@@ -1287,7 +1335,7 @@ function PartyActors({
|
||||
stuckProgress = createPartyStuckRecoveryState(current, routeNow);
|
||||
stuckProgressRef.current.set(member.id, stuckProgress);
|
||||
}
|
||||
const recoveryGoal = memberTargetPosition ? `mob:${memberTargetId}`
|
||||
const recoveryGoal = rejoining ? "resurrection-rejoin:player" : memberTargetPosition ? `mob:${memberTargetId}`
|
||||
: index === leaderIndex ? `objective:${party.objectiveBossId}` : `follow:${leaderMember?.id}`;
|
||||
const recovery = updatePartyStuckRecovery(stuckProgress, {
|
||||
position: current,
|
||||
@@ -1296,7 +1344,7 @@ function PartyActors({
|
||||
movementExpected,
|
||||
health: member.health,
|
||||
paused: !active || game.paused || game.mapOpen || game.companionOpen,
|
||||
stopped: party.command === "stop",
|
||||
stopped: party.command === "stop" && !rejoining,
|
||||
casting: member.activeCast !== null,
|
||||
controlled: member.controlledUntil > combatNow,
|
||||
nowMs: routeNow,
|
||||
@@ -1316,7 +1364,7 @@ function PartyActors({
|
||||
const landing = choosePartyStuckRecoveryPosition({
|
||||
current,
|
||||
player: playerNavigation,
|
||||
groupAnchor: index === leaderIndex ? playerNavigation : leaderPosition ?? playerNavigation,
|
||||
groupAnchor: rejoining || index === leaderIndex ? playerNavigation : leaderPosition ?? playerNavigation,
|
||||
trailPoints: [...leaderTrailRef.current.points, ...playerTrailRef.current.points].map((point) => point.position),
|
||||
validate: recoveryPointAllowed,
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user