From faa34b072c0b114b601b69dfc34382bf2cf6cb38 Mon Sep 17 00:00:00 2001 From: ad044 Date: Wed, 17 Feb 2021 20:21:27 +0400 Subject: [PATCH] done refactoring state management, fixed some typing and renamed some stuff for clarity --- src/App.tsx | 4 +- .../BootScene/BootMainMenuComponents.tsx | 2 +- .../EndScene/EndSelectionScreen.tsx | 4 +- src/components/Images.tsx | 6 +- src/components/KeyPressHandler.tsx | 168 +++------- .../MainScene/PauseSubscene/Pause.tsx | 4 +- src/components/MainScene/Site.tsx | 38 ++- .../MainScene/Site/ActiveLevelNodes.tsx | 6 +- .../MainScene/Site/InactiveLevelNode.tsx | 6 +- .../MainScene/Site/InactiveLevelNodes.tsx | 4 +- src/components/MainScene/Site/Node.tsx | 8 +- .../NodeAnimations/NodeExplosion/GoldNode.tsx | 6 +- src/components/MainScene/Site/Rings.tsx | 8 +- .../MediaScene/Selectables/LeftSide.tsx | 9 +- .../MediaScene/Selectables/RightSide.tsx | 14 +- src/components/Prompt.tsx | 4 +- .../SsknBackground.tsx} | 4 +- .../SSknHUD.tsx => SsknScene/SsknHUD.tsx} | 20 +- .../SSknIcon.tsx => SsknScene/SsknIcon.tsx} | 4 +- .../SsknLoadingBar.tsx} | 4 +- .../{SiteBigLetter.tsx => BigLetter.tsx} | 13 +- .../TextRenderer/MainYellowTextAnimator.tsx | 4 +- .../TextRenderer/MediaYellowTextAnimator.tsx | 13 +- .../handleBootSceneEvent.ts | 84 +++++ .../handleEndSceneEvent.ts | 20 ++ .../handleMainSceneEvent.ts | 143 +++++++-- .../handleMediaSceneEvent.ts | 92 ++++++ .../handleSsknSceneEvent.ts | 42 +++ .../handleBootSceneKeyPress.ts | 3 +- .../handleMainSceneKeyPress.ts | 86 ++++-- .../handleMediaSceneKeyPress.ts | 150 ++++----- .../handleSSknSceneKeyPress.ts | 24 -- .../handleSsknSceneKeyPress.ts | 26 ++ src/core/setters/boot/bootManager.ts | 56 ---- src/core/setters/boot/bootSubsceneManager.ts | 27 -- src/core/setters/end/endManager.ts | 24 -- src/core/setters/gameLoader.ts | 34 -- src/core/setters/gameSaver.ts | 33 -- src/core/setters/main/idleManager.ts | 23 -- .../level_selection/levelSelectionManager.ts | 24 -- src/core/setters/main/mainSubsceneManager.ts | 48 --- src/core/setters/main/pause/pauseManager.ts | 52 ---- src/core/setters/main/site/lainManager.ts | 67 ---- src/core/setters/main/site/levelManager.ts | 30 -- src/core/setters/main/site/nodeManager.ts | 191 ------------ src/core/setters/main/site/siteManager.ts | 51 --- src/core/setters/media/mediaManager.ts | 80 ----- src/core/setters/progressManager.ts | 101 ------ src/core/setters/promptManager.ts | 44 --- src/core/setters/sceneManager.ts | 103 ------- src/core/setters/soundManager.ts | 179 ----------- src/core/setters/sskn/ssknManager.ts | 31 -- src/resources/initial_progress.json | 14 +- src/resources/site_a.json | 8 +- src/resources/site_b.json | 6 +- src/scenes/ChangeDiscScene.tsx | 8 +- src/scenes/GateScene.tsx | 9 +- src/scenes/MainScene.tsx | 6 +- src/scenes/MediaScene.tsx | 4 +- src/scenes/PolytanScene.tsx | 33 +- src/scenes/SSknScene.tsx | 16 - src/scenes/SsknScene.tsx | 14 + src/scenes/TaKScene.tsx | 42 ++- src/store.ts | 291 +++++++++++------- src/utils/idle-utils.ts | 4 +- src/utils/media-utils.ts | 6 +- src/utils/node-animations.ts | 131 ++++++++ src/utils/node-utils.ts | 30 +- 68 files changed, 1075 insertions(+), 1768 deletions(-) rename src/components/{SSknScene/SSknBackground.tsx => SsknScene/SsknBackground.tsx} (95%) rename src/components/{SSknScene/SSknHUD.tsx => SsknScene/SsknHUD.tsx} (87%) rename src/components/{SSknScene/SSknIcon.tsx => SsknScene/SsknIcon.tsx} (96%) rename src/components/{SSknScene/SSknLoadingBar.tsx => SsknScene/SsknLoadingBar.tsx} (98%) rename src/components/TextRenderer/{SiteBigLetter.tsx => BigLetter.tsx} (90%) create mode 100644 src/core/scene-event-handlers/handleBootSceneEvent.ts create mode 100644 src/core/scene-event-handlers/handleEndSceneEvent.ts create mode 100644 src/core/scene-event-handlers/handleMediaSceneEvent.ts create mode 100644 src/core/scene-event-handlers/handleSsknSceneEvent.ts delete mode 100644 src/core/scene-keypress-handlers/handleSSknSceneKeyPress.ts create mode 100644 src/core/scene-keypress-handlers/handleSsknSceneKeyPress.ts delete mode 100644 src/core/setters/boot/bootManager.ts delete mode 100644 src/core/setters/boot/bootSubsceneManager.ts delete mode 100644 src/core/setters/end/endManager.ts delete mode 100644 src/core/setters/gameLoader.ts delete mode 100644 src/core/setters/gameSaver.ts delete mode 100644 src/core/setters/main/idleManager.ts delete mode 100644 src/core/setters/main/level_selection/levelSelectionManager.ts delete mode 100644 src/core/setters/main/mainSubsceneManager.ts delete mode 100644 src/core/setters/main/pause/pauseManager.ts delete mode 100644 src/core/setters/main/site/lainManager.ts delete mode 100644 src/core/setters/main/site/levelManager.ts delete mode 100644 src/core/setters/main/site/nodeManager.ts delete mode 100644 src/core/setters/main/site/siteManager.ts delete mode 100644 src/core/setters/media/mediaManager.ts delete mode 100644 src/core/setters/progressManager.ts delete mode 100644 src/core/setters/promptManager.ts delete mode 100644 src/core/setters/sceneManager.ts delete mode 100644 src/core/setters/soundManager.ts delete mode 100644 src/core/setters/sskn/ssknManager.ts delete mode 100644 src/scenes/SSknScene.tsx create mode 100644 src/scenes/SsknScene.tsx create mode 100644 src/utils/node-animations.ts diff --git a/src/App.tsx b/src/App.tsx index e6c6f37..8cbccd0 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -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: , gate: , boot: , - sskn: , + sskn: , polytan: , tak: , change_disc: , diff --git a/src/components/BootScene/BootMainMenuComponents.tsx b/src/components/BootScene/BootMainMenuComponents.tsx index d38c93e..e5adfa7 100644 --- a/src/components/BootScene/BootMainMenuComponents.tsx +++ b/src/components/BootScene/BootMainMenuComponents.tsx @@ -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); diff --git a/src/components/EndScene/EndSelectionScreen.tsx b/src/components/EndScene/EndSelectionScreen.tsx index 310ca37..41f8f1d 100644 --- a/src/components/EndScene/EndSelectionScreen.tsx +++ b/src/components/EndScene/EndSelectionScreen.tsx @@ -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 = () => { diff --git a/src/components/Images.tsx b/src/components/Images.tsx index 91337ee..4e6af8b 100644 --- a/src/components/Images.tsx +++ b/src/components/Images.tsx @@ -15,7 +15,7 @@ const Images = () => { const [sceneImages, setSceneImages] = useState([] as any); const [activeImage, setActiveImage] = useState(); - 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) => { diff --git a/src/components/KeyPressHandler.tsx b/src/components/KeyPressHandler.tsx index 781e565..588598c 100644 --- a/src/components/KeyPressHandler.tsx +++ b/src/components/KeyPressHandler.tsx @@ -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(() => { diff --git a/src/components/MainScene/PauseSubscene/Pause.tsx b/src/components/MainScene/PauseSubscene/Pause.tsx index 5d61f5d..50a6dac 100644 --- a/src/components/MainScene/PauseSubscene/Pause.tsx +++ b/src/components/MainScene/PauseSubscene/Pause.tsx @@ -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) => { diff --git a/src/components/MainScene/Site.tsx b/src/components/MainScene/Site.tsx index 602ab44..b20fdce 100644 --- a/src/components/MainScene/Site.tsx +++ b/src/components/MainScene/Site.tsx @@ -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 ( }> - - + + diff --git a/src/components/MainScene/Site/ActiveLevelNodes.tsx b/src/components/MainScene/Site/ActiveLevelNodes.tsx index 6cc52f1..9e7a944 100644 --- a/src/components/MainScene/Site/ActiveLevelNodes.tsx +++ b/src/components/MainScene/Site/ActiveLevelNodes.tsx @@ -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 ( { const tex = useMemo(() => { if (props.nodeName.includes("S")) { - return [SSkn, SSknViewed]; + return [Sskn, SsknViewed]; } else if ( props.nodeName.startsWith("P") || props.nodeName.startsWith("G") || diff --git a/src/components/MainScene/Site/InactiveLevelNodes.tsx b/src/components/MainScene/Site/InactiveLevelNodes.tsx index a4d57b6..adce464 100644 --- a/src/components/MainScene/Site/InactiveLevelNodes.tsx +++ b/src/components/MainScene/Site/InactiveLevelNodes.tsx @@ -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) => { diff --git a/src/components/MainScene/Site/Node.tsx b/src/components/MainScene/Site/Node.tsx index ce6423b..1db779f 100644 --- a/src/components/MainScene/Site/Node.tsx +++ b/src/components/MainScene/Site/Node.tsx @@ -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") || diff --git a/src/components/MainScene/Site/NodeAnimations/NodeExplosion/GoldNode.tsx b/src/components/MainScene/Site/NodeAnimations/NodeExplosion/GoldNode.tsx index 3d8cec3..25a6651 100644 --- a/src/components/MainScene/Site/NodeAnimations/NodeExplosion/GoldNode.tsx +++ b/src/components/MainScene/Site/NodeAnimations/NodeExplosion/GoldNode.tsx @@ -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") || diff --git a/src/components/MainScene/Site/Rings.tsx b/src/components/MainScene/Site/Rings.tsx index cc89022..b4c84b5 100644 --- a/src/components/MainScene/Site/Rings.tsx +++ b/src/components/MainScene/Site/Rings.tsx @@ -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) => { diff --git a/src/components/MediaScene/Selectables/LeftSide.tsx b/src/components/MediaScene/Selectables/LeftSide.tsx index 7106c82..e8623a7 100644 --- a/src/components/MediaScene/Selectables/LeftSide.tsx +++ b/src/components/MediaScene/Selectables/LeftSide.tsx @@ -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, diff --git a/src/components/MediaScene/Selectables/RightSide.tsx b/src/components/MediaScene/Selectables/RightSide.tsx index 669710b..2bed2d3 100644 --- a/src/components/MediaScene/Selectables/RightSide.tsx +++ b/src/components/MediaScene/Selectables/RightSide.tsx @@ -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 ( diff --git a/src/components/Prompt.tsx b/src/components/Prompt.tsx index 505d712..a20ebfd 100644 --- a/src/components/Prompt.tsx +++ b/src/components/Prompt.tsx @@ -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 ( <> diff --git a/src/components/SSknScene/SSknBackground.tsx b/src/components/SsknScene/SsknBackground.tsx similarity index 95% rename from src/components/SSknScene/SSknBackground.tsx rename to src/components/SsknScene/SsknBackground.tsx index 0f68638..6df08ba 100644 --- a/src/components/SSknScene/SSknBackground.tsx +++ b/src/components/SsknScene/SsknBackground.tsx @@ -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; diff --git a/src/components/SSknScene/SSknHUD.tsx b/src/components/SsknScene/SsknHUD.tsx similarity index 87% rename from src/components/SSknScene/SSknHUD.tsx rename to src/components/SsknScene/SsknHUD.tsx index c576cdc..7b55f77 100644 --- a/src/components/SSknScene/SSknHUD.tsx +++ b/src/components/SsknScene/SsknHUD.tsx @@ -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 ? ( - + ) : ( { { { ); }); -export default SSknHUD; +export default SsknHUD; diff --git a/src/components/SSknScene/SSknIcon.tsx b/src/components/SsknScene/SsknIcon.tsx similarity index 96% rename from src/components/SSknScene/SSknIcon.tsx rename to src/components/SsknScene/SsknIcon.tsx index 5274b35..f48d35a 100644 --- a/src/components/SSknScene/SSknIcon.tsx +++ b/src/components/SsknScene/SsknIcon.tsx @@ -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(); const ssknIconShadowRef = useRef(); @@ -51,4 +51,4 @@ const SSknIcon = memo(() => { ); }); -export default SSknIcon; +export default SsknIcon; diff --git a/src/components/SSknScene/SSknLoadingBar.tsx b/src/components/SsknScene/SsknLoadingBar.tsx similarity index 98% rename from src/components/SSknScene/SSknLoadingBar.tsx rename to src/components/SsknScene/SsknLoadingBar.tsx index db3ecca..4a94c03 100644 --- a/src/components/SSknScene/SSknLoadingBar.tsx +++ b/src/components/SsknScene/SsknLoadingBar.tsx @@ -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; diff --git a/src/components/TextRenderer/SiteBigLetter.tsx b/src/components/TextRenderer/BigLetter.tsx similarity index 90% rename from src/components/TextRenderer/SiteBigLetter.tsx rename to src/components/TextRenderer/BigLetter.tsx index 4f2127e..5a5c85a 100644 --- a/src/components/TextRenderer/SiteBigLetter.tsx +++ b/src/components/TextRenderer/BigLetter.tsx @@ -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; diff --git a/src/components/TextRenderer/MainYellowTextAnimator.tsx b/src/components/TextRenderer/MainYellowTextAnimator.tsx index ba8e477..bd890a8 100644 --- a/src/components/TextRenderer/MainYellowTextAnimator.tsx +++ b/src/components/TextRenderer/MainYellowTextAnimator.tsx @@ -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]} > - + ))} diff --git a/src/components/TextRenderer/MediaYellowTextAnimator.tsx b/src/components/TextRenderer/MediaYellowTextAnimator.tsx index 8502fe7..d452f5f 100644 --- a/src/components/TextRenderer/MediaYellowTextAnimator.tsx +++ b/src/components/TextRenderer/MediaYellowTextAnimator.tsx @@ -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]} > - + ))} diff --git a/src/core/scene-event-handlers/handleBootSceneEvent.ts b/src/core/scene-event-handlers/handleBootSceneEvent.ts new file mode 100644 index 0000000..03cfcd3 --- /dev/null +++ b/src/core/scene-event-handlers/handleBootSceneEvent.ts @@ -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; diff --git a/src/core/scene-event-handlers/handleEndSceneEvent.ts b/src/core/scene-event-handlers/handleEndSceneEvent.ts new file mode 100644 index 0000000..1707772 --- /dev/null +++ b/src/core/scene-event-handlers/handleEndSceneEvent.ts @@ -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; diff --git a/src/core/scene-event-handlers/handleMainSceneEvent.ts b/src/core/scene-event-handlers/handleMainSceneEvent.ts index 860e543..715b3e0 100644 --- a/src/core/scene-event-handlers/handleMainSceneEvent.ts +++ b/src/core/scene-event-handlers/handleMainSceneEvent.ts @@ -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); } }; diff --git a/src/core/scene-event-handlers/handleMediaSceneEvent.ts b/src/core/scene-event-handlers/handleMediaSceneEvent.ts new file mode 100644 index 0000000..80a1ee4 --- /dev/null +++ b/src/core/scene-event-handlers/handleMediaSceneEvent.ts @@ -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; diff --git a/src/core/scene-event-handlers/handleSsknSceneEvent.ts b/src/core/scene-event-handlers/handleSsknSceneEvent.ts new file mode 100644 index 0000000..009731a --- /dev/null +++ b/src/core/scene-event-handlers/handleSsknSceneEvent.ts @@ -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; diff --git a/src/core/scene-keypress-handlers/handleBootSceneKeyPress.ts b/src/core/scene-keypress-handlers/handleBootSceneKeyPress.ts index 64c376a..edd0439 100644 --- a/src/core/scene-keypress-handlers/handleBootSceneKeyPress.ts +++ b/src/core/scene-keypress-handlers/handleBootSceneKeyPress.ts @@ -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, diff --git a/src/core/scene-keypress-handlers/handleMainSceneKeyPress.ts b/src/core/scene-keypress-handlers/handleMainSceneKeyPress.ts index 791a9ce..b8bef8d 100644 --- a/src/core/scene-keypress-handlers/handleMainSceneKeyPress.ts +++ b/src/core/scene-keypress-handlers/handleMainSceneKeyPress.ts @@ -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], }; } } diff --git a/src/core/scene-keypress-handlers/handleMediaSceneKeyPress.ts b/src/core/scene-keypress-handlers/handleMediaSceneKeyPress.ts index dba18a0..c90ff0d 100644 --- a/src/core/scene-keypress-handlers/handleMediaSceneKeyPress.ts +++ b/src/core/scene-keypress-handlers/handleMediaSceneKeyPress.ts @@ -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`, - }; - } } } }; diff --git a/src/core/scene-keypress-handlers/handleSSknSceneKeyPress.ts b/src/core/scene-keypress-handlers/handleSSknSceneKeyPress.ts deleted file mode 100644 index 2e72889..0000000 --- a/src/core/scene-keypress-handlers/handleSSknSceneKeyPress.ts +++ /dev/null @@ -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; diff --git a/src/core/scene-keypress-handlers/handleSsknSceneKeyPress.ts b/src/core/scene-keypress-handlers/handleSsknSceneKeyPress.ts new file mode 100644 index 0000000..6c5a42e --- /dev/null +++ b/src/core/scene-keypress-handlers/handleSsknSceneKeyPress.ts @@ -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; diff --git a/src/core/setters/boot/bootManager.ts b/src/core/setters/boot/bootManager.ts deleted file mode 100644 index 62bb8e6..0000000 --- a/src/core/setters/boot/bootManager.ts +++ /dev/null @@ -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; diff --git a/src/core/setters/boot/bootSubsceneManager.ts b/src/core/setters/boot/bootSubsceneManager.ts deleted file mode 100644 index de0b4fe..0000000 --- a/src/core/setters/boot/bootSubsceneManager.ts +++ /dev/null @@ -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; diff --git a/src/core/setters/end/endManager.ts b/src/core/setters/end/endManager.ts deleted file mode 100644 index 2dc4df5..0000000 --- a/src/core/setters/end/endManager.ts +++ /dev/null @@ -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; diff --git a/src/core/setters/gameLoader.ts b/src/core/setters/gameLoader.ts deleted file mode 100644 index 4f6f08a..0000000 --- a/src/core/setters/gameLoader.ts +++ /dev/null @@ -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; diff --git a/src/core/setters/gameSaver.ts b/src/core/setters/gameSaver.ts deleted file mode 100644 index 17e2734..0000000 --- a/src/core/setters/gameSaver.ts +++ /dev/null @@ -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; diff --git a/src/core/setters/main/idleManager.ts b/src/core/setters/main/idleManager.ts deleted file mode 100644 index 6264c19..0000000 --- a/src/core/setters/main/idleManager.ts +++ /dev/null @@ -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; diff --git a/src/core/setters/main/level_selection/levelSelectionManager.ts b/src/core/setters/main/level_selection/levelSelectionManager.ts deleted file mode 100644 index 90a0c57..0000000 --- a/src/core/setters/main/level_selection/levelSelectionManager.ts +++ /dev/null @@ -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; diff --git a/src/core/setters/main/mainSubsceneManager.ts b/src/core/setters/main/mainSubsceneManager.ts deleted file mode 100644 index 55da928..0000000 --- a/src/core/setters/main/mainSubsceneManager.ts +++ /dev/null @@ -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; diff --git a/src/core/setters/main/pause/pauseManager.ts b/src/core/setters/main/pause/pauseManager.ts deleted file mode 100644 index 9b79f05..0000000 --- a/src/core/setters/main/pause/pauseManager.ts +++ /dev/null @@ -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; diff --git a/src/core/setters/main/site/lainManager.ts b/src/core/setters/main/site/lainManager.ts deleted file mode 100644 index 4ed3fde..0000000 --- a/src/core/setters/main/site/lainManager.ts +++ /dev/null @@ -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; diff --git a/src/core/setters/main/site/levelManager.ts b/src/core/setters/main/site/levelManager.ts deleted file mode 100644 index c840c87..0000000 --- a/src/core/setters/main/site/levelManager.ts +++ /dev/null @@ -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; diff --git a/src/core/setters/main/site/nodeManager.ts b/src/core/setters/main/site/nodeManager.ts deleted file mode 100644 index 39fbebc..0000000 --- a/src/core/setters/main/site/nodeManager.ts +++ /dev/null @@ -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; diff --git a/src/core/setters/main/site/siteManager.ts b/src/core/setters/main/site/siteManager.ts deleted file mode 100644 index ea5173b..0000000 --- a/src/core/setters/main/site/siteManager.ts +++ /dev/null @@ -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; diff --git a/src/core/setters/media/mediaManager.ts b/src/core/setters/media/mediaManager.ts deleted file mode 100644 index ffaaa5a..0000000 --- a/src/core/setters/media/mediaManager.ts +++ /dev/null @@ -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; diff --git a/src/core/setters/progressManager.ts b/src/core/setters/progressManager.ts deleted file mode 100644 index 2eeb25b..0000000 --- a/src/core/setters/progressManager.ts +++ /dev/null @@ -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; diff --git a/src/core/setters/promptManager.ts b/src/core/setters/promptManager.ts deleted file mode 100644 index f985746..0000000 --- a/src/core/setters/promptManager.ts +++ /dev/null @@ -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; diff --git a/src/core/setters/sceneManager.ts b/src/core/setters/sceneManager.ts deleted file mode 100644 index a5f1abb..0000000 --- a/src/core/setters/sceneManager.ts +++ /dev/null @@ -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; diff --git a/src/core/setters/soundManager.ts b/src/core/setters/soundManager.ts deleted file mode 100644 index e307978..0000000 --- a/src/core/setters/soundManager.ts +++ /dev/null @@ -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; diff --git a/src/core/setters/sskn/ssknManager.ts b/src/core/setters/sskn/ssknManager.ts deleted file mode 100644 index be7f0cf..0000000 --- a/src/core/setters/sskn/ssknManager.ts +++ /dev/null @@ -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; diff --git a/src/resources/initial_progress.json b/src/resources/initial_progress.json index 427d11f..5573b9c 100644 --- a/src/resources/initial_progress.json +++ b/src/resources/initial_progress.json @@ -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 }, diff --git a/src/resources/site_a.json b/src/resources/site_a.json index 1d3d969..2ea5c1d 100644 --- a/src/resources/site_a.json +++ b/src/resources/site_a.json @@ -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.", diff --git a/src/resources/site_b.json b/src/resources/site_b.json index 1731fc6..e30ecfb 100644 --- a/src/resources/site_b.json +++ b/src/resources/site_b.json @@ -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.", diff --git a/src/scenes/ChangeDiscScene.tsx b/src/scenes/ChangeDiscScene.tsx index b1a1a85..2f3370f 100644 --- a/src/scenes/ChangeDiscScene.tsx +++ b/src/scenes/ChangeDiscScene.tsx @@ -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 <>; }; diff --git a/src/scenes/GateScene.tsx b/src/scenes/GateScene.tsx index 47e3923..f0e28d6 100644 --- a/src/scenes/GateScene.tsx +++ b/src/scenes/GateScene.tsx @@ -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 ( diff --git a/src/scenes/MainScene.tsx b/src/scenes/MainScene.tsx index a28d41d..9653385 100644 --- a/src/scenes/MainScene.tsx +++ b/src/scenes/MainScene.tsx @@ -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) { diff --git a/src/scenes/MediaScene.tsx b/src/scenes/MediaScene.tsx index ad83d5f..c4304ec 100644 --- a/src/scenes/MediaScene.tsx +++ b/src/scenes/MediaScene.tsx @@ -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 ( diff --git a/src/scenes/PolytanScene.tsx b/src/scenes/PolytanScene.tsx index 92e00d7..96c4616 100644 --- a/src/scenes/PolytanScene.tsx +++ b/src/scenes/PolytanScene.tsx @@ -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 ( diff --git a/src/scenes/SSknScene.tsx b/src/scenes/SSknScene.tsx deleted file mode 100644 index 8551c54..0000000 --- a/src/scenes/SSknScene.tsx +++ /dev/null @@ -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 ( - <> - - - - - ); -}; - -export default SSknScene; diff --git a/src/scenes/SsknScene.tsx b/src/scenes/SsknScene.tsx new file mode 100644 index 0000000..eb71455 --- /dev/null +++ b/src/scenes/SsknScene.tsx @@ -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 = () => ( + <> + + + + +); + +export default SsknScene; diff --git a/src/scenes/TaKScene.tsx b/src/scenes/TaKScene.tsx index 25f7f14..cc4903e 100644 --- a/src/scenes/TaKScene.tsx +++ b/src/scenes/TaKScene.tsx @@ -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 ; }; diff --git a/src/store.ts b/src/store.ts index ae7f4ca..01fa24d 100644 --- a/src/store.ts +++ b/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 }; + } +}; diff --git a/src/utils/idle-utils.ts b/src/utils/idle-utils.ts index 1d18930..3445058 100644 --- a/src/utils/idle-utils.ts +++ b/src/utils/idle-utils.ts @@ -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) { diff --git a/src/utils/media-utils.ts b/src/utils/media-utils.ts index 8a7f5be..4739c2a 100644 --- a/src/utils/media-utils.ts +++ b/src/utils/media-utils.ts @@ -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) => diff --git a/src/utils/node-animations.ts b/src/utils/node-animations.ts new file mode 100644 index 0000000..d712031 --- /dev/null +++ b/src/utils/node-animations.ts @@ -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"); + })(); +}; diff --git a/src/utils/node-utils.ts b/src/utils/node-utils.ts index 409c05e..9b170b8 100644 --- a/src/utils/node-utils.ts +++ b/src/utils/node-utils.ts @@ -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) => {