63 lines
2.4 KiB
TypeScript
63 lines
2.4 KiB
TypeScript
import { useFrame } from "@react-three/fiber";
|
|
import { useRef } from "react";
|
|
import type { Group } from "three";
|
|
import { useGameStore } from "../game/store";
|
|
import {
|
|
useWailingEncounterStore,
|
|
wailingDisciplePosition,
|
|
} from "../game/wailingCavernsEncounter";
|
|
import { WorldNpcPrompt } from "./WorldNpcPrompt";
|
|
|
|
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 groupRef = useRef<Group>(null);
|
|
|
|
useFrame(() => {
|
|
if (activeDungeonId !== "wailing-caverns" || gameMode !== "dungeon") return;
|
|
const now = Date.now();
|
|
const position = wailingDisciplePosition(
|
|
useWailingEncounterStore.getState().phase,
|
|
useWailingEncounterStore.getState().phaseStartedAt,
|
|
now,
|
|
);
|
|
groupRef.current?.position.set(...position);
|
|
});
|
|
|
|
if (activeDungeonId !== "wailing-caverns" || gameMode !== "dungeon") return null;
|
|
const initialPosition = wailingDisciplePosition(phase, phaseStartedAt);
|
|
return (
|
|
<group ref={groupRef} name="disciple-of-naralex-event" position={initialPosition}>
|
|
<mesh position={[0, 0.9, 0]} castShadow>
|
|
<capsuleGeometry args={[0.34, 1.15, 6, 10]} />
|
|
<meshStandardMaterial color="#526d3d" roughness={0.76} />
|
|
</mesh>
|
|
<mesh position={[0, 1.72, 0]} castShadow>
|
|
<sphereGeometry args={[0.3, 12, 8]} />
|
|
<meshStandardMaterial color="#b9d67a" roughness={0.7} />
|
|
</mesh>
|
|
<WorldNpcPrompt position={[0, 2.45, 0]}>
|
|
<div className="naralex-event-prompt">
|
|
<strong>Disciple of Naralex</strong>
|
|
{phase === "locked" ? <small>Defeat the four Fanglords</small> : null}
|
|
{phase === "ready" ? (
|
|
<button
|
|
type="button"
|
|
onClick={(event) => {
|
|
event.stopPropagation();
|
|
useWailingEncounterStore.getState().start();
|
|
}}
|
|
>
|
|
Begin the awakening
|
|
</button>
|
|
) : null}
|
|
{phase === "cleansing" ? <small>Channeling Serpentine Cleansing…</small> : null}
|
|
{phase === "complete" ? <small>Naralex has awakened</small> : null}
|
|
</div>
|
|
</WorldNpcPrompt>
|
|
</group>
|
|
);
|
|
}
|