refactoring the store

This commit is contained in:
ad044 2021-01-20 21:43:58 +04:00
parent e3764925fa
commit 81593d4266
10 changed files with 307 additions and 332 deletions

View file

@ -67,7 +67,6 @@ const HUD = () => {
]
);
console.log('called')
const longHudTex = useLoader(THREE.TextureLoader, longHud);
const longHudMirroredTex = useLoader(THREE.TextureLoader, longHudMirrored);

View file

@ -1,6 +1,5 @@
import orangeFont from "../../static/sprite/orange_font_texture.png";
import yellowFont from "../../static/sprite/yellow_font_texture.png";
import whiteFont from "../../static/sprite/white_and_green_texture.png";
import * as THREE from "three";
import { useLoader } from "react-three-fiber";
import orange_font_json from "../../resources/font_data/big_font.json";
@ -12,62 +11,55 @@ const BigLetter = memo(
color: string;
letter: string;
letterIdx: number;
xOffsetCoeff: number;
xOffset: number;
}) => {
const colorToTexture = (color: string) => {
const colorTexture = {
orange: orangeFont,
yellow: yellowFont,
white: whiteFont,
};
return colorTexture[color as keyof typeof colorTexture];
};
const tex = useMemo(
() =>
props.color === "orange" || props.letterIdx === 0
? orangeFont
: yellowFont,
[props.color, props.letterIdx]
);
// first letter in big font is always orange in this case so make it orange if so. else,
// run through the function.
const color =
props.letterIdx === 0 ? orangeFont : colorToTexture(props.color);
const colorTexture: THREE.Texture = useLoader(THREE.TextureLoader, tex);
const colorTexture: THREE.Texture = useLoader(THREE.TextureLoader, color);
// i have yet to figure out a genrealizable way of
// calculating the y offset, this shit will do for now
// also, we dont have all the lines since i dont need them yet.
// also, baseline offsets dont work properly since i dont need them yet either
// should be trivial to calculate though, im just lazy
const getLineNum = (letter: string) => {
const lineYOffset = useMemo(() => {
const lineOne = "ABCDEFGHIJKLMNOPQ";
const lineTwo = "RSTUVWXYZ01234567";
const lineThree = "89abcdefghijklmnopqrs";
if (letter === " ") return 5;
if (lineOne.includes(letter)) {
return 1;
} else if (lineTwo.includes(letter)) {
return 2;
} else if (lineThree.includes(letter)) {
return 3;
let lineNum: number;
if (props.letter === " ") {
lineNum = 5;
} else {
return 4;
if (lineOne.includes(props.letter)) {
lineNum = 1;
} else if (lineTwo.includes(props.letter)) {
lineNum = 2;
} else if (lineThree.includes(props.letter)) {
lineNum = 3;
} else {
lineNum = 4;
}
}
};
const lineYOffsets = useMemo(
() => ({
const offsets = {
1: 0.884,
2: 0.765,
3: 0.648,
4: 0.47,
5: 1,
}),
[]
);
};
return offsets[lineNum as keyof typeof offsets];
}, [props.letter]);
const letterData =
orange_font_json.glyphs[
props.letter as keyof typeof orange_font_json.glyphs
];
const letterData = useMemo(
() =>
orange_font_json.glyphs[
props.letter as keyof typeof orange_font_json.glyphs
],
[props.letter]
);
const geom = useMemo(() => {
const geometry = new THREE.PlaneBufferGeometry();
@ -80,25 +72,21 @@ const BigLetter = memo(
u = (u * letterData[2]) / 256 + letterData[0] / 256;
v =
(v * letterData[3]) / 136 +
lineYOffsets[getLineNum(props.letter)] -
letterData[4] / 136;
v = (v * letterData[3]) / 136 + lineYOffset - letterData[4] / 136;
uvAttribute.setXY(i, u, v);
}
return geometry;
}, [letterData, lineYOffsets, props.letter]);
}, [letterData, lineYOffset]);
const textRendererState = useSpring({
letterOffsetXCoeff:
props.letterIdx + 0.3 + (props.letterIdx + 0.3) * props.xOffsetCoeff,
const letterState = useSpring({
xOffset: props.letterIdx + 0.3 + (props.letterIdx + 0.3) * props.xOffset,
config: { duration: 200 },
});
return (
<a.mesh
position-x={textRendererState.letterOffsetXCoeff}
position-x={letterState.xOffset}
position-y={-letterData[4] / 12.5}
scale={[1, 1, 0]}
geometry={geom}

View file

@ -25,7 +25,7 @@ const MediaYellowTextAnimator = () => {
>
<BigLetter
color={"yellow"}
xOffsetCoeff={transformState.xOffset}
xOffset={transformState.xOffset}
letter={textArr[idx]}
letterIdx={idx}
key={idx}

View file

@ -7,45 +7,44 @@ import React, { useMemo, memo } from "react";
const MediumLetter = memo((props: { 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
// also, we dont have all the lines since i dont need them yet.
// also, baseline offsets dont work properly since i dont need them yet either
// should be trivial to calculate though, im just lazy
const getLineNum = (letter: string) => {
const lineYOffset = useMemo(() => {
const lineOne = "ABCDEFGHIJKLMNOPQQRSTUVW";
const lineTwo = "XYZ0123456789abcdefghij";
const lineThree = "klmnopqrstuvwxyz,.*";
if (letter === " ") return 5;
if (lineOne.includes(letter)) {
return 1;
} else if (lineTwo.includes(letter)) {
return 2;
} else if (lineThree.includes(letter)) {
return 3;
let lineNum: number;
if (props.letter === " ") {
lineNum = 5;
} else {
return 4;
if (lineOne.includes(props.letter)) {
lineNum = 1;
} else if (lineTwo.includes(props.letter)) {
lineNum = 2;
} else if (lineThree.includes(props.letter)) {
lineNum = 3;
} else {
lineNum = 4;
}
}
};
// 5th one is just a space, this is my hacky way of doing it.
const lineYOffsets = useMemo(
() => ({
const offsets = {
1: 0.355,
2: 0.297,
3: 0.238,
4: 0.18,
5: 1,
}),
[]
);
};
return offsets[lineNum as keyof typeof offsets];
}, [props.letter]);
const letterData =
medium_font_json.glyphs[
props.letter as keyof typeof medium_font_json.glyphs
];
const letterData = useMemo(
() =>
medium_font_json.glyphs[
props.letter as keyof typeof medium_font_json.glyphs
],
[props.letter]
);
const geom = useMemo(() => {
const geometry = new THREE.PlaneBufferGeometry();
@ -58,16 +57,13 @@ const MediumLetter = memo((props: { letter: string; letterIdx: number }) => {
u = (u * letterData[2]) / 256 + letterData[0] / 256;
v =
(v * letterData[3]) / 136 +
lineYOffsets[getLineNum(props.letter)] -
letterData[4] / 136;
v = (v * letterData[3]) / 136 + lineYOffset - letterData[4] / 136;
uvAttribute.setXY(i, u, v);
}
return geometry;
}, [letterData, lineYOffsets, props.letter]);
}, [letterData, lineYOffset]);
return (
<a.mesh

View file

@ -1,82 +1,58 @@
import React, { useEffect, useRef } from "react";
import { BigTextState, useBigTextStore } from "../../store";
import { a, useSpring, useTrail } from "@react-spring/three";
import { useMainSceneStore } from "../../store";
import { a, useTrail } from "@react-spring/three";
import BigLetter from "./BigLetter";
const YellowTextRenderer = (props: { visible?: boolean }) => {
const disableTrail = useBigTextStore((state) => state.disableTrail);
const transformState = useBigTextStore((state) => state.transformState);
const xOffset = useMainSceneStore((state) => state.bigTextXOffset);
const visible = useMainSceneStore((state) => state.bigTextVisible);
const color = useMainSceneStore((state) => state.bigTextColor);
const visible = useBigTextStore((state) => state.visible);
const color = useBigTextStore((state) => state.color);
const textRef = useRef(useMainSceneStore.getState().bigText.split(""));
const textArrRef = useRef(useBigTextStore.getState().text.split(""));
const transformRef = useRef(useBigTextStore.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,
const [trail, set] = useTrail(textRef.current.length, () => ({
posX: 0,
posY: 0,
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(
() =>
useBigTextStore.subscribe(
useMainSceneStore.subscribe(
(state) => {
transformRef.current = (state as BigTextState).transformState;
textArrRef.current = (state as BigTextState).text.split("");
textRef.current = (state as any).bigText.split("");
},
(state) => state
),
[]
);
useEffect(() => {
useMainSceneStore.subscribe(set, (state) => ({
posX: state.bigTextPos[0],
posY: state.bigTextPos[1],
}));
}, [set]);
return (
<group position={[0, 0, 10]} visible={props.visible && visible}>
{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={color}
xOffsetCoeff={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={color}
xOffsetCoeff={transformRef.current.xOffset}
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={color}
xOffset={xOffset}
letter={textRef.current[idx]}
letterIdx={idx}
key={idx}
/>
</a.group>
))}
</group>
);
};

View file

@ -20,7 +20,7 @@ import {
} from "../../store";
import MediaComponentManager from "./MediaSceneManagers/MediaComponentManager";
import SceneManager from "./GameManagers/SceneManager";
import YellowTextManager from "./MainSceneManagers/YellowTextManager";
import BigTextManager from "./MainSceneManagers/BigTextManager";
import LevelManager from "./MainSceneManagers/LevelManager";
import BootComponentManager from "./BootSceneManagers/BootComponentManager";
import SSknComponentManager from "./SSknSceneManagers/SSknComponentManager";
@ -283,7 +283,7 @@ const EventManager = () => {
<MiddleRingManager eventState={eventState!} />
<MediaComponentManager eventState={eventState!} />
<SceneManager eventState={eventState!} />
<YellowTextManager eventState={eventState!} />
<BigTextManager eventState={eventState!} />
<LevelManager eventState={eventState!} />
<BootComponentManager eventState={eventState!} />
<SSknComponentManager eventState={eventState!} />

View file

@ -1,9 +1,8 @@
import { useCallback, useEffect } from "react";
import {
useBigTextStore,
useGreenTextStore,
useHudStore,
useLevelStore,
useMainSceneStore,
useNodeStore,
useSiteSaveStore,
useSiteStore,
@ -25,17 +24,9 @@ const GameLoader = (props: StateManagerProps) => {
// level setter
const setActiveLevel = useLevelStore((state) => state.setActiveLevel);
// yellow text setter
const setYellowTextTransformState = useBigTextStore(
(state) => state.setTransformState
);
const setYellowText = useBigTextStore((state) => state.setText);
// green text setter
const setGreenText = useGreenTextStore((state) => state.setText);
const setGreenTextTransformState = useGreenTextStore(
(state) => state.setTransformState
);
// big text setter
const setBigTexPos = useMainSceneStore((state) => state.setBigTextPos);
const setBigText = useMainSceneStore((state) => state.setBigText);
// site setter
const setSiteTransformState = useSiteStore(
@ -69,39 +60,15 @@ const GameLoader = (props: StateManagerProps) => {
setActiveLevel(siteToLoad.level);
// load new site yellow text
setYellowTextTransformState(
node_huds[siteToLoad.nodeHudId as keyof typeof node_huds].big_text[0],
"posX"
);
setYellowTextTransformState(
node_huds[siteToLoad.nodeHudId as keyof typeof node_huds].big_text[1],
"posY"
setBigTexPos(
node_huds[siteToLoad.nodeHudId as keyof typeof node_huds].big_text[0]
);
const targetYellowText = (siteData as SiteType)[siteToLoad.level][
siteToLoad.activeNodeId
].node_name;
setYellowText(targetYellowText);
// load new site green text
const targetGreenText = (siteData as SiteType)[siteToLoad.level][
siteToLoad.activeNodeId
].title;
const targetGreenTextPosData =
node_huds[siteToLoad.nodeHudId as keyof typeof node_huds].medium_text;
setGreenTextTransformState(
{
initial: targetGreenTextPosData.initial_position[0],
final: targetGreenTextPosData.position[0],
},
"posX"
);
setGreenTextTransformState(targetGreenTextPosData.position[1], "posY");
setGreenText(targetGreenText);
setBigText(targetYellowText);
// load new site node
setActiveNodeState(siteToLoad.activeNodeId, "id");
@ -113,14 +80,12 @@ const GameLoader = (props: StateManagerProps) => {
[
setActiveLevel,
setActiveNodeState,
setBigTexPos,
setBigText,
setCurrentSite,
setGreenText,
setGreenTextTransformState,
setHudId,
setNodeMatrixIndices,
setSiteTransformState,
setYellowText,
setYellowTextTransformState,
siteASaveState,
siteBSaveState,
]

View file

@ -15,7 +15,7 @@ import SiteManager from "./MainSceneManagers/SiteManager";
import LainManager from "./MainSceneManagers/LainManager";
import MiddleRingManager from "./MainSceneManagers/MiddleRingManager";
import SceneManager from "./GameManagers/SceneManager";
import YellowTextManager from "./MainSceneManagers/YellowTextManager";
import BigTextManager from "./MainSceneManagers/BigTextManager";
import LevelManager from "./MainSceneManagers/LevelManager";
import LevelSelectionManager from "./MainSceneManagers/LevelSelectionManager";
import SubsceneManager from "./GameManagers/SubsceneManager";
@ -148,7 +148,7 @@ const MainSceneEventManager = (props: MainSceneEventManagerProps) => {
<LainManager eventState={eventState!} />
<MiddleRingManager eventState={eventState!} />
<SceneManager eventState={eventState!} />
<YellowTextManager eventState={eventState!} />
<BigTextManager eventState={eventState!} />
<LevelManager eventState={eventState!} />
<LevelSelectionManager eventState={eventState!} />
<SubsceneManager eventState={eventState!} />

View file

@ -1,29 +1,21 @@
import { useCallback, useEffect, useMemo } from "react";
import { useCallback, useEffect } from "react";
import node_huds from "../../../resources/node_huds.json";
import site_a from "../../../resources/site_a.json";
import site_b from "../../../resources/site_b.json";
import { useBigTextStore, useSiteStore } from "../../../store";
import { useMainSceneStore } from "../../../store";
import { SiteType } from "../../../components/MainScene/SyncedComponents/Site";
import { StateManagerProps } from "../EventManager";
const YellowTextManager = (props: StateManagerProps) => {
const setTransformState = useBigTextStore((state) => state.setTransformState);
const addToTransformState = useBigTextStore(
(state) => state.addToTransformState
const BigTextManager = (props: StateManagerProps) => {
const setText = useMainSceneStore((state) => state.setBigText);
const setColor = useMainSceneStore((state) => state.setBigTextColor);
const setVisible = useMainSceneStore((state) => state.setBigTextVisible);
const setXOffset = useMainSceneStore((state) => state.setBigTextXOffset);
const setPos = useMainSceneStore((state) => state.setBigTextPos);
const siteData = useMainSceneStore(
useCallback((state) => (state.activeSite === "a" ? site_a : site_b), [])
);
const setText = useBigTextStore((state) => state.setText);
const setDisableTrail = useBigTextStore((state) => state.setDisableTrail);
const setColor = useBigTextStore((state) => state.setColor);
const setVisible = useBigTextStore((state) => state.setVisible);
const currentSite = useSiteStore((state) => state.currentSite);
const siteData = useMemo(() => (currentSite === "a" ? site_a : site_b), [
currentSite,
]);
const animateYellowTextWithMove = useCallback(
(
@ -34,30 +26,21 @@ const YellowTextManager = (props: StateManagerProps) => {
newLevel: string,
delay: number
) => {
setDisableTrail(true);
// animate the letters to match that of site's
// to create an illusion of not moving
setTimeout(() => {
addToTransformState(posXOffset, "posX");
addToTransformState(posYOffset, "posY");
}, delay);
// setTimeout(() => {
// addToTransformState(posXOffset, "posX");
// addToTransformState(posYOffset, "posY");
// }, delay);
setTimeout(() => {
// make current hud big text shrink
setTransformState(-1, "xOffset");
setXOffset(-1, "xOffset");
}, 2500);
setTimeout(() => {
// animate it to new pos x/y
setTransformState(
node_huds[newActiveHudId as keyof typeof node_huds].big_text[0],
"posX"
);
setTransformState(
node_huds[newActiveHudId as keyof typeof node_huds].big_text[1],
"posY"
);
setPos(node_huds[newActiveHudId as keyof typeof node_huds].big_text);
// set new text according to the node name
const targetText =
newActiveNodeId === "UNKNOWN"
@ -65,32 +48,24 @@ const YellowTextManager = (props: StateManagerProps) => {
: (siteData as SiteType)[newLevel][newActiveNodeId].node_name;
setText(targetText);
setDisableTrail(false);
}, 3000);
// unshrink text
setTimeout(() => {
setTransformState(0, "xOffset");
setXOffset(0);
}, 3900);
},
[addToTransformState, setDisableTrail, setText, setTransformState, siteData]
[setPos, setText, setXOffset, siteData]
);
const animateYellowTextWithoutMove = useCallback(
(newActiveHudId: string, newActiveNodeId: string, level: string) => {
// make current hud big text shrink
setTransformState(-1, "xOffset");
setXOffset(-1);
setTimeout(() => {
// animate it to new pos x/y
setTransformState(
node_huds[newActiveHudId as keyof typeof node_huds].big_text[0],
"posX"
);
setTransformState(
node_huds[newActiveHudId as keyof typeof node_huds].big_text[1],
"posY"
);
setPos(node_huds[newActiveHudId as keyof typeof node_huds].big_text);
}, 400);
setTimeout(() => {
@ -100,19 +75,17 @@ const YellowTextManager = (props: StateManagerProps) => {
setTimeout(() => {
// unshrink text
setTransformState(0, "xOffset");
setXOffset(0);
}, 1200);
},
[setText, setTransformState, siteData]
[setPos, setText, setXOffset, siteData]
);
const initializeLevelSelection = useCallback(() => {
setTransformState(-1, "xOffset");
setXOffset(-1);
setTimeout(() => {
setTransformState(-0.02, "posX");
setTransformState(0.005, "posY");
setPos([-0.02, 0.005, -8.7]);
}, 400);
setTimeout(() => {
@ -121,23 +94,16 @@ const YellowTextManager = (props: StateManagerProps) => {
}, 1000);
setTimeout(() => {
setTransformState(0, "xOffset");
setXOffset(0);
}, 1200);
}, [setColor, setText, setTransformState]);
}, [setColor, setPos, setText, setXOffset]);
const levelSelectionBack = useCallback(
(activeNodeId: string, activeHudId: string, level: string) => {
setTransformState(-1, "xOffset");
setXOffset(-1);
setTimeout(() => {
setTransformState(
node_huds[activeHudId as keyof typeof node_huds].big_text[0],
"posX"
);
setTransformState(
node_huds[activeHudId as keyof typeof node_huds].big_text[1],
"posY"
);
setPos(node_huds[activeHudId as keyof typeof node_huds].big_text);
}, 400);
setTimeout(() => {
@ -146,10 +112,10 @@ const YellowTextManager = (props: StateManagerProps) => {
}, 1000);
setTimeout(() => {
setTransformState(0, "xOffset");
setXOffset(0);
}, 1200);
},
[setColor, setText, setTransformState, siteData]
[setColor, setPos, setText, setXOffset, siteData]
);
const toggleVisibleAfterLevelSelect = useCallback(
@ -157,14 +123,7 @@ const YellowTextManager = (props: StateManagerProps) => {
setVisible(false);
setTimeout(() => {
setTransformState(
node_huds[activeHudId as keyof typeof node_huds].big_text[0],
"posX"
);
setTransformState(
node_huds[activeHudId as keyof typeof node_huds].big_text[1],
"posY"
);
setPos(node_huds[activeHudId as keyof typeof node_huds].big_text[0]);
setColor("yellow");
const targetText =
activeNodeId === "UNKNOWN"
@ -178,7 +137,7 @@ const YellowTextManager = (props: StateManagerProps) => {
setVisible(true);
}, 3900);
},
[setColor, setText, setTransformState, setVisible, siteData]
[setColor, setPos, setText, setVisible, siteData]
);
const dispatchObject = useCallback(
@ -298,4 +257,4 @@ const YellowTextManager = (props: StateManagerProps) => {
return null;
};
export default YellowTextManager;
export default BigTextManager;

View file

@ -1,6 +1,8 @@
import create from "zustand";
import { combine } from "zustand/middleware";
import * as THREE from "three";
import site_a from "./resources/site_a.json";
import site_b from "./resources/site_b.json";
import authorize_user_letters from "./resources/authorize_user_letters.json";
import game_progress from "./resources/initial_progress.json";
@ -239,66 +241,6 @@ export const useMediaBigTextStore = create(
)
);
export const useBigTextStore = create(
combine(
{
visible: true,
color: "yellow",
disableTrail: false,
text: "Tda028",
transformState: {
posX: -0.35,
posY: 0.23,
xOffset: 0,
},
} as BigTextState,
(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,
},
})),
setColor: (to: string) => set(() => ({ color: to })),
setVisible: (to: boolean) => set(() => ({ visible: to })),
})
)
);
export const useGreenTextStore = create(
combine(
{
text: "TOUKO's DIARY",
transformState: {
posX: { initial: 1.18, final: 0.18 },
posY: 0.16,
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) => ({
id: "fg_hud_1",
active: 1,
@ -506,12 +448,162 @@ export const useAuthorizeUserStore = create<AuthorizeUserState>((set) => ({
set(() => ({ activeLetterTextureOffset: to })),
}));
export const useMainSceneStore = create<MainSceneState>((set) => ({
intro: true,
subscene: "site",
setSubscene: (to) => set(() => ({ subscene: to })),
setIntro: (to) => set(() => ({ intro: to })),
}));
export const useMainSceneStore = create(
combine(
{
// game progress
gameProgress: game_progress,
// subscene
subscene: "site",
// whether or not to play the intro anim
intro: true,
// big text (the one that displays node names)
bigText: "Tda028",
bigTextVisible: true,
bigTextColor: "yellow",
bigTextPos: [-0.35, 0.23, 0],
bigTextXOffset: 0,
// hud
hudId: "fg_hud_1",
hudActive: 1,
// nodes
activeNodeId: "0422",
activeNodeMatrixIndices: { matrixIdx: 7, rowIdx: 0, colIdx: 0 },
activeNodePos: [0, 0, 0],
activeNodeRot: [0, 0, 0],
activeNodeState: {
interactedWith: false,
exploding: false,
shrinking: false,
visible: true,
},
// lain
lainMoveState: "standing",
// starfield
mainStarfieldVisible: true,
introStarfieldVisible: false,
mainStarBoostVal: 0.2,
// site
activeSite: "a",
siteRot: [0, 0, 0],
sitePos: [0, 0, 0],
// middle ring
middleRingPos: [0, -0.11, 0],
middleRingRot: [0, 0, 0],
middleRingWobbleAmp: 0,
middleRingNoiseAmp: 0,
middleRingPartSeparatorVal: 1,
middleRingAnimDuration: 600,
middleRingRotating: true,
fakeMiddleRingVisible: false,
// level
activeLevel: "04",
// level selection
selectedLevel: 4,
levelSelectionToggled: 0,
// pause
pauseComponentMatrix: ["load", "about", "change", "save", "exit"],
pauseComponentMatrixIdx: 2,
pauseExitAnimation: false,
} as any,
(set) => ({
// subscene setters
setSubscene: (to: "pause" | "level_selection") =>
set(() => ({ subscene: to })),
// intro setters
setIntro: (to: boolean) => set(() => ({ intro: to })),
// big text setters
setBigText: (to: string) => set(() => ({ bigText: to })),
setBigTextVisible: (to: boolean) => set(() => ({ bigTextVisible: to })),
setBigTextColor: (to: "yellow" | "orange") =>
set(() => ({ bigTextColor: to })),
setBigTextPos: (to: number[]) => set(() => ({ bigTextPos: to })),
setBigTextXOffset: (to: number) => set(() => ({ bigTextXOffset: to })),
// hud setters
setHudId: (to: string) => set(() => ({ hudId: to })),
toggleHudActive: () =>
set((state) => ({ hudActive: Number(!state.hudActive) })),
// node setters
setActiveNodeId: (to: string) => set(() => ({ activeNodeId: to })),
setActiveNodeMatrixIndices: (to: {
matrixIdx: number;
rowIdx: number;
colIdx: number;
}) => set(() => ({ activeNodeMatrixIndices: to })),
setActiveNodePos: (to: number[]) => set(() => ({ activeNodePos: to })),
setActiveNodeRot: (to: number[]) => set(() => ({ activeNodeRot: to })),
setActiveNodeState: (
to: boolean,
at: "interactedWith" | "visible" | "exploding" | "shrinking"
) =>
set((state) => ({
activeNodeState: { ...state.activeNodeState, [at]: to },
})),
// lain setters
setLainMoveState: (to: string) => set(() => ({ lainMoveState: to })),
// starfield setters
setMainStarfieldVisible: (to: boolean) =>
set(() => ({ mainStarfieldVisible: to })),
setMainStarBoostVal: (to: number) =>
set(() => ({ mainStarBoostVal: to })),
setIntroStarfieldVisible: (to: boolean) =>
set(() => ({ introStarfieldVisible: to })),
// site setters
setActiveSite: (to: "a" | "b") => set(() => ({ activeSite: to })),
setSiteRot: (to: number[]) => set(() => ({ siteRot: to })),
setSitePos: (to: number[]) => set(() => ({ sitePos: to })),
// middle ring setters
setMiddleRingPos: (to: number[]) => set(() => ({ middleRingPos: to })),
setMiddleRingRot: (to: number[]) => set(() => ({ middleRingRot: to })),
setMiddleRingWobbleAmp: (to: number) =>
set(() => ({ middleRingWobbleAmp: to })),
setMiddleRingNoiseAmp: (to: number) =>
set(() => ({ middleRingNoiseAmp: to })),
setMiddleRingPartSeparatorVal: (to: number) =>
set(() => ({ middleRingPartSeparatorVal: to })),
setMiddleRingRotating: (to: boolean) =>
set(() => ({ middleRingRotating: to })),
setFakeMiddleRingVisible: (to: boolean) =>
set(() => ({ fakeMiddleRingVisible: to })),
// level setters
setActiveLevel: (to: string) => set(() => ({ activeLevel: to })),
// level selection setters
setSelectedLevel: (to: number) => set(() => ({ selectedLevel: to })),
toggleLevelSelection: () =>
set((state) => ({
levelSelectionToggled: Number(!state.levelSelectionToggled),
})),
// pause setters
setPauseComponentMatrixIdx: (to: number) =>
set(() => ({ pauseComponentMatrixIdx: to })),
setPauseExitAnimation: (to: boolean) =>
set(() => ({ pauseExitAnimation: to })),
})
)
);
export const useBootStore = create(
combine(