public void UpdateViewInfo(NovelScript script, int line) { var linemsg = script.lines[line]; Label.GetComponent <TextMeshProUGUI>().text = ""; OptionA.GetComponent <TextMeshProUGUI>().text = ""; OptionB.GetComponent <TextMeshProUGUI>().text = ""; var avatar = LeftAvatar; if (linemsg.left) { LeftAvatar.Find("Avatar").GetComponent <Image>().color = Color.white; RightAvatar.Find("Avatar").GetComponent <Image>().color = Color.gray; LeftAvatar.Find("Name").transform.localScale = Vector3.one; RightAvatar.Find("Name").transform.localScale = Vector3.zero; } else { LeftAvatar.Find("Avatar").GetComponent <Image>().color = Color.gray; RightAvatar.Find("Avatar").GetComponent <Image>().color = Color.white; LeftAvatar.Find("Name").transform.localScale = Vector3.zero; RightAvatar.Find("Name").transform.localScale = Vector3.one; avatar = RightAvatar; } avatar.Find("Avatar").GetComponent <Image>().sprite = linemsg.sprite; avatar.Find("Name").GetComponent <TextMeshProUGUI>().text = linemsg.name; if (linemsg.options.Length == 0) { Label.GetComponent <TextMeshProUGUI>().text = linemsg.content; if (line < script.lines.Length - 1) { Tip.GetComponent <TextMeshProUGUI>().text = "按X继续对话"; } else { Tip.GetComponent <TextMeshProUGUI>().text = "按X结束对话"; } } else { OptionA.GetComponent <TextMeshProUGUI>().text = "<color=red>按Z选择:" + linemsg.options[0].label + "</color>"; OptionB.GetComponent <TextMeshProUGUI>().text = "<color=blue>按X选择:" + linemsg.options[1].label + "</color>"; Tip.GetComponent <TextMeshProUGUI>().text = ""; } }
private NovelScript ParseScript(string name, NovelParserBlock block, NovelFunctionPool funcPool = null) { //Setup script ParsedScript = new NovelScript(name); ParsedScript.DelegateFunctionList = funcPool; try { ParsedScript = ParseScript(ParsedScript, block, ParentBlockType.StartBlock, 0); } catch (NovelException exception) { //TODO remove //Print the exception Console.WriteLine(exception.Message); } return(ParsedScript); }
public void NextLine(bool choice) { var currentLineMsg = currentscript.lines[currentLine]; if (currentLineMsg.options.Length > 0) { if (choice) { currentscript = currentLineMsg.options[1].result; currentLine = 0; view.UpdateViewInfo(currentscript, currentLine); } else { currentscript = currentLineMsg.options[0].result; currentLine = 0; view.UpdateViewInfo(currentscript, currentLine); } } else { if (currentLine + 1 < currentscript.lines.Length) { view.UpdateViewInfo(currentscript, currentLine + 1); foreach (var eff in currentLineMsg.effstring) { EffectResolve(eff); } } else { view.gameObject.SetActive(false); isShowing = false; foreach (var eff in currentLineMsg.effstring) { EffectResolve(eff); } //MapController.Instance.ShowMap(); } currentLine++; } }
public void InitScript(NovelScript script) { if (script == null) { MapController.Instance.ShowMap(); return; } //UIWindowController.Instance.arrow.transform.position = new Vector3(10000, 0, 90.0f); currentscript = script; currentLine = 0; view.gameObject.SetActive(true); view.UpdateViewInfo(currentscript, currentLine); isShowing = true; }
public NovelExecutor(NovelScript script) { IsExecuting = false; Script = script; InstructionPointer = 0; }
private NovelScript ParseScript(NovelScript script, NovelParserBlock block, ParentBlockType parentType, int nestLevel) { if (parentType == ParentBlockType.Function) { ContainsUserReturn = false; } //Prepeare variable scope Variables.AddScope(); //For each content in block for (int i = 0; i < block.Content.Count(); i++) { //Get the phrase var phrase = block.Content[i]; //Setting up the line for debbugging purposes ParsedLine = phrase.CodeLine; //If its another block if (phrase is NovelParserBlock) { var localBlock = phrase as NovelParserBlock; var header = localBlock.Header; //If header is the function signature if (IsFunctionSignature(header)) { //If the function signatures are nested if (parentType != ParentBlockType.StartBlock) { throw new NovelException("Function signatures cannot be nested", ParsedFile, ParsedLine); } //Get the function object var function = ParseFunctionSignature(header, script.Instructions.Count); //Add function to list script.FunctionList.Add(function); Variables.AddScope(); //Add arguments to stack for (int j = 0; j < function.ParameterNameList.Count; j++) { Variables.AddVaraible(function.ParameterNameList[j]); } //Parse the local block script = ParseScript(script, localBlock, ParentBlockType.Function, nestLevel + 1); Variables.RemoveScope(); } //If header indicates that this is condition start else if (IsCondition(header)) { //Check if condition is inside function block or another condition block if (parentType != ParentBlockType.Function && parentType != ParentBlockType.Condition) { throw new NovelException("Condition has to be in function", ParsedFile, ParsedLine); } //Getting the condition level int conditionLevel = -1; List <NovelInstruction> instructions = new List <NovelInstruction>(); //Get the novel condition var condition = ParseCondition(header, out conditionLevel, ref instructions); //TODO check boolean type compatibility //Check if the last term element is logical type //var terms = condition.Expression.Term; //var lastTerm = terms[terms.Count - 1]; //if( !(lastTerm is NovelLogicOperator) ) // throw new NovelException("Condition does not contain logic expression", ParsedFile, ParsedLine); //Getting last type of condition (if, else if, else) int lastLevel = Conditions.GetLastConditionLevel(nestLevel); //Check if the upcoming condition is higher than //those in condition scope, or if those are else if if (conditionLevel > lastLevel || (conditionLevel == 1 && lastLevel == 1)) { //If lastLevel is "If" or "Else if" then if (lastLevel == 0 || lastLevel == 1) { script.Instructions.Add(new NovelJump()); } int firstInstruction = script.Instructions.Count; foreach (var inst in instructions) { script.Instructions.Add(inst); } Conditions.AddCondition(nestLevel, firstInstruction, script.Instructions.Count, conditionLevel, ConditionScope.ConditionType.Normal); script.Instructions.Add(condition); } else { throw new NovelException("Invalid type of conditional instruction in this context", ParsedFile, ParsedLine); } ParsedScript = ParseScript(script, localBlock, ParentBlockType.Condition, nestLevel + 1); } //If header indicates that this is a loop else if (IsWhileLoop(header)) { //Check if condition is inside function block or another condition block if (parentType != ParentBlockType.Function && parentType != ParentBlockType.Condition) { throw new NovelException("Condition has to be in function", ParsedFile, ParsedLine); } List <NovelInstruction> instructions = new List <NovelInstruction>(); var condition = ParseWhileLoop(header, ref instructions); //Get the index of where the local variables for condition start int firstInstructionOfCndIndex = script.Instructions.Count; //Add all instructions foreach (var instruction in instructions) { script.Instructions.Add(instruction); } //Add stuff to condition scope Conditions.AddCondition(nestLevel, firstInstructionOfCndIndex, script.Instructions.Count, 1, ConditionScope.ConditionType.Loop); //Add condition at the end script.Instructions.Add(condition); ParsedScript = ParseScript(script, localBlock, ParentBlockType.Condition, nestLevel + 1); } } //Or if its a plain text else if (phrase is NovelParserText) { //If condition scope contains if (Conditions.GetLastConditionLevel(nestLevel) > -1) { UpdateConditions(nestLevel); } var localText = phrase as NovelParserText; var instruction = localText.Instruction; //If is assignment expression //if (IsAssigment(instruction)) //{ // //Parse assignment (supports initialization) // var instructions = ParseAssignment(instruction); // foreach (var inst in instructions) // script.Instructions.Add(inst); //} if (IsReturn(instruction)) { var instructions = ParseReturn(instruction); foreach (var inst in instructions) { script.Instructions.Add(inst); } ContainsUserReturn = true; } //If its other kind of expression else { //Parse expression (supports initialization) var instructions = ParseExpression(instruction); foreach (var inst in instructions) { script.Instructions.Add(inst); } } } //TODO find a better way to this //Now we have to handle returning values //If the last instruction of this block isn't the return value then return default } //If the end of the block then end condition UpdateConditions(nestLevel); //Return value should cause local variables to unstack if (parentType == ParentBlockType.Function) { //If contains returns in function but last instruction is not a return if (ContainsUserReturn == true && !(script.Instructions[script.Instructions.Count() - 1] is NovelReturn)) { throw new NovelException("Function does not return a value.", ParsedFile, ParsedLine); } //If last instruction isn't return else if (!(script.Instructions[script.Instructions.Count() - 1] is NovelReturn)) { script.Instructions.Add(new NovelReturn(new NovelExpressionLiteral((int)0))); } } //No return so manual unstacking else { //Unstack local variables var stackVars = Variables.GetScopeStackVariablesCount(); if (stackVars > 0) { foreach (var v in Variables.GetScopeStackVariables()) { Console.WriteLine(v); } script.Instructions.Add(new NovelExpandStack(-stackVars)); } } //Remove scope before return Variables.RemoveScope(); return(script); }