mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 23:19:06 +00:00
state management refactor almost done
This commit is contained in:
parent
a1bb6260ae
commit
cd584dd33b
48 changed files with 1383 additions and 2307 deletions
|
@ -5,10 +5,10 @@ import bigHud from "../../../static/sprite/big_hud.png";
|
|||
import longHud from "../../../static/sprite/long_hud.png";
|
||||
import boringHud from "../../../static/sprite/long_hud_boring.png";
|
||||
import { useStore } from "../../../store";
|
||||
import { getNodeHud } from "../../../core/nodeSelector";
|
||||
import lerp from "../../../core/utils/lerp";
|
||||
import lerp from "../../../utils/lerp";
|
||||
import GreenTextRenderer from "../../TextRenderer/GreenTextRenderer";
|
||||
import usePrevious from "../../../hooks/usePrevious";
|
||||
import {getNodeHud} from "../../../utils/nodeUtils";
|
||||
|
||||
export type HUDType = {
|
||||
mirrored: number;
|
||||
|
|
|
@ -6,7 +6,7 @@ import { a, useSpring } from "@react-spring/three";
|
|||
import { useStore } from "../../../store";
|
||||
import MiddleRingPart from "./MiddleRing/MiddleRingPart";
|
||||
import usePrevious from "../../../hooks/usePrevious";
|
||||
import lerp from "../../../core/utils/lerp";
|
||||
import lerp from "../../../utils/lerp";
|
||||
|
||||
const MiddleRing = () => {
|
||||
const middleRingTex = useLoader(THREE.TextureLoader, middleRingTexture);
|
||||
|
|
|
@ -7,11 +7,11 @@ import NodeAnimations from "./Site/NodeAnimations";
|
|||
import InactiveLevelNodes from "./Site/InactiveLevelNodes";
|
||||
import { useFrame } from "react-three-fiber";
|
||||
import * as THREE from "three";
|
||||
import filterInvisibleNodes from "../../../core/utils/filterInvisibleNodes";
|
||||
import site_a from "../../../resources/site_a.json";
|
||||
import site_b from "../../../resources/site_b.json";
|
||||
import level_y_values from "../../../resources/level_y_values.json";
|
||||
import usePrevious from "../../../hooks/usePrevious";
|
||||
import { filterInvisibleNodes } from "../../../utils/nodeUtils";
|
||||
|
||||
export type NodeDataType = {
|
||||
id: string;
|
||||
|
|
|
@ -2,11 +2,11 @@ import React, { memo, useEffect, useState } from "react";
|
|||
import Node from "./Node";
|
||||
import node_positions from "../../../../resources/node_positions.json";
|
||||
import { useStore } from "../../../../store";
|
||||
import { isNodeVisible } from "../../../../core/nodeSelector";
|
||||
import site_a from "../../../../resources/site_a.json";
|
||||
import site_b from "../../../../resources/site_b.json";
|
||||
import { NodeDataType, SiteType } from "../Site";
|
||||
import usePrevious from "../../../../hooks/usePrevious";
|
||||
import {isNodeVisible} from "../../../../utils/nodeUtils";
|
||||
|
||||
type ActiveLevelNodesProps = {
|
||||
visibleNodes: SiteType;
|
||||
|
|
|
@ -4,7 +4,7 @@ import { useStore } from "../../../../store";
|
|||
import { SiteType } from "../Site";
|
||||
import InactiveLevelNode from "./InactiveLevelNode";
|
||||
import usePrevious from "../../../../hooks/usePrevious";
|
||||
import { generateInactiveNodes } from "../../../../core/utils/nodeUtils";
|
||||
import { generateInactiveNodes } from "../../../../utils/nodeUtils";
|
||||
|
||||
type ActiveLevelNodesProps = {
|
||||
visibleNodes: SiteType;
|
||||
|
|
|
@ -2,8 +2,8 @@ import React, { useEffect, useState } from "react";
|
|||
import { useStore } from "../../store";
|
||||
import { a, useTrail } from "@react-spring/three";
|
||||
import BigLetter from "./BigLetter";
|
||||
import { getNodeHud } from "../../core/nodeSelector";
|
||||
import usePrevious from "../../hooks/usePrevious";
|
||||
import {getNodeHud} from "../../utils/nodeUtils";
|
||||
|
||||
const YellowTextRenderer = (props: { visible?: boolean }) => {
|
||||
const activeNode = useStore((state) => state.activeNode);
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
import { useCallback, useEffect } from "react";
|
||||
import { StateManagerProps } from "../EventManager";
|
||||
import { useStore } from "../../../store";
|
||||
|
||||
const BootComponentManager = (props: StateManagerProps) => {
|
||||
const toggleComponentMatrixIdx = useStore(
|
||||
(state) => state.toggleBootComponentMatrixIdx
|
||||
);
|
||||
|
||||
const dispatchObject = useCallback(
|
||||
(
|
||||
event: string,
|
||||
activeSubscene: string,
|
||||
newAuthorizeUserMatrixIdx: number
|
||||
) => {
|
||||
switch (event) {
|
||||
case "main_menu_down":
|
||||
case "main_menu_up":
|
||||
case "load_data_left":
|
||||
case "load_data_right":
|
||||
return {
|
||||
action: toggleComponentMatrixIdx,
|
||||
value: activeSubscene,
|
||||
};
|
||||
case "authorize_user_right":
|
||||
case "authorize_user_up":
|
||||
case "authorize_user_left":
|
||||
case "authorize_user_down":
|
||||
}
|
||||
},
|
||||
[toggleComponentMatrixIdx]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.eventState) {
|
||||
const eventAction = props.eventState.event;
|
||||
const newAuthorizeUserMatrixIdx =
|
||||
props.eventState.newAuthorizeUserMatrixIdx;
|
||||
const activeSubscene = props.eventState.subscene;
|
||||
|
||||
const dispatchedObject = dispatchObject(
|
||||
eventAction,
|
||||
activeSubscene,
|
||||
newAuthorizeUserMatrixIdx
|
||||
);
|
||||
|
||||
if (dispatchedObject) {
|
||||
dispatchedObject.action(dispatchedObject.value as never);
|
||||
}
|
||||
}
|
||||
}, [dispatchObject, props.eventState]);
|
||||
return null;
|
||||
};
|
||||
|
||||
export default BootComponentManager;
|
|
@ -1,89 +0,0 @@
|
|||
import { useCallback, useEffect } from "react";
|
||||
import { useStore, useSiteSaveStore } from "../../../store";
|
||||
import { StateManagerProps } from "../EventManager";
|
||||
import node_huds from "../../../resources/node_huds.json";
|
||||
import site_a from "../../../resources/site_a.json";
|
||||
import site_b from "../../../resources/site_b.json";
|
||||
import { SiteType } from "../../../components/MainScene/SyncedComponents/Site";
|
||||
|
||||
const GameLoader = (props: StateManagerProps) => {
|
||||
const siteASaveState = useSiteSaveStore((state) => state.a);
|
||||
const siteBSaveState = useSiteSaveStore((state) => state.b);
|
||||
|
||||
// setters for components, setting them all like this instead of their respective ones
|
||||
// makes more sense since they all needed extra bit of context just for this certain event,
|
||||
// which imo didn't make much sense
|
||||
|
||||
// level setter
|
||||
// const setActiveLevel = useLevelStore((state) => state.setActiveLevel);
|
||||
|
||||
// site setter
|
||||
const setSiteRot = useStore((state) => state.setSiteRot);
|
||||
const setCurrentSite = useStore((state) => state.setActiveSite);
|
||||
|
||||
// node setter
|
||||
const setActiveNode = useStore((state) => state.setNode);
|
||||
|
||||
// node hud setter
|
||||
|
||||
const changeSite = useCallback((site: string) => {
|
||||
// load new site
|
||||
// const siteToLoad = site === "a" ? siteASaveState : siteBSaveState;
|
||||
// const siteData = site === "a" ? site_a : site_b;
|
||||
//
|
||||
// // load new site (the object itself)
|
||||
// setCurrentSite(site);
|
||||
// setSiteRot(siteToLoad.siteRotY);
|
||||
// setSitePos(siteToLoad.sitePosY);
|
||||
//
|
||||
// // load new site level
|
||||
// setActiveLevel(siteToLoad.level);
|
||||
//
|
||||
// // load new site yellow text
|
||||
// setBigTexPos(
|
||||
// node_huds[siteToLoad.nodeHudId as keyof typeof node_huds].big_text[0]
|
||||
// );
|
||||
//
|
||||
// const targetYellowText = (siteData as SiteType)[siteToLoad.level][
|
||||
// siteToLoad.activeNodeId
|
||||
// ].node_name;
|
||||
//
|
||||
// setBigText(targetYellowText);
|
||||
//
|
||||
// // load new site node
|
||||
// setActiveNode(siteToLoad.activeNodeId);
|
||||
// setNodeMatrixIndices(siteToLoad.nodeMatrixIndices);
|
||||
//
|
||||
// // load new site node hud
|
||||
// setHud(siteToLoad.nodeHudId);
|
||||
}, []);
|
||||
|
||||
const dispatchObject = useCallback(
|
||||
(eventState: { event: string; site: string }) => {
|
||||
switch (eventState.event) {
|
||||
case "pause_change_select":
|
||||
return {
|
||||
action: changeSite,
|
||||
value: [eventState.site],
|
||||
actionDelay: 0,
|
||||
};
|
||||
}
|
||||
},
|
||||
[changeSite]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.eventState) {
|
||||
const dispatchedObject = dispatchObject(props.eventState);
|
||||
|
||||
if (dispatchedObject) {
|
||||
setTimeout(() => {
|
||||
dispatchedObject.action.apply(null, dispatchedObject.value as any);
|
||||
}, dispatchedObject.actionDelay);
|
||||
}
|
||||
}
|
||||
}, [dispatchObject, props.eventState]);
|
||||
return null;
|
||||
};
|
||||
|
||||
export default GameLoader;
|
|
@ -1,59 +0,0 @@
|
|||
import { useCallback, useEffect } from "react";
|
||||
import { useSiteSaveStore } from "../../../store";
|
||||
import { StateManagerProps } from "../EventManager";
|
||||
|
||||
const GameSaver = (props: StateManagerProps) => {
|
||||
const setSiteSaveState = useSiteSaveStore((state) => state.setSiteSaveState);
|
||||
|
||||
const dispatchObject = useCallback(
|
||||
(eventState: {
|
||||
event: string;
|
||||
currentSitePosY: number;
|
||||
currentSiteRotY: number;
|
||||
currentNodeId: string;
|
||||
currentNodeMatrixIndices: {
|
||||
matrixIdx: number;
|
||||
rowIdx: number;
|
||||
colIdx: number;
|
||||
};
|
||||
currentHudId: string;
|
||||
currentLevel: string;
|
||||
site: string;
|
||||
}) => {
|
||||
switch (eventState.event) {
|
||||
case "pause_change_select":
|
||||
return {
|
||||
action: setSiteSaveState,
|
||||
value: [
|
||||
eventState.site === "a" ? "b" : "a",
|
||||
{
|
||||
activeNodeId: eventState.currentNodeId,
|
||||
nodeMatrixIndices: eventState.currentNodeMatrixIndices,
|
||||
nodeHudId: eventState.currentHudId,
|
||||
siteRotY: eventState.currentSiteRotY,
|
||||
sitePosY: eventState.currentSitePosY,
|
||||
level: eventState.currentLevel,
|
||||
},
|
||||
],
|
||||
actionDelay: 0,
|
||||
};
|
||||
}
|
||||
},
|
||||
[setSiteSaveState]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.eventState) {
|
||||
const dispatchedObject = dispatchObject(props.eventState);
|
||||
|
||||
if (dispatchedObject) {
|
||||
setTimeout(() => {
|
||||
dispatchedObject.action.apply(null, dispatchedObject.value as any);
|
||||
}, dispatchedObject.actionDelay);
|
||||
}
|
||||
}
|
||||
}, [dispatchObject, props.eventState]);
|
||||
return null;
|
||||
};
|
||||
|
||||
export default GameSaver;
|
|
@ -1,88 +0,0 @@
|
|||
import { useCallback, useEffect } from "react";
|
||||
import { StateManagerProps } from "../EventManager";
|
||||
import { useStore } from "../../../store";
|
||||
|
||||
const SceneManager = (props: StateManagerProps) => {
|
||||
const setScene = useStore((state) => state.setScene);
|
||||
const setMainSceneIntro = useStore((state) => state.setIntro);
|
||||
|
||||
const dispatchObject = useCallback(
|
||||
(eventState: { event: string; scene: string }) => {
|
||||
switch (eventState.event) {
|
||||
case "throw_node_media":
|
||||
case "throw_node_gate":
|
||||
case "throw_node_sskn":
|
||||
case "throw_node_tak":
|
||||
return {
|
||||
action: setScene,
|
||||
value: eventState.scene,
|
||||
delay: 3450,
|
||||
setMainSceneIntro: false,
|
||||
};
|
||||
case "rip_node_media":
|
||||
case "rip_node_gate":
|
||||
case "rip_node_sskn":
|
||||
case "rip_node_tak":
|
||||
return {
|
||||
action: setScene,
|
||||
value: eventState.scene,
|
||||
delay: 6000,
|
||||
setMainSceneIntro: false,
|
||||
};
|
||||
|
||||
case "media_exit_select":
|
||||
case "exit_gate":
|
||||
case "sskn_cancel_select":
|
||||
return {
|
||||
action: setScene,
|
||||
value: "main",
|
||||
delay: 0,
|
||||
};
|
||||
case "sskn_ok_select":
|
||||
return {
|
||||
action: setScene,
|
||||
value: "main",
|
||||
delay: 6000,
|
||||
};
|
||||
case "pause_change_select":
|
||||
return {
|
||||
action: setScene,
|
||||
value: "change_disc",
|
||||
delay: 0,
|
||||
setMainSceneIntro: true,
|
||||
};
|
||||
case "play_idle_media":
|
||||
return {
|
||||
action: setScene,
|
||||
value: "idle_media",
|
||||
delay: 0,
|
||||
setMainSceneIntro: false,
|
||||
};
|
||||
}
|
||||
},
|
||||
[setScene]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.eventState) {
|
||||
const dispatchedObject = dispatchObject(props.eventState);
|
||||
|
||||
if (dispatchedObject) {
|
||||
setTimeout(() => {
|
||||
dispatchedObject.action(dispatchedObject.value);
|
||||
}, dispatchedObject.delay);
|
||||
if (dispatchedObject.setMainSceneIntro !== undefined) {
|
||||
if (dispatchedObject.setMainSceneIntro) {
|
||||
setMainSceneIntro(true);
|
||||
} else {
|
||||
setMainSceneIntro(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [props.eventState, dispatchObject, setMainSceneIntro]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export default SceneManager;
|
|
@ -1,74 +0,0 @@
|
|||
import { useCallback, useEffect } from "react";
|
||||
import { StateManagerProps } from "../EventManager";
|
||||
import { useStore } from "../../../store";
|
||||
|
||||
const SubsceneManager = (props: StateManagerProps) => {
|
||||
const setMainSubscene = useStore((state) => state.setMainSubscene);
|
||||
const setBootSubscene = useStore((state) => state.setBootSubscene);
|
||||
|
||||
const dispatchObject = useCallback(
|
||||
(eventState: { event: string }) => {
|
||||
switch (eventState.event) {
|
||||
case "level_selection_back":
|
||||
case "select_level_up":
|
||||
case "select_level_down":
|
||||
return {
|
||||
action: setMainSubscene,
|
||||
value: "site",
|
||||
delay: 0,
|
||||
};
|
||||
case "toggle_level_selection":
|
||||
return {
|
||||
action: setMainSubscene,
|
||||
value: "level_selection",
|
||||
delay: 0,
|
||||
};
|
||||
case "pause_game":
|
||||
return {
|
||||
action: setMainSubscene,
|
||||
value: "pause",
|
||||
delay: 0,
|
||||
};
|
||||
case "pause_exit_select":
|
||||
case "pause_change_select":
|
||||
return {
|
||||
action: setMainSubscene,
|
||||
value: "site",
|
||||
delay: 1800,
|
||||
};
|
||||
case "authorize_user_back":
|
||||
case "load_data_no_select":
|
||||
return {
|
||||
action: setBootSubscene,
|
||||
value: "main_menu",
|
||||
delay: 0,
|
||||
};
|
||||
case "authorize_user_select":
|
||||
return {
|
||||
action: setBootSubscene,
|
||||
value: "authorize_user",
|
||||
delay: 0,
|
||||
};
|
||||
case "load_data_select":
|
||||
return { action: setBootSubscene, value: "load_data", delay: 0 };
|
||||
}
|
||||
},
|
||||
[setBootSubscene, setMainSubscene]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.eventState) {
|
||||
const dispatchedObject = dispatchObject(props.eventState);
|
||||
|
||||
if (dispatchedObject) {
|
||||
setTimeout(() => {
|
||||
dispatchedObject.action(dispatchedObject.value as any);
|
||||
}, dispatchedObject.delay);
|
||||
}
|
||||
}
|
||||
}, [props.eventState, dispatchObject]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export default SubsceneManager;
|
|
@ -1,6 +1,5 @@
|
|||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { getKeyCodeAssociation } from "../utils/keyPressUtils";
|
||||
import SceneManager from "./GameManagers/SceneManager";
|
||||
import { getKeyCodeAssociation } from "../../utils/keyPressUtils";
|
||||
|
||||
const GateSceneManager = () => {
|
||||
const [eventState, setEventState] = useState<any>();
|
||||
|
|
|
@ -1,44 +1,39 @@
|
|||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { useStore } from "../../store";
|
||||
import React, { useCallback, useEffect, useMemo, useRef } from "react";
|
||||
import { getMainSceneContext, useStore } from "../../store";
|
||||
import handleMainSceneEvent from "../mainSceneEventHandler";
|
||||
import { getKeyCodeAssociation } from "../utils/keyPressUtils";
|
||||
import NodeManager from "./MainSceneManagers/NodeManager";
|
||||
import SiteManager from "./MainSceneManagers/SiteManager";
|
||||
import LainManager from "./MainSceneManagers/LainManager";
|
||||
import SceneManager from "./GameManagers/SceneManager";
|
||||
import LevelManager from "./MainSceneManagers/LevelManager";
|
||||
import LevelSelectionManager from "./MainSceneManagers/LevelSelectionManager";
|
||||
import SubsceneManager from "./GameManagers/SubsceneManager";
|
||||
import PauseComponentManager from "./MainSceneManagers/PauseComponentManager";
|
||||
import GameSaver from "./GameManagers/GameSaver";
|
||||
import GameLoader from "./GameManagers/GameLoader";
|
||||
import IdleManager from "./MainSceneManagers/IdleManager";
|
||||
import { getKeyCodeAssociation } from "../../utils/keyPressUtils";
|
||||
import { useFrame } from "react-three-fiber";
|
||||
import levelSelectionManager from "../setters/main/level_selection/levelSelectionManager";
|
||||
import lainManager from "../setters/main/site/lainManager";
|
||||
import levelManager from "../setters/main/site/levelManager";
|
||||
import nodeManager from "../setters/main/site/nodeManager";
|
||||
import pauseManager from "../setters/main/pause/pauseManager";
|
||||
import siteManager from "../setters/main/site/siteManager";
|
||||
import mainSubsceneManager from "../setters/main/mainSubsceneManager";
|
||||
import sceneManager from "../setters/sceneManager";
|
||||
|
||||
type MainSceneEventManagerProps = {
|
||||
loaded: boolean;
|
||||
};
|
||||
|
||||
const MainSceneEventManager = (props: MainSceneEventManagerProps) => {
|
||||
// all the possible context needed to calculate new state
|
||||
const currentSite = useStore((state) => state.activeSite);
|
||||
const activeNodeId = useStore((state) => state.activeNode.id);
|
||||
const nodeMatrixIndices = useStore((state) => state.activeNode.matrixIndices);
|
||||
const siteRotY = useStore((state) => state.siteRot[1]);
|
||||
const activeLevel = useStore((state) => state.activeLevel);
|
||||
const mainSubscene = useStore((state) => state.mainSubscene);
|
||||
const selectedLevel = useStore((state) => state.selectedLevel);
|
||||
const pauseMatrixIdx = useStore((state) => state.pauseComponentMatrixIdx);
|
||||
const activePauseComponent = useStore(
|
||||
useCallback((state) => state.pauseComponentMatrix[pauseMatrixIdx], [
|
||||
pauseMatrixIdx,
|
||||
])
|
||||
);
|
||||
const gameProgress = useStore((state) => state.gameProgress);
|
||||
|
||||
const timePassedSinceLastKeyPress = useRef(-1);
|
||||
|
||||
const [eventState, setEventState] = useState<any>();
|
||||
const mainSceneSetters = useMemo(
|
||||
() => [
|
||||
levelSelectionManager,
|
||||
nodeManager,
|
||||
levelManager,
|
||||
lainManager,
|
||||
siteManager,
|
||||
pauseManager,
|
||||
mainSubsceneManager,
|
||||
sceneManager,
|
||||
],
|
||||
[]
|
||||
);
|
||||
|
||||
useFrame(() => {
|
||||
const now = Date.now();
|
||||
|
@ -76,7 +71,7 @@ const MainSceneEventManager = (props: MainSceneEventManagerProps) => {
|
|||
];
|
||||
|
||||
const event = moves[Math.floor(Math.random() * moves.length)];
|
||||
setEventState({ event: event });
|
||||
// setEventState({ event: event });
|
||||
timePassedSinceLastKeyPress.current = now - 2500;
|
||||
}
|
||||
}
|
||||
|
@ -90,36 +85,13 @@ const MainSceneEventManager = (props: MainSceneEventManagerProps) => {
|
|||
|
||||
if (keyPress && props.loaded) {
|
||||
timePassedSinceLastKeyPress.current = Date.now() + 2500;
|
||||
const event = handleMainSceneEvent({
|
||||
mainSubscene: mainSubscene,
|
||||
keyPress: keyPress,
|
||||
siteRotY: siteRotY,
|
||||
activeNodeId: activeNodeId,
|
||||
nodeMatrixIndices: nodeMatrixIndices,
|
||||
activeLevel: activeLevel,
|
||||
selectedLevel: selectedLevel,
|
||||
pauseMatrixIdx: pauseMatrixIdx,
|
||||
activePauseComponent: activePauseComponent,
|
||||
gameProgress: gameProgress,
|
||||
currentSite: currentSite,
|
||||
});
|
||||
const ctx = { ...getMainSceneContext(), keyPress: keyPress };
|
||||
|
||||
setEventState(event);
|
||||
const event = handleMainSceneEvent(ctx);
|
||||
mainSceneSetters.forEach((fn) => fn(event));
|
||||
}
|
||||
},
|
||||
[
|
||||
props.loaded,
|
||||
mainSubscene,
|
||||
siteRotY,
|
||||
activeNodeId,
|
||||
nodeMatrixIndices,
|
||||
activeLevel,
|
||||
selectedLevel,
|
||||
pauseMatrixIdx,
|
||||
activePauseComponent,
|
||||
gameProgress,
|
||||
currentSite,
|
||||
]
|
||||
[mainSceneSetters, props.loaded]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -130,21 +102,7 @@ const MainSceneEventManager = (props: MainSceneEventManagerProps) => {
|
|||
};
|
||||
}, [handleKeyPress]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<NodeManager eventState={eventState!} />
|
||||
<SiteManager eventState={eventState!} />
|
||||
<LainManager eventState={eventState!} />
|
||||
<SceneManager eventState={eventState!} />
|
||||
<LevelManager eventState={eventState!} />
|
||||
<LevelSelectionManager eventState={eventState!} />
|
||||
<SubsceneManager eventState={eventState!} />
|
||||
<PauseComponentManager eventState={eventState!} />
|
||||
<GameSaver eventState={eventState!} />
|
||||
<GameLoader eventState={eventState!} />
|
||||
<IdleManager eventState={eventState!} />
|
||||
</>
|
||||
);
|
||||
return null;
|
||||
};
|
||||
|
||||
export default MainSceneEventManager;
|
||||
|
|
|
@ -1,115 +0,0 @@
|
|||
import React, { useCallback, useEffect } from "react";
|
||||
import { StateManagerProps } from "../EventManager";
|
||||
import { SiteType } from "../../../components/MainScene/SyncedComponents/Site";
|
||||
import site_a from "../../../resources/site_a.json";
|
||||
import site_b from "../../../resources/site_b.json";
|
||||
import { useStore } from "../../../store";
|
||||
|
||||
const IdleManager = (props: StateManagerProps) => {
|
||||
const setImages = useStore((state) => state.setIdleImages);
|
||||
const setMedia = useStore((state) => state.setIdleMedia);
|
||||
|
||||
const playIdleMedia = useCallback(
|
||||
(site: string) => {
|
||||
const siteAIdleNodes = {
|
||||
audio: [
|
||||
"0000",
|
||||
"0001",
|
||||
"0002",
|
||||
"0003",
|
||||
"0004",
|
||||
"0005",
|
||||
"0006",
|
||||
"0007",
|
||||
"0008",
|
||||
"0009",
|
||||
],
|
||||
video: [
|
||||
"INS01.STR",
|
||||
"INS02.STR",
|
||||
"INS03.STR",
|
||||
"INS04.STR",
|
||||
"INS05.STR",
|
||||
"INS06.STR",
|
||||
"INS07.STR",
|
||||
"INS08.STR",
|
||||
"INS09.STR",
|
||||
"INS10.STR",
|
||||
"INS11.STR",
|
||||
"INS12.STR",
|
||||
"INS13.STR",
|
||||
"INS14.STR",
|
||||
"INS15.STR",
|
||||
"INS16.STR",
|
||||
"INS17.STR",
|
||||
"INS18.STR",
|
||||
"INS19.STR",
|
||||
"INS20.STR",
|
||||
"INS21.STR",
|
||||
"INS22.STR",
|
||||
],
|
||||
};
|
||||
|
||||
const siteBIdleNodes = {
|
||||
audio: ["1015", "1219", "0419", "0500", "0501", "0508", "0510", "0513"],
|
||||
video: [
|
||||
"INS16.STR",
|
||||
"INS17.STR",
|
||||
"INS18.STR",
|
||||
"INS19.STR",
|
||||
"INS20.STR",
|
||||
"INS21.STR",
|
||||
"INS22.STR",
|
||||
],
|
||||
};
|
||||
|
||||
const siteData = site === "a" ? site_a : site_b;
|
||||
const idleNodes = site === "a" ? siteAIdleNodes : siteBIdleNodes;
|
||||
|
||||
if (Math.random() < 0.5) {
|
||||
const nodeToPlay =
|
||||
idleNodes.audio[Math.floor(Math.random() * idleNodes.audio.length)];
|
||||
|
||||
const level = nodeToPlay.substr(0, 2);
|
||||
|
||||
const images = (siteData as SiteType)[level][nodeToPlay]
|
||||
.image_table_indices;
|
||||
const media = (siteData as SiteType)[level][nodeToPlay].media_file;
|
||||
|
||||
setMedia(media);
|
||||
setImages(images);
|
||||
} else {
|
||||
setMedia(
|
||||
idleNodes.video[Math.floor(Math.random() * idleNodes.video.length)]
|
||||
);
|
||||
}
|
||||
},
|
||||
[setImages, setMedia]
|
||||
);
|
||||
|
||||
const dispatchObject = useCallback(
|
||||
(eventState: { event: string; site: string }) => {
|
||||
switch (eventState.event) {
|
||||
case "play_idle_media":
|
||||
return {
|
||||
action: playIdleMedia,
|
||||
value: eventState.site,
|
||||
};
|
||||
}
|
||||
},
|
||||
[playIdleMedia]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.eventState) {
|
||||
const dispatchedObject = dispatchObject(props.eventState);
|
||||
|
||||
if (dispatchedObject) {
|
||||
dispatchedObject.action(dispatchedObject.value);
|
||||
}
|
||||
}
|
||||
}, [dispatchObject, props.eventState]);
|
||||
return null;
|
||||
};
|
||||
|
||||
export default IdleManager;
|
|
@ -1,87 +0,0 @@
|
|||
import { useCallback, useEffect } from "react";
|
||||
import { useStore } from "../../../store";
|
||||
import { StateManagerProps } from "../EventManager";
|
||||
|
||||
const LainManager = (props: StateManagerProps) => {
|
||||
const setLainMoveState = useStore((state) => state.setLainMoveState);
|
||||
|
||||
const dispatchObject = useCallback(
|
||||
(eventState: { event: string }) => {
|
||||
switch (eventState.event) {
|
||||
case "site_up":
|
||||
case "site_down":
|
||||
case "site_left":
|
||||
case "site_right":
|
||||
case "select_level_up":
|
||||
case "select_level_down":
|
||||
case "pause_game":
|
||||
case "knock_node":
|
||||
case "prayer":
|
||||
case "touch_sleeve":
|
||||
case "thinking":
|
||||
case "stretch_2":
|
||||
case "stretch":
|
||||
case "spin":
|
||||
case "scratch_head":
|
||||
case "blush":
|
||||
case "hands_behind_head":
|
||||
case "hands_on_hips":
|
||||
case "hands_on_hips_2":
|
||||
case "hands_together":
|
||||
case "lean_forward":
|
||||
case "lean_left":
|
||||
case "lean_right":
|
||||
case "look_around":
|
||||
case "play_with_hair":
|
||||
return {
|
||||
action: setLainMoveState,
|
||||
value: eventState.event,
|
||||
duration: 3900,
|
||||
};
|
||||
case "throw_node_media":
|
||||
case "throw_node_gate":
|
||||
case "throw_node_sskn":
|
||||
case "throw_node_tak":
|
||||
return {
|
||||
action: setLainMoveState,
|
||||
value: "throw_node",
|
||||
duration: 3900,
|
||||
};
|
||||
case "rip_node_media":
|
||||
case "rip_node_gate":
|
||||
case "rip_node_sskn":
|
||||
case "rip_node_tak":
|
||||
return {
|
||||
action: setLainMoveState,
|
||||
value: "rip_node",
|
||||
duration: 6000,
|
||||
};
|
||||
case "knock_node_and_fall":
|
||||
return {
|
||||
action: setLainMoveState,
|
||||
value: "knock_node_and_fall",
|
||||
duration: 6000,
|
||||
};
|
||||
}
|
||||
},
|
||||
[setLainMoveState]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.eventState) {
|
||||
const dispatchedObject = dispatchObject(props.eventState);
|
||||
|
||||
if (dispatchedObject) {
|
||||
dispatchedObject.action(dispatchedObject.value);
|
||||
|
||||
setTimeout(() => {
|
||||
setLainMoveState("standing");
|
||||
}, dispatchedObject.duration);
|
||||
}
|
||||
}
|
||||
}, [props.eventState, setLainMoveState, dispatchObject]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export default LainManager;
|
|
@ -1,40 +0,0 @@
|
|||
import { useCallback, useEffect } from "react";
|
||||
import { StateManagerProps } from "../EventManager";
|
||||
import { useStore } from "../../../store";
|
||||
|
||||
const LevelManager = (props: StateManagerProps) => {
|
||||
const setActiveLevel = useStore((state) => state.setActiveLevel);
|
||||
|
||||
const dispatchObject = useCallback(
|
||||
(eventState: { event: string; level: string }) => {
|
||||
switch (eventState.event) {
|
||||
case "site_up":
|
||||
case "select_level_down":
|
||||
case "select_level_up":
|
||||
case "site_down":
|
||||
return {
|
||||
action: setActiveLevel,
|
||||
value: eventState.level,
|
||||
delay: 0,
|
||||
};
|
||||
}
|
||||
},
|
||||
[setActiveLevel]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.eventState) {
|
||||
const dispatchedObject = dispatchObject(props.eventState);
|
||||
|
||||
if (dispatchedObject) {
|
||||
setTimeout(() => {
|
||||
dispatchedObject.action(dispatchedObject.value as any);
|
||||
}, dispatchedObject.delay);
|
||||
}
|
||||
}
|
||||
}, [props.eventState, dispatchObject]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export default LevelManager;
|
|
@ -1,44 +0,0 @@
|
|||
import { useCallback, useEffect } from "react";
|
||||
import { StateManagerProps } from "../EventManager";
|
||||
import { useStore } from "../../../store";
|
||||
|
||||
const LevelSelectionManager = (props: StateManagerProps) => {
|
||||
const setSelectedLevel = useStore((state) => state.setSelectedLevel);
|
||||
|
||||
const dispatchObject = useCallback(
|
||||
(eventState: {
|
||||
event: string;
|
||||
selectedLevelIdx: number;
|
||||
level: number;
|
||||
}) => {
|
||||
switch (eventState.event) {
|
||||
case "toggle_level_selection":
|
||||
return {
|
||||
action: setSelectedLevel,
|
||||
value: eventState.level,
|
||||
};
|
||||
case "level_selection_up":
|
||||
case "level_selection_down":
|
||||
return {
|
||||
action: setSelectedLevel,
|
||||
value: eventState.selectedLevelIdx,
|
||||
};
|
||||
}
|
||||
},
|
||||
[setSelectedLevel]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.eventState) {
|
||||
const dispatchedObject = dispatchObject(props.eventState);
|
||||
|
||||
if (dispatchedObject) {
|
||||
dispatchedObject.action(dispatchedObject.value as any);
|
||||
}
|
||||
}
|
||||
}, [props.eventState, dispatchObject]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export default LevelSelectionManager;
|
|
@ -1,245 +0,0 @@
|
|||
import { useCallback, useEffect } from "react";
|
||||
import { useStore } from "../../../store";
|
||||
import { StateManagerProps } from "../EventManager";
|
||||
import { NodeDataType } from "../../../components/MainScene/SyncedComponents/Site";
|
||||
|
||||
const NodeManager = (props: StateManagerProps) => {
|
||||
const setActiveNode = useStore((state) => state.setNode);
|
||||
const setActiveNodePos = useStore((state) => state.setNodePos);
|
||||
const setActiveNodeRot = useStore((state) => state.setNodeRot);
|
||||
const setActiveNodeState = useStore((state) => state.setNodeState);
|
||||
|
||||
const calculateCoordsBasedOnRotation = (
|
||||
x: number,
|
||||
z: number,
|
||||
rotation: number
|
||||
) => ({
|
||||
x: x * Math.cos(rotation) - z * Math.sin(rotation),
|
||||
z: x * Math.sin(rotation) + z * Math.cos(rotation),
|
||||
});
|
||||
|
||||
const animateActiveNodeThrow = useCallback(
|
||||
(siteRotY: number) => {
|
||||
setActiveNodeState(true, "interactedWith");
|
||||
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(0.9, 0.3, siteRotY);
|
||||
const sndCoordSet = calculateCoordsBasedOnRotation(0.5, 0.2, siteRotY);
|
||||
const thirdCoordSet = calculateCoordsBasedOnRotation(1.55, 0.2, siteRotY);
|
||||
const fourthCoordSet = calculateCoordsBasedOnRotation(0, 2, siteRotY);
|
||||
|
||||
setActiveNodePos([fstCoordSet.x, 0, fstCoordSet.z]);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodePos([sndCoordSet.x, 0, sndCoordSet.z]);
|
||||
}, 800);
|
||||
setTimeout(() => {
|
||||
setActiveNodePos([thirdCoordSet.x, 0, sndCoordSet.z]);
|
||||
setActiveNodeRot([0, 0, -0.005]);
|
||||
}, 2600);
|
||||
setTimeout(() => {
|
||||
setActiveNodePos([fourthCoordSet.x, 0, fourthCoordSet.z]);
|
||||
setActiveNodeRot([0, 0, -0.5]);
|
||||
}, 2700);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeRot([0, 0, 0]);
|
||||
setActiveNodeState(false, "interactedWith");
|
||||
}, 3800);
|
||||
},
|
||||
[setActiveNodePos, setActiveNodeRot, setActiveNodeState]
|
||||
);
|
||||
|
||||
const animateNodeKnock = useCallback(
|
||||
(siteRotY: number) => {
|
||||
setActiveNodeState(true, "interactedWith");
|
||||
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(1.1, 0.2, siteRotY);
|
||||
|
||||
setActiveNodePos([fstCoordSet.x, -0.6, fstCoordSet.z]);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(false, "interactedWith");
|
||||
}, 2500);
|
||||
},
|
||||
[setActiveNodePos, setActiveNodeState]
|
||||
);
|
||||
|
||||
const animateNodeKnockAndFall = useCallback(
|
||||
(siteRotY: number) => {
|
||||
setActiveNodeState(true, "interactedWith");
|
||||
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(1.1, 0.2, siteRotY);
|
||||
|
||||
setActiveNodePos([fstCoordSet.x, -0.6, fstCoordSet.z]);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(false, "visible");
|
||||
}, 2300);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(false, "interactedWith");
|
||||
}, 2500);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(true, "visible");
|
||||
}, 3200);
|
||||
},
|
||||
[setActiveNodePos, setActiveNodeState]
|
||||
);
|
||||
|
||||
const animateNodeTouchAndScare = useCallback(
|
||||
(siteRotY: number) => {
|
||||
setActiveNodeState(true, "interactedWith");
|
||||
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(-0.6, 0.2, siteRotY);
|
||||
|
||||
setActiveNodePos([fstCoordSet.x, 0, fstCoordSet.z]);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(true, "exploding");
|
||||
setActiveNodeState(false, "visible");
|
||||
}, 1200);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(false, "interactedWith");
|
||||
setActiveNodeRot([0, 0, 0]);
|
||||
}, 1400);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(false, "exploding");
|
||||
}, 3150);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(true, "visible");
|
||||
}, 3500);
|
||||
},
|
||||
[setActiveNodePos, setActiveNodeRot, setActiveNodeState]
|
||||
);
|
||||
|
||||
const animateShrinkAndRip = useCallback(
|
||||
(siteRotY: number) => {
|
||||
setActiveNodeState(true, "interactedWith");
|
||||
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(0.9, 0.3, siteRotY);
|
||||
const sndCoordSet = calculateCoordsBasedOnRotation(0.5, 0.2, siteRotY);
|
||||
const thirdCoordSet = calculateCoordsBasedOnRotation(0, 0.2, siteRotY);
|
||||
|
||||
setActiveNodePos([fstCoordSet.x, 0, fstCoordSet.z]);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodePos([sndCoordSet.x, 0, sndCoordSet.z]);
|
||||
}, 800);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodePos([thirdCoordSet.x, -0.4, thirdCoordSet.z]);
|
||||
}, 2800);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(true, "shrinking");
|
||||
}, 3000);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodePos([thirdCoordSet.x, -1.5, thirdCoordSet.z]);
|
||||
}, 3200);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(false, "visible");
|
||||
}, 3500);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(false, "interactedWith");
|
||||
setActiveNodeState(false, "shrinking");
|
||||
setActiveNodeRot([0, 0, 0]);
|
||||
}, 6400);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(true, "visible");
|
||||
}, 7500);
|
||||
},
|
||||
[setActiveNodePos, setActiveNodeRot, setActiveNodeState]
|
||||
);
|
||||
|
||||
const updateActiveNode = useCallback(
|
||||
(
|
||||
node: NodeDataType,
|
||||
newNodeMatrixIndices: {
|
||||
matrixIdx: number;
|
||||
rowIdx: number;
|
||||
colIdx: number;
|
||||
},
|
||||
isMoving?: boolean,
|
||||
delay?: number
|
||||
) => {
|
||||
setTimeout(() => {
|
||||
node.matrixIndices = newNodeMatrixIndices;
|
||||
setActiveNode(node);
|
||||
}, delay);
|
||||
},
|
||||
[setActiveNode]
|
||||
);
|
||||
|
||||
const dispatchObject = useCallback(
|
||||
(eventState: {
|
||||
event: string;
|
||||
node: NodeDataType;
|
||||
nodeMatrixIndices: {
|
||||
matrixIdx: number;
|
||||
rowIdx: number;
|
||||
colIdx: number;
|
||||
};
|
||||
siteRotY: number;
|
||||
idleNodeId?: string;
|
||||
}) => {
|
||||
switch (eventState.event) {
|
||||
case "site_up":
|
||||
case "site_down":
|
||||
case "site_left":
|
||||
case "site_right":
|
||||
case "select_level_up":
|
||||
case "select_level_down":
|
||||
return {
|
||||
action: updateActiveNode,
|
||||
value: [eventState.node, eventState.nodeMatrixIndices, true, 3900],
|
||||
};
|
||||
case "change_node":
|
||||
return {
|
||||
action: updateActiveNode,
|
||||
value: [eventState.node, eventState.nodeMatrixIndices],
|
||||
};
|
||||
case "throw_node_media":
|
||||
case "throw_node_gate":
|
||||
case "throw_node_sskn":
|
||||
case "throw_node_tak":
|
||||
return {
|
||||
action: animateActiveNodeThrow,
|
||||
value: [eventState.siteRotY],
|
||||
};
|
||||
case "rip_node_media":
|
||||
case "rip_node_gate":
|
||||
case "rip_node_sskn":
|
||||
case "rip_node_tak":
|
||||
return {
|
||||
action: animateShrinkAndRip,
|
||||
value: [eventState.siteRotY],
|
||||
};
|
||||
}
|
||||
},
|
||||
[animateActiveNodeThrow, animateShrinkAndRip, updateActiveNode]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.eventState) {
|
||||
const dispatchedObject = dispatchObject(props.eventState);
|
||||
|
||||
if (dispatchedObject) {
|
||||
(dispatchedObject.action as any).apply(
|
||||
null,
|
||||
dispatchedObject.value as never
|
||||
);
|
||||
}
|
||||
}
|
||||
}, [props.eventState, setActiveNodeState, dispatchObject]);
|
||||
return null;
|
||||
};
|
||||
|
||||
export default NodeManager;
|
|
@ -1,49 +0,0 @@
|
|||
import { useCallback, useEffect } from "react";
|
||||
import { StateManagerProps } from "../EventManager";
|
||||
import { useStore } from "../../../store";
|
||||
|
||||
const PauseComponentManager = (props: StateManagerProps) => {
|
||||
const setComponentMatrixIdx = useStore(
|
||||
(state) => state.setPauseComponentMatrixIdx
|
||||
);
|
||||
const setExitAnimation = useStore(
|
||||
(state) => state.setPauseExitAnimation
|
||||
);
|
||||
|
||||
const dispatchObject = useCallback(
|
||||
(eventState: { event: string; pauseMatrixIdx: number }) => {
|
||||
switch (eventState.event) {
|
||||
case "pause_up":
|
||||
case "pause_down":
|
||||
return {
|
||||
action: setComponentMatrixIdx,
|
||||
value: eventState.pauseMatrixIdx,
|
||||
};
|
||||
case "pause_exit_select":
|
||||
return {
|
||||
action: setExitAnimation,
|
||||
value: true,
|
||||
};
|
||||
case "pause_game":
|
||||
return {
|
||||
action: setExitAnimation,
|
||||
value: false,
|
||||
};
|
||||
}
|
||||
},
|
||||
[setComponentMatrixIdx, setExitAnimation]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.eventState) {
|
||||
const dispatchedObject = dispatchObject(props.eventState);
|
||||
|
||||
if (dispatchedObject) {
|
||||
dispatchedObject.action(dispatchedObject.value as never);
|
||||
}
|
||||
}
|
||||
}, [dispatchObject, props.eventState]);
|
||||
return null;
|
||||
};
|
||||
|
||||
export default PauseComponentManager;
|
|
@ -1,53 +0,0 @@
|
|||
import { useCallback, useEffect } from "react";
|
||||
import { useStore } from "../../../store";
|
||||
import { StateManagerProps } from "../EventManager";
|
||||
|
||||
const SiteManager = (props: StateManagerProps) => {
|
||||
const setRot = useStore((state) => state.setSiteRot);
|
||||
const setRotX = useStore((state) => state.setSiteRotX);
|
||||
|
||||
const dispatchObject = useCallback(
|
||||
(eventState: { event: string; siteRotY: number }) => {
|
||||
switch (eventState.event) {
|
||||
case "site_left":
|
||||
case "site_right":
|
||||
return {
|
||||
action: setRot,
|
||||
value: [[0, eventState.siteRotY, 0]],
|
||||
actionDelay: 1100,
|
||||
};
|
||||
case "pause_game":
|
||||
return {
|
||||
action: setRotX,
|
||||
value: [Math.PI / 2],
|
||||
actionDelay: 3600,
|
||||
};
|
||||
case "pause_exit_select":
|
||||
return {
|
||||
action: setRotX,
|
||||
value: [0],
|
||||
actionDelay: 0,
|
||||
};
|
||||
}
|
||||
},
|
||||
[setRot, setRotX]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.eventState) {
|
||||
const dispatchedObject = dispatchObject(props.eventState);
|
||||
|
||||
if (dispatchedObject) {
|
||||
setTimeout(() => {
|
||||
(dispatchedObject.action as any).apply(
|
||||
null,
|
||||
dispatchedObject.value as any
|
||||
);
|
||||
}, dispatchedObject.actionDelay);
|
||||
}
|
||||
}
|
||||
}, [dispatchObject, props.eventState]);
|
||||
return null;
|
||||
};
|
||||
|
||||
export default SiteManager;
|
|
@ -1,33 +1,12 @@
|
|||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { useStore } from "../../store";
|
||||
import { getKeyCodeAssociation } from "../utils/keyPressUtils";
|
||||
import SceneManager from "./GameManagers/SceneManager";
|
||||
import React, { useCallback, useEffect, useMemo } from "react";
|
||||
import { getMediaSceneContext } from "../../store";
|
||||
import { getKeyCodeAssociation } from "../../utils/keyPressUtils";
|
||||
import mediaManager from "../setters/media/mediaManager";
|
||||
import handleMediaSceneEvent from "../mediaSceneEventHandler";
|
||||
import MediaComponentManager from "./MediaSceneManagers/MediaComponentManager";
|
||||
import sceneManager from "../setters/sceneManager";
|
||||
|
||||
const MediaSceneEventManager = () => {
|
||||
// all the possible context needed to calculate new state
|
||||
const activeMediaComponent = useStore(
|
||||
useCallback(
|
||||
(state) =>
|
||||
state.mediaComponentMatrix[state.mediaComponentMatrixIndices.sideIdx][
|
||||
state.mediaComponentMatrixIndices.sideIdx === 0
|
||||
? state.mediaComponentMatrixIndices.leftSideIdx
|
||||
: state.mediaComponentMatrixIndices.rightSideIdx
|
||||
],
|
||||
[]
|
||||
)
|
||||
);
|
||||
|
||||
const rightSideComponentIdx = useStore(
|
||||
(state) => state.mediaComponentMatrixIndices.rightSideIdx
|
||||
);
|
||||
|
||||
const wordPosStateIdx = useStore(
|
||||
(state) => state.mediaWordPosStateIdx
|
||||
);
|
||||
|
||||
const [eventState, setEventState] = useState<any>();
|
||||
const mediaSceneSetters = useMemo(() => [mediaManager, sceneManager], []);
|
||||
|
||||
const handleKeyPress = useCallback(
|
||||
(event) => {
|
||||
|
@ -36,17 +15,14 @@ const MediaSceneEventManager = () => {
|
|||
const keyPress = getKeyCodeAssociation(keyCode);
|
||||
|
||||
if (keyPress) {
|
||||
const event = handleMediaSceneEvent({
|
||||
keyPress: keyPress,
|
||||
activeMediaComponent: activeMediaComponent,
|
||||
wordPosStateIdx: wordPosStateIdx,
|
||||
rightSideComponentIdx: rightSideComponentIdx,
|
||||
});
|
||||
const ctx = { ...getMediaSceneContext(), keyPress: keyPress };
|
||||
|
||||
setEventState(event);
|
||||
const event = handleMediaSceneEvent(ctx);
|
||||
|
||||
mediaSceneSetters.forEach((fn) => fn(event));
|
||||
}
|
||||
},
|
||||
[activeMediaComponent, rightSideComponentIdx, wordPosStateIdx]
|
||||
[mediaSceneSetters]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -57,12 +33,7 @@ const MediaSceneEventManager = () => {
|
|||
};
|
||||
}, [handleKeyPress]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<MediaComponentManager eventState={eventState!} />
|
||||
<SceneManager eventState={eventState!} />
|
||||
</>
|
||||
);
|
||||
return null;
|
||||
};
|
||||
|
||||
export default MediaSceneEventManager;
|
||||
|
|
|
@ -1,114 +0,0 @@
|
|||
import { useCallback, useEffect } from "react";
|
||||
import { StateManagerProps } from "../EventManager";
|
||||
import { useStore } from "../../../store";
|
||||
import * as THREE from "three";
|
||||
|
||||
const MediaComponentManager = (props: StateManagerProps) => {
|
||||
const toggleSide = useStore((state) => state.toggleMediaSide);
|
||||
const setLeftComponentMatrixIdx = useStore(
|
||||
(state) => state.setMediaLeftComponentMatrixIdx
|
||||
);
|
||||
const setRightComponentMatrixIdx = useStore(
|
||||
(state) => state.setMediaRightComponentMatrixIdx
|
||||
);
|
||||
const setWordPosStateIdx = useStore((state) => state.setMediaWordPosStateIdx);
|
||||
|
||||
const resetComponentMatrixIndices = useStore(
|
||||
(state) => state.resetMediaComponentMatrixIndices
|
||||
);
|
||||
const resetWordPosStateIdx = useStore(
|
||||
(state) => state.resetMediaWordPosStateIdx
|
||||
);
|
||||
|
||||
const setAudioAnalyser = useStore((state) => state.setAudioAnalyser);
|
||||
|
||||
const playMedia = useCallback(() => {
|
||||
const mediaElement = document.getElementById("media") as HTMLMediaElement;
|
||||
|
||||
if (mediaElement && mediaElement.paused) {
|
||||
const listener = new THREE.AudioListener();
|
||||
const audio = new THREE.Audio(listener);
|
||||
|
||||
audio.setMediaElementSource(mediaElement);
|
||||
|
||||
setAudioAnalyser(new THREE.AudioAnalyser(audio, 2048));
|
||||
|
||||
mediaElement.play();
|
||||
}
|
||||
}, [setAudioAnalyser]);
|
||||
|
||||
const exitMedia = useCallback(() => {
|
||||
const mediaElement = document.getElementById("media") as HTMLMediaElement;
|
||||
if (mediaElement) {
|
||||
mediaElement.pause();
|
||||
mediaElement.currentTime = 0;
|
||||
}
|
||||
resetComponentMatrixIndices();
|
||||
resetWordPosStateIdx();
|
||||
}, [resetComponentMatrixIndices, resetWordPosStateIdx]);
|
||||
|
||||
const updateRightSide = useCallback(
|
||||
(newRightSideComponentIdx: 0 | 1 | 2, newWordPosStateIdx: number) => {
|
||||
setRightComponentMatrixIdx(newRightSideComponentIdx);
|
||||
setWordPosStateIdx(newWordPosStateIdx);
|
||||
},
|
||||
[setRightComponentMatrixIdx, setWordPosStateIdx]
|
||||
);
|
||||
|
||||
const dispatchObject = useCallback(
|
||||
(eventState: {
|
||||
event: string;
|
||||
leftSideComponentIdx: number;
|
||||
rightSideComponentIdx: number;
|
||||
wordPosStateIdx: number;
|
||||
}) => {
|
||||
switch (eventState.event) {
|
||||
case "media_rightside_down":
|
||||
case "media_rightside_up":
|
||||
return {
|
||||
action: updateRightSide,
|
||||
value: [
|
||||
eventState.rightSideComponentIdx,
|
||||
eventState.wordPosStateIdx,
|
||||
],
|
||||
};
|
||||
case "media_leftside_down":
|
||||
case "media_leftside_up":
|
||||
return {
|
||||
action: setLeftComponentMatrixIdx,
|
||||
value: [eventState.leftSideComponentIdx],
|
||||
};
|
||||
case "media_leftside_right":
|
||||
case "media_rightside_left":
|
||||
return {
|
||||
action: toggleSide,
|
||||
};
|
||||
case "media_play_select":
|
||||
return { action: playMedia };
|
||||
case "media_exit_select":
|
||||
return { action: exitMedia };
|
||||
}
|
||||
},
|
||||
[
|
||||
exitMedia,
|
||||
playMedia,
|
||||
setLeftComponentMatrixIdx,
|
||||
toggleSide,
|
||||
updateRightSide,
|
||||
]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.eventState) {
|
||||
const dispatchedObject = dispatchObject(props.eventState);
|
||||
|
||||
if (dispatchedObject) {
|
||||
(dispatchedObject.action as any).apply(null, dispatchedObject.value);
|
||||
}
|
||||
}
|
||||
}, [props.eventState, dispatchObject]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export default MediaComponentManager;
|
|
@ -1,20 +1,12 @@
|
|||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { getKeyCodeAssociation } from "../utils/keyPressUtils";
|
||||
import SceneManager from "./GameManagers/SceneManager";
|
||||
import React, { useCallback, useEffect, useMemo } from "react";
|
||||
import { getKeyCodeAssociation } from "../../utils/keyPressUtils";
|
||||
import handleSSknSceneEvent from "../ssknSceneEventHandler";
|
||||
import { useStore } from "../../store";
|
||||
import SSknComponentManager from "./SSknSceneManagers/SSknComponentManager";
|
||||
import { getSSknSceneContext } from "../../store";
|
||||
import ssknManager from "../setters/sskn/ssknManager";
|
||||
import sceneManager from "../setters/sceneManager";
|
||||
|
||||
const SSknSceneManager = () => {
|
||||
// all the possible context needed to calculate new state
|
||||
const activeSSknComponent = useStore(
|
||||
useCallback(
|
||||
(state) => state.ssknComponentMatrix[state.ssknComponentMatrixIdx],
|
||||
[]
|
||||
)
|
||||
);
|
||||
|
||||
const [eventState, setEventState] = useState<any>();
|
||||
const ssknSceneSetters = useMemo(() => [ssknManager, sceneManager], []);
|
||||
|
||||
const handleKeyPress = useCallback(
|
||||
(event) => {
|
||||
|
@ -23,15 +15,14 @@ const SSknSceneManager = () => {
|
|||
const keyPress = getKeyCodeAssociation(keyCode);
|
||||
|
||||
if (keyPress) {
|
||||
const event = handleSSknSceneEvent({
|
||||
keyPress: keyPress,
|
||||
activeSSknComponent: activeSSknComponent,
|
||||
});
|
||||
const ctx = { ...getSSknSceneContext(), keyPress: keyPress };
|
||||
|
||||
setEventState(event);
|
||||
const event = handleSSknSceneEvent(ctx);
|
||||
|
||||
ssknSceneSetters.forEach((fn) => fn(event));
|
||||
}
|
||||
},
|
||||
[activeSSknComponent]
|
||||
[ssknSceneSetters]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -42,12 +33,7 @@ const SSknSceneManager = () => {
|
|||
};
|
||||
}, [handleKeyPress]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<SceneManager eventState={eventState!} />
|
||||
<SSknComponentManager eventState={eventState!} />
|
||||
</>
|
||||
);
|
||||
return null;
|
||||
};
|
||||
|
||||
export default SSknSceneManager;
|
||||
|
|
|
@ -1,55 +0,0 @@
|
|||
import { useCallback, useEffect } from "react";
|
||||
import { StateManagerProps } from "../EventManager";
|
||||
import { useStore } from "../../../store";
|
||||
|
||||
const SSknComponentManager = (props: StateManagerProps) => {
|
||||
const toggleComponentMatrixIdx = useStore(
|
||||
(state) => state.toggleSSknComponentMatrixIdx
|
||||
);
|
||||
const resetComponentMatrixIdx = useStore(
|
||||
(state) => state.resetSSknComponentMatrixIdx
|
||||
);
|
||||
const setSSknLoading = useStore((state) => state.setSSknLoading);
|
||||
|
||||
const dispatchObject = useCallback(
|
||||
(eventState: { event: string }) => {
|
||||
switch (eventState.event) {
|
||||
case "throw_node_sskn":
|
||||
case "rip_node_sskn":
|
||||
return {
|
||||
action: resetComponentMatrixIdx,
|
||||
};
|
||||
case "sskn_ok_down":
|
||||
case "sskn_cancel_up":
|
||||
return {
|
||||
action: toggleComponentMatrixIdx,
|
||||
};
|
||||
case "sskn_ok_select":
|
||||
return {
|
||||
action: setSSknLoading,
|
||||
value: true,
|
||||
};
|
||||
case "sskn_cancel_select":
|
||||
return {
|
||||
action: setSSknLoading,
|
||||
value: false,
|
||||
};
|
||||
}
|
||||
},
|
||||
[resetComponentMatrixIdx, setSSknLoading, toggleComponentMatrixIdx]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.eventState) {
|
||||
const dispatchedObject = dispatchObject(props.eventState);
|
||||
|
||||
if (dispatchedObject) {
|
||||
dispatchedObject.action(dispatchedObject.value as any);
|
||||
}
|
||||
}
|
||||
}, [props.eventState, dispatchObject]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export default SSknComponentManager;
|
|
@ -1,110 +1,131 @@
|
|||
import nodeSelector, { getNode, getNodeById, getNodeHud } from "./nodeSelector";
|
||||
import { findNode } from "./utils/nodeUtils";
|
||||
import {findNode, getNodeById} from "../utils/nodeUtils";
|
||||
|
||||
const handleMainSceneEvent = (gameContext: any) => {
|
||||
let event;
|
||||
const handleMainSceneEvent = (mainSceneContext: any) => {
|
||||
const {
|
||||
subscene,
|
||||
selectedLevel,
|
||||
pauseMatrixIdx,
|
||||
activePauseComponent,
|
||||
gameProgress,
|
||||
currentSite,
|
||||
siteRotY,
|
||||
activeNode,
|
||||
level,
|
||||
keyPress,
|
||||
} = mainSceneContext;
|
||||
|
||||
const keyPress = gameContext.keyPress;
|
||||
const subscene = gameContext.mainSubscene;
|
||||
const selectedLevel = gameContext.selectedLevel;
|
||||
const pauseMatrixIdx = gameContext.pauseMatrixIdx;
|
||||
const activePauseComponent = gameContext.activePauseComponent;
|
||||
const gameProgress = gameContext.gameProgress;
|
||||
const currentSite = gameContext.currentSite;
|
||||
|
||||
const siteASaveState = gameContext.siteASaveState;
|
||||
const siteBSaveState = gameContext.siteBSaveState;
|
||||
|
||||
let activeNode = gameContext.activeNode;
|
||||
let activeHud;
|
||||
let nodeMatrixIndices = gameContext.nodeMatrixIndices;
|
||||
let level = parseInt(gameContext.activeLevel);
|
||||
let siteRotY = gameContext.siteRotY;
|
||||
let sitePosY = gameContext.sitePosY;
|
||||
let scene = gameContext.scene;
|
||||
|
||||
if (subscene === "site") {
|
||||
switch (subscene) {
|
||||
case "site":
|
||||
switch (keyPress) {
|
||||
case "LEFT":
|
||||
case "RIGHT":
|
||||
case "RIGHT": {
|
||||
const keyPressToLower = keyPress.toLowerCase();
|
||||
|
||||
const nodeData = findNode.apply(null, [
|
||||
const nodeData = findNode(
|
||||
keyPressToLower,
|
||||
nodeMatrixIndices,
|
||||
activeNode.matrixIndices!,
|
||||
level,
|
||||
currentSite,
|
||||
gameProgress
|
||||
]);
|
||||
);
|
||||
|
||||
if (nodeData) {
|
||||
if (!nodeData) return;
|
||||
|
||||
if (nodeData.didMove) {
|
||||
return {
|
||||
event: nodeData.didMove
|
||||
? `site_${keyPressToLower}`
|
||||
: "change_node",
|
||||
event: keyPressToLower === "left" ? `site_left` : "site_right",
|
||||
siteRotY:
|
||||
keyPressToLower === "left"
|
||||
? siteRotY + Math.PI / 4
|
||||
: siteRotY - Math.PI / 4,
|
||||
node: {
|
||||
...getNodeById(nodeData.node, currentSite),
|
||||
matrixIndices: nodeData.matrixIndices,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
event: "change_node",
|
||||
nodeMatrixIndices: nodeData.matrixIndices,
|
||||
node: getNodeById(nodeData.node, currentSite),
|
||||
node: {
|
||||
...getNodeById(nodeData.node, currentSite),
|
||||
matrixIndices: nodeData.matrixIndices,
|
||||
},
|
||||
};
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "UP":
|
||||
case "DOWN":
|
||||
const keyp = keyPress.toLowerCase();
|
||||
const t = findNode.apply(null, [
|
||||
keyp,
|
||||
nodeMatrixIndices,
|
||||
case "DOWN": {
|
||||
const keyPressToLower = keyPress.toLowerCase();
|
||||
const nodeData = findNode(
|
||||
keyPressToLower,
|
||||
activeNode.matrixIndices!,
|
||||
level,
|
||||
currentSite,
|
||||
gameProgress
|
||||
]);
|
||||
if (t) {
|
||||
);
|
||||
|
||||
if (!nodeData) return;
|
||||
|
||||
if (nodeData.didMove) {
|
||||
return {
|
||||
event: t.didMove ? `site_${keyp}` : "change_node",
|
||||
nodeMatrixIndices: t.matrixIndices,
|
||||
level: (keyp === "up" ? level + 1 : level - 1)
|
||||
event: keyPressToLower === "up" ? "site_up" : "site_down",
|
||||
level: (keyPressToLower === "up" ? level + 1 : level - 1)
|
||||
.toString()
|
||||
.padStart(2, "0"),
|
||||
node: getNodeById(t.node, currentSite),
|
||||
node: {
|
||||
...getNodeById(nodeData.node, currentSite),
|
||||
matrixIndices: nodeData.matrixIndices,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
event: "change_node",
|
||||
node: {
|
||||
...getNodeById(nodeData.node, currentSite),
|
||||
matrixIndices: nodeData.matrixIndices,
|
||||
},
|
||||
};
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "CIRCLE":
|
||||
activeNode = getNode(level, nodeMatrixIndices, currentSite);
|
||||
const eventAnimation =
|
||||
Math.random() < 0.4 ? "rip_node" : "throw_node";
|
||||
|
||||
const nodeType = activeNode.type;
|
||||
|
||||
const eventAnimation = Math.random() < 0.4 ? "rip_node" : "throw_node";
|
||||
|
||||
switch (nodeType) {
|
||||
case 0:
|
||||
case 2:
|
||||
case 4:
|
||||
case 3:
|
||||
case 5:
|
||||
event = `${eventAnimation}_media`;
|
||||
scene = "media";
|
||||
break;
|
||||
return {
|
||||
event: `${eventAnimation}_media`,
|
||||
scene: "media",
|
||||
};
|
||||
case 6:
|
||||
if (activeNode.node_name.substr(0, 3) === "TaK") {
|
||||
event = `${eventAnimation}_tak`;
|
||||
scene = "tak";
|
||||
return {
|
||||
event: `${eventAnimation}_tak`,
|
||||
scene: "tak",
|
||||
};
|
||||
} else {
|
||||
event = `${eventAnimation}_media`;
|
||||
scene = "media";
|
||||
return {
|
||||
event: `${eventAnimation}_media`,
|
||||
scene: "media",
|
||||
};
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
event = `${eventAnimation}_gate`;
|
||||
scene = "gate";
|
||||
break;
|
||||
return {
|
||||
event: `${eventAnimation}_gate`,
|
||||
scene: "gate",
|
||||
};
|
||||
case 7:
|
||||
event = `${eventAnimation}_sskn`;
|
||||
scene = "sskn";
|
||||
break;
|
||||
return {
|
||||
event: `${eventAnimation}_sskn`,
|
||||
scene: "sskn",
|
||||
};
|
||||
}
|
||||
break;
|
||||
case "L2":
|
||||
|
@ -114,18 +135,8 @@ const handleMainSceneEvent = (gameContext: any) => {
|
|||
case "SPACE":
|
||||
return { event: "play_with_hair", siteRotY: siteRotY };
|
||||
}
|
||||
|
||||
return {
|
||||
event: event,
|
||||
nodeMatrixIndices: nodeMatrixIndices,
|
||||
sitePosY: sitePosY,
|
||||
siteRotY: siteRotY,
|
||||
level: level.toString().padStart(2, "0"),
|
||||
scene: scene,
|
||||
node: activeNode,
|
||||
hud: activeHud,
|
||||
};
|
||||
} else if (subscene === "level_selection") {
|
||||
break;
|
||||
case "level_selection":
|
||||
switch (keyPress) {
|
||||
case "UP":
|
||||
if (currentSite === "a") {
|
||||
|
@ -152,36 +163,36 @@ const handleMainSceneEvent = (gameContext: any) => {
|
|||
case "X":
|
||||
return {
|
||||
event: "level_selection_back",
|
||||
node: getNode(level, nodeMatrixIndices, currentSite),
|
||||
hud: getNodeHud(nodeMatrixIndices),
|
||||
};
|
||||
case "CIRCLE":
|
||||
const selectedNodeData = nodeSelector({
|
||||
action: "select_level",
|
||||
activeId: activeNode,
|
||||
nodeMatrixIndices: nodeMatrixIndices,
|
||||
level: selectedLevel,
|
||||
siteRotY: siteRotY,
|
||||
sitePosY: sitePosY,
|
||||
gameProgress: gameProgress,
|
||||
currentSite: currentSite,
|
||||
});
|
||||
|
||||
if (level === selectedLevel) break;
|
||||
if (selectedNodeData) {
|
||||
case "CIRCLE":
|
||||
if (level === selectedLevel) return;
|
||||
|
||||
const direction = selectedLevel > level ? "up" : "down";
|
||||
|
||||
const nodeData = findNode(
|
||||
direction,
|
||||
activeNode.matrixIndices!,
|
||||
selectedLevel,
|
||||
currentSite,
|
||||
gameProgress
|
||||
);
|
||||
|
||||
if (nodeData) {
|
||||
const event =
|
||||
selectedLevel < level ? "select_level_down" : "select_level_up";
|
||||
return {
|
||||
event: event,
|
||||
nodeMatrixIndices: selectedNodeData.nodeMatrixIndices,
|
||||
sitePosY: -selectedNodeData.sitePosY!,
|
||||
node: {
|
||||
...getNodeById(nodeData.node, currentSite),
|
||||
matrixIndices: nodeData.matrixIndices,
|
||||
},
|
||||
level: selectedLevel.toString().padStart(2, "0"),
|
||||
node: selectedNodeData.node,
|
||||
hud: selectedNodeData.activeHud,
|
||||
};
|
||||
}
|
||||
}
|
||||
} else if (subscene === "pause") {
|
||||
break;
|
||||
case "pause":
|
||||
switch (keyPress) {
|
||||
case "UP":
|
||||
if (pauseMatrixIdx - 1 < 0) break;
|
||||
|
@ -198,13 +209,6 @@ const handleMainSceneEvent = (gameContext: any) => {
|
|||
case "CIRCLE":
|
||||
return {
|
||||
event: `pause_${activePauseComponent}_select`,
|
||||
currentSitePosY: sitePosY,
|
||||
currentSiteRotY: siteRotY,
|
||||
currentNodeId: activeNode,
|
||||
currentNodeMatrixIndices: nodeMatrixIndices,
|
||||
currentHud: getNodeHud(nodeMatrixIndices),
|
||||
currentLevel: level.toString().padStart(2, "0"),
|
||||
site: currentSite === "a" ? "b" : "a",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
const handleMediaSceneEvent = (gameContext: any) => {
|
||||
const keyPress = gameContext.keyPress;
|
||||
const activeMediaComponent = gameContext.activeMediaComponent;
|
||||
|
||||
const wordPosStateIdx = gameContext.wordPosStateIdx;
|
||||
const rightSideComponentIdx = gameContext.rightSideComponentIdx;
|
||||
|
||||
const rightSideComponents = ["fstWord", "sndWord", "thirdWord"];
|
||||
const handleMediaSceneEvent = (mediaSceneContext: any) => {
|
||||
const {
|
||||
keyPress,
|
||||
activeMediaComponent,
|
||||
wordPosStateIdx,
|
||||
rightSideComponentIdx,
|
||||
} = mediaSceneContext;
|
||||
|
||||
const calculateNewRightSide = (
|
||||
direction: string,
|
||||
|
@ -43,7 +42,7 @@ const handleMediaSceneEvent = (gameContext: any) => {
|
|||
case "DOWN":
|
||||
case "RIGHT":
|
||||
case "LEFT":
|
||||
if (rightSideComponents.includes(activeMediaComponent)) {
|
||||
if (["fstWord", "sndWord", "thirdWord"].includes(activeMediaComponent)) {
|
||||
const rightSide = calculateNewRightSide(
|
||||
keyPress,
|
||||
wordPosStateIdx,
|
||||
|
|
|
@ -1,475 +0,0 @@
|
|||
import node_matrices from "../resources/node_matrices.json";
|
||||
import site_a from "../resources/site_a.json";
|
||||
import site_b from "../resources/site_b.json";
|
||||
import {
|
||||
NodeDataType,
|
||||
SiteType,
|
||||
} from "../components/MainScene/SyncedComponents/Site";
|
||||
import unlocked_nodes from "../resources/initial_progress.json";
|
||||
import level_y_values from "../resources/level_y_values.json";
|
||||
import node_huds from "../resources/node_huds.json";
|
||||
import filterInvisibleNodes from "./utils/filterInvisibleNodes";
|
||||
import {
|
||||
findNode,
|
||||
getVisibleNodesMatrix,
|
||||
} from "./utils/nodeUtils";
|
||||
|
||||
type NodeSelectorContext = {
|
||||
action: string;
|
||||
activeId: string;
|
||||
nodeMatrixIndices: { matrixIdx: number; rowIdx: number; colIdx: number };
|
||||
level: number;
|
||||
siteRotY: number;
|
||||
sitePosY: number;
|
||||
gameProgress: typeof unlocked_nodes;
|
||||
currentSite: string;
|
||||
};
|
||||
|
||||
const hudAssocs = {
|
||||
"00": "fg_hud_1",
|
||||
"10": "fg_hud_2",
|
||||
"20": "fg_hud_3",
|
||||
"01": "bg_hud_1",
|
||||
"11": "bg_hud_2",
|
||||
"21": "bg_hud_3",
|
||||
"02": "bg_hud_4",
|
||||
"12": "bg_hud_5",
|
||||
"22": "bg_hud_6",
|
||||
"03": "fg_hud_4",
|
||||
"13": "fg_hud_5",
|
||||
"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 = (
|
||||
level: number,
|
||||
nodeMatrixIndices: {
|
||||
matrixIdx: number;
|
||||
rowIdx: number;
|
||||
colIdx: number;
|
||||
},
|
||||
currentSite: string
|
||||
) => {
|
||||
const siteData = currentSite === "a" ? site_a : site_b;
|
||||
|
||||
const formattedLevel = level.toString().padStart(2, "0");
|
||||
const nodePos =
|
||||
node_matrices[
|
||||
nodeMatrixIndices.matrixIdx.toString() as keyof typeof node_matrices
|
||||
][nodeMatrixIndices.rowIdx][nodeMatrixIndices.colIdx];
|
||||
|
||||
const id = formattedLevel + nodePos;
|
||||
|
||||
return (siteData as SiteType)[formattedLevel][id];
|
||||
};
|
||||
|
||||
export const getNodeHud = (nodeMatrixIndices: {
|
||||
matrixIdx: number;
|
||||
rowIdx: number;
|
||||
colIdx: number;
|
||||
}) =>
|
||||
node_huds[
|
||||
hudAssocs[
|
||||
`${nodeMatrixIndices.rowIdx}${nodeMatrixIndices.colIdx}` as keyof typeof hudAssocs
|
||||
] as keyof typeof node_huds
|
||||
];
|
||||
|
||||
export const isNodeVisible = (
|
||||
node: NodeDataType,
|
||||
gameProgress: typeof unlocked_nodes
|
||||
) => {
|
||||
if (node) {
|
||||
const unlockedBy = node.unlocked_by;
|
||||
|
||||
let unlocked;
|
||||
if (unlockedBy === "") unlocked = true;
|
||||
else
|
||||
unlocked =
|
||||
gameProgress[unlockedBy as keyof typeof gameProgress].is_viewed;
|
||||
|
||||
// visible = (global_final_viewcount > 0) && (req_final_viewcount <= global_final_viewcount + 1)
|
||||
|
||||
return (
|
||||
unlocked &&
|
||||
gameProgress[node.node_name as keyof typeof gameProgress].is_visible
|
||||
);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
const tryCol = (col: number, triedCols: number[]) => {
|
||||
const possibleCols = [0, 1, 2, 3].filter((elem) => elem !== col);
|
||||
return possibleCols.find((elem) => !triedCols.includes(elem));
|
||||
};
|
||||
|
||||
const tryRow = (row: number, triedRows: number[]) => {
|
||||
const possibleRows = [0, 1, 2].filter((elem) => elem !== row);
|
||||
return possibleRows.find((elem) => !triedRows.includes(elem));
|
||||
};
|
||||
|
||||
const findNodeAfterLevelSelection = (
|
||||
gameProgress: typeof unlocked_nodes,
|
||||
targetLevel: number,
|
||||
nodeMatrixIndices: { matrixIdx: number; rowIdx: number; colIdx: number },
|
||||
currentSite: string
|
||||
) => {
|
||||
let newMatIndices = Object.assign({}, nodeMatrixIndices);
|
||||
|
||||
let triedCols: number[] = [];
|
||||
|
||||
newMatIndices.rowIdx = 0;
|
||||
|
||||
let newNode: NodeDataType | "UNKNOWN" = getNode(
|
||||
targetLevel,
|
||||
newMatIndices,
|
||||
currentSite
|
||||
);
|
||||
|
||||
while (!isNodeVisible(newNode, gameProgress)) {
|
||||
if (triedCols.length < 4) {
|
||||
triedCols.push(newMatIndices.colIdx);
|
||||
const colToTry = tryCol(newMatIndices.colIdx, triedCols);
|
||||
if (colToTry !== undefined) {
|
||||
newMatIndices.colIdx = colToTry;
|
||||
}
|
||||
} else {
|
||||
if (newMatIndices.rowIdx === 2) {
|
||||
newMatIndices.colIdx = nodeMatrixIndices.colIdx;
|
||||
newNode = "UNKNOWN";
|
||||
break;
|
||||
} else {
|
||||
newMatIndices.rowIdx++;
|
||||
triedCols = [];
|
||||
newMatIndices.colIdx = 0;
|
||||
}
|
||||
}
|
||||
newNode = getNode(targetLevel, newMatIndices, currentSite);
|
||||
}
|
||||
|
||||
const newNodeHud = getNodeHud(newMatIndices);
|
||||
|
||||
return {
|
||||
newLevel: targetLevel,
|
||||
node: newNode,
|
||||
newNodeHud: newNodeHud,
|
||||
newNodeMatrixIndices: newMatIndices,
|
||||
newSitePosY:
|
||||
level_y_values[
|
||||
targetLevel.toString().padStart(2, "0") as keyof typeof level_y_values
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
const findNodeVertical = (
|
||||
direction: string,
|
||||
gameProgress: typeof unlocked_nodes,
|
||||
level: number,
|
||||
nodeMatrixIndices: { matrixIdx: number; rowIdx: number; colIdx: number },
|
||||
currentSite: string
|
||||
) => {
|
||||
let newNode: NodeDataType | "UNKNOWN";
|
||||
let newLevel = level;
|
||||
let newMatIndices = Object.assign({}, nodeMatrixIndices);
|
||||
|
||||
if (direction === "down") {
|
||||
newMatIndices.rowIdx++;
|
||||
|
||||
let triedCols: number[] = [];
|
||||
|
||||
if (newMatIndices.rowIdx > 2) {
|
||||
newMatIndices.rowIdx = 0;
|
||||
newLevel = level - 1;
|
||||
}
|
||||
|
||||
newNode = getNode(newLevel, newMatIndices, currentSite);
|
||||
|
||||
while (!isNodeVisible(newNode, gameProgress)) {
|
||||
if (triedCols.length < 4) {
|
||||
triedCols.push(newMatIndices.colIdx);
|
||||
const colToTry = tryCol(newMatIndices.colIdx, triedCols);
|
||||
if (colToTry !== undefined) {
|
||||
newMatIndices.colIdx = colToTry;
|
||||
}
|
||||
} else {
|
||||
if (newMatIndices.rowIdx === 2) {
|
||||
if (newLevel === level - 1) {
|
||||
newNode = "UNKNOWN";
|
||||
newMatIndices.colIdx = nodeMatrixIndices.colIdx;
|
||||
break;
|
||||
}
|
||||
newMatIndices.rowIdx = 0;
|
||||
newLevel = level - 1;
|
||||
} else {
|
||||
newMatIndices.rowIdx++;
|
||||
newMatIndices.colIdx = 0;
|
||||
triedCols = [];
|
||||
}
|
||||
}
|
||||
newNode = getNode(newLevel, newMatIndices, currentSite);
|
||||
}
|
||||
} else if (direction === "up") {
|
||||
newMatIndices.rowIdx--;
|
||||
|
||||
let triedCols: number[] = [];
|
||||
|
||||
if (newMatIndices.rowIdx < 0) {
|
||||
newMatIndices.rowIdx = 2;
|
||||
newLevel = level + 1;
|
||||
}
|
||||
|
||||
newNode = getNode(newLevel, newMatIndices, currentSite);
|
||||
|
||||
while (!isNodeVisible(newNode, gameProgress)) {
|
||||
if (triedCols.length < 4) {
|
||||
triedCols.push(newMatIndices.colIdx);
|
||||
const colToTry = tryCol(newMatIndices.colIdx, triedCols);
|
||||
if (colToTry !== undefined) {
|
||||
newMatIndices.colIdx = colToTry;
|
||||
}
|
||||
} else {
|
||||
if (newMatIndices.rowIdx === 0) {
|
||||
if (newLevel === level + 1) {
|
||||
newNode = "UNKNOWN";
|
||||
newMatIndices.colIdx = nodeMatrixIndices.colIdx;
|
||||
break;
|
||||
}
|
||||
newMatIndices.rowIdx = 2;
|
||||
newLevel = level + 1;
|
||||
} else {
|
||||
newMatIndices.rowIdx--;
|
||||
newMatIndices.colIdx = 0;
|
||||
triedCols = [];
|
||||
}
|
||||
}
|
||||
newNode = getNode(newLevel, newMatIndices, currentSite);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
node: newNode!,
|
||||
newNodeHud: getNodeHud(newMatIndices),
|
||||
newLevel: newLevel,
|
||||
newNodeMatrixIndices: newMatIndices,
|
||||
};
|
||||
};
|
||||
|
||||
const findNodeHorizontal = (
|
||||
direction: string,
|
||||
gameProgress: typeof unlocked_nodes,
|
||||
level: number,
|
||||
activeId: string,
|
||||
nodeMatrixIndices: { matrixIdx: number; rowIdx: number; colIdx: number },
|
||||
currentSite: string
|
||||
) => {
|
||||
let newNode: NodeDataType | "UNKNOWN";
|
||||
let newMatIndices = Object.assign({}, nodeMatrixIndices);
|
||||
|
||||
let didMove = false;
|
||||
|
||||
if (direction === "left") {
|
||||
newMatIndices.colIdx--;
|
||||
|
||||
let triedRows: number[] = [];
|
||||
|
||||
if (newMatIndices.colIdx < 0) {
|
||||
didMove = true;
|
||||
newMatIndices.colIdx = 0;
|
||||
newMatIndices.matrixIdx =
|
||||
newMatIndices.matrixIdx + 1 > 8 ? 1 : newMatIndices.matrixIdx + 1;
|
||||
}
|
||||
|
||||
newNode = getNode(level, newMatIndices, currentSite);
|
||||
|
||||
while (!isNodeVisible(newNode, gameProgress)) {
|
||||
if (triedRows.length < 3) {
|
||||
triedRows.push(newMatIndices.rowIdx);
|
||||
const rowToTry = tryRow(newMatIndices.rowIdx, triedRows);
|
||||
if (rowToTry !== undefined) {
|
||||
newMatIndices.rowIdx = rowToTry;
|
||||
}
|
||||
} else {
|
||||
if (newMatIndices.colIdx > 3 && didMove) return;
|
||||
|
||||
if (newMatIndices.colIdx < 0) {
|
||||
if (activeId === "UNKNOWN") {
|
||||
didMove = true;
|
||||
newMatIndices.colIdx = nodeMatrixIndices.colIdx;
|
||||
newMatIndices.matrixIdx =
|
||||
newMatIndices.matrixIdx + 1 > 8 ? 1 : newMatIndices.matrixIdx + 1;
|
||||
newNode = "UNKNOWN";
|
||||
break;
|
||||
} else {
|
||||
didMove = true;
|
||||
newMatIndices.colIdx = 0;
|
||||
newMatIndices.matrixIdx =
|
||||
newMatIndices.matrixIdx + 1 > 8 ? 1 : newMatIndices.matrixIdx + 1;
|
||||
}
|
||||
} else {
|
||||
didMove ? newMatIndices.colIdx++ : newMatIndices.colIdx--;
|
||||
triedRows = [];
|
||||
newMatIndices.rowIdx = 0;
|
||||
}
|
||||
}
|
||||
newNode = getNode(level, newMatIndices, currentSite);
|
||||
}
|
||||
} else if (direction === "right") {
|
||||
newMatIndices.colIdx++;
|
||||
|
||||
let triedRows: number[] = [];
|
||||
|
||||
if (newMatIndices.colIdx > 3) {
|
||||
didMove = true;
|
||||
newMatIndices.colIdx = 3;
|
||||
newMatIndices.matrixIdx =
|
||||
newMatIndices.matrixIdx - 1 < 1 ? 8 : newMatIndices.matrixIdx - 1;
|
||||
}
|
||||
|
||||
newNode = getNode(level, newMatIndices, currentSite);
|
||||
|
||||
while (!isNodeVisible(newNode, gameProgress)) {
|
||||
if (triedRows.length < 3) {
|
||||
triedRows.push(newMatIndices.rowIdx);
|
||||
const rowToTry = tryRow(newMatIndices.rowIdx, triedRows);
|
||||
if (rowToTry !== undefined) {
|
||||
newMatIndices.rowIdx = rowToTry;
|
||||
}
|
||||
} else {
|
||||
if (newMatIndices.colIdx < 0 && didMove) return;
|
||||
|
||||
if (newMatIndices.colIdx > 3) {
|
||||
if (activeId === "UNKNOWN") {
|
||||
didMove = true;
|
||||
newMatIndices.colIdx = nodeMatrixIndices.colIdx;
|
||||
newMatIndices.matrixIdx =
|
||||
newMatIndices.matrixIdx - 1 < 1 ? 8 : newMatIndices.matrixIdx - 1;
|
||||
newNode = "UNKNOWN";
|
||||
break;
|
||||
} else {
|
||||
if (didMove) return;
|
||||
else {
|
||||
didMove = true;
|
||||
newMatIndices.colIdx = 3;
|
||||
newMatIndices.matrixIdx =
|
||||
newMatIndices.matrixIdx - 1 < 1
|
||||
? 8
|
||||
: newMatIndices.matrixIdx - 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
didMove ? newMatIndices.colIdx-- : newMatIndices.colIdx++;
|
||||
triedRows = [];
|
||||
newMatIndices.rowIdx = 0;
|
||||
}
|
||||
}
|
||||
newNode = getNode(level, newMatIndices, currentSite);
|
||||
}
|
||||
}
|
||||
|
||||
const newNodeHud = getNodeHud(newMatIndices);
|
||||
|
||||
return {
|
||||
didMove: didMove,
|
||||
node: newNode!,
|
||||
newNodeHud: newNodeHud,
|
||||
newNodeMatrixIndices: newMatIndices,
|
||||
};
|
||||
};
|
||||
|
||||
const nodeSelector = (context: NodeSelectorContext) => {
|
||||
let newNodeData;
|
||||
let move;
|
||||
|
||||
switch (context.action) {
|
||||
case "site_left":
|
||||
case "site_right":
|
||||
const t = findNode(
|
||||
context.action === "site_right" ? "right" : "left",
|
||||
context.nodeMatrixIndices,
|
||||
context.level,
|
||||
context.currentSite,
|
||||
context.gameProgress
|
||||
);
|
||||
|
||||
move = context.action === "site_left" ? "left" : "right";
|
||||
newNodeData = findNodeHorizontal(
|
||||
move,
|
||||
context.gameProgress,
|
||||
context.level,
|
||||
context.activeId,
|
||||
context.nodeMatrixIndices,
|
||||
context.currentSite
|
||||
);
|
||||
|
||||
console.log(t!.matrixIndices);
|
||||
if (newNodeData) {
|
||||
const siteRotYModifier = move === "left" ? Math.PI / 4 : -Math.PI / 4;
|
||||
|
||||
return {
|
||||
event: newNodeData.didMove ? context.action : "change_node",
|
||||
node: getNodeById(t!.node, context.currentSite),
|
||||
newActiveHud: newNodeData.newNodeHud,
|
||||
newNodeMatrixIndices: t!.matrixIndices,
|
||||
newSiteRotY: newNodeData.didMove
|
||||
? context.siteRotY + siteRotYModifier
|
||||
: context.siteRotY,
|
||||
newSitePosY: context.sitePosY,
|
||||
newLevel: context.level,
|
||||
};
|
||||
}
|
||||
break;
|
||||
case "site_up":
|
||||
case "site_down":
|
||||
move = context.action === "site_up" ? "up" : "down";
|
||||
|
||||
newNodeData = findNodeVertical(
|
||||
move,
|
||||
context.gameProgress,
|
||||
context.level,
|
||||
context.nodeMatrixIndices,
|
||||
context.currentSite
|
||||
);
|
||||
|
||||
if (newNodeData) {
|
||||
const didMove = context.level !== newNodeData.newLevel;
|
||||
const sitePosYModifier = move === "up" ? -1.5 : 1.5;
|
||||
return {
|
||||
event: didMove ? context.action : "change_node",
|
||||
node: newNodeData.node,
|
||||
newNodeMatrixIndices: newNodeData.newNodeMatrixIndices,
|
||||
newActiveHud: newNodeData.newNodeHud,
|
||||
newSiteRotY: context.siteRotY,
|
||||
newSitePosY: didMove
|
||||
? context.sitePosY + sitePosYModifier
|
||||
: context.sitePosY,
|
||||
newLevel: newNodeData.newLevel,
|
||||
};
|
||||
}
|
||||
break;
|
||||
case "select_level":
|
||||
newNodeData = findNodeAfterLevelSelection(
|
||||
context.gameProgress,
|
||||
context.level,
|
||||
context.nodeMatrixIndices,
|
||||
context.currentSite
|
||||
);
|
||||
|
||||
if (newNodeData) {
|
||||
return {
|
||||
node: newNodeData.node,
|
||||
nodeMatrixIndices: newNodeData.newNodeMatrixIndices,
|
||||
activeHud: newNodeData.newNodeHud,
|
||||
siteRotY: context.siteRotY,
|
||||
level: newNodeData.newLevel,
|
||||
sitePosY: newNodeData.newSitePosY,
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default nodeSelector;
|
29
src/core/setters/boot/bootSubsceneManager.ts
Normal file
29
src/core/setters/boot/bootSubsceneManager.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { useStore } from "../../../store";
|
||||
|
||||
const bootSubsceneManager = (eventState: any) => {
|
||||
const setBootSubscene = useStore.getState().setBootSubscene;
|
||||
|
||||
const dispatchAction = (eventState: { event: string }) => {
|
||||
switch (eventState.event) {
|
||||
case "authorize_user_back":
|
||||
case "load_data_no_select":
|
||||
return {
|
||||
action: () => setBootSubscene("main_menu"),
|
||||
};
|
||||
case "authorize_user_select":
|
||||
return {
|
||||
action: () => setBootSubscene("authorize_user"),
|
||||
};
|
||||
case "load_data_select":
|
||||
return { action: () => setBootSubscene("load_data") };
|
||||
}
|
||||
};
|
||||
|
||||
const { action } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) {
|
||||
action();
|
||||
}
|
||||
};
|
||||
|
||||
export default bootSubsceneManager;
|
33
src/core/setters/main/idleManager.ts
Normal file
33
src/core/setters/main/idleManager.ts
Normal file
|
@ -0,0 +1,33 @@
|
|||
import { useStore } from "../../../store";
|
||||
|
||||
const idleManager = (eventState: any) => {
|
||||
const dispatchAction = (eventState: {
|
||||
media: string;
|
||||
images?: { "1": string; "2": string; "3": string };
|
||||
}) => {
|
||||
if (eventState.images) {
|
||||
return {
|
||||
action: () =>
|
||||
useStore.setState({
|
||||
idleMedia: eventState.media,
|
||||
idleImages: eventState.images,
|
||||
}),
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
action: () =>
|
||||
useStore.setState({
|
||||
idleMedia: eventState.media,
|
||||
}),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const { action } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) {
|
||||
action();
|
||||
}
|
||||
};
|
||||
|
||||
export default idleManager;
|
|
@ -0,0 +1,26 @@
|
|||
import { useStore } from "../../../../store";
|
||||
|
||||
const levelSelectionManager = (eventState: any) => {
|
||||
const setSelectedLevel = useStore.getState().setSelectedLevel;
|
||||
|
||||
const dispatchAction = (eventState: any) => {
|
||||
switch (eventState.event) {
|
||||
case "toggle_level_selection":
|
||||
return {
|
||||
action: () => setSelectedLevel(eventState.level),
|
||||
};
|
||||
case "level_selection_up":
|
||||
case "level_selection_down":
|
||||
return {
|
||||
action: () => setSelectedLevel(eventState.selectedLevelIdx),
|
||||
};
|
||||
}
|
||||
};
|
||||
const { action } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) {
|
||||
action();
|
||||
}
|
||||
};
|
||||
|
||||
export default levelSelectionManager;
|
44
src/core/setters/main/mainSubsceneManager.ts
Normal file
44
src/core/setters/main/mainSubsceneManager.ts
Normal file
|
@ -0,0 +1,44 @@
|
|||
import { useStore } from "../../../store";
|
||||
|
||||
const mainSubsceneManager = (eventState: any) => {
|
||||
const setMainSubscene = useStore.getState().setMainSubscene;
|
||||
|
||||
const dispatchAction = (eventState: { event: string }) => {
|
||||
switch (eventState.event) {
|
||||
case "level_selection_back":
|
||||
case "select_level_up":
|
||||
case "select_level_down":
|
||||
return {
|
||||
action: () => setMainSubscene("site"),
|
||||
delay: 0,
|
||||
};
|
||||
case "toggle_level_selection":
|
||||
return {
|
||||
action: () => setMainSubscene("level_selection"),
|
||||
delay: 0,
|
||||
};
|
||||
case "pause_game":
|
||||
return {
|
||||
action: () => setMainSubscene("pause"),
|
||||
value: "pause",
|
||||
delay: 0,
|
||||
};
|
||||
case "pause_exit_select":
|
||||
case "pause_change_select":
|
||||
return {
|
||||
action: () => setMainSubscene("site"),
|
||||
delay: 1800,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const { action, delay } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) {
|
||||
setTimeout(() => {
|
||||
action();
|
||||
}, delay);
|
||||
}
|
||||
};
|
||||
|
||||
export default mainSubsceneManager;
|
31
src/core/setters/main/pause/pauseManager.ts
Normal file
31
src/core/setters/main/pause/pauseManager.ts
Normal file
|
@ -0,0 +1,31 @@
|
|||
import { useStore } from "../../../../store";
|
||||
|
||||
type PauseManagerProps = { event: string; pauseMatrixIdx: number };
|
||||
|
||||
const pauseManager = (eventState: any) => {
|
||||
const setComponentMatrixIdx = useStore.getState().setPauseComponentMatrixIdx;
|
||||
const setExitAnimation = useStore.getState().setPauseExitAnimation;
|
||||
|
||||
const dispatchAction = (eventState: PauseManagerProps) => {
|
||||
switch (eventState.event) {
|
||||
case "pause_up":
|
||||
case "pause_down":
|
||||
return {
|
||||
action: () => setComponentMatrixIdx(eventState.pauseMatrixIdx),
|
||||
};
|
||||
case "pause_exit_select":
|
||||
return {
|
||||
action: () => setExitAnimation(true),
|
||||
};
|
||||
case "pause_game":
|
||||
return { action: () => setExitAnimation(false) };
|
||||
}
|
||||
};
|
||||
const { action } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) {
|
||||
action();
|
||||
}
|
||||
};
|
||||
|
||||
export default pauseManager;
|
65
src/core/setters/main/site/lainManager.ts
Normal file
65
src/core/setters/main/site/lainManager.ts
Normal file
|
@ -0,0 +1,65 @@
|
|||
import { useStore } from "../../../../store";
|
||||
|
||||
const lainManager = (eventState: any) => {
|
||||
const setLainMoveState = useStore.getState().setLainMoveState;
|
||||
|
||||
const dispatchAction = (eventState: any) => {
|
||||
switch (eventState.event) {
|
||||
case "site_up":
|
||||
case "site_down":
|
||||
case "site_left":
|
||||
case "site_right":
|
||||
case "select_level_up":
|
||||
case "select_level_down":
|
||||
case "pause_game":
|
||||
case "knock_node":
|
||||
case "prayer":
|
||||
case "touch_sleeve":
|
||||
case "thinking":
|
||||
case "stretch_2":
|
||||
case "stretch":
|
||||
case "spin":
|
||||
case "scratch_head":
|
||||
case "blush":
|
||||
case "hands_behind_head":
|
||||
case "hands_on_hips":
|
||||
case "hands_on_hips_2":
|
||||
case "hands_together":
|
||||
case "lean_forward":
|
||||
case "lean_left":
|
||||
case "lean_right":
|
||||
case "look_around":
|
||||
case "play_with_hair":
|
||||
return {
|
||||
action: () => setLainMoveState(eventState.event),
|
||||
duration: 3900,
|
||||
};
|
||||
case "throw_node_media":
|
||||
case "throw_node_gate":
|
||||
case "throw_node_sskn":
|
||||
case "throw_node_tak":
|
||||
return { action: () => setLainMoveState("throw_node"), duration: 3900 };
|
||||
case "rip_node_media":
|
||||
case "rip_node_gate":
|
||||
case "rip_node_sskn":
|
||||
case "rip_node_tak":
|
||||
return { action: () => setLainMoveState("rip_node"), duration: 6000 };
|
||||
case "knock_node_and_fall":
|
||||
return {
|
||||
action: () => setLainMoveState("knock_node_and_fall"),
|
||||
duration: 6000,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const { action, duration } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) {
|
||||
action();
|
||||
setTimeout(() => {
|
||||
setLainMoveState("standing");
|
||||
}, duration);
|
||||
}
|
||||
};
|
||||
|
||||
export default lainManager;
|
23
src/core/setters/main/site/levelManager.ts
Normal file
23
src/core/setters/main/site/levelManager.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
import { useStore } from "../../../../store";
|
||||
|
||||
const levelManager = (eventState: any) => {
|
||||
const setActiveLevel = useStore.getState().setActiveLevel;
|
||||
|
||||
const dispatchAction = (eventState: any) => {
|
||||
switch (eventState.event) {
|
||||
case "site_up":
|
||||
case "site_down":
|
||||
case "select_level_up":
|
||||
case "select_level_down":
|
||||
return { action: () => setActiveLevel(eventState.level) };
|
||||
}
|
||||
};
|
||||
|
||||
const { action } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) {
|
||||
action();
|
||||
}
|
||||
};
|
||||
|
||||
export default levelManager;
|
190
src/core/setters/main/site/nodeManager.ts
Normal file
190
src/core/setters/main/site/nodeManager.ts
Normal file
|
@ -0,0 +1,190 @@
|
|||
import { useStore } from "../../../../store";
|
||||
import { NodeDataType } from "../../../../components/MainScene/SyncedComponents/Site";
|
||||
|
||||
const nodeManager = (eventState: any) => {
|
||||
const setActiveNode = useStore.getState().setNode;
|
||||
const setActiveNodePos = useStore.getState().setNodePos;
|
||||
const setActiveNodeRot = useStore.getState().setNodeRot;
|
||||
const setActiveNodeState = useStore.getState().setNodeState;
|
||||
|
||||
const calculateCoordsBasedOnRotation = (
|
||||
x: number,
|
||||
z: number,
|
||||
rotation: number
|
||||
) => ({
|
||||
x: x * Math.cos(rotation) - z * Math.sin(rotation),
|
||||
z: x * Math.sin(rotation) + z * Math.cos(rotation),
|
||||
});
|
||||
|
||||
const animateActiveNodeThrow = (siteRotY: number) => {
|
||||
setActiveNodeState(true, "interactedWith");
|
||||
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(0.9, 0.3, siteRotY);
|
||||
const sndCoordSet = calculateCoordsBasedOnRotation(0.5, 0.2, siteRotY);
|
||||
const thirdCoordSet = calculateCoordsBasedOnRotation(1.55, 0.2, siteRotY);
|
||||
const fourthCoordSet = calculateCoordsBasedOnRotation(0, 2, siteRotY);
|
||||
|
||||
setActiveNodePos([fstCoordSet.x, 0, fstCoordSet.z]);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodePos([sndCoordSet.x, 0, sndCoordSet.z]);
|
||||
}, 800);
|
||||
setTimeout(() => {
|
||||
setActiveNodePos([thirdCoordSet.x, 0, sndCoordSet.z]);
|
||||
setActiveNodeRot([0, 0, -0.005]);
|
||||
}, 2600);
|
||||
setTimeout(() => {
|
||||
setActiveNodePos([fourthCoordSet.x, 0, fourthCoordSet.z]);
|
||||
setActiveNodeRot([0, 0, -0.5]);
|
||||
}, 2700);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeRot([0, 0, 0]);
|
||||
setActiveNodeState(false, "interactedWith");
|
||||
}, 3800);
|
||||
};
|
||||
|
||||
const animateNodeKnock = (siteRotY: number) => {
|
||||
setActiveNodeState(true, "interactedWith");
|
||||
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(1.1, 0.2, siteRotY);
|
||||
|
||||
setActiveNodePos([fstCoordSet.x, -0.6, fstCoordSet.z]);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(false, "interactedWith");
|
||||
}, 2500);
|
||||
};
|
||||
|
||||
const animateNodeKnockAndFall = (siteRotY: number) => {
|
||||
setActiveNodeState(true, "interactedWith");
|
||||
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(1.1, 0.2, siteRotY);
|
||||
|
||||
setActiveNodePos([fstCoordSet.x, -0.6, fstCoordSet.z]);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(false, "visible");
|
||||
}, 2300);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(false, "interactedWith");
|
||||
}, 2500);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(true, "visible");
|
||||
}, 3200);
|
||||
};
|
||||
|
||||
const animateNodeTouchAndScare = (siteRotY: number) => {
|
||||
setActiveNodeState(true, "interactedWith");
|
||||
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(-0.6, 0.2, siteRotY);
|
||||
|
||||
setActiveNodePos([fstCoordSet.x, 0, fstCoordSet.z]);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(true, "exploding");
|
||||
setActiveNodeState(false, "visible");
|
||||
}, 1200);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(false, "interactedWith");
|
||||
setActiveNodeRot([0, 0, 0]);
|
||||
}, 1400);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(false, "exploding");
|
||||
}, 3150);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(true, "visible");
|
||||
}, 3500);
|
||||
};
|
||||
|
||||
const animateShrinkAndRip = (siteRotY: number) => {
|
||||
setActiveNodeState(true, "interactedWith");
|
||||
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(0.9, 0.3, siteRotY);
|
||||
const sndCoordSet = calculateCoordsBasedOnRotation(0.5, 0.2, siteRotY);
|
||||
const thirdCoordSet = calculateCoordsBasedOnRotation(0, 0.2, siteRotY);
|
||||
|
||||
setActiveNodePos([fstCoordSet.x, 0, fstCoordSet.z]);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodePos([sndCoordSet.x, 0, sndCoordSet.z]);
|
||||
}, 800);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodePos([thirdCoordSet.x, -0.4, thirdCoordSet.z]);
|
||||
}, 2800);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(true, "shrinking");
|
||||
}, 3000);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodePos([thirdCoordSet.x, -1.5, thirdCoordSet.z]);
|
||||
}, 3200);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(false, "visible");
|
||||
}, 3500);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(false, "interactedWith");
|
||||
setActiveNodeState(false, "shrinking");
|
||||
setActiveNodeRot([0, 0, 0]);
|
||||
}, 6400);
|
||||
|
||||
setTimeout(() => {
|
||||
setActiveNodeState(true, "visible");
|
||||
}, 7500);
|
||||
};
|
||||
|
||||
const updateActiveNode = (node: NodeDataType, delay?: number) => {
|
||||
setTimeout(() => {
|
||||
setActiveNode(node);
|
||||
}, delay);
|
||||
};
|
||||
|
||||
const dispatchAction = (eventState: any) => {
|
||||
switch (eventState.event) {
|
||||
case "site_up":
|
||||
case "site_down":
|
||||
case "site_left":
|
||||
case "site_right":
|
||||
case "select_level_up":
|
||||
case "select_level_down":
|
||||
return {
|
||||
action: () => updateActiveNode(eventState.node, 3900),
|
||||
};
|
||||
case "change_node":
|
||||
return {
|
||||
action: () => updateActiveNode(eventState.node),
|
||||
};
|
||||
case "throw_node_media":
|
||||
case "throw_node_gate":
|
||||
case "throw_node_sskn":
|
||||
case "throw_node_tak":
|
||||
return {
|
||||
action: () => animateActiveNodeThrow(eventState.siteRotY),
|
||||
};
|
||||
case "rip_node_media":
|
||||
case "rip_node_gate":
|
||||
case "rip_node_sskn":
|
||||
case "rip_node_tak":
|
||||
return {
|
||||
action: () => animateActiveNodeThrow(eventState.siteRotY),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const { action } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) {
|
||||
action();
|
||||
}
|
||||
};
|
||||
|
||||
export default nodeManager;
|
37
src/core/setters/main/site/siteManager.ts
Normal file
37
src/core/setters/main/site/siteManager.ts
Normal file
|
@ -0,0 +1,37 @@
|
|||
import { useStore } from "../../../../store";
|
||||
|
||||
const siteManager = (eventState: any) => {
|
||||
const setRotY = useStore.getState().setSiteRotY;
|
||||
const setRotX = useStore.getState().setSiteRotX;
|
||||
|
||||
const dispatchAction = (eventState: any) => {
|
||||
switch (eventState.event) {
|
||||
case "site_left":
|
||||
case "site_right":
|
||||
return {
|
||||
action: () => setRotY(eventState.siteRotY),
|
||||
delay: 1100,
|
||||
};
|
||||
case "pause_game":
|
||||
return {
|
||||
action: () => setRotX(Math.PI / 2),
|
||||
delay: 3600,
|
||||
};
|
||||
case "pause_exit_select":
|
||||
return {
|
||||
action: () => setRotX(0),
|
||||
delay: 0,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const { action, delay } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) {
|
||||
setTimeout(() => {
|
||||
action();
|
||||
}, delay);
|
||||
}
|
||||
};
|
||||
|
||||
export default siteManager;
|
81
src/core/setters/media/mediaManager.ts
Normal file
81
src/core/setters/media/mediaManager.ts
Normal file
|
@ -0,0 +1,81 @@
|
|||
import { useStore } from "../../../store";
|
||||
import { useCallback } from "react";
|
||||
import * as THREE from "three";
|
||||
|
||||
const mediaManager = (eventState: any) => {
|
||||
const toggleSide = useStore.getState().toggleMediaSide;
|
||||
const setLeftComponentMatrixIdx = useStore.getState()
|
||||
.setMediaLeftComponentMatrixIdx;
|
||||
|
||||
const updateRightSide = useStore.getState().updateRightSide;
|
||||
|
||||
const resetScene = useStore.getState().resetMediaScene;
|
||||
|
||||
const setAudioAnalyser = useStore.getState().setAudioAnalyser;
|
||||
|
||||
const playMedia = () => {
|
||||
const mediaElement = document.getElementById("media") as HTMLMediaElement;
|
||||
|
||||
if (mediaElement && mediaElement.paused) {
|
||||
const listener = new THREE.AudioListener();
|
||||
const audio = new THREE.Audio(listener);
|
||||
|
||||
audio.setMediaElementSource(mediaElement);
|
||||
|
||||
setAudioAnalyser(new THREE.AudioAnalyser(audio, 2048));
|
||||
|
||||
mediaElement.play();
|
||||
}
|
||||
};
|
||||
|
||||
const exitMedia = () => {
|
||||
const mediaElement = document.getElementById("media") as HTMLMediaElement;
|
||||
if (mediaElement) {
|
||||
mediaElement.pause();
|
||||
mediaElement.currentTime = 0;
|
||||
}
|
||||
resetScene();
|
||||
};
|
||||
|
||||
const dispatchAction = (eventState: {
|
||||
event: string;
|
||||
leftSideComponentIdx: 0 | 1;
|
||||
rightSideComponentIdx: 0 | 1 | 2;
|
||||
wordPosStateIdx: number;
|
||||
}) => {
|
||||
switch (eventState.event) {
|
||||
case "media_rightside_down":
|
||||
case "media_rightside_up":
|
||||
return {
|
||||
action: () =>
|
||||
updateRightSide(
|
||||
eventState.rightSideComponentIdx,
|
||||
eventState.wordPosStateIdx
|
||||
),
|
||||
};
|
||||
case "media_leftside_down":
|
||||
case "media_leftside_up":
|
||||
return {
|
||||
action: () =>
|
||||
setLeftComponentMatrixIdx(eventState.leftSideComponentIdx),
|
||||
};
|
||||
case "media_leftside_right":
|
||||
case "media_rightside_left":
|
||||
return {
|
||||
action: () => toggleSide,
|
||||
};
|
||||
case "media_play_select":
|
||||
return { action: () => playMedia };
|
||||
case "media_exit_select":
|
||||
return { action: () => exitMedia };
|
||||
}
|
||||
};
|
||||
|
||||
const { action } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) {
|
||||
action();
|
||||
}
|
||||
};
|
||||
|
||||
export default mediaManager;
|
62
src/core/setters/sceneManager.ts
Normal file
62
src/core/setters/sceneManager.ts
Normal file
|
@ -0,0 +1,62 @@
|
|||
import { useStore } from "../../store";
|
||||
|
||||
const sceneManager = (eventState: any) => {
|
||||
const dispatchAction = (eventState: { event: string; scene: string }) => {
|
||||
switch (eventState.event) {
|
||||
case "throw_node_media":
|
||||
case "throw_node_gate":
|
||||
case "throw_node_sskn":
|
||||
case "throw_node_tak":
|
||||
return {
|
||||
action: () =>
|
||||
useStore.setState({ currentScene: eventState.scene, intro: false }),
|
||||
delay: 3450,
|
||||
};
|
||||
case "rip_node_media":
|
||||
case "rip_node_gate":
|
||||
case "rip_node_sskn":
|
||||
case "rip_node_tak":
|
||||
return {
|
||||
action: () =>
|
||||
useStore.setState({ currentScene: eventState.scene, intro: false }),
|
||||
delay: 6000,
|
||||
};
|
||||
case "media_exit_select":
|
||||
case "exit_gate":
|
||||
case "sskn_cancel_select":
|
||||
return {
|
||||
action: () =>
|
||||
useStore.setState({ currentScene: "main", intro: false }),
|
||||
delay: 0,
|
||||
};
|
||||
case "sskn_ok_select":
|
||||
return {
|
||||
action: () =>
|
||||
useStore.setState({ currentScene: "main", intro: false }),
|
||||
delay: 6000,
|
||||
};
|
||||
case "pause_change_select":
|
||||
return {
|
||||
action: () =>
|
||||
useStore.setState({ currentScene: "change_dic", intro: true }),
|
||||
delay: 0,
|
||||
};
|
||||
case "play_idle_media":
|
||||
return {
|
||||
action: () =>
|
||||
useStore.setState({ currentScene: "idle_media", intro: false }),
|
||||
delay: 0,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const { action, delay } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) {
|
||||
setTimeout(() => {
|
||||
action();
|
||||
}, delay);
|
||||
}
|
||||
};
|
||||
|
||||
export default sceneManager;
|
40
src/core/setters/sskn/ssknManager.ts
Normal file
40
src/core/setters/sskn/ssknManager.ts
Normal file
|
@ -0,0 +1,40 @@
|
|||
import { useStore } from "../../../store";
|
||||
|
||||
const ssknManager = (eventState: any) => {
|
||||
const toggleComponentMatrixIdx = useStore.getState()
|
||||
.toggleSSknComponentMatrixIdx;
|
||||
const resetComponentMatrixIdx = useStore.getState()
|
||||
.resetSSknComponentMatrixIdx;
|
||||
const setSSknLoading = useStore.getState().setSSknLoading;
|
||||
|
||||
const dispatchAction = (eventState: { event: string }) => {
|
||||
switch (eventState.event) {
|
||||
case "throw_node_sskn":
|
||||
case "rip_node_sskn":
|
||||
return {
|
||||
action: () => resetComponentMatrixIdx(),
|
||||
};
|
||||
case "sskn_ok_down":
|
||||
case "sskn_cancel_up":
|
||||
return {
|
||||
action: () => toggleComponentMatrixIdx(),
|
||||
};
|
||||
case "sskn_ok_select":
|
||||
return {
|
||||
action: () => setSSknLoading(true),
|
||||
};
|
||||
case "sskn_cancel_select":
|
||||
return {
|
||||
action: () => setSSknLoading(false),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const { action } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) {
|
||||
action();
|
||||
}
|
||||
};
|
||||
|
||||
export default ssknManager;
|
|
@ -1,6 +1,6 @@
|
|||
const handleSSknSceneEvent = (gameContext: any) => {
|
||||
const keyPress = gameContext.keyPress;
|
||||
const activeSSknComponent = gameContext.activeSSknComponent;
|
||||
const handleSSknSceneEvent = (ssknSceneContext: any) => {
|
||||
const { keyPress, activeSSknComponent } = ssknSceneContext;
|
||||
|
||||
switch (keyPress) {
|
||||
case "UP":
|
||||
case "DOWN":
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
export const calculatePosAfterMove = (
|
||||
currentData: {
|
||||
siteRotY: number;
|
||||
sitePosY: number;
|
||||
matrixIndices: { rowIdx: number; colIdx: number; matrixIdx: number };
|
||||
},
|
||||
prevData: { siteRotY: number; sitePosY: number }
|
||||
) => {
|
||||
if (currentData.sitePosY > prevData.sitePosY) {
|
||||
// todo
|
||||
// instead of 1 i need to calculate the amplifier value
|
||||
return { posX: 0, posY: 1 * 1 };
|
||||
} else if (currentData.sitePosY < prevData.sitePosY) {
|
||||
return { posX: 0, posY: -1 * 1 };
|
||||
} else {
|
||||
if (
|
||||
currentData.matrixIndices.colIdx === 0 ||
|
||||
currentData.matrixIndices.colIdx === 3
|
||||
) {
|
||||
if (currentData.siteRotY > prevData.siteRotY) {
|
||||
return { posX: 1.5, posY: 0 };
|
||||
} else if (currentData.siteRotY < prevData.siteRotY) {
|
||||
return { posX: -1.5, posY: 0 };
|
||||
}
|
||||
} else if (
|
||||
currentData.matrixIndices.colIdx === 1 ||
|
||||
currentData.matrixIndices.colIdx === 2
|
||||
) {
|
||||
if (currentData.siteRotY > prevData.siteRotY) {
|
||||
return { posX: 0.5, posY: 0 };
|
||||
} else if (currentData.siteRotY < prevData.siteRotY) {
|
||||
return { posX: -0.5, posY: 0 };
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
|
@ -1,22 +0,0 @@
|
|||
import { SiteType } from "../../components/MainScene/SyncedComponents/Site";
|
||||
import game_progress from "../../resources/initial_progress.json";
|
||||
import { isNodeVisible } from "../nodeSelector";
|
||||
|
||||
const filterInvisibleNodes = (
|
||||
siteData: SiteType,
|
||||
gameProgress: typeof game_progress
|
||||
) => {
|
||||
const visibleNodes: SiteType = {};
|
||||
Object.entries(siteData).forEach((level) => {
|
||||
visibleNodes[level[0]] = {};
|
||||
Object.entries(level[1]).forEach((node) => {
|
||||
if (isNodeVisible(node[1], gameProgress)) {
|
||||
visibleNodes[level[0]][node[0]] = node[1];
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return visibleNodes;
|
||||
};
|
||||
|
||||
export default filterInvisibleNodes;
|
|
@ -1,235 +0,0 @@
|
|||
import { SiteType } from "../../components/MainScene/SyncedComponents/Site";
|
||||
import node_matrices from "../../resources/node_matrices.json";
|
||||
import { getNode, getNodeById, isNodeVisible } from "../nodeSelector";
|
||||
|
||||
export const generateInactiveNodes = (
|
||||
visibleNodes: SiteType,
|
||||
activeLevel: string
|
||||
) => {
|
||||
const obj = {};
|
||||
const activeLevelNr = parseInt(activeLevel);
|
||||
const visibleLevels = [
|
||||
(activeLevelNr - 2).toString().padStart(2, "0"),
|
||||
(activeLevelNr - 1).toString().padStart(2, "0"),
|
||||
(activeLevelNr + 1).toString().padStart(2, "0"),
|
||||
(activeLevelNr + 2).toString().padStart(2, "0"),
|
||||
];
|
||||
|
||||
visibleLevels.forEach((level) => {
|
||||
Object.assign(obj, visibleNodes[level as keyof typeof visibleNodes]);
|
||||
});
|
||||
|
||||
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;
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
function reorder<T>(array: T[], order: number[]): T[]
|
||||
{
|
||||
return order.map(i => array[i]);
|
||||
}
|
||||
|
||||
function transpose<T>(matrix: T[][]): T[][]
|
||||
{
|
||||
return Object.keys(matrix[0])
|
||||
.map(Number)
|
||||
.map(
|
||||
(c: number) => matrix.map(
|
||||
(r: T[]) => r[c]));
|
||||
}
|
||||
|
||||
function RowPrecedence(rowIdx: number): number[]
|
||||
{
|
||||
switch (rowIdx) {
|
||||
default: case 0: return [0, 1, 2];
|
||||
case 1: return [1, 0, 2];
|
||||
case 2: return [2, 1, 0];
|
||||
}
|
||||
};
|
||||
|
||||
function ColPrecedence(colIdx: number): number[]
|
||||
{
|
||||
switch (colIdx) {
|
||||
default: case 0: return [0, 1, 2, 3];
|
||||
case 1: return [1, 0, 2, 3];
|
||||
case 2: return [2, 1, 3, 0];
|
||||
case 3: return [3, 2, 1, 0];
|
||||
}
|
||||
}
|
||||
|
||||
function getNodesMatrixWithIndices
|
||||
(
|
||||
matrixIdx: number,
|
||||
activeLevel: number,
|
||||
currentSite: string,
|
||||
gameProgress: any
|
||||
)
|
||||
: any[][]
|
||||
{
|
||||
return getVisibleNodesMatrix(
|
||||
matrixIdx,
|
||||
activeLevel,
|
||||
currentSite,
|
||||
gameProgress
|
||||
)
|
||||
.map(
|
||||
(r, i) => r.map(
|
||||
(n, j) => n ? {
|
||||
node: n,
|
||||
matrixIndices: {
|
||||
matrixIdx,
|
||||
rowIdx: i,
|
||||
colIdx: j
|
||||
}
|
||||
} : null
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
interface NodeMatrixIndices {
|
||||
matrixIdx: number;
|
||||
rowIdx: number;
|
||||
colIdx: number;
|
||||
}
|
||||
|
||||
function findNode_current
|
||||
(
|
||||
direction: string,
|
||||
{matrixIdx, rowIdx, colIdx}: NodeMatrixIndices,
|
||||
level: number,
|
||||
currentSite: string,
|
||||
gameProgress: any
|
||||
)
|
||||
: any | undefined
|
||||
{
|
||||
const nodes = getNodesMatrixWithIndices(
|
||||
matrixIdx,
|
||||
level,
|
||||
currentSite,
|
||||
gameProgress
|
||||
);
|
||||
|
||||
const filters: any = {
|
||||
left: () => transpose(
|
||||
reorder(nodes, RowPrecedence(rowIdx))
|
||||
.map(r => r.slice(0, colIdx).reverse())
|
||||
).flat(),
|
||||
|
||||
right: () => transpose(
|
||||
reorder(nodes, RowPrecedence(rowIdx))
|
||||
.map(r => r.slice(colIdx + 1))
|
||||
).flat(),
|
||||
|
||||
up: () => nodes.slice(0, rowIdx).reverse()
|
||||
.flatMap(r => reorder(r, ColPrecedence(colIdx))),
|
||||
|
||||
down: () => nodes.slice(rowIdx + 1)
|
||||
.flatMap(r => reorder(r, ColPrecedence(colIdx)))
|
||||
};
|
||||
|
||||
const chosen = filters[direction]().find((e: any) => e);
|
||||
if (chosen) return {...chosen, didMove: false};
|
||||
}
|
||||
|
||||
function findNode_next
|
||||
(
|
||||
direction: string,
|
||||
{matrixIdx, rowIdx, colIdx}: NodeMatrixIndices,
|
||||
level: number,
|
||||
currentSite: string,
|
||||
gameProgress: any
|
||||
)
|
||||
: any | undefined
|
||||
{
|
||||
const funcs: any = {
|
||||
left: {
|
||||
getMatrix: () => getNodesMatrixWithIndices(
|
||||
matrixIdx + 1 > 8 ? 1 : matrixIdx + 1,
|
||||
level,
|
||||
currentSite,
|
||||
gameProgress
|
||||
),
|
||||
|
||||
filter: (ns: any[]) => transpose(
|
||||
reorder(ns, RowPrecedence(rowIdx))
|
||||
).flat()
|
||||
},
|
||||
|
||||
right: {
|
||||
getMatrix: () => getNodesMatrixWithIndices(
|
||||
matrixIdx - 1 < 1 ? 8 : matrixIdx - 1,
|
||||
level,
|
||||
currentSite,
|
||||
gameProgress
|
||||
),
|
||||
|
||||
filter: (ns: any[]) => transpose(
|
||||
reorder(ns, RowPrecedence(rowIdx))
|
||||
.map(r => [...r].reverse())
|
||||
).flat()
|
||||
},
|
||||
|
||||
up: {
|
||||
getMatrix: () => getNodesMatrixWithIndices(
|
||||
matrixIdx,
|
||||
level + 1,
|
||||
currentSite,
|
||||
gameProgress
|
||||
),
|
||||
|
||||
filter: (ns: any[]) => ns
|
||||
.reverse()
|
||||
.flatMap(r => reorder(r, ColPrecedence(colIdx)))
|
||||
},
|
||||
|
||||
down: {
|
||||
getMatrix: () => getNodesMatrixWithIndices(
|
||||
matrixIdx,
|
||||
level - 1,
|
||||
currentSite,
|
||||
gameProgress
|
||||
),
|
||||
|
||||
filter: (ns: any[]) => ns
|
||||
.flatMap(r => reorder(r, ColPrecedence(colIdx)))
|
||||
}
|
||||
};
|
||||
|
||||
const {getMatrix, filter} = funcs[direction];
|
||||
|
||||
const chosen = filter(getMatrix()).find((e: any) => e);
|
||||
if (chosen) return {...chosen, didMove: true};
|
||||
}
|
||||
|
||||
export function findNode(...args: [
|
||||
string,
|
||||
NodeMatrixIndices,
|
||||
number,
|
||||
string,
|
||||
any
|
||||
])
|
||||
: any | undefined
|
||||
{
|
||||
return (
|
||||
findNode_current(...args) ??
|
||||
findNode_next(...args)
|
||||
);
|
||||
}
|
73
src/store.ts
73
src/store.ts
|
@ -5,6 +5,7 @@ import authorize_user_letters from "./resources/authorize_user_letters.json";
|
|||
import game_progress from "./resources/initial_progress.json";
|
||||
import { HUDType } from "./components/MainScene/SyncedComponents/HUD";
|
||||
import { NodeDataType } from "./components/MainScene/SyncedComponents/Site";
|
||||
import { useCallback } from "react";
|
||||
|
||||
type SiteSaveState = {
|
||||
a: {
|
||||
|
@ -271,12 +272,17 @@ export const useStore = create(
|
|||
|
||||
// site setters
|
||||
setActiveSite: (to: "a" | "b") => set(() => ({ activeSite: to })),
|
||||
setSiteRot: (to: number[]) => set(() => ({ siteRot: to })),
|
||||
setSiteRotY: (to: number) =>
|
||||
set((prev) => {
|
||||
const nextRot = [...prev.siteRot];
|
||||
nextRot[1] = to;
|
||||
return { siteRot: nextRot };
|
||||
}),
|
||||
setSiteRotX: (to: number) =>
|
||||
set((prev) => {
|
||||
const nextPos = [...prev.siteRot];
|
||||
nextPos[0] = to;
|
||||
return { siteRot: nextPos };
|
||||
const nextRot = [...prev.siteRot];
|
||||
nextRot[0] = to;
|
||||
return { siteRot: nextRot };
|
||||
}),
|
||||
|
||||
// level setters
|
||||
|
@ -308,28 +314,27 @@ export const useStore = create(
|
|||
leftSideIdx: to,
|
||||
},
|
||||
})),
|
||||
setMediaRightComponentMatrixIdx: (to: 0 | 1 | 2) =>
|
||||
updateRightSide: (matrixIdx: 0 | 1 | 2, wordPosIdx: number) =>
|
||||
set((state) => ({
|
||||
mediaComponentMatrixIndices: {
|
||||
...state.mediaComponentMatrixIndices,
|
||||
rightSideIdx: to,
|
||||
rightSideIdx: matrixIdx,
|
||||
},
|
||||
mediaWordPosStateIdx: wordPosIdx,
|
||||
})),
|
||||
resetMediaComponentMatrixIndices: () =>
|
||||
setPercentageElapsed: (to: number) =>
|
||||
set(() => ({ mediaPercentageElapsed: to })),
|
||||
setAudioAnalyser: (to: THREE.AudioAnalyser) =>
|
||||
set(() => ({ audioAnalyser: to })),
|
||||
resetMediaScene: () =>
|
||||
set(() => ({
|
||||
mediaWordPosStateIdx: 1,
|
||||
mediaComponentMatrixIndices: {
|
||||
sideIdx: 0,
|
||||
leftSideIdx: 0,
|
||||
rightSideIdx: 0,
|
||||
},
|
||||
})),
|
||||
setPercentageElapsed: (to: number) =>
|
||||
set(() => ({ mediaPercentageElapsed: to })),
|
||||
setAudioAnalyser: (to: THREE.AudioAnalyser) =>
|
||||
set(() => ({ audioAnalyser: to })),
|
||||
setMediaWordPosStateIdx: (to: number) =>
|
||||
set(() => ({ mediaWordPosStateIdx: to })),
|
||||
resetMediaWordPosStateIdx: () => set(() => ({ mediaWordPosStateIdx: 1 })),
|
||||
|
||||
// idle media setters
|
||||
setIdleMedia: (to: any) => set(() => ({ idleMedia: to })),
|
||||
|
@ -414,4 +419,42 @@ export const useSiteSaveStore = create(
|
|||
)
|
||||
);
|
||||
|
||||
export const getMainSceneContext = () => useStore.getState().activeNode;
|
||||
export const getMainSceneContext = () => {
|
||||
const state = useStore.getState();
|
||||
|
||||
return {
|
||||
subscene: state.mainSubscene,
|
||||
selectedLevel: state.selectedLevel,
|
||||
pauseMatrixIdx: state.pauseComponentMatrixIdx,
|
||||
activePauseComponent:
|
||||
state.pauseComponentMatrix[state.pauseComponentMatrixIdx],
|
||||
gameProgress: state.gameProgress,
|
||||
currentSite: state.activeSite,
|
||||
siteRotY: state.siteRot[1],
|
||||
activeNode: state.activeNode,
|
||||
level: parseInt(state.activeLevel),
|
||||
};
|
||||
};
|
||||
|
||||
export const getSSknSceneContext = () => {
|
||||
const state = useStore.getState();
|
||||
return {
|
||||
activeSSknComponent:
|
||||
state.ssknComponentMatrix[state.ssknComponentMatrixIdx],
|
||||
};
|
||||
};
|
||||
|
||||
export const getMediaSceneContext = () => {
|
||||
const state = useStore.getState();
|
||||
|
||||
return {
|
||||
activeMediaComponent:
|
||||
state.mediaComponentMatrix[state.mediaComponentMatrixIndices.sideIdx][
|
||||
state.mediaComponentMatrixIndices.sideIdx === 0
|
||||
? state.mediaComponentMatrixIndices.leftSideIdx
|
||||
: state.mediaComponentMatrixIndices.rightSideIdx
|
||||
],
|
||||
rightSideComponentIdx: state.mediaComponentMatrixIndices.rightSideIdx,
|
||||
wordPosStateIdx: state.mediaWordPosStateIdx,
|
||||
};
|
||||
};
|
||||
|
|
84
src/utils/getIdleMedia.ts
Normal file
84
src/utils/getIdleMedia.ts
Normal file
|
@ -0,0 +1,84 @@
|
|||
import site_a from "../resources/site_a.json";
|
||||
import site_b from "../resources/site_b.json";
|
||||
import { SiteType } from "../components/MainScene/SyncedComponents/Site";
|
||||
import { useStore } from "../store";
|
||||
|
||||
const getIdleMedia = (site: string) => {
|
||||
const siteAIdleNodes = {
|
||||
audio: [
|
||||
"0000",
|
||||
"0001",
|
||||
"0002",
|
||||
"0003",
|
||||
"0004",
|
||||
"0005",
|
||||
"0006",
|
||||
"0007",
|
||||
"0008",
|
||||
"0009",
|
||||
],
|
||||
video: [
|
||||
"INS01.STR",
|
||||
"INS02.STR",
|
||||
"INS03.STR",
|
||||
"INS04.STR",
|
||||
"INS05.STR",
|
||||
"INS06.STR",
|
||||
"INS07.STR",
|
||||
"INS08.STR",
|
||||
"INS09.STR",
|
||||
"INS10.STR",
|
||||
"INS11.STR",
|
||||
"INS12.STR",
|
||||
"INS13.STR",
|
||||
"INS14.STR",
|
||||
"INS15.STR",
|
||||
"INS16.STR",
|
||||
"INS17.STR",
|
||||
"INS18.STR",
|
||||
"INS19.STR",
|
||||
"INS20.STR",
|
||||
"INS21.STR",
|
||||
"INS22.STR",
|
||||
],
|
||||
};
|
||||
|
||||
const siteBIdleNodes = {
|
||||
audio: ["1015", "1219", "0419", "0500", "0501", "0508", "0510", "0513"],
|
||||
video: [
|
||||
"INS16.STR",
|
||||
"INS17.STR",
|
||||
"INS18.STR",
|
||||
"INS19.STR",
|
||||
"INS20.STR",
|
||||
"INS21.STR",
|
||||
"INS22.STR",
|
||||
],
|
||||
};
|
||||
|
||||
const siteData = site === "a" ? site_a : site_b;
|
||||
const idleNodes = site === "a" ? siteAIdleNodes : siteBIdleNodes;
|
||||
|
||||
if (Math.random() < 0.5) {
|
||||
const nodeToPlay =
|
||||
idleNodes.audio[Math.floor(Math.random() * idleNodes.audio.length)];
|
||||
|
||||
const level = nodeToPlay.substr(0, 2);
|
||||
|
||||
const images = (siteData as SiteType)[level][nodeToPlay]
|
||||
.image_table_indices;
|
||||
const media = (siteData as SiteType)[level][nodeToPlay].media_file;
|
||||
|
||||
useStore.setState({
|
||||
idleImages: images,
|
||||
idleMedia: media,
|
||||
});
|
||||
} else {
|
||||
useStore.setState({
|
||||
idleMedia:
|
||||
idleNodes.video[Math.floor(Math.random() * idleNodes.video.length)],
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default getIdleMedia;
|
306
src/utils/nodeUtils.ts
Normal file
306
src/utils/nodeUtils.ts
Normal file
|
@ -0,0 +1,306 @@
|
|||
import {
|
||||
NodeDataType,
|
||||
SiteType,
|
||||
} from "../components/MainScene/SyncedComponents/Site";
|
||||
import node_matrices from "../resources/node_matrices.json";
|
||||
import game_progress from "../resources/initial_progress.json";
|
||||
import unlocked_nodes from "../resources/initial_progress.json";
|
||||
import node_huds from "../resources/node_huds.json";
|
||||
import site_a from "../resources/site_a.json";
|
||||
import site_b from "../resources/site_b.json";
|
||||
|
||||
export const generateInactiveNodes = (
|
||||
visibleNodes: SiteType,
|
||||
activeLevel: string
|
||||
) => {
|
||||
const obj = {};
|
||||
const activeLevelNr = parseInt(activeLevel);
|
||||
const visibleLevels = [
|
||||
(activeLevelNr - 2).toString().padStart(2, "0"),
|
||||
(activeLevelNr - 1).toString().padStart(2, "0"),
|
||||
(activeLevelNr + 1).toString().padStart(2, "0"),
|
||||
(activeLevelNr + 2).toString().padStart(2, "0"),
|
||||
];
|
||||
|
||||
visibleLevels.forEach((level) => {
|
||||
Object.assign(obj, visibleNodes[level as keyof typeof visibleNodes]);
|
||||
});
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
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 getNodeHud = (nodeMatrixIndices: {
|
||||
matrixIdx: number;
|
||||
rowIdx: number;
|
||||
colIdx: number;
|
||||
}) => {
|
||||
const hudAssocs = {
|
||||
"00": "fg_hud_1",
|
||||
"10": "fg_hud_2",
|
||||
"20": "fg_hud_3",
|
||||
"01": "bg_hud_1",
|
||||
"11": "bg_hud_2",
|
||||
"21": "bg_hud_3",
|
||||
"02": "bg_hud_4",
|
||||
"12": "bg_hud_5",
|
||||
"22": "bg_hud_6",
|
||||
"03": "fg_hud_4",
|
||||
"13": "fg_hud_5",
|
||||
"23": "fg_hud_6",
|
||||
};
|
||||
|
||||
return node_huds[
|
||||
hudAssocs[
|
||||
`${nodeMatrixIndices.rowIdx}${nodeMatrixIndices.colIdx}` as keyof typeof hudAssocs
|
||||
] as keyof typeof node_huds
|
||||
];
|
||||
};
|
||||
export const isNodeVisible = (
|
||||
node: NodeDataType,
|
||||
gameProgress: typeof unlocked_nodes
|
||||
) => {
|
||||
if (node) {
|
||||
const unlockedBy = node.unlocked_by;
|
||||
|
||||
let unlocked;
|
||||
if (unlockedBy === "") unlocked = true;
|
||||
else
|
||||
unlocked =
|
||||
gameProgress[unlockedBy as keyof typeof gameProgress].is_viewed;
|
||||
|
||||
// visible = (global_final_viewcount > 0) && (req_final_viewcount <= global_final_viewcount + 1)
|
||||
|
||||
return (
|
||||
unlocked &&
|
||||
gameProgress[node.node_name as keyof typeof gameProgress].is_visible
|
||||
);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
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;
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
function reorder<T>(array: T[], order: number[]): T[] {
|
||||
return order.map((i) => array[i]);
|
||||
}
|
||||
|
||||
function transpose<T>(matrix: T[][]): T[][] {
|
||||
return Object.keys(matrix[0])
|
||||
.map(Number)
|
||||
.map((c: number) => matrix.map((r: T[]) => r[c]));
|
||||
}
|
||||
|
||||
function RowPrecedence(rowIdx: number): number[] {
|
||||
switch (rowIdx) {
|
||||
default:
|
||||
case 0:
|
||||
return [0, 1, 2];
|
||||
case 1:
|
||||
return [1, 0, 2];
|
||||
case 2:
|
||||
return [2, 1, 0];
|
||||
}
|
||||
}
|
||||
|
||||
function ColPrecedence(colIdx: number): number[] {
|
||||
switch (colIdx) {
|
||||
default:
|
||||
case 0:
|
||||
return [0, 1, 2, 3];
|
||||
case 1:
|
||||
return [1, 0, 2, 3];
|
||||
case 2:
|
||||
return [2, 1, 3, 0];
|
||||
case 3:
|
||||
return [3, 2, 1, 0];
|
||||
}
|
||||
}
|
||||
|
||||
function getNodesMatrixWithIndices(
|
||||
matrixIdx: number,
|
||||
activeLevel: number,
|
||||
currentSite: string,
|
||||
gameProgress: any
|
||||
): any[][] {
|
||||
return getVisibleNodesMatrix(
|
||||
matrixIdx,
|
||||
activeLevel,
|
||||
currentSite,
|
||||
gameProgress
|
||||
).map((r, i) =>
|
||||
r.map((n, j) =>
|
||||
n
|
||||
? {
|
||||
node: n,
|
||||
matrixIndices: {
|
||||
matrixIdx,
|
||||
rowIdx: i,
|
||||
colIdx: j,
|
||||
},
|
||||
}
|
||||
: null
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
interface NodeMatrixIndices {
|
||||
matrixIdx: number;
|
||||
rowIdx: number;
|
||||
colIdx: number;
|
||||
}
|
||||
|
||||
function findNode_current(
|
||||
direction: string,
|
||||
{ matrixIdx, rowIdx, colIdx }: NodeMatrixIndices,
|
||||
level: number,
|
||||
currentSite: string,
|
||||
gameProgress: any
|
||||
): any | undefined {
|
||||
const nodes = getNodesMatrixWithIndices(
|
||||
matrixIdx,
|
||||
level,
|
||||
currentSite,
|
||||
gameProgress
|
||||
);
|
||||
|
||||
const filters: any = {
|
||||
left: () =>
|
||||
transpose(
|
||||
reorder(nodes, RowPrecedence(rowIdx)).map((r) =>
|
||||
r.slice(0, colIdx).reverse()
|
||||
)
|
||||
).flat(),
|
||||
|
||||
right: () =>
|
||||
transpose(
|
||||
reorder(nodes, RowPrecedence(rowIdx)).map((r) => r.slice(colIdx + 1))
|
||||
).flat(),
|
||||
|
||||
up: () =>
|
||||
nodes
|
||||
.slice(0, rowIdx)
|
||||
.reverse()
|
||||
.flatMap((r) => reorder(r, ColPrecedence(colIdx))),
|
||||
|
||||
down: () =>
|
||||
nodes.slice(rowIdx + 1).flatMap((r) => reorder(r, ColPrecedence(colIdx))),
|
||||
};
|
||||
|
||||
const chosen = filters[direction]().find((e: any) => e);
|
||||
if (chosen) return { ...chosen, didMove: false };
|
||||
}
|
||||
|
||||
function findNode_next(
|
||||
direction: string,
|
||||
{ matrixIdx, rowIdx, colIdx }: NodeMatrixIndices,
|
||||
level: number,
|
||||
currentSite: string,
|
||||
gameProgress: any
|
||||
): any | undefined {
|
||||
const funcs: any = {
|
||||
left: {
|
||||
getMatrix: () =>
|
||||
getNodesMatrixWithIndices(
|
||||
matrixIdx + 1 > 8 ? 1 : matrixIdx + 1,
|
||||
level,
|
||||
currentSite,
|
||||
gameProgress
|
||||
),
|
||||
|
||||
filter: (ns: any[]) =>
|
||||
transpose(reorder(ns, RowPrecedence(rowIdx))).flat(),
|
||||
},
|
||||
|
||||
right: {
|
||||
getMatrix: () =>
|
||||
getNodesMatrixWithIndices(
|
||||
matrixIdx - 1 < 1 ? 8 : matrixIdx - 1,
|
||||
level,
|
||||
currentSite,
|
||||
gameProgress
|
||||
),
|
||||
|
||||
filter: (ns: any[]) =>
|
||||
transpose(
|
||||
reorder(ns, RowPrecedence(rowIdx)).map((r) => [...r].reverse())
|
||||
).flat(),
|
||||
},
|
||||
|
||||
up: {
|
||||
getMatrix: () =>
|
||||
getNodesMatrixWithIndices(
|
||||
matrixIdx,
|
||||
level + 1,
|
||||
currentSite,
|
||||
gameProgress
|
||||
),
|
||||
|
||||
filter: (ns: any[]) =>
|
||||
ns.reverse().flatMap((r) => reorder(r, ColPrecedence(colIdx))),
|
||||
},
|
||||
|
||||
down: {
|
||||
getMatrix: () =>
|
||||
getNodesMatrixWithIndices(
|
||||
matrixIdx,
|
||||
level - 1,
|
||||
currentSite,
|
||||
gameProgress
|
||||
),
|
||||
|
||||
filter: (ns: any[]) =>
|
||||
ns.flatMap((r) => reorder(r, ColPrecedence(colIdx))),
|
||||
},
|
||||
};
|
||||
|
||||
const { getMatrix, filter } = funcs[direction];
|
||||
|
||||
const chosen = filter(getMatrix()).find((e: any) => e);
|
||||
if (chosen) return { ...chosen, didMove: true };
|
||||
}
|
||||
|
||||
export function findNode(
|
||||
...args: [string, NodeMatrixIndices, number, string, any]
|
||||
): any | undefined {
|
||||
return findNode_current(...args) ?? findNode_next(...args);
|
||||
}
|
||||
|
||||
export const filterInvisibleNodes = (
|
||||
siteData: SiteType,
|
||||
gameProgress: typeof game_progress
|
||||
) => {
|
||||
const visibleNodes: SiteType = {};
|
||||
Object.entries(siteData).forEach((level) => {
|
||||
visibleNodes[level[0]] = {};
|
||||
Object.entries(level[1]).forEach((node) => {
|
||||
if (isNodeVisible(node[1], gameProgress)) {
|
||||
visibleNodes[level[0]][node[0]] = node[1];
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return visibleNodes;
|
||||
};
|
Loading…
Reference in a new issue