DialogueTree.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. class DialogueTree {
  2. public id : string;
  3. private nodes : {[id : string] : DialogueNode} = {};
  4. public startNode : DialogueNode = undefined;
  5. private repeatChoices : boolean = true;
  6. private lastPrintedChoice : Array<HTMLElement>;
  7. public constructor (id : string) {
  8. this.id = id;
  9. }
  10. public addNode (node : DialogueNode) {
  11. this.nodes[node.id] = node;
  12. if (node.type == NodeType.Node) {
  13. this.nodes[node.name] = node; // This is a label!
  14. }
  15. }
  16. public addStartNode (node : DialogueNode) {
  17. this.addNode(node);
  18. this.startNode = node;
  19. }
  20. public getNode (id : string) {
  21. return this.nodes[id];
  22. }
  23. public getNext (node : DialogueNode) {
  24. let next = node.getNext();
  25. if (next != undefined) {
  26. return this.getNode(next);
  27. }
  28. }
  29. public setRepeatChoices (doIt : boolean) {
  30. this.repeatChoices = doIt;
  31. }
  32. public async execute (startId? : string) {
  33. console.debug(Rulebook.getIndentation() + "[DialogueTree] Running " + this.id);
  34. Rulebook.increaseIndentation(this);
  35. let node : DialogueNode;
  36. if (startId == undefined) {
  37. node = this.startNode;
  38. } else {
  39. node = this.getNode(startId);
  40. }
  41. if (node == undefined) {
  42. Elements.CurrentTurnHandler.printAsError("Unable to start dialogue " + this.id + ": A starting node could not be found.");
  43. return;
  44. }
  45. let previousNode : DialogueNode;
  46. while (node != undefined) {
  47. let nextNode = await this.processNode(node, previousNode);
  48. previousNode = node;
  49. node = nextNode;
  50. }
  51. Rulebook.decreaseIndentation();
  52. }
  53. public async processNode (node : DialogueNode, previousNode : DialogueNode) {
  54. console.debug(Rulebook.getIndentation() + "[" + node.type + "] " + node.id);
  55. Rulebook.increaseIndentation(node);
  56. let doChoices = node.hasChoices();
  57. if (node.type == NodeType.Tree) {
  58. await (<DialogueNodeTree> node).tree().execute();
  59. } else if (node.type == NodeType.Text) {
  60. let say = (<DialogueText> node).getSay();
  61. Elements.CurrentTurnHandler.printAsContent(say);
  62. } else if (node.type == NodeType.Set) {
  63. let runningSet = (<DialogueSet> node).run();
  64. if (runningSet instanceof Promise) {
  65. await runningSet;
  66. }
  67. }
  68. if (doChoices) {
  69. // Next node is decided by the choices
  70. let branchingDialogue = new BranchingDialogue();
  71. let choices = node.choices;
  72. let options = [];
  73. for (let i = 0; i < choices.length; i++) {
  74. let choice = <DialogueChoice> this.getNode(choices[i]);
  75. let branchingOption = new BranchingOption(choice.getSay(), choice.isAvailable());
  76. options.push(branchingOption);
  77. branchingDialogue.addOptions(branchingOption);
  78. }
  79. let chosenOption : BranchingOption = await branchingDialogue.getChosenOption();
  80. let chosenNodeId = choices[options.indexOf(chosenOption)];
  81. let chosenNode = <DialogueChoice> this.getNode(chosenNodeId);
  82. if (this.repeatChoices) {
  83. let say = new Say(new SayBold(" > ", chosenNode.getSay()));
  84. this.lastPrintedChoice = await Elements.CurrentTurnHandler.getSayElementsAsContent(say);
  85. await Elements.CurrentTurnHandler.print(...this.lastPrintedChoice);
  86. }
  87. console.debug(Rulebook.getIndentation() + "[Choice] Picked " + chosenNodeId);
  88. console.debug(Rulebook.getIndentation() + "[Choice] Going to " + chosenNode.getNext());
  89. Rulebook.increaseIndentation(chosenNodeId);
  90. Rulebook.decreaseIndentation();
  91. Rulebook.decreaseIndentation();
  92. return this.getNext(chosenNode);
  93. } else {
  94. Rulebook.decreaseIndentation();
  95. return this.getNext(node);
  96. }
  97. }
  98. public unprintLastChoice () {
  99. Elements.CurrentTurnHandler.unprint(...this.lastPrintedChoice);
  100. }
  101. }