diff --git a/public/models/cut_cube.glb b/public/models/cut_cube.glb new file mode 100644 index 0000000..fb5e34d Binary files /dev/null and b/public/models/cut_cube.glb differ diff --git a/public/models/cyancrystal.glb b/public/models/cyan_crystal.glb similarity index 100% rename from public/models/cyancrystal.glb rename to public/models/cyan_crystal.glb diff --git a/public/models/gatePass.glb b/public/models/gate_mirror.glb similarity index 100% rename from public/models/gatePass.glb rename to public/models/gate_mirror.glb diff --git a/public/models/gold_node.glb b/public/models/gold_node.glb new file mode 100644 index 0000000..efccaf9 Binary files /dev/null and b/public/models/gold_node.glb differ diff --git a/src/App.tsx b/src/App.tsx index 9e27f53..52eb142 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -13,8 +13,8 @@ import TaKScene from "./scenes/TaKScene"; import ChangeDiscScene from "./scenes/ChangeDiscScene"; import EndScene from "./scenes/EndScene"; import IdleMediaScene from "./scenes/IdleMediaScene"; -import KeyPressHandler from "./core/state-management/KeyPressHandler"; -import Preloader from "./core/Preloader"; +import KeyPressHandler from "./components/KeyPressHandler"; +import Preloader from "./components/Preloader"; const App = () => { const currentScene = useStore((state) => state.currentScene); diff --git a/src/components/GateScene/GateMiddleObject/Mirror.tsx b/src/components/GateScene/GateMiddleObject/Mirror.tsx index 367a5d8..ec4940e 100644 --- a/src/components/GateScene/GateMiddleObject/Mirror.tsx +++ b/src/components/GateScene/GateMiddleObject/Mirror.tsx @@ -21,7 +21,7 @@ type MirrorProps = { const Mirror = (props: MirrorProps) => { const mirrorTex = useLoader(THREE.TextureLoader, mirrorTexture); - const { nodes } = useLoader(GLTFLoader, "models/gatePass.glb"); + const { nodes } = useLoader(GLTFLoader, "models/gate_mirror.glb"); const mirrorGroupRef = useRef(); const materialRef = useRef(); diff --git a/src/core/state-management/KeyPressHandler.tsx b/src/components/KeyPressHandler.tsx similarity index 65% rename from src/core/state-management/KeyPressHandler.tsx rename to src/components/KeyPressHandler.tsx index 4edd93b..95b850c 100644 --- a/src/core/state-management/KeyPressHandler.tsx +++ b/src/components/KeyPressHandler.tsx @@ -4,21 +4,23 @@ import { getMediaSceneContext, getSSknSceneContext, useStore, -} from "../../store"; -import { getKeyCodeAssociation } from "../../utils/keyPressUtils"; -import mediaManager from "../state-management/setters/media/mediaManager"; -import handleMediaSceneEvent from "./scene-keypress-handlers/handleMediaKeyPress"; -import sceneManager from "../state-management/setters/sceneManager"; -import levelSelectionManager from "./setters/main/level_selection/levelSelectionManager"; -import nodeManager from "./setters/main/site/nodeManager"; -import levelManager from "./setters/main/site/levelManager"; -import lainManager from "./setters/main/site/lainManager"; -import siteManager from "./setters/main/site/siteManager"; -import pauseManager from "./setters/main/pause/pauseManager"; -import mainSubsceneManager from "./setters/main/mainSubsceneManager"; -import ssknManager from "./setters/sskn/ssknManager"; -import handleSSknSceneEvent from "./scene-keypress-handlers/handleSSknKeyPress"; -import handleMainSceneEvent from "./scene-keypress-handlers/handleMainKeyPress"; +} from "../store"; +import { getKeyCodeAssociation } from "../utils/keyPressUtils"; +import mediaManager from "../core/setters/media/mediaManager"; +import handleMediaSceneEvent from "../core/scene-keypress-handlers/handleMediaKeyPress"; +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 handleSSknSceneEvent from "../core/scene-keypress-handlers/handleSSknKeyPress"; +import handleMainSceneEvent from "../core/scene-keypress-handlers/handleMainKeyPress"; +import gameLoader from "../core/setters/gameLoader"; +import gameSaver from "../core/setters/gameSaver"; const KeyPressHandler = () => { const mediaSceneSetters = useMemo(() => [mediaManager, sceneManager], []); @@ -33,6 +35,8 @@ const KeyPressHandler = () => { pauseManager, mainSubsceneManager, sceneManager, + gameLoader, + gameSaver, ], [] ); @@ -49,7 +53,7 @@ const KeyPressHandler = () => { const now = Date.now(); - if (keyPress && now > timePassedSinceLastKeyPress.current + 1500) { + if (keyPress) { timePassedSinceLastKeyPress.current = Date.now(); const sceneFns = (() => { diff --git a/src/components/MainScene/SyncedComponents/Site/CyanCrystal.tsx b/src/components/MainScene/SyncedComponents/Site/CyanCrystal.tsx index 13211ee..217f116 100644 --- a/src/components/MainScene/SyncedComponents/Site/CyanCrystal.tsx +++ b/src/components/MainScene/SyncedComponents/Site/CyanCrystal.tsx @@ -15,7 +15,7 @@ type GLTFResult = GLTF & { }; const CyanCrystal = memo((props: CrystalRingProps) => { - const { nodes } = useLoader(GLTFLoader, "models/cyancrystal.glb"); + const { nodes } = useLoader(GLTFLoader, "models/cyan_crystal.glb"); return ( { - const { nodes } = useLoader(GLTFLoader, "models/goldNode.glb"); + const { nodes } = useLoader(GLTFLoader, "models/gold_node.glb"); const activeNodeName = useStore( (state) => state.activeNode.node_name diff --git a/src/components/MediaScene/Selectables/LeftSide/TriangularPrism.tsx b/src/components/MediaScene/Selectables/LeftSide/TriangularPrism.tsx index 53a4490..7aa3c13 100644 --- a/src/components/MediaScene/Selectables/LeftSide/TriangularPrism.tsx +++ b/src/components/MediaScene/Selectables/LeftSide/TriangularPrism.tsx @@ -19,7 +19,7 @@ const TriangularPrism = memo((props: ShapeProps) => { const grayTex = useLoader(THREE.TextureLoader, grayTextureFile); const darkGrayTex = useLoader(THREE.TextureLoader, darkGrayTextureFile); - const { nodes } = useLoader(GLTFLoader, "models/cutcube.glb"); + const { nodes } = useLoader(GLTFLoader, "models/cut_cube.glb"); const prismRef = useRef(); diff --git a/src/core/Preloader.tsx b/src/components/Preloader.tsx similarity index 100% rename from src/core/Preloader.tsx rename to src/components/Preloader.tsx diff --git a/src/core/state-management/scene-keypress-handlers/handleBootKeyPress.ts b/src/core/scene-keypress-handlers/handleBootKeyPress.ts similarity index 100% rename from src/core/state-management/scene-keypress-handlers/handleBootKeyPress.ts rename to src/core/scene-keypress-handlers/handleBootKeyPress.ts diff --git a/src/core/state-management/scene-keypress-handlers/handleMainKeyPress.ts b/src/core/scene-keypress-handlers/handleMainKeyPress.ts similarity index 98% rename from src/core/state-management/scene-keypress-handlers/handleMainKeyPress.ts rename to src/core/scene-keypress-handlers/handleMainKeyPress.ts index 2709796..3554611 100644 --- a/src/core/state-management/scene-keypress-handlers/handleMainKeyPress.ts +++ b/src/core/scene-keypress-handlers/handleMainKeyPress.ts @@ -1,4 +1,4 @@ -import {findNode, getNodeById} from "../../../utils/node-utils"; +import { findNode, getNodeById } from "../../utils/node-utils"; const handleMainSceneEvent = (mainSceneContext: any) => { const { @@ -209,6 +209,7 @@ const handleMainSceneEvent = (mainSceneContext: any) => { case "CIRCLE": return { event: `pause_${activePauseComponent}_select`, + site: currentSite, }; } } diff --git a/src/core/state-management/scene-keypress-handlers/handleMediaKeyPress.ts b/src/core/scene-keypress-handlers/handleMediaKeyPress.ts similarity index 100% rename from src/core/state-management/scene-keypress-handlers/handleMediaKeyPress.ts rename to src/core/scene-keypress-handlers/handleMediaKeyPress.ts diff --git a/src/core/state-management/scene-keypress-handlers/handleSSknKeyPress.ts b/src/core/scene-keypress-handlers/handleSSknKeyPress.ts similarity index 100% rename from src/core/state-management/scene-keypress-handlers/handleSSknKeyPress.ts rename to src/core/scene-keypress-handlers/handleSSknKeyPress.ts diff --git a/src/core/state-management/setters/boot/bootSubsceneManager.ts b/src/core/setters/boot/bootSubsceneManager.ts similarity index 93% rename from src/core/state-management/setters/boot/bootSubsceneManager.ts rename to src/core/setters/boot/bootSubsceneManager.ts index 080c5cf..6be54d3 100644 --- a/src/core/state-management/setters/boot/bootSubsceneManager.ts +++ b/src/core/setters/boot/bootSubsceneManager.ts @@ -1,4 +1,4 @@ -import { useStore } from "../../../../store"; +import { useStore } from "../../../store"; const bootSubsceneManager = (eventState: any) => { const setBootSubscene = useStore.getState().setBootSubscene; diff --git a/src/core/setters/gameLoader.ts b/src/core/setters/gameLoader.ts new file mode 100644 index 0000000..96a07dd --- /dev/null +++ b/src/core/setters/gameLoader.ts @@ -0,0 +1,22 @@ +import { useStore } from "../../store"; + +const gameLoader = (eventState: any) => { + const loadSiteSaveState = useStore.getState().loadSiteSaveState; + + const dispatchAction = (eventState: { event: string; site: "a" | "b" }) => { + switch (eventState.event) { + case "pause_change_select": + return { + action: () => loadSiteSaveState(eventState.site === "a" ? "b" : "a"), + }; + } + }; + + const { action } = { ...dispatchAction(eventState) }; + + if (action) { + action(); + } +}; + +export default gameLoader; diff --git a/src/core/setters/gameSaver.ts b/src/core/setters/gameSaver.ts new file mode 100644 index 0000000..85fde49 --- /dev/null +++ b/src/core/setters/gameSaver.ts @@ -0,0 +1,23 @@ +import { getSiteState, useStore } from "../../store"; + +const gameSaver = (eventState: any) => { + const setSiteSaveState = useStore.getState().setSiteSaveState; + + const dispatchAction = (eventState: { event: string; site: "a" | "b" }) => { + switch (eventState.event) { + case "pause_change_select": + return { + action: () => + setSiteSaveState(eventState.site, getSiteState(eventState.site)), + }; + } + }; + + const { action } = { ...dispatchAction(eventState) }; + + if (action) { + action(); + } +}; + +export default gameSaver; diff --git a/src/core/state-management/setters/main/idleManager.ts b/src/core/setters/main/idleManager.ts similarity index 93% rename from src/core/state-management/setters/main/idleManager.ts rename to src/core/setters/main/idleManager.ts index fd65665..0447b34 100644 --- a/src/core/state-management/setters/main/idleManager.ts +++ b/src/core/setters/main/idleManager.ts @@ -1,4 +1,4 @@ -import { useStore } from "../../../../store"; +import { useStore } from "../../../store"; const idleManager = (eventState: any) => { const dispatchAction = (eventState: { diff --git a/src/core/state-management/setters/main/level_selection/levelSelectionManager.ts b/src/core/setters/main/level_selection/levelSelectionManager.ts similarity index 92% rename from src/core/state-management/setters/main/level_selection/levelSelectionManager.ts rename to src/core/setters/main/level_selection/levelSelectionManager.ts index 0175c9f..8d9feb2 100644 --- a/src/core/state-management/setters/main/level_selection/levelSelectionManager.ts +++ b/src/core/setters/main/level_selection/levelSelectionManager.ts @@ -1,4 +1,4 @@ -import { useStore } from "../../../../../store"; +import { useStore } from "../../../../store"; const levelSelectionManager = (eventState: any) => { const setSelectedLevel = useStore.getState().setSelectedLevel; diff --git a/src/core/state-management/setters/main/mainSubsceneManager.ts b/src/core/setters/main/mainSubsceneManager.ts similarity index 95% rename from src/core/state-management/setters/main/mainSubsceneManager.ts rename to src/core/setters/main/mainSubsceneManager.ts index 042760a..5e97a26 100644 --- a/src/core/state-management/setters/main/mainSubsceneManager.ts +++ b/src/core/setters/main/mainSubsceneManager.ts @@ -1,4 +1,4 @@ -import { useStore } from "../../../../store"; +import { useStore } from "../../../store"; const mainSubsceneManager = (eventState: any) => { const setMainSubscene = useStore.getState().setMainSubscene; diff --git a/src/core/state-management/setters/main/pause/pauseManager.ts b/src/core/setters/main/pause/pauseManager.ts similarity index 94% rename from src/core/state-management/setters/main/pause/pauseManager.ts rename to src/core/setters/main/pause/pauseManager.ts index 8a57616..6e1eb42 100644 --- a/src/core/state-management/setters/main/pause/pauseManager.ts +++ b/src/core/setters/main/pause/pauseManager.ts @@ -1,4 +1,4 @@ -import { useStore } from "../../../../../store"; +import { useStore } from "../../../../store"; type PauseManagerProps = { event: string; pauseMatrixIdx: number }; diff --git a/src/core/state-management/setters/main/site/lainManager.ts b/src/core/setters/main/site/lainManager.ts similarity index 97% rename from src/core/state-management/setters/main/site/lainManager.ts rename to src/core/setters/main/site/lainManager.ts index 746f91a..af3ffb7 100644 --- a/src/core/state-management/setters/main/site/lainManager.ts +++ b/src/core/setters/main/site/lainManager.ts @@ -1,4 +1,4 @@ -import { useStore } from "../../../../../store"; +import { useStore } from "../../../../store"; const lainManager = (eventState: any) => { const setLainMoveState = useStore.getState().setLainMoveState; diff --git a/src/core/state-management/setters/main/site/levelManager.ts b/src/core/setters/main/site/levelManager.ts similarity index 91% rename from src/core/state-management/setters/main/site/levelManager.ts rename to src/core/setters/main/site/levelManager.ts index e9ed5e1..5717bfc 100644 --- a/src/core/state-management/setters/main/site/levelManager.ts +++ b/src/core/setters/main/site/levelManager.ts @@ -1,4 +1,4 @@ -import { useStore } from "../../../../../store"; +import { useStore } from "../../../../store"; const levelManager = (eventState: any) => { const setActiveLevel = useStore.getState().setActiveLevel; diff --git a/src/core/state-management/setters/main/site/nodeManager.ts b/src/core/setters/main/site/nodeManager.ts similarity index 97% rename from src/core/state-management/setters/main/site/nodeManager.ts rename to src/core/setters/main/site/nodeManager.ts index 1a2ac25..95e5701 100644 --- a/src/core/state-management/setters/main/site/nodeManager.ts +++ b/src/core/setters/main/site/nodeManager.ts @@ -1,5 +1,5 @@ -import { useStore } from "../../../../../store"; -import { NodeDataType } from "../../../../../components/MainScene/SyncedComponents/Site"; +import { useStore } from "../../../../store"; +import { NodeDataType } from "../../../../components/MainScene/SyncedComponents/Site"; const nodeManager = (eventState: any) => { const setActiveNode = useStore.getState().setNode; diff --git a/src/core/state-management/setters/main/site/siteManager.ts b/src/core/setters/main/site/siteManager.ts similarity index 90% rename from src/core/state-management/setters/main/site/siteManager.ts rename to src/core/setters/main/site/siteManager.ts index 0efd85a..5c84024 100644 --- a/src/core/state-management/setters/main/site/siteManager.ts +++ b/src/core/setters/main/site/siteManager.ts @@ -1,4 +1,4 @@ -import { useStore } from "../../../../../store"; +import { useStore } from "../../../../store"; const siteManager = (eventState: any) => { const setRotY = useStore.getState().setSiteRotY; @@ -18,6 +18,7 @@ const siteManager = (eventState: any) => { delay: 3600, }; case "pause_exit_select": + case "pause_change_select": return { action: () => setRotX(0), delay: 0, diff --git a/src/core/state-management/setters/media/mediaManager.ts b/src/core/setters/media/mediaManager.ts similarity index 97% rename from src/core/state-management/setters/media/mediaManager.ts rename to src/core/setters/media/mediaManager.ts index e458445..11d787a 100644 --- a/src/core/state-management/setters/media/mediaManager.ts +++ b/src/core/setters/media/mediaManager.ts @@ -1,4 +1,4 @@ -import { useStore } from "../../../../store"; +import { useStore } from "../../../store"; import { useCallback } from "react"; import * as THREE from "three"; diff --git a/src/core/state-management/setters/sceneManager.ts b/src/core/setters/sceneManager.ts similarity index 97% rename from src/core/state-management/setters/sceneManager.ts rename to src/core/setters/sceneManager.ts index 346f971..f72830d 100644 --- a/src/core/state-management/setters/sceneManager.ts +++ b/src/core/setters/sceneManager.ts @@ -1,4 +1,4 @@ -import { useStore } from "../../../store"; +import { useStore } from "../../store"; const sceneManager = (eventState: any) => { const dispatchAction = (eventState: { event: string; scene: string }) => { diff --git a/src/core/state-management/setters/sskn/ssknManager.ts b/src/core/setters/sskn/ssknManager.ts similarity index 95% rename from src/core/state-management/setters/sskn/ssknManager.ts rename to src/core/setters/sskn/ssknManager.ts index d60af48..e964f51 100644 --- a/src/core/state-management/setters/sskn/ssknManager.ts +++ b/src/core/setters/sskn/ssknManager.ts @@ -1,4 +1,4 @@ -import { useStore } from "../../../../store"; +import { useStore } from "../../../store"; const ssknManager = (eventState: any) => { const toggleComponentMatrixIdx = useStore.getState() diff --git a/src/scenes/MainScene.tsx b/src/scenes/MainScene.tsx index 1640278..dac7e77 100644 --- a/src/scenes/MainScene.tsx +++ b/src/scenes/MainScene.tsx @@ -1,6 +1,6 @@ import { OrbitControls } from "@react-three/drei"; import React, { Suspense, useEffect, useMemo } from "react"; -import Preloader from "../core/Preloader"; +import Preloader from "../components/Preloader"; import { useStore } from "../store"; import Pause from "../components/MainScene/PauseSubscene/Pause"; import SyncedComponentLoader from "../components/MainScene/SyncedComponentLoader"; diff --git a/src/store.ts b/src/store.ts index 692b07b..65878b9 100644 --- a/src/store.ts +++ b/src/store.ts @@ -4,6 +4,7 @@ import * as THREE from "three"; import authorize_user_letters from "./resources/authorize_user_letters.json"; import game_progress from "./resources/initial_progress.json"; import { NodeDataType } from "./components/MainScene/SyncedComponents/Site"; +import { getNodeById } from "./utils/node-utils"; type State = { currentScene: string; @@ -92,6 +93,21 @@ type State = { // end scene endMediaPlayedCount: number; + + // save state + + siteSaveState: { + a: { + activeNode: NodeDataType; + siteRot: number[]; + activeLevel: string; + }; + b: { + activeNode: NodeDataType; + siteRot: number[]; + activeLevel: string; + }; + }; }; export const useStore = create( @@ -223,6 +239,26 @@ export const useStore = create( // end scene endMediaPlayedCount: 0, + + // save states for loading the game/changing sites + siteSaveState: { + a: { + activeNode: { + ...getNodeById("0422", "a"), + matrixIndices: { matrixIdx: 7, rowIdx: 0, colIdx: 0 }, + }, + siteRot: [0, 0, 0], + activeLevel: "04", + }, + b: { + activeNode: { + ...getNodeById("0414", "b"), + matrixIndices: { matrixIdx: 7, rowIdx: 1, colIdx: 0 }, + }, + siteRot: [0, 0, 0], + activeLevel: "04", + }, + }, } as State, (set) => ({ // scene data setters @@ -354,10 +390,44 @@ export const useStore = create( endMediaPlayedCount: state.endMediaPlayedCount + 1, })), resetEndMediaPlayedCount: () => set(() => ({ endMediaPlayedCount: 0 })), + + // site state setters + setSiteSaveState: ( + site: string, + to: { + activeNode: NodeDataType; + siteRot: number[]; + activeLevel: string; + } + ) => + set((state) => ({ + siteSaveState: { ...state.siteSaveState, [site]: to }, + })), + + loadSiteSaveState: (site: "a" | "b") => + set((state) => { + const stateToLoad = state.siteSaveState[site]; + return { + activeSite: site, + activeNode: stateToLoad.activeNode, + siteRot: stateToLoad.siteRot, + activeLevel: stateToLoad.activeLevel, + }; + }), }) ) ); +export const getSiteState = (site: "a" | "b") => { + const siteState = useStore.getState().siteSaveState[site]; + + return { + activeNode: siteState.activeNode, + siteRot: siteState.siteRot, + activeLevel: siteState.activeLevel, + }; +}; + export const getMainSceneContext = () => { const state = useStore.getState();