feat: add progression logic for puzzle residences
- Implemented functions to manage puzzle progress including checking if residences are started, complete, and unlocked. - Added utility functions to retrieve piece IDs based on residence and route. - Introduced a new TypeScript file for progression management. - Integrated puzzle data configuration and residence data for seamless progression tracking.
This commit is contained in:
1 parent
5a1c3cc368
commit
284302341c
72 files changed
+1104
-517
No files matched your search
@@ -0,0 +1,79 @@
|
||||
import { puzzleDataConfig } from './puzzleData'
|
||||
import { PUZZLE_RESIDENCES } from './puzzleResidences'
|
||||
|
||||
export type PuzzleProgress = Record<string, Set<number>>
|
||||
|
||||
const getResidenceIndex = (residence: string) =>
|
||||
PUZZLE_RESIDENCES.findIndex((item) => item.residence === residence)
|
||||
|
||||
const getConfiguredPieceIds = (residence: string) => {
|
||||
const pieces = puzzleDataConfig[residence]
|
||||
if (!pieces) return []
|
||||
return Object.keys(pieces).map(Number)
|
||||
}
|
||||
|
||||
const arePiecesUnlocked = (residence: string, puzzles: PuzzleProgress, pieceIds: number[]) => {
|
||||
if (pieceIds.length === 0) return false
|
||||
const unlockedPieces = puzzles[residence]
|
||||
if (!unlockedPieces) return false
|
||||
return pieceIds.every((pieceId) => unlockedPieces.has(pieceId))
|
||||
}
|
||||
|
||||
export const isResidenceStarted = (residence: string, puzzles: PuzzleProgress) => {
|
||||
return (puzzles[residence]?.size ?? 0) > 0
|
||||
}
|
||||
|
||||
export const isResidenceComplete = (residence: string, puzzles: PuzzleProgress) => {
|
||||
return arePiecesUnlocked(residence, puzzles, getConfiguredPieceIds(residence))
|
||||
}
|
||||
|
||||
export const isResidenceUnlocked = (residence: string, puzzles: PuzzleProgress) => {
|
||||
const index = getResidenceIndex(residence)
|
||||
if (index === 0) return true
|
||||
if (index < 0) return false
|
||||
|
||||
const previousResidence = PUZZLE_RESIDENCES[index - 1]
|
||||
if (!previousResidence) return false
|
||||
return isResidenceComplete(previousResidence.residence, puzzles)
|
||||
}
|
||||
|
||||
export const isMenuModuleUnlocked = (moduleName: string, puzzles: PuzzleProgress) => {
|
||||
return PUZZLE_RESIDENCES.some(
|
||||
(item) => item.moduleName === moduleName && isResidenceUnlocked(item.residence, puzzles)
|
||||
)
|
||||
}
|
||||
|
||||
export const isMenuModuleStarted = (moduleName: string, puzzles: PuzzleProgress) => {
|
||||
return PUZZLE_RESIDENCES.some(
|
||||
(item) => item.moduleName === moduleName && isResidenceStarted(item.residence, puzzles)
|
||||
)
|
||||
}
|
||||
|
||||
export const isMenuModuleComplete = (moduleName: string, puzzles: PuzzleProgress) => {
|
||||
const residences = PUZZLE_RESIDENCES.filter((item) => item.moduleName === moduleName)
|
||||
if (residences.length === 0) return false
|
||||
return residences.every((item) => isResidenceComplete(item.residence, puzzles))
|
||||
}
|
||||
|
||||
const getPieceIdsByRoute = (residence: string, routePrefix: string) => {
|
||||
const pieces = puzzleDataConfig[residence]
|
||||
if (!pieces) return []
|
||||
|
||||
return Object.entries(pieces)
|
||||
.filter(([, piece]) => piece.route.startsWith(routePrefix))
|
||||
.map(([pieceId]) => Number(pieceId))
|
||||
}
|
||||
|
||||
export const getResidenceStageUnlocks = (residence: string, puzzles: PuzzleProgress) => {
|
||||
const residenceUnlocked = isResidenceUnlocked(residence, puzzles)
|
||||
|
||||
return {
|
||||
dialogueUnlocked: residenceUnlocked,
|
||||
reflectionUnlocked:
|
||||
residenceUnlocked &&
|
||||
arePiecesUnlocked(residence, puzzles, getPieceIdsByRoute(residence, 'place')),
|
||||
internalizationUnlocked:
|
||||
residenceUnlocked &&
|
||||
arePiecesUnlocked(residence, puzzles, getPieceIdsByRoute(residence, 'reflection')),
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user