/// <summary>
        /// Loads the attributes from the current tree as AttributeConstraints
        /// and Check-tags nodes that have unique attributes.
        /// </summary>
        /// <remarks>
        /// Character class changes after calling this method will not influence the attributes
        /// (which have the old character class calculated into them)
        /// </remarks>
        private void LoadAttributesFromTree()
        {
            Tree.UntagAllNodes();

            var attributes = new Dictionary <string, float>();

            foreach (var node in Tree.SkilledNodes)
            {
                var skillNode          = SkillTree.Skillnodes[node];
                var hasUniqueAttribute = false;
                foreach (var attribute in SkillTree.ExpandHybridAttributes(skillNode.Attributes))
                {
                    var attr = attribute.Key;
                    if (_attributes.Contains(attr))
                    {
                        if (attribute.Value.Count == 0)
                        {
                            continue;
                        }
                        if (attributes.ContainsKey(attr))
                        {
                            attributes[attr] += attribute.Value[0];
                        }
                        else
                        {
                            attributes[attr] = attribute.Value[0];
                        }
                    }
                    else if (!AttributeBlackList.Contains(attr))
                    {
                        hasUniqueAttribute = true;
                    }
                }
                if (hasUniqueAttribute)
                {
                    Tree.CycleNodeTagForward(skillNode);
                }
            }

            foreach (var attr in CreateInitialAttributes())
            {
                if (attributes.ContainsKey(attr.Key))
                {
                    attributes[attr.Key] += attr.Value;
                }
            }

            AttributeConstraints.Clear();
            foreach (var attribute in attributes)
            {
                AttributeConstraints.Add(new AttributeConstraint(attribute.Key)
                {
                    TargetValue = attribute.Value
                });
            }
        }
        public override ISolver CreateSolver(SolverSettings settings)
        {
            var attributeConstraints = AttributeConstraints.ToDictionary(
                constraint => constraint.Data,
                constraint => new Tuple <float, double>(constraint.TargetValue, constraint.Weight / 100.0));
            var pseudoConstraints = PseudoAttributeConstraints.ToDictionary(
                constraint => constraint.Data,
                constraint => new Tuple <float, double>(constraint.TargetValue, constraint.Weight / 100.0));

            return(new AdvancedSolver(Tree, new AdvancedSolverSettings(settings, CreateInitialAttributes(), attributeConstraints,
                                                                       pseudoConstraints, WeaponClass, Tags, OffHand)));
        }
 public override void Reset()
 {
     _addedAttributes.Clear();
     AttributeConstraints.Clear();
     AttributesView.Refresh();
     AttributesView.MoveCurrentToFirst();
     NewAttributeConstraint = new AttributeConstraint(AttributesView.CurrentItem as string);
     _addedPseudoAttributes.Clear();
     PseudoAttributeConstraints.Clear();
     PseudoAttributesView.Refresh();
     PseudoAttributesView.MoveCurrentToFirst();
     NewPseudoAttributeConstraint =
         new PseudoAttributeConstraint(PseudoAttributesView.CurrentItem as PseudoAttribute);
     TreePlusItemsMode = TreePlusItemsModeDefaultValue;
     WeaponClass       = WeaponClassDefaultValue;
     OffHand           = OffHandDefaultValue;
     Tags = TagsDefaultValue;
 }