/// <summary> /// Simple converter that takes in a ScriptItem and returns a string /// </summary> /// <param name="item">item to process</param> /// <returns>string equivelant of the scriptitem</returns> private string TextProcessItem(TalkScript.ScriptItem item) { switch (item.Command) { case TalkScript.TalkCommand.AvatarsName: return(gameStateRef.AvatarsName); case TalkScript.TalkCommand.NewLine: return("\n"); case TalkScript.TalkCommand.PlainString: return(item.Str); case TalkScript.TalkCommand.Rune: runeMode = !runeMode; if (runeMode) { return(" "); } return(string.Empty); default: throw new Exception("Passed in an unsupported TalkCommand: " + item.Command.ToString() + " to the TextProcessItem method"); } }
/// <summary> /// Add a ScriptItem to the output buffer that will be consumed by the outside process (ie. World) /// </summary> /// <param name="output">ScripItem to add to queue</param> private void EnqueToOutputBuffer(TalkScript.ScriptItem output) { lock (((ICollection)outputBufferQueue).SyncRoot) { outputBufferQueue.Enqueue(output); EnqueuedScriptItemCallback(this); } }
/// <summary> /// Process an individual line. /// The method evaluates each scriptitem within the line, adding items and text to the output buffer as required. /// Mega function /// </summary> /// <remarks>If you do not SPLIT the line ahead of time then it is going to act wonky...</remarks> /// <param name="scriptLine"></param> /// <param name="nTalkLineIndex"></param> /// <param name="nSplitLine"></param> /// <returns></returns> async private Task ProcessLine(TalkScript.ScriptLine scriptLine, int nTalkLineIndex, int nSplitLine) { // if they already know the avatar then they aren't going to ask again if (scriptLine.ContainsCommand(TalkScript.TalkCommand.AskName) && Npc.KnowTheAvatar) { currentSkipInstruction = SkipInstruction.DontSkip; return; } int nItem = 0; int nItems = scriptLine.NumberOfScriptItems; do { TalkScript.ScriptItem item = scriptLine.GetScriptItem(nItem); // if this is the very first position of conversation // we must describe what we "see" if (nTalkLineIndex == (int)TalkScript.TalkConstants.Description && nSplitLine == 0 && nItem == 0) { EnqueToOutputBuffer(new TalkScript.ScriptItem(TalkScript.TalkCommand.PlainString, GetConversationStr(DataOvlReference.CHUNK__PHRASES_CONVERSATION.YOU_SEE) + " ")); } switch (item.Command) { case TalkScript.TalkCommand.IfElseKnowsName: Debug.Assert(nItems == 1); if (Npc.KnowTheAvatar) { // we continue to the next block, but skip the one after currentSkipInstruction = SkipInstruction.SkipAfterNext; return; } else { // we skip the next block because it is the line used when we actually know the Avatar currentSkipInstruction = SkipInstruction.SkipNext; return; } case TalkScript.TalkCommand.AvatarsName: // we should already know if they know the avatars name.... Debug.Assert(Npc.KnowTheAvatar); EnqueToOutputBuffer(new TalkScript.ScriptItem(TalkScript.TalkCommand.PlainString, TextProcessItem(item))); break; case TalkScript.TalkCommand.AskName: EnqueToOutputBuffer(new TalkScript.ScriptItem(TalkScript.TalkCommand.PlainString, GetConversationStr(DataOvlReference.CHUNK__PHRASES_CONVERSATION.WHATS_YOUR_NAME))); EnqueToOutputBuffer(item); // we actually wait in the function for the user to respond await AwaitResponse(); string avatarNameResponse = GetResponse(); // did they actually provide the Avatars name? if (avatarNameResponse.ToLower() == gameStateRef.AvatarsName.ToLower()) { // i met them gameStateRef.SetMetNPC(Npc); EnqueToOutputBuffer(new TalkScript.ScriptItem(TalkScript.TalkCommand.PlainString, GetConversationStr(DataOvlReference.CHUNK__PHRASES_CONVERSATION.PLEASURE))); break; } else { EnqueToOutputBuffer(new TalkScript.ScriptItem(TalkScript.TalkCommand.PlainString, GetConversationStr(DataOvlReference.CHUNK__PHRASES_CONVERSATION.IF_SAY_SO))); } break; case TalkScript.TalkCommand.CallGuards: EnqueToOutputBuffer(item); break; case TalkScript.TalkCommand.Change: EnqueToOutputBuffer(item); break; case TalkScript.TalkCommand.DefineLabel: // if I find a goto label, then i expect I have no further conversation lines left //Debug.Assert(nConversationIndex == conversationOrderScriptLines.Count - 1); // we are going to add the GotoLabel to the script conversationOrder.Add((int)script.GetScriptLineLabelIndex(item.LabelNum)); conversationOrderScriptLines.Add(script.GetScriptLine(script.GetScriptLineLabelIndex(item.LabelNum))); currentSkipInstruction = SkipInstruction.SkipToLabel; return; //return SkipInstruction.SkipToLabel; case TalkScript.TalkCommand.EndCoversation: EnqueToOutputBuffer(item); ConversationEnded = true; break; case TalkScript.TalkCommand.Gold: EnqueToOutputBuffer(item); break; case TalkScript.TalkCommand.JoinParty: if (gameStateRef.IsFullParty()) { string noJoinResponse = GetConversationStr(DataOvlReference.CHUNK__PHRASES_CONVERSATION.CANT_JOIN_1) + GetConversationStr(DataOvlReference.CHUNK__PHRASES_CONVERSATION.CANT_JOIN_2); EnqueToOutputBuffer(new TalkScript.ScriptItem(TalkScript.TalkCommand.PlainString, noJoinResponse)); //"Thou hast no room for me in thy party! Seek me again if one of thy members doth leave thee.\n")); } else { EnqueToOutputBuffer(item); ConversationEnded = true; } break; case TalkScript.TalkCommand.KarmaMinusOne: EnqueToOutputBuffer(item); break; case TalkScript.TalkCommand.KarmaPlusOne: EnqueToOutputBuffer(item); break; case TalkScript.TalkCommand.KeyWait: EnqueToOutputBuffer(item); break; case TalkScript.TalkCommand.NewLine: EnqueToOutputBuffer(new TalkScript.ScriptItem(TalkScript.TalkCommand.PlainString, TextProcessItem(item))); break; case TalkScript.TalkCommand.Pause: EnqueToOutputBuffer(item); break; case TalkScript.TalkCommand.PlainString: // we put it through the processor to change the text around if we are wrapped in a rune tag EnqueToOutputBuffer(new TalkScript.ScriptItem(TalkScript.TalkCommand.PlainString, TextProcessItem(item))); break; case TalkScript.TalkCommand.Rune: EnqueToOutputBuffer(new TalkScript.ScriptItem(TalkScript.TalkCommand.PlainString, TextProcessItem(item))); break; case TalkScript.TalkCommand.UserInputNotRecognized: EnqueToOutputBuffer(new TalkScript.ScriptItem(TalkScript.TalkCommand.PlainString, GetConversationStr(DataOvlReference.CHUNK__PHRASES_CONVERSATION.CANNOT_HELP) + "\n")); break; case TalkScript.TalkCommand.Unknown_Enter: break; case TalkScript.TalkCommand.DoNothingSection: // appears to signify an empty section break; case TalkScript.TalkCommand.StartLabelDefinition: // dirty - advance past the label that it will sink in... nItem++; break; case TalkScript.TalkCommand.Or: case TalkScript.TalkCommand.StartNewSection: throw new Exception("We should never see the <OR> or <A2> code in conversation"); default: throw new Exception("Recieved TalkCommand I wasn't expecting during conversation"); } nItem++; // while we still have more items in the current split line } while (nItem < nItems); currentSkipInstruction = SkipInstruction.DontSkip; return; //return SkipInstruction.DontSkip; }