Skip to content
Snippets Groups Projects
Commit 89470950 authored by Jonas Zohren's avatar Jonas Zohren :speech_balloon:
Browse files

Added moar stuff

parent 60ffa253
No related branches found
No related tags found
No related merge requests found
......@@ -909,6 +909,11 @@
}
}
},
"svelte-local-storage-store": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/svelte-local-storage-store/-/svelte-local-storage-store-0.1.4.tgz",
"integrity": "sha512-XlSJqMdV1UAROsKHYQSKwI9xU0u8En/nQ6ti2flmUhBA0PM+oqXjvCyM2849ONb5JbrpyUO18CwXcSJgxYCR8w=="
},
"svelte-preprocess": {
"version": "4.6.9",
"resolved": "https://registry.npmjs.org/svelte-preprocess/-/svelte-preprocess-4.6.9.tgz",
......
......@@ -26,6 +26,7 @@
"typescript": "^4.0.0"
},
"dependencies": {
"sirv-cli": "^1.0.0"
"sirv-cli": "^1.0.0",
"svelte-local-storage-store": "^0.1.4"
}
}
{
"title": "Frank Thorsten Breuer – Studienkoordinator",
"imageUrl": "./Breuer_Frank_Thorsten.jpg",
"startDialogName": "start",
"dialogs": {
"start": {
"title": "Frank Thorsten Breuer – Studienkoordinator",
"imageUrl": "./Breuer_Frank_Thorsten.jpg",
"text": "Hallo, kann ich etwas für sie tun?",
"text": "",
"options": [
{
"text": "Hallo Herr Breuer, ich grüße sie recht herzlich!",
"linksToDialog": "greetBreuer"
},
{
"text": "Geht es ihnen gut? Sie sehen etwas bleich aus.",
"linksToDialog": "mayIBringSomething",
"forbiddenFacts": ["acceptedFtbMateQuest"]
},
{
"text": "Ich habe ihnen ihre Mate gebracht!",
"linksToDialog": "giveMate",
"requiredFacts": ["collectedFtbMate"],
"forbiddenFacts": ["completedFtbMateQuest"]
},
{
"text": "Hallo, ich suche den Hörsaal E23",
"forbiddenFacts": ["askedFtbForHs"],
"linksToDialog": "seekHS"
}
]
},
"mayIBringSomething": {
"text": "Oh ja!\nIch verdurste fast, könnten sie mir eine Mate bringen?\nIch kann hier leider erstmal nicht weg und das selbst tun, zu viel Arbeit...",
"options": [
{
"text": "Klar, warum nicht.",
"linksToDialog": "acceptFtbMateQuest"
},
{
"text": "Danke, kein Interesse",
"linksToDialog": "rejectFtbMateQuest"
}
]
},
"giveMate": {
"text": "Ah, das tut gut. Vielen Dank, das war jetzt nötig. Sie haben was gut bei mir.",
"addFacts": ["completedFtbMateQuest"],
"options": [
{
"text": "Gern geschehen.",
"linksToDialog": "start"
}
]
},
"acceptFtbMateQuest": {
"text": "Ich danke ihnen. Der Kiosk ist direkt links, wenn sie in den Fachschaftsflur kommen. Das ist der Gang auf rechten Seite von der Eingangstür.",
"addFacts": ["acceptedFtbMateQuest"],
"options": [
{
"text": "Ok",
"linksToDialog": "start"
}
]
},
"rejectFtbMateQuest": {
"text": "Schade. Sollten sie sich noch umentscheiden, melden sie sich gerne bei mir.",
"options": [
{
"text": "Ok",
"linksToDialog": "start"
}
]
},
"seekHS": {
"title": "Frank Thorsten Breuer – Studienkoordinator",
"imageUrl": "./Breuer_Frank_Thorsten.jpg",
"text": "Da müssen sie den Flur wieder zurück gehen und im Foyer nach hinten durchgehen. Den Hörsaal erkennen sie an der großen Doppeltür",
"options": []
"addFacts": ["askedFtbForHs"],
"options": [
{
"text": "Ah, danke",
"linksToDialog": "start"
}
]
},
"greetBreuer": {
"title": "Frank Thorsten Breuer – Studienkoordinator",
"imageUrl": "./Breuer_Frank_Thorsten.jpg",
"text": "Ich grüße sie auch recht herzlich, studieren sie zufälligerweise Informatik?",
"options": [
{
......@@ -38,29 +94,22 @@
]
},
"longTimeStudent": {
"title": "Frank Thorsten Breuer – Studienkoordinator",
"imageUrl": "./Breuer_Frank_Thorsten.jpg",
"text": "Dann sollten sie mal schnell weiter studieren gehen!",
"options": []
},
"startedToStudy": {
"title": "Frank Thorsten Breuer – Studienkoordinator",
"imageUrl": "./Breuer_Frank_Thorsten.jpg",
"text": "Wunderbar, ich kann deine, verzeihung, ich darf sie doch duzen, oder?\\n\\nAlso ich brauche deine Hilfe. Der Studiengang Informatik muss regelmäßig akkreditiert werden, damit wir ihn weiter anbieten dürfen. Jetzt haben leider die verdammten Studenten von der Fachschaft in den letzten genehnmigten Studienplan das Modul \"Angewandte Chaostheorie\" hineingeschmuggelt. Das ist bei uns leider niemanden aufgefallen, der Akkreditierungskommission vom Bildungsministerium aber schon. Wenn wir nicht bald nachweisen können, dass jemand dieses Modul auch belegt und erfolgreich abgeschlossen hat, wird uns die Akkreditierung entzogen und der Informatik-Studiengang muss eingestellt werden. Ich bitte sie, helfen sie mir!",
"text": "Wunderbar, ich kann deine, verzeihung, ich darf sie doch duzen, oder?\nAlso ich brauche deine Hilfe. Der Studiengang Informatik muss regelmäßig akkreditiert werden, damit wir ihn weiter anbieten dürfen. Jetzt haben leider die verdammten Studenten von der Fachschaft in den letzten genehnmigten Studienplan das Modul \"Angewandte Chaostheorie\" hineingeschmuggelt. Das ist bei uns leider niemanden aufgefallen, der Akkreditierungskommission vom Bildungsministerium aber schon. Wenn wir nicht bald nachweisen können, dass jemand dieses Modul auch belegt und erfolgreich abgeschlossen hat, wird uns die Akkreditierung entzogen und der Informatik-Studiengang muss eingestellt werden. Ich bitte sie, helfen sie mir!",
"addFacts": ["acceptedMainQuest"],
"options": [
{ "text": "Ich helfe gerne!", "linksToDialog": "agreeToHelp" },
{ "text": "Was geht mich das denn an?", "linksToDialog": "denyHelp" }
]
},
"denyHelp": {
"title": "Frank Thorsten Breuer – Studienkoordinator",
"imageUrl": "./Breuer_Frank_Thorsten.jpg",
"text": "Schade, ich dachte sie hätten das Zeug dazu. Nun gut, gehen sie studieren, ich finde schon selbst eine Lösung.",
"options": []
},
"agreeToHelp": {
"title": "Frank Thorsten Breuer – Studienkoordinator",
"imageUrl": "./Breuer_Frank_Thorsten.jpg",
"text": "Wunderbar, sobald mehr Story geschrieben wurde, erhalten sie hier eine epische Quest um die Fakultät vor Schmach und Schande zu retten.",
"options": []
}
......
......@@ -5,7 +5,7 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>OH14 Workadventure Story</title>
<title>OH14 Work Adventure Story</title>
<link rel="icon" type="image/png" href="./favicon.png" />
<link rel="stylesheet" href="./global.css" />
......
<script lang="ts">
import DialogSetComponent from "./DialogSetComponent.svelte";
import { fetchDialogSet } from "./utils";
import Debugger from "./Debugger.svelte";
import type { Dialog } from "./types";
const dialogSetPromise = fetchDialogSet();
let currentDialog: Dialog;
</script>
<main>
{#await dialogSetPromise then dialogSet}
<DialogSetComponent {...dialogSet} />
{:catch error}
<DialogSetComponent bind:currentDialog={currentDialog} {...dialogSet} />
<br>
<Debugger dialogSet={dialogSet} bind:currentDialog={currentDialog}/>
{:catch _error}
<h3>Oh no :(</h3>
<p>
We could not load that dialogSet that you specified in the url. Sorry.
We could not load that dialogSet that you specified in the url. Sorry. Please go complain to your friendly admin(s).
</p>
{/await}
</main>
<script lang="ts">
import { gameFactsStore, addGameFactToFactArray, toggleFactInFactArray } from './gameFacts'
import type { Dialog, DialogMap, DialogSet, FactId } from './types';
export let currentDialog: Dialog;
export let dialogSet: DialogSet;
$: dialogNames = Object.keys(dialogSet.dialogs)
export let selectedDialogName: string
function getDialogFacts(dialogMap: DialogMap): FactId[] {
const dialogs = [];
for (const dmKey of Object.keys(dialogMap)) dialogs.push(dialogMap[dmKey]);
return dialogs.map(dialog => [...(dialog.addFacts || []), ...(dialog.removeFacts || [])]).flat()
}
let seenFactIds = new Set<FactId>([...$gameFactsStore, ...getDialogFacts(dialogSet.dialogs)]);
$: seenFactIdsArray = Array.from(seenFactIds)
let addFactInputValue: string;
</script>
<div>
<h3>Dialog-Debugger</h3>
Jump to dialog:
<!-- svelte-ignore a11y-no-onchange -->
<select bind:value={selectedDialogName} on:change="{() => currentDialog = dialogSet.dialogs[selectedDialogName]}">
{#each dialogNames as dialogName}
<option value={dialogName} selected={dialogName === selectedDialogName}>
{dialogName}
</option>
{/each}
</select>
<hr>
<h3>Quest-Debugger</h3>
<b>GameFacts:</b>
<ul>
{#each seenFactIdsArray as gameFact}
<li>
<input type="checkbox" checked={$gameFactsStore.includes(gameFact)} on:change={() => gameFactsStore.set(toggleFactInFactArray(gameFact, $gameFactsStore))}>
{gameFact}
</li>
{/each}
</ul>
Add fact:
<input type="text" bind:value={addFactInputValue}>
<button style="width: 3rem;" on:click={() => {
gameFactsStore.set(addGameFactToFactArray(addFactInputValue, $gameFactsStore));
seenFactIds = seenFactIds.add(addFactInputValue);
addFactInputValue = '';
}}>Add</button>
</div>
<style>
div {
border: 1px solid;
padding: 10px;
margin: 5px;
}
</style>
\ No newline at end of file
<script lang="ts">
import SingleDialogComponent from "./SingleDialogComponent.svelte";
import type { DialogMap } from "./types";
export let title: string;
export let imageUrl: string;
export let startDialogName: string;
export let dialogs: DialogMap;
let currentDialog = dialogs[startDialogName];
export let currentDialog = dialogs[startDialogName];
function switchDialog(targetDialog: string) {
currentDialog = dialogs[targetDialog];
......@@ -19,6 +21,6 @@
</script>
<SingleDialogComponent
{...currentDialog}
imageUrl={imageUrl} title={title} {...currentDialog}
on:switchToDialog={(event) => switchDialog(event.detail)}
/>
<script lang="ts">
import type { DialogOption } from "./types";
import type { DialogOption, FactId } from "./types";
import { createEventDispatcher } from "svelte";
import { gameFactsStore, addGameFactToFactArray } from './gameFacts'
const dispatch = createEventDispatcher();
export let imageUrl: string;
export let title: string | undefined;
export let text: string;
export let options: DialogOption[];
export let options: DialogOption[] = [];
$: usableOptions = options.filter(option => isDialogOptionAllowedByGameFacts(option, $gameFactsStore))
export let addFacts: FactId[] = [];
$: {
if (Array.isArray(addFacts)) {
const gameFactsAfterAddedFacts = addFacts.reduce((accFacts, factToAdd) => addGameFactToFactArray(factToAdd, accFacts), $gameFactsStore)
$gameFactsStore = gameFactsAfterAddedFacts;
}
}
export let removeFacts: FactId[] = [];
$: {
if (Array.isArray(removeFacts)) {
const gameFactsAfterRemovedFacts = removeFacts.reduce((accFacts, factToRemove) => accFacts.filter(f => f !== factToRemove), $gameFactsStore)
$gameFactsStore = gameFactsAfterRemovedFacts;
}
}
function isDialogOptionAllowedByGameFacts(option: DialogOption, gameFacts: FactId[]): boolean {
// Check if all required facts are given
if (Array.isArray(option.requiredFacts)) {
const isOk = option.requiredFacts.every(requiredFact => gameFacts.includes(requiredFact));
if (!isOk) {
return false;
}
}
// Check if no forbidden facts are given
if (Array.isArray(option.forbiddenFacts)) {
const isOk = option.forbiddenFacts.every(forbiddenFact => !gameFacts.includes(forbiddenFact));
if (!isOk) {
return false;
}
}
return true;
}
function handleDialogOptionClick(option: DialogOption): void {
dispatch("switchToDialog", option.linksToDialog)
}
</script>
{#if typeof title === "string"}
......@@ -19,16 +59,16 @@
<img src={imageUrl} alt="Portrait" />
<div>
{#each text.split("\n\n") as para}
{#each text.split("\n") as para}
<p>{para}</p>
{/each}
</div>
<hr />
<div>
{#each options as option}
<button on:click={() => dispatch("switchToDialog", option.linksToDialog)}
>{option.text}</button
>
{#each usableOptions as option}
<button on:click={() => handleDialogOptionClick(option)}>
{option.text}
</button>
<br />
{/each}
</div>
import { writable } from "svelte-local-storage-store";
import type { Writable } from "svelte/store";
import type { FactId } from "./types";
export const gameFactsStore: Writable<FactId[]> = writable("gameFacts", [
"debugRequiredFact",
]);
export function addGameFactToFactArray(
gameFact: FactId,
factArray: FactId[]
): FactId[] {
if (!factArray.includes(gameFact)) {
return [...factArray, gameFact];
} else {
return factArray;
}
}
export function toggleFactInFactArray(
gameFact: FactId,
factArray: FactId[]
): FactId[] {
if (!factArray.includes(gameFact)) {
return [...factArray, gameFact];
} else {
return factArray.filter((f) => f !== gameFact);
}
}
export interface DialogSet {
title?: string;
imageUrl: string;
startDialogName: string;
dialogs: DialogMap;
}
......@@ -8,13 +10,19 @@ export type DialogMap = {
};
export interface Dialog {
imageUrl: string;
title?: string;
text: string;
title?: string; // Can be used to overwrite title from DialogSet
imageUrl?: string; // Can be used to overwrite imageUrl from DialogSet
text?: string;
options: DialogOption[];
addFacts?: FactId[];
removeFacts?: FactId[];
}
export interface DialogOption {
text: string;
linksToDialog: string;
requiredFacts?: FactId[];
forbiddenFacts?: FactId[];
}
export type FactId = String;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment