diff --git a/resource/passages/testpassages.xml b/resource/passages/testpassages.xml index c6579ac..3f803c7 100644 --- a/resource/passages/testpassages.xml +++ b/resource/passages/testpassages.xml @@ -3,13 +3,18 @@ Test Passage 1 This is a test passage. + [check visited3 eq true]You have visited passage 3.[/check] + [check visited2 eq true]You have visited passage 2.[/check] + Test Passage 2 + [set visited2 true] + [set var1 5] This is another test passage. @@ -19,10 +24,12 @@ Test Passage 3 + [set visited3 true] The third test passage. + [check var1 gte 5]The check passed[/check] - + \ No newline at end of file diff --git a/src/js/games/pstcc/gameState.js b/src/js/games/pstcc/gameState.js new file mode 100644 index 0000000..c7707dc --- /dev/null +++ b/src/js/games/pstcc/gameState.js @@ -0,0 +1,35 @@ +export default class GameState { + constructor() { + this.stateDictionary = {}; + } + + setValue(key, value) { + this.stateDictionary[key.trim()] = value.trim(); + } + + checkValue(key, op, check) { + if (op == "eq") { + return this.stateDictionary[key] == check; + } + + let checknum = parseInt(check); + let value = parseInt(this.stateDictionary[key]); + + if (op == "lt") { + return value < checknum; + } + + if (op == "gt") { + console.log(checknum, value); + return value > checknum; + } + + if (op == "lte") { + return value <= checknum; + } + + if (op == "gte") { + return value >= checknum; + } + } +} \ No newline at end of file diff --git a/src/js/games/pstcc/inputhandler.js b/src/js/games/pstcc/inputhandler.js index 787397b..4b0f143 100644 --- a/src/js/games/pstcc/inputhandler.js +++ b/src/js/games/pstcc/inputhandler.js @@ -18,6 +18,11 @@ export default class InputHandler{ // } keyDown(e) { + if(e.keyCode == 32 && e.target == document.body) { + //Prevents spacebar from scrolling page + e.preventDefault(); + } + if(this.inputEnabled) { const key = String(e.key); diff --git a/src/js/games/pstcc/passageController.js b/src/js/games/pstcc/passageController.js index 98c7b2c..df7fd52 100644 --- a/src/js/games/pstcc/passageController.js +++ b/src/js/games/pstcc/passageController.js @@ -1,19 +1,23 @@ import * as PIXI from "pixi.js"; import TextRenderer from "./textrenderer"; import StoryNode from "./storyNode"; +import GameState from "./gameState"; export default class PassageController { constructor(app, input) { this.textRenderer = new TextRenderer(app); this.app = app; this.input = input; + this.state = new GameState(); this.storyNodes = {}; this.currentNode = null; this.previousNodes = []; // Stack for tracking previous nodes this.parser = new DOMParser(); this.passageFolder = "../resource/passages"; - this.passageFile = "testpassages2.xml"; + this.passageFile = "testpassages.xml"; this.endText = "The End"; // Default end text + this.currentPassageText = null; + this.currentPassageOptions = null; } async loadPassages() { @@ -46,17 +50,37 @@ export default class PassageController { renderCurrentNode() { this.textRenderer.clear(); - + + //Read any tags out of the text + let passageText = this.parseTags(this.currentNode.text); + this.currentPassageText = passageText.trim(); + + //Read check tags out of the options + let parsedOptions = []; + this.currentNode.options.forEach(item => { + let optionText = this.parseTags(item.text); + //If the option is empty after parsing tags, ignore it + if (optionText.length > 0) { + const newOption = { + text: optionText, + id: item.id, + textBroken: optionText.split(' ') + } + parsedOptions.push(newOption); + } + }); + this.currentPassageOptions = parsedOptions; + // Display the current passage text and title if (this.currentNode) { this.textRenderer.addTextLine(this.currentNode.title); this.textRenderer.addLineBreak(); - this.textRenderer.addTextLine(this.currentNode.text); + this.textRenderer.addTextLine(this.currentPassageText); this.textRenderer.addLineBreak(); // Display options or end text - if (this.currentNode.options.length > 0) { - this.currentNode.options.forEach(option => { + if (this.currentPassageOptions.length > 0) { + this.currentPassageOptions.forEach(option => { this.textRenderer.addTextLine(`${option.id}) ${option.text}`); }); } else { @@ -82,6 +106,82 @@ export default class PassageController { } } + parseTags(text) { + //Parses and removes 'set' tags from the text + let parsedText = text; + let removedText = []; + + for (let i = 0; i < text.length; i++) { + if (text[i] == '[') { + if (i < 0 && text[i - 1] == '\\') + { + //Escape character + continue; + } + + if (text.slice(i, i + 6) == "[check") { + let begin = i; + let startIndex = i + 7; + let endIndex = 0; + let words = []; + for (endIndex = startIndex; text[endIndex] != "]"; endIndex++) { + //Pull out the options for the check tag + if (text[endIndex] == ' ') { + words.push(text.slice(startIndex, endIndex)); + startIndex = endIndex + 1; + } + } + words.push(text.slice(startIndex, endIndex)); + //Words now contains the options for the check + + removedText.push(text.slice(begin, endIndex + 1)); + + //Find the end tag + removedText.push("[/check]") + for (let j = endIndex + 1; j < text.length; j++) { + if (text[j] == '[' && text.slice(j, j + 8) == "[/check]") { + //j marks the start of the end tag + //If the check fails, remove everything between tags + if (!this.state.checkValue(words[0].trim(), words[1].trim(), words[2].trim())) { + removedText.push(text.slice(endIndex + 1, j)); + } + break; + } + } + } + + if (text.slice(i, i + 4) == "[set") { + let begin = i; + let startIndex = i + 5; + let endIndex = 0; + let words = []; + + for (endIndex = startIndex; text[endIndex] != "]"; endIndex++) { + //Pull out the options for the check tag + if (text[endIndex] == ' ') { + words.push(text.slice(startIndex, endIndex)); + startIndex = endIndex; + } + } + words.push(text.slice(startIndex, endIndex)); + //words now contains the options for the set + + removedText.push(text.slice(begin, endIndex + 1)); + //There is no end tag for set + + this.state.setValue(words[0], words[1]); + } + } + } + + //Remove all tags from the output + for (let i = 0; i < removedText.length; i++) { + parsedText = parsedText.replace(removedText[i], "") + } + + return parsedText.trim(); + } + goBack() { // Pop the previous node from the stack and set it as the current node if (this.previousNodes.length > 0) { @@ -113,6 +213,7 @@ export default class PassageController { } getOptions() { - return this.currentNode.options; + //return this.currentNode.options; + return this.currentPassageOptions; } }