mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 23:19:06 +00:00
merged popups, main scene events done moving on to media
This commit is contained in:
parent
93d1b442ea
commit
7620610097
32 changed files with 561 additions and 862 deletions
|
@ -1,12 +1,16 @@
|
|||
import { useCallback, useEffect, useRef } from "react";
|
||||
import {
|
||||
BootSceneContext,
|
||||
EndSceneContext,
|
||||
getBootSceneContext,
|
||||
getEndSceneContext,
|
||||
getMainSceneContext,
|
||||
getMediaSceneContext,
|
||||
getSsknSceneContext,
|
||||
MainSceneContext,
|
||||
MediaSceneContext,
|
||||
playAudio,
|
||||
SsknSceneContext,
|
||||
useStore,
|
||||
} from "../store";
|
||||
import { getKeyCodeAssociation } from "../utils/keyPressUtils";
|
||||
|
@ -18,11 +22,11 @@ import { useFrame } from "react-three-fiber";
|
|||
import { getRandomIdleLainAnim } from "../utils/idle-utils";
|
||||
import * as audio from "../static/sfx";
|
||||
import handleEndSceneKeyPress from "../core/scene-keypress-handlers/handleEndSceneKeyPress";
|
||||
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";
|
||||
import handleEvent from "../core/scene-event-handlers/handleEvent";
|
||||
|
||||
const KeyPressHandler = () => {
|
||||
const scene = useStore((state) => state.currentScene);
|
||||
|
@ -79,66 +83,66 @@ const KeyPressHandler = () => {
|
|||
const now = Date.now();
|
||||
|
||||
if (
|
||||
keyPress &&
|
||||
!inputCooldown &&
|
||||
now > timeSinceLastKeyPress.current + 1500
|
||||
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,
|
||||
keyPressHandler: handleMainSceneKeyPress,
|
||||
eventHandler: handleMainSceneEvent,
|
||||
};
|
||||
case "media":
|
||||
return {
|
||||
contextProvider: getMediaSceneContext,
|
||||
keyPressHandler: handleMediaSceneKeyPress,
|
||||
eventHandler: handleMediaSceneEvent,
|
||||
};
|
||||
case "sskn":
|
||||
return {
|
||||
contextProvider: getSsknSceneContext,
|
||||
keyPressHandler: handleSsknSceneKeyPress,
|
||||
eventHandler: handleSsknSceneEvent,
|
||||
};
|
||||
case "boot":
|
||||
return {
|
||||
contextProvider: getBootSceneContext,
|
||||
keyPressHandler: handleBootSceneKeyPress,
|
||||
eventHandler: handleBootSceneEvent,
|
||||
};
|
||||
case "end":
|
||||
return {
|
||||
contextProvider: getEndSceneContext,
|
||||
keyPressHandler: handleEndSceneKeyPress,
|
||||
eventHandler: handleEndSceneEvent,
|
||||
};
|
||||
case "gate":
|
||||
case "polytan":
|
||||
useStore.setState({ currentScene: "main" });
|
||||
break;
|
||||
case "idle_media":
|
||||
useStore.setState({
|
||||
currentScene: "main",
|
||||
idleStarting: false,
|
||||
});
|
||||
break;
|
||||
// case "sskn":
|
||||
// return {
|
||||
// contextProvider: getSsknSceneContext,
|
||||
// keyPressHandler: handleSsknSceneKeyPress,
|
||||
// eventHandler: handleSsknSceneEvent,
|
||||
// };
|
||||
// case "boot":
|
||||
// return {
|
||||
// contextProvider: getBootSceneContext,
|
||||
// keyPressHandler: handleBootSceneKeyPress,
|
||||
// eventHandler: handleBootSceneEvent,
|
||||
// };
|
||||
// case "end":
|
||||
// return {
|
||||
// contextProvider: getEndSceneContext,
|
||||
// keyPressHandler: handleEndSceneKeyPress,
|
||||
// eventHandler: handleEndSceneEvent,
|
||||
// };
|
||||
// case "gate":
|
||||
// case "polytan":
|
||||
// useStore.setState({ currentScene: "main" });
|
||||
// break;
|
||||
// case "idle_media":
|
||||
// useStore.setState({
|
||||
// currentScene: "main",
|
||||
// idleStarting: false,
|
||||
// });
|
||||
// break;
|
||||
}
|
||||
})();
|
||||
|
||||
if (sceneFns) {
|
||||
const { contextProvider, keyPressHandler, eventHandler } = sceneFns;
|
||||
const { contextProvider, keyPressHandler } = sceneFns;
|
||||
|
||||
const ctx = contextProvider(keyPress);
|
||||
const event = keyPressHandler(ctx);
|
||||
if (event) eventHandler(event);
|
||||
const event = keyPressHandler(ctx as any) as any;
|
||||
if (event) handleEvent(event);
|
||||
// if (event) eventHandler(event.event, event.mutations);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { useMemo, useRef, memo } from "react";
|
||||
import * as THREE from "three";
|
||||
import { useFrame } from "react-three-fiber";
|
||||
import GrayPlane from "./GrayPlanes/GrayPlane";
|
||||
import GrayPlane from "./GrayPlane";
|
||||
|
||||
const GrayPlanes = memo(() => {
|
||||
const grayPlaneGroupRef = useRef<THREE.Object3D>();
|
|
@ -1,7 +1,7 @@
|
|||
import React, {Suspense, useEffect, useMemo, useRef, useState} from "react";
|
||||
import {useFrame, useLoader} from "react-three-fiber";
|
||||
import React, { Suspense, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useFrame, useLoader } from "react-three-fiber";
|
||||
import * as THREE from "three";
|
||||
import {PlainSingularAnimator} from "three-plain-animator/lib/plain-singular-animator";
|
||||
import { PlainSingularAnimator } from "three-plain-animator/lib/plain-singular-animator";
|
||||
import moveDownSpriteSheet from "../../static/sprite/jump_down.png";
|
||||
import moveUpSpriteSheet from "../../static/sprite/jump_up.png";
|
||||
import moveLeftSpriteSheet from "../../static/sprite/move_left.png";
|
||||
|
@ -12,7 +12,7 @@ import throwNodeSpriteSheet from "../../static/sprite/throw_node.png";
|
|||
import ripMiddleRingSpriteSheet from "../../static/sprite/rip_middle_ring.png";
|
||||
import knockSpriteSheet from "../../static/sprite/knock.png";
|
||||
import knockAndFallSpriteSheet from "../../static/sprite/knock_and_fall.png";
|
||||
import touchAndScareSpriteSheet from "../../static/sprite/touch_and_scare.png";
|
||||
import touchAndScareSpriteSheet from "../../static/sprite/touch_node_and_get_scared.png";
|
||||
import ripNodeSpriteSheet from "../../static/sprite/rip_node.png";
|
||||
import touchSleeveSpriteSheet from "../../static/sprite/touch_sleeve.png";
|
||||
import prayerSpriteSheet from "../../static/sprite/prayer.png";
|
||||
|
@ -32,7 +32,7 @@ import leanRightSpriteSheet from "../../static/sprite/lean_right.png";
|
|||
import lookAroundSpriteSheet from "../../static/sprite/look_around.png";
|
||||
import playWithHairSpriteSheet from "../../static/sprite/play_with_hair.png";
|
||||
|
||||
import {useStore} from "../../store";
|
||||
import { useStore } from "../../store";
|
||||
|
||||
type LainConstructorProps = {
|
||||
sprite: string;
|
||||
|
@ -368,17 +368,17 @@ const Lain = (props: LainProps) => {
|
|||
const lainAnimationDispatch = useMemo(() => {
|
||||
const anims = {
|
||||
standing: <LainStanding />,
|
||||
site_left: <LainMoveLeft />,
|
||||
site_right: <LainMoveRight />,
|
||||
site_up: <LainMoveUp />,
|
||||
site_down: <LainMoveDown />,
|
||||
move_left: <LainMoveLeft />,
|
||||
move_right: <LainMoveRight />,
|
||||
jump_up: <LainMoveUp />,
|
||||
jump_down: <LainMoveDown />,
|
||||
knock_and_fall: <LainKnockAndFall />,
|
||||
touch_and_scare: <LainTouchAndScare />,
|
||||
touch_node_and_get_scared: <LainTouchAndScare />,
|
||||
knock: <LainKnock />,
|
||||
select_level_down: <LainMoveDown />,
|
||||
select_level_up: <LainMoveUp />,
|
||||
throw_node: <LainThrowNode />,
|
||||
pause_game: <LainRipMiddleRing />,
|
||||
rip_middle_ring: <LainRipMiddleRing />,
|
||||
rip_node: <LainRipNode />,
|
||||
prayer: <LainPrayer />,
|
||||
scratch_head: <LainScratchHead />,
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import React, { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useFrame, useLoader } from "react-three-fiber";
|
||||
import middleRingTexture from "../../static/sprite/middle_ring_tex.png";
|
||||
import middleRingTexture from "../../../static/sprite/middle_ring_tex.png";
|
||||
import * as THREE from "three";
|
||||
import { a, useSpring } from "@react-spring/three";
|
||||
import { useStore } from "../../store";
|
||||
import MiddleRingPart from "./MiddleRing/MiddleRingPart";
|
||||
import usePrevious from "../../hooks/usePrevious";
|
||||
import lerp from "../../utils/lerp";
|
||||
import sleep from "../../utils/sleep";
|
||||
import { useStore } from "../../../store";
|
||||
import MiddleRingPart from "./MiddleRingPart";
|
||||
import usePrevious from "../../../hooks/usePrevious";
|
||||
import lerp from "../../../utils/lerp";
|
||||
import sleep from "../../../utils/sleep";
|
||||
|
||||
const MiddleRing = () => {
|
||||
const middleRingTex = useLoader(THREE.TextureLoader, middleRingTexture);
|
|
@ -1,48 +0,0 @@
|
|||
import React from "react";
|
||||
import notFound from "../../static/sprite/not_found.png";
|
||||
import notFoundLof from "../../static/sprite/not_found_lof.png";
|
||||
import { useLoader } from "react-three-fiber";
|
||||
import * as THREE from "three";
|
||||
|
||||
type NotFoundProps = {
|
||||
visible: boolean;
|
||||
};
|
||||
|
||||
const NotFound = (props: NotFoundProps) => {
|
||||
const notFoundTex = useLoader(THREE.TextureLoader, notFound);
|
||||
const notFoundLofTex = useLoader(THREE.TextureLoader, notFoundLof);
|
||||
|
||||
return (
|
||||
<>
|
||||
{props.visible && (
|
||||
<>
|
||||
<sprite
|
||||
scale={[1, 0.25, 0]}
|
||||
renderOrder={106}
|
||||
position={[-1, -0.05, 0]}
|
||||
>
|
||||
<spriteMaterial
|
||||
attach="material"
|
||||
map={notFoundLofTex}
|
||||
depthTest={false}
|
||||
/>
|
||||
</sprite>
|
||||
|
||||
<sprite
|
||||
scale={[4.1, 0.6, 0]}
|
||||
renderOrder={105}
|
||||
position={[0, -0.15, 0]}
|
||||
>
|
||||
<spriteMaterial
|
||||
attach="material"
|
||||
map={notFoundTex}
|
||||
depthTest={false}
|
||||
/>
|
||||
</sprite>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default NotFound;
|
|
@ -50,6 +50,8 @@ const Pause = () => {
|
|||
|
||||
const subscene = useStore((state) => state.mainSubscene);
|
||||
|
||||
const setInputCooldown = useStore((state) => state.setInputCooldown);
|
||||
|
||||
useEffect(() => {
|
||||
setAnimation(false);
|
||||
setIntro(true);
|
||||
|
@ -62,10 +64,11 @@ const Pause = () => {
|
|||
setTimeout(() => {
|
||||
setShowActiveComponent(true);
|
||||
setIntro(false);
|
||||
setInputCooldown(false);
|
||||
}, 3500);
|
||||
}, 3400);
|
||||
}
|
||||
}, [subscene]);
|
||||
}, [setInputCooldown, subscene]);
|
||||
|
||||
return (
|
||||
<>
|
|
@ -1,42 +0,0 @@
|
|||
import React from "react";
|
||||
import About from "./About";
|
||||
import Prompt from "../../Prompt";
|
||||
import PermissionDenied from "./PermissionDenied";
|
||||
import { useStore } from "../../../store";
|
||||
import Status from "../../Status";
|
||||
|
||||
const PausePopUps = () => {
|
||||
const subscene = useStore((state) => state.mainSubscene);
|
||||
|
||||
const showingAbout = useStore((state) => state.showingAbout);
|
||||
const promptVisible = useStore((state) => state.promptVisible);
|
||||
const permissionDenied = useStore((state) => state.permissionDenied);
|
||||
|
||||
return (
|
||||
<group
|
||||
position={[-0.85, -0.7, 0]}
|
||||
scale={[0.85, 0.85, 0]}
|
||||
visible={subscene === "pause"}
|
||||
>
|
||||
{showingAbout && <About />}
|
||||
<group
|
||||
position={[1, 0.6, 0]}
|
||||
scale={[1.2, 1.2, 0]}
|
||||
visible={promptVisible}
|
||||
>
|
||||
<Prompt />
|
||||
</group>
|
||||
<group
|
||||
position={[1, 0.6, 0]}
|
||||
scale={[1.2, 1.2, 0]}
|
||||
visible={permissionDenied}
|
||||
>
|
||||
<PermissionDenied />
|
||||
</group>
|
||||
|
||||
<Status />
|
||||
</group>
|
||||
);
|
||||
};
|
||||
|
||||
export default PausePopUps;
|
|
@ -5,6 +5,7 @@ import * as THREE from "three";
|
|||
import { useStore } from "../../../store";
|
||||
|
||||
const About = () => {
|
||||
const showingAbout = useStore((state) => state.showingAbout);
|
||||
const setShowingAbout = useStore((state) => state.setShowingAbout);
|
||||
const aboutBgTex = useLoader(THREE.TextureLoader, aboutBg);
|
||||
|
||||
|
@ -23,17 +24,29 @@ const About = () => {
|
|||
|
||||
return (
|
||||
<>
|
||||
<sprite renderOrder={199} scale={[100, 100, 0]}>
|
||||
<spriteMaterial attach="material" color={0x000000} depthTest={false} />
|
||||
</sprite>
|
||||
<sprite
|
||||
ref={bgRef}
|
||||
scale={[10.5 / 2.5, 52.8 / 2.5, 0]}
|
||||
position={[1.1, -13, 0.1]}
|
||||
renderOrder={200}
|
||||
>
|
||||
<spriteMaterial attach="material" map={aboutBgTex} depthTest={false} />
|
||||
</sprite>
|
||||
{showingAbout && (
|
||||
<>
|
||||
<sprite renderOrder={199} scale={[100, 100, 0]}>
|
||||
<spriteMaterial
|
||||
attach="material"
|
||||
color={0x000000}
|
||||
depthTest={false}
|
||||
/>
|
||||
</sprite>
|
||||
<sprite
|
||||
ref={bgRef}
|
||||
scale={[10.5 / 2.5, 52.8 / 2.5, 0]}
|
||||
position={[1.1, -13, 0.1]}
|
||||
renderOrder={200}
|
||||
>
|
||||
<spriteMaterial
|
||||
attach="material"
|
||||
map={aboutBgTex}
|
||||
depthTest={false}
|
||||
/>
|
||||
</sprite>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
28
src/components/MainScene/Popups/NotFound.tsx
Normal file
28
src/components/MainScene/Popups/NotFound.tsx
Normal file
|
@ -0,0 +1,28 @@
|
|||
import React, { memo } from "react";
|
||||
import notFound from "../../../static/sprite/not_found.png";
|
||||
import notFoundLof from "../../../static/sprite/not_found_lof.png";
|
||||
import { useLoader } from "react-three-fiber";
|
||||
import * as THREE from "three";
|
||||
|
||||
const NotFound = memo(() => {
|
||||
const notFoundTex = useLoader(THREE.TextureLoader, notFound);
|
||||
const notFoundLofTex = useLoader(THREE.TextureLoader, notFoundLof);
|
||||
|
||||
return (
|
||||
<group visible={false}>
|
||||
<sprite scale={[1, 0.25, 0]} renderOrder={106} position={[-1, -0.05, 0]}>
|
||||
<spriteMaterial
|
||||
attach="material"
|
||||
map={notFoundLofTex}
|
||||
depthTest={false}
|
||||
/>
|
||||
</sprite>
|
||||
|
||||
<sprite scale={[4.1, 0.6, 0]} renderOrder={105} position={[0, -0.15, 0]}>
|
||||
<spriteMaterial attach="material" map={notFoundTex} depthTest={false} />
|
||||
</sprite>
|
||||
</group>
|
||||
);
|
||||
});
|
||||
|
||||
export default NotFound;
|
|
@ -3,13 +3,16 @@ import headerContainer from "../../../static/sprite/prompt_question_container.pn
|
|||
import { useLoader } from "react-three-fiber";
|
||||
import * as THREE from "three";
|
||||
import StaticOrangeLetter from "../../TextRenderer/StaticOrangeLetter";
|
||||
import { useStore } from "../../../store";
|
||||
|
||||
const PermissionDenied = memo(() => {
|
||||
const headerContainerTex = useLoader(THREE.TextureLoader, headerContainer);
|
||||
|
||||
const permissionDenied = useStore((state) => state.permissionDenied);
|
||||
|
||||
return (
|
||||
<>
|
||||
<sprite scale={[4.1, 0.3, 0]} renderOrder={200} position={[0, 0.2, 0]}>
|
||||
<group position={[0, 0.5, 0]} visible={permissionDenied}>
|
||||
<sprite scale={[5, 0.36, 0]} renderOrder={200} position={[1, 0.2, 0]}>
|
||||
<spriteMaterial
|
||||
map={headerContainerTex}
|
||||
attach="material"
|
||||
|
@ -18,16 +21,12 @@ const PermissionDenied = memo(() => {
|
|||
depthTest={false}
|
||||
/>
|
||||
</sprite>
|
||||
<group scale={[0.08, 0.7, 0]} position={[-1, 0.19, 0]}>
|
||||
<group scale={[0.08, 0.7, 0]} position={[0, 0.19, 0]}>
|
||||
{"Permission denied".split("").map((letter, idx) => (
|
||||
<StaticOrangeLetter
|
||||
letter={letter}
|
||||
letterIdx={idx}
|
||||
key={idx}
|
||||
/>
|
||||
<StaticOrangeLetter letter={letter} letterIdx={idx} key={idx} />
|
||||
))}
|
||||
</group>
|
||||
</>
|
||||
</group>
|
||||
);
|
||||
});
|
||||
|
24
src/components/MainScene/Popups/Popups.tsx
Normal file
24
src/components/MainScene/Popups/Popups.tsx
Normal file
|
@ -0,0 +1,24 @@
|
|||
import React, { memo } from "react";
|
||||
import About from "./About";
|
||||
import Prompt from "../../Prompt";
|
||||
import PermissionDenied from "./PermissionDenied";
|
||||
import Status from "../../Status";
|
||||
import NotFound from "./NotFound";
|
||||
|
||||
const Popups = memo(() => {
|
||||
return (
|
||||
<>
|
||||
<group position={[-0.85, -0.7, 0]} scale={[0.85, 0.85, 0]}>
|
||||
<group position={[1, 0.6, 0]} scale={[1.2, 1.2, 0]}>
|
||||
<Prompt />
|
||||
</group>
|
||||
<About />
|
||||
<PermissionDenied />
|
||||
<Status />
|
||||
</group>
|
||||
<NotFound />
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
export default Popups;
|
|
@ -2,7 +2,7 @@ import React, { memo, useEffect, useState } from "react";
|
|||
import Node from "./Node";
|
||||
import node_positions from "../../../resources/node_positions.json";
|
||||
import { useStore } from "../../../store";
|
||||
import { NodeData, SiteData } from "../Site";
|
||||
import { NodeData, SiteData } from "./Site";
|
||||
import usePrevious from "../../../hooks/usePrevious";
|
||||
|
||||
type ActiveLevelNodesProps = {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { memo, useEffect, useState } from "react";
|
||||
import node_positions from "../../../resources/node_positions.json";
|
||||
import { useStore } from "../../../store";
|
||||
import { SiteData } from "../Site";
|
||||
import { SiteData } from "./Site";
|
||||
import InactiveLevelNode from "./InactiveLevelNode";
|
||||
import usePrevious from "../../../hooks/usePrevious";
|
||||
import { generateInactiveNodes } from "../../../utils/node-utils";
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import React, { Suspense, useEffect, useMemo } from "react";
|
||||
import { a, useSpring } from "@react-spring/three";
|
||||
import { useStore } from "../../store";
|
||||
import ActiveLevelNodes from "./Site/ActiveLevelNodes";
|
||||
import Rings from "./Site/Rings";
|
||||
import NodeAnimations from "./Site/NodeAnimations";
|
||||
import InactiveLevelNodes from "./Site/InactiveLevelNodes";
|
||||
import site_a from "../../resources/site_a.json";
|
||||
import site_b from "../../resources/site_b.json";
|
||||
import level_y_values from "../../resources/level_y_values.json";
|
||||
import { filterInvisibleNodes } from "../../utils/node-utils";
|
||||
import Loading from "../Loading";
|
||||
import { useStore } from "../../../store";
|
||||
import ActiveLevelNodes from "./ActiveLevelNodes";
|
||||
import Rings from "./Rings";
|
||||
import NodeAnimations from "./NodeAnimations";
|
||||
import InactiveLevelNodes from "./InactiveLevelNodes";
|
||||
import site_a from "../../../resources/site_a.json";
|
||||
import site_b from "../../../resources/site_b.json";
|
||||
import level_y_values from "../../../resources/level_y_values.json";
|
||||
import { filterInvisibleNodes } from "../../../utils/node-utils";
|
||||
import Loading from "../../Loading";
|
||||
|
||||
export type NodeData = {
|
||||
id: string;
|
|
@ -1,5 +1,5 @@
|
|||
import React, { memo, useEffect, useMemo, useState } from "react";
|
||||
import Star from "./Starfield/Star";
|
||||
import Star from "./Star";
|
||||
|
||||
type StarfieldProps = {
|
||||
shouldIntro: boolean;
|
|
@ -13,7 +13,7 @@ import ripNodeSpriteSheet from "../static/sprite/rip_node.png";
|
|||
import prayerSpriteSheet from "../static/sprite/prayer.png";
|
||||
import knockSpriteSheet from "../static/sprite/knock.png";
|
||||
import knockAndFallSpriteSheet from "../static/sprite/knock_and_fall.png";
|
||||
import touchAndScareSpriteSheet from "../static/sprite/touch_and_scare.png";
|
||||
import touchAndScareSpriteSheet from "../static/sprite/touch_node_and_get_scared.png";
|
||||
import touchSleeveSpriteSheet from "../static/sprite/touch_sleeve.png";
|
||||
import thinkingSpriteSheet from "../static/sprite/thinking.png";
|
||||
import stretchSpriteSheet from "../static/sprite/stretch.png";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from "react";
|
||||
import React, { memo } from "react";
|
||||
import answerContainer from "../static/sprite/prompt_answer_container.png";
|
||||
import questionContainer from "../static/sprite/prompt_question_container.png";
|
||||
import yes from "../static/sprite/prompt_yes.png";
|
||||
|
@ -8,7 +8,7 @@ import { useLoader } from "react-three-fiber";
|
|||
import * as THREE from "three";
|
||||
import { useStore } from "../store";
|
||||
|
||||
const Prompt = () => {
|
||||
const Prompt = memo(() => {
|
||||
const questionContainerTex = useLoader(
|
||||
THREE.TextureLoader,
|
||||
questionContainer
|
||||
|
@ -20,8 +20,10 @@ const Prompt = () => {
|
|||
|
||||
const activeComponent = useStore((state) => state.activePromptComponent);
|
||||
|
||||
const promptVisible = useStore((state) => state.promptVisible);
|
||||
|
||||
return (
|
||||
<>
|
||||
<group visible={promptVisible}>
|
||||
<sprite scale={[4.1, 0.3, 0]} renderOrder={200} position={[0, 0.2, 0]}>
|
||||
<spriteMaterial
|
||||
map={questionContainerTex}
|
||||
|
@ -79,8 +81,8 @@ const Prompt = () => {
|
|||
depthTest={false}
|
||||
/>
|
||||
</sprite>
|
||||
</>
|
||||
</group>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
export default Prompt;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { NodeData } from "../components/MainScene/Site";
|
||||
import { NodeData } from "../components/MainScene/Site/Site";
|
||||
import * as audio from "../static/sfx";
|
||||
import {
|
||||
nodeExplodeAnimation,
|
||||
|
@ -7,6 +7,7 @@ import {
|
|||
nodeRipAnimation,
|
||||
nodeThrowAnimation,
|
||||
} from "../utils/node-animations";
|
||||
import { playAudio } from "../store";
|
||||
|
||||
export const siteMoveHorizontal = (calculatedState: {
|
||||
lainMoveAnimation: string;
|
||||
|
@ -263,3 +264,159 @@ export const changePauseComponent = (calculatedState: {
|
|||
],
|
||||
audio: [{ sfx: [audio.sound1], delay: 0 }],
|
||||
});
|
||||
|
||||
export const showPermissionDenied = {
|
||||
state: [
|
||||
{ mutation: { permissionDenied: true }, delay: 0 },
|
||||
{ mutation: { permissionDenied: false }, delay: 1200 },
|
||||
],
|
||||
audio: [{ sfx: [audio.sound0], delay: 0 }],
|
||||
};
|
||||
|
||||
export const displayPrompt = {
|
||||
state: [{ mutation: { promptVisible: true }, delay: 0 }],
|
||||
audio: [{ sfx: [audio.sound0], delay: 0 }],
|
||||
};
|
||||
|
||||
export const showAbout = {
|
||||
state: [{ mutation: { showingAbout: true }, delay: 0 }],
|
||||
audio: [{ sfx: [audio.sound0], delay: 0 }],
|
||||
};
|
||||
|
||||
export const exitPause = (calculatedState: { siteRot: number[] }) => ({
|
||||
state: [
|
||||
{
|
||||
mutation: {
|
||||
siteRot: calculatedState.siteRot,
|
||||
pauseExitAnimation: true,
|
||||
activePauseComponent: "change",
|
||||
inputCooldown: true,
|
||||
},
|
||||
delay: 0,
|
||||
},
|
||||
{
|
||||
mutation: {
|
||||
mainSubscene: "site",
|
||||
inputCooldown: false,
|
||||
lainMoveState: "standing",
|
||||
},
|
||||
delay: 1200,
|
||||
},
|
||||
],
|
||||
audio: [{ sfx: [audio.sound0], delay: 0 }],
|
||||
});
|
||||
|
||||
export const exitAbout = {
|
||||
state: [{ mutation: { showingAbout: false }, delay: 0 }],
|
||||
};
|
||||
|
||||
export const changePromptComponent = (calculatedState: {
|
||||
activePromptComponent: "yes" | "no";
|
||||
}) => ({
|
||||
state: [
|
||||
{
|
||||
mutation: {
|
||||
activePromptComponent: calculatedState.activePromptComponent,
|
||||
},
|
||||
delay: 0,
|
||||
},
|
||||
],
|
||||
audio: [{ sfx: [audio.sound1], delay: 0 }],
|
||||
});
|
||||
|
||||
export const exitPrompt = {
|
||||
state: [
|
||||
{
|
||||
mutation: { activePromptComponent: "no", promptVisible: false },
|
||||
delay: 0,
|
||||
},
|
||||
],
|
||||
audio: [{ sfx: [audio.sound28], delay: 0 }],
|
||||
};
|
||||
|
||||
// todo actually save
|
||||
export const saveGame = () => ({
|
||||
state: [
|
||||
{
|
||||
mutation: { saveSuccessful: true },
|
||||
delay: 0,
|
||||
},
|
||||
{
|
||||
mutation: { saveSuccessful: undefined },
|
||||
delay: 1200,
|
||||
},
|
||||
],
|
||||
audio: [{ sfx: [audio.sound28], delay: 0 }],
|
||||
});
|
||||
|
||||
// todo actually load
|
||||
export const loadGame = () => ({
|
||||
state: [
|
||||
{
|
||||
mutation: { loadSuccessful: true },
|
||||
delay: 0,
|
||||
},
|
||||
{
|
||||
mutation: { loadSuccessful: undefined },
|
||||
delay: 1200,
|
||||
},
|
||||
],
|
||||
audio: [{ sfx: [audio.sound28], delay: 0 }],
|
||||
});
|
||||
|
||||
export const changeSite = (calculatedState: {
|
||||
newActiveSite: "a" | "b";
|
||||
newActiveNode: NodeData;
|
||||
newActiveLevel: string;
|
||||
newSiteRot: number[];
|
||||
newSiteSaveState: {
|
||||
a: {
|
||||
activeNode: NodeData;
|
||||
siteRot: number[];
|
||||
activeLevel: string;
|
||||
};
|
||||
b: {
|
||||
activeNode: NodeData;
|
||||
siteRot: number[];
|
||||
activeLevel: string;
|
||||
};
|
||||
};
|
||||
}) => ({
|
||||
state: [
|
||||
{
|
||||
mutation: {
|
||||
currentScene: "change_disc",
|
||||
lainMoveState: "standing",
|
||||
promptVisible: false,
|
||||
activePromptComponent: "no",
|
||||
mainSubscene: "site",
|
||||
// load state
|
||||
activeSite: calculatedState.newActiveSite,
|
||||
activeNode: calculatedState.newActiveNode,
|
||||
siteRot: calculatedState.newSiteRot,
|
||||
activeLevel: calculatedState.newActiveLevel,
|
||||
// save state
|
||||
siteSaveState: calculatedState.newSiteSaveState,
|
||||
},
|
||||
delay: 0,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
export const changeLeftMediaComponent = (calculatedState: {
|
||||
activeComponent: "play" | "exit";
|
||||
}) => ({
|
||||
state: [
|
||||
{ mutation: { activeMediaComponent: calculatedState.activeComponent } },
|
||||
],
|
||||
audio: [{ sfx: [audio.sound1], delay: 0 }],
|
||||
});
|
||||
|
||||
export const changeMediaSide = (calculatedState: {
|
||||
activeMediaComponent: "fstWord" | "sndWord" | "thirdWord" | "exit" | "play";
|
||||
lastActiveMediaComponents: {
|
||||
left: "play" | "exit";
|
||||
right: "fstWord" | "sndWord" | "thirdWord";
|
||||
};
|
||||
currentMediaSide: "right" | "left";
|
||||
}) => ({});
|
||||
|
|
|
@ -2,7 +2,7 @@ import { playAudio, useStore } from "../../store";
|
|||
import sleep from "../../utils/sleep";
|
||||
|
||||
type Mutation = {
|
||||
mutation: any;
|
||||
mutation: Object;
|
||||
delay: number;
|
||||
};
|
||||
|
||||
|
@ -19,7 +19,6 @@ type Event = {
|
|||
|
||||
// the async/await here might be misleading for some, it functions as a setTimeout that fires
|
||||
// multiple async calls without stopping the execution, which is what we want.
|
||||
|
||||
const handleEvent = (event: Event) => {
|
||||
const now = performance.now();
|
||||
const setState = useStore.setState;
|
||||
|
@ -42,7 +41,7 @@ const handleEvent = (event: Event) => {
|
|||
});
|
||||
}
|
||||
|
||||
console.log(performance.now() - now);
|
||||
// console.log(performance.now() - now);
|
||||
};
|
||||
|
||||
export default handleEvent;
|
||||
|
|
|
@ -1,321 +0,0 @@
|
|||
import { playAudio, useStore } from "../../store";
|
||||
import sleep from "../../utils/sleep";
|
||||
import * as audio from "../../static/sfx";
|
||||
import { NodeData } from "../../components/MainScene/Site";
|
||||
import {
|
||||
nodeKnock,
|
||||
nodeKnockAndFall,
|
||||
nodeRip,
|
||||
nodeThrow,
|
||||
nodeTouchAndScare,
|
||||
} from "../../utils/node-animations";
|
||||
|
||||
type MainSceneMutations = {
|
||||
level?: string;
|
||||
node?: NodeData;
|
||||
};
|
||||
|
||||
const handleMainSceneEvent = (eventState: any) => {
|
||||
const setState = useStore.setState;
|
||||
|
||||
const changeSite = useStore.getState().changeSite;
|
||||
|
||||
switch (eventState.event) {
|
||||
case "site_up":
|
||||
case "site_down":
|
||||
(async () => {
|
||||
setState({
|
||||
lainMoveState: eventState.event,
|
||||
activeLevel: eventState.level,
|
||||
inputCooldown: true,
|
||||
});
|
||||
playAudio(audio.sound13);
|
||||
|
||||
await sleep(1300);
|
||||
playAudio(audio.sound10);
|
||||
playAudio(audio.sound9);
|
||||
|
||||
await sleep(1400);
|
||||
playAudio(audio.sound8);
|
||||
|
||||
await sleep(1200);
|
||||
setState({
|
||||
activeNode: eventState.node,
|
||||
lainMoveState: "standing",
|
||||
inputCooldown: false,
|
||||
});
|
||||
})();
|
||||
break;
|
||||
case "site_left":
|
||||
case "site_right":
|
||||
(async () => {
|
||||
setState({
|
||||
lainMoveState: eventState.event,
|
||||
siteRot: [0, eventState.siteRotY, 0],
|
||||
inputCooldown: true,
|
||||
});
|
||||
|
||||
await sleep(1100);
|
||||
playAudio(audio.sound6);
|
||||
playAudio(audio.sound34);
|
||||
|
||||
await sleep(2800);
|
||||
setState({
|
||||
activeNode: eventState.node,
|
||||
lainMoveState: "standing",
|
||||
inputCooldown: false,
|
||||
});
|
||||
})();
|
||||
break;
|
||||
case "change_node":
|
||||
setState({ activeNode: eventState.node });
|
||||
playAudio(audio.sound1);
|
||||
break;
|
||||
case "throw_node_media":
|
||||
case "throw_node_sskn":
|
||||
case "throw_node_gate":
|
||||
case "throw_node_tak":
|
||||
case "throw_node_polytan":
|
||||
(async () => {
|
||||
setState({
|
||||
lainMoveState: "throw_node",
|
||||
oldLevel: eventState.level,
|
||||
oldSiteRot: [eventState.siteRotY, 0],
|
||||
inputCooldown: true,
|
||||
});
|
||||
|
||||
nodeThrow(eventState.siteRotY);
|
||||
|
||||
playAudio(audio.sound0);
|
||||
|
||||
await sleep(1600);
|
||||
playAudio(audio.sound12);
|
||||
|
||||
await sleep(1200);
|
||||
playAudio(audio.sound13);
|
||||
playAudio(audio.sound14);
|
||||
|
||||
await sleep(650);
|
||||
|
||||
setState({
|
||||
currentScene: eventState.event.split("_")[2],
|
||||
intro: false,
|
||||
lainMoveState: "standing",
|
||||
});
|
||||
})();
|
||||
break;
|
||||
case "rip_node_media":
|
||||
case "rip_node_gate":
|
||||
case "rip_node_sskn":
|
||||
case "rip_node_tak":
|
||||
case "rip_node_polytan":
|
||||
(async () => {
|
||||
setState({
|
||||
lainMoveState: "rip_node",
|
||||
oldLevel: eventState.level,
|
||||
oldSiteRot: [eventState.siteRotY, 0],
|
||||
inputCooldown: true,
|
||||
});
|
||||
nodeRip(eventState.siteRotY);
|
||||
playAudio(audio.sound0);
|
||||
|
||||
await sleep(1600);
|
||||
playAudio(audio.sound12);
|
||||
|
||||
await sleep(2400);
|
||||
playAudio(audio.sound15);
|
||||
playAudio(audio.sound13);
|
||||
|
||||
await sleep(2000);
|
||||
setState({
|
||||
currentScene: eventState.event.split("_")[2],
|
||||
intro: false,
|
||||
lainMoveState: "standing",
|
||||
});
|
||||
})();
|
||||
break;
|
||||
case "touch_and_scare":
|
||||
(async () => {
|
||||
setState({
|
||||
lainMoveState: "touch_and_scare",
|
||||
inputCooldown: true,
|
||||
});
|
||||
nodeTouchAndScare(eventState.siteRotY);
|
||||
|
||||
await sleep(2400);
|
||||
playAudio(audio.sound17);
|
||||
|
||||
await sleep(750);
|
||||
playAudio(audio.sound33);
|
||||
|
||||
await sleep(650);
|
||||
setState({
|
||||
lainMoveState: "standing",
|
||||
inputCooldown: false,
|
||||
});
|
||||
})();
|
||||
break;
|
||||
case "knock":
|
||||
(async () => {
|
||||
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", inputCooldown: true });
|
||||
nodeKnockAndFall(eventState.siteRotY);
|
||||
|
||||
await sleep(1200);
|
||||
playAudio(audio.sound18);
|
||||
|
||||
await sleep(1100);
|
||||
|
||||
playAudio(audio.sound19);
|
||||
|
||||
await sleep(850);
|
||||
playAudio(audio.sound33);
|
||||
|
||||
await sleep(3350);
|
||||
setState({ lainMoveState: "standing", inputCooldown: false });
|
||||
})();
|
||||
break;
|
||||
case "enter_level_selection":
|
||||
setState({
|
||||
selectedLevel: eventState.level,
|
||||
mainSubscene: "level_selection",
|
||||
});
|
||||
playAudio(audio.sound1);
|
||||
break;
|
||||
case "level_selection_up":
|
||||
case "level_selection_down":
|
||||
setState({ selectedLevel: eventState.selectedLevelIdx });
|
||||
break;
|
||||
case "level_selection_back":
|
||||
setState({ mainSubscene: "site" });
|
||||
playAudio(audio.sound1);
|
||||
break;
|
||||
case "select_level_up":
|
||||
case "select_level_down":
|
||||
(async () => {
|
||||
setState({
|
||||
lainMoveState: eventState.event,
|
||||
activeLevel: eventState.level,
|
||||
mainSubscene: "site",
|
||||
inputCooldown: true,
|
||||
});
|
||||
|
||||
await sleep(1300);
|
||||
playAudio(audio.sound10);
|
||||
playAudio(audio.sound9);
|
||||
|
||||
await sleep(1400);
|
||||
playAudio(audio.sound8);
|
||||
|
||||
await sleep(1200);
|
||||
setState({
|
||||
activeNode: eventState.node,
|
||||
lainMoveState: "standing",
|
||||
inputCooldown: false,
|
||||
});
|
||||
})();
|
||||
break;
|
||||
case "exit_not_found":
|
||||
setState({ mainSubscene: "site" });
|
||||
break;
|
||||
case "pause_game":
|
||||
(async () => {
|
||||
setState({
|
||||
lainMoveState: "pause_game",
|
||||
pauseExitAnimation: false,
|
||||
mainSubscene: "pause",
|
||||
inputCooldown: true,
|
||||
});
|
||||
playAudio(audio.sound7);
|
||||
|
||||
await sleep(3600);
|
||||
useStore.getState().setSiteRotX(Math.PI / 2);
|
||||
playAudio(audio.sound23);
|
||||
})();
|
||||
break;
|
||||
case "pause_up":
|
||||
case "pause_down":
|
||||
setState({ activePauseComponent: eventState.activePauseComponent });
|
||||
playAudio(audio.sound1);
|
||||
break;
|
||||
case "pause_exit_select":
|
||||
setState({
|
||||
pauseExitAnimation: true,
|
||||
activePauseComponent: "change",
|
||||
siteRot: eventState.siteRot,
|
||||
inputCooldown: true,
|
||||
});
|
||||
playAudio(audio.sound0);
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
export default handleMainSceneEvent;
|
|
@ -37,14 +37,6 @@ const handleMediaSceneEvent = (eventState: any) => {
|
|||
});
|
||||
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,
|
||||
|
|
|
@ -4,7 +4,6 @@ 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":
|
||||
|
@ -25,7 +24,7 @@ const handleSsknSceneEvent = (eventState: any) => {
|
|||
is_viewed: 1,
|
||||
is_visible: 0,
|
||||
});
|
||||
incrementSsknLvl();
|
||||
// incrementSsknLvl();
|
||||
|
||||
setTimeout(() => setState({ currentScene: "main" }), 6000);
|
||||
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
const handleEndSceneKeyPress = (endSceneContext: any) => {
|
||||
import { EndSceneContext } from "../../store";
|
||||
|
||||
const handleEndSceneKeyPress = (endSceneContext: EndSceneContext) => {
|
||||
const { keyPress, selectionVisible, activeEndComponent } = endSceneContext;
|
||||
|
||||
if (selectionVisible) {
|
||||
|
|
|
@ -5,6 +5,30 @@ import {
|
|||
unknownNodeTemplate,
|
||||
} from "../../utils/node-utils";
|
||||
import { MainSceneContext } from "../../store";
|
||||
import {
|
||||
changeNode,
|
||||
changePauseComponent,
|
||||
changePromptComponent,
|
||||
changeSelectedLevel,
|
||||
changeSite,
|
||||
displayPrompt,
|
||||
enterLevelSelection,
|
||||
exitAbout,
|
||||
exitLevelSelection,
|
||||
exitPause,
|
||||
exitPrompt,
|
||||
explodeNode,
|
||||
knockNode,
|
||||
knockNodeAndFall,
|
||||
loadGame,
|
||||
pauseGame,
|
||||
saveGame,
|
||||
selectLevel,
|
||||
showAbout,
|
||||
showPermissionDenied,
|
||||
siteMoveHorizontal,
|
||||
siteMoveVertical,
|
||||
} from "../eventTemplates";
|
||||
|
||||
const handleMainSceneKeyPress = (mainSceneContext: MainSceneContext) => {
|
||||
const {
|
||||
|
@ -22,23 +46,47 @@ const handleMainSceneKeyPress = (mainSceneContext: MainSceneContext) => {
|
|||
promptVisible,
|
||||
activePromptComponent,
|
||||
gateLvl,
|
||||
siteSaveState,
|
||||
} = mainSceneContext;
|
||||
|
||||
if (promptVisible) {
|
||||
switch (keyPress) {
|
||||
case "LEFT":
|
||||
return { event: "prompt_left" };
|
||||
return changePromptComponent({ activePromptComponent: "yes" });
|
||||
case "RIGHT":
|
||||
return { event: "prompt_right" };
|
||||
return changePromptComponent({ activePromptComponent: "no" });
|
||||
case "CIRCLE":
|
||||
switch (activePromptComponent) {
|
||||
case "no":
|
||||
return { event: "exit_prompt" };
|
||||
return exitPrompt;
|
||||
case "yes":
|
||||
return {
|
||||
event: `pause_${activePauseComponent}_select`,
|
||||
site: activeSite === "a" ? "b" : "a",
|
||||
};
|
||||
switch (activePauseComponent) {
|
||||
case "change":
|
||||
const siteToLoad = activeSite === "a" ? "b" : "a";
|
||||
const stateToLoad = siteSaveState[siteToLoad];
|
||||
|
||||
const newSiteSaveState = {
|
||||
...siteSaveState,
|
||||
[activeSite]: {
|
||||
activeNode: activeNode,
|
||||
siteRot: [0, siteRotY, 0],
|
||||
activeLevel: level.toString().padStart(2, "0"),
|
||||
},
|
||||
};
|
||||
console.log(newSiteSaveState);
|
||||
|
||||
return changeSite({
|
||||
newActiveSite: siteToLoad,
|
||||
newActiveNode: stateToLoad.activeNode,
|
||||
newSiteRot: stateToLoad.siteRot,
|
||||
newActiveLevel: stateToLoad.activeLevel,
|
||||
newSiteSaveState: newSiteSaveState,
|
||||
});
|
||||
case "save":
|
||||
return saveGame();
|
||||
case "load":
|
||||
return loadGame();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -47,11 +95,10 @@ const handleMainSceneKeyPress = (mainSceneContext: MainSceneContext) => {
|
|||
switch (keyPress) {
|
||||
case "LEFT":
|
||||
case "RIGHT": {
|
||||
const keyPressToLower = keyPress.toLowerCase();
|
||||
|
||||
const direction = keyPress.toLowerCase();
|
||||
const nodeData = findNode(
|
||||
activeNode.id,
|
||||
keyPressToLower,
|
||||
direction,
|
||||
activeNode.matrixIndices!,
|
||||
level,
|
||||
activeSite,
|
||||
|
@ -61,37 +108,38 @@ const handleMainSceneKeyPress = (mainSceneContext: MainSceneContext) => {
|
|||
|
||||
if (!nodeData) return;
|
||||
|
||||
const lainMoveAnimation = `move_${direction}`;
|
||||
const newSiteRot = [
|
||||
0,
|
||||
direction === "left"
|
||||
? siteRotY + Math.PI / 4
|
||||
: siteRotY - Math.PI / 4,
|
||||
0,
|
||||
];
|
||||
const newNode = {
|
||||
...(nodeData.node !== "unknown"
|
||||
? getNodeById(nodeData.node, activeSite)
|
||||
: unknownNodeTemplate),
|
||||
matrixIndices: nodeData.matrixIndices,
|
||||
};
|
||||
|
||||
if (nodeData.didMove) {
|
||||
return {
|
||||
event: keyPressToLower === "left" ? `site_left` : "site_right",
|
||||
siteRotY:
|
||||
keyPressToLower === "left"
|
||||
? siteRotY + Math.PI / 4
|
||||
: siteRotY - Math.PI / 4,
|
||||
node: {
|
||||
...(nodeData.node !== "unknown"
|
||||
? getNodeById(nodeData.node, activeSite)
|
||||
: unknownNodeTemplate),
|
||||
matrixIndices: nodeData.matrixIndices,
|
||||
},
|
||||
};
|
||||
return siteMoveHorizontal({
|
||||
lainMoveAnimation: lainMoveAnimation,
|
||||
siteRot: newSiteRot,
|
||||
activeNode: newNode,
|
||||
});
|
||||
} else {
|
||||
return {
|
||||
event: "change_node",
|
||||
nodeMatrixIndices: nodeData.matrixIndices,
|
||||
node: {
|
||||
...getNodeById(nodeData.node, activeSite),
|
||||
matrixIndices: nodeData.matrixIndices,
|
||||
},
|
||||
};
|
||||
return changeNode({ activeNode: newNode });
|
||||
}
|
||||
}
|
||||
case "UP":
|
||||
case "DOWN": {
|
||||
const keyPressToLower = keyPress.toLowerCase();
|
||||
const direction = keyPress.toLowerCase();
|
||||
|
||||
const nodeData = findNode(
|
||||
activeNode.id,
|
||||
keyPressToLower,
|
||||
direction,
|
||||
activeNode.matrixIndices!,
|
||||
level,
|
||||
activeSite,
|
||||
|
@ -101,28 +149,24 @@ const handleMainSceneKeyPress = (mainSceneContext: MainSceneContext) => {
|
|||
|
||||
if (!nodeData) return;
|
||||
|
||||
if (nodeData.didMove) {
|
||||
return {
|
||||
event: keyPressToLower === "up" ? "site_up" : "site_down",
|
||||
level: (keyPressToLower === "up" ? level + 1 : level - 1)
|
||||
.toString()
|
||||
.padStart(2, "0"),
|
||||
node: {
|
||||
...(nodeData.node !== "unknown"
|
||||
? getNodeById(nodeData.node, activeSite)
|
||||
: unknownNodeTemplate),
|
||||
matrixIndices: nodeData.matrixIndices,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
event: "change_node",
|
||||
node: {
|
||||
...getNodeById(nodeData.node, activeSite),
|
||||
matrixIndices: nodeData.matrixIndices,
|
||||
},
|
||||
};
|
||||
}
|
||||
const lainMoveAnimation = `jump_${direction}`;
|
||||
const newLevel = (direction === "up" ? level + 1 : level - 1)
|
||||
.toString()
|
||||
.padStart(2, "0");
|
||||
const newNode = {
|
||||
...(nodeData.node !== "unknown"
|
||||
? getNodeById(nodeData.node, activeSite)
|
||||
: unknownNodeTemplate),
|
||||
matrixIndices: nodeData.matrixIndices,
|
||||
};
|
||||
|
||||
if (nodeData.didMove)
|
||||
return siteMoveVertical({
|
||||
lainMoveAnimation: lainMoveAnimation,
|
||||
activeLevel: newLevel,
|
||||
activeNode: newNode,
|
||||
});
|
||||
else return changeNode({ activeNode: newNode });
|
||||
}
|
||||
case "CIRCLE":
|
||||
const eventAnimation =
|
||||
|
@ -137,21 +181,8 @@ const handleMainSceneKeyPress = (mainSceneContext: MainSceneContext) => {
|
|||
return;
|
||||
|
||||
if (activeNode.upgrade_requirement > ssknLvl) {
|
||||
const rejectAnimations = [
|
||||
"touch_and_scare",
|
||||
"knock_and_fall",
|
||||
"knock",
|
||||
];
|
||||
|
||||
const pickedAnim =
|
||||
rejectAnimations[
|
||||
Math.floor(Math.random() * rejectAnimations.length)
|
||||
];
|
||||
|
||||
return {
|
||||
event: pickedAnim,
|
||||
siteRotY: siteRotY,
|
||||
};
|
||||
const rejectEvents = [explodeNode, knockNode, knockNodeAndFall];
|
||||
return rejectEvents[Math.floor(Math.random() * 3)];
|
||||
}
|
||||
|
||||
switch (nodeType) {
|
||||
|
@ -162,101 +193,56 @@ const handleMainSceneKeyPress = (mainSceneContext: MainSceneContext) => {
|
|||
case 5:
|
||||
return {
|
||||
event: `${eventAnimation}_media`,
|
||||
scene: "media",
|
||||
siteRotY: siteRotY,
|
||||
level: level.toString().padStart(2, "0"),
|
||||
mutations: { scene: "media" },
|
||||
};
|
||||
case 6:
|
||||
if (activeNode.node_name.substr(0, 3) === "TaK") {
|
||||
return {
|
||||
event: `${eventAnimation}_tak`,
|
||||
scene: "tak",
|
||||
siteRotY: siteRotY,
|
||||
node: activeNode,
|
||||
mutations: { scene: "tak" },
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
event: `${eventAnimation}_media`,
|
||||
scene: "media",
|
||||
siteRotY: siteRotY,
|
||||
level: level.toString().padStart(2, "0"),
|
||||
mutations: { scene: "media" },
|
||||
};
|
||||
}
|
||||
case 8:
|
||||
return {
|
||||
event: `${eventAnimation}_gate`,
|
||||
scene: "gate",
|
||||
siteRotY: siteRotY,
|
||||
node: activeNode,
|
||||
mutations: { scene: "gate" },
|
||||
};
|
||||
case 7:
|
||||
return {
|
||||
event: `${eventAnimation}_sskn`,
|
||||
scene: "sskn",
|
||||
siteRotY: siteRotY,
|
||||
mutations: { scene: "sskn" },
|
||||
};
|
||||
case 9:
|
||||
const bodyPart = (() => {
|
||||
switch (parseInt(activeNode.node_name.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";
|
||||
}
|
||||
})();
|
||||
return {
|
||||
event: `${eventAnimation}_polytan`,
|
||||
scene: "polytan",
|
||||
siteRotY: siteRotY,
|
||||
node: activeNode,
|
||||
bodyPart: bodyPart,
|
||||
mutations: { scene: "polytan" },
|
||||
};
|
||||
}
|
||||
break;
|
||||
case "L2":
|
||||
return { event: "enter_level_selection", level: level };
|
||||
return enterLevelSelection({ selectedLevel: level });
|
||||
case "TRIANGLE":
|
||||
return { event: "pause_game" };
|
||||
case "SPACE":
|
||||
return { event: "play_with_hair", siteRotY: siteRotY };
|
||||
return pauseGame({ siteRot: [Math.PI / 2, siteRotY, 0] });
|
||||
}
|
||||
break;
|
||||
case "level_selection":
|
||||
switch (keyPress) {
|
||||
case "UP":
|
||||
if (activeSite === "a") {
|
||||
if (selectedLevel + 1 <= 22)
|
||||
return {
|
||||
event: `level_selection_up`,
|
||||
selectedLevelIdx: selectedLevel + 1,
|
||||
};
|
||||
} else if (activeSite === "b") {
|
||||
if (selectedLevel + 1 <= 13)
|
||||
return {
|
||||
event: `level_selection_up`,
|
||||
selectedLevelIdx: selectedLevel + 1,
|
||||
};
|
||||
}
|
||||
const upperLimit = activeSite === "a" ? 22 : 13;
|
||||
if (selectedLevel + 1 <= upperLimit)
|
||||
return changeSelectedLevel({ selectedLevel: selectedLevel + 1 });
|
||||
break;
|
||||
case "DOWN":
|
||||
if (selectedLevel - 1 >= 1)
|
||||
return {
|
||||
event: `level_selection_down`,
|
||||
selectedLevelIdx: selectedLevel - 1,
|
||||
};
|
||||
return changeSelectedLevel({ selectedLevel: selectedLevel - 1 });
|
||||
break;
|
||||
case "X":
|
||||
return {
|
||||
event: "level_selection_back",
|
||||
};
|
||||
return exitLevelSelection;
|
||||
|
||||
case "CIRCLE":
|
||||
if (level === selectedLevel) return;
|
||||
|
@ -275,96 +261,59 @@ const handleMainSceneKeyPress = (mainSceneContext: MainSceneContext) => {
|
|||
);
|
||||
|
||||
if (nodeData) {
|
||||
const event =
|
||||
selectedLevel < level ? "select_level_down" : "select_level_up";
|
||||
return {
|
||||
event: event,
|
||||
node: {
|
||||
...(nodeData.node !== "unknown"
|
||||
? getNodeById(nodeData.node, activeSite)
|
||||
: unknownNodeTemplate),
|
||||
matrixIndices: nodeData.matrixIndices,
|
||||
},
|
||||
level: selectedLevel.toString().padStart(2, "0"),
|
||||
const newLevel = selectedLevel.toString().padStart(2, "0");
|
||||
const newNode = {
|
||||
...(nodeData.node !== "unknown"
|
||||
? getNodeById(nodeData.node, activeSite)
|
||||
: unknownNodeTemplate),
|
||||
matrixIndices: nodeData.matrixIndices,
|
||||
};
|
||||
const lainMoveState =
|
||||
selectedLevel < level ? "jump_down" : "jump_up";
|
||||
|
||||
return selectLevel({
|
||||
lainMoveState: lainMoveState,
|
||||
activeLevel: newLevel,
|
||||
activeNode: newNode,
|
||||
});
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "pause":
|
||||
if (showingAbout)
|
||||
return {
|
||||
event: "exit_about",
|
||||
};
|
||||
else {
|
||||
switch (keyPress) {
|
||||
case "UP": {
|
||||
const newComponent = (() => {
|
||||
switch (activePauseComponent) {
|
||||
case "exit":
|
||||
return "save";
|
||||
case "save":
|
||||
return "change";
|
||||
case "change":
|
||||
return "about";
|
||||
case "about":
|
||||
return "load";
|
||||
}
|
||||
})();
|
||||
if (showingAbout) return exitAbout;
|
||||
switch (keyPress) {
|
||||
case "UP":
|
||||
case "DOWN":
|
||||
const direction = keyPress.toLowerCase();
|
||||
const components = ["load", "about", "change", "save", "exit"];
|
||||
|
||||
if (newComponent)
|
||||
return {
|
||||
event: "pause_up",
|
||||
activePauseComponent: newComponent,
|
||||
};
|
||||
break;
|
||||
const newComponent =
|
||||
components[
|
||||
components.indexOf(activePauseComponent) +
|
||||
(direction === "up" ? -1 : 1)
|
||||
];
|
||||
|
||||
if (newComponent)
|
||||
return changePauseComponent({
|
||||
activePauseComponent: newComponent,
|
||||
});
|
||||
break;
|
||||
case "CIRCLE":
|
||||
switch (activePauseComponent) {
|
||||
case "about":
|
||||
return showAbout;
|
||||
case "exit":
|
||||
return exitPause({ siteRot: [0, siteRotY, 0] });
|
||||
case "save":
|
||||
case "load":
|
||||
return displayPrompt;
|
||||
case "change":
|
||||
if (activePauseComponent === "change" && gateLvl > 4)
|
||||
return showPermissionDenied;
|
||||
else return displayPrompt;
|
||||
}
|
||||
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) {
|
||||
return { event: "show_permission_denied" };
|
||||
} else {
|
||||
return {
|
||||
event: "display_prompt",
|
||||
};
|
||||
}
|
||||
} else if (
|
||||
activePauseComponent === "save" ||
|
||||
activePauseComponent === "load"
|
||||
) {
|
||||
return {
|
||||
event: "display_prompt",
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
event: `pause_${activePauseComponent}_select`,
|
||||
siteRot: [0, siteRotY, 0],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "not_found":
|
||||
return { event: "exit_not_found" };
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { findNodeFromWord } from "../../utils/media-utils";
|
||||
import { MediaSceneContext } from "../../store";
|
||||
import { changeLeftMediaComponent, changeMediaSide } from "../eventTemplates";
|
||||
|
||||
const handleMediaSceneKeyPress = (mediaSceneContext: MediaSceneContext) => {
|
||||
const {
|
||||
|
@ -17,16 +18,21 @@ const handleMediaSceneKeyPress = (mediaSceneContext: MediaSceneContext) => {
|
|||
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 "DOWN": {
|
||||
const direction = keyPress.toLowerCase();
|
||||
const newComponent = direction === "up" ? "play" : "exit";
|
||||
return changeLeftMediaComponent({ activeComponent: newComponent });
|
||||
}
|
||||
case "RIGHT": {
|
||||
return changeMediaSide({
|
||||
activeMediaComponent: lastActiveMediaComponents.right,
|
||||
lastActiveMediaComponents: {
|
||||
...lastActiveMediaComponents,
|
||||
left: activeMediaComponent as "play" | "exit",
|
||||
},
|
||||
currentMediaSide: "right",
|
||||
});
|
||||
}
|
||||
case "CIRCLE":
|
||||
switch (activeMediaComponent) {
|
||||
case "play":
|
||||
|
@ -84,11 +90,17 @@ const handleMediaSceneKeyPress = (mediaSceneContext: MediaSceneContext) => {
|
|||
}
|
||||
|
||||
case "LEFT":
|
||||
return {
|
||||
event: "media_rightside_left",
|
||||
lastActiveComponent: activeMediaComponent,
|
||||
newActiveComponent: lastActiveMediaComponents.left,
|
||||
};
|
||||
return changeMediaSide({
|
||||
activeMediaComponent: lastActiveMediaComponents.left,
|
||||
lastActiveMediaComponents: {
|
||||
...lastActiveMediaComponents,
|
||||
right: activeMediaComponent as
|
||||
| "fstWord"
|
||||
| "sndWord"
|
||||
| "thirdWord",
|
||||
},
|
||||
currentMediaSide: "left",
|
||||
});
|
||||
|
||||
case "CIRCLE":
|
||||
const data = findNodeFromWord(
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
import { OrbitControls } from "@react-three/drei";
|
||||
import React, { Suspense, useEffect, useRef, useState } from "react";
|
||||
import { playAudio, useStore } from "../store";
|
||||
import Pause from "../components/MainScene/PauseSubscene/Pause";
|
||||
import Pause from "../components/MainScene/Pause/Pause";
|
||||
import LevelSelection from "../components/MainScene/LevelSelection";
|
||||
import HUD from "../components/MainScene/HUD";
|
||||
import MainYellowTextAnimator from "../components/TextRenderer/MainYellowTextAnimator";
|
||||
import YellowOrb from "../components/MainScene/YellowOrb";
|
||||
import MiddleRing from "../components/MainScene/MiddleRing";
|
||||
import GrayPlanes from "../components/MainScene/GrayPlanes";
|
||||
import Starfield from "../components/MainScene/Starfield";
|
||||
import Site from "../components/MainScene/Site";
|
||||
import MiddleRing from "../components/MainScene/MiddleRing/MiddleRing";
|
||||
import GrayPlanes from "../components/MainScene/GrayPlanes/GrayPlanes";
|
||||
import Starfield from "../components/MainScene/Starfield/Starfield";
|
||||
import Site from "../components/MainScene/Site/Site";
|
||||
import Lain from "../components/MainScene/Lain";
|
||||
import * as THREE from "three";
|
||||
import { useFrame } from "react-three-fiber";
|
||||
import NotFound from "../components/MainScene/NotFound";
|
||||
import PausePopUps from "../components/MainScene/PauseSubscene/PausePopUps";
|
||||
import Popups from "../components/MainScene/Popups/Popups";
|
||||
import * as audio from "../static/sfx";
|
||||
import Loading from "../components/Loading";
|
||||
import usePrevious from "../hooks/usePrevious";
|
||||
|
@ -94,9 +93,8 @@ const MainScene = () => {
|
|||
<perspectiveCamera position-z={3}>
|
||||
<Suspense fallback={<Loading />}>
|
||||
<LevelSelection />
|
||||
<PausePopUps />
|
||||
<Popups />
|
||||
<Pause />
|
||||
<NotFound visible={subscene === "not_found"} />
|
||||
<group visible={!paused}>
|
||||
<group visible={!wordSelected && (intro ? introFinished : true)}>
|
||||
<group visible={subscene !== "not_found"}>
|
||||
|
|
115
src/store.ts
115
src/store.ts
|
@ -2,7 +2,7 @@ import create from "zustand";
|
|||
import { combine } from "zustand/middleware";
|
||||
import * as THREE from "three";
|
||||
import game_progress from "./resources/initial_progress.json";
|
||||
import { NodeData } from "./components/MainScene/Site";
|
||||
import { NodeData } from "./components/MainScene/Site/Site";
|
||||
import { getNodeById } from "./utils/node-utils";
|
||||
import site_a from "./resources/site_a.json";
|
||||
|
||||
|
@ -126,7 +126,7 @@ export const useStore = create(
|
|||
combine(
|
||||
{
|
||||
// scene data
|
||||
currentScene: "boot",
|
||||
currentScene: "media",
|
||||
|
||||
// game progress
|
||||
gameProgress: game_progress,
|
||||
|
@ -258,14 +258,7 @@ export const useStore = create(
|
|||
// scene data setters
|
||||
setScene: (to: string) => set(() => ({ currentScene: to })),
|
||||
|
||||
// main subscene setter
|
||||
setMainSubscene: (to: string) => set(() => ({ mainSubscene: to })),
|
||||
|
||||
// intro setters
|
||||
setIntro: (to: boolean) => set(() => ({ intro: to })),
|
||||
|
||||
// node setters
|
||||
setNode: (to: NodeData) => set(() => ({ activeNode: to })),
|
||||
setNodePos: (to: number[]) => set(() => ({ activeNodePos: to })),
|
||||
setNodeRot: (to: number[]) => set(() => ({ activeNodeRot: to })),
|
||||
setNodeAttributes: (
|
||||
|
@ -280,41 +273,19 @@ export const useStore = create(
|
|||
setLainMoveState: (to: string) => set(() => ({ lainMoveState: to })),
|
||||
|
||||
// site setters
|
||||
setActiveSite: (to: "a" | "b") => set(() => ({ activeSite: to })),
|
||||
setSiteRotY: (to: number) =>
|
||||
set((prev) => {
|
||||
const nextRot = [...prev.siteRot];
|
||||
nextRot[1] = to;
|
||||
return { siteRot: nextRot };
|
||||
}),
|
||||
setSiteRotX: (to: number) =>
|
||||
set((prev) => {
|
||||
const nextRot = [...prev.siteRot];
|
||||
nextRot[0] = to;
|
||||
return { siteRot: nextRot };
|
||||
}),
|
||||
setOldSiteRot: (to: number[]) =>
|
||||
set(() => ({
|
||||
oldSiteRot: to,
|
||||
})),
|
||||
|
||||
// level setters
|
||||
setActiveLevel: (to: string) => set(() => ({ activeLevel: to })),
|
||||
setOldLevel: (to: string) => set(() => ({ oldLevel: to })),
|
||||
|
||||
// level selection setters
|
||||
setSelectedLevel: (to: number) => set(() => ({ selectedLevel: to })),
|
||||
|
||||
// end scene setters
|
||||
setEndSceneSelectionVisible: (to: boolean) =>
|
||||
set(() => ({ endSceneSelectionVisible: to })),
|
||||
|
||||
// pause setters
|
||||
setPauseExitAnimation: (to: boolean) =>
|
||||
set(() => ({ pauseExitAnimation: to })),
|
||||
setShowingAbout: (to: boolean) => set(() => ({ showingAbout: to })),
|
||||
setPermissionDenied: (to: boolean) =>
|
||||
set(() => ({ permissionDenied: to })),
|
||||
|
||||
// media scene setters
|
||||
setAudioAnalyser: (to: any) => set(() => ({ audioAnalyser: to })),
|
||||
|
@ -368,41 +339,6 @@ export const useStore = create(
|
|||
},
|
||||
})),
|
||||
|
||||
// gate scene setters
|
||||
incrementGateLvl: () => set((state) => ({ gateLvl: state.gateLvl + 1 })),
|
||||
|
||||
// player name setters
|
||||
setPlayerName: (to: string) => set(() => ({ playerName: to })),
|
||||
|
||||
// boot scene setters
|
||||
setBootSubscene: (to: "load_data" | "authorize_user" | "main_menu") =>
|
||||
set(() => ({ bootSubscene: to })),
|
||||
|
||||
setAuthorizeUserLetterIdx: (to: number) =>
|
||||
set(() => ({ authorizeUserLetterIdx: to })),
|
||||
|
||||
// site state setters
|
||||
setSiteSaveState: (
|
||||
site: string,
|
||||
to: {
|
||||
activeNode: NodeData;
|
||||
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,
|
||||
};
|
||||
}),
|
||||
changeSite: (to: "a" | "b") =>
|
||||
set((state) => {
|
||||
const newState = state.siteSaveState[to];
|
||||
|
@ -428,12 +364,6 @@ export const useStore = create(
|
|||
};
|
||||
}),
|
||||
|
||||
// status notifier setters
|
||||
setSaveSuccessful: (to: boolean | undefined) =>
|
||||
set(() => ({ saveSuccessful: to })),
|
||||
setLoadSuccessful: (to: boolean | undefined) =>
|
||||
set(() => ({ loadSuccessful: to })),
|
||||
|
||||
// progress setters
|
||||
setNodeViewed: (
|
||||
nodeName: string,
|
||||
|
@ -447,22 +377,10 @@ export const useStore = create(
|
|||
})),
|
||||
|
||||
setInputCooldown: (to: boolean) => set(() => ({ inputCooldown: to })),
|
||||
|
||||
incrementSsknLvl: () => set((state) => ({ ssknLvl: state.ssknLvl + 1 })),
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
export const getSiteState = (site: "a" | "b") => {
|
||||
const siteState = useStore.getState().siteSaveState[site];
|
||||
|
||||
return {
|
||||
activeNode: siteState.activeNode,
|
||||
siteRot: siteState.siteRot,
|
||||
activeLevel: siteState.activeLevel,
|
||||
};
|
||||
};
|
||||
|
||||
type PromptContext = {
|
||||
activePromptComponent: "yes" | "no";
|
||||
promptVisible: boolean;
|
||||
|
@ -490,6 +408,18 @@ export interface MainSceneContext extends PromptContext {
|
|||
siteRotY: number;
|
||||
activeSite: "a" | "b";
|
||||
selectedLevel: number;
|
||||
siteSaveState: {
|
||||
a: {
|
||||
activeNode: NodeData;
|
||||
siteRot: number[];
|
||||
activeLevel: string;
|
||||
};
|
||||
b: {
|
||||
activeNode: NodeData;
|
||||
siteRot: number[];
|
||||
activeLevel: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export const getMainSceneContext = (keyPress: string): MainSceneContext => {
|
||||
|
@ -509,6 +439,7 @@ export const getMainSceneContext = (keyPress: string): MainSceneContext => {
|
|||
ssknLvl: state.ssknLvl,
|
||||
showingAbout: state.showingAbout,
|
||||
gateLvl: state.gateLvl,
|
||||
siteSaveState: state.siteSaveState,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -610,19 +541,3 @@ export const createAudioAnalyser = () => {
|
|||
|
||||
return new THREE.AudioAnalyser(audio, 2048);
|
||||
};
|
||||
|
||||
export const getSceneResetValues = (scene: string) => {
|
||||
switch (scene) {
|
||||
case "media":
|
||||
return {
|
||||
mediaWordPosStateIdx: 1,
|
||||
mediaComponentMatrixIndices: {
|
||||
sideIdx: 0,
|
||||
leftSideIdx: 0,
|
||||
rightSideIdx: 0,
|
||||
},
|
||||
};
|
||||
case "sskn":
|
||||
return { ssknComponentMatrixIdx: 0, ssknLoading: false };
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import site_a from "../resources/site_a.json";
|
||||
import site_b from "../resources/site_b.json";
|
||||
import { SiteData } from "../components/MainScene/Site";
|
||||
import { SiteData } from "../components/MainScene/Site/Site";
|
||||
import { useStore } from "../store";
|
||||
|
||||
export const getRandomIdleMedia = () => {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
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 { NodeData, SiteData } from "../components/MainScene/Site";
|
||||
import { NodeData, SiteData } from "../components/MainScene/Site/Site";
|
||||
import { isNodeVisible } from "./node-utils";
|
||||
|
||||
export const findNodeFromWord = (
|
||||
|
|
|
@ -14,8 +14,14 @@ const calculateCoordsBasedOnRotation = (
|
|||
z: x * Math.sin(rotation) + z * Math.cos(rotation),
|
||||
});
|
||||
|
||||
export const nodeThrow = (siteRotY: number) => {
|
||||
// async calls in this file are executed inside IIAFE-s because defining them as async would
|
||||
// throw a warning about an unhandled promise, and we dont care about that.
|
||||
// async/awaits here are used simply to improve readability, nothing else.
|
||||
|
||||
export const nodeThrowAnimation = () => {
|
||||
(async () => {
|
||||
const siteRotY = useStore.getState().siteRot[1];
|
||||
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(0.9, 0.3, siteRotY);
|
||||
const sndCoordSet = calculateCoordsBasedOnRotation(0.5, 0.2, siteRotY);
|
||||
const thirdCoordSet = calculateCoordsBasedOnRotation(1.55, 0.2, siteRotY);
|
||||
|
@ -42,7 +48,9 @@ export const nodeThrow = (siteRotY: number) => {
|
|||
})();
|
||||
};
|
||||
|
||||
export const nodeKnock = (siteRotY: number) => {
|
||||
export const nodeKnockAnimation = () => {
|
||||
const siteRotY = useStore.getState().siteRot[1];
|
||||
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(1.1, 0.2, siteRotY);
|
||||
|
||||
setActiveNodeAttributes(true, "interactedWith");
|
||||
|
@ -52,8 +60,10 @@ export const nodeKnock = (siteRotY: number) => {
|
|||
setTimeout(() => setActiveNodeAttributes(false, "interactedWith"), 2500);
|
||||
};
|
||||
|
||||
export const nodeKnockAndFall = (siteRotY: number) => {
|
||||
export const nodeKnockAndFallAnimation = () => {
|
||||
(async () => {
|
||||
const siteRotY = useStore.getState().siteRot[1];
|
||||
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(1.1, 0.2, siteRotY);
|
||||
|
||||
setActiveNodeAttributes(true, "interactedWith");
|
||||
|
@ -71,8 +81,10 @@ export const nodeKnockAndFall = (siteRotY: number) => {
|
|||
})();
|
||||
};
|
||||
|
||||
export const nodeTouchAndScare = (siteRotY: number) => {
|
||||
export const nodeExplodeAnimation = () => {
|
||||
(async () => {
|
||||
const siteRotY = useStore.getState().siteRot[1];
|
||||
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(-0.6, 0.2, siteRotY);
|
||||
|
||||
setActiveNodeAttributes(true, "interactedWith");
|
||||
|
@ -95,8 +107,10 @@ export const nodeTouchAndScare = (siteRotY: number) => {
|
|||
})();
|
||||
};
|
||||
|
||||
export const nodeRip = (siteRotY: number) => {
|
||||
export const nodeRipAnimation = () => {
|
||||
(async () => {
|
||||
const siteRotY = useStore.getState().siteRot[1];
|
||||
|
||||
const fstCoordSet = calculateCoordsBasedOnRotation(0.9, 0.3, siteRotY);
|
||||
const sndCoordSet = calculateCoordsBasedOnRotation(0.5, 0.2, siteRotY);
|
||||
const thirdCoordSet = calculateCoordsBasedOnRotation(0, 0.2, siteRotY);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { NodeData, SiteData } from "../components/MainScene/Site";
|
||||
import { NodeData, SiteData } from "../components/MainScene/Site/Site";
|
||||
import node_matrices from "../resources/node_matrices.json";
|
||||
import unlocked_nodes from "../resources/initial_progress.json";
|
||||
import node_huds from "../resources/node_huds.json";
|
||||
|
|
Loading…
Reference in a new issue