123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- /// <reference path="../Save/StoredVariable.ts" />
- class DialogueTree {
- public id : string;
- private nodes : {[id : string] : DialogueNode} = {};
- public startNode : DialogueNode = undefined;
- private repeatChoices : boolean = true;
- private lastPrintedChoice : Array<HTMLElement>;
- private executedCount : StoredVariable<number>;
- public static ReturnValue : any = undefined; // Use this to mimic a return value if using a dialogue tree to find a value.
- public constructor (id : string) {
- this.id = id;
- this.executedCount = new StoredVariable({id: "DialogueTree " + id, value : 0});
- }
- public hasRan () {
- return this.executedCount.value > 0;
- }
- public ranTimes () {
- return this.executedCount.value;
- }
- public incrementRanCount () {
- this.executedCount.value = (this.ranTimes() + 1);
- }
- public addNode (node : DialogueNode) {
- this.nodes[node.id] = node;
- if (node.type == NodeType.Node) {
- this.nodes[node.name] = node; // This is a label!
- }
- }
- public addStartNode (node : DialogueNode) {
- this.addNode(node);
- this.startNode = node;
- }
- public getNode (id : string) {
- return this.nodes[id];
- }
- public getNext (node : DialogueNode) {
- let next = node.getNext();
- if (next != undefined) {
- return this.getNode(next);
- }
- }
- public setRepeatChoices (doIt : boolean) {
- this.repeatChoices = doIt;
- }
- public async execute (startId? : string) {
- this.incrementRanCount();
- console.debug(Rulebook.getIndentation() + "[DialogueTree] Running " + this.id);
- Rulebook.increaseIndentation(this);
- DialogueTree.ReturnValue = undefined;
- let node : DialogueNode;
- if (startId == undefined) {
- node = this.startNode;
- } else {
- node = this.getNode(startId);
- }
- if (node == undefined) {
- Elements.CurrentTurnHandler.printAsError("Unable to start dialogue " + this.id + ": A starting node could not be found.");
- return;
- }
- let previousNode : DialogueNode;
- while (node != undefined) {
- let nextNode = await this.processNode(node, previousNode);
- previousNode = node;
- node = nextNode;
- }
- Rulebook.decreaseIndentation();
- return (DialogueTree.ReturnValue);
- }
- public async processNode (node : DialogueNode, previousNode : DialogueNode) {
- console.debug(Rulebook.getIndentation() + "[" + node.type + "] " + node.id);
- Rulebook.increaseIndentation(node);
- let doChoices = node.hasChoices();
- if (node.type == NodeType.Tree) {
- await (<DialogueNodeTree> node).tree().execute();
- } else if (node.type == NodeType.Text) {
- let say = (<DialogueText> node).getSay();
- Elements.CurrentTurnHandler.printAsContent(say);
- } else if (node.type == NodeType.Set) {
- let runningSet = (<DialogueSet> node).run();
- if (runningSet instanceof Promise) {
- await runningSet;
- }
- }
- if (doChoices) {
- // Next node is decided by the choices
- let branchingDialogue = new BranchingDialogue();
- let choices = node.choices;
- let options = [];
- for (let i = 0; i < choices.length; i++) {
- let choice = <DialogueChoice> this.getNode(choices[i]);
- let branchingOption = new BranchingOption(choice.getSay(), choice.isAvailable());
- options.push(branchingOption);
- branchingDialogue.addOptions(branchingOption);
- }
- let chosenOption : BranchingOption = await branchingDialogue.getChosenOption();
- let chosenNodeId = choices[options.indexOf(chosenOption)];
- let chosenNode = <DialogueChoice> this.getNode(chosenNodeId);
- if (this.repeatChoices) {
- let say = new Say(new SayBold(" > ", chosenNode.getSay()));
- this.lastPrintedChoice = await Elements.CurrentTurnHandler.getSayElementsAsContent(say);
- await Elements.CurrentTurnHandler.print(...this.lastPrintedChoice);
- }
- console.debug(Rulebook.getIndentation() + "[Choice] Picked " + chosenNodeId);
- console.debug(Rulebook.getIndentation() + "[Choice] Going to " + chosenNode.getNext());
- Rulebook.increaseIndentation(chosenNodeId);
- Rulebook.decreaseIndentation();
- Rulebook.decreaseIndentation();
- return this.getNext(chosenNode);
- } else {
- Rulebook.decreaseIndentation();
- return this.getNext(node);
- }
- }
- public unprintLastChoice () {
- Elements.CurrentTurnHandler.unprint(...this.lastPrintedChoice);
- }
- }
|