/// <summary> /// Creates a NPCChatDialogViewNode as a child of this NPCChatDialogViewNode. /// </summary> /// <param name="dialogItem">The NPCChatDialogItemBase the child node will handle.</param> /// <returns>A NPCChatDialogViewNode as a child of this NPCChatDialogViewNode.</returns> NPCChatDialogViewNode CreateNode(NPCChatDialogItemBase dialogItem) { // Check if the node already exists var children = Nodes.OfType <NPCChatDialogViewNode>(); var retNode = children.FirstOrDefault( x => (x.ChatItemType == NPCChatDialogViewNodeItemType.DialogItem || x.ChatItemType == NPCChatDialogViewNodeItemType.Redirect) && x.ChatItemAsDialogItem == dialogItem); // Create the new node if needed if (retNode == null) { // Check if it has to be a redirect node var existingDialogNode = TreeViewCasted.GetNodeForDialogItem(dialogItem); if (existingDialogNode != null) { retNode = new NPCChatDialogViewNode(this, existingDialogNode); } else { retNode = new NPCChatDialogViewNode(this, dialogItem); } } return(retNode); }
/// <summary> /// Gets the NPCChatDialogViewNode for the given NPCChatDialogItemBase. Nodes that redirect to the /// given NPCChatDialogItemBase are not included. /// </summary> /// <param name="dialogItem">The NPCChatDialogItemBase to find the NPCChatDialogViewNode for.</param> /// <returns>The NPCChatDialogViewNode for the given <paramref name="dialogItem"/>, or null if /// no NPCChatDialogViewNode was found that handles the given <paramref name="dialogItem"/>.</returns> public NPCChatDialogViewNode GetNodeForDialogItem(NPCChatDialogItemBase dialogItem) { if (NPCChatDialog == null) { return(null); } List <NPCChatDialogViewNode> ret; if (!_objToTreeNode.TryGetValue(dialogItem, out ret)) { return(null); } // Remove dead nodes foreach (var deadNode in ret.Where(x => x.IsDead)) { NotifyNodeDestroyed(deadNode); } Debug.Assert(ret.Count(x => x.ChatItemType == NPCChatDialogViewNodeItemType.DialogItem) <= 1, "Was only expected 0 or 1 TreeNodes to be directly for this dialogItem."); var r = ret.FirstOrDefault(x => x.ChatItemType == NPCChatDialogViewNodeItemType.DialogItem); Debug.Assert(r.ChatItemAsDialogItem == dialogItem); return(r); }
/// <summary> /// Gets all of the <see cref="NPCChatDialogItemBase"/>s that <paramref name="root"/> can go to from any response /// and assuming an infinite number of branches can be taken. /// </summary> /// <param name="root">The root dialog to get all the possible branches for.</param> /// <returns>All of the <see cref="NPCChatDialogItemBase"/>s that this <see cref="NPCChatDialogItemBase"/> can go to from any response /// and assuming an infinite number of branches can be taken.</returns> /// <exception cref="ArgumentNullException"><paramref name="root" /> is <c>null</c>.</exception> public IEnumerable<NPCChatDialogItemBase> GetChildDialogItems(NPCChatDialogItemBase root) { if (root == null) throw new ArgumentNullException("root"); var foundItems = new SortedList<NPCChatDialogItemID, NPCChatDialogItemBase>(); GetChildDialogItems(root, foundItems); return foundItems.Values; }
/// <summary> /// Gets all of the <see cref="NPCChatDialogItemBase"/>s that <paramref name="root"/> can go to from any response /// and assuming an infinite number of branches can be taken. /// </summary> /// <param name="root">The root dialog to get all the possible branches for.</param> /// <returns>All of the <see cref="NPCChatDialogItemBase"/>s that this <see cref="NPCChatDialogItemBase"/> can go to from any response /// and assuming an infinite number of branches can be taken.</returns> /// <exception cref="ArgumentNullException"><paramref name="root" /> is <c>null</c>.</exception> public IEnumerable <NPCChatDialogItemBase> GetChildDialogItems(NPCChatDialogItemBase root) { if (root == null) { throw new ArgumentNullException("root"); } var foundItems = new SortedList <NPCChatDialogItemID, NPCChatDialogItemBase>(); GetChildDialogItems(root, foundItems); return(foundItems.Values); }
void GetChildDialogItems(NPCChatDialogItemBase current, IDictionary<NPCChatDialogItemID, NPCChatDialogItemBase> found) { foreach (var response in current.Responses) { var page = response.Page; if (found.ContainsKey(page)) continue; var dialog = GetDialogItem(page); found.Add(page, dialog); GetChildDialogItems(dialog, found); } }
/// <summary> /// Gets the text for a NPCChatDialogItemBase. /// </summary> /// <param name="item">The NPCChatDialogItemBase.</param> /// <returns>The text for a NPCChatDialogItemBase.</returns> static string GetText(NPCChatDialogItemBase item) { var text = item.Title; if (string.IsNullOrEmpty(text)) { text = item.Text; if (text.Length > 100) { text = text.Substring(0, 100); } } return(text); }
void GetChildDialogItems(NPCChatDialogItemBase current, IDictionary <NPCChatDialogItemID, NPCChatDialogItemBase> found) { foreach (var response in current.Responses) { var page = response.Page; if (found.ContainsKey(page)) { continue; } var dialog = GetDialogItem(page); found.Add(page, dialog); GetChildDialogItems(dialog, found); } }
/// <summary> /// Gets an IEnumerable of all the NPCChatDialogViewNodes that handle the given <paramref name="dialogItem"/>. /// This includes any NPCChatDialogViewNodes that redirect to the NPCChatDialogItemBase. /// </summary> /// <param name="dialogItem">The NPCChatDialogItemBase to find the NPCChatDialogViewNodes for.</param> /// <returns>An IEnumerable of all the NPCChatDialogViewNodes that handle the given /// <paramref name="dialogItem"/>.</returns> public IEnumerable <NPCChatDialogViewNode> GetNodesForDialogItem(NPCChatDialogItemBase dialogItem) { if (NPCChatDialog == null) { return(null); } List <NPCChatDialogViewNode> ret; if (!_objToTreeNode.TryGetValue(dialogItem, out ret)) { return(Enumerable.Empty <NPCChatDialogViewNode>()); } // Remove dead nodes foreach (var deadNode in ret.Where(x => x.IsDead)) { NotifyNodeDestroyed(deadNode); } Debug.Assert(ret.All(x => x.ChatItemAsDialogItem == dialogItem)); return(ret); }
/// <summary> /// Gets all of the <see cref="NPCChatResponseBase"/>s that direct to the given <paramref name="dialogItem"/>. /// </summary> /// <param name="dialogItem">The <see cref="NPCChatDialogItemBase"/> to find the source <see cref="NPCChatResponseBase"/> for.</param> /// <returns>All of the <see cref="NPCChatResponseBase"/>s that direct to the given <paramref name="dialogItem"/>.</returns> public IEnumerable <NPCChatResponseBase> GetSourceResponses(NPCChatDialogItemBase dialogItem) { var responses = GetResponses(); return(responses.Where(x => x.Page == dialogItem.ID)); }
/// <summary> /// Gets all of the <see cref="NPCChatResponseBase"/>s that direct to the given <paramref name="dialogItem"/>. /// </summary> /// <param name="dialogItem">The <see cref="NPCChatDialogItemBase"/> to find the source <see cref="NPCChatResponseBase"/> for.</param> /// <returns>All of the <see cref="NPCChatResponseBase"/>s that direct to the given <paramref name="dialogItem"/>.</returns> public IEnumerable<NPCChatResponseBase> GetSourceResponses(NPCChatDialogItemBase dialogItem) { var responses = GetResponses(); return responses.Where(x => x.Page == dialogItem.ID); }
public void SetPageIndex(NPCChatDialogItemID pageID, IEnumerable<byte> responsesToSkip) { _page = _dialog.GetDialogItem(pageID); if (_page == null) { const string errmsg = "Page `{0}` in dialog `{1}` is null. The Client should never be trying to set an invalid page."; if (log.IsErrorEnabled) log.ErrorFormat(errmsg, pageID, _dialog); Debug.Fail(string.Format(errmsg, pageID, _dialog)); EndDialog(); return; } if (responsesToSkip != null) _responses = _page.Responses.Where(x => !responsesToSkip.Contains(x.Value)).OrderBy(x => x.Value).ToArray(); else _responses = _page.Responses.OrderBy(x => x.Value).ToArray(); _dialogTextControl.Text = _page.Text; SetResponseOffset(0); IsVisible = true; }
/// <summary> /// Gets an IEnumerable of all the NPCChatDialogViewNodes that handle the given <paramref name="dialogItem"/>. /// This includes any NPCChatDialogViewNodes that redirect to the NPCChatDialogItemBase. /// </summary> /// <param name="dialogItem">The NPCChatDialogItemBase to find the NPCChatDialogViewNodes for.</param> /// <returns>An IEnumerable of all the NPCChatDialogViewNodes that handle the given /// <paramref name="dialogItem"/>.</returns> public IEnumerable<NPCChatDialogViewNode> GetNodesForDialogItem(NPCChatDialogItemBase dialogItem) { if (NPCChatDialog == null) return null; List<NPCChatDialogViewNode> ret; if (!_objToTreeNode.TryGetValue(dialogItem, out ret)) return Enumerable.Empty<NPCChatDialogViewNode>(); // Remove dead nodes foreach (var deadNode in ret.Where(x => x.IsDead)) { NotifyNodeDestroyed(deadNode); } Debug.Assert(ret.All(x => x.ChatItemAsDialogItem == dialogItem)); return ret; }
/// <summary> /// Gets the NPCChatDialogViewNode for the given NPCChatDialogItemBase. Nodes that redirect to the /// given NPCChatDialogItemBase are not included. /// </summary> /// <param name="dialogItem">The NPCChatDialogItemBase to find the NPCChatDialogViewNode for.</param> /// <returns>The NPCChatDialogViewNode for the given <paramref name="dialogItem"/>, or null if /// no NPCChatDialogViewNode was found that handles the given <paramref name="dialogItem"/>.</returns> public NPCChatDialogViewNode GetNodeForDialogItem(NPCChatDialogItemBase dialogItem) { if (NPCChatDialog == null) return null; List<NPCChatDialogViewNode> ret; if (!_objToTreeNode.TryGetValue(dialogItem, out ret)) return null; // Remove dead nodes foreach (var deadNode in ret.Where(x => x.IsDead)) { NotifyNodeDestroyed(deadNode); } Debug.Assert(ret.Count(x => x.ChatItemType == NPCChatDialogViewNodeItemType.DialogItem) <= 1, "Was only expected 0 or 1 TreeNodes to be directly for this dialogItem."); var r = ret.FirstOrDefault(x => x.ChatItemType == NPCChatDialogViewNodeItemType.DialogItem); Debug.Assert(r.ChatItemAsDialogItem == dialogItem); return r; }
/// <summary> /// Gets the text for a NPCChatDialogItemBase. /// </summary> /// <param name="item">The NPCChatDialogItemBase.</param> /// <returns>The text for a NPCChatDialogItemBase.</returns> static string GetText(NPCChatDialogItemBase item) { var text = item.Title; if (string.IsNullOrEmpty(text)) { text = item.Text; if (text.Length > 100) text = text.Substring(0, 100); } return text; }
/// <summary> /// Creates a NPCChatDialogViewNode as a child of this NPCChatDialogViewNode. /// </summary> /// <param name="dialogItem">The NPCChatDialogItemBase the child node will handle.</param> /// <returns>A NPCChatDialogViewNode as a child of this NPCChatDialogViewNode.</returns> NPCChatDialogViewNode CreateNode(NPCChatDialogItemBase dialogItem) { // Check if the node already exists var children = Nodes.OfType<NPCChatDialogViewNode>(); var retNode = children.FirstOrDefault( x => (x.ChatItemType == NPCChatDialogViewNodeItemType.DialogItem || x.ChatItemType == NPCChatDialogViewNodeItemType.Redirect) && x.ChatItemAsDialogItem == dialogItem); // Create the new node if needed if (retNode == null) { // Check if it has to be a redirect node var existingDialogNode = TreeViewCasted.GetNodeForDialogItem(dialogItem); if (existingDialogNode != null) retNode = new NPCChatDialogViewNode(this, existingDialogNode); else retNode = new NPCChatDialogViewNode(this, dialogItem); } return retNode; }
/// <summary> /// Attempts to start a chat dialog with the given <paramref name="npc"/>. /// </summary> /// <param name="npc">NPC to start the chat dialog with.</param> /// <returns>True if the dialog was started with the <paramref name="npc"/>; otherwise false.</returns> public bool StartChat(NPC npc) { // Check if the chat can be started if (!CanStartChat(npc)) return false; _chattingWith = npc; // Tell the client to open the dialog using (var pw = ServerPacket.StartChatDialog(npc.MapEntityIndex, ChatDialog.ID)) { _user.Send(pw, ServerMessageType.GUI); } // Get the first page to use var initialPage = ChatDialog.GetInitialDialogItem(); Debug.Assert(initialPage != null); _dialogItem = GetNextDialogPage(initialPage); // Tell the user which page to use NotifyUserOfNewPage(); return true; }
/// <summary> /// If the given <paramref name="page"/> is a dialog-less page, this will skip to the next page /// that contains dialog. If the <paramref name="page"/> has dialog, this will just return /// that same <paramref name="page"/>. /// </summary> /// <param name="page">The page to attempt to skip through.</param> /// <returns>The page to use, or null if the dialog has ended.</returns> NPCChatDialogItemBase GetNextDialogPage(NPCChatDialogItemBase page) { // Skip until we find a null page, or we are no longer at a branch while (page != null && page.IsBranch) { // Evaluate the branch to get the response var branchResponse = page.EvaluateBranch(_user, _chattingWith); // Make sure we execute any actions on the response if (branchResponse.Actions != null) { foreach (var action in branchResponse.Actions) { action.Execute(_user, _chattingWith); } } // Get the next dialog item page from the response page = ChatDialog.GetDialogItem(branchResponse.Page); } return page; }
/// <summary> /// Progresses the chat dialog by using the given <paramref name="responseIndex"/>. /// </summary> /// <param name="responseIndex">The index of the response to use for the current dialog page.</param> /// <exception cref="Exception">The <see cref="_responseConditionalFailureType"/> is invalid.</exception> public void EnterResponse(byte responseIndex) { // Ensure there is a chat session going on if (!IsChatting) { const string errmsg = "Could not enter response of index `{0}` since there is no chat session active."; if (log.IsErrorEnabled) log.ErrorFormat(errmsg, responseIndex); Debug.Fail(string.Format(errmsg, responseIndex)); return; } // Check for a valid range if (!_user.Intersects(_chattingWith)) { if (log.IsInfoEnabled) log.Info("Dialog aborted since the User is no longer near the target."); EndChat(); return; } // Get the response var response = _dialogItem.GetResponse(responseIndex); if (response == null) { EndChat(); return; } Debug.Assert(response.Value == responseIndex, "Something went wrong, and we got the wrong response. lolwtf?"); // Ensure the selected response index is allowed (response conditionals check) if (!response.CheckConditionals(_user, _chattingWith)) { #pragma warning disable 162 switch (_responseConditionalFailureType) { case ResponseConditionalFailureHandleType.EndDialog: EndChat(); return; case ResponseConditionalFailureHandleType.ResendDialogItem: NotifyUserOfNewPage(); return; default: throw new Exception("Invalid _responseConditionalFailureType."); } #pragma warning restore 162 } // Execute the actions if (response.Actions != null) { foreach (var action in response.Actions) { action.Execute(_user, _chattingWith); } } // Get the next page var nextPage = ChatDialog.GetDialogItem(response.Page); nextPage = GetNextDialogPage(nextPage); // Set the new page _dialogItem = nextPage; // Check if the dialog has ended, otherwise just notify the user of the new page if (_dialogItem == null) EndChat(); else NotifyUserOfNewPage(); }
/// <summary> /// Forces the chat session to end if it has not already. /// </summary> public void EndChat() { if (!IsChatting) return; _dialogItem = null; _chattingWith = null; NotifyUserOfNewPage(); }