connect game progression state to world

This commit is contained in:
Tom Boullay
2026-04-30 14:24:59 +02:00
parent 2696289483
commit 7c7dbdb588
7 changed files with 372 additions and 7 deletions
+179 -5
View File
@@ -1,7 +1,14 @@
import { create } from "zustand";
export type MainGameState = "intro" | "bike" | "pylone" | "ferme" | "outro";
export type MissionStep = "locked" | "inspect" | "repair" | "done";
export type MissionStep =
| "locked"
| "waiting"
| "inspected"
| "fragmented"
| "scanning"
| "repairing"
| "done";
export interface IntroState {
dialogueAudio: string | null;
@@ -39,31 +46,54 @@ interface GameActions {
setPyloneState: (pylone: Partial<GameState["pylone"]>) => void;
setFermeState: (ferme: Partial<GameState["ferme"]>) => void;
setOutroState: (outro: Partial<GameState["outro"]>) => void;
completeIntro: () => void;
completeBike: () => void;
completePylone: () => void;
completeFerme: () => void;
startOutro: () => void;
advanceGameState: () => void;
resetGame: () => void;
}
export type GameStore = GameState & GameActions;
function getNextMissionStep(step: MissionStep): MissionStep {
switch (step) {
case "locked":
case "waiting":
return "inspected";
case "inspected":
return "fragmented";
case "fragmented":
return "scanning";
case "scanning":
return "repairing";
case "repairing":
case "done":
return "done";
}
}
function createInitialGameState(): GameState {
return {
mainState: "intro",
intro: {
dialogueAudio: ""null,
dialogueAudio: null,
hasCompleted: false,
isBikeUnlocked: false,
},
bike: {
currentStep: "locked",
currentStep: "waiting",
dialogueAudio: null,
isRepaired: false,
},
pylone: {
currentStep: "locked",
currentStep: "waiting",
dialogueAudio: null,
isPowered: false,
},
ferme: {
currentStep: "locked",
currentStep: "waiting",
dialogueAudio: null,
irrigationFixed: false,
},
@@ -87,5 +117,149 @@ export const useGameStore = create<GameStore>()((set) => ({
set((state) => ({ ferme: { ...state.ferme, ...ferme } })),
setOutroState: (outro) =>
set((state) => ({ outro: { ...state.outro, ...outro } })),
completeIntro: () =>
set((state) => ({
mainState: "bike",
intro: {
...state.intro,
hasCompleted: true,
isBikeUnlocked: true,
},
bike: {
...state.bike,
currentStep: "inspected",
},
})),
completeBike: () =>
set((state) => ({
mainState: "pylone",
bike: {
...state.bike,
currentStep: "done",
isRepaired: true,
},
pylone: {
...state.pylone,
currentStep: "inspected",
},
})),
completePylone: () =>
set((state) => ({
mainState: "ferme",
pylone: {
...state.pylone,
currentStep: "done",
isPowered: true,
},
ferme: {
...state.ferme,
currentStep: "inspected",
},
})),
completeFerme: () =>
set((state) => ({
mainState: "outro",
ferme: {
...state.ferme,
currentStep: "done",
irrigationFixed: true,
},
outro: {
...state.outro,
hasStarted: true,
},
})),
startOutro: () =>
set((state) => ({
mainState: "outro",
outro: {
...state.outro,
hasStarted: true,
},
})),
advanceGameState: () =>
set((state) => {
if (state.mainState === "intro") {
return {
mainState: "bike",
intro: {
...state.intro,
hasCompleted: true,
isBikeUnlocked: true,
},
bike: {
...state.bike,
currentStep: "inspected",
},
};
}
if (state.mainState === "bike") {
const nextStep = getNextMissionStep(state.bike.currentStep);
if (nextStep === "done") {
return {
mainState: "pylone",
bike: {
...state.bike,
currentStep: "done",
isRepaired: true,
},
pylone: {
...state.pylone,
currentStep: "inspected",
},
};
}
return { bike: { ...state.bike, currentStep: nextStep } };
}
if (state.mainState === "pylone") {
const nextStep = getNextMissionStep(state.pylone.currentStep);
if (nextStep === "done") {
return {
mainState: "ferme",
pylone: {
...state.pylone,
currentStep: "done",
isPowered: true,
},
ferme: {
...state.ferme,
currentStep: "inspected",
},
};
}
return { pylone: { ...state.pylone, currentStep: nextStep } };
}
if (state.mainState === "ferme") {
const nextStep = getNextMissionStep(state.ferme.currentStep);
if (nextStep === "done") {
return {
mainState: "outro",
ferme: {
...state.ferme,
currentStep: "done",
irrigationFixed: true,
},
outro: {
...state.outro,
hasStarted: true,
},
};
}
return { ferme: { ...state.ferme, currentStep: nextStep } };
}
return {
outro: {
...state.outro,
hasStarted: true,
},
};
}),
resetGame: () => set(createInitialGameState()),
}));