예제 #1
0
 public void HighlightNode(SkillNode node, HighlightState newFlags)
 {
     if (newFlags == 0) return;
     if (nodeHighlights.ContainsKey(node))
         nodeHighlights[node] |= newFlags;
     else nodeHighlights.Add(node, newFlags);
 }
예제 #2
0
 /// <summary>
 ///  Adds a skill node to the graph. New nodes are automatically
 ///  connected to existing adjacent nodes.
 /// </summary>
 /// <param name="node">The skill node to be added.</param>
 /// <returns>The graph node that is added to the graph.</returns>
 public GraphNode AddNode(SkillNode node)
 {
     SingleNode graphNode = new SingleNode(node);
     NodeDict.Add(node, graphNode);
     CheckLinks(node);
     return graphNode;
 }
예제 #3
0
        // Builds a graph from an adjacency matrix.
        // Only the lower left half is checked.
        SearchGraph SearchGraphFromData(bool[,] adjacencyMatrix)
        {
            int n = adjacencyMatrix.GetUpperBound(0) + 1;
            // Don't screw this up.
            Assert.IsTrue(n == adjacencyMatrix.GetUpperBound(1) + 1);

            List<SkillNode> nodes = new List<SkillNode>();
            for (int i = 0; i < n; i++)
            {
                SkillNode node = new SkillNode();
                node.Id = (ushort)i;
                nodes.Add(node);
            }

            for (int i = 0; i < n; i++)
            {
                nodes[i].Neighbor = new List<SkillNode>();
                for (int j = 0; j < i; j++)
                {
                    if (adjacencyMatrix[i, j])
                    {
                        nodes[i].Neighbor.Add(nodes[j]);
                        // No directed edges atm.
                        nodes[j].Neighbor.Add(nodes[i]);
                    }
                }
            }

            SearchGraph graph = new SearchGraph();
            foreach (SkillNode node in nodes)
            {
                graph.AddNode(node);
            }
            return graph;
        }
예제 #4
0
 /// <summary>
 ///  Adds a skill node to the graph. New nodes are automatically
 ///  connected to existing adjacent nodes.
 /// </summary>
 /// <param name="node">The skill node to be added.</param>
 /// <returns>The graph node that is added to the graph.</returns>
 public GraphNode AddNode(SkillNode node)
 {
     var graphNode = new GraphNode(node.Id);
     NodeDict.Add(node, graphNode);
     CheckLinks(node);
     return graphNode;
 }
예제 #5
0
 public bool NodeHasHighlights(SkillNode node, HighlightState flags)
 {
     if (_nodeHighlights.ContainsKey(node))
     {
         return _nodeHighlights[node].HasFlag(flags);
     }
     return false;
 }
예제 #6
0
 public void HighlightNode(SkillNode node, HighlightState newFlags)
 {
     var flags = CleanFlags(node, newFlags);
     if (flags == 0) return;
     if (_nodeHighlights.ContainsKey(node))
         _nodeHighlights[node] |= flags;
     else _nodeHighlights.Add(node, flags);
 }
예제 #7
0
 public void UnhighlightNode(SkillNode node, HighlightState removeFlags)
 {
     if (_nodeHighlights.ContainsKey(node))
     {
         // Each flag only remains set if it's not one of the flags to be removed.
         HighlightState newState = _nodeHighlights[node] & ~removeFlags;
         if (newState == 0) _nodeHighlights.Remove(node);
         else _nodeHighlights[node] = newState;
     }
 }
예제 #8
0
 public void ToggleHighlightNode(SkillNode node, HighlightState toggleFlags)
 {
     if (toggleFlags == 0) return;
     if (nodeHighlights.ContainsKey(node))
     {
         nodeHighlights[node] ^= toggleFlags;
         if (nodeHighlights[node] == 0) nodeHighlights.Remove(node);
     }
     else nodeHighlights.Add(node, toggleFlags);
 }
예제 #9
0
 public void HighlightNode(SkillNode node, HighlightState newFlags)
 {
     if (newFlags == 0)
     {
         return;
     }
     if (nodeHighlights.ContainsKey(node))
     {
         nodeHighlights[node] |= newFlags;
     }
     else
     {
         nodeHighlights.Add(node, newFlags);
     }
 }
예제 #10
0
        private void DrawLinkBackgroundLayer(List <ushort[]> links)
        {
            picLinks = new DrawingVisual();
            var pen2 = new Pen(Brushes.DarkSlateGray, 20f);

            using (DrawingContext dc = picLinks.RenderOpen())
            {
                foreach (var nid in links)
                {
                    SkillNode n1 = Skillnodes[nid[0]];
                    SkillNode n2 = Skillnodes[nid[1]];
                    DrawConnection(dc, pen2, n1, n2);
                }
            }
        }
예제 #11
0
        public void DrawJewelHighlight(SkillNode node)
        {
            const int thickness = 10;
            var       radiusPen = new Pen(Brushes.Cyan, thickness);

            const int smallRadius  = 800 - thickness / 2;
            const int mediumRadius = 1200 - thickness / 2;
            const int largeRadius  = 1500 - thickness / 2;

            using (DrawingContext dc = picJewelHighlight.RenderOpen())
            {
                dc.DrawEllipse(null, radiusPen, node.Position, smallRadius, smallRadius);
                dc.DrawEllipse(null, radiusPen, node.Position, mediumRadius, mediumRadius);
                dc.DrawEllipse(null, radiusPen, node.Position, largeRadius, largeRadius);
            }
        }
예제 #12
0
 public void UnhighlightNode(SkillNode node, HighlightState removeFlags)
 {
     if (nodeHighlights.ContainsKey(node))
     {
         // Each flag only remains set if it's not one of the flags to be removed.
         HighlightState newState = nodeHighlights[node] & ~removeFlags;
         if (newState == 0)
         {
             nodeHighlights.Remove(node);
         }
         else
         {
             nodeHighlights[node] = newState;
         }
     }
 }
예제 #13
0
        public void HighlightNode(SkillNode node, HighlightState newFlags)
        {
            var flags = CleanFlags(node, newFlags);

            if (flags == 0)
            {
                return;
            }
            if (_nodeHighlights.ContainsKey(node))
            {
                _nodeHighlights[node] |= flags;
            }
            else
            {
                _nodeHighlights.Add(node, flags);
            }
        }
예제 #14
0
        private HashSet <ushort> GetAvailableNodes(HashSet <ushort> skilledNodes)
        {
            HashSet <ushort> availNodes = new HashSet <ushort>();

            foreach (ushort inode in skilledNodes)
            {
                SkillNode node = Skillnodes[inode];
                foreach (SkillNode skillNode in node.Neighbor)
                {
                    if (!CharName.Contains(skillNode.Name) && !SkilledNodes.Contains(skillNode.Id))
                    {
                        availNodes.Add(skillNode.Id);
                    }
                }
            }
            return(availNodes);
        }
예제 #15
0
 /// <summary>
 /// Changes the HighlightState of the node:
 /// ... <- None <- Checked <- Crossed <- None
 /// (preserves other HighlightStates than Checked and Crossed)
 /// </summary>
 /// <param name="node">Node to change the HighlightState for</param>
 public void CycleNodeTagBackward(SkillNode node)
 {
     if (_nodeHighlighter.NodeHasHighlights(node, HighlightState.Crossed))
     {
         _nodeHighlighter.UnhighlightNode(node, HighlightState.Crossed);
         _nodeHighlighter.HighlightNode(node, HighlightState.Checked);
     }
     else if (_nodeHighlighter.NodeHasHighlights(node, HighlightState.Checked))
     {
         _nodeHighlighter.UnhighlightNode(node, HighlightState.Checked);
     }
     else
     {
         _nodeHighlighter.HighlightNode(node, HighlightState.Crossed);
     }
     DrawHighlights(_nodeHighlighter);
 }
예제 #16
0
        private void CheckLinks(SkillNode node)
        {
            if (!NodeDict.ContainsKey(node)) return;
            GraphNode currentNode = NodeDict[node];

            foreach (SkillNode neighbor in node.Neighbor)
            {
                if (NodeDict.ContainsKey(neighbor))
                {
                    GraphNode adjacentNode = NodeDict[neighbor];

                    if (adjacentNode == currentNode) continue;

                    adjacentNode.AddNeighbor(currentNode);
                    currentNode.AddNeighbor(adjacentNode);
                }
            }
        }
예제 #17
0
 public void ToggleHighlightNode(SkillNode node, HighlightState toggleFlags)
 {
     if (toggleFlags == 0)
     {
         return;
     }
     if (nodeHighlights.ContainsKey(node))
     {
         nodeHighlights[node] ^= toggleFlags;
         if (nodeHighlights[node] == 0)
         {
             nodeHighlights.Remove(node);
         }
     }
     else
     {
         nodeHighlights.Add(node, toggleFlags);
     }
 }
예제 #18
0
        public void DrawPath(List <ushort> path)
        {
            var pen2 = new Pen(Brushes.LawnGreen, 15f);

            pen2.DashStyle = new DashStyle(new DoubleCollection {
                2
            }, 2);

            using (DrawingContext dc = picPathOverlay.RenderOpen())
            {
                for (int i = -1; i < path.Count - 1; i++)
                {
                    SkillNode n1 = i == -1
                        ? Skillnodes[path[i + 1]].Neighbor.First(sn => SkilledNodes.Contains(sn.Id))
                        : Skillnodes[path[i]];
                    SkillNode n2 = Skillnodes[path[i + 1]];

                    DrawConnection(dc, pen2, n1, n2);
                }
            }
        }
예제 #19
0
        public static void DecodeURL(string url, out HashSet <ushort> skillednodes, out int chartype)
        {
            skillednodes = new HashSet <ushort>();
            url          = Regex.Replace(url, @"\t| |\n|\r", "");
            string s =
                url.Substring(TreeAddress.Length + (url.StartsWith("https") ? 1 : 0))
                .Replace("-", "+")
                .Replace("_", "/");

            byte[] decbuff = Convert.FromBase64String(s);
            int    i       = BitConverter.ToInt32(new[] { decbuff[3], decbuff[2], decbuff[1], decbuff[1] }, 0);
            byte   b       = decbuff[4];
            long   j       = 0L;

            if (i > 0)
            {
                j = decbuff[5];
            }
            var nodes = new List <UInt16>();

            for (int k = 6; k < decbuff.Length; k += 2)
            {
                byte[] dbff = { decbuff[k + 1], decbuff[k + 0] };
                if (Skillnodes.Keys.Contains(BitConverter.ToUInt16(dbff, 0)))
                {
                    nodes.Add((BitConverter.ToUInt16(dbff, 0)));
                }
            }
            chartype = b;


            SkillNode startnode = Skillnodes.First(nd => nd.Value.Name.ToUpper() == CharName[b].ToUpper()).Value;

            skillednodes.Add(startnode.Id);
            foreach (ushort node in nodes)
            {
                skillednodes.Add(node);
            }
        }
예제 #20
0
 private void DrawConnection(DrawingContext dc, Pen pen2, SkillNode n1, SkillNode n2)
 {
     if (n1.SkillNodeGroup == n2.SkillNodeGroup && n1.Orbit == n2.Orbit)
     {
         if (n1.Arc - n2.Arc > 0 && n1.Arc - n2.Arc <= Math.PI ||
             n1.Arc - n2.Arc < -Math.PI)
         {
             dc.DrawArc(null, pen2, n1.Position, n2.Position,
                        new Size(SkillNode.OrbitRadii[n1.Orbit],
                                 SkillNode.OrbitRadii[n1.Orbit]));
         }
         else
         {
             dc.DrawArc(null, pen2, n2.Position, n1.Position,
                        new Size(SkillNode.OrbitRadii[n1.Orbit],
                                 SkillNode.OrbitRadii[n1.Orbit]));
         }
     }
     else
     {
         dc.DrawLine(pen2, n1.Position, n2.Position);
     }
 }
예제 #21
0
 private void DrawConnection(DrawingContext dc, Pen pen2, SkillNode n1, SkillNode n2)
 {
     if (n1.VisibleNeighbors.Contains(n2) && n2.VisibleNeighbors.Contains(n1))
     {
         if (n1.SkillNodeGroup == n2.SkillNodeGroup && n1.Orbit == n2.Orbit)
         {
             if (n1.Arc - n2.Arc > 0 && n1.Arc - n2.Arc <= Math.PI ||
                 n1.Arc - n2.Arc < -Math.PI)
             {
                 dc.DrawArc(null, pen2, n1.Position, n2.Position,
                            new Size(SkillNode.OrbitRadii[n1.Orbit],
                                     SkillNode.OrbitRadii[n1.Orbit]));
             }
             else
             {
                 dc.DrawArc(null, pen2, n2.Position, n1.Position,
                            new Size(SkillNode.OrbitRadii[n1.Orbit],
                                     SkillNode.OrbitRadii[n1.Orbit]));
             }
         }
         else
         {
             var draw = true;
             foreach (var attibute in n1.attributes)
             {
                 if (AscendantClassStartRegex.IsMatch(attibute))
                 {
                     draw = false;
                 }
             }
             if (draw)
             {
                 dc.DrawLine(pen2, n1.Position, n2.Position);
             }
         }
     }
 }
예제 #22
0
 public void ToggleNodeHighlight(SkillNode node)
 {
     _nodeHighlighter.ToggleHighlightNode(node, HighlightState.FromNode);
     DrawHighlights(_nodeHighlighter);
 }
예제 #23
0
        public static Dictionary <string, List <float> > GetAttributesWithoutImplicit(IEnumerable <ushort> skilledNodes, int chartype)
        {
            var temp = new Dictionary <string, List <float> >();

            foreach (var attr in CharBaseAttributes[chartype])
            {
                if (!temp.ContainsKey(attr.Key))
                {
                    temp[attr.Key] = new List <float>();
                }

                if (temp.ContainsKey(attr.Key) && temp[attr.Key].Count > 0)
                {
                    temp[attr.Key][0] += attr.Value;
                }
                else
                {
                    temp[attr.Key].Add(attr.Value);
                }
            }

            foreach (var attr in BaseAttributes)
            {
                if (!temp.ContainsKey(attr.Key))
                {
                    temp[attr.Key] = new List <float>();
                }

                if (temp.ContainsKey(attr.Key) && temp[attr.Key].Count > 0)
                {
                    temp[attr.Key][0] += attr.Value;
                }
                else
                {
                    temp[attr.Key].Add(attr.Value);
                }
            }

            foreach (ushort inode in skilledNodes)
            {
                SkillNode node = Skillnodes[inode];
                foreach (var attr in ExpandHybridAttributes(node.Attributes))
                {
                    if (!temp.ContainsKey(attr.Key))
                    {
                        temp[attr.Key] = new List <float>();
                    }
                    for (int i = 0; i < attr.Value.Count; i++)
                    {
                        if (temp.ContainsKey(attr.Key) && temp[attr.Key].Count > i)
                        {
                            temp[attr.Key][i] += attr.Value[i];
                        }
                        else
                        {
                            temp[attr.Key].Add(attr.Value[i]);
                        }
                    }
                }
            }

            return(temp);
        }
예제 #24
0
 private static void DrawConnection(DrawingContext dc, Pen pen2, SkillNode n1, SkillNode n2)
 {
     if (!n1.VisibleNeighbors.Contains(n2) || !n2.VisibleNeighbors.Contains(n1)) return;
     if (n1.SkillNodeGroup == n2.SkillNodeGroup && n1.Orbit == n2.Orbit)
     {
         if (n1.Arc - n2.Arc > 0 && n1.Arc - n2.Arc <= Math.PI ||
             n1.Arc - n2.Arc < -Math.PI)
         {
             dc.DrawArc(null, pen2, n1.Position, n2.Position,
                 new Size(SkillNode.OrbitRadii[n1.Orbit],
                     SkillNode.OrbitRadii[n1.Orbit]));
         }
         else
         {
             dc.DrawArc(null, pen2, n2.Position, n1.Position,
                 new Size(SkillNode.OrbitRadii[n1.Orbit],
                     SkillNode.OrbitRadii[n1.Orbit]));
         }
     }
     else
     {
         var draw = true;
         foreach (var attibute in n1.attributes)
         {
             if (AscendantClassStartRegex.IsMatch(attibute))
                 draw = false;
         }
         if (n1.Type == NodeType.Mastery || n2.Type == NodeType.Mastery)
             draw = false;
         if (draw)
             dc.DrawLine(pen2, n1.Position, n2.Position);
     }
 }
예제 #25
0
        /// <summary>
        ///     Loads from the unofficial online tool
        /// </summary>
        public static async Task LoadBuildFromPoezone(IDialogCoordinator dialogCoordinator, SkillTree tree, string buildUrl)
        {
            if (!buildUrl.Contains('#'))
            {
                throw new FormatException();
            }

            const string dataUrl      = "http://poezone.ru/skilltree/data.js";
            const string buildPostUrl = "http://poezone.ru/skilltree/";
            string       build        = buildUrl.Substring(buildUrl.LastIndexOf('#') + 1);

            string dataFile, buildFile;

            {
                var req = (HttpWebRequest)WebRequest.Create(dataUrl);
                req.UserAgent =
                    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.30 (KHTML, like Gecko) Iron/12.0.750.0 Chrome/12.0.750.0 Safari/534.30";
                WebResponse resp = req.GetResponse();
                dataFile = new StreamReader(resp.GetResponseStream()).ReadToEnd();
            }

            {
                string postData  = "build=" + build;
                byte[] postBytes = Encoding.ASCII.GetBytes(postData);
                var    req       = (HttpWebRequest)WebRequest.Create(buildPostUrl);
                req.Method        = "POST";
                req.ContentLength = postBytes.Length;
                req.ContentType   = "application/x-www-form-urlencoded";
                req.UserAgent     =
                    "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.30 (KHTML, like Gecko) Iron/12.0.750.0 Chrome/12.0.750.0 Safari/534.30";
                req.Accept  = "application/json, text/javascript, */*; q=0.01";
                req.Host    = "poezone.ru";
                req.Referer = "http://poezone.ru/skilltree/";
                req.AutomaticDecompression = DecompressionMethods.GZip;
                req.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.3");
                req.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
                req.Headers.Add("Accept-Language", "en-US,en;q=0.8");
                req.Headers.Add("Origin", "http://poezone.ru");
                req.Headers.Add("X-Requested-With", "XMLHttpRequest");
                req.Expect      = "";
                req.Credentials = CredentialCache.DefaultCredentials;

                Stream dataStream = req.GetRequestStream();
                dataStream.Write(postBytes, 0, postBytes.Length);
                dataStream.Close();

                WebResponse resp = req.GetResponse();
                buildFile = new StreamReader(resp.GetResponseStream()).ReadToEnd();
            }

            if (!buildFile.Contains("["))
            {
                await dialogCoordinator.ShowErrorAsync(tree, string.Format(
                                                           L10n.Message("An error occured while attempting to load Skill tree from {0} location."),
                                                           "poezone.ru"));

                return;
            }

            // position decompose
            var positions = new List <Vector2D?>();

            string[] lines = dataFile.Split('\n');
            foreach (string line in lines)
            {
                if (line.StartsWith("skillpos="))
                {
                    string posString = line.Substring(line.IndexOf('[') + 1,
                                                      line.LastIndexOf(']') - line.IndexOf('[') - 1);
                    var  sb        = new StringBuilder();
                    bool inBracket = false;
                    foreach (char c in posString)
                    {
                        if (!inBracket && c == ',')
                        {
                            positions.Add(sb.Length == 0
                                ? null
                                : new Vector2D?(new Vector2D(
                                                    int.Parse(sb.ToString().Split(',')[0]),
                                                    int.Parse(sb.ToString().Split(',')[1])
                                                    )));
                            sb.Clear();
                        }
                        else
                        {
                            if (c == '[')
                            {
                                inBracket = true;
                            }
                            else if (c == ']')
                            {
                                inBracket = false;
                            }
                            else
                            {
                                sb.Append(c);
                            }
                        }
                    }
                    positions.Add(sb.Length == 0
                        ? null
                        : new Vector2D?(new Vector2D(
                                            int.Parse(sb.ToString().Split(',')[0]),
                                            int.Parse(sb.ToString().Split(',')[1])
                                            )));
                }
            }

            // min max
            double minx = float.MaxValue, miny = float.MaxValue, maxx = float.MinValue, maxy = float.MinValue;

            foreach (var posn in positions)
            {
                if (!posn.HasValue)
                {
                    continue;
                }
                Vector2D pos = posn.Value;
                minx = Math.Min(pos.X, minx);
                miny = Math.Min(pos.Y, miny);
                maxx = Math.Max(pos.X, maxx);
                maxy = Math.Max(pos.Y, maxy);
            }

            double nminx = float.MaxValue, nminy = float.MaxValue, nmaxx = float.MinValue, nmaxy = float.MinValue;

            foreach (SkillNode node in SkillTree.Skillnodes.Values)
            {
                Vector2D pos = node.Position;
                nminx = Math.Min(pos.X, nminx);
                nminy = Math.Min(pos.Y, nminy);
                nmaxx = Math.Max(pos.X, nmaxx);
                nmaxy = Math.Max(pos.Y, nmaxy);
            }

            //respose
            string[] buildResp = buildFile.Replace("[", "").Replace("]", "").Split(',');
            int      character = int.Parse(buildResp[0]);
            var      skilled   = new List <int>();

            tree.Chartype = character;
            tree.SkilledNodes.Clear();
            SkillNode startnode =
                SkillTree.Skillnodes.First(nd => nd.Value.Name == SkillTree.CharName[tree.Chartype].ToUpper()).Value;

            tree.AllocateSkillNode(startnode);

            for (int i = 1; i < buildResp.Length; ++i)
            {
                if (!positions[int.Parse(buildResp[i])].HasValue)
                {
                    Debugger.Break();
                }

                Vector2D poezonePos = (positions[int.Parse(buildResp[i])].Value - new Vector2D(minx, miny)) *
                                      new Vector2D(1 / (maxx - minx), 1 / (maxy - miny));
                double minDis  = 2;
                var    minNode = new KeyValuePair <ushort, SkillNode>();
                foreach (var node in SkillTree.Skillnodes)
                {
                    Vector2D nodePos = (node.Value.Position - new Vector2D(nminx, nminy)) *
                                       new Vector2D(1 / (nmaxx - nminx), 1 / (nmaxy - nminy));
                    double dis = (nodePos - poezonePos).Length;
                    if (dis < minDis)
                    {
                        minDis  = dis;
                        minNode = node;
                    }
                }

                tree.AllocateSkillNode(minNode.Value);
            }
        }
예제 #26
0
 private void DrawConnection(DrawingContext dc, Pen pen2, SkillNode n1, SkillNode n2)
 {
     if (n1.SkillNodeGroup == n2.SkillNodeGroup && n1.Orbit == n2.Orbit)
     {
         if (n1.Arc - n2.Arc > 0 && n1.Arc - n2.Arc <= Math.PI ||
             n1.Arc - n2.Arc < -Math.PI)
         {
             dc.DrawArc(null, pen2, n1.Position, n2.Position,
                 new Size(SkillNode.OrbitRadii[n1.Orbit],
                     SkillNode.OrbitRadii[n1.Orbit]));
         }
         else
         {
             dc.DrawArc(null, pen2, n2.Position, n1.Position,
                 new Size(SkillNode.OrbitRadii[n1.Orbit],
                     SkillNode.OrbitRadii[n1.Orbit]));
         }
     }
     else
     {
         dc.DrawLine(pen2, n1.Position, n2.Position);
     }
 }
예제 #27
0
 public void ToggleNodeHighlight(SkillNode node)
 {
     _nodeHighlighter.ToggleHighlightNode(node, HighlightState.FromNode);
     DrawHighlights(_nodeHighlighter);
 }
예제 #28
0
 /// <summary>
 /// Returns flags without HighlightState.Tags if the node is an ascendancy node.
 /// Returns flags unchanged if it is not.
 /// </summary>
 private static HighlightState CleanFlags(SkillNode node, HighlightState flags)
 {
     if (node.ascendancyName == null) return flags;
     return flags & ~HighlightState.Tags;
 }
예제 #29
0
        public void ForceRefundNode(SkillNode node)
        {
            if (!SkilledNodes.Contains(node)) return;
            var charStartNode = GetCharNode();
            var front = new HashSet<SkillNode>() { charStartNode };
            foreach (var i in charStartNode.Neighbor)
                if (SkilledNodes.Contains(i) && i != node)
                    front.Add(i);
            var reachable = new HashSet<SkillNode>(front);

            while (front.Any())
            {
                var newFront = new HashSet<SkillNode>();
                foreach (var i in front)
                {
                    foreach (var j in i.Neighbor)
                    {
                        if (reachable.Contains(j) || !SkilledNodes.Contains(j) || j == node) continue;
                        newFront.Add(j);
                        reachable.Add(j);
                    }
                }
                front = newFront;
            }
            var removable = SkilledNodes.Except(reachable).ToList();
            SkilledNodes.ExceptWith(removable);
        }
예제 #30
0
        public HashSet<SkillNode> ForceRefundNodePreview(SkillNode node)
        {
            if (!SkilledNodes.Contains(node)) return new HashSet<SkillNode>();

            var charStartNode = GetCharNode();
            var front = new HashSet<SkillNode>() { charStartNode };
            foreach (var i in charStartNode.Neighbor)
                if (SkilledNodes.Contains(i) && i != node)
                    front.Add(i);
            var reachable = new HashSet<SkillNode>(front);

            while (front.Any())
            {
                var newFront = new HashSet<SkillNode>();
                foreach (var i in front)
                {
                    foreach (var j in i.Neighbor)
                    {
                        if (j == node || reachable.Contains(j) || !SkilledNodes.Contains(j)) continue;
                        newFront.Add(j);
                        reachable.Add(j);
                    }
                }
                front = newFront;
            }
            var unreachable = new HashSet<SkillNode>(SkilledNodes);
            unreachable.ExceptWith(reachable);
            return unreachable;
        }
예제 #31
0
        public List<SkillNode> GetShortestPathTo(SkillNode targetNode, IEnumerable<SkillNode> start)
        {
            var startNodes = start as IList<SkillNode> ?? start.ToList();
            if (startNodes.Contains(targetNode))
                return new List<SkillNode>();
            var adjacent = GetAvailableNodes(startNodes);
            if (adjacent.Contains(targetNode))
                return new List<SkillNode> { targetNode };

            var visited = new HashSet<SkillNode>(startNodes);
            var distance = new Dictionary<SkillNode, int>();
            var parent = new Dictionary<SkillNode, SkillNode>();
            var newOnes = new Queue<SkillNode>();
            var toOmit = new HashSet<SkillNode>(
                         from entry in _nodeHighlighter.NodeHighlights
                         where entry.Value.HasFlag(HighlightState.Crossed)
                         select entry.Key);

            foreach (var node in adjacent)
            {
                if (toOmit.Contains(node))
                {
                    continue;
                }
                newOnes.Enqueue(node);
                distance.Add(node, 1);
            }

            while (newOnes.Count > 0)
            {
                var newNode = newOnes.Dequeue();
                var dis = distance[newNode];
                visited.Add(newNode);
                foreach (var connection in newNode.Neighbor)
                {
                    if (toOmit.Contains(connection))
                        continue;
                    if (visited.Contains(connection))
                        continue;
                    if (distance.ContainsKey(connection))
                        continue;
                    if (newNode.Spc.HasValue)
                        continue;
                    if (newNode.Type == NodeType.Mastery)
                        continue;
                    if (IsAscendantClassStartNode(newNode))
                        continue;
                    distance.Add(connection, dis + 1);
                    newOnes.Enqueue(connection);

                    parent.Add(connection, newNode);

                    if (connection == targetNode)
                    {
                        newOnes.Clear();
                        break;
                    }
                }
            }

            if (!distance.ContainsKey(targetNode))
                return new List<SkillNode>();

            var curr = targetNode;
            var result = new List<SkillNode> { curr };
            while (parent.ContainsKey(curr))
            {
                result.Add(parent[curr]);
                curr = parent[curr];
            }
            result.Reverse();
            return result;
        }
예제 #32
0
 /// <summary>
 /// Returns true iff node is a Ascendant "Path of the ..." node.
 /// </summary>
 public static bool IsAscendantClassStartNode(SkillNode node)
 {
     return node.attributes.Any(s => AscendantClassStartRegex.IsMatch(s));
 }
예제 #33
0
        public void DrawJewelHighlight(SkillNode node)
        {
            const int thickness = 10;
            var radiusPen = new Pen(Brushes.Cyan, thickness);

            const int smallRadius = 800 - thickness / 2;
            const int mediumRadius = 1200 - thickness / 2;
            const int largeRadius = 1500 - thickness / 2;

            using (DrawingContext dc = picJewelHighlight.RenderOpen())
            {
                dc.DrawEllipse(null, radiusPen, node.Position, smallRadius, smallRadius);
                dc.DrawEllipse(null, radiusPen, node.Position, mediumRadius, mediumRadius);
                dc.DrawEllipse(null, radiusPen, node.Position, largeRadius, largeRadius);
            }
        }
예제 #34
0
        private void DrawSurround(DrawingContext dc, SkillNode node, bool onlyAscendancy = false, bool isActive = false, bool isHighlight = false)
        {
            if (onlyAscendancy && node.ascendancyName == null) return;
            var surroundBrush = _nodeSurroundBrushes;
            var factor = 1f;
            var activeOffset = 0;
            if (isActive)
                activeOffset = 1;
            if (isHighlight)
            {
                surroundBrush = _nodeSurroundComparisonBrushes;
                factor = HighlightFactor;
            }
            var ascendancyClassName = AscClasses.GetClassName(_chartype, AscType);

            if (node.IsAscendancyStart)
            {
                if (!DrawAscendancy || isHighlight || isActive) return;

                const string ascStartName = "PassiveSkillScreenAscendancyMiddle";
                var bitmap = Assets[ascStartName];
                var brush = new ImageBrush(Assets[ascStartName]);
                if (_persistentData.Options.ShowAllAscendancyClasses || node.ascendancyName == ascendancyClassName)
                    dc.DrawRectangle(brush, null,
                        new Rect(node.Position - new Vector2D(bitmap.PixelWidth, bitmap.PixelHeight),
                                new Size(bitmap.PixelWidth * 2, bitmap.PixelHeight * 2)));
            }
            else if (node.ascendancyName != null && node.Type == NodeType.Notable)
            {
                if (!DrawAscendancy) return;

                if (_persistentData.Options.ShowAllAscendancyClasses || node.ascendancyName == ascendancyClassName)
                    dc.DrawRectangle(surroundBrush[10 + activeOffset].Value, null,
                        new Rect((int)node.Position.X - surroundBrush[10 + activeOffset].Key.Width * .875 * factor,
                            (int)node.Position.Y - surroundBrush[10 + activeOffset].Key.Height * .875 * factor,
                            surroundBrush[10 + activeOffset].Key.Width * 1.75 * factor,
                            surroundBrush[10 + activeOffset].Key.Height * 1.75 * factor));
            }
            else if (node.ascendancyName != null && node.Type == NodeType.Normal)
            {
                if (!DrawAscendancy) return;

                if (_persistentData.Options.ShowAllAscendancyClasses || node.ascendancyName == ascendancyClassName)
                    dc.DrawRectangle(surroundBrush[8 + activeOffset].Value, null,
                        new Rect((int)node.Position.X - surroundBrush[8 + activeOffset].Key.Width * factor,
                            (int)node.Position.Y - surroundBrush[8 + activeOffset].Key.Height * factor,
                            surroundBrush[8 + activeOffset].Key.Width * 2 * factor,
                            surroundBrush[8 + activeOffset].Key.Height * 2 * factor));
            }
            else if (node.Type == NodeType.Notable)
            {
                dc.DrawRectangle(surroundBrush[2 + activeOffset].Value, null,
                    new Rect((int)node.Position.X - surroundBrush[2 + activeOffset].Key.Width * factor,
                        (int)node.Position.Y - surroundBrush[2 + activeOffset].Key.Height * factor,
                        surroundBrush[2 + activeOffset].Key.Width * 2 * factor,
                        surroundBrush[2 + activeOffset].Key.Height * 2 * factor));
            }
            else if (node.Type == NodeType.Keystone)
            {
                dc.DrawRectangle(surroundBrush[4 + activeOffset].Value, null,
                    new Rect((int)node.Position.X - surroundBrush[4 + activeOffset].Key.Width * factor,
                        (int)node.Position.Y - surroundBrush[4 + activeOffset].Key.Height * factor,
                        surroundBrush[4 + activeOffset].Key.Width * 2 * factor,
                        surroundBrush[4 + activeOffset].Key.Height * 2 * factor));
            }
            else if (node.Type == NodeType.Mastery)
            {
                //Needs to be here so that "Masteries" (Middle images of nodes) don't get anything drawn around them.
            }
            else if (node.Type == NodeType.JewelSocket)
            {
                dc.DrawRectangle(surroundBrush[6 + activeOffset].Value, null,
                    new Rect((int)node.Position.X - surroundBrush[6 + activeOffset].Key.Width * factor,
                        (int)node.Position.Y - surroundBrush[6 + activeOffset].Key.Height * factor,
                        surroundBrush[6 + activeOffset].Key.Width * 2 * factor,
                        surroundBrush[6 + activeOffset].Key.Height * 2 * factor));
            }
            else
            {
                dc.DrawRectangle(surroundBrush[0 + activeOffset].Value, null,
                    new Rect((int)node.Position.X - surroundBrush[0 + activeOffset].Key.Width * factor,
                        (int)node.Position.Y - surroundBrush[0 + activeOffset].Key.Height * factor,
                        surroundBrush[0 + activeOffset].Key.Width * 2 * factor,
                        surroundBrush[0 + activeOffset].Key.Height * 2 * factor));
            }
        }
예제 #35
0
 public void AllocateSkillNode(SkillNode node, bool bulk = false)
 {
     if (node == null) return;
     if (node.IsAscendancyStart)
     {
         var remove = SkilledNodes.Where(x => x.ascendancyName != null && x.ascendancyName != node.ascendancyName).ToArray();
         ChangeAscClass(AscClasses.GetClassNumber(node.ascendancyName));
         SkilledNodes.ExceptWith(remove);
     }
     else if (node.IsMultipleChoiceOption)
     {
         var remove = SkilledNodes.Where(x => x.IsMultipleChoiceOption && AscClasses.GetStartingClass(node.Name) == AscClasses.GetStartingClass(x.Name)).ToArray();
         SkilledNodes.ExceptWith(remove);
     }
     if (!bulk)
         SkilledNodes.Add(node);
 }
예제 #36
0
        private void DrawSkillNodeIcon(DrawingContext dc, SkillNode skillNode, bool onlyAscendancy = false, bool isActive = false)
        {
            if (onlyAscendancy && skillNode.ascendancyName == null) return;

            Rect rect;
            BitmapImage bitmapImage;

            if (isActive)
            {
                rect = IconActiveSkills.SkillPositions[skillNode.IconKey];
                bitmapImage = IconActiveSkills.GetSkillImage(skillNode.IconKey);
            }
            else
            {
                rect = IconInActiveSkills.SkillPositions[skillNode.IconKey];
                bitmapImage = IconInActiveSkills.GetSkillImage(skillNode.IconKey);
            }

            var imageBrush = new ImageBrush()
            {
                Stretch = Stretch.Uniform,
                ImageSource = bitmapImage,
                ViewboxUnits = BrushMappingMode.RelativeToBoundingBox,
                Viewbox = new Rect(rect.X / bitmapImage.PixelWidth, rect.Y / bitmapImage.PixelHeight,
                       rect.Width / bitmapImage.PixelWidth, rect.Height / bitmapImage.PixelHeight)
            };

            dc.DrawEllipse(imageBrush, null, skillNode.Position, rect.Width, rect.Height);
        }
예제 #37
0
 /// <summary>
 /// Changes the HighlightState of the node:
 /// None -> FromNode -> Crossed -> None -> ...
 /// (preserves other HighlightStates than FromNode and Crossed)
 /// </summary>
 /// <param name="node">Node to change the HighlightState for</param>
 public void CycleNodeHighlightForward(SkillNode node)
 {
     if (_nodeHighlighter.NodeHasHighlights(node, HighlightState.FromNode))
     {
         _nodeHighlighter.UnhighlightNode(node, HighlightState.FromNode);
         _nodeHighlighter.HighlightNode(node, HighlightState.Crossed);
     }
     else if (_nodeHighlighter.NodeHasHighlights(node, HighlightState.Crossed))
     {
         _nodeHighlighter.UnhighlightNode(node, HighlightState.Crossed);
     }
     else
     {
         _nodeHighlighter.HighlightNode(node, HighlightState.FromNode);
     }
     DrawHighlights(_nodeHighlighter);
 }
예제 #38
0
 public SingleNode(SkillNode baseNode)
     : base(baseNode.Id)
 { }
예제 #39
0
        private async Task InitializeAsync(string treestring, string opsstring, [CanBeNull] ProgressDialogController controller,
            AssetLoader assetLoader)
        {
            if (!_initialized)
            {
                var jss = new JsonSerializerSettings
                {
                    Error = (sender, args) =>
                    {
                        // This one is known: "515":{"x":_,"y":_,"oo":[],"n":[]}} has an Array in "oo".
                        if (args.ErrorContext.Path != "groups.515.oo")
                            Log.Error("Exception while deserializing Json tree", args.ErrorContext.Error);
                        args.ErrorContext.Handled = true;
                    }
                };

                var inTree = JsonConvert.DeserializeObject<PoESkillTree>(treestring, jss);
                var inOpts = JsonConvert.DeserializeObject<Opts>(opsstring, jss);

                controller?.SetProgress(0.25);
                await assetLoader.DownloadSkillNodeSpritesAsync(inTree, d => controller?.SetProgress(0.25 + d * 0.30));
                IconInActiveSkills = new SkillIcons();
                IconActiveSkills = new SkillIcons();
                foreach (var obj in inTree.skillSprites)
                {
                    SkillIcons icons;
                    string prefix;
                    if (obj.Key.EndsWith("Active"))
                    {
                        // Adds active nodes to IconActiveSkills
                        icons = IconActiveSkills;
                        prefix = obj.Key.Substring(0, obj.Key.Length - "Active".Length);
                    }
                    else if (obj.Key.EndsWith("Inactive"))
                    {
                        // Adds inactive nodes to IconInActiveSkills
                        icons = IconInActiveSkills;
                        prefix = obj.Key.Substring(0, obj.Key.Length - "Inactive".Length);
                    }
                    else
                    {
                        // Adds masteries to IconInActiveSkills
                        icons = IconInActiveSkills;
                        prefix = obj.Key;
                    }
                    var sprite = obj.Value[AssetZoomLevel];
                    var path = _assetsFolderPath + sprite.filename;
                    icons.Images[sprite.filename] = ImageHelper.OnLoadBitmapImage(new Uri(path, UriKind.Absolute));
                    foreach (var o in sprite.coords)
                    {
                        var iconKey = prefix + "_" + o.Key;
                        icons.SkillPositions[iconKey] = new Rect(o.Value.x, o.Value.y, o.Value.w, o.Value.h);
                        icons.SkillImages[iconKey] = sprite.filename;
                    }
                }

                controller?.SetProgress(0.55);
                // The last percent progress is reserved for rounding errors as progress must not get > 1.
                await assetLoader.DownloadAssetsAsync(inTree, d => controller?.SetProgress(0.55 + d * 0.44));
                foreach (var ass in inTree.assets)
                {
                    var path = _assetsFolderPath + ass.Key + ".png";
                    Assets[ass.Key] = ImageHelper.OnLoadBitmapImage(new Uri(path, UriKind.Absolute));
                }

                RootNodeList = new List<int>();
                if (inTree.root != null)
                {
                    foreach (int i in inTree.root.ot)
                    {
                        RootNodeList.Add(i);
                    }
                }
                else if (inTree.main != null)
                {
                    foreach (int i in inTree.main.ot)
                    {
                        RootNodeList.Add(i);
                    }
                }

                _ascClasses = new AscendancyClasses();
                if (inOpts != null)
                {
                    foreach (KeyValuePair<int, baseToAscClass> ascClass in inOpts.ascClasses)
                    {
                        var classes = new List<AscendancyClasses.Class>();
                        foreach (KeyValuePair<int, classes> asc in ascClass.Value.classes)
                        {
                            var newClass = new AscendancyClasses.Class
                            {
                                Order = asc.Key,
                                DisplayName = asc.Value.displayName,
                                Name = asc.Value.name,
                                FlavourText = asc.Value.flavourText,
                                FlavourTextColour = asc.Value.flavourTextColour.Split(',').Select(int.Parse).ToArray()
                            };
                            int[] tempPointList = asc.Value.flavourTextRect.Split(',').Select(int.Parse).ToArray();
                            newClass.FlavourTextRect = new Vector2D(tempPointList[0], tempPointList[1]);
                            classes.Add(newClass);

                        }
                        AscClasses.Classes.Add(ascClass.Value.name, classes);
                    }
                }

                CharBaseAttributes = new Dictionary<string, float>[7];
                foreach (var c in inTree.characterData)
                {
                    CharBaseAttributes[c.Key] = new Dictionary<string, float>
                    {
                        {"+# to Strength", c.Value.base_str},
                        {"+# to Dexterity", c.Value.base_dex},
                        {"+# to Intelligence", c.Value.base_int}
                    };
                }

                Skillnodes = new Dictionary<ushort, SkillNode>();
                RootNodeClassDictionary = new Dictionary<string, int>();
                StartNodeDictionary = new Dictionary<int, int>();
                AscRootNodeList = new HashSet<SkillNode>();

                foreach (var nd in inTree.nodes)
                {
                    var skillNode = new SkillNode
                    {
                        Id = nd.id,
                        Name = nd.dn,
                        //this value should not be split on '\n' as it causes the attribute list to seperate nodes
                        attributes = nd.dn.Contains("Jewel Socket") ? new[] { "+1 Jewel Socket" } : nd.sd,
                        Orbit = nd.o,
                        OrbitIndex = nd.oidx,
                        Icon = nd.icon,
                        LinkId = nd.ot,
                        G = nd.g,
                        Da = nd.da,
                        Ia = nd.ia,
                        Sa = nd.sa,
                        Spc = nd.spc.Length > 0 ? (int?)nd.spc[0] : null,
                        IsMultipleChoice = nd.isMultipleChoice,
                        IsMultipleChoiceOption = nd.isMultipleChoiceOption,
                        passivePointsGranted = nd.passivePointsGranted,
                        ascendancyName = nd.ascendancyName,
                        IsAscendancyStart = nd.isAscendancyStart,
                        reminderText = nd.reminderText
                    };
                    if (nd.ks && !nd.not && !nd.isJewelSocket && !nd.m)
                    {
                        skillNode.Type = NodeType.Keystone;
                    }
                    else if (!nd.ks && nd.not && !nd.isJewelSocket && !nd.m)
                    {
                        skillNode.Type = NodeType.Notable;
                    }
                    else if (!nd.ks && !nd.not && nd.isJewelSocket && !nd.m)
                    {
                        skillNode.Type = NodeType.JewelSocket;
                    }
                    else if (!nd.ks && !nd.not && !nd.isJewelSocket && nd.m)
                    {
                        skillNode.Type = NodeType.Mastery;
                    }
                    else if (!nd.ks && !nd.not && !nd.isJewelSocket && !nd.m)
                    {
                        skillNode.Type = NodeType.Normal;
                    }
                    else
                    {
                        throw new InvalidOperationException($"Invalid node type for node {skillNode.Name}");
                    }
                    Skillnodes.Add(nd.id, skillNode);
                    if(skillNode.IsAscendancyStart)
                        if(!AscRootNodeList.Contains(skillNode))
                            AscRootNodeList.Add(skillNode);
                    if (RootNodeList.Contains(nd.id))
                    {
                        if (!RootNodeClassDictionary.ContainsKey(nd.dn.ToUpperInvariant()))
                        {
                            RootNodeClassDictionary.Add(nd.dn.ToUpperInvariant(), nd.id);
                        }
                        foreach (var linkedNode in nd.ot)
                        {
                            if (!StartNodeDictionary.ContainsKey(nd.id) && !nd.isAscendancyStart)
                            {
                                StartNodeDictionary.Add(linkedNode, nd.id);
                            }
                        }
                    }
                    foreach (var node in nd.ot)
                    {
                        if (!StartNodeDictionary.ContainsKey(nd.id) && RootNodeList.Contains(node))
                        {
                            StartNodeDictionary.Add(nd.id, node);
                        }
                    }

                }

                foreach (var skillNode in Skillnodes)
                {
                    foreach (var i in skillNode.Value.LinkId)
                    {
                        if (Links.Count(nd => (nd[0] == i && nd[1] == skillNode.Key) || nd[0] == skillNode.Key && nd[1] == i) != 1)
                            Links.Add(new[] { skillNode.Key, i });
                    }
                }
                foreach (var ints in Links)
                {
                    Regex regexString = new Regex(@"Can Allocate Passives from the .* starting point");
                    bool isScionAscendancyNotable = false;
                    foreach (var attibute in Skillnodes[ints[0]].attributes)
                    {
                        if (regexString.IsMatch(attibute))
                            isScionAscendancyNotable = true;
                    }
                    foreach (var attibute in Skillnodes[ints[1]].attributes)
                    {
                        if (regexString.IsMatch(attibute))
                            isScionAscendancyNotable = true;
                    }

                    if (isScionAscendancyNotable && StartNodeDictionary.Keys.Contains(ints[0]))
                    {
                        if (!Skillnodes[ints[1]].Neighbor.Contains(Skillnodes[ints[0]]))
                            Skillnodes[ints[1]].Neighbor.Add(Skillnodes[ints[0]]);
                    }
                    else if (isScionAscendancyNotable && StartNodeDictionary.Keys.Contains(ints[1]))
                    {
                        if (!Skillnodes[ints[0]].Neighbor.Contains(Skillnodes[ints[1]]))
                            Skillnodes[ints[0]].Neighbor.Add(Skillnodes[ints[1]]);
                    }
                    else
                    {
                        if (!Skillnodes[ints[0]].Neighbor.Contains(Skillnodes[ints[1]]))
                            Skillnodes[ints[0]].Neighbor.Add(Skillnodes[ints[1]]);
                        if (!Skillnodes[ints[1]].Neighbor.Contains(Skillnodes[ints[0]]))
                            Skillnodes[ints[1]].Neighbor.Add(Skillnodes[ints[0]]);
                    }
                }

                var regexAttrib = new Regex("[0-9]*\\.?[0-9]+");
                foreach (var skillnode in Skillnodes)
                {
                    //add each other as visible neighbors
                    foreach (var snn in skillnode.Value.Neighbor)
                    {
                        if (snn.IsAscendancyStart && skillnode.Value.LinkId.Contains(snn.Id))
                            continue;
                        skillnode.Value.VisibleNeighbors.Add(snn);
                    }

                    //populate the Attributes fields with parsed attributes 
                    skillnode.Value.Attributes = new Dictionary<string, List<float>>();
                    foreach (string s in skillnode.Value.attributes)
                    {
                        var values = new List<float>();

                        foreach (Match m in regexAttrib.Matches(s))
                        {
                            if (!AttributeTypes.Contains(regexAttrib.Replace(s, "#")))
                                AttributeTypes.Add(regexAttrib.Replace(s, "#"));
                            if (m.Value == "")
                                values.Add(float.NaN);
                            else
                                values.Add(float.Parse(m.Value, CultureInfo.InvariantCulture));
                        }
                        string cs = (regexAttrib.Replace(s, "#"));

                        skillnode.Value.Attributes[cs] = values;
                    }
                }

                NodeGroups = new List<SkillNodeGroup>();
                foreach (var gp in inTree.groups)
                {
                    var ng = new SkillNodeGroup();

                    ng.OcpOrb = gp.Value.oo;
                    ng.Position = new Vector2D(gp.Value.x, gp.Value.y);
                    foreach (var node in gp.Value.n)
                    {
                        ng.Nodes.Add(Skillnodes[node]);
                    }
                    NodeGroups.Add(ng);
                }
                foreach (SkillNodeGroup group in NodeGroups)
                {
                    foreach (SkillNode node in group.Nodes)
                    {
                        node.SkillNodeGroup = group;
                    }
                }

                const int padding = 500; //This is to account for jewel range circles. Might need to find a better way to do it.
                SkillTreeRect = new Rect2D(new Vector2D(inTree.min_x * 1.1 - padding, inTree.min_y * 1.1 - padding),
                    new Vector2D(inTree.max_x * 1.1 + padding, inTree.max_y * 1.1 + padding));
            }

            if (_persistentData.Options.ShowAllAscendancyClasses)
                DrawAscendancy = true;

            InitialSkillTreeDrawing();
            controller?.SetProgress(1);

            _initialized = true;
        }
예제 #40
0
 /// <summary>
 /// Changes the HighlightState of the node:
 /// ... <- None <- Checked <- Crossed <- None
 /// (preserves other HighlightStates than Checked and Crossed)
 /// </summary>
 /// <param name="node">Node to change the HighlightState for</param>
 public void CycleNodeTagBackward(SkillNode node)
 {
     if (_nodeHighlighter.NodeHasHighlights(node, HighlightState.Crossed))
     {
         _nodeHighlighter.UnhighlightNode(node, HighlightState.Crossed);
         _nodeHighlighter.HighlightNode(node, HighlightState.Checked);
     }
     else if (_nodeHighlighter.NodeHasHighlights(node, HighlightState.Checked))
     {
         _nodeHighlighter.UnhighlightNode(node, HighlightState.Checked);
     }
     else
     {
         _nodeHighlighter.HighlightNode(node, HighlightState.Crossed);
     }
     DrawHighlights();
 }
예제 #41
0
 /// <summary>
 /// Changes the HighlightState of the node:
 /// ... &lt;- None &lt;- Checked &lt;- Crossed &lt;- None
 /// (preserves other HighlightStates than Checked and Crossed)
 /// </summary>
 /// <param name="node">Node to change the HighlightState for</param>
 public void CycleNodeTagBackward(SkillNode node)
 {
     var id = node.Id;
     var build = _persistentData.CurrentBuild;
     if (_nodeHighlighter.NodeHasHighlights(node, HighlightState.Crossed))
     {
         _nodeHighlighter.UnhighlightNode(node, HighlightState.Crossed);
         _nodeHighlighter.HighlightNode(node, HighlightState.Checked);
         build.CrossedNodeIds.Remove(id);
         build.CheckedNodeIds.Add(id);
     }
     else if (_nodeHighlighter.NodeHasHighlights(node, HighlightState.Checked))
     {
         _nodeHighlighter.UnhighlightNode(node, HighlightState.Checked);
         build.CheckedNodeIds.Remove(id);
     }
     else
     {
         _nodeHighlighter.HighlightNode(node, HighlightState.Crossed);
         build.CrossedNodeIds.Add(id);
     }
     DrawHighlights();
 }