private void ProcessConversation(NPCResponseStep NPCRS, SMCharacter invokingCharacter) { // First get the conversation string[] rsd = NPCRS.ResponseStepData.Split('.'); // Get the conversation NPCConversations npcc = this.NPCConversationStructures.FirstOrDefault(constructure => constructure.ConversationID == rsd[0]); // Check we definitely found a structure to use if (npcc != null) { ProcessConversationStep(npcc, rsd[1], invokingCharacter); } }
public void AddResponse(NPCConversations npcc, NPCConversationStep npccs, SMCharacter invokingCharacter, List <ShortcutToken> stl, string responseOptions) { // Set up a list to hold them in the character (if there isn't one already) if (this.AwaitingCharacterResponses == null) { this.AwaitingCharacterResponses = new List <SMNPCAwaitingCharacterResponse>(); } // Create the awaiting response token. SMNPCAwaitingCharacterResponse acr = new SMNPCAwaitingCharacterResponse(); acr.ConversationID = npcc.ConversationID; acr.ConversationStep = npccs.StepID; acr.WaitingForCharacter = invokingCharacter; acr.RoomID = this.RoomID; // Work out the timeout conversation if there is one. string nextStepAfterTimeout = null; int timeout = 10000; if (npccs.NextStep != null) { string[] getNextStep = npccs.NextStep.Split('.'); nextStepAfterTimeout = getNextStep[0]; timeout = int.Parse(getNextStep[1]); } // Set the conversation timeout acr.ConversationStepAfterTimeout = nextStepAfterTimeout; acr.UnixTimeStampTimeout = Utility.Utils.GetUnixTimeOffset(timeout); // Add the item to the character, and send a message to the player regarding the available responses. this.AwaitingCharacterResponses.Add(acr); invokingCharacter.SetAwaitingResponse(this.UserID, stl, timeout, this.RoomID); if ((responseOptions != null) && (!responseOptions.Contains("{variable}"))) { invokingCharacter.sendMessageToPlayer(responseOptions); } }
public void ProcessCharacterResponse(string responseShortCut, SMCharacter invokingCharacter) { // Get the current unix time int currentUnixTime = Utility.Utils.GetUnixTime(); // Double check we're not going to get a null exception if (this.AwaitingCharacterResponses != null) { // Delete all responses over that time // this.AwaitingCharacterResponses.RemoveAll(awaitingitems => awaitingitems.UnixTimeStampTimeout < currentUnixTime); if (this.AwaitingCharacterResponses.Count > 0) { // Get the Character Response. SMNPCAwaitingCharacterResponse acr = this.AwaitingCharacterResponses.FirstOrDefault(rw => rw.WaitingForCharacter.UserID == invokingCharacter.UserID); // Make sure we've returned something if (acr != null) { // Load the conversation NPCConversations npcc = this.NPCConversationStructures.FirstOrDefault(nc => nc.ConversationID == acr.ConversationID); if (npcc != null) { // Get the relevant part of the conversation to go to NPCConversationStep currentStep = npcc.ConversationSteps.FirstOrDefault(step => step.StepID == acr.ConversationStep); if ((currentStep != null) && (currentStep.ResponseOptions != null)) { NPCConversationStepResponseOptions nextstep = currentStep.ResponseOptions.FirstOrDefault(ro => ro.ResponseOptionShortcut.ToLower() == responseShortCut.ToLower()); // TODO - Update this location with the character variable info. if (nextstep == null) { nextstep = currentStep.ResponseOptions.FirstOrDefault(ro => ro.ResponseOptionShortcut.ToLower() == "{variable}"); invokingCharacter.VariableResponse = responseShortCut; } if (nextstep != null) { NPCResponseOptionAction nroa = nextstep.ResponseOptionActionSteps.FirstOrDefault(); if (nroa != null) { // Get the conversation / step to go to. string[] convostep = nroa.AdditionalData.Split('.'); // check whether the conversation is the same as the original if not get the new one if (convostep[0] != npcc.ConversationID) { npcc = this.NPCConversationStructures.FirstOrDefault(nc => nc.ConversationID == convostep[0]); } // Remove the item from the awaiting items. AwaitingCharacterResponses.Remove(acr); // Remove it from the character too, it's processed now so we don't need it any more! invokingCharacter.NPCsWaitingForResponses.RemoveAll(ar => ar.NPCID == this.UserID); invokingCharacter.SaveToApplication(); invokingCharacter.SaveToFile(); // process it ProcessConversationStep(npcc, convostep[1], invokingCharacter); } } } } } } } }
/// <summary> /// Process the response options for an action. /// </summary> /// <param name="npcc">The conversation that is taking place</param> /// <param name="npccs">The step in the conversation</param> /// <param name="invokingCharacter">The invoking character</param> private void ProcessResponseOptions(NPCConversations npcc, NPCConversationStep npccs, SMCharacter invokingCharacter) { // Set the response option variables up string responseOptions = OutputFormatterFactory.Get().Bold(this.GetFullName() + " Responses:") + OutputFormatterFactory.Get().NewLine; bool thereIsAnOption = false; List <ShortcutToken> stl = new List <ShortcutToken>(); // Loop around the options building up the various parts foreach (NPCConversationStepResponseOptions npcccsro in npccs.ResponseOptions) { // Variable to hold whether the response can be added - it may not be allowed due to some prereqs.. bool canAddResponse = true; // Check if there is a prereq... if (npcccsro.PreRequisites != null) { // get the quests for use later List <SMQuestStatus> smqs = new List <SMQuestStatus>(); if (invokingCharacter.QuestLog != null) { smqs = invokingCharacter.QuestLog; } // .. if there is, loop around them. foreach (NPCConversationStepResponseOptionsPreRequisites prereq in npcccsro.PreRequisites) { switch (prereq.Type) { case "HasDoneQuest": if (smqs.Count(quest => (quest.QuestName == prereq.AdditionalData) && (quest.Completed)) == 0) { canAddResponse = false; } break; case "InProgressQuest": if (smqs.Count(quest => (quest.QuestName == prereq.AdditionalData) && (!quest.Completed)) == 0) { canAddResponse = false; } break; case "HasNotDoneQuest": if (smqs.Count(quest => (quest.QuestName == prereq.AdditionalData)) != 0) { canAddResponse = false; } break; case "IsNotInProgressQuest": if (smqs.Count(quest => (quest.QuestName == prereq.AdditionalData) && (!quest.Completed)) != 0) { canAddResponse = false; } break; } } } // Check that the response can be added if (canAddResponse) { responseOptions += OutputFormatterFactory.Get().ListItem(ProcessResponseString(npcccsro.ResponseOptionText, invokingCharacter) + " (" + npcccsro.ResponseOptionShortcut + ")"); ShortcutToken st = new ShortcutToken(); st.ShortCutToken = npcccsro.ResponseOptionShortcut; stl.Add(st); thereIsAnOption = true; } } // If an option has been set.. if (thereIsAnOption) { AddResponse(npcc, npccs, invokingCharacter, stl, responseOptions); } }
private void ProcessConversationStep(NPCConversations npcc, string stepID, SMCharacter invokingCharacter) { NPCConversationStep npccs = npcc.ConversationSteps.FirstOrDefault(cs => cs.StepID == stepID); bool continueToNextStep = true; if (npccs != null) { switch (npccs.Scope.ToLower()) { case "choice": string[] choices = npccs.AdditionalData.Split(','); int choicesNumber = choices.Count(); int randomChoice = (new Random().Next(1, choicesNumber + 1)) - 1; if (randomChoice > choicesNumber) { randomChoice = 0; } ProcessConversationStep(npcc, choices[randomChoice], invokingCharacter); break; case "say": this.Say(ProcessResponseString(npccs.AdditionalData, invokingCharacter)); break; case "shout": this.Shout(ProcessResponseString(npccs.AdditionalData, invokingCharacter)); break; case "whisper": this.Whisper(ProcessResponseString(npccs.AdditionalData, invokingCharacter), invokingCharacter.GetFullName()); break; case "emote": this.GetRoom().ChatEmote(ProcessResponseString(npccs.AdditionalData, invokingCharacter), this, this); break; case "saytoplayer": // Construct the message string sayToPlayerMessage = OutputFormatterFactory.Get().Italic(this.GetFullName() + " says:", 0) + " \"" + ProcessResponseString(npccs.AdditionalData, invokingCharacter) + "\""; // Send the message invokingCharacter.sendMessageToPlayer(sayToPlayerMessage); break; case "emotetoplayer": // Construct the message string emoteToPlayerMessage = OutputFormatterFactory.Get().Italic(this.GetFullName() + " " + ProcessResponseString(npccs.AdditionalData, invokingCharacter)); // Send the message invokingCharacter.sendMessageToPlayer(emoteToPlayerMessage); break; case "attack": // Simply attack a target player this.Attack(invokingCharacter.GetFullName()); break; case "giveitem": // give an item to the player string[] additionalDataSplit = npccs.AdditionalData.Split(','); string[] itemParts = additionalDataSplit[0].Split('.'); // Create the item.. if (itemParts.Count() == 2) { int numberToCreate = int.Parse(additionalDataSplit[1]); // Create the right number of the items. while (numberToCreate > 0) { // Get the item (with a new GUID) SMItem itemBeingGiven = SMItemFactory.Get(itemParts[0], itemParts[1]); // Pass it to the player invokingCharacter.PickUpItem("", itemBeingGiven, true); // Reduce the number to create numberToCreate--; } } break; case "addquest": // Load the quest SMQuest smq = SMQuestFactory.Get(npccs.AdditionalData); if (smq != null) { invokingCharacter.AddQuest(smq); } break; case "updatequest": // Load the quest SMQuest qtu = SMQuestFactory.Get(npccs.AdditionalData); if (qtu != null) { invokingCharacter.UpdateQuest(qtu); } break; case "checkquestinprogress": // Check the quest log isn't null if (invokingCharacter.QuestLog != null) { if (invokingCharacter.QuestLog.Count(questcheck => (questcheck.QuestName.ToLower() == npccs.AdditionalData.ToLower()) && (questcheck.Completed)) > 0) { continueToNextStep = false; } } break; case "setplayerattribute": // Add a response option switch (npccs.AdditionalData.ToLower()) { case "firstname": invokingCharacter.FirstName = invokingCharacter.VariableResponse; break; case "lastname": invokingCharacter.LastName = invokingCharacter.VariableResponse; break; case "sex": invokingCharacter.Sex = char.Parse(invokingCharacter.VariableResponse); break; } invokingCharacter.SaveToApplication(); invokingCharacter.SaveToFile(); break; case "setvariableresponse": invokingCharacter.VariableResponse = npccs.AdditionalData.ToLower(); break; case "teachskill": // Check if the player already has the skill if (invokingCharacter.Skills == null) { invokingCharacter.Skills = new List <SMSkillHeld>(); } // Get the skill and level to teach to string[] skillToTeach = npccs.AdditionalData.Split('.'); // Check if the character already has the skill if (invokingCharacter.Skills.Count(skill => skill.SkillName == skillToTeach[0]) == 0) { // Create a new skill help object SMSkillHeld smsh = new SMSkillHeld(); smsh.SkillName = skillToTeach[0]; smsh.SkillLevel = int.Parse(skillToTeach[1]); // Finally add it to the player invokingCharacter.Skills.Add(smsh); // Save the player invokingCharacter.SaveToApplication(); invokingCharacter.SaveToFile(); // Inform the player they have learnt a new skill invokingCharacter.sendMessageToPlayer(OutputFormatterFactory.Get().Italic($"You learn a new skill: {smsh.SkillName}({smsh.SkillLevel}).")); } break; case "wait": System.Threading.Thread.Sleep(int.Parse(npccs.AdditionalData) * 1000); break; } if (continueToNextStep) { if (npccs.ResponseOptions != null) { if (npccs.ResponseOptions.Count > 0) { ProcessResponseOptions(npcc, npccs, invokingCharacter); } } if (npccs.NextStep != null) { string[] splitNextStep = npccs.NextStep.Split('.'); if (splitNextStep[1] != "0") { System.Threading.Thread.Sleep(int.Parse(splitNextStep[1]) * 1000); } ProcessConversationStep(npcc, splitNextStep[0], invokingCharacter); } } } }