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 longHud from "../../../static/sprite/long_hud.png";
|
||||||
import boringHud from "../../../static/sprite/long_hud_boring.png";
|
import boringHud from "../../../static/sprite/long_hud_boring.png";
|
||||||
import { useStore } from "../../../store";
|
import { useStore } from "../../../store";
|
||||||
import { getNodeHud } from "../../../core/nodeSelector";
|
import lerp from "../../../utils/lerp";
|
||||||
import lerp from "../../../core/utils/lerp";
|
|
||||||
import GreenTextRenderer from "../../TextRenderer/GreenTextRenderer";
|
import GreenTextRenderer from "../../TextRenderer/GreenTextRenderer";
|
||||||
import usePrevious from "../../../hooks/usePrevious";
|
import usePrevious from "../../../hooks/usePrevious";
|
||||||
|
import {getNodeHud} from "../../../utils/nodeUtils";
|
||||||
|
|
||||||
export type HUDType = {
|
export type HUDType = {
|
||||||
mirrored: number;
|
mirrored: number;
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { a, useSpring } from "@react-spring/three";
|
||||||
import { useStore } from "../../../store";
|
import { useStore } from "../../../store";
|
||||||
import MiddleRingPart from "./MiddleRing/MiddleRingPart";
|
import MiddleRingPart from "./MiddleRing/MiddleRingPart";
|
||||||
import usePrevious from "../../../hooks/usePrevious";
|
import usePrevious from "../../../hooks/usePrevious";
|
||||||
import lerp from "../../../core/utils/lerp";
|
import lerp from "../../../utils/lerp";
|
||||||
|
|
||||||
const MiddleRing = () => {
|
const MiddleRing = () => {
|
||||||
const middleRingTex = useLoader(THREE.TextureLoader, middleRingTexture);
|
const middleRingTex = useLoader(THREE.TextureLoader, middleRingTexture);
|
||||||
|
|
|
@ -7,11 +7,11 @@ import NodeAnimations from "./Site/NodeAnimations";
|
||||||
import InactiveLevelNodes from "./Site/InactiveLevelNodes";
|
import InactiveLevelNodes from "./Site/InactiveLevelNodes";
|
||||||
import { useFrame } from "react-three-fiber";
|
import { useFrame } from "react-three-fiber";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import filterInvisibleNodes from "../../../core/utils/filterInvisibleNodes";
|
|
||||||
import site_a from "../../../resources/site_a.json";
|
import site_a from "../../../resources/site_a.json";
|
||||||
import site_b from "../../../resources/site_b.json";
|
import site_b from "../../../resources/site_b.json";
|
||||||
import level_y_values from "../../../resources/level_y_values.json";
|
import level_y_values from "../../../resources/level_y_values.json";
|
||||||
import usePrevious from "../../../hooks/usePrevious";
|
import usePrevious from "../../../hooks/usePrevious";
|
||||||
|
import { filterInvisibleNodes } from "../../../utils/nodeUtils";
|
||||||
|
|
||||||
export type NodeDataType = {
|
export type NodeDataType = {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
|
@ -2,11 +2,11 @@ import React, { memo, useEffect, useState } from "react";
|
||||||
import Node from "./Node";
|
import Node from "./Node";
|
||||||
import node_positions from "../../../../resources/node_positions.json";
|
import node_positions from "../../../../resources/node_positions.json";
|
||||||
import { useStore } from "../../../../store";
|
import { useStore } from "../../../../store";
|
||||||
import { isNodeVisible } from "../../../../core/nodeSelector";
|
|
||||||
import site_a from "../../../../resources/site_a.json";
|
import site_a from "../../../../resources/site_a.json";
|
||||||
import site_b from "../../../../resources/site_b.json";
|
import site_b from "../../../../resources/site_b.json";
|
||||||
import { NodeDataType, SiteType } from "../Site";
|
import { NodeDataType, SiteType } from "../Site";
|
||||||
import usePrevious from "../../../../hooks/usePrevious";
|
import usePrevious from "../../../../hooks/usePrevious";
|
||||||
|
import {isNodeVisible} from "../../../../utils/nodeUtils";
|
||||||
|
|
||||||
type ActiveLevelNodesProps = {
|
type ActiveLevelNodesProps = {
|
||||||
visibleNodes: SiteType;
|
visibleNodes: SiteType;
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useStore } from "../../../../store";
|
||||||
import { SiteType } from "../Site";
|
import { SiteType } from "../Site";
|
||||||
import InactiveLevelNode from "./InactiveLevelNode";
|
import InactiveLevelNode from "./InactiveLevelNode";
|
||||||
import usePrevious from "../../../../hooks/usePrevious";
|
import usePrevious from "../../../../hooks/usePrevious";
|
||||||
import { generateInactiveNodes } from "../../../../core/utils/nodeUtils";
|
import { generateInactiveNodes } from "../../../../utils/nodeUtils";
|
||||||
|
|
||||||
type ActiveLevelNodesProps = {
|
type ActiveLevelNodesProps = {
|
||||||
visibleNodes: SiteType;
|
visibleNodes: SiteType;
|
||||||
|
|
|
@ -2,8 +2,8 @@ import React, { useEffect, useState } from "react";
|
||||||
import { useStore } from "../../store";
|
import { useStore } from "../../store";
|
||||||
import { a, useTrail } from "@react-spring/three";
|
import { a, useTrail } from "@react-spring/three";
|
||||||
import BigLetter from "./BigLetter";
|
import BigLetter from "./BigLetter";
|
||||||
import { getNodeHud } from "../../core/nodeSelector";
|
|
||||||
import usePrevious from "../../hooks/usePrevious";
|
import usePrevious from "../../hooks/usePrevious";
|
||||||
|
import {getNodeHud} from "../../utils/nodeUtils";
|
||||||
|
|
||||||
const YellowTextRenderer = (props: { visible?: boolean }) => {
|
const YellowTextRenderer = (props: { visible?: boolean }) => {
|
||||||
const activeNode = useStore((state) => state.activeNode);
|
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 React, { useCallback, useEffect, useState } from "react";
|
||||||
import { getKeyCodeAssociation } from "../utils/keyPressUtils";
|
import { getKeyCodeAssociation } from "../../utils/keyPressUtils";
|
||||||
import SceneManager from "./GameManagers/SceneManager";
|
|
||||||
|
|
||||||
const GateSceneManager = () => {
|
const GateSceneManager = () => {
|
||||||
const [eventState, setEventState] = useState<any>();
|
const [eventState, setEventState] = useState<any>();
|
||||||
|
|
|
@ -1,44 +1,39 @@
|
||||||
import React, { useCallback, useEffect, useRef, useState } from "react";
|
import React, { useCallback, useEffect, useMemo, useRef } from "react";
|
||||||
import { useStore } from "../../store";
|
import { getMainSceneContext, useStore } from "../../store";
|
||||||
import handleMainSceneEvent from "../mainSceneEventHandler";
|
import handleMainSceneEvent from "../mainSceneEventHandler";
|
||||||
import { getKeyCodeAssociation } from "../utils/keyPressUtils";
|
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 { useFrame } from "react-three-fiber";
|
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 = {
|
type MainSceneEventManagerProps = {
|
||||||
loaded: boolean;
|
loaded: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const MainSceneEventManager = (props: MainSceneEventManagerProps) => {
|
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 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 timePassedSinceLastKeyPress = useRef(-1);
|
||||||
|
|
||||||
const [eventState, setEventState] = useState<any>();
|
const mainSceneSetters = useMemo(
|
||||||
|
() => [
|
||||||
|
levelSelectionManager,
|
||||||
|
nodeManager,
|
||||||
|
levelManager,
|
||||||
|
lainManager,
|
||||||
|
siteManager,
|
||||||
|
pauseManager,
|
||||||
|
mainSubsceneManager,
|
||||||
|
sceneManager,
|
||||||
|
],
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
useFrame(() => {
|
useFrame(() => {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
|
@ -76,7 +71,7 @@ const MainSceneEventManager = (props: MainSceneEventManagerProps) => {
|
||||||
];
|
];
|
||||||
|
|
||||||
const event = moves[Math.floor(Math.random() * moves.length)];
|
const event = moves[Math.floor(Math.random() * moves.length)];
|
||||||
setEventState({ event: event });
|
// setEventState({ event: event });
|
||||||
timePassedSinceLastKeyPress.current = now - 2500;
|
timePassedSinceLastKeyPress.current = now - 2500;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,36 +85,13 @@ const MainSceneEventManager = (props: MainSceneEventManagerProps) => {
|
||||||
|
|
||||||
if (keyPress && props.loaded) {
|
if (keyPress && props.loaded) {
|
||||||
timePassedSinceLastKeyPress.current = Date.now() + 2500;
|
timePassedSinceLastKeyPress.current = Date.now() + 2500;
|
||||||
const event = handleMainSceneEvent({
|
const ctx = { ...getMainSceneContext(), keyPress: keyPress };
|
||||||
mainSubscene: mainSubscene,
|
|
||||||
keyPress: keyPress,
|
|
||||||
siteRotY: siteRotY,
|
|
||||||
activeNodeId: activeNodeId,
|
|
||||||
nodeMatrixIndices: nodeMatrixIndices,
|
|
||||||
activeLevel: activeLevel,
|
|
||||||
selectedLevel: selectedLevel,
|
|
||||||
pauseMatrixIdx: pauseMatrixIdx,
|
|
||||||
activePauseComponent: activePauseComponent,
|
|
||||||
gameProgress: gameProgress,
|
|
||||||
currentSite: currentSite,
|
|
||||||
});
|
|
||||||
|
|
||||||
setEventState(event);
|
const event = handleMainSceneEvent(ctx);
|
||||||
|
mainSceneSetters.forEach((fn) => fn(event));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[
|
[mainSceneSetters, props.loaded]
|
||||||
props.loaded,
|
|
||||||
mainSubscene,
|
|
||||||
siteRotY,
|
|
||||||
activeNodeId,
|
|
||||||
nodeMatrixIndices,
|
|
||||||
activeLevel,
|
|
||||||
selectedLevel,
|
|
||||||
pauseMatrixIdx,
|
|
||||||
activePauseComponent,
|
|
||||||
gameProgress,
|
|
||||||
currentSite,
|
|
||||||
]
|
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -130,21 +102,7 @@ const MainSceneEventManager = (props: MainSceneEventManagerProps) => {
|
||||||
};
|
};
|
||||||
}, [handleKeyPress]);
|
}, [handleKeyPress]);
|
||||||
|
|
||||||
return (
|
return null;
|
||||||
<>
|
|
||||||
<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!} />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MainSceneEventManager;
|
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 React, { useCallback, useEffect, useMemo } from "react";
|
||||||
import { useStore } from "../../store";
|
import { getMediaSceneContext } from "../../store";
|
||||||
import { getKeyCodeAssociation } from "../utils/keyPressUtils";
|
import { getKeyCodeAssociation } from "../../utils/keyPressUtils";
|
||||||
import SceneManager from "./GameManagers/SceneManager";
|
import mediaManager from "../setters/media/mediaManager";
|
||||||
import handleMediaSceneEvent from "../mediaSceneEventHandler";
|
import handleMediaSceneEvent from "../mediaSceneEventHandler";
|
||||||
import MediaComponentManager from "./MediaSceneManagers/MediaComponentManager";
|
import sceneManager from "../setters/sceneManager";
|
||||||
|
|
||||||
const MediaSceneEventManager = () => {
|
const MediaSceneEventManager = () => {
|
||||||
// all the possible context needed to calculate new state
|
const mediaSceneSetters = useMemo(() => [mediaManager, sceneManager], []);
|
||||||
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 handleKeyPress = useCallback(
|
const handleKeyPress = useCallback(
|
||||||
(event) => {
|
(event) => {
|
||||||
|
@ -36,17 +15,14 @@ const MediaSceneEventManager = () => {
|
||||||
const keyPress = getKeyCodeAssociation(keyCode);
|
const keyPress = getKeyCodeAssociation(keyCode);
|
||||||
|
|
||||||
if (keyPress) {
|
if (keyPress) {
|
||||||
const event = handleMediaSceneEvent({
|
const ctx = { ...getMediaSceneContext(), keyPress: keyPress };
|
||||||
keyPress: keyPress,
|
|
||||||
activeMediaComponent: activeMediaComponent,
|
|
||||||
wordPosStateIdx: wordPosStateIdx,
|
|
||||||
rightSideComponentIdx: rightSideComponentIdx,
|
|
||||||
});
|
|
||||||
|
|
||||||
setEventState(event);
|
const event = handleMediaSceneEvent(ctx);
|
||||||
|
|
||||||
|
mediaSceneSetters.forEach((fn) => fn(event));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[activeMediaComponent, rightSideComponentIdx, wordPosStateIdx]
|
[mediaSceneSetters]
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -57,12 +33,7 @@ const MediaSceneEventManager = () => {
|
||||||
};
|
};
|
||||||
}, [handleKeyPress]);
|
}, [handleKeyPress]);
|
||||||
|
|
||||||
return (
|
return null;
|
||||||
<>
|
|
||||||
<MediaComponentManager eventState={eventState!} />
|
|
||||||
<SceneManager eventState={eventState!} />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MediaSceneEventManager;
|
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 React, { useCallback, useEffect, useMemo } from "react";
|
||||||
import { getKeyCodeAssociation } from "../utils/keyPressUtils";
|
import { getKeyCodeAssociation } from "../../utils/keyPressUtils";
|
||||||
import SceneManager from "./GameManagers/SceneManager";
|
|
||||||
import handleSSknSceneEvent from "../ssknSceneEventHandler";
|
import handleSSknSceneEvent from "../ssknSceneEventHandler";
|
||||||
import { useStore } from "../../store";
|
import { getSSknSceneContext } from "../../store";
|
||||||
import SSknComponentManager from "./SSknSceneManagers/SSknComponentManager";
|
import ssknManager from "../setters/sskn/ssknManager";
|
||||||
|
import sceneManager from "../setters/sceneManager";
|
||||||
|
|
||||||
const SSknSceneManager = () => {
|
const SSknSceneManager = () => {
|
||||||
// all the possible context needed to calculate new state
|
const ssknSceneSetters = useMemo(() => [ssknManager, sceneManager], []);
|
||||||
const activeSSknComponent = useStore(
|
|
||||||
useCallback(
|
|
||||||
(state) => state.ssknComponentMatrix[state.ssknComponentMatrixIdx],
|
|
||||||
[]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
const [eventState, setEventState] = useState<any>();
|
|
||||||
|
|
||||||
const handleKeyPress = useCallback(
|
const handleKeyPress = useCallback(
|
||||||
(event) => {
|
(event) => {
|
||||||
|
@ -23,15 +15,14 @@ const SSknSceneManager = () => {
|
||||||
const keyPress = getKeyCodeAssociation(keyCode);
|
const keyPress = getKeyCodeAssociation(keyCode);
|
||||||
|
|
||||||
if (keyPress) {
|
if (keyPress) {
|
||||||
const event = handleSSknSceneEvent({
|
const ctx = { ...getSSknSceneContext(), keyPress: keyPress };
|
||||||
keyPress: keyPress,
|
|
||||||
activeSSknComponent: activeSSknComponent,
|
|
||||||
});
|
|
||||||
|
|
||||||
setEventState(event);
|
const event = handleSSknSceneEvent(ctx);
|
||||||
|
|
||||||
|
ssknSceneSetters.forEach((fn) => fn(event));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[activeSSknComponent]
|
[ssknSceneSetters]
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -42,12 +33,7 @@ const SSknSceneManager = () => {
|
||||||
};
|
};
|
||||||
}, [handleKeyPress]);
|
}, [handleKeyPress]);
|
||||||
|
|
||||||
return (
|
return null;
|
||||||
<>
|
|
||||||
<SceneManager eventState={eventState!} />
|
|
||||||
<SSknComponentManager eventState={eventState!} />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SSknSceneManager;
|
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, getNodeById} from "../utils/nodeUtils";
|
||||||
import { findNode } from "./utils/nodeUtils";
|
|
||||||
|
|
||||||
const handleMainSceneEvent = (gameContext: any) => {
|
const handleMainSceneEvent = (mainSceneContext: any) => {
|
||||||
let event;
|
const {
|
||||||
|
subscene,
|
||||||
|
selectedLevel,
|
||||||
|
pauseMatrixIdx,
|
||||||
|
activePauseComponent,
|
||||||
|
gameProgress,
|
||||||
|
currentSite,
|
||||||
|
siteRotY,
|
||||||
|
activeNode,
|
||||||
|
level,
|
||||||
|
keyPress,
|
||||||
|
} = mainSceneContext;
|
||||||
|
|
||||||
const keyPress = gameContext.keyPress;
|
switch (subscene) {
|
||||||
const subscene = gameContext.mainSubscene;
|
case "site":
|
||||||
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 (keyPress) {
|
switch (keyPress) {
|
||||||
case "LEFT":
|
case "LEFT":
|
||||||
case "RIGHT":
|
case "RIGHT": {
|
||||||
const keyPressToLower = keyPress.toLowerCase();
|
const keyPressToLower = keyPress.toLowerCase();
|
||||||
|
|
||||||
const nodeData = findNode.apply(null, [
|
const nodeData = findNode(
|
||||||
keyPressToLower,
|
keyPressToLower,
|
||||||
nodeMatrixIndices,
|
activeNode.matrixIndices!,
|
||||||
level,
|
level,
|
||||||
currentSite,
|
currentSite,
|
||||||
gameProgress
|
gameProgress
|
||||||
]);
|
);
|
||||||
|
|
||||||
if (nodeData) {
|
if (!nodeData) return;
|
||||||
|
|
||||||
|
if (nodeData.didMove) {
|
||||||
return {
|
return {
|
||||||
event: nodeData.didMove
|
event: keyPressToLower === "left" ? `site_left` : "site_right",
|
||||||
? `site_${keyPressToLower}`
|
|
||||||
: "change_node",
|
|
||||||
siteRotY:
|
siteRotY:
|
||||||
keyPressToLower === "left"
|
keyPressToLower === "left"
|
||||||
? siteRotY + Math.PI / 4
|
? siteRotY + Math.PI / 4
|
||||||
: siteRotY - Math.PI / 4,
|
: siteRotY - Math.PI / 4,
|
||||||
|
node: {
|
||||||
|
...getNodeById(nodeData.node, currentSite),
|
||||||
|
matrixIndices: nodeData.matrixIndices,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return {
|
||||||
|
event: "change_node",
|
||||||
nodeMatrixIndices: nodeData.matrixIndices,
|
nodeMatrixIndices: nodeData.matrixIndices,
|
||||||
node: getNodeById(nodeData.node, currentSite),
|
node: {
|
||||||
|
...getNodeById(nodeData.node, currentSite),
|
||||||
|
matrixIndices: nodeData.matrixIndices,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case "UP":
|
case "UP":
|
||||||
case "DOWN":
|
case "DOWN": {
|
||||||
const keyp = keyPress.toLowerCase();
|
const keyPressToLower = keyPress.toLowerCase();
|
||||||
const t = findNode.apply(null, [
|
const nodeData = findNode(
|
||||||
keyp,
|
keyPressToLower,
|
||||||
nodeMatrixIndices,
|
activeNode.matrixIndices!,
|
||||||
level,
|
level,
|
||||||
currentSite,
|
currentSite,
|
||||||
gameProgress
|
gameProgress
|
||||||
]);
|
);
|
||||||
if (t) {
|
|
||||||
|
if (!nodeData) return;
|
||||||
|
|
||||||
|
if (nodeData.didMove) {
|
||||||
return {
|
return {
|
||||||
event: t.didMove ? `site_${keyp}` : "change_node",
|
event: keyPressToLower === "up" ? "site_up" : "site_down",
|
||||||
nodeMatrixIndices: t.matrixIndices,
|
level: (keyPressToLower === "up" ? level + 1 : level - 1)
|
||||||
level: (keyp === "up" ? level + 1 : level - 1)
|
|
||||||
.toString()
|
.toString()
|
||||||
.padStart(2, "0"),
|
.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":
|
case "CIRCLE":
|
||||||
activeNode = getNode(level, nodeMatrixIndices, currentSite);
|
const eventAnimation =
|
||||||
|
Math.random() < 0.4 ? "rip_node" : "throw_node";
|
||||||
|
|
||||||
const nodeType = activeNode.type;
|
const nodeType = activeNode.type;
|
||||||
|
|
||||||
const eventAnimation = Math.random() < 0.4 ? "rip_node" : "throw_node";
|
|
||||||
|
|
||||||
switch (nodeType) {
|
switch (nodeType) {
|
||||||
case 0:
|
case 0:
|
||||||
case 2:
|
case 2:
|
||||||
case 4:
|
case 4:
|
||||||
case 3:
|
case 3:
|
||||||
case 5:
|
case 5:
|
||||||
event = `${eventAnimation}_media`;
|
return {
|
||||||
scene = "media";
|
event: `${eventAnimation}_media`,
|
||||||
break;
|
scene: "media",
|
||||||
|
};
|
||||||
case 6:
|
case 6:
|
||||||
if (activeNode.node_name.substr(0, 3) === "TaK") {
|
if (activeNode.node_name.substr(0, 3) === "TaK") {
|
||||||
event = `${eventAnimation}_tak`;
|
return {
|
||||||
scene = "tak";
|
event: `${eventAnimation}_tak`,
|
||||||
|
scene: "tak",
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
event = `${eventAnimation}_media`;
|
return {
|
||||||
scene = "media";
|
event: `${eventAnimation}_media`,
|
||||||
|
scene: "media",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case 8:
|
case 8:
|
||||||
event = `${eventAnimation}_gate`;
|
return {
|
||||||
scene = "gate";
|
event: `${eventAnimation}_gate`,
|
||||||
break;
|
scene: "gate",
|
||||||
|
};
|
||||||
case 7:
|
case 7:
|
||||||
event = `${eventAnimation}_sskn`;
|
return {
|
||||||
scene = "sskn";
|
event: `${eventAnimation}_sskn`,
|
||||||
break;
|
scene: "sskn",
|
||||||
|
};
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "L2":
|
case "L2":
|
||||||
|
@ -114,18 +135,8 @@ const handleMainSceneEvent = (gameContext: any) => {
|
||||||
case "SPACE":
|
case "SPACE":
|
||||||
return { event: "play_with_hair", siteRotY: siteRotY };
|
return { event: "play_with_hair", siteRotY: siteRotY };
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
return {
|
case "level_selection":
|
||||||
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") {
|
|
||||||
switch (keyPress) {
|
switch (keyPress) {
|
||||||
case "UP":
|
case "UP":
|
||||||
if (currentSite === "a") {
|
if (currentSite === "a") {
|
||||||
|
@ -152,36 +163,36 @@ const handleMainSceneEvent = (gameContext: any) => {
|
||||||
case "X":
|
case "X":
|
||||||
return {
|
return {
|
||||||
event: "level_selection_back",
|
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;
|
case "CIRCLE":
|
||||||
if (selectedNodeData) {
|
if (level === selectedLevel) return;
|
||||||
|
|
||||||
|
const direction = selectedLevel > level ? "up" : "down";
|
||||||
|
|
||||||
|
const nodeData = findNode(
|
||||||
|
direction,
|
||||||
|
activeNode.matrixIndices!,
|
||||||
|
selectedLevel,
|
||||||
|
currentSite,
|
||||||
|
gameProgress
|
||||||
|
);
|
||||||
|
|
||||||
|
if (nodeData) {
|
||||||
const event =
|
const event =
|
||||||
selectedLevel < level ? "select_level_down" : "select_level_up";
|
selectedLevel < level ? "select_level_down" : "select_level_up";
|
||||||
return {
|
return {
|
||||||
event: event,
|
event: event,
|
||||||
nodeMatrixIndices: selectedNodeData.nodeMatrixIndices,
|
node: {
|
||||||
sitePosY: -selectedNodeData.sitePosY!,
|
...getNodeById(nodeData.node, currentSite),
|
||||||
|
matrixIndices: nodeData.matrixIndices,
|
||||||
|
},
|
||||||
level: selectedLevel.toString().padStart(2, "0"),
|
level: selectedLevel.toString().padStart(2, "0"),
|
||||||
node: selectedNodeData.node,
|
|
||||||
hud: selectedNodeData.activeHud,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (subscene === "pause") {
|
break;
|
||||||
|
case "pause":
|
||||||
switch (keyPress) {
|
switch (keyPress) {
|
||||||
case "UP":
|
case "UP":
|
||||||
if (pauseMatrixIdx - 1 < 0) break;
|
if (pauseMatrixIdx - 1 < 0) break;
|
||||||
|
@ -198,13 +209,6 @@ const handleMainSceneEvent = (gameContext: any) => {
|
||||||
case "CIRCLE":
|
case "CIRCLE":
|
||||||
return {
|
return {
|
||||||
event: `pause_${activePauseComponent}_select`,
|
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 handleMediaSceneEvent = (mediaSceneContext: any) => {
|
||||||
const keyPress = gameContext.keyPress;
|
const {
|
||||||
const activeMediaComponent = gameContext.activeMediaComponent;
|
keyPress,
|
||||||
|
activeMediaComponent,
|
||||||
const wordPosStateIdx = gameContext.wordPosStateIdx;
|
wordPosStateIdx,
|
||||||
const rightSideComponentIdx = gameContext.rightSideComponentIdx;
|
rightSideComponentIdx,
|
||||||
|
} = mediaSceneContext;
|
||||||
const rightSideComponents = ["fstWord", "sndWord", "thirdWord"];
|
|
||||||
|
|
||||||
const calculateNewRightSide = (
|
const calculateNewRightSide = (
|
||||||
direction: string,
|
direction: string,
|
||||||
|
@ -43,7 +42,7 @@ const handleMediaSceneEvent = (gameContext: any) => {
|
||||||
case "DOWN":
|
case "DOWN":
|
||||||
case "RIGHT":
|
case "RIGHT":
|
||||||
case "LEFT":
|
case "LEFT":
|
||||||
if (rightSideComponents.includes(activeMediaComponent)) {
|
if (["fstWord", "sndWord", "thirdWord"].includes(activeMediaComponent)) {
|
||||||
const rightSide = calculateNewRightSide(
|
const rightSide = calculateNewRightSide(
|
||||||
keyPress,
|
keyPress,
|
||||||
wordPosStateIdx,
|
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 handleSSknSceneEvent = (ssknSceneContext: any) => {
|
||||||
const keyPress = gameContext.keyPress;
|
const { keyPress, activeSSknComponent } = ssknSceneContext;
|
||||||
const activeSSknComponent = gameContext.activeSSknComponent;
|
|
||||||
switch (keyPress) {
|
switch (keyPress) {
|
||||||
case "UP":
|
case "UP":
|
||||||
case "DOWN":
|
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 game_progress from "./resources/initial_progress.json";
|
||||||
import { HUDType } from "./components/MainScene/SyncedComponents/HUD";
|
import { HUDType } from "./components/MainScene/SyncedComponents/HUD";
|
||||||
import { NodeDataType } from "./components/MainScene/SyncedComponents/Site";
|
import { NodeDataType } from "./components/MainScene/SyncedComponents/Site";
|
||||||
|
import { useCallback } from "react";
|
||||||
|
|
||||||
type SiteSaveState = {
|
type SiteSaveState = {
|
||||||
a: {
|
a: {
|
||||||
|
@ -271,12 +272,17 @@ export const useStore = create(
|
||||||
|
|
||||||
// site setters
|
// site setters
|
||||||
setActiveSite: (to: "a" | "b") => set(() => ({ activeSite: to })),
|
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) =>
|
setSiteRotX: (to: number) =>
|
||||||
set((prev) => {
|
set((prev) => {
|
||||||
const nextPos = [...prev.siteRot];
|
const nextRot = [...prev.siteRot];
|
||||||
nextPos[0] = to;
|
nextRot[0] = to;
|
||||||
return { siteRot: nextPos };
|
return { siteRot: nextRot };
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// level setters
|
// level setters
|
||||||
|
@ -308,28 +314,27 @@ export const useStore = create(
|
||||||
leftSideIdx: to,
|
leftSideIdx: to,
|
||||||
},
|
},
|
||||||
})),
|
})),
|
||||||
setMediaRightComponentMatrixIdx: (to: 0 | 1 | 2) =>
|
updateRightSide: (matrixIdx: 0 | 1 | 2, wordPosIdx: number) =>
|
||||||
set((state) => ({
|
set((state) => ({
|
||||||
mediaComponentMatrixIndices: {
|
mediaComponentMatrixIndices: {
|
||||||
...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(() => ({
|
set(() => ({
|
||||||
|
mediaWordPosStateIdx: 1,
|
||||||
mediaComponentMatrixIndices: {
|
mediaComponentMatrixIndices: {
|
||||||
sideIdx: 0,
|
sideIdx: 0,
|
||||||
leftSideIdx: 0,
|
leftSideIdx: 0,
|
||||||
rightSideIdx: 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
|
// idle media setters
|
||||||
setIdleMedia: (to: any) => set(() => ({ idleMedia: to })),
|
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