Update Healer Man server

This commit is contained in:
phenom committed 2026-09-26 17:51:56 -04:00
1 parent 9c5fb4c614
commit bd073fb00f
113 files changed
+4902 -273

No files matched your search

+45 -10
View File
@@ -1,10 +1,17 @@
import { useFrame } from "@react-three/fiber";
import { useRef } from "react";
import { useRef, useSyncExternalStore } from "react";
import type { Group } from "three";
import { BITE_SIZED_WAILING_CAVERNS_DUNGEON_ID } from "../game/dungeonContentSource";
import {
dispatchDungeonEncounterSignal,
dungeonEncounterSnapshot,
subscribeDungeonEncounterSnapshots,
} from "../game/dungeonEncounterRuntime";
import { useGameStore } from "../game/store";
import {
useWailingEncounterStore,
wailingDisciplePosition,
type WailingEncounterPhase,
} from "../game/wailingCavernsEncounter";
import { WorldNpcPrompt } from "./WorldNpcPrompt";
import { dungeonSimulationNow } from "../game/dungeonSimulationStore";
@@ -12,23 +19,44 @@ import { dungeonSimulationNow } from "../game/dungeonSimulationStore";
export function WailingNaralexEvent() {
const activeDungeonId = useGameStore((state) => state.activeDungeonId);
const gameMode = useGameStore((state) => state.gameMode);
const phase = useWailingEncounterStore((state) => state.phase);
const phaseStartedAt = useWailingEncounterStore((state) => state.phaseStartedAt);
const sourcePhase = useWailingEncounterStore((state) => state.phase);
const sourcePhaseStartedAt = useWailingEncounterStore((state) => state.phaseStartedAt);
const biteEncounterId = `${BITE_SIZED_WAILING_CAVERNS_DUNGEON_ID}:naralex-escort`;
useSyncExternalStore(
subscribeDungeonEncounterSnapshots,
() => dungeonEncounterSnapshot(biteEncounterId)?.revision ?? 0,
() => 0,
);
const biteSnapshot = dungeonEncounterSnapshot(biteEncounterId);
const phase = activeDungeonId === BITE_SIZED_WAILING_CAVERNS_DUNGEON_ID
? biteSnapshot?.phase ?? "ready"
: sourcePhase;
const phaseStartedAt = activeDungeonId === BITE_SIZED_WAILING_CAVERNS_DUNGEON_ID
? biteSnapshot?.phaseStartedAt ?? 0
: sourcePhaseStartedAt;
const isBiteSized = activeDungeonId === BITE_SIZED_WAILING_CAVERNS_DUNGEON_ID;
const groupRef = useRef<Group>(null);
useFrame(() => {
if (activeDungeonId !== "wailing-caverns" || gameMode !== "dungeon") return;
if (
(activeDungeonId !== "wailing-caverns" && !isBiteSized)
|| gameMode !== "dungeon"
) return;
const liveSnapshot = isBiteSized ? dungeonEncounterSnapshot(biteEncounterId) : null;
const now = dungeonSimulationNow();
const position = wailingDisciplePosition(
useWailingEncounterStore.getState().phase,
useWailingEncounterStore.getState().phaseStartedAt,
(liveSnapshot?.phase ?? useWailingEncounterStore.getState().phase) as Parameters<typeof wailingDisciplePosition>[0],
liveSnapshot?.phaseStartedAt ?? useWailingEncounterStore.getState().phaseStartedAt,
now,
);
groupRef.current?.position.set(...position);
});
if (activeDungeonId !== "wailing-caverns" || gameMode !== "dungeon") return null;
const initialPosition = wailingDisciplePosition(phase, phaseStartedAt);
if (
(activeDungeonId !== "wailing-caverns" && !isBiteSized)
|| gameMode !== "dungeon"
) return null;
const initialPosition = wailingDisciplePosition(phase as WailingEncounterPhase, phaseStartedAt);
return (
<group ref={groupRef} name="disciple-of-naralex-event" position={initialPosition}>
<mesh position={[0, 0.9, 0]} castShadow>
@@ -48,14 +76,21 @@ export function WailingNaralexEvent() {
type="button"
onClick={(event) => {
event.stopPropagation();
useWailingEncounterStore.getState().start();
if (isBiteSized) {
dispatchDungeonEncounterSignal(
`${BITE_SIZED_WAILING_CAVERNS_DUNGEON_ID}:naralex-start`,
dungeonSimulationNow(),
);
} else {
useWailingEncounterStore.getState().start();
}
}}
>
Begin the awakening
</button>
) : null}
{phase === "cleansing" ? <small>Channeling Serpentine Cleansing…</small> : null}
{phase === "complete" ? <small>Naralex has awakened</small> : null}
{phase === "complete" ? <small>{isBiteSized ? "Naralex has been rescued" : "Naralex has awakened"}</small> : null}
</div>
</WorldNpcPrompt>
</group>