feat: add dev diary and ending thumbnails, update chapter endings display
This commit is contained in:
@@ -117,6 +117,43 @@ function endingStatus(endingId: string) {
|
||||
return props.visitedIds.has(props.endings.find(e => e.id === endingId)?.sceneId ?? '')
|
||||
}
|
||||
|
||||
function isKeyMoment(sceneId: string): boolean {
|
||||
const scene = props.scenes[sceneId]
|
||||
if (!scene) return false
|
||||
if (scene.keyMoment !== undefined) return scene.keyMoment
|
||||
if (props.chapters.some(c => c.startScene === sceneId)) return true
|
||||
if (scene.choices && scene.choices.length > 0) return true
|
||||
if (props.endings.some(e => e.sceneId === sceneId)) return true
|
||||
return false
|
||||
}
|
||||
|
||||
function collectKeyTargets(sceneId: string, depth: number, pathSet: Set<string>): string[] {
|
||||
if (depth > 10 || pathSet.has(sceneId)) return []
|
||||
pathSet.add(sceneId)
|
||||
const scene = props.scenes[sceneId]
|
||||
if (!scene) return []
|
||||
if (isKeyMoment(sceneId)) return [sceneId]
|
||||
const results: string[] = []
|
||||
function pushTarget(target: string | undefined) {
|
||||
if (!target) return
|
||||
results.push(...collectKeyTargets(target, depth + 1, pathSet))
|
||||
}
|
||||
if (scene.choices) for (const c of scene.choices) pushTarget(c.targetScene)
|
||||
if (scene.nextScene) {
|
||||
if (Array.isArray(scene.nextScene)) {
|
||||
for (const r of scene.nextScene) pushTarget(r.targetScene)
|
||||
} else {
|
||||
pushTarget(scene.nextScene)
|
||||
}
|
||||
}
|
||||
if (scene.qte) {
|
||||
pushTarget(scene.qte.successScene)
|
||||
pushTarget(scene.qte.failScene)
|
||||
}
|
||||
if (scene.hotspots) for (const h of scene.hotspots) pushTarget(h.targetScene)
|
||||
return results
|
||||
}
|
||||
|
||||
function resolveInitialChapter(): string {
|
||||
const saved = localStorage.getItem('story_chapter')
|
||||
if (saved && props.chapters.some(c => c.id === saved)) return saved
|
||||
@@ -146,21 +183,24 @@ function buildPlayerTree(sceneId: string, chapterId: string, depth: number, path
|
||||
if (scene) {
|
||||
function pushChild(target: string | undefined) {
|
||||
if (!target) return
|
||||
if (isOtherChapterStart(target, chapterId)) {
|
||||
const gatewayCh = props.chapters.find(c => c.startScene === target)
|
||||
children.push({
|
||||
sceneId: '',
|
||||
label: gatewayCh ? (t(gatewayCh.labelKey || gatewayCh.label)) : target,
|
||||
visited: false,
|
||||
locked: !props.unlockedChapterIds.has(gatewayCh?.id ?? ''),
|
||||
children: [],
|
||||
isGateway: true,
|
||||
gatewayChapterId: gatewayCh?.id,
|
||||
})
|
||||
return
|
||||
const keyIds = collectKeyTargets(target, 0, new Set())
|
||||
for (const keyId of keyIds) {
|
||||
if (isOtherChapterStart(keyId, chapterId)) {
|
||||
const gatewayCh = props.chapters.find(c => c.startScene === keyId)
|
||||
children.push({
|
||||
sceneId: '',
|
||||
label: gatewayCh ? (t(gatewayCh.labelKey || gatewayCh.label)) : keyId,
|
||||
visited: false,
|
||||
locked: !props.unlockedChapterIds.has(gatewayCh?.id ?? ''),
|
||||
children: [],
|
||||
isGateway: true,
|
||||
gatewayChapterId: gatewayCh?.id,
|
||||
})
|
||||
} else {
|
||||
const child = buildPlayerTree(keyId, chapterId, depth + 1, pathSet)
|
||||
if (child) children.push(child)
|
||||
}
|
||||
}
|
||||
const child = buildPlayerTree(target, chapterId, depth + 1, pathSet)
|
||||
if (child) children.push(child)
|
||||
}
|
||||
if (scene.choices) {
|
||||
for (const c of scene.choices) pushChild(c.targetScene)
|
||||
|
||||
Reference in New Issue
Block a user