mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 23:19:06 +00:00
done refactoring state management, fixed some typing and renamed some stuff for clarity
This commit is contained in:
parent
8e76361374
commit
faa34b072c
68 changed files with 1075 additions and 1768 deletions
|
@ -7,7 +7,7 @@ import MediaScene from "./scenes/MediaScene";
|
|||
import { useStore } from "./store";
|
||||
import GateScene from "./scenes/GateScene";
|
||||
import BootScene from "./scenes/BootScene";
|
||||
import SSknScene from "./scenes/SSknScene";
|
||||
import SsknScene from "./scenes/SsknScene";
|
||||
import PolytanScene from "./scenes/PolytanScene";
|
||||
import TaKScene from "./scenes/TaKScene";
|
||||
import ChangeDiscScene from "./scenes/ChangeDiscScene";
|
||||
|
@ -30,7 +30,7 @@ const App = () => {
|
|||
idle_media: <IdleMediaScene />,
|
||||
gate: <GateScene />,
|
||||
boot: <BootScene />,
|
||||
sskn: <SSknScene />,
|
||||
sskn: <SsknScene />,
|
||||
polytan: <PolytanScene />,
|
||||
tak: <TaKScene />,
|
||||
change_disc: <ChangeDiscScene />,
|
||||
|
|
|
@ -27,7 +27,7 @@ const BootMainMenuComponents = (props: BootMainMenuProps) => {
|
|||
);
|
||||
|
||||
const activeMainMenuElement = useStore(
|
||||
(state) => state.mainMenuComponentMatrix[state.mainMenuComponentMatrixIdx]
|
||||
(state) => state.activeMainMenuComponent
|
||||
);
|
||||
|
||||
const loadDataActiveTex = useLoader(THREE.TextureLoader, loadDataActive);
|
||||
|
|
|
@ -23,7 +23,7 @@ const EndSelectionScreen = () => {
|
|||
const continueTextTex = useLoader(THREE.TextureLoader, continueText);
|
||||
const middleLainTex = useLoader(THREE.TextureLoader, middleLain);
|
||||
|
||||
const componentMatrixIdx = useStore((state) => state.endComponentMatrixIdx);
|
||||
const activeComponent = useStore((state) => state.activeEndComponent);
|
||||
|
||||
const [middleSpritesheetAnimator] = useState(() => {
|
||||
const anim = new PlainAnimator(middleSpritesheetTex, 1, 4, 4, 24);
|
||||
|
@ -75,7 +75,7 @@ const EndSelectionScreen = () => {
|
|||
<meshBasicMaterial attach="material" color={0x000000} />
|
||||
</mesh>
|
||||
<sprite
|
||||
position={componentMatrixIdx === 0 ? [0, 1, 0] : [0, -1.5, 0]}
|
||||
position={activeComponent === "end" ? [0, 1, 0] : [0, -1.5, 0]}
|
||||
scale={[0.5, 0.5, 0]}
|
||||
>
|
||||
<spriteMaterial attach="material" map={circleSpritesheetTex} />
|
||||
|
|
|
@ -15,7 +15,7 @@ const Images = () => {
|
|||
const [sceneImages, setSceneImages] = useState([] as any);
|
||||
const [activeImage, setActiveImage] = useState<THREE.Texture>();
|
||||
|
||||
const currentSite = useStore((state) => state.activeSite);
|
||||
const activeSite = useStore((state) => state.activeSite);
|
||||
|
||||
const dummyTex = useLoader(THREE.TextureLoader, dummy);
|
||||
|
||||
|
@ -49,7 +49,7 @@ const Images = () => {
|
|||
imgTries++;
|
||||
if (img[1] !== "-1") {
|
||||
import(
|
||||
"../static/media_images/" + currentSite + "/" + img[1] + ".png"
|
||||
"../static/media_images/" + activeSite + "/" + img[1] + ".png"
|
||||
).then((imageSrc: { default: string }) => {
|
||||
imgArr.splice(parseInt(img[0]), 0, imageSrc);
|
||||
if (imgTries === 3) {
|
||||
|
@ -60,7 +60,7 @@ const Images = () => {
|
|||
}
|
||||
});
|
||||
}
|
||||
}, [currentScene, currentSite, idleNodeImages, nodeImages]);
|
||||
}, [currentScene, activeSite, idleNodeImages, nodeImages]);
|
||||
|
||||
useEffect(() => {
|
||||
const loadNewImage = (imgIdx: number) => {
|
||||
|
|
|
@ -1,99 +1,37 @@
|
|||
import { useCallback, useEffect, useMemo, useRef } from "react";
|
||||
import { useCallback, useEffect, useRef } from "react";
|
||||
import {
|
||||
getBootSceneContext,
|
||||
getEndSceneContext,
|
||||
getMainSceneContext,
|
||||
getMediaSceneContext,
|
||||
getSSknSceneContext,
|
||||
getSsknSceneContext,
|
||||
MainSceneContext,
|
||||
playAudio,
|
||||
useStore,
|
||||
} from "../store";
|
||||
import { getKeyCodeAssociation } from "../utils/keyPressUtils";
|
||||
import mediaManager from "../core/setters/media/mediaManager";
|
||||
import handleMediaSceneKeyPress from "../core/scene-keypress-handlers/handleMediaSceneKeyPress";
|
||||
import sceneManager from "../core/setters/sceneManager";
|
||||
import levelSelectionManager from "../core/setters/main/level_selection/levelSelectionManager";
|
||||
import nodeManager from "../core/setters/main/site/nodeManager";
|
||||
import levelManager from "../core/setters/main/site/levelManager";
|
||||
import lainManager from "../core/setters/main/site/lainManager";
|
||||
import siteManager from "../core/setters/main/site/siteManager";
|
||||
import pauseManager from "../core/setters/main/pause/pauseManager";
|
||||
import mainSubsceneManager from "../core/setters/main/mainSubsceneManager";
|
||||
import ssknManager from "../core/setters/sskn/ssknManager";
|
||||
import handleSSknSceneKeyPress from "../core/scene-keypress-handlers/handleSSknSceneKeyPress";
|
||||
import handleSsknSceneKeyPress from "../core/scene-keypress-handlers/handleSsknSceneKeyPress";
|
||||
import handleMainSceneKeyPress from "../core/scene-keypress-handlers/handleMainSceneKeyPress";
|
||||
import gameLoader from "../core/setters/gameLoader";
|
||||
import gameSaver from "../core/setters/gameSaver";
|
||||
import progressManager from "../core/setters/progressManager";
|
||||
import promptManager from "../core/setters/promptManager";
|
||||
import bootSubsceneManager from "../core/setters/boot/bootSubsceneManager";
|
||||
import bootManager from "../core/setters/boot/bootManager";
|
||||
import handleBootSceneKeyPress from "../core/scene-keypress-handlers/handleBootSceneKeyPress";
|
||||
import soundManager from "../core/setters/soundManager";
|
||||
import { useFrame } from "react-three-fiber";
|
||||
import { getRandomIdleLainAnim, getRandomIdleMedia } from "../utils/idle-utils";
|
||||
import idleManager from "../core/setters/main/idleManager";
|
||||
import { getRandomIdleLainAnim } from "../utils/idle-utils";
|
||||
import * as audio from "../static/sfx";
|
||||
import handleEndSceneKeyPress from "../core/scene-keypress-handlers/handleEndSceneKeyPress";
|
||||
import endManager from "../core/setters/end/endManager";
|
||||
import handleMainSceneEvent from "../core/scene-event-handlers/handleMainSceneEvent";
|
||||
import handleMediaSceneEvent from "../core/scene-event-handlers/handleMediaSceneEvent";
|
||||
import handleSsknSceneEvent from "../core/scene-event-handlers/handleSsknSceneEvent";
|
||||
import handleBootSceneEvent from "../core/scene-event-handlers/handleBootSceneEvent";
|
||||
import handleEndSceneEvent from "../core/scene-event-handlers/handleEndSceneEvent";
|
||||
|
||||
const KeyPressHandler = () => {
|
||||
const mediaSceneSetters = useMemo(
|
||||
() => [
|
||||
mediaManager,
|
||||
sceneManager,
|
||||
nodeManager,
|
||||
levelManager,
|
||||
siteManager,
|
||||
progressManager,
|
||||
mainSubsceneManager,
|
||||
soundManager,
|
||||
],
|
||||
[]
|
||||
);
|
||||
const ssknSceneSetters = useMemo(
|
||||
() => [ssknManager, sceneManager, progressManager],
|
||||
[]
|
||||
);
|
||||
const mainSceneSetters = useMemo(
|
||||
() => [
|
||||
levelSelectionManager,
|
||||
nodeManager,
|
||||
levelManager,
|
||||
lainManager,
|
||||
siteManager,
|
||||
pauseManager,
|
||||
mainSubsceneManager,
|
||||
sceneManager,
|
||||
gameLoader,
|
||||
gameSaver,
|
||||
progressManager,
|
||||
promptManager,
|
||||
soundManager,
|
||||
],
|
||||
[]
|
||||
);
|
||||
|
||||
const bootSceneSetters = useMemo(
|
||||
() => [
|
||||
bootSubsceneManager,
|
||||
bootManager,
|
||||
promptManager,
|
||||
gameLoader,
|
||||
soundManager,
|
||||
sceneManager,
|
||||
],
|
||||
[]
|
||||
);
|
||||
|
||||
const endSceneSetters = useMemo(
|
||||
() => [sceneManager, soundManager, endManager],
|
||||
[]
|
||||
);
|
||||
|
||||
const scene = useStore((state) => state.currentScene);
|
||||
const mainSubscene = useStore((state) => state.mainSubscene);
|
||||
const inputCooldown = useStore((state) => state.inputCooldown);
|
||||
|
||||
const setLainMoveState = useStore((state) => state.setLainMoveState);
|
||||
|
||||
const timeSinceLastKeyPress = useRef(-1);
|
||||
const lainIdleCounter = useRef(-1);
|
||||
const idleSceneCounter = useRef(-1);
|
||||
|
||||
|
@ -107,7 +45,7 @@ const KeyPressHandler = () => {
|
|||
scene === "main"
|
||||
) {
|
||||
if (now > lainIdleCounter.current + 10000) {
|
||||
lainManager({ event: getRandomIdleLainAnim() });
|
||||
setLainMoveState(getRandomIdleLainAnim());
|
||||
// after one idle animation plays, the second comes sooner than it would after a regular keypress
|
||||
lainIdleCounter.current = now - 2500;
|
||||
}
|
||||
|
@ -118,11 +56,11 @@ const KeyPressHandler = () => {
|
|||
// but i'm way too lazy for that
|
||||
idleSceneCounter.current = -1;
|
||||
|
||||
idleManager(getRandomIdleMedia());
|
||||
// idleManager(getRandomIdleMedia());
|
||||
playAudio(audio.sound32);
|
||||
|
||||
setTimeout(() => {
|
||||
sceneManager({ event: "play_idle_media" });
|
||||
// useStore.setState({ event: "play_idle_media" });
|
||||
}, 1200);
|
||||
}
|
||||
}
|
||||
|
@ -140,83 +78,71 @@ const KeyPressHandler = () => {
|
|||
|
||||
const now = Date.now();
|
||||
|
||||
if (keyPress) {
|
||||
if (
|
||||
keyPress &&
|
||||
!inputCooldown &&
|
||||
now > timeSinceLastKeyPress.current + 1500
|
||||
) {
|
||||
if (scene === "main") {
|
||||
lainIdleCounter.current = now;
|
||||
idleSceneCounter.current = now;
|
||||
timeSinceLastKeyPress.current = now;
|
||||
}
|
||||
const sceneFns = (() => {
|
||||
switch (scene) {
|
||||
case "main":
|
||||
return {
|
||||
contextProvider: getMainSceneContext,
|
||||
handler: handleMainSceneKeyPress,
|
||||
setters: mainSceneSetters,
|
||||
keyPressHandler: handleMainSceneKeyPress,
|
||||
eventHandler: handleMainSceneEvent,
|
||||
};
|
||||
case "media":
|
||||
return {
|
||||
contextProvider: getMediaSceneContext,
|
||||
handler: handleMediaSceneKeyPress,
|
||||
setters: mediaSceneSetters,
|
||||
keyPressHandler: handleMediaSceneKeyPress,
|
||||
eventHandler: handleMediaSceneEvent,
|
||||
};
|
||||
case "sskn":
|
||||
return {
|
||||
contextProvider: getSSknSceneContext,
|
||||
handler: handleSSknSceneKeyPress,
|
||||
setters: ssknSceneSetters,
|
||||
contextProvider: getSsknSceneContext,
|
||||
keyPressHandler: handleSsknSceneKeyPress,
|
||||
eventHandler: handleSsknSceneEvent,
|
||||
};
|
||||
case "boot":
|
||||
return {
|
||||
contextProvider: getBootSceneContext,
|
||||
handler: handleBootSceneKeyPress,
|
||||
setters: bootSceneSetters,
|
||||
keyPressHandler: handleBootSceneKeyPress,
|
||||
eventHandler: handleBootSceneEvent,
|
||||
};
|
||||
case "end":
|
||||
return {
|
||||
contextProvider: getEndSceneContext,
|
||||
handler: handleEndSceneKeyPress,
|
||||
setters: endSceneSetters,
|
||||
keyPressHandler: handleEndSceneKeyPress,
|
||||
eventHandler: handleEndSceneEvent,
|
||||
};
|
||||
case "gate":
|
||||
case "polytan":
|
||||
return {
|
||||
action: () => useStore.setState({ currentScene: "main" }),
|
||||
};
|
||||
useStore.setState({ currentScene: "main" });
|
||||
break;
|
||||
case "idle_media":
|
||||
return {
|
||||
action: () =>
|
||||
useStore.setState({
|
||||
currentScene: "main",
|
||||
idleStarting: false,
|
||||
}),
|
||||
};
|
||||
useStore.setState({
|
||||
currentScene: "main",
|
||||
idleStarting: false,
|
||||
});
|
||||
break;
|
||||
}
|
||||
})();
|
||||
|
||||
if (sceneFns) {
|
||||
// in case of polytan/gate we only need to do one thing, which is reset the scene.
|
||||
// we check for that here
|
||||
if (sceneFns.action) {
|
||||
sceneFns.action();
|
||||
} else {
|
||||
const { contextProvider, handler, setters } = { ...sceneFns };
|
||||
const ctx = { ...contextProvider(), keyPress: keyPress };
|
||||
const event = handler(ctx);
|
||||
if (event) {
|
||||
setters.forEach((fn) => fn(event));
|
||||
}
|
||||
}
|
||||
const { contextProvider, keyPressHandler, eventHandler } = sceneFns;
|
||||
|
||||
const ctx = contextProvider(keyPress);
|
||||
const event = keyPressHandler(ctx);
|
||||
if (event) eventHandler(event);
|
||||
}
|
||||
}
|
||||
},
|
||||
[
|
||||
bootSceneSetters,
|
||||
endSceneSetters,
|
||||
mainSceneSetters,
|
||||
mediaSceneSetters,
|
||||
scene,
|
||||
ssknSceneSetters,
|
||||
]
|
||||
[inputCooldown, scene]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
@ -22,9 +22,7 @@ const Pause = () => {
|
|||
);
|
||||
|
||||
const activeComponent = useStore((state) =>
|
||||
showActiveComponent
|
||||
? state.pauseComponentMatrix[state.pauseComponentMatrixIdx]
|
||||
: ""
|
||||
showActiveComponent ? state.activePauseComponent : ""
|
||||
);
|
||||
|
||||
const generateSqaureGeom = useCallback((row: number, square: number) => {
|
||||
|
|
|
@ -11,7 +11,7 @@ import level_y_values from "../../resources/level_y_values.json";
|
|||
import { filterInvisibleNodes } from "../../utils/node-utils";
|
||||
import Loading from "../Loading";
|
||||
|
||||
export type NodeDataType = {
|
||||
export type NodeData = {
|
||||
id: string;
|
||||
image_table_indices: { 1: string; 2: string; 3: string };
|
||||
triggers_final_video: number;
|
||||
|
@ -32,12 +32,12 @@ export type NodeDataType = {
|
|||
is_viewed?: number;
|
||||
};
|
||||
|
||||
export type LevelType = {
|
||||
[key: string]: NodeDataType;
|
||||
export type Level = {
|
||||
[key: string]: NodeData;
|
||||
};
|
||||
|
||||
export type SiteType = {
|
||||
[key: string]: LevelType;
|
||||
export type SiteData = {
|
||||
[key: string]: Level;
|
||||
};
|
||||
|
||||
type SiteProps = {
|
||||
|
@ -47,11 +47,16 @@ type SiteProps = {
|
|||
const Site = (props: SiteProps) => {
|
||||
const wordSelected = useStore((state) => state.wordSelected);
|
||||
|
||||
const [rotState, setRot] = useSpring(() => ({
|
||||
x: wordSelected ? 0 : useStore.getState().siteRot[0],
|
||||
const [rotXState, setRotX] = useSpring(() => ({
|
||||
x: 0,
|
||||
config: { duration: 1200 },
|
||||
}));
|
||||
|
||||
const [rotYState, setRotY] = useSpring(() => ({
|
||||
y: wordSelected
|
||||
? useStore.getState().oldSiteRot[1]
|
||||
: useStore.getState().siteRot[1],
|
||||
delay: 1100,
|
||||
config: { duration: 1200 },
|
||||
}));
|
||||
|
||||
|
@ -68,29 +73,32 @@ const Site = (props: SiteProps) => {
|
|||
}));
|
||||
|
||||
useEffect(() => {
|
||||
useStore.subscribe(setRot, (state) => ({
|
||||
x: state.siteRot[0],
|
||||
useStore.subscribe(setRotY, (state) => ({
|
||||
y: state.siteRot[1],
|
||||
delay: 1100,
|
||||
}));
|
||||
useStore.subscribe(setRotX, (state) => ({
|
||||
x: state.siteRot[0],
|
||||
}));
|
||||
useStore.subscribe(setPos, (state) => ({
|
||||
y: -level_y_values[state.activeLevel as keyof typeof level_y_values],
|
||||
delay: 1300,
|
||||
}));
|
||||
}, [setPos, setRot]);
|
||||
}, [setPos, setRotX, setRotY]);
|
||||
|
||||
const currentSite = useStore((state) => state.activeSite);
|
||||
const activeSite = useStore((state) => state.activeSite);
|
||||
const gameProgress = useStore((state) => state.gameProgress);
|
||||
|
||||
const visibleNodes = useMemo(
|
||||
() =>
|
||||
filterInvisibleNodes(currentSite === "a" ? site_a : site_b, gameProgress),
|
||||
[currentSite, gameProgress]
|
||||
filterInvisibleNodes(activeSite === "a" ? site_a : site_b, gameProgress),
|
||||
[activeSite, gameProgress]
|
||||
);
|
||||
|
||||
return (
|
||||
<Suspense fallback={<Loading />}>
|
||||
<a.group rotation-x={rotState.x}>
|
||||
<a.group rotation-y={rotState.y} position-y={posState.y}>
|
||||
<a.group rotation-x={rotXState.x}>
|
||||
<a.group rotation-y={rotYState.y} position-y={posState.y}>
|
||||
<ActiveLevelNodes visibleNodes={visibleNodes} />
|
||||
<InactiveLevelNodes visibleNodes={visibleNodes} />
|
||||
<Rings activateAllRings={props.introFinished} />
|
||||
|
|
|
@ -2,11 +2,11 @@ import React, { memo, useEffect, useState } from "react";
|
|||
import Node from "./Node";
|
||||
import node_positions from "../../../resources/node_positions.json";
|
||||
import { useStore } from "../../../store";
|
||||
import { NodeDataType, SiteType } from "../Site";
|
||||
import { NodeData, SiteData } from "../Site";
|
||||
import usePrevious from "../../../hooks/usePrevious";
|
||||
|
||||
type ActiveLevelNodesProps = {
|
||||
visibleNodes: SiteType;
|
||||
visibleNodes: SiteData;
|
||||
};
|
||||
|
||||
const ActiveLevelNodes = memo((props: ActiveLevelNodesProps) => {
|
||||
|
@ -43,7 +43,7 @@ const ActiveLevelNodes = memo((props: ActiveLevelNodesProps) => {
|
|||
|
||||
return (
|
||||
<>
|
||||
{Object.values(visibleNodes).map((node: NodeDataType) => {
|
||||
{Object.values(visibleNodes).map((node: NodeData) => {
|
||||
return (
|
||||
<Node
|
||||
nodeName={node.node_name}
|
||||
|
|
|
@ -6,8 +6,8 @@ import Cou from "../../../static/sprite/Cou.png";
|
|||
import CouViewed from "../../../static/sprite/Cou_viewed.png";
|
||||
import Dc from "../../../static/sprite/Dc.png";
|
||||
import DcViewed from "../../../static/sprite/Dc_viewed.png";
|
||||
import SSkn from "../../../static/sprite/SSkn.png";
|
||||
import SSknViewed from "../../../static/sprite/SSkn_viewed.png";
|
||||
import Sskn from "../../../static/sprite/SSkn.png";
|
||||
import SsknViewed from "../../../static/sprite/SSkn_viewed.png";
|
||||
import Tda from "../../../static/sprite/Tda.png";
|
||||
import TdaViewed from "../../../static/sprite/Tda_viewed.png";
|
||||
import Dia from "../../../static/sprite/Dia.png";
|
||||
|
@ -29,7 +29,7 @@ type NodeContructorProps = {
|
|||
const InactiveLevelNode = memo((props: NodeContructorProps) => {
|
||||
const tex = useMemo(() => {
|
||||
if (props.nodeName.includes("S")) {
|
||||
return [SSkn, SSknViewed];
|
||||
return [Sskn, SsknViewed];
|
||||
} else if (
|
||||
props.nodeName.startsWith("P") ||
|
||||
props.nodeName.startsWith("G") ||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import React, { memo, useEffect, useState } from "react";
|
||||
import node_positions from "../../../resources/node_positions.json";
|
||||
import { useStore } from "../../../store";
|
||||
import { SiteType } from "../Site";
|
||||
import { SiteData } from "../Site";
|
||||
import InactiveLevelNode from "./InactiveLevelNode";
|
||||
import usePrevious from "../../../hooks/usePrevious";
|
||||
import { generateInactiveNodes } from "../../../utils/node-utils";
|
||||
|
||||
type ActiveLevelNodesProps = {
|
||||
visibleNodes: SiteType;
|
||||
visibleNodes: SiteData;
|
||||
};
|
||||
|
||||
const InactiveLevelNodes = memo((props: ActiveLevelNodesProps) => {
|
||||
|
|
|
@ -8,9 +8,9 @@ import CouViewed from "../../../static/sprite/Cou_viewed.png";
|
|||
import Dc from "../../../static/sprite/Dc.png";
|
||||
import DcActive from "../../../static/sprite/Dc_active.png";
|
||||
import DcViewed from "../../../static/sprite/Dc_viewed.png";
|
||||
import SSkn from "../../../static/sprite/SSkn.png";
|
||||
import SSKnActive from "../../../static/sprite/SSkn_active.png";
|
||||
import SSknViewed from "../../../static/sprite/SSkn_viewed.png";
|
||||
import Sskn from "../../../static/sprite/SSkn.png";
|
||||
import SsknActive from "../../../static/sprite/SSkn_active.png";
|
||||
import SsknViewed from "../../../static/sprite/SSkn_viewed.png";
|
||||
import Tda from "../../../static/sprite/Tda.png";
|
||||
import TdaActive from "../../../static/sprite/Tda_active.png";
|
||||
import TdaViewed from "../../../static/sprite/Tda_viewed.png";
|
||||
|
@ -38,7 +38,7 @@ type NodeContructorProps = {
|
|||
const Node = memo((props: NodeContructorProps) => {
|
||||
const tex = useMemo(() => {
|
||||
if (props.nodeName.includes("S")) {
|
||||
return [SSkn, SSKnActive, SSknViewed];
|
||||
return [Sskn, SsknActive, SsknViewed];
|
||||
} else if (
|
||||
props.nodeName.startsWith("P") ||
|
||||
props.nodeName.startsWith("G") ||
|
||||
|
|
|
@ -6,8 +6,8 @@ import Cou from "../../../../../static/sprite/Cou.png";
|
|||
import CouGold from "../../../../../static/sprite/Cou_gold.png";
|
||||
import Dc from "../../../../../static/sprite/Dc.png";
|
||||
import DcGold from "../../../../../static/sprite/Dc_gold.png";
|
||||
import SSkn from "../../../../../static/sprite/SSkn.png";
|
||||
import SSKnGold from "../../../../../static/sprite/SSkn_gold.png";
|
||||
import Sskn from "../../../../../static/sprite/SSkn.png";
|
||||
import SsknGold from "../../../../../static/sprite/SSkn_gold.png";
|
||||
import Tda from "../../../../../static/sprite/Tda.png";
|
||||
import TdaGold from "../../../../../static/sprite/Tda_gold.png";
|
||||
import Dia from "../../../../../static/sprite/Dia.png";
|
||||
|
@ -41,7 +41,7 @@ const GoldNode = (props: GoldNodeProps) => {
|
|||
|
||||
const tex = useMemo(() => {
|
||||
if (activeNodeName.includes("S")) {
|
||||
return [SSkn, SSKnGold];
|
||||
return [Sskn, SsknGold];
|
||||
} else if (
|
||||
activeNodeName.startsWith("P") ||
|
||||
activeNodeName.startsWith("G") ||
|
||||
|
|
|
@ -12,10 +12,10 @@ type RingsProps = {
|
|||
const Rings = memo((props: RingsProps) => {
|
||||
const activeLevel = useStore((state) => state.activeLevel);
|
||||
|
||||
const currentSite = useStore((state) => state.activeSite);
|
||||
const activeSite = useStore((state) => state.activeSite);
|
||||
|
||||
const levelUpperLimit = useMemo(() => (currentSite === "a" ? 22 : 13), [
|
||||
currentSite,
|
||||
const levelUpperLimit = useMemo(() => (activeSite === "a" ? 22 : 13), [
|
||||
activeSite,
|
||||
]);
|
||||
|
||||
const possibleLevels = useMemo(
|
||||
|
@ -55,7 +55,7 @@ const Rings = memo((props: RingsProps) => {
|
|||
<PurpleRing
|
||||
purpleRingPosY={0.44}
|
||||
level={level[0]}
|
||||
site={currentSite}
|
||||
site={activeSite}
|
||||
/>
|
||||
<GrayRing grayRingPosY={-0.29} />
|
||||
<CyanCrystal crystalRingPosY={-0.45} />
|
||||
|
|
|
@ -11,14 +11,7 @@ export type ShapeProps = {
|
|||
};
|
||||
|
||||
const LeftSide = memo(() => {
|
||||
const activeMediaComponent = useStore(
|
||||
(state) =>
|
||||
state.mediaComponentMatrix[state.mediaComponentMatrixIndices.sideIdx][
|
||||
state.mediaComponentMatrixIndices.sideIdx === 0
|
||||
? state.mediaComponentMatrixIndices.leftSideIdx
|
||||
: state.mediaComponentMatrixIndices.rightSideIdx
|
||||
]
|
||||
);
|
||||
const activeMediaComponent = useStore((state) => state.activeMediaComponent);
|
||||
|
||||
const cubesActive = useMemo(() => activeMediaComponent === "exit", [
|
||||
activeMediaComponent,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { memo, useCallback, useMemo } from "react";
|
||||
import React, { memo, useMemo } from "react";
|
||||
import { useStore } from "../../../store";
|
||||
import Word from "./RightSide/Word";
|
||||
import { a, useSpring } from "@react-spring/three";
|
||||
|
@ -37,17 +37,7 @@ const RightSide = memo(() => {
|
|||
[]
|
||||
);
|
||||
|
||||
const activeMediaComponent = useStore(
|
||||
useCallback(
|
||||
(state) =>
|
||||
state.mediaComponentMatrix[state.mediaComponentMatrixIndices.sideIdx][
|
||||
state.mediaComponentMatrixIndices.sideIdx === 0
|
||||
? state.mediaComponentMatrixIndices.leftSideIdx
|
||||
: state.mediaComponentMatrixIndices.rightSideIdx
|
||||
],
|
||||
[]
|
||||
)
|
||||
);
|
||||
const activeMediaComponent = useStore((state) => state.activeMediaComponent);
|
||||
|
||||
return (
|
||||
<group position={[0, 0, -3]}>
|
||||
|
|
|
@ -18,9 +18,7 @@ const Prompt = () => {
|
|||
const yesTex = useLoader(THREE.TextureLoader, yes);
|
||||
const noTex = useLoader(THREE.TextureLoader, no);
|
||||
|
||||
const activeComponent = useStore(
|
||||
(state) => state.promptComponentMatrix[state.promptComponentMatrixIdx]
|
||||
);
|
||||
const activeComponent = useStore((state) => state.activePromptComponent);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
|
@ -6,7 +6,7 @@ import * as THREE from "three";
|
|||
import ssknTopLabel from "../../static/sprite/sskn_top_label.png";
|
||||
import ssknDango from "../../static/sprite/sskn_dango.png";
|
||||
|
||||
const SSknBackground = memo(() => {
|
||||
const SsknBackground = memo(() => {
|
||||
const ssknBackgroundTex = useLoader(THREE.TextureLoader, ssknBackground);
|
||||
const ssknBackgroundTextTex = useLoader(
|
||||
THREE.TextureLoader,
|
||||
|
@ -43,4 +43,4 @@ const SSknBackground = memo(() => {
|
|||
);
|
||||
});
|
||||
|
||||
export default SSknBackground;
|
||||
export default SsknBackground;
|
|
@ -10,10 +10,10 @@ import ssknTextWrapperInactive from "../../static/sprite/sskn_text_wrapper_inact
|
|||
import ssknLine from "../../static/sprite/sskn_line.png";
|
||||
import { useLoader } from "react-three-fiber";
|
||||
import * as THREE from "three";
|
||||
import SSknLoadingBar from "./SSknLoadingBar";
|
||||
import SsknLoadingBar from "./SsknLoadingBar";
|
||||
import { useStore } from "../../store";
|
||||
|
||||
const SSknHUD = memo(() => {
|
||||
const SsknHUD = memo(() => {
|
||||
const ssknOkTex = useLoader(THREE.TextureLoader, ssknOk);
|
||||
const ssknOkInactiveTex = useLoader(THREE.TextureLoader, ssknOkInactive);
|
||||
const ssknCancelTex = useLoader(THREE.TextureLoader, ssknCancel);
|
||||
|
@ -30,29 +30,27 @@ const SSknHUD = memo(() => {
|
|||
);
|
||||
const ssknLineTex = useLoader(THREE.TextureLoader, ssknLine);
|
||||
|
||||
const activeSSknComponent = useStore(
|
||||
(state) => state.ssknComponentMatrix[state.ssknComponentMatrixIdx]
|
||||
);
|
||||
const activeSsknComponent = useStore((state) => state.activeSsknComponent);
|
||||
|
||||
const loading = useStore((state) => state.ssknLoading);
|
||||
|
||||
return (
|
||||
<>
|
||||
{loading ? (
|
||||
<SSknLoadingBar />
|
||||
<SsknLoadingBar />
|
||||
) : (
|
||||
<group>
|
||||
<sprite position={[2.8, -2, 0]} scale={[1, 0.5, 0]}>
|
||||
<spriteMaterial
|
||||
attach="material"
|
||||
map={activeSSknComponent === "ok" ? ssknOkTex : ssknOkInactiveTex}
|
||||
map={activeSsknComponent === "ok" ? ssknOkTex : ssknOkInactiveTex}
|
||||
/>
|
||||
</sprite>
|
||||
<sprite position={[3.3, -3, 0]} scale={[2, 0.5, 0]}>
|
||||
<spriteMaterial
|
||||
attach="material"
|
||||
map={
|
||||
activeSSknComponent === "cancel"
|
||||
activeSsknComponent === "cancel"
|
||||
? ssknCancelTex
|
||||
: ssknCancelInactiveTex
|
||||
}
|
||||
|
@ -62,7 +60,7 @@ const SSknHUD = memo(() => {
|
|||
<spriteMaterial
|
||||
attach="material"
|
||||
map={
|
||||
activeSSknComponent === "ok"
|
||||
activeSsknComponent === "ok"
|
||||
? ssknTextWrapperTex
|
||||
: ssknTextWrapperInactiveTex
|
||||
}
|
||||
|
@ -72,7 +70,7 @@ const SSknHUD = memo(() => {
|
|||
<spriteMaterial
|
||||
attach="material"
|
||||
map={
|
||||
activeSSknComponent === "cancel"
|
||||
activeSsknComponent === "cancel"
|
||||
? ssknTextWrapperTex
|
||||
: ssknTextWrapperInactiveTex
|
||||
}
|
||||
|
@ -101,4 +99,4 @@ const SSknHUD = memo(() => {
|
|||
);
|
||||
});
|
||||
|
||||
export default SSknHUD;
|
||||
export default SsknHUD;
|
|
@ -3,7 +3,7 @@ import ssknIcon from "../../static/sprite/SSkn_icon.png";
|
|||
import { useFrame, useLoader } from "react-three-fiber";
|
||||
import * as THREE from "three";
|
||||
|
||||
const SSknIcon = memo(() => {
|
||||
const SsknIcon = memo(() => {
|
||||
const ssknIconTex = useLoader(THREE.TextureLoader, ssknIcon);
|
||||
const ssknIconRef = useRef<THREE.Object3D>();
|
||||
const ssknIconShadowRef = useRef<THREE.Object3D>();
|
||||
|
@ -51,4 +51,4 @@ const SSknIcon = memo(() => {
|
|||
);
|
||||
});
|
||||
|
||||
export default SSknIcon;
|
||||
export default SsknIcon;
|
|
@ -9,7 +9,7 @@ import loadingBar40Perc from "../../static/sprite/media_loading_bar_40perc.png";
|
|||
import loadingBar50Perc from "../../static/sprite/media_loading_bar_50perc.png";
|
||||
import loadingBar from "../../static/sprite/media_loading_bar.png";
|
||||
|
||||
const SSknLoadingBar = () => {
|
||||
const SsknLoadingBar = () => {
|
||||
const ssknLoadingBarContainerTex = useLoader(
|
||||
THREE.TextureLoader,
|
||||
ssknLoadingBarContainer
|
||||
|
@ -92,4 +92,4 @@ const SSknLoadingBar = () => {
|
|||
);
|
||||
};
|
||||
|
||||
export default SSknLoadingBar;
|
||||
export default SsknLoadingBar;
|
|
@ -8,7 +8,7 @@ import React, { memo, useEffect, useMemo, useState } from "react";
|
|||
import { useStore } from "../../store";
|
||||
import usePrevious from "../../hooks/usePrevious";
|
||||
|
||||
const SiteBigLetter = memo((props: { letter: string; letterIdx: number }) => {
|
||||
const BigLetter = memo((props: { letter: string; letterIdx: number }) => {
|
||||
const [color, setColor] = useState("yellow");
|
||||
|
||||
const tex = useMemo(
|
||||
|
@ -76,14 +76,7 @@ const SiteBigLetter = memo((props: { letter: string; letterIdx: number }) => {
|
|||
}, [letterData, lineYOffset]);
|
||||
|
||||
const activeNode = useStore((state) => state.activeNode);
|
||||
const activeMediaComponent = useStore(
|
||||
(state) =>
|
||||
state.mediaComponentMatrix[state.mediaComponentMatrixIndices.sideIdx][
|
||||
state.mediaComponentMatrixIndices.sideIdx === 0
|
||||
? state.mediaComponentMatrixIndices.leftSideIdx
|
||||
: state.mediaComponentMatrixIndices.rightSideIdx
|
||||
]
|
||||
);
|
||||
const activeMediaComponent = useStore((state) => state.activeMediaComponent);
|
||||
|
||||
const subscene = useStore((state) => state.mainSubscene);
|
||||
const scene = useStore((state) => state.currentScene);
|
||||
|
@ -150,4 +143,4 @@ const SiteBigLetter = memo((props: { letter: string; letterIdx: number }) => {
|
|||
);
|
||||
});
|
||||
|
||||
export default SiteBigLetter;
|
||||
export default BigLetter;
|
|
@ -1,7 +1,7 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { useStore } from "../../store";
|
||||
import { a, useTrail } from "@react-spring/three";
|
||||
import SiteBigLetter from "./SiteBigLetter";
|
||||
import BigLetter from "./BigLetter";
|
||||
import usePrevious from "../../hooks/usePrevious";
|
||||
import { getNodeHud } from "../../utils/node-utils";
|
||||
|
||||
|
@ -45,7 +45,7 @@ const MainYellowTextAnimator = (props: { visible?: boolean }) => {
|
|||
position-z={-8.7}
|
||||
scale={[0.04, 0.06, 0.04]}
|
||||
>
|
||||
<SiteBigLetter letter={text[idx]} letterIdx={idx} key={idx} />
|
||||
<BigLetter letter={text[idx]} letterIdx={idx} key={idx} />
|
||||
</a.group>
|
||||
))}
|
||||
</a.group>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { memo, useEffect, useState } from "react";
|
||||
import { useStore } from "../../store";
|
||||
import { a, useTrail } from "@react-spring/three";
|
||||
import SiteBigLetter from "./SiteBigLetter";
|
||||
import BigLetter from "./BigLetter";
|
||||
|
||||
const MediaYellowTextAnimator = memo(() => {
|
||||
const [lastLeftComponent, setLastLeftComponent] = useState("play");
|
||||
|
@ -13,14 +13,7 @@ const MediaYellowTextAnimator = memo(() => {
|
|||
config: { duration: 280 },
|
||||
});
|
||||
|
||||
const activeMediaComponent = useStore(
|
||||
(state) =>
|
||||
state.mediaComponentMatrix[state.mediaComponentMatrixIndices.sideIdx][
|
||||
state.mediaComponentMatrixIndices.sideIdx === 0
|
||||
? state.mediaComponentMatrixIndices.leftSideIdx
|
||||
: state.mediaComponentMatrixIndices.rightSideIdx
|
||||
]
|
||||
);
|
||||
const activeMediaComponent = useStore((state) => state.activeMediaComponent);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
|
@ -66,7 +59,7 @@ const MediaYellowTextAnimator = memo(() => {
|
|||
position-z={-8.7}
|
||||
scale={[0.04, 0.06, 0.04]}
|
||||
>
|
||||
<SiteBigLetter letter={textArr[idx]} letterIdx={idx} key={idx} />
|
||||
<BigLetter letter={textArr[idx]} letterIdx={idx} key={idx} />
|
||||
</a.group>
|
||||
))}
|
||||
</group>
|
||||
|
|
84
src/core/scene-event-handlers/handleBootSceneEvent.ts
Normal file
84
src/core/scene-event-handlers/handleBootSceneEvent.ts
Normal file
|
@ -0,0 +1,84 @@
|
|||
import { playAudio, useStore } from "../../store";
|
||||
import * as audio from "../../static/sfx";
|
||||
|
||||
const handleBootSceneEvent = (eventState: any) => {
|
||||
const setState = useStore.setState;
|
||||
|
||||
switch (eventState.event) {
|
||||
case "main_menu_up":
|
||||
setState({ activeMainMenuComponent: "authorize_user" });
|
||||
playAudio(audio.sound1);
|
||||
break;
|
||||
case "main_menu_down":
|
||||
setState({ activeMainMenuComponent: "load_data" });
|
||||
playAudio(audio.sound1);
|
||||
break;
|
||||
case "main_menu_load_data_select":
|
||||
setState({ bootSubscene: "load_data" });
|
||||
playAudio(audio.sound0);
|
||||
|
||||
setTimeout(() => setState({ promptVisible: true }), 500);
|
||||
break;
|
||||
case "main_menu_authorize_user_select":
|
||||
setState({ authorizeUserLetterIdx: 0, bootSubscene: "authorize_user" });
|
||||
playAudio(audio.sound0);
|
||||
break;
|
||||
case "authorize_user_up":
|
||||
case "authorize_user_down":
|
||||
case "authorize_user_left":
|
||||
case "authorize_user_right":
|
||||
setState({
|
||||
authorizeUserLetterIdx: eventState.authorizeUserLetterIdx,
|
||||
});
|
||||
break;
|
||||
case "authorize_user_back":
|
||||
setState({
|
||||
playerName: "",
|
||||
bootSubscene: "main_menu",
|
||||
});
|
||||
playAudio(audio.sound29);
|
||||
break;
|
||||
case "update_player_name":
|
||||
setState({
|
||||
playerName: eventState.playerName,
|
||||
});
|
||||
playAudio(audio.sound0);
|
||||
break;
|
||||
case "update_player_name_denied":
|
||||
playAudio(audio.sound0);
|
||||
break;
|
||||
case "remove_last_char":
|
||||
setState({ playerName: eventState.playerName });
|
||||
playAudio(audio.sound29);
|
||||
break;
|
||||
case "load_data_no":
|
||||
setState({
|
||||
bootSubscene: "main_menu",
|
||||
promptVisible: false,
|
||||
activePromptComponent: "no",
|
||||
});
|
||||
playAudio(audio.sound29);
|
||||
break;
|
||||
case "load_data_yes":
|
||||
// todo check if data exists
|
||||
setState({ loadSuccessful: true });
|
||||
playAudio(audio.sound28);
|
||||
|
||||
//todo actually load
|
||||
setTimeout(() => setState({ loadSuccessful: undefined }), 1200);
|
||||
break;
|
||||
case "prompt_left":
|
||||
setState({ activePromptComponent: "yes" });
|
||||
playAudio(audio.sound1);
|
||||
break;
|
||||
case "prompt_right":
|
||||
setState({ activePromptComponent: "no" });
|
||||
playAudio(audio.sound1);
|
||||
break;
|
||||
case "start_new_game":
|
||||
setState({ currentScene: "main", intro: true });
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
export default handleBootSceneEvent;
|
20
src/core/scene-event-handlers/handleEndSceneEvent.ts
Normal file
20
src/core/scene-event-handlers/handleEndSceneEvent.ts
Normal file
|
@ -0,0 +1,20 @@
|
|||
import { useStore } from "../../store";
|
||||
|
||||
const handleEndSceneEvent = (eventState: any) => {
|
||||
const setState = useStore.setState;
|
||||
switch (eventState.event) {
|
||||
case "end_selection_up":
|
||||
setState({ activeEndComponent: "end" });
|
||||
break;
|
||||
case "end_selection_down":
|
||||
setState({ activeEndComponent: "continue" });
|
||||
break;
|
||||
case "end_continue_select":
|
||||
setState({ currentScene: "change_disc", intro: true });
|
||||
break;
|
||||
case "end_end_select":
|
||||
setState({ currentScene: "boot" });
|
||||
}
|
||||
};
|
||||
|
||||
export default handleEndSceneEvent;
|
|
@ -1,7 +1,7 @@
|
|||
import { playAudio, useStore } from "../../store";
|
||||
import sleep from "../../utils/sleep";
|
||||
import * as audio from "../../static/sfx";
|
||||
import { NodeDataType } from "../../components/MainScene/Site";
|
||||
import { NodeData } from "../../components/MainScene/Site";
|
||||
import {
|
||||
nodeKnock,
|
||||
nodeKnockAndFall,
|
||||
|
@ -12,12 +12,14 @@ import {
|
|||
|
||||
type MainSceneMutations = {
|
||||
level?: string;
|
||||
node?: NodeDataType;
|
||||
node?: NodeData;
|
||||
};
|
||||
|
||||
const handleMainSceneEvent = (eventState: any) => {
|
||||
const setState = useStore.setState;
|
||||
|
||||
const changeSite = useStore.getState().changeSite;
|
||||
|
||||
switch (eventState.event) {
|
||||
case "site_up":
|
||||
case "site_down":
|
||||
|
@ -25,6 +27,7 @@ const handleMainSceneEvent = (eventState: any) => {
|
|||
setState({
|
||||
lainMoveState: eventState.event,
|
||||
activeLevel: eventState.level,
|
||||
inputCooldown: true,
|
||||
});
|
||||
playAudio(audio.sound13);
|
||||
|
||||
|
@ -36,7 +39,11 @@ const handleMainSceneEvent = (eventState: any) => {
|
|||
playAudio(audio.sound8);
|
||||
|
||||
await sleep(1200);
|
||||
setState({ activeNode: eventState.node });
|
||||
setState({
|
||||
activeNode: eventState.node,
|
||||
lainMoveState: "standing",
|
||||
inputCooldown: false,
|
||||
});
|
||||
})();
|
||||
break;
|
||||
case "site_left":
|
||||
|
@ -45,6 +52,7 @@ const handleMainSceneEvent = (eventState: any) => {
|
|||
setState({
|
||||
lainMoveState: eventState.event,
|
||||
siteRot: [0, eventState.siteRotY, 0],
|
||||
inputCooldown: true,
|
||||
});
|
||||
|
||||
await sleep(1100);
|
||||
|
@ -52,7 +60,11 @@ const handleMainSceneEvent = (eventState: any) => {
|
|||
playAudio(audio.sound34);
|
||||
|
||||
await sleep(2800);
|
||||
setState({ activeNode: eventState.node });
|
||||
setState({
|
||||
activeNode: eventState.node,
|
||||
lainMoveState: "standing",
|
||||
inputCooldown: false,
|
||||
});
|
||||
})();
|
||||
break;
|
||||
case "change_node":
|
||||
|
@ -69,6 +81,7 @@ const handleMainSceneEvent = (eventState: any) => {
|
|||
lainMoveState: "throw_node",
|
||||
oldLevel: eventState.level,
|
||||
oldSiteRot: [eventState.siteRotY, 0],
|
||||
inputCooldown: true,
|
||||
});
|
||||
|
||||
nodeThrow(eventState.siteRotY);
|
||||
|
@ -87,6 +100,7 @@ const handleMainSceneEvent = (eventState: any) => {
|
|||
setState({
|
||||
currentScene: eventState.event.split("_")[2],
|
||||
intro: false,
|
||||
lainMoveState: "standing",
|
||||
});
|
||||
})();
|
||||
break;
|
||||
|
@ -100,6 +114,7 @@ const handleMainSceneEvent = (eventState: any) => {
|
|||
lainMoveState: "rip_node",
|
||||
oldLevel: eventState.level,
|
||||
oldSiteRot: [eventState.siteRotY, 0],
|
||||
inputCooldown: true,
|
||||
});
|
||||
nodeRip(eventState.siteRotY);
|
||||
playAudio(audio.sound0);
|
||||
|
@ -115,6 +130,7 @@ const handleMainSceneEvent = (eventState: any) => {
|
|||
setState({
|
||||
currentScene: eventState.event.split("_")[2],
|
||||
intro: false,
|
||||
lainMoveState: "standing",
|
||||
});
|
||||
})();
|
||||
break;
|
||||
|
@ -122,6 +138,7 @@ const handleMainSceneEvent = (eventState: any) => {
|
|||
(async () => {
|
||||
setState({
|
||||
lainMoveState: "touch_and_scare",
|
||||
inputCooldown: true,
|
||||
});
|
||||
nodeTouchAndScare(eventState.siteRotY);
|
||||
|
||||
|
@ -130,20 +147,29 @@ const handleMainSceneEvent = (eventState: any) => {
|
|||
|
||||
await sleep(750);
|
||||
playAudio(audio.sound33);
|
||||
|
||||
await sleep(650);
|
||||
setState({
|
||||
lainMoveState: "standing",
|
||||
inputCooldown: false,
|
||||
});
|
||||
})();
|
||||
break;
|
||||
case "knock":
|
||||
(async () => {
|
||||
setState({ lainMoveState: "knock" });
|
||||
setState({ lainMoveState: "knock", inputCooldown: true });
|
||||
nodeKnock(eventState.siteRotY);
|
||||
|
||||
await sleep(1200);
|
||||
playAudio(audio.sound18);
|
||||
|
||||
await sleep(1700);
|
||||
setState({ lainMoveState: "standing", inputCooldown: false });
|
||||
})();
|
||||
break;
|
||||
case "knock_and_fall":
|
||||
(async () => {
|
||||
setState({ lainMoveState: "knock_and_fall" });
|
||||
setState({ lainMoveState: "knock_and_fall", inputCooldown: true });
|
||||
nodeKnockAndFall(eventState.siteRotY);
|
||||
|
||||
await sleep(1200);
|
||||
|
@ -155,16 +181,17 @@ const handleMainSceneEvent = (eventState: any) => {
|
|||
|
||||
await sleep(850);
|
||||
playAudio(audio.sound33);
|
||||
|
||||
await sleep(3350);
|
||||
setState({ lainMoveState: "standing", inputCooldown: false });
|
||||
})();
|
||||
break;
|
||||
case "enter_level_selection":
|
||||
(async () => {
|
||||
setState({
|
||||
selectedLevel: eventState.level,
|
||||
mainSubscene: "level_selection",
|
||||
});
|
||||
playAudio(audio.sound1);
|
||||
})();
|
||||
setState({
|
||||
selectedLevel: eventState.level,
|
||||
mainSubscene: "level_selection",
|
||||
});
|
||||
playAudio(audio.sound1);
|
||||
break;
|
||||
case "level_selection_up":
|
||||
case "level_selection_down":
|
||||
|
@ -181,6 +208,7 @@ const handleMainSceneEvent = (eventState: any) => {
|
|||
lainMoveState: eventState.event,
|
||||
activeLevel: eventState.level,
|
||||
mainSubscene: "site",
|
||||
inputCooldown: true,
|
||||
});
|
||||
|
||||
await sleep(1300);
|
||||
|
@ -191,7 +219,11 @@ const handleMainSceneEvent = (eventState: any) => {
|
|||
playAudio(audio.sound8);
|
||||
|
||||
await sleep(1200);
|
||||
setState({ activeNode: eventState.node });
|
||||
setState({
|
||||
activeNode: eventState.node,
|
||||
lainMoveState: "standing",
|
||||
inputCooldown: false,
|
||||
});
|
||||
})();
|
||||
break;
|
||||
case "exit_not_found":
|
||||
|
@ -203,33 +235,86 @@ const handleMainSceneEvent = (eventState: any) => {
|
|||
lainMoveState: "pause_game",
|
||||
pauseExitAnimation: false,
|
||||
mainSubscene: "pause",
|
||||
inputCooldown: true,
|
||||
});
|
||||
playAudio(audio.sound7);
|
||||
|
||||
await sleep(3400);
|
||||
playAudio(audio.sound23);
|
||||
|
||||
await sleep(200);
|
||||
await sleep(3600);
|
||||
useStore.getState().setSiteRotX(Math.PI / 2);
|
||||
playAudio(audio.sound23);
|
||||
})();
|
||||
break;
|
||||
case "pause_up":
|
||||
case "pause_down":
|
||||
setState({ pauseComponentMatrixIdx: eventState.pauseMatrixIdx });
|
||||
setState({ activePauseComponent: eventState.activePauseComponent });
|
||||
playAudio(audio.sound1);
|
||||
break;
|
||||
case "pause_exit_select":
|
||||
(async () => {
|
||||
setState({
|
||||
pauseExitAnimation: true,
|
||||
pauseComponentMatrixIdx: 2,
|
||||
siteRot: eventState.siteRot,
|
||||
});
|
||||
playAudio(audio.sound0);
|
||||
setState({
|
||||
pauseExitAnimation: true,
|
||||
activePauseComponent: "change",
|
||||
siteRot: eventState.siteRot,
|
||||
inputCooldown: true,
|
||||
});
|
||||
playAudio(audio.sound0);
|
||||
|
||||
await sleep(1100);
|
||||
setState({ mainSubscene: "site" });
|
||||
})();
|
||||
setTimeout(
|
||||
() =>
|
||||
setState({
|
||||
mainSubscene: "site",
|
||||
inputCooldown: false,
|
||||
lainMoveState: "standing",
|
||||
}),
|
||||
1200
|
||||
);
|
||||
break;
|
||||
case "pause_about_select":
|
||||
setState({ showingAbout: true });
|
||||
playAudio(audio.sound0);
|
||||
break;
|
||||
case "exit_about":
|
||||
setState({ showingAbout: false });
|
||||
break;
|
||||
case "display_prompt":
|
||||
setState({ promptVisible: true });
|
||||
playAudio(audio.sound0);
|
||||
break;
|
||||
case "exit_prompt":
|
||||
setState({ promptVisible: false, activePromptComponent: "no" });
|
||||
playAudio(audio.sound28);
|
||||
break;
|
||||
case "prompt_left":
|
||||
setState({ activePromptComponent: "yes" });
|
||||
playAudio(audio.sound1);
|
||||
break;
|
||||
case "prompt_right":
|
||||
setState({ activePromptComponent: "no" });
|
||||
playAudio(audio.sound1);
|
||||
break;
|
||||
case "show_permission_denied":
|
||||
setState({ permissionDenied: true });
|
||||
playAudio(audio.sound0);
|
||||
|
||||
setTimeout(() => setState({ permissionDenied: false }), 1200);
|
||||
break;
|
||||
case "pause_save_select":
|
||||
setState({ saveSuccessful: true });
|
||||
playAudio(audio.sound28);
|
||||
|
||||
//todo actually save
|
||||
setTimeout(() => setState({ saveSuccessful: undefined }), 1200);
|
||||
break;
|
||||
case "pause_load_select":
|
||||
// todo check if data exists
|
||||
setState({ loadSuccessful: true });
|
||||
playAudio(audio.sound28);
|
||||
|
||||
//todo actually load
|
||||
setTimeout(() => setState({ loadSuccessful: undefined }), 1200);
|
||||
break;
|
||||
case "pause_change_select":
|
||||
const siteToLoad: "a" | "b" = eventState.site;
|
||||
changeSite(siteToLoad);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
92
src/core/scene-event-handlers/handleMediaSceneEvent.ts
Normal file
92
src/core/scene-event-handlers/handleMediaSceneEvent.ts
Normal file
|
@ -0,0 +1,92 @@
|
|||
import { playAudio, useStore } from "../../store";
|
||||
import * as audio from "../../static/sfx";
|
||||
|
||||
const handleMediaSceneEvent = (eventState: any) => {
|
||||
const setState = useStore.setState;
|
||||
|
||||
const setNodeViewed = useStore.getState().setNodeViewed;
|
||||
const updateLeftSide = useStore.getState().updateLeftSide;
|
||||
const updateRightSide = useStore.getState().updateRightSide;
|
||||
|
||||
const setPercentageElapsed = useStore.getState().setPercentageElapsed;
|
||||
|
||||
const playMedia = () => {
|
||||
const mediaElement = document.getElementById("media") as HTMLMediaElement;
|
||||
|
||||
if (mediaElement && mediaElement.paused) {
|
||||
setPercentageElapsed(0);
|
||||
|
||||
mediaElement.play();
|
||||
}
|
||||
};
|
||||
|
||||
const exitMedia = () => {
|
||||
const mediaElement = document.getElementById("media") as HTMLMediaElement;
|
||||
if (mediaElement) {
|
||||
mediaElement.pause();
|
||||
mediaElement.currentTime = 0;
|
||||
}
|
||||
};
|
||||
|
||||
switch (eventState.event) {
|
||||
case "media_rightside_down":
|
||||
case "media_rightside_up":
|
||||
setState({
|
||||
activeMediaComponent: eventState.newActiveComponent,
|
||||
mediaWordPosStateIdx: eventState.wordPosStateIdx,
|
||||
});
|
||||
playAudio(audio.sound1);
|
||||
break;
|
||||
case "media_leftside_down":
|
||||
setState({ activeMediaComponent: "exit" });
|
||||
playAudio(audio.sound1);
|
||||
break;
|
||||
case "media_leftside_up":
|
||||
setState({ activeMediaComponent: "play" });
|
||||
playAudio(audio.sound1);
|
||||
break;
|
||||
case "media_leftside_right":
|
||||
updateLeftSide(
|
||||
eventState.newActiveComponent,
|
||||
eventState.lastActiveComponent
|
||||
);
|
||||
break;
|
||||
case "media_rightside_left":
|
||||
updateRightSide(
|
||||
eventState.newActiveComponent,
|
||||
eventState.lastActiveComponent
|
||||
);
|
||||
break;
|
||||
case "media_play_select":
|
||||
setNodeViewed(eventState.node.node_name, {
|
||||
is_viewed: 1,
|
||||
is_visible: 1,
|
||||
});
|
||||
playMedia();
|
||||
break;
|
||||
case "media_exit_select":
|
||||
exitMedia();
|
||||
playAudio(audio.sound29);
|
||||
break;
|
||||
case "media_word_select":
|
||||
exitMedia();
|
||||
playAudio(audio.sound29);
|
||||
setState({
|
||||
wordSelected: true,
|
||||
activeLevel: eventState.level,
|
||||
siteRot: [0, eventState.siteRotY, 0],
|
||||
activeNode: eventState.node,
|
||||
currentScene: "main",
|
||||
});
|
||||
break;
|
||||
case "word_node_not_found":
|
||||
exitMedia();
|
||||
playAudio(audio.sound30);
|
||||
setState({
|
||||
mainSubscene: "not_found",
|
||||
currentScene: "main",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default handleMediaSceneEvent;
|
42
src/core/scene-event-handlers/handleSsknSceneEvent.ts
Normal file
42
src/core/scene-event-handlers/handleSsknSceneEvent.ts
Normal file
|
@ -0,0 +1,42 @@
|
|||
import { useStore } from "../../store";
|
||||
|
||||
const handleSsknSceneEvent = (eventState: any) => {
|
||||
const setState = useStore.setState;
|
||||
|
||||
const setNodeViewed = useStore.getState().setNodeViewed;
|
||||
const incrementSsknLvl = useStore.getState().incrementSsknLvl;
|
||||
|
||||
switch (eventState.event) {
|
||||
case "sskn_cancel_up":
|
||||
setState({
|
||||
activeSsknComponent: "ok",
|
||||
});
|
||||
break;
|
||||
case "sskn_ok_down":
|
||||
setState({
|
||||
activeSsknComponent: "cancel",
|
||||
});
|
||||
break;
|
||||
case "sskn_ok_select":
|
||||
setState({
|
||||
ssknLoading: true,
|
||||
});
|
||||
setNodeViewed(eventState.node.node_name, {
|
||||
is_viewed: 1,
|
||||
is_visible: 0,
|
||||
});
|
||||
incrementSsknLvl();
|
||||
|
||||
setTimeout(() => setState({ currentScene: "main" }), 6000);
|
||||
|
||||
break;
|
||||
case "sskn_cancel_select":
|
||||
setState({
|
||||
ssknLoading: false,
|
||||
currentScene: "main",
|
||||
activeSsknComponent: "ok",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default handleSsknSceneEvent;
|
|
@ -1,7 +1,8 @@
|
|||
import authorize_user_letters from "../../resources/authorize_user_letters.json";
|
||||
import handleNameSelection from "../../utils/handleNameSelection";
|
||||
import { BootSceneContext } from "../../store";
|
||||
|
||||
const handleBootSceneKeyPress = (bootSceneContext: any) => {
|
||||
const handleBootSceneKeyPress = (bootSceneContext: BootSceneContext) => {
|
||||
const {
|
||||
keyPress,
|
||||
subscene,
|
||||
|
|
|
@ -4,15 +4,15 @@ import {
|
|||
isNodeVisible,
|
||||
unknownNodeTemplate,
|
||||
} from "../../utils/node-utils";
|
||||
import { MainSceneContext } from "../../store";
|
||||
|
||||
const handleMainSceneKeyPress = (mainSceneContext: any) => {
|
||||
const handleMainSceneKeyPress = (mainSceneContext: MainSceneContext) => {
|
||||
const {
|
||||
subscene,
|
||||
selectedLevel,
|
||||
pauseMatrixIdx,
|
||||
activePauseComponent,
|
||||
gameProgress,
|
||||
currentSite,
|
||||
activeSite,
|
||||
siteRotY,
|
||||
activeNode,
|
||||
level,
|
||||
|
@ -37,7 +37,7 @@ const handleMainSceneKeyPress = (mainSceneContext: any) => {
|
|||
case "yes":
|
||||
return {
|
||||
event: `pause_${activePauseComponent}_select`,
|
||||
site: currentSite,
|
||||
site: activeSite === "a" ? "b" : "a",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ const handleMainSceneKeyPress = (mainSceneContext: any) => {
|
|||
keyPressToLower,
|
||||
activeNode.matrixIndices!,
|
||||
level,
|
||||
currentSite,
|
||||
activeSite,
|
||||
gameProgress,
|
||||
true
|
||||
);
|
||||
|
@ -70,7 +70,7 @@ const handleMainSceneKeyPress = (mainSceneContext: any) => {
|
|||
: siteRotY - Math.PI / 4,
|
||||
node: {
|
||||
...(nodeData.node !== "unknown"
|
||||
? getNodeById(nodeData.node, currentSite)
|
||||
? getNodeById(nodeData.node, activeSite)
|
||||
: unknownNodeTemplate),
|
||||
matrixIndices: nodeData.matrixIndices,
|
||||
},
|
||||
|
@ -80,7 +80,7 @@ const handleMainSceneKeyPress = (mainSceneContext: any) => {
|
|||
event: "change_node",
|
||||
nodeMatrixIndices: nodeData.matrixIndices,
|
||||
node: {
|
||||
...getNodeById(nodeData.node, currentSite),
|
||||
...getNodeById(nodeData.node, activeSite),
|
||||
matrixIndices: nodeData.matrixIndices,
|
||||
},
|
||||
};
|
||||
|
@ -94,7 +94,7 @@ const handleMainSceneKeyPress = (mainSceneContext: any) => {
|
|||
keyPressToLower,
|
||||
activeNode.matrixIndices!,
|
||||
level,
|
||||
currentSite,
|
||||
activeSite,
|
||||
gameProgress,
|
||||
true
|
||||
);
|
||||
|
@ -109,7 +109,7 @@ const handleMainSceneKeyPress = (mainSceneContext: any) => {
|
|||
.padStart(2, "0"),
|
||||
node: {
|
||||
...(nodeData.node !== "unknown"
|
||||
? getNodeById(nodeData.node, currentSite)
|
||||
? getNodeById(nodeData.node, activeSite)
|
||||
: unknownNodeTemplate),
|
||||
matrixIndices: nodeData.matrixIndices,
|
||||
},
|
||||
|
@ -118,7 +118,7 @@ const handleMainSceneKeyPress = (mainSceneContext: any) => {
|
|||
return {
|
||||
event: "change_node",
|
||||
node: {
|
||||
...getNodeById(nodeData.node, currentSite),
|
||||
...getNodeById(nodeData.node, activeSite),
|
||||
matrixIndices: nodeData.matrixIndices,
|
||||
},
|
||||
};
|
||||
|
@ -222,7 +222,7 @@ const handleMainSceneKeyPress = (mainSceneContext: any) => {
|
|||
}
|
||||
break;
|
||||
case "L2":
|
||||
return { event: "toggle_level_selection", level: level };
|
||||
return { event: "enter_level_selection", level: level };
|
||||
case "TRIANGLE":
|
||||
return { event: "pause_game" };
|
||||
case "SPACE":
|
||||
|
@ -232,13 +232,13 @@ const handleMainSceneKeyPress = (mainSceneContext: any) => {
|
|||
case "level_selection":
|
||||
switch (keyPress) {
|
||||
case "UP":
|
||||
if (currentSite === "a") {
|
||||
if (activeSite === "a") {
|
||||
if (selectedLevel + 1 <= 22)
|
||||
return {
|
||||
event: `level_selection_up`,
|
||||
selectedLevelIdx: selectedLevel + 1,
|
||||
};
|
||||
} else if (currentSite === "b") {
|
||||
} else if (activeSite === "b") {
|
||||
if (selectedLevel + 1 <= 13)
|
||||
return {
|
||||
event: `level_selection_up`,
|
||||
|
@ -269,7 +269,7 @@ const handleMainSceneKeyPress = (mainSceneContext: any) => {
|
|||
direction,
|
||||
{ ...activeNode.matrixIndices!, rowIdx: rowIdx },
|
||||
selectedLevel,
|
||||
currentSite,
|
||||
activeSite,
|
||||
gameProgress,
|
||||
false
|
||||
);
|
||||
|
@ -281,7 +281,7 @@ const handleMainSceneKeyPress = (mainSceneContext: any) => {
|
|||
event: event,
|
||||
node: {
|
||||
...(nodeData.node !== "unknown"
|
||||
? getNodeById(nodeData.node, currentSite)
|
||||
? getNodeById(nodeData.node, activeSite)
|
||||
: unknownNodeTemplate),
|
||||
matrixIndices: nodeData.matrixIndices,
|
||||
},
|
||||
|
@ -297,21 +297,50 @@ const handleMainSceneKeyPress = (mainSceneContext: any) => {
|
|||
};
|
||||
else {
|
||||
switch (keyPress) {
|
||||
case "UP":
|
||||
if (pauseMatrixIdx - 1 < 0) break;
|
||||
return {
|
||||
event: "pause_up",
|
||||
pauseMatrixIdx: pauseMatrixIdx - 1,
|
||||
};
|
||||
case "DOWN":
|
||||
if (pauseMatrixIdx + 1 > 4) break;
|
||||
return {
|
||||
event: "pause_down",
|
||||
pauseMatrixIdx: pauseMatrixIdx + 1,
|
||||
};
|
||||
case "UP": {
|
||||
const newComponent = (() => {
|
||||
switch (activePauseComponent) {
|
||||
case "exit":
|
||||
return "save";
|
||||
case "save":
|
||||
return "change";
|
||||
case "change":
|
||||
return "about";
|
||||
case "about":
|
||||
return "load";
|
||||
}
|
||||
})();
|
||||
|
||||
if (newComponent)
|
||||
return {
|
||||
event: "pause_up",
|
||||
activePauseComponent: newComponent,
|
||||
};
|
||||
break;
|
||||
}
|
||||
case "DOWN": {
|
||||
const newComponent = (() => {
|
||||
switch (activePauseComponent) {
|
||||
case "load":
|
||||
return "about";
|
||||
case "about":
|
||||
return "change";
|
||||
case "change":
|
||||
return "save";
|
||||
case "save":
|
||||
return "exit";
|
||||
}
|
||||
})();
|
||||
if (newComponent)
|
||||
return {
|
||||
event: "pause_down",
|
||||
activePauseComponent: newComponent,
|
||||
};
|
||||
break;
|
||||
}
|
||||
case "CIRCLE":
|
||||
if (activePauseComponent === "change") {
|
||||
if (gateLvl < 4) {
|
||||
if (gateLvl > 4) {
|
||||
return { event: "show_permission_denied" };
|
||||
} else {
|
||||
return {
|
||||
|
@ -328,6 +357,7 @@ const handleMainSceneKeyPress = (mainSceneContext: any) => {
|
|||
} else {
|
||||
return {
|
||||
event: `pause_${activePauseComponent}_select`,
|
||||
siteRot: [0, siteRotY, 0],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,75 +1,96 @@
|
|||
import { findNodeFromWord } from "../../utils/media-utils";
|
||||
import { MediaSceneContext } from "../../store";
|
||||
|
||||
const handleMediaSceneKeyPress = (mediaSceneContext: any) => {
|
||||
const handleMediaSceneKeyPress = (mediaSceneContext: MediaSceneContext) => {
|
||||
const {
|
||||
keyPress,
|
||||
activeMediaComponent,
|
||||
wordPosStateIdx,
|
||||
rightSideComponentIdx,
|
||||
activeNode,
|
||||
activeSite,
|
||||
gameProgress,
|
||||
currentMediaSide,
|
||||
lastActiveMediaComponents,
|
||||
} = mediaSceneContext;
|
||||
|
||||
const calculateNewRightSide = (
|
||||
direction: string,
|
||||
wordPosStateIdx: number,
|
||||
rightSideComponentIdx: number
|
||||
) => {
|
||||
if (direction === "UP") {
|
||||
wordPosStateIdx--;
|
||||
if (wordPosStateIdx < 1) {
|
||||
wordPosStateIdx = 6;
|
||||
switch (currentMediaSide) {
|
||||
case "left":
|
||||
switch (keyPress) {
|
||||
case "UP":
|
||||
case "DOWN":
|
||||
return {
|
||||
event: `media_leftside_${keyPress.toLowerCase()}`,
|
||||
};
|
||||
case "RIGHT":
|
||||
return {
|
||||
event: "media_leftside_right",
|
||||
lastActiveComponent: activeMediaComponent,
|
||||
newActiveComponent: lastActiveMediaComponents.right,
|
||||
};
|
||||
case "CIRCLE":
|
||||
switch (activeMediaComponent) {
|
||||
case "play":
|
||||
return {
|
||||
event: "media_play_select",
|
||||
node: activeNode,
|
||||
};
|
||||
case "exit":
|
||||
return {
|
||||
event: "media_play_select",
|
||||
};
|
||||
}
|
||||
}
|
||||
rightSideComponentIdx--;
|
||||
if (rightSideComponentIdx < 0) {
|
||||
rightSideComponentIdx = 2;
|
||||
}
|
||||
} else if (direction === "DOWN") {
|
||||
wordPosStateIdx++;
|
||||
if (wordPosStateIdx > 6) {
|
||||
wordPosStateIdx = 1;
|
||||
}
|
||||
rightSideComponentIdx++;
|
||||
if (rightSideComponentIdx > 2) {
|
||||
rightSideComponentIdx = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "right":
|
||||
switch (keyPress) {
|
||||
case "UP": {
|
||||
const newWordPosStateIdx =
|
||||
wordPosStateIdx - 1 < 1 ? 6 : wordPosStateIdx - 1;
|
||||
const newComponent = (() => {
|
||||
switch (activeMediaComponent) {
|
||||
case "fstWord":
|
||||
return "thirdWord";
|
||||
case "sndWord":
|
||||
return "fstWord";
|
||||
case "thirdWord":
|
||||
return "sndWord";
|
||||
}
|
||||
})();
|
||||
return {
|
||||
event: "media_rightside_up",
|
||||
newActiveComponent: newComponent,
|
||||
wordPosStateIdx: newWordPosStateIdx,
|
||||
};
|
||||
}
|
||||
case "DOWN": {
|
||||
const newWordPosStateIdx =
|
||||
wordPosStateIdx + 1 > 6 ? 1 : wordPosStateIdx + 1;
|
||||
const newComponent = (() => {
|
||||
switch (activeMediaComponent) {
|
||||
case "fstWord":
|
||||
return "sndWord";
|
||||
case "sndWord":
|
||||
return "thirdWord";
|
||||
case "thirdWord":
|
||||
return "fstWord";
|
||||
}
|
||||
})();
|
||||
|
||||
return {
|
||||
wordPosStateIdx: wordPosStateIdx,
|
||||
rightSideComponentIdx: rightSideComponentIdx,
|
||||
};
|
||||
};
|
||||
return {
|
||||
event: "media_rightside_down",
|
||||
newActiveComponent: newComponent,
|
||||
wordPosStateIdx: newWordPosStateIdx,
|
||||
};
|
||||
}
|
||||
|
||||
switch (keyPress) {
|
||||
case "UP":
|
||||
case "DOWN":
|
||||
case "RIGHT":
|
||||
case "LEFT":
|
||||
if (["fstWord", "sndWord", "thirdWord"].includes(activeMediaComponent)) {
|
||||
const rightSide = calculateNewRightSide(
|
||||
keyPress,
|
||||
wordPosStateIdx,
|
||||
rightSideComponentIdx
|
||||
);
|
||||
return {
|
||||
event: `media_rightside_${keyPress.toLowerCase()}`,
|
||||
rightSideComponentIdx: rightSide.rightSideComponentIdx,
|
||||
wordPosStateIdx: rightSide.wordPosStateIdx,
|
||||
};
|
||||
} else {
|
||||
const leftSideComponentIdx = keyPress === "UP" ? 0 : 1;
|
||||
return {
|
||||
event: `media_leftside_${keyPress.toLowerCase()}`,
|
||||
leftSideComponentIdx: leftSideComponentIdx,
|
||||
};
|
||||
}
|
||||
case "CIRCLE":
|
||||
switch (activeMediaComponent) {
|
||||
case "fstWord":
|
||||
case "sndWord":
|
||||
case "thirdWord":
|
||||
case "LEFT":
|
||||
return {
|
||||
event: "media_rightside_left",
|
||||
lastActiveComponent: activeMediaComponent,
|
||||
newActiveComponent: lastActiveMediaComponents.left,
|
||||
};
|
||||
|
||||
case "CIRCLE":
|
||||
const data = findNodeFromWord(
|
||||
activeMediaComponent,
|
||||
activeNode,
|
||||
|
@ -78,21 +99,10 @@ const handleMediaSceneKeyPress = (mediaSceneContext: any) => {
|
|||
);
|
||||
|
||||
if (data) {
|
||||
return { event: `media_${activeMediaComponent}_select`, ...data };
|
||||
return { event: `media_word_select`, ...data };
|
||||
} else {
|
||||
return { event: `word_node_not_found` };
|
||||
}
|
||||
default:
|
||||
if (activeMediaComponent === "play") {
|
||||
return {
|
||||
event: `media_play_select`,
|
||||
node: activeNode,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
event: `media_exit_select`,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
const handleSSknSceneKeyPress = (ssknSceneContext: any) => {
|
||||
const { keyPress, activeSSknComponent, activeNode } = ssknSceneContext;
|
||||
|
||||
switch (keyPress) {
|
||||
case "UP":
|
||||
case "DOWN":
|
||||
return {
|
||||
event: `sskn_${activeSSknComponent}_${keyPress.toLowerCase()}`,
|
||||
};
|
||||
case "CIRCLE":
|
||||
if (activeSSknComponent === "ok") {
|
||||
return {
|
||||
event: `sskn_ok_select`,
|
||||
node: activeNode,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
event: `sskn_cancel_select`,
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default handleSSknSceneKeyPress;
|
26
src/core/scene-keypress-handlers/handleSsknSceneKeyPress.ts
Normal file
26
src/core/scene-keypress-handlers/handleSsknSceneKeyPress.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
import { SsknSceneContext } from "../../store";
|
||||
|
||||
const handleSsknSceneKeyPress = (ssknSceneContext: SsknSceneContext) => {
|
||||
const { keyPress, activeSsknComponent, activeNode } = ssknSceneContext;
|
||||
|
||||
switch (keyPress) {
|
||||
case "UP":
|
||||
case "DOWN":
|
||||
return {
|
||||
event: `sskn_${activeSsknComponent}_${keyPress.toLowerCase()}`,
|
||||
};
|
||||
case "CIRCLE":
|
||||
if (activeSsknComponent === "ok") {
|
||||
return {
|
||||
event: `sskn_ok_select`,
|
||||
node: activeNode,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
event: `sskn_cancel_select`,
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default handleSsknSceneKeyPress;
|
|
@ -1,56 +0,0 @@
|
|||
import { useStore } from "../../../store";
|
||||
|
||||
const bootManager = (eventState: any) => {
|
||||
const setMainMenuComponentMatrixIdx = useStore.getState()
|
||||
.setMainMenuComponentMatrixIdx;
|
||||
|
||||
const setAuthorizeUserLetterIdx = useStore.getState()
|
||||
.setAuthorizeUserLetterIdx;
|
||||
|
||||
const setPlayerName = useStore.getState().setPlayerName;
|
||||
|
||||
const dispatchAction = (eventState: {
|
||||
event: string;
|
||||
authorizeUserLetterIdx: number;
|
||||
playerName: string;
|
||||
}) => {
|
||||
switch (eventState.event) {
|
||||
case "main_menu_up":
|
||||
return {
|
||||
action: () => setMainMenuComponentMatrixIdx(0),
|
||||
};
|
||||
case "main_menu_down":
|
||||
return {
|
||||
action: () => setMainMenuComponentMatrixIdx(1),
|
||||
};
|
||||
case "main_menu_authorize_user_select":
|
||||
return { action: () => setAuthorizeUserLetterIdx(0) };
|
||||
case "authorize_user_up":
|
||||
case "authorize_user_down":
|
||||
case "authorize_user_left":
|
||||
case "authorize_user_right":
|
||||
return {
|
||||
action: () =>
|
||||
setAuthorizeUserLetterIdx(eventState.authorizeUserLetterIdx),
|
||||
};
|
||||
case "authorize_user_back":
|
||||
return {
|
||||
action: () => setPlayerName(""),
|
||||
};
|
||||
case "update_player_name":
|
||||
return {
|
||||
action: () => setPlayerName(eventState.playerName),
|
||||
};
|
||||
case "remove_last_char":
|
||||
return {
|
||||
action: () => setPlayerName(eventState.playerName),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const { action } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) action();
|
||||
};
|
||||
|
||||
export default bootManager;
|
|
@ -1,27 +0,0 @@
|
|||
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":
|
||||
return {
|
||||
action: () => setBootSubscene("main_menu"),
|
||||
};
|
||||
case "main_menu_authorize_user_select":
|
||||
return {
|
||||
action: () => setBootSubscene("authorize_user"),
|
||||
};
|
||||
case "main_menu_load_data_select":
|
||||
return { action: () => setBootSubscene("load_data") };
|
||||
}
|
||||
};
|
||||
|
||||
const { action } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) action();
|
||||
};
|
||||
|
||||
export default bootSubsceneManager;
|
|
@ -1,24 +0,0 @@
|
|||
import { useStore } from "../../../store";
|
||||
|
||||
const endManager = (eventState: any) => {
|
||||
const setComponentMatrixIdx = useStore.getState().setEndComponentMatrixIdx;
|
||||
|
||||
const dispatchAction = (eventState: { event: string }) => {
|
||||
switch (eventState.event) {
|
||||
case "end_selection_up":
|
||||
return {
|
||||
action: () => setComponentMatrixIdx(0),
|
||||
};
|
||||
case "end_selection_down":
|
||||
return {
|
||||
action: () => setComponentMatrixIdx(1),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const { action } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) action();
|
||||
};
|
||||
|
||||
export default endManager;
|
|
@ -1,34 +0,0 @@
|
|||
import { useStore } from "../../store";
|
||||
import sleep from "../../utils/sleep";
|
||||
|
||||
const gameLoader = (eventState: any) => {
|
||||
const loadSiteSaveState = useStore.getState().loadSiteSaveState;
|
||||
const setLoadSuccessful = useStore.getState().setLoadSuccessful;
|
||||
|
||||
const dispatchAction = (eventState: { event: string; site: "a" | "b" }) => {
|
||||
switch (eventState.event) {
|
||||
case "pause_change_select":
|
||||
return {
|
||||
action: () => loadSiteSaveState(eventState.site === "a" ? "b" : "a"),
|
||||
};
|
||||
case "pause_load_select":
|
||||
case "load_data_yes":
|
||||
return {
|
||||
action: async () => {
|
||||
// todo check if data exists
|
||||
setLoadSuccessful(true);
|
||||
|
||||
await sleep(1200);
|
||||
//todo actually load
|
||||
setLoadSuccessful(undefined);
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const { action } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) action();
|
||||
};
|
||||
|
||||
export default gameLoader;
|
|
@ -1,33 +0,0 @@
|
|||
import { getSiteState, useStore } from "../../store";
|
||||
import sleep from "../../utils/sleep";
|
||||
|
||||
const gameSaver = (eventState: any) => {
|
||||
const setSiteSaveState = useStore.getState().setSiteSaveState;
|
||||
const setSaveSuccessful = useStore.getState().setSaveSuccessful;
|
||||
|
||||
const dispatchAction = (eventState: { event: string; site: "a" | "b" }) => {
|
||||
switch (eventState.event) {
|
||||
case "pause_change_select":
|
||||
return {
|
||||
action: () =>
|
||||
setSiteSaveState(eventState.site, getSiteState(eventState.site)),
|
||||
};
|
||||
case "pause_save_select":
|
||||
return {
|
||||
action: async () => {
|
||||
setSaveSuccessful(true);
|
||||
|
||||
await sleep(1200);
|
||||
//todo actually save
|
||||
setSaveSuccessful(undefined);
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const { action } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) action();
|
||||
};
|
||||
|
||||
export default gameSaver;
|
|
@ -1,23 +0,0 @@
|
|||
import { useStore } from "../../../store";
|
||||
|
||||
const idleManager = (eventState: any) => {
|
||||
const setIdleStarting = useStore.getState().setIdleStarting;
|
||||
const setIdleScene = useStore.getState().setIdleScene;
|
||||
|
||||
const dispatchAction = (eventState: {
|
||||
media: string;
|
||||
images: { "1": string; "2": string; "3": string } | undefined;
|
||||
nodeName: string | undefined;
|
||||
}) => ({
|
||||
action: () => {
|
||||
setIdleStarting(true);
|
||||
setIdleScene(eventState);
|
||||
},
|
||||
});
|
||||
|
||||
const { action } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) action();
|
||||
};
|
||||
|
||||
export default idleManager;
|
|
@ -1,24 +0,0 @@
|
|||
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;
|
|
@ -1,48 +0,0 @@
|
|||
import { useStore } from "../../../store";
|
||||
import sleep from "../../../utils/sleep";
|
||||
|
||||
const mainSubsceneManager = (eventState: any) => {
|
||||
const setMainSubscene = useStore.getState().setMainSubscene;
|
||||
|
||||
const dispatchAction = (eventState: { event: string }) => {
|
||||
switch (eventState.event) {
|
||||
case "word_node_not_found":
|
||||
return {
|
||||
action: () => setMainSubscene("not_found"),
|
||||
};
|
||||
case "level_selection_back":
|
||||
case "select_level_up":
|
||||
case "select_level_down":
|
||||
case "exit_not_found":
|
||||
return {
|
||||
action: () => setMainSubscene("site"),
|
||||
};
|
||||
case "toggle_level_selection":
|
||||
return {
|
||||
action: () => setMainSubscene("level_selection"),
|
||||
};
|
||||
case "pause_game":
|
||||
return {
|
||||
action: () => setMainSubscene("pause"),
|
||||
};
|
||||
case "pause_exit_select":
|
||||
case "pause_change_select":
|
||||
return {
|
||||
action: () => {
|
||||
setMainSubscene("site");
|
||||
},
|
||||
delay: 1800,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const { action, delay } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action)
|
||||
(async () => {
|
||||
if (delay) await sleep(delay);
|
||||
action();
|
||||
})();
|
||||
};
|
||||
|
||||
export default mainSubsceneManager;
|
|
@ -1,52 +0,0 @@
|
|||
import { useStore } from "../../../../store";
|
||||
import sleep from "../../../../utils/sleep";
|
||||
|
||||
type PauseManagerProps = { event: string; pauseMatrixIdx: number };
|
||||
|
||||
const pauseManager = (eventState: any) => {
|
||||
const setComponentMatrixIdx = useStore.getState().setPauseComponentMatrixIdx;
|
||||
const setExitAnimation = useStore.getState().setPauseExitAnimation;
|
||||
const setShowingAbout = useStore.getState().setShowingAbout;
|
||||
const setPermissionDenied = useStore.getState().setPermissionDenied;
|
||||
|
||||
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);
|
||||
setComponentMatrixIdx(2);
|
||||
},
|
||||
};
|
||||
case "show_permission_denied":
|
||||
return {
|
||||
action: async () => {
|
||||
setPermissionDenied(true);
|
||||
|
||||
await sleep(1200);
|
||||
setPermissionDenied(false);
|
||||
},
|
||||
};
|
||||
case "pause_about_select":
|
||||
return {
|
||||
action: () => setShowingAbout(true),
|
||||
};
|
||||
case "exit_about":
|
||||
return {
|
||||
action: () => setShowingAbout(false),
|
||||
};
|
||||
case "pause_game":
|
||||
return { action: () => setExitAnimation(false) };
|
||||
}
|
||||
};
|
||||
const { action } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) action();
|
||||
};
|
||||
|
||||
export default pauseManager;
|
|
@ -1,67 +0,0 @@
|
|||
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":
|
||||
case "throw_node_polytan":
|
||||
return { action: () => setLainMoveState("throw_node"), duration: 3900 };
|
||||
case "rip_node_media":
|
||||
case "rip_node_gate":
|
||||
case "rip_node_sskn":
|
||||
case "rip_node_tak":
|
||||
case "rip_node_polytan":
|
||||
return { action: () => setLainMoveState("rip_node"), duration: 6000 };
|
||||
case "knock_and_fall":
|
||||
case "knock":
|
||||
case "touch_and_scare":
|
||||
return {
|
||||
action: () => setLainMoveState(eventState.event),
|
||||
duration: 6000,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const { action, duration } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) {
|
||||
action();
|
||||
setTimeout(() => setLainMoveState("standing"), duration);
|
||||
}
|
||||
};
|
||||
|
||||
export default lainManager;
|
|
@ -1,30 +0,0 @@
|
|||
import { useStore } from "../../../../store";
|
||||
|
||||
const levelManager = (eventState: any) => {
|
||||
const setActiveLevel = useStore.getState().setActiveLevel;
|
||||
const setOldLevel = useStore.getState().setOldLevel;
|
||||
|
||||
const dispatchAction = (eventState: any) => {
|
||||
switch (eventState.event) {
|
||||
case "throw_node_media":
|
||||
case "rip_node_media":
|
||||
return {
|
||||
action: () => setOldLevel(eventState.level),
|
||||
};
|
||||
case "site_up":
|
||||
case "site_down":
|
||||
case "select_level_up":
|
||||
case "select_level_down":
|
||||
case "media_fstWord_select":
|
||||
case "media_sndWord_select":
|
||||
case "media_thirdWord_select":
|
||||
return { action: () => setActiveLevel(eventState.level) };
|
||||
}
|
||||
};
|
||||
|
||||
const { action } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) action();
|
||||
};
|
||||
|
||||
export default levelManager;
|
|
@ -1,191 +0,0 @@
|
|||
import { useStore } from "../../../../store";
|
||||
import { NodeDataType } from "../../../../components/MainScene/Site";
|
||||
import sleep from "../../../../utils/sleep";
|
||||
|
||||
const nodeManager = (eventState: any) => {
|
||||
const setActiveNode = useStore.getState().setNode;
|
||||
const setActiveNodePos = useStore.getState().setNodePos;
|
||||
const setActiveNodeRot = useStore.getState().setNodeRot;
|
||||
const setActiveNodeAttributes = useStore.getState().setNodeAttributes;
|
||||
|
||||
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 = async (siteRotY: number) => {
|
||||
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);
|
||||
|
||||
setActiveNodeAttributes(true, "interactedWith");
|
||||
|
||||
setActiveNodePos([fstCoordSet.x, 0, fstCoordSet.z]);
|
||||
|
||||
await sleep(800);
|
||||
setActiveNodePos([sndCoordSet.x, 0, sndCoordSet.z]);
|
||||
|
||||
await sleep(1800);
|
||||
setActiveNodePos([thirdCoordSet.x, 0, sndCoordSet.z]);
|
||||
setActiveNodeRot([0, 0, -0.005]);
|
||||
|
||||
await sleep(100);
|
||||
setActiveNodePos([fourthCoordSet.x, 0, fourthCoordSet.z]);
|
||||
setActiveNodeRot([0, 0, -0.5]);
|
||||
|
||||
await sleep(1100);
|
||||
setActiveNodeRot([0, 0, 0]);
|
||||
setActiveNodeAttributes(false, "interactedWith");
|
||||
};
|
||||
|
||||
const animateNodeKnock = async (siteRotY: number) => {
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(1.1, 0.2, siteRotY);
|
||||
|
||||
setActiveNodeAttributes(true, "interactedWith");
|
||||
|
||||
setActiveNodePos([fstCoordSet.x, -0.6, fstCoordSet.z]);
|
||||
|
||||
await sleep(2500);
|
||||
setActiveNodeAttributes(false, "interactedWith");
|
||||
};
|
||||
|
||||
const animateNodeKnockAndFall = async (siteRotY: number) => {
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(1.1, 0.2, siteRotY);
|
||||
|
||||
setActiveNodeAttributes(true, "interactedWith");
|
||||
|
||||
setActiveNodePos([fstCoordSet.x, -0.6, fstCoordSet.z]);
|
||||
|
||||
await sleep(2300);
|
||||
setActiveNodeAttributes(false, "visible");
|
||||
|
||||
await sleep(200);
|
||||
setActiveNodeAttributes(false, "interactedWith");
|
||||
|
||||
await sleep(700);
|
||||
setActiveNodeAttributes(true, "visible");
|
||||
};
|
||||
|
||||
const animateNodeTouchAndScare = async (siteRotY: number) => {
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(-0.6, 0.2, siteRotY);
|
||||
|
||||
setActiveNodeAttributes(true, "interactedWith");
|
||||
|
||||
setActiveNodePos([fstCoordSet.x, 0, fstCoordSet.z]);
|
||||
|
||||
await sleep(1200);
|
||||
setActiveNodeAttributes(true, "exploding");
|
||||
setActiveNodeAttributes(false, "visible");
|
||||
|
||||
await sleep(200);
|
||||
setActiveNodeAttributes(false, "interactedWith");
|
||||
setActiveNodeRot([0, 0, 0]);
|
||||
|
||||
await sleep(1750);
|
||||
setActiveNodeAttributes(false, "exploding");
|
||||
|
||||
await sleep(350);
|
||||
setActiveNodeAttributes(true, "visible");
|
||||
};
|
||||
|
||||
const animateShrinkAndRip = async (siteRotY: number) => {
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(0.9, 0.3, siteRotY);
|
||||
const sndCoordSet = calculateCoordsBasedOnRotation(0.5, 0.2, siteRotY);
|
||||
const thirdCoordSet = calculateCoordsBasedOnRotation(0, 0.2, siteRotY);
|
||||
|
||||
setActiveNodeAttributes(true, "interactedWith");
|
||||
|
||||
setActiveNodePos([fstCoordSet.x, 0, fstCoordSet.z]);
|
||||
|
||||
await sleep(800);
|
||||
setActiveNodePos([sndCoordSet.x, 0, sndCoordSet.z]);
|
||||
|
||||
await sleep(2000);
|
||||
setActiveNodePos([thirdCoordSet.x, -0.4, thirdCoordSet.z]);
|
||||
|
||||
await sleep(200);
|
||||
setActiveNodeAttributes(true, "shrinking");
|
||||
|
||||
await sleep(200);
|
||||
setActiveNodePos([thirdCoordSet.x, -1.5, thirdCoordSet.z]);
|
||||
|
||||
await sleep(300);
|
||||
setActiveNodeAttributes(false, "visible");
|
||||
|
||||
await sleep(2900);
|
||||
setActiveNodeAttributes(false, "interactedWith");
|
||||
setActiveNodeAttributes(false, "shrinking");
|
||||
setActiveNodeRot([0, 0, 0]);
|
||||
|
||||
await sleep(1100);
|
||||
setActiveNodeAttributes(true, "visible");
|
||||
};
|
||||
|
||||
const updateActiveNode = async (node: NodeDataType) => {
|
||||
setActiveNode(node);
|
||||
};
|
||||
|
||||
const dispatchAction = (eventState: any) => {
|
||||
switch (eventState.event) {
|
||||
case "touch_and_scare":
|
||||
return {
|
||||
action: () => animateNodeTouchAndScare(eventState.siteRotY),
|
||||
};
|
||||
case "knock_and_fall":
|
||||
return {
|
||||
action: () => animateNodeKnockAndFall(eventState.siteRotY),
|
||||
};
|
||||
case "knock":
|
||||
return {
|
||||
action: () => animateNodeKnock(eventState.siteRotY),
|
||||
};
|
||||
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),
|
||||
delay: 3900,
|
||||
};
|
||||
case "change_node":
|
||||
case "media_fstWord_select":
|
||||
case "media_sndWord_select":
|
||||
case "media_thirdWord_select":
|
||||
return {
|
||||
action: () => updateActiveNode(eventState.node),
|
||||
};
|
||||
case "throw_node_media":
|
||||
case "throw_node_gate":
|
||||
case "throw_node_sskn":
|
||||
case "throw_node_tak":
|
||||
case "throw_node_polytan":
|
||||
return {
|
||||
action: () => animateActiveNodeThrow(eventState.siteRotY),
|
||||
};
|
||||
case "rip_node_media":
|
||||
case "rip_node_gate":
|
||||
case "rip_node_sskn":
|
||||
case "rip_node_tak":
|
||||
case "rip_node_polytan":
|
||||
return {
|
||||
action: () => animateShrinkAndRip(eventState.siteRotY),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const { action, delay } = { ...dispatchAction(eventState) };
|
||||
|
||||
(async () => {
|
||||
if (delay) await sleep(delay);
|
||||
if (action) action();
|
||||
})();
|
||||
};
|
||||
|
||||
export default nodeManager;
|
|
@ -1,51 +0,0 @@
|
|||
import { useStore } from "../../../../store";
|
||||
import sleep from "../../../../utils/sleep";
|
||||
|
||||
const siteManager = (eventState: any) => {
|
||||
const setRotY = useStore.getState().setSiteRotY;
|
||||
const setRotX = useStore.getState().setSiteRotX;
|
||||
const setOldRot = useStore.getState().setOldSiteRot;
|
||||
|
||||
const dispatchAction = (eventState: any) => {
|
||||
switch (eventState.event) {
|
||||
case "throw_node_media":
|
||||
case "rip_node_media":
|
||||
return {
|
||||
action: () => setOldRot([0, eventState.siteRotY, 0]),
|
||||
};
|
||||
case "site_left":
|
||||
case "site_right":
|
||||
case "media_fstWord_select":
|
||||
case "media_sndWord_select":
|
||||
case "media_thirdWord_select":
|
||||
return {
|
||||
action: async () => {
|
||||
setRotY(eventState.siteRotY);
|
||||
},
|
||||
delay: 1100,
|
||||
};
|
||||
case "pause_game":
|
||||
return {
|
||||
action: () => {
|
||||
setRotX(Math.PI / 2);
|
||||
},
|
||||
delay: 3600,
|
||||
};
|
||||
case "pause_exit_select":
|
||||
case "pause_change_select":
|
||||
return {
|
||||
action: () => setRotX(0),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const { action, delay } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action)
|
||||
(async () => {
|
||||
if (delay) await sleep(delay);
|
||||
action();
|
||||
})();
|
||||
};
|
||||
|
||||
export default siteManager;
|
|
@ -1,80 +0,0 @@
|
|||
import { useStore } from "../../../store";
|
||||
|
||||
const mediaManager = (eventState: any) => {
|
||||
const toggleSide = useStore.getState().toggleMediaSide;
|
||||
const setLeftComponentMatrixIdx = useStore.getState()
|
||||
.setMediaLeftComponentMatrixIdx;
|
||||
|
||||
const setWordSelected = useStore.getState().setWordSelected;
|
||||
|
||||
const updateRightSide = useStore.getState().updateRightSide;
|
||||
|
||||
const setPercentageElapsed = useStore.getState().setPercentageElapsed;
|
||||
|
||||
const playMedia = () => {
|
||||
const mediaElement = document.getElementById("media") as HTMLMediaElement;
|
||||
|
||||
if (mediaElement && mediaElement.paused) {
|
||||
setPercentageElapsed(0);
|
||||
|
||||
mediaElement.play();
|
||||
}
|
||||
};
|
||||
|
||||
const exitMedia = () => {
|
||||
const mediaElement = document.getElementById("media") as HTMLMediaElement;
|
||||
if (mediaElement) {
|
||||
mediaElement.pause();
|
||||
mediaElement.currentTime = 0;
|
||||
}
|
||||
};
|
||||
|
||||
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() };
|
||||
case "media_fstWord_select":
|
||||
case "media_sndWord_select":
|
||||
case "media_thirdWord_select":
|
||||
return {
|
||||
action: () => {
|
||||
exitMedia();
|
||||
setWordSelected(true);
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const { action } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) action();
|
||||
};
|
||||
|
||||
export default mediaManager;
|
|
@ -1,101 +0,0 @@
|
|||
import { useStore } from "../../store";
|
||||
import { NodeDataType } from "../../components/MainScene/Site";
|
||||
import sleep from "../../utils/sleep";
|
||||
|
||||
const progressManager = (eventState: any) => {
|
||||
const updateNodeViewed = useStore.getState().setNodeViewed;
|
||||
const setPolytanPartUnlocked = useStore.getState().setPolytanPartUnlocked;
|
||||
const incrementGateLvl = useStore.getState().incrementGateLvl;
|
||||
const incrementSSknLvl = useStore.getState().incrementSSknLvl;
|
||||
|
||||
const nodesThatTurnInvisibleAfterWatching = ["SSkn", "GaTE", "P2"];
|
||||
|
||||
const dispatchAction = (eventState: {
|
||||
event: string;
|
||||
bodyPart: string;
|
||||
node: NodeDataType;
|
||||
}) => {
|
||||
switch (eventState.event) {
|
||||
case "throw_node_tak":
|
||||
case "rip_node_tak":
|
||||
return {
|
||||
action: () =>
|
||||
updateNodeViewed(eventState.node.node_name, {
|
||||
is_viewed: 1,
|
||||
is_visible: Number(
|
||||
!nodesThatTurnInvisibleAfterWatching.some((node) =>
|
||||
eventState.node.node_name.includes(node)
|
||||
)
|
||||
),
|
||||
}),
|
||||
delay: 8000,
|
||||
};
|
||||
case "rip_node_gate":
|
||||
case "throw_node_gate":
|
||||
return {
|
||||
action: () => {
|
||||
updateNodeViewed(eventState.node.node_name, {
|
||||
is_viewed: 1,
|
||||
is_visible: Number(
|
||||
!nodesThatTurnInvisibleAfterWatching.some((node) =>
|
||||
eventState.node.node_name.includes(node)
|
||||
)
|
||||
),
|
||||
});
|
||||
incrementGateLvl();
|
||||
},
|
||||
};
|
||||
case "throw_node_polytan":
|
||||
case "rip_node_polytan":
|
||||
return {
|
||||
action: () => {
|
||||
updateNodeViewed(eventState.node.node_name, {
|
||||
is_viewed: 1,
|
||||
is_visible: Number(
|
||||
!nodesThatTurnInvisibleAfterWatching.some((node) =>
|
||||
eventState.node.node_name.includes(node)
|
||||
)
|
||||
),
|
||||
});
|
||||
setPolytanPartUnlocked(eventState.bodyPart);
|
||||
},
|
||||
};
|
||||
case "media_play_select":
|
||||
return {
|
||||
action: () =>
|
||||
updateNodeViewed(eventState.node.node_name, {
|
||||
is_viewed: 1,
|
||||
is_visible: Number(
|
||||
!nodesThatTurnInvisibleAfterWatching.some((node) =>
|
||||
eventState.node.node_name.includes(node)
|
||||
)
|
||||
),
|
||||
}),
|
||||
};
|
||||
case "sskn_ok_select":
|
||||
return {
|
||||
action: () => {
|
||||
updateNodeViewed(eventState.node.node_name, {
|
||||
is_viewed: 1,
|
||||
is_visible: Number(
|
||||
!nodesThatTurnInvisibleAfterWatching.some((node) =>
|
||||
eventState.node.node_name.includes(node)
|
||||
)
|
||||
),
|
||||
});
|
||||
incrementSSknLvl();
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const { action, delay } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action)
|
||||
(async () => {
|
||||
if (delay) await sleep(delay);
|
||||
action();
|
||||
})();
|
||||
};
|
||||
|
||||
export default progressManager;
|
|
@ -1,44 +0,0 @@
|
|||
import { useStore } from "../../store";
|
||||
import sleep from "../../utils/sleep";
|
||||
|
||||
const promptManager = (eventState: any) => {
|
||||
const setComponentMatrixIdx = useStore.getState().setPromptComponentMatrixIdx;
|
||||
const setPromptVisible = useStore.getState().setPromptVisible;
|
||||
|
||||
const exitAndResetPrompt = () => {
|
||||
setPromptVisible(false);
|
||||
setComponentMatrixIdx(1);
|
||||
};
|
||||
|
||||
const dispatchAction = (eventState: { event: string; scene: string }) => {
|
||||
switch (eventState.event) {
|
||||
case "display_prompt": {
|
||||
return { action: () => setPromptVisible(true) };
|
||||
}
|
||||
case "prompt_right":
|
||||
return {
|
||||
action: () => setComponentMatrixIdx(1),
|
||||
};
|
||||
case "prompt_left":
|
||||
return { action: () => setComponentMatrixIdx(0) };
|
||||
case "pause_change_select":
|
||||
return { action: () => exitAndResetPrompt() };
|
||||
case "exit_prompt":
|
||||
case "load_data_no":
|
||||
return { action: () => exitAndResetPrompt() };
|
||||
case "main_menu_load_data_select":
|
||||
return {
|
||||
action: async () => {
|
||||
await sleep(500);
|
||||
setPromptVisible(true);
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const { action } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) action();
|
||||
};
|
||||
|
||||
export default promptManager;
|
|
@ -1,103 +0,0 @@
|
|||
import { useStore } from "../../store";
|
||||
import sleep from "../../utils/sleep";
|
||||
|
||||
const sceneManager = (eventState: any) => {
|
||||
const dispatchAction = (eventState: { event: string; scene: string }) => {
|
||||
switch (eventState.event) {
|
||||
case "throw_node_sskn":
|
||||
case "rip_node_sskn":
|
||||
return {
|
||||
action: () => {
|
||||
useStore.setState({
|
||||
currentScene: eventState.scene,
|
||||
intro: false,
|
||||
ssknComponentMatrixIdx: 0,
|
||||
ssknLoading: false,
|
||||
});
|
||||
},
|
||||
delay: eventState.event === "throw_node_sskn" ? 3450 : 6000,
|
||||
};
|
||||
case "throw_node_media":
|
||||
case "rip_node_media":
|
||||
return {
|
||||
action: () => {
|
||||
useStore.setState({
|
||||
currentScene: eventState.scene,
|
||||
intro: false,
|
||||
mediaWordPosStateIdx: 1,
|
||||
mediaComponentMatrixIndices: {
|
||||
sideIdx: 0,
|
||||
leftSideIdx: 0,
|
||||
rightSideIdx: 0,
|
||||
},
|
||||
});
|
||||
},
|
||||
delay: eventState.event === "throw_node_media" ? 3450 : 6000,
|
||||
};
|
||||
case "throw_node_gate":
|
||||
case "throw_node_tak":
|
||||
case "throw_node_polytan":
|
||||
return {
|
||||
action: () => {
|
||||
useStore.setState({ currentScene: eventState.scene, intro: false });
|
||||
},
|
||||
delay: 3450,
|
||||
};
|
||||
case "rip_node_gate":
|
||||
case "rip_node_tak":
|
||||
case "rip_node_polytan":
|
||||
return {
|
||||
action: () => {
|
||||
useStore.setState({ currentScene: eventState.scene, intro: false });
|
||||
},
|
||||
delay: 6000,
|
||||
};
|
||||
case "media_exit_select":
|
||||
case "sskn_cancel_select":
|
||||
case "media_fstWord_select":
|
||||
case "media_sndWord_select":
|
||||
case "media_thirdWord_select":
|
||||
case "word_node_not_found":
|
||||
return {
|
||||
action: () =>
|
||||
useStore.setState({ currentScene: "main", intro: false }),
|
||||
};
|
||||
case "sskn_ok_select":
|
||||
return {
|
||||
action: () => {
|
||||
useStore.setState({ currentScene: "main", intro: false });
|
||||
},
|
||||
delay: 6000,
|
||||
};
|
||||
case "pause_change_select":
|
||||
case "end_continue_select":
|
||||
return {
|
||||
action: () =>
|
||||
useStore.setState({ currentScene: "change_disc", intro: true }),
|
||||
};
|
||||
case "play_idle_media":
|
||||
return {
|
||||
action: () =>
|
||||
useStore.setState({ currentScene: "idle_media", intro: false }),
|
||||
};
|
||||
case "start_new_game":
|
||||
return {
|
||||
action: () => useStore.setState({ currentScene: "main" }),
|
||||
};
|
||||
case "end_end_select":
|
||||
return {
|
||||
action: () => useStore.setState({ currentScene: "boot" }),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const { action, delay } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action)
|
||||
(async () => {
|
||||
if (delay) await sleep(delay);
|
||||
action();
|
||||
})();
|
||||
};
|
||||
|
||||
export default sceneManager;
|
|
@ -1,179 +0,0 @@
|
|||
import { playAudio } from "../../store";
|
||||
import * as audio from "../../static/sfx";
|
||||
import sleep from "../../utils/sleep";
|
||||
|
||||
const soundManager = (eventState: any) => {
|
||||
const dispatchAction = (eventState: { event: string; scene: string }) => {
|
||||
switch (eventState.event) {
|
||||
case "knock_and_fall":
|
||||
return {
|
||||
action: async () => {
|
||||
await sleep(1200);
|
||||
playAudio(audio.sound14);
|
||||
|
||||
await sleep(1100);
|
||||
|
||||
playAudio(audio.sound19);
|
||||
|
||||
await sleep(850);
|
||||
playAudio(audio.sound33);
|
||||
},
|
||||
};
|
||||
case "knock":
|
||||
return {
|
||||
action: async () => {
|
||||
await sleep(1200);
|
||||
playAudio(audio.sound18);
|
||||
},
|
||||
};
|
||||
case "touch_and_scare":
|
||||
return {
|
||||
action: async () => {
|
||||
await sleep(2400);
|
||||
playAudio(audio.sound17);
|
||||
|
||||
await sleep(750);
|
||||
playAudio(audio.sound33);
|
||||
},
|
||||
};
|
||||
case "throw_node_media":
|
||||
case "throw_node_gate":
|
||||
case "throw_node_sskn":
|
||||
case "throw_node_tak":
|
||||
case "throw_node_polytan":
|
||||
return {
|
||||
action: async () => {
|
||||
playAudio(audio.sound0);
|
||||
|
||||
await sleep(1600);
|
||||
playAudio(audio.sound12);
|
||||
|
||||
await sleep(1200);
|
||||
playAudio(audio.sound13);
|
||||
playAudio(audio.sound14);
|
||||
},
|
||||
};
|
||||
case "rip_node_media":
|
||||
case "rip_node_gate":
|
||||
case "rip_node_sskn":
|
||||
case "rip_node_tak":
|
||||
case "rip_node_polytan":
|
||||
return {
|
||||
action: async () => {
|
||||
playAudio(audio.sound0);
|
||||
|
||||
await sleep(1600);
|
||||
playAudio(audio.sound12);
|
||||
|
||||
await sleep(2400);
|
||||
playAudio(audio.sound15);
|
||||
playAudio(audio.sound13);
|
||||
},
|
||||
};
|
||||
|
||||
case "update_player_name":
|
||||
case "update_player_name_denied":
|
||||
case "main_menu_authorize_user_select":
|
||||
case "main_menu_load_data_select":
|
||||
case "show_permission_denied":
|
||||
case "pause_about_select":
|
||||
case "display_prompt":
|
||||
case "pause_exit_select":
|
||||
case "end_continue_select":
|
||||
case "end_end_select":
|
||||
return {
|
||||
action: () => playAudio(audio.sound0),
|
||||
};
|
||||
case "site_left":
|
||||
case "site_right":
|
||||
return {
|
||||
action: async () => {
|
||||
await sleep(1100);
|
||||
playAudio(audio.sound6);
|
||||
playAudio(audio.sound34);
|
||||
},
|
||||
};
|
||||
case "pause_game":
|
||||
return {
|
||||
action: async () => {
|
||||
playAudio(audio.sound7);
|
||||
|
||||
await sleep(3400);
|
||||
playAudio(audio.sound23);
|
||||
},
|
||||
};
|
||||
case "select_level_up":
|
||||
case "select_level_down":
|
||||
return {
|
||||
action: async () => {
|
||||
await sleep(1300);
|
||||
playAudio(audio.sound10);
|
||||
playAudio(audio.sound9);
|
||||
|
||||
await sleep(1400);
|
||||
playAudio(audio.sound8);
|
||||
},
|
||||
};
|
||||
case "site_up":
|
||||
case "site_down":
|
||||
return {
|
||||
action: async () => {
|
||||
playAudio(audio.sound13);
|
||||
|
||||
await sleep(1300);
|
||||
playAudio(audio.sound10);
|
||||
playAudio(audio.sound9);
|
||||
|
||||
await sleep(1400);
|
||||
playAudio(audio.sound8);
|
||||
},
|
||||
};
|
||||
case "main_menu_down":
|
||||
case "main_menu_up":
|
||||
case "prompt_left":
|
||||
case "prompt_right":
|
||||
case "change_node":
|
||||
case "toggle_level_selection":
|
||||
case "level_selection_back":
|
||||
case "pause_up":
|
||||
case "pause_down":
|
||||
case "media_leftside_down":
|
||||
case "media_leftside_up":
|
||||
case "media_rightside_down":
|
||||
case "media_rightside_up":
|
||||
case "end_selection_up":
|
||||
case "end_selection_down":
|
||||
return {
|
||||
action: () => playAudio(audio.sound1),
|
||||
};
|
||||
case "authorize_user_back":
|
||||
case "remove_last_char":
|
||||
case "load_data_no":
|
||||
case "media_fstWord_select":
|
||||
case "media_sndWord_select":
|
||||
case "media_thirdWord_select":
|
||||
case "media_exit_select":
|
||||
return {
|
||||
action: () => playAudio(audio.sound29),
|
||||
};
|
||||
case "load_data_yes":
|
||||
case "exit_prompt":
|
||||
case "pause_save_select":
|
||||
case "pause_load_select":
|
||||
case "pause_change_select":
|
||||
return {
|
||||
action: () => playAudio(audio.sound28),
|
||||
};
|
||||
case "word_node_not_found":
|
||||
return {
|
||||
action: () => playAudio(audio.sound30),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const { action } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) action();
|
||||
};
|
||||
|
||||
export default soundManager;
|
|
@ -1,31 +0,0 @@
|
|||
import { useStore } from "../../../store";
|
||||
|
||||
const ssknManager = (eventState: any) => {
|
||||
const toggleComponentMatrixIdx = useStore.getState()
|
||||
.toggleSSknComponentMatrixIdx;
|
||||
const setSSknLoading = useStore.getState().setSSknLoading;
|
||||
|
||||
const dispatchAction = (eventState: { event: string }) => {
|
||||
switch (eventState.event) {
|
||||
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;
|
|
@ -1743,31 +1743,31 @@
|
|||
"is_viewed": 0,
|
||||
"is_visible": 1
|
||||
},
|
||||
"SSkn01": {
|
||||
"Sskn01": {
|
||||
"is_viewed": 0,
|
||||
"is_visible": 1
|
||||
},
|
||||
"SSkn02": {
|
||||
"Sskn02": {
|
||||
"is_viewed": 0,
|
||||
"is_visible": 1
|
||||
},
|
||||
"SSkn03": {
|
||||
"Sskn03": {
|
||||
"is_viewed": 0,
|
||||
"is_visible": 1
|
||||
},
|
||||
"SSkn04": {
|
||||
"Sskn04": {
|
||||
"is_viewed": 0,
|
||||
"is_visible": 1
|
||||
},
|
||||
"SSkn04#": {
|
||||
"Sskn04#": {
|
||||
"is_viewed": 0,
|
||||
"is_visible": 1
|
||||
},
|
||||
"SSkn05": {
|
||||
"Sskn05": {
|
||||
"is_viewed": 0,
|
||||
"is_visible": 1
|
||||
},
|
||||
"SSkn06": {
|
||||
"Sskn06": {
|
||||
"is_viewed": 0,
|
||||
"is_visible": 1
|
||||
},
|
||||
|
|
|
@ -1644,7 +1644,7 @@
|
|||
"3": "-1"
|
||||
},
|
||||
"media_file": "INS01.STR",
|
||||
"node_name": "SSkn01",
|
||||
"node_name": "Sskn01",
|
||||
"required_final_video_viewcount": 0,
|
||||
"site": "A",
|
||||
"title": "mT up-date App.",
|
||||
|
@ -2748,7 +2748,7 @@
|
|||
"3": "-1"
|
||||
},
|
||||
"media_file": "INS02.STR",
|
||||
"node_name": "SSkn02",
|
||||
"node_name": "Sskn02",
|
||||
"required_final_video_viewcount": 0,
|
||||
"site": "A",
|
||||
"title": "mT up-date App.",
|
||||
|
@ -4892,7 +4892,7 @@
|
|||
"3": "-1"
|
||||
},
|
||||
"media_file": "INS03.STR",
|
||||
"node_name": "SSkn03",
|
||||
"node_name": "Sskn03",
|
||||
"required_final_video_viewcount": 0,
|
||||
"site": "A",
|
||||
"title": "mT up-date App.",
|
||||
|
@ -7302,7 +7302,7 @@
|
|||
"3": "-1"
|
||||
},
|
||||
"media_file": "INS04.STR",
|
||||
"node_name": "SSkn04",
|
||||
"node_name": "Sskn04",
|
||||
"required_final_video_viewcount": 0,
|
||||
"site": "A",
|
||||
"title": "mT up-date App.",
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
"3": "-1"
|
||||
},
|
||||
"media_file": "INS05.STR",
|
||||
"node_name": "SSkn04#",
|
||||
"node_name": "Sskn04#",
|
||||
"required_final_video_viewcount": 0,
|
||||
"site": "B",
|
||||
"title": "mT up-date App.",
|
||||
|
@ -1510,7 +1510,7 @@
|
|||
"3": "-1"
|
||||
},
|
||||
"media_file": "INS06.STR",
|
||||
"node_name": "SSkn05",
|
||||
"node_name": "Sskn05",
|
||||
"required_final_video_viewcount": 0,
|
||||
"site": "B",
|
||||
"title": "mT up-date App.",
|
||||
|
@ -2968,7 +2968,7 @@
|
|||
"3": "-1"
|
||||
},
|
||||
"media_file": "INS07.STR",
|
||||
"node_name": "SSkn06",
|
||||
"node_name": "Sskn06",
|
||||
"required_final_video_viewcount": 0,
|
||||
"site": "B",
|
||||
"title": "mT up-date App.",
|
||||
|
|
|
@ -3,13 +3,13 @@ import { useStore } from "../store";
|
|||
|
||||
const ChangeDiscScene = () => {
|
||||
const setScene = useStore((state) => state.setScene);
|
||||
const currentSite = useStore((state) => state.activeSite);
|
||||
const activeSite = useStore((state) => state.activeSite);
|
||||
|
||||
useEffect(() => {
|
||||
if (currentSite === "a") {
|
||||
if (activeSite === "a") {
|
||||
document.getElementsByTagName("canvas")[0].className =
|
||||
"change-disc-scene-a-background";
|
||||
} else if (currentSite === "b") {
|
||||
} else if (activeSite === "b") {
|
||||
document.getElementsByTagName("canvas")[0].className =
|
||||
"change-disc-scene-b-background";
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ const ChangeDiscScene = () => {
|
|||
document.getElementsByTagName("canvas")[0].className =
|
||||
"main-scene-background";
|
||||
};
|
||||
}, [currentSite, setScene]);
|
||||
}, [activeSite, setScene]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
|
|
@ -9,9 +9,16 @@ const GateScene = () => {
|
|||
const gateLvl = useStore((state) => state.gateLvl);
|
||||
const [introAnim, setIntroAnim] = useState(true);
|
||||
|
||||
const activeNodeName = useStore((state) => state.activeNode.node_name);
|
||||
const setNodeViewed = useStore((state) => state.setNodeViewed);
|
||||
|
||||
useEffect(() => {
|
||||
setNodeViewed(activeNodeName, {
|
||||
is_viewed: 1,
|
||||
is_visible: 0,
|
||||
});
|
||||
setTimeout(() => setIntroAnim(false), 2500);
|
||||
}, []);
|
||||
}, [activeNodeName, setNodeViewed]);
|
||||
|
||||
return (
|
||||
<perspectiveCamera position-z={3}>
|
||||
|
|
|
@ -17,11 +17,13 @@ import NotFound from "../components/MainScene/NotFound";
|
|||
import PausePopUps from "../components/MainScene/PauseSubscene/PausePopUps";
|
||||
import * as audio from "../static/sfx";
|
||||
import Loading from "../components/Loading";
|
||||
import usePrevious from "../hooks/usePrevious";
|
||||
|
||||
const MainScene = () => {
|
||||
const intro = useStore((state) => state.intro);
|
||||
const [paused, setPaused] = useState(false);
|
||||
const subscene = useStore((state) => state.mainSubscene);
|
||||
const prevData = usePrevious({ subscene });
|
||||
|
||||
const wordSelected = useStore((state) => state.wordSelected);
|
||||
const setWordSelected = useStore((state) => state.setWordSelected);
|
||||
|
@ -29,10 +31,10 @@ const MainScene = () => {
|
|||
useEffect(() => {
|
||||
if (subscene === "pause") {
|
||||
setTimeout(() => setPaused(true), 3400);
|
||||
} else {
|
||||
} else if (prevData?.subscene === "pause" && subscene === "site") {
|
||||
setPaused(false);
|
||||
}
|
||||
}, [subscene]);
|
||||
}, [prevData?.subscene, subscene]);
|
||||
|
||||
useEffect(() => {
|
||||
if (wordSelected) {
|
||||
|
|
|
@ -13,6 +13,7 @@ import Loading from "../components/Loading";
|
|||
const MediaScene = () => {
|
||||
const percentageElapsed = useStore((state) => state.mediaPercentageElapsed);
|
||||
|
||||
const setInputCooldown = useStore((state) => state.setInputCooldown);
|
||||
const setAudioAnalyser = useStore((state) => state.setAudioAnalyser);
|
||||
|
||||
const activeNode = useStore((state) => state.activeNode);
|
||||
|
@ -70,7 +71,8 @@ const MediaScene = () => {
|
|||
|
||||
useEffect(() => {
|
||||
setLoaded(true);
|
||||
}, []);
|
||||
setTimeout(() => setInputCooldown(false), 1000);
|
||||
}, [setInputCooldown]);
|
||||
|
||||
return (
|
||||
<perspectiveCamera position-z={3}>
|
||||
|
|
|
@ -1,12 +1,37 @@
|
|||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import PolytanBear from "../components/PolytanScene/PolytanBear";
|
||||
import PolytanBackground from "../components/PolytanScene/PolytanBackground";
|
||||
import { useStore } from "../store";
|
||||
|
||||
const PolytanScene = () => {
|
||||
const unlockedParts = useStore(
|
||||
(state) => state.polytanUnlockedParts
|
||||
);
|
||||
const unlockedParts = useStore((state) => state.polytanUnlockedParts);
|
||||
const setNodeViewed = useStore((state) => state.setNodeViewed);
|
||||
const setPolytanPartUnlocked = useStore.getState().setPolytanPartUnlocked;
|
||||
const activeNodeName = useStore((state) => state.activeNode.node_name);
|
||||
|
||||
useEffect(() => {
|
||||
setNodeViewed(activeNodeName, {
|
||||
is_viewed: 1,
|
||||
is_visible: 0,
|
||||
});
|
||||
const bodyPart = (() => {
|
||||
switch (parseInt(activeNodeName.slice(-1))) {
|
||||
case 6:
|
||||
return "head";
|
||||
case 5:
|
||||
return "rightArm";
|
||||
case 4:
|
||||
return "leftArm";
|
||||
case 3:
|
||||
return "rightLeg";
|
||||
case 2:
|
||||
return "leftLeg";
|
||||
case 1:
|
||||
return "body";
|
||||
}
|
||||
})();
|
||||
if (bodyPart) setPolytanPartUnlocked(bodyPart);
|
||||
}, [activeNodeName, setNodeViewed, setPolytanPartUnlocked]);
|
||||
|
||||
return (
|
||||
<perspectiveCamera>
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
import React from "react";
|
||||
import SSknIcon from "../components/SSknScene/SSknIcon";
|
||||
import SSknBackground from "../components/SSknScene/SSknBackground";
|
||||
import SSknHUD from "../components/SSknScene/SSknHUD";
|
||||
|
||||
const SSknScene = () => {
|
||||
return (
|
||||
<>
|
||||
<SSknBackground />
|
||||
<SSknIcon />
|
||||
<SSknHUD />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default SSknScene;
|
14
src/scenes/SsknScene.tsx
Normal file
14
src/scenes/SsknScene.tsx
Normal file
|
@ -0,0 +1,14 @@
|
|||
import React from "react";
|
||||
import SsknIcon from "../components/SsknScene/SsknIcon";
|
||||
import SsknBackground from "../components/SsknScene/SsknBackground";
|
||||
import SsknHUD from "../components/SsknScene/SsknHUD";
|
||||
|
||||
const SsknScene = () => (
|
||||
<>
|
||||
<SsknBackground />
|
||||
<SsknIcon />
|
||||
<SsknHUD />
|
||||
</>
|
||||
);
|
||||
|
||||
export default SsknScene;
|
|
@ -6,14 +6,22 @@ const TaKScene = () => {
|
|||
const setScene = useStore((state) => state.setScene);
|
||||
const setAudioAnalyser = useStore((state) => state.setAudioAnalyser);
|
||||
|
||||
const nodeMedia = useStore((state) => state.activeNode.media_file);
|
||||
const nodeName = useStore((state) => state.activeNode.node_name);
|
||||
const activeNode = useStore((state) => state.activeNode);
|
||||
|
||||
const [isIntro, setIsIntro] = useState(true);
|
||||
const [isOutro, setIsOutro] = useState(false);
|
||||
|
||||
const percentageElapsed = useStore((state) => state.mediaPercentageElapsed);
|
||||
|
||||
const setNodeViewed = useStore((state) => state.setNodeViewed);
|
||||
|
||||
useEffect(() => {
|
||||
setNodeViewed(activeNode.node_name, {
|
||||
is_viewed: 1,
|
||||
is_visible: 1,
|
||||
});
|
||||
}, [activeNode.node_name, setNodeViewed]);
|
||||
|
||||
useEffect(() => {
|
||||
if (percentageElapsed === 100) {
|
||||
setIsOutro(true);
|
||||
|
@ -30,30 +38,34 @@ const TaKScene = () => {
|
|||
if (mediaElement) {
|
||||
setAudioAnalyser(createAudioAnalyser());
|
||||
mediaElement.currentTime = 0;
|
||||
import("../static/webvtt/" + nodeName + ".vtt")
|
||||
import("../static/webvtt/" + activeNode.node_name + ".vtt")
|
||||
.then((vtt) => {
|
||||
if (vtt) trackElement.src = vtt.default;
|
||||
})
|
||||
// some entries have no spoken words, so the file doesnt exist. we catch that here.
|
||||
.catch((e) => console.log(e));
|
||||
|
||||
if (nodeMedia.includes("XA")) {
|
||||
import("../static/audio/" + nodeMedia + ".ogg").then((media) => {
|
||||
mediaElement.src = media.default;
|
||||
mediaElement.load();
|
||||
mediaElement.play();
|
||||
});
|
||||
if (activeNode.media_file.includes("XA")) {
|
||||
import("../static/audio/" + activeNode.media_file + ".ogg").then(
|
||||
(media) => {
|
||||
mediaElement.src = media.default;
|
||||
mediaElement.load();
|
||||
mediaElement.play();
|
||||
}
|
||||
);
|
||||
} else {
|
||||
import("../static/movie/" + nodeMedia + "[0].webm").then((media) => {
|
||||
mediaElement.src = media.default;
|
||||
mediaElement.load();
|
||||
mediaElement.play();
|
||||
});
|
||||
import("../static/movie/" + activeNode.media_file + "[0].webm").then(
|
||||
(media) => {
|
||||
mediaElement.src = media.default;
|
||||
mediaElement.load();
|
||||
mediaElement.play();
|
||||
}
|
||||
);
|
||||
}
|
||||
setIsIntro(false);
|
||||
}
|
||||
}, 3800);
|
||||
}, [nodeMedia, nodeName, setAudioAnalyser]);
|
||||
}, [activeNode.media_file, activeNode.node_name, setAudioAnalyser]);
|
||||
|
||||
return <LainSpeak intro={isIntro} outro={isOutro} />;
|
||||
};
|
||||
|
|
291
src/store.ts
291
src/store.ts
|
@ -2,20 +2,22 @@ import create from "zustand";
|
|||
import { combine } from "zustand/middleware";
|
||||
import * as THREE from "three";
|
||||
import game_progress from "./resources/initial_progress.json";
|
||||
import { NodeDataType } from "./components/MainScene/Site";
|
||||
import { NodeData } from "./components/MainScene/Site";
|
||||
import { getNodeById } from "./utils/node-utils";
|
||||
import site_a from "./resources/site_a.json";
|
||||
|
||||
export type GameProgress = typeof game_progress;
|
||||
|
||||
type State = {
|
||||
currentScene: string;
|
||||
|
||||
gameProgress: typeof game_progress;
|
||||
gameProgress: GameProgress;
|
||||
|
||||
mainSubscene: string;
|
||||
|
||||
intro: boolean;
|
||||
|
||||
activeNode: NodeDataType;
|
||||
activeNode: NodeData;
|
||||
activeNodePos: number[];
|
||||
activeNodeRot: number[];
|
||||
activeNodeAttributes: {
|
||||
|
@ -41,13 +43,11 @@ type State = {
|
|||
selectedLevel: number;
|
||||
|
||||
// end scene
|
||||
endComponentMatrix: ["end", "continue"];
|
||||
endComponentMatrixIdx: 0 | 1;
|
||||
activeEndComponent: "end" | "continue";
|
||||
endSceneSelectionVisible: boolean;
|
||||
|
||||
// pause
|
||||
pauseComponentMatrix: ["load", "about", "change", "save", "exit"];
|
||||
pauseComponentMatrixIdx: number;
|
||||
activePauseComponent: "load" | "about" | "change" | "save" | "exit";
|
||||
pauseExitAnimation: boolean;
|
||||
showingAbout: boolean;
|
||||
permissionDenied: boolean;
|
||||
|
@ -55,12 +55,13 @@ type State = {
|
|||
// media/media scene
|
||||
audioAnalyser: any;
|
||||
mediaPercentageElapsed: number;
|
||||
mediaComponentMatrix: [["play", "exit"], ["fstWord", "sndWord", "thirdWord"]];
|
||||
mediaComponentMatrixIndices: {
|
||||
sideIdx: 0 | 1;
|
||||
leftSideIdx: 0 | 1;
|
||||
rightSideIdx: 0 | 1 | 2;
|
||||
currentMediaSide: "left" | "right";
|
||||
activeMediaComponent: "play" | "exit" | "fstWord" | "sndWord" | "thirdWord";
|
||||
lastActiveMediaComponents: {
|
||||
left: "play" | "exit";
|
||||
right: "fstWord" | "sndWord" | "thirdWord";
|
||||
};
|
||||
|
||||
mediaWordPosStateIdx: number;
|
||||
wordSelected: boolean;
|
||||
|
||||
|
@ -71,8 +72,7 @@ type State = {
|
|||
idleNodeName: string | undefined;
|
||||
|
||||
// sskn scene
|
||||
ssknComponentMatrix: ["ok", "cancel"];
|
||||
ssknComponentMatrixIdx: 0 | 1;
|
||||
activeSsknComponent: "ok" | "cancel";
|
||||
ssknLoading: boolean;
|
||||
ssknLvl: number;
|
||||
|
||||
|
@ -93,15 +93,13 @@ type State = {
|
|||
playerName: string;
|
||||
|
||||
// boot scene
|
||||
mainMenuComponentMatrix: ["authorize_user", "load_data"];
|
||||
mainMenuComponentMatrixIdx: 0 | 1;
|
||||
activeMainMenuComponent: "authorize_user" | "load_data";
|
||||
authorizeUserLetterIdx: number;
|
||||
bootSubscene: "main_menu" | "load_data" | "authorize_user";
|
||||
|
||||
// prompt
|
||||
promptVisible: boolean;
|
||||
promptComponentMatrix: ["yes", "no"];
|
||||
promptComponentMatrixIdx: 1 | 0;
|
||||
activePromptComponent: "yes" | "no";
|
||||
|
||||
// status notifiers
|
||||
loadSuccessful: boolean | undefined;
|
||||
|
@ -110,23 +108,25 @@ type State = {
|
|||
// save state
|
||||
siteSaveState: {
|
||||
a: {
|
||||
activeNode: NodeDataType;
|
||||
activeNode: NodeData;
|
||||
siteRot: number[];
|
||||
activeLevel: string;
|
||||
};
|
||||
b: {
|
||||
activeNode: NodeDataType;
|
||||
activeNode: NodeData;
|
||||
siteRot: number[];
|
||||
activeLevel: string;
|
||||
};
|
||||
};
|
||||
|
||||
inputCooldown: boolean;
|
||||
};
|
||||
|
||||
export const useStore = create(
|
||||
combine(
|
||||
{
|
||||
// scene data
|
||||
currentScene: "main",
|
||||
currentScene: "boot",
|
||||
|
||||
// game progress
|
||||
gameProgress: game_progress,
|
||||
|
@ -169,13 +169,11 @@ export const useStore = create(
|
|||
selectedLevel: 4,
|
||||
|
||||
// end scene
|
||||
endComponentMatrix: ["end", "continue"],
|
||||
endComponentMatrixIdx: 0,
|
||||
activeEndComponent: "end",
|
||||
endSceneSelectionVisible: false,
|
||||
|
||||
// pause
|
||||
pauseComponentMatrix: ["load", "about", "change", "save", "exit"],
|
||||
pauseComponentMatrixIdx: 2,
|
||||
activePauseComponent: "change",
|
||||
pauseExitAnimation: false,
|
||||
showingAbout: false,
|
||||
permissionDenied: false,
|
||||
|
@ -183,17 +181,12 @@ export const useStore = create(
|
|||
// media scene
|
||||
audioAnalyser: undefined,
|
||||
mediaPercentageElapsed: 0,
|
||||
mediaComponentMatrix: [
|
||||
["play", "exit"],
|
||||
["fstWord", "sndWord", "thirdWord"],
|
||||
],
|
||||
mediaComponentMatrixIndices: {
|
||||
// 0 or 1 (left/right)
|
||||
sideIdx: 0,
|
||||
// 0 or 1 ("play" or "exit")
|
||||
leftSideIdx: 0,
|
||||
// 0 or 1 or 2 ("fstWord", "sndWord" or "thirdWord")
|
||||
rightSideIdx: 0,
|
||||
|
||||
currentMediaSide: "left",
|
||||
activeMediaComponent: "play",
|
||||
lastActiveMediaComponents: {
|
||||
left: "play",
|
||||
right: "fstWord",
|
||||
},
|
||||
mediaWordPosStateIdx: 1,
|
||||
wordSelected: false,
|
||||
|
@ -206,8 +199,7 @@ export const useStore = create(
|
|||
idleImages: site_a["00"]["0000"].image_table_indices,
|
||||
|
||||
// sskn scene
|
||||
ssknComponentMatrix: ["ok", "cancel"],
|
||||
ssknComponentMatrixIdx: 0,
|
||||
activeSsknComponent: "ok",
|
||||
ssknLoading: false,
|
||||
ssknLvl: 0,
|
||||
|
||||
|
@ -228,15 +220,13 @@ export const useStore = create(
|
|||
playerName: "アイウエオ",
|
||||
|
||||
// boot scene
|
||||
mainMenuComponentMatrix: ["authorize_user", "load_data"],
|
||||
mainMenuComponentMatrixIdx: 0,
|
||||
activeMainMenuComponent: "authorize_user",
|
||||
authorizeUserLetterIdx: 0,
|
||||
bootSubscene: "main_menu",
|
||||
|
||||
// prompt
|
||||
promptVisible: false,
|
||||
promptComponentMatrix: ["yes", "no"],
|
||||
promptComponentMatrixIdx: 1,
|
||||
activePromptComponent: "no",
|
||||
|
||||
// status notifiers
|
||||
loadSuccessful: undefined,
|
||||
|
@ -261,6 +251,8 @@ export const useStore = create(
|
|||
activeLevel: "04",
|
||||
},
|
||||
},
|
||||
|
||||
inputCooldown: false,
|
||||
} as State,
|
||||
(set) => ({
|
||||
// scene data setters
|
||||
|
@ -273,7 +265,7 @@ export const useStore = create(
|
|||
setIntro: (to: boolean) => set(() => ({ intro: to })),
|
||||
|
||||
// node setters
|
||||
setNode: (to: NodeDataType) => set(() => ({ activeNode: to })),
|
||||
setNode: (to: NodeData) => set(() => ({ activeNode: to })),
|
||||
setNodePos: (to: number[]) => set(() => ({ activeNodePos: to })),
|
||||
setNodeRot: (to: number[]) => set(() => ({ activeNodeRot: to })),
|
||||
setNodeAttributes: (
|
||||
|
@ -314,14 +306,10 @@ export const useStore = create(
|
|||
setSelectedLevel: (to: number) => set(() => ({ selectedLevel: to })),
|
||||
|
||||
// end scene setters
|
||||
setEndComponentMatrixIdx: (to: 0 | 1) =>
|
||||
set(() => ({ endComponentMatrixIdx: to })),
|
||||
setEndSceneSelectionVisible: (to: boolean) =>
|
||||
set(() => ({ endSceneSelectionVisible: to })),
|
||||
|
||||
// pause setters
|
||||
setPauseComponentMatrixIdx: (to: number) =>
|
||||
set(() => ({ pauseComponentMatrixIdx: to })),
|
||||
setPauseExitAnimation: (to: boolean) =>
|
||||
set(() => ({ pauseExitAnimation: to })),
|
||||
setShowingAbout: (to: boolean) => set(() => ({ showingAbout: to })),
|
||||
|
@ -330,33 +318,33 @@ export const useStore = create(
|
|||
|
||||
// media scene setters
|
||||
setAudioAnalyser: (to: any) => set(() => ({ audioAnalyser: to })),
|
||||
toggleMediaSide: () =>
|
||||
set((state) => ({
|
||||
mediaComponentMatrixIndices: {
|
||||
...state.mediaComponentMatrixIndices,
|
||||
sideIdx: Number(!state.mediaComponentMatrixIndices.sideIdx) as
|
||||
| 0
|
||||
| 1,
|
||||
},
|
||||
})),
|
||||
setMediaLeftComponentMatrixIdx: (to: 0 | 1) =>
|
||||
set((state) => ({
|
||||
mediaComponentMatrixIndices: {
|
||||
...state.mediaComponentMatrixIndices,
|
||||
leftSideIdx: to,
|
||||
},
|
||||
})),
|
||||
updateRightSide: (matrixIdx: 0 | 1 | 2, wordPosIdx: number) =>
|
||||
set((state) => ({
|
||||
mediaComponentMatrixIndices: {
|
||||
...state.mediaComponentMatrixIndices,
|
||||
rightSideIdx: matrixIdx,
|
||||
},
|
||||
mediaWordPosStateIdx: wordPosIdx,
|
||||
})),
|
||||
setPercentageElapsed: (to: number) =>
|
||||
set(() => ({ mediaPercentageElapsed: to })),
|
||||
setWordSelected: (to: boolean) => set(() => ({ wordSelected: to })),
|
||||
updateLeftSide: (
|
||||
newActiveComponent: "fstWord" | "sndWord" | "thirdWord",
|
||||
lastActiveComponent: "exit" | "play"
|
||||
) =>
|
||||
set((state) => ({
|
||||
activeMediaComponent: newActiveComponent,
|
||||
lastActiveMediaComponents: {
|
||||
...state.lastActiveMediaComponents,
|
||||
left: lastActiveComponent,
|
||||
},
|
||||
currentMediaSide: "right",
|
||||
})),
|
||||
updateRightSide: (
|
||||
newActiveComponent: "play" | "exit",
|
||||
lastActiveComponent: "fstWord" | "sndWord" | "thirdWord"
|
||||
) =>
|
||||
set((state) => ({
|
||||
activeMediaComponent: newActiveComponent,
|
||||
lastActiveMediaComponents: {
|
||||
...state.lastActiveMediaComponents,
|
||||
right: lastActiveComponent,
|
||||
},
|
||||
currentMediaSide: "left",
|
||||
})),
|
||||
|
||||
// idle media setters
|
||||
setIdleStarting: (to: boolean) => set(() => ({ idleStarting: to })),
|
||||
|
@ -379,15 +367,6 @@ export const useStore = create(
|
|||
[bodyPart]: true,
|
||||
},
|
||||
})),
|
||||
// sskn scene setters
|
||||
toggleSSknComponentMatrixIdx: () =>
|
||||
set((state) => ({
|
||||
ssknComponentMatrixIdx: Number(!state.ssknComponentMatrixIdx) as
|
||||
| 0
|
||||
| 1,
|
||||
})),
|
||||
setSSknLoading: (to: boolean) => set(() => ({ ssknLoading: to })),
|
||||
incrementSSknLvl: () => set((state) => ({ ssknLvl: state.ssknLvl + 1 })),
|
||||
|
||||
// gate scene setters
|
||||
incrementGateLvl: () => set((state) => ({ gateLvl: state.gateLvl + 1 })),
|
||||
|
@ -398,23 +377,15 @@ export const useStore = create(
|
|||
// boot scene setters
|
||||
setBootSubscene: (to: "load_data" | "authorize_user" | "main_menu") =>
|
||||
set(() => ({ bootSubscene: to })),
|
||||
setMainMenuComponentMatrixIdx: (to: 0 | 1) =>
|
||||
set(() => ({
|
||||
mainMenuComponentMatrixIdx: to,
|
||||
})),
|
||||
|
||||
setAuthorizeUserLetterIdx: (to: number) =>
|
||||
set(() => ({ authorizeUserLetterIdx: to })),
|
||||
|
||||
// prompt setters
|
||||
setPromptVisible: (to: boolean) => set(() => ({ promptVisible: to })),
|
||||
setPromptComponentMatrixIdx: (to: 1 | 0) =>
|
||||
set(() => ({ promptComponentMatrixIdx: to })),
|
||||
|
||||
// site state setters
|
||||
setSiteSaveState: (
|
||||
site: string,
|
||||
to: {
|
||||
activeNode: NodeDataType;
|
||||
activeNode: NodeData;
|
||||
siteRot: number[];
|
||||
activeLevel: string;
|
||||
}
|
||||
|
@ -432,6 +403,30 @@ export const useStore = create(
|
|||
activeLevel: stateToLoad.activeLevel,
|
||||
};
|
||||
}),
|
||||
changeSite: (to: "a" | "b") =>
|
||||
set((state) => {
|
||||
const newState = state.siteSaveState[to];
|
||||
return {
|
||||
currentScene: "change_disc",
|
||||
promptVisible: false,
|
||||
activePromptComponent: "no",
|
||||
mainSubscene: "site",
|
||||
// load new state
|
||||
activeSite: to,
|
||||
activeNode: newState.activeNode,
|
||||
siteRot: newState.siteRot,
|
||||
activeLevel: newState.activeLevel,
|
||||
// save current state
|
||||
siteSaveState: {
|
||||
...state.siteSaveState,
|
||||
[to === "a" ? "b" : "a"]: {
|
||||
activeNode: state.activeNode,
|
||||
siteRot: [0, state.siteRot[1], 0],
|
||||
activeLevel: state.activeLevel,
|
||||
},
|
||||
},
|
||||
};
|
||||
}),
|
||||
|
||||
// status notifier setters
|
||||
setSaveSuccessful: (to: boolean | undefined) =>
|
||||
|
@ -450,6 +445,10 @@ export const useStore = create(
|
|||
[nodeName]: to,
|
||||
},
|
||||
})),
|
||||
|
||||
setInputCooldown: (to: boolean) => set(() => ({ inputCooldown: to })),
|
||||
|
||||
incrementSsknLvl: () => set((state) => ({ ssknLvl: state.ssknLvl + 1 })),
|
||||
})
|
||||
)
|
||||
);
|
||||
|
@ -464,28 +463,46 @@ export const getSiteState = (site: "a" | "b") => {
|
|||
};
|
||||
};
|
||||
|
||||
type PromptContext = {
|
||||
activePromptComponent: "yes" | "no";
|
||||
promptVisible: boolean;
|
||||
};
|
||||
|
||||
const getPromptContext = () => {
|
||||
const state = useStore.getState();
|
||||
|
||||
return {
|
||||
promptVisible: state.promptVisible,
|
||||
activePromptComponent:
|
||||
state.promptComponentMatrix[state.promptComponentMatrixIdx],
|
||||
activePromptComponent: state.activePromptComponent,
|
||||
};
|
||||
};
|
||||
|
||||
export const getMainSceneContext = () => {
|
||||
export interface MainSceneContext extends PromptContext {
|
||||
keyPress: string;
|
||||
ssknLvl: number;
|
||||
activeNode: NodeData;
|
||||
showingAbout: boolean;
|
||||
level: number;
|
||||
activePauseComponent: "load" | "about" | "change" | "save" | "exit";
|
||||
gameProgress: GameProgress;
|
||||
gateLvl: number;
|
||||
subscene: string;
|
||||
siteRotY: number;
|
||||
activeSite: "a" | "b";
|
||||
selectedLevel: number;
|
||||
}
|
||||
|
||||
export const getMainSceneContext = (keyPress: string): MainSceneContext => {
|
||||
const state = useStore.getState();
|
||||
|
||||
return {
|
||||
...getPromptContext(),
|
||||
keyPress: keyPress,
|
||||
subscene: state.mainSubscene,
|
||||
selectedLevel: state.selectedLevel,
|
||||
pauseMatrixIdx: state.pauseComponentMatrixIdx,
|
||||
activePauseComponent:
|
||||
state.pauseComponentMatrix[state.pauseComponentMatrixIdx],
|
||||
activePauseComponent: state.activePauseComponent,
|
||||
gameProgress: state.gameProgress,
|
||||
currentSite: state.activeSite,
|
||||
activeSite: state.activeSite,
|
||||
siteRotY: state.siteRot[1],
|
||||
activeNode: state.activeNode,
|
||||
level: parseInt(state.activeLevel),
|
||||
|
@ -495,26 +512,43 @@ export const getMainSceneContext = () => {
|
|||
};
|
||||
};
|
||||
|
||||
export const getSSknSceneContext = () => {
|
||||
export type SsknSceneContext = {
|
||||
keyPress: string;
|
||||
activeSsknComponent: "ok" | "cancel";
|
||||
activeNode: NodeData;
|
||||
};
|
||||
|
||||
export const getSsknSceneContext = (keyPress: string): SsknSceneContext => {
|
||||
const state = useStore.getState();
|
||||
return {
|
||||
activeSSknComponent:
|
||||
state.ssknComponentMatrix[state.ssknComponentMatrixIdx],
|
||||
keyPress: keyPress,
|
||||
activeSsknComponent: state.activeSsknComponent,
|
||||
activeNode: state.activeNode,
|
||||
};
|
||||
};
|
||||
|
||||
export const getMediaSceneContext = () => {
|
||||
export type MediaSceneContext = {
|
||||
keyPress: string;
|
||||
wordPosStateIdx: number;
|
||||
currentMediaSide: "left" | "right";
|
||||
activeMediaComponent: "play" | "exit" | "fstWord" | "sndWord" | "thirdWord";
|
||||
activeNode: NodeData;
|
||||
gameProgress: GameProgress;
|
||||
lastActiveMediaComponents: {
|
||||
left: "play" | "exit";
|
||||
right: "fstWord" | "sndWord" | "thirdWord";
|
||||
};
|
||||
activeSite: "a" | "b";
|
||||
};
|
||||
|
||||
export const getMediaSceneContext = (keyPress: string): MediaSceneContext => {
|
||||
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,
|
||||
keyPress: keyPress,
|
||||
lastActiveMediaComponents: state.lastActiveMediaComponents,
|
||||
currentMediaSide: state.currentMediaSide,
|
||||
activeMediaComponent: state.activeMediaComponent,
|
||||
wordPosStateIdx: state.mediaWordPosStateIdx,
|
||||
activeNode: state.activeNode,
|
||||
activeSite: state.activeSite,
|
||||
|
@ -522,24 +556,39 @@ export const getMediaSceneContext = () => {
|
|||
};
|
||||
};
|
||||
|
||||
export const getBootSceneContext = () => {
|
||||
export interface BootSceneContext extends PromptContext {
|
||||
keyPress: string;
|
||||
playerName: string;
|
||||
subscene: "main_menu" | "load_data" | "authorize_user";
|
||||
activeMainMenuComponent: "load_data" | "authorize_user";
|
||||
authorizeUserLetterIdx: number;
|
||||
}
|
||||
|
||||
export const getBootSceneContext = (keyPress: string): BootSceneContext => {
|
||||
const state = useStore.getState();
|
||||
|
||||
return {
|
||||
...getPromptContext(),
|
||||
keyPress: keyPress,
|
||||
playerName: state.playerName,
|
||||
subscene: state.bootSubscene,
|
||||
activeMainMenuComponent:
|
||||
state.mainMenuComponentMatrix[state.mainMenuComponentMatrixIdx],
|
||||
activeMainMenuComponent: state.activeMainMenuComponent,
|
||||
authorizeUserLetterIdx: state.authorizeUserLetterIdx,
|
||||
};
|
||||
};
|
||||
|
||||
export const getEndSceneContext = () => {
|
||||
export type EndSceneContext = {
|
||||
keyPress: string;
|
||||
activeEndComponent: "end" | "continue";
|
||||
selectionVisible: boolean;
|
||||
};
|
||||
|
||||
export const getEndSceneContext = (keyPress: string): EndSceneContext => {
|
||||
const state = useStore.getState();
|
||||
|
||||
return {
|
||||
activeEndComponent: state.endComponentMatrix[state.endComponentMatrixIdx],
|
||||
keyPress: keyPress,
|
||||
activeEndComponent: state.activeEndComponent,
|
||||
selectionVisible: state.endSceneSelectionVisible,
|
||||
};
|
||||
};
|
||||
|
@ -561,3 +610,19 @@ export const createAudioAnalyser = () => {
|
|||
|
||||
return new THREE.AudioAnalyser(audio, 2048);
|
||||
};
|
||||
|
||||
export const getSceneResetValues = (scene: string) => {
|
||||
switch (scene) {
|
||||
case "media":
|
||||
return {
|
||||
mediaWordPosStateIdx: 1,
|
||||
mediaComponentMatrixIndices: {
|
||||
sideIdx: 0,
|
||||
leftSideIdx: 0,
|
||||
rightSideIdx: 0,
|
||||
},
|
||||
};
|
||||
case "sskn":
|
||||
return { ssknComponentMatrixIdx: 0, ssknLoading: false };
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import site_a from "../resources/site_a.json";
|
||||
import site_b from "../resources/site_b.json";
|
||||
import { SiteType } from "../components/MainScene/Site";
|
||||
import { SiteData } from "../components/MainScene/Site";
|
||||
import { useStore } from "../store";
|
||||
|
||||
export const getRandomIdleMedia = () => {
|
||||
|
@ -58,7 +58,7 @@ export const getRandomIdleMedia = () => {
|
|||
|
||||
const site = useStore.getState().activeSite;
|
||||
|
||||
const siteData: SiteType = site === "a" ? site_a : site_b;
|
||||
const siteData: SiteData = site === "a" ? site_a : site_b;
|
||||
const idleNodes = site === "a" ? siteAIdleNodes : siteBIdleNodes;
|
||||
|
||||
if (Math.random() < 0.5) {
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import site_a from "../resources/site_a.json";
|
||||
import site_b from "../resources/site_b.json";
|
||||
import node_matrices from "../resources/node_matrices.json";
|
||||
import { NodeDataType, SiteType } from "../components/MainScene/Site";
|
||||
import { NodeData, SiteData } from "../components/MainScene/Site";
|
||||
import { isNodeVisible } from "./node-utils";
|
||||
|
||||
export const findNodeFromWord = (
|
||||
wordLabel: string,
|
||||
activeNode: NodeDataType,
|
||||
activeNode: NodeData,
|
||||
site: "a" | "b",
|
||||
gameProgress: any
|
||||
) => {
|
||||
|
@ -23,7 +23,7 @@ export const findNodeFromWord = (
|
|||
|
||||
const wordToFind = activeNode.words[labelToIdx!];
|
||||
|
||||
const siteData: SiteType = site === "a" ? site_a : site_b;
|
||||
const siteData: SiteData = site === "a" ? site_a : site_b;
|
||||
|
||||
const nodesWithSameWords = Object.values(siteData)
|
||||
.flatMap((level) =>
|
||||
|
|
131
src/utils/node-animations.ts
Normal file
131
src/utils/node-animations.ts
Normal file
|
@ -0,0 +1,131 @@
|
|||
import { useStore } from "../store";
|
||||
import sleep from "./sleep";
|
||||
|
||||
const setActiveNodePos = useStore.getState().setNodePos;
|
||||
const setActiveNodeRot = useStore.getState().setNodeRot;
|
||||
const setActiveNodeAttributes = useStore.getState().setNodeAttributes;
|
||||
|
||||
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),
|
||||
});
|
||||
|
||||
export const nodeThrow = (siteRotY: number) => {
|
||||
(async () => {
|
||||
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);
|
||||
|
||||
setActiveNodeAttributes(true, "interactedWith");
|
||||
|
||||
setActiveNodePos([fstCoordSet.x, 0, fstCoordSet.z]);
|
||||
|
||||
await sleep(800);
|
||||
setActiveNodePos([sndCoordSet.x, 0, sndCoordSet.z]);
|
||||
|
||||
await sleep(1800);
|
||||
setActiveNodePos([thirdCoordSet.x, 0, sndCoordSet.z]);
|
||||
setActiveNodeRot([0, 0, -0.005]);
|
||||
|
||||
await sleep(100);
|
||||
setActiveNodePos([fourthCoordSet.x, 0, fourthCoordSet.z]);
|
||||
setActiveNodeRot([0, 0, -0.5]);
|
||||
|
||||
await sleep(1100);
|
||||
setActiveNodeRot([0, 0, 0]);
|
||||
setActiveNodeAttributes(false, "interactedWith");
|
||||
})();
|
||||
};
|
||||
|
||||
export const nodeKnock = (siteRotY: number) => {
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(1.1, 0.2, siteRotY);
|
||||
|
||||
setActiveNodeAttributes(true, "interactedWith");
|
||||
|
||||
setActiveNodePos([fstCoordSet.x, -0.6, fstCoordSet.z]);
|
||||
|
||||
setTimeout(() => setActiveNodeAttributes(false, "interactedWith"), 2500);
|
||||
};
|
||||
|
||||
export const nodeKnockAndFall = (siteRotY: number) => {
|
||||
(async () => {
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(1.1, 0.2, siteRotY);
|
||||
|
||||
setActiveNodeAttributes(true, "interactedWith");
|
||||
|
||||
setActiveNodePos([fstCoordSet.x, -0.6, fstCoordSet.z]);
|
||||
|
||||
await sleep(2300);
|
||||
setActiveNodeAttributes(false, "visible");
|
||||
|
||||
await sleep(200);
|
||||
setActiveNodeAttributes(false, "interactedWith");
|
||||
|
||||
await sleep(700);
|
||||
setActiveNodeAttributes(true, "visible");
|
||||
})();
|
||||
};
|
||||
|
||||
export const nodeTouchAndScare = (siteRotY: number) => {
|
||||
(async () => {
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(-0.6, 0.2, siteRotY);
|
||||
|
||||
setActiveNodeAttributes(true, "interactedWith");
|
||||
|
||||
setActiveNodePos([fstCoordSet.x, 0, fstCoordSet.z]);
|
||||
|
||||
await sleep(1200);
|
||||
setActiveNodeAttributes(true, "exploding");
|
||||
setActiveNodeAttributes(false, "visible");
|
||||
|
||||
await sleep(200);
|
||||
setActiveNodeAttributes(false, "interactedWith");
|
||||
setActiveNodeRot([0, 0, 0]);
|
||||
|
||||
await sleep(1750);
|
||||
setActiveNodeAttributes(false, "exploding");
|
||||
|
||||
await sleep(350);
|
||||
setActiveNodeAttributes(true, "visible");
|
||||
})();
|
||||
};
|
||||
|
||||
export const nodeRip = (siteRotY: number) => {
|
||||
(async () => {
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(0.9, 0.3, siteRotY);
|
||||
const sndCoordSet = calculateCoordsBasedOnRotation(0.5, 0.2, siteRotY);
|
||||
const thirdCoordSet = calculateCoordsBasedOnRotation(0, 0.2, siteRotY);
|
||||
|
||||
setActiveNodeAttributes(true, "interactedWith");
|
||||
|
||||
setActiveNodePos([fstCoordSet.x, 0, fstCoordSet.z]);
|
||||
|
||||
await sleep(800);
|
||||
setActiveNodePos([sndCoordSet.x, 0, sndCoordSet.z]);
|
||||
|
||||
await sleep(2000);
|
||||
setActiveNodePos([thirdCoordSet.x, -0.4, thirdCoordSet.z]);
|
||||
|
||||
await sleep(200);
|
||||
setActiveNodeAttributes(true, "shrinking");
|
||||
|
||||
await sleep(200);
|
||||
setActiveNodePos([thirdCoordSet.x, -1.5, thirdCoordSet.z]);
|
||||
|
||||
await sleep(300);
|
||||
setActiveNodeAttributes(false, "visible");
|
||||
|
||||
await sleep(2900);
|
||||
setActiveNodeAttributes(false, "interactedWith");
|
||||
setActiveNodeAttributes(false, "shrinking");
|
||||
setActiveNodeRot([0, 0, 0]);
|
||||
|
||||
await sleep(1100);
|
||||
setActiveNodeAttributes(true, "visible");
|
||||
})();
|
||||
};
|
|
@ -1,13 +1,13 @@
|
|||
import { NodeDataType, SiteType } from "../components/MainScene/Site";
|
||||
import { NodeData, SiteData } from "../components/MainScene/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";
|
||||
import {GameProgress} from "../store";
|
||||
|
||||
export const generateInactiveNodes = (
|
||||
visibleNodes: SiteType,
|
||||
visibleNodes: SiteData,
|
||||
activeLevel: string
|
||||
) => {
|
||||
const obj = {};
|
||||
|
@ -26,10 +26,10 @@ export const generateInactiveNodes = (
|
|||
return obj;
|
||||
};
|
||||
|
||||
export const getNodeById = (id: string, currentSite: string) => {
|
||||
const siteData = currentSite === "a" ? site_a : site_b;
|
||||
export const getNodeById = (id: string, activeSite: string) => {
|
||||
const siteData = activeSite === "a" ? site_a : site_b;
|
||||
const level = id.substr(0, 2);
|
||||
return (siteData as SiteType)[level][id];
|
||||
return (siteData as SiteData)[level][id];
|
||||
};
|
||||
export const getNodeHud = (nodeMatrixIndices: {
|
||||
matrixIdx: number;
|
||||
|
@ -60,7 +60,7 @@ export const getNodeHud = (nodeMatrixIndices: {
|
|||
|
||||
//visible = (global_final_viewcount > 0) && (req_final_viewcount <= global_final_viewcount + 1)
|
||||
export const isNodeVisible = (
|
||||
node: NodeDataType,
|
||||
node: NodeData,
|
||||
gameProgress: typeof unlocked_nodes
|
||||
) => {
|
||||
return node
|
||||
|
@ -74,7 +74,7 @@ export const isNodeVisible = (
|
|||
export const getVisibleNodesMatrix = (
|
||||
matrixIdx: number,
|
||||
activeLevel: number,
|
||||
currentSite: string,
|
||||
activeSite: string,
|
||||
gameProgress: any
|
||||
) => {
|
||||
const formattedLevel = activeLevel.toString().padStart(2, "0");
|
||||
|
@ -84,7 +84,7 @@ export const getVisibleNodesMatrix = (
|
|||
return currentMatrix.map((row: string[]) =>
|
||||
row.map((nodePos: string) => {
|
||||
const nodeId = formattedLevel + nodePos;
|
||||
if (isNodeVisible(getNodeById(nodeId, currentSite), gameProgress))
|
||||
if (isNodeVisible(getNodeById(nodeId, activeSite), gameProgress))
|
||||
return nodeId;
|
||||
else return undefined;
|
||||
})
|
||||
|
@ -174,8 +174,8 @@ export const findNode = (
|
|||
}: { matrixIdx: number; rowIdx: number; colIdx: number },
|
||||
|
||||
level: number,
|
||||
currentSite: string,
|
||||
gameProgress: typeof game_progress,
|
||||
activeSite: string,
|
||||
gameProgress: GameProgress,
|
||||
shouldSearchNext: boolean
|
||||
) => {
|
||||
const funcs: {
|
||||
|
@ -198,7 +198,7 @@ export const findNode = (
|
|||
const nodes = getVisibleNodesMatrix(
|
||||
matrixIdx,
|
||||
level,
|
||||
currentSite,
|
||||
activeSite,
|
||||
gameProgress
|
||||
);
|
||||
|
||||
|
@ -237,10 +237,10 @@ export const findNode = (
|
|||
}
|
||||
};
|
||||
export const filterInvisibleNodes = (
|
||||
siteData: SiteType,
|
||||
gameProgress: typeof game_progress
|
||||
siteData: SiteData,
|
||||
gameProgress: GameProgress
|
||||
) => {
|
||||
const visibleNodes: SiteType = {};
|
||||
const visibleNodes: SiteData = {};
|
||||
Object.entries(siteData).forEach((level) => {
|
||||
visibleNodes[level[0]] = {};
|
||||
Object.entries(level[1]).forEach((node) => {
|
||||
|
|
Loading…
Reference in a new issue