diff --git a/src/Debugger.svelte b/src/Debugger.svelte index c3332890d818fae427839f3cd884f6da227aa755..108c791dbe3d8f1d0c7eaeed0857f642a43320c5 100644 --- a/src/Debugger.svelte +++ b/src/Debugger.svelte @@ -1,6 +1,7 @@ <script lang="ts"> import { gameFactsStore, addGameFactToFactArray, toggleFactInFactArray } from './gameFacts' import type { Dialog, DialogMap, DialogSet } from './types'; + import {findDialogSetProblems} from "./utils" export let currentDialog: Dialog; export let dialogSet: DialogSet; @@ -28,7 +29,16 @@ {dialogName} </option> {/each} - </select> + </select> + <br> + <ol> + {#each findDialogSetProblems(dialogSet) as {sourceDialog, text}} + <li> + {sourceDialog}: <code style="color: orange">{text}</code> + </li> + {/each} + </ol> + <hr> <h3>Quest-Debugger</h3> diff --git a/src/utils.ts b/src/utils.ts index 7cf9d7494388f35c772486ae0b96395104c173a8..f314da677f79367e07a7da4aff646694337f00ea 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,4 @@ -import type { DialogSet } from "./types"; +import type { DialogMap, DialogOption, DialogSet } from "./types"; /** * Returns true, if input is a valid name of a dialogSet. @@ -39,3 +39,58 @@ export async function fetchDialogSet(): Promise<DialogSet> { throw error; } } + +export function findDialogSetProblems(dialogSet: DialogSet) { + const dialogReferenceProblems = checkForInvalidDialogReferences(dialogSet); + return [...dialogReferenceProblems]; +} + +interface DialogReferenceProblem { + type: "DialogReferenceProblem"; + sourceDialog: string; + text: string; +} + +function checkForInvalidDialogReferences( + dialogSet: DialogSet +): DialogReferenceProblem[] { + const dialogs = dialogSet.dialogs; + const problems: DialogReferenceProblem[] = []; + const allDialogKeys = Object.keys(dialogs); + const allLinkedToDialogKeys: Set<string> = new Set(); + for (const dialogName of allDialogKeys) { + // TODO check all buttons for invalid references + for (const { text, linksToDialog } of dialogs[dialogName].options) { + allLinkedToDialogKeys.add(linksToDialog); + if (!allDialogKeys.includes(linksToDialog)) { + problems.push({ + type: "DialogReferenceProblem", + sourceDialog: dialogName, + text: `Dialog ${dialogName}'s option "${text}" links to unknown dialog '${linksToDialog}'`, + }); + } + + if (linksToDialog === dialogName) { + problems.push({ + type: "DialogReferenceProblem", + sourceDialog: dialogName, + text: `Dialog ${dialogName}'s option "${text}" links to itself!`, + }); + } + } + } + + for (const dialogName of allDialogKeys) { + if ( + !allLinkedToDialogKeys.has(dialogName) && + dialogSet.startDialogName !== dialogName + ) { + problems.push({ + type: "DialogReferenceProblem", + sourceDialog: dialogName, + text: `Dialog ${dialogName} is unreachable: Neither linked to from any other dialog, nor startDialog`, + }); + } + } + return problems; +}