mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 23:19:06 +00:00
implementing new node seelction algo along with some otehr stuff
This commit is contained in:
parent
51cbd41c93
commit
1b0192a20b
13 changed files with 301 additions and 100 deletions
11
src/App.tsx
11
src/App.tsx
|
@ -21,8 +21,8 @@ const App = () => {
|
||||||
document.title = "< index >";
|
document.title = "< index >";
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const dispatchScene = useMemo(() => {
|
const dispatchScene = useMemo(
|
||||||
return {
|
() => ({
|
||||||
main: <MainScene />,
|
main: <MainScene />,
|
||||||
media: <MediaScene />,
|
media: <MediaScene />,
|
||||||
idle_media: <IdleMediaScene />,
|
idle_media: <IdleMediaScene />,
|
||||||
|
@ -33,8 +33,9 @@ const App = () => {
|
||||||
tak: <TaKScene />,
|
tak: <TaKScene />,
|
||||||
change_disc: <ChangeDiscScene />,
|
change_disc: <ChangeDiscScene />,
|
||||||
end: <EndScene />,
|
end: <EndScene />,
|
||||||
};
|
}),
|
||||||
}, []);
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id="game-root" className="game">
|
<div id="game-root" className="game">
|
||||||
|
@ -45,7 +46,9 @@ const App = () => {
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</Canvas>
|
</Canvas>
|
||||||
</span>
|
</span>
|
||||||
|
{["media", "idle_media", "tak", "end"].includes(currentScene) && (
|
||||||
<MediaPlayer />
|
<MediaPlayer />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,10 +40,10 @@ const HUD = memo(() => {
|
||||||
(state) => state.activeNode.matrixIndices
|
(state) => state.activeNode.matrixIndices
|
||||||
);
|
);
|
||||||
const siteRotY = useStore((state) => state.siteRot[1]);
|
const siteRotY = useStore((state) => state.siteRot[1]);
|
||||||
const sitePosY = useStore((state) => state.sitePos[1]);
|
const activeLevel = useStore((state) => state.activeLevel);
|
||||||
const subscene = useStore((state) => state.mainSubscene);
|
const subscene = useStore((state) => state.mainSubscene);
|
||||||
const scene = useStore((state) => state.currentScene);
|
const scene = useStore((state) => state.currentScene);
|
||||||
const prevData = usePrevious({ siteRotY, sitePosY, subscene, scene });
|
const prevData = usePrevious({ siteRotY, activeLevel, subscene, scene });
|
||||||
|
|
||||||
// this part is imperative because it performs a lot better than having a toggleable spring.
|
// this part is imperative because it performs a lot better than having a toggleable spring.
|
||||||
useFrame(() => {
|
useFrame(() => {
|
||||||
|
@ -123,7 +123,7 @@ const HUD = memo(() => {
|
||||||
} else {
|
} else {
|
||||||
if (
|
if (
|
||||||
prevData?.siteRotY !== siteRotY ||
|
prevData?.siteRotY !== siteRotY ||
|
||||||
prevData?.sitePosY !== sitePosY ||
|
prevData?.activeLevel !== activeLevel ||
|
||||||
subscene === "level_selection"
|
subscene === "level_selection"
|
||||||
) {
|
) {
|
||||||
activeRef.current = false;
|
activeRef.current = false;
|
||||||
|
@ -165,13 +165,13 @@ const HUD = memo(() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
|
activeLevel,
|
||||||
activeNodeMatrixIndices,
|
activeNodeMatrixIndices,
|
||||||
|
prevData?.activeLevel,
|
||||||
prevData?.scene,
|
prevData?.scene,
|
||||||
prevData?.sitePosY,
|
|
||||||
prevData?.siteRotY,
|
prevData?.siteRotY,
|
||||||
prevData?.subscene,
|
prevData?.subscene,
|
||||||
scene,
|
scene,
|
||||||
sitePosY,
|
|
||||||
siteRotY,
|
siteRotY,
|
||||||
subscene,
|
subscene,
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -111,6 +111,7 @@ const LevelSelection = () => {
|
||||||
}, [
|
}, [
|
||||||
activeLevel,
|
activeLevel,
|
||||||
downArrowActiveTex,
|
downArrowActiveTex,
|
||||||
|
downArrowTex,
|
||||||
prevData?.selectedLevel,
|
prevData?.selectedLevel,
|
||||||
prevData?.subscene,
|
prevData?.subscene,
|
||||||
selectedLevel,
|
selectedLevel,
|
||||||
|
|
|
@ -7,10 +7,11 @@ import NodeAnimations from "./Site/NodeAnimations";
|
||||||
import InactiveLevelNodes from "./Site/InactiveLevelNodes";
|
import InactiveLevelNodes from "./Site/InactiveLevelNodes";
|
||||||
import { useFrame } from "react-three-fiber";
|
import { useFrame } from "react-three-fiber";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import lerp from "../../../core/utils/lerp";
|
|
||||||
import filterInvisibleNodes from "../../../core/utils/filterInvisibleNodes";
|
import filterInvisibleNodes from "../../../core/utils/filterInvisibleNodes";
|
||||||
import site_a from "../../../resources/site_a.json";
|
import site_a from "../../../resources/site_a.json";
|
||||||
import site_b from "../../../resources/site_b.json";
|
import site_b from "../../../resources/site_b.json";
|
||||||
|
import level_y_values from "../../../resources/level_y_values.json";
|
||||||
|
import usePrevious from "../../../hooks/usePrevious";
|
||||||
|
|
||||||
export type NodeDataType = {
|
export type NodeDataType = {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -47,14 +48,33 @@ type SiteProps = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const Site = (props: SiteProps) => {
|
const Site = (props: SiteProps) => {
|
||||||
const siteRot = useStore((state) => state.siteRot);
|
const activeLevel = useStore((state) => state.activeLevel);
|
||||||
const sitePos = useStore((state) => state.sitePos);
|
|
||||||
const siteState = useSpring({
|
const [state, setState] = useSpring(() => ({
|
||||||
siteRotX: siteRot[0],
|
posY: -level_y_values[
|
||||||
siteRotY: siteRot[1],
|
useStore.getState().activeLevel as keyof typeof level_y_values
|
||||||
sitePosY: sitePos[1],
|
],
|
||||||
|
rotX: useStore.getState().siteRot[0],
|
||||||
|
rotY: useStore.getState().siteRot[1],
|
||||||
config: { duration: 1200 },
|
config: { duration: 1200 },
|
||||||
|
}));
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
setState({
|
||||||
|
posY: -level_y_values[activeLevel as keyof typeof level_y_values],
|
||||||
});
|
});
|
||||||
|
}, 1200);
|
||||||
|
}, [activeLevel, setState]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
useStore.subscribe(setState, (state) => {
|
||||||
|
return {
|
||||||
|
rotX: state.siteRot[0],
|
||||||
|
rotY: state.siteRot[1],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}, [setState]);
|
||||||
|
|
||||||
const introWrapperRef = useRef<THREE.Object3D>();
|
const introWrapperRef = useRef<THREE.Object3D>();
|
||||||
|
|
||||||
|
@ -90,18 +110,15 @@ const Site = (props: SiteProps) => {
|
||||||
return (
|
return (
|
||||||
<Suspense fallback={null}>
|
<Suspense fallback={null}>
|
||||||
<a.group ref={introWrapperRef}>
|
<a.group ref={introWrapperRef}>
|
||||||
<a.group rotation-x={siteState.siteRotX}>
|
<a.group rotation-x={state.rotX}>
|
||||||
<a.group
|
<a.group rotation-y={state.rotY} position-y={state.posY}>
|
||||||
rotation-y={siteState.siteRotY}
|
|
||||||
position-y={siteState.sitePosY}
|
|
||||||
>
|
|
||||||
<ActiveLevelNodes visibleNodes={visibleNodes} />
|
<ActiveLevelNodes visibleNodes={visibleNodes} />
|
||||||
<InactiveLevelNodes visibleNodes={visibleNodes} />
|
<InactiveLevelNodes visibleNodes={visibleNodes} />
|
||||||
<NodeAnimations />
|
|
||||||
<Rings
|
<Rings
|
||||||
activateAllRings={props.shouldIntro ? props.introFinished : true}
|
activateAllRings={props.shouldIntro ? props.introFinished : true}
|
||||||
/>
|
/>
|
||||||
</a.group>
|
</a.group>
|
||||||
|
<NodeAnimations />
|
||||||
</a.group>
|
</a.group>
|
||||||
</a.group>
|
</a.group>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
|
|
@ -31,6 +31,11 @@ const MediaLoadingBar = () => {
|
||||||
// doing it declaratively like this fixes that concern
|
// doing it declaratively like this fixes that concern
|
||||||
const loadingBarState = useMemo(() => {
|
const loadingBarState = useMemo(() => {
|
||||||
const mediaPercentageDispatch = {
|
const mediaPercentageDispatch = {
|
||||||
|
0: {
|
||||||
|
scaleX: 0,
|
||||||
|
texture: loadingBar10PercTex,
|
||||||
|
offsetX: 0,
|
||||||
|
},
|
||||||
5: {
|
5: {
|
||||||
scaleX: 0.25,
|
scaleX: 0.25,
|
||||||
texture: loadingBar10PercTex,
|
texture: loadingBar10PercTex,
|
||||||
|
|
|
@ -9,8 +9,8 @@ import React, {
|
||||||
import { useStore } from "../../store";
|
import { useStore } from "../../store";
|
||||||
import t from "../../static/webvtt/test.vtt";
|
import t from "../../static/webvtt/test.vtt";
|
||||||
import endroll from "../../static/movie/ENDROLL1.STR[0].webm";
|
import endroll from "../../static/movie/ENDROLL1.STR[0].webm";
|
||||||
import xa0001 from "../../static/audio/a/Xa0001.mp4";
|
import xa0001 from "../../static/audio/Xa0001.mp4";
|
||||||
import xa0006 from "../../static/audio/a/Xa0006.mp4";
|
import xa0006 from "../../static/audio/Xa0006.mp4";
|
||||||
|
|
||||||
const MediaPlayer = () => {
|
const MediaPlayer = () => {
|
||||||
const [mediaSource, setMediaSource] = useState<any>();
|
const [mediaSource, setMediaSource] = useState<any>();
|
||||||
|
@ -18,9 +18,7 @@ const MediaPlayer = () => {
|
||||||
const currentScene = useStore((state) => state.currentScene);
|
const currentScene = useStore((state) => state.currentScene);
|
||||||
const setScene = useStore((state) => state.setScene);
|
const setScene = useStore((state) => state.setScene);
|
||||||
|
|
||||||
const setPercentageElapsed = useStore(
|
const setPercentageElapsed = useStore((state) => state.setPercentageElapsed);
|
||||||
(state) => state.setPercentageElapsed
|
|
||||||
);
|
|
||||||
|
|
||||||
const idleMedia = useStore((state) => state.idleMedia);
|
const idleMedia = useStore((state) => state.idleMedia);
|
||||||
const nodeMedia = useStore((state) => state.activeNode.media_file);
|
const nodeMedia = useStore((state) => state.activeNode.media_file);
|
||||||
|
@ -32,12 +30,8 @@ const MediaPlayer = () => {
|
||||||
const requestRef = useRef();
|
const requestRef = useRef();
|
||||||
const videoRef = createRef<HTMLVideoElement>();
|
const videoRef = createRef<HTMLVideoElement>();
|
||||||
|
|
||||||
const currentSite = useStore((state) => state.activeSite);
|
|
||||||
|
|
||||||
// end scene specific stuff
|
// end scene specific stuff
|
||||||
const endMediaPlayedCount = useStore(
|
const endMediaPlayedCount = useStore((state) => state.endMediaPlayedCount);
|
||||||
(state) => state.endMediaPlayedCount
|
|
||||||
);
|
|
||||||
const incrementEndMediaPlayedCount = useStore(
|
const incrementEndMediaPlayedCount = useStore(
|
||||||
(state) => state.incrementEndMediaPlayedCount
|
(state) => state.incrementEndMediaPlayedCount
|
||||||
);
|
);
|
||||||
|
@ -47,10 +41,7 @@ const MediaPlayer = () => {
|
||||||
|
|
||||||
const updateTime = useCallback(() => {
|
const updateTime = useCallback(() => {
|
||||||
(requestRef.current as any) = requestAnimationFrame(updateTime);
|
(requestRef.current as any) = requestAnimationFrame(updateTime);
|
||||||
if (
|
if (videoRef.current) {
|
||||||
videoRef.current &&
|
|
||||||
["media", "idle_media", "tak", "end"].includes(currentScene)
|
|
||||||
) {
|
|
||||||
const timeElapsed = videoRef.current.currentTime;
|
const timeElapsed = videoRef.current.currentTime;
|
||||||
const duration = videoRef.current.duration;
|
const duration = videoRef.current.duration;
|
||||||
const percentageElapsed = Math.floor((timeElapsed / duration) * 100);
|
const percentageElapsed = Math.floor((timeElapsed / duration) * 100);
|
||||||
|
@ -58,6 +49,7 @@ const MediaPlayer = () => {
|
||||||
if (percentageElapsed % 5 === 0 && percentageElapsed !== 0) {
|
if (percentageElapsed % 5 === 0 && percentageElapsed !== 0) {
|
||||||
setPercentageElapsed(percentageElapsed);
|
setPercentageElapsed(percentageElapsed);
|
||||||
if (percentageElapsed === 100) {
|
if (percentageElapsed === 100) {
|
||||||
|
if (currentScene === "media") setPercentageElapsed(0);
|
||||||
videoRef.current.currentTime = 0;
|
videoRef.current.currentTime = 0;
|
||||||
if (currentScene === "idle_media") {
|
if (currentScene === "idle_media") {
|
||||||
videoRef.current.pause();
|
videoRef.current.pause();
|
||||||
|
@ -124,18 +116,17 @@ const MediaPlayer = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (currentScene === "media" || currentScene === "tak") {
|
if (
|
||||||
if (nodeMedia.includes("XA")) {
|
currentScene === "media" ||
|
||||||
import(
|
currentScene === "tak" ||
|
||||||
"../../static/audio/" + currentSite + "/" + nodeMedia + ".ogg"
|
currentScene === "idle_media"
|
||||||
).then((media) => {
|
) {
|
||||||
setMediaSource(media.default);
|
if (currentScene === "media") setPercentageElapsed(0);
|
||||||
if (videoRef.current) {
|
const mediaToPlay =
|
||||||
videoRef.current.load();
|
currentScene === "idle_media" ? idleMedia : nodeMedia;
|
||||||
}
|
if (mediaToPlay) {
|
||||||
});
|
if (mediaToPlay.includes("XA")) {
|
||||||
} else {
|
import("../../static/audio/" + mediaToPlay + ".ogg").then(
|
||||||
import("../../static/movie/" + nodeMedia + "[0].webm").then(
|
|
||||||
(media) => {
|
(media) => {
|
||||||
setMediaSource(media.default);
|
setMediaSource(media.default);
|
||||||
if (videoRef.current) {
|
if (videoRef.current) {
|
||||||
|
@ -143,26 +134,12 @@ const MediaPlayer = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
|
||||||
} else if (currentScene === "idle_media") {
|
|
||||||
if (idleMedia) {
|
|
||||||
if (idleMedia.includes("XA")) {
|
|
||||||
import(
|
|
||||||
"../../static/audio/" + currentSite + "/" + idleMedia + ".ogg"
|
|
||||||
).then((media) => {
|
|
||||||
setMediaSource(media.default);
|
|
||||||
if (videoRef.current) {
|
|
||||||
videoRef.current.load();
|
|
||||||
videoRef.current.play();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
import("../../static/movie/" + idleMedia + "[0].webm").then(
|
import("../../static/movie/" + mediaToPlay + "[0].webm").then(
|
||||||
(media) => {
|
(media) => {
|
||||||
setMediaSource(media.default);
|
setMediaSource(media.default);
|
||||||
if (videoRef.current) {
|
if (videoRef.current) {
|
||||||
videoRef.current.load();
|
videoRef.current.load();
|
||||||
videoRef.current.play();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -172,10 +149,10 @@ const MediaPlayer = () => {
|
||||||
}
|
}
|
||||||
}, [
|
}, [
|
||||||
currentScene,
|
currentScene,
|
||||||
currentSite,
|
|
||||||
endMediaPlayedCount,
|
endMediaPlayedCount,
|
||||||
idleMedia,
|
idleMedia,
|
||||||
nodeMedia,
|
nodeMedia,
|
||||||
|
setPercentageElapsed,
|
||||||
videoRef,
|
videoRef,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
|
@ -137,6 +137,7 @@ const BigLetter = memo((props: { letter: string; letterIdx: number }) => {
|
||||||
activeMediaComponent,
|
activeMediaComponent,
|
||||||
lastMediaLeftComponent,
|
lastMediaLeftComponent,
|
||||||
prevData?.scene,
|
prevData?.scene,
|
||||||
|
prevData?.subscene,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -25,7 +25,6 @@ const MainSceneEventManager = (props: MainSceneEventManagerProps) => {
|
||||||
const activeNodeId = useStore((state) => state.activeNode.id);
|
const activeNodeId = useStore((state) => state.activeNode.id);
|
||||||
const nodeMatrixIndices = useStore((state) => state.activeNode.matrixIndices);
|
const nodeMatrixIndices = useStore((state) => state.activeNode.matrixIndices);
|
||||||
const siteRotY = useStore((state) => state.siteRot[1]);
|
const siteRotY = useStore((state) => state.siteRot[1]);
|
||||||
const sitePosY = useStore((state) => state.sitePos[1]);
|
|
||||||
const activeLevel = useStore((state) => state.activeLevel);
|
const activeLevel = useStore((state) => state.activeLevel);
|
||||||
const mainSubscene = useStore((state) => state.mainSubscene);
|
const mainSubscene = useStore((state) => state.mainSubscene);
|
||||||
const selectedLevel = useStore((state) => state.selectedLevel);
|
const selectedLevel = useStore((state) => state.selectedLevel);
|
||||||
|
@ -54,7 +53,7 @@ const MainSceneEventManager = (props: MainSceneEventManagerProps) => {
|
||||||
// scene: "idle_media",
|
// scene: "idle_media",
|
||||||
// site: currentSite,
|
// site: currentSite,
|
||||||
// });
|
// });
|
||||||
// timePassedSinceLastKeyPress.current = -1;
|
timePassedSinceLastKeyPress.current = -1;
|
||||||
} else if (now > timePassedSinceLastKeyPress.current + 10000) {
|
} else if (now > timePassedSinceLastKeyPress.current + 10000) {
|
||||||
const moves = [
|
const moves = [
|
||||||
"prayer",
|
"prayer",
|
||||||
|
@ -94,7 +93,6 @@ const MainSceneEventManager = (props: MainSceneEventManagerProps) => {
|
||||||
const event = handleMainSceneEvent({
|
const event = handleMainSceneEvent({
|
||||||
mainSubscene: mainSubscene,
|
mainSubscene: mainSubscene,
|
||||||
keyPress: keyPress,
|
keyPress: keyPress,
|
||||||
sitePosY: sitePosY,
|
|
||||||
siteRotY: siteRotY,
|
siteRotY: siteRotY,
|
||||||
activeNodeId: activeNodeId,
|
activeNodeId: activeNodeId,
|
||||||
nodeMatrixIndices: nodeMatrixIndices,
|
nodeMatrixIndices: nodeMatrixIndices,
|
||||||
|
@ -112,7 +110,6 @@ const MainSceneEventManager = (props: MainSceneEventManagerProps) => {
|
||||||
[
|
[
|
||||||
props.loaded,
|
props.loaded,
|
||||||
mainSubscene,
|
mainSubscene,
|
||||||
sitePosY,
|
|
||||||
siteRotY,
|
siteRotY,
|
||||||
activeNodeId,
|
activeNodeId,
|
||||||
nodeMatrixIndices,
|
nodeMatrixIndices,
|
||||||
|
|
|
@ -3,22 +3,12 @@ import { useStore } from "../../../store";
|
||||||
import { StateManagerProps } from "../EventManager";
|
import { StateManagerProps } from "../EventManager";
|
||||||
|
|
||||||
const SiteManager = (props: StateManagerProps) => {
|
const SiteManager = (props: StateManagerProps) => {
|
||||||
const setPos = useStore((state) => state.setSitePos);
|
|
||||||
const setRot = useStore((state) => state.setSiteRot);
|
const setRot = useStore((state) => state.setSiteRot);
|
||||||
const setRotX = useStore((state) => state.setSiteRotX);
|
const setRotX = useStore((state) => state.setSiteRotX);
|
||||||
|
|
||||||
const dispatchObject = useCallback(
|
const dispatchObject = useCallback(
|
||||||
(eventState: { event: string; sitePosY: number; siteRotY: number }) => {
|
(eventState: { event: string; siteRotY: number }) => {
|
||||||
switch (eventState.event) {
|
switch (eventState.event) {
|
||||||
case "site_up":
|
|
||||||
case "site_down":
|
|
||||||
case "select_level_up":
|
|
||||||
case "select_level_down":
|
|
||||||
return {
|
|
||||||
action: setPos,
|
|
||||||
value: [[0, eventState.sitePosY, 0]],
|
|
||||||
actionDelay: 1300,
|
|
||||||
};
|
|
||||||
case "site_left":
|
case "site_left":
|
||||||
case "site_right":
|
case "site_right":
|
||||||
return {
|
return {
|
||||||
|
@ -40,7 +30,7 @@ const SiteManager = (props: StateManagerProps) => {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[setPos, setRot, setRotX]
|
[setRot, setRotX]
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
|
@ -8,6 +8,12 @@ import {
|
||||||
import unlocked_nodes from "../resources/initial_progress.json";
|
import unlocked_nodes from "../resources/initial_progress.json";
|
||||||
import level_y_values from "../resources/level_y_values.json";
|
import level_y_values from "../resources/level_y_values.json";
|
||||||
import node_huds from "../resources/node_huds.json";
|
import node_huds from "../resources/node_huds.json";
|
||||||
|
import filterInvisibleNodes from "./utils/filterInvisibleNodes";
|
||||||
|
import {
|
||||||
|
findNodeLeft,
|
||||||
|
findNodeRight,
|
||||||
|
getVisibleNodesMatrix,
|
||||||
|
} from "./utils/nodeUtils";
|
||||||
|
|
||||||
type NodeSelectorContext = {
|
type NodeSelectorContext = {
|
||||||
action: string;
|
action: string;
|
||||||
|
@ -35,6 +41,12 @@ const hudAssocs = {
|
||||||
"23": "fg_hud_6",
|
"23": "fg_hud_6",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getNodeById = (id: string, currentSite: string) => {
|
||||||
|
const siteData = currentSite === "a" ? site_a : site_b;
|
||||||
|
const level = id.substr(0, 2);
|
||||||
|
return (siteData as SiteType)[level][id];
|
||||||
|
};
|
||||||
|
|
||||||
export const getNode = (
|
export const getNode = (
|
||||||
level: number,
|
level: number,
|
||||||
nodeMatrixIndices: {
|
nodeMatrixIndices: {
|
||||||
|
@ -377,6 +389,21 @@ const nodeSelector = (context: NodeSelectorContext) => {
|
||||||
switch (context.action) {
|
switch (context.action) {
|
||||||
case "site_left":
|
case "site_left":
|
||||||
case "site_right":
|
case "site_right":
|
||||||
|
const t =
|
||||||
|
context.action === "site_right"
|
||||||
|
? findNodeRight(
|
||||||
|
context.nodeMatrixIndices,
|
||||||
|
context.level,
|
||||||
|
context.currentSite,
|
||||||
|
context.gameProgress
|
||||||
|
)
|
||||||
|
: findNodeLeft(
|
||||||
|
context.nodeMatrixIndices,
|
||||||
|
context.level,
|
||||||
|
context.currentSite,
|
||||||
|
context.gameProgress
|
||||||
|
);
|
||||||
|
|
||||||
move = context.action === "site_left" ? "left" : "right";
|
move = context.action === "site_left" ? "left" : "right";
|
||||||
newNodeData = findNodeHorizontal(
|
newNodeData = findNodeHorizontal(
|
||||||
move,
|
move,
|
||||||
|
@ -387,14 +414,15 @@ const nodeSelector = (context: NodeSelectorContext) => {
|
||||||
context.currentSite
|
context.currentSite
|
||||||
);
|
);
|
||||||
|
|
||||||
|
console.log(t!.matrixIndices);
|
||||||
if (newNodeData) {
|
if (newNodeData) {
|
||||||
const siteRotYModifier = move === "left" ? Math.PI / 4 : -Math.PI / 4;
|
const siteRotYModifier = move === "left" ? Math.PI / 4 : -Math.PI / 4;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
event: newNodeData.didMove ? context.action : "change_node",
|
event: newNodeData.didMove ? context.action : "change_node",
|
||||||
node: newNodeData.node,
|
node: getNodeById(t!.node, context.currentSite),
|
||||||
newActiveHud: newNodeData.newNodeHud,
|
newActiveHud: newNodeData.newNodeHud,
|
||||||
newNodeMatrixIndices: newNodeData.newNodeMatrixIndices,
|
newNodeMatrixIndices: t!.matrixIndices,
|
||||||
newSiteRotY: newNodeData.didMove
|
newSiteRotY: newNodeData.didMove
|
||||||
? context.siteRotY + siteRotYModifier
|
? context.siteRotY + siteRotYModifier
|
||||||
: context.siteRotY,
|
: context.siteRotY,
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import { SiteType } from "../../components/MainScene/SyncedComponents/Site";
|
import { SiteType } from "../../components/MainScene/SyncedComponents/Site";
|
||||||
|
import node_matrices from "../../resources/node_matrices.json";
|
||||||
|
import { getNode, getNodeById, isNodeVisible } from "../nodeSelector";
|
||||||
|
|
||||||
export const generateInactiveNodes = (
|
export const generateInactiveNodes = (
|
||||||
visibleNodes: SiteType,
|
visibleNodes: SiteType,
|
||||||
|
@ -19,3 +21,186 @@ export const generateInactiveNodes = (
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getVisibleNodesMatrix = (
|
||||||
|
matrixIdx: number,
|
||||||
|
activeLevel: number,
|
||||||
|
currentSite: string,
|
||||||
|
gameProgress: any
|
||||||
|
) => {
|
||||||
|
const formattedLevel = activeLevel.toString().padStart(2, "0");
|
||||||
|
const currentMatrix =
|
||||||
|
node_matrices[matrixIdx.toString() as keyof typeof node_matrices];
|
||||||
|
|
||||||
|
return currentMatrix.map((row: string[]) =>
|
||||||
|
row.map((nodePos: string) => {
|
||||||
|
const nodeId = formattedLevel + nodePos;
|
||||||
|
if (isNodeVisible(getNodeById(nodeId, currentSite), gameProgress))
|
||||||
|
return nodeId;
|
||||||
|
else return undefined;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const generateRowPrecedence = (rowIdx: number) => {
|
||||||
|
switch (rowIdx) {
|
||||||
|
case 0:
|
||||||
|
return [0, 1, 2];
|
||||||
|
case 1:
|
||||||
|
return [1, 0, 2];
|
||||||
|
case 2:
|
||||||
|
return [2, 1, 0];
|
||||||
|
default:
|
||||||
|
return [0, 1, 2];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const findNodeLeft = (
|
||||||
|
nodeMatrixIndices: {
|
||||||
|
matrixIdx: number;
|
||||||
|
rowIdx: number;
|
||||||
|
colIdx: number;
|
||||||
|
},
|
||||||
|
level: number,
|
||||||
|
currentSite: string,
|
||||||
|
gameProgress: any
|
||||||
|
) => {
|
||||||
|
const { matrixIdx, rowIdx, colIdx } = nodeMatrixIndices;
|
||||||
|
|
||||||
|
const visibleNodes = getVisibleNodesMatrix(
|
||||||
|
matrixIdx,
|
||||||
|
level,
|
||||||
|
currentSite,
|
||||||
|
gameProgress
|
||||||
|
);
|
||||||
|
|
||||||
|
const precedence = generateRowPrecedence(rowIdx);
|
||||||
|
|
||||||
|
let chosenNode;
|
||||||
|
let matrixIndices;
|
||||||
|
loop: for (let col = colIdx - 1; col > -1; col--) {
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
const current = visibleNodes[precedence[i]][col];
|
||||||
|
if (current) {
|
||||||
|
chosenNode = current;
|
||||||
|
matrixIndices = {
|
||||||
|
matrixIdx: matrixIdx,
|
||||||
|
rowIdx: precedence[i],
|
||||||
|
colIdx: col,
|
||||||
|
};
|
||||||
|
break loop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chosenNode) {
|
||||||
|
return {
|
||||||
|
node: chosenNode,
|
||||||
|
matrixIndices: matrixIndices,
|
||||||
|
didRotate: false,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const newMatrixIdx = matrixIdx + 1 > 8 ? 1 : matrixIdx + 1;
|
||||||
|
const visibleNodes = getVisibleNodesMatrix(
|
||||||
|
newMatrixIdx,
|
||||||
|
level,
|
||||||
|
currentSite,
|
||||||
|
gameProgress
|
||||||
|
);
|
||||||
|
|
||||||
|
loop: for (let col = 0; col < 4; col++) {
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
const current = visibleNodes[precedence[i]][col];
|
||||||
|
if (current) {
|
||||||
|
chosenNode = current;
|
||||||
|
matrixIndices = {
|
||||||
|
matrixIdx: newMatrixIdx,
|
||||||
|
rowIdx: precedence[i],
|
||||||
|
colIdx: col,
|
||||||
|
};
|
||||||
|
break loop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chosenNode)
|
||||||
|
return {
|
||||||
|
node: chosenNode,
|
||||||
|
matrixIndices: matrixIndices,
|
||||||
|
didRotate: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const findNodeRight = (
|
||||||
|
nodeMatrixIndices: {
|
||||||
|
matrixIdx: number;
|
||||||
|
rowIdx: number;
|
||||||
|
colIdx: number;
|
||||||
|
},
|
||||||
|
level: number,
|
||||||
|
currentSite: string,
|
||||||
|
gameProgress: any
|
||||||
|
) => {
|
||||||
|
const { matrixIdx, rowIdx, colIdx } = nodeMatrixIndices;
|
||||||
|
|
||||||
|
const visibleNodes = getVisibleNodesMatrix(
|
||||||
|
matrixIdx,
|
||||||
|
level,
|
||||||
|
currentSite,
|
||||||
|
gameProgress
|
||||||
|
);
|
||||||
|
|
||||||
|
const precedence = generateRowPrecedence(rowIdx);
|
||||||
|
|
||||||
|
let chosenNode;
|
||||||
|
let matrixIndices;
|
||||||
|
loop: for (let col = colIdx + 1; col < 4; col++) {
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
const current = visibleNodes[precedence[i]][col];
|
||||||
|
if (current) {
|
||||||
|
chosenNode = current;
|
||||||
|
matrixIndices = {
|
||||||
|
matrixIdx: matrixIdx,
|
||||||
|
rowIdx: precedence[i],
|
||||||
|
colIdx: col,
|
||||||
|
};
|
||||||
|
break loop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chosenNode) {
|
||||||
|
return { node: chosenNode, didRotate: false, matrixIndices: matrixIndices };
|
||||||
|
} else {
|
||||||
|
const newMatrixIdx = matrixIdx - 1 < 1 ? 8 : matrixIdx - 1;
|
||||||
|
const visibleNodes = getVisibleNodesMatrix(
|
||||||
|
newMatrixIdx,
|
||||||
|
level,
|
||||||
|
currentSite,
|
||||||
|
gameProgress
|
||||||
|
);
|
||||||
|
|
||||||
|
loop: for (let col = 3; col > -1; col--) {
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
const current = visibleNodes[precedence[i]][col];
|
||||||
|
if (current) {
|
||||||
|
chosenNode = current;
|
||||||
|
matrixIndices = {
|
||||||
|
matrixIdx: newMatrixIdx,
|
||||||
|
rowIdx: precedence[i],
|
||||||
|
colIdx: col,
|
||||||
|
};
|
||||||
|
break loop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chosenNode)
|
||||||
|
return {
|
||||||
|
node: chosenNode,
|
||||||
|
matrixIndices: matrixIndices,
|
||||||
|
didRotate: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -6,12 +6,12 @@ const IdleMediaScene = () => {
|
||||||
const idleMedia = useStore((state) => state.idleMedia);
|
const idleMedia = useStore((state) => state.idleMedia);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.getElementsByTagName("canvas")[0].className =
|
const mediaElement = document.getElementById("media") as HTMLMediaElement;
|
||||||
"media-scene-background";
|
|
||||||
|
|
||||||
return () => {
|
if (mediaElement) {
|
||||||
document.getElementsByTagName("canvas")[0].className = "";
|
mediaElement.currentTime = 0;
|
||||||
};
|
mediaElement.play();
|
||||||
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -50,7 +50,6 @@ type State = {
|
||||||
// site
|
// site
|
||||||
activeSite: "a" | "b";
|
activeSite: "a" | "b";
|
||||||
siteRot: number[];
|
siteRot: number[];
|
||||||
sitePos: number[];
|
|
||||||
|
|
||||||
// level
|
// level
|
||||||
activeLevel: string;
|
activeLevel: string;
|
||||||
|
@ -175,7 +174,6 @@ export const useStore = create(
|
||||||
// site
|
// site
|
||||||
activeSite: "a",
|
activeSite: "a",
|
||||||
siteRot: [0, 0, 0],
|
siteRot: [0, 0, 0],
|
||||||
sitePos: [0, 0, 0],
|
|
||||||
|
|
||||||
// level
|
// level
|
||||||
activeLevel: "04",
|
activeLevel: "04",
|
||||||
|
@ -280,7 +278,6 @@ export const useStore = create(
|
||||||
nextPos[0] = to;
|
nextPos[0] = to;
|
||||||
return { siteRot: nextPos };
|
return { siteRot: nextPos };
|
||||||
}),
|
}),
|
||||||
setSitePos: (to: number[]) => set(() => ({ sitePos: to })),
|
|
||||||
|
|
||||||
// level setters
|
// level setters
|
||||||
setActiveLevel: (to: string) => set(() => ({ activeLevel: to })),
|
setActiveLevel: (to: string) => set(() => ({ activeLevel: to })),
|
||||||
|
|
Loading…
Reference in a new issue