address zustand progression review feedback

This commit is contained in:
Tom Boullay
2026-04-30 14:59:41 +02:00
parent 8884edb281
commit a14f776e5d
2 changed files with 88 additions and 115 deletions
+6 -1
View File
@@ -44,10 +44,15 @@ export function GameStateHUD(): React.JSX.Element | null {
<p className="game-state-hud__detail">Sub state: {detail}</p> <p className="game-state-hud__detail">Sub state: {detail}</p>
<div className="game-state-hud__states" aria-label="Main states"> <div
className="game-state-hud__states"
aria-label="Main states"
role="group"
>
{MAIN_STATES.map((state) => ( {MAIN_STATES.map((state) => (
<button <button
key={state} key={state}
aria-pressed={state === mainState}
className={state === mainState ? "is-active" : undefined} className={state === mainState ? "is-active" : undefined}
type="button" type="button"
onClick={() => setMainState(state)} onClick={() => setMainState(state)}
+82 -114
View File
@@ -56,10 +56,12 @@ interface GameActions {
} }
export type GameStore = GameState & GameActions; export type GameStore = GameState & GameActions;
type GameStateUpdate = Partial<GameState>;
function getNextMissionStep(step: MissionStep): MissionStep { function getNextMissionStep(step: MissionStep): MissionStep {
switch (step) { switch (step) {
case "locked": case "locked":
return "waiting";
case "waiting": case "waiting":
return "inspected"; return "inspected";
case "inspected": case "inspected":
@@ -74,6 +76,76 @@ function getNextMissionStep(step: MissionStep): MissionStep {
} }
} }
function completeIntroState(state: GameState): GameStateUpdate {
return {
mainState: "bike",
intro: {
...state.intro,
hasCompleted: true,
isBikeUnlocked: true,
},
bike: {
...state.bike,
currentStep: "waiting",
},
};
}
function completeBikeState(state: GameState): GameStateUpdate {
return {
mainState: "pylone",
bike: {
...state.bike,
currentStep: "done",
isRepaired: true,
},
pylone: {
...state.pylone,
currentStep: "waiting",
},
};
}
function completePyloneState(state: GameState): GameStateUpdate {
return {
mainState: "ferme",
pylone: {
...state.pylone,
currentStep: "done",
isPowered: true,
},
ferme: {
...state.ferme,
currentStep: "waiting",
},
};
}
function completeFermeState(state: GameState): GameStateUpdate {
return {
mainState: "outro",
ferme: {
...state.ferme,
currentStep: "done",
irrigationFixed: true,
},
outro: {
...state.outro,
hasStarted: true,
},
};
}
function startOutroState(state: GameState): GameStateUpdate {
return {
mainState: "outro",
outro: {
...state.outro,
hasStarted: true,
},
};
}
function createInitialGameState(): GameState { function createInitialGameState(): GameState {
return { return {
mainState: "intro", mainState: "intro",
@@ -117,98 +189,21 @@ export const useGameStore = create<GameStore>()((set) => ({
set((state) => ({ ferme: { ...state.ferme, ...ferme } })), set((state) => ({ ferme: { ...state.ferme, ...ferme } })),
setOutroState: (outro) => setOutroState: (outro) =>
set((state) => ({ outro: { ...state.outro, ...outro } })), set((state) => ({ outro: { ...state.outro, ...outro } })),
completeIntro: () => completeIntro: () => set(completeIntroState),
set((state) => ({ completeBike: () => set(completeBikeState),
mainState: "bike", completePylone: () => set(completePyloneState),
intro: { completeFerme: () => set(completeFermeState),
...state.intro, startOutro: () => set(startOutroState),
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: () => advanceGameState: () =>
set((state) => { set((state) => {
if (state.mainState === "intro") { if (state.mainState === "intro") {
return { return completeIntroState(state);
mainState: "bike",
intro: {
...state.intro,
hasCompleted: true,
isBikeUnlocked: true,
},
bike: {
...state.bike,
currentStep: "inspected",
},
};
} }
if (state.mainState === "bike") { if (state.mainState === "bike") {
const nextStep = getNextMissionStep(state.bike.currentStep); const nextStep = getNextMissionStep(state.bike.currentStep);
if (nextStep === "done") { if (nextStep === "done") {
return { return completeBikeState(state);
mainState: "pylone",
bike: {
...state.bike,
currentStep: "done",
isRepaired: true,
},
pylone: {
...state.pylone,
currentStep: "inspected",
},
};
} }
return { bike: { ...state.bike, currentStep: nextStep } }; return { bike: { ...state.bike, currentStep: nextStep } };
@@ -217,18 +212,7 @@ export const useGameStore = create<GameStore>()((set) => ({
if (state.mainState === "pylone") { if (state.mainState === "pylone") {
const nextStep = getNextMissionStep(state.pylone.currentStep); const nextStep = getNextMissionStep(state.pylone.currentStep);
if (nextStep === "done") { if (nextStep === "done") {
return { return completePyloneState(state);
mainState: "ferme",
pylone: {
...state.pylone,
currentStep: "done",
isPowered: true,
},
ferme: {
...state.ferme,
currentStep: "inspected",
},
};
} }
return { pylone: { ...state.pylone, currentStep: nextStep } }; return { pylone: { ...state.pylone, currentStep: nextStep } };
@@ -237,29 +221,13 @@ export const useGameStore = create<GameStore>()((set) => ({
if (state.mainState === "ferme") { if (state.mainState === "ferme") {
const nextStep = getNextMissionStep(state.ferme.currentStep); const nextStep = getNextMissionStep(state.ferme.currentStep);
if (nextStep === "done") { if (nextStep === "done") {
return { return completeFermeState(state);
mainState: "outro",
ferme: {
...state.ferme,
currentStep: "done",
irrigationFixed: true,
},
outro: {
...state.outro,
hasStarted: true,
},
};
} }
return { ferme: { ...state.ferme, currentStep: nextStep } }; return { ferme: { ...state.ferme, currentStep: nextStep } };
} }
return { return startOutroState(state);
outro: {
...state.outro,
hasStarted: true,
},
};
}), }),
resetGame: () => set(createInitialGameState()), resetGame: () => set(createInitialGameState()),
})); }));