private IEnumerable <Dialogue.RunnerResult> RunShortcutOptionGroup(Parser.ShortcutOptionGroup shortcutOptionGroup) { var optionsToDisplay = new List <Parser.ShortcutOption> (); // Determine which options to present foreach (var option in shortcutOptionGroup.options) { var include = true; if (option.condition != null) { include = EvaluateExpression(option.condition).AsBool != false; } if (include) { optionsToDisplay.Add(option); } } if (optionsToDisplay.Count > 0) { // Give this list to our client var optionStrings = new List <string> (); foreach (var option in optionsToDisplay) { optionStrings.Add(option.label); } Parser.ShortcutOption selectedOption = null; yield return(new Dialogue.OptionSetResult(optionStrings, delegate(int selectedOptionIndex) { selectedOption = optionsToDisplay[selectedOptionIndex]; })); if (selectedOption == null) { dialogue.LogErrorMessage("The OptionChooser I provided was not called before the " + "next line was run! Stopping dialogue."); yield break; } if (selectedOption.optionNode != null) { foreach (var command in RunStatements(selectedOption.optionNode.statements)) { yield return(command); } } } // Done running these options; run the stuff that came afterwards if (shortcutOptionGroup.epilogue != null) { foreach (var command in RunStatements(shortcutOptionGroup.epilogue.statements)) { yield return(command); } } }
void GenerateCode(Node node, Parser.ShortcutOptionGroup statement) { var endOfGroupLabel = RegisterLabel("group_end"); var labels = new List <string> (); int optionCount = 0; foreach (var shortcutOption in statement.options) { var optionDestinationLabel = RegisterLabel("option_" + (optionCount + 1)); labels.Add(optionDestinationLabel); string endOfClauseLabel = null; if (shortcutOption.condition != null) { endOfClauseLabel = RegisterLabel("conditional_" + optionCount); GenerateCode(node, shortcutOption.condition); Emit(node, ByteCode.JumpIfFalse, endOfClauseLabel); } var labelLineID = GetLineIDFromNodeTags(shortcutOption); var labelStringID = program.RegisterString(shortcutOption.label, node.name, labelLineID, shortcutOption.lineNumber, true); Emit(node, ByteCode.AddOption, labelStringID, optionDestinationLabel); if (shortcutOption.condition != null) { Emit(node, ByteCode.Label, endOfClauseLabel); Emit(node, ByteCode.Pop); } optionCount++; } Emit(node, ByteCode.ShowOptions); if (flags.DisableShuffleOptionsAfterNextSet == true) { Emit(node, ByteCode.PushBool, false); Emit(node, ByteCode.StoreVariable, VirtualMachine.SpecialVariables.ShuffleOptions); Emit(node, ByteCode.Pop); flags.DisableShuffleOptionsAfterNextSet = false; } Emit(node, ByteCode.Jump); optionCount = 0; foreach (var shortcutOption in statement.options) { Emit(node, ByteCode.Label, labels [optionCount]); if (shortcutOption.optionNode != null) { GenerateCode(node, shortcutOption.optionNode.statements); } Emit(node, ByteCode.JumpTo, endOfGroupLabel); optionCount++; } // reached the end of the option group Emit(node, ByteCode.Label, endOfGroupLabel); // clean up after the jump Emit(node, ByteCode.Pop); }