cleaning up state

This commit is contained in:
ad044 2020-11-25 01:24:35 +04:00
parent 339962fec4
commit a2c3e77e1f
26 changed files with 711 additions and 956 deletions

View file

@ -5,17 +5,17 @@ import site_a from "../../resources/site_a.json";
import { useNodeStore, useLevelStore, useSiteStore } from "../../store";
import { a, useSpring } from "@react-spring/three";
const CurrentLevelNodes = () => {
const activeNodeId = useNodeStore((state) => state.activeNodeId);
const currentLevel = useLevelStore((state) => state.currentLevel);
const ActiveLevelNodes = () => {
const activeNodeState = useNodeStore((state) => state.activeNodeState);
const activeLevel = useLevelStore((state) => state.activeLevel);
const currentLevelNodes = useMemo(
() => site_a[currentLevel as keyof typeof site_a],
[currentLevel]
const activeLevelNodes = useMemo(
() => site_a[activeLevel as keyof typeof site_a],
[activeLevel]
);
const siteRotY = useSiteStore((state) => state.siteRotY);
const sitePosY = useSiteStore((state) => state.sitePosY);
const siteRotY = useSiteStore((state) => state.siteRotY);
const siteState = useSpring({
siteRotY: siteRotY,
@ -25,22 +25,20 @@ const CurrentLevelNodes = () => {
return (
<a.group rotation-y={siteState.siteRotY} position-y={siteState.sitePosY}>
{Object.entries(currentLevelNodes).map((node: [string, any]) => {
{Object.entries(activeLevelNodes).map((node: [string, any]) => {
return (
<Node
sprite={node[1].node_name}
position={
node_positions[
node[0].substr(2) as keyof typeof node_positions
].position
node_positions[node[0].substr(2) as keyof typeof node_positions]
.position
}
rotation={
node_positions[
node[0].substr(2) as keyof typeof node_positions
].rotation
node_positions[node[0].substr(2) as keyof typeof node_positions]
.rotation
}
key={node[1].node_name}
active={node[0] === activeNodeId}
active={node[0] === activeNodeState.id}
level={node[0].substr(0, 2)}
/>
);
@ -49,4 +47,4 @@ const CurrentLevelNodes = () => {
);
};
export default CurrentLevelNodes;
export default ActiveLevelNodes;

View file

@ -8,21 +8,20 @@ import longHudMirrored from "../../static/sprite/long_hud_mirrored.png";
import boringHud from "../../static/sprite/long_hud_boring.png";
import boringHudMirrored from "../../static/sprite/long_hud_boring_mirrored.png";
import { a, useSpring } from "@react-spring/three";
import {useNodeStore, useHudStore} from "../../store";
import { useHudStore } from "../../store";
import node_huds from "../../resources/node_huds.json";
const HUD = memo(() => {
const hudActive = useHudStore((state) => state.hudActive);
const currentHudId = useHudStore((state) => state.activeHudId);
const active = useHudStore((state) => state.active);
const id = useHudStore((state) => state.id);
const visible = useHudStore((state) => state.visible);
const hudVisible = useHudStore((state) => state.hudVisible);
const currentHud = node_huds[currentHudId as keyof typeof node_huds];
const currentHud = node_huds[id as keyof typeof node_huds];
const hudElementState = useSpring({
bigHUDPositionX: hudActive,
longHUDPositionX: hudActive,
boringHUDPositionX: hudActive,
bigHUDPositionX: active,
longHUDPositionX: active,
boringHUDPositionX: active,
config: { duration: 500 },
});
@ -84,7 +83,7 @@ const HUD = memo(() => {
);
return (
<group visible={hudVisible} position={[0, 0, 10]}>
<group visible={visible} position={[0, 0, 10]}>
<a.sprite
position-x={longHUDPosX}
position-y={currentHud!.long.position[1]}

View file

@ -8,35 +8,24 @@ import { useMiddleRingStore } from "../../store";
const MiddleRing = () => {
const middleRingTex = useLoader(THREE.TextureLoader, middleRingTexture);
const middleRingWobbleStrength = useMiddleRingStore(
(state) => state.middleRingWobbleStrength
);
const middleRingRotating = useMiddleRingStore(
(state) => state.middleRingRotating
);
const middleRingNoise = useMiddleRingStore((state) => state.middleRingNoise);
const middleRingPosY = useMiddleRingStore((state) => state.middleRingPosY);
const middleRingRotX = useMiddleRingStore((state) => state.middleRingRotX);
const middleRingRotZ = useMiddleRingStore((state) => state.middleRingRotZ);
const transformState = useMiddleRingStore((state) => state.transformState);
const rotating = useMiddleRingStore((state) => state.isRotating);
const animDuration = useMiddleRingStore((state) => state.animDuration);
const middleRingAnimDuration = useMiddleRingStore(
(state) => state.middleRingAnimDuration
);
const middleRingWobbleState = useSpring({
middleRingWobbleStrength: middleRingWobbleStrength,
middleRingNoise: middleRingNoise,
const wobbleState = useSpring({
wobbleStrength: transformState.wobbleStrength,
noiseStrength: transformState.noiseStrength,
config: { duration: 200 },
});
const middleRingPosState = useSpring({
middleRingPosY: middleRingPosY,
config: { duration: middleRingAnimDuration },
const posState = useSpring({
posY: transformState.posY,
config: { duration: animDuration },
});
const middleRingRotState = useSpring({
middleRingRotX: middleRingRotX,
middleRingRotZ: middleRingRotZ,
const rotState = useSpring({
rotX: transformState.rotX,
rotZ: transformState.rotZ,
config: { duration: 1000 },
});
@ -199,24 +188,24 @@ const MiddleRing = () => {
useFrame(() => {
if (middleRingMaterialRef.current) {
middleRingMaterialRef.current.uniforms.uTime.value = clock.getElapsedTime();
middleRingMaterialRef.current.uniforms.wobbleStrength.value = middleRingWobbleState.middleRingWobbleStrength.get();
middleRingMaterialRef.current.uniforms.noiseAmp.value = middleRingWobbleState.middleRingNoise.get();
middleRingMaterialRef.current.uniforms.wobbleStrength.value = wobbleState.wobbleStrength.get();
middleRingMaterialRef.current.uniforms.noiseAmp.value = wobbleState.noiseStrength.get();
middleRingMaterialRef.current.needsUpdate = true;
}
if (middleRingRotating) {
if (rotating) {
middleRingRef.current!.rotation.y += 0.05;
}
});
return (
<a.group rotation-z={middleRingRotState.middleRingRotZ}>
<a.group rotation-z={rotState.rotZ}>
<a.mesh
position={[0, 0, 0.3]}
position-y={middleRingPosState.middleRingPosY}
position-y={posState.posY}
ref={middleRingRef}
rotation={[0, 0.9, 0]}
rotation-x={middleRingRotState.middleRingRotX}
rotation-x={rotState.rotX}
>
<cylinderBufferGeometry
args={[0.75, 0.75, 0.027, 64, 64, true]}

View file

@ -115,46 +115,37 @@ const Node = (props: NodeContructorProps) => {
// these pieces of state get updated transiently rather than reactively
// to avoid excess unnecessary renders (this is absolutely crucial for performance).
const [
{
activeNodePosX,
activeNodePosY,
activeNodePosZ,
activeNodeRotZ,
},
{ activeNodePosX, activeNodePosY, activeNodePosZ, activeNodeRotZ },
set,
] = useSpring(() => ({
activeNodePosX: useNodeStore.getState().isActiveNodeInteractedWith
? useNodeStore.getState().activeNodePosX
activeNodePosX: useNodeStore.getState().activeNodeState.interactedWith
? useNodeStore.getState().activeNodeState.posX
: props.position[0],
activeNodePosY: useNodeStore.getState().isActiveNodeInteractedWith
activeNodePosY: useNodeStore.getState().activeNodeState.interactedWith
? level_y_values[props.level as keyof typeof level_y_values]
: props.position[1],
activeNodePosZ: useNodeStore.getState().isActiveNodeInteractedWith
? useNodeStore.getState().activeNodePosZ
activeNodePosZ: useNodeStore.getState().activeNodeState.interactedWith
? useNodeStore.getState().activeNodeState.posZ
: props.position[2],
activeNodeRotZ: useNodeStore.getState().isActiveNodeInteractedWith
? useNodeStore.getState().activeNodeRotZ
activeNodeRotZ: useNodeStore.getState().activeNodeState.interactedWith
? useNodeStore.getState().activeNodeState.rotZ
: 0,
config: { duration: 800 },
}));
useEffect(() => {
useNodeStore.subscribe(set, (state) => ({
activeNodePosX: useNodeStore.getState()
.isActiveNodeInteractedWith
? state.activeNodePosX
activeNodePosX: useNodeStore.getState().activeNodeState.interactedWith
? state.activeNodeState.posX
: props.position[0],
activeNodePosY: useNodeStore.getState()
.isActiveNodeInteractedWith
activeNodePosY: useNodeStore.getState().activeNodeState.interactedWith
? level_y_values[props.level as keyof typeof level_y_values]
: props.position[1],
activeNodePosZ: useNodeStore.getState()
.isActiveNodeInteractedWith
? state.activeNodePosZ
activeNodePosZ: useNodeStore.getState().activeNodeState.interactedWith
? state.activeNodeState.posZ
: props.position[2],
activeNodeRotZ: useNodeStore.getState()
.isActiveNodeInteractedWith
? state.activeNodeRotZ
activeNodeRotZ: useNodeStore.getState().activeNodeState.interactedWith
? state.activeNodeState.rotZ
: 0,
}));
}, [

View file

@ -37,15 +37,23 @@ export type SiteType = {
};
const Site = memo(() => {
const activeLevels = useLevelStore((state) => state.activeLevels);
const activeLevel = useLevelStore((state) => state.activeLevel);
const visibleNodes = useMemo(() => {
const obj = {};
activeLevels.forEach((level) => {
const activeLevelNr = parseInt(activeLevel);
const visibleLevels = [
(activeLevelNr - 2).toString().padStart(2, "0"),
(activeLevelNr - 1).toString().padStart(2, "0"),
(activeLevelNr + 1).toString().padStart(2, "0"),
(activeLevelNr + 2).toString().padStart(2, "0"),
];
visibleLevels.forEach((level) => {
Object.assign(obj, site_a[level as keyof typeof site_a]);
});
return obj;
}, [activeLevels]);
}, [activeLevel]);
const siteRotY = useSiteStore((state) => state.siteRotY);
const sitePosY = useSiteStore((state) => state.sitePosY);
@ -70,14 +78,12 @@ const Site = memo(() => {
<Node
sprite={node[1].node_name}
position={
node_positions[
node[0].substr(2) as keyof typeof node_positions
].position
node_positions[node[0].substr(2) as keyof typeof node_positions]
.position
}
rotation={
node_positions[
node[0].substr(2) as keyof typeof node_positions
].rotation
node_positions[node[0].substr(2) as keyof typeof node_positions]
.rotation
}
key={node[1].node_name}
level={node[0].substr(0, 2)}

View file

@ -3,7 +3,6 @@ import {
useGrayPlanesStore,
useHudStore,
useLainStore,
useMainGroupStore,
useStarfieldStore,
useYellowOrbStore,
} from "../store";
@ -14,7 +13,13 @@ import {
// inside <Suspense> tags makes it behave in a more stable manner
// by waiting for the components to load and synchronously calling the functions.
const MainSceneIntro = memo(() => {
const toggleHud = useHudStore((state) => state.toggleHud);
// todo component
// -2.5 - intro val
//-9.5 - intro val
//1.5 - intro val
const toggleHud = useHudStore((state) => state.toggleActive);
//const setHudVisible = useSetRecoilState(hudVisibilityAtom);
const setOrbVisible = useYellowOrbStore((state) => state.setYellowOrbVisible);
@ -31,21 +36,11 @@ const MainSceneIntro = memo(() => {
(state) => state.setMainStarfieldBoostVal
);
const setMainGroupPosY = useMainGroupStore((state) => state.setMainGroupPosY);
const setMainGroupPosZ = useMainGroupStore((state) => state.setMainGroupPosZ);
const setMainGroupRotX = useMainGroupStore((state) => state.setMainGroupRotX);
const setGrayPlanesVisible = useGrayPlanesStore(
(state) => state.setGrayPlanesVisible
);
useEffect(() => {
setMainGroupPosY(0);
setMainGroupPosZ(0);
setTimeout(() => {
setMainGroupRotX(0);
}, 2400);
setTimeout(() => {
setGrayPlanesVisible(true);
}, 2500);
@ -77,9 +72,6 @@ const MainSceneIntro = memo(() => {
setMainStarfieldVisible,
setOrbVisible,
setIntroStarfieldVisible,
setMainGroupRotX,
setMainGroupPosZ,
setMainGroupPosY,
setLainMoveState,
toggleHud,
]);

View file

@ -1,16 +1,17 @@
import React, { useEffect, useState } from "react";
import React, { useEffect, useMemo, useState } from "react";
import { useLoader } from "react-three-fiber";
import { useImageStore, useMediaStore } from "../../store";
import * as THREE from "three";
import sex from "../../static/sprite/gray_ring_lof.png";
import { useLevelStore, useMediaStore, useNodeStore } from "../../store";
import { a, useSpring } from "@react-spring/three";
import image_table from "../../resources/image_table.json";
import { LevelType } from "../MainScene/Site";
import site_a from "../../resources/site_a.json";
import * as THREE from "three";
const Images = () => {
const activeNodeId = useNodeStore((state) => state.activeNodeState.id);
const [imageScaleY, setImageScaleY] = useState(3.75);
const images = useImageStore((state) => state.images);
const [activeImage, setActiveImage] = useState<any>(sex);
const activeImageTex = useLoader(THREE.TextureLoader, activeImage);
const [sceneImages, setSceneImages] = useState([] as any);
const [activeImage, setActiveImage] = useState<THREE.Texture>();
const mediaPercentageElapsed = useMediaStore(
(state) => state.mediaPercentageElapsed
@ -21,28 +22,49 @@ const Images = () => {
config: { duration: 300 },
});
useEffect(() => {
if (images[1]) {
setActiveImage(images[1].default);
}
}, [images]);
const activeLevel = useLevelStore((state) => state.activeLevel);
const activeLevelData: LevelType = useMemo(
() => site_a[activeLevel as keyof typeof site_a],
[activeLevel]
);
useEffect(() => {
if (mediaPercentageElapsed === 35 && images[2]) {
const nodeName = activeLevelData[activeNodeId].node_name;
const images = image_table[nodeName as keyof typeof image_table];
const imgArr: { default: string }[] = [];
Object.values(images).forEach((img) => {
import("../../static/media_images/site_a/" + img + ".png").then(
(imageSrc: { default: string }) => {
// images are unordered by default so we insert them into the arr
// according to their last char
imgArr.splice(parseInt(img.substr(img.length - 1)), 0, imageSrc);
if (imgArr.length === 3) {
setSceneImages(imgArr);
new THREE.TextureLoader().load(imgArr[0].default, setActiveImage);
}
}
);
});
}, [activeLevelData, activeNodeId]);
useEffect(() => {
if (mediaPercentageElapsed === 35 && sceneImages[1]) {
setImageScaleY(0);
setTimeout(() => {
setActiveImage(images[2]!.default);
new THREE.TextureLoader().load(sceneImages[1].default, setActiveImage);
setImageScaleY(3.75);
}, 300);
}
if (mediaPercentageElapsed === 70 && images[3]) {
if (mediaPercentageElapsed === 70 && sceneImages[2]) {
setImageScaleY(0);
setTimeout(() => {
setActiveImage(images[3]!.default);
new THREE.TextureLoader().load(sceneImages[2].default, setActiveImage);
setImageScaleY(3.75);
}, 300);
}
}, [images, mediaPercentageElapsed]);
}, [mediaPercentageElapsed, sceneImages]);
return (
<a.sprite
@ -50,7 +72,11 @@ const Images = () => {
scale={[5, 3.75, 0]}
scale-y={imageScaleState.imageScaleY}
>
<spriteMaterial attach="material" map={activeImageTex} />
{sceneImages.length === 3 ? (
<spriteMaterial attach="material" map={activeImage} />
) : (
<></>
)}
</a.sprite>
);
};

View file

@ -35,6 +35,7 @@ const MediaPlayer = () => {
<video
width="800"
height="600"
controls
id="media"
ref={videoRef}
style={{ display: currentScene === "media" ? "block" : "none" }}

View file

@ -4,14 +4,14 @@ import * as THREE from "three";
import { useLoader } from "react-three-fiber";
import orange_font_json from "../../resources/font_data/big_font.json";
import { a, useSpring } from "@react-spring/three";
import React, {useEffect, useMemo} from "react";
import { LetterProps } from "./TextRenderer";
import React, { useMemo } from "react";
interface BigLetterProps extends LetterProps {
const BigLetter = (props: {
color: string;
letter: string;
letterIdx: number;
yellowTextOffsetXCoeff: number;
}
const BigLetter = (props: BigLetterProps) => {
}) => {
const colorToTexture = (color: string) => {
const colorTexture = { orange: orangeFont, yellow: yellowFont };
return colorTexture[color as keyof typeof colorTexture];

View file

@ -0,0 +1,57 @@
import { a, useSpring } from "@react-spring/three";
import React, { useEffect, useRef } from "react";
import { GreenTextState, useGreenTextStore } from "../../store";
import MediumLetter from "./MediumLetter";
const GreenTextRenderer = () => {
const greenTextActive = useGreenTextStore((state) => state.active);
const transformRef = useRef(useGreenTextStore.getState().transformState);
const textArrRef = useRef(useGreenTextStore.getState().text.split(""));
const { greenTextPosXToggle } = useSpring({
greenTextPosXToggle: greenTextActive,
config: { duration: 500 },
});
const greenTextPosX = greenTextPosXToggle.to(
[0, 1],
[transformRef.current.posX.initial, transformRef.current.posX.final]
);
// subscribing to state and updating transiently
useEffect(
() =>
useGreenTextStore.subscribe(
(state) => {
transformRef.current = (state as GreenTextState).transformState;
textArrRef.current = (state as GreenTextState).text.split("");
},
(state) => state
),
[]
);
return (
<group position={[0, 0, 10]}>
<a.group
position-x={greenTextPosX}
position-y={transformRef.current.posY}
position-z={-8.7}
scale={[0.02, 0.035, 0.02]}
>
{textArrRef.current.map((letter, idx) => (
<MediumLetter
color={"yellow"}
letter={letter}
letterIdx={idx}
key={idx}
/>
))}
</a.group>
</group>
);
};
export default GreenTextRenderer;

View file

@ -4,9 +4,12 @@ import greenFont from "../../static/sprite/white_and_green_texture.png";
import medium_font_json from "../../resources/font_data/medium_font.json";
import { a } from "@react-spring/three";
import React, { useMemo } from "react";
import { LetterProps } from "./TextRenderer";
const MediumLetter = (props: LetterProps) => {
const MediumLetter = (props: {
color: string;
letter: string;
letterIdx: number;
}) => {
const colorTexture = useLoader(THREE.TextureLoader, greenFont);
// i have yet to figure out a genrealizable way of
// calculating the y offset, this shit will do for now

View file

@ -1,162 +0,0 @@
import { a, useSpring, useTrail } from "@react-spring/three";
import React, { useEffect, useRef } from "react";
import {
TextRendererState,
useSiteStore,
useTextRendererStore,
} from "../../store";
import BigLetter from "./BigLetter";
import MediumLetter from "./MediumLetter";
export type LetterProps = {
color: string;
letter: string;
letterIdx: number;
};
const TextRenderer = () => {
const isSiteChangingY = useSiteStore((state) => state.isSiteChangingY);
// ======================================= YELLOW TEXT ======================================
// yellow text posx and posy need to be updated reactively aswell when changing site rotation/y value
const yellowTextPosX = useTextRendererStore((state) => state.yellowTextPosX);
const yellowTextPosY = useTextRendererStore((state) => state.yellowTextPosY);
const yellowTextOffsetXCoeff = useTextRendererStore(
(state) => state.yellowTextOffsetXCoeff
);
const yellowTextArrRef = useRef(
useTextRendererStore.getState().yellowText.split("")
);
const yellowTextPosXRef = useRef(
useTextRendererStore.getState().yellowTextPosX
);
const yellowTextPosYRef = useRef(
useTextRendererStore.getState().yellowTextPosY
);
// this is used to animate the letters moving one after another
const yellowLetterTrail = useTrail(yellowTextArrRef.current.length, {
yellowLetterPosX: yellowTextPosXRef.current,
yellowLetterPosY: yellowTextPosYRef.current,
config: { duration: 280 },
});
// this is used when the whole GROUP itself needs to be animated
const yellowLetterSpring = useSpring({
yellowLetterPosX: yellowTextPosX,
yellowLetterPosY: yellowTextPosY,
config: { duration: 1200 },
});
// ==================================== GREEN TEXT ============================================
const greenTextActive = useTextRendererStore(
(state) => state.greenTextActive
);
const greenTextPosYRef = useRef(
useTextRendererStore.getState().greenTextPosY
);
const greenTextPosXRef = useRef(
useTextRendererStore.getState().greenTextPosX
);
const greenTextArrRef = useRef(
useTextRendererStore.getState().greenText.split("")
);
const { greenTextPosXToggle } = useSpring({
greenTextPosXToggle: greenTextActive,
config: { duration: 500 },
});
const greenTextPosX = greenTextPosXToggle.to(
[0, 1],
[greenTextPosXRef.current.initial, greenTextPosXRef.current.final]
);
// subscribing to state and updating transiently
useEffect(
() =>
useTextRendererStore.subscribe(
(state) => {
yellowTextPosXRef.current = (state as TextRendererState).yellowTextPosX;
yellowTextPosYRef.current = (state as TextRendererState).yellowTextPosY;
yellowTextArrRef.current = (state as TextRendererState).yellowText.split(
""
);
greenTextPosYRef.current = (state as TextRendererState).greenTextPosY;
greenTextPosXRef.current = (state as TextRendererState).greenTextPosX;
greenTextArrRef.current = (state as TextRendererState).greenText.split(
""
);
},
(state) => state
),
[]
);
return (
<group position={[0, 0, 10]}>
{isSiteChangingY
? yellowTextArrRef.current.map((letter, idx) => (
<a.group
key={idx}
position-x={yellowLetterSpring.yellowLetterPosX}
position-y={yellowLetterSpring.yellowLetterPosY}
position-z={-8.7}
scale={[0.04, 0.06, 0.04]}
>
<BigLetter
color={"yellow"}
yellowTextOffsetXCoeff={0}
letter={yellowTextArrRef.current[idx]}
letterIdx={idx}
key={idx}
/>
</a.group>
))
: yellowLetterTrail.map(
({ yellowLetterPosX, yellowLetterPosY }, idx) => (
<a.group
key={idx}
position-x={yellowLetterPosX}
position-y={yellowLetterPosY}
position-z={-8.7}
scale={[0.04, 0.06, 0.04]}
>
<BigLetter
color={"yellow"}
yellowTextOffsetXCoeff={yellowTextOffsetXCoeff}
letter={yellowTextArrRef.current[idx]}
letterIdx={idx}
key={idx}
/>
</a.group>
)
)}
<a.group
position-x={greenTextPosX}
position-y={greenTextPosYRef.current}
position-z={-8.7}
scale={[0.02, 0.035, 0.02]}
>
{greenTextArrRef.current.map((letter, idx) => (
<MediumLetter
color={"yellow"}
letter={letter}
letterIdx={idx}
key={idx}
/>
))}
</a.group>
</group>
);
};
export default TextRenderer;

View file

@ -0,0 +1,81 @@
import React, { useEffect, useRef } from "react";
import { useYellowTextStore, YellowTextState } from "../../store";
import { a, useSpring, useTrail } from "@react-spring/three";
import BigLetter from "./BigLetter";
const YellowTextRenderer = () => {
const disableTrail = useYellowTextStore((state) => state.disableTrail);
const transformState = useYellowTextStore((state) => state.transformState);
const textArrRef = useRef(useYellowTextStore.getState().text.split(""));
const transformRef = useRef(useYellowTextStore.getState().transformState);
// this is used to animate the letters moving one after another
const trail = useTrail(textArrRef.current.length, {
posX: transformRef.current.posX,
posY: transformRef.current.posY,
config: { duration: 280 },
});
// this is used when the whole GROUP itself needs to be animated
const spring = useSpring({
posX: transformState.posX,
posY: transformState.posY,
config: { duration: 1200 },
});
useEffect(
() =>
useYellowTextStore.subscribe(
(state) => {
transformRef.current = (state as YellowTextState).transformState;
textArrRef.current = (state as YellowTextState).text.split("");
},
(state) => state
),
[]
);
return (
<group position={[0, 0, 10]}>
{disableTrail
? textArrRef.current.map((letter, idx) => (
<a.group
key={idx}
position-x={spring.posX}
position-y={spring.posY}
position-z={-8.7}
scale={[0.04, 0.06, 0.04]}
>
<BigLetter
color={"yellow"}
yellowTextOffsetXCoeff={0}
letter={textArrRef.current[idx]}
letterIdx={idx}
key={idx}
/>
</a.group>
))
: trail.map(({ posX, posY }, idx) => (
<a.group
key={idx}
position-x={posX}
position-y={posY}
position-z={-8.7}
scale={[0.04, 0.06, 0.04]}
>
<BigLetter
color={"yellow"}
yellowTextOffsetXCoeff={transformRef.current.xOffset}
letter={textArrRef.current[idx]}
letterIdx={idx}
key={idx}
/>
</a.group>
))}
</group>
);
};
export default YellowTextRenderer;

View file

@ -18,7 +18,6 @@ import MediaComponentManager from "./MediaComponentManager";
import MediaWordManager from "./MediaWordManager";
import SceneManager from "./SceneManager";
import YellowTextManager from "./YellowTextManager";
import MediaImageManager from "./MediaImageManager";
import computeAction from "../computeAction";
import LevelManager from "./LevelManager";
import BootManager from "./BootManager";
@ -53,9 +52,14 @@ export type GameContext = {
keyPress?: string;
scene: string;
bootSubscene: string;
nodeMatrixIndices: { rowIdx: number; colIdx: number };
currentLevel: string;
siteRotIdx: string;
nodeMatrixIndices: {
matrixIdx: number;
rowIdx: number;
colIdx: number;
};
activeLevel: string;
siteRotY: number;
sitePosY: number;
activeMediaComponent: string;
activeBootElement: string;
activeSSknComponent: string;
@ -66,8 +70,9 @@ const EventManager = () => {
// main scene
const nodeMatrixIndices = useNodeStore((state) => state.nodeMatrixIndices);
const siteRotIdx = useSiteStore((state) => state.siteRotIdx);
const currentLevel = useLevelStore((state) => state.currentLevel);
const sitePosY = useSiteStore((state) => state.sitePosY);
const siteRotY = useSiteStore((state) => state.siteRotY);
const activeLevel = useLevelStore((state) => state.activeLevel);
// media scene
const mediaComponentMatrixIndices = useMediaStore(
@ -116,9 +121,10 @@ const EventManager = () => {
() => ({
scene: currentScene,
bootSubscene: currentBootSubscene,
siteRotIdx: siteRotIdx,
siteRotY: siteRotY,
sitePosY: sitePosY,
nodeMatrixIndices: nodeMatrixIndices,
currentLevel: currentLevel,
activeLevel: activeLevel,
activeMediaComponent: activeMediaComponent,
activeBootElement: activeBootElement,
activeSSknComponent: activeSSknComponent,
@ -126,9 +132,10 @@ const EventManager = () => {
[
currentScene,
currentBootSubscene,
siteRotIdx,
siteRotY,
sitePosY,
nodeMatrixIndices,
currentLevel,
activeLevel,
activeMediaComponent,
activeBootElement,
activeSSknComponent,
@ -170,7 +177,6 @@ const EventManager = () => {
<MediaWordManager eventState={eventState!} />
<SceneManager eventState={eventState!} />
<YellowTextManager eventState={eventState!} />
<MediaImageManager eventState={eventState!} />
<LevelManager eventState={eventState!} />
<BootManager eventState={eventState!} />
<SSknComponentManager eventState={eventState!} />

View file

@ -1,20 +1,15 @@
import { useCallback, useEffect } from "react";
import { useTextRendererStore } from "../../store";
import { StateManagerProps } from "./EventManager";
import node_huds from "../../resources/node_huds.json";
import site_a from "../../resources/site_a.json";
import { SiteType } from "../../components/MainScene/Site";
import { useGreenTextStore } from "../../store";
const GreenTextManager = (props: StateManagerProps) => {
const setGreenText = useTextRendererStore((state) => state.setGreenText);
const setGreenTextPosY = useTextRendererStore(
(state) => state.setGreenTextPosY
);
const setGreenTextPosX = useTextRendererStore(
(state) => state.setGreenTextPosX
);
const toggleGreenText = useTextRendererStore(
(state) => state.toggleGreenText
const setGreenText = useGreenTextStore((state) => state.setText);
const toggleActive = useGreenTextStore((state) => state.toggleActive);
const setTransformState = useGreenTextStore(
(state) => state.setTransformState
);
const toggleAndSetGreenText = useCallback(
@ -30,30 +25,39 @@ const GreenTextManager = (props: StateManagerProps) => {
const targetGreenTextPosData =
node_huds[newActiveHudId as keyof typeof node_huds].medium_text;
toggleGreenText();
toggleActive();
setTimeout(() => {
setGreenTextPosX({
initial: targetGreenTextPosData.initial_position[0],
final: targetGreenTextPosData.position[0],
});
setGreenTextPosY(targetGreenTextPosData.position[1]);
setTransformState(
{
initial: targetGreenTextPosData.initial_position[0],
final: targetGreenTextPosData.position[0],
},
"posX"
);
setTransformState(targetGreenTextPosData.position[1], "posY");
setGreenText(targetGreenText);
toggleGreenText();
toggleActive();
}, delay);
},
[setGreenText, setGreenTextPosX, setGreenTextPosY, toggleGreenText]
[setGreenText, setTransformState, toggleActive]
);
const initializeGreenTextForMediaScene = useCallback(
(activeNodeId: string, level: string) => {
setTimeout(() => {
setGreenText((site_a as SiteType)[level][activeNodeId].node_name);
setGreenTextPosX({ initial: 0.0, final: 0.009 });
setGreenTextPosY(0.675);
setTransformState(
{
initial: 0,
final: 0.009,
},
"posX"
);
setTransformState(0.675, "posY");
}, 3950);
},
[setGreenText, setGreenTextPosX, setGreenTextPosY]
[setGreenText, setTransformState]
);
const dispatchObject = useCallback(

View file

@ -3,35 +3,20 @@ import { StateManagerProps } from "./EventManager";
import { useLevelStore } from "../../store";
const LevelManager = (props: StateManagerProps) => {
const setCurrentLevel = useLevelStore((state) => state.setCurrentLevel);
const setActiveLevels = useLevelStore((state) => state.setActiveLevels);
const setActiveLevel = useLevelStore((state) => state.setActiveLevel);
const updateLevel = useCallback(
(newLevel: string) => {
setTimeout(() => {
setCurrentLevel(newLevel);
setActiveLevels([
(parseInt(newLevel) - 2).toString().padStart(2, "0"),
(parseInt(newLevel) - 1).toString().padStart(2, "0"),
(parseInt(newLevel) + 1).toString().padStart(2, "0"),
(parseInt(newLevel) + 2).toString().padStart(2, "0"),
]);
}, 1500);
},
[setActiveLevels, setCurrentLevel]
);
const dispatchObject = useCallback(
(event: string, newLevel: string) => {
switch (event) {
case "move_up":
case "move_down":
return {
action: updateLevel,
action: setActiveLevel,
value: newLevel,
};
}
},
[updateLevel]
[setActiveLevel]
);
useEffect(() => {

View file

@ -1,83 +0,0 @@
import { useCallback, useEffect, useMemo } from "react";
import { StateManagerProps } from "./EventManager";
import site_a from "../../resources/site_a.json";
import image_table from "../../resources/image_table.json";
import { ImageSrc, useImageStore, useLevelStore } from "../../store";
import { LevelType } from "../../components/MainScene/Site";
const MediaImageManager = (props: StateManagerProps) => {
const setImages = useImageStore((state) => state.setImages);
const currentLevel = useLevelStore((state) => state.currentLevel);
const currentLevelData: LevelType = useMemo(
() => site_a[currentLevel as keyof typeof site_a],
[currentLevel]
);
const updateSceneImages = useCallback(
(newActiveNodeId: string) => {
const nodeName = currentLevelData[newActiveNodeId].node_name;
const images = image_table[nodeName as keyof typeof image_table];
Object.values(images).forEach((img) => {
switch (img.substr(img.length - 1)) {
case "0":
import("../../static/media_images/site_a/" + img + ".png").then(
(imageSrc: ImageSrc) => {
setImages(imageSrc, 1);
}
);
break;
case "1":
import("../../static/media_images/site_a/" + img + ".png").then(
(imageSrc: ImageSrc) => {
setImages(imageSrc, 2);
}
);
break;
case "2":
import("../../static/media_images/site_a/" + img + ".png").then(
(imageSrc: ImageSrc) => {
setImages(imageSrc, 3);
}
);
break;
default:
break;
}
});
},
[currentLevelData, setImages]
);
const dispatchObject = useCallback(
(event: string, newActiveNodeId: string) => {
const dispatcherObjects = {
throw_node_media: {
action: updateSceneImages,
value: newActiveNodeId,
},
};
return dispatcherObjects[event as keyof typeof dispatcherObjects];
},
[updateSceneImages]
);
useEffect(() => {
if (props.eventState) {
const eventAction = props.eventState.event;
const newActiveNodeId = props.eventState.newActiveNodeId;
const dispatchedObject = dispatchObject(eventAction, newActiveNodeId);
if (dispatchedObject) {
dispatchedObject.action(dispatchedObject.value);
}
}
}, [props.eventState, dispatchObject]);
return null;
};
export default MediaImageManager;

View file

@ -2,217 +2,169 @@ import { useCallback, useEffect, useMemo } from "react";
import { useMiddleRingStore } from "../../store";
const MiddleRingManager = (props: any) => {
const setMiddleRingWobbleStrength = useMiddleRingStore(
(state) => state.setMiddleRingWobbleStrength
const setTransformState = useMiddleRingStore(
(state) => state.setTransformState
);
const setMiddleRingRotating = useMiddleRingStore(
(state) => state.setMiddleRingRotating
);
const setMiddleRingNoise = useMiddleRingStore(
(state) => state.setMiddleRingNoise
);
const addToMiddleRingPosY = useMiddleRingStore(
(state) => state.addToMiddleRingPosY
);
const setMiddleRingRotX = useMiddleRingStore(
(state) => state.setMiddleRingRotX
);
const setMiddleRingRotZ = useMiddleRingStore(
(state) => state.setMiddleRingRotZ
);
const setMiddleRingAnimDuration = useMiddleRingStore(
(state) => state.setMiddleRingAnimDuration
const setAnimDuration = useMiddleRingStore((state) => state.setAnimDuration);
const setRotating = useMiddleRingStore((state) => state.setRotating);
const rotate = useCallback(
(direction: string) => {
const rotValues = direction === "right" ? [-0.07, 0.03] : [0.07, -0.03];
setTimeout(() => {
setTransformState(rotValues[0], "rotZ");
}, 2300);
setTimeout(() => {
setTransformState(rotValues[1], "rotZ");
}, 3500);
setTimeout(() => {
setTransformState(0, "rotZ");
}, 4500);
},
[setTransformState]
);
const rotateMiddleRingRight = useCallback(() => {
setTimeout(() => {
setMiddleRingRotZ(-0.07);
}, 2300);
setTimeout(() => {
setMiddleRingRotZ(0.03);
}, 3500);
setTimeout(() => {
setMiddleRingRotZ(0);
}, 4500);
}, [setMiddleRingRotZ]);
const rotateMiddleRingLeft = useCallback(() => {
setTimeout(() => {
setMiddleRingRotZ(0.07);
}, 2300);
setTimeout(() => {
setMiddleRingRotZ(-0.03);
}, 3500);
setTimeout(() => {
setMiddleRingRotZ(0);
}, 4500);
}, [setMiddleRingRotZ]);
const moveMiddleRingDown = useCallback(() => {
const moveDown = useCallback(() => {
// set the anim duration value to match that of the site's
setMiddleRingAnimDuration(1200);
setAnimDuration(1200);
// make noise appear again
setTimeout(() => {
setMiddleRingNoise(0.06);
setTransformState(0.06, "noiseStrength");
}, 800);
// disable rotation of the ring
setTimeout(() => {
setMiddleRingRotating(false);
setRotating(false);
}, 700);
setTimeout(() => {
addToMiddleRingPosY(1.5);
setTransformState(1.39, "posY");
}, 1300);
// set ring rotation on x axis to craete motion effect
setTimeout(() => {
setMiddleRingRotX(0.3);
setTransformState(0.3, "rotX");
}, 1500);
setTimeout(() => {
setMiddleRingAnimDuration(600);
setAnimDuration(600);
}, 2900);
setTimeout(() => {
addToMiddleRingPosY(-1.7);
setTransformState(-0.31, "posY");
}, 3000);
setTimeout(() => {
addToMiddleRingPosY(0.2);
setTransformState(-0.11, "posY");
}, 3150);
// rotate it again, set ring noise to 0
setTimeout(() => {
setMiddleRingRotX(-0.1);
setMiddleRingNoise(0);
setTransformState(-0.1, "rotX");
setTransformState(0, "noiseStrength");
}, 3500);
// rotate it back AGAIN (holy fuk psx game)
setTimeout(() => {
setMiddleRingRotX(0.05);
setTransformState(0.05, "rotX");
}, 4500);
// reset value, set noise to 0
setTimeout(() => {
setMiddleRingRotX(0);
setMiddleRingRotating(true);
setTransformState(0, "rotX");
setRotating(true);
}, 4800);
// enable noise again in about 11-12 secs
setTimeout(() => {
setMiddleRingNoise(0.03);
setTransformState(0.03, "noiseStrength");
}, 11600);
}, [
addToMiddleRingPosY,
setMiddleRingAnimDuration,
setMiddleRingNoise,
setMiddleRingRotX,
setMiddleRingRotating,
]);
}, [setAnimDuration, setRotating, setTransformState]);
const moveMiddleRingUp = useCallback(() => {
const moveUp = useCallback(() => {
// change noise to 0, make the ring bend downwards
setTimeout(() => {
setMiddleRingNoise(0);
setMiddleRingWobbleStrength(0.2);
setTransformState(0, "noiseStrength");
setTransformState(0.2, "wobbleStrength");
}, 300);
// disable rotation of the ring
setTimeout(() => {
setMiddleRingRotating(false);
setRotating(false);
}, 700);
// make the ring bend upwards
setTimeout(() => {
setMiddleRingWobbleStrength(-0.3);
setTransformState(-0.3, "wobbleStrength");
// the middle ring stays in place, therefore we animate it
// in the same direction as the site, creating that illusion.
// set the anim duration value to match that of the site's
setMiddleRingAnimDuration(1200);
setAnimDuration(1200);
// animate it after
addToMiddleRingPosY(-1.5);
setTransformState(-1.39, "posY");
}, 1300);
// reset the ring bend, set the rotation to slightly curve
// to replicate a motion effect (since its moving upwards)
// and enable rotation again
setTimeout(() => {
setMiddleRingWobbleStrength(0.0);
setMiddleRingRotX(-0.2);
setMiddleRingRotating(true);
setTransformState(0, "wobbleStrength");
setTransformState(-0.2, "rotX");
setRotating(true);
}, 1500);
// reset anim duration back to default
setTimeout(() => {
setMiddleRingAnimDuration(600);
setAnimDuration(600);
}, 2300);
setTimeout(() => {
addToMiddleRingPosY(1.7);
}, 2400);
setTransformState(0.09, "posY");
}, 2900);
// reset the rotation value to 0
setTimeout(() => {
setMiddleRingRotX(0);
addToMiddleRingPosY(-0.2);
}, 2650);
setTransformState(0, "rotX");
setTransformState(-0.11, "posY");
}, 3150);
// enable noise again in about 8~ secs
setTimeout(() => {
setMiddleRingNoise(0.03);
setTransformState(0.03, "noiseStrength");
}, 7800);
}, [
addToMiddleRingPosY,
setMiddleRingAnimDuration,
setMiddleRingNoise,
setMiddleRingRotX,
setMiddleRingRotating,
setMiddleRingWobbleStrength,
]);
}, [setAnimDuration, setRotating, setTransformState]);
const dispatcherObjects = useMemo(
() => ({
move_up: { action: moveMiddleRingUp },
move_down: { action: moveMiddleRingDown },
move_left: { action: rotateMiddleRingLeft },
move_right: { action: rotateMiddleRingRight },
}),
[
moveMiddleRingDown,
moveMiddleRingUp,
rotateMiddleRingLeft,
rotateMiddleRingRight,
]
const dispatchObject = useCallback(
(event: string) => {
switch (event) {
case "move_up":
return { action: moveUp };
case "move_down":
return { action: moveDown };
case "move_left":
return { action: rotate, value: ["left"] };
case "move_right":
return { action: rotate, value: ["right"] };
}
},
[moveDown, moveUp, rotate]
);
useEffect(() => {
if (props.eventState) {
const eventAction = props.eventState.event;
const dispatchedObject =
dispatcherObjects[eventAction as keyof typeof dispatcherObjects];
const dispatchedObject = dispatchObject(eventAction);
if (dispatchedObject) {
dispatchedObject.action();
dispatchedObject.action.apply(null, dispatchedObject.value as any);
}
}
}, [
dispatcherObjects,
props.eventState,
setMiddleRingAnimDuration,
setMiddleRingNoise,
setMiddleRingRotX,
setMiddleRingRotZ,
setMiddleRingRotating,
setMiddleRingWobbleStrength,
]);
}, [dispatchObject, props.eventState]);
return null;
};

View file

@ -3,10 +3,8 @@ import { useHudStore } from "../../store";
import { StateManagerProps } from "./EventManager";
const NodeHUDManager = (props: StateManagerProps) => {
const setActiveNodeHudId = useHudStore(
(state) => state.setActiveNodeHudId
);
const toggleHud = useHudStore((state) => state.toggleHud);
const setId = useHudStore((state) => state.setId);
const toggleActive = useHudStore((state) => state.toggleActive);
const dispatchObject = useCallback(
(event: string, targetNodeHudId: string) => {
@ -16,19 +14,19 @@ const NodeHUDManager = (props: StateManagerProps) => {
case "move_left":
case "move_right":
return {
action: setActiveNodeHudId,
action: setId,
value: targetNodeHudId,
actionDelay: 3903.704,
};
case "change_node":
return {
action: setActiveNodeHudId,
action: setId,
value: targetNodeHudId,
actionDelay: 500,
};
}
},
[setActiveNodeHudId]
[setId]
);
useEffect(() => {
@ -39,15 +37,15 @@ const NodeHUDManager = (props: StateManagerProps) => {
const dispatchedObject = dispatchObject(eventAction, newActiveHudId);
if (dispatchedObject) {
toggleHud();
toggleActive();
setTimeout(() => {
dispatchedObject.action(dispatchedObject.value);
toggleHud();
toggleActive();
}, dispatchedObject.actionDelay);
}
}
}, [props.eventState, setActiveNodeHudId, toggleHud, dispatchObject]);
}, [props.eventState, toggleActive, dispatchObject]);
return null;
};

View file

@ -2,51 +2,37 @@ import { useCallback, useEffect } from "react";
import { useNodeStore } from "../../store";
import { StateManagerProps } from "./EventManager";
type SetIsActiveNodeInteractedWith = (value: boolean) => void;
const NodeManager = (props: StateManagerProps) => {
const setActiveNode = useNodeStore((state) => state.setActiveNodeId);
const setActiveNodeState = useNodeStore((state) => state.setActiveNodeState);
const setNodeMatrixIndices = useNodeStore(
(state) => state.setNodeMatrixIndices
);
const setIsActiveNodeInteractedWith: SetIsActiveNodeInteractedWith = useNodeStore(
(state) => state.setIsActiveNodeInteractedWith
);
const setActiveNodePosX = useNodeStore((state) => state.setActiveNodePosX);
const setActiveNodePosZ = useNodeStore((state) => state.setActiveNodePosZ);
const setActiveNodeRotZ = useNodeStore((state) => state.setActiveNodeRotZ);
const animateActiveNodeThrow = useCallback(() => {
setIsActiveNodeInteractedWith(true);
setActiveNodePosZ(0.3);
setActiveNodePosX(0.9);
setTimeout(() => {
setActiveNodePosZ(0.2);
setActiveNodePosX(0.5);
}, 800);
setTimeout(() => {
setActiveNodePosX(1.55);
setActiveNodeRotZ(-0.005);
}, 2600);
setTimeout(() => {
setActiveNodePosZ(2);
setActiveNodePosX(0);
setActiveNodeRotZ(-0.5);
}, 2700);
setTimeout(() => {
setActiveNodeRotZ(0);
setIsActiveNodeInteractedWith(false);
}, 3800);
}, [
setActiveNodePosX,
setActiveNodePosZ,
setActiveNodeRotZ,
setIsActiveNodeInteractedWith,
]);
// const animateActiveNodeThrow = useCallback(() => {
// setIsActiveNodeInteractedWith(true);
//
// setActiveNodePosZ(0.3);
// setActiveNodePosX(0.9);
//
// setTimeout(() => {
// setActiveNodePosZ(0.2);
// setActiveNodePosX(0.5);
// }, 800);
// setTimeout(() => {
// setActiveNodePosX(1.55);
// setActiveNodeRotZ(-0.005);
// }, 2600);
// setTimeout(() => {
// setActiveNodePosZ(2);
// setActiveNodePosX(0);
// setActiveNodeRotZ(-0.5);
// }, 2700);
//
// setTimeout(() => {
// setActiveNodeRotZ(0);
// setIsActiveNodeInteractedWith(false);
// }, 3800);
// }, []);
const updateActiveNode = useCallback(
(
@ -54,17 +40,19 @@ const NodeManager = (props: StateManagerProps) => {
isMoving: boolean,
newActiveNodeId: string,
newNodeColIdx: number,
newNodeRowIdx: number
newNodeRowIdx: number,
newNodeMatIdx: number
) => {
setTimeout(() => {
setActiveNode(newActiveNodeId);
setActiveNodeState(newActiveNodeId, "id");
setNodeMatrixIndices({
matrixIdx: newNodeMatIdx,
rowIdx: newNodeRowIdx,
colIdx: newNodeColIdx,
});
}, delay);
},
[setActiveNode, setNodeMatrixIndices]
[setActiveNodeState, setNodeMatrixIndices]
);
const dispatchObject = useCallback(
@ -72,7 +60,8 @@ const NodeManager = (props: StateManagerProps) => {
event: string,
newActiveNodeId: string,
newNodeColIdx: number,
newNodeRowIdx: number
newNodeRowIdx: number,
newNodeMatIdx: number
) => {
switch (event) {
case "move_up":
@ -87,23 +76,31 @@ const NodeManager = (props: StateManagerProps) => {
newActiveNodeId,
newNodeColIdx,
newNodeRowIdx,
newNodeMatIdx,
],
};
case "change_node":
return {
action: updateActiveNode,
value: [0, false, newActiveNodeId, newNodeColIdx, newNodeRowIdx],
};
case "throw_node_media":
case "throw_node_gate":
case "throw_node_sskn":
return {
action: animateActiveNodeThrow,
value: [0, true],
value: [
0,
false,
newActiveNodeId,
newNodeColIdx,
newNodeRowIdx,
newNodeMatIdx,
],
};
// case "throw_node_media":
// case "throw_node_gate":
// case "throw_node_sskn":
// return {
// action: animateActiveNodeThrow,
// value: [0, true],
// };
}
},
[animateActiveNodeThrow, updateActiveNode]
[updateActiveNode]
);
useEffect(() => {
@ -112,19 +109,21 @@ const NodeManager = (props: StateManagerProps) => {
const newActiveNodeId = props.eventState.newActiveNodeId;
const newNodeRowIdx = props.eventState.newNodeRowIdx;
const newNodeColIdx = props.eventState.newNodeColIdx;
const newNodeMatIdx = props.eventState.newNodeMatIdx;
const dispatchedObject = dispatchObject(
eventAction,
newActiveNodeId,
newNodeColIdx,
newNodeRowIdx
newNodeRowIdx,
newNodeMatIdx
);
if (dispatchedObject) {
dispatchedObject.action.apply(null, dispatchedObject.value as never);
}
}
}, [props.eventState, setActiveNode, dispatchObject]);
}, [props.eventState, setActiveNodeState, dispatchObject]);
return null;
};

View file

@ -3,70 +3,49 @@ import { useSiteStore } from "../../store";
import { StateManagerProps } from "./EventManager";
const SiteManager = (props: StateManagerProps) => {
const addToSiteRotY = useSiteStore((state) => state.addToSiteRotY);
const addToSitePosY = useSiteStore((state) => state.addToSitePosY);
const setSiteRotIdx = useSiteStore((state) => state.setSiteRotIdx);
const setIsSiteYChanging = useSiteStore((state) => state.setIsSiteChanging);
const rotateSite = useCallback(
(value: number, newSiteRotIdx: string) => {
addToSiteRotY(value);
setSiteRotIdx(newSiteRotIdx);
},
[addToSiteRotY, setSiteRotIdx]
);
const setSiteRotY = useSiteStore((state) => state.setSiteRotY);
const setSitePosY = useSiteStore((state) => state.setSitePosY);
const dispatchObject = useCallback(
(event: string, newSiteRotIdx: string) => {
(event: string, newSitePosY: number, newSiteRotY: number) => {
switch (event) {
case "move_up":
return {
action: addToSitePosY,
value: [-1.5],
actionDelay: 1300,
};
case "move_down":
return {
action: addToSitePosY,
value: [1.5],
action: setSitePosY,
value: newSitePosY,
actionDelay: 1300,
};
case "move_left":
return {
action: rotateSite,
value: [Math.PI / 4, newSiteRotIdx],
actionDelay: 1100,
};
case "move_right":
return {
action: rotateSite,
value: [-Math.PI / 4, newSiteRotIdx],
action: setSiteRotY,
value: newSiteRotY,
actionDelay: 1100,
};
}
},
[addToSitePosY, rotateSite]
[setSitePosY, setSiteRotY]
);
useEffect(() => {
if (props.eventState) {
const eventAction = props.eventState.event;
const newSiteRotIdx = props.eventState.newSiteRotIdx;
const newSiteRotY = props.eventState.newSiteRotY;
const newSitePosY = props.eventState.newSitePosY;
const dispatchedObject = dispatchObject(eventAction, newSiteRotIdx);
const dispatchedObject = dispatchObject(
eventAction,
newSitePosY,
newSiteRotY
);
if (dispatchedObject) {
setIsSiteYChanging(true);
setTimeout(() => {
(dispatchedObject.action as any).apply(null, dispatchedObject.value);
dispatchedObject.action(dispatchedObject.value);
}, dispatchedObject.actionDelay);
setTimeout(() => {
setIsSiteYChanging(false);
}, 3000);
}
}
}, [dispatchObject, props.eventState, setIsSiteYChanging]);
}, [dispatchObject, props.eventState]);
return null;
};

View file

@ -1,110 +1,95 @@
import { useCallback, useEffect } from "react";
import node_huds from "../../resources/node_huds.json";
import site_a from "../../resources/site_a.json";
import { useTextRendererStore } from "../../store";
import { useYellowTextStore } from "../../store";
import { SiteType } from "../../components/MainScene/Site";
import { StateManagerProps } from "./EventManager";
const YellowTextManager = (props: any) => {
const setYellowText = useTextRendererStore((state) => state.setYellowText);
const YellowTextManager = (props: StateManagerProps) => {
const setTransformState = useYellowTextStore(
(state) => state.setTransformState
);
const addToTransformState = useYellowTextStore(
(state) => state.addToTransformState
);
const setText = useYellowTextStore((state) => state.setText);
const setYellowTextOffsetXCoeff = useTextRendererStore(
(state) => state.setYellowTextOffsetXCoeff
);
const addToYellowTextPosY = useTextRendererStore(
(state) => state.addToYellowTextPosY
);
const addToYellowTextPosX = useTextRendererStore(
(state) => state.addToYellowTextPosX
);
const setYellowTextPosY = useTextRendererStore(
(state) => state.setYellowTextPosY
);
const setYellowTextPosX = useTextRendererStore(
(state) => state.setYellowTextPosX
);
const setDisableTrail = useYellowTextStore((state) => state.setDisableTrail);
const animateYellowTextWithMove = useCallback(
(
yellowLetterPosXOffset: number,
yellowLetterPosYOffset: number,
posXOffset: number,
posYOffset: number,
newActiveHudId: string,
newActiveNodeId: string,
newLevel: string,
delay: number
) => {
setDisableTrail(true);
// animate the letters to match that of site's
// to create an illusion of not moving
setTimeout(() => {
addToYellowTextPosY(yellowLetterPosYOffset);
addToYellowTextPosX(yellowLetterPosXOffset);
addToTransformState(posXOffset, "posX");
addToTransformState(posYOffset, "posY");
}, delay);
setTimeout(() => {
// make current hud big text shrink
setYellowTextOffsetXCoeff(-1);
setTransformState(-1, "xOffset");
}, 2500);
setTimeout(() => {
// animate it to new pos x/y
setYellowTextPosX(
node_huds[newActiveHudId as keyof typeof node_huds].big_text[0]
setTransformState(
node_huds[newActiveHudId as keyof typeof node_huds].big_text[0],
"posX"
);
setYellowTextPosY(
node_huds[newActiveHudId as keyof typeof node_huds].big_text[1]
setTransformState(
node_huds[newActiveHudId as keyof typeof node_huds].big_text[1],
"posY"
);
// set new text according to the node name
setYellowText(
(site_a as SiteType)[newLevel][newActiveNodeId].node_name
);
setText((site_a as SiteType)[newLevel][newActiveNodeId].node_name);
setDisableTrail(false);
}, 3000);
// unshrink text
setTimeout(() => {
setYellowTextOffsetXCoeff(0);
setTransformState(0, "xOffset");
}, 3900);
},
[
addToYellowTextPosX,
addToYellowTextPosY,
setYellowText,
setYellowTextOffsetXCoeff,
setYellowTextPosX,
setYellowTextPosY,
]
[addToTransformState, setDisableTrail, setText, setTransformState]
);
const animateYellowTextWithoutMove = useCallback(
(newActiveHudId: string, newActiveNodeId: string, level: string) => {
// make current hud big text shrink
setYellowTextOffsetXCoeff(-1);
setTransformState(-1, "xOffset");
setTimeout(() => {
setYellowTextPosX(
node_huds[newActiveHudId as keyof typeof node_huds].big_text[0]
// animate it to new pos x/y
setTransformState(
node_huds[newActiveHudId as keyof typeof node_huds].big_text[0],
"posX"
);
setYellowTextPosY(
node_huds[newActiveHudId as keyof typeof node_huds].big_text[1]
setTransformState(
node_huds[newActiveHudId as keyof typeof node_huds].big_text[1],
"posY"
);
}, 400);
// animate it to new pos x/y
setTimeout(() => {
// set new text according to the node name
setYellowText((site_a as SiteType)[level][newActiveNodeId].node_name);
setText((site_a as SiteType)[level][newActiveNodeId].node_name);
}, 1000);
setTimeout(() => {
// unshrink text
setYellowTextOffsetXCoeff(0);
setTransformState(0, "xOffset");
}, 1200);
},
[
setYellowText,
setYellowTextOffsetXCoeff,
setYellowTextPosX,
setYellowTextPosY,
]
[setText, setTransformState]
);
const animateMediaYellowText = useCallback(
@ -113,49 +98,46 @@ const YellowTextManager = (props: any) => {
targetMediaComponentTextPos: number[]
) => {
// make current text shrink
setYellowTextOffsetXCoeff(-1);
setTransformState(-1, "xOffset");
setTimeout(() => {
setYellowTextPosX(targetMediaComponentTextPos[0]);
setYellowTextPosY(targetMediaComponentTextPos[1]);
setTransformState(targetMediaComponentTextPos[0], "posX");
setTransformState(targetMediaComponentTextPos[1], "posY");
}, 400);
setTimeout(() => {
setYellowText(targetMediaComponentText);
setText(targetMediaComponentText);
}, 1000);
setTimeout(() => {
// unshrink text
setYellowTextOffsetXCoeff(0);
setTransformState(0, "xOffset");
}, 1200);
},
[
setYellowText,
setYellowTextOffsetXCoeff,
setYellowTextPosX,
setYellowTextPosY,
]
[setText, setTransformState]
);
const initializeYellowTextForMediaScene = useCallback(() => {
setTimeout(() => {
setYellowText("Play");
setYellowTextPosX(-0.8);
setYellowTextPosY(0.05);
setText("Play");
setTransformState(-0.8, "posX");
setTransformState(0.05, "posY");
}, 3950);
}, [setYellowText, setYellowTextPosX, setYellowTextPosY]);
}, [setText, setTransformState]);
const initializeYellowTextForMainScene = useCallback(
(activeNodeId: string, level: string) => {
setYellowText((site_a as SiteType)[level][activeNodeId].node_name);
setYellowTextPosX(
node_huds[activeNodeId as keyof typeof node_huds].big_text[0]
setText((site_a as SiteType)[level][activeNodeId].node_name);
setTransformState(
node_huds[activeNodeId as keyof typeof node_huds].big_text[0],
"posX"
);
setYellowTextPosY(
node_huds[activeNodeId as keyof typeof node_huds].big_text[1]
setTransformState(
node_huds[activeNodeId as keyof typeof node_huds].big_text[1],
"posY"
);
},
[setYellowText, setYellowTextPosX, setYellowTextPosY]
[setText, setTransformState]
);
const dispatchObject = useCallback(
@ -258,8 +240,6 @@ const YellowTextManager = (props: any) => {
animateYellowTextWithMove,
animateYellowTextWithoutMove,
props.eventState,
props.newActiveHudId,
props.newActiveNodeId,
dispatchObject,
]);

View file

@ -25,22 +25,23 @@ const handleMainSceneEvent = (gameContext: GameContext) => {
const nodeColIdx = gameContext.nodeMatrixIndices.colIdx;
const nodeRowIdx = gameContext.nodeMatrixIndices.rowIdx;
let newNodeMatIdx = gameContext.nodeMatrixIndices.matrixIdx;
let newNodeColIdx = gameContext.nodeMatrixIndices.colIdx;
let newNodeRowIdx = gameContext.nodeMatrixIndices.rowIdx;
let newLevel = gameContext.currentLevel;
let newSiteRotIdx = gameContext.siteRotIdx;
let newLevel = gameContext.activeLevel;
let newSiteRotY = gameContext.siteRotY;
let newSitePosY = gameContext.sitePosY;
let newScene = gameContext.scene;
switch (keyPress) {
case "left":
newNodeColIdx = nodeColIdx - 1;
if (newNodeColIdx < 0) {
event = "move_left";
newSiteRotIdx =
parseInt(gameContext.siteRotIdx) + 1 > 8
? "1"
: (parseInt(gameContext.siteRotIdx) + 1).toString();
newNodeMatIdx = newNodeMatIdx + 1 > 8 ? 1 : newNodeMatIdx + 1;
newNodeColIdx = 0;
newSiteRotY -= -Math.PI / 4;
} else {
event = "change_node";
}
@ -50,10 +51,11 @@ const handleMainSceneEvent = (gameContext: GameContext) => {
if (newNodeRowIdx > 2) {
event = "move_down";
newLevel = (parseInt(gameContext.currentLevel) - 1)
newLevel = (parseInt(gameContext.activeLevel) - 1)
.toString()
.padStart(2, "0");
newNodeRowIdx = 0;
newSitePosY += 1.5;
} else {
event = "change_node";
}
@ -63,11 +65,12 @@ const handleMainSceneEvent = (gameContext: GameContext) => {
if (newNodeRowIdx < 0) {
event = "move_up";
newLevel = (parseInt(gameContext.currentLevel) + 1)
newLevel = (parseInt(gameContext.activeLevel) + 1)
.toString()
.padStart(2, "0");
newNodeRowIdx = 2;
newSitePosY -= 1.5;
} else {
event = "change_node";
}
@ -76,12 +79,9 @@ const handleMainSceneEvent = (gameContext: GameContext) => {
newNodeColIdx = nodeColIdx + 1;
if (newNodeColIdx > 3) {
event = "move_right";
newSiteRotIdx =
parseInt(gameContext.siteRotIdx) - 1 < 1
? "8"
: (parseInt(gameContext.siteRotIdx) - 1).toString();
newNodeMatIdx = newNodeMatIdx - 1 < 1 ? 8 : newNodeMatIdx - 1;
newNodeColIdx = 3;
newSiteRotY += -Math.PI / 4;
} else {
event = "change_node";
}
@ -92,7 +92,7 @@ const handleMainSceneEvent = (gameContext: GameContext) => {
// new active blue orb here.
const newActiveNodeId =
newLevel +
node_matrices[newSiteRotIdx as keyof typeof node_matrices][
node_matrices[newNodeMatIdx.toString() as keyof typeof node_matrices][
newNodeRowIdx as number
][newNodeColIdx as number];
@ -119,7 +119,7 @@ const handleMainSceneEvent = (gameContext: GameContext) => {
const newActiveNodeId =
newLevel +
node_matrices[newSiteRotIdx as keyof typeof node_matrices][
node_matrices[newNodeMatIdx.toString() as keyof typeof node_matrices][
newNodeRowIdx as number
][newNodeColIdx as number];
@ -130,7 +130,9 @@ const handleMainSceneEvent = (gameContext: GameContext) => {
event: event,
newNodeColIdx: newNodeColIdx,
newNodeRowIdx: newNodeRowIdx,
newSiteRotIdx: newSiteRotIdx,
newNodeMatIdx: newNodeMatIdx,
newSitePosY: newSitePosY,
newSiteRotY: newSiteRotY,
newLevel: newLevel,
newScene: newScene,
newActiveNodeId: newActiveNodeId,

View file

@ -1,4 +1,4 @@
import { a, useSpring } from "@react-spring/three";
import { a } from "@react-spring/three";
import { OrbitControls } from "@react-three/drei";
import React, { Suspense, useEffect } from "react";
import Site from "../components/MainScene/Site";
@ -9,60 +9,33 @@ import MainSceneIntro from "../components/MainSceneIntro";
import GrayPlanes from "../components/MainScene/GrayPlanes";
import MiddleRing from "../components/MainScene/MiddleRing";
import Starfield from "../components/MainScene/Starfield";
import {
useNodeStore,
useHudStore,
useLainStore,
useMainGroupStore,
} from "../store";
import TextRenderer from "../components/TextRenderer/TextRenderer";
import { useHudStore, useLainStore } from "../store";
import TextRenderer from "../components/TextRenderer/GreenTextRenderer";
import HUD from "../components/MainScene/HUD";
import YellowOrb from "../components/MainScene/YellowOrb";
import CurrentLevelNodes from "../components/MainScene/CurrentLevelNodes";
import ActiveLevelNodes from "../components/MainScene/ActiveLevelNodes";
import YellowTextRenderer from "../components/TextRenderer/YellowTextRenderer";
const MainScene = () => {
const setLainMoveState = useLainStore((state) => state.setLainMoveState);
const setActiveNode = useNodeStore((state) => state.setActiveNodeId);
const setActiveNodeHudId = useHudStore(
(state) => state.setActiveNodeHudId
);
const mainGroupPosY = useMainGroupStore((state) => state.mainGroupPosY);
const mainGroupPosZ = useMainGroupStore((state) => state.mainGroupPosZ);
const mainGroupRotX = useMainGroupStore((state) => state.mainGroupRotX);
const mainGroupStatePos = useSpring({
mainGroupPosY: mainGroupPosY,
mainGroupPosZ: mainGroupPosZ,
config: { duration: 3644 },
});
const mainGroupStateRot = useSpring({
mainGroupRotX: mainGroupRotX,
config: { duration: 1500 },
});
const setActiveNodeHudId = useHudStore((state) => state.setId);
useEffect(() => {
setLainMoveState("standing");
setActiveNode("0422");
setActiveNodeHudId("fg_hud_1");
}, [setActiveNode, setActiveNodeHudId, setLainMoveState]);
// set lain intro spritesheet before the page loads fully
}, [setActiveNodeHudId, setLainMoveState]);
return (
<perspectiveCamera position-z={3}>
<Suspense fallback={null}>
<MainSceneIntro />
<a.group
rotation-x={mainGroupStateRot.mainGroupRotX}
position-y={mainGroupStatePos.mainGroupPosY}
position-z={mainGroupStatePos.mainGroupPosZ}
>
<a.group>
<Preloader />
<Site />
<CurrentLevelNodes />
<ActiveLevelNodes />
<HUD />
<TextRenderer />
<YellowTextRenderer />
<YellowOrb />
<Starfield />
<GrayPlanes />

View file

@ -1,6 +1,6 @@
import React, { useCallback, useEffect, useMemo } from "react";
import { useMediaStore } from "../store";
import TextRenderer from "../components/TextRenderer/TextRenderer";
import TextRenderer from "../components/TextRenderer/GreenTextRenderer";
import LeftSide from "../components/MediaScene/Selectables/LeftSide";
import RightSide from "../components/MediaScene/Selectables/RightSide";
import AudioVisualizer from "../components/MediaScene/AudioVisualizer/AudioVisualizer";

View file

@ -8,26 +8,22 @@ type SceneState = {
};
type HUDState = {
activeHudId: string;
hudActive: number;
hudVisible: boolean;
setActiveNodeHudId: (to: string) => void;
toggleHud: () => void;
id: string;
active: number;
visible: boolean;
setId: (to: string) => void;
toggleActive: () => void;
};
type NodeState = {
activeNodeId: string;
isActiveNodeInteractedWith: boolean;
activeNodePosX: number;
activeNodePosZ: number;
activeNodeRotZ: number;
setActiveNodePosX: (to: number) => void;
setActiveNodePosZ: (to: number) => void;
setActiveNodeRotZ: (to: number) => void;
setActiveNodeId: (to: string) => void;
setIsActiveNodeInteractedWith: (to: boolean) => void;
nodeMatrixIndices: { rowIdx: number; colIdx: number };
setNodeMatrixIndices: (to: { rowIdx: number; colIdx: number }) => void;
activeNodeState: {
id: string;
posX: number;
posZ: number;
rotZ: number;
interactedWith: boolean;
};
nodeMatrixIndices: { matrixIdx: number; rowIdx: number; colIdx: number };
};
type LainState = {
@ -35,15 +31,6 @@ type LainState = {
setLainMoveState: (to: string) => void;
};
type MainGroupState = {
mainGroupPosY: number;
mainGroupPosZ: number;
mainGroupRotX: number;
setMainGroupPosY: (to: number) => void;
setMainGroupPosZ: (to: number) => void;
setMainGroupRotX: (to: number) => void;
};
type GrayPlanesState = {
grayPlanesVisible: boolean;
setGrayPlanesVisible: (to: boolean) => void;
@ -66,39 +53,25 @@ type YellowOrbState = {
type SiteState = {
siteRotY: number;
sitePosY: number;
isSiteChangingY: boolean;
addToSiteRotY: (by: number) => void;
addToSitePosY: (by: number) => void;
setSiteRotY: (to: number) => void;
setSitePosY: (to: number) => void;
setIsSiteChanging: (to: boolean) => void;
siteRotIdx: string;
setSiteRotIdx: (to: string) => void;
};
type LevelState = {
currentLevel: string;
activeLevels: string[];
setActiveLevels: (to: string[]) => void;
setCurrentLevel: (to: string) => void;
activeLevel: string;
setActiveLevel: (to: string) => void;
};
type MiddleRingState = {
middleRingWobbleStrength: number;
middleRingRotating: boolean;
middleRingNoise: number;
middleRingPosY: number;
middleRingRotX: number;
middleRingRotZ: number;
middleRingAnimDuration: number;
setMiddleRingWobbleStrength: (to: number) => void;
setMiddleRingRotating: (to: boolean) => void;
setMiddleRingNoise: (to: number) => void;
addToMiddleRingPosY: (val: number) => void;
setMiddleRingPosY: (to: number) => void;
setMiddleRingRotX: (to: number) => void;
setMiddleRingRotZ: (to: number) => void;
setMiddleRingAnimDuration: (to: number) => void;
transformState: {
wobbleStrength: number;
noiseStrength: number;
posY: number;
rotX: number;
rotZ: number;
};
isRotating: boolean;
animDuration: number;
};
type MediaWordState = {
@ -115,17 +88,27 @@ type MediaWordState = {
resetWordPositionDataStructIdx: () => void;
};
export type YellowTextState = {
disableTrail: boolean;
text: string;
transformState: {
posX: number;
posY: number;
xOffset: number;
};
};
export type GreenTextState = {
text: string;
transformState: {
posX: { initial: number; final: number };
posY: number;
xOffset: number;
};
active: number;
};
export type TextRendererState = {
yellowText: string;
yellowTextPosY: number;
yellowTextPosX: number;
yellowTextOffsetXCoeff: number;
setYellowText: (to: string) => void;
addToYellowTextPosY: (val: number) => void;
addToYellowTextPosX: (val: number) => void;
setYellowTextPosY: (to: number) => void;
setYellowTextPosX: (to: number) => void;
setYellowTextOffsetXCoeff: (to: number) => void;
greenTextPosY: number;
greenTextPosX: { initial: number; final: number };
greenText: string;
@ -136,18 +119,6 @@ export type TextRendererState = {
toggleGreenText: () => void;
};
export type ImageSrc = {
default: string;
};
type ImageState = {
images: {
1: ImageSrc | undefined;
2: ImageSrc | undefined;
3: ImageSrc | undefined;
};
};
type GateState = {
gateLvl: number;
incrementGateLvl: () => void;
@ -162,76 +133,101 @@ type SSknState = {
toggleLoading: () => void;
};
export const useTextRendererStore = create<TextRendererState>((set) => ({
// yellow text
yellowText: "Play",
yellowTextPosY: 0.23,
yellowTextPosX: -0.35,
yellowTextOffsetXCoeff: 0,
setYellowText: (to) => set(() => ({ yellowText: to })),
addToYellowTextPosY: (val) =>
set((state) => ({ yellowTextPosY: state.yellowTextPosY + val })),
addToYellowTextPosX: (val) =>
set((state) => ({ yellowTextPosX: state.yellowTextPosX + val })),
setYellowTextPosY: (to) => set(() => ({ yellowTextPosY: to })),
setYellowTextPosX: (to) => set(() => ({ yellowTextPosX: to })),
setYellowTextOffsetXCoeff: (to) =>
set(() => ({ yellowTextOffsetXCoeff: to })),
// green text
greenText: "TOUKO's DIARY",
greenTextPosY: 0,
greenTextPosX: { initial: 0, final: 0 },
greenTextActive: 1,
setGreenTextPosY: (to) => set(() => ({ greenTextPosY: to })),
setGreenTextPosX: (to) => set({ greenTextPosX: to }),
setGreenText: (to) => set(() => ({ greenText: to })),
toggleGreenText: () =>
set((state) => ({ greenTextActive: Number(!state.greenTextActive) })),
}));
export const useYellowTextStore = create(
combine(
{
disableTrail: false,
text: "Play",
transformState: {
posX: 0,
posY: 0,
xOffset: 0,
},
} as YellowTextState,
(set) => ({
setDisableTrail: (to: boolean) => set(() => ({ disableTrail: to })),
setText: (to: string) => set(() => ({ text: to })),
setTransformState: (to: number, at: string) =>
set((state) => ({
transformState: { ...state.transformState, [at]: to },
})),
addToTransformState: (val: number, at: string) =>
set((state) => ({
transformState: {
...state.transformState,
[at]:
state.transformState[at as keyof typeof state.transformState] +
val,
},
})),
})
)
);
export const useGreenTextStore = create(
combine(
{
text: "TOUKO's DIARY",
transformState: {
posX: { initial: 0, final: 0 },
posY: 0,
xOffset: 0,
},
active: 1,
} as GreenTextState,
(set) => ({
setText: (to: string) => set(() => ({ text: to })),
setTransformState: (
to: number | { initial: number; final: number },
at: string
) =>
set((state) => ({
transformState: { ...state.transformState, [at]: to },
})),
toggleActive: () => set((state) => ({ active: Number(!state.active) })),
})
)
);
export const useHudStore = create<HUDState>((set) => ({
activeHudId: "fg_hud_1",
hudActive: 1,
hudVisible: true,
setActiveNodeHudId: (to) => set(() => ({ activeHudId: to })),
toggleHud: () => set((state) => ({ hudActive: Number(!state.hudActive) })),
id: "fg_hud_1",
active: 1,
visible: true,
setId: (to) => set(() => ({ id: to })),
toggleActive: () => set((state) => ({ active: Number(!state.active) })),
}));
export const useNodeStore = create<NodeState>((set) => ({
activeNodeId: "0422",
isActiveNodeInteractedWith: false,
activeNodePosX: 0,
activeNodePosZ: 0,
activeNodeRotZ: 0,
setActiveNodePosX: (to) => set(() => ({ activeNodePosX: to })),
setActiveNodePosZ: (to) => set(() => ({ activeNodePosZ: to })),
setActiveNodeRotZ: (to) => set(() => ({ activeNodeRotZ: to })),
setActiveNodeId: (to) => set(() => ({ activeNodeId: to })),
setIsActiveNodeInteractedWith: (to) =>
set(() => ({ isActiveNodeInteractedWith: to })),
nodeRowIdx: 0,
nodeMatrixIndices: { rowIdx: 0, colIdx: 0 },
setNodeMatrixIndices: (to) => set(() => ({ nodeMatrixIndices: to })),
}));
export const useNodeStore = create(
combine(
{
activeNodeState: {
id: "0422",
posX: 0,
posZ: 0,
rotZ: 0,
interactedWith: false,
},
nodeMatrixIndices: { matrixIdx: 7, rowIdx: 0, colIdx: 0 },
} as NodeState,
(set) => ({
setActiveNodeState: (to: number | boolean | string, at: string) =>
set((state) => ({
activeNodeState: { ...state.activeNodeState, [at]: to },
})),
setNodeMatrixIndices: (to: {
matrixIdx: number;
rowIdx: number;
colIdx: number;
}) => set(() => ({ nodeMatrixIndices: to })),
})
)
);
export const useLainStore = create<LainState>((set) => ({
lainMoveState: "standing",
setLainMoveState: (to) => set(() => ({ lainMoveState: to })),
}));
// -2.5 - intro val
//-9.5 - intro val
//1.5 - intro val
export const useMainGroupStore = create<MainGroupState>((set) => ({
mainGroupPosY: 0,
mainGroupPosZ: 0,
mainGroupRotX: 0,
setMainGroupPosY: (to) => set(() => ({ mainGroupPosY: to })),
setMainGroupPosZ: (to) => set(() => ({ mainGroupPosZ: to })),
setMainGroupRotX: (to) => set(() => ({ mainGroupRotX: to })),
}));
export const useGrayPlanesStore = create<GrayPlanesState>((set) => ({
grayPlanesVisible: true,
setGrayPlanesVisible: (to) => set(() => ({ grayPlanesVisible: to })),
@ -254,42 +250,37 @@ export const useYellowOrbStore = create<YellowOrbState>((set) => ({
export const useSiteStore = create<SiteState>((set) => ({
sitePosY: 0,
siteRotY: 0,
isSiteChangingY: false,
addToSitePosY: (by) => set((state) => ({ sitePosY: state.sitePosY + by })),
addToSiteRotY: (by) => set((state) => ({ siteRotY: state.siteRotY + by })),
setSitePosY: (to) => set(() => ({ sitePosY: to })),
setSiteRotY: (to) => set(() => ({ siteRotY: to })),
setIsSiteChanging: (to) => set(() => ({ isSiteChangingY: to })),
siteRotIdx: "7",
setSiteRotIdx: (to) => set(() => ({ siteRotIdx: to })),
}));
export const useMiddleRingStore = create<MiddleRingState>((set) => ({
middleRingWobbleStrength: 0,
middleRingRotating: true,
middleRingNoise: 0.03,
middleRingPosY: -0.11,
middleRingRotX: 0,
middleRingRotZ: 0,
middleRingAnimDuration: 600,
setMiddleRingWobbleStrength: (to) =>
set(() => ({ middleRingWobbleStrength: to })),
setMiddleRingRotating: (to) => set(() => ({ middleRingRotating: to })),
setMiddleRingNoise: (to) => set(() => ({ middleRingNoise: to })),
addToMiddleRingPosY: (by) =>
set((state) => ({ middleRingPosY: state.middleRingPosY + by })),
setMiddleRingPosY: (to) => set(() => ({ middleRingPosY: to })),
setMiddleRingRotX: (to) => set(() => ({ middleRingRotX: to })),
setMiddleRingRotZ: (to) => set(() => ({ middleRingRotZ: to })),
setMiddleRingAnimDuration: (to) =>
set(() => ({ middleRingAnimDuration: to })),
}));
export const useMiddleRingStore = create(
combine(
{
transformState: {
wobbleStrength: 0,
noiseStrength: 0.03,
posY: -0.11,
rotX: 0,
rotZ: 0,
},
isRotating: true,
animDuration: 600,
} as MiddleRingState,
(set) => ({
setTransformState: (to: number, at: string) =>
set((state) => ({
transformState: { ...state.transformState, [at]: to },
})),
setRotating: (to: boolean) => ({ isRotating: to }),
setAnimDuration: (to: number) => ({ animDuration: to }),
})
)
);
export const useLevelStore = create<LevelState>((set) => ({
currentLevel: "04",
activeLevels: ["02", "03", "05", "06"],
setActiveLevels: (to) => set(() => ({ activeLevels: to })),
setCurrentLevel: (to) => set(() => ({ currentLevel: to })),
activeLevel: "04",
setActiveLevel: (to) => set(() => ({ activeLevel: to })),
}));
export const useMediaStore = create(
@ -442,7 +433,7 @@ export const useSSknStore = create<SSknState>((set) => ({
}));
export const useSceneStore = create<SceneState>((set) => ({
currentScene: "polytan",
currentScene: "media",
setScene: (to) => set(() => ({ currentScene: to })),
}));
@ -586,18 +577,6 @@ export const useBootStore = create(
)
);
export const useImageStore = create(
combine(
{
images: { 1: undefined, 2: undefined, 3: undefined },
} as ImageState,
(set) => ({
setImages: (to: ImageSrc, idx: number) =>
set((state) => ({ images: { ...state.images, [idx]: to } })),
})
)
);
export const usePolytanStore = create<any>((set) => ({
unlockedParts: {
body: true,