refactor: move mission flow state into game store
🔍 Lint / 🪄 Check lint (pull_request) Has been cancelled
🔍 Lint / 🎨 Check format (pull_request) Has been cancelled
🔍 Lint / 🔎 Typecheck (pull_request) Has been cancelled
🔍 Lint / 🏗 Build (pull_request) Has been cancelled
📊 Quality / 🔒 Security Audit (pull_request) Has been cancelled
📊 Quality / 📋 Dependency Freshness (pull_request) Has been cancelled
📊 Quality / 📦 Bundle Size (pull_request) Has been cancelled
🔍 Lint / 🪄 Check lint (pull_request) Has been cancelled
🔍 Lint / 🎨 Check format (pull_request) Has been cancelled
🔍 Lint / 🔎 Typecheck (pull_request) Has been cancelled
🔍 Lint / 🏗 Build (pull_request) Has been cancelled
📊 Quality / 🔒 Security Audit (pull_request) Has been cancelled
📊 Quality / 📋 Dependency Freshness (pull_request) Has been cancelled
📊 Quality / 📦 Bundle Size (pull_request) Has been cancelled
This commit is contained in:
@@ -1,95 +0,0 @@
|
||||
import type { GameStep, GameStepSnapshot } from "@/types/game";
|
||||
import { useMissionFlowStore } from "@/managers/stores/useMissionFlowStore";
|
||||
|
||||
export class GameStepManager {
|
||||
private static _instance: GameStepManager | null = null;
|
||||
|
||||
private _currentStep: GameStep = "intro";
|
||||
private _playerName = "";
|
||||
private _canMove = false;
|
||||
private readonly _listeners = new Set<() => void>();
|
||||
private _cachedSnapshot: GameStepSnapshot | null = null;
|
||||
|
||||
static getInstance(): GameStepManager {
|
||||
if (!GameStepManager._instance) {
|
||||
GameStepManager._instance = new GameStepManager();
|
||||
}
|
||||
|
||||
return GameStepManager._instance;
|
||||
}
|
||||
|
||||
private constructor() {}
|
||||
|
||||
getStep(): GameStep {
|
||||
return this._currentStep;
|
||||
}
|
||||
|
||||
getPlayerName(): string {
|
||||
return this._playerName;
|
||||
}
|
||||
|
||||
canMove(): boolean {
|
||||
return this._canMove;
|
||||
}
|
||||
|
||||
getSnapshot(): GameStepSnapshot {
|
||||
if (!this._cachedSnapshot) {
|
||||
this._cachedSnapshot = {
|
||||
step: this._currentStep,
|
||||
playerName: this._playerName,
|
||||
canMove: this._canMove,
|
||||
transitionTo: this.transitionTo.bind(this),
|
||||
setPlayerName: this.setPlayerName.bind(this),
|
||||
};
|
||||
}
|
||||
return this._cachedSnapshot;
|
||||
}
|
||||
|
||||
transitionTo(step: GameStep): void {
|
||||
if (this._currentStep === step) return;
|
||||
|
||||
this._currentStep = step;
|
||||
this._cachedSnapshot = null;
|
||||
useMissionFlowStore.getState().setStep(step);
|
||||
this._emit();
|
||||
}
|
||||
|
||||
setPlayerName(name: string): void {
|
||||
if (this._playerName === name) return;
|
||||
|
||||
this._playerName = name;
|
||||
this._cachedSnapshot = null;
|
||||
useMissionFlowStore.getState().setPlayerName(name);
|
||||
this._emit();
|
||||
}
|
||||
|
||||
setCanMove(canMove: boolean): void {
|
||||
if (this._canMove === canMove) return;
|
||||
|
||||
this._canMove = canMove;
|
||||
this._cachedSnapshot = null;
|
||||
useMissionFlowStore.getState().setCanMove(canMove);
|
||||
this._emit();
|
||||
}
|
||||
|
||||
subscribe(listener: () => void): () => void {
|
||||
this._listeners.add(listener);
|
||||
|
||||
return () => {
|
||||
this._listeners.delete(listener);
|
||||
};
|
||||
}
|
||||
|
||||
destroy(): void {
|
||||
this._currentStep = "intro";
|
||||
this._playerName = "";
|
||||
this._canMove = false;
|
||||
this._listeners.clear();
|
||||
this._cachedSnapshot = null;
|
||||
GameStepManager._instance = null;
|
||||
}
|
||||
|
||||
private _emit(): void {
|
||||
this._listeners.forEach((cb) => cb());
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { create } from "zustand";
|
||||
import type { GameStep } from "@/types/game";
|
||||
import {
|
||||
isRepairMissionId,
|
||||
type MissionStep,
|
||||
@@ -19,9 +20,18 @@ interface MissionState {
|
||||
dialogueAudio: string | null;
|
||||
}
|
||||
|
||||
interface MissionFlowState {
|
||||
activityCity: boolean;
|
||||
canMove: boolean;
|
||||
dialogMessage: string | null;
|
||||
playerName: string;
|
||||
step: GameStep;
|
||||
}
|
||||
|
||||
interface GameState {
|
||||
mainState: MainGameState;
|
||||
isCinematicPlaying: boolean;
|
||||
missionFlow: MissionFlowState;
|
||||
intro: IntroState;
|
||||
bike: MissionState & {
|
||||
isRepaired: boolean;
|
||||
@@ -41,7 +51,12 @@ interface GameState {
|
||||
interface GameActions {
|
||||
setMainState: (mainState: MainGameState) => void;
|
||||
setCinematicPlaying: (isCinematicPlaying: boolean) => void;
|
||||
hideDialog: () => void;
|
||||
setActivityCity: (activityCity: boolean) => void;
|
||||
setCanMove: (canMove: boolean) => void;
|
||||
setFlowStep: (step: GameStep) => void;
|
||||
setIntroState: (intro: Partial<IntroState>) => void;
|
||||
setPlayerName: (playerName: string) => void;
|
||||
setBikeState: (bike: Partial<GameState["bike"]>) => void;
|
||||
setPyloneState: (pylone: Partial<GameState["pylone"]>) => void;
|
||||
setFermeState: (ferme: Partial<GameState["ferme"]>) => void;
|
||||
@@ -56,6 +71,7 @@ interface GameActions {
|
||||
advanceGameState: () => void;
|
||||
rewindGameState: () => void;
|
||||
resetGame: () => void;
|
||||
showDialog: (dialogMessage: string) => void;
|
||||
}
|
||||
|
||||
type GameStore = GameState & GameActions;
|
||||
@@ -225,6 +241,13 @@ function createInitialGameState(): GameState {
|
||||
return {
|
||||
mainState: "intro",
|
||||
isCinematicPlaying: false,
|
||||
missionFlow: {
|
||||
activityCity: true,
|
||||
canMove: false,
|
||||
dialogMessage: null,
|
||||
playerName: "",
|
||||
step: "intro",
|
||||
},
|
||||
intro: {
|
||||
dialogueAudio: null,
|
||||
hasCompleted: false,
|
||||
@@ -256,8 +279,26 @@ export const useGameStore = create<GameStore>()((set) => ({
|
||||
...createInitialGameState(),
|
||||
setMainState: (mainState) => set({ mainState }),
|
||||
setCinematicPlaying: (isCinematicPlaying) => set({ isCinematicPlaying }),
|
||||
hideDialog: () =>
|
||||
set((state) => ({
|
||||
missionFlow: { ...state.missionFlow, dialogMessage: null },
|
||||
})),
|
||||
setActivityCity: (activityCity) =>
|
||||
set((state) => ({
|
||||
missionFlow: { ...state.missionFlow, activityCity },
|
||||
})),
|
||||
setCanMove: (canMove) =>
|
||||
set((state) => ({
|
||||
missionFlow: { ...state.missionFlow, canMove },
|
||||
})),
|
||||
setFlowStep: (step) =>
|
||||
set((state) => ({ missionFlow: { ...state.missionFlow, step } })),
|
||||
setIntroState: (intro) =>
|
||||
set((state) => ({ intro: { ...state.intro, ...intro } })),
|
||||
setPlayerName: (playerName) =>
|
||||
set((state) => ({
|
||||
missionFlow: { ...state.missionFlow, playerName },
|
||||
})),
|
||||
setBikeState: (bike) =>
|
||||
set((state) => ({ bike: { ...state.bike, ...bike } })),
|
||||
setPyloneState: (pylone) =>
|
||||
@@ -300,4 +341,8 @@ export const useGameStore = create<GameStore>()((set) => ({
|
||||
return { outro: { ...state.outro, hasStarted: false } };
|
||||
}),
|
||||
resetGame: () => set(createInitialGameState()),
|
||||
showDialog: (dialogMessage) =>
|
||||
set((state) => ({
|
||||
missionFlow: { ...state.missionFlow, dialogMessage },
|
||||
})),
|
||||
}));
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
import { create } from "zustand";
|
||||
import type { GameStep } from "@/types/game";
|
||||
|
||||
interface MissionFlowState {
|
||||
activityCity: boolean;
|
||||
canMove: boolean;
|
||||
dialogMessage: string | null;
|
||||
playerName: string;
|
||||
step: GameStep;
|
||||
}
|
||||
|
||||
interface MissionFlowActions {
|
||||
hideDialog: () => void;
|
||||
setActivityCity: (value: boolean) => void;
|
||||
setCanMove: (canMove: boolean) => void;
|
||||
setPlayerName: (name: string) => void;
|
||||
setStep: (step: GameStep) => void;
|
||||
showDialog: (message: string) => void;
|
||||
}
|
||||
|
||||
export const useMissionFlowStore = create<
|
||||
MissionFlowState & MissionFlowActions
|
||||
>((set) => ({
|
||||
activityCity: true,
|
||||
canMove: false,
|
||||
dialogMessage: null,
|
||||
playerName: "",
|
||||
step: "intro",
|
||||
hideDialog: () => set({ dialogMessage: null }),
|
||||
setActivityCity: (activityCity) => set({ activityCity }),
|
||||
setCanMove: (canMove) => set({ canMove }),
|
||||
setPlayerName: (playerName) => set({ playerName }),
|
||||
setStep: (step) => set({ step }),
|
||||
showDialog: (dialogMessage) => set({ dialogMessage }),
|
||||
}));
|
||||
Reference in New Issue
Block a user