diff --git a/src/components/MainScene/SyncedComponents/HUD.tsx b/src/components/MainScene/SyncedComponents/HUD.tsx index f0d477f..f9864ef 100644 --- a/src/components/MainScene/SyncedComponents/HUD.tsx +++ b/src/components/MainScene/SyncedComponents/HUD.tsx @@ -67,7 +67,6 @@ const HUD = () => { ] ); - console.log('called') const longHudTex = useLoader(THREE.TextureLoader, longHud); const longHudMirroredTex = useLoader(THREE.TextureLoader, longHudMirrored); diff --git a/src/components/TextRenderer/BigLetter.tsx b/src/components/TextRenderer/BigLetter.tsx index ea58277..6b2d20b 100644 --- a/src/components/TextRenderer/BigLetter.tsx +++ b/src/components/TextRenderer/BigLetter.tsx @@ -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 ( { > { 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 ( { - 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 ( - {disableTrail - ? textArrRef.current.map((letter, idx) => ( - - - - )) - : trail.map(({ posX, posY }, idx) => ( - - - - ))} + {trail.map(({ posX, posY }, idx) => ( + + + + ))} ); }; diff --git a/src/core/StateManagers/EventManager.tsx b/src/core/StateManagers/EventManager.tsx index d479d93..8d5439e 100644 --- a/src/core/StateManagers/EventManager.tsx +++ b/src/core/StateManagers/EventManager.tsx @@ -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 = () => { - + diff --git a/src/core/StateManagers/GameManagers/GameLoader.tsx b/src/core/StateManagers/GameManagers/GameLoader.tsx index 787de9e..1265e01 100644 --- a/src/core/StateManagers/GameManagers/GameLoader.tsx +++ b/src/core/StateManagers/GameManagers/GameLoader.tsx @@ -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, ] diff --git a/src/core/StateManagers/MainSceneEventManager.tsx b/src/core/StateManagers/MainSceneEventManager.tsx index 71a12c1..b1b2436 100644 --- a/src/core/StateManagers/MainSceneEventManager.tsx +++ b/src/core/StateManagers/MainSceneEventManager.tsx @@ -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) => { - + diff --git a/src/core/StateManagers/MainSceneManagers/YellowTextManager.tsx b/src/core/StateManagers/MainSceneManagers/BigTextManager.tsx similarity index 67% rename from src/core/StateManagers/MainSceneManagers/YellowTextManager.tsx rename to src/core/StateManagers/MainSceneManagers/BigTextManager.tsx index 4eeafbb..f5781ba 100644 --- a/src/core/StateManagers/MainSceneManagers/YellowTextManager.tsx +++ b/src/core/StateManagers/MainSceneManagers/BigTextManager.tsx @@ -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; diff --git a/src/store.ts b/src/store.ts index b1a3dcd..02f804d 100644 --- a/src/store.ts +++ b/src/store.ts @@ -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((set) => ({ id: "fg_hud_1", active: 1, @@ -506,12 +448,162 @@ export const useAuthorizeUserStore = create((set) => ({ set(() => ({ activeLetterTextureOffset: to })), })); -export const useMainSceneStore = create((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(