From 269628948330a6e9af98a930ab62f9a7932a1293 Mon Sep 17 00:00:00 2001 From: Tom Boullay Date: Thu, 30 Apr 2026 14:04:01 +0200 Subject: [PATCH] add zustand game progression store --- package-lock.json | 3 +- package.json | 3 +- src/managers/stores/useGameStore.ts | 91 +++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 src/managers/stores/useGameStore.ts diff --git a/package-lock.json b/package-lock.json index aa6d43a..a417dbf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,7 +21,8 @@ "react-dom": "^19.2.4", "react-markdown": "^10.1.0", "remark-gfm": "^4.0.1", - "three": "^0.183.2" + "three": "^0.183.2", + "zustand": "^5.0.12" }, "devDependencies": { "@eslint/js": "^9.39.4", diff --git a/package.json b/package.json index e9c0ac5..00d7630 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,8 @@ "react-dom": "^19.2.4", "react-markdown": "^10.1.0", "remark-gfm": "^4.0.1", - "three": "^0.183.2" + "three": "^0.183.2", + "zustand": "^5.0.12" }, "devDependencies": { "@eslint/js": "^9.39.4", diff --git a/src/managers/stores/useGameStore.ts b/src/managers/stores/useGameStore.ts new file mode 100644 index 0000000..6d0e8fd --- /dev/null +++ b/src/managers/stores/useGameStore.ts @@ -0,0 +1,91 @@ +import { create } from "zustand"; + +export type MainGameState = "intro" | "bike" | "pylone" | "ferme" | "outro"; +export type MissionStep = "locked" | "inspect" | "repair" | "done"; + +export interface IntroState { + dialogueAudio: string | null; + hasCompleted: boolean; + isBikeUnlocked: boolean; +} + +export interface MissionState { + currentStep: MissionStep; + dialogueAudio: string | null; +} + +export interface GameState { + mainState: MainGameState; + intro: IntroState; + bike: MissionState & { + isRepaired: boolean; + }; + pylone: MissionState & { + isPowered: boolean; + }; + ferme: MissionState & { + irrigationFixed: boolean; + }; + outro: { + dialogueAudio: string | null; + hasStarted: boolean; + }; +} + +interface GameActions { + setMainState: (mainState: MainGameState) => void; + setIntroState: (intro: Partial) => void; + setBikeState: (bike: Partial) => void; + setPyloneState: (pylone: Partial) => void; + setFermeState: (ferme: Partial) => void; + setOutroState: (outro: Partial) => void; + resetGame: () => void; +} + +export type GameStore = GameState & GameActions; + +function createInitialGameState(): GameState { + return { + mainState: "intro", + intro: { + dialogueAudio: ""null, + hasCompleted: false, + isBikeUnlocked: false, + }, + bike: { + currentStep: "locked", + dialogueAudio: null, + isRepaired: false, + }, + pylone: { + currentStep: "locked", + dialogueAudio: null, + isPowered: false, + }, + ferme: { + currentStep: "locked", + dialogueAudio: null, + irrigationFixed: false, + }, + outro: { + dialogueAudio: null, + hasStarted: false, + }, + }; +} + +export const useGameStore = create()((set) => ({ + ...createInitialGameState(), + setMainState: (mainState) => set({ mainState }), + setIntroState: (intro) => + set((state) => ({ intro: { ...state.intro, ...intro } })), + setBikeState: (bike) => + set((state) => ({ bike: { ...state.bike, ...bike } })), + setPyloneState: (pylone) => + set((state) => ({ pylone: { ...state.pylone, ...pylone } })), + setFermeState: (ferme) => + set((state) => ({ ferme: { ...state.ferme, ...ferme } })), + setOutroState: (outro) => + set((state) => ({ outro: { ...state.outro, ...outro } })), + resetGame: () => set(createInitialGameState()), +}));