/// <summary>
        /// Load the Mentor Spirit from the XmlNode.
        /// </summary>
        /// <param name="objNode">XmlNode to load.</param>
        public void Load(XmlNode objNode)
        {
            objNode.TryGetField("guid", Guid.TryParse, out _guiID);
            if (objNode.TryGetStringFieldQuickly("name", ref _strName))
            {
                _objCachedMyXmlNode = null;
            }
            if (objNode["mentortype"] != null)
            {
                _eMentorType        = Improvement.ConvertToImprovementType(objNode["mentortype"].InnerText);
                _objCachedMyXmlNode = null;
            }
            objNode.TryGetStringFieldQuickly("extra", ref _strExtra);
            objNode.TryGetStringFieldQuickly("source", ref _strSource);
            objNode.TryGetStringFieldQuickly("page", ref _strPage);
            objNode.TryGetStringFieldQuickly("advantage", ref _strAdvantage);
            objNode.TryGetStringFieldQuickly("disadvantage", ref _strDisadvantage);
            objNode.TryGetBoolFieldQuickly("mentormask", ref _blnMentorMask);
            _nodBonus   = objNode["bonus"];
            _nodChoice1 = objNode["choice1"];
            _nodChoice2 = objNode["choice2"];
            objNode.TryGetStringFieldQuickly("notes", ref _strNotes);

            if (!objNode.TryGetField("id", Guid.TryParse, out _sourceID))
            {
                XmlNode objNewNode = XmlManager.Load("qualities.xml").SelectSingleNode("/chummer/mentors/mentor[name = \"" + Name + "\"]");
                objNewNode?.TryGetField("id", Guid.TryParse, out _sourceID);
            }
        }
        /// <summary>
        /// Processes the string strDrain into a calculated Drain dicepool and appropriate display attributes and labels.
        /// </summary>
        /// <param name="strDrain"></param>
        /// <param name="objImprovementManager"></param>
        /// <param name="drain"></param>
        /// <param name="attributeText"></param>
        /// <param name="valueText"></param>
        /// <param name="tooltip"></param>
        public void CalculateTraditionDrain(string strDrain, Improvement.ImprovementType drain, Label attributeText, Label valueText, ToolTip tooltip)
        {
            if (string.IsNullOrWhiteSpace(strDrain))
            {
                return;
            }
            string strDisplayDrain = strDrain;
            string strTip          = strDrain;
            var    intDrain        = 0;
            // Update the Fading CharacterAttribute Value.
            var            objXmlDocument = new XmlDocument();
            XPathNavigator nav            = objXmlDocument.CreateNavigator();

            foreach (string strAttribute in Character.AttributeStrings)
            {
                CharacterAttrib objAttrib = _objCharacter.GetAttribute(strAttribute);
                strDrain        = strDrain.Replace(objAttrib.Abbrev, objAttrib.TotalValue.ToString());
                strDisplayDrain = strDisplayDrain.Replace(objAttrib.Abbrev, objAttrib.DisplayAbbrev);
            }
            XPathExpression xprFading = nav.Compile(strDrain);
            object          o         = nav.Evaluate(xprFading);

            if (o != null)
            {
                intDrain = Convert.ToInt32(o.ToString());
            }
            intDrain          += ImprovementManager.ValueOf(_objCharacter, drain);
            attributeText.Text = strDisplayDrain;
            valueText.Text     = intDrain.ToString();
            strTip             = Character.AttributeStrings.Select(strAttribute => _objCharacter.GetAttribute(strAttribute)).Aggregate(strTip, (current, objAttrib) => current.Replace(objAttrib.Abbrev, objAttrib.DisplayAbbrev + " (" + objAttrib.TotalValue.ToString() + ")"));
            tooltip.SetToolTip(valueText, strTip);
        }
        /// <summary>
        /// Processes the string strDrain into a calculated Drain dicepool and appropriate display attributes and labels.
        /// </summary>
        /// <param name="strDrain"></param>
        /// <param name="objImprovementManager"></param>
        /// <param name="drain"></param>
        /// <param name="attributeText"></param>
        /// <param name="valueText"></param>
        /// <param name="tooltip"></param>
        public void CalculateTraditionDrain(string strDrain, Improvement.ImprovementType drain, Label attributeText = null, Label valueText = null, ToolTip tooltip = null)
        {
            if (string.IsNullOrWhiteSpace(strDrain) || (attributeText == null && valueText == null && tooltip == null))
            {
                return;
            }
            StringBuilder objDrain        = valueText != null ? new StringBuilder(strDrain) : null;
            StringBuilder objDisplayDrain = attributeText != null ? new StringBuilder(strDrain) : null;
            StringBuilder objTip          = tooltip != null ? new StringBuilder(strDrain) : null;
            int           intDrain        = 0;

            // Update the Fading CharacterAttribute Value.
            foreach (string strAttribute in AttributeSection.AttributeStrings)
            {
                CharacterAttrib objAttrib = _objCharacter.GetAttribute(strAttribute);
                if (strDrain.Contains(objAttrib.Abbrev))
                {
                    string strAttribTotalValue = objAttrib.TotalValue.ToString();
                    objDrain?.Replace(objAttrib.Abbrev, strAttribTotalValue);
                    objDisplayDrain?.Replace(objAttrib.Abbrev, objAttrib.DisplayAbbrev);
                    objTip?.Replace(objAttrib.Abbrev, objAttrib.DisplayAbbrev + " (" + strAttribTotalValue + ")");
                }
            }
            if (objDrain != null)
            {
                try
                {
                    intDrain = Convert.ToInt32(Math.Ceiling((double)CommonFunctions.EvaluateInvariantXPath(objDrain.ToString())));
                }
                catch (XPathException) { }
                catch (OverflowException) { }    // Result is text and not a double
                catch (InvalidCastException) { } // Result is text and not a double
            }

            if (valueText != null || tooltip != null)
            {
                int intBonusDrain = ImprovementManager.ValueOf(_objCharacter, drain);
                if (intBonusDrain != 0)
                {
                    intDrain += intBonusDrain;
                    objTip?.Append(" + " + LanguageManager.GetString("Tip_Modifiers") + " (" + intBonusDrain.ToString() + ")");
                }
            }

            if (attributeText != null)
            {
                attributeText.Text = objDisplayDrain.ToString();
            }
            if (valueText != null)
            {
                valueText.Text = intDrain.ToString();
            }
            if (tooltip != null)
            {
                tooltip.SetToolTip(valueText, objTip.ToString());
            }
        }
Exemple #4
0
        public MentorSpirit(Character objCharacter, XmlNode xmlNodeMentor = null)
        {
            // Create the GUID for the new Mentor Spirit.
            _guiID        = Guid.NewGuid();
            _objCharacter = objCharacter;
            XmlNode namenode = xmlNodeMentor?.SelectSingleNode("name");

            if (namenode != null)
            {
                Name = namenode.InnerText;
            }
            XmlNode typenode = xmlNodeMentor?.SelectSingleNode("mentortype");

            if (typenode != null && Enum.TryParse(typenode.InnerText, true, out Improvement.ImprovementType outEnum))
            {
                _eMentorType = outEnum;
            }
        }
Exemple #5
0
 /// <summary>
 /// Load the Mentor Spirit from the XmlNode.
 /// </summary>
 /// <param name="objNode">XmlNode to load.</param>
 public void Load(XmlNode objNode)
 {
     if (objNode == null)
     {
         return;
     }
     if (!objNode.TryGetField("guid", Guid.TryParse, out _guiID))
     {
         _guiID = Guid.NewGuid();
     }
     if (!objNode.TryGetGuidFieldQuickly("sourceid", ref _guiSourceID))
     {
         XmlNode node = GetNode(GlobalOptions.Language);
         if (node?.TryGetGuidFieldQuickly("id", ref _guiSourceID) == false)
         {
             XmlNode objNewNode = _objCharacter.LoadData("qualities.xml").SelectSingleNode("/chummer/mentors/mentor[name = \"" + Name + "\"]");
             objNewNode?.TryGetGuidFieldQuickly("id", ref _guiSourceID);
         }
     }
     if (objNode.TryGetStringFieldQuickly("name", ref _strName))
     {
         _objCachedMyXmlNode = null;
     }
     if (objNode["mentortype"] != null)
     {
         _eMentorType        = Improvement.ConvertToImprovementType(objNode["mentortype"].InnerText);
         _objCachedMyXmlNode = null;
     }
     objNode.TryGetStringFieldQuickly("extra", ref _strExtra);
     objNode.TryGetStringFieldQuickly("source", ref _strSource);
     objNode.TryGetStringFieldQuickly("page", ref _strPage);
     objNode.TryGetMultiLineStringFieldQuickly("advantage", ref _strAdvantage);
     objNode.TryGetMultiLineStringFieldQuickly("disadvantage", ref _strDisadvantage);
     objNode.TryGetBoolFieldQuickly("mentormask", ref _blnMentorMask);
     _nodBonus   = objNode["bonus"];
     _nodChoice1 = objNode["choice1"];
     _nodChoice2 = objNode["choice2"];
     objNode.TryGetMultiLineStringFieldQuickly("notes", ref _strNotes);
 }
Exemple #6
0
        /// <summary>
        /// Create a Mentor Spirit from an XmlNode.
        /// </summary>
        /// <param name="xmlMentor">XmlNode to create the object from.</param>
        /// <param name="eMentorType">Whether this is a Mentor or a Paragon.</param>
        /// <param name="strForceValueChoice1">Name/Text for Choice 1.</param>
        /// <param name="strForceValueChoice2">Name/Text for Choice 2.</param>
        /// <param name="strForceValue">Force a value to be selected for the Mentor Spirit.</param>
        public void Create(XmlNode xmlMentor, Improvement.ImprovementType eMentorType, string strForceValue = "", string strForceValueChoice1 = "", string strForceValueChoice2 = "")
        {
            _eMentorType          = eMentorType;
            _objCachedMyXmlNode   = null;
            _objCachedMyXPathNode = null;
            xmlMentor.TryGetStringFieldQuickly("name", ref _strName);
            xmlMentor.TryGetStringFieldQuickly("source", ref _strSource);
            xmlMentor.TryGetStringFieldQuickly("page", ref _strPage);
            if (!xmlMentor.TryGetMultiLineStringFieldQuickly("altnotes", ref _strNotes))
            {
                xmlMentor.TryGetMultiLineStringFieldQuickly("notes", ref _strNotes);
            }

            if (string.IsNullOrEmpty(_strNotes))
            {
                _strNotes = CommonFunctions.GetBookNotes(xmlMentor, Name, DisplayNameShort(GlobalSettings.Language), Source, Page,
                                                         DisplayPage(GlobalSettings.Language), _objCharacter);
            }

            if (!xmlMentor.TryGetField("id", Guid.TryParse, out _guiSourceID))
            {
                Log.Warn(new object[] { "Missing id field for xmlnode", xmlMentor });
                Utils.BreakIfDebug();
            }

            // Cache the English list of advantages gained through the Mentor Spirit.
            xmlMentor.TryGetMultiLineStringFieldQuickly("advantage", ref _strAdvantage);
            xmlMentor.TryGetMultiLineStringFieldQuickly("disadvantage", ref _strDisadvantage);

            _nodBonus = xmlMentor["bonus"];
            if (_nodBonus != null)
            {
                string strOldForce    = ImprovementManager.ForcedValue;
                string strOldSelected = ImprovementManager.SelectedValue;
                ImprovementManager.ForcedValue = strForceValue;
                if (!ImprovementManager.CreateImprovements(_objCharacter, Improvement.ImprovementSource.MentorSpirit, _guiID.ToString("D", GlobalSettings.InvariantCultureInfo), _nodBonus, 1, DisplayNameShort(GlobalSettings.Language)))
                {
                    _guiID = Guid.Empty;
                    return;
                }
                _strExtra = ImprovementManager.SelectedValue;
                ImprovementManager.ForcedValue   = strOldForce;
                ImprovementManager.SelectedValue = strOldSelected;
            }
            else if (!string.IsNullOrEmpty(strForceValue))
            {
                _strExtra = strForceValue;
            }
            _nodChoice1 = xmlMentor.SelectSingleNode("choices/choice[name = " + strForceValueChoice1.CleanXPath() + "]/bonus");
            if (_nodChoice1 != null)
            {
                string strOldForce    = ImprovementManager.ForcedValue;
                string strOldSelected = ImprovementManager.SelectedValue;
                //ImprovementManager.ForcedValue = strForceValueChoice1;
                if (!ImprovementManager.CreateImprovements(_objCharacter, Improvement.ImprovementSource.MentorSpirit, _guiID.ToString("D", GlobalSettings.InvariantCultureInfo), _nodChoice1, 1, DisplayNameShort(GlobalSettings.Language)))
                {
                    _guiID = Guid.Empty;
                    return;
                }
                if (string.IsNullOrEmpty(_strExtra))
                {
                    _strExtra = ImprovementManager.SelectedValue;
                }
                ImprovementManager.ForcedValue   = strOldForce;
                ImprovementManager.SelectedValue = strOldSelected;
            }
            else if (string.IsNullOrEmpty(_strExtra) && !string.IsNullOrEmpty(strForceValueChoice1))
            {
                _strExtra = strForceValueChoice1;
            }
            _nodChoice2 = xmlMentor.SelectSingleNode("choices/choice[name = " + strForceValueChoice2.CleanXPath() + "]/bonus");
            if (_nodChoice2 != null)
            {
                string strOldForce    = ImprovementManager.ForcedValue;
                string strOldSelected = ImprovementManager.SelectedValue;
                //ImprovementManager.ForcedValue = strForceValueChoice2;
                if (!ImprovementManager.CreateImprovements(_objCharacter, Improvement.ImprovementSource.MentorSpirit, _guiID.ToString("D", GlobalSettings.InvariantCultureInfo), _nodChoice2, 1, DisplayNameShort(GlobalSettings.Language)))
                {
                    _guiID = Guid.Empty;
                    return;
                }
                if (string.IsNullOrEmpty(_strExtra))
                {
                    _strExtra = ImprovementManager.SelectedValue;
                }
                ImprovementManager.ForcedValue   = strOldForce;
                ImprovementManager.SelectedValue = strOldSelected;
            }
            else if (string.IsNullOrEmpty(_strExtra) && !string.IsNullOrEmpty(strForceValueChoice2))
            {
                _strExtra = strForceValueChoice2;
            }

            /*
             * if (string.IsNullOrEmpty(_strNotes))
             * {
             *  _strNotes = CommonFunctions.GetTextFromPdf(_strSource + ' ' + _strPage, _strName);
             *  if (string.IsNullOrEmpty(_strNotes))
             *  {
             *      _strNotes = CommonFunctions.GetTextFromPdf(Source + ' ' + DisplayPage(GlobalSettings.Language), CurrentDisplayName);
             *  }
             * }
             */
        }
Exemple #7
0
        /// <summary>
        /// Load the Mentor Spirit from the XmlNode.
        /// </summary>
        /// <param name="objNode">XmlNode to load.</param>
        public void Load(XmlNode objNode)
        {
            if (objNode == null)
            {
                return;
            }
            if (!objNode.TryGetField("guid", Guid.TryParse, out _guiID))
            {
                _guiID = Guid.NewGuid();
            }
            if (objNode.TryGetStringFieldQuickly("name", ref _strName))
            {
                _objCachedMyXmlNode   = null;
                _objCachedMyXPathNode = null;
            }

            if (objNode["mentortype"] != null)
            {
                _eMentorType          = Improvement.ConvertToImprovementType(objNode["mentortype"].InnerText);
                _objCachedMyXmlNode   = null;
                _objCachedMyXPathNode = null;
            }
            Lazy <XPathNavigator> objMyNode = new Lazy <XPathNavigator>(this.GetNodeXPath);

            if (!objNode.TryGetGuidFieldQuickly("sourceid", ref _guiSourceID) && objMyNode.Value?.TryGetGuidFieldQuickly("id", ref _guiSourceID) == false)
            {
                _objCharacter.LoadDataXPath("qualities.xml")
                .SelectSingleNode("/chummer/mentors/mentor[name = " + Name.CleanXPath() + ']')
                ?.TryGetGuidFieldQuickly("id", ref _guiSourceID);
            }
            objNode.TryGetStringFieldQuickly("extra", ref _strExtra);
            objNode.TryGetStringFieldQuickly("source", ref _strSource);
            objNode.TryGetStringFieldQuickly("page", ref _strPage);
            if (_objCharacter.LastSavedVersion <= new Version(5, 217, 31))
            {
                // Cache advantages from data file because localized version used to be cached directly.
                XPathNavigator node = objMyNode.Value;
                if (node != null)
                {
                    if (!node.TryGetMultiLineStringFieldQuickly("advantage", ref _strAdvantage))
                    {
                        objNode.TryGetMultiLineStringFieldQuickly("advantage", ref _strAdvantage);
                    }
                    if (!node.TryGetMultiLineStringFieldQuickly("disadvantage", ref _strDisadvantage))
                    {
                        objNode.TryGetMultiLineStringFieldQuickly("disadvantage", ref _strDisadvantage);
                    }
                }
                else
                {
                    objNode.TryGetMultiLineStringFieldQuickly("advantage", ref _strAdvantage);
                    objNode.TryGetMultiLineStringFieldQuickly("disadvantage", ref _strDisadvantage);
                }
            }
            else
            {
                objNode.TryGetMultiLineStringFieldQuickly("advantage", ref _strAdvantage);
                objNode.TryGetMultiLineStringFieldQuickly("disadvantage", ref _strDisadvantage);
            }
            objNode.TryGetBoolFieldQuickly("mentormask", ref _blnMentorMask);
            _nodBonus   = objNode["bonus"];
            _nodChoice1 = objNode["choice1"];
            _nodChoice2 = objNode["choice2"];
            objNode.TryGetMultiLineStringFieldQuickly("notes", ref _strNotes);
        }
        /// <summary>
        /// Create a Mentor Spirit from an XmlNode.
        /// </summary>
        /// <param name="xmlMentor">XmlNode to create the object from.</param>
        /// <param name="eMentorType">Whether this is a Mentor or a Paragon.</param>
        /// <param name="strForceValueChoice1">Name/Text for Choice 1.</param>
        /// <param name="strForceValueChoice2">Name/Text for Choice 2.</param>
        /// <param name="strForceValue">Force a value to be selected for the Mentor Spirit.</param>
        /// <param name="blnMentorMask">Whether the Mentor's Mask is enabled.</param>
        public void Create(XmlNode xmlMentor, Improvement.ImprovementType eMentorType, string strForceValue = "", string strForceValueChoice1 = "", string strForceValueChoice2 = "", bool blnMentorMask = false)
        {
            _blnMentorMask      = blnMentorMask;
            _eMentorType        = eMentorType;
            _objCachedMyXmlNode = null;
            xmlMentor.TryGetStringFieldQuickly("name", ref _strName);
            xmlMentor.TryGetStringFieldQuickly("source", ref _strSource);
            xmlMentor.TryGetStringFieldQuickly("page", ref _strPage);
            if (!xmlMentor.TryGetStringFieldQuickly("altnotes", ref _strNotes))
            {
                xmlMentor.TryGetStringFieldQuickly("notes", ref _strNotes);
            }
            if (xmlMentor.TryGetField("id", Guid.TryParse, out Guid guiTemp))
            {
                _sourceID = guiTemp;
            }

            // Build the list of advantages gained through the Mentor Spirit.
            if (!xmlMentor.TryGetStringFieldQuickly("altadvantage", ref _strAdvantage))
            {
                xmlMentor.TryGetStringFieldQuickly("advantage", ref _strAdvantage);
            }
            if (!xmlMentor.TryGetStringFieldQuickly("altdisadvantage", ref _strDisadvantage))
            {
                xmlMentor.TryGetStringFieldQuickly("disadvantage", ref _strDisadvantage);
            }

            _nodBonus = xmlMentor["bonus"];
            if (_nodBonus != null)
            {
                string strOldForce    = ImprovementManager.ForcedValue;
                string strOldSelected = ImprovementManager.SelectedValue;
                ImprovementManager.ForcedValue = strForceValue;
                if (!ImprovementManager.CreateImprovements(_objCharacter, Improvement.ImprovementSource.MentorSpirit, _guiID.ToString("D"), _nodBonus, false, 1, DisplayNameShort(GlobalOptions.Language)))
                {
                    _guiID = Guid.Empty;
                    return;
                }
                _strExtra = ImprovementManager.SelectedValue;
                ImprovementManager.ForcedValue   = strOldForce;
                ImprovementManager.SelectedValue = strOldSelected;
            }
            else if (!string.IsNullOrEmpty(strForceValue))
            {
                _strExtra = strForceValue;
            }
            _nodChoice1 = xmlMentor.SelectSingleNode("choices/choice[name = \"" + strForceValueChoice1 + "\"]/bonus");
            if (_nodChoice1 != null)
            {
                string strOldForce    = ImprovementManager.ForcedValue;
                string strOldSelected = ImprovementManager.SelectedValue;
                ImprovementManager.ForcedValue = strForceValueChoice1;
                if (!ImprovementManager.CreateImprovements(_objCharacter, Improvement.ImprovementSource.MentorSpirit, _guiID.ToString("D"), _nodChoice1, false, 1, DisplayNameShort(GlobalOptions.Language)))
                {
                    _guiID = Guid.Empty;
                    return;
                }
                if (string.IsNullOrEmpty(_strExtra))
                {
                    _strExtra = ImprovementManager.SelectedValue;
                }
                ImprovementManager.ForcedValue   = strOldForce;
                ImprovementManager.SelectedValue = strOldSelected;
            }
            else if (string.IsNullOrEmpty(_strExtra) && !string.IsNullOrEmpty(strForceValueChoice1))
            {
                _strExtra = strForceValueChoice1;
            }
            _nodChoice2 = xmlMentor.SelectSingleNode("choices/choice[name = \"" + strForceValueChoice2 + "\"]/bonus");
            if (_nodChoice2 != null)
            {
                string strOldForce    = ImprovementManager.ForcedValue;
                string strOldSelected = ImprovementManager.SelectedValue;
                ImprovementManager.ForcedValue = strForceValueChoice2;
                if (!ImprovementManager.CreateImprovements(_objCharacter, Improvement.ImprovementSource.MentorSpirit, _guiID.ToString("D"), _nodChoice2, false, 1, DisplayNameShort(GlobalOptions.Language)))
                {
                    _guiID = Guid.Empty;
                    return;
                }
                if (string.IsNullOrEmpty(_strExtra))
                {
                    _strExtra = ImprovementManager.SelectedValue;
                }
                ImprovementManager.ForcedValue   = strOldForce;
                ImprovementManager.SelectedValue = strOldSelected;
            }
            else if (string.IsNullOrEmpty(_strExtra) && !string.IsNullOrEmpty(strForceValueChoice2))
            {
                _strExtra = strForceValueChoice2;
            }
            if (_blnMentorMask)
            {
                ImprovementManager.CreateImprovement(_objCharacter, string.Empty, Improvement.ImprovementSource.MentorSpirit, _guiID.ToString("D"), Improvement.ImprovementType.AdeptPowerPoints, string.Empty, 1);
                ImprovementManager.CreateImprovement(_objCharacter, string.Empty, Improvement.ImprovementSource.MentorSpirit, _guiID.ToString("D"), Improvement.ImprovementType.DrainValue, string.Empty, -1);
                ImprovementManager.Commit(_objCharacter);
            }

            /*
             * if (string.IsNullOrEmpty(_strNotes))
             * {
             *  _strNotes = CommonFunctions.GetTextFromPDF($"{_strSource} {_strPage}", _strName);
             *  if (string.IsNullOrEmpty(_strNotes))
             *  {
             *      _strNotes = CommonFunctions.GetTextFromPDF($"{Source} {Page(GlobalOptions.Language)}", DisplayName(GlobalOptions.Language));
             *  }
             * }*/
        }
Exemple #9
0
        /// <summary>
        /// Create a Mentor Spirit from an XmlNode.
        /// </summary>
        /// <param name="xmlMentor">XmlNode to create the object from.</param>
        /// <param name="eMentorType">Whether this is a Mentor or a Paragon.</param>
        /// <param name="strForceValueChoice1">Name/Text for Choice 1.</param>
        /// <param name="strForceValueChoice2">Name/Text for Choice 2.</param>
        /// <param name="strForceValue">Force a value to be selected for the Mentor Spirit.</param>
        public void Create(XmlNode xmlMentor, Improvement.ImprovementType eMentorType, string strForceValue = "", string strForceValueChoice1 = "", string strForceValueChoice2 = "")
        {
            _eMentorType        = eMentorType;
            _objCachedMyXmlNode = null;
            xmlMentor.TryGetStringFieldQuickly("name", ref _strName);
            xmlMentor.TryGetStringFieldQuickly("source", ref _strSource);
            xmlMentor.TryGetStringFieldQuickly("page", ref _strPage);
            if (!xmlMentor.TryGetStringFieldQuickly("altnotes", ref _strNotes))
            {
                xmlMentor.TryGetStringFieldQuickly("notes", ref _strNotes);
            }
            if (!xmlMentor.TryGetField("id", Guid.TryParse, out _guiSourceID))
            {
                Log.Warn(new object[] { "Missing id field for xmlnode", xmlMentor });
                Utils.BreakIfDebug();
            }

            // Build the list of advantages gained through the Mentor Spirit.
            if (!xmlMentor.TryGetStringFieldQuickly("altadvantage", ref _strAdvantage))
            {
                xmlMentor.TryGetStringFieldQuickly("advantage", ref _strAdvantage);
            }
            if (!xmlMentor.TryGetStringFieldQuickly("altdisadvantage", ref _strDisadvantage))
            {
                xmlMentor.TryGetStringFieldQuickly("disadvantage", ref _strDisadvantage);
            }

            _nodBonus = xmlMentor["bonus"];
            if (_nodBonus != null)
            {
                string strOldForce    = ImprovementManager.ForcedValue;
                string strOldSelected = ImprovementManager.SelectedValue;
                ImprovementManager.ForcedValue = strForceValue;
                if (!ImprovementManager.CreateImprovements(_objCharacter, Improvement.ImprovementSource.MentorSpirit, _guiID.ToString("D"), _nodBonus, false, 1, DisplayNameShort(GlobalOptions.Language)))
                {
                    _guiID = Guid.Empty;
                    return;
                }
                _strExtra = ImprovementManager.SelectedValue;
                ImprovementManager.ForcedValue   = strOldForce;
                ImprovementManager.SelectedValue = strOldSelected;
            }
            else if (!string.IsNullOrEmpty(strForceValue))
            {
                _strExtra = strForceValue;
            }
            _nodChoice1 = xmlMentor.SelectSingleNode("choices/choice[name = \"" + strForceValueChoice1 + "\"]/bonus");
            if (_nodChoice1 != null)
            {
                string strOldForce    = ImprovementManager.ForcedValue;
                string strOldSelected = ImprovementManager.SelectedValue;
                //ImprovementManager.ForcedValue = strForceValueChoice1;
                if (!ImprovementManager.CreateImprovements(_objCharacter, Improvement.ImprovementSource.MentorSpirit, _guiID.ToString("D"), _nodChoice1, false, 1, DisplayNameShort(GlobalOptions.Language)))
                {
                    _guiID = Guid.Empty;
                    return;
                }
                if (string.IsNullOrEmpty(_strExtra))
                {
                    _strExtra = ImprovementManager.SelectedValue;
                }
                ImprovementManager.ForcedValue   = strOldForce;
                ImprovementManager.SelectedValue = strOldSelected;
            }
            else if (string.IsNullOrEmpty(_strExtra) && !string.IsNullOrEmpty(strForceValueChoice1))
            {
                _strExtra = strForceValueChoice1;
            }
            _nodChoice2 = xmlMentor.SelectSingleNode("choices/choice[name = \"" + strForceValueChoice2 + "\"]/bonus");
            if (_nodChoice2 != null)
            {
                string strOldForce    = ImprovementManager.ForcedValue;
                string strOldSelected = ImprovementManager.SelectedValue;
                //ImprovementManager.ForcedValue = strForceValueChoice2;
                if (!ImprovementManager.CreateImprovements(_objCharacter, Improvement.ImprovementSource.MentorSpirit, _guiID.ToString("D"), _nodChoice2, false, 1, DisplayNameShort(GlobalOptions.Language)))
                {
                    _guiID = Guid.Empty;
                    return;
                }
                if (string.IsNullOrEmpty(_strExtra))
                {
                    _strExtra = ImprovementManager.SelectedValue;
                }
                ImprovementManager.ForcedValue   = strOldForce;
                ImprovementManager.SelectedValue = strOldSelected;
            }
            else if (string.IsNullOrEmpty(_strExtra) && !string.IsNullOrEmpty(strForceValueChoice2))
            {
                _strExtra = strForceValueChoice2;
            }

            /*
             * if (string.IsNullOrEmpty(_strNotes))
             * {
             *  _strNotes = CommonFunctions.GetTextFromPDF($"{_strSource} {_strPage}", _strName);
             *  if (string.IsNullOrEmpty(_strNotes))
             *  {
             *      _strNotes = CommonFunctions.GetTextFromPDF($"{Source} {Page(GlobalOptions.Language)}", DisplayName(GlobalOptions.Language));
             *  }
             * }*/
        }
Exemple #10
0
        /// <summary>
        /// Create all of the Improvements for an XML Node.
        /// </summary>
        /// <param name="objImprovementSource">Type of object that grants these Improvements.</param>
        /// <param name="strSourceName">Name of the item that grants these Improvements.</param>
        /// <param name="nodBonus">bonus XMLXode from the source data file.</param>
        /// <param name="blnConcatSelectedValue">Whether or not any selected values should be concatinated with the SourceName string when storing.</param>
        /// <param name="intRating">Selected Rating value that is used to replace the Rating string in an Improvement.</param>
        /// <param name="strFriendlyName">Friendly name to show in any dialogue windows that ask for a value.</param>
        public bool CreateImprovements(Improvement.ImprovementSource objImprovementSource, string strSourceName, XmlNode nodBonus, bool blnConcatSelectedValue = false, int intRating = 1, string strFriendlyName = "", bool blnConditional = false)
        {
            if (nodBonus == null)
            {
                _strForcedValue = "";
                _strLimitSelection = "";
                return true;
            }

            if (blnConditional)
            {
                _objCharacter.ImprovementGroups.Add(strSourceName);
            }

            string strUnique = "";
            if (nodBonus.Attributes["unique"] != null)
                strUnique = nodBonus.Attributes["unique"].InnerText;

            bool blnSuccess = true;
            _strSelectedValue = "";

            // If no friendly name was provided, use the one from SourceName.
            if (strFriendlyName == "")
                strFriendlyName = strSourceName;

            if (nodBonus.HasChildNodes)
            {
                // Select Text (custom entry for things like Allergy).
                if (NodeExists(nodBonus, "selecttext"))
                {
                    if (_strForcedValue != "")
                        _strLimitSelection = _strForcedValue;

                    // Display the Select Text window and record the value that was entered.
                    frmSelectText frmPickText = new frmSelectText();
                    frmPickText.Description = LanguageManager.Instance.GetString("String_Improvement_SelectText").Replace("{0}", strFriendlyName);

                    if (_strLimitSelection != "")
                    {
                        frmPickText.SelectedValue = _strLimitSelection;
                        frmPickText.Opacity = 0;
                    }

                    frmPickText.ShowDialog();

                    // Make sure the dialogue window was not canceled.
                    if (frmPickText.DialogResult == DialogResult.Cancel)
                    {
                        Rollback();
                        blnSuccess = false;
                        _strForcedValue = "";
                        _strLimitSelection = "";
                        return false;
                    }

                    _strSelectedValue = frmPickText.SelectedValue;
                    if (blnConcatSelectedValue)
                        strSourceName += " (" + _strSelectedValue + ")";

                    // Create the Improvement.
                    CreateImprovement(frmPickText.SelectedValue, objImprovementSource, strSourceName, Improvement.ImprovementType.Text, strUnique, blnConditional);
                }
            }

            // If there is no character object, don't attempt to add any Improvements.
            if (_objCharacter == null)
                return true;

            // Check to see what bonuses the node grants.
            if (nodBonus.HasChildNodes)
            {
                // Add an Attribute.
                if (NodeExists(nodBonus, "addattribute"))
                {
                    if (nodBonus["addattribute"]["name"].InnerText == "MAG")
                    {
                        _objCharacter.MAGEnabled = true;
                        CreateImprovement("MAG", objImprovementSource, strSourceName, Improvement.ImprovementType.Attribute, "enableattribute", blnConditional, 0, 0);
                        if (nodBonus["addattribute"]["min"] != null)
                            _objCharacter.MAG.MetatypeMinimum = Convert.ToInt32(nodBonus["addattribute"]["min"].InnerText);
                        if (nodBonus["addattribute"]["max"] != null)
                            _objCharacter.MAG.MetatypeMaximum = Convert.ToInt32(nodBonus["addattribute"]["max"].InnerText);
                        if (nodBonus["addattribute"]["aug"] != null)
                            _objCharacter.MAG.MetatypeAugmentedMaximum = Convert.ToInt32(nodBonus["addattribute"]["aug"].InnerText);
                        if (nodBonus["addattribute"]["val"] != null)
                            _objCharacter.MAG.Value = Convert.ToInt32(nodBonus["addattribute"]["val"].InnerText);
                    }
                    else if (nodBonus["addattribute"]["name"].InnerText == "RES")
                    {
                        _objCharacter.RESEnabled = true;
                        CreateImprovement("RES", objImprovementSource, strSourceName, Improvement.ImprovementType.Attribute, "enableattribute", blnConditional, 0, 0);
                        if (nodBonus["addattribute"]["min"] != null)
                            _objCharacter.RES.MetatypeMinimum = Convert.ToInt32(nodBonus["addattribute"]["min"].InnerText);
                        if (nodBonus["addattribute"]["max"] != null)
                            _objCharacter.RES.MetatypeMaximum = Convert.ToInt32(nodBonus["addattribute"]["max"].InnerText);
                        if (nodBonus["addattribute"]["aug"] != null)
                            _objCharacter.RES.MetatypeAugmentedMaximum = Convert.ToInt32(nodBonus["addattribute"]["aug"].InnerText);
                        if (nodBonus["addattribute"]["val"] != null)
                            _objCharacter.RES.Value = Convert.ToInt32(nodBonus["addattribute"]["val"].InnerText);
                    }
                }

                // Enable a special tab.
                if (NodeExists(nodBonus, "enabletab"))
                {
                    foreach (XmlNode objXmlEnable in nodBonus["enabletab"].ChildNodes)
                    {
                        switch (objXmlEnable.InnerText)
                        {
                            case "magician":
                                _objCharacter.MagicianEnabled = true;
                                CreateImprovement("Magician", objImprovementSource, strSourceName, Improvement.ImprovementType.SpecialTab, "enabletab", blnConditional, 0, 0);
                                break;
                            case "adept":
                                _objCharacter.AdeptEnabled = true;
                                CreateImprovement("Adept", objImprovementSource, strSourceName, Improvement.ImprovementType.SpecialTab, "enabletab", blnConditional, 0, 0);
                                break;
                            case "technomancer":
                                _objCharacter.TechnomancerEnabled = true;
                                CreateImprovement("Technomancer", objImprovementSource, strSourceName, Improvement.ImprovementType.SpecialTab, "enabletab", blnConditional, 0, 0);
                                break;
                            case "critter":
                                _objCharacter.CritterEnabled = true;
                                CreateImprovement("Critter", objImprovementSource, strSourceName, Improvement.ImprovementType.SpecialTab, "enabletab", blnConditional, 0, 0);
                                break;
                            case "initiation":
                                _objCharacter.InitiationEnabled = true;
                                CreateImprovement("Initiation", objImprovementSource, strSourceName, Improvement.ImprovementType.SpecialTab, "enabletab", blnConditional, 0, 0);
                                break;
                        }
                    }
                }

                // Select Restricted (select Restricted items for Fake Licenses).
                if (NodeExists(nodBonus, "selectrestricted"))
                {
                    frmSelectItem frmPickItem = new frmSelectItem();
                    frmPickItem.Character = _objCharacter;
                    if (_strForcedValue != string.Empty)
                        frmPickItem.ForceItem = _strForcedValue;
                    frmPickItem.AllowAutoSelect = false;
                    frmPickItem.ShowDialog();

                    // Make sure the dialogue window was not canceled.
                    if (frmPickItem.DialogResult == DialogResult.Cancel)
                    {
                        Rollback();
                        blnSuccess = false;
                        _strForcedValue = "";
                        _strLimitSelection = "";
                        return false;
                    }

                    _strSelectedValue = frmPickItem.SelectedItem;
                    if (blnConcatSelectedValue)
                        strSourceName += " (" + _strSelectedValue + ")";

                    // Create the Improvement.
                    CreateImprovement(frmPickItem.SelectedItem, objImprovementSource, strSourceName, Improvement.ImprovementType.Restricted, strUnique, blnConditional);
                }

                // Select a Skill.
                if (NodeExists(nodBonus, "selectskill"))
                {
                    // Display the Select Skill window and record which Skill was selected.
                    frmSelectSkill frmPickSkill = new frmSelectSkill(_objCharacter);
                    if (strFriendlyName != "")
                        frmPickSkill.Description = LanguageManager.Instance.GetString("String_Improvement_SelectSkillNamed").Replace("{0}", strFriendlyName);
                    else
                        frmPickSkill.Description = LanguageManager.Instance.GetString("String_Improvement_SelectSkill");

                    if (nodBonus.SelectSingleNode("selectskill").OuterXml.Contains("skillgroup"))
                        frmPickSkill.OnlySkillGroup = nodBonus.SelectSingleNode("selectskill").Attributes["skillgroup"].InnerText;
                    else if (nodBonus.SelectSingleNode("selectskill").OuterXml.Contains("skillcategory"))
                        frmPickSkill.OnlyCategory = nodBonus.SelectSingleNode("selectskill").Attributes["skillcategory"].InnerText;
                    else if (nodBonus.SelectSingleNode("selectskill").OuterXml.Contains("excludecategory"))
                        frmPickSkill.ExcludeCategory = nodBonus.SelectSingleNode("selectskill").Attributes["excludecategory"].InnerText;
                    else if (nodBonus.SelectSingleNode("selectskill").OuterXml.Contains("limittoskill"))
                        frmPickSkill.LimitToSkill = nodBonus.SelectSingleNode("selectskill").Attributes["limittoskill"].InnerText;
                    if (_strForcedValue != "")
                    {
                        frmPickSkill.OnlySkill = _strForcedValue;
                        frmPickSkill.Opacity = 0;
                    }

                    frmPickSkill.ShowDialog();

                    // Make sure the dialogue window was not canceled.
                    if (frmPickSkill.DialogResult == DialogResult.Cancel)
                    {
                        Rollback();
                        blnSuccess = false;
                        _strForcedValue = "";
                        _strLimitSelection = "";
                        return false;
                    }

                    bool blnAddToRating = false;
                    if (nodBonus["selectskill"]["applytorating"] != null)
                    {
                        if (nodBonus["selectskill"]["applytorating"].InnerText == "yes")
                            blnAddToRating = true;
                    }

                    _strSelectedValue = frmPickSkill.SelectedSkill;
                    if (blnConcatSelectedValue)
                        strSourceName += " (" + _strSelectedValue + ")";

                    // Find the selected Skill.
                    foreach (Skill objSkill in _objCharacter.Skills)
                    {
                        if (frmPickSkill.SelectedSkill.Contains("Exotic Melee Weapon") || frmPickSkill.SelectedSkill.Contains("Exotic Ranged Weapon") || frmPickSkill.SelectedSkill.Contains("Pilot Exotic Vehicle"))
                        {
                            if (objSkill.Name + " (" + objSkill.Specialization + ")" == frmPickSkill.SelectedSkill)
                            {
                                // We've found the selected Skill.
                                if (nodBonus["selectskill"]["val"] != null)
                                    CreateImprovement(objSkill.Name + " (" + objSkill.Specialization + ")", objImprovementSource, strSourceName, Improvement.ImprovementType.Skill, strUnique, blnConditional, ValueToInt(nodBonus["selectskill"]["val"].InnerText, intRating), 1, 0, 0, 0, 0, "", blnAddToRating);

                                if (nodBonus["selectskill"]["max"] != null)
                                    CreateImprovement(objSkill.Name + " (" + objSkill.Specialization + ")", objImprovementSource, strSourceName, Improvement.ImprovementType.Skill, strUnique, blnConditional, 0, 1, 0, ValueToInt(nodBonus["selectskill"]["max"].InnerText, intRating), 0, 0, "", blnAddToRating);

                                if (nodBonus["selectskill"]["weapondv"] != null)
                                    CreateImprovement(objSkill.Name + " (" + objSkill.Specialization + ")", objImprovementSource, strSourceName, Improvement.ImprovementType.WeaponSkillDV, strUnique, blnConditional, ValueToInt(nodBonus["selectskill"]["weapondv"].InnerText, intRating));

                                if (nodBonus["selectskill"]["accuracy"] != null)
                                    CreateImprovement(objSkill.Name + " (" + objSkill.Specialization + ")", objImprovementSource, strSourceName, Improvement.ImprovementType.WeaponSkillAccuracy, strUnique, blnConditional, ValueToInt(nodBonus["selectskill"]["accuracy"].InnerText, intRating));
                            }
                        }
                        else
                        {
                            if (objSkill.Name == frmPickSkill.SelectedSkill)
                            {
                                // We've found the selected Skill.
                                if (nodBonus["selectskill"]["val"] != null)
                                    CreateImprovement(objSkill.Name, objImprovementSource, strSourceName, Improvement.ImprovementType.Skill, strUnique, blnConditional, ValueToInt(nodBonus["selectskill"]["val"].InnerText, intRating), 1, 0, 0, 0, 0, "", blnAddToRating);

                                if (nodBonus["selectskill"]["max"] != null)
                                    CreateImprovement(objSkill.Name, objImprovementSource, strSourceName, Improvement.ImprovementType.Skill, strUnique, blnConditional, 0, 1, 0, ValueToInt(nodBonus["selectskill"]["max"].InnerText, intRating), 0, 0, "", blnAddToRating);

                                if (nodBonus["selectskill"]["weapondv"] != null)
                                    CreateImprovement(objSkill.Name, objImprovementSource, strSourceName, Improvement.ImprovementType.WeaponSkillDV, strUnique, blnConditional, ValueToInt(nodBonus["selectskill"]["weapondv"].InnerText, intRating));

                                if (nodBonus["selectskill"]["accuracy"] != null)
                                    CreateImprovement(objSkill.Name, objImprovementSource, strSourceName, Improvement.ImprovementType.WeaponSkillAccuracy, strUnique, blnConditional, ValueToInt(nodBonus["selectskill"]["accuracy"].InnerText, intRating));
                            }
                        }
                    }
                }

                // Select a Skill Group.
                if (NodeExists(nodBonus, "selectskillgroup"))
                {
                    string strExclude = "";
                    if (nodBonus["selectskillgroup"].Attributes["excludecategory"] != null)
                        strExclude = nodBonus["selectskillgroup"].Attributes["excludecategory"].InnerText;

                    frmSelectSkillGroup frmPickSkillGroup = new frmSelectSkillGroup();
                    if (strFriendlyName != "")
                        frmPickSkillGroup.Description = LanguageManager.Instance.GetString("String_Improvement_SelectSkillGroupName").Replace("{0}", strFriendlyName);
                    else
                        frmPickSkillGroup.Description = LanguageManager.Instance.GetString("String_Improvement_SelectSkillGroup");

                    if (_strForcedValue != "")
                    {
                        frmPickSkillGroup.OnlyGroup = _strForcedValue;
                        frmPickSkillGroup.Opacity = 0;
                    }

                    if (strExclude != string.Empty)
                        frmPickSkillGroup.ExcludeCategory = strExclude;

                    frmPickSkillGroup.ShowDialog();

                    // Make sure the dialogue window was not canceled.
                    if (frmPickSkillGroup.DialogResult == DialogResult.Cancel)
                    {
                        Rollback();
                        blnSuccess = false;
                        _strForcedValue = "";
                        _strLimitSelection = "";
                        return false;
                    }

                    bool blnAddToRating = false;
                    if (nodBonus["selectskillgroup"]["applytorating"] != null)
                    {
                        if (nodBonus["selectskillgroup"]["applytorating"].InnerText == "yes")
                            blnAddToRating = true;
                    }

                    _strSelectedValue = frmPickSkillGroup.SelectedSkillGroup;

                    CreateImprovement(_strSelectedValue, objImprovementSource, strSourceName, Improvement.ImprovementType.SkillGroup, strUnique, blnConditional, ValueToInt(nodBonus["selectskillgroup"]["bonus"].InnerText, intRating), 1, 0, 0, 0, 0, strExclude, blnAddToRating);
                }

                // Select an Attribute.
                if (NodeExists(nodBonus, "selectattribute"))
                {
                    // Display the Select Attribute window and record which Skill was selected.
                    frmSelectAttribute frmPickAttribute = new frmSelectAttribute();
                    if (strFriendlyName != "")
                        frmPickAttribute.Description = LanguageManager.Instance.GetString("String_Improvement_SelectAttributeNamed").Replace("{0}", strFriendlyName);
                    else
                        frmPickAttribute.Description = LanguageManager.Instance.GetString("String_Improvement_SelectAttribute");

                    // Add MAG and/or RES to the list of Attributes if they are enabled on the form.
                    if (_objCharacter.MAGEnabled)
                        frmPickAttribute.AddMAG();
                    if (_objCharacter.RESEnabled)
                        frmPickAttribute.AddRES();

                    if (nodBonus["selectattribute"]["attribute"] != null)
                    {
                        List<string> strValue = new List<string>();
                        foreach (XmlNode objXmlAttribute in nodBonus["selectattribute"].SelectNodes("attribute"))
                            strValue.Add(objXmlAttribute.InnerText);
                        frmPickAttribute.LimitToList(strValue);
                    }

                    if (nodBonus["selectattribute"]["excludeattribute"] != null)
                    {
                        List<string> strValue = new List<string>();
                        foreach (XmlNode objXmlAttribute in nodBonus["selectattribute"].SelectNodes("excludeattribute"))
                            strValue.Add(objXmlAttribute.InnerText);
                        frmPickAttribute.RemoveFromList(strValue);
                    }

                    // Check to see if there is only one possible selection because of _strLimitSelection.
                    if (_strForcedValue != "")
                        _strLimitSelection = _strForcedValue;

                    if (_strLimitSelection != "")
                    {
                        frmPickAttribute.SingleAttribute(_strLimitSelection);
                        frmPickAttribute.Opacity = 0;
                    }

                    frmPickAttribute.ShowDialog();

                    // Make sure the dialogue window was not canceled.
                    if (frmPickAttribute.DialogResult == DialogResult.Cancel)
                    {
                        Rollback();
                        blnSuccess = false;
                        _strForcedValue = "";
                        _strLimitSelection = "";
                        return false;
                    }

                    _strSelectedValue = frmPickAttribute.SelectedAttribute;
                    if (blnConcatSelectedValue)
                        strSourceName += " (" + _strSelectedValue + ")";

                    // Record the improvement.
                    int intMin = 0;
                    int intAug = 0;
                    int intMax = 0;
                    int intAugMax = 0;

                    // Extract the modifiers.
                    if (nodBonus["selectattribute"]["min"] != null)
                        intMin = ValueToInt(nodBonus["selectattribute"]["min"].InnerXml, intRating);
                    if (nodBonus["selectattribute"]["val"] != null)
                        intAug = ValueToInt(nodBonus["selectattribute"]["val"].InnerXml, intRating);
                    if (nodBonus["selectattribute"]["max"] != null)
                        intMax = ValueToInt(nodBonus["selectattribute"]["max"].InnerXml, intRating);
                    if (nodBonus["selectattribute"]["aug"] != null)
                        intAugMax = ValueToInt(nodBonus["selectattribute"]["aug"].InnerXml, intRating);

                    string strAttribute = frmPickAttribute.SelectedAttribute;

                    if (nodBonus["selectattribute"]["affectbase"] != null)
                        strAttribute += "Base";

                    CreateImprovement(strAttribute, objImprovementSource, strSourceName, Improvement.ImprovementType.Attribute, strUnique, blnConditional, 0, 1, intMin, intMax, intAug, intAugMax);
                }

                // Select an Attribute.
                if (NodeExists(nodBonus, "swapskillattribute"))
                {
                    // Display the Select Attribute window and record which Skill was selected.
                    frmSelectAttribute frmPickAttribute = new frmSelectAttribute();
                    if (strFriendlyName != "")
                        frmPickAttribute.Description = LanguageManager.Instance.GetString("String_Improvement_SelectAttributeNamed").Replace("{0}", strFriendlyName);
                    else
                        frmPickAttribute.Description = LanguageManager.Instance.GetString("String_Improvement_SelectAttribute");

                    List<string> strValue = new List<string>();
                    strValue.Add("LOG");
                    strValue.Add("WIL");
                    strValue.Add("INT");
                    strValue.Add("CHA");
                    strValue.Add("EDG");
                    strValue.Add("MAG");
                    strValue.Add("RES");
                    frmPickAttribute.RemoveFromList(strValue);

                    if (nodBonus["swapskillattribute"]["attribute"] != null)
                    {
                        List<string> strLimitValue = new List<string>();
                        foreach (XmlNode objXmlAttribute in nodBonus["swapskillattribute"].SelectNodes("attribute"))
                            strLimitValue.Add(objXmlAttribute.InnerText);
                        frmPickAttribute.LimitToList(strLimitValue);
                    }

                    // Check to see if there is only one possible selection because of _strLimitSelection.
                    if (_strForcedValue != "")
                        _strLimitSelection = _strForcedValue;

                    if (_strLimitSelection != "")
                    {
                        frmPickAttribute.SingleAttribute(_strLimitSelection);
                        frmPickAttribute.Opacity = 0;
                    }

                    frmPickAttribute.ShowDialog();

                    // Make sure the dialogue window was not canceled.
                    if (frmPickAttribute.DialogResult == DialogResult.Cancel)
                    {
                        Rollback();
                        blnSuccess = false;
                        _strForcedValue = "";
                        _strLimitSelection = "";
                        return false;
                    }

                    _strSelectedValue = frmPickAttribute.SelectedAttribute;
                    if (blnConcatSelectedValue)
                        strSourceName += " (" + _strSelectedValue + ")";

                    CreateImprovement(frmPickAttribute.SelectedAttribute, objImprovementSource, strSourceName, Improvement.ImprovementType.SwapSkillAttribute, strUnique, blnConditional);
                }

                // Select a Spell.
                if (NodeExists(nodBonus, "selectspell"))
                {
                    // Display the Select Spell window.
                    frmSelectSpell frmPickSpell = new frmSelectSpell(_objCharacter);

                    if (nodBonus["selectspell"].Attributes["category"] != null)
                        frmPickSpell.LimitCategory = nodBonus["selectspell"].Attributes["category"].InnerText;
                    if (_strForcedValue != "")
                    {
                        frmPickSpell.ForceSpellName = _strForcedValue;
                        frmPickSpell.Opacity = 0;
                    }

                    frmPickSpell.ShowDialog();

                    // Make sure the dialogue window was not canceled.
                    if (frmPickSpell.DialogResult == DialogResult.Cancel)
                    {
                        Rollback();
                        blnSuccess = false;
                        _strForcedValue = "";
                        _strLimitSelection = "";
                        return false;
                    }

                    _strSelectedValue = frmPickSpell.SelectedSpell;
                    if (blnConcatSelectedValue)
                        strSourceName += " (" + _strSelectedValue + ")";

                    CreateImprovement(frmPickSpell.SelectedSpell, objImprovementSource, strSourceName, Improvement.ImprovementType.Text, strUnique, blnConditional);
                }

                // Affect a Specific Attribute.
                if (NodeExists(nodBonus, "specificattribute"))
                {
                    XmlNodeList objXmlAttributeList = nodBonus.SelectNodes("specificattribute");
                    foreach (XmlNode objXmlAttribute in objXmlAttributeList)
                    {
                        if (objXmlAttribute["name"].InnerText != "ESS")
                        {
                            // Display the Select Attribute window and record which Attribute was selected.
                            // Record the improvement.
                            int intMin = 0;
                            int intAug = 0;
                            int intMax = 0;
                            int intAugMax = 0;

                            // Extract the modifiers.
                            if (objXmlAttribute["min"] != null)
                                intMin = ValueToInt(objXmlAttribute["min"].InnerXml, intRating);
                            if (objXmlAttribute["val"] != null)
                                intAug = ValueToInt(objXmlAttribute["val"].InnerXml, intRating);
                            if (objXmlAttribute["max"] != null)
                            {
                                if (objXmlAttribute["max"].InnerText.Contains("-natural"))
                                {
                                    intMax = Convert.ToInt32(objXmlAttribute["max"].InnerText.Replace("-natural", string.Empty)) - _objCharacter.GetAttribute(objXmlAttribute["name"].InnerText).MetatypeMaximum;
                                }
                                else
                                    intMax = ValueToInt(objXmlAttribute["max"].InnerXml, intRating);
                            }
                            if (objXmlAttribute["aug"] != null)
                                intAugMax = ValueToInt(objXmlAttribute["aug"].InnerXml, intRating);

                            string strUseUnique = strUnique;
                            if (objXmlAttribute["name"].Attributes["precedence"] != null)
                                strUseUnique = "precedence" + objXmlAttribute["name"].Attributes["precedence"].InnerText;

                            string strAttribute = objXmlAttribute["name"].InnerText;

                            if (objXmlAttribute["affectbase"] != null)
                                strAttribute += "Base";

                            CreateImprovement(strAttribute, objImprovementSource, strSourceName, Improvement.ImprovementType.Attribute, strUseUnique, blnConditional, 0, 1, intMin, intMax, intAug, intAugMax);
                        }
                        else
                            CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Essence, "", blnConditional, Convert.ToInt32(objXmlAttribute["val"].InnerText));
                    }
                }

                // Change the maximum number of BP that can be spent on Nuyen.
                if (NodeExists(nodBonus, "nuyenmaxbp"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.NuyenMaxBP, "", blnConditional, ValueToInt(nodBonus["nuyenmaxbp"].InnerText, intRating));
                }

                // Change the amount of Nuyen the character has at creation time (this can put the character over the amount they're normally allowed).
                if (NodeExists(nodBonus, "nuyenamt"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Nuyen, strUnique, blnConditional, ValueToInt(nodBonus["nuyenamt"].InnerText, intRating));
                }

                // Improve Condition Monitors.
                if (NodeExists(nodBonus, "conditionmonitor"))
                {
                    // Physical Condition.
                    if (nodBonus["conditionmonitor"]["physical"] != null)
                        CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.PhysicalCM, strUnique, blnConditional, ValueToInt(nodBonus["conditionmonitor"]["physical"].InnerText, intRating));

                    // Stun Condition.
                    if (nodBonus["conditionmonitor"]["stun"] != null)
                        CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.StunCM, strUnique, blnConditional, ValueToInt(nodBonus["conditionmonitor"]["stun"].InnerText, intRating));

                    // Condition Monitor Threshold.
                    if (NodeExists(nodBonus.SelectSingleNode("conditionmonitor"), "threshold"))
                    {
                        string strUseUnique = strUnique;
                        if (nodBonus["conditionmonitor"]["threshold"].Attributes["precedence"] != null)
                            strUseUnique = "precedence" + nodBonus["conditionmonitor"]["threshold"].Attributes["precedence"].InnerText;

                        CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.CMThreshold, strUseUnique, blnConditional, ValueToInt(nodBonus.SelectSingleNode("conditionmonitor")["threshold"].InnerText, intRating));
                    }

                    // Condition Monitor Threshold Offset. (Additioal boxes appear before the FIRST Condition Monitor penalty)
                    if (NodeExists(nodBonus.SelectSingleNode("conditionmonitor"), "thresholdoffset"))
                    {
                        string strUseUnique = strUnique;
                        if (nodBonus["conditionmonitor"]["thresholdoffset"].Attributes["precedence"] != null)
                            strUseUnique = "precedence" + nodBonus["conditionmonitor"]["thresholdoffset"].Attributes["precedence"].InnerText;

                        CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.CMThresholdOffset, strUseUnique, blnConditional, ValueToInt(nodBonus.SelectSingleNode("conditionmonitor")["thresholdoffset"].InnerText, intRating));
                    }

                    // Condition Monitor Overflow.
                    if (nodBonus["conditionmonitor"]["overflow"] != null)
                        CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.CMOverflow, strUnique, blnConditional, ValueToInt(nodBonus["conditionmonitor"]["overflow"].InnerText, intRating));
                }

                // Improve Living Personal Attributes.
                if (NodeExists(nodBonus, "livingpersona"))
                {
                    // Response.
                    if (nodBonus["livingpersona"]["response"] != null)
                        CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.LivingPersonaResponse, strUnique, blnConditional, ValueToInt(nodBonus["livingpersona"]["response"].InnerText, intRating));

                    // Signal.
                    if (nodBonus["livingpersona"]["signal"] != null)
                        CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.LivingPersonaSignal, strUnique, blnConditional, ValueToInt(nodBonus["livingpersona"]["signal"].InnerText, intRating));

                    // Firewall.
                    if (nodBonus["livingpersona"]["firewall"] != null)
                        CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.LivingPersonaFirewall, strUnique, blnConditional, ValueToInt(nodBonus["livingpersona"]["firewall"].InnerText, intRating));

                    // System.
                    if (nodBonus["livingpersona"]["system"] != null)
                        CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.LivingPersonaSystem, strUnique, blnConditional, ValueToInt(nodBonus["livingpersona"]["system"].InnerText, intRating));

                    // Biofeedback Filter.
                    if (nodBonus["livingpersona"]["biofeedback"] != null)
                        CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.LivingPersonaBiofeedback, strUnique, blnConditional, ValueToInt(nodBonus["livingpersona"]["biofeedback"].InnerText, intRating));
                }

                // The Improvement adjusts a specific Skill.
                if (NodeExists(nodBonus, "specificskill"))
                {
                    XmlNodeList objXmlSkillList = nodBonus.SelectNodes("specificskill");
                    // Run through each specific Skill since there may be more than one affected.
                    foreach (XmlNode objXmlSkill in objXmlSkillList)
                    {
                        bool blnAddToRating = false;
                        if (objXmlSkill["applytorating"] != null)
                        {
                            if (objXmlSkill["applytorating"].InnerText == "yes")
                                blnAddToRating = true;
                        }

                        string strUseUnique = strUnique;
                        if (nodBonus["specificskill"].Attributes["precedence"] != null)
                            strUseUnique = "precedence" + nodBonus["specificskill"].Attributes["precedence"].InnerText;

                        // Record the improvement.
                        if (objXmlSkill["bonus"] != null)
                            CreateImprovement(objXmlSkill["name"].InnerText, objImprovementSource, strSourceName, Improvement.ImprovementType.Skill, strUseUnique, blnConditional, ValueToInt(objXmlSkill["bonus"].InnerXml, intRating), 1, 0, 0, 0, 0, "", blnAddToRating);
                        if (objXmlSkill["max"] != null)
                            CreateImprovement(objXmlSkill["name"].InnerText, objImprovementSource, strSourceName, Improvement.ImprovementType.Skill, strUseUnique, blnConditional, 0, 1, 0, ValueToInt(objXmlSkill["max"].InnerText, intRating), 0, 0, "", blnAddToRating);
                    }
                }

                // The Improvement adjusts a Skill Category.
                if (NodeExists(nodBonus, "skillcategory"))
                {
                    XmlNodeList objXmlSkillList = nodBonus.SelectNodes("skillcategory");
                    // Run through each of the Skill Categories since there may be more than one affected.
                    foreach (XmlNode objXmlSkill in objXmlSkillList)
                    {
                        bool blnAddToRating = false;
                        if (objXmlSkill["applytorating"] != null)
                        {
                            if (objXmlSkill["applytorating"].InnerText == "yes")
                                blnAddToRating = true;
                        }
                        if (objXmlSkill["exclude"] != null)
                            CreateImprovement(objXmlSkill["name"].InnerText, objImprovementSource, strSourceName, Improvement.ImprovementType.SkillCategory, strUnique, blnConditional, ValueToInt(objXmlSkill["bonus"].InnerXml, intRating), 1, 0, 0, 0, 0, objXmlSkill["exclude"].InnerText, blnAddToRating);
                        else
                            CreateImprovement(objXmlSkill["name"].InnerText, objImprovementSource, strSourceName, Improvement.ImprovementType.SkillCategory, strUnique, blnConditional, ValueToInt(objXmlSkill["bonus"].InnerXml, intRating), 1, 0, 0, 0, 0, "", blnAddToRating);
                    }
                }

                // The Improvement adjusts a Skill Group.
                if (NodeExists(nodBonus, "skillgroup"))
                {
                    XmlNodeList objXmlSkillList = nodBonus.SelectNodes("skillgroup");
                    // Run through each of the Skill Groups since there may be more than one affected.
                    foreach (XmlNode objXmlSkill in objXmlSkillList)
                    {
                        bool blnAddToRating = false;
                        if (objXmlSkill["applytorating"] != null)
                        {
                            if (objXmlSkill["applytorating"].InnerText == "yes")
                                blnAddToRating = true;
                        }
                        if (objXmlSkill["exclude"] != null)
                            CreateImprovement(objXmlSkill["name"].InnerText, objImprovementSource, strSourceName, Improvement.ImprovementType.SkillGroup, strUnique, blnConditional, ValueToInt(objXmlSkill["bonus"].InnerXml, intRating), 1, 0, 0, 0, 0, objXmlSkill["exclude"].InnerText, blnAddToRating);
                        else
                            CreateImprovement(objXmlSkill["name"].InnerText, objImprovementSource, strSourceName, Improvement.ImprovementType.SkillGroup, strUnique, blnConditional, ValueToInt(objXmlSkill["bonus"].InnerXml, intRating), 1, 0, 0, 0, 0, "", blnAddToRating);
                    }
                }

                // The Improvement adjust Skills with the given Attribute.
                if (NodeExists(nodBonus, "skillattribute"))
                {
                    XmlNodeList objXmlSkillList = nodBonus.SelectNodes("skillattribute");
                    // Run through each of the Skill Attributes since there may be more than one affected.
                    foreach (XmlNode objXmlSkill in objXmlSkillList)
                    {
                        string strUseUnique = strUnique;
                        if (objXmlSkill["name"].Attributes["precedence"] != null)
                            strUseUnique = "precedence" + objXmlSkill["name"].Attributes["precedence"].InnerText;

                        bool blnAddToRating = false;
                        if (objXmlSkill["applytorating"] != null)
                        {
                            if (objXmlSkill["applytorating"].InnerText == "yes")
                                blnAddToRating = true;
                        }
                        if (objXmlSkill["exclude"] != null)
                            CreateImprovement(objXmlSkill["name"].InnerText, objImprovementSource, strSourceName, Improvement.ImprovementType.SkillAttribute, strUseUnique, blnConditional, ValueToInt(objXmlSkill["value"].InnerXml, intRating), 1, 0, 0, 0, 0, objXmlSkill["exclude"].InnerText, blnAddToRating);
                        else
                            CreateImprovement(objXmlSkill["name"].InnerText, objImprovementSource, strSourceName, Improvement.ImprovementType.SkillAttribute, strUseUnique, blnConditional, ValueToInt(objXmlSkill["value"].InnerXml, intRating), 1, 0, 0, 0, 0, "", blnAddToRating);
                    }
                }

                // The Improvement comes from Enhanced Articulation (improves Physical Active Skills linked to a Physical Attribute).
                if (NodeExists(nodBonus, "skillarticulation"))
                {
                    XmlNode objXmlSkill = nodBonus.SelectSingleNode("skillarticulation");
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.EnhancedArticulation, strUnique, blnConditional, ValueToInt(objXmlSkill["bonus"].InnerText, intRating));
                }

                // Check for Armor modifiers.
                if (NodeExists(nodBonus, "armorvalue"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.ArmorValue, strUnique, blnConditional, ValueToInt(nodBonus["armorvalue"].InnerText, intRating));
                }

                // Check for Reach modifiers.
                if (NodeExists(nodBonus, "reach"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Reach, strUnique, blnConditional, ValueToInt(nodBonus["reach"].InnerText, intRating));
                }

                // Check for Unarmed Damage Value modifiers.
                if (NodeExists(nodBonus, "unarmeddv"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.UnarmedDV, strUnique, blnConditional, ValueToInt(nodBonus["unarmeddv"].InnerText, intRating));
                }

                // Check for Unarmed Damage Value Physical.
                if (NodeExists(nodBonus, "unarmeddvphysical"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.UnarmedDVPhysical, "", blnConditional);
                }

                // Check for Unarmed Armor Penetration.
                if (NodeExists(nodBonus, "unarmedap"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.UnarmedAP, strUnique, blnConditional, ValueToInt(nodBonus["unarmedap"].InnerText, intRating));
                }

                // Check for Initiative modifiers.
                if (NodeExists(nodBonus, "initiative"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Initiative, strUnique, blnConditional, ValueToInt(nodBonus["initiative"].InnerText, intRating));
                }

                // Check for Initiative Dice modifiers.
                if (NodeExists(nodBonus, "initiativedice"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.InitiativeDice, strUnique, blnConditional, ValueToInt(nodBonus["initiativedice"].InnerText, intRating));
                }

                // Check for Matrix Initiative modifiers.
                if (NodeExists(nodBonus, "matrixinitiative"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.MatrixInitiative, strUnique, blnConditional, ValueToInt(nodBonus["matrixinitiative"].InnerText, intRating));
                }

                // Check for Matrix Initiative Pass modifiers.
                if (NodeExists(nodBonus, "matrixinitiativepass"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.MatrixInitiativePass, "matrixinitiativepass", blnConditional, ValueToInt(nodBonus["matrixinitiativepass"].InnerText, intRating));
                }

                // Check for Matrix Initiative Pass modifiers.
                if (NodeExists(nodBonus, "matrixinitiativepassadd"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.MatrixInitiativePass, strUnique, blnConditional, ValueToInt(nodBonus["matrixinitiativepassadd"].InnerText, intRating));
                }

                // Check for Lifestyle cost modifiers.
                if (NodeExists(nodBonus, "lifestylecost"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.LifestyleCost, strUnique, blnConditional, ValueToInt(nodBonus["lifestylecost"].InnerText, intRating));
                }

                // Check for basic Lifestyle cost modifiers.
                if (NodeExists(nodBonus, "basiclifestylecost"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.BasicLifestyleCost, strUnique, blnConditional, ValueToInt(nodBonus["basiclifestylecost"].InnerText, intRating));
                }

                // Check for Genetech Cost modifiers.
                if (NodeExists(nodBonus, "genetechcostmultiplier"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.GenetechCostMultiplier, strUnique, blnConditional, ValueToInt(nodBonus["genetechcostmultiplier"].InnerText, intRating));
                }

                // Check for Genetech: Transgenics Cost modifiers.
                if (NodeExists(nodBonus, "transgenicsgenetechcost"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.TransgenicsBiowareCost, strUnique, blnConditional, ValueToInt(nodBonus["transgenicsgenetechcost"].InnerText, intRating));
                }

                // Check for Basic Bioware Essence Cost modifiers.
                if (NodeExists(nodBonus, "basicbiowareessmultiplier"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.BasicBiowareEssCost, strUnique, blnConditional, ValueToInt(nodBonus["basicbiowareessmultiplier"].InnerText, intRating));
                }

                // Check for Bioware Essence Cost modifiers.
                if (NodeExists(nodBonus, "biowareessmultiplier"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.BiowareEssCost, strUnique, blnConditional, ValueToInt(nodBonus["biowareessmultiplier"].InnerText, intRating));
                }

                // Check for Cybeware Essence Cost modifiers.
                if (NodeExists(nodBonus, "cyberwareessmultiplier"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.CyberwareEssCost, strUnique, blnConditional, ValueToInt(nodBonus["cyberwareessmultiplier"].InnerText, intRating));
                }

                // Check for Uneducated modifiers.
                if (NodeExists(nodBonus, "uneducated"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Uneducated, strUnique, blnConditional);
                    _objCharacter.Uneducated = true;
                }

                // Check for Uncouth modifiers.
                if (NodeExists(nodBonus, "uncouth"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Uncouth, strUnique, blnConditional);
                    _objCharacter.Uncouth = true;
                }

                // Check for Infirm modifiers.
                if (NodeExists(nodBonus, "infirm"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Infirm, strUnique, blnConditional);
                    _objCharacter.Infirm = true;
                }

                // Check for Adept Linguistics.
                if (NodeExists(nodBonus, "adeptlinguistics"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.AdeptLinguistics, strUnique, blnConditional, 1);
                }

                // Check for Weapon Category DV modifiers.
                if (NodeExists(nodBonus, "weaponcategorydv"))
                {
                    XmlNodeList objXmlCategoryList = nodBonus.SelectNodes("weaponcategorydv");
                    // Run through each of the Skill Groups since there may be more than one affected.
                    foreach (XmlNode objXmlCategory in objXmlCategoryList)
                        CreateImprovement(objXmlCategory["name"].InnerText, objImprovementSource, strSourceName, Improvement.ImprovementType.WeaponCategoryDV, strUnique, blnConditional, ValueToInt(objXmlCategory["bonus"].InnerXml, intRating));
                }

                // Check for Mentor Spirit bonuses.
                if (NodeExists(nodBonus, "selectmentorspirit"))
                {
                    frmSelectMentorSpirit frmPickMentorSpirit = new frmSelectMentorSpirit(_objCharacter);
                    frmPickMentorSpirit.ShowDialog();

                    // Make sure the dialogue window was not canceled.
                    if (frmPickMentorSpirit.DialogResult == DialogResult.Cancel)
                    {
                        Rollback();
                        blnSuccess = false;
                        _strForcedValue = "";
                        _strLimitSelection = "";
                        return blnSuccess;
                    }

                    _strSelectedValue = frmPickMentorSpirit.SelectedMentor;
                    string strHoldValue = _strSelectedValue;
                    if (blnConcatSelectedValue)
                        strSourceName += " (" + _strSelectedValue + ")";

                    if (frmPickMentorSpirit.BonusNode != null)
                    {
                        blnSuccess = CreateImprovements(objImprovementSource, strSourceName, frmPickMentorSpirit.BonusNode, blnConcatSelectedValue, intRating, strFriendlyName);
                        if (!blnSuccess)
                        {
                            Rollback();
                            _strForcedValue = "";
                            _strLimitSelection = "";
                            return blnSuccess;
                        }
                    }

                    if (frmPickMentorSpirit.BonusNode2 != null)
                    {
                        blnSuccess = CreateImprovements(objImprovementSource, strSourceName, frmPickMentorSpirit.BonusNode2, blnConcatSelectedValue, intRating, strFriendlyName);
                        if (!blnSuccess)
                        {
                            Rollback();
                            _strForcedValue = "";
                            _strLimitSelection = "";
                            return blnSuccess;
                        }
                    }

                    if (frmPickMentorSpirit.Choice1BonusNode != null)
                    {
                        string strForce = _strForcedValue;
                        _strForcedValue = frmPickMentorSpirit.Choice1;
                        blnSuccess = CreateImprovements(objImprovementSource, strSourceName, frmPickMentorSpirit.Choice1BonusNode, blnConcatSelectedValue, intRating, strFriendlyName);
                        if (!blnSuccess)
                        {
                            Rollback();
                            _strForcedValue = "";
                            _strLimitSelection = "";
                            return blnSuccess;
                        }
                        _strForcedValue = strForce;
                        _objCharacter.Improvements.Last().Notes = frmPickMentorSpirit.Choice1;
                    }

                    if (frmPickMentorSpirit.Choice2BonusNode != null)
                    {
                        string strForce = _strForcedValue;
                        _strForcedValue = frmPickMentorSpirit.Choice2;
                        blnSuccess = CreateImprovements(objImprovementSource, strSourceName, frmPickMentorSpirit.Choice2BonusNode, blnConcatSelectedValue, intRating, strFriendlyName);
                        if (!blnSuccess)
                        {
                            Rollback();
                            _strForcedValue = "";
                            _strLimitSelection = "";
                            return blnSuccess;
                        }
                        _strForcedValue = strForce;
                        _objCharacter.Improvements.Last().Notes = frmPickMentorSpirit.Choice2;
                    }

                    _strSelectedValue = strHoldValue;
                }

                // Check for Paragon bonuses.
                if (NodeExists(nodBonus, "selectparagon"))
                {
                    frmSelectMentorSpirit frmPickMentorSpirit = new frmSelectMentorSpirit(_objCharacter);
                    frmPickMentorSpirit.XmlFile = "paragons.xml";
                    frmPickMentorSpirit.ShowDialog();

                    // Make sure the dialogue window was not canceled.
                    if (frmPickMentorSpirit.DialogResult == DialogResult.Cancel)
                    {
                        Rollback();
                        blnSuccess = false;
                        _strForcedValue = "";
                        _strLimitSelection = "";
                        return blnSuccess;
                    }

                    _strSelectedValue = frmPickMentorSpirit.SelectedMentor;
                    string strHoldValue = _strSelectedValue;
                    if (blnConcatSelectedValue)
                        strSourceName += " (" + _strSelectedValue + ")";

                    if (frmPickMentorSpirit.BonusNode != null)
                    {
                        blnSuccess = CreateImprovements(objImprovementSource, strSourceName, frmPickMentorSpirit.BonusNode, blnConcatSelectedValue, intRating, strFriendlyName);
                        if (!blnSuccess)
                        {
                            Rollback();
                            _strForcedValue = "";
                            _strLimitSelection = "";
                            return blnSuccess;
                        }
                    }

                    if (frmPickMentorSpirit.Choice1BonusNode != null)
                    {
                        string strForce = _strForcedValue;
                        _strForcedValue = frmPickMentorSpirit.Choice1;
                        blnSuccess = CreateImprovements(objImprovementSource, strSourceName, frmPickMentorSpirit.Choice1BonusNode, blnConcatSelectedValue, intRating, strFriendlyName);
                        if (!blnSuccess)
                        {
                            Rollback();
                            _strForcedValue = "";
                            _strLimitSelection = "";
                            return blnSuccess;
                        }
                        _strForcedValue = strForce;
                        _objCharacter.Improvements.Last().Notes = frmPickMentorSpirit.Choice1;
                    }

                    if (frmPickMentorSpirit.Choice2BonusNode != null)
                    {
                        string strForce = _strForcedValue;
                        _strForcedValue = frmPickMentorSpirit.Choice2;
                        blnSuccess = CreateImprovements(objImprovementSource, strSourceName, frmPickMentorSpirit.Choice2BonusNode, blnConcatSelectedValue, intRating, strFriendlyName);
                        if (!blnSuccess)
                        {
                            Rollback();
                            _strForcedValue = "";
                            _strLimitSelection = "";
                            return blnSuccess;
                        }
                        _strForcedValue = strForce;
                        _objCharacter.Improvements.Last().Notes = frmPickMentorSpirit.Choice2;
                    }

                    _strSelectedValue = strHoldValue;
                }

                // Check for Smartlink bonus.
                if (NodeExists(nodBonus, "smartlink"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Smartlink, "smartlink", blnConditional);
                }

                // Check for Adapsin bonus.
                if (NodeExists(nodBonus, "adapsin"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Adapsin, "adapsin", blnConditional);
                }

                // Check for SoftWeave bonus.
                if (NodeExists(nodBonus, "softweave"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.SoftWeave, "softweave", blnConditional);
                }

                // Check for Sensitive System.
                if (NodeExists(nodBonus, "sensitivesystem"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.SensitiveSystem, "sensitivesystem", blnConditional);
                    _objCharacter.SensitiveSystem = true;
                }

                // Check for Movement Percent.
                if (NodeExists(nodBonus, "movementpercent"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.MovementPercent, "", blnConditional, ValueToInt(nodBonus["movementpercent"].InnerText, intRating));
                }

                // Check for Swim Percent.
                if (NodeExists(nodBonus, "swimpercent"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.SwimPercent, "", blnConditional, ValueToInt(nodBonus["swimpercent"].InnerText, intRating));
                }

                // Check for Fly Percent.
                if (NodeExists(nodBonus, "flypercent"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.FlyPercent, "", blnConditional, ValueToInt(nodBonus["flypercent"].InnerText, intRating));
                }

                // Check for Fly Speed.
                if (NodeExists(nodBonus, "flyspeed"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.FlySpeed, "", blnConditional, ValueToInt(nodBonus["flyspeed"].InnerText, intRating));
                }

                // Check for free Positive Qualities.
                if (NodeExists(nodBonus, "freepositivequalities"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.FreePositiveQualities, "", blnConditional, ValueToInt(nodBonus["freepositivequalities"].InnerText, intRating));
                }

                // Check for free Negative Qualities.
                if (NodeExists(nodBonus, "freenegativequalities"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.FreeNegativeQualities, "", blnConditional, ValueToInt(nodBonus["freenegativequalities"].InnerText, intRating));
                }

                // Check for Select Side.
                if (NodeExists(nodBonus, "selectside"))
                {
                    frmSelectSide frmPickSide = new frmSelectSide();
                    frmPickSide.Description = LanguageManager.Instance.GetString("Label_SelectSide").Replace("{0}", strFriendlyName);
                    if (_strForcedValue != "")
                        frmPickSide.ForceValue(_strForcedValue);
                    else
                        frmPickSide.ShowDialog();

                    // Make sure the dialogue window was not canceled.
                    if (frmPickSide.DialogResult == DialogResult.Cancel)
                    {
                        Rollback();
                        blnSuccess = false;
                        _strForcedValue = "";
                        _strLimitSelection = "";
                        return blnSuccess;
                    }

                    _strSelectedValue = frmPickSide.SelectedSide;
                }

                // Check for Free Spirit Power Points.
                if (NodeExists(nodBonus, "freespiritpowerpoints"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.FreeSpiritPowerPoints, "", blnConditional, ValueToInt(nodBonus["freespiritpowerpoints"].InnerText, intRating));
                }

                // Check for Adept Power Points.
                if (NodeExists(nodBonus, "adeptpowerpoints"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.AdeptPowerPoints, "", blnConditional, ValueToInt(nodBonus["adeptpowerpoints"].InnerText, intRating));
                }

                // Check for Armor Encumbrance Penalty.
                if (NodeExists(nodBonus, "armorencumbrancepenalty"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.ArmorEncumbrancePenalty, "", blnConditional, ValueToInt(nodBonus["armorencumbrancepenalty"].InnerText, intRating));
                }

                // Check for Initiation.
                if (NodeExists(nodBonus, "initiation"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Initiation, "", blnConditional, ValueToInt(nodBonus["initiation"].InnerText, intRating));
                    _objCharacter.InitiateGrade += ValueToInt(nodBonus["initiation"].InnerText, intRating);
                }

                // Check for Submersion.
                if (NodeExists(nodBonus, "submersion"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Submersion, "", blnConditional, ValueToInt(nodBonus["submersion"].InnerText, intRating));
                    _objCharacter.SubmersionGrade += ValueToInt(nodBonus["submersion"].InnerText, intRating);
                }

                // Check for Skillwires.
                if (NodeExists(nodBonus, "skillwire"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Skillwire, "", blnConditional, ValueToInt(nodBonus["skillwire"].InnerText, intRating));
                }

                // Check for Damage Resistance.
                if (NodeExists(nodBonus, "damageresistance"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.DamageResistance, "damageresistance", blnConditional, ValueToInt(nodBonus["damageresistance"].InnerText, intRating));
                }

                // Check for Restricted Item Count.
                if (NodeExists(nodBonus, "restricteditemcount"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.RestrictedItemCount, "", blnConditional, ValueToInt(nodBonus["restricteditemcount"].InnerText, intRating));
                }

                // Check for Judge Intentions.
                if (NodeExists(nodBonus, "judgeintentions"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.JudgeIntentions, "", blnConditional, ValueToInt(nodBonus["judgeintentions"].InnerText, intRating));
                }

                // Check for Select Inherent Limit.
                if (NodeExists(nodBonus, "selectinherentlimit"))
                {
                    frmSelectItem frmPickItem = new frmSelectItem();
                    frmPickItem.ManualMode = "InherentLimits";
                    frmPickItem.Description = LanguageManager.Instance.GetString("String_SelectInherentLimit");
                    frmPickItem.ShowDialog();

                    if (frmPickItem.DialogResult == DialogResult.Cancel)
                    {
                        Rollback();
                        blnSuccess = false;
                        _strForcedValue = "";
                        _strLimitSelection = "";
                        return blnSuccess;
                    }

                    _strSelectedValue = frmPickItem.SelectedItem;

                    Improvement.ImprovementType objImprovementType = new Improvement.ImprovementType();
                    switch (frmPickItem.SelectedItem)
                    {
                        case "mentallimit":
                            objImprovementType = Improvement.ImprovementType.MentalLimit;
                            break;
                        case "physicallimit":
                            objImprovementType = Improvement.ImprovementType.PhysicalLimit;
                            break;
                        case "sociallimit":
                            objImprovementType = Improvement.ImprovementType.SocialLimit;
                            break;
                    }
                    CreateImprovement(frmPickItem.SelectedItem, objImprovementSource, strSourceName, Improvement.ImprovementType.AddSprite, "", blnConditional);
                    CreateImprovement("", objImprovementSource, strSourceName, objImprovementType, "", blnConditional, ValueToInt(nodBonus["selectinherentlimit"]["value"].InnerText, intRating));
                }

                // Check for Mental Limit.
                if (NodeExists(nodBonus, "mentallimit"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.MentalLimit, "", blnConditional, ValueToInt(nodBonus["mentallimit"].InnerText, intRating));
                }

                // Check for Physical Limit.
                if (NodeExists(nodBonus, "physicallimit"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.PhysicalLimit, "", blnConditional, ValueToInt(nodBonus["physicallimit"].InnerText, intRating));
                }

                // Check for Social Limit.
                if (NodeExists(nodBonus, "sociallimit"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.SocialLimit, "", blnConditional, ValueToInt(nodBonus["sociallimit"].InnerText, intRating));
                }

                // Check for Surprise.
                if (NodeExists(nodBonus, "surprise"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Surprise, "", blnConditional, ValueToInt(nodBonus["surprise"].InnerText, intRating));
                }

                // Check for Composure.
                if (NodeExists(nodBonus, "composure"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Composure, "", blnConditional, ValueToInt(nodBonus["composure"].InnerText, intRating));
                }

                // Check for Lift and Carry.
                if (NodeExists(nodBonus, "liftandcarry"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.LiftAndCarry, "", blnConditional, ValueToInt(nodBonus["liftandcarry"].InnerText, intRating));
                }

                // Check for Memory.
                if (NodeExists(nodBonus, "memory"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Memory, "", blnConditional, ValueToInt(nodBonus["memory"].InnerText, intRating));
                }

                // Check for Concealability.
                if (NodeExists(nodBonus, "concealability"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Concealability, "", blnConditional, ValueToInt(nodBonus["concealability"].InnerText, intRating));
                }

                // Check for Drain Resistance.
                if (NodeExists(nodBonus, "drainresist"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.DrainResistance, "", blnConditional, ValueToInt(nodBonus["drainresist"].InnerText, intRating));
                }

                // Check for Fading Resistance.
                if (NodeExists(nodBonus, "fadingresist"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.FadingResistance, "", blnConditional, ValueToInt(nodBonus["fadingresist"].InnerText, intRating));
                }

                // Check for Notoriety.
                if (NodeExists(nodBonus, "notoriety"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Notoriety, "", blnConditional, ValueToInt(nodBonus["notoriety"].InnerText, intRating));
                }

                // Check for Complex Form Limit.
                if (NodeExists(nodBonus, "complexformlimit"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.ComplexFormLimit, "", blnConditional, ValueToInt(nodBonus["complexformlimit"].InnerText, intRating));
                }

                // Check for Spell Limit.
                if (NodeExists(nodBonus, "spelllimit"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.SpellLimit, "", blnConditional, ValueToInt(nodBonus["spelllimit"].InnerText, intRating));
                }

                // Check for Spell Category bonuses.
                if (NodeExists(nodBonus, "spellcategory"))
                {
                    XmlNodeList objXmlCategoryList = nodBonus.SelectNodes("spellcategory");

                    // Run through each of the Spell Categories since there may be more than one affected.
                    foreach (XmlNode nodSpellCategory in objXmlCategoryList)
                    {
                        string strUseUnique = strUnique;
                        if (nodSpellCategory["name"].Attributes["precedence"] != null)
                            strUseUnique = "precedence" + nodSpellCategory["name"].Attributes["precedence"].InnerText;

                        CreateImprovement(nodSpellCategory["name"].InnerText, objImprovementSource, strSourceName, Improvement.ImprovementType.SpellCategory, strUseUnique, blnConditional, ValueToInt(nodSpellCategory["val"].InnerText, intRating));
                    }
                }

                // Check for Throwing Range bonuses.
                if (NodeExists(nodBonus, "throwrange"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.ThrowRange, strUnique, blnConditional, ValueToInt(nodBonus["throwrange"].InnerText, intRating));
                }

                // Check for Throwing STR bonuses.
                if (NodeExists(nodBonus, "throwstr"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.ThrowSTR, strUnique, blnConditional, ValueToInt(nodBonus["throwstr"].InnerText, intRating));
                }

                // Check for Accuracy bonuses.
                if (NodeExists(nodBonus, "accuracy"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Accuracy, strUnique, blnConditional, ValueToInt(nodBonus["accuracy"].InnerText, intRating));
                }

                // Check for Skillsoft access.
                if (NodeExists(nodBonus, "skillsoftaccess"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.SkillsoftAccess, "", blnConditional);
                }

                if (NodeExists(nodBonus, "knowsoftaccess"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.KnowsoftAccess, "", blnConditional);
                }

                // Check for Quickening Metamagic.
                if (NodeExists(nodBonus, "quickeningmetamagic"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.QuickeningMetamagic, "", blnConditional);
                }

                // Check for ignore Stun CM Penalty.
                if (NodeExists(nodBonus, "ignorecmpenaltystun"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.IgnoreCMPenaltyStun, "", blnConditional);
                }

                // Check for ignore Physical CM Penalty.
                if (NodeExists(nodBonus, "ignorecmpenaltyphysical"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.IgnoreCMPenaltyPhysical, "", blnConditional);
                }

                // Check for Maximum Essence which will permanently modify the character's Maximum Essence value.
                if (NodeExists(nodBonus, "essencemax"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.EssenceMax, "", blnConditional, ValueToInt(nodBonus["essencemax"].InnerText, intRating));
                }

                // Check for Select Sprite.
                if (NodeExists(nodBonus, "selectsprite"))
                {
                    XmlDocument objXmlDocument = XmlManager.Instance.Load("critters.xml");
                    XmlNodeList objXmlNodeList = objXmlDocument.SelectNodes("/chummer/metatypes/metatype[contains(category, \"Sprites\")]");
                    List<ListItem> lstCritters = new List<ListItem>();
                    foreach (XmlNode objXmlNode in objXmlNodeList)
                    {
                        ListItem objItem = new ListItem();
                        if (objXmlNode["translate"] != null)
                            objItem.Name = objXmlNode["translate"].InnerText;
                        else
                            objItem.Name = objXmlNode["name"].InnerText;
                        objItem.Value = objItem.Name;
                        lstCritters.Add(objItem);
                    }

                    frmSelectItem frmPickItem = new frmSelectItem();
                    frmPickItem.GeneralItems = lstCritters;
                    frmPickItem.ShowDialog();

                    if (frmPickItem.DialogResult == DialogResult.Cancel)
                    {
                        Rollback();
                        blnSuccess = false;
                        _strForcedValue = "";
                        _strLimitSelection = "";
                        return blnSuccess;
                    }

                    _strSelectedValue = frmPickItem.SelectedItem;

                    CreateImprovement(frmPickItem.SelectedItem, objImprovementSource, strSourceName, Improvement.ImprovementType.AddSprite, "", blnConditional);
                }

                // Check for Black Market Discount.
                if (NodeExists(nodBonus, "blackmarketdiscount"))
                {
                    CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.BlackMarketDiscount, strUnique, blnConditional);
                    _objCharacter.BlackMarket = true;
                }

                // Select Weapon (custom entry for things like Spare Clip).
                if (NodeExists(nodBonus, "selectweapon"))
                {
                    string strSelectedValue = "";
                    if (_strForcedValue != "")
                        _strLimitSelection = _strForcedValue;

                    if (_objCharacter == null)
                    {
                        // If the character is null (this is a Vehicle), the user must enter their own string.
                        // Display the Select Item window and record the value that was entered.
                        frmSelectText frmPickText = new frmSelectText();
                        frmPickText.Description = LanguageManager.Instance.GetString("String_Improvement_SelectText").Replace("{0}", strFriendlyName);

                        if (_strLimitSelection != "")
                        {
                            frmPickText.SelectedValue = _strLimitSelection;
                            frmPickText.Opacity = 0;
                        }

                        frmPickText.ShowDialog();

                        // Make sure the dialogue window was not canceled.
                        if (frmPickText.DialogResult == DialogResult.Cancel)
                        {
                            Rollback();
                            blnSuccess = false;
                            _strForcedValue = "";
                            _strLimitSelection = "";
                            return false;
                        }

                        _strSelectedValue = frmPickText.SelectedValue;
                        if (blnConcatSelectedValue)
                            strSourceName += " (" + _strSelectedValue + ")";

                        strSelectedValue = frmPickText.SelectedValue;
                    }
                    else
                    {
                        List<ListItem> lstWeapons = new List<ListItem>();
                        foreach (Weapon objWeapon in _objCharacter.Weapons)
                        {
                            ListItem objItem = new ListItem();
                            objItem.Value = objWeapon.Name;
                            objItem.Name = objWeapon.DisplayName;
                            lstWeapons.Add(objItem);
                        }

                        frmSelectItem frmPickItem = new frmSelectItem();
                        frmPickItem.Description = LanguageManager.Instance.GetString("String_Improvement_SelectText").Replace("{0}", strFriendlyName);
                        frmPickItem.GeneralItems = lstWeapons;

                        if (_strLimitSelection != "")
                        {
                            frmPickItem.ForceItem = _strLimitSelection;
                            frmPickItem.Opacity = 0;
                        }

                        frmPickItem.ShowDialog();

                        // Make sure the dialogue window was not canceled.
                        if (frmPickItem.DialogResult == DialogResult.Cancel)
                        {
                            Rollback();
                            blnSuccess = false;
                            _strForcedValue = "";
                            _strLimitSelection = "";
                            return false;
                        }

                        _strSelectedValue = frmPickItem.SelectedItem;
                        if (blnConcatSelectedValue)
                            strSourceName += " (" + _strSelectedValue + ")";

                        strSelectedValue = frmPickItem.SelectedItem;
                    }

                    // Create the Improvement.
                    CreateImprovement(strSelectedValue, objImprovementSource, strSourceName, Improvement.ImprovementType.Text, strUnique, blnConditional);
                }
            }

            // If we've made it this far, everything went OK, so commit the Improvements.
            Commit();
            // Clear the Forced Value and Limit Selection strings once we're done to prevent these from forcing their values on other Improvements.
            _strForcedValue = "";
            _strLimitSelection = "";
            return blnSuccess;
        }