Example #1
0
		public bool Absorb(Skill skill)
		{
			if (CharacterObject.Skills.Remove(skill))
			{
				_fold.Add(skill);
				Karma += skill.Karma;	  //This is not a question about if, but when this will cause bugs
				Base += skill.Base;		 //but i hope nothing will show until after rewrite of clsImprovement
				Rating += skill.Rating; //then skill will need rewrite anyway to use features
			}						   //Removing life modules will probably give bugs here
									  //Easier fix, expand all when removing? Might not happen all that often?
									 //Save state and recollect later? Dirty as f**k, but might just be the duct
									//tape this codebase deserves? Not the duct tape it needs... Yeah, batman reference
								   //But this have more shit that Gotham, as long as we don't count The Joker. The Joker is awesome.

									 //sudden toughts, don't even need to expand all, if remove does a check if it exists in objCharacter.Skills or a sub

			return false;
		}
Example #2
0
		private bool ProcessBonus(Improvement.ImprovementSource objImprovementSource, ref string strSourceName,
			bool blnConcatSelectedValue,
			int intRating, string strFriendlyName, XmlNode bonusNode, string strUnique)
		{
			Log.Info("Has Child Nodes");
			// Add an Attribute.
			if (bonusNode.LocalName == ("addattribute"))
			{
				Log.Info("addattribute");
				if (bonusNode["name"].InnerText == "MAG")
				{
					_objCharacter.MAGEnabled = true;
					Log.Info("Calling CreateImprovement for MAG");
					CreateImprovement("MAG", objImprovementSource, strSourceName, Improvement.ImprovementType.Attribute,
						"enableattribute", 0, 0);
				}
				else if (bonusNode["name"].InnerText == "RES")
				{
					_objCharacter.RESEnabled = true;
					Log.Info("Calling CreateImprovement for RES");
					CreateImprovement("RES", objImprovementSource, strSourceName, Improvement.ImprovementType.Attribute,
						"enableattribute", 0, 0);
				}
			}

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

			// Select Restricted (select Restricted items for Fake Licenses).
			if (bonusNode.LocalName == ("selectrestricted"))
			{
				Log.Info("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();
					_strForcedValue = "";
					_strLimitSelection = "";
					return false;
				}

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

				Log.Info("_strSelectedValue = " + _strSelectedValue);
				Log.Info("strSourceName = " + strSourceName);

				// Create the Improvement.
				Log.Info("Calling CreateImprovement");
				CreateImprovement(frmPickItem.SelectedItem, objImprovementSource, strSourceName,
					Improvement.ImprovementType.Restricted, strUnique);
			}

			if (bonusNode.LocalName == "cyberseeker")
			{
				//Check if valid attrib
				if (new string[] {"BOD", "AGI", "STR", "REA", "LOG", "CHA", "INT", "WIL", "BOX"}.Any(x => x == bonusNode.InnerText))
				{
					CreateImprovement(bonusNode.InnerText, objImprovementSource, strSourceName, Improvement.ImprovementType.Seeker, strUnique,0,0,0,0,0,0);

				}
				else
				{
					Utils.BreakIfDebug();
				}

			}

			// Select a Skill.
			if (bonusNode.LocalName == ("selectskill"))
			{
				Log.Info("selectskill");
				if (_strForcedValue == "+2 to a Combat Skill")
					_strForcedValue = "";

				Log.Info("_strSelectedValue = " + _strSelectedValue);
				Log.Info("_strForcedValue = " + _strForcedValue);

				// 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");

				Log.Info("selectskill = " + bonusNode.OuterXml.ToString());
				if (bonusNode.OuterXml.Contains("skillgroup"))
					frmPickSkill.OnlySkillGroup = bonusNode.Attributes["skillgroup"].InnerText;
				else if (bonusNode.OuterXml.Contains("skillcategory"))
					frmPickSkill.OnlyCategory = bonusNode.Attributes["skillcategory"].InnerText;
				else if (bonusNode.OuterXml.Contains("excludecategory"))
					frmPickSkill.ExcludeCategory = bonusNode.Attributes["excludecategory"].InnerText;
				else if (bonusNode.OuterXml.Contains("limittoskill"))
					frmPickSkill.LimitToSkill = bonusNode.Attributes["limittoskill"].InnerText;
				else if (bonusNode.OuterXml.Contains("limittoattribute"))
					frmPickSkill.LinkedAttribute = bonusNode.Attributes["limittoattribute"].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();
					_strForcedValue = "";
					_strLimitSelection = "";
					return false;
				}

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

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

				Log.Info("_strSelectedValue = " + _strSelectedValue);
				Log.Info("strSourceName = " + strSourceName);

				// 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 (bonusNode.InnerXml.Contains("val"))
							{
								Log.Info("Calling CreateImprovement");
								CreateImprovement(objSkill.Name + " (" + objSkill.Specialization + ")", objImprovementSource, strSourceName,
									Improvement.ImprovementType.Skill, strUnique, ValueToInt(bonusNode["val"].InnerText, intRating), 1,
									0, 0, 0, 0, "", blnAddToRating);
							}

							if (bonusNode.InnerXml.Contains("max"))
							{
								Log.Info("Calling CreateImprovement");
								CreateImprovement(objSkill.Name + " (" + objSkill.Specialization + ")", objImprovementSource, strSourceName,
									Improvement.ImprovementType.Skill, strUnique, 0, 1, 0,
									ValueToInt(bonusNode["max"].InnerText, intRating), 0, 0, "", blnAddToRating);
							}
						}
					}
					else
					{
						if (objSkill.Name == frmPickSkill.SelectedSkill)
						{
							// We've found the selected Skill.
							if (bonusNode.InnerXml.Contains("val"))
							{
								Log.Info("Calling CreateImprovement");
								CreateImprovement(objSkill.Name, objImprovementSource, strSourceName, Improvement.ImprovementType.Skill,
									strUnique,
									ValueToInt(bonusNode["val"].InnerText, intRating), 1, 0, 0, 0, 0, "", blnAddToRating);
							}

							if (bonusNode.InnerXml.Contains("max"))
							{
								Log.Info("Calling CreateImprovement");
								CreateImprovement(objSkill.Name, objImprovementSource, strSourceName, Improvement.ImprovementType.Skill,
									strUnique,
									0, 1, 0, ValueToInt(bonusNode["max"].InnerText, intRating), 0, 0, "", blnAddToRating);
							}
						}
					}
				}
			}

			// Select a Skill Group.
			if (bonusNode.LocalName == ("selectskillgroup"))
			{
				Log.Info("selectskillgroup");
				string strExclude = "";
				if (bonusNode.Attributes["excludecategory"] != null)
					strExclude = bonusNode.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");

				Log.Info("_strForcedValue = " + _strForcedValue);
				Log.Info("_strLimitSelection = " + _strLimitSelection);

				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();

					_strForcedValue = "";
					_strLimitSelection = "";
					return false;
				}

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

				_strSelectedValue = frmPickSkillGroup.SelectedSkillGroup;

				Log.Info("_strSelectedValue = " + _strSelectedValue);
				Log.Info("strSourceName = " + strSourceName);

				if (bonusNode.SelectSingleNode("bonus") != null)
				{
					Log.Info("Calling CreateImprovement");
					CreateImprovement(_strSelectedValue, objImprovementSource, strSourceName, Improvement.ImprovementType.SkillGroup,
						strUnique, ValueToInt(bonusNode["bonus"].InnerText, intRating), 1, 0, 0, 0, 0, strExclude,
						blnAddToRating);
				}
				else
				{
					Log.Info("Calling CreateImprovement");
					CreateImprovement(_strSelectedValue, objImprovementSource, strSourceName, Improvement.ImprovementType.SkillGroup,
						strUnique, ValueToInt(bonusNode["max"].InnerText, intRating), 0, 0, 1, 0, 0, strExclude,
						blnAddToRating);
				}
			}

			if (bonusNode.LocalName == ("selectattributes"))
			{
				foreach (XmlNode objXmlAttribute in bonusNode.SelectNodes("selectattribute"))
				{
					Log.Info("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();

					Log.Info("selectattribute = " + bonusNode.OuterXml.ToString());

					if (objXmlAttribute.InnerXml.Contains("<attribute>"))
					{
						List<string> strValue = new List<string>();
						foreach (XmlNode objSubNode in objXmlAttribute.SelectNodes("attribute"))
							strValue.Add(objSubNode.InnerText);
						frmPickAttribute.LimitToList(strValue);
					}

					if (bonusNode.InnerXml.Contains("<excludeattribute>"))
					{
						List<string> strValue = new List<string>();
						foreach (XmlNode objSubNode in objXmlAttribute.SelectNodes("excludeattribute"))
							strValue.Add(objSubNode.InnerText);
						frmPickAttribute.RemoveFromList(strValue);
					}

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

					Log.Info("_strForcedValue = " + _strForcedValue);
					Log.Info("_strLimitSelection = " + _strLimitSelection);

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

					frmPickAttribute.ShowDialog();

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

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

					Log.Info("_strSelectedValue = " + _strSelectedValue);
					Log.Info("strSourceName = " + strSourceName);

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

					// Extract the modifiers.
					if (objXmlAttribute.InnerXml.Contains("min"))
						intMin = Convert.ToInt32(objXmlAttribute["min"].InnerText);
					if (objXmlAttribute.InnerXml.Contains("val"))
						intAug = Convert.ToInt32(objXmlAttribute["val"].InnerText);
                    if (objXmlAttribute.InnerXml.Contains("max"))
						intMax = Convert.ToInt32(objXmlAttribute["max"].InnerText);
					if (objXmlAttribute.InnerXml.Contains("aug"))
						intAugMax = Convert.ToInt32(objXmlAttribute["aug"].InnerText);

					string strAttribute = frmPickAttribute.SelectedAttribute;

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

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

			// Select an Attribute.
			if (bonusNode.LocalName == ("selectattribute"))
			{
				Log.Info("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();

				Log.Info("selectattribute = " + bonusNode.OuterXml.ToString());

				if (bonusNode.InnerXml.Contains("<attribute>"))
				{
					List<string> strValue = new List<string>();
					foreach (XmlNode objXmlAttribute in bonusNode.SelectNodes("attribute"))
						strValue.Add(objXmlAttribute.InnerText);
					frmPickAttribute.LimitToList(strValue);
				}

				if (bonusNode.InnerXml.Contains("<excludeattribute>"))
				{
					List<string> strValue = new List<string>();
					foreach (XmlNode objXmlAttribute in bonusNode.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;

				Log.Info("_strForcedValue = " + _strForcedValue);
				Log.Info("_strLimitSelection = " + _strLimitSelection);

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

				frmPickAttribute.ShowDialog();

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

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

				Log.Info("_strSelectedValue = " + _strSelectedValue);
				Log.Info("strSourceName = " + strSourceName);

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

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

				string strAttribute = frmPickAttribute.SelectedAttribute;

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

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

			// Select a Limit.
			if (bonusNode.LocalName == ("selectlimit"))
			{
				Log.Info("selectlimit");
				// Display the Select Limit window and record which Limit was selected.
				frmSelectLimit frmPickLimit = new frmSelectLimit();
				if (strFriendlyName != "")
					frmPickLimit.Description = LanguageManager.Instance.GetString("String_Improvement_SelectLimitNamed")
						.Replace("{0}", strFriendlyName);
				else
					frmPickLimit.Description = LanguageManager.Instance.GetString("String_Improvement_SelectLimit");

				Log.Info("selectlimit = " + bonusNode.OuterXml.ToString());

				if (bonusNode.InnerXml.Contains("<limit>"))
				{
					List<string> strValue = new List<string>();
					foreach (XmlNode objXmlAttribute in bonusNode.SelectNodes("limit"))
						strValue.Add(objXmlAttribute.InnerText);
					frmPickLimit.LimitToList(strValue);
				}

				if (bonusNode.InnerXml.Contains("<excludelimit>"))
				{
					List<string> strValue = new List<string>();
					foreach (XmlNode objXmlAttribute in bonusNode.SelectNodes("excludelimit"))
						strValue.Add(objXmlAttribute.InnerText);
					frmPickLimit.RemoveFromList(strValue);
				}

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

				Log.Info("_strForcedValue = " + _strForcedValue);
				Log.Info("_strLimitSelection = " + _strLimitSelection);

				if (_strLimitSelection != "")
				{
					frmPickLimit.SingleLimit(_strLimitSelection);
					frmPickLimit.Opacity = 0;
				}

				frmPickLimit.ShowDialog();

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

				_strSelectedValue = frmPickLimit.SelectedLimit;
				if (blnConcatSelectedValue)
					strSourceName += " (" + _strSelectedValue + ")";

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

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

				string strLimit = frmPickLimit.SelectedLimit;

				if (bonusNode["affectbase"] != null)
					strLimit += "Base";

				Log.Info("_strSelectedValue = " + _strSelectedValue);
				Log.Info("strSourceName = " + strSourceName);

				LimitModifier objLimitMod = new LimitModifier(_objCharacter);
				// string strBonus = bonusNode["value"].InnerText;
				int intBonus = intAug;
				string strName = strFriendlyName;
				TreeNode nodTemp = new TreeNode();
				Improvement.ImprovementType objType = Improvement.ImprovementType.PhysicalLimit;

				switch (strLimit)
				{
					case "Mental":
						{
							objType = Improvement.ImprovementType.MentalLimit;
							break;
						}
					case "Social":
						{
							objType = Improvement.ImprovementType.SocialLimit;
							break;
						}
					default:
						{
							objType = Improvement.ImprovementType.PhysicalLimit;
							break;
						}
				}

				Log.Info("Calling CreateImprovement");
				CreateImprovement(strLimit, objImprovementSource, strSourceName, objType, strFriendlyName, intBonus, 0, intMin,
					intMax,
					intAug, intAugMax);
			}

			// Select an Attribute to use instead of the default on a skill.
			if (bonusNode.LocalName == ("swapskillattribute"))
			{
				Log.Info("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);

				Log.Info("swapskillattribute = " + bonusNode.OuterXml.ToString());

				if (bonusNode.InnerXml.Contains("<attribute>"))
				{
					List<string> strLimitValue = new List<string>();
					foreach (XmlNode objXmlAttribute in bonusNode.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;

				Log.Info("_strForcedValue = " + _strForcedValue);
				Log.Info("_strLimitSelection = " + _strLimitSelection);

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

				frmPickAttribute.ShowDialog();

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

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

				Log.Info("_strSelectedValue = " + _strSelectedValue);
				Log.Info("strSourceName = " + strSourceName);

				Log.Info("Calling CreateImprovement");
				CreateImprovement(frmPickAttribute.SelectedAttribute, objImprovementSource, strSourceName,
					Improvement.ImprovementType.SwapSkillAttribute, strUnique);
			}

			// Select a Spell.
			if (bonusNode.LocalName == ("selectspell"))
			{
				Log.Info("selectspell");
				// Display the Select Spell window.
				frmSelectSpell frmPickSpell = new frmSelectSpell(_objCharacter);

				if (bonusNode.Attributes["category"] != null)
					frmPickSpell.LimitCategory = bonusNode.Attributes["category"].InnerText;

				Log.Info("selectspell = " + bonusNode.OuterXml.ToString());
				Log.Info("_strForcedValue = " + _strForcedValue);
				Log.Info("_strLimitSelection = " + _strLimitSelection);

				if (_strForcedValue != "")
				{
					frmPickSpell.ForceSpellName = _strForcedValue;
					frmPickSpell.Opacity = 0;
				}

				frmPickSpell.ShowDialog();

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

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

				Log.Info("_strSelectedValue = " + _strSelectedValue);
				Log.Info("strSourceName = " + strSourceName);

				Log.Info("Calling CreateImprovement");
				CreateImprovement(frmPickSpell.SelectedSpell, objImprovementSource, strSourceName, Improvement.ImprovementType.Text,
					strUnique);
			}

			// Select a Contact
			if (bonusNode.LocalName == ("selectcontact"))
			{
				Log.Info("selectcontact");
				XmlNode nodSelect = bonusNode;

				frmSelectItem frmSelect = new frmSelectItem();

				String strMode = NodeExists(nodSelect, "type")
					? nodSelect["type"].InnerText
					: "all";

				List<Contact> selectedContactsList;
				if (strMode == "all")
				{
					selectedContactsList = new List<Contact>(_objCharacter.Contacts);
				}
				else if (strMode == "group" || strMode == "nongroup")
				{
					bool blnGroup = strMode == "group";


					//Select any contact where IsGroup equals blnGroup
					//and add to a list
					selectedContactsList =
						new List<Contact>(from contact in _objCharacter.Contacts
							where contact.IsGroup == blnGroup
							select contact);
				}
				else
				{
					Rollback();
					return false;
				}

				if (selectedContactsList.Count == 0)
				{
					MessageBox.Show(LanguageManager.Instance.GetString("Message_NoContactFound"),
						LanguageManager.Instance.GetString("MessageTitle_NoContactFound"), MessageBoxButtons.OK, MessageBoxIcon.Error);
					Rollback();
					return false;
				}

				int count = 0;
				//Black magic LINQ to cast content of list to another type
				List<ListItem> contacts = new List<ListItem>(from x in selectedContactsList
					select new ListItem() {Name = x.Name, Value = (count++).ToString()});

				String strPrice = NodeExists(nodSelect, "cost")
					? nodSelect["cost"].InnerText
					: "";

				frmSelect.GeneralItems = contacts;
				frmSelect.ShowDialog();

				int index = int.Parse(frmSelect.SelectedItem);
				if (frmSelect.DialogResult != DialogResult.Cancel)
				{
					Contact selectedContact = selectedContactsList[index];

					if (nodSelect["mademan"] != null)
					{
						selectedContact.MadeMan = true;
						CreateImprovement(selectedContact.GUID, Improvement.ImprovementSource.Quality, strSourceName,
							Improvement.ImprovementType.ContactMadeMan, selectedContact.GUID);
					}

					if (String.IsNullOrWhiteSpace(_strSelectedValue))
					{
						_strSelectedValue = selectedContact.Name;
					}
					else
					{
						_strSelectedValue += (", " + selectedContact.Name);
					}
                }
				else
				{
					Rollback();
					return false;
				}
			}

			if (bonusNode.LocalName == "addcontact")
			{
				Log.Info("addcontact");

				int loyality, connection;
				
				bonusNode.TryGetField("loyality", out loyality, 1);
				bonusNode.TryGetField("connection", out connection, 1);
				bool group = bonusNode["group"] != null;
				bool free = bonusNode["free"] != null;

				Contact contact = new Contact(_objCharacter);
				contact.Free = free;
				contact.IsGroup = group;
				contact.Loyalty = loyality;
				contact.Connection = connection;
				contact.ReadOnly = true;
				_objCharacter.Contacts.Add(contact);

				CreateImprovement(contact.GUID, Improvement.ImprovementSource.Quality, strSourceName,
							Improvement.ImprovementType.AddContact, contact.GUID);
			}

			// Affect a Specific Attribute.
			if (bonusNode.LocalName == ("specificattribute"))
			{
				Log.Info("specificattribute");

				if (bonusNode["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 (bonusNode.InnerXml.Contains("min"))
						intMin = ValueToInt(bonusNode["min"].InnerXml, intRating);
					if (bonusNode.InnerXml.Contains("val"))
						intAug = ValueToInt(bonusNode["val"].InnerXml, intRating);
					if (bonusNode.InnerXml.Contains("max"))
					{
						if (bonusNode["max"].InnerText.Contains("-natural"))
						{
							intMax = Convert.ToInt32(bonusNode["max"].InnerText.Replace("-natural", string.Empty)) -
							         _objCharacter.GetAttribute(bonusNode["name"].InnerText).MetatypeMaximum;
						}
						else
							intMax = ValueToInt(bonusNode["max"].InnerXml, intRating);
					}
					if (bonusNode.InnerXml.Contains("aug"))
						intAugMax = ValueToInt(bonusNode["aug"].InnerXml, intRating);

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

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

					if (bonusNode["affectbase"] != null)
						strAttribute += "Base";
					
					CreateImprovement(strAttribute, objImprovementSource, strSourceName, Improvement.ImprovementType.Attribute,
						strUseUnique, 0, 1, intMin, intMax, intAug, intAugMax);
				}
				else
				{
					CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Essence, "",
						Convert.ToInt32(bonusNode["val"].InnerText));
				}
			}

			// Add a paid increase to an attribute
			if (bonusNode.LocalName == ("attributelevel"))
			{
				Log.Info(new object[] {"attributelevel", bonusNode.OuterXml});
				String strAttrib;
				int value;
				bonusNode.TryGetField("val", out value, 1);

				if (bonusNode.TryGetField("name", out strAttrib))
				{
					CreateImprovement(strAttrib, objImprovementSource, strSourceName,
						Improvement.ImprovementType.Attributelevel, "", value);
				}
				else
				{
					Log.Error(new object[] {"attributelevel", bonusNode.OuterXml});
				}
			}

			if (bonusNode.LocalName == ("skilllevel"))
			{
				Log.Info(new object[] {"skilllevel", bonusNode.OuterXml});
				String strSkill;
				int value;
				bonusNode.TryGetField("val", out value, 1);
                if (bonusNode.TryGetField("name", out strSkill))
				{
					CreateImprovement(strSkill, objImprovementSource, strSourceName,
						Improvement.ImprovementType.SkillLevel, "", value);


				}
				else
				{
					Log.Error(new object[] {"skilllevel", bonusNode.OuterXml});
				}
			}

			if (bonusNode.LocalName == "pushtext")
			{

				String push = bonusNode.InnerText;
				if (!String.IsNullOrWhiteSpace(push))
				{
					_objCharacter.Pushtext.Push(push);
				}
			}

			if (bonusNode.LocalName == "knowledgeskilllevel")
			{
				Log.Info(new object[] {"knowledgeskilllevel", bonusNode.OuterXml});
				int value;
				String group;
				if (bonusNode.TryGetField("group", out group))
				{
					if (!bonusNode.TryGetField("val", out value))
					{
						value = 1;
					}



					Guid id;

					bool blnFound = false;

					if (bonusNode.TryGetField("id", Guid.TryParse, out id, Guid.NewGuid()))
					{
						foreach (Improvement improvement in _objCharacter.Improvements)
						{
							if (improvement.ImprovedName == id.ToString())
							{
								blnFound = true;
							}
						}
					}

					if (!blnFound)
					{
						Skill objNSkill = new Skill(_objCharacter);
						objNSkill.Id = id;
						objNSkill.IdImprovement = true;
						objNSkill.AllowDelete = false;
						objNSkill.KnowledgeSkill = true;
						objNSkill.LockKnowledge = true;
						objNSkill.SkillCategory = group;
						int max;
						bonusNode.TryGetField("max", out max, 9);
						objNSkill.RatingMaximum = max;

						String name;
						if (bonusNode.TryGetField("name", out name))
						{
							objNSkill.Name = name;
						}
						if (bonusNode["options"] != null)
						{
							List<String> Options = new List<String>();
							foreach (XmlNode node in bonusNode["options"].ChildNodes)
							{
								Options.Add(node.InnerText);
							}
							objNSkill.KnowledgeSkillCatagories = Options;
						}

						_objCharacter.Skills.Add(objNSkill);
					}

					CreateImprovement(id.ToString(), objImprovementSource, strSourceName,
						Improvement.ImprovementType.SkillLevel, "", value);


				}
			}

			if (bonusNode.LocalName == ("skillgrouplevel"))
			{
				Log.Info(new object[] {"skillgrouplevel", bonusNode.OuterXml});
				String strSkillGroup;
				int value;
				if (bonusNode.TryGetField("name", out strSkillGroup) &&
				    bonusNode.TryGetField("val", out value))
				{
					CreateImprovement(strSkillGroup, objImprovementSource, strSourceName,
						Improvement.ImprovementType.SkillGroupLevel, "", value);
				}
				else
				{
					Log.Error(new object[] {"skillgrouplevel", bonusNode.OuterXml});
				}
			}

			// Change the maximum number of BP that can be spent on Nuyen.
			if (bonusNode.LocalName == ("nuyenmaxbp"))
			{
				Log.Info("nuyenmaxbp");
				Log.Info("nuyenmaxbp = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.NuyenMaxBP, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Apply a bonus/penalty to physical limit.
			if (bonusNode.LocalName == ("physicallimit"))
			{
				Log.Info("physicallimit");
				Log.Info("physicallimit = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.PhysicalLimit, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Apply a bonus/penalty to mental limit.
			if (bonusNode.LocalName == ("mentallimit"))
			{
				Log.Info("mentallimit");
				Log.Info("mentallimit = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.MentalLimit, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Apply a bonus/penalty to social limit.
			if (bonusNode.LocalName == ("sociallimit"))
			{
				Log.Info("sociallimit");
				Log.Info("sociallimit = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.SocialLimit, "",
					ValueToInt(bonusNode.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 (bonusNode.LocalName == ("nuyenamt"))
			{
				Log.Info("nuyenamt");
				Log.Info("nuyenamt = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Nuyen, strUnique,
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Improve Condition Monitors.
			if (bonusNode.LocalName == ("conditionmonitor"))
			{
				Log.Info("conditionmonitor");
				Log.Info("conditionmonitor = " + bonusNode.OuterXml.ToString());
				// Physical Condition.
				if (bonusNode.InnerXml.Contains("physical"))
				{
					Log.Info("Calling CreateImprovement for Physical");
					CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.PhysicalCM, strUnique,
						ValueToInt(bonusNode["physical"].InnerText, intRating));
				}

				// Stun Condition.
				if (bonusNode.InnerXml.Contains("stun"))
				{
					Log.Info("Calling CreateImprovement for Stun");
					CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.StunCM, strUnique,
						ValueToInt(bonusNode["stun"].InnerText, intRating));
				}

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

					Log.Info("Calling CreateImprovement for Threshold");
					CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.CMThreshold, strUseUnique,
						ValueToInt(bonusNode["threshold"].InnerText, intRating));
				}

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

					Log.Info("Calling CreateImprovement for Threshold Offset");
					CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.CMThresholdOffset,
						strUseUnique, ValueToInt(bonusNode["thresholdoffset"].InnerText, intRating));
				}

				// Condition Monitor Overflow.
				if (bonusNode.InnerXml.Contains("overflow"))
				{
					Log.Info("Calling CreateImprovement for Overflow");
					CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.CMOverflow, strUnique,
						ValueToInt(bonusNode["overflow"].InnerText, intRating));
				}
			}

			// Improve Living Personal Attributes.
			if (bonusNode.LocalName == ("livingpersona"))
			{
				Log.Info("livingpersona");
				Log.Info("livingpersona = " + bonusNode.OuterXml.ToString());
				// Response.
				if (bonusNode.InnerXml.Contains("response"))
				{
					Log.Info("Calling CreateImprovement for response");
					CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.LivingPersonaResponse,
						strUnique, ValueToInt(bonusNode["response"].InnerText, intRating));
				}

				// Signal.
				if (bonusNode.InnerXml.Contains("signal"))
				{
					Log.Info("Calling CreateImprovement for signal");
					CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.LivingPersonaSignal,
						strUnique,
						ValueToInt(bonusNode["signal"].InnerText, intRating));
				}

				// Firewall.
				if (bonusNode.InnerXml.Contains("firewall"))
				{
					Log.Info("Calling CreateImprovement for firewall");
					CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.LivingPersonaFirewall,
						strUnique, ValueToInt(bonusNode["firewall"].InnerText, intRating));
				}

				// System.
				if (bonusNode.InnerXml.Contains("system"))
				{
					Log.Info("Calling CreateImprovement for system");
					CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.LivingPersonaSystem,
						strUnique,
						ValueToInt(bonusNode["system"].InnerText, intRating));
				}

				// Biofeedback Filter.
				if (bonusNode.InnerXml.Contains("biofeedback"))
				{
					Log.Info("Calling CreateImprovement for biofeedback");
					CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.LivingPersonaBiofeedback,
						strUnique, ValueToInt(bonusNode["biofeedback"].InnerText, intRating));
				}
			}

			// The Improvement adjusts a specific Skill.
			if (bonusNode.LocalName == ("specificskill"))
			{
				Log.Info("specificskill");
				Log.Info("specificskill = " + bonusNode.OuterXml.ToString());
				bool blnAddToRating = false;
				if (bonusNode["applytorating"] != null)
				{
					if (bonusNode["applytorating"].InnerText == "yes")
						blnAddToRating = true;
				}

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

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

			// The Improvement adds a martial art
			if (bonusNode.LocalName == ("martialart"))
			{
				Log.Info("martialart");
				Log.Info("martialart = " + bonusNode.OuterXml.ToString());
				XmlDocument _objXmlDocument = XmlManager.Instance.Load("martialarts.xml");
				XmlNode objXmlArt =
					_objXmlDocument.SelectSingleNode("/chummer/martialarts/martialart[name = \"" + bonusNode.InnerText +
					                                 "\"]");

				TreeNode objNode = new TreeNode();
				MartialArt objMartialArt = new MartialArt(_objCharacter);
				objMartialArt.Create(objXmlArt, objNode, _objCharacter);
				objMartialArt.IsQuality = true;
				_objCharacter.MartialArts.Add(objMartialArt);
			}

			// The Improvement adds a limit modifier
			if (bonusNode.LocalName == ("limitmodifier"))
			{
				Log.Info("limitmodifier");
				Log.Info("limitmodifier = " + bonusNode.OuterXml.ToString());
				LimitModifier objLimitMod = new LimitModifier(_objCharacter);
				string strLimit = bonusNode["limit"].InnerText;
				string strBonus = bonusNode["value"].InnerText;
				string strCondition = "";
				try
				{
					strCondition = bonusNode["condition"].InnerText;
				}
				catch
				{
				}
				int intBonus = 0;
				if (strBonus == "Rating")
					intBonus = intRating;
				else
					intBonus = Convert.ToInt32(strBonus);
				string strName = strFriendlyName;
				TreeNode nodTemp = new TreeNode();
				Log.Info("Calling CreateImprovement");
				CreateImprovement(strLimit, objImprovementSource, strSourceName, Improvement.ImprovementType.LimitModifier,
					strFriendlyName, intBonus, 0, 0, 0, 0, 0, strCondition);
			}

			// The Improvement adjusts a Skill Category.
			if (bonusNode.LocalName == ("skillcategory"))
			{
				Log.Info("skillcategory");
				Log.Info("skillcategory = " + bonusNode.OuterXml.ToString());

				bool blnAddToRating = false;
				if (bonusNode["applytorating"] != null)
				{
					if (bonusNode["applytorating"].InnerText == "yes")
						blnAddToRating = true;
				}
				if (bonusNode.InnerXml.Contains("exclude"))
				{
					Log.Info("Calling CreateImprovement - exclude");
					CreateImprovement(bonusNode["name"].InnerText, objImprovementSource, strSourceName,
						Improvement.ImprovementType.SkillCategory, strUnique, ValueToInt(bonusNode["bonus"].InnerXml, intRating), 1, 0,
						0,
						0, 0, bonusNode["exclude"].InnerText, blnAddToRating);
				}
				else
				{
					Log.Info("Calling CreateImprovement");
					CreateImprovement(bonusNode["name"].InnerText, objImprovementSource, strSourceName,
						Improvement.ImprovementType.SkillCategory, strUnique, ValueToInt(bonusNode["bonus"].InnerXml, intRating), 1, 0,
						0,
						0, 0, "", blnAddToRating);
				}
			}

			// The Improvement adjusts a Skill Group.
			if (bonusNode.LocalName == ("skillgroup"))
			{
				Log.Info("skillgroup");
				Log.Info("skillgroup = " + bonusNode.OuterXml.ToString());

				bool blnAddToRating = false;
				if (bonusNode["applytorating"] != null)
				{
					if (bonusNode["applytorating"].InnerText == "yes")
						blnAddToRating = true;
				}
				if (bonusNode.InnerXml.Contains("exclude"))
				{
					Log.Info("Calling CreateImprovement - exclude");
					CreateImprovement(bonusNode["name"].InnerText, objImprovementSource, strSourceName,
						Improvement.ImprovementType.SkillGroup, strUnique, ValueToInt(bonusNode["bonus"].InnerXml, intRating), 1, 0, 0, 0,
						0, bonusNode["exclude"].InnerText, blnAddToRating);
				}
				else
				{
					Log.Info("Calling CreateImprovement");
					CreateImprovement(bonusNode["name"].InnerText, objImprovementSource, strSourceName,
						Improvement.ImprovementType.SkillGroup, strUnique, ValueToInt(bonusNode["bonus"].InnerXml, intRating), 1, 0, 0, 0,
						0, "", blnAddToRating);
				}
			}

			// The Improvement adjust Skills with the given Attribute.
			if (bonusNode.LocalName == ("skillattribute"))
			{
				Log.Info("skillattribute");
				Log.Info("skillattribute = " + bonusNode.OuterXml.ToString());

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

				bool blnAddToRating = false;
				if (bonusNode["applytorating"] != null)
				{
					if (bonusNode["applytorating"].InnerText == "yes")
						blnAddToRating = true;
				}
				if (bonusNode.InnerXml.Contains("exclude"))
				{
					Log.Info("Calling CreateImprovement - exclude");
					CreateImprovement(bonusNode["name"].InnerText, objImprovementSource, strSourceName,
						Improvement.ImprovementType.SkillAttribute, strUseUnique, ValueToInt(bonusNode["bonus"].InnerXml, intRating), 1,
						0, 0, 0, 0, bonusNode["exclude"].InnerText, blnAddToRating);
				}
				else
				{
					Log.Info("Calling CreateImprovement");
					CreateImprovement(bonusNode["name"].InnerText, objImprovementSource, strSourceName,
						Improvement.ImprovementType.SkillAttribute, strUseUnique, ValueToInt(bonusNode["bonus"].InnerXml, intRating), 1,
						0, 0, 0, 0, "", blnAddToRating);
				}
			}

			// The Improvement comes from Enhanced Articulation (improves Physical Active Skills linked to a Physical Attribute).
			if (bonusNode.LocalName == ("skillarticulation"))
			{
				Log.Info("skillarticulation");
				Log.Info("skillarticulation = " + bonusNode.OuterXml.ToString());

				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.EnhancedArticulation,
					strUnique,
					ValueToInt(bonusNode["bonus"].InnerText, intRating));
			}

			// Check for Armor modifiers.
			if (bonusNode.LocalName == ("armor"))
			{
				Log.Info("armor");
				Log.Info("armor = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				string strUseUnique = strUnique;
				if (bonusNode.Attributes["precedence"] != null)
					strUseUnique = "precedence" + bonusNode.Attributes["precedence"].InnerText;
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Armor, strUseUnique,
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Reach modifiers.
			if (bonusNode.LocalName == ("reach"))
			{
				Log.Info("reach");
				Log.Info("reach = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Reach, strUnique,
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Unarmed Damage Value modifiers.
			if (bonusNode.LocalName == ("unarmeddv"))
			{
				Log.Info("unarmeddv");
				Log.Info("unarmeddv = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.UnarmedDV, strUnique,
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Unarmed Damage Value Physical.
			if (bonusNode.LocalName == ("unarmeddvphysical"))
			{
				Log.Info("unarmeddvphysical");
				Log.Info("unarmeddvphysical = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.UnarmedDVPhysical, "");
			}

			// Check for Unarmed Armor Penetration.
			if (bonusNode.LocalName == ("unarmedap"))
			{
				Log.Info("unarmedap");
				Log.Info("unarmedap = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.UnarmedAP, strUnique,
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Initiative modifiers.
			if (bonusNode.LocalName == ("initiative"))
			{
				Log.Info("initiative");
				Log.Info("initiative = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Initiative, strUnique,
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Initiative Pass modifiers. Only the highest one ever applies.
			if (bonusNode.LocalName == ("initiativepass"))
			{
				Log.Info("initiativepass");
				Log.Info("initiativepass = "******"Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.InitiativePass,
					"initiativepass", ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Initiative Pass modifiers. Only the highest one ever applies.
			if (bonusNode.LocalName == ("initiativepassadd"))
			{
				Log.Info("initiativepassadd");
				Log.Info("initiativepassadd = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.InitiativePassAdd, strUnique,
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Matrix Initiative modifiers.
			if (bonusNode.LocalName == ("matrixinitiative"))
			{
				Log.Info("matrixinitiative");
				Log.Info("matrixinitiative = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.MatrixInitiative, strUnique,
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Matrix Initiative Pass modifiers.
			if (bonusNode.LocalName == ("matrixinitiativepass"))
			{
				Log.Info("matrixinitiativepass");
				Log.Info("matrixinitiativepass = "******"Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.MatrixInitiativePass,
					"matrixinitiativepass", ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Matrix Initiative Pass modifiers.
			if (bonusNode.LocalName == ("matrixinitiativepassadd"))
			{
				Log.Info("matrixinitiativepassadd");
				Log.Info("matrixinitiativepassadd = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.MatrixInitiativePass,
					strUnique,
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Lifestyle cost modifiers.
			if (bonusNode.LocalName == ("lifestylecost"))
			{
				Log.Info("lifestylecost");
				Log.Info("lifestylecost = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.LifestyleCost, strUnique,
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for basic Lifestyle cost modifiers.
			if (bonusNode.LocalName == ("basiclifestylecost"))
			{
				Log.Info("basiclifestylecost");
				Log.Info("basiclifestylecost = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.BasicLifestyleCost, strUnique,
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Genetech Cost modifiers.
			if (bonusNode.LocalName == ("genetechcostmultiplier"))
			{
				Log.Info("genetechcostmultiplier");
				Log.Info("genetechcostmultiplier = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.GenetechCostMultiplier,
					strUnique, ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Genetech: Transgenics Cost modifiers.
			if (bonusNode.LocalName == ("transgenicsgenetechcost"))
			{
				Log.Info("transgenicsgenetechcost");
				Log.Info("transgenicsgenetechcost = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.TransgenicsBiowareCost,
					strUnique, ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Basic Bioware Essence Cost modifiers.
			if (bonusNode.LocalName == ("basicbiowareessmultiplier"))
			{
				Log.Info("basicbiowareessmultiplier");
				Log.Info("basicbiowareessmultiplier = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.BasicBiowareEssCost,
					strUnique,
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Bioware Essence Cost modifiers.
			if (bonusNode.LocalName == ("biowareessmultiplier"))
			{
				Log.Info("biowareessmultiplier");
				Log.Info("biowareessmultiplier = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.BiowareEssCost, strUnique,
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Cybeware Essence Cost modifiers.
			if (bonusNode.LocalName == ("cyberwareessmultiplier"))
			{
				Log.Info("cyberwareessmultiplier");
				Log.Info("cyberwareessmultiplier = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.CyberwareEssCost, strUnique,
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Uneducated modifiers.
			if (bonusNode.LocalName == ("uneducated"))
			{
				Log.Info("uneducated");
				Log.Info("uneducated = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Uneducated, strUnique);
				_objCharacter.Uneducated = true;
			}

			// Check for College Education modifiers.
			if (bonusNode.LocalName == ("collegeeducation"))
			{
				Log.Info("collegeeducation");
				Log.Info("collegeeducation = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.CollegeEducation, strUnique);
				_objCharacter.CollegeEducation = true;
			}

			// Check for Jack Of All Trades modifiers.
			if (bonusNode.LocalName == ("jackofalltrades"))
			{
				Log.Info("jackofalltrades");
				Log.Info("jackofalltrades = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.JackOfAllTrades, strUnique);
				_objCharacter.JackOfAllTrades = true;
			}

			// Check for Prototype Transhuman modifiers.
			if (bonusNode.LocalName == ("prototypetranshuman"))
			{
				Log.Info("prototypetranshuman");
				Log.Info("prototypetranshuman = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				_objCharacter.PrototypeTranshuman = Convert.ToDecimal(bonusNode.InnerText);
			}
			// Check for Uncouth modifiers.
			if (bonusNode.LocalName == ("uncouth"))
			{
				Log.Info("uncouth");
				Log.Info("uncouth = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Uncouth, strUnique);
				_objCharacter.Uncouth = true;
			}

			// Check for Friends In High Places modifiers.
			if (bonusNode.LocalName == ("friendsinhighplaces"))
			{
				Log.Info("friendsinhighplaces");
				Log.Info("friendsinhighplaces = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.FriendsInHighPlaces,
					strUnique);
				_objCharacter.FriendsInHighPlaces = true;
			}
			// Check for School of Hard Knocks modifiers.
			if (bonusNode.LocalName == ("schoolofhardknocks"))
			{
				Log.Info("schoolofhardknocks");
				Log.Info("schoolofhardknocks = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.SchoolOfHardKnocks, strUnique);
				_objCharacter.SchoolOfHardKnocks = true;
			}
			// Check for ExCon modifiers.
			if (bonusNode.LocalName == ("excon"))
			{
				Log.Info("ExCon");
				Log.Info("ExCon = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.ExCon, strUnique);
				_objCharacter.ExCon = true;
			}

			// Check for TrustFund modifiers.
			if (bonusNode.LocalName == ("trustfund"))
			{
				Log.Info("TrustFund");
				Log.Info("TrustFund = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.TrustFund,
					strUnique,
					ValueToInt(bonusNode.InnerText, intRating));
				_objCharacter.TrustFund = ValueToInt(bonusNode.InnerText, intRating);
			}

			// Check for BlackMarket modifiers.
			if (bonusNode.LocalName == ("blackmarket"))
			{
				Log.Info("BlackMarket");
				Log.Info("BlackMarket = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.BlackMarket, strUnique);
				_objCharacter.BlackMarket = true;
			}


			// Check for Tech School modifiers.
			if (bonusNode.LocalName == ("techschool"))
			{
				Log.Info("techschool");
				Log.Info("techschool = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.TechSchool, strUnique);
				_objCharacter.TechSchool = true;
			}
			// Check for MadeMan modifiers.
			if (bonusNode.LocalName == ("mademan"))
			{
				Log.Info("MadeMan");
				Log.Info("MadeMan = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.MadeMan, strUnique);
				_objCharacter.MadeMan = true;
			}

			// Check for Linguist modifiers.
			if (bonusNode.LocalName == ("linguist"))
			{
				Log.Info("Linguist");
				Log.Info("Linguist = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Linguist, strUnique);
				_objCharacter.Linguist = true;
			}

			// Check for LightningReflexes modifiers.
			if (bonusNode.LocalName == ("lightningreflexes"))
			{
				Log.Info("LightningReflexes");
				Log.Info("LightningReflexes = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.LightningReflexes, strUnique);
				_objCharacter.LightningReflexes = true;
			}

			// Check for Fame modifiers.
			if (bonusNode.LocalName == ("fame"))
			{
				Log.Info("Fame");
				Log.Info("Fame = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Fame, strUnique);
				_objCharacter.Fame = true;
			}
			// Check for BornRich modifiers.
			if (bonusNode.LocalName == ("bornrich"))
			{
				Log.Info("BornRich");
				Log.Info("BornRich = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.BornRich, strUnique);
				_objCharacter.BornRich = true;
			}
			// Check for Erased modifiers.
			if (bonusNode.LocalName == ("erased"))
			{
				Log.Info("Erased");
				Log.Info("Erased = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Erased, strUnique);
				_objCharacter.Erased = true;
			}
			// Check for Erased modifiers.
			if (bonusNode.LocalName == ("overclocker"))
			{
				Log.Info("OverClocker");
				Log.Info("Overclocker = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Overclocker, strUnique);
				_objCharacter.Overclocker = true;
			}

			// Check for Restricted Gear modifiers.
			if (bonusNode.LocalName == ("restrictedgear"))
			{
				Log.Info("restrictedgear");
				Log.Info("restrictedgear = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.RestrictedGear, strUnique);
				_objCharacter.RestrictedGear = true;
			}

			// Check for Adept Linguistics.
			if (bonusNode.LocalName == ("adeptlinguistics"))
			{
				Log.Info("adeptlinguistics");
				Log.Info("adeptlinguistics = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.AdeptLinguistics, strUnique,
					1);
			}

			// Check for Weapon Category DV modifiers.
			if (bonusNode.LocalName == ("weaponcategorydv"))
			{
				//TODO: FIX THIS
				/*
				 * I feel like talking a little bit about improvementmanager at
				 * this point. It is an intresting class. First of all, it 
				 * manages to throw out everything we ever learned about OOP
				 * and create a class based on functional programming.
				 * 
				 * That is true, it is a class, based on manipulating a single
				 * list on another class.
				 * 
				 * But atleast there is a reference to it somewhere right?
				 * 
				 * No, you create one wherever you need it, meaning there are
				 * tens of instances of this class, all operating on the same 
				 * list
				 * 
				 * After that, it is just plain stupid.
				 * If you have an list of xmlNodes and some might be the same
				 * it checks if a specific node exists (sometimes even by text
				 * comparison on .OuterXml) and then runs specific code for 
				 * each. If it is there multiple times either of those 2 things
				 * happen.
				 * 
				 * 1. Sad, nothing we can do, guess you have to survive
				 * 2. Lets create a foreach in that specific part of the code
				 * 
				 * F**k ImprovementManager, kill it with fire, burn the ashes
				 * and feed what remains to a dragon that eats unholy 
				 * abominations
				 */


				Log.Info("weaponcategorydv");
				Log.Info("weaponcategorydv = " + bonusNode.OuterXml.ToString());
				XmlNodeList objXmlCategoryList = bonusNode.SelectNodes("weaponcategorydv");
				XmlNode nodWeapon = bonusNode;

				if (NodeExists(nodWeapon, "selectskill"))
				{
					// Display the Select Skill window and record which Skill was selected.
					frmSelectItem frmPickCategory = new frmSelectItem();
					List<ListItem> lstGeneralItems = new List<ListItem>();

					ListItem liBlades = new ListItem();
					liBlades.Name = "Blades";
					liBlades.Value = "Blades";

					ListItem liClubs = new ListItem();
					liClubs.Name = "Clubs";
					liClubs.Value = "Clubs";

					ListItem liUnarmed = new ListItem();
					liUnarmed.Name = "Unarmed";
					liUnarmed.Value = "Unarmed";

					ListItem liAstral = new ListItem();
					liAstral.Name = "Astral Combat";
					liAstral.Value = "Astral Combat";

					ListItem liExotic = new ListItem();
					liExotic.Name = "Exotic Melee Weapons";
					liExotic.Value = "Exotic Melee Weapons";

					lstGeneralItems.Add(liAstral);
					lstGeneralItems.Add(liBlades);
					lstGeneralItems.Add(liClubs);
					lstGeneralItems.Add(liExotic);
					lstGeneralItems.Add(liUnarmed);
					frmPickCategory.GeneralItems = lstGeneralItems;

					if (strFriendlyName != "")
						frmPickCategory.Description =
							LanguageManager.Instance.GetString("String_Improvement_SelectSkillNamed").Replace("{0}", strFriendlyName);
					else
						frmPickCategory.Description = LanguageManager.Instance.GetString("Title_SelectWeaponCategory");

					Log.Info("_strForcedValue = " + _strForcedValue);

					if (_strForcedValue.StartsWith("Adept:") || _strForcedValue.StartsWith("Magician:"))
						_strForcedValue = "";

					if (_strForcedValue != "")
					{
						frmPickCategory.Opacity = 0;
					}
					frmPickCategory.ShowDialog();

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

					_strSelectedValue = frmPickCategory.SelectedItem;

					Log.Info("strSelected = " + _strSelectedValue);

					foreach (Power objPower in _objCharacter.Powers)
					{
						if (objPower.InternalId == strSourceName)
						{
							objPower.Extra = _strSelectedValue;
						}
					}

					Log.Info("Calling CreateImprovement");
					CreateImprovement(_strSelectedValue, objImprovementSource, strSourceName,
						Improvement.ImprovementType.WeaponCategoryDV, strUnique, ValueToInt(nodWeapon["bonus"].InnerXml, intRating));
				}
				else
				{
					// Run through each of the Skill Groups since there may be more than one affected.
					foreach (XmlNode objXmlCategory in objXmlCategoryList)
					{
						Log.Info("Calling CreateImprovement");
						CreateImprovement(objXmlCategory["name"].InnerText, objImprovementSource, strSourceName,
							Improvement.ImprovementType.WeaponCategoryDV, strUnique, ValueToInt(objXmlCategory["bonus"].InnerXml, intRating));
					}
				}
			}

			// Check for Mentor Spirit bonuses.
			if (bonusNode.LocalName == ("selectmentorspirit"))
			{
				Log.Info("selectmentorspirit");
				Log.Info("selectmentorspirit = " + bonusNode.OuterXml.ToString());
				frmSelectMentorSpirit frmPickMentorSpirit = new frmSelectMentorSpirit(_objCharacter);
				frmPickMentorSpirit.ShowDialog();

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

				_strSelectedValue = frmPickMentorSpirit.SelectedMentor;

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

				Log.Info("_strSelectedValue = " + _strSelectedValue);
				Log.Info("strSourceName = " + strSourceName);

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

				if (frmPickMentorSpirit.Choice1BonusNode != null)
				{
					Log.Info("frmPickMentorSpirit.Choice1BonusNode = " + frmPickMentorSpirit.Choice1BonusNode.OuterXml.ToString());
					string strForce = _strForcedValue;
					if (!frmPickMentorSpirit.Choice1.StartsWith("Adept:") && !frmPickMentorSpirit.Choice1.StartsWith("Magician:"))
						_strForcedValue = frmPickMentorSpirit.Choice1;
					else
						_strForcedValue = "";
					Log.Info("Calling CreateImprovement");
					bool blnSuccess = CreateImprovements(objImprovementSource, strSourceName, frmPickMentorSpirit.Choice1BonusNode,
						blnConcatSelectedValue, intRating, strFriendlyName);
					if (!blnSuccess)
					{
						Rollback();
						_strForcedValue = "";
						_strLimitSelection = "";
						return false;
					}
					_strForcedValue = strForce;
					_objCharacter.Improvements.Last().Notes = frmPickMentorSpirit.Choice1;
				}

				if (frmPickMentorSpirit.Choice2BonusNode != null)
				{
					Log.Info("frmPickMentorSpirit.Choice2BonusNode = " + frmPickMentorSpirit.Choice2BonusNode.OuterXml.ToString());
					string strForce = _strForcedValue;
					if (!frmPickMentorSpirit.Choice2.StartsWith("Adept:") && !frmPickMentorSpirit.Choice2.StartsWith("Magician:"))
						_strForcedValue = frmPickMentorSpirit.Choice2;
					else
						_strForcedValue = "";
					Log.Info("Calling CreateImprovement");
					bool blnSuccess = CreateImprovements(objImprovementSource, strSourceName, frmPickMentorSpirit.Choice2BonusNode,
						blnConcatSelectedValue, intRating, strFriendlyName);
					if (!blnSuccess)
					{
						Rollback();
						_strForcedValue = "";
						_strLimitSelection = "";
						return false;
					}
					_strForcedValue = strForce;
					_objCharacter.Improvements.Last().Notes = frmPickMentorSpirit.Choice2;
				}

				_strSelectedValue = strHoldValue;
				Log.Info("_strSelectedValue = " + _strSelectedValue);
				Log.Info("_strForcedValue = " + _strForcedValue);
			}

			// Check for Paragon bonuses.
			if (bonusNode.LocalName == ("selectparagon"))
			{
				Log.Info("selectparagon");
				Log.Info("selectparagon = " + bonusNode.OuterXml.ToString());
				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();
					_strForcedValue = "";
					_strLimitSelection = "";
					return false;
				}

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

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

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

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

				_strSelectedValue = strHoldValue;
			}

			// Check for Smartlink bonus.
			if (bonusNode.LocalName == ("smartlink"))
			{
				Log.Info("smartlink");
				Log.Info("smartlink = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Smartlink, "smartlink");
			}

			// Check for Adapsin bonus.
			if (bonusNode.LocalName == ("adapsin"))
			{
				Log.Info("adapsin");
				Log.Info("adapsin = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Adapsin, "adapsin");
			}

			// Check for SoftWeave bonus.
			if (bonusNode.LocalName == ("softweave"))
			{
				Log.Info("softweave");
				Log.Info("softweave = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.SoftWeave, "softweave");
			}

			// Check for Sensitive System.
			if (bonusNode.LocalName == ("sensitivesystem"))
			{
				Log.Info("sensitivesystem");
				Log.Info("sensitivesystem = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.SensitiveSystem,
					"sensitivesystem");
			}

			// Check for Movement Percent.
			if (bonusNode.LocalName == ("movementpercent"))
			{
				Log.Info("movementpercent");
				Log.Info("movementpercent = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.MovementPercent, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Swim Percent.
			if (bonusNode.LocalName == ("swimpercent"))
			{
				Log.Info("swimpercent");
				Log.Info("swimpercent = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.SwimPercent, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Fly Percent.
			if (bonusNode.LocalName == ("flypercent"))
			{
				Log.Info("flypercent");
				Log.Info("flypercent = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.FlyPercent, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Fly Speed.
			if (bonusNode.LocalName == ("flyspeed"))
			{
				Log.Info("flyspeed");
				Log.Info("flyspeed = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.FlySpeed, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for free Positive Qualities.
			if (bonusNode.LocalName == ("freepositivequalities"))
			{
				Log.Info("freepositivequalities");
				Log.Info("freepositivequalities = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.FreePositiveQualities, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for free Negative Qualities.
			if (bonusNode.LocalName == ("freenegativequalities"))
			{
				Log.Info("freenegativequalities");
				Log.Info("freenegativequalities = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.FreeNegativeQualities, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Select Side.
			if (bonusNode.LocalName == ("selectside"))
			{
				Log.Info("selectside");
				Log.Info("selectside = " + bonusNode.OuterXml.ToString());
				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();
					_strForcedValue = "";
					_strLimitSelection = "";
					return false;
				}

				_strSelectedValue = frmPickSide.SelectedSide;
				Log.Info("_strSelectedValue = " + _strSelectedValue);
			}

			// Check for Free Spirit Power Points.
			if (bonusNode.LocalName == ("freespiritpowerpoints"))
			{
				Log.Info("freespiritpowerpoints");
				Log.Info("freespiritpowerpoints = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.FreeSpiritPowerPoints, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Adept Power Points.
			if (bonusNode.LocalName == ("adeptpowerpoints"))
			{
				Log.Info("adeptpowerpoints");
				Log.Info("adeptpowerpoints = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.AdeptPowerPoints, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Adept Powers
			if (bonusNode.LocalName == ("specificpower"))
			{
				//TODO: Probably broken
				Log.Info("specificpower");
				Log.Info("specificpower = " + bonusNode.OuterXml.ToString());
				// If the character isn't an adept or mystic adept, skip the rest of this.
				if (_objCharacter.AdeptEnabled)
				{
					string strSelection = "";
					_strForcedValue = "";


					Log.Info("objXmlSpecificPower = " + bonusNode.OuterXml.ToString());

					string strPowerName = bonusNode["name"].InnerText;
					int intLevels = 0;
					if (bonusNode["val"] != null)
						intLevels = Convert.ToInt32(bonusNode["val"].InnerText);
					bool blnFree = false;
					if (bonusNode["free"] != null)
						blnFree = (bonusNode["free"].InnerText == "yes");

					string strPowerNameLimit = strPowerName;
					if (bonusNode["selectlimit"] != null)
					{
						Log.Info("selectlimit = " + bonusNode["selectlimit"].OuterXml.ToString());
						_strForcedValue = "";
						// Display the Select Limit window and record which Limit was selected.
						frmSelectLimit frmPickLimit = new frmSelectLimit();
						if (strFriendlyName != "")
							frmPickLimit.Description = LanguageManager.Instance.GetString("String_Improvement_SelectLimitNamed")
								.Replace("{0}", strFriendlyName);
						else
							frmPickLimit.Description = LanguageManager.Instance.GetString("String_Improvement_SelectLimit");

						if (bonusNode["selectlimit"].InnerXml.Contains("<limit>"))
						{
							List<string> strValue = new List<string>();
							foreach (XmlNode objXmlAttribute in bonusNode["selectlimit"].SelectNodes("limit"))
								strValue.Add(objXmlAttribute.InnerText);
							frmPickLimit.LimitToList(strValue);
						}

						if (bonusNode["selectlimit"].InnerXml.Contains("<excludelimit>"))
						{
							List<string> strValue = new List<string>();
							foreach (XmlNode objXmlAttribute in bonusNode["selectlimit"].SelectNodes("excludelimit"))
								strValue.Add(objXmlAttribute.InnerText);
							frmPickLimit.RemoveFromList(strValue);
						}

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

						Log.Info("_strForcedValue = " + _strForcedValue);
						Log.Info("_strLimitSelection = " + _strLimitSelection);

						if (_strLimitSelection != "")
						{
							frmPickLimit.SingleLimit(_strLimitSelection);
							frmPickLimit.Opacity = 0;
						}

						frmPickLimit.ShowDialog();

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

						_strSelectedValue = frmPickLimit.SelectedLimit;
						strSelection = _strSelectedValue;
						_strForcedValue = _strSelectedValue;

						Log.Info("_strForcedValue = " + _strForcedValue);
						Log.Info("_strLimitSelection = " + _strLimitSelection);
					}

					if (bonusNode["selectskill"] != null)
					{
						Log.Info("selectskill = " + bonusNode["selectskill"].OuterXml.ToString());
						XmlNode nodSkill = bonusNode;
						// 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 (nodSkill.SelectSingleNode("selectskill").OuterXml.Contains("skillgroup"))
							frmPickSkill.OnlySkillGroup = nodSkill.SelectSingleNode("selectskill").Attributes["skillgroup"].InnerText;
						else if (nodSkill.SelectSingleNode("selectskill").OuterXml.Contains("skillcategory"))
							frmPickSkill.OnlyCategory = nodSkill.SelectSingleNode("selectskill").Attributes["skillcategory"].InnerText;
						else if (nodSkill.SelectSingleNode("selectskill").OuterXml.Contains("excludecategory"))
							frmPickSkill.ExcludeCategory = nodSkill.SelectSingleNode("selectskill").Attributes["excludecategory"].InnerText;
						else if (nodSkill.SelectSingleNode("selectskill").OuterXml.Contains("limittoskill"))
							frmPickSkill.LimitToSkill = nodSkill.SelectSingleNode("selectskill").Attributes["limittoskill"].InnerText;

						if (_strForcedValue.StartsWith("Adept:") || _strForcedValue.StartsWith("Magician:"))
							_strForcedValue = "";

						Log.Info("_strForcedValue = " + _strForcedValue);
						Log.Info("_strLimitSelection = " + _strLimitSelection);

						if (_strForcedValue != "")
						{
							frmPickSkill.OnlySkill = _strForcedValue;
							frmPickSkill.Opacity = 0;
						}
						frmPickSkill.ShowDialog();

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

						_strSelectedValue = frmPickSkill.SelectedSkill;
						_strForcedValue = _strSelectedValue;
						strSelection = _strSelectedValue;

						Log.Info("_strForcedValue = " + _strForcedValue);
						Log.Info("_strSelectedValue = " + _strSelectedValue);
						Log.Info("strSelection = " + strSelection);
					}

					if (bonusNode["selecttext"] != null)
					{
						Log.Info("selecttext = " + bonusNode["selecttext"].OuterXml.ToString());
						frmSelectText frmPickText = new frmSelectText();


						if (_objCharacter.Pushtext.Count > 0)
						{
							strSelection = _objCharacter.Pushtext.Pop();
						}
						else
						{
							frmPickText.Description = LanguageManager.Instance.GetString("String_Improvement_SelectText")
								.Replace("{0}", strFriendlyName);

							Log.Info("_strForcedValue = " + _strForcedValue);
							Log.Info("_strLimitSelection = " + _strLimitSelection);

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

							frmPickText.ShowDialog();

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

							strSelection = frmPickText.SelectedValue;
							_strLimitSelection = strSelection;
						}
						Log.Info("_strLimitSelection = " + _strLimitSelection);
						Log.Info("strSelection = " + strSelection);
					}

					if (bonusNode["specificattribute"] != null)
					{
						Log.Info("specificattribute = " + bonusNode["specificattribute"].OuterXml.ToString());
						strSelection = bonusNode["specificattribute"]["name"].InnerText.ToString();
						Log.Info(
							"strSelection = " + strSelection);
					}

					if (bonusNode["selectattribute"] != null)
					{
						Log.Info("selectattribute = " + bonusNode["selectattribute"].OuterXml.ToString());
						XmlNode nodSkill = bonusNode;
						if (_strForcedValue.StartsWith("Adept"))
							_strForcedValue = "";

						// Display the Select Attribute window and record which Attribute 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 (nodSkill["selectattribute"].InnerXml.Contains("<attribute>"))
						{
							List<string> strValue = new List<string>();
							foreach (XmlNode objXmlAttribute in nodSkill["selectattribute"].SelectNodes("attribute"))
								strValue.Add(objXmlAttribute.InnerText);
							frmPickAttribute.LimitToList(strValue);
						}

						if (nodSkill["selectattribute"].InnerXml.Contains("<excludeattribute>"))
						{
							List<string> strValue = new List<string>();
							foreach (XmlNode objXmlAttribute in nodSkill["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;

						Log.Info("_strForcedValue = " + _strForcedValue);
						Log.Info("_strLimitSelection = " + _strLimitSelection);

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

						frmPickAttribute.ShowDialog();

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

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

						Log.Info("_strSelectedValue = " + _strSelectedValue);
						Log.Info("strSourceName = " + strSourceName);
						Log.Info("_strForcedValue = " + _strForcedValue);
					}

					// Check if the character already has this power
					Log.Info("strSelection = " + strSelection);
					bool blnHasPower = false;
					Power objPower = new Power(_objCharacter);
					foreach (Power power in _objCharacter.Powers)
					{
						if (power.Name == strPowerNameLimit)
						{
							if (power.Extra != "" && power.Extra == strSelection)
							{
								blnHasPower = true;
								objPower = power;
							}
							else if (power.Extra == "")
							{
								blnHasPower = true;
								objPower = power;
							}
						}
					}

					Log.Info("blnHasPower = " + blnHasPower);

					if (blnHasPower)
					{
						// If yes, mark it free or give it free levels
						if (blnFree)
						{
							objPower.Free = true;
						}
						else
						{
							objPower.FreeLevels += intLevels;
							if (objPower.Rating < objPower.FreeLevels)
								objPower.Rating = objPower.FreeLevels;
						}
					}
					else
					{
						Log.Info("Adding Power " + strPowerName);
						// If no, add the power and mark it free or give it free levels
						objPower = new Power(_objCharacter);
						_objCharacter.Powers.Add(objPower);

						// Get the Power information
						XmlDocument objXmlDocument = new XmlDocument();
						objXmlDocument = XmlManager.Instance.Load("powers.xml");
						XmlNode objXmlPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"" + strPowerName + "\"]");
						Log.Info("objXmlPower = " + objXmlPower.OuterXml.ToString());

						bool blnLevels = false;
						if (objXmlPower["levels"] != null)
							blnLevels = (objXmlPower["levels"].InnerText == "yes");
						objPower.LevelsEnabled = blnLevels;
						objPower.Name = strPowerNameLimit;
						objPower.PointsPerLevel = Convert.ToDecimal(objXmlPower["points"].InnerText, GlobalOptions.Instance.CultureInfo);
						objPower.Source = objXmlPower["source"].InnerText;
						objPower.Page = objXmlPower["page"].InnerText;
						if (strSelection != string.Empty)
							objPower.Extra = strSelection;
						if (objXmlPower["doublecost"] != null)
							objPower.DoubleCost = false;

						if (blnFree)
						{
							objPower.Free = true;
						}
						else
						{
							objPower.FreeLevels += intLevels;
							if (objPower.Rating < intLevels)
								objPower.Rating = objPower.FreeLevels;
						}

						if (objXmlPower.InnerXml.Contains("bonus"))
						{
							objPower.Bonus = objXmlPower["bonus"];
							Log.Info("Calling CreateImprovements");
							if (
								!CreateImprovements(Improvement.ImprovementSource.Power, objPower.InternalId, objPower.Bonus, false,
									Convert.ToInt32(objPower.Rating), objPower.DisplayNameShort))
							{
								_objCharacter.Powers.Remove(objPower);
							}
						}
					}
					_strSelectedValue = "";
					_strForcedValue = "";
					strSelection = "";
				}
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.AdeptPower, "");
			}

			// Select a Power.
			if (bonusNode.LocalName == ("selectpowers"))
			{
				XmlNodeList objXmlPowerList = bonusNode.SelectNodes("selectpower");
				foreach (XmlNode objNode in objXmlPowerList)
				{
					Log.Info("selectpower");
					Log.Info("_strSelectedValue = " + _strSelectedValue);
					Log.Info("_strForcedValue = " + _strForcedValue);

					bool blnExistingPower = false;
					foreach (Power objExistingPower in _objCharacter.Powers)
					{
						if (objExistingPower.BonusSource == strSourceName)
						{
								if (objExistingPower.Name.StartsWith("Improved Reflexes"))
								{
									if (objExistingPower.Name.EndsWith("1"))
									{
										if (intRating >= 6)
											objExistingPower.FreePoints = 1.5M;
										else
											objExistingPower.FreePoints = 0;
									}
									else if (objExistingPower.Name.EndsWith("2"))
									{
										if (intRating >= 10)
											objExistingPower.FreePoints = 2.5M;
										else if (intRating >= 4)
											objExistingPower.FreePoints = 1.0M;
										else
											objExistingPower.FreePoints = 0;
									}
									else
									{
										if (intRating >= 14)
											objExistingPower.FreePoints = 3.5M;
										else if (intRating >= 8)
											objExistingPower.FreePoints = 2.0M;
										else if (intRating >= 4)
											objExistingPower.FreePoints = 1.0M;
										else
											objExistingPower.FreePoints = 0;
									}
								}
								else
								{
									// we have to adjust the number of free levels.
									decimal decLevels = Convert.ToDecimal(intRating)/4;
									decLevels = Math.Floor(decLevels/objExistingPower.PointsPerLevel);
									objExistingPower.FreeLevels = Convert.ToInt32(decLevels);
									if (objExistingPower.Rating < intRating)
										objExistingPower.Rating = objExistingPower.FreeLevels;
									break;
								}
							}
					}

					if (!blnExistingPower)
					{
						// Display the Select Skill window and record which Skill was selected.
						frmSelectPower frmPickPower = new frmSelectPower(_objCharacter);
						Log.Info("selectpower = " + objNode.OuterXml.ToString());

						if (objNode.OuterXml.Contains("limittopowers"))
							frmPickPower.LimitToPowers = objNode.Attributes["limittopowers"].InnerText;
						frmPickPower.ShowDialog();

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

						_strSelectedValue = frmPickPower.SelectedPower;
						if (blnConcatSelectedValue)
							strSourceName += " (" + _strSelectedValue + ")";

						XmlDocument objXmlDocument = XmlManager.Instance.Load("powers.xml");
						XmlNode objXmlPower =
							objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"" + _strSelectedValue + "\"]");
						string strSelection = "";

						Log.Info("_strSelectedValue = " + _strSelectedValue);
						Log.Info("strSourceName = " + strSourceName);

						XmlNode objBonus = objXmlPower["bonus"];

						string strPowerNameLimit = _strSelectedValue;
						if (objBonus != null)
						{
							if (objBonus["selectlimit"] != null)
							{
								Log.Info("selectlimit = " + objBonus["selectlimit"].OuterXml.ToString());
								_strForcedValue = "";
								// Display the Select Limit window and record which Limit was selected.
								frmSelectLimit frmPickLimit = new frmSelectLimit();
								if (strFriendlyName != "")
									frmPickLimit.Description = LanguageManager.Instance.GetString("String_Improvement_SelectLimitNamed")
										.Replace("{0}", strFriendlyName);
								else
									frmPickLimit.Description = LanguageManager.Instance.GetString("String_Improvement_SelectLimit");

								if (objBonus["selectlimit"].InnerXml.Contains("<limit>"))
								{
									List<string> strValue = new List<string>();
									foreach (XmlNode objXmlAttribute in objBonus["selectlimit"].SelectNodes("limit"))
										strValue.Add(objXmlAttribute.InnerText);
									frmPickLimit.LimitToList(strValue);
								}

								if (objBonus["selectlimit"].InnerXml.Contains("<excludelimit>"))
								{
									List<string> strValue = new List<string>();
									foreach (XmlNode objXmlAttribute in objBonus["selectlimit"].SelectNodes("excludelimit"))
										strValue.Add(objXmlAttribute.InnerText);
									frmPickLimit.RemoveFromList(strValue);
								}

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

								Log.Info("_strForcedValue = " + _strForcedValue);
								Log.Info("_strLimitSelection = " + _strLimitSelection);

								if (_strLimitSelection != "")
								{
									frmPickLimit.SingleLimit(_strLimitSelection);
									frmPickLimit.Opacity = 0;
								}

								frmPickLimit.ShowDialog();

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

								_strSelectedValue = frmPickLimit.SelectedLimit;
								strSelection = _strSelectedValue;
								_strForcedValue = _strSelectedValue;

								Log.Info("_strForcedValue = " + _strForcedValue);
								Log.Info("_strLimitSelection = " + _strLimitSelection);
							}

							if (objBonus["selectskill"] != null)
							{
								Log.Info("selectskill = " + objBonus["selectskill"].OuterXml.ToString());
								XmlNode nodSkill = objBonus;
								// 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 (nodSkill.SelectSingleNode("selectskill").OuterXml.Contains("skillgroup"))
									frmPickSkill.OnlySkillGroup = nodSkill.SelectSingleNode("selectskill").Attributes["skillgroup"].InnerText;
								else if (nodSkill.SelectSingleNode("selectskill").OuterXml.Contains("skillcategory"))
									frmPickSkill.OnlyCategory = nodSkill.SelectSingleNode("selectskill").Attributes["skillcategory"].InnerText;
								else if (nodSkill.SelectSingleNode("selectskill").OuterXml.Contains("excludecategory"))
									frmPickSkill.ExcludeCategory = nodSkill.SelectSingleNode("selectskill").Attributes["excludecategory"].InnerText;
								else if (nodSkill.SelectSingleNode("selectskill").OuterXml.Contains("limittoskill"))
									frmPickSkill.LimitToSkill = nodSkill.SelectSingleNode("selectskill").Attributes["limittoskill"].InnerText;

								if (_strForcedValue.StartsWith("Adept:") || _strForcedValue.StartsWith("Magician:"))
									_strForcedValue = "";

								Log.Info("_strForcedValue = " + _strForcedValue);
								Log.Info("_strLimitSelection = " + _strLimitSelection);

								if (_strForcedValue != "")
								{
									frmPickSkill.OnlySkill = _strForcedValue;
									frmPickSkill.Opacity = 0;
								}
								frmPickSkill.ShowDialog();

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

								_strSelectedValue = frmPickSkill.SelectedSkill;
								_strForcedValue = _strSelectedValue;
								strSelection = _strSelectedValue;

								Log.Info("_strForcedValue = " + _strForcedValue);
								Log.Info("_strSelectedValue = " + _strSelectedValue);
								Log.Info("strSelection = " + strSelection);
							}

							if (objBonus["selecttext"] != null)
							{
								Log.Info("selecttext = " + objBonus["selecttext"].OuterXml.ToString());
								frmSelectText frmPickText = new frmSelectText();
								frmPickText.Description = LanguageManager.Instance.GetString("String_Improvement_SelectText")
									.Replace("{0}", strFriendlyName);

								Log.Info("_strForcedValue = " + _strForcedValue);
								Log.Info("_strLimitSelection = " + _strLimitSelection);

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

								frmPickText.ShowDialog();

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

								strSelection = frmPickText.SelectedValue;
								_strLimitSelection = strSelection;

								Log.Info("_strLimitSelection = " + _strLimitSelection);
								Log.Info("strSelection = " + strSelection);
							}

							if (objBonus["specificattribute"] != null)
							{
								Log.Info("specificattribute = " + objBonus["specificattribute"].OuterXml.ToString());
								strSelection = objBonus["specificattribute"]["name"].InnerText.ToString();
								Log.Info("strSelection = " + strSelection);
							}

							if (objBonus["selectattribute"] != null)
							{
								Log.Info("selectattribute = " + objBonus["selectattribute"].OuterXml.ToString());
								XmlNode nodSkill = objBonus;
								if (_strForcedValue.StartsWith("Adept"))
									_strForcedValue = "";

								// Display the Select Attribute window and record which Attribute 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 (nodSkill["selectattribute"].InnerXml.Contains("<attribute>"))
								{
									List<string> strValue = new List<string>();
									foreach (XmlNode objXmlAttribute in nodSkill["selectattribute"].SelectNodes("attribute"))
										strValue.Add(objXmlAttribute.InnerText);
									frmPickAttribute.LimitToList(strValue);
								}

								if (nodSkill["selectattribute"].InnerXml.Contains("<excludeattribute>"))
								{
									List<string> strValue = new List<string>();
									foreach (XmlNode objXmlAttribute in nodSkill["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;

								Log.Info("_strForcedValue = " + _strForcedValue);
								Log.Info("_strLimitSelection = " + _strLimitSelection);

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

								frmPickAttribute.ShowDialog();

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

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

								Log.Info("_strSelectedValue = " + _strSelectedValue);
								Log.Info("strSourceName = " + strSourceName);
								Log.Info("_strForcedValue = " + _strForcedValue);
							}
						}

						// If no, add the power and mark it free or give it free levels
						Power objPower = new Power(_objCharacter);
						bool blnHasPower = false;

						foreach (Power power in _objCharacter.Powers)
						{
							if (power.Name == objXmlPower["name"].InnerText)
							{
								if (power.Extra != "" && power.Extra == strSelection)
								{
									blnHasPower = true;
									objPower = power;
								}
								else if (power.Extra == "")
								{
									blnHasPower = true;
									objPower = power;
								}
							}
						}

						Log.Info("blnHasPower = " + blnHasPower);

						if (blnHasPower)
						{
							// If yes, mark it free or give it free levels
							if (objXmlPower["levels"].InnerText == "no")
							{
								if (objPower.Name.StartsWith("Improved Reflexes"))
								{
									if (objPower.Name.EndsWith("1"))
									{
										if (intRating >= 6)
											objPower.FreePoints = 1.5M;
										else
											objPower.FreePoints = 0;
									}
									else if (objPower.Name.EndsWith("2"))
									{
										if (intRating >= 10)
											objPower.FreePoints = 2.5M;
										else if (intRating >= 4)
											objPower.FreePoints = 1.0M;
										else
											objPower.FreePoints = 0;
									}
									else
									{
										if (intRating >= 14)
											objPower.FreePoints = 3.5M;
										else if (intRating >= 8)
											objPower.FreePoints = 2.0M;
										else if (intRating >= 4)
											objPower.FreePoints = 1.0M;
										else
											objPower.FreePoints = 0;
									}
								}
								else
								{
									objPower.Free = true;
								}
							}
							else
							{
								decimal decLevels = Convert.ToDecimal(intRating)/4;
								decLevels = Math.Floor(decLevels/objPower.PointsPerLevel);
								objPower.FreeLevels += Convert.ToInt32(decLevels);
								objPower.Rating += Convert.ToInt32(decLevels);
							}
							objPower.BonusSource = strSourceName;
						}
						else
						{
							Log.Info("Adding Power " + _strSelectedValue);
							// Get the Power information
							_objCharacter.Powers.Add(objPower);
							Log.Info("objXmlPower = " + objXmlPower.OuterXml.ToString());

							bool blnLevels = false;
							if (objXmlPower["levels"] != null)
								blnLevels = (objXmlPower["levels"].InnerText == "yes");
							objPower.LevelsEnabled = blnLevels;
							objPower.Name = objXmlPower["name"].InnerText;
							objPower.PointsPerLevel = Convert.ToDecimal(objXmlPower["points"].InnerText, GlobalOptions.Instance.CultureInfo);
							objPower.Source = objXmlPower["source"].InnerText;
							objPower.Page = objXmlPower["page"].InnerText;
							objPower.BonusSource = strSourceName;
							if (strSelection != string.Empty)
								objPower.Extra = strSelection;
							if (objXmlPower["doublecost"] != null)
								objPower.DoubleCost = false;

							if (objXmlPower["levels"].InnerText == "no")
							{
								if (objPower.Name.StartsWith("Improved Reflexes"))
								{
									if (objPower.Name.EndsWith("1"))
									{
										if (intRating >= 6)
											objPower.FreePoints = 1.5M;
										else
											objPower.FreePoints = 0;
									}
									else if (objPower.Name.EndsWith("2"))
									{
										if (intRating >= 10)
											objPower.FreePoints = 2.5M;
										else if (intRating >= 4)
											objPower.FreePoints = 1.0M;
										else
											objPower.FreePoints = 0;
									}
									else
									{
										if (intRating >= 14)
											objPower.FreePoints = 3.5M;
										else if (intRating >= 8)
											objPower.FreePoints = 2.0M;
										else if (intRating >= 4)
											objPower.FreePoints = 1.0M;
										else
											objPower.FreePoints = 0;
									}
								}
								else
								{
									objPower.Free = true;
								}
							}
							else
							{
								decimal decLevels = Convert.ToDecimal(intRating)/4;
								decLevels = Math.Floor(decLevels/objPower.PointsPerLevel);
								objPower.FreeLevels += Convert.ToInt32(decLevels);
								if (objPower.Rating < intRating)
									objPower.Rating = objPower.FreeLevels;
							}

							if (objXmlPower.InnerXml.Contains("bonus"))
							{
								objPower.Bonus = objXmlPower["bonus"];
								Log.Info("Calling CreateImprovements");
								if (
									!CreateImprovements(Improvement.ImprovementSource.Power, objPower.InternalId, objPower.Bonus, false,
										Convert.ToInt32(objPower.Rating), objPower.DisplayNameShort))
								{
									_objCharacter.Powers.Remove(objPower);
								}
							}
						}
					}
				}
			}

			// Check for Armor Encumbrance Penalty.
			if (bonusNode.LocalName == ("armorencumbrancepenalty"))
			{
				Log.Info("armorencumbrancepenalty");
				Log.Info("armorencumbrancepenalty = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.ArmorEncumbrancePenalty, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Initiation.
			if (bonusNode.LocalName == ("initiation"))
			{
				Log.Info("initiation");
				Log.Info("initiation = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Initiation, "",
					ValueToInt(bonusNode.InnerText, intRating));
				_objCharacter.InitiateGrade += ValueToInt(bonusNode.InnerText, intRating);
			}

			// Check for Submersion.
			if (bonusNode.LocalName == ("submersion"))
			{
				Log.Info("submersion");
				Log.Info("submersion = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Submersion, "",
					ValueToInt(bonusNode.InnerText, intRating));
				_objCharacter.SubmersionGrade += ValueToInt(bonusNode.InnerText, intRating);
			}

			// Check for Skillwires.
			if (bonusNode.LocalName == ("skillwire"))
			{
				Log.Info("skillwire");
				Log.Info("skillwire = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Skillwire, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Hardwires.
			if (bonusNode.LocalName == ("hardwires"))
			{
				Log.Info("hardwire");
				Log.Info("hardwire = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");

				Log.Info("_strSelectedValue = " + _strSelectedValue);
				Log.Info("_strForcedValue = " + _strForcedValue);

				// 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");

				Log.Info("selectskill = " + bonusNode.OuterXml.ToString());
				if (bonusNode.OuterXml.Contains("skillgroup"))
					frmPickSkill.OnlySkillGroup = bonusNode.Attributes["skillgroup"].InnerText;
				else if (bonusNode.OuterXml.Contains("skillcategory"))
					frmPickSkill.OnlyCategory = bonusNode.Attributes["skillcategory"].InnerText;
				else if (bonusNode.OuterXml.Contains("excludecategory"))
					frmPickSkill.ExcludeCategory = bonusNode.Attributes["excludecategory"].InnerText;
				else if (bonusNode.OuterXml.Contains("limittoskill"))
					frmPickSkill.LimitToSkill = bonusNode.Attributes["limittoskill"].InnerText;
				else if (bonusNode.OuterXml.Contains("limittoattribute"))
					frmPickSkill.LinkedAttribute = bonusNode.Attributes["limittoattribute"].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();
					_strForcedValue = "";
					_strLimitSelection = "";
					return false;
				}

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

				Log.Info("_strSelectedValue = " + _strSelectedValue);
				Log.Info("strSourceName = " + strSourceName);
				CreateImprovement(_strSelectedValue, objImprovementSource, strSourceName, Improvement.ImprovementType.Hardwire, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Damage Resistance.
			if (bonusNode.LocalName == ("damageresistance"))
			{
				Log.Info("damageresistance");
				Log.Info("damageresistance = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.DamageResistance,
					"damageresistance", ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Restricted Item Count.
			if (bonusNode.LocalName == ("restricteditemcount"))
			{
				Log.Info("restricteditemcount");
				Log.Info("restricteditemcount = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.RestrictedItemCount, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Judge Intentions.
			if (bonusNode.LocalName == ("judgeintentions"))
			{
				Log.Info("judgeintentions");
				Log.Info("judgeintentions = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.JudgeIntentions, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Composure.
			if (bonusNode.LocalName == ("composure"))
			{
				Log.Info("composure");
				Log.Info("composure = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Composure, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Lift and Carry.
			if (bonusNode.LocalName == ("liftandcarry"))
			{
				Log.Info("liftandcarry");
				Log.Info("liftandcarry = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.LiftAndCarry, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Memory.
			if (bonusNode.LocalName == ("memory"))
			{
				Log.Info("memory");
				Log.Info("memory = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Memory, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Concealability.
			if (bonusNode.LocalName == ("concealability"))
			{
				Log.Info("concealability");
				Log.Info("concealability = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Concealability, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Drain Resistance.
			if (bonusNode.LocalName == ("drainresist"))
			{
				Log.Info("drainresist");
				Log.Info("drainresist = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.DrainResistance, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Fading Resistance.
			if (bonusNode.LocalName == ("fadingresist"))
			{
				Log.Info("fadingresist");
				Log.Info("fadingresist = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.FadingResistance, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Notoriety.
			if (bonusNode.LocalName == ("notoriety"))
			{
				Log.Info("notoriety");
				Log.Info("notoriety = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.Notoriety, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Complex Form Limit.
			if (bonusNode.LocalName == ("complexformlimit"))
			{
				Log.Info("complexformlimit");
				Log.Info("complexformlimit = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.ComplexFormLimit, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Spell Limit.
			if (bonusNode.LocalName == ("spelllimit"))
			{
				Log.Info("spelllimit");
				Log.Info("spelllimit = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.SpellLimit, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Spell Category bonuses.
			if (bonusNode.LocalName == ("spellcategory"))
			{
				Log.Info("spellcategory");
				Log.Info("spellcategory = " + bonusNode.OuterXml.ToString());

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

				Log.Info("Calling CreateImprovement");
				CreateImprovement(bonusNode["name"].InnerText, objImprovementSource, strSourceName,
					Improvement.ImprovementType.SpellCategory, strUseUnique, ValueToInt(bonusNode["val"].InnerText, intRating));
			}

			// Check for Throwing Range bonuses.
			if (bonusNode.LocalName == ("throwrange"))
			{
				Log.Info("throwrange");
				Log.Info("throwrange = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.ThrowRange, strUnique,
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Throwing STR bonuses.
			if (bonusNode.LocalName == ("throwstr"))
			{
				Log.Info("throwstr");
				Log.Info("throwstr = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.ThrowSTR, strUnique,
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Skillsoft access.
			if (bonusNode.LocalName == ("skillsoftaccess"))
			{
				Log.Info("skillsoftaccess");
				Log.Info("skillsoftaccess = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.SkillsoftAccess, "");
			}

			// Check for Quickening Metamagic.
			if (bonusNode.LocalName == ("quickeningmetamagic"))
			{
				Log.Info("quickeningmetamagic");
				Log.Info("quickeningmetamagic = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.QuickeningMetamagic, "");
			}

			// Check for ignore Stun CM Penalty.
			if (bonusNode.LocalName == ("ignorecmpenaltystun"))
			{
				Log.Info("ignorecmpenaltystun");
				Log.Info("ignorecmpenaltystun = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.IgnoreCMPenaltyStun, "");
			}

			// Check for ignore Physical CM Penalty.
			if (bonusNode.LocalName == ("ignorecmpenaltyphysical"))
			{
				Log.Info("ignorecmpenaltyphysical");
				Log.Info("ignorecmpenaltyphysical = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.IgnoreCMPenaltyPhysical, "");
			}

			// Check for a Cyborg Essence which will permanently set the character's ESS to 0.1.
			if (bonusNode.LocalName == ("cyborgessence"))
			{
				Log.Info("cyborgessence");
				Log.Info("cyborgessence = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.CyborgEssence, "");
			}

			// Check for Maximum Essence which will permanently modify the character's Maximum Essence value.
			if (bonusNode.LocalName == ("essencemax"))
			{
				Log.Info("essencemax");
				Log.Info("essencemax = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.EssenceMax, "",
					ValueToInt(bonusNode.InnerText, intRating));
			}

			// Check for Select Sprite.
			if (bonusNode.LocalName == ("selectsprite"))
			{
				Log.Info("selectsprite");
				Log.Info("selectsprite = " + bonusNode.OuterXml.ToString());
				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();
					_strForcedValue = "";
					_strLimitSelection = "";
					return false;
				}

				_strSelectedValue = frmPickItem.SelectedItem;

				Log.Info("Calling CreateImprovement");
				CreateImprovement(frmPickItem.SelectedItem, objImprovementSource, strSourceName,
					Improvement.ImprovementType.AddSprite,
					"");
			}

			// Check for Black Market Discount.
			if (bonusNode.LocalName == ("blackmarketdiscount"))
			{
				Log.Info("blackmarketdiscount");
				Log.Info("blackmarketdiscount = " + bonusNode.OuterXml.ToString());
				Log.Info("Calling CreateImprovement");
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.BlackMarketDiscount,
					strUnique);
				_objCharacter.BlackMarket = true;
			}
			// Select Armor (Mostly used for Custom Fit (Stack)).
			if (bonusNode.LocalName == ("selectarmor"))
			{
				Log.Info("selectarmor");
				Log.Info("selectarmor = " + bonusNode.OuterXml.ToString());
				string strSelectedValue = "";
				if (_strForcedValue != "")
					_strLimitSelection = _strForcedValue;

				// Display the Select Item window and record the value that was entered.

				List<ListItem> lstArmors = new List<ListItem>();
				foreach (Armor objArmor in _objCharacter.Armor)
				{
					foreach (ArmorMod objMod in objArmor.ArmorMods)
					{
						if (objMod.Name.StartsWith("Custom Fit"))
						{
							ListItem objItem = new ListItem();
							objItem.Value = objArmor.Name;
							objItem.Name = objArmor.DisplayName;
							lstArmors.Add(objItem);
						}
					}
				}

				if (lstArmors.Count > 0)
				{

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

					Log.Info( "_strLimitSelection = " + _strLimitSelection);
					Log.Info( "_strForcedValue = " + _strForcedValue);

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

					frmPickItem.ShowDialog();

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

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

					strSelectedValue = frmPickItem.SelectedItem;
					Log.Info( "_strSelectedValue = " + _strSelectedValue);
					Log.Info( "strSelectedValue = " + strSelectedValue);
				}

			}

			// Select Weapon (custom entry for things like Spare Clip).
			if (bonusNode.LocalName == ("selectweapon"))
			{
				Log.Info("selectweapon");
				Log.Info("selectweapon = " + bonusNode.OuterXml.ToString());
				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);

					Log.Info("_strLimitSelection = " + _strLimitSelection);
					Log.Info("_strForcedValue = " + _strForcedValue);

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

					frmPickText.ShowDialog();

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

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

					strSelectedValue = frmPickText.SelectedValue;
					Log.Info("_strSelectedValue = " + _strSelectedValue);
					Log.Info("strSelectedValue = " + strSelectedValue);
				}
				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;

					Log.Info("_strLimitSelection = " + _strLimitSelection);
					Log.Info("_strForcedValue = " + _strForcedValue);

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

					frmPickItem.ShowDialog();

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

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

					strSelectedValue = frmPickItem.SelectedItem;
					Log.Info("_strSelectedValue = " + _strSelectedValue);
					Log.Info("strSelectedValue = " + strSelectedValue);
				}

				// Create the Improvement.
				Log.Info("Calling CreateImprovement");
				CreateImprovement(strSelectedValue, objImprovementSource, strSourceName, Improvement.ImprovementType.Text, strUnique);
			}
			// Select an Optional Power.
			if (bonusNode.LocalName == ("optionalpowers"))
			{
				XmlNodeList objXmlPowerList = bonusNode.SelectNodes("optionalpower");
				//Log.Info("selectoptionalpower");
				// Display the Select Attribute window and record which Skill was selected.
				frmSelectOptionalPower frmPickPower = new frmSelectOptionalPower();
				frmPickPower.Description = LanguageManager.Instance.GetString("String_Improvement_SelectOptionalPower");
				string strForcedValue = "";

				List<KeyValuePair<string, string>> lstValue = new List<KeyValuePair<string,string>>();
				foreach (XmlNode objXmlOptionalPower in objXmlPowerList)
				{
					string strQuality = objXmlOptionalPower.InnerText;
					if (objXmlOptionalPower.Attributes["select"] != null)
					{
						strForcedValue = objXmlOptionalPower.Attributes["select"].InnerText;
					}
					//values.Add(new KeyValuePair<string, Stream>(title, contents));
					lstValue.Add(new KeyValuePair<string, string>(strQuality,strForcedValue));
				}
				frmPickPower.LimitToList(lstValue);


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

				Log.Info( "_strForcedValue = " + _strForcedValue);
				Log.Info( "_strLimitSelection = " + _strLimitSelection);

				if (_strLimitSelection != "")
				{
					frmPickPower.SinglePower(_strLimitSelection);
					frmPickPower.Opacity = 0;
				}

				frmPickPower.ShowDialog();

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

				_strSelectedValue = frmPickPower.SelectedPower;
				// Record the improvement.
				XmlDocument objXmlDocument = XmlManager.Instance.Load("critterpowers.xml");
				XmlNode objXmlPowerNode = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"" + _strSelectedValue + "\"]");
				TreeNode objPowerNode = new TreeNode();
				CritterPower objPower = new CritterPower(_objCharacter);
				
                objPower.Create(objXmlPowerNode, _objCharacter, objPowerNode, intRating, strForcedValue);
				_objCharacter.CritterPowers.Add(objPower);
			}

			if (bonusNode.LocalName == "publicawareness")
			{
				CreateImprovement("", objImprovementSource, strSourceName, Improvement.ImprovementType.PublicAwareness, strUnique, ValueToInt(bonusNode.InnerText));
			}

			//nothing went wrong, so return true
			return true;
		}
Example #3
0
		/// <summary>
		/// Load the Attribute from the XmlNode.
		/// </summary>
		/// <param name="objNode">XmlNode to load.</param>
		public void Load(XmlNode objNode)
		{
			string strId;
			if (objNode.TryGetField("id", out strId))
			{
				Id = Guid.Parse(strId);
			}
			_strName = objNode["name"].InnerText;
			_strSkillGroup = objNode["skillgroup"].InnerText;
			_strSkillCategory = objNode["skillcategory"].InnerText;
			_blnIsGrouped = Convert.ToBoolean(objNode["grouped"].InnerText);
            _blnDefault = Convert.ToBoolean(objNode["default"].InnerText);
			_intRating = Convert.ToInt32(objNode["rating"].InnerText);
			bool basefail = false;
            try
            {
                _intBase = Convert.ToInt32(objNode["base"].InnerText);
            }
            catch
            {
                _intBase = _intRating;
	            basefail = true;
            }
            try
            {
                _intKarma = Convert.ToInt32(objNode["karma"].InnerText);
            }
            catch
            {
                _intKarma = 0;
            }

			if (!basefail)
			{
				if (_intRating != _intKarma + _intBase)
				{
					_intBase = _intRating - _intKarma;
				}
			}

            _intFreeLevels = Convert.ToInt32(objNode["freelevels"].InnerText);
            _intRatingMaximum = Convert.ToInt32(objNode["ratingmax"].InnerText);
			_blnKnowledgeSkill = Convert.ToBoolean(objNode["knowledge"].InnerText);
			try
			{
				_blnExoticSkill = Convert.ToBoolean(objNode["exotic"].InnerText);
			}
			catch
			{
			}
            try
            {
                _blnBuyWithKarma = Convert.ToBoolean(objNode["buywithkarma"].InnerText);
            }
            catch
            {
            }
            if (objNode["spec"].InnerText.Contains("Hold-Outs"))
				objNode["spec"].InnerText = "Holdouts";
			_strSkillSpec = objNode["spec"].InnerText;

            if (_strSkillSpec != "")
            {
                SkillSpecialization objSpec = new SkillSpecialization(_strSkillSpec);
                _lstSpecializations.Add(objSpec);
                _strSkillSpec = "";
            }

			_blnAllowDelete = Convert.ToBoolean(objNode["allowdelete"].InnerText);
			_strAttribute = objNode["attribute"].InnerText;
            if (objNode.InnerXml.Contains("skillspecializations"))
            {
                XmlNodeList nodSpecializations = objNode.SelectNodes("skillspecializations/skillspecialization");
                foreach (XmlNode nodSpecialization in nodSpecializations)
                {
                    SkillSpecialization objSpec = new SkillSpecialization("");
                    objSpec.Load(nodSpecialization);
                    _lstSpecializations.Add(objSpec);
                }
            }
            try
			{
				_strSource = objNode["source"].InnerText;
				_strPage = objNode["page"].InnerText;
			}
			catch
			{
			}

			if (objNode["folded"] != null)
			{
				foreach (XmlNode foldNode in objNode["folded"].ChildNodes)
				{
					Skill s = new Skill(_objCharacter);
					s.Load(foldNode);

					_fold.Add(s);
				}
			}
		}
Example #4
0
        /// <summary>
        /// Load the character's Metatype information from the XML file.
        /// </summary>
        /// <param name="guiMetatype">GUID of the Metatype to load.</param>
        /// <param name="strXmlFile">Name of the XML file to load from (default: metatypes.xml).</param>
        /// <param name="intForce">Force that the Spirit was summoned with (default: 0).</param>
        /// <param name="blnBloodSpirit">Whether or not this character is a Blood Spirit (default: false).</param>
        /// <param name="blnPossessionBased">Whether or not this Spirit uses a Possession-based tradition (default: false).</param>
        /// <param name="strPossessionMethod">Possession method the Spirit uses (default: empty).</param>
        public void LoadMetatype(Guid guiMetatype, string strXmlFile = "metatypes.xml", int intForce = 0, bool blnBloodSpirit = false, bool blnPossessionBased = false, string strPossessionMethod = "")
        {
            ImprovementManager objImprovementManager = new ImprovementManager(this);
            XmlDocument objXmlDocument = XmlManager.Instance.Load(strXmlFile);

            XmlNode objXmlMetatype = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[id = \"" + guiMetatype.ToString() + "\"]");

            _guiMetatype = guiMetatype;

            // Set Metatype information.
            if (strXmlFile != "critters.xml")
            {
                BOD.AssignLimits(ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["bodmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["bodaug"].InnerText, intForce, 0));
                AGI.AssignLimits(ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["agimax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["agiaug"].InnerText, intForce, 0));
                REA.AssignLimits(ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["reamax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["reaaug"].InnerText, intForce, 0));
                STR.AssignLimits(ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["strmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["straug"].InnerText, intForce, 0));
                CHA.AssignLimits(ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["chamax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["chaaug"].InnerText, intForce, 0));
                INT.AssignLimits(ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["intmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["intaug"].InnerText, intForce, 0));
                LOG.AssignLimits(ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["logmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["logaug"].InnerText, intForce, 0));
                WIL.AssignLimits(ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["wilmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["wilaug"].InnerText, intForce, 0));
                MAG.AssignLimits(ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["magmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["magaug"].InnerText, intForce, 0));
                RES.AssignLimits(ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["resmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["resaug"].InnerText, intForce, 0));
                EDG.AssignLimits(ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["edgmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["edgaug"].InnerText, intForce, 0));
                ESS.AssignLimits(ExpressionToString(objXmlMetatype["essmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essaug"].InnerText, intForce, 0));
            }
            else
            {
                int intMinModifier = -3;
                if (objXmlMetatype["category"].InnerText == "Mutant Critters")
                    intMinModifier = 0;
                BOD.AssignLimits(ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, 3));
                AGI.AssignLimits(ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, 3));
                REA.AssignLimits(ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, 3));
                STR.AssignLimits(ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, 3));
                CHA.AssignLimits(ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, 3));
                INT.AssignLimits(ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, 3));
                LOG.AssignLimits(ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, 3));
                WIL.AssignLimits(ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, 3));
                MAG.AssignLimits(ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, 3));
                RES.AssignLimits(ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, 3));
                EDG.AssignLimits(ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, 3));
                ESS.AssignLimits(ExpressionToString(objXmlMetatype["essmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essaug"].InnerText, intForce, 0));
            }

            // If we're working with a Critter, set the Attributes to their default values.
            if (strXmlFile == "critters.xml")
            {
                BOD.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, 0));
                AGI.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, 0));
                REA.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, 0));
                STR.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, 0));
                CHA.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, 0));
                INT.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, 0));
                LOG.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, 0));
                WIL.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, 0));
                MAG.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, 0));
                RES.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, 0));
                EDG.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, 0));
                ESS.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["essmax"].InnerText, intForce, 0));
            }

            // Sprites can never have Physical Attributes or WIL.
            if (objXmlMetatype["category"].InnerText.EndsWith("Sprite"))
            {
                BOD.AssignLimits("0", "0", "0");
                AGI.AssignLimits("0", "0", "0");
                REA.AssignLimits("0", "0", "0");
                STR.AssignLimits("0", "0", "0");
                WIL.AssignLimits("0", "0", "0");
            }

            Metatype = objXmlMetatype["name"].InnerText;
            MetatypeCategory = objXmlMetatype["category"].InnerText;
            Metavariant = "";
            MetatypeBP = 0;

            _intWalk = Convert.ToInt32(objXmlMetatype["walk"].InnerText);
            _intRun = Convert.ToInt32(objXmlMetatype["run"].InnerText);
            _intSprint = Convert.ToInt32(objXmlMetatype["sprint"].InnerText);

            // Load the Qualities file.
            XmlDocument objXmlQualityDocument = XmlManager.Instance.Load("qualities.xml");

            // Determine if the Metatype has any bonuses.
            if (objXmlMetatype["bonus"] != null)
                objImprovementManager.CreateImprovements(Improvement.ImprovementSource.Metatype, Metatype, objXmlMetatype.SelectSingleNode("bonus"), false, 1, Metatype);

            // Create the Qualities that come with the Metatype.
            foreach (XmlNode objXmlQualityItem in objXmlMetatype.SelectNodes("qualities/positive/quality"))
            {
                XmlNode objXmlQuality = objXmlQualityDocument.SelectSingleNode("/chummer/qualities/quality[id = \"" + objXmlQualityItem.InnerText + "\"]");
                TreeNode objNode = new TreeNode();
                List<Weapon> objWeapons = new List<Weapon>();
                List<TreeNode> objWeaponNodes = new List<TreeNode>();
                Quality objQuality = new Quality(this);
                string strForceValue = "";
                if (objXmlQualityItem.Attributes["select"] != null)
                    strForceValue = objXmlQualityItem.Attributes["select"].InnerText;
                QualitySource objSource = new QualitySource();
                objSource = QualitySource.Metatype;
                if (objXmlQualityItem.Attributes["removable"] != null)
                    objSource = QualitySource.MetatypeRemovable;
                objQuality.Create(objXmlQuality, this, objSource, objNode, objWeapons, objWeaponNodes, strForceValue);
                Qualities.Add(objQuality);

                // Add any created Weapons to the character.
                foreach (Weapon objWeapon in objWeapons)
                    Weapons.Add(objWeapon);
            }
            foreach (XmlNode objXmlQualityItem in objXmlMetatype.SelectNodes("qualities/negative/quality"))
            {
                XmlNode objXmlQuality = objXmlQualityDocument.SelectSingleNode("/chummer/qualities/quality[id = \"" + objXmlQualityItem.InnerText + "\"]");
                TreeNode objNode = new TreeNode();
                List<Weapon> objWeapons = new List<Weapon>();
                List<TreeNode> objWeaponNodes = new List<TreeNode>();
                Quality objQuality = new Quality(this);
                string strForceValue = "";
                if (objXmlQualityItem.Attributes["select"] != null)
                    strForceValue = objXmlQualityItem.Attributes["select"].InnerText;
                QualitySource objSource = new QualitySource();
                objSource = QualitySource.Metatype;
                if (objXmlQualityItem.Attributes["removable"] != null)
                    objSource = QualitySource.MetatypeRemovable;
                objQuality.Create(objXmlQuality, this, objSource, objNode, objWeapons, objWeaponNodes, strForceValue);
                Qualities.Add(objQuality);

                // Add any created Weapons to the character.
                foreach (Weapon objWeapon in objWeapons)
                    Weapons.Add(objWeapon);
            }

            // Run through the character's Attributes one more time and make sure their value matches their minimum value.
            if (strXmlFile == "metatypes.xml")
            {
                BOD.Value = BOD.TotalMinimum;
                AGI.Value = AGI.TotalMinimum;
                REA.Value = REA.TotalMinimum;
                STR.Value = STR.TotalMinimum;
                CHA.Value = CHA.TotalMinimum;
                INT.Value = INT.TotalMinimum;
                LOG.Value = LOG.TotalMinimum;
                WIL.Value = WIL.TotalMinimum;
            }

            // Add any Critter Powers the Metatype/Critter should have.
            XmlNode objXmlCritter = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[id = \"" + guiMetatype.ToString() + "\"]");

            objXmlDocument = XmlManager.Instance.Load("critterpowers.xml");
            foreach (XmlNode objXmlPower in objXmlCritter.SelectNodes("powers/power"))
            {
                XmlNode objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[id = \"" + objXmlPower.InnerText + "\"]");
                TreeNode objNode = new TreeNode();
                CritterPower objPower = new CritterPower(this);
                string strForcedValue = "";
                int intRating = 0;

                if (objXmlPower.Attributes["rating"] != null)
                    intRating = Convert.ToInt32(objXmlPower.Attributes["rating"].InnerText);
                if (objXmlPower.Attributes["select"] != null)
                    strForcedValue = objXmlPower.Attributes["select"].InnerText;

                objPower.Create(objXmlCritterPower, this, objNode, intRating, strForcedValue);
                objPower.CountTowardsLimit = false;
                CritterPowers.Add(objPower);
            }

            // If this is a Blood Spirit, add their free Critter Powers.
            if (blnBloodSpirit)
            {
                XmlNode objXmlCritterPower;
                TreeNode objNode;
                CritterPower objPower;
                bool blnAddPower = true;

                // Energy Drain.
                foreach (CritterPower objFindPower in CritterPowers)
                {
                    if (objFindPower.Name == "Energy Drain")
                    {
                        blnAddPower = false;
                        break;
                    }
                }
                if (blnAddPower)
                {
                    objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"Energy Drain\"]");
                    objNode = new TreeNode();
                    objPower = new CritterPower(this);
                    objPower.Create(objXmlCritterPower, this, objNode, 0, "");
                    objPower.CountTowardsLimit = false;
                    CritterPowers.Add(objPower);
                }

                // Fear.
                blnAddPower = true;
                foreach (CritterPower objFindPower in CritterPowers)
                {
                    if (objFindPower.Name == "Fear")
                    {
                        blnAddPower = false;
                        break;
                    }
                }
                if (blnAddPower)
                {
                    objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"Fear\"]");
                    objNode = new TreeNode();
                    objPower = new CritterPower(this);
                    objPower.Create(objXmlCritterPower, this, objNode, 0, "");
                    objPower.CountTowardsLimit = false;
                    CritterPowers.Add(objPower);
                }

                // Natural Weapon.
                objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"Natural Weapon\"]");
                objNode = new TreeNode();
                objPower = new CritterPower(this);
                objPower.Create(objXmlCritterPower, this, objNode, 0, "DV " + intForce.ToString() + "P, AP 0");
                objPower.CountTowardsLimit = false;
                CritterPowers.Add(objPower);

                // Evanescence.
                blnAddPower = true;
                foreach (CritterPower objFindPower in CritterPowers)
                {
                    if (objFindPower.Name == "Evanescence")
                    {
                        blnAddPower = false;
                        break;
                    }
                }
                if (blnAddPower)
                {
                    objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"Evanescence\"]");
                    objNode = new TreeNode();
                    objPower = new CritterPower(this);
                    objPower.Create(objXmlCritterPower, this, objNode, 0, "");
                    objPower.CountTowardsLimit = false;
                    CritterPowers.Add(objPower);
                }
            }

            // Remove the Critter's Materialization Power if they have it. Add the Possession or Inhabitation Power if the Possession-based Tradition checkbox is checked.
            if (blnPossessionBased)
            {
                foreach (CritterPower objCritterPower in CritterPowers)
                {
                    if (objCritterPower.Name == "Materialization")
                    {
                        CritterPowers.Remove(objCritterPower);
                        break;
                    }
                }

                // Add the selected Power.
                XmlNode objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"" + strPossessionMethod + "\"]");
                TreeNode objNode = new TreeNode();
                CritterPower objPower = new CritterPower(this);
                objPower.Create(objXmlCritterPower, this, objNode, 0, "");
                objPower.CountTowardsLimit = false;
                CritterPowers.Add(objPower);
            }

            // Set the Skill Ratings for the Critter.
            foreach (XmlNode objXmlSkill in objXmlCritter.SelectNodes("skills/skill"))
            {
                if (objXmlSkill.InnerText.Contains("Exotic"))
                {
                    Skill objExotic = new Skill(this);
                    objExotic.ExoticSkill = true;
                    objExotic.Attribute = "AGI";
                    if (objXmlSkill.Attributes["spec"] != null)
                        objExotic.Specialization = objXmlSkill.Attributes["spec"].InnerText;
                    if (Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, intForce, 0)) > 6)
                        objExotic.RatingMaximum = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, intForce, 0));
                    objExotic.Rating = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, intForce, 0));
                    objExotic.Name = objXmlSkill.InnerText;
                    Skills.Add(objExotic);
                }
                else
                {
                    foreach (Skill objSkill in Skills)
                    {
                        if (objSkill.Name == objXmlSkill.InnerText)
                        {
                            if (objXmlSkill.Attributes["spec"] != null)
                                objSkill.Specialization = objXmlSkill.Attributes["spec"].InnerText;
                            if (Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, intForce, 0)) > 6)
                                objSkill.RatingMaximum = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, intForce, 0));
                            objSkill.Rating = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, intForce, 0));
                            break;
                        }
                    }
                }
            }

            // Set the Skill Group Ratings for the Critter.
            foreach (XmlNode objXmlSkill in objXmlCritter.SelectNodes("skills/group"))
            {
                foreach (SkillGroup objSkill in SkillGroups)
                {
                    if (objSkill.Name == objXmlSkill.InnerText)
                    {
                        objSkill.RatingMaximum = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, intForce, 0));
                        objSkill.Rating = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, intForce, 0));
                        break;
                    }
                }
            }

            // Set the Knowledge Skill Ratings for the Critter.
            foreach (XmlNode objXmlSkill in objXmlCritter.SelectNodes("skills/knowledge"))
            {
                Skill objKnowledge = new Skill(this);
                objKnowledge.Name = objXmlSkill.InnerText;
                objKnowledge.KnowledgeSkill = true;
                if (objXmlSkill.Attributes["spec"] != null)
                    objKnowledge.Specialization = objXmlSkill.Attributes["spec"].InnerText;
                objKnowledge.SkillCategory = objXmlSkill.Attributes["category"].InnerText;
                if (Convert.ToInt32(objXmlSkill.Attributes["rating"].InnerText) > 6)
                    objKnowledge.RatingMaximum = Convert.ToInt32(objXmlSkill.Attributes["rating"].InnerText);
                objKnowledge.Rating = Convert.ToInt32(objXmlSkill.Attributes["rating"].InnerText);
                Skills.Add(objKnowledge);
            }

            // If this is a Critter with a Force (which dictates their Skill Rating/Maximum Skill Rating), set their Skill Rating Maximums.
            if (intForce > 0)
            {
                int intMaxRating = intForce;
                // Determine the highest Skill Rating the Critter has.
                foreach (Skill objSkill in Skills)
                {
                    if (objSkill.RatingMaximum > intMaxRating)
                        intMaxRating = objSkill.RatingMaximum;
                }

                // Now that we know the upper limit, set all of the Skill Rating Maximums to match.
                foreach (Skill objSkill in Skills)
                    objSkill.RatingMaximum = intMaxRating;
                foreach (SkillGroup objGroup in SkillGroups)
                    objGroup.RatingMaximum = intMaxRating;

                // Set the MaxSkillRating for the character so it can be used later when they add new Knowledge Skills or Exotic Skills.
                MaxSkillRating = intMaxRating;
            }

            // Add any Complex Forms the Critter comes with (typically Sprites)
            XmlDocument objXmlProgramDocument = XmlManager.Instance.Load("programs.xml");
            foreach (XmlNode objXmlComplexForm in objXmlCritter.SelectNodes("complexforms/complexform"))
            {
                int intRating = 0;
                if (objXmlComplexForm.Attributes["rating"] != null)
                    intRating = Convert.ToInt32(ExpressionToString(objXmlComplexForm.Attributes["rating"].InnerText, intForce, 0));
                string strForceValue = "";
                if (objXmlComplexForm.Attributes["select"] != null)
                    strForceValue = objXmlComplexForm.Attributes["select"].InnerText;
                XmlNode objXmlProgram = objXmlProgramDocument.SelectSingleNode("/chummer/programs/program[name = \"" + objXmlComplexForm.InnerText + "\"]");
                TreeNode objNode = new TreeNode();
                TechProgram objProgram = new TechProgram(this);
                objProgram.Create(objXmlProgram, this, objNode, strForceValue);
                objProgram.Rating = intRating;
                TechPrograms.Add(objProgram);

                // Add the Program Option if applicable.
                if (objXmlComplexForm.Attributes["option"] != null)
                {
                    int intOptRating = 0;
                    if (objXmlComplexForm.Attributes["optionrating"] != null)
                        intOptRating = Convert.ToInt32(ExpressionToString(objXmlComplexForm.Attributes["optionrating"].InnerText, intForce, 0));
                    string strOptForceValue = "";
                    if (objXmlComplexForm.Attributes["optionselect"] != null)
                        strOptForceValue = objXmlComplexForm.Attributes["optionselect"].InnerText;
                    XmlNode objXmlOption = objXmlProgramDocument.SelectSingleNode("/chummer/options/option[name = \"" + objXmlComplexForm.Attributes["option"].InnerText + "\"]");
                    TreeNode objNodeOpt = new TreeNode();
                    TechProgramOption objOption = new TechProgramOption(this);
                    objOption.Create(objXmlOption, this, objNodeOpt, strOptForceValue);
                    objOption.Rating = intOptRating;
                    objProgram.Options.Add(objOption);
                }
            }

            // Add any Gear the Critter comes with (typically Programs for A.I.s)
            XmlDocument objXmlGearDocument = XmlManager.Instance.Load("gear.xml");
            foreach (XmlNode objXmlGear in objXmlCritter.SelectNodes("gears/gear"))
            {
                int intRating = 0;
                if (objXmlGear.Attributes["rating"] != null)
                    intRating = Convert.ToInt32(ExpressionToString(objXmlGear.Attributes["rating"].InnerText, intForce, 0));
                string strForceValue = "";
                if (objXmlGear.Attributes["select"] != null)
                    strForceValue = objXmlGear.Attributes["select"].InnerText;
                XmlNode objXmlGearItem = objXmlGearDocument.SelectSingleNode("/chummer/gears/gear[id = \"" + objXmlGear.InnerText + "\"]");
                TreeNode objNode = new TreeNode();
                Gear objGear = new Gear(this);
                List<Weapon> lstWeapons = new List<Weapon>();
                List<TreeNode> lstWeaponNodes = new List<TreeNode>();
                objGear.Create(objXmlGearItem, this, objNode, intRating, lstWeapons, lstWeaponNodes, strForceValue);
                objGear.Cost = "0";
                objGear.Cost3 = "0";
                objGear.Cost6 = "0";
                objGear.Cost10 = "0";
                Gear.Add(objGear);
            }

            // If this is a Mutant Critter, count up the number of Skill points they start with.
            if (MetatypeCategory == "Mutant Critters")
            {
                foreach (Skill objSkill in Skills)
                    MutantCritterBaseSkills += objSkill.Rating;
            }
        }
Example #5
0
        /// <summary>
        /// Update the Character information.
        /// </summary>
        public void UpdateCharacterInfo()
        {
            if (_blnLoading)
                return;

            if (!_blnSkipUpdate)
            {
                string strTip = "";
                _blnSkipUpdate = true;

                // Calculate the character's move.
                string strMovement = "";
                if (_objOptions.CyberlegMovement)
                {
                    int intLegs = 0;
                    int intAGI = 0;
                    foreach (Cyberware objCyber in _objCharacter.Cyberware)
                    {
                        if (objCyber.LimbSlot == "leg")
                        {
                            intLegs++;
                            if (intAGI > 0)
                                intAGI = Math.Min(intAGI, objCyber.TotalAgility);
                            else
                                intAGI = objCyber.TotalAgility;
                        }
                    }
                    if (intLegs == 2)
                        strMovement = String.Format("{0}/{1}", (intAGI * 2), (intAGI * 4));
                    else
                        strMovement = String.Format("{0}/{1}", (_objCharacter.AGI.TotalValue * 2), (_objCharacter.AGI.TotalValue * 4));
                }
                else
                    strMovement = String.Format("{0}/{1}", (_objCharacter.AGI.TotalValue * 2), (_objCharacter.AGI.TotalValue * 4));

                _objCharacter.Movement = strMovement;
                lblMovement.Text = _objCharacter.Movement;

                string strFormat;
                if (_objCharacter.Options.EssenceDecimals == 4)
                    strFormat = "{0:0.0000}";
                else
                    strFormat = "{0:0.00}";
                decimal decESS = _objCharacter.Essence;
                lblESSMax.Text = decESS.ToString();
                tssEssence.Text = string.Format(strFormat, decESS);

                lblCyberwareESS.Text = string.Format(strFormat, _objCharacter.CyberwareEssence);
                lblBiowareESS.Text = string.Format(strFormat, _objCharacter.BiowareEssence);
                lblEssenceHoleESS.Text = string.Format(strFormat, _objCharacter.EssenceHole);

                // Reduce a character's MAG and RES from Essence Loss.
                int intReduction = _objCharacter.ESS.MetatypeMaximum - Convert.ToInt32(Math.Floor(decESS));

                // Remove any Improvements from MAG and RES from Essence Loss.
                _objImprovementManager.RemoveImprovements(Improvement.ImprovementSource.EssenceLoss, "Essence Loss");

                // Create the Essence Loss Improvements.
                if (intReduction > 0)
                {
                    _objImprovementManager.CreateImprovement("MAG", Improvement.ImprovementSource.EssenceLoss, "Essence Loss", Improvement.ImprovementType.Attribute, "", 0, intReduction * -1, 0, 1, 1, 0);
                    _objImprovementManager.CreateImprovement("RES", Improvement.ImprovementSource.EssenceLoss, "Essence Loss", Improvement.ImprovementType.Attribute, "", 0, intReduction * -1, 0, 1, 1, 0);

                    if (_objCharacter.AdeptEnabled)
                    {
                        CalculatePowerPoints();
                    }
                }

                int intEssenceLoss = 0;
                if (!_objOptions.ESSLossReducesMaximumOnly && !_objCharacter.OverrideSpecialAttributeEssenceLoss)
                    intEssenceLoss = _objCharacter.EssencePenalty;
                else
                {
                    if (_objCharacter.MAGEnabled)
                    {
                        if (_objCharacter.MAG.Value > _objCharacter.MAG.TotalMaximum)
                            intEssenceLoss = _objCharacter.MAG.Value - _objCharacter.MAG.TotalMaximum;
                    }
                    else if (_objCharacter.RESEnabled)
                    {
                        if (_objCharacter.RES.Value > _objCharacter.RES.TotalMaximum)
                            intEssenceLoss = _objCharacter.RES.Value - _objCharacter.RES.TotalMaximum;
                    }
                }

                // Update the Attribute information.
                lblBOD.Text = _objCharacter.BOD.Value.ToString();
                lblAGI.Text = _objCharacter.AGI.Value.ToString();
                lblREA.Text = _objCharacter.REA.Value.ToString();
                lblSTR.Text = _objCharacter.STR.Value.ToString();
                lblCHA.Text = _objCharacter.CHA.Value.ToString();
                lblINT.Text = _objCharacter.INT.Value.ToString();
                lblLOG.Text = _objCharacter.LOG.Value.ToString();
                lblWIL.Text = _objCharacter.WIL.Value.ToString();
                lblEDG.Text = _objCharacter.EDG.Value.ToString();
                if (_objCharacter.MAG.Value - intEssenceLoss < 0)
                    lblMAG.Text = "0";
                else
                    lblMAG.Text = (_objCharacter.MAG.Value - intEssenceLoss).ToString();
                if (_objCharacter.RES.Value - intEssenceLoss < 0)
                    lblRES.Text = "0";
                else
                    lblRES.Text = (_objCharacter.RES.Value - intEssenceLoss).ToString();

                // If the Attribute reaches 0, the character has burned out.
                if (_objCharacter.MAG.Value - intEssenceLoss < 1 && _objCharacter.MAGEnabled)
                {
                    _objCharacter.MAG.Value = 0;
                    _objCharacter.MAG.MetatypeMinimum = 0;
                    _objCharacter.MAG.MetatypeMaximum = 0;
                    _objCharacter.MAG.MetatypeAugmentedMaximum = 0;

                    if (_objCharacter.MAGEnabled)
                    {
                        // Move all MAG-linked Active Skills to Knowledge Skills.
                        List<Skill> lstNewSkills = new List<Skill>();
                        foreach (Skill objSkill in _objCharacter.Skills)
                        {
                            if (objSkill.Attribute == "MAG" && objSkill.Rating > 0)
                            {
                                int i = panKnowledgeSkills.Controls.Count;
                                Skill objKnowledge = new Skill(_objCharacter);

                                SkillControl objSkillControl = new SkillControl();
                                objKnowledge.Name = objSkill.Name;
                                objSkillControl.SkillObject = objKnowledge;

                                // Attach an EventHandler for the RatingChanged and SpecializationChanged Events.
                                objSkillControl.RatingChanged += objKnowledgeSkill_RatingChanged;
                                objSkillControl.SpecializationChanged += objSkill_SpecializationChanged;
                                objSkillControl.DeleteSkill += objKnowledgeSkill_DeleteSkill;
                                objSkillControl.SkillKarmaClicked += objKnowledgeSkill_KarmaClicked;
                                objSkillControl.DiceRollerClicked += objSkill_DiceRollerClicked;

                                objSkillControl.KnowledgeSkill = true;
                                objSkillControl.AllowDelete = true;
                                if (objSkill.Rating > 13)
                                    objSkillControl.SkillRatingMaximum = objSkill.Rating;
                                else
                                    objSkillControl.SkillRatingMaximum = 12;
                                objSkillControl.SkillRating = objSkill.Rating;
                                objSkillControl.SkillCategory = "Professional";
                                // Set the SkillControl's Location since scrolling the Panel causes it to actually change the child Controls' Locations.
                                objSkillControl.Location = new Point(0, objSkillControl.Height * i + panKnowledgeSkills.AutoScrollPosition.Y);
                                panKnowledgeSkills.Controls.Add(objSkillControl);

                                lstNewSkills.Add(objKnowledge);
                            }
                        }
                        foreach (Skill objSkill in lstNewSkills)
                            _objCharacter.Skills.Add(objSkill);
                    }

                    _objCharacter.MAGEnabled = false;
                    _objCharacter.MagicianEnabled = false;
                    _objCharacter.AdeptEnabled = false;
                }
                if (_objCharacter.RES.Value - intEssenceLoss < 1 && _objCharacter.RESEnabled)
                {
                    _objCharacter.RES.Value = 0;
                    _objCharacter.RES.MetatypeMinimum = 0;
                    _objCharacter.RES.MetatypeMinimum = 0;
                    _objCharacter.RES.MetatypeAugmentedMaximum = 0;

                    if (_objCharacter.RESEnabled)
                    {
                        // Move all RES-linked Active Skills to Knowledge Skills.
                        List<Skill> lstNewSkills = new List<Skill>();
                        foreach (Skill objSkill in _objCharacter.Skills)
                        {
                            if (objSkill.Attribute == "RES" && objSkill.Rating > 0)
                            {
                                int i = panKnowledgeSkills.Controls.Count;
                                Skill objKnowledge = new Skill(_objCharacter);

                                SkillControl objSkillControl = new SkillControl();
                                objKnowledge.Name = objSkill.Name;
                                objSkillControl.SkillObject = objKnowledge;

                                // Attach an EventHandler for the RatingChanged and SpecializationChanged Events.
                                objSkillControl.RatingChanged += objKnowledgeSkill_RatingChanged;
                                objSkillControl.SpecializationChanged += objSkill_SpecializationChanged;
                                objSkillControl.DeleteSkill += objKnowledgeSkill_DeleteSkill;
                                objSkillControl.SkillKarmaClicked += objKnowledgeSkill_KarmaClicked;
                                objSkillControl.DiceRollerClicked += objSkill_DiceRollerClicked;

                                objSkillControl.KnowledgeSkill = true;
                                objSkillControl.AllowDelete = true;
                                if (objSkill.Rating > 13)
                                    objSkillControl.SkillRatingMaximum = objSkill.Rating;
                                else
                                    objSkillControl.SkillRatingMaximum = 12;
                                objSkillControl.SkillRating = objSkill.Rating;
                                objSkillControl.SkillCategory = "Professional";
                                // Set the SkillControl's Location since scrolling the Panel causes it to actually change the child Controls' Locations.
                                objSkillControl.Location = new Point(0, objSkillControl.Height * i + panKnowledgeSkills.AutoScrollPosition.Y);
                                panKnowledgeSkills.Controls.Add(objSkillControl);

                                lstNewSkills.Add(objKnowledge);
                            }
                        }
                        foreach (Skill objSkill in lstNewSkills)
                            _objCharacter.Skills.Add(objSkill);
                    }

                    _objCharacter.RESEnabled = false;
                    _objCharacter.TechnomancerEnabled = false;
                }

                if (_objCharacter.MAGAdept > _objCharacter.MAG.TotalValue)
                    _objCharacter.MAGAdept = _objCharacter.MAG.TotalValue;

                // If the character is an A.I., set the Edge MetatypeMaximum to their Rating.
                if (_objCharacter.Metatype.EndsWith("A.I.") || _objCharacter.MetatypeCategory == "Technocritters" || _objCharacter.MetatypeCategory == "Protosapients")
                    _objCharacter.EDG.MetatypeMaximum = _objCharacter.Rating;

                // If the character is Cyberzombie, adjust their Attributes based on their Essence.
                if (_objCharacter.MetatypeCategory == "Cyberzombie")
                {
                    int intESSModifier = _objCharacter.EssencePenalty - Convert.ToInt32(_objCharacter.EssenceMaximum);
                    _objImprovementManager.RemoveImprovements(Improvement.ImprovementSource.Cyberzombie, "Cyberzombie Attributes");
                    _objImprovementManager.CreateImprovement("BOD", Improvement.ImprovementSource.Cyberzombie, "Cyberzombie Attributes", Improvement.ImprovementType.Attribute, "", 0, 1, 0, intESSModifier);
                    _objImprovementManager.CreateImprovement("AGI", Improvement.ImprovementSource.Cyberzombie, "Cyberzombie Attributes", Improvement.ImprovementType.Attribute, "", 0, 1, 0, intESSModifier);
                    _objImprovementManager.CreateImprovement("REA", Improvement.ImprovementSource.Cyberzombie, "Cyberzombie Attributes", Improvement.ImprovementType.Attribute, "", 0, 1, 0, intESSModifier);
                    _objImprovementManager.CreateImprovement("STR", Improvement.ImprovementSource.Cyberzombie, "Cyberzombie Attributes", Improvement.ImprovementType.Attribute, "", 0, 1, 0, intESSModifier);
                    _objImprovementManager.CreateImprovement("CHA", Improvement.ImprovementSource.Cyberzombie, "Cyberzombie Attributes", Improvement.ImprovementType.Attribute, "", 0, 1, 0, intESSModifier);
                    _objImprovementManager.CreateImprovement("INT", Improvement.ImprovementSource.Cyberzombie, "Cyberzombie Attributes", Improvement.ImprovementType.Attribute, "", 0, 1, 0, intESSModifier);
                    _objImprovementManager.CreateImprovement("LOG", Improvement.ImprovementSource.Cyberzombie, "Cyberzombie Attributes", Improvement.ImprovementType.Attribute, "", 0, 1, 0, intESSModifier);
                    _objImprovementManager.CreateImprovement("WIL", Improvement.ImprovementSource.Cyberzombie, "Cyberzombie Attributes", Improvement.ImprovementType.Attribute, "", 0, 1, 0, intESSModifier);
                }

                // Update the Attribute Improvement Cost ToolTips.
                string strTooltip = "";
                if (!_objOptions.AlternateMetatypeAttributeKarma)
                {
                    strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.BOD.Value + _objCharacter.BOD.AttributeValueModifiers + 1).ToString()).Replace("{1}", ((_objCharacter.BOD.Value + _objCharacter.BOD.AttributeValueModifiers + 1) * _objOptions.KarmaAttribute).ToString());
                    tipTooltip.SetToolTip(cmdImproveBOD, strTooltip);
                    strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.AGI.Value + _objCharacter.AGI.AttributeValueModifiers + 1).ToString()).Replace("{1}", ((_objCharacter.AGI.Value + _objCharacter.AGI.AttributeValueModifiers + 1) * _objOptions.KarmaAttribute).ToString());
                    tipTooltip.SetToolTip(cmdImproveAGI, strTooltip);
                    strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.REA.Value + _objCharacter.REA.AttributeValueModifiers + 1).ToString()).Replace("{1}", ((_objCharacter.REA.Value + _objCharacter.REA.AttributeValueModifiers + 1) * _objOptions.KarmaAttribute).ToString());
                    tipTooltip.SetToolTip(cmdImproveREA, strTooltip);
                    strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.STR.Value + _objCharacter.STR.AttributeValueModifiers + 1).ToString()).Replace("{1}", ((_objCharacter.STR.Value + _objCharacter.STR.AttributeValueModifiers + 1) * _objOptions.KarmaAttribute).ToString());
                    tipTooltip.SetToolTip(cmdImproveSTR, strTooltip);
                    strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.CHA.Value + _objCharacter.CHA.AttributeValueModifiers + 1).ToString()).Replace("{1}", ((_objCharacter.CHA.Value + _objCharacter.CHA.AttributeValueModifiers + 1) * _objOptions.KarmaAttribute).ToString());
                    tipTooltip.SetToolTip(cmdImproveCHA, strTooltip);
                    strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.INT.Value + _objCharacter.INT.AttributeValueModifiers + 1).ToString()).Replace("{1}", ((_objCharacter.INT.Value + _objCharacter.INT.AttributeValueModifiers + 1) * _objOptions.KarmaAttribute).ToString());
                    tipTooltip.SetToolTip(cmdImproveINT, strTooltip);
                    strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.LOG.Value + _objCharacter.LOG.AttributeValueModifiers + 1).ToString()).Replace("{1}", ((_objCharacter.LOG.Value + _objCharacter.LOG.AttributeValueModifiers + 1) * _objOptions.KarmaAttribute).ToString());
                    tipTooltip.SetToolTip(cmdImproveLOG, strTooltip);
                    strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.WIL.Value + _objCharacter.WIL.AttributeValueModifiers + 1).ToString()).Replace("{1}", ((_objCharacter.WIL.Value + _objCharacter.WIL.AttributeValueModifiers + 1) * _objOptions.KarmaAttribute).ToString());
                    tipTooltip.SetToolTip(cmdImproveWIL, strTooltip);
                    strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.EDG.Value + _objCharacter.EDG.AttributeValueModifiers + 1).ToString()).Replace("{1}", ((_objCharacter.EDG.Value + _objCharacter.EDG.AttributeValueModifiers + 1) * _objOptions.KarmaAttribute).ToString());
                    tipTooltip.SetToolTip(cmdImproveEDG, strTooltip);
                    if (!_objOptions.SpecialKarmaCostBasedOnShownValue)
                    {
                        strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.MAG.Value + _objCharacter.MAG.AttributeValueModifiers + 1).ToString()).Replace("{1}", ((_objCharacter.MAG.Value + _objCharacter.MAG.AttributeValueModifiers + 1) * _objOptions.KarmaAttribute).ToString());
                        tipTooltip.SetToolTip(cmdImproveMAG, strTooltip);
                        strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.RES.Value + _objCharacter.RES.AttributeValueModifiers + 1).ToString()).Replace("{1}", ((_objCharacter.RES.Value + _objCharacter.RES.AttributeValueModifiers + 1) * _objOptions.KarmaAttribute).ToString());
                        tipTooltip.SetToolTip(cmdImproveRES, strTooltip);
                    }
                    else
                    {
                        strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.MAG.Value - _objCharacter.EssencePenalty + 1).ToString()).Replace("{1}", ((_objCharacter.MAG.Value + _objCharacter.EssencePenalty + 1) * _objOptions.KarmaAttribute).ToString());
                        tipTooltip.SetToolTip(cmdImproveMAG, strTooltip);
                        strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.RES.Value - _objCharacter.EssencePenalty + 1).ToString()).Replace("{1}", ((_objCharacter.RES.Value + _objCharacter.EssencePenalty + 1) * _objOptions.KarmaAttribute).ToString());
                        tipTooltip.SetToolTip(cmdImproveRES, strTooltip);
                    }
                }
                else
                {
                    strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.BOD.Value + _objCharacter.BOD.AttributeValueModifiers + 1).ToString()).Replace("{1}", ((_objCharacter.BOD.Value + _objCharacter.BOD.AttributeValueModifiers - _objCharacter.BOD.MetatypeMinimum + 2) * _objOptions.KarmaAttribute).ToString());
                    tipTooltip.SetToolTip(cmdImproveBOD, strTooltip);
                    strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.AGI.Value + _objCharacter.AGI.AttributeValueModifiers + 1).ToString()).Replace("{1}", ((_objCharacter.AGI.Value + _objCharacter.AGI.AttributeValueModifiers - _objCharacter.AGI.MetatypeMinimum + 2) * _objOptions.KarmaAttribute).ToString());
                    tipTooltip.SetToolTip(cmdImproveAGI, strTooltip);
                    strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.REA.Value + _objCharacter.REA.AttributeValueModifiers + 1).ToString()).Replace("{1}", ((_objCharacter.REA.Value + _objCharacter.REA.AttributeValueModifiers - _objCharacter.REA.MetatypeMinimum + 2) * _objOptions.KarmaAttribute).ToString());
                    tipTooltip.SetToolTip(cmdImproveREA, strTooltip);
                    strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.STR.Value + _objCharacter.STR.AttributeValueModifiers + 1).ToString()).Replace("{1}", ((_objCharacter.STR.Value + _objCharacter.STR.AttributeValueModifiers - _objCharacter.STR.MetatypeMinimum + 2) * _objOptions.KarmaAttribute).ToString());
                    tipTooltip.SetToolTip(cmdImproveSTR, strTooltip);
                    strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.CHA.Value + _objCharacter.CHA.AttributeValueModifiers + 1).ToString()).Replace("{1}", ((_objCharacter.CHA.Value + _objCharacter.CHA.AttributeValueModifiers - _objCharacter.CHA.MetatypeMinimum + 2) * _objOptions.KarmaAttribute).ToString());
                    tipTooltip.SetToolTip(cmdImproveCHA, strTooltip);
                    strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.INT.Value + _objCharacter.INT.AttributeValueModifiers + 1).ToString()).Replace("{1}", ((_objCharacter.INT.Value + _objCharacter.INT.AttributeValueModifiers - _objCharacter.INT.MetatypeMinimum + 2) * _objOptions.KarmaAttribute).ToString());
                    tipTooltip.SetToolTip(cmdImproveINT, strTooltip);
                    strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.LOG.Value + _objCharacter.LOG.AttributeValueModifiers + 1).ToString()).Replace("{1}", ((_objCharacter.LOG.Value + _objCharacter.LOG.AttributeValueModifiers - _objCharacter.LOG.MetatypeMinimum + 2) * _objOptions.KarmaAttribute).ToString());
                    tipTooltip.SetToolTip(cmdImproveLOG, strTooltip);
                    strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.WIL.Value + _objCharacter.WIL.AttributeValueModifiers + 1).ToString()).Replace("{1}", ((_objCharacter.WIL.Value + _objCharacter.WIL.AttributeValueModifiers - _objCharacter.WIL.MetatypeMinimum + 2) * _objOptions.KarmaAttribute).ToString());
                    tipTooltip.SetToolTip(cmdImproveWIL, strTooltip);
                    strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.EDG.Value + _objCharacter.EDG.AttributeValueModifiers + 1).ToString()).Replace("{1}", ((_objCharacter.EDG.Value + _objCharacter.EDG.AttributeValueModifiers - _objCharacter.EDG.MetatypeMinimum + 2) * _objOptions.KarmaAttribute).ToString());
                    tipTooltip.SetToolTip(cmdImproveEDG, strTooltip);
                    if (!_objOptions.SpecialKarmaCostBasedOnShownValue)
                    {
                        strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.MAG.Value + _objCharacter.MAG.AttributeValueModifiers + 1).ToString()).Replace("{1}", ((_objCharacter.MAG.Value + _objCharacter.MAG.AttributeValueModifiers + 1) * _objOptions.KarmaAttribute).ToString());
                        tipTooltip.SetToolTip(cmdImproveMAG, strTooltip);
                        strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.RES.Value + _objCharacter.RES.AttributeValueModifiers + 1).ToString()).Replace("{1}", ((_objCharacter.RES.Value + _objCharacter.RES.AttributeValueModifiers + 1) * _objOptions.KarmaAttribute).ToString());
                        tipTooltip.SetToolTip(cmdImproveRES, strTooltip);
                    }
                    else
                    {
                        strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.MAG.Value - _objCharacter.EssencePenalty + 1).ToString()).Replace("{1}", ((_objCharacter.MAG.Value - _objCharacter.EssencePenalty + 1) * _objOptions.KarmaAttribute).ToString());
                        tipTooltip.SetToolTip(cmdImproveMAG, strTooltip);
                        strTooltip = LanguageManager.Instance.GetString("Tip_ImproveItem").Replace("{0}", (_objCharacter.RES.Value - _objCharacter.EssencePenalty + 1).ToString()).Replace("{1}", ((_objCharacter.RES.Value - _objCharacter.EssencePenalty + 1) * _objOptions.KarmaAttribute).ToString());
                        tipTooltip.SetToolTip(cmdImproveRES, strTooltip);
                    }
                }

                // Disable any Attribute Karma buttons that have reached their Total Metatype Maximum.
                cmdImproveBOD.Enabled = !(_objCharacter.BOD.Value == _objCharacter.BOD.TotalMaximum);
                cmdImproveAGI.Enabled = !(_objCharacter.AGI.Value == _objCharacter.AGI.TotalMaximum);
                cmdImproveREA.Enabled = !(_objCharacter.REA.Value == _objCharacter.REA.TotalMaximum);
                cmdImproveSTR.Enabled = !(_objCharacter.STR.Value == _objCharacter.STR.TotalMaximum);
                cmdImproveCHA.Enabled = !(_objCharacter.CHA.Value == _objCharacter.CHA.TotalMaximum);
                cmdImproveINT.Enabled = !(_objCharacter.INT.Value == _objCharacter.INT.TotalMaximum);
                cmdImproveLOG.Enabled = !(_objCharacter.LOG.Value == _objCharacter.LOG.TotalMaximum);
                cmdImproveWIL.Enabled = !(_objCharacter.WIL.Value == _objCharacter.WIL.TotalMaximum);
                cmdImproveEDG.Enabled = !(_objCharacter.EDG.Value == _objCharacter.EDG.TotalMaximum);

                // Disable the Magic or Resonance Karma buttons if they have reached their current limits.
                if (_objCharacter.MAGEnabled)
                    cmdImproveMAG.Enabled = !(_objCharacter.MAG.Value - intEssenceLoss >= _objCharacter.MAG.TotalMaximum);
                else
                    cmdImproveMAG.Enabled = false;

                if (_objCharacter.RESEnabled)
                    cmdImproveRES.Enabled = !(_objCharacter.RES.Value - intEssenceLoss >= _objCharacter.RES.TotalMaximum);
                else
                    cmdImproveRES.Enabled = false;

                // Condition Monitor.
                double dblBOD = _objCharacter.BOD.TotalValue;
                double dblWIL = _objCharacter.WIL.TotalValue;
                int intCMPhysical = _objCharacter.PhysicalCM;
                int intCMStun = _objCharacter.StunCM;
                int intCMOverflow = _objCharacter.CMOverflow;

                // Update the Condition Monitor labels.
                lblCMPhysical.Text = intCMPhysical.ToString();
                lblCMStun.Text = intCMStun.ToString();
                string strCM = "8 + (BOD/2)(" + ((int)Math.Ceiling(dblBOD / 2)).ToString() + ")";
                if (_objImprovementManager.ValueOf(Improvement.ImprovementType.PhysicalCM) != 0)
                    strCM += " + " + LanguageManager.Instance.GetString("Tip_Modifiers") + " (" + _objImprovementManager.ValueOf(Improvement.ImprovementType.PhysicalCM).ToString() + ")";
                tipTooltip.SetToolTip(lblCMPhysical, strCM);
                strCM = "8 + (WIL/2)(" + ((int)Math.Ceiling(dblWIL / 2)).ToString() + ")";
                if (_objImprovementManager.ValueOf(Improvement.ImprovementType.StunCM) != 0)
                    strCM += " + " + LanguageManager.Instance.GetString("Tip_Modifiers") + " (" + _objImprovementManager.ValueOf(Improvement.ImprovementType.StunCM).ToString() + ")";
                tipTooltip.SetToolTip(lblCMStun, strCM);

                int intCMThreshold = _objCharacter.CMThreshold;
                int intPhysicalCMPenalty = 0;
                int intStunCMPenalty = 0;
                int intCMPenalty = 0;

                // Hide any unused Physical CM boxes.
                foreach (CheckBox objPhysicalCM in panPhysicalCM.Controls.OfType<CheckBox>())
                {
                    if (Convert.ToInt32(objPhysicalCM.Tag.ToString()) <= intCMPhysical + intCMOverflow)
                    {
                        if (Convert.ToInt32(objPhysicalCM.Tag.ToString()) <= _objCharacter.PhysicalCMFilled)
                            objPhysicalCM.Checked = true;

                        objPhysicalCM.Visible = true;

                        if (Convert.ToInt32(objPhysicalCM.Tag.ToString()) <= intCMPhysical)
                        {
                            // If this is within the Physical CM limits, act normally.
                            objPhysicalCM.BackColor = SystemColors.Control;
                            objPhysicalCM.UseVisualStyleBackColor = true;
                            if ((Convert.ToInt32(objPhysicalCM.Tag.ToString()) - _objImprovementManager.ValueOf(Improvement.ImprovementType.CMThresholdOffset)) % intCMThreshold == 0 && Convert.ToInt32(objPhysicalCM.Tag.ToString()) > _objImprovementManager.ValueOf(Improvement.ImprovementType.CMThresholdOffset))
                            {
                                int intModifiers = ((Convert.ToInt32(objPhysicalCM.Tag.ToString()) - _objImprovementManager.ValueOf(Improvement.ImprovementType.CMThresholdOffset)) / intCMThreshold) * -1;
                                objPhysicalCM.Text = intModifiers.ToString();
                                if (objPhysicalCM.Checked)
                                {
                                    if (intModifiers < intPhysicalCMPenalty)
                                        intPhysicalCMPenalty = intModifiers;
                                }
                            }
                            else
                                objPhysicalCM.Text = "";
                        }
                        else if (Convert.ToInt32(objPhysicalCM.Tag.ToString()) > intCMPhysical)
                        {
                            objPhysicalCM.BackColor = SystemColors.ControlDark;
                            if (Convert.ToInt32(objPhysicalCM.Tag.ToString()) == intCMPhysical + intCMOverflow)
                                objPhysicalCM.Text = "D";
                            else
                                objPhysicalCM.Text = "";
                        }
                    }
                    else
                    {
                        objPhysicalCM.Visible = false;
                        objPhysicalCM.Text = "";
                    }
                }

                // Hide any unused Stun CM boxes.
                foreach (CheckBox objStunCM in panStunCM.Controls.OfType<CheckBox>())
                {
                    if (Convert.ToInt32(objStunCM.Tag.ToString()) <= intCMStun)
                    {
                        if (Convert.ToInt32(objStunCM.Tag.ToString()) <= _objCharacter.StunCMFilled)
                            objStunCM.Checked = true;

                        objStunCM.Visible = true;
                        if ((Convert.ToInt32(objStunCM.Tag.ToString()) - _objImprovementManager.ValueOf(Improvement.ImprovementType.CMThresholdOffset)) % intCMThreshold == 0 && Convert.ToInt32(objStunCM.Tag.ToString()) > _objImprovementManager.ValueOf(Improvement.ImprovementType.CMThresholdOffset))
                        {
                            int intModifiers = ((Convert.ToInt32(objStunCM.Tag.ToString()) - _objImprovementManager.ValueOf(Improvement.ImprovementType.CMThresholdOffset)) / intCMThreshold) * -1;
                            objStunCM.Text = intModifiers.ToString();
                            if (objStunCM.Checked)
                            {
                                if (intModifiers < intStunCMPenalty)
                                    intStunCMPenalty = intModifiers;
                            }
                        }
                        else
                            objStunCM.Text = "";
                    }
                    else
                    {
                        objStunCM.Visible = false;
                        objStunCM.Text = "";
                    }
                }

                // Reduce the CM Penalties to 0 if the character has Improvements to ignore them.
                if (_objCharacter.HasImprovement(Improvement.ImprovementType.IgnoreCMPenaltyStun, true))
                    intStunCMPenalty = 0;
                if (_objCharacter.HasImprovement(Improvement.ImprovementType.IgnoreCMPenaltyPhysical, true))
                    intPhysicalCMPenalty = 0;

                intCMPenalty = intPhysicalCMPenalty + intStunCMPenalty;
                lblCMPenalty.Text = intCMPenalty.ToString();

                // Discard any old Condition Monitor penalties.
                _objImprovementManager.RemoveImprovements(Improvement.ImprovementSource.ConditionMonitor, "");

                // Create the new Condition Monitor penalties.
                if (intCMPenalty < 0)
                    _objImprovementManager.CreateImprovement("", Improvement.ImprovementSource.ConditionMonitor, "", Improvement.ImprovementType.ConditionMonitor, "", intCMPenalty);

                // Update the character's Skill information.
                foreach (SkillControl objSkillControl in panActiveSkills.Controls)
                {
                    objSkillControl.SkillRatingMaximum = objSkillControl.SkillObject.RatingMaximum;
                    objSkillControl.RefreshControl();
                }

                // Update the character's Knowledge Skill information.
                foreach (SkillControl objSkillControl in panKnowledgeSkills.Controls)
                {
                    objSkillControl.SkillRatingMaximum = objSkillControl.SkillObject.RatingMaximum;
                    objSkillControl.RefreshControl();
                }

                // Armor Ratings.
                lblArmor.Text = _objCharacter.TotalArmorRating.ToString();
                lblCMArmor.Text = lblArmor.Text;
                string strArmorToolTip = "";
                strArmorToolTip = LanguageManager.Instance.GetString("Tip_Armor") + " (" + _objCharacter.ArmorRating.ToString() + ")";
                if (_objCharacter.ArmorRating != _objCharacter.TotalArmorRating)
                    strArmorToolTip += " + " + LanguageManager.Instance.GetString("Tip_Modifiers") + " (" + (_objCharacter.TotalArmorRating - _objCharacter.ArmorRating).ToString() + ")";
                tipTooltip.SetToolTip(lblArmor, strArmorToolTip);

                // Remove any Improvements from Armor Encumbrance.
                _objImprovementManager.RemoveImprovements(Improvement.ImprovementSource.ArmorEncumbrance, "Armor Encumbrance");
                // Create the Armor Encumbrance Improvements.
                if (_objCharacter.ArmorEncumbrance < 0)
                {
                    _objImprovementManager.CreateImprovement("AGI", Improvement.ImprovementSource.ArmorEncumbrance, "Armor Encumbrance", Improvement.ImprovementType.Attribute, "", 0, 1, 0, 0, _objCharacter.ArmorEncumbrance);
                    _objImprovementManager.CreateImprovement("REA", Improvement.ImprovementSource.ArmorEncumbrance, "Armor Encumbrance", Improvement.ImprovementType.Attribute, "", 0, 1, 0, 0, _objCharacter.ArmorEncumbrance);
                }

                // Update the Attribute information.
                // Attribute: Body.
                lblBODMetatype.Text = string.Format("{0} / {1} ({2})", _objCharacter.BOD.TotalMinimum, _objCharacter.BOD.TotalMaximum, _objCharacter.BOD.TotalAugmentedMaximum);
                if (_objCharacter.BOD.HasModifiers)
                {
                    lblBODAug.Text = string.Format("({0})", _objCharacter.BOD.TotalValue);
                    tipTooltip.SetToolTip(lblBODAug, _objCharacter.BOD.ToolTip());
                }
                else
                {
                    lblBODAug.Text = "";
                    tipTooltip.SetToolTip(lblBODAug, "");
                }

                // Attribute: Agility.
                lblAGIMetatype.Text = string.Format("{0} / {1} ({2})", _objCharacter.AGI.TotalMinimum, _objCharacter.AGI.TotalMaximum, _objCharacter.AGI.TotalAugmentedMaximum);
                if (_objCharacter.AGI.HasModifiers)
                {
                    lblAGIAug.Text = string.Format("({0})", _objCharacter.AGI.TotalValue);
                    tipTooltip.SetToolTip(lblAGIAug, _objCharacter.AGI.ToolTip());
                }
                else
                {
                    lblAGIAug.Text = "";
                    tipTooltip.SetToolTip(lblAGIAug, "");
                }

                // Attribute: Reaction.
                lblREAMetatype.Text = string.Format("{0} / {1} ({2})", _objCharacter.REA.TotalMinimum, _objCharacter.REA.TotalMaximum, _objCharacter.REA.TotalAugmentedMaximum);
                if (_objCharacter.REA.HasModifiers)
                {
                    lblREAAug.Text = string.Format("({0})", _objCharacter.REA.TotalValue);
                    tipTooltip.SetToolTip(lblREAAug, _objCharacter.REA.ToolTip());
                }
                else
                {
                    lblREAAug.Text = "";
                    tipTooltip.SetToolTip(lblREAAug, "");
                }

                // Attribute: Strength.
                lblSTRMetatype.Text = string.Format("{0} / {1} ({2})", _objCharacter.STR.TotalMinimum, _objCharacter.STR.TotalMaximum, _objCharacter.STR.TotalAugmentedMaximum);
                if (_objCharacter.STR.HasModifiers)
                {
                    lblSTRAug.Text = string.Format("({0})", _objCharacter.STR.TotalValue);
                    tipTooltip.SetToolTip(lblSTRAug, _objCharacter.STR.ToolTip());
                }
                else
                {
                    lblSTRAug.Text = "";
                    tipTooltip.SetToolTip(lblSTRAug, "");
                }

                // Attribute: Charisma.
                lblCHAMetatype.Text = string.Format("{0} / {1} ({2})", _objCharacter.CHA.TotalMinimum, _objCharacter.CHA.TotalMaximum, _objCharacter.CHA.TotalAugmentedMaximum);
                if (_objCharacter.CHA.HasModifiers)
                {
                    lblCHAAug.Text = string.Format("({0})", _objCharacter.CHA.TotalValue);
                    tipTooltip.SetToolTip(lblCHAAug, _objCharacter.CHA.ToolTip());
                }
                else
                {
                    lblCHAAug.Text = "";
                    tipTooltip.SetToolTip(lblCHAAug, "");
                }

                // Attribute: Intuition.
                lblINTMetatype.Text = string.Format("{0} / {1} ({2})", _objCharacter.INT.TotalMinimum, _objCharacter.INT.TotalMaximum, _objCharacter.INT.TotalAugmentedMaximum);
                if (_objCharacter.INT.HasModifiers)
                {
                    lblINTAug.Text = string.Format("({0})", _objCharacter.INT.TotalValue);
                    tipTooltip.SetToolTip(lblINTAug, _objCharacter.INT.ToolTip());
                }
                else
                {
                    lblINTAug.Text = "";
                    tipTooltip.SetToolTip(lblINTAug, "");
                }

                // Attribute: Logic.
                lblLOGMetatype.Text = string.Format("{0} / {1} ({2})", _objCharacter.LOG.TotalMinimum, _objCharacter.LOG.TotalMaximum, _objCharacter.LOG.TotalAugmentedMaximum);
                if (_objCharacter.LOG.HasModifiers)
                {
                    lblLOGAug.Text = string.Format("({0})", _objCharacter.LOG.TotalValue);
                    tipTooltip.SetToolTip(lblLOGAug, _objCharacter.LOG.ToolTip());
                }
                else
                {
                    lblLOGAug.Text = "";
                    tipTooltip.SetToolTip(lblLOGAug, "");
                }

                // Attribute: Willpower.
                lblWILMetatype.Text = string.Format("{0} / {1} ({2})", _objCharacter.WIL.TotalMinimum, _objCharacter.WIL.TotalMaximum, _objCharacter.WIL.TotalAugmentedMaximum);
                if (_objCharacter.WIL.HasModifiers)
                {
                    lblWILAug.Text = string.Format("({0})", _objCharacter.WIL.TotalValue);
                    tipTooltip.SetToolTip(lblWILAug, _objCharacter.WIL.ToolTip());
                }
                else
                {
                    lblWILAug.Text = "";
                    tipTooltip.SetToolTip(lblWILAug, "");
                }

                // Attribute: Edge.
                lblEDGMetatype.Text = string.Format("{0} / {1} ({2})", _objCharacter.EDG.TotalMinimum, _objCharacter.EDG.TotalMaximum, _objCharacter.EDG.TotalAugmentedMaximum);
                if (_objCharacter.EDG.HasModifiers)
                {
                    lblEDGAug.Text = string.Format("({0})", _objCharacter.EDG.TotalValue);
                    tipTooltip.SetToolTip(lblEDGAug, _objCharacter.EDG.ToolTip());
                }
                else
                {
                    lblEDGAug.Text = "";
                    tipTooltip.SetToolTip(lblEDGAug, "");
                }

                // Attribute: Magic.
                lblMAGMetatype.Text = string.Format("{0} / {1} ({2})", _objCharacter.MAG.TotalMinimum, _objCharacter.MAG.TotalMaximum, _objCharacter.MAG.TotalAugmentedMaximum);
                if (_objCharacter.MAG.HasModifiers)
                {
                    lblMAGAug.Text = string.Format("({0})", _objCharacter.MAG.TotalValue);
                    tipTooltip.SetToolTip(lblMAGAug, _objCharacter.MAG.ToolTip());
                }
                else
                {
                    lblMAGAug.Text = "";
                    tipTooltip.SetToolTip(lblMAGAug, "");
                }

                // Attribute: Resonance.
                lblRESMetatype.Text = string.Format("{0} / {1} ({2})", _objCharacter.RES.TotalMinimum, _objCharacter.RES.TotalMaximum, _objCharacter.RES.TotalAugmentedMaximum);
                if (_objCharacter.RES.HasModifiers)
                {
                    lblRESAug.Text = string.Format("({0})", _objCharacter.RES.TotalValue);
                    tipTooltip.SetToolTip(lblRESAug, _objCharacter.RES.ToolTip());
                }
                else
                {
                    lblRESAug.Text = "";
                    tipTooltip.SetToolTip(lblRESAug, "");
                }

                // Update the MAG pseudo-Attributes if applicable.
                int intCharacterMAG = _objCharacter.MAG.TotalValue;
                if (_objCharacter.AdeptEnabled && _objCharacter.MagicianEnabled)
                {
                    lblMysticAdeptMAGAdept.Text = _objCharacter.MAGAdept.ToString();
                    intCharacterMAG = _objCharacter.MAGMagician;
                }

                // Update the maximum Force for all Spirits.
                foreach (SpiritControl objSpiritControl in panSpirits.Controls)
                {
                    if (_objOptions.SpiritForceBasedOnTotalMAG)
                        objSpiritControl.ForceMaximum = _objCharacter.MAG.TotalValue * 2;
                    else
                    {
                        int intLocalMAG = intCharacterMAG;
                        if (intLocalMAG == 0)
                            intLocalMAG = 1;

                        objSpiritControl.ForceMaximum = intLocalMAG * 2;
                    }
                    objSpiritControl.RebuildSpiritList(_objCharacter.MagicTradition);
                }

                // Update Adept Powers.
                int intMAG = _objCharacter.MAG.TotalValue;
                foreach (PowerControl objPowerControl in panPowers.Controls)
                {
                    // Maximum Power Level for Mystic Adepts is based on their total MAG.
                    objPowerControl.RefreshMaximum(_objCharacter.MAG.TotalValue);
                    objPowerControl.RefreshTooltip();
                }

                // Update the Drain Attribute Value.
                if (_objCharacter.MAGEnabled && lblDrainAttributes.Text != "")
                {
                    try
                    {
                        XmlDocument objXmlDocument = new XmlDocument();
                        XPathNavigator nav = objXmlDocument.CreateNavigator();
                        string strDrain = lblDrainAttributes.Text.Replace(LanguageManager.Instance.GetString("String_AttributeBODShort"), _objCharacter.BOD.TotalValue.ToString());
                        strDrain = strDrain.Replace(LanguageManager.Instance.GetString("String_AttributeAGIShort"), _objCharacter.AGI.TotalValue.ToString());
                        strDrain = strDrain.Replace(LanguageManager.Instance.GetString("String_AttributeREAShort"), _objCharacter.REA.TotalValue.ToString());
                        strDrain = strDrain.Replace(LanguageManager.Instance.GetString("String_AttributeSTRShort"), _objCharacter.STR.TotalValue.ToString());
                        strDrain = strDrain.Replace(LanguageManager.Instance.GetString("String_AttributeCHAShort"), _objCharacter.CHA.TotalValue.ToString());
                        strDrain = strDrain.Replace(LanguageManager.Instance.GetString("String_AttributeINTShort"), _objCharacter.INT.TotalValue.ToString());
                        strDrain = strDrain.Replace(LanguageManager.Instance.GetString("String_AttributeLOGShort"), _objCharacter.LOG.TotalValue.ToString());
                        strDrain = strDrain.Replace(LanguageManager.Instance.GetString("String_AttributeWILShort"), _objCharacter.WIL.TotalValue.ToString());
                        strDrain = strDrain.Replace(LanguageManager.Instance.GetString("String_AttributeMAGShort"), _objCharacter.MAG.TotalValue.ToString());
                        XPathExpression xprDrain = nav.Compile(strDrain);
                        int intDrain = Convert.ToInt32(nav.Evaluate(xprDrain).ToString());
                        intDrain += _objImprovementManager.ValueOf(Improvement.ImprovementType.DrainResistance);
                        lblDrainAttributesValue.Text = intDrain.ToString();
                    }
                    catch
                    {
                    }
                }

                // Update the maximum Force for all Sprites.
                foreach (SpiritControl objSpiritControl in panSprites.Controls)
                {
                    objSpiritControl.ForceMaximum = _objCharacter.RES.TotalValue * 2;
                    objSpiritControl.RebuildSpiritList(_objCharacter.TechnomancerStream);
                }

                // Update the Fading Attribute Value.
                if (_objCharacter.RESEnabled && lblFadingAttributes.Text != "")
                {
                    try
                    {
                        XmlDocument objXmlDocument = new XmlDocument();
                        XPathNavigator nav = objXmlDocument.CreateNavigator();
                        string strFading = lblFadingAttributes.Text.Replace(LanguageManager.Instance.GetString("String_AttributeBODShort"), _objCharacter.BOD.TotalValue.ToString());
                        strFading = strFading.Replace(LanguageManager.Instance.GetString("String_AttributeAGIShort"), _objCharacter.AGI.TotalValue.ToString());
                        strFading = strFading.Replace(LanguageManager.Instance.GetString("String_AttributeREAShort"), _objCharacter.REA.TotalValue.ToString());
                        strFading = strFading.Replace(LanguageManager.Instance.GetString("String_AttributeSTRShort"), _objCharacter.STR.TotalValue.ToString());
                        strFading = strFading.Replace(LanguageManager.Instance.GetString("String_AttributeCHAShort"), _objCharacter.CHA.TotalValue.ToString());
                        strFading = strFading.Replace(LanguageManager.Instance.GetString("String_AttributeINTShort"), _objCharacter.INT.TotalValue.ToString());
                        strFading = strFading.Replace(LanguageManager.Instance.GetString("String_AttributeLOGShort"), _objCharacter.LOG.TotalValue.ToString());
                        strFading = strFading.Replace(LanguageManager.Instance.GetString("String_AttributeWILShort"), _objCharacter.WIL.TotalValue.ToString());
                        strFading = strFading.Replace(LanguageManager.Instance.GetString("String_AttributeRESShort"), _objCharacter.RES.TotalValue.ToString());
                        XPathExpression xprFading = nav.Compile(strFading);
                        int intFading = Convert.ToInt32(nav.Evaluate(xprFading).ToString());
                        intFading += _objImprovementManager.ValueOf(Improvement.ImprovementType.FadingResistance);
                        lblFadingAttributesValue.Text = intFading.ToString();

                        strTip = lblFadingAttributes.Text.Replace(LanguageManager.Instance.GetString("String_AttributeBODShort"), LanguageManager.Instance.GetString("String_AttributeBODShort") + " (" + _objCharacter.BOD.TotalValue.ToString() + ")");
                        strTip = strTip.Replace(LanguageManager.Instance.GetString("String_AttributeAGIShort"), LanguageManager.Instance.GetString("String_AttributeAGIShort") + " (" + _objCharacter.AGI.TotalValue.ToString() + ")");
                        strTip = strTip.Replace(LanguageManager.Instance.GetString("String_AttributeREAShort"), LanguageManager.Instance.GetString("String_AttributeREAShort") + " (" + _objCharacter.REA.TotalValue.ToString() + ")");
                        strTip = strTip.Replace(LanguageManager.Instance.GetString("String_AttributeSTRShort"), LanguageManager.Instance.GetString("String_AttributeSTRShort") + " (" + _objCharacter.STR.TotalValue.ToString() + ")");
                        strTip = strTip.Replace(LanguageManager.Instance.GetString("String_AttributeCHAShort"), LanguageManager.Instance.GetString("String_AttributeCHAShort") + " (" + _objCharacter.CHA.TotalValue.ToString() + ")");
                        strTip = strTip.Replace(LanguageManager.Instance.GetString("String_AttributeINTShort"), LanguageManager.Instance.GetString("String_AttributeINTShort") + " (" + _objCharacter.INT.TotalValue.ToString() + ")");
                        strTip = strTip.Replace(LanguageManager.Instance.GetString("String_AttributeLOGShort"), LanguageManager.Instance.GetString("String_AttributeLOGShort") + " (" + _objCharacter.LOG.TotalValue.ToString() + ")");
                        strTip = strTip.Replace(LanguageManager.Instance.GetString("String_AttributeWILShort"), LanguageManager.Instance.GetString("String_AttributeWILShort") + " (" + _objCharacter.WIL.TotalValue.ToString() + ")");
                        strTip = strTip.Replace(LanguageManager.Instance.GetString("String_AttributeRESShort"), LanguageManager.Instance.GetString("String_AttributeRESShort") + " (" + _objCharacter.RES.TotalValue.ToString() + ")");
                        tipTooltip.SetToolTip(lblFadingAttributesValue, strTip);
                    }
                    catch
                    {
                    }
                }

                // Update Living Persona values.
                if (_objCharacter.RESEnabled)
                {
                    string strPersonaTip = "";
                    int intFirewall = _objCharacter.WIL.TotalValue + _objImprovementManager.ValueOf(Improvement.ImprovementType.LivingPersonaFirewall);
                    int intResponse = _objCharacter.INT.TotalValue + _objImprovementManager.ValueOf(Improvement.ImprovementType.LivingPersonaResponse);
                    int intSignal = Convert.ToInt32(Math.Ceiling((Convert.ToDecimal(_objCharacter.RES.TotalValue, GlobalOptions.Instance.CultureInfo) / 2))) + _objImprovementManager.ValueOf(Improvement.ImprovementType.LivingPersonaSignal);
                    int intSystem = _objCharacter.LOG.TotalValue + _objImprovementManager.ValueOf(Improvement.ImprovementType.LivingPersonaSystem);
                    int intBiofeedback = _objCharacter.CHA.TotalValue + _objImprovementManager.ValueOf(Improvement.ImprovementType.LivingPersonaBiofeedback);

                    // If this is a Technocritter, their Matrix Attributes always equal their RES.
                    if (_objCharacter.MetatypeCategory == "Technocritters")
                    {
                        intFirewall = _objCharacter.RES.TotalValue;
                        intSystem = _objCharacter.RES.TotalValue;
                        intResponse = _objCharacter.RES.TotalValue;
                        intSignal = _objCharacter.RES.TotalValue;
                        intBiofeedback = _objCharacter.RES.TotalValue;
                    }

                    // Make sure none of the Attributes exceed the Technomancer's RES.
                    intFirewall = Math.Min(intFirewall, _objCharacter.RES.TotalValue);
                    intResponse = Math.Min(intResponse, _objCharacter.RES.TotalValue);
                    intSignal = Math.Min(intSignal, _objCharacter.RES.TotalValue);
                    intSystem = Math.Min(intSystem, _objCharacter.RES.TotalValue);

                    lblLivingPersonaDeviceRating.Text = _objCharacter.RES.TotalValue.ToString();
                    strPersonaTip = "RES (" + _objCharacter.RES.TotalValue.ToString() + ")";
                    tipTooltip.SetToolTip(lblLivingPersonaDeviceRating, strPersonaTip);

                    lblLivingPersonaAttack.Text = _objCharacter.CHA.TotalValue.ToString();
                    strPersonaTip = "CHA (" + _objCharacter.CHA.TotalValue.ToString() + ")";
                    tipTooltip.SetToolTip(lblLivingPersonaAttack, strPersonaTip);

                    lblLivingPersonaSleaze.Text = _objCharacter.INT.TotalValue.ToString();
                    strPersonaTip = "INT (" + _objCharacter.INT.TotalValue.ToString() + ")";
                    tipTooltip.SetToolTip(lblLivingPersonaSleaze, strPersonaTip);

                    lblLivingPersonaDataProcessing.Text = _objCharacter.LOG.TotalValue.ToString();
                    strPersonaTip = "LOG (" + _objCharacter.LOG.TotalValue.ToString() + ")";
                    tipTooltip.SetToolTip(lblLivingPersonaDataProcessing, strPersonaTip);

                    lblLivingPersonaFirewall.Text = _objCharacter.WIL.TotalValue.ToString();
                    strPersonaTip = "WIL (" + _objCharacter.WIL.TotalValue.ToString() + ")";
                    tipTooltip.SetToolTip(lblLivingPersonaFirewall, strPersonaTip);
                }

                // Skill Limits
                lblPhysical.Text = _objCharacter.LimitPhysical.ToString();
                string strPhysical = "(STR [" + _objCharacter.STR.TotalValue.ToString() + "] * 2) + BOD [" + _objCharacter.BOD.TotalValue.ToString() + "] + REA [" + _objCharacter.REA.TotalValue.ToString() + "] / 3";
                tipTooltip.SetToolTip(lblPhysical, strPhysical);

                lblMental.Text = _objCharacter.LimitMental.ToString();
                string strMental = "(LOG [" + _objCharacter.LOG.TotalValue.ToString() + "] * 2) + INT [" + _objCharacter.INT.TotalValue.ToString() + "] + WIL [" + _objCharacter.WIL.TotalValue.ToString() + "] / 3";
                tipTooltip.SetToolTip(lblMental, strMental);

                lblSocial.Text = _objCharacter.LimitSocial.ToString();
                string strSocial = "(CHA [" + _objCharacter.CHA.TotalValue.ToString() + "] * 2) + WIL [" + _objCharacter.WIL.TotalValue.ToString() + "] + ESS [" + _objCharacter.Essence.ToString() + "] / 3";
                tipTooltip.SetToolTip(lblSocial, strSocial);

                lblAstral.Text = _objCharacter.LimitAstral.ToString();

                // Initiative.
                lblINI.Text = _objCharacter.Initiative;
                string strInit = "REA (" + _objCharacter.REA.Value.ToString() + ") + INT (" + _objCharacter.INT.Value.ToString() + ")";
                if (_objCharacter.INI.AttributeModifiers > 0 || _objImprovementManager.ValueOf(Improvement.ImprovementType.Initiative) > 0 || _objCharacter.INT.AttributeModifiers > 0 || _objCharacter.REA.AttributeModifiers > 0)
                    strInit += " + " + LanguageManager.Instance.GetString("Tip_Modifiers") + " (" + (_objCharacter.INI.AttributeModifiers + _objImprovementManager.ValueOf(Improvement.ImprovementType.Initiative) + _objCharacter.INT.AttributeModifiers + _objCharacter.REA.AttributeModifiers).ToString() + ")";
                strInit += " + (" + _objCharacter.InitiativePasses.ToString() + "d6)";
                tipTooltip.SetToolTip(lblINI, strInit);

                // Astral Initiative.
                if (_objCharacter.MAGEnabled)
                {
                    lblAstralINI.Text = _objCharacter.AstralInitiative;
                    strInit = "INT (" + _objCharacter.INT.TotalValue.ToString() + ") x 2";
                    if (_objCharacter.INT.AttributeModifiers > 0)
                        strInit += " + " + LanguageManager.Instance.GetString("Tip_Modifiers") + " (" + (_objCharacter.INT.AttributeModifiers).ToString() + ")";
                    strInit += " + 2d6";
                    tipTooltip.SetToolTip(lblAstralINI, strInit);
                }

                // Matrix Initiative (AR).
                lblMatrixINI.Text = _objCharacter.MatrixInitiative;
                strInit = "REA (" + _objCharacter.REA.Value.ToString() + ") + INT (" + _objCharacter.INT.Value.ToString() + ")";
                if (_objCharacter.INT.AttributeModifiers > 0 || _objCharacter.REA.AttributeModifiers > 0)
                    strInit += " + " + LanguageManager.Instance.GetString("Tip_Modifiers") + " (" + (_objCharacter.REA.AttributeModifiers + _objCharacter.INT.AttributeModifiers).ToString() + ")";
                strInit += " + 1d6";
                tipTooltip.SetToolTip(lblMatrixINI, strInit);

                // Matrix Initiative (Cold).
                lblMatrixINICold.Text = _objCharacter.MatrixInitiativeCold;
                strInit = "Data Processing + INT (" + _objCharacter.INT.TotalValue.ToString() + ")";
                if (_objCharacter.INT.AttributeModifiers > 0)
                    strInit += " + " + LanguageManager.Instance.GetString("Tip_Modifiers") + " (" + (_objCharacter.INT.AttributeModifiers).ToString() + ")";
                strInit += " + 3d6";
                tipTooltip.SetToolTip(lblMatrixINICold, strInit);

                // Matrix Initiative (Hot).
                lblMatrixINIHot.Text = _objCharacter.MatrixInitiativeHot;
                strInit = "Data Processing + INT (" + _objCharacter.INT.TotalValue.ToString() + ")";
                if (_objCharacter.INT.AttributeModifiers > 0)
                    strInit += " + " + LanguageManager.Instance.GetString("Tip_Modifiers") + " (" + (_objCharacter.INT.AttributeModifiers).ToString() + ")";
                strInit += " + 4d6";
                tipTooltip.SetToolTip(lblMatrixINIHot, strInit);

                // Rigger Initiative.
                lblRiggingINI.Text = _objCharacter.RiggerInitiative;
                strInit = "REA (" + _objCharacter.REA.Value.ToString() + ") + INT (" + _objCharacter.INT.Value.ToString() + ")";
                if (_objCharacter.INT.AttributeModifiers > 0 || _objCharacter.REA.AttributeModifiers > 0)
                    strInit += " + " + LanguageManager.Instance.GetString("Tip_Modifiers") + " (" + (_objCharacter.REA.AttributeModifiers + _objCharacter.INT.AttributeModifiers).ToString() + ")";
                strInit += " + 1d6";
                tipTooltip.SetToolTip(lblRiggingINI, strInit);

                if (_objCharacter.AdeptEnabled)
                    CalculatePowerPoints();
                if ((_objCharacter.Metatype == "Free Spirit" && !_objCharacter.IsCritter) || _objCharacter.MetatypeCategory.EndsWith("Spirits"))
                {
                    lblCritterPowerPointsLabel.Visible = true;
                    lblCritterPowerPoints.Visible = true;
                    lblCritterPowerPoints.Text = _objController.CalculateFreeSpiritPowerPoints();
                }
                if (_objCharacter.IsFreeSprite)
                {
                    lblCritterPowerPointsLabel.Visible = true;
                    lblCritterPowerPoints.Visible = true;
                    lblCritterPowerPoints.Text = _objController.CalculateFreeSpritePowerPoints();
                }

                // Update the Nuyen and Karma for the character.
                tssNuyen.Text = String.Format("{0:###,###,##0Â¥}", _objCharacter.Nuyen);
                lblRemainingNuyen.Text = String.Format("{0:###,###,##0Â¥}", _objCharacter.Nuyen);
                tssKarma.Text = _objCharacter.Karma.ToString();

                PopulateExpenseList();

                // Movement.
                lblMovement.Text = _objCharacter.Movement;
                lblSwim.Text = _objCharacter.Swim;
                lblFly.Text = _objCharacter.Fly;

                // Special Attribute-Only Test.
                lblComposure.Text = _objCharacter.Composure.ToString();
                strTip = "WIL (" + _objCharacter.WIL.TotalValue.ToString() + ") + CHA (" + _objCharacter.CHA.TotalValue.ToString() + ")";
                tipTooltip.SetToolTip(lblComposure, strTip);
                lblJudgeIntentions.Text = _objCharacter.JudgeIntentions.ToString();
                strTip = "INT (" + _objCharacter.INT.TotalValue.ToString() + ") + CHA (" + _objCharacter.CHA.TotalValue.ToString() + ")";
                if (_objImprovementManager.ValueOf(Improvement.ImprovementType.JudgeIntentions) != 0)
                    strTip += " + " + LanguageManager.Instance.GetString("Tip_Modifiers") + " (" + _objImprovementManager.ValueOf(Improvement.ImprovementType.JudgeIntentions).ToString() + ")";
                tipTooltip.SetToolTip(lblJudgeIntentions, strTip);
                lblLiftCarry.Text = _objCharacter.LiftAndCarry.ToString();
                strTip = "STR (" + _objCharacter.STR.TotalValue.ToString() + ") + BOD (" + _objCharacter.BOD.TotalValue.ToString() + ")";
                if (_objImprovementManager.ValueOf(Improvement.ImprovementType.LiftAndCarry) != 0)
                    strTip += " + " + LanguageManager.Instance.GetString("Tip_Modifiers") + " (" + _objImprovementManager.ValueOf(Improvement.ImprovementType.LiftAndCarry).ToString() + ")";
                strTip += "\n" + LanguageManager.Instance.GetString("Tip_LiftAndCarry").Replace("{0}", (_objCharacter.STR.TotalValue * 15).ToString()).Replace("{1}", (_objCharacter.STR.TotalValue * 10).ToString());
                tipTooltip.SetToolTip(lblLiftCarry, strTip);
                lblMemory.Text = _objCharacter.Memory.ToString();
                strTip = "LOG (" + _objCharacter.LOG.TotalValue.ToString() + ") + WIL (" + _objCharacter.WIL.TotalValue.ToString() + ")";
                if (_objImprovementManager.ValueOf(Improvement.ImprovementType.Memory) != 0)
                    strTip += " + " + LanguageManager.Instance.GetString("Tip_Modifiers") + " (" + _objImprovementManager.ValueOf(Improvement.ImprovementType.Memory).ToString() + ")";
                tipTooltip.SetToolTip(lblMemory, strTip);

                // Career Karma.
                lblCareerKarma.Text = String.Format("{0:###,###,##0}", _objCharacter.CareerKarma);

                // Career Nuyen.
                lblCareerNuyen.Text = String.Format("{0:###,###,##0Â¥}", _objCharacter.CareerNuyen);

                // Update A.I. Attributes.
                if (_objCharacter.Metatype.EndsWith("A.I.") || _objCharacter.MetatypeCategory == "Technocritters" || _objCharacter.MetatypeCategory == "Protosapients")
                {
                    lblRating.Text = _objCharacter.Rating.ToString();
                    lblSystem.Text = _objCharacter.System.ToString();
                    lblFirewall.Text = _objCharacter.Firewall.ToString();
                }

                // Update Damage Resistance Pool.
                lblCMDamageResistancePool.Text = (_objCharacter.BOD.TotalValue + _objImprovementManager.ValueOf(Improvement.ImprovementType.DamageResistance)).ToString();

                // Update EDG Remaining Info on the Condition Monitor tab.
                string strEDG = _objCharacter.EDG.TotalValue.ToString() + " " + LanguageManager.Instance.GetString("String_Of") + " " + _objCharacter.EDG.Value.ToString() + " " + LanguageManager.Instance.GetString("String_Remaining");
                lblEDGInfo.Text = strEDG;

                foreach (SkillControl objSkillControl in panActiveSkills.Controls.OfType<SkillControl>())
                    objSkillControl.RefreshControl();

                foreach (SkillControl objSkillControl in panKnowledgeSkills.Controls.OfType<SkillControl>())
                    objSkillControl.RefreshControl();

                _blnSkipUpdate = false;

                _objImprovementManager.Commit();

                // If the Viewer window is open for this character, call its RefreshView method which updates it asynchronously
                if (_objCharacter.PrintWindow != null)
                    _objCharacter.PrintWindow.RefreshView();

                cmdQuickenSpell.Visible = _objCharacter.HasImprovement(Improvement.ImprovementType.QuickeningMetamagic, true);
            }
            RefreshLimitModifiers();
            RefreshImprovements();
            UpdateReputation();
        }
Example #6
0
        /// <summary>
        /// Buid the list of Skills.
        /// </summary>
        private void BuildSkillList()
        {
            // Load the Skills information.
            XmlDocument objXmlDocument = XmlManager.Instance.Load("skills.xml");

            // Populate the Skills list.
            XmlNodeList objXmlSkillList = objXmlDocument.SelectNodes("/chummer/skills/skill[not(exotic) and (" + Options.BookXPath() + ")]");

            // First pass, build up a list of all of the Skills so we can sort them in alphabetical order for the current language.
            List<ListItem> lstSkillOrder = new List<ListItem>();
            foreach (XmlNode objXmlSkill in objXmlSkillList)
            {
                ListItem objSkill = new ListItem();
                objSkill.Value = objXmlSkill["name"].InnerText;
                if (objXmlSkill["translate"] != null)
                    objSkill.Name = objXmlSkill["translate"].InnerText;
                else
                    objSkill.Name = objXmlSkill["name"].InnerText;
                lstSkillOrder.Add(objSkill);
            }
            SortListItem objSort = new SortListItem();
            lstSkillOrder.Sort(objSort.Compare);

            // Second pass, retrieve the Skills in the order they're presented in the list.
            foreach (ListItem objItem in lstSkillOrder)
            {
                XmlNode objXmlSkill = objXmlDocument.SelectSingleNode("/chummer/skills/skill[name = \"" + objItem.Value + "\"]");
                Skill objSkill = new Skill(this);
                objSkill.Name = objXmlSkill["name"].InnerText;
                objSkill.Id = Guid.Parse(objXmlSkill["id"].InnerText);
                objSkill.SkillCategory = objXmlSkill["category"].InnerText;
                objSkill.SkillGroup = objXmlSkill["skillgroup"].InnerText;
                objSkill.Attribute = objXmlSkill["attribute"].InnerText;
                if (objXmlSkill["default"].InnerText.ToLower() == "yes")
                    objSkill.Default = true;
                else
                    objSkill.Default = false;
                if (objXmlSkill["source"] != null)
                    objSkill.Source = objXmlSkill["source"].InnerText;
                if (objXmlSkill["page"] != null)
                    objSkill.Page = objXmlSkill["page"].InnerText;
                _lstSkills.Add(objSkill);
            }
        }
Example #7
0
        private void cmdAddKnowledgeSkill_Click(object sender, EventArgs e)
        {
            int i = panKnowledgeSkills.Controls.Count;
            Skill objSkill = new Skill(_objCharacter);
            objSkill.Attribute = "LOG";
            objSkill.SkillCategory = "Academic";
            if (_objCharacter.MaxSkillRating > 0)
                objSkill.RatingMaximum = _objCharacter.MaxSkillRating;

            SkillControl objSkillControl = new SkillControl(_objCharacter);
            objSkillControl.SkillObject = objSkill;


            // Attach an EventHandler for the RatingChanged and SpecializationChanged Events.
            objSkillControl.RatingChanged += objKnowledgeSkill_RatingChanged;
            objSkillControl.SpecializationChanged += objSkill_SpecializationChanged;
            objSkillControl.DeleteSkill += objKnowledgeSkill_DeleteSkill;
            objSkillControl.BuyWithKarmaChanged += objKnowledgeSkill_BuyWithKarmaChanged;
			objSkillControl.MergeClicked += knoSkill_MergeClick;
            objSkillControl.KnowledgeSkill = true;
            objSkillControl.AllowDelete = true;
			if (_objCharacter.IgnoreRules)
			{
				objSkillControl.SkillRatingMaximum = 12;
			}
			else
			{
				objSkillControl.SkillRatingMaximum = 6;
			}
			// Set the SkillControl's Location since scrolling the Panel causes it to actually change the child Controls' Locations.
			objSkillControl.Location = new Point(0, objSkillControl.Height * i + panKnowledgeSkills.AutoScrollPosition.Y);
            panKnowledgeSkills.Controls.Add(objSkillControl);

            _objCharacter.Skills.Add(objSkill);

            _blnIsDirty = true;
            UpdateWindowTitle();
        }
Example #8
0
        public void SkillTest()
        {
            // Create a new character with a BOD of 4.
            Character objCharacter = new Character();
            objCharacter.BOD.Value = 4;

            // Create a new Skill.
            Skill objSkill = new Skill(objCharacter);
            objSkill.Name = "Diving";
            objSkill.Attribute = "BOD";
            objSkill.SkillCategory = "Physical Active";
            objSkill.Default = true;
            objSkill.RatingMaximum = 12;
            objSkill.Rating = 3;
            objSkill.Source = "Test";
            objSkill.Page = "123";

            // Make sure the Skill's properties are valid.
            Assert.AreEqual("Diving", objSkill.Name, "Skill name mismatch.");
            Assert.AreEqual(3, objSkill.Rating, "Skill Rating mismatch.");
            Assert.AreEqual("BOD", objSkill.Attribute, "Skill Attribute mismatch.");
            Assert.AreEqual("Physical Active", objSkill.SkillCategory, "Skill Category mismatch.");
            Assert.AreEqual("Test", objSkill.Source, "Skill Source mistmatch.");
            Assert.AreEqual("123", objSkill.Page, "Skill Page mismatch.");
            Assert.AreEqual(4, objSkill.AttributeModifiers, "Skill's Attribute value does not match actual Attribute value.");
            Assert.AreEqual(7, objSkill.TotalRating, "Skill Rating does not equal the expected value of 7.");
        }
Example #9
0
        void TestMetatype(string strFile)
        {
            XmlDocument objXmlDocument = XmlManager.Instance.Load(strFile);

            pgbProgress.Minimum = 0;
            pgbProgress.Value = 0;
            pgbProgress.Maximum = objXmlDocument.SelectNodes("/chummer/metatypes/metatype").Count;

            foreach (XmlNode objXmlMetatype in objXmlDocument.SelectNodes("/chummer/metatypes/metatype"))
            {
                pgbProgress.Value++;
                Application.DoEvents();

                objXmlDocument = XmlManager.Instance.Load(strFile);
                Character _objCharacter = new Character();
                ImprovementManager objImprovementManager = new ImprovementManager(_objCharacter);

                try
                {
                    int intForce = 0;
                    if (objXmlMetatype["forcecreature"] != null)
                        intForce = 1;

                    // Set Metatype information.
                    if (strFile != "critters.xml" || objXmlMetatype["name"].InnerText == "Ally Spirit")
                    {
                        _objCharacter.BOD.AssignLimits(ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["bodmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["bodaug"].InnerText, intForce, 0));
                        _objCharacter.AGI.AssignLimits(ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["agimax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["agiaug"].InnerText, intForce, 0));
                        _objCharacter.REA.AssignLimits(ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["reamax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["reaaug"].InnerText, intForce, 0));
                        _objCharacter.STR.AssignLimits(ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["strmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["straug"].InnerText, intForce, 0));
                        _objCharacter.CHA.AssignLimits(ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["chamax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["chaaug"].InnerText, intForce, 0));
                        _objCharacter.INT.AssignLimits(ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["intmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["intaug"].InnerText, intForce, 0));
                        _objCharacter.LOG.AssignLimits(ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["logmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["logaug"].InnerText, intForce, 0));
                        _objCharacter.WIL.AssignLimits(ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["wilmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["wilaug"].InnerText, intForce, 0));
                        _objCharacter.INI.AssignLimits(ExpressionToString(objXmlMetatype["inimin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["inimax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["iniaug"].InnerText, intForce, 0));
                        _objCharacter.MAG.AssignLimits(ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["magmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["magaug"].InnerText, intForce, 0));
                        _objCharacter.RES.AssignLimits(ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["resmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["resaug"].InnerText, intForce, 0));
                        _objCharacter.EDG.AssignLimits(ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["edgmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["edgaug"].InnerText, intForce, 0));
                        _objCharacter.ESS.AssignLimits(ExpressionToString(objXmlMetatype["essmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essaug"].InnerText, intForce, 0));
                    }
                    else
                    {
                        int intMinModifier = -3;
                        if (objXmlMetatype["category"].InnerText == "Mutant Critters")
                            intMinModifier = 0;
                        _objCharacter.BOD.AssignLimits(ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, 3));
                        _objCharacter.AGI.AssignLimits(ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, 3));
                        _objCharacter.REA.AssignLimits(ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, 3));
                        _objCharacter.STR.AssignLimits(ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, 3));
                        _objCharacter.CHA.AssignLimits(ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, 3));
                        _objCharacter.INT.AssignLimits(ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, 3));
                        _objCharacter.LOG.AssignLimits(ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, 3));
                        _objCharacter.WIL.AssignLimits(ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, 3));
                        _objCharacter.INI.AssignLimits(ExpressionToString(objXmlMetatype["inimin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["inimax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["iniaug"].InnerText, intForce, 0));
                        _objCharacter.MAG.AssignLimits(ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, 3));
                        _objCharacter.RES.AssignLimits(ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, 3));
                        _objCharacter.EDG.AssignLimits(ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, 3));
                        _objCharacter.ESS.AssignLimits(ExpressionToString(objXmlMetatype["essmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essaug"].InnerText, intForce, 0));
                    }

                    // If we're working with a Critter, set the Attributes to their default values.
                    if (strFile == "critters.xml")
                    {
                        _objCharacter.BOD.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, 0));
                        _objCharacter.AGI.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, 0));
                        _objCharacter.REA.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, 0));
                        _objCharacter.STR.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, 0));
                        _objCharacter.CHA.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, 0));
                        _objCharacter.INT.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, 0));
                        _objCharacter.LOG.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, 0));
                        _objCharacter.WIL.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, 0));
                        _objCharacter.MAG.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, 0));
                        _objCharacter.RES.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, 0));
                        _objCharacter.EDG.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, 0));
                        _objCharacter.ESS.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["essmax"].InnerText, intForce, 0));
                    }

                    // Sprites can never have Physical Attributes or WIL.
                    if (objXmlMetatype["name"].InnerText.EndsWith("Sprite"))
                    {
                        _objCharacter.BOD.AssignLimits("0", "0", "0");
                        _objCharacter.AGI.AssignLimits("0", "0", "0");
                        _objCharacter.REA.AssignLimits("0", "0", "0");
                        _objCharacter.STR.AssignLimits("0", "0", "0");
                        _objCharacter.WIL.AssignLimits("0", "0", "0");
                        _objCharacter.INI.MetatypeMinimum = Convert.ToInt32(ExpressionToString(objXmlMetatype["inimax"].InnerText, intForce, 0));
                        _objCharacter.INI.MetatypeMaximum = Convert.ToInt32(ExpressionToString(objXmlMetatype["inimax"].InnerText, intForce, 0));
                    }

                    _objCharacter.Metatype = objXmlMetatype["name"].InnerText;
                    _objCharacter.MetatypeCategory = objXmlMetatype["category"].InnerText;
                    _objCharacter.Metavariant = "";
                    _objCharacter.MetatypeBP = 400;

                    if (objXmlMetatype["movement"] != null)
                        _objCharacter.Movement = objXmlMetatype["movement"].InnerText;
                    // Load the Qualities file.
                    XmlDocument objXmlQualityDocument = XmlManager.Instance.Load("qualities.xml");

                    // Determine if the Metatype has any bonuses.
                    if (objXmlMetatype.InnerXml.Contains("bonus"))
                        objImprovementManager.CreateImprovements(Improvement.ImprovementSource.Metatype, objXmlMetatype["name"].InnerText, objXmlMetatype.SelectSingleNode("bonus"), false, 1, objXmlMetatype["name"].InnerText);

                    // Create the Qualities that come with the Metatype.
                    foreach (XmlNode objXmlQualityItem in objXmlMetatype.SelectNodes("qualities/positive/quality"))
                    {
                        XmlNode objXmlQuality = objXmlQualityDocument.SelectSingleNode("/chummer/qualities/quality[name = \"" + objXmlQualityItem.InnerText + "\"]");
                        TreeNode objNode = new TreeNode();
                        List<Weapon> objWeapons = new List<Weapon>();
                        List<TreeNode> objWeaponNodes = new List<TreeNode>();
                        Quality objQuality = new Quality(_objCharacter);
                        string strForceValue = "";
                        if (objXmlQualityItem.Attributes["select"] != null)
                            strForceValue = objXmlQualityItem.Attributes["select"].InnerText;
                        QualitySource objSource = new QualitySource();
                        objSource = QualitySource.Metatype;
                        if (objXmlQualityItem.Attributes["removable"] != null)
                            objSource = QualitySource.MetatypeRemovable;
                        objQuality.Create(objXmlQuality, _objCharacter, objSource, objNode, objWeapons, objWeaponNodes, strForceValue);
                        _objCharacter.Qualities.Add(objQuality);
                    }
                    foreach (XmlNode objXmlQualityItem in objXmlMetatype.SelectNodes("qualities/negative/quality"))
                    {
                        XmlNode objXmlQuality = objXmlQualityDocument.SelectSingleNode("/chummer/qualities/quality[name = \"" + objXmlQualityItem.InnerText + "\"]");
                        TreeNode objNode = new TreeNode();
                        List<Weapon> objWeapons = new List<Weapon>();
                        List<TreeNode> objWeaponNodes = new List<TreeNode>();
                        Quality objQuality = new Quality(_objCharacter);
                        string strForceValue = "";
                        if (objXmlQualityItem.Attributes["select"] != null)
                            strForceValue = objXmlQualityItem.Attributes["select"].InnerText;
                        QualitySource objSource = new QualitySource();
                        objSource = QualitySource.Metatype;
                        if (objXmlQualityItem.Attributes["removable"] != null)
                            objSource = QualitySource.MetatypeRemovable;
                        objQuality.Create(objXmlQuality, _objCharacter, objSource, objNode, objWeapons, objWeaponNodes, strForceValue);
                        _objCharacter.Qualities.Add(objQuality);
                    }

                    // Run through the character's Attributes one more time and make sure their value matches their minimum value.
                    if (strFile == "metatypes.xml")
                    {
                        _objCharacter.BOD.Value = _objCharacter.BOD.TotalMinimum;
                        _objCharacter.AGI.Value = _objCharacter.AGI.TotalMinimum;
                        _objCharacter.REA.Value = _objCharacter.REA.TotalMinimum;
                        _objCharacter.STR.Value = _objCharacter.STR.TotalMinimum;
                        _objCharacter.CHA.Value = _objCharacter.CHA.TotalMinimum;
                        _objCharacter.INT.Value = _objCharacter.INT.TotalMinimum;
                        _objCharacter.LOG.Value = _objCharacter.LOG.TotalMinimum;
                        _objCharacter.WIL.Value = _objCharacter.WIL.TotalMinimum;
                    }

                    // Add any Critter Powers the Metatype/Critter should have.
                    XmlNode objXmlCritter = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + _objCharacter.Metatype + "\"]");

                    objXmlDocument = XmlManager.Instance.Load("critterpowers.xml");
                    foreach (XmlNode objXmlPower in objXmlCritter.SelectNodes("powers/power"))
                    {
                        XmlNode objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"" + objXmlPower.InnerText + "\"]");
                        TreeNode objNode = new TreeNode();
                        CritterPower objPower = new CritterPower(_objCharacter);
                        string strForcedValue = "";
                        int intRating = 0;

                        if (objXmlPower.Attributes["rating"] != null)
                            intRating = Convert.ToInt32(objXmlPower.Attributes["rating"].InnerText);
                        if (objXmlPower.Attributes["select"] != null)
                            strForcedValue = objXmlPower.Attributes["select"].InnerText;

                        objPower.Create(objXmlCritterPower, _objCharacter, objNode, intRating, strForcedValue);
                        _objCharacter.CritterPowers.Add(objPower);
                    }

                    // Set the Skill Ratings for the Critter.
                    foreach (XmlNode objXmlSkill in objXmlCritter.SelectNodes("skills/skill"))
                    {
                        if (objXmlSkill.InnerText.Contains("Exotic"))
                        {
                            Skill objExotic = new Skill(_objCharacter);
                            objExotic.ExoticSkill = true;
                            objExotic.Attribute = "AGI";
                            if (objXmlSkill.Attributes["spec"] != null)
                                objExotic.Specialization = objXmlSkill.Attributes["spec"].InnerText;
                            if (Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(intForce), 0)) > 6)
                                objExotic.RatingMaximum = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(intForce), 0));
                            objExotic.Rating = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(intForce), 0));
                            objExotic.Name = objXmlSkill.InnerText;
                            _objCharacter.Skills.Add(objExotic);
                        }
                        else
                        {
                            foreach (Skill objSkill in _objCharacter.Skills)
                            {
                                if (objSkill.Name == objXmlSkill.InnerText)
                                {
                                    if (objXmlSkill.Attributes["spec"] != null)
                                        objSkill.Specialization = objXmlSkill.Attributes["spec"].InnerText;
                                    if (Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(intForce), 0)) > 6)
                                        objSkill.RatingMaximum = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(intForce), 0));
                                    objSkill.Rating = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(intForce), 0));
                                    break;
                                }
                            }
                        }
                    }

                    // Set the Skill Group Ratings for the Critter.
                    foreach (XmlNode objXmlSkill in objXmlCritter.SelectNodes("skills/group"))
                    {
                        foreach (SkillGroup objSkill in _objCharacter.SkillGroups)
                        {
                            if (objSkill.Name == objXmlSkill.InnerText)
                            {
                                objSkill.RatingMaximum = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(intForce), 0));
                                objSkill.Rating = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(intForce), 0));
                                break;
                            }
                        }
                    }

                    // Set the Knowledge Skill Ratings for the Critter.
                    foreach (XmlNode objXmlSkill in objXmlCritter.SelectNodes("skills/knowledge"))
                    {
                        Skill objKnowledge = new Skill(_objCharacter);
                        objKnowledge.Name = objXmlSkill.InnerText;
                        objKnowledge.KnowledgeSkill = true;
                        if (objXmlSkill.Attributes["spec"] != null)
                            objKnowledge.Specialization = objXmlSkill.Attributes["spec"].InnerText;
                        objKnowledge.SkillCategory = objXmlSkill.Attributes["category"].InnerText;
                        if (Convert.ToInt32(objXmlSkill.Attributes["rating"].InnerText) > 6)
                            objKnowledge.RatingMaximum = Convert.ToInt32(objXmlSkill.Attributes["rating"].InnerText);
                        objKnowledge.Rating = Convert.ToInt32(objXmlSkill.Attributes["rating"].InnerText);
                        _objCharacter.Skills.Add(objKnowledge);
                    }

                    // If this is a Critter with a Force (which dictates their Skill Rating/Maximum Skill Rating), set their Skill Rating Maximums.
                    if (intForce > 0)
                    {
                        int intMaxRating = intForce;
                        // Determine the highest Skill Rating the Critter has.
                        foreach (Skill objSkill in _objCharacter.Skills)
                        {
                            if (objSkill.RatingMaximum > intMaxRating)
                                intMaxRating = objSkill.RatingMaximum;
                        }

                        // Now that we know the upper limit, set all of the Skill Rating Maximums to match.
                        foreach (Skill objSkill in _objCharacter.Skills)
                            objSkill.RatingMaximum = intMaxRating;
                        foreach (SkillGroup objGroup in _objCharacter.SkillGroups)
                            objGroup.RatingMaximum = intMaxRating;

                        // Set the MaxSkillRating for the character so it can be used later when they add new Knowledge Skills or Exotic Skills.
                        _objCharacter.MaxSkillRating = intMaxRating;
                    }

                    // Add any Complex Forms the Critter comes with (typically Sprites)
                    XmlDocument objXmlProgramDocument = XmlManager.Instance.Load("programs.xml");
                    foreach (XmlNode objXmlComplexForm in objXmlCritter.SelectNodes("complexforms/complexform"))
                    {
                        int intRating = 0;
                        if (objXmlComplexForm.Attributes["rating"] != null)
                            intRating = Convert.ToInt32(ExpressionToString(objXmlComplexForm.Attributes["rating"].InnerText, Convert.ToInt32(intForce), 0));
                        string strForceValue = "";
                        if (objXmlComplexForm.Attributes["select"] != null)
                            strForceValue = objXmlComplexForm.Attributes["select"].InnerText;
                        XmlNode objXmlProgram = objXmlProgramDocument.SelectSingleNode("/chummer/programs/program[name = \"" + objXmlComplexForm.InnerText + "\"]");
                        TreeNode objNode = new TreeNode();
                        TechProgram objProgram = new TechProgram(_objCharacter);
                        objProgram.Create(objXmlProgram, _objCharacter, objNode, strForceValue);
                        objProgram.Rating = intRating;
                        _objCharacter.TechPrograms.Add(objProgram);

                        // Add the Program Option if applicable.
                        if (objXmlComplexForm.Attributes["option"] != null)
                        {
                            int intOptRating = 0;
                            if (objXmlComplexForm.Attributes["optionrating"] != null)
                                intOptRating = Convert.ToInt32(ExpressionToString(objXmlComplexForm.Attributes["optionrating"].InnerText, Convert.ToInt32(intForce), 0));
                            string strOptForceValue = "";
                            if (objXmlComplexForm.Attributes["optionselect"] != null)
                                strOptForceValue = objXmlComplexForm.Attributes["optionselect"].InnerText;
                            XmlNode objXmlOption = objXmlProgramDocument.SelectSingleNode("/chummer/options/option[name = \"" + objXmlComplexForm.Attributes["option"].InnerText + "\"]");
                            TreeNode objNodeOpt = new TreeNode();
                            TechProgramOption objOption = new TechProgramOption(_objCharacter);
                            objOption.Create(objXmlOption, _objCharacter, objNodeOpt, strOptForceValue);
                            objOption.Rating = intOptRating;
                            objProgram.Options.Add(objOption);
                        }
                    }

                    // Add any Gear the Critter comes with (typically Programs for A.I.s)
                    XmlDocument objXmlGearDocument = XmlManager.Instance.Load("gear.xml");
                    foreach (XmlNode objXmlGear in objXmlCritter.SelectNodes("gears/gear"))
                    {
                        int intRating = 0;
                        if (objXmlGear.Attributes["rating"] != null)
                            intRating = Convert.ToInt32(ExpressionToString(objXmlGear.Attributes["rating"].InnerText, Convert.ToInt32(intForce), 0));
                        string strForceValue = "";
                        if (objXmlGear.Attributes["select"] != null)
                            strForceValue = objXmlGear.Attributes["select"].InnerText;
                        XmlNode objXmlGearItem = objXmlGearDocument.SelectSingleNode("/chummer/gears/gear[name = \"" + objXmlGear.InnerText + "\"]");
                        TreeNode objNode = new TreeNode();
                        Gear objGear = new Gear(_objCharacter);
                        List<Weapon> lstWeapons = new List<Weapon>();
                        List<TreeNode> lstWeaponNodes = new List<TreeNode>();
                        objGear.Create(objXmlGearItem, _objCharacter, objNode, intRating, lstWeapons, lstWeaponNodes, strForceValue);
                        objGear.Cost = "0";
                        objGear.Cost3 = "0";
                        objGear.Cost6 = "0";
                        objGear.Cost10 = "0";
                        _objCharacter.Gear.Add(objGear);
                    }

                    // If this is a Mutant Critter, count up the number of Skill points they start with.
                    if (_objCharacter.MetatypeCategory == "Mutant Critters")
                    {
                        foreach (Skill objSkill in _objCharacter.Skills)
                            _objCharacter.MutantCritterBaseSkills += objSkill.Rating;
                    }
                }
                catch
                {
                    txtOutput.Text += _objCharacter.Metatype + " general failure\n";
                }
            }
        }
Example #10
0
        /// <summary>
        /// Print this character information to a MemoryStream. This creates only the character object itself, not any of the opening or closing XmlDocument items.
        /// This can be used to write multiple characters to a single XmlDocument.
        /// </summary>
        /// <param name="objStream">MemoryStream to use.</param>
        /// <param name="objWriter">XmlTextWriter to write to.</param>
        public void PrintToStream(MemoryStream objStream, XmlTextWriter objWriter)
        {
            XmlDocument objXmlDocument = new XmlDocument();

            XmlDocument objMetatypeDoc = new XmlDocument();
            XmlNode objMetatypeNode;
            string strMetatype = "";
            string strMetavariant = "";
            // Get the name of the Metatype and Metavariant.
            objMetatypeDoc = XmlManager.Instance.Load("metatypes.xml");
            {
                objMetatypeNode = objMetatypeDoc.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + _strMetatype + "\"]");
                if (objMetatypeNode == null)
                    objMetatypeDoc = XmlManager.Instance.Load("critters.xml");
                objMetatypeNode = objMetatypeDoc.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + _strMetatype + "\"]");

                if (objMetatypeNode["translate"] != null)
                    strMetatype = objMetatypeNode["translate"].InnerText;
                else
                    strMetatype = _strMetatype;

                if (_strMetavariant != "")
                {
                    objMetatypeNode = objMetatypeNode.SelectSingleNode("metavariants/metavariant[name = \"" + _strMetavariant + "\"]");

                    if (objMetatypeNode["translate"] != null)
                        strMetavariant = objMetatypeNode["translate"].InnerText;
                    else
                        strMetavariant = _strMetavariant;
                }
            }

            Guid guiImage = new Guid();
            guiImage = Guid.NewGuid();
            // This line left in for debugging. Write the output to a fixed file name.
            //FileStream objStream = new FileStream("D:\\temp\\print.xml", FileMode.Create, FileAccess.Write, FileShare.ReadWrite);//(_strFileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);

            // <character>
            objWriter.WriteStartElement("character");

            // <metatype />
            objWriter.WriteElementString("metatype", strMetatype);
            // <metatype_english />
            objWriter.WriteElementString("metatype_english", _strMetatype);
            // <metavariant />
            objWriter.WriteElementString("metavariant", strMetavariant);
            // <metavariant_english />
            objWriter.WriteElementString("metavariant_english", _strMetavariant);
            // <movement />
            objWriter.WriteElementString("movement", FullMovement());
            // <movementwalk />
            objWriter.WriteElementString("movementwalk", Movement);
            // <movementswim />
            objWriter.WriteElementString("movementswim", Swim);
            // <movementfly />
            objWriter.WriteElementString("movementfly", Fly);

            // If the character does not have a name, call them Unnamed Character. This prevents a transformed document from having a self-terminated title tag which causes browser to not rendering anything.
            // <name />
            if (_strName != "")
                objWriter.WriteElementString("name", _strName);
            else
                objWriter.WriteElementString("name", LanguageManager.Instance.GetString("String_UnnamedCharacter"));

            // Since IE is retarded and can't handle base64 images before IE9, we need to dump the image to a temporary directory and re-write the information.
            // If you give it an extension of jpg, gif, or png, it expects the file to be in that format and won't render the image unless it was originally that type.
            // But if you give it the extension img, it will render whatever you give it (which doesn't make any damn sense, but that's IE for you).
            string strMugshotPath = "";
            if (_strMugshot != "")
            {
                if (!Directory.Exists(Application.StartupPath + Path.DirectorySeparatorChar + "mugshots"))
                    Directory.CreateDirectory(Application.StartupPath + Path.DirectorySeparatorChar + "mugshots");
                byte[] bytImage = Convert.FromBase64String(_strMugshot);
                MemoryStream objImageStream = new MemoryStream(bytImage, 0, bytImage.Length);
                objImageStream.Write(bytImage, 0, bytImage.Length);
                Image imgMugshot = Image.FromStream(objImageStream, true);
                imgMugshot.Save(Application.StartupPath + Path.DirectorySeparatorChar + "mugshots" + Path.DirectorySeparatorChar + guiImage.ToString() + ".img");
                strMugshotPath = "file://" + (Application.StartupPath + Path.DirectorySeparatorChar + "mugshots" + Path.DirectorySeparatorChar + guiImage.ToString() + ".img").Replace(Path.DirectorySeparatorChar, '/');
            }
            // <mugshot />
            objWriter.WriteElementString("mugshot", strMugshotPath);
            // <mugshotbase64 />
            objWriter.WriteElementString("mugshotbase64", _strMugshot);
            // <sex />
            objWriter.WriteElementString("sex", _strSex);
            // <age />
            objWriter.WriteElementString("age", _strAge);
            // <eyes />
            objWriter.WriteElementString("eyes", _strEyes);
            // <height />
            objWriter.WriteElementString("height", _strHeight);
            // <weight />
            objWriter.WriteElementString("weight", _strWeight);
            // <skin />
            objWriter.WriteElementString("skin", _strSkin);
            // <hair />
            objWriter.WriteElementString("hair", _strHair);
            // <description />
            objWriter.WriteElementString("description", _strDescription);
            // <background />
            objWriter.WriteElementString("background", _strBackground);
            // <concept />
            objWriter.WriteElementString("concept", _strConcept);
            // <notes />
            objWriter.WriteElementString("notes", _strNotes);
            // <alias />
            objWriter.WriteElementString("alias", _strAlias);
            // <playername />
            objWriter.WriteElementString("playername", _strPlayerName);
            // <gamenotes />
            objWriter.WriteElementString("gamenotes", _strGameNotes);

            // <karma />
            objWriter.WriteElementString("karma", _intKarma.ToString());
            // <totalkarma />
            objWriter.WriteElementString("totalkarma", String.Format("{0:###,###,##0}", Convert.ToInt32(CareerKarma)));
            // <streetcred />
            objWriter.WriteElementString("streetcred", _intStreetCred.ToString());
            // <calculatedstreetcred />
            objWriter.WriteElementString("calculatedstreetcred", CalculatedStreetCred.ToString());
            // <totalstreetcred />
            objWriter.WriteElementString("totalstreetcred", TotalStreetCred.ToString());
            // <burntstreetcred />
            objWriter.WriteElementString("burntstreetcred", _intBurntStreetCred.ToString());
            // <notoriety />
            objWriter.WriteElementString("notoriety", _intNotoriety.ToString());
            // <calculatednotoriety />
            objWriter.WriteElementString("calculatednotoriety", CalculatedNotoriety.ToString());
            // <totalnotoriety />
            objWriter.WriteElementString("totalnotoriety", TotalNotoriety.ToString());
            // <publicawareness />
            objWriter.WriteElementString("publicawareness", _intPublicAwareness.ToString());
            // <calculatedpublicawareness />
            objWriter.WriteElementString("calculatedpublicawareness", CalculatedPublicAwareness.ToString());
            // <totalpublicawareness />
            objWriter.WriteElementString("totalpublicawareness", TotalPublicAwareness.ToString());
            // <created />
            objWriter.WriteElementString("created", _blnCreated.ToString());
            // <nuyen />
            objWriter.WriteElementString("nuyen", _intNuyen.ToString());

            // <adept />
            objWriter.WriteElementString("adept", _blnAdeptEnabled.ToString());
            // <magician />
            objWriter.WriteElementString("magician", _blnMagicianEnabled.ToString());
            // <technomancer />
            objWriter.WriteElementString("technomancer", _blnTechnomancerEnabled.ToString());
            // <critter />
            objWriter.WriteElementString("critter", _blnCritterEnabled.ToString());

            // <tradition />
            objWriter.WriteElementString("tradition", _strMagicTradition);
            // <stream />
            objWriter.WriteElementString("stream", _strTechnomancerStream);
            // <drain />
            if (_strMagicTradition != "")
            {
                string strDrainAtt = "";
                objXmlDocument = new XmlDocument();
                objXmlDocument = XmlManager.Instance.Load("traditions.xml");

                XmlNode objXmlTradition = objXmlDocument.SelectSingleNode("/chummer/traditions/tradition[name = \"" + _strMagicTradition + "\"]");
                strDrainAtt = objXmlTradition["drain"].InnerText;

                XPathNavigator nav = objXmlDocument.CreateNavigator();
                string strDrain = strDrainAtt.Replace("BOD", _attBOD.TotalValue.ToString());
                strDrain = strDrain.Replace("AGI", _attAGI.TotalValue.ToString());
                strDrain = strDrain.Replace("REA", _attREA.TotalValue.ToString());
                strDrain = strDrain.Replace("STR", _attSTR.TotalValue.ToString());
                strDrain = strDrain.Replace("CHA", _attCHA.TotalValue.ToString());
                strDrain = strDrain.Replace("INT", _attINT.TotalValue.ToString());
                strDrain = strDrain.Replace("LOG", _attLOG.TotalValue.ToString());
                strDrain = strDrain.Replace("WIL", _attWIL.TotalValue.ToString());
                strDrain = strDrain.Replace("MAG", _attMAG.TotalValue.ToString());
                XPathExpression xprDrain = nav.Compile(strDrain);

                // Add any Improvements for Drain Resistance.
                int intDrain = Convert.ToInt32(nav.Evaluate(xprDrain)) + _objImprovementManager.ValueOf(Improvement.ImprovementType.DrainResistance);

                objWriter.WriteElementString("drain", strDrainAtt + " (" + intDrain.ToString() + ")");
            }
            if (_strTechnomancerStream != "")
            {
                string strDrainAtt = "";
                objXmlDocument = new XmlDocument();
                objXmlDocument = XmlManager.Instance.Load("streams.xml");

                XmlNode objXmlTradition = objXmlDocument.SelectSingleNode("/chummer/traditions/tradition[name = \"" + _strTechnomancerStream + "\"]");
                strDrainAtt = objXmlTradition["drain"].InnerText;

                XPathNavigator nav = objXmlDocument.CreateNavigator();
                string strDrain = strDrainAtt.Replace("BOD", _attBOD.TotalValue.ToString());
                strDrain = strDrain.Replace("AGI", _attAGI.TotalValue.ToString());
                strDrain = strDrain.Replace("REA", _attREA.TotalValue.ToString());
                strDrain = strDrain.Replace("STR", _attSTR.TotalValue.ToString());
                strDrain = strDrain.Replace("CHA", _attCHA.TotalValue.ToString());
                strDrain = strDrain.Replace("INT", _attINT.TotalValue.ToString());
                strDrain = strDrain.Replace("LOG", _attLOG.TotalValue.ToString());
                strDrain = strDrain.Replace("WIL", _attWIL.TotalValue.ToString());
                strDrain = strDrain.Replace("RES", _attRES.TotalValue.ToString());
                XPathExpression xprDrain = nav.Compile(strDrain);

                // Add any Improvements for Fading Resistance.
                int intDrain = Convert.ToInt32(nav.Evaluate(xprDrain)) + _objImprovementManager.ValueOf(Improvement.ImprovementType.FadingResistance);

                objWriter.WriteElementString("drain", strDrainAtt + " (" + intDrain.ToString() + ")");
            }

            // <attributes>
            objWriter.WriteStartElement("attributes");
            _attBOD.Print(objWriter);
            _attAGI.Print(objWriter);
            _attREA.Print(objWriter);
            _attSTR.Print(objWriter);
            _attCHA.Print(objWriter);
            _attINT.Print(objWriter);
            _attLOG.Print(objWriter);
            _attWIL.Print(objWriter);
            _attINI.Print(objWriter);
            _attEDG.Print(objWriter);
            _attMAG.Print(objWriter);
            _attRES.Print(objWriter);
            if (_strMetatype.EndsWith("A.I.") || _strMetatypeCategory == "Technocritters" || _strMetatypeCategory == "Protosapients")
            {
                objWriter.WriteElementString("signal", _intSignal.ToString());
                objWriter.WriteElementString("response", _intResponse.ToString());
                objWriter.WriteElementString("system", System.ToString());
                objWriter.WriteElementString("firewall", Firewall.ToString());
                objWriter.WriteElementString("rating", Rating.ToString());
            }

            objWriter.WriteStartElement("attribute");
            objWriter.WriteElementString("name", "ESS");
            objWriter.WriteElementString("base", Essence.ToString());
            objWriter.WriteEndElement();

            // </attributes>
            objWriter.WriteEndElement();

            // <armorb />
            objWriter.WriteElementString("armorb", TotalBallisticArmorRating.ToString());
            // <armori />
            objWriter.WriteElementString("armori", TotalImpactArmorRating.ToString());

            // Condition Monitors.
            // <physicalcm />
            objWriter.WriteElementString("physicalcm", PhysicalCM.ToString());
            // <stuncm />
            objWriter.WriteElementString("stuncm", StunCM.ToString());

            // Condition Monitor Progress.
            // <physicalcmfilled />
            objWriter.WriteElementString("physicalcmfilled", _intPhysicalCMFilled.ToString());
            // <stuncmfilled />
            objWriter.WriteElementString("stuncmfilled", _intStunCMFilled.ToString());

            // <cmthreshold>
            objWriter.WriteElementString("cmthreshold", CMThreshold.ToString());
            // <cmthresholdoffset>
            objWriter.WriteElementString("cmthresholdoffset", CMThresholdOffset.ToString());
            // <cmoverflow>
            objWriter.WriteElementString("cmoverflow", CMOverflow.ToString());

            // Calculate Initiatives.
            // Initiative.
            // Start by adding INT and REA together.
            int intINI = _attINT.TotalValue + _attREA.TotalValue;
            // Add modifiers.
            intINI += _attINI.AttributeModifiers;
            // Add in any Initiative Improvements.
            intINI += _objImprovementManager.ValueOf(Improvement.ImprovementType.Initiative);
            // If INI exceeds the Metatype maximum set it back to the maximum.
            if (intINI > _attINI.MetatypeAugmentedMaximum)
                intINI = _attINI.MetatypeAugmentedMaximum;

            objWriter.WriteStartElement("init");
            objWriter.WriteElementString("base", (_attINT.Value + _attREA.Value).ToString());
            objWriter.WriteElementString("total", intINI.ToString());
            objWriter.WriteEndElement();

            // Initiative Passes.
            int intIP = 1 + Convert.ToInt32(_objImprovementManager.ValueOf(Improvement.ImprovementType.InitiativePass)) + Convert.ToInt32(_objImprovementManager.ValueOf(Improvement.ImprovementType.InitiativePassAdd));
            objWriter.WriteStartElement("ip");
            objWriter.WriteElementString("base", "1");
            objWriter.WriteElementString("total", intIP.ToString());
            objWriter.WriteEndElement();

            // Astral Initiative.
            if (_blnMAGEnabled)
            {
                int intAstralInit = _attINT.TotalValue * 2;

                objWriter.WriteStartElement("astralinit");
                objWriter.WriteElementString("base", intAstralInit.ToString());
                objWriter.WriteEndElement();

                objWriter.WriteStartElement("astralip");
                objWriter.WriteElementString("base", "3");
                objWriter.WriteEndElement();
            }

            // Matrix Initiative.
            objWriter.WriteStartElement("matrixinit");
            objWriter.WriteElementString("base", MatrixInitiative);
            objWriter.WriteEndElement();

            objWriter.WriteStartElement("matrixip");
            objWriter.WriteElementString("base", MatrixInitiativePasses);
            objWriter.WriteEndElement();

            // <magenabled />
            objWriter.WriteElementString("magenabled", _blnMAGEnabled.ToString());
            // <initiategrade />
            objWriter.WriteElementString("initiategrade", _intInitiateGrade.ToString());
            // <resenabled />
            objWriter.WriteElementString("resenabled", _blnRESEnabled.ToString());
            // <submersiongrade />
            objWriter.WriteElementString("submersiongrade", _intSubmersionGrade.ToString());
            // <groupmember />
            objWriter.WriteElementString("groupmember", _blnGroupMember.ToString());
            // <groupname />
            objWriter.WriteElementString("groupname", _strGroupName);
            // <groupnotes />
            objWriter.WriteElementString("groupnotes", _strGroupNotes);

            // <composure />
            objWriter.WriteElementString("composure", Composure.ToString());
            // <judgeintentions />
            objWriter.WriteElementString("judgeintentions", JudgeIntentions.ToString());
            // <liftandcarry />
            objWriter.WriteElementString("liftandcarry", LiftAndCarry.ToString());
            // <memory />
            objWriter.WriteElementString("memory", Memory.ToString());
            // <liftweight />
            objWriter.WriteElementString("liftweight", (_attSTR.TotalValue * 15).ToString());
            // <carryweight />
            objWriter.WriteElementString("carryweight", (_attSTR.TotalValue * 10).ToString());

            // Staple on the alternate Leadership Skills.
            Skill objLeadership = new Skill(this);
            Skill objLeadershipCommand = new Skill(this);
            Skill objLeadershipDirect = new Skill(this);

            if (_objOptions.PrintLeadershipAlternates)
            {
                foreach (Skill objSkill in _lstSkills)
                {
                    if (objSkill.Name == "Leadership")
                    {
                        objLeadership = objSkill;
                        break;
                    }
                }

                // Leadership, Command.
                objLeadershipCommand.Name = objLeadership.DisplayName + ", " + LanguageManager.Instance.GetString("String_SkillCommand");
                objLeadershipCommand.SkillGroup = objLeadership.SkillGroup;
                objLeadershipCommand.SkillCategory = objLeadership.SkillCategory;
                objLeadershipCommand.IsGrouped = objLeadership.IsGrouped;
                objLeadershipCommand.Default = objLeadership.Default;
                objLeadershipCommand.Rating = objLeadership.Rating;
                objLeadershipCommand.RatingMaximum = objLeadership.RatingMaximum;
                objLeadershipCommand.KnowledgeSkill = objLeadership.KnowledgeSkill;
                objLeadershipCommand.ExoticSkill = objLeadership.ExoticSkill;
                objLeadershipCommand.Specialization = objLeadership.Specialization;
                objLeadershipCommand.Attribute = "LOG";
                objLeadershipCommand.Source = objLeadership.Source;
                objLeadershipCommand.Page = objLeadership.Page;
                _lstSkills.Add(objLeadershipCommand);

                // Leadership, Direct Fire
                objLeadershipDirect.Name = objLeadership.DisplayName + ", " + LanguageManager.Instance.GetString("String_SkillDirectFire");
                objLeadershipDirect.SkillGroup = objLeadership.SkillGroup;
                objLeadershipDirect.SkillCategory = objLeadership.SkillCategory;
                objLeadershipDirect.IsGrouped = objLeadership.IsGrouped;
                objLeadershipDirect.Default = objLeadership.Default;
                objLeadershipDirect.Rating = objLeadership.Rating;
                objLeadershipDirect.RatingMaximum = objLeadership.RatingMaximum;
                objLeadershipDirect.KnowledgeSkill = objLeadership.KnowledgeSkill;
                objLeadershipDirect.ExoticSkill = objLeadership.ExoticSkill;
                objLeadershipDirect.Specialization = objLeadership.Specialization;
                objLeadershipDirect.Attribute = "INT";
                objLeadershipDirect.Source = objLeadership.Source;
                objLeadershipDirect.Page = objLeadership.Page;
                _lstSkills.Add(objLeadershipDirect);
            }

            // Staple on the alternate Arcana Skills.
            Skill objArcana = new Skill(this);
            Skill objArcanaMetamagic = new Skill(this);
            Skill objArcanaArtificing = new Skill(this);

            if (_objOptions.PrintArcanaAlternates)
            {
                foreach (Skill objSkill in _lstSkills)
                {
                    if (objSkill.Name == "Arcana")
                    {
                        objArcana = objSkill;
                        break;
                    }
                }
                // Arcana, Metamagic.
                objArcanaMetamagic.Name = objArcana.DisplayName + ", " + LanguageManager.Instance.GetString("String_SkillMetamagic");
                objArcanaMetamagic.SkillGroup = objArcana.SkillGroup;
                objArcanaMetamagic.SkillCategory = objArcana.SkillCategory;
                objArcanaMetamagic.IsGrouped = objArcana.IsGrouped;
                objArcanaMetamagic.Default = objArcana.Default;
                objArcanaMetamagic.Rating = objArcana.Rating;
                objArcanaMetamagic.RatingMaximum = objArcana.RatingMaximum;
                objArcanaMetamagic.KnowledgeSkill = objArcana.KnowledgeSkill;
                objArcanaMetamagic.ExoticSkill = objArcana.ExoticSkill;
                objArcanaMetamagic.Specialization = objArcana.Specialization;
                objArcanaMetamagic.Attribute = "INT";
                objArcanaMetamagic.Source = objArcana.Source;
                objArcanaMetamagic.Page = objArcana.Page;
                _lstSkills.Add(objArcanaMetamagic);

                // Arcana, Artificing
                objArcanaArtificing.Name = objArcana.DisplayName + ", " + LanguageManager.Instance.GetString("String_SkillArtificing");
                objArcanaArtificing.SkillGroup = objArcana.SkillGroup;
                objArcanaArtificing.SkillCategory = objArcana.SkillCategory;
                objArcanaArtificing.IsGrouped = objArcana.IsGrouped;
                objArcanaArtificing.Default = objArcana.Default;
                objArcanaArtificing.Rating = objArcana.Rating;
                objArcanaArtificing.RatingMaximum = objArcana.RatingMaximum;
                objArcanaArtificing.KnowledgeSkill = objArcana.KnowledgeSkill;
                objArcanaArtificing.ExoticSkill = objArcana.ExoticSkill;
                objArcanaArtificing.Specialization = objArcana.Specialization;
                objArcanaArtificing.Attribute = "MAG";
                objArcanaArtificing.Source = objArcana.Source;
                objArcanaArtificing.Page = objArcana.Page;
                _lstSkills.Add(objArcanaArtificing);
            }

            // <skills>
            objWriter.WriteStartElement("skills");
            foreach (Skill objSkill in _lstSkills)
            {
                if (_objOptions.PrintSkillsWithZeroRating || (!_objOptions.PrintSkillsWithZeroRating && objSkill.Rating > 0) || objSkill.KnowledgeSkill)
                    objSkill.Print(objWriter);
            }
            // </skills>
            objWriter.WriteEndElement();

            // Remove the stapled on Leadership Skills now that we're done with them.
            if (_objOptions.PrintLeadershipAlternates)
            {
                _lstSkills.Remove(objLeadershipCommand);
                _lstSkills.Remove(objLeadershipDirect);
            }

            // Remove the stapled on Arcana Skills now that we're done with them.
            if (_objOptions.PrintArcanaAlternates)
            {
                _lstSkills.Remove(objArcanaMetamagic);
                _lstSkills.Remove(objArcanaArtificing);
            }

            // <contacts>
            objWriter.WriteStartElement("contacts");
            foreach (Contact objContact in _lstContacts)
            {
                objContact.Print(objWriter);
            }
            // </contacts>
            objWriter.WriteEndElement();

            // <spells>
            objWriter.WriteStartElement("spells");
            foreach (Spell objSpell in _lstSpells)
            {
                objSpell.Print(objWriter);
            }
            // </spells>
            objWriter.WriteEndElement();

            // <powers>
            objWriter.WriteStartElement("powers");
            foreach (Power objPower in _lstPowers)
            {
                objPower.Print(objWriter);
            }
            // </powers>
            objWriter.WriteEndElement();

            // <spirits>
            objWriter.WriteStartElement("spirits");
            foreach (Spirit objSpirit in _lstSpirits)
            {
                objSpirit.Print(objWriter);
            }
            // </spirits>
            objWriter.WriteEndElement();

            // <techprograms>
            objWriter.WriteStartElement("techprograms");
            foreach (TechProgram objProgram in _lstTechPrograms)
            {
                objProgram.Print(objWriter);
            }
            // </techprograms>
            objWriter.WriteEndElement();

            // <martialarts>
            objWriter.WriteStartElement("martialarts");
            foreach (MartialArt objMartialArt in _lstMartialArts)
            {
                objMartialArt.Print(objWriter);
            }
            // </martialarts>
            objWriter.WriteEndElement();

            // <martialartmaneuvers>
            objWriter.WriteStartElement("martialartmaneuvers");
            foreach (MartialArtManeuver objManeuver in _lstMartialArtManeuvers)
            {
                objManeuver.Print(objWriter);
            }
            // </martialartmaneuvers>
            objWriter.WriteEndElement();

            // <armors>
            objWriter.WriteStartElement("armors");
            foreach (Armor objArmor in _lstArmor)
            {
                objArmor.Print(objWriter);
            }
            // </armors>
            objWriter.WriteEndElement();

            // <weapons>
            objWriter.WriteStartElement("weapons");
            foreach (Weapon objWeapon in _lstWeapons)
            {
                objWeapon.Print(objWriter);
            }
            // </weapons>
            objWriter.WriteEndElement();

            // <cyberwares>
            objWriter.WriteStartElement("cyberwares");
            foreach (Cyberware objCyberware in _lstCyberware)
            {
                objCyberware.Print(objWriter);
            }
            // </cyberwares>
            objWriter.WriteEndElement();

            // Load the Qualities file so we can figure out whether or not each Quality should be printed.
            objXmlDocument = XmlManager.Instance.Load("qualities.xml");

            // <qualities>
            objWriter.WriteStartElement("qualities");
            foreach (Quality objQuality in _lstQualities)
            {
                objQuality.Print(objWriter);
            }
            // </qualities>
            objWriter.WriteEndElement();

            // <lifestyles>
            objWriter.WriteStartElement("lifestyles");
            foreach (Lifestyle objLifestyle in _lstLifestyles)
            {
                objLifestyle.Print(objWriter);
            }
            // </lifestyles>
            objWriter.WriteEndElement();

            // <gears>
            objWriter.WriteStartElement("gears");
            foreach (Gear objGear in _lstGear)
            {
                // Use the Gear's SubClass if applicable.
                if (objGear.GetType() == typeof(Commlink))
                {
                    Commlink objCommlink = new Commlink(this);
                    objCommlink = (Commlink)objGear;
                    objCommlink.Print(objWriter);
                }
                else if (objGear.GetType() == typeof(OperatingSystem))
                {
                    OperatingSystem objOperatinSystem = new OperatingSystem(this);
                    objOperatinSystem = (OperatingSystem)objGear;
                    objOperatinSystem.Print(objWriter);
                }
                else
                {
                    objGear.Print(objWriter);
                }
            }
            // If the character is a Technomander, write out the Living Persona "Commlink".
            if (_blnTechnomancerEnabled)
            {
                int intFirewall = _attWIL.TotalValue + _objImprovementManager.ValueOf(Improvement.ImprovementType.LivingPersonaFirewall);
                int intResponse = _attINT.TotalValue + _objImprovementManager.ValueOf(Improvement.ImprovementType.LivingPersonaResponse);
                int intSignal = Convert.ToInt32(Math.Ceiling((Convert.ToDecimal(_attRES.TotalValue, GlobalOptions.Instance.CultureInfo) / 2))) + _objImprovementManager.ValueOf(Improvement.ImprovementType.LivingPersonaSignal);
                int intSystem = _attLOG.TotalValue + _objImprovementManager.ValueOf(Improvement.ImprovementType.LivingPersonaSystem);

                // Make sure none of the Attributes exceed the Technomancer's RES.
                intFirewall = Math.Min(intFirewall, _attRES.TotalValue);
                intResponse = Math.Min(intResponse, _attRES.TotalValue);
                intSignal = Math.Min(intSignal, _attRES.TotalValue);
                intSystem = Math.Min(intSystem, _attRES.TotalValue);

                Commlink objLivingPersona = new Commlink(this);
                objLivingPersona.Name = LanguageManager.Instance.GetString("String_LivingPersona");
                objLivingPersona.Category = LanguageManager.Instance.GetString("String_Commlink");
                objLivingPersona.Response = intResponse;
                objLivingPersona.Signal = intSignal;
                objLivingPersona.Source = _objOptions.LanguageBookShort("SR4");
                objLivingPersona.Page = "239";
                objLivingPersona.IsLivingPersona = true;

                OperatingSystem objLivingPersonaOS = new OperatingSystem(this);
                objLivingPersonaOS.Name = LanguageManager.Instance.GetString("String_LivingPersona");
                objLivingPersonaOS.Category = LanguageManager.Instance.GetString("String_CommlinkOperatingSystem");
                objLivingPersonaOS.Firewall = intFirewall;
                objLivingPersonaOS.System = intSystem;
                objLivingPersonaOS.Source = _objOptions.LanguageBookShort("SR4");
                objLivingPersonaOS.Page = "239";

                Gear objLivingPersonaFilter = new Gear(this);
                objLivingPersonaFilter.Name = LanguageManager.Instance.GetString("String_BiofeedbackFilter");
                objLivingPersonaFilter.Category = LanguageManager.Instance.GetString("String_LivingPersonaGear");
                objLivingPersonaFilter.MaxRating = _attCHA.TotalValue + _objImprovementManager.ValueOf(Improvement.ImprovementType.LivingPersonaBiofeedback);
                objLivingPersonaFilter.Rating = _attCHA.TotalValue + _objImprovementManager.ValueOf(Improvement.ImprovementType.LivingPersonaBiofeedback);
                objLivingPersonaFilter.Source = _objOptions.LanguageBookShort("SR4");
                objLivingPersonaFilter.Page = "239";

                objLivingPersona.Children.Add(objLivingPersonaOS);
                objLivingPersona.Children.Add(objLivingPersonaFilter);

                objLivingPersona.Print(objWriter);
            }
            // </gears>
            objWriter.WriteEndElement();

            // <vehicles>
            objWriter.WriteStartElement("vehicles");
            foreach (Vehicle objVehicle in _lstVehicles)
            {
                objVehicle.Print(objWriter);
            }
            // </vehicles>
            objWriter.WriteEndElement();

            // <metamagics>
            objWriter.WriteStartElement("metamagics");
            foreach (Metamagic objMetamagic in _lstMetamagics)
            {
                objMetamagic.Print(objWriter);
            }
            // </metamagics>
            objWriter.WriteEndElement();

            // <critterpowers>
            objWriter.WriteStartElement("critterpowers");
            foreach (CritterPower objPower in _lstCritterPowers)
            {
                objPower.Print(objWriter);
            }
            // </critterpowers>
            objWriter.WriteEndElement();

            // Print the Expense Log Entries if the option is enabled.
            if (_objOptions.PrintExpenses)
            {
                // <expenses>
                objWriter.WriteStartElement("expenses");
                _lstExpenseLog.Sort(ExpenseLogEntry.CompareDate);
                foreach (ExpenseLogEntry objExpense in _lstExpenseLog)
                    objExpense.Print(objWriter);
                // </expenses>
                objWriter.WriteEndElement();
            }

            // </character>
            objWriter.WriteEndElement();
        }
        /// <summary>
        /// A Metatype has been selected, so fill in all of the necessary Character information.
        /// </summary>
        void MetatypeSelected()
        {
            if (cboTalents.SelectedIndex == -1)
            {
                MessageBox.Show(LanguageManager.Instance.GetString("Message_Metatype_SelectTalent"), LanguageManager.Instance.GetString("MessageTitle_Metatype_SelectTalent"), MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            if ((cboSkill1.SelectedIndex == -1 && cboSkill1.Visible) || (cboSkill2.SelectedIndex == -1 && cboSkill2.Visible))
            {
                MessageBox.Show(LanguageManager.Instance.GetString("Message_Metatype_SelectSkill"), LanguageManager.Instance.GetString("MessageTitle_Metatype_SelectSkill"), MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            if (cboSkill1.Visible && cboSkill2.Visible && cboSkill1.SelectedValue.ToString() == cboSkill2.SelectedValue.ToString())
            {
                MessageBox.Show(LanguageManager.Instance.GetString("Message_Metatype_Duplicate"), LanguageManager.Instance.GetString("MessageTitle_Metatype_Duplicate"), MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            if (lstMetatypes.Text != "")
            {
                ImprovementManager objImprovementManager = new ImprovementManager(_objCharacter);
                XmlDocument objXmlDocument = XmlManager.Instance.Load(_strXmlFile);

                XmlNode objXmlMetatype = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + lstMetatypes.SelectedValue + "\"]");
                XmlNode objXmlMetavariant = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + lstMetatypes.SelectedValue + "\"]/metavariants/metavariant[name = \"" + cboMetavariant.SelectedValue + "\"]");

                int intForce = 0;
                if (nudForce.Visible)
                    intForce = Convert.ToInt32(nudForce.Value);

                // Set Metatype information.
                if (cboMetavariant.SelectedValue.ToString() != "None")
                {
                    _objCharacter.BOD.AssignLimits(ExpressionToString(objXmlMetavariant["bodmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["bodmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["bodaug"].InnerText, intForce, 0));
                    _objCharacter.AGI.AssignLimits(ExpressionToString(objXmlMetavariant["agimin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["agimax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["agiaug"].InnerText, intForce, 0));
                    _objCharacter.REA.AssignLimits(ExpressionToString(objXmlMetavariant["reamin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["reamax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["reaaug"].InnerText, intForce, 0));
                    _objCharacter.STR.AssignLimits(ExpressionToString(objXmlMetavariant["strmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["strmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["straug"].InnerText, intForce, 0));
                    _objCharacter.CHA.AssignLimits(ExpressionToString(objXmlMetavariant["chamin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["chamax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["chaaug"].InnerText, intForce, 0));
                    _objCharacter.INT.AssignLimits(ExpressionToString(objXmlMetavariant["intmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["intmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["intaug"].InnerText, intForce, 0));
                    _objCharacter.LOG.AssignLimits(ExpressionToString(objXmlMetavariant["logmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["logmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["logaug"].InnerText, intForce, 0));
                    _objCharacter.WIL.AssignLimits(ExpressionToString(objXmlMetavariant["wilmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["wilmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["wilaug"].InnerText, intForce, 0));
                    _objCharacter.INI.AssignLimits(ExpressionToString(objXmlMetavariant["inimin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["inimax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["iniaug"].InnerText, intForce, 0));
                    _objCharacter.MAG.AssignLimits(ExpressionToString(objXmlMetavariant["magmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["magmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["magaug"].InnerText, intForce, 0));
                    _objCharacter.RES.AssignLimits(ExpressionToString(objXmlMetavariant["resmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["resmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["resaug"].InnerText, intForce, 0));
                    _objCharacter.EDG.AssignLimits(ExpressionToString(objXmlMetavariant["edgmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["edgmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["edgaug"].InnerText, intForce, 0));
                    _objCharacter.ESS.AssignLimits(ExpressionToString(objXmlMetavariant["essmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["essmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["essaug"].InnerText, intForce, 0));
                    _objCharacter.MetatypeBP = Convert.ToInt32(lblMetavariantBP.Text);
                }
                else if (_strXmlFile != "critters.xml" || lstMetatypes.SelectedValue.ToString() == "Ally Spirit")
                {
                    _objCharacter.BOD.AssignLimits(ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["bodmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["bodaug"].InnerText, intForce, 0));
                    _objCharacter.AGI.AssignLimits(ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["agimax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["agiaug"].InnerText, intForce, 0));
                    _objCharacter.REA.AssignLimits(ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["reamax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["reaaug"].InnerText, intForce, 0));
                    _objCharacter.STR.AssignLimits(ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["strmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["straug"].InnerText, intForce, 0));
                    _objCharacter.CHA.AssignLimits(ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["chamax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["chaaug"].InnerText, intForce, 0));
                    _objCharacter.INT.AssignLimits(ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["intmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["intaug"].InnerText, intForce, 0));
                    _objCharacter.LOG.AssignLimits(ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["logmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["logaug"].InnerText, intForce, 0));
                    _objCharacter.WIL.AssignLimits(ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["wilmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["wilaug"].InnerText, intForce, 0));
                    _objCharacter.INI.AssignLimits(ExpressionToString(objXmlMetatype["inimin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["inimax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["iniaug"].InnerText, intForce, 0));
                    _objCharacter.MAG.AssignLimits(ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["magmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["magaug"].InnerText, intForce, 0));
                    _objCharacter.RES.AssignLimits(ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["resmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["resaug"].InnerText, intForce, 0));
                    _objCharacter.EDG.AssignLimits(ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["edgmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["edgaug"].InnerText, intForce, 0));
                    _objCharacter.ESS.AssignLimits(ExpressionToString(objXmlMetatype["essmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essaug"].InnerText, intForce, 0));
                }
                else
                {
                    int intMinModifier = -3;
                    if (cboCategory.SelectedValue.ToString() == "Mutant Critters")
                        intMinModifier = 0;
                    _objCharacter.BOD.AssignLimits(ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, 3));
                    _objCharacter.AGI.AssignLimits(ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, 3));
                    _objCharacter.REA.AssignLimits(ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, 3));
                    _objCharacter.STR.AssignLimits(ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, 3));
                    _objCharacter.CHA.AssignLimits(ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, 3));
                    _objCharacter.INT.AssignLimits(ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, 3));
                    _objCharacter.LOG.AssignLimits(ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, 3));
                    _objCharacter.WIL.AssignLimits(ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, 3));
                    _objCharacter.INI.AssignLimits(ExpressionToString(objXmlMetatype["inimin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["inimax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["iniaug"].InnerText, intForce, 0));
                    _objCharacter.MAG.AssignLimits(ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, 3));
                    _objCharacter.RES.AssignLimits(ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, 3));
                    _objCharacter.EDG.AssignLimits(ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, 3));
                    _objCharacter.ESS.AssignLimits(ExpressionToString(objXmlMetatype["essmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essaug"].InnerText, intForce, 0));
                }

                // If we're working with a Critter, set the Attributes to their default values.
                if (_strXmlFile == "critters.xml")
                {
                    _objCharacter.BOD.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, 0));
                    _objCharacter.AGI.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, 0));
                    _objCharacter.REA.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, 0));
                    _objCharacter.STR.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, 0));
                    _objCharacter.CHA.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, 0));
                    _objCharacter.INT.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, 0));
                    _objCharacter.LOG.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, 0));
                    _objCharacter.WIL.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, 0));
                    _objCharacter.MAG.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, 0));
                    _objCharacter.RES.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, 0));
                    _objCharacter.EDG.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, 0));
                    _objCharacter.ESS.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["essmax"].InnerText, intForce, 0));
                }

                // Sprites can never have Physical Attributes or WIL.
                if (lstMetatypes.SelectedValue.ToString().EndsWith("Sprite"))
                {
                    _objCharacter.BOD.AssignLimits("0", "0", "0");
                    _objCharacter.AGI.AssignLimits("0", "0", "0");
                    _objCharacter.REA.AssignLimits("0", "0", "0");
                    _objCharacter.STR.AssignLimits("0", "0", "0");
                    _objCharacter.WIL.AssignLimits("0", "0", "0");
                    _objCharacter.INI.MetatypeMinimum = Convert.ToInt32(ExpressionToString(objXmlMetatype["inimax"].InnerText, intForce, 0));
                    _objCharacter.INI.MetatypeMaximum = Convert.ToInt32(ExpressionToString(objXmlMetatype["inimax"].InnerText, intForce, 0));
                }

                // If this is a Shapeshifter, a Metavariant must be selected. Default to Human if None is selected.
                if (cboCategory.SelectedValue.ToString() == "Shapeshifter" && cboMetavariant.SelectedValue.ToString() == "None")
                    cboMetavariant.SelectedValue = "Human";

                _objCharacter.Metatype = lstMetatypes.SelectedValue.ToString();
                _objCharacter.MetatypeCategory = cboCategory.SelectedValue.ToString();
                if (cboMetavariant.SelectedValue.ToString() == "None")
                {
                    _objCharacter.Metavariant = "";
                }
                else
                {
                    _objCharacter.Metavariant = cboMetavariant.SelectedValue.ToString();
                }

                if (objXmlMetatype["movement"] != null) // TODO: Replace with Walk/Run
                    _objCharacter.Movement = objXmlMetatype["movement"].InnerText;

                // Load the Qualities file.
                XmlDocument objXmlQualityDocument = XmlManager.Instance.Load("qualities.xml");

                if (cboMetavariant.SelectedValue.ToString() == "None")
                {
                    // Determine if the Metatype has any bonuses.
                    if (objXmlMetatype.InnerXml.Contains("bonus"))
                        objImprovementManager.CreateImprovements(Improvement.ImprovementSource.Metatype, lstMetatypes.SelectedValue.ToString(), objXmlMetatype.SelectSingleNode("bonus"), false, 1, lstMetatypes.SelectedValue.ToString());

                    // Create the Qualities that come with the Metatype.
                    foreach (XmlNode objXmlQualityItem in objXmlMetatype.SelectNodes("qualities/positive/quality"))
                    {
                        XmlNode objXmlQuality = objXmlQualityDocument.SelectSingleNode("/chummer/qualities/quality[name = \"" + objXmlQualityItem.InnerText + "\"]");
                        TreeNode objNode = new TreeNode();
                        List<Weapon> objWeapons = new List<Weapon>();
                        List<TreeNode> objWeaponNodes = new List<TreeNode>();
                        Quality objQuality = new Quality(_objCharacter);
                        string strForceValue = "";
                        if (objXmlQualityItem.Attributes["select"] != null)
                            strForceValue = objXmlQualityItem.Attributes["select"].InnerText;
                        QualitySource objSource = new QualitySource();
                        objSource = QualitySource.Metatype;
                        if (objXmlQualityItem.Attributes["removable"] != null)
                            objSource = QualitySource.MetatypeRemovable;
                        objQuality.Create(objXmlQuality, _objCharacter, objSource, objNode, objWeapons, objWeaponNodes, strForceValue);
                        objQuality.ContributeToLimit = false;
                        _objCharacter.Qualities.Add(objQuality);

                        // Add any created Weapons to the character.
                        foreach (Weapon objWeapon in objWeapons)
                            _objCharacter.Weapons.Add(objWeapon);
                    }
                    foreach (XmlNode objXmlQualityItem in objXmlMetatype.SelectNodes("qualities/negative/quality"))
                    {
                        XmlNode objXmlQuality = objXmlQualityDocument.SelectSingleNode("/chummer/qualities/quality[name = \"" + objXmlQualityItem.InnerText + "\"]");
                        TreeNode objNode = new TreeNode();
                        List<Weapon> objWeapons = new List<Weapon>();
                        List<TreeNode> objWeaponNodes = new List<TreeNode>();
                        Quality objQuality = new Quality(_objCharacter);
                        string strForceValue = "";
                        if (objXmlQualityItem.Attributes["select"] != null)
                            strForceValue = objXmlQualityItem.Attributes["select"].InnerText;
                        QualitySource objSource = new QualitySource();
                        objSource = QualitySource.Metatype;
                        if (objXmlQualityItem.Attributes["removable"] != null)
                            objSource = QualitySource.MetatypeRemovable;
                        objQuality.Create(objXmlQuality, _objCharacter, objSource, objNode, objWeapons, objWeaponNodes, strForceValue);
                        objQuality.ContributeToLimit = false;
                        _objCharacter.Qualities.Add(objQuality);

                        // Add any created Weapons to the character.
                        foreach (Weapon objWeapon in objWeapons)
                            _objCharacter.Weapons.Add(objWeapon);
                    }
                }

                // If a Metavariant has been selected, locate it in the file.
                if (cboMetavariant.SelectedValue.ToString() != "None")
                {
                    // Determine if the Metavariant has any bonuses.
                    if (objXmlMetavariant.InnerXml.Contains("bonus"))
                        objImprovementManager.CreateImprovements(Improvement.ImprovementSource.Metavariant, cboMetavariant.SelectedValue.ToString(), objXmlMetavariant.SelectSingleNode("bonus"), false, 1, cboMetavariant.SelectedValue.ToString());

                    // Create the Qualities that come with the Metatype.
                    foreach (XmlNode objXmlQualityItem in objXmlMetavariant.SelectNodes("qualities/positive/quality"))
                    {
                        XmlNode objXmlQuality = objXmlQualityDocument.SelectSingleNode("/chummer/qualities/quality[name = \"" + objXmlQualityItem.InnerText + "\"]");
                        TreeNode objNode = new TreeNode();
                        List<Weapon> objWeapons = new List<Weapon>();
                        List<TreeNode> objWeaponNodes = new List<TreeNode>();
                        Quality objQuality = new Quality(_objCharacter);
                        objQuality.ContributeToLimit = false;
                        string strForceValue = "";
                        if (objXmlQualityItem.Attributes["select"] != null)
                            strForceValue = objXmlQualityItem.Attributes["select"].InnerText;
                        QualitySource objSource = new QualitySource();
                        objSource = QualitySource.Metatype;
                        if (objXmlQualityItem.Attributes["removable"] != null)
                            objSource = QualitySource.MetatypeRemovable;
                        objQuality.Create(objXmlQuality, _objCharacter, objSource, objNode, objWeapons, objWeaponNodes, strForceValue);
                        objQuality.ContributeToLimit = false;
                        _objCharacter.Qualities.Add(objQuality);

                        // Add any created Weapons to the character.
                        foreach (Weapon objWeapon in objWeapons)
                            _objCharacter.Weapons.Add(objWeapon);
                    }
                    foreach (XmlNode objXmlQualityItem in objXmlMetavariant.SelectNodes("qualities/negative/quality"))
                    {
                        XmlNode objXmlQuality = objXmlQualityDocument.SelectSingleNode("/chummer/qualities/quality[name = \"" + objXmlQualityItem.InnerText + "\"]");
                        TreeNode objNode = new TreeNode();
                        List<Weapon> objWeapons = new List<Weapon>();
                        List<TreeNode> objWeaponNodes = new List<TreeNode>();
                        Quality objQuality = new Quality(_objCharacter);
                        string strForceValue = "";
                        if (objXmlQualityItem.Attributes["select"] != null)
                            strForceValue = objXmlQualityItem.Attributes["select"].InnerText;
                        QualitySource objSource = new QualitySource();
                        objSource = QualitySource.Metatype;
                        if (objXmlQualityItem.Attributes["removable"] != null)
                            objSource = QualitySource.MetatypeRemovable;
                        objQuality.Create(objXmlQuality, _objCharacter, objSource, objNode, objWeapons, objWeaponNodes, strForceValue);
                        objQuality.ContributeToLimit = false;
                        _objCharacter.Qualities.Add(objQuality);

                        // Add any created Weapons to the character.
                        foreach (Weapon objWeapon in objWeapons)
                            _objCharacter.Weapons.Add(objWeapon);
                    }
                }

                // Run through the character's Attributes one more time and make sure their value matches their minimum value.
                if (_strXmlFile == "metatypes.xml")
                {
                    _objCharacter.BOD.Value = _objCharacter.BOD.TotalMinimum;
                    _objCharacter.AGI.Value = _objCharacter.AGI.TotalMinimum;
                    _objCharacter.REA.Value = _objCharacter.REA.TotalMinimum;
                    _objCharacter.STR.Value = _objCharacter.STR.TotalMinimum;
                    _objCharacter.CHA.Value = _objCharacter.CHA.TotalMinimum;
                    _objCharacter.INT.Value = _objCharacter.INT.TotalMinimum;
                    _objCharacter.LOG.Value = _objCharacter.LOG.TotalMinimum;
                    _objCharacter.WIL.Value = _objCharacter.WIL.TotalMinimum;

                    _objCharacter.BOD.Base = _objCharacter.BOD.TotalMinimum;
                    _objCharacter.AGI.Base = _objCharacter.AGI.TotalMinimum;
                    _objCharacter.REA.Base = _objCharacter.REA.TotalMinimum;
                    _objCharacter.STR.Base = _objCharacter.STR.TotalMinimum;
                    _objCharacter.CHA.Base = _objCharacter.CHA.TotalMinimum;
                    _objCharacter.INT.Base = _objCharacter.INT.TotalMinimum;
                    _objCharacter.LOG.Base = _objCharacter.LOG.TotalMinimum;
                    _objCharacter.WIL.Base = _objCharacter.WIL.TotalMinimum;

                    _objCharacter.BOD.Karma = 0;
                    _objCharacter.AGI.Karma = 0;
                    _objCharacter.REA.Karma = 0;
                    _objCharacter.STR.Karma = 0;
                    _objCharacter.CHA.Karma = 0;
                    _objCharacter.INT.Karma = 0;
                    _objCharacter.LOG.Karma = 0;
                    _objCharacter.WIL.Karma = 0;
                    _objCharacter.EDG.Karma = 0;
                    _objCharacter.MAG.Karma = 0;
                    _objCharacter.RES.Karma = 0;
                }

                // Add any Critter Powers the Metatype/Critter should have.
                XmlNode objXmlCritter = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + _objCharacter.Metatype + "\"]");

                objXmlDocument = XmlManager.Instance.Load("critterpowers.xml");
                foreach (XmlNode objXmlPower in objXmlCritter.SelectNodes("powers/power"))
                {
                    XmlNode objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"" + objXmlPower.InnerText + "\"]");
                    TreeNode objNode = new TreeNode();
                    CritterPower objPower = new CritterPower(_objCharacter);
                    string strForcedValue = "";
                    int intRating = 0;

                    if (objXmlPower.Attributes["rating"] != null)
                        intRating = Convert.ToInt32(objXmlPower.Attributes["rating"].InnerText);
                    if (objXmlPower.Attributes["select"] != null)
                        strForcedValue = objXmlPower.Attributes["select"].InnerText;

                    objPower.Create(objXmlCritterPower, _objCharacter, objNode, intRating, strForcedValue);
                    objPower.CountTowardsLimit = false;
                    _objCharacter.CritterPowers.Add(objPower);
                }

                // Add any Critter Powers the Metavariant should have.
                if (cboMetavariant.SelectedValue.ToString() != "None")
                {
                    foreach (XmlNode objXmlPower in objXmlMetavariant.SelectNodes("powers/power"))
                    {
                        XmlNode objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"" + objXmlPower.InnerText + "\"]");
                        TreeNode objNode = new TreeNode();
                        CritterPower objPower = new CritterPower(_objCharacter);
                        string strForcedValue = "";
                        int intRating = 0;

                        if (objXmlPower.Attributes["rating"] != null)
                            intRating = Convert.ToInt32(objXmlPower.Attributes["rating"].InnerText);
                        if (objXmlPower.Attributes["select"] != null)
                            strForcedValue = objXmlPower.Attributes["select"].InnerText;

                        objPower.Create(objXmlCritterPower, _objCharacter, objNode, intRating, strForcedValue);
                        objPower.CountTowardsLimit = false;
                        _objCharacter.CritterPowers.Add(objPower);
                    }
                }

                // If this is a Blood Spirit, add their free Critter Powers.
                if (chkBloodSpirit.Checked)
                {
                    XmlNode objXmlCritterPower;
                    TreeNode objNode;
                    CritterPower objPower;
                    bool blnAddPower = true;

                    // Energy Drain.
                    foreach (CritterPower objFindPower in _objCharacter.CritterPowers)
                    {
                        if (objFindPower.Name == "Energy Drain")
                        {
                            blnAddPower = false;
                            break;
                        }
                    }
                    if (blnAddPower)
                    {
                        objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"Energy Drain\"]");
                        objNode = new TreeNode();
                        objPower = new CritterPower(_objCharacter);
                        objPower.Create(objXmlCritterPower, _objCharacter, objNode, 0, "");
                        objPower.CountTowardsLimit = false;
                        _objCharacter.CritterPowers.Add(objPower);
                    }

                    // Fear.
                    blnAddPower = true;
                    foreach (CritterPower objFindPower in _objCharacter.CritterPowers)
                    {
                        if (objFindPower.Name == "Fear")
                        {
                            blnAddPower = false;
                            break;
                        }
                    }
                    if (blnAddPower)
                    {
                        objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"Fear\"]");
                        objNode = new TreeNode();
                        objPower = new CritterPower(_objCharacter);
                        objPower.Create(objXmlCritterPower, _objCharacter, objNode, 0, "");
                        objPower.CountTowardsLimit = false;
                        _objCharacter.CritterPowers.Add(objPower);
                    }

                    // Natural Weapon.
                    objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"Natural Weapon\"]");
                    objNode = new TreeNode();
                    objPower = new CritterPower(_objCharacter);
                    objPower.Create(objXmlCritterPower, _objCharacter, objNode, 0, "DV " + intForce.ToString() + "P, AP 0");
                    objPower.CountTowardsLimit = false;
                    _objCharacter.CritterPowers.Add(objPower);

                    // Evanescence.
                    blnAddPower = true;
                    foreach (CritterPower objFindPower in _objCharacter.CritterPowers)
                    {
                        if (objFindPower.Name == "Evanescence")
                        {
                            blnAddPower = false;
                            break;
                        }
                    }
                    if (blnAddPower)
                    {
                        objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"Evanescence\"]");
                        objNode = new TreeNode();
                        objPower = new CritterPower(_objCharacter);
                        objPower.Create(objXmlCritterPower, _objCharacter, objNode, 0, "");
                        objPower.CountTowardsLimit = false;
                        _objCharacter.CritterPowers.Add(objPower);
                    }
                }

                // Remove the Critter's Materialization Power if they have it. Add the Possession or Inhabitation Power if the Possession-based Tradition checkbox is checked.
                if (chkPossessionBased.Checked)
                {
                    foreach (CritterPower objCritterPower in _objCharacter.CritterPowers)
                    {
                        if (objCritterPower.Name == "Materialization")
                        {
                            _objCharacter.CritterPowers.Remove(objCritterPower);
                            break;
                        }
                    }

                    // Add the selected Power.
                    XmlNode objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"" + cboPossessionMethod.SelectedValue.ToString() + "\"]");
                    TreeNode objNode = new TreeNode();
                    CritterPower objPower = new CritterPower(_objCharacter);
                    objPower.Create(objXmlCritterPower, _objCharacter, objNode, 0, "");
                    objPower.CountTowardsLimit = false;
                    _objCharacter.CritterPowers.Add(objPower);
                }

                // Set the Skill Ratings for the Critter.
                foreach (XmlNode objXmlSkill in objXmlCritter.SelectNodes("skills/skill"))
                {
                    if (objXmlSkill.InnerText.Contains("Exotic"))
                    {
                        Skill objExotic = new Skill(_objCharacter);
                        objExotic.ExoticSkill = true;
                        objExotic.Attribute = "AGI";
                        if (objXmlSkill.Attributes["spec"] != null)
                        {
                            SkillSpecialization objSpec = new SkillSpecialization(objXmlSkill.Attributes["spec"].InnerText);
                            objExotic.Specializations.Add(objSpec);
                        }
                        if (Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0)) > 6)
                            objExotic.RatingMaximum = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0));
                        objExotic.Rating = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0));
                        objExotic.Name = objXmlSkill.InnerText;
                        _objCharacter.Skills.Add(objExotic);
                    }
                    else
                    {
                        foreach (Skill objSkill in _objCharacter.Skills)
                        {
                            if (objSkill.Name == objXmlSkill.InnerText)
                            {
                                if (objXmlSkill.Attributes["spec"] != null)
                                {
                                    SkillSpecialization objSpec = new SkillSpecialization(objXmlSkill.Attributes["spec"].InnerText);
                                    objSkill.Specializations.Add(objSpec);
                                }
                                if (Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0)) > 6)
                                    objSkill.RatingMaximum = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0));
                                objSkill.Rating = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0));
                                break;
                            }
                        }
                    }
                }

                // Set the Skill Group Ratings for the Critter.
                foreach (XmlNode objXmlSkill in objXmlCritter.SelectNodes("skills/group"))
                {
                    foreach (SkillGroup objSkill in _objCharacter.SkillGroups)
                    {
                        if (objSkill.Name == objXmlSkill.InnerText)
                        {
                            objSkill.RatingMaximum = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0));
                            objSkill.Rating = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0));
                            break;
                        }
                    }
                }

                // Set the Knowledge Skill Ratings for the Critter.
                foreach (XmlNode objXmlSkill in objXmlCritter.SelectNodes("skills/knowledge"))
                {
                    Skill objKnowledge = new Skill(_objCharacter);
                    objKnowledge.Name = objXmlSkill.InnerText;
                    objKnowledge.KnowledgeSkill = true;
                    if (objXmlSkill.Attributes["spec"] != null)
                    {
                        SkillSpecialization objSpec = new SkillSpecialization(objXmlSkill.Attributes["spec"].InnerText);
                        objKnowledge.Specializations.Add(objSpec);
                    }
                    objKnowledge.SkillCategory = objXmlSkill.Attributes["category"].InnerText;
                    if (Convert.ToInt32(objXmlSkill.Attributes["rating"].InnerText) > 6)
                        objKnowledge.RatingMaximum = Convert.ToInt32(objXmlSkill.Attributes["rating"].InnerText);
                    objKnowledge.Rating = Convert.ToInt32(objXmlSkill.Attributes["rating"].InnerText);
                    _objCharacter.Skills.Add(objKnowledge);
                }

                // If this is a Critter with a Force (which dictates their Skill Rating/Maximum Skill Rating), set their Skill Rating Maximums.
                if (intForce > 0)
                {
                    int intMaxRating = intForce;
                    // Determine the highest Skill Rating the Critter has.
                    foreach (Skill objSkill in _objCharacter.Skills)
                    {
                        if (objSkill.RatingMaximum > intMaxRating)
                            intMaxRating = objSkill.RatingMaximum;
                    }

                    // Now that we know the upper limit, set all of the Skill Rating Maximums to match.
                    foreach (Skill objSkill in _objCharacter.Skills)
                        objSkill.RatingMaximum = intMaxRating;
                    foreach (SkillGroup objGroup in _objCharacter.SkillGroups)
                        objGroup.RatingMaximum = intMaxRating;

                    // Set the MaxSkillRating for the character so it can be used later when they add new Knowledge Skills or Exotic Skills.
                    _objCharacter.MaxSkillRating = intMaxRating;
                }

                // Add any Complex Forms the Critter comes with (typically Sprites)
                XmlDocument objXmlProgramDocument = XmlManager.Instance.Load("complexforms.xml");
                foreach (XmlNode objXmlComplexForm in objXmlCritter.SelectNodes("complexforms/complexform"))
                {
                    string strForceValue = "";
                    if (objXmlComplexForm.Attributes["select"] != null)
                        strForceValue = objXmlComplexForm.Attributes["select"].InnerText;
                    XmlNode objXmlProgram = objXmlProgramDocument.SelectSingleNode("/chummer/complexforms/complexform[name = \"" + objXmlComplexForm.InnerText + "\"]");
                    TreeNode objNode = new TreeNode();
                    ComplexForm objProgram = new ComplexForm(_objCharacter);
                    objProgram.Create(objXmlProgram, _objCharacter, objNode, strForceValue);
                    _objCharacter.ComplexForms.Add(objProgram);
                }

                // Add any Gear the Critter comes with (typically Programs for A.I.s)
                XmlDocument objXmlGearDocument = XmlManager.Instance.Load("gear.xml");
                foreach (XmlNode objXmlGear in objXmlCritter.SelectNodes("gears/gear"))
                {
                    int intRating = 0;
                    if (objXmlGear.Attributes["rating"] != null)
                        intRating = Convert.ToInt32(ExpressionToString(objXmlGear.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0));
                    string strForceValue = "";
                    if (objXmlGear.Attributes["select"] != null)
                        strForceValue = objXmlGear.Attributes["select"].InnerText;
                    XmlNode objXmlGearItem = objXmlGearDocument.SelectSingleNode("/chummer/gears/gear[name = \"" + objXmlGear.InnerText + "\"]");
                    TreeNode objNode = new TreeNode();
                    Gear objGear = new Gear(_objCharacter);
                    List<Weapon> lstWeapons = new List<Weapon>();
                    List<TreeNode> lstWeaponNodes = new List<TreeNode>();
                    objGear.Create(objXmlGearItem, _objCharacter, objNode, intRating, lstWeapons, lstWeaponNodes, strForceValue);
                    objGear.Cost = "0";
                    objGear.Cost3 = "0";
                    objGear.Cost6 = "0";
                    objGear.Cost10 = "0";
                    _objCharacter.Gear.Add(objGear);
                }

                // If this is a Mutant Critter, count up the number of Skill points they start with.
                if (_objCharacter.MetatypeCategory == "Mutant Critters")
                {
                    foreach (Skill objSkill in _objCharacter.Skills)
                        _objCharacter.MutantCritterBaseSkills += objSkill.Rating;
                }

                // begin priority based character settings
                // Load the Priority information.
                XmlDocument objXmlDocumentPriority = XmlManager.Instance.Load(_strPrioritiesXmlFile);

                // Set the character priority selections
                _objCharacter.MetatypePriority = cboHeritage.Text.ToString();
                _objCharacter.AttributesPriority = cboAttributes.Text.ToString();
                _objCharacter.SpecialPriority = cboTalent.Text.ToString();
                _objCharacter.SkillsPriority = cboSkills.Text.ToString();
                _objCharacter.ResourcesPriority = cboResources.Text.ToString();

                // Set starting nuyen
                XmlNodeList objXmResourceList = objXmlDocumentPriority.SelectNodes("/chummer/priorities/priority[category = \"Resources\" and gameplayoption = \"" + _objCharacter.GameplayOption + "\" and value = \"" + cboResources.SelectedValue + "\"]");
                if (objXmResourceList.Count > 0)
                {
                    _objCharacter.Nuyen = Convert.ToInt32(objXmResourceList[0]["resources"].InnerText.ToString());
                    _objCharacter.StartingNuyen = _objCharacter.Nuyen;
                }

                // Set starting positive qualities
                foreach (XmlNode objXmlQualityItem in objXmlDocumentPriority.SelectNodes("/chummer/priorities/priority[category = \"Talent\" and value = \"" + cboTalent.SelectedValue + "\"]/talents/talent[value = \"" + cboTalents.SelectedValue + "\"]/qualities/quality"))
                {
                    XmlNode objXmlQuality = objXmlQualityDocument.SelectSingleNode("/chummer/qualities/quality[name = \"" + objXmlQualityItem.InnerText + "\"]");
                    TreeNode objNode = new TreeNode();
                    List<Weapon> objWeapons = new List<Weapon>();
                    List<TreeNode> objWeaponNodes = new List<TreeNode>();
                    Quality objQuality = new Quality(_objCharacter);
                    string strForceValue = "";
                    if (objXmlQualityItem.Attributes["select"] != null)
                        strForceValue = objXmlQualityItem.Attributes["select"].InnerText;
                    QualitySource objSource = new QualitySource();
                    objSource = QualitySource.Metatype;
                    if (objXmlQualityItem.Attributes["removable"] != null)
                        objSource = QualitySource.MetatypeRemovable;
                    objQuality.Create(objXmlQuality, _objCharacter, objSource, objNode, objWeapons, objWeaponNodes, strForceValue);
                    _objCharacter.Qualities.Add(objQuality);

                    // Add any created Weapons to the character.
                    foreach (Weapon objWeapon in objWeapons)
                        _objCharacter.Weapons.Add(objWeapon);
                }

                // Set starting magic
                XmlNodeList objXmlTalentList = objXmlDocumentPriority.SelectNodes("/chummer/priorities/priority[category = \"Talent\" and value = \"" + cboTalent.SelectedValue + "\"]/talents/talent[value = \"" + cboTalents.SelectedValue + "\"]");
                if (objXmlTalentList[0]["magic"] != null)
                {
                    _objCharacter.MAG.Value = Convert.ToInt32(objXmlTalentList[0]["magic"].InnerText);
                    _objCharacter.MAG.MetatypeMinimum = Convert.ToInt32(objXmlTalentList[0]["magic"].InnerText);
                    if (_objCharacter.MAG.Value > 0)
                        _objCharacter.MAGEnabled = true;
                    if (objXmlTalentList[0]["spells"] != null)
                    {
                        _objCharacter.SpellLimit = Convert.ToInt32(objXmlTalentList[0]["spells"].InnerText);
                    }
                    else
                    {
                        _objCharacter.SpellLimit = 0;
                    }
                }

                if (objXmlTalentList[0]["maxmagic"] != null)
                    _objCharacter.MAG.MetatypeMaximum = Convert.ToInt32(objXmlTalentList[0]["magic"].InnerText);

                // Set starting resonance
                objXmlTalentList = objXmlDocumentPriority.SelectNodes("/chummer/priorities/priority[category = \"Talent\" and value = \"" + cboTalent.SelectedValue + "\"]/talents/talent[value = \"" + cboTalents.SelectedValue + "\"]");
                if (objXmlTalentList[0]["resonance"] != null)
                {
                    _objCharacter.RES.Value = Convert.ToInt32(objXmlTalentList[0]["resonance"].InnerText);
                    _objCharacter.RES.MetatypeMinimum = Convert.ToInt32(objXmlTalentList[0]["resonance"].InnerText);
                    _objCharacter.RESEnabled = true;
                    _objCharacter.CFPLimit = Convert.ToInt32(objXmlTalentList[0]["cfp"].InnerText);
                }

                if (objXmlTalentList[0]["maxresonance"] != null)
                    _objCharacter.RES.MetatypeMaximum = Convert.ToInt32(objXmlTalentList[0]["resonance"].InnerText);

                // Set starting talent tabs
                switch (cboTalents.SelectedValue.ToString())
                {
                    case "Magician":
                        _objCharacter.MagicianEnabled = true;
                        break;
                    case "Aspected Magician":
                        _objCharacter.MagicianEnabled = true;
                        break;
                    case "Adept":
                        _objCharacter.AdeptEnabled = true;
                        break;
                    case "Mystic Adept":
                        _objCharacter.MagicianEnabled = true;
                        _objCharacter.AdeptEnabled = true;
                        break;
                    case "Technomancer":
                        _objCharacter.TechnomancerEnabled = true;
                        break;
                    default:
                        break;
                }

                // Set Free Skills/Skill Groups
                int intFreeLevels = 0;
                bool blnGroup = (cboTalents.SelectedValue.ToString() == "Aspected Magician");
                if (cboTalent.SelectedValue.ToString() == "A")
                    intFreeLevels = 5;
                else if (cboTalent.SelectedValue.ToString() == "B")
                    intFreeLevels = 4;
                else if (cboTalent.SelectedValue.ToString() == "C")
                    intFreeLevels = 2;
                foreach (Skill objSkill in _objCharacter.Skills)
                {
                    if (cboSkill1.Visible && objSkill.Name == cboSkill1.Text && !blnGroup)
                    {
                        objSkill.FreeLevels = intFreeLevels;
                        if (objSkill.Rating < intFreeLevels)
                            objSkill.Rating = intFreeLevels;
                        _objCharacter.PriorityBonusSkill1 = cboSkill1.Text.ToString();
                    }
                    else if (cboSkill2.Visible && objSkill.Name == cboSkill2.Text && !blnGroup)
                    {
                        objSkill.FreeLevels = intFreeLevels;
                        if (objSkill.Rating < intFreeLevels)
                            objSkill.Rating = intFreeLevels;
                        _objCharacter.PriorityBonusSkill2 = cboSkill2.Text.ToString();
                    }
                    else
                    {
                        objSkill.FreeLevels = 0;
                        if (blnGroup)
                        {
                            // if this skill is a magical skill not belonging to the selected group, reduce the skill maximum to 0
                            if (objSkill.SkillGroup == "Conjuring" || objSkill.SkillGroup == "Enchanting" || objSkill.SkillGroup == "Sorcery")
                            {
                                if (objSkill.SkillGroup != cboSkill1.SelectedValue.ToString())
                                    objSkill.RatingMaximum = 0;
                                else
                                {
                                    if (_objCharacter.IgnoreRules)
                                        objSkill.RatingMaximum = 12;
                                    else
                                        objSkill.RatingMaximum = 6;
                                }
                                _objCharacter.PriorityBonusSkillGroup = cboSkill1.Text.ToString();
                            }
                        }
                    }
                }
                foreach (SkillGroup objSkillGroup in _objCharacter.SkillGroups)
                {
                    if (cboSkill1.Visible && objSkillGroup.Name == cboSkill1.Text && blnGroup)
                    {
                        objSkillGroup.FreeLevels = intFreeLevels;
                        if (objSkillGroup.Base < intFreeLevels)
                            objSkillGroup.Base = intFreeLevels;
                        _objCharacter.PriorityBonusSkillGroup = cboSkill1.Text.ToString();
                    }
                    else
                        objSkillGroup.FreeLevels = 0;

                    if (blnGroup)
                    {
                        // if this skill is a magical skill not belonging to the selected group, reduce the skill maximum to 0
                        if (objSkillGroup.Name == "Conjuring" || objSkillGroup.Name == "Enchanting" || objSkillGroup.Name == "Sorcery")
                        {
                            if (objSkillGroup.Name != cboSkill1.SelectedValue.ToString())
                                objSkillGroup.RatingMaximum = 0;
                            else
                            {
                                if (_objCharacter.IgnoreRules)
                                    objSkillGroup.RatingMaximum = 12;
                                else
                                    objSkillGroup.RatingMaximum = 6;
                            }
                        }
                    }
                }

                // Ignore Rules
                if (_objCharacter.IgnoreRules)
                {
                    foreach (Skill objSkill in _objCharacter.Skills)
                    {
                        objSkill.RatingMaximum = 99;
                    }
                    foreach (SkillGroup objSkillGroup in _objCharacter.SkillGroups)
                    {
                        objSkillGroup.RatingMaximum = 99;
                    }
                }

                // Set Special Attributes
                _objCharacter.Special = Convert.ToInt32(lblSpecial.Text);
                _objCharacter.TotalSpecial = Convert.ToInt32(lblSpecial.Text);

                // Set Attributes
                XmlNodeList objXmlPriorityList = objXmlDocumentPriority.SelectNodes("/chummer/priorities/priority[category = \"Attributes\" and value = \"" + cboAttributes.SelectedValue + "\"]");
                if (objXmlPriorityList[0]["attributes"] != null)
                {
                    _objCharacter.Attributes = Convert.ToInt32(objXmlPriorityList[0]["attributes"].InnerText);
                    _objCharacter.TotalAttributes = _objCharacter.Attributes;
                }

                // Set Skills and Skill Groups
                objXmlPriorityList = objXmlDocumentPriority.SelectNodes("/chummer/priorities/priority[category = \"Skills\" and value = \"" + cboSkills.SelectedValue + "\"]");
                if (objXmlPriorityList[0]["skills"] != null)
                {
                    _objCharacter.SkillPoints = Convert.ToInt32(objXmlPriorityList[0]["skills"].InnerText);
                    _objCharacter.SkillPointsMaximum = _objCharacter.SkillPoints;
                    _objCharacter.SkillGroupPoints = Convert.ToInt32(objXmlPriorityList[0]["skillgroups"].InnerText);
                    _objCharacter.SkillGroupPointsMaximum = _objCharacter.SkillGroupPoints;
                }

                // Load the Priority information.
                XmlNode objXmlGameplayOption = objXmlDocumentPriority.SelectSingleNode("/chummer/gameplayoptions/gameplayoption[name = \"" + _objCharacter.GameplayOption + "\"]");
                string strKarma = objXmlGameplayOption["karma"].InnerText;
                string strNuyen = objXmlGameplayOption["maxnuyen"].InnerText;
                string strContactMultiplier = objXmlGameplayOption["contactmultiplier"].InnerText;
                _objCharacter.MaxKarma = Convert.ToInt32(strKarma);
                _objCharacter.MaxNuyen = Convert.ToInt32(strNuyen);
                _objCharacter.ContactMultiplier = Convert.ToInt32(strContactMultiplier);

                // Set free contact points
                _objCharacter.ContactPoints = _objCharacter.CHA.Value * _objCharacter.ContactMultiplier;

                // Set starting karma
                _objCharacter.BuildKarma = _objCharacter.MaxKarma;

                // Set starting movement rate
                _objCharacter.Movement = (_objCharacter.AGI.TotalValue * 2).ToString() + "/" + (_objCharacter.AGI.TotalValue * 4).ToString();

                this.DialogResult = DialogResult.OK;
                this.Close();
            }
            else
            {
                MessageBox.Show(LanguageManager.Instance.GetString("Message_Metatype_SelectMetatype"), LanguageManager.Instance.GetString("MessageTitle_Metatype_SelectMetatype"), MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
Example #12
0
        /// <summary>
        /// Load the Character from an XML file.
        /// </summary>
        public bool Load()
        {
            XmlDocument objXmlDocument = new XmlDocument();
            objXmlDocument.Load(_strFileName);

            XmlNode objXmlCharacter = objXmlDocument.SelectSingleNode("/character");
            XmlNodeList objXmlNodeList;

            try
            {
                _blnIgnoreRules = Convert.ToBoolean(objXmlCharacter["ignorerules"].InnerText);
            }
            catch
            {
                _blnIgnoreRules = false;
            }
            try
            {
                _blnCreated = Convert.ToBoolean(objXmlCharacter["created"].InnerText);
            }
            catch
            {
            }

            ResetCharacter();

            // Get the game edition of the file if possible and make sure it's intended to be used with this version of the application.
            try
            {
                if (objXmlCharacter["gameedition"].InnerText != string.Empty && objXmlCharacter["gameedition"].InnerText != "SR4")
                {
                    MessageBox.Show(LanguageManager.Instance.GetString("Message_IncorrectGameVersion_SR5"), LanguageManager.Instance.GetString("MessageTitle_IncorrectGameVersion"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return false;
                }
            }
            catch
            {
            }

            // Get the name of the settings file in use if possible.
            try
            {
                _strSettingsFileName = objXmlCharacter["settings"].InnerText;
            }
            catch
            {
            }

            // Load the character's settings file.
            if (!_objOptions.Load(_strSettingsFileName))
                return false;

            try
            {
                _decEssenceAtSpecialStart = Convert.ToDecimal(objXmlCharacter["essenceatspecialstart"].InnerText, GlobalOptions.Instance.CultureInfo);
                // fix to work around a mistake made when saving decimal values in previous versions.
                if (_decEssenceAtSpecialStart > EssenceMaximum)
                    _decEssenceAtSpecialStart /= 10;
            }
            catch
            {
            }

            // Metatype information.
            _strMetatype = objXmlCharacter["metatype"].InnerText;
            try
            {
                _strMovement = objXmlCharacter["movement"].InnerText;
            }
            catch
            {
            }
            _intMetatypeBP = Convert.ToInt32(objXmlCharacter["metatypebp"].InnerText);
            _strMetavariant = objXmlCharacter["metavariant"].InnerText;
            try
            {
                _strMetatypeCategory = objXmlCharacter["metatypecategory"].InnerText;
            }
            catch
            {
            }
            try
            {
                _intMutantCritterBaseSkills = Convert.ToInt32(objXmlCharacter["mutantcritterbaseskills"].InnerText);
            }
            catch
            {
            }

            // General character information.
            _strName = objXmlCharacter["name"].InnerText;
            try
            {
                _strMugshot = objXmlCharacter["mugshot"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strSex = objXmlCharacter["sex"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strAge = objXmlCharacter["age"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strEyes = objXmlCharacter["eyes"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strHeight = objXmlCharacter["height"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strWeight = objXmlCharacter["weight"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strSkin = objXmlCharacter["skin"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strHair = objXmlCharacter["hair"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strDescription = objXmlCharacter["description"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strBackground = objXmlCharacter["background"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strConcept = objXmlCharacter["concept"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strNotes = objXmlCharacter["notes"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strAlias = objXmlCharacter["alias"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strPlayerName = objXmlCharacter["playername"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strGameNotes = objXmlCharacter["gamenotes"].InnerText;
            }
            catch
            {
            }

            try
            {
                _blnIsCritter = Convert.ToBoolean(objXmlCharacter["iscritter"].InnerText);
            }
            catch
            {
            }

            try
            {
                _blnPossessed = Convert.ToBoolean(objXmlCharacter["possessed"].InnerText);
            }
            catch
            {
            }

            try
            {
                _blnOverrideSpecialAttributeESSLoss = Convert.ToBoolean(objXmlCharacter["overridespecialattributeessloss"].InnerText);
            }
            catch
            {
            }

            try
            {
                _intKarma = Convert.ToInt32(objXmlCharacter["karma"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intTotalKarma = Convert.ToInt32(objXmlCharacter["totalkarma"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intStreetCred = Convert.ToInt32(objXmlCharacter["streetcred"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intNotoriety = Convert.ToInt32(objXmlCharacter["notoriety"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intPublicAwareness = Convert.ToInt32(objXmlCharacter["publicawareness"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intBurntStreetCred = Convert.ToInt32(objXmlCharacter["burntstreetcred"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intMaxAvail = Convert.ToInt32(objXmlCharacter["maxavail"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intNuyen = Convert.ToInt32(objXmlCharacter["nuyen"].InnerText);
            }
            catch
            {
            }

            // Build Points/Karma.
            _intBuildPoints = Convert.ToInt32(objXmlCharacter["bp"].InnerText);
            try
            {
                _intBuildKarma = Convert.ToInt32(objXmlCharacter["buildkarma"].InnerText);
            }
            catch
            {
            }
            try
            {
                _objBuildMethod = ConvertToCharacterBuildMethod(objXmlCharacter["buildmethod"].InnerText);
            }
            catch
            {
            }
            _intKnowledgeSkillPoints = Convert.ToInt32(objXmlCharacter["knowpts"].InnerText);
            _decNuyenBP = Convert.ToDecimal(objXmlCharacter["nuyenbp"].InnerText, GlobalOptions.Instance.CultureInfo);
            _decNuyenMaximumBP = Convert.ToDecimal(objXmlCharacter["nuyenmaxbp"].InnerText, GlobalOptions.Instance.CultureInfo);
            _blnAdeptEnabled = Convert.ToBoolean(objXmlCharacter["adept"].InnerText);
            _blnMagicianEnabled = Convert.ToBoolean(objXmlCharacter["magician"].InnerText);
            _blnTechnomancerEnabled = Convert.ToBoolean(objXmlCharacter["technomancer"].InnerText);
            try
            {
                _blnInitiationEnabled = Convert.ToBoolean(objXmlCharacter["initiationoverride"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnCritterEnabled = Convert.ToBoolean(objXmlCharacter["critter"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnUneducated = Convert.ToBoolean(objXmlCharacter["uneducated"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnUncouth = Convert.ToBoolean(objXmlCharacter["uncouth"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnInfirm = Convert.ToBoolean(objXmlCharacter["infirm"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnBlackMarket = Convert.ToBoolean(objXmlCharacter["blackmarket"].InnerText);
            }
            catch
            {
            }
            _blnMAGEnabled = Convert.ToBoolean(objXmlCharacter["magenabled"].InnerText);
            try
            {
                _intInitiateGrade = Convert.ToInt32(objXmlCharacter["initiategrade"].InnerText);
            }
            catch
            {
            }
            _blnRESEnabled = Convert.ToBoolean(objXmlCharacter["resenabled"].InnerText);
            try
            {
                _intSubmersionGrade = Convert.ToInt32(objXmlCharacter["submersiongrade"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnGroupMember = Convert.ToBoolean(objXmlCharacter["groupmember"].InnerText);
            }
            catch
            {
            }
            try
            {
                _strGroupName = objXmlCharacter["groupname"].InnerText;
                _strGroupNotes = objXmlCharacter["groupnotes"].InnerText;
            }
            catch
            {
            }

            // Improvements.
            XmlNodeList objXmlImprovementList = objXmlDocument.SelectNodes("/character/improvements/improvement");
            foreach (XmlNode objXmlImprovement in objXmlImprovementList)
            {
                Improvement objImprovement = new Improvement();
                objImprovement.Load(objXmlImprovement);
                _lstImprovements.Add(objImprovement);
            }

            // Qualities
            objXmlNodeList = objXmlDocument.SelectNodes("/character/qualities/quality");
            bool blnHasOldQualities = false;
            foreach (XmlNode objXmlQuality in objXmlNodeList)
            {
                if (objXmlQuality["name"] != null)
                {
                    Quality objQuality = new Quality(this);
                    objQuality.Load(objXmlQuality);
                    _lstQualities.Add(objQuality);
                }
                else
                {
                    // If the Quality does not have a name tag, it is in the old format. Set the flag to show that old Qualities are in use.
                    blnHasOldQualities = true;
                }
            }
            // If old Qualities are in use, they need to be converted before we can continue.
            if (blnHasOldQualities)
                ConvertOldQualities(objXmlNodeList);

            // Attributes.
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"BOD\"]");
            _attBOD.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"AGI\"]");
            _attAGI.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"REA\"]");
            _attREA.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"STR\"]");
            _attSTR.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"CHA\"]");
            _attCHA.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"INT\"]");
            _attINT.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"LOG\"]");
            _attLOG.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"WIL\"]");
            _attWIL.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"INI\"]");
            _attINI.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"EDG\"]");
            _attEDG.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"MAG\"]");
            _attMAG.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"RES\"]");
            _attRES.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"ESS\"]");
            _attESS.Load(objXmlCharacter);

            // A.I. Attributes.
            try
            {
                _intSignal = Convert.ToInt32(objXmlDocument.SelectSingleNode("/character/attributes/signal").InnerText);
                _intResponse = Convert.ToInt32(objXmlDocument.SelectSingleNode("/character/attributes/response").InnerText);
            }
            catch
            {
            }

            // Force.
            try
            {
                _intMaxSkillRating = Convert.ToInt32(objXmlDocument.SelectSingleNode("/character/attributes/maxskillrating").InnerText);
            }
            catch
            {
            }

            // Attempt to load the split MAG Attribute information for Mystic Adepts.
            if (_blnAdeptEnabled && _blnMagicianEnabled)
            {
                try
                {
                    _intMAGAdept = Convert.ToInt32(objXmlDocument.SelectSingleNode("/character/magsplitadept").InnerText);
                    _intMAGMagician = Convert.ToInt32(objXmlDocument.SelectSingleNode("/character/magsplitmagician").InnerText);
                }
                catch
                {
                }
            }

            // Attempt to load the Magic Tradition.
            try
            {
                _strMagicTradition = objXmlDocument.SelectSingleNode("/character/tradition").InnerText;
            }
            catch
            {
            }
            // Attempt to load the Technomancer Stream.
            try
            {
                _strTechnomancerStream = objXmlDocument.SelectSingleNode("/character/stream").InnerText;
            }
            catch
            {
            }

            // Attempt to load Condition Monitor Progress.
            try
            {
                _intPhysicalCMFilled = Convert.ToInt32(objXmlDocument.SelectSingleNode("/character/physicalcmfilled").InnerText);
                _intStunCMFilled = Convert.ToInt32(objXmlDocument.SelectSingleNode("/character/stuncmfilled").InnerText);
            }
            catch
            {
            }

            // Skills.
            foreach (Skill objSkill in _lstSkills)
            {
                XmlNode objXmlSkill = objXmlDocument.SelectSingleNode("/character/skills/skill[name = \"" + objSkill.Name + "\"]");
                if (objXmlSkill != null)
                {
                    objSkill.Load(objXmlSkill);
                }
            }

            // Exotic Skills.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/skills/skill[exotic = \"True\"]");
            foreach (XmlNode objXmlSkill in objXmlNodeList)
            {
                Skill objSkill = new Skill(this);
                objSkill.Load(objXmlSkill);
                _lstSkills.Add(objSkill);
            }

            // SkillGroups.
            foreach (SkillGroup objGroup in _lstSkillGroups)
            {
                XmlNode objXmlSkill = objXmlDocument.SelectSingleNode("/character/skillgroups/skillgroup[name = \"" + objGroup.Name + "\"]");
                if (objXmlSkill != null)
                {
                    objGroup.Load(objXmlSkill);
                    // If the character is set to ignore rules or is in Career Mode, Skill Groups should have a maximum Rating of 6 unless they have been given a higher maximum Rating already.
                    if ((_blnIgnoreRules || _blnCreated) && objGroup.RatingMaximum < 6)
                        objGroup.RatingMaximum = 6;
                }
            }

            // Knowledge Skills.
            List<ListItem> lstKnowledgeSkillOrder = new List<ListItem>();
            objXmlNodeList = objXmlDocument.SelectNodes("/character/skills/skill[knowledge = \"True\"]");
            // Sort the Knowledge Skills in alphabetical order.
            foreach (XmlNode objXmlSkill in objXmlNodeList)
            {
                ListItem objGroup = new ListItem();
                objGroup.Value = objXmlSkill["name"].InnerText;
                objGroup.Name = objXmlSkill["name"].InnerText;
                lstKnowledgeSkillOrder.Add(objGroup);
            }
            SortListItem objSort = new SortListItem();
            lstKnowledgeSkillOrder.Sort(objSort.Compare);

            foreach (ListItem objItem in lstKnowledgeSkillOrder)
            {
                Skill objSkill = new Skill(this);
                XmlNode objNode = objXmlDocument.SelectSingleNode("/character/skills/skill[knowledge = \"True\" and name = " + CleanXPath(objItem.Value) + "]");
                objSkill.Load(objNode);
                _lstSkills.Add(objSkill);
            }

            // Contacts.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/contacts/contact");
            foreach (XmlNode objXmlContact in objXmlNodeList)
            {
                Contact objContact = new Contact(this);
                objContact.Load(objXmlContact);
                _lstContacts.Add(objContact);
            }

            // Armor.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/armors/armor");
            foreach (XmlNode objXmlArmor in objXmlNodeList)
            {
                Armor objArmor = new Armor(this);
                objArmor.Load(objXmlArmor);
                _lstArmor.Add(objArmor);
            }

            // Weapons.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/weapons/weapon");
            foreach (XmlNode objXmlWeapon in objXmlNodeList)
            {
                Weapon objWeapon = new Weapon(this);
                objWeapon.Load(objXmlWeapon);
                _lstWeapons.Add(objWeapon);
            }

            // Cyberware/Bioware.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/cyberwares/cyberware");
            foreach (XmlNode objXmlCyberware in objXmlNodeList)
            {
                Cyberware objCyberware = new Cyberware(this);
                objCyberware.Load(objXmlCyberware);
                _lstCyberware.Add(objCyberware);
            }

            // Spells.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/spells/spell");
            foreach (XmlNode objXmlSpell in objXmlNodeList)
            {
                Spell objSpell = new Spell(this);
                objSpell.Load(objXmlSpell);
                _lstSpells.Add(objSpell);
            }

            // Foci.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/foci/focus");
            foreach (XmlNode objXmlFocus in objXmlNodeList)
            {
                Focus objFocus = new Focus();
                objFocus.Load(objXmlFocus);
                _lstFoci.Add(objFocus);
            }

            // Stacked Foci.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/stackedfoci/stackedfocus");
            foreach (XmlNode objXmlStack in objXmlNodeList)
            {
                StackedFocus objStack = new StackedFocus(this);
                objStack.Load(objXmlStack);
                _lstStackedFoci.Add(objStack);
            }

            // Powers.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/powers/power");
            foreach (XmlNode objXmlPower in objXmlNodeList)
            {
                Power objPower = new Power(this);
                objPower.Load(objXmlPower);
                _lstPowers.Add(objPower);
            }

            // Spirits/Sprites.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/spirits/spirit");
            foreach (XmlNode objXmlSpirit in objXmlNodeList)
            {
                Spirit objSpirit = new Spirit(this);
                objSpirit.Load(objXmlSpirit);
                _lstSpirits.Add(objSpirit);
            }

            // Compex Forms/Technomancer Programs.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/techprograms/techprogram");
            foreach (XmlNode objXmlProgram in objXmlNodeList)
            {
                TechProgram objProgram = new TechProgram(this);
                objProgram.Load(objXmlProgram);
                _lstTechPrograms.Add(objProgram);
            }

            // Martial Arts.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/martialarts/martialart");
            foreach (XmlNode objXmlArt in objXmlNodeList)
            {
                MartialArt objMartialArt = new MartialArt(this);
                objMartialArt.Load(objXmlArt);
                _lstMartialArts.Add(objMartialArt);
            }

            // Martial Art Maneuvers.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/martialartmaneuvers/martialartmaneuver");
            foreach (XmlNode objXmlManeuver in objXmlNodeList)
            {
                MartialArtManeuver objManeuver = new MartialArtManeuver(this);
                objManeuver.Load(objXmlManeuver);
                _lstMartialArtManeuvers.Add(objManeuver);
            }

            // Lifestyles.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/lifestyles/lifestyle");
            foreach (XmlNode objXmlLifestyle in objXmlNodeList)
            {
                Lifestyle objLifestyle = new Lifestyle(this);
                objLifestyle.Load(objXmlLifestyle);
                _lstLifestyles.Add(objLifestyle);
            }

            // <gears>
            objXmlNodeList = objXmlDocument.SelectNodes("/character/gears/gear");
            foreach (XmlNode objXmlGear in objXmlNodeList)
            {
                switch (objXmlGear["category"].InnerText)
                {
                    case "Commlink":
                    case "Commlink Upgrade":
                        Commlink objCommlink = new Commlink(this);
                        objCommlink.Load(objXmlGear);
                        _lstGear.Add(objCommlink);
                        break;
                    case "Commlink Operating System":
                    case "Commlink Operating System Upgrade":
                        OperatingSystem objOperatingSystem = new OperatingSystem(this);
                        objOperatingSystem.Load(objXmlGear);
                        _lstGear.Add(objOperatingSystem);
                        break;
                    default:
                        Gear objGear = new Gear(this);
                        objGear.Load(objXmlGear);
                        _lstGear.Add(objGear);
                        break;
                }
            }

            // Vehicles.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/vehicles/vehicle");
            foreach (XmlNode objXmlVehicle in objXmlNodeList)
            {
                Vehicle objVehicle = new Vehicle(this);
                objVehicle.Load(objXmlVehicle);
                _lstVehicles.Add(objVehicle);
            }

            // Metamagics/Echoes.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/metamagics/metamagic");
            foreach (XmlNode objXmlMetamagic in objXmlNodeList)
            {
                Metamagic objMetamagic = new Metamagic(this);
                objMetamagic.Load(objXmlMetamagic);
                _lstMetamagics.Add(objMetamagic);
            }

            // Critter Powers.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/critterpowers/critterpower");
            foreach (XmlNode objXmlPower in objXmlNodeList)
            {
                CritterPower objPower = new CritterPower(this);
                objPower.Load(objXmlPower);
                _lstCritterPowers.Add(objPower);
            }

            // Initiation Grades.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/initiationgrades/initiationgrade");
            foreach (XmlNode objXmlGrade in objXmlNodeList)
            {
                InitiationGrade objGrade = new InitiationGrade(this);
                objGrade.Load(objXmlGrade);
                _lstInitiationGrades.Add(objGrade);
            }

            // Expense Log Entries.
            XmlNodeList objXmlExpenseList = objXmlDocument.SelectNodes("/character/expenses/expense");
            foreach (XmlNode objXmlExpense in objXmlExpenseList)
            {
                ExpenseLogEntry objExpenseLogEntry = new ExpenseLogEntry();
                objExpenseLogEntry.Load(objXmlExpense);
                _lstExpenseLog.Add(objExpenseLogEntry);
            }

            // Locations.
            XmlNodeList objXmlLocationList = objXmlDocument.SelectNodes("/character/locations/location");
            foreach (XmlNode objXmlLocation in objXmlLocationList)
            {
                _lstLocations.Add(objXmlLocation.InnerText);
            }

            // Armor Bundles.
            XmlNodeList objXmlBundleList = objXmlDocument.SelectNodes("/character/armorbundles/armorbundle");
            foreach (XmlNode objXmlBundle in objXmlBundleList)
            {
                _lstArmorBundles.Add(objXmlBundle.InnerText);
            }

            // Weapon Locations.
            XmlNodeList objXmlWeaponLocationList = objXmlDocument.SelectNodes("/character/weaponlocations/weaponlocation");
            foreach (XmlNode objXmlLocation in objXmlWeaponLocationList)
            {
                _lstWeaponLocations.Add(objXmlLocation.InnerText);
            }

            // Improvement Groups.
            XmlNodeList objXmlGroupList = objXmlDocument.SelectNodes("/character/improvementgroups/improvementgroup");
            foreach (XmlNode objXmlGroup in objXmlGroupList)
            {
                _lstImprovementGroups.Add(objXmlGroup.InnerText);
            }

            // Calendar.
            XmlNodeList objXmlWeekList = objXmlDocument.SelectNodes("/character/calendar/week");
            foreach (XmlNode objXmlWeek in objXmlWeekList)
            {
                CalendarWeek objWeek = new CalendarWeek();
                objWeek.Load(objXmlWeek);
                _lstCalendar.Add(objWeek);
            }

            // If the character had old Qualities that were converted, immediately save the file so they are in the new format.
            if (blnHasOldQualities)
                Save();

            return true;
        }
Example #13
0
        /// <summary>
        /// Open the Select Cyberware window and handle adding to the Tree and Character.
        /// </summary>
        private bool PickCyberware(Improvement.ImprovementSource objSource = Improvement.ImprovementSource.Cyberware)
        {
            // Determine the lowest whole number for the character's current Essence.
            decimal decStartingESS = Math.Floor(_objCharacter.Essence);

            Cyberware objSelectedCyberware = new Cyberware(_objCharacter);
            int intNode = 0;
            if (objSource == Improvement.ImprovementSource.Bioware)
                intNode = 1;

            // Attempt to locate the selected piece of Cyberware.
            try
            {
                if (treCyberware.SelectedNode.Level > 0)
                    objSelectedCyberware = (Cyberware)_objFunctions.FindEquipment(treCyberware.SelectedNode.Tag.ToString(), _objCharacter.Cyberware, typeof(Cyberware));
            }
            catch
            {
            }

            frmSelectCyberware frmPickCyberware = new frmSelectCyberware(_objCharacter, true);
            double dblMultiplier = 1;
            // Apply the character's Cyberware Essence cost multiplier if applicable.
            if (_objImprovementManager.ValueOf(Improvement.ImprovementType.CyberwareEssCost) != 0 && objSource == Improvement.ImprovementSource.Cyberware)
            {
                foreach (Improvement objImprovement in _objCharacter.Improvements)
                {
                    if (objImprovement.ImproveType == Improvement.ImprovementType.CyberwareEssCost && objImprovement.Enabled)
                        dblMultiplier -= (1 - (Convert.ToDouble(objImprovement.Value, GlobalOptions.Instance.CultureInfo) / 100));
                }
                frmPickCyberware.CharacterESSMultiplier = dblMultiplier;
            }

            // Apply the character's Bioware Essence cost multiplier if applicable.
            if (_objImprovementManager.ValueOf(Improvement.ImprovementType.BiowareEssCost) != 0 && objSource == Improvement.ImprovementSource.Bioware)
            {
                foreach (Improvement objImprovement in _objCharacter.Improvements)
                {
                    if (objImprovement.ImproveType == Improvement.ImprovementType.BiowareEssCost && objImprovement.Enabled)
                        dblMultiplier -= (1 - (Convert.ToDouble(objImprovement.Value, GlobalOptions.Instance.CultureInfo) / 100));
                }
                frmPickCyberware.CharacterESSMultiplier = dblMultiplier;
            }

            // Apply the character's Basic Bioware Essence cost multiplier if applicable.
            if (_objImprovementManager.ValueOf(Improvement.ImprovementType.BasicBiowareEssCost) != 0 && objSource == Improvement.ImprovementSource.Bioware)
            {
                double dblBasicMultiplier = 1;
                foreach (Improvement objImprovement in _objCharacter.Improvements)
                {
                    if (objImprovement.ImproveType == Improvement.ImprovementType.BasicBiowareEssCost && objImprovement.Enabled)
                        dblBasicMultiplier -= (1 - (Convert.ToDouble(objImprovement.Value, GlobalOptions.Instance.CultureInfo) / 100));
                }
                frmPickCyberware.BasicBiowareESSMultiplier = dblBasicMultiplier;
            }

            // Genetech Cost multiplier.
            if (_objImprovementManager.ValueOf(Improvement.ImprovementType.GenetechCostMultiplier) != 0 && objSource == Improvement.ImprovementSource.Bioware)
            {
                dblMultiplier = 1;
                foreach (Improvement objImprovement in _objCharacter.Improvements)
                {
                    if (objImprovement.ImproveType == Improvement.ImprovementType.GenetechCostMultiplier && objImprovement.Enabled)
                        dblMultiplier -= (1 - (Convert.ToDouble(objImprovement.Value, GlobalOptions.Instance.CultureInfo) / 100));
                }
                frmPickCyberware.GenetechCostMultiplier = dblMultiplier;
            }

            // Transgenics Cost multiplier.
            if (_objImprovementManager.ValueOf(Improvement.ImprovementType.TransgenicsBiowareCost) != 0 && objSource == Improvement.ImprovementSource.Bioware)
            {
                dblMultiplier = 1;
                foreach (Improvement objImprovement in _objCharacter.Improvements)
                {
                    if (objImprovement.ImproveType == Improvement.ImprovementType.TransgenicsBiowareCost && objImprovement.Enabled)
                        dblMultiplier -= (1 - (Convert.ToDouble(objImprovement.Value, GlobalOptions.Instance.CultureInfo) / 100));
                }
                frmPickCyberware.TransgenicsBiowareCostMultiplier = dblMultiplier;
            }

            try
            {
                if (treCyberware.SelectedNode.Level > 0)
                {
                    frmPickCyberware.SetGrade = lblCyberwareGrade.Text;
                    frmPickCyberware.LockGrade();
                    // If the Cyberware has a Capacity with no brackets (meaning it grants Capacity), show only Subsystems (those that conume Capacity).
                    if (!objSelectedCyberware.Capacity.Contains('['))
                    {
                        frmPickCyberware.ShowOnlySubsystems = true;
                        frmPickCyberware.Subsystems = objSelectedCyberware.Subsytems;
                        frmPickCyberware.MaximumCapacity = objSelectedCyberware.CapacityRemaining;

                        // Do not allow the user to add a new piece of Cyberware if its Capacity has been reached.
                        if (_objOptions.EnforceCapacity && objSelectedCyberware.CapacityRemaining < 0)
                        {
                            MessageBox.Show(LanguageManager.Instance.GetString("Message_CapacityReached"), LanguageManager.Instance.GetString("MessageTitle_CapacityReached"), MessageBoxButtons.OK, MessageBoxIcon.Information);
                            return false;
                        }
                    }
                }
            }
            catch
            {
            }

            if (objSource == Improvement.ImprovementSource.Bioware)
                frmPickCyberware.WindowMode = frmSelectCyberware.Mode.Bioware;

            frmPickCyberware.AllowModularPlugins = objSelectedCyberware.AllowModularPlugins;

            frmPickCyberware.ShowDialog(this);

            // Make sure the dialogue window was not canceled.
            if (frmPickCyberware.DialogResult == DialogResult.Cancel)
                return false;

            // Open the Cyberware XML file and locate the selected piece.
            XmlDocument objXmlDocument = new XmlDocument();
            if (objSource == Improvement.ImprovementSource.Bioware)
                objXmlDocument = XmlManager.Instance.Load("bioware.xml");
            else
                objXmlDocument = XmlManager.Instance.Load("cyberware.xml");

            XmlNode objXmlCyberware;
            if (objSource == Improvement.ImprovementSource.Bioware)
                objXmlCyberware = objXmlDocument.SelectSingleNode("/chummer/biowares/bioware[id = \"" + frmPickCyberware.SelectedCyberware + "\"]");
            else
                objXmlCyberware = objXmlDocument.SelectSingleNode("/chummer/cyberwares/cyberware[id = \"" + frmPickCyberware.SelectedCyberware + "\"]");

            // Create the Cyberware object.
            Cyberware objCyberware = new Cyberware(_objCharacter);
            List<Weapon> objWeapons = new List<Weapon>();
            TreeNode objNode = new TreeNode();
            List<TreeNode> objWeaponNodes = new List<TreeNode>();
            objCyberware.Create(objXmlCyberware, _objCharacter, frmPickCyberware.SelectedGrade, objSource, frmPickCyberware.SelectedRating, objNode, objWeapons, objWeaponNodes);
            if (objCyberware.InternalId == Guid.Empty.ToString())
                return false;

            // Force the item to be Transgenic if selected.
            if (frmPickCyberware.ForceTransgenic)
                objCyberware.Category = "Genetech: Transgenics";

            int intCost = objCyberware.TotalCost;

            // Check the item's Cost and make sure the character can afford it.
            if (!frmPickCyberware.FreeCost)
            {
                if (intCost > _objCharacter.Nuyen)
                {
                    MessageBox.Show(LanguageManager.Instance.GetString("Message_NotEnoughNuyen"), LanguageManager.Instance.GetString("MessageTitle_NotEnoughNuyen"), MessageBoxButtons.OK, MessageBoxIcon.Information);
                    // Remove any Improvements created by the Cyberware.
                    _objImprovementManager.RemoveImprovements(objCyberware.SourceType, objCyberware.InternalId);
                    return frmPickCyberware.AddAgain;
                }
                else
                {
                    // Create the Expense Log Entry.
                    ExpenseLogEntry objExpense = new ExpenseLogEntry();
                    string strEntry = "";
                    if (objCyberware.SourceType == Improvement.ImprovementSource.Cyberware)
                        strEntry = LanguageManager.Instance.GetString("String_ExpensePurchaseCyberware");
                    else
                        strEntry = LanguageManager.Instance.GetString("String_ExpensePurchaseBioware");
                    objExpense.Create(intCost * -1, strEntry + " " + objCyberware.DisplayNameShort, ExpenseType.Nuyen, DateTime.Now);
                    _objCharacter.ExpenseEntries.Add(objExpense);
                    _objCharacter.Nuyen -= intCost;

                    ExpenseUndo objUndo = new ExpenseUndo();
                    objUndo.CreateNuyen(NuyenExpenseType.AddCyberware, objCyberware.InternalId);
                    objExpense.Undo = objUndo;
                }
            }

            try
            {
                if (treCyberware.SelectedNode.Level > 0)
                {
                    treCyberware.SelectedNode.Nodes.Add(objNode);
                    treCyberware.SelectedNode.Expand();
                    objSelectedCyberware.Cyberwares.Add(objCyberware);
                    objCyberware.Parent = objSelectedCyberware;
                }
                else
                {
                    treCyberware.Nodes[intNode].Nodes.Add(objNode);
                    treCyberware.Nodes[intNode].Expand();
                    _objCharacter.Cyberware.Add(objCyberware);
                }
            }
            catch
            {
                treCyberware.Nodes[intNode].Nodes.Add(objNode);
                treCyberware.Nodes[intNode].Expand();
                _objCharacter.Cyberware.Add(objCyberware);
            }

            // Select the node that was just added.
            if (objSource == Improvement.ImprovementSource.Cyberware)
                objNode.ContextMenuStrip = cmsCyberware;
            else if (objSource == Improvement.ImprovementSource.Bioware)
                objNode.ContextMenuStrip = cmsBioware;

            foreach (Weapon objWeapon in objWeapons)
                _objCharacter.Weapons.Add(objWeapon);

            // Create the Weapon Node if one exists.
            foreach (TreeNode objWeaponNode in objWeaponNodes)
            {
                objWeaponNode.ContextMenuStrip = cmsWeapon;
                treWeapons.Nodes[0].Nodes.Add(objWeaponNode);
                treWeapons.Nodes[0].Expand();
            }

            // Determine the lowest whole number for the character's Essence after adding the 'Ware.
            decimal decEndingESS = Math.Floor(_objCharacter.Essence);
            decimal decDifferent = decStartingESS - decEndingESS;

            if (decDifferent > 0.0m)
            {
                // Permanently reduce the character's MAG/RES Attributes.
                _objCharacter.MAG.Value -= Convert.ToInt32(decDifferent);
                _objCharacter.RES.Value -= Convert.ToInt32(decDifferent);

                // If the Attribute reaches 0, the character has burned out.
                if (_objCharacter.MAG.Value < 1)
                {
                    _objCharacter.MAG.Value = 0;
                    _objCharacter.MAG.MetatypeMinimum = 0;
                    _objCharacter.MAG.MetatypeMaximum = 0;
                    _objCharacter.MAG.MetatypeAugmentedMaximum = 0;

                    if (_objCharacter.MAGEnabled)
                    {
                        // Move all MAG-linked Active Skills to Knowledge Skills.
                        List<Skill> lstNewSkills = new List<Skill>();
                        foreach (Skill objSkill in _objCharacter.Skills)
                        {
                            if (objSkill.Attribute == "MAG" && objSkill.Rating > 0)
                            {
                                int i = panKnowledgeSkills.Controls.Count;
                                Skill objKnowledge = new Skill(_objCharacter);

                                SkillControl objSkillControl = new SkillControl();
                                objKnowledge.Name = objSkill.Name;
                                objSkillControl.SkillObject = objKnowledge;

                                // Attach an EventHandler for the RatingChanged and SpecializationChanged Events.
                                objSkillControl.RatingChanged += objKnowledgeSkill_RatingChanged;
                                objSkillControl.SpecializationChanged += objSkill_SpecializationChanged;
                                objSkillControl.DeleteSkill += objKnowledgeSkill_DeleteSkill;
                                objSkillControl.SkillKarmaClicked += objKnowledgeSkill_KarmaClicked;
                                objSkillControl.DiceRollerClicked += objSkill_DiceRollerClicked;

                                objSkillControl.KnowledgeSkill = true;
                                objSkillControl.AllowDelete = true;
                                if (objSkill.Rating > 7)
                                    objSkillControl.SkillRatingMaximum = objSkill.Rating;
                                else
                                    objSkillControl.SkillRatingMaximum = 6;
                                objSkillControl.SkillRating = objSkill.Rating;
                                objSkillControl.SkillCategory = "Professional";
                                // Set the SkillControl's Location since scrolling the Panel causes it to actually change the child Controls' Locations.
                                objSkillControl.Location = new Point(0, objSkillControl.Height * i + panKnowledgeSkills.AutoScrollPosition.Y);
                                panKnowledgeSkills.Controls.Add(objSkillControl);

                                lstNewSkills.Add(objKnowledge);
                            }
                        }
                        foreach (Skill objSkill in lstNewSkills)
                            _objCharacter.Skills.Add(objSkill);
                    }

                    _objCharacter.MAGEnabled = false;
                    _objCharacter.MagicianEnabled = false;
                    _objCharacter.AdeptEnabled = false;
                }
                if (_objCharacter.RES.Value < 1)
                {
                    _objCharacter.RES.Value = 0;
                    _objCharacter.RES.MetatypeMinimum = 0;
                    _objCharacter.RES.MetatypeMinimum = 0;
                    _objCharacter.RES.MetatypeAugmentedMaximum = 0;

                    if (_objCharacter.RESEnabled)
                    {
                        // Move all RES-linked Active Skills to Knowledge Skills.
                        List<Skill> lstNewSkills = new List<Skill>();
                        foreach (Skill objSkill in _objCharacter.Skills)
                        {
                            if (objSkill.Attribute == "RES" && objSkill.Rating > 0)
                            {
                                int i = panKnowledgeSkills.Controls.Count;
                                Skill objKnowledge = new Skill(_objCharacter);

                                SkillControl objSkillControl = new SkillControl();
                                objKnowledge.Name = objSkill.Name;
                                objSkillControl.SkillObject = objKnowledge;

                                // Attach an EventHandler for the RatingChanged and SpecializationChanged Events.
                                objSkillControl.RatingChanged += objKnowledgeSkill_RatingChanged;
                                objSkillControl.SpecializationChanged += objSkill_SpecializationChanged;
                                objSkillControl.DeleteSkill += objKnowledgeSkill_DeleteSkill;
                                objSkillControl.SkillKarmaClicked += objKnowledgeSkill_KarmaClicked;
                                objSkillControl.DiceRollerClicked += objSkill_DiceRollerClicked;

                                objSkillControl.KnowledgeSkill = true;
                                objSkillControl.AllowDelete = true;
                                if (objSkill.Rating > 7)
                                    objSkillControl.SkillRatingMaximum = objSkill.Rating;
                                else
                                    objSkillControl.SkillRatingMaximum = 6;
                                objSkillControl.SkillRating = objSkill.Rating;
                                objSkillControl.SkillCategory = "Professional";
                                // Set the SkillControl's Location since scrolling the Panel causes it to actually change the child Controls' Locations.
                                objSkillControl.Location = new Point(0, objSkillControl.Height * i + panKnowledgeSkills.AutoScrollPosition.Y);
                                panKnowledgeSkills.Controls.Add(objSkillControl);

                                lstNewSkills.Add(objKnowledge);
                            }
                        }
                        foreach (Skill objSkill in lstNewSkills)
                            _objCharacter.Skills.Add(objSkill);
                    }

                    _objCharacter.RESEnabled = false;
                    _objCharacter.TechnomancerEnabled = false;
                }
            }

            _objFunctions.SortTree(treCyberware);
            treCyberware.SelectedNode = objNode;
            UpdateCharacterInfo();
            RefreshSelectedCyberware();
            PopulateGearList();

            if (frmPickCyberware.DialogResult != DialogResult.Cancel)
            {
                _blnIsDirty = true;
                UpdateWindowTitle();
            }

            return frmPickCyberware.AddAgain;
        }
Example #14
0
		private void cmdAddExoticSkill_Click(object sender, EventArgs e)
		{
			frmSelectExoticSkill frmPickExoticSkill = new frmSelectExoticSkill();
			frmPickExoticSkill.ShowDialog(this);

			if (frmPickExoticSkill.DialogResult == DialogResult.Cancel)
				return;

			XmlDocument objXmlDocument = XmlManager.Instance.Load("skills.xml");

			XmlNode nodSkill = objXmlDocument.SelectSingleNode("/chummer/skills/skill[name = \"" + frmPickExoticSkill.SelectedExoticSkill + "\"]");

			int i = panActiveSkills.Controls.Count;
			Skill objSkill = new Skill(_objCharacter);
			SkillSpecialization objSkillSpec = new SkillSpecialization(frmPickExoticSkill.SelectedExoticSkillSpecialisation);
			objSkill.Attribute = nodSkill["attribute"].InnerText;
			objSkill.Specializations.Add(objSkillSpec);
			if (_objCharacter.MaxSkillRating > 0)
				objSkill.RatingMaximum = _objCharacter.MaxSkillRating;

			SkillControl objSkillControl = new SkillControl();
			objSkillControl.SkillObject = objSkill;
			objSkillControl.Width = 510;

			// Attach an EventHandler for the RatingChanged and SpecializationChanged Events.
			objSkillControl.RatingChanged += objActiveSkill_RatingChanged;
			objSkillControl.SpecializationChanged += objSkill_SpecializationChanged;
			objSkillControl.SkillKarmaClicked += objSkill_KarmaClicked;
			objSkillControl.SkillName = frmPickExoticSkill.SelectedExoticSkill;
			objSkillControl.DiceRollerClicked += objSkill_DiceRollerClicked;
			objSkillControl.DeleteSkill += objSkill_DeleteExoticSkill;
			objSkillControl.SkillCategory = nodSkill["category"].InnerText;
			if (nodSkill["default"].InnerText == "Yes")
				objSkill.Default = true;
			else
				objSkill.Default = false;

			objSkill.ExoticSkill = true;
			_objCharacter.Skills.Add(objSkill);

			objSkillControl.SkillRatingMaximum = 12;
			// Set the SkillControl's Location since scrolling the Panel causes it to actually change the child Controls' Locations.
			objSkillControl.Location = new Point(0, objSkillControl.Height * i + panActiveSkills.AutoScrollPosition.Y);
			panActiveSkills.Controls.Add(objSkillControl);

			_blnIsDirty = true;
			UpdateWindowTitle();
		}
Example #15
0
		public void Free(Skill skill)
		{
			if (_fold.Remove(skill))
			{
				CharacterObject.Skills.Add(skill);
				Karma -= skill.Karma;
				Base -= skill.Base;
				Rating -= skill.Rating;
			}
		}
Example #16
0
        /// <summary>
        /// A Metatype has been selected, so fill in all of the necessary Character information.
        /// </summary>
        void MetatypeSelected()
        {
            if (lstMetatypes.Text != "")
            {
                ImprovementManager objImprovementManager = new ImprovementManager(_objCharacter);
                XmlDocument objXmlDocument = XmlManager.Instance.Load(_strXmlFile);
                XmlNode objXmlMetatype = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + lstMetatypes.SelectedValue + "\"]");
                XmlNode objXmlMetavariant = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + lstMetatypes.SelectedValue + "\"]/metavariants/metavariant[name = \"" + cboMetavariant.SelectedValue + "\"]");
                int intForce = 0;
                if (nudForce.Visible)
                    intForce = Convert.ToInt32(nudForce.Value);

                // Set Metatype information.

                if (cboMetavariant.SelectedValue.ToString() != "None")
                {
                    _objCharacter.BOD.AssignLimits(ExpressionToString(objXmlMetavariant["bodmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["bodmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["bodaug"].InnerText, intForce, 0));
                    _objCharacter.AGI.AssignLimits(ExpressionToString(objXmlMetavariant["agimin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["agimax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["agiaug"].InnerText, intForce, 0));
                    _objCharacter.REA.AssignLimits(ExpressionToString(objXmlMetavariant["reamin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["reamax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["reaaug"].InnerText, intForce, 0));
                    _objCharacter.STR.AssignLimits(ExpressionToString(objXmlMetavariant["strmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["strmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["straug"].InnerText, intForce, 0));
                    _objCharacter.CHA.AssignLimits(ExpressionToString(objXmlMetavariant["chamin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["chamax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["chaaug"].InnerText, intForce, 0));
                    _objCharacter.INT.AssignLimits(ExpressionToString(objXmlMetavariant["intmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["intmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["intaug"].InnerText, intForce, 0));
                    _objCharacter.LOG.AssignLimits(ExpressionToString(objXmlMetavariant["logmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["logmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["logaug"].InnerText, intForce, 0));
                    _objCharacter.WIL.AssignLimits(ExpressionToString(objXmlMetavariant["wilmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["wilmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["wilaug"].InnerText, intForce, 0));
                    _objCharacter.INI.AssignLimits(ExpressionToString(objXmlMetavariant["inimin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["inimax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["iniaug"].InnerText, intForce, 0));
                    _objCharacter.MAG.AssignLimits(ExpressionToString(objXmlMetavariant["magmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["magmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["magaug"].InnerText, intForce, 0));
                    _objCharacter.RES.AssignLimits(ExpressionToString(objXmlMetavariant["resmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["resmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["resaug"].InnerText, intForce, 0));
                    _objCharacter.EDG.AssignLimits(ExpressionToString(objXmlMetavariant["edgmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["edgmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["edgaug"].InnerText, intForce, 0));
                    _objCharacter.ESS.AssignLimits(ExpressionToString(objXmlMetavariant["essmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["essmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetavariant["essaug"].InnerText, intForce, 0));
                }
                else if (_strXmlFile != "critters.xml" || lstMetatypes.SelectedValue.ToString() == "Ally Spirit")
                {
                    _objCharacter.BOD.AssignLimits(ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["bodmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["bodaug"].InnerText, intForce, 0));
                    _objCharacter.AGI.AssignLimits(ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["agimax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["agiaug"].InnerText, intForce, 0));
                    _objCharacter.REA.AssignLimits(ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["reamax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["reaaug"].InnerText, intForce, 0));
                    _objCharacter.STR.AssignLimits(ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["strmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["straug"].InnerText, intForce, 0));
                    _objCharacter.CHA.AssignLimits(ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["chamax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["chaaug"].InnerText, intForce, 0));
                    _objCharacter.INT.AssignLimits(ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["intmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["intaug"].InnerText, intForce, 0));
                    _objCharacter.LOG.AssignLimits(ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["logmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["logaug"].InnerText, intForce, 0));
                    _objCharacter.WIL.AssignLimits(ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["wilmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["wilaug"].InnerText, intForce, 0));
                    _objCharacter.INI.AssignLimits(ExpressionToString(objXmlMetatype["inimin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["inimax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["iniaug"].InnerText, intForce, 0));
                    _objCharacter.MAG.AssignLimits(ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["magmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["magaug"].InnerText, intForce, 0));
                    _objCharacter.RES.AssignLimits(ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["resmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["resaug"].InnerText, intForce, 0));
                    _objCharacter.EDG.AssignLimits(ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["edgmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["edgaug"].InnerText, intForce, 0));
                    _objCharacter.ESS.AssignLimits(ExpressionToString(objXmlMetatype["essmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essaug"].InnerText, intForce, 0));
                }
                else
                {
                    int intMinModifier = -3;
                    if (cboCategory.SelectedValue.ToString() == "Mutant Critters")
                        intMinModifier = 0;
                    _objCharacter.BOD.AssignLimits(ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, 3));
                    _objCharacter.AGI.AssignLimits(ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, 3));
                    _objCharacter.REA.AssignLimits(ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, 3));
                    _objCharacter.STR.AssignLimits(ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, 3));
                    _objCharacter.CHA.AssignLimits(ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, 3));
                    _objCharacter.INT.AssignLimits(ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, 3));
                    _objCharacter.LOG.AssignLimits(ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, 3));
                    _objCharacter.WIL.AssignLimits(ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, 3));
                    _objCharacter.INI.AssignLimits(ExpressionToString(objXmlMetatype["inimin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["inimax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["iniaug"].InnerText, intForce, 0));
                    _objCharacter.MAG.AssignLimits(ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, 3));
                    _objCharacter.RES.AssignLimits(ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, 3));
                    _objCharacter.EDG.AssignLimits(ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, 3));
                    _objCharacter.ESS.AssignLimits(ExpressionToString(objXmlMetatype["essmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essaug"].InnerText, intForce, 0));
                }

                // If we're working with a Critter, set the Attributes to their default values.
                if (_strXmlFile == "critters.xml")
                {
                    _objCharacter.BOD.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, 0));
                    _objCharacter.AGI.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, 0));
                    _objCharacter.REA.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, 0));
                    _objCharacter.STR.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, 0));
                    _objCharacter.CHA.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, 0));
                    _objCharacter.INT.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, 0));
                    _objCharacter.LOG.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, 0));
                    _objCharacter.WIL.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, 0));
                    _objCharacter.MAG.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, 0));
                    _objCharacter.RES.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, 0));
                    _objCharacter.EDG.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, 0));
                    _objCharacter.ESS.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["essmax"].InnerText, intForce, 0));
                }

                // Sprites can never have Physical Attributes or WIL.
                if (lstMetatypes.SelectedValue.ToString().EndsWith("Sprite"))
                {
                    _objCharacter.BOD.AssignLimits("0", "0", "0");
                    _objCharacter.AGI.AssignLimits("0", "0", "0");
                    _objCharacter.REA.AssignLimits("0", "0", "0");
                    _objCharacter.STR.AssignLimits("0", "0", "0");
                    _objCharacter.WIL.AssignLimits("0", "0", "0");
                    _objCharacter.INI.MetatypeMinimum = Convert.ToInt32(ExpressionToString(objXmlMetatype["inimax"].InnerText, intForce, 0));
                    _objCharacter.INI.MetatypeMaximum = Convert.ToInt32(ExpressionToString(objXmlMetatype["inimax"].InnerText, intForce, 0));
                }

                // If this is a Shapeshifter, a Metavariant must be selected. Default to Human if None is selected.
                if (cboCategory.SelectedValue.ToString() == "Shapeshifter" && cboMetavariant.SelectedValue.ToString() == "None")
                    cboMetavariant.SelectedValue = "Human";

                _objCharacter.Metatype = lstMetatypes.SelectedValue.ToString();
                _objCharacter.MetatypeCategory = cboCategory.SelectedValue.ToString();
                if (cboMetavariant.SelectedValue.ToString() == "None")
                {
                    _objCharacter.Metavariant = "";
                    _objCharacter.MetatypeBP = Convert.ToInt32(lblBP.Text);
                }
                else
                {
                    _objCharacter.Metavariant = cboMetavariant.SelectedValue.ToString();
                    _objCharacter.MetatypeBP = Convert.ToInt32(lblMetavariantBP.Text);
                }

                if (objXmlMetatype["movement"] != null)
                    _objCharacter.Movement = objXmlMetatype["movement"].InnerText;
                // Load the Qualities file.
                XmlDocument objXmlQualityDocument = XmlManager.Instance.Load("qualities.xml");

                if (cboMetavariant.SelectedValue.ToString() == "None")
                {
                    // Determine if the Metatype has any bonuses.
                    if (objXmlMetatype.InnerXml.Contains("bonus"))
                        objImprovementManager.CreateImprovements(Improvement.ImprovementSource.Metatype, lstMetatypes.SelectedValue.ToString(), objXmlMetatype.SelectSingleNode("bonus"), false, 1, lstMetatypes.SelectedValue.ToString());

                    // Create the Qualities that come with the Metatype.
                    foreach (XmlNode objXmlQualityItem in objXmlMetatype.SelectNodes("qualities/positive/quality"))
                    {
                        XmlNode objXmlQuality = objXmlQualityDocument.SelectSingleNode("/chummer/qualities/quality[name = \"" + objXmlQualityItem.InnerText + "\"]");
                        TreeNode objNode = new TreeNode();
                        List<Weapon> objWeapons = new List<Weapon>();
                        List<TreeNode> objWeaponNodes = new List<TreeNode>();
                        Quality objQuality = new Quality(_objCharacter);
                        string strForceValue = "";
                        if (objXmlQualityItem.Attributes["select"] != null)
                            strForceValue = objXmlQualityItem.Attributes["select"].InnerText;
                        QualitySource objSource = new QualitySource();
                        objSource = QualitySource.Metatype;
                        if (objXmlQualityItem.Attributes["removable"] != null)
                            objSource = QualitySource.MetatypeRemovable;
                        objQuality.Create(objXmlQuality, _objCharacter, objSource, objNode, objWeapons, objWeaponNodes, strForceValue);
                        objQuality.ContributeToLimit = false;
                        _objCharacter.Qualities.Add(objQuality);

                        // Add any created Weapons to the character.
                        foreach (Weapon objWeapon in objWeapons)
                            _objCharacter.Weapons.Add(objWeapon);
                    }
                    foreach (XmlNode objXmlQualityItem in objXmlMetatype.SelectNodes("qualities/negative/quality"))
                    {
                        XmlNode objXmlQuality = objXmlQualityDocument.SelectSingleNode("/chummer/qualities/quality[name = \"" + objXmlQualityItem.InnerText + "\"]");
                        TreeNode objNode = new TreeNode();
                        List<Weapon> objWeapons = new List<Weapon>();
                        List<TreeNode> objWeaponNodes = new List<TreeNode>();
                        Quality objQuality = new Quality(_objCharacter);
                        string strForceValue = "";
                        if (objXmlQualityItem.Attributes["select"] != null)
                            strForceValue = objXmlQualityItem.Attributes["select"].InnerText;
                        QualitySource objSource = new QualitySource();
                        objSource = QualitySource.Metatype;
                        if (objXmlQualityItem.Attributes["removable"] != null)
                            objSource = QualitySource.MetatypeRemovable;
                        objQuality.Create(objXmlQuality, _objCharacter, objSource, objNode, objWeapons, objWeaponNodes, strForceValue);
                        objQuality.ContributeToLimit = false;
                        _objCharacter.Qualities.Add(objQuality);

                        // Add any created Weapons to the character.
                        foreach (Weapon objWeapon in objWeapons)
                            _objCharacter.Weapons.Add(objWeapon);
                    }
                }

                // If a Metavariant has been selected, locate it in the file.
                if (cboMetavariant.SelectedValue.ToString() != "None")
                {
                    // Determine if the Metavariant has any bonuses.
                    if (objXmlMetavariant.InnerXml.Contains("bonus"))
                    {
                        objImprovementManager.CreateImprovements(Improvement.ImprovementSource.Metavariant, cboMetavariant.SelectedValue.ToString(), objXmlMetavariant.SelectSingleNode("bonus"), false, 1, cboMetavariant.SelectedValue.ToString());
                    }

                    // Create the Qualities that come with the Metatype.
                    foreach (XmlNode objXmlQualityItem in objXmlMetavariant.SelectNodes("qualities/positive/quality"))
                    {
                        XmlNode objXmlQuality = objXmlQualityDocument.SelectSingleNode("/chummer/qualities/quality[name = \"" + objXmlQualityItem.InnerText + "\"]");
                        TreeNode objNode = new TreeNode();
                        List<Weapon> objWeapons = new List<Weapon>();
                        List<TreeNode> objWeaponNodes = new List<TreeNode>();
                        Quality objQuality = new Quality(_objCharacter);
                        string strForceValue = "";
                        if (objXmlQualityItem.Attributes["select"] != null)
                            strForceValue = objXmlQualityItem.Attributes["select"].InnerText;
                        QualitySource objSource = new QualitySource();
                        objSource = QualitySource.Metatype;
                        if (objXmlQualityItem.Attributes["removable"] != null)
                            objSource = QualitySource.MetatypeRemovable;
                        objQuality.Create(objXmlQuality, _objCharacter, objSource, objNode, objWeapons, objWeaponNodes, strForceValue);
                        objQuality.ContributeToLimit = false;
                        _objCharacter.Qualities.Add(objQuality);

                        // Add any created Weapons to the character.
                        foreach (Weapon objWeapon in objWeapons)
                            _objCharacter.Weapons.Add(objWeapon);
                    }
                    foreach (XmlNode objXmlQualityItem in objXmlMetavariant.SelectNodes("qualities/negative/quality"))
                    {
                        XmlNode objXmlQuality = objXmlQualityDocument.SelectSingleNode("/chummer/qualities/quality[name = \"" + objXmlQualityItem.InnerText + "\"]");
                        TreeNode objNode = new TreeNode();
                        List<Weapon> objWeapons = new List<Weapon>();
                        List<TreeNode> objWeaponNodes = new List<TreeNode>();
                        Quality objQuality = new Quality(_objCharacter);
                        string strForceValue = "";
                        if (objXmlQualityItem.Attributes["select"] != null)
                            strForceValue = objXmlQualityItem.Attributes["select"].InnerText;
                        QualitySource objSource = new QualitySource();
                        objSource = QualitySource.Metatype;
                        if (objXmlQualityItem.Attributes["removable"] != null)
                            objSource = QualitySource.MetatypeRemovable;
                        objQuality.Create(objXmlQuality, _objCharacter, objSource, objNode, objWeapons, objWeaponNodes, strForceValue);
                        objQuality.ContributeToLimit = false;
                        _objCharacter.Qualities.Add(objQuality);

                        // Add any created Weapons to the character.
                        foreach (Weapon objWeapon in objWeapons)
                            _objCharacter.Weapons.Add(objWeapon);
                    }
                }

                // Run through the character's Attributes one more time and make sure their value matches their minimum value.
                if (_strXmlFile == "metatypes.xml")
                {
                    _objCharacter.BOD.Value = _objCharacter.BOD.TotalMinimum;
                    _objCharacter.AGI.Value = _objCharacter.AGI.TotalMinimum;
                    _objCharacter.REA.Value = _objCharacter.REA.TotalMinimum;
                    _objCharacter.STR.Value = _objCharacter.STR.TotalMinimum;
                    _objCharacter.CHA.Value = _objCharacter.CHA.TotalMinimum;
                    _objCharacter.INT.Value = _objCharacter.INT.TotalMinimum;
                    _objCharacter.LOG.Value = _objCharacter.LOG.TotalMinimum;
                    _objCharacter.WIL.Value = _objCharacter.WIL.TotalMinimum;
                }

                // Add any Critter Powers the Metatype/Critter should have.
                XmlNode objXmlCritter = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + _objCharacter.Metatype + "\"]");

                objXmlDocument = XmlManager.Instance.Load("critterpowers.xml");
                foreach (XmlNode objXmlPower in objXmlCritter.SelectNodes("powers/power"))
                {
                    XmlNode objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"" + objXmlPower.InnerText + "\"]");
                    TreeNode objNode = new TreeNode();
                    CritterPower objPower = new CritterPower(_objCharacter);
                    string strForcedValue = "";
                    int intRating = 0;

                    if (objXmlPower.Attributes["rating"] != null)
                        intRating = Convert.ToInt32(objXmlPower.Attributes["rating"].InnerText);
                    if (objXmlPower.Attributes["select"] != null)
                        strForcedValue = objXmlPower.Attributes["select"].InnerText;

                    objPower.Create(objXmlCritterPower, _objCharacter, objNode, intRating, strForcedValue);
                    objPower.CountTowardsLimit = false;
                    _objCharacter.CritterPowers.Add(objPower);
                }

                // Add any Critter Powers the Metavariant should have.
                if (cboMetavariant.SelectedValue.ToString() != "None")
                {
                    foreach (XmlNode objXmlPower in objXmlMetavariant.SelectNodes("powers/power"))
                    {
                        XmlNode objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"" + objXmlPower.InnerText + "\"]");
                        TreeNode objNode = new TreeNode();
                        CritterPower objPower = new CritterPower(_objCharacter);
                        string strForcedValue = "";
                        int intRating = 0;

                        if (objXmlPower.Attributes["rating"] != null)
                            intRating = Convert.ToInt32(objXmlPower.Attributes["rating"].InnerText);
                        if (objXmlPower.Attributes["select"] != null)
                            strForcedValue = objXmlPower.Attributes["select"].InnerText;

                        objPower.Create(objXmlCritterPower, _objCharacter, objNode, intRating, strForcedValue);
                        objPower.CountTowardsLimit = false;
                        _objCharacter.CritterPowers.Add(objPower);
                    }
                }

                // If this is a Blood Spirit, add their free Critter Powers.
                if (chkBloodSpirit.Checked)
                {
                    XmlNode objXmlCritterPower;
                    TreeNode objNode;
                    CritterPower objPower;
                    bool blnAddPower = true;

                    // Energy Drain.
                    foreach (CritterPower objFindPower in _objCharacter.CritterPowers)
                    {
                        if (objFindPower.Name == "Energy Drain")
                        {
                            blnAddPower = false;
                            break;
                        }
                    }
                    if (blnAddPower)
                    {
                        objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"Energy Drain\"]");
                        objNode = new TreeNode();
                        objPower = new CritterPower(_objCharacter);
                        objPower.Create(objXmlCritterPower, _objCharacter, objNode, 0, "");
                        objPower.CountTowardsLimit = false;
                        _objCharacter.CritterPowers.Add(objPower);
                    }

                    // Fear.
                    blnAddPower = true;
                    foreach (CritterPower objFindPower in _objCharacter.CritterPowers)
                    {
                        if (objFindPower.Name == "Fear")
                        {
                            blnAddPower = false;
                            break;
                        }
                    }
                    if (blnAddPower)
                    {
                        objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"Fear\"]");
                        objNode = new TreeNode();
                        objPower = new CritterPower(_objCharacter);
                        objPower.Create(objXmlCritterPower, _objCharacter, objNode, 0, "");
                        objPower.CountTowardsLimit = false;
                        _objCharacter.CritterPowers.Add(objPower);
                    }

                    // Natural Weapon.
                    objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"Natural Weapon\"]");
                    objNode = new TreeNode();
                    objPower = new CritterPower(_objCharacter);
                    objPower.Create(objXmlCritterPower, _objCharacter, objNode, 0, "DV " + intForce.ToString() + "P, AP 0");
                    objPower.CountTowardsLimit = false;
                    _objCharacter.CritterPowers.Add(objPower);

                    // Evanescence.
                    blnAddPower = true;
                    foreach (CritterPower objFindPower in _objCharacter.CritterPowers)
                    {
                        if (objFindPower.Name == "Evanescence")
                        {
                            blnAddPower = false;
                            break;
                        }
                    }
                    if (blnAddPower)
                    {
                        objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"Evanescence\"]");
                        objNode = new TreeNode();
                        objPower = new CritterPower(_objCharacter);
                        objPower.Create(objXmlCritterPower, _objCharacter, objNode, 0, "");
                        objPower.CountTowardsLimit = false;
                        _objCharacter.CritterPowers.Add(objPower);
                    }
                }

                // Remove the Critter's Materialization Power if they have it. Add the Possession or Inhabitation Power if the Possession-based Tradition checkbox is checked.
                if (chkPossessionBased.Checked)
                {
                    foreach (CritterPower objCritterPower in _objCharacter.CritterPowers)
                    {
                        if (objCritterPower.Name == "Materialization")
                        {
                            _objCharacter.CritterPowers.Remove(objCritterPower);
                            break;
                        }
                    }

                    // Add the selected Power.
                    XmlNode objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"" + cboPossessionMethod.SelectedValue.ToString() + "\"]");
                    TreeNode objNode = new TreeNode();
                    CritterPower objPower = new CritterPower(_objCharacter);
                    objPower.Create(objXmlCritterPower, _objCharacter, objNode, 0, "");
                    objPower.CountTowardsLimit = false;
                    _objCharacter.CritterPowers.Add(objPower);
                }

                // Set the Skill Ratings for the Critter.
                foreach (XmlNode objXmlSkill in objXmlCritter.SelectNodes("skills/skill"))
                {
                    if (objXmlSkill.InnerText.Contains("Exotic"))
                    {
                        Skill objExotic = new Skill(_objCharacter);
                        objExotic.ExoticSkill = true;
                        objExotic.Attribute = "AGI";
                        if (objXmlSkill.Attributes["spec"] != null)
                        {
                            SkillSpecialization objSpec = new SkillSpecialization(objXmlSkill.Attributes["spec"].InnerText);
                            objExotic.Specializations.Add(objSpec);
                        }
                        if (Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0)) > 6)
                            objExotic.RatingMaximum = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0));
                        objExotic.Rating = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0));
                        objExotic.Name = objXmlSkill.InnerText;
                        _objCharacter.Skills.Add(objExotic);
                    }
                    else
                    {
                        foreach (Skill objSkill in _objCharacter.Skills)
                        {
                            if (objSkill.Name == objXmlSkill.InnerText)
                            {
                                if (objXmlSkill.Attributes["spec"] != null)
                                {
                                    SkillSpecialization objSpec = new SkillSpecialization(objXmlSkill.Attributes["spec"].InnerText);
                                    objSkill.Specializations.Add(objSpec);
                                }
                                if (Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0)) > 6)
                                    objSkill.RatingMaximum = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0));
                                objSkill.Rating = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0));
                                break;
                            }
                        }
                    }
                }

                // Set the Skill Group Ratings for the Critter.
                foreach (XmlNode objXmlSkill in objXmlCritter.SelectNodes("skills/group"))
                {
                    foreach (SkillGroup objSkill in _objCharacter.SkillGroups)
                    {
                        if (objSkill.Name == objXmlSkill.InnerText)
                        {
                            objSkill.RatingMaximum = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0));
                            objSkill.Rating = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0));
                            break;
                        }
                    }
                }

                // Set the Knowledge Skill Ratings for the Critter.
                foreach (XmlNode objXmlSkill in objXmlCritter.SelectNodes("skills/knowledge"))
                {
                    Skill objKnowledge = new Skill(_objCharacter);
                    objKnowledge.Name = objXmlSkill.InnerText;
                    objKnowledge.KnowledgeSkill = true;
                    if (objXmlSkill.Attributes["spec"] != null)
                    {
                        SkillSpecialization objSpec = new SkillSpecialization(objXmlSkill.Attributes["spec"].InnerText);
                        objKnowledge.Specializations.Add(objSpec);
                    }
                    objKnowledge.SkillCategory = objXmlSkill.Attributes["category"].InnerText;
             					if (Convert.ToInt32(objXmlSkill.Attributes["rating"].InnerText) > 6)
                        objKnowledge.RatingMaximum = Convert.ToInt32(objXmlSkill.Attributes["rating"].InnerText);
                    objKnowledge.Rating = Convert.ToInt32(objXmlSkill.Attributes["rating"].InnerText);
                    _objCharacter.Skills.Add(objKnowledge);
                }

                // If this is a Critter with a Force (which dictates their Skill Rating/Maximum Skill Rating), set their Skill Rating Maximums.
                if (intForce > 0)
                {
                    int intMaxRating = intForce;
                    // Determine the highest Skill Rating the Critter has.
                    foreach (Skill objSkill in _objCharacter.Skills)
                    {
                        if (objSkill.RatingMaximum > intMaxRating)
                            intMaxRating = objSkill.RatingMaximum;
                    }

                    // Now that we know the upper limit, set all of the Skill Rating Maximums to match.
                    foreach (Skill objSkill in _objCharacter.Skills)
                        objSkill.RatingMaximum = intMaxRating;
                    foreach (SkillGroup objGroup in _objCharacter.SkillGroups)
                        objGroup.RatingMaximum = intMaxRating;

                    // Set the MaxSkillRating for the character so it can be used later when they add new Knowledge Skills or Exotic Skills.
                    _objCharacter.MaxSkillRating = intMaxRating;
                }

                // Add any Complex Forms the Critter comes with (typically Sprites)
                XmlDocument objXmlProgramDocument = XmlManager.Instance.Load("complexforms.xml");
                foreach (XmlNode objXmlComplexForm in objXmlCritter.SelectNodes("complexforms/complexform"))
                {
                    string strForceValue = "";
                    if (objXmlComplexForm.Attributes["select"] != null)
                        strForceValue = objXmlComplexForm.Attributes["select"].InnerText;
                    XmlNode objXmlProgram = objXmlProgramDocument.SelectSingleNode("/chummer/complexforms/complexform[name = \"" + objXmlComplexForm.InnerText + "\"]");
                    TreeNode objNode = new TreeNode();
                    ComplexForm objProgram = new ComplexForm(_objCharacter);
                    objProgram.Create(objXmlProgram, _objCharacter, objNode, strForceValue);
                    _objCharacter.ComplexForms.Add(objProgram);
                }

                // Add any Gear the Critter comes with (typically Programs for A.I.s)
                XmlDocument objXmlGearDocument = XmlManager.Instance.Load("gear.xml");
                foreach (XmlNode objXmlGear in objXmlCritter.SelectNodes("gears/gear"))
                {
                    int intRating = 0;
                    if (objXmlGear.Attributes["rating"] != null)
                        intRating = Convert.ToInt32(ExpressionToString(objXmlGear.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0));
                    string strForceValue = "";
                    if (objXmlGear.Attributes["select"] != null)
                        strForceValue = objXmlGear.Attributes["select"].InnerText;
                    XmlNode objXmlGearItem = objXmlGearDocument.SelectSingleNode("/chummer/gears/gear[name = \"" + objXmlGear.InnerText + "\"]");
                    TreeNode objNode = new TreeNode();
                    Gear objGear = new Gear(_objCharacter);
                    List<Weapon> lstWeapons = new List<Weapon>();
                    List<TreeNode> lstWeaponNodes = new List<TreeNode>();
                    objGear.Create(objXmlGearItem, _objCharacter, objNode, intRating, lstWeapons, lstWeaponNodes, strForceValue);
                    objGear.Cost = "0";
                    objGear.Cost3 = "0";
                    objGear.Cost6 = "0";
                    objGear.Cost10 = "0";
                    _objCharacter.Gear.Add(objGear);
                }

                // If this is a Mutant Critter, count up the number of Skill points they start with.
                if (_objCharacter.MetatypeCategory == "Mutant Critters")
                {
                    foreach (Skill objSkill in _objCharacter.Skills)
                        _objCharacter.MutantCritterBaseSkills += objSkill.Rating;
                }

                if (cboMetavariant.Text != "None")
                {
                    int x = 0;
                       int.TryParse(lblMetavariantBP.Text, out x);
                    //_objCharacter.BuildKarma = _objCharacter.BuildKarma - x;
                }
                else
                {
                    int x = 0;
                       int.TryParse(lblBP.Text, out x);
                    //_objCharacter.BuildKarma = _objCharacter.BuildKarma - x;
                }
                this.DialogResult = DialogResult.OK;
                this.Close();
            }
            else
            {
                MessageBox.Show(LanguageManager.Instance.GetString("Message_Metatype_SelectMetatype"), LanguageManager.Instance.GetString("MessageTitle_Metatype_SelectMetatype"), MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

            _objCharacter.Movement = (_objCharacter.AGI.TotalValue * 2).ToString() + "/" + (_objCharacter.AGI.TotalValue * 4).ToString();
        }
Example #17
0
        /// <summary>
        /// Load the Character from an XML file.
        /// </summary>
        public bool Load()
        {
            XmlDocument objXmlDocument = new XmlDocument();
            objXmlDocument.Load(_strFileName);

            XmlNode objXmlCharacter = objXmlDocument.SelectSingleNode("/character");
            XmlNodeList objXmlNodeList;

            try
            {
                _blnIgnoreRules = Convert.ToBoolean(objXmlCharacter["ignorerules"].InnerText);
            }
            catch
            {
                _blnIgnoreRules = false;
            }
            try
            {
                _blnCreated = Convert.ToBoolean(objXmlCharacter["created"].InnerText);
            }
            catch
            {
            }

            ResetCharacter();

            // Get the game edition of the file if possible and make sure it's intended to be used with this version of the application.
            try
            {
                if (objXmlCharacter["gameedition"].InnerText != string.Empty && objXmlCharacter["gameedition"].InnerText != "SR5")
                {
                    MessageBox.Show(LanguageManager.Instance.GetString("Message_IncorrectGameVersion_SR4"), LanguageManager.Instance.GetString("MessageTitle_IncorrectGameVersion"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return false;
                }
            }
            catch
            {
            }

            // Get the name of the settings file in use if possible.
            try
            {
                _strSettingsFileName = objXmlCharacter["settings"].InnerText;
            }
            catch
            {
            }

            // Load the character's settings file.
            if (!_objOptions.Load(_strSettingsFileName))
                return false;

            try
            {
                _decEssenceAtSpecialStart = Convert.ToDecimal(objXmlCharacter["essenceatspecialstart"].InnerText, GlobalOptions.Instance.CultureInfo);
                // fix to work around a mistake made when saving decimal values in previous versions.
                if (_decEssenceAtSpecialStart > EssenceMaximum)
                    _decEssenceAtSpecialStart /= 10;
            }
            catch
            {
            }

            try
            {
                _strVersionCreated = objXmlCharacter["createdversion"].InnerText;
            }
            catch
            {
            }

            // Metatype information.
            _strMetatype = objXmlCharacter["metatype"].InnerText;
            try
            {
                _strWalk = objXmlCharacter["walk"].InnerText;
                _strRun = objXmlCharacter["run"].InnerText;
                _strSprint = objXmlCharacter["sprint"].InnerText;
            }
            catch
            {
            }
            _intMetatypeBP = Convert.ToInt32(objXmlCharacter["metatypebp"].InnerText);
            _strMetavariant = objXmlCharacter["metavariant"].InnerText;
            try
            {
                _strMetatypeCategory = objXmlCharacter["metatypecategory"].InnerText;
            }
            catch
            {
            }
            try
            {
                _intMutantCritterBaseSkills = Convert.ToInt32(objXmlCharacter["mutantcritterbaseskills"].InnerText);
            }
            catch
            {
            }

            // General character information.
            _strName = objXmlCharacter["name"].InnerText;
            try
            {
                _strMugshot = objXmlCharacter["mugshot"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strSex = objXmlCharacter["sex"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strAge = objXmlCharacter["age"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strEyes = objXmlCharacter["eyes"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strHeight = objXmlCharacter["height"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strWeight = objXmlCharacter["weight"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strSkin = objXmlCharacter["skin"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strHair = objXmlCharacter["hair"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strDescription = objXmlCharacter["description"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strBackground = objXmlCharacter["background"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strConcept = objXmlCharacter["concept"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strNotes = objXmlCharacter["notes"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strAlias = objXmlCharacter["alias"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strPlayerName = objXmlCharacter["playername"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strGameNotes = objXmlCharacter["gamenotes"].InnerText;
            }
            catch
            {
            }

            try
            {
                _strGameplayOption = objXmlCharacter["gameplayoption"].InnerText;
            }
            catch
            {
            }
            try
            {
                _intMaxNuyen = Convert.ToInt32(objXmlCharacter["maxnuyen"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intContactMultiplier = Convert.ToInt32(objXmlCharacter["contactmultiplier"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intMaxKarma = Convert.ToInt32(objXmlCharacter["maxkarma"].InnerText);
            }
            catch
            {
            }
            try
            {
                _strPriorityMetatype = objXmlCharacter["prioritymetatype"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strPriorityAttributes = objXmlCharacter["priorityattributes"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strPrioritySpecial = objXmlCharacter["priorityspecial"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strPrioritySkills = objXmlCharacter["priorityskills"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strPriorityResources = objXmlCharacter["priorityresources"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strSkill1 = objXmlCharacter["priorityskill1"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strSkill2 = objXmlCharacter["priorityskill2"].InnerText;
            }
            catch
            {
            }
            try
            {
                _strSkillGroup = objXmlCharacter["priorityskillgroup"].InnerText;
            }
            catch
            {
            }

            try
            {
                _blnIsCritter = Convert.ToBoolean(objXmlCharacter["iscritter"].InnerText);
            }
            catch
            {
            }

            try
            {
                _blnPossessed = Convert.ToBoolean(objXmlCharacter["possessed"].InnerText);
            }
            catch
            {
            }

            try
            {
                _blnOverrideSpecialAttributeESSLoss = Convert.ToBoolean(objXmlCharacter["overridespecialattributeessloss"].InnerText);
            }
            catch
            {
            }

            try
            {
                _intContactPoints = Convert.ToInt32(objXmlCharacter["contactpoints"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intContactPointsUsed = Convert.ToInt32(objXmlCharacter["contactpointsused"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intCFPLimit = Convert.ToInt32(objXmlCharacter["cfplimit"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intSpellLimit = Convert.ToInt32(objXmlCharacter["spelllimit"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intKarma = Convert.ToInt32(objXmlCharacter["karma"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intTotalKarma = Convert.ToInt32(objXmlCharacter["totalkarma"].InnerText);
            }
            catch
            {
            }

            try
            {
                _intSpecial = Convert.ToInt32(objXmlCharacter["special"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intTotalSpecial = Convert.ToInt32(objXmlCharacter["totalspecial"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intAttributes = Convert.ToInt32(objXmlCharacter["attributes"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intTotalAttributes = Convert.ToInt32(objXmlCharacter["totalattributes"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intContactPoints = Convert.ToInt32(objXmlCharacter["contactpoints"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intContactPointsUsed = Convert.ToInt32(objXmlCharacter["contactpointsused"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intStreetCred = Convert.ToInt32(objXmlCharacter["streetcred"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intNotoriety = Convert.ToInt32(objXmlCharacter["notoriety"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intPublicAwareness = Convert.ToInt32(objXmlCharacter["publicawareness"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intBurntStreetCred = Convert.ToInt32(objXmlCharacter["burntstreetcred"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intMaxAvail = Convert.ToInt32(objXmlCharacter["maxavail"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intNuyen = Convert.ToInt32(objXmlCharacter["nuyen"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intStartingNuyen = Convert.ToInt32(objXmlCharacter["startingnuyen"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intAdeptWayDiscount = Convert.ToInt32(objXmlCharacter["adeptwaydiscount"].InnerText);
            }
            catch
            {
            }

            // Sum to X point value.
            try
            {
                _intSumtoTen = Convert.ToInt32(objXmlCharacter["sumtoten"].InnerText);
            }
            catch
            {
            }
            // Build Points/Karma.
            _intBuildPoints = Convert.ToInt32(objXmlCharacter["bp"].InnerText);
            try
            {
                _intBuildKarma = Convert.ToInt32(objXmlCharacter["buildkarma"].InnerText);
                if (_intMaxKarma == 0)
                    _intMaxKarma = _intBuildKarma;
                if (_intBuildKarma == 35 && _strGameplayOption == "")
                {
                    _strGameplayOption = "Prime Runner";
                }
                if (_intBuildKarma == 35 && _intMaxNuyen == 0)
                {
                    _intMaxNuyen = 25;
                }
            }
            catch
            {
            }
            //Maximum number of Karma that can be spent/gained on Qualities.
            try
            {
                _intGameplayOptionQualityLimit = Convert.ToInt32(objXmlCharacter["gameplayoptionqualitylimit"].InnerText);
            }
            catch
            {
            }
            try
            {
                _objBuildMethod = ConvertToCharacterBuildMethod(objXmlCharacter["buildmethod"].InnerText);
            }
            catch
            {
            }
            try
            {
                _intKnowledgeSkills = Convert.ToInt32(objXmlCharacter["knowskillpts"].InnerText);

            }
            catch { }
            _intKnowledgeSkillPoints = Convert.ToInt32(objXmlCharacter["knowpts"].InnerText);
            _intSkillPoints = Convert.ToInt32(objXmlCharacter["skillpts"].InnerText);
            _intSkillPointsMaximum = Convert.ToInt32(objXmlCharacter["skillptsmax"].InnerText);
            _intSkillGroups = Convert.ToInt32(objXmlCharacter["skillgrps"].InnerText);
            _intSkillGroupsMaximum = Convert.ToInt32(objXmlCharacter["skillgrpsmax"].InnerText);
            _decNuyenBP = Convert.ToDecimal(objXmlCharacter["nuyenbp"].InnerText, GlobalOptions.Instance.CultureInfo);
            _decNuyenMaximumBP = Convert.ToDecimal(objXmlCharacter["nuyenmaxbp"].InnerText, GlobalOptions.Instance.CultureInfo);
            _blnAdeptEnabled = Convert.ToBoolean(objXmlCharacter["adept"].InnerText);
            _blnMagicianEnabled = Convert.ToBoolean(objXmlCharacter["magician"].InnerText);
            _blnTechnomancerEnabled = Convert.ToBoolean(objXmlCharacter["technomancer"].InnerText);
            try
            {
                _blnInitiationEnabled = Convert.ToBoolean(objXmlCharacter["initiationoverride"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnCritterEnabled = Convert.ToBoolean(objXmlCharacter["critter"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnUneducated = Convert.ToBoolean(objXmlCharacter["uneducated"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnUncouth = Convert.ToBoolean(objXmlCharacter["uncouth"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnSchoolOfHardKnocks = Convert.ToBoolean(objXmlCharacter["schoolofhardknocks"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnFriendsInHighPlaces = Convert.ToBoolean(objXmlCharacter["friendsinhighplaces"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnCollegeEducation = Convert.ToBoolean(objXmlCharacter["collegeeducation"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnJackOfAllTrades = Convert.ToBoolean(objXmlCharacter["jackofalltrades"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnInfirm = Convert.ToBoolean(objXmlCharacter["infirm"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnBlackMarket = Convert.ToBoolean(objXmlCharacter["blackmarket"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnExCon = Convert.ToBoolean(objXmlCharacter["excon"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnTrustFund = Convert.ToBoolean(objXmlCharacter["trustfund"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnTechSchool = Convert.ToBoolean(objXmlCharacter["techschool"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnRestrictedGear = Convert.ToBoolean(objXmlCharacter["restrictedgear"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnOverclocker = Convert.ToBoolean(objXmlCharacter["overclocker"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnMadeMan = Convert.ToBoolean(objXmlCharacter["mademan"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnLinguist = Convert.ToBoolean(objXmlCharacter["linguist"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnLightningReflexes = Convert.ToBoolean(objXmlCharacter["lightningreflexes"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnFame = Convert.ToBoolean(objXmlCharacter["fame"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnBornRich = Convert.ToBoolean(objXmlCharacter["bornrich"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnErased = Convert.ToBoolean(objXmlCharacter["erased"].InnerText);
            }
            catch
            {
            }
            _blnMAGEnabled = Convert.ToBoolean(objXmlCharacter["magenabled"].InnerText);
            try
            {
                _intInitiateGrade = Convert.ToInt32(objXmlCharacter["initiategrade"].InnerText);
            }
            catch
            {
            }
            _blnRESEnabled = Convert.ToBoolean(objXmlCharacter["resenabled"].InnerText);
            try
            {
                _intSubmersionGrade = Convert.ToInt32(objXmlCharacter["submersiongrade"].InnerText);
            }
            catch
            {
            }
            try
            {
                _blnGroupMember = Convert.ToBoolean(objXmlCharacter["groupmember"].InnerText);
            }
            catch
            {
            }
            try
            {
                _strGroupName = objXmlCharacter["groupname"].InnerText;
                _strGroupNotes = objXmlCharacter["groupnotes"].InnerText;
            }
            catch
            {
            }

            // Improvements.
            XmlNodeList objXmlImprovementList = objXmlDocument.SelectNodes("/character/improvements/improvement");
            foreach (XmlNode objXmlImprovement in objXmlImprovementList)
            {
                Improvement objImprovement = new Improvement();
                objImprovement.Load(objXmlImprovement);
                _lstImprovements.Add(objImprovement);
            }

            // Qualities
            objXmlNodeList = objXmlDocument.SelectNodes("/character/qualities/quality");
            bool blnHasOldQualities = false;
            foreach (XmlNode objXmlQuality in objXmlNodeList)
            {
                if (objXmlQuality["name"] != null)
                {
                    Quality objQuality = new Quality(this);
                    objQuality.Load(objXmlQuality);
                    _lstQualities.Add(objQuality);
                }
                else
                {
                    // If the Quality does not have a name tag, it is in the old format. Set the flag to show that old Qualities are in use.
                    blnHasOldQualities = true;
                }
            }
            // If old Qualities are in use, they need to be converted before we can continue.
            if (blnHasOldQualities)
                ConvertOldQualities(objXmlNodeList);

            // Attributes.
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"BOD\"]");
            _attBOD.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"AGI\"]");
            _attAGI.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"REA\"]");
            _attREA.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"STR\"]");
            _attSTR.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"CHA\"]");
            _attCHA.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"INT\"]");
            _attINT.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"LOG\"]");
            _attLOG.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"WIL\"]");
            _attWIL.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"INI\"]");
            _attINI.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"EDG\"]");
            _attEDG.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"MAG\"]");
            _attMAG.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"RES\"]");
            _attRES.Load(objXmlCharacter);
            objXmlCharacter = objXmlDocument.SelectSingleNode("/character/attributes/attribute[name = \"ESS\"]");
            _attESS.Load(objXmlCharacter);

            // A.I. Attributes.
            try
            {
                _intSignal = Convert.ToInt32(objXmlDocument.SelectSingleNode("/character/attributes/signal").InnerText);
                _intResponse = Convert.ToInt32(objXmlDocument.SelectSingleNode("/character/attributes/response").InnerText);
            }
            catch
            {
            }

            // Force.
            try
            {
                _intMaxSkillRating = Convert.ToInt32(objXmlDocument.SelectSingleNode("/character/attributes/maxskillrating").InnerText);
            }
            catch
            {
            }

            // Attempt to load the split MAG Attribute information for Mystic Adepts.
            if (_blnAdeptEnabled && _blnMagicianEnabled)
            {
                try
                {
                    _intMAGAdept = Convert.ToInt32(objXmlDocument.SelectSingleNode("/character/magsplitadept").InnerText);
                    _intMAGMagician = Convert.ToInt32(objXmlDocument.SelectSingleNode("/character/magsplitmagician").InnerText);
                }
                catch
                {
                }
            }

            // Attempt to load the Magic Tradition.
            try
            {
                _strMagicTradition = objXmlDocument.SelectSingleNode("/character/tradition").InnerText;
            }
            catch
            {
            }
            // Attempt to load the Magic Tradition Drain Attributes.
            try
            {
                _strTraditionDrain = objXmlDocument.SelectSingleNode("/character/traditiondrain").InnerText;
            }
            catch
            {
            }
            // Attempt to load the Magic Tradition Name.
            try
            {
                _strTraditionName = objXmlDocument.SelectSingleNode("/character/traditionname").InnerText;
            }
            catch
            {
            }
            // Attempt to load the Spirit Combat Name.
            try
            {
                _strSpiritCombat = objXmlDocument.SelectSingleNode("/character/spiritcombat").InnerText;
            }
            catch
            {
            }
            // Attempt to load the Spirit Detection Name.
            try
            {
                _strSpiritDetection = objXmlDocument.SelectSingleNode("/character/spiritdetection").InnerText;
            }
            catch
            {
            }
            // Attempt to load the Spirit Health Name.
            try
            {
                _strSpiritHealth = objXmlDocument.SelectSingleNode("/character/spirithealth").InnerText;
            }
            catch
            {
            }
            // Attempt to load the Spirit Illusion Name.
            try
            {
                _strSpiritIllusion = objXmlDocument.SelectSingleNode("/character/spiritillusion").InnerText;
            }
            catch
            {
            }
            // Attempt to load the Spirit Manipulation Name.
            try
            {
                _strSpiritManipulation = objXmlDocument.SelectSingleNode("/character/spiritmanipulation").InnerText;
            }
            catch
            {
            }
            // Attempt to load the Technomancer Stream.
            try
            {
                _strTechnomancerStream = objXmlDocument.SelectSingleNode("/character/stream").InnerText;
            }
            catch
            {
            }

            // Attempt to load Condition Monitor Progress.
            try
            {
                _intPhysicalCMFilled = Convert.ToInt32(objXmlDocument.SelectSingleNode("/character/physicalcmfilled").InnerText);
                _intStunCMFilled = Convert.ToInt32(objXmlDocument.SelectSingleNode("/character/stuncmfilled").InnerText);
            }
            catch
            {
            }

            // Skills.
            foreach (Skill objSkill in _lstSkills)
            {
                XmlNode objXmlSkill = objXmlDocument.SelectSingleNode("/character/skills/skill[name = \"" + objSkill.Name + "\"]");
                if (objXmlSkill != null)
                {
                    objSkill.Load(objXmlSkill);
                }
            }

            // Exotic Skills.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/skills/skill[exotic = \"True\"]");
            foreach (XmlNode objXmlSkill in objXmlNodeList)
            {
                Skill objSkill = new Skill(this);
                objSkill.Load(objXmlSkill);
                _lstSkills.Add(objSkill);
            }

            // SkillGroups.
            foreach (SkillGroup objGroup in _lstSkillGroups)
            {
                XmlNode objXmlSkill = objXmlDocument.SelectSingleNode("/character/skillgroups/skillgroup[name = \"" + objGroup.Name + "\"]");
                if (objXmlSkill != null)
                {
                    objGroup.Load(objXmlSkill);
                    // If the character is set to ignore rules or is in Career Mode, Skill Groups should have a maximum Rating of 6 unless they have been given a higher maximum Rating already.
                    if ((_blnIgnoreRules || _blnCreated) && objGroup.RatingMaximum < 12)
                        objGroup.RatingMaximum = 12;
                }
            }

            // Apply the broken skill group fix
            foreach (Skill objSkill in _lstSkills)
            {
                foreach (SkillGroup objGroup in _lstSkillGroups)
                {
                    if (objGroup.Broken && objGroup.Name == objSkill.SkillGroup)
                    {
                        objSkill.FreeLevels = objGroup.Rating;
                        objSkill.Base = objGroup.Rating;
                        objSkill.Karma = objSkill.Rating - objSkill.Base;
                    }
                }
            }

            foreach (SkillGroup objGroup in _lstSkillGroups)
            {
                if (objGroup.Base == 0 && objGroup.Karma == 0 && objGroup.Rating > 0)
                    objGroup.Base = objGroup.Rating;
            }

            // Knowledge Skills.
            List<ListItem> lstKnowledgeSkillOrder = new List<ListItem>();
            objXmlNodeList = objXmlDocument.SelectNodes("/character/skills/skill[knowledge = \"True\"]");
            // Sort the Knowledge Skills in alphabetical order.
            foreach (XmlNode objXmlSkill in objXmlNodeList)
            {
                ListItem objGroup = new ListItem();
                objGroup.Value = objXmlSkill["name"].InnerText;
                objGroup.Name = objXmlSkill["name"].InnerText;
                lstKnowledgeSkillOrder.Add(objGroup);
            }
            SortListItem objSort = new SortListItem();
            lstKnowledgeSkillOrder.Sort(objSort.Compare);

            foreach (ListItem objItem in lstKnowledgeSkillOrder)
            {
                Skill objSkill = new Skill(this);
                XmlNode objNode = objXmlDocument.SelectSingleNode("/character/skills/skill[knowledge = \"True\" and name = " + CleanXPath(objItem.Value) + "]");
                objSkill.Load(objNode);
                _lstSkills.Add(objSkill);
            }

            // Contacts.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/contacts/contact");
            foreach (XmlNode objXmlContact in objXmlNodeList)
            {
                Contact objContact = new Contact(this);
                objContact.Load(objXmlContact);
                _lstContacts.Add(objContact);
            }

            // Armor.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/armors/armor");
            foreach (XmlNode objXmlArmor in objXmlNodeList)
            {
                Armor objArmor = new Armor(this);
                objArmor.Load(objXmlArmor);
                _lstArmor.Add(objArmor);
            }

            // Weapons.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/weapons/weapon");
            foreach (XmlNode objXmlWeapon in objXmlNodeList)
            {
                Weapon objWeapon = new Weapon(this);
                objWeapon.Load(objXmlWeapon);
                _lstWeapons.Add(objWeapon);
            }

            // Cyberware/Bioware.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/cyberwares/cyberware");
            foreach (XmlNode objXmlCyberware in objXmlNodeList)
            {
                Cyberware objCyberware = new Cyberware(this);
                objCyberware.Load(objXmlCyberware);
                _lstCyberware.Add(objCyberware);
            }

            // Spells.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/spells/spell");
            foreach (XmlNode objXmlSpell in objXmlNodeList)
            {
                Spell objSpell = new Spell(this);
                objSpell.Load(objXmlSpell);
                _lstSpells.Add(objSpell);
            }

            // Foci.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/foci/focus");
            foreach (XmlNode objXmlFocus in objXmlNodeList)
            {
                Focus objFocus = new Focus();
                objFocus.Load(objXmlFocus);
                _lstFoci.Add(objFocus);
            }

            // Stacked Foci.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/stackedfoci/stackedfocus");
            foreach (XmlNode objXmlStack in objXmlNodeList)
            {
                StackedFocus objStack = new StackedFocus(this);
                objStack.Load(objXmlStack);
                _lstStackedFoci.Add(objStack);
            }

            // Powers.
            List<ListItem> lstPowerOrder = new List<ListItem>();
            objXmlNodeList = objXmlDocument.SelectNodes("/character/powers/power");
            // Sort the Powers in alphabetical order.
            foreach (XmlNode objXmlPower in objXmlNodeList)
            {
                ListItem objGroup = new ListItem();
                objGroup.Value = objXmlPower["extra"].InnerText;
                objGroup.Name = objXmlPower["name"].InnerText;

                lstPowerOrder.Add(objGroup);
            }
            objSort = new SortListItem();
            lstPowerOrder.Sort(objSort.Compare);

            foreach (ListItem objItem in lstPowerOrder)
            {
                Power objPower = new Power(this);
                XmlNode objNode = objXmlDocument.SelectSingleNode("/character/powers/power[name = " + CleanXPath(objItem.Name) + " and extra = " + CleanXPath(objItem.Value) + "]");
                objPower.Load(objNode);
                _lstPowers.Add(objPower);
            }

            // Spirits/Sprites.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/spirits/spirit");
            foreach (XmlNode objXmlSpirit in objXmlNodeList)
            {
                Spirit objSpirit = new Spirit(this);
                objSpirit.Load(objXmlSpirit);
                _lstSpirits.Add(objSpirit);
            }

            // Compex Forms/Technomancer Programs.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/complexforms/complexform");
            foreach (XmlNode objXmlProgram in objXmlNodeList)
            {
                ComplexForm objProgram = new ComplexForm(this);
                objProgram.Load(objXmlProgram);
                _lstComplexForms.Add(objProgram);
            }

            // Martial Arts.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/martialarts/martialart");
            foreach (XmlNode objXmlArt in objXmlNodeList)
            {
                MartialArt objMartialArt = new MartialArt(this);
                objMartialArt.Load(objXmlArt);
                _lstMartialArts.Add(objMartialArt);
            }

            // Martial Art Maneuvers.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/martialartmaneuvers/martialartmaneuver");
            foreach (XmlNode objXmlManeuver in objXmlNodeList)
            {
                MartialArtManeuver objManeuver = new MartialArtManeuver(this);
                objManeuver.Load(objXmlManeuver);
                _lstMartialArtManeuvers.Add(objManeuver);
            }

            // Limit Modifiers.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/limitmodifiers/limitmodifier");
            foreach (XmlNode objXmlLimit in objXmlNodeList)
            {
                LimitModifier obLimitModifier = new LimitModifier(this);
                obLimitModifier.Load(objXmlLimit);
                _lstLimitModifiers.Add(obLimitModifier);
            }

            // Lifestyles.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/lifestyles/lifestyle");
            foreach (XmlNode objXmlLifestyle in objXmlNodeList)
            {
                Lifestyle objLifestyle = new Lifestyle(this);
                objLifestyle.Load(objXmlLifestyle);
                _lstLifestyles.Add(objLifestyle);
            }

            // <gears>
            objXmlNodeList = objXmlDocument.SelectNodes("/character/gears/gear");
            foreach (XmlNode objXmlGear in objXmlNodeList)
            {
                switch (objXmlGear["category"].InnerText)
                {
                    case "Commlinks":
                    case "Cyberdecks":
                    case "Rigger Command Consoles":
                        Commlink objCommlink = new Commlink(this);
                        objCommlink.Load(objXmlGear);
                        _lstGear.Add(objCommlink);
                        break;
                    default:
                        Gear objGear = new Gear(this);
                        objGear.Load(objXmlGear);
                        _lstGear.Add(objGear);
                        break;
                }
            }

            // Vehicles.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/vehicles/vehicle");
            foreach (XmlNode objXmlVehicle in objXmlNodeList)
            {
                Vehicle objVehicle = new Vehicle(this);
                objVehicle.Load(objXmlVehicle);
                _lstVehicles.Add(objVehicle);
            }

            // Metamagics/Echoes.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/metamagics/metamagic");
            foreach (XmlNode objXmlMetamagic in objXmlNodeList)
            {
                Metamagic objMetamagic = new Metamagic(this);
                objMetamagic.Load(objXmlMetamagic);
                _lstMetamagics.Add(objMetamagic);
            }

            // Arts
            objXmlNodeList = objXmlDocument.SelectNodes("/character/arts/art");
            foreach (XmlNode objXmlArt in objXmlNodeList)
            {
                Art objArt = new Art(this);
                objArt.Load(objXmlArt);
                _lstArts.Add(objArt);
            }

            // Enhancements
            objXmlNodeList = objXmlDocument.SelectNodes("/character/enhancements/enhancement");
            foreach (XmlNode objXmlEnhancement in objXmlNodeList)
            {
                Enhancement objEnhancement = new Enhancement(this);
                objEnhancement.Load(objXmlEnhancement);
                _lstEnhancements.Add(objEnhancement);
            }

            // Critter Powers.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/critterpowers/critterpower");
            foreach (XmlNode objXmlPower in objXmlNodeList)
            {
                CritterPower objPower = new CritterPower(this);
                objPower.Load(objXmlPower);
                _lstCritterPowers.Add(objPower);
            }

            // Initiation Grades.
            objXmlNodeList = objXmlDocument.SelectNodes("/character/initiationgrades/initiationgrade");
            foreach (XmlNode objXmlGrade in objXmlNodeList)
            {
                InitiationGrade objGrade = new InitiationGrade(this);
                objGrade.Load(objXmlGrade);
                _lstInitiationGrades.Add(objGrade);
            }

            // Expense Log Entries.
            XmlNodeList objXmlExpenseList = objXmlDocument.SelectNodes("/character/expenses/expense");
            foreach (XmlNode objXmlExpense in objXmlExpenseList)
            {
                ExpenseLogEntry objExpenseLogEntry = new ExpenseLogEntry();
                objExpenseLogEntry.Load(objXmlExpense);
                _lstExpenseLog.Add(objExpenseLogEntry);
            }

            // Locations.
            XmlNodeList objXmlLocationList = objXmlDocument.SelectNodes("/character/locations/location");
            foreach (XmlNode objXmlLocation in objXmlLocationList)
            {
                _lstLocations.Add(objXmlLocation.InnerText);
            }

            // Armor Bundles.
            XmlNodeList objXmlBundleList = objXmlDocument.SelectNodes("/character/armorbundles/armorbundle");
            foreach (XmlNode objXmlBundle in objXmlBundleList)
            {
                _lstArmorBundles.Add(objXmlBundle.InnerText);
            }

            // Weapon Locations.
            XmlNodeList objXmlWeaponLocationList = objXmlDocument.SelectNodes("/character/weaponlocations/weaponlocation");
            foreach (XmlNode objXmlLocation in objXmlWeaponLocationList)
            {
                _lstWeaponLocations.Add(objXmlLocation.InnerText);
            }

            // Improvement Groups.
            XmlNodeList objXmlGroupList = objXmlDocument.SelectNodes("/character/improvementgroups/improvementgroup");
            foreach (XmlNode objXmlGroup in objXmlGroupList)
            {
                _lstImprovementGroups.Add(objXmlGroup.InnerText);
            }

            // Calendar.
            XmlNodeList objXmlWeekList = objXmlDocument.SelectNodes("/character/calendar/week");
            foreach (XmlNode objXmlWeek in objXmlWeekList)
            {
                CalendarWeek objWeek = new CalendarWeek();
                objWeek.Load(objXmlWeek);
                _lstCalendar.Add(objWeek);
            }

            // Look for the unarmed attack
            bool blnFoundUnarmed = false;
            foreach (Weapon objWeapon in _lstWeapons)
            {
                if (objWeapon.Name == "Unarmed Attack")
                    blnFoundUnarmed = true;
            }

            if (!blnFoundUnarmed)
            {
                // Add the Unarmed Attack Weapon to the character.
                try
                {
                    XmlDocument objXmlWeaponDoc = XmlManager.Instance.Load("weapons.xml");
                    XmlNode objXmlWeapon = objXmlWeaponDoc.SelectSingleNode("/chummer/weapons/weapon[name = \"Unarmed Attack\"]");
                    TreeNode objGearWeaponNode = new TreeNode();
                    Weapon objWeapon = new Weapon(this);
                    objWeapon.Create(objXmlWeapon, this, objGearWeaponNode, null, null, null);
                    objGearWeaponNode.ForeColor = SystemColors.GrayText;
                    _lstWeapons.Add(objWeapon);
                }
                catch
                {
                }
            }

            // converting from old dwarven resistance to new dwarven resistance
            if (this.Metatype.ToLower().Equals("dwarf")
                && this.Qualities.Where(x => x.Name.Equals("Dwarf Resistance")).FirstOrDefault() == null
                && this.Qualities.Where(x => x.Name.Equals("Resistance to Pathogens and Toxins")).FirstOrDefault() != null)
            {
                this.Qualities.Remove(this.Qualities.Where(x => x.Name.Equals("Resistance to Pathogens and Toxins")).First());
                XmlNode objXmlDwarfQuality = XmlManager.Instance.Load("qualities.xml").SelectSingleNode("/chummer/qualities/quality[name = \"Dwarf Resistance\"]");

                TreeNode objNode = new TreeNode();
                List<Weapon> objWeapons = new List<Weapon>();
                List<TreeNode> objWeaponNodes = new List<TreeNode>();
                Quality objQuality = new Quality(this);

                objQuality.Create(objXmlDwarfQuality, this, QualitySource.Metatype, objNode, objWeapons, objWeaponNodes);
                this._lstQualities.Add(objQuality);
                blnHasOldQualities = true;
            }

            // load issue where the contact multiplier was set to 0
            if (_intContactMultiplier == 0 && _strGameplayOption != string.Empty)
            {
                XmlDocument objXmlDocumentPriority = XmlManager.Instance.Load("gameplayoptions.xml");
                XmlNode objXmlGameplayOption = objXmlDocumentPriority.SelectSingleNode("/chummer/gameplayoptions/gameplayoption[name = \"" + _strGameplayOption + "\"]");
                string strKarma = objXmlGameplayOption["karma"].InnerText;
                string strNuyen = objXmlGameplayOption["maxnuyen"].InnerText;
                string strContactMultiplier = "0";
                if (!_objOptions.FreeContactsMultiplierEnabled)
                {

                    strContactMultiplier = objXmlGameplayOption["contactmultiplier"].InnerText;
                }
                else
                {
                    strContactMultiplier = _objOptions.FreeContactsMultiplier.ToString();
                }
                _intMaxKarma = Convert.ToInt32(strKarma);
                _intMaxNuyen = Convert.ToInt32(strNuyen);
                _intContactMultiplier = Convert.ToInt32(strContactMultiplier);
                _intContactPoints = (CHA.Base + CHA.Karma) * _intContactMultiplier;
            }

            // If the character had old Qualities that were converted, immediately save the file so they are in the new format.
            if (blnHasOldQualities)
                Save();

            return true;
        }
Example #18
0
        /// <summary>
        /// Refresh the Skill information for the currently selected Complex Form.
        /// </summary>
        private void RefreshComplexFormSkill()
        {
            // Locate the Program that is selected in the tree.
            try
            {
                if (treComplexForms.SelectedNode == null)
                    return;
            }
            catch
            {
                return;
            }

            TechProgram objProgram = _objFunctions.FindTechProgram(treComplexForms.SelectedNode.Tag.ToString(), _objCharacter.TechPrograms);
            if (objProgram == null)
                return;

            // Update the Dice Pool information.
            Skill objSkill = new Skill(_objCharacter);
            foreach (Skill objCharacterSkill in _objCharacter.Skills)
            {
                if (objCharacterSkill.Name == cboComplexFormSkill.SelectedValue.ToString())
                {
                    objSkill = objCharacterSkill;
                    break;
                }
            }

            if (!_objOptions.AlternateMatrixAttribute)
            {
                if (!_objOptions.AlternateComplexFormCost)
                    lblComplexFormDicePool.Text = " + " + objProgram.Rating.ToString() + " = " + (objSkill.TotalRating - objSkill.AttributeModifiers + objProgram.Rating).ToString();
                else
                    lblComplexFormDicePool.Text = " + " + nudComplexFormRating.Value.ToString() + " = " + (objSkill.TotalRating - objSkill.AttributeModifiers + nudComplexFormRating.Value).ToString();
            }
            else
            {
                // If using the Alternate Matrix Attribute optional rule, use the selected Attribute instead of the Program's Rating.
                lblComplexFormDicePool.Text = " = " + (objSkill.TotalRating - objSkill.AttributeModifiers + _objCharacter.GetAttribute(cboComplexFormAttribute.SelectedValue.ToString()).TotalValue).ToString();
            }
        }
Example #19
0
        /// <summary>
        /// Add a PACKS Kit to the character.
        /// </summary>
        public void AddPACKSKit()
        {
            frmSelectPACKSKit frmPickPACKSKit = new frmSelectPACKSKit(_objCharacter);
            frmPickPACKSKit.ShowDialog(this);

            bool blnCreateChildren = true;

            // If the form was canceled, don't do anything.
            if (frmPickPACKSKit.DialogResult == DialogResult.Cancel)
                return;

            XmlDocument objXmlDocument = XmlManager.Instance.Load("packs.xml");

            // Do not create child items for Gear if the chosen Kit is in the Custom category since these items will contain the exact plugins desired.
            if (frmPickPACKSKit.SelectedCategory == "Custom")
                blnCreateChildren = false;

            XmlNode objXmlKit = objXmlDocument.SelectSingleNode("/chummer/packs/pack[name = \"" + frmPickPACKSKit.SelectedKit + "\" and category = \"" + frmPickPACKSKit.SelectedCategory + "\"]");
            // Update Qualities.
            if (objXmlKit["qualities"] != null)
            {
                XmlDocument objXmlQualityDocument = XmlManager.Instance.Load("qualities.xml");

                // Positive Qualities.
                foreach (XmlNode objXmlQuality in objXmlKit.SelectNodes("qualities/positive/quality"))
                {
                    XmlNode objXmlQualityNode = objXmlQualityDocument.SelectSingleNode("/chummer/qualities/quality[name = \"" + objXmlQuality.InnerText + "\"]");

                    TreeNode objNode = new TreeNode();
                    List<Weapon> objWeapons = new List<Weapon>();
                    List<TreeNode> objWeaponNodes = new List<TreeNode>();
                    Quality objQuality = new Quality(_objCharacter);
                    string strForceValue = "";

                    if (objXmlQuality.Attributes["select"] != null)
                        strForceValue = objXmlQuality.Attributes["select"].InnerText;

                    objQuality.Create(objXmlQualityNode, _objCharacter, QualitySource.Selected, objNode, objWeapons, objWeaponNodes, strForceValue);
                    _objCharacter.Qualities.Add(objQuality);

                    treQualities.Nodes[0].Nodes.Add(objNode);
                    treQualities.Nodes[0].Expand();

                    // Add any created Weapons to the character.
                    foreach (Weapon objWeapon in objWeapons)
                        _objCharacter.Weapons.Add(objWeapon);

                    // Create the Weapon Node if one exists.
                    foreach (TreeNode objWeaponNode in objWeaponNodes)
                    {
                        objWeaponNode.ContextMenuStrip = cmsWeapon;
                        treWeapons.Nodes[0].Nodes.Add(objWeaponNode);
                        treWeapons.Nodes[0].Expand();
                    }
                }

                // Negative Qualities.
                foreach (XmlNode objXmlQuality in objXmlKit.SelectNodes("qualities/negative/quality"))
                {
                    XmlNode objXmlQualityNode = objXmlQualityDocument.SelectSingleNode("/chummer/qualities/quality[name = \"" + objXmlQuality.InnerText + "\"]");

                    TreeNode objNode = new TreeNode();
                    List<Weapon> objWeapons = new List<Weapon>();
                    List<TreeNode> objWeaponNodes = new List<TreeNode>();
                    Quality objQuality = new Quality(_objCharacter);
                    string strForceValue = "";

                    if (objXmlQuality.Attributes["select"] != null)
                        strForceValue = objXmlQuality.Attributes["select"].InnerText;

                    objQuality.Create(objXmlQualityNode, _objCharacter, QualitySource.Selected, objNode, objWeapons, objWeaponNodes, strForceValue);
                    _objCharacter.Qualities.Add(objQuality);

                    treQualities.Nodes[1].Nodes.Add(objNode);
                    treQualities.Nodes[1].Expand();

                    // Add any created Weapons to the character.
                    foreach (Weapon objWeapon in objWeapons)
                        _objCharacter.Weapons.Add(objWeapon);

                    // Create the Weapon Node if one exists.
                    foreach (TreeNode objWeaponNode in objWeaponNodes)
                    {
                        objWeaponNode.ContextMenuStrip = cmsWeapon;
                        treWeapons.Nodes[0].Nodes.Add(objWeaponNode);
                        treWeapons.Nodes[0].Expand();
                    }
                }
            }

            // Update Attributes.
            if (objXmlKit["attributes"] != null)
            {
                // Reset all Attributes back to 1 so we don't go over any BP limits.
                nudBOD.Value = nudBOD.Minimum;
                nudAGI.Value = nudAGI.Minimum;
                nudREA.Value = nudREA.Minimum;
                nudSTR.Value = nudSTR.Minimum;
                nudCHA.Value = nudCHA.Minimum;
                nudINT.Value = nudINT.Minimum;
                nudLOG.Value = nudLOG.Minimum;
                nudWIL.Value = nudWIL.Minimum;
                nudEDG.Value = nudEDG.Minimum;
                nudMAG.Value = nudMAG.Minimum;
                nudRES.Value = nudRES.Minimum;
                foreach (XmlNode objXmlAttribute in objXmlKit["attributes"])
                {
                    // The Attribute is calculated as given value - (6 - Metatype Maximum) so that each Metatype has the values from the file adjusted correctly.
                    switch (objXmlAttribute.Name)
                    {
                        case "bod":
                            nudBOD.Value = Convert.ToInt32(objXmlAttribute.InnerText) - (6 - _objCharacter.BOD.MetatypeMaximum);
                            break;
                        case "agi":
                            nudAGI.Value = Convert.ToInt32(objXmlAttribute.InnerText) - (6 - _objCharacter.AGI.MetatypeMaximum);
                            break;
                        case "rea":
                            nudREA.Value = Convert.ToInt32(objXmlAttribute.InnerText) - (6 - _objCharacter.REA.MetatypeMaximum);
                            break;
                        case "str":
                            nudSTR.Value = Convert.ToInt32(objXmlAttribute.InnerText) - (6 - _objCharacter.STR.MetatypeMaximum);
                            break;
                        case "cha":
                            nudCHA.Value = Convert.ToInt32(objXmlAttribute.InnerText) - (6 - _objCharacter.CHA.MetatypeMaximum);
                            break;
                        case "int":
                            nudINT.Value = Convert.ToInt32(objXmlAttribute.InnerText) - (6 - _objCharacter.INT.MetatypeMaximum);
                            break;
                        case "log":
                            nudLOG.Value = Convert.ToInt32(objXmlAttribute.InnerText) - (6 - _objCharacter.LOG.MetatypeMaximum);
                            break;
                        case "wil":
                            nudWIL.Value = Convert.ToInt32(objXmlAttribute.InnerText) - (6 - _objCharacter.WIL.MetatypeMaximum);
                            break;
                        case "mag":
                            nudMAG.Value = Convert.ToInt32(objXmlAttribute.InnerText) - (6 - _objCharacter.MAG.MetatypeMaximum);
                            break;
                        case "res":
                            nudRES.Value = Convert.ToInt32(objXmlAttribute.InnerText) - (6 - _objCharacter.RES.MetatypeMaximum);
                            break;
                        default:
                            nudEDG.Value = Convert.ToInt32(objXmlAttribute.InnerText) - (6 - _objCharacter.EDG.MetatypeMaximum);
                            break;
                    }
                }
            }

            // Update Skills.
            if (objXmlKit["skills"] != null)
            {
                // Active Skills.
                foreach (XmlNode objXmlSkill in objXmlKit.SelectNodes("skills/skill"))
                {
                    if (objXmlSkill["name"].InnerText.Contains("Exotic"))
                    {
                        int i = panActiveSkills.Controls.Count;
                        Skill objSkill = new Skill(_objCharacter);

                        SkillControl objSkillControl = new SkillControl(_objCharacter);
                        objSkillControl.SkillObject = objSkill;
                        objSkillControl.Width = 510;

                        // Attach an EventHandler for the RatingChanged and SpecializationChanged Events.
                        objSkillControl.RatingChanged += objActiveSkill_RatingChanged;
                        objSkillControl.SpecializationChanged += objSkill_SpecializationChanged;
                        objSkillControl.SkillName = objXmlSkill["name"].InnerText;

                        switch (objXmlSkill["name"].InnerText)
                        {
                            case "Exotic Ranged Weapon":
                            case "Exotic Melee Weapon":
                                objSkill.Attribute = "AGI";
                                objSkillControl.SkillCategory = "Combat Active";
                                objSkill.Default = true;
                                break;
                            default:
                                objSkill.Attribute = "REA";
                                objSkillControl.SkillCategory = "Vehicle Active";
                                objSkill.Default = false;
                                break;
                        }
                        objSkill.ExoticSkill = true;
                        _objCharacter.Skills.Add(objSkill);


						if (_objCharacter.IgnoreRules)
						{
							objSkillControl.SkillRatingMaximum = 12;
						}
						else
						{
							objSkillControl.SkillRatingMaximum = 6;
						}

						// Make sure it's not going above the maximum number.
						if (Convert.ToInt32(objXmlSkill["rating"].InnerText) > objSkillControl.SkillRatingMaximum)
                            objSkillControl.SkillRating = objSkillControl.SkillRatingMaximum;
                        else
                            objSkillControl.SkillRating = Convert.ToInt32(objXmlSkill["rating"].InnerText);

                        if (objXmlSkill["spec"] != null)
                            objSkillControl.SkillSpec = objXmlSkill["spec"].InnerText;
                        else
                            objSkillControl.SkillSpec = "";

                        // Set the SkillControl's Location since scrolling the Panel causes it to actually change the child Controls' Locations.
                        objSkillControl.Location = new Point(0, objSkillControl.Height * i + panActiveSkills.AutoScrollPosition.Y);
                        panActiveSkills.Controls.Add(objSkillControl);
                    }
                    else
                    {
                        // Find the correct Skill Control.
                        SkillControl objSkillControl = new SkillControl(_objCharacter);
                        foreach (SkillControl objControl in panActiveSkills.Controls)
                        {
                            if (objControl.SkillName == objXmlSkill["name"].InnerText)
                            {
                                objSkillControl = objControl;
                                break;
                            }
                        }

                        // Make sure it's not going above the maximum number.
                        if (Convert.ToInt32(objXmlSkill["rating"].InnerText) > objSkillControl.SkillRatingMaximum)
                            objSkillControl.SkillRating = objSkillControl.SkillRatingMaximum;
                        else
                            objSkillControl.SkillRating = Convert.ToInt32(objXmlSkill["rating"].InnerText);

                        if (objXmlSkill["spec"] != null)
                            objSkillControl.SkillSpec = objXmlSkill["spec"].InnerText;
                        else
                            objSkillControl.SkillSpec = "";
                    }
                }

                // Skill Groups.
                foreach (XmlNode objXmlGroup in objXmlKit.SelectNodes("skills/skillgroup"))
                {
                    // Find the correct SkillGroupControl.
                    SkillGroupControl objSkillGroupControl = new SkillGroupControl(_objCharacter.Options, _objCharacter);
                    foreach (SkillGroupControl objControl in panSkillGroups.Controls)
                    {
                        if (objControl.GroupName == objXmlGroup["name"].InnerText)
                        {
                            objSkillGroupControl = objControl;
                            break;
                        }
                    }

                    // Make sure it's not going above the maximum number.
                    if (Convert.ToInt32(objXmlGroup["base"].InnerText) > objSkillGroupControl.GroupRatingMaximum)
                    {
                        objSkillGroupControl.BaseRating = objSkillGroupControl.GroupRatingMaximum;
                        objSkillGroupControl.KarmaRating = 0;
                    }
                    else if (Convert.ToInt32(objXmlGroup["base"].InnerText) + Convert.ToInt32(objXmlGroup["karma"].InnerText) > objSkillGroupControl.GroupRatingMaximum)
                    {
                        objSkillGroupControl.BaseRating = Convert.ToInt32(objXmlGroup["base"].InnerText);
                        objSkillGroupControl.KarmaRating = objSkillGroupControl.GroupRatingMaximum - objSkillGroupControl.BaseRating;
                    }
                    else
                    {
                        objSkillGroupControl.BaseRating = Convert.ToInt32(objXmlGroup["base"].InnerText);
                        objSkillGroupControl.KarmaRating = Convert.ToInt32(objXmlGroup["karma"].InnerText);
                    }
                }
            }

            // Update Knowledge Skills.
            if (objXmlKit["knowledgeskills"] != null)
            {
                foreach (XmlNode objXmlSkill in objXmlKit.SelectNodes("knowledgeskills/skill"))
                {
                    int i = panKnowledgeSkills.Controls.Count;
                    Skill objSkill = new Skill(_objCharacter);
                    objSkill.Name = objXmlSkill["name"].InnerText;

                    SkillControl objSkillControl = new SkillControl(_objCharacter);
                    objSkillControl.SkillObject = objSkill;

                    // Attach an EventHandler for the RatingChanged and SpecializationChanged Events.
                    objSkillControl.RatingChanged += objKnowledgeSkill_RatingChanged;
                    objSkillControl.SpecializationChanged += objSkill_SpecializationChanged;
                    objSkillControl.DeleteSkill += objKnowledgeSkill_DeleteSkill;

                    objSkillControl.KnowledgeSkill = true;
                    objSkillControl.AllowDelete = true;

					if (_objCharacter.IgnoreRules)
					{
						objSkillControl.SkillRatingMaximum = 12;
					}
					else
					{
						objSkillControl.SkillRatingMaximum = 6;
					}
					// Set the SkillControl's Location since scrolling the Panel causes it to actually change the child Controls' Locations.
					objSkillControl.Location = new Point(0, objSkillControl.Height * i + panKnowledgeSkills.AutoScrollPosition.Y);
                    panKnowledgeSkills.Controls.Add(objSkillControl);

                    objSkillControl.SkillName = objXmlSkill["name"].InnerText;

                    // Make sure it's not going above the maximum number.
                    if (Convert.ToInt32(objXmlSkill["rating"].InnerText) > objSkillControl.SkillRatingMaximum)
                        objSkillControl.SkillRating = objSkillControl.SkillRatingMaximum;
                    else
                        objSkillControl.SkillRating = Convert.ToInt32(objXmlSkill["rating"].InnerText);

                    if (objXmlSkill["spec"] != null)
                        objSkillControl.SkillSpec = objXmlSkill["spec"].InnerText;
                    else
                        objSkillControl.SkillSpec = "";

                    if (objXmlSkill["category"] != null)
                        objSkillControl.SkillCategory = objXmlSkill["category"].InnerText;

                    _objCharacter.Skills.Add(objSkill);
                }
            }

            // Select a Martial Art.
            if (objXmlKit["selectmartialart"] != null)
            {
                string strForcedValue = "";
                int intRating = 1;
                if (objXmlKit["selectmartialart"].Attributes["select"] != null)
                    strForcedValue = objXmlKit["selectmartialart"].Attributes["select"].InnerText;
                if (objXmlKit["selectmartialart"].Attributes["rating"] != null)
                    intRating = Convert.ToInt32(objXmlKit["selectmartialart"].Attributes["rating"].InnerText);

                frmSelectMartialArt frmPickMartialArt = new frmSelectMartialArt(_objCharacter);
                frmPickMartialArt.ForcedValue = strForcedValue;
                frmPickMartialArt.ShowDialog(this);

                if (frmPickMartialArt.DialogResult != DialogResult.Cancel)
                {
                    // Open the Martial Arts XML file and locate the selected piece.
                    XmlDocument objXmlMartialArtDocument = XmlManager.Instance.Load("martialarts.xml");

                    XmlNode objXmlArt = objXmlMartialArtDocument.SelectSingleNode("/chummer/martialarts/martialart[name = \"" + frmPickMartialArt.SelectedMartialArt + "\"]");

                    TreeNode objNode = new TreeNode();
                    MartialArt objMartialArt = new MartialArt(_objCharacter);
                    objMartialArt.Create(objXmlArt, objNode, _objCharacter);
                    objMartialArt.Rating = intRating;
                    _objCharacter.MartialArts.Add(objMartialArt);

                    objNode.ContextMenuStrip = cmsMartialArts;

                    treMartialArts.Nodes[0].Nodes.Add(objNode);
                    treMartialArts.Nodes[0].Expand();

                    treMartialArts.SelectedNode = objNode;
                }
            }

            // Update Martial Arts.
            if (objXmlKit["martialarts"] != null)
            {
                // Open the Martial Arts XML file and locate the selected art.
                XmlDocument objXmlMartialArtDocument = XmlManager.Instance.Load("martialarts.xml");

                foreach (XmlNode objXmlArt in objXmlKit.SelectNodes("martialarts/martialart"))
                {
                    TreeNode objNode = new TreeNode();
                    MartialArt objArt = new MartialArt(_objCharacter);
                    XmlNode objXmlArtNode = objXmlMartialArtDocument.SelectSingleNode("/chummer/martialarts/martialart[name = \"" + objXmlArt["name"].InnerText + "\"]");
                    objArt.Create(objXmlArtNode, objNode, _objCharacter);
                    objArt.Rating = Convert.ToInt32(objXmlArt["rating"].InnerText);
                    _objCharacter.MartialArts.Add(objArt);

                    // Check for Advantages.
                    foreach (XmlNode objXmlAdvantage in objXmlArt.SelectNodes("techniques/technique"))
                    {
                        TreeNode objChildNode = new TreeNode();
                        MartialArtAdvantage objAdvantage = new MartialArtAdvantage(_objCharacter);
                        XmlNode objXmlAdvantageNode = objXmlMartialArtDocument.SelectSingleNode("/chummer/martialarts/martialart[name = \"" + objXmlArt["name"].InnerText + "\"]/techniques/technique[. = \"" + objXmlAdvantage.InnerText + "\"]");
                        objAdvantage.Create(objXmlAdvantageNode, _objCharacter, objChildNode);
                        objArt.Advantages.Add(objAdvantage);

                        objNode.Nodes.Add(objChildNode);
                        objNode.Expand();
                    }

                    treMartialArts.Nodes[0].Nodes.Add(objNode);
                    treMartialArts.Nodes[0].Expand();
                }
            }

            // Update Adept Powers.
            if (objXmlKit["powers"] != null)
            {
                // Open the Powers XML file and locate the selected power.
                XmlDocument objXmlPowerDocument = XmlManager.Instance.Load("powers.xml");

                foreach (XmlNode objXmlPower in objXmlKit.SelectNodes("powers/power"))
                {
                    XmlNode objXmlPowerNode = objXmlPowerDocument.SelectSingleNode("/chummer/powers/power[name = \"" + objXmlPower["name"].InnerText + "\"]");

                    int i = panPowers.Controls.Count;

                    Power objPower = new Power(_objCharacter);
                    _objCharacter.Powers.Add(objPower);

                    PowerControl objPowerControl = new PowerControl();
                    objPowerControl.PowerObject = objPower;

                    // Attach an EventHandler for the PowerRatingChanged Event.
                    objPowerControl.PowerRatingChanged += objPower_PowerRatingChanged;
                    objPowerControl.DeletePower += objPower_DeletePower;

                    objPowerControl.PowerName = objXmlPowerNode["name"].InnerText;
                    objPowerControl.PointsPerLevel = Convert.ToDecimal(objXmlPowerNode["points"].InnerText, GlobalOptions.Instance.CultureInfo);
                    objPowerControl.AdeptWayDiscount = Convert.ToDecimal(objXmlPowerNode["adeptway"].InnerText, GlobalOptions.Instance.CultureInfo);
                    if (objXmlPowerNode["levels"].InnerText == "no")
                    {
                        objPowerControl.LevelEnabled = false;
                    }
                    else
                    {
                        objPowerControl.LevelEnabled = true;
                        if (objXmlPowerNode["levels"].InnerText != "yes")
                            objPower.MaxLevels = Convert.ToInt32(objXmlPowerNode["levels"].InnerText);
                    }

                    objPower.Source = objXmlPowerNode["source"].InnerText;
                    objPower.Page = objXmlPowerNode["page"].InnerText;
                    if (objXmlPowerNode["doublecost"] != null)
                        objPower.DoubleCost = false;

                    if (objXmlPowerNode.InnerXml.Contains("bonus"))
                    {
                        objPower.Bonus = objXmlPowerNode["bonus"];

                        if (objXmlPower["name"].Attributes["select"] != null)
                            _objImprovementManager.ForcedValue = objXmlPower["name"].Attributes["select"].InnerText;

                        _objImprovementManager.CreateImprovements(Improvement.ImprovementSource.Power, objPower.InternalId, objPower.Bonus, false, Convert.ToInt32(objPower.Rating), objPower.DisplayNameShort);
                        objPowerControl.Extra = _objImprovementManager.SelectedValue;
                    }

                    objPowerControl.Top = i * objPowerControl.Height;
                    panPowers.Controls.Add(objPowerControl);

                    // Set the Rating of the Power if applicable.
                    if (objXmlPower["rating"] != null)
                        objPowerControl.PowerLevel = Convert.ToInt32(objXmlPower["rating"].InnerText);
                }
            }

            // Update Complex Forms.
            if (objXmlKit["programs"] != null)
            {
                // Open the Programs XML file and locate the selected program.
                XmlDocument objXmlProgramDocument = XmlManager.Instance.Load("complexforms.xml");

                foreach (XmlNode objXmlProgram in objXmlKit.SelectNodes("complexforms/complexform"))
                {
                    XmlNode objXmlProgramNode = objXmlProgramDocument.SelectSingleNode("/chummer/complexforms/complexform[name = \"" + objXmlProgram["name"].InnerText + "\"]");

                    string strForceValue = "";
                    if (objXmlProgram.Attributes["select"] != null)
                        strForceValue = objXmlProgram.Attributes["select"].InnerText;

                    TreeNode objNode = new TreeNode();
                    ComplexForm objProgram = new ComplexForm(_objCharacter);
                    objProgram.Create(objXmlProgramNode, _objCharacter, objNode, strForceValue);

                    treComplexForms.Nodes[0].Nodes.Add(objNode);
                    treComplexForms.Nodes[0].Expand();

                    _objCharacter.ComplexForms.Add(objProgram);

                    treComplexForms.SortCustom();
                }
            }

            // Update Spells.
            if (objXmlKit["spells"] != null)
            {
                XmlDocument objXmlSpellDocument = XmlManager.Instance.Load("spells.xml");

                foreach (XmlNode objXmlSpell in objXmlKit.SelectNodes("spells/spell"))
                {
                    // Make sure the Spell has not already been added to the character.
                    bool blnFound = false;
                    foreach (TreeNode nodSpell in treSpells.Nodes[0].Nodes)
                    {
                        if (nodSpell.Text == objXmlSpell.InnerText)
                        {
                            blnFound = true;
                            break;
                        }
                    }

                    // The Spell is not in the list, so add it.
                    if (!blnFound)
                    {
                        string strForceValue = "";
                        if (objXmlSpell.Attributes["select"] != null)
                            strForceValue = objXmlSpell.Attributes["select"].InnerText;

                        XmlNode objXmlSpellNode = objXmlSpellDocument.SelectSingleNode("/chummer/spells/spell[name = \"" + objXmlSpell.InnerText + "\"]");

                        Spell objSpell = new Spell(_objCharacter);
                        TreeNode objNode = new TreeNode();
                        objSpell.Create(objXmlSpellNode, _objCharacter, objNode, strForceValue);
                        objNode.ContextMenuStrip = cmsSpell;
                        _objCharacter.Spells.Add(objSpell);

                        switch (objSpell.Category)
                        {
                            case "Combat":
                                treSpells.Nodes[0].Nodes.Add(objNode);
                                treSpells.Nodes[0].Expand();
                                break;
                            case "Detection":
                                treSpells.Nodes[1].Nodes.Add(objNode);
                                treSpells.Nodes[1].Expand();
                                break;
                            case "Health":
                                treSpells.Nodes[2].Nodes.Add(objNode);
                                treSpells.Nodes[2].Expand();
                                break;
                            case "Illusion":
                                treSpells.Nodes[3].Nodes.Add(objNode);
                                treSpells.Nodes[3].Expand();
                                break;
                            case "Manipulation":
                                treSpells.Nodes[4].Nodes.Add(objNode);
                                treSpells.Nodes[4].Expand();
                                break;
                            case "Rituals":
                                int intNode = 5;
                                if (_objCharacter.AdeptEnabled && !_objCharacter.MagicianEnabled)
                                    intNode = 0;
                                treSpells.Nodes[intNode].Nodes.Add(objNode);
                                treSpells.Nodes[intNode].Expand();
                                break;
                        }

                        treSpells.SortCustom();
                    }
                }
            }

            // Update Spirits.
            if (objXmlKit["spirits"] != null)
            {
                foreach (XmlNode objXmlSpirit in objXmlKit.SelectNodes("spirits/spirit"))
                {
                    int i = panSpirits.Controls.Count;

                    Spirit objSpirit = new Spirit(_objCharacter);
                    _objCharacter.Spirits.Add(objSpirit);

                    SpiritControl objSpiritControl = new SpiritControl();
                    objSpiritControl.SpiritObject = objSpirit;
                    objSpiritControl.EntityType = SpiritType.Spirit;

                    // Attach an EventHandler for the ServicesOwedChanged Event.
                    objSpiritControl.ServicesOwedChanged += objSpirit_ServicesOwedChanged;
                    objSpiritControl.ForceChanged += objSpirit_ForceChanged;
                    objSpiritControl.BoundChanged += objSpirit_BoundChanged;
                    objSpiritControl.DeleteSpirit += objSpirit_DeleteSpirit;

                    objSpiritControl.Name = objXmlSpirit["name"].InnerText;
                    objSpiritControl.Force = Convert.ToInt32(objXmlSpirit["force"].InnerText);
                    objSpiritControl.ServicesOwed = Convert.ToInt32(objXmlSpirit["services"].InnerText);

                    objSpiritControl.Top = i * objSpiritControl.Height;
                    panSpirits.Controls.Add(objSpiritControl);
                }
            }

            // Update Lifestyles.
            if (objXmlKit["lifestyles"] != null)
            {
                XmlDocument objXmlLifestyleDocument = XmlManager.Instance.Load("lifestyles.xml");

                foreach (XmlNode objXmlLifestyle in objXmlKit.SelectNodes("lifestyles/lifestyle"))
                {
                    string strName = objXmlLifestyle["name"].InnerText;
                    int intMonths = Convert.ToInt32(objXmlLifestyle["months"].InnerText);

                    // Create the Lifestyle.
                    TreeNode objNode = new TreeNode();
                    Lifestyle objLifestyle = new Lifestyle(_objCharacter);

                    XmlNode objXmlLifestyleNode = objXmlLifestyleDocument.SelectSingleNode("/chummer/lifestyles/lifestyle[name = \"" + strName + "\"]");
                    if (objXmlLifestyleNode != null)
                    {
                        // This is a standard Lifestyle, so just use the Create method.
                        objLifestyle.Create(objXmlLifestyleNode, objNode);
                        objLifestyle.Months = intMonths;
                    }
                    else
                    {
                        // This is an Advanced Lifestyle, so build it manually.
                        objLifestyle.Name = strName;
                        objLifestyle.Months = intMonths;
                        objLifestyle.Cost = Convert.ToInt32(objXmlLifestyle["cost"].InnerText);
                        objLifestyle.Dice = Convert.ToInt32(objXmlLifestyle["dice"].InnerText);
                        objLifestyle.Multiplier = Convert.ToInt32(objXmlLifestyle["multiplier"].InnerText);
                        objLifestyle.BaseLifestyle = objXmlLifestyle["baselifestyle"].InnerText;
                        objLifestyle.Source = "SR5";
                        objLifestyle.Page = "373";
                        objLifestyle.Comforts = Convert.ToInt32(objXmlLifestyle["comforts"].InnerText);
                        objLifestyle.ComfortsEntertainment = Convert.ToInt32(objXmlLifestyle["comfortsentertainment"].InnerText);
                        objLifestyle.Security = Convert.ToInt32(objXmlLifestyle["security"].InnerText);
                        objLifestyle.SecurityEntertainment = Convert.ToInt32(objXmlLifestyle["securityentertainment"].InnerText);
                        objLifestyle.Area = Convert.ToInt32(objXmlLifestyle["area"].InnerText);
                        objLifestyle.AreaEntertainment = Convert.ToInt32(objXmlLifestyle["areaentertainment"].InnerText);

                        foreach (LifestyleQuality objXmlQuality in objXmlLifestyle.SelectNodes("lifestylequalities/lifestylequality"))
                            objLifestyle.LifestyleQualities.Add(objXmlQuality);

                        objNode.Text = strName;
                    }

                    // Add the Lifestyle to the character and Lifestyle Tree.
                    if (objLifestyle.BaseLifestyle != "")
                        objNode.ContextMenuStrip = cmsAdvancedLifestyle;
                    else
                        objNode.ContextMenuStrip = cmsLifestyleNotes;
                    _objCharacter.Lifestyles.Add(objLifestyle);
                    treLifestyles.Nodes[0].Nodes.Add(objNode);
                    treLifestyles.Nodes[0].Expand();
                }
            }

            // Update NuyenBP.
            if (objXmlKit["nuyenbp"] != null)
            {
                int intAmount = Convert.ToInt32(objXmlKit["nuyenbp"].InnerText);
                //if (_objCharacter.BuildMethod == CharacterBuildMethod.Karma)
                //intAmount *= 2;

                // Make sure we don't go over the field's maximum which would throw an Exception.
                if (nudNuyen.Value + intAmount > nudNuyen.Maximum)
                    nudNuyen.Value = nudNuyen.Maximum;
                else
                    nudNuyen.Value += intAmount;
            }

            // Update Armor.
            if (objXmlKit["armors"] != null)
            {
                XmlDocument objXmlArmorDocument = XmlManager.Instance.Load("armor.xml");

                foreach (XmlNode objXmlArmor in objXmlKit.SelectNodes("armors/armor"))
                {
                    XmlNode objXmlArmorNode = objXmlArmorDocument.SelectSingleNode("/chummer/armors/armor[name = \"" + objXmlArmor["name"].InnerText + "\"]");

                    Armor objArmor = new Armor(_objCharacter);
                    TreeNode objNode = new TreeNode();
                    objArmor.Create(objXmlArmorNode, objNode, cmsArmorMod, Convert.ToInt32(objXmlArmor["rating"].InnerText), false, blnCreateChildren);
                    _objCharacter.Armor.Add(objArmor);

                    // Look for Armor Mods.
                    if (objXmlArmor["mods"] != null)
                    {
                        foreach (XmlNode objXmlMod in objXmlArmor.SelectNodes("mods/mod"))
                        {
                            List<Weapon> lstWeapons = new List<Weapon>();
                            List<TreeNode> lstWeaponNodes = new List<TreeNode>();
                            XmlNode objXmlModNode = objXmlArmorDocument.SelectSingleNode("/chummer/mods/mod[name = \"" + objXmlMod["name"].InnerText + "\"]");
                            ArmorMod objMod = new ArmorMod(_objCharacter);
                            TreeNode objModNode = new TreeNode();
                            int intRating = 0;
                            if (objXmlMod["rating"] != null)
                                intRating = Convert.ToInt32(objXmlMod["rating"].InnerText);
                            objMod.Create(objXmlModNode, objModNode, intRating, lstWeapons, lstWeaponNodes);
                            objModNode.ContextMenuStrip = cmsArmorMod;
                            objMod.Parent = objArmor;

                            objArmor.ArmorMods.Add(objMod);

                            objNode.Nodes.Add(objModNode);
                            objNode.Expand();

                            // Add any Weapons created by the Mod.
                            foreach (Weapon objWeapon in lstWeapons)
                                _objCharacter.Weapons.Add(objWeapon);

                            foreach (TreeNode objWeaponNode in lstWeaponNodes)
                            {
                                objWeaponNode.ContextMenuStrip = cmsWeapon;
                                treWeapons.Nodes[0].Nodes.Add(objWeaponNode);
                                treWeapons.Nodes[0].Expand();
                            }
                        }
                    }

                    XmlDocument objXmlGearDocument = XmlManager.Instance.Load("gear.xml");
                    foreach (XmlNode objXmlGear in objXmlArmor.SelectNodes("gears/gear"))
                        AddPACKSGear(objXmlGearDocument, objXmlGear, objNode, objArmor, cmsArmorGear, blnCreateChildren);

                    objNode.ContextMenuStrip = cmsArmor;
                    treArmor.Nodes[0].Nodes.Add(objNode);
                    treArmor.Nodes[0].Expand();
                }
            }

            // Update Weapons.
            if (objXmlKit["weapons"] != null)
            {
                XmlDocument objXmlWeaponDocument = XmlManager.Instance.Load("weapons.xml");

                pgbProgress.Visible = true;
                pgbProgress.Value = 0;
                pgbProgress.Maximum = objXmlKit.SelectNodes("weapons/weapon").Count;
                int i = 0;
                foreach (XmlNode objXmlWeapon in objXmlKit.SelectNodes("weapons/weapon"))
                {
                    i++;
                    pgbProgress.Value = i;
                    Application.DoEvents();

                    XmlNode objXmlWeaponNode = objXmlWeaponDocument.SelectSingleNode("/chummer/weapons/weapon[name = \"" + objXmlWeapon["name"].InnerText + "\"]");

                    Weapon objWeapon = new Weapon(_objCharacter);
                    TreeNode objNode = new TreeNode();
                    objWeapon.Create(objXmlWeaponNode, _objCharacter, objNode, cmsWeapon, cmsWeaponAccessory, cmsWeaponMod, blnCreateChildren);
                    _objCharacter.Weapons.Add(objWeapon);

                    // Look for Weapon Accessories.
                    if (objXmlWeapon["accessories"] != null)
                    {
                        foreach (XmlNode objXmlAccessory in objXmlWeapon.SelectNodes("accessories/accessory"))
                        {
                            XmlNode objXmlAccessoryNode = objXmlWeaponDocument.SelectSingleNode("/chummer/accessories/accessory[name = \"" + objXmlAccessory["name"].InnerText + "\"]");
                            WeaponAccessory objMod = new WeaponAccessory(_objCharacter);
                            TreeNode objModNode = new TreeNode();
                            string strMount = "";
							int intRating = 0;
                            if (objXmlAccessory["mount"] != null)
                                strMount = objXmlAccessory["mount"].InnerText;
                            objMod.Create(objXmlAccessoryNode, objModNode, strMount, intRating);
                            objModNode.ContextMenuStrip = cmsWeaponAccessory;
                            objMod.Parent = objWeapon;

                            objWeapon.WeaponAccessories.Add(objMod);

                            XmlDocument objXmlGearDocument = XmlManager.Instance.Load("gear.xml");
                            foreach (XmlNode objXmlGear in objXmlAccessory.SelectNodes("gears/gear"))
                                AddPACKSGear(objXmlGearDocument, objXmlGear, objModNode, objMod, cmsWeaponAccessoryGear, blnCreateChildren);

                            objNode.Nodes.Add(objModNode);
                            objNode.Expand();
                        }
                    }

                    // Look for Weapon Mods.
                    if (objXmlWeapon["mods"] != null)
                    {
                        foreach (XmlNode objXmlMod in objXmlWeapon.SelectNodes("mods/mod"))
                        {
                            XmlNode objXmlModNode = objXmlWeaponDocument.SelectSingleNode("/chummer/mods/mod[name = \"" + objXmlMod["name"].InnerText + "\"]");
                            WeaponMod objMod = new WeaponMod(_objCharacter);
                            TreeNode objModNode = new TreeNode();
                            objMod.Create(objXmlModNode, objModNode);
                            objModNode.ContextMenuStrip = cmsWeaponMod;
                            objMod.Parent = objWeapon;

                            objWeapon.WeaponMods.Add(objMod);

                            objNode.Nodes.Add(objModNode);
                            objNode.Expand();
                        }
                    }

                    // Look for an Underbarrel Weapon.
                    if (objXmlWeapon["underbarrel"] != null)
                    {
                        XmlNode objXmlUnderbarrelNode = objXmlWeaponDocument.SelectSingleNode("/chummer/weapons/weapon[name = \"" + objXmlWeapon["underbarrel"].InnerText + "\"]");

                        Weapon objUnderbarrelWeapon = new Weapon(_objCharacter);
                        TreeNode objUnderbarrelNode = new TreeNode();
                        objUnderbarrelWeapon.Create(objXmlUnderbarrelNode, _objCharacter, objUnderbarrelNode, cmsWeapon, cmsWeaponAccessory, cmsWeaponMod, blnCreateChildren);
                        objWeapon.UnderbarrelWeapons.Add(objUnderbarrelWeapon);
                        objNode.Nodes.Add(objUnderbarrelNode);
                        objNode.Expand();
                    }

                    objNode.ContextMenuStrip = cmsWeapon;
                    treWeapons.Nodes[0].Nodes.Add(objNode);
                    treWeapons.Nodes[0].Expand();

                    Application.DoEvents();
                }
            }

            // Update Cyberware.
            if (objXmlKit["cyberwares"] != null)
            {
                XmlDocument objXmlCyberwareDocument = XmlManager.Instance.Load("cyberware.xml");
                XmlDocument objXmlGearDocument = XmlManager.Instance.Load("gear.xml");

                pgbProgress.Visible = true;
                pgbProgress.Value = 0;
                pgbProgress.Maximum = objXmlKit.SelectNodes("cyberwares/cyberware").Count;
                int i = 0;
                foreach (XmlNode objXmlCyberware in objXmlKit.SelectNodes("cyberwares/cyberware"))
                {
                    i++;
                    pgbProgress.Value = i;
                    Application.DoEvents();

                    List<Weapon> objWeapons = new List<Weapon>();
                    List<TreeNode> objWeaponNodes = new List<TreeNode>();
                    TreeNode objNode = new TreeNode();
                    Cyberware objCyberware = new Cyberware(_objCharacter);
                    Grade objGrade = objCyberware.ConvertToCyberwareGrade(objXmlCyberware["grade"].InnerText, Improvement.ImprovementSource.Cyberware);

                    int intRating = 0;
                    if (objXmlCyberware["rating"] != null)
                        intRating = Convert.ToInt32(objXmlCyberware["rating"].InnerText);

                    XmlNode objXmlCyberwareNode = objXmlCyberwareDocument.SelectSingleNode("/chummer/cyberwares/cyberware[name = \"" + objXmlCyberware["name"].InnerText + "\"]");
                    objCyberware.Create(objXmlCyberwareNode, _objCharacter, objGrade, Improvement.ImprovementSource.Cyberware, intRating, objNode, objWeapons, objWeaponNodes, true, blnCreateChildren);
                    _objCharacter.Cyberware.Add(objCyberware);

                    // Add any children.
                    if (objXmlCyberware["cyberwares"] != null)
                    {
                        foreach (XmlNode objXmlChild in objXmlCyberware.SelectNodes("cyberwares/cyberware"))
                        {
                            TreeNode objChildNode = new TreeNode();
                            Cyberware objChildCyberware = new Cyberware(_objCharacter);

                            int intChildRating = 0;
                            if (objXmlChild["rating"] != null)
                                intChildRating = Convert.ToInt32(objXmlChild["rating"].InnerText);

                            XmlNode objXmlChildNode = objXmlCyberwareDocument.SelectSingleNode("/chummer/cyberwares/cyberware[name = \"" + objXmlChild["name"].InnerText + "\"]");
                            objChildCyberware.Create(objXmlChildNode, _objCharacter, objGrade, Improvement.ImprovementSource.Cyberware, intChildRating, objChildNode, objWeapons, objWeaponNodes, true, blnCreateChildren);
                            objCyberware.Children.Add(objChildCyberware);
                            objChildNode.ContextMenuStrip = cmsCyberware;

                            foreach (XmlNode objXmlGear in objXmlChild.SelectNodes("gears/gear"))
                                AddPACKSGear(objXmlGearDocument, objXmlGear, objChildNode, objChildCyberware, cmsCyberwareGear, blnCreateChildren);

                            objNode.Nodes.Add(objChildNode);
                            objNode.Expand();
                        }
                    }

                    foreach (XmlNode objXmlGear in objXmlCyberware.SelectNodes("gears/gear"))
                        AddPACKSGear(objXmlGearDocument, objXmlGear, objNode, objCyberware, cmsCyberwareGear, blnCreateChildren);

                    objNode.ContextMenuStrip = cmsCyberware;
                    treCyberware.Nodes[0].Nodes.Add(objNode);
                    treCyberware.Nodes[0].Expand();

                    // Add any Weapons created by the Gear.
                    foreach (Weapon objWeapon in objWeapons)
                        _objCharacter.Weapons.Add(objWeapon);

                    foreach (TreeNode objWeaponNode in objWeaponNodes)
                    {
                        objWeaponNode.ContextMenuStrip = cmsWeapon;
                        treWeapons.Nodes[0].Nodes.Add(objWeaponNode);
                        treWeapons.Nodes[0].Expand();
                    }

                    Application.DoEvents();
                }

                treCyberware.SortCustom();
            }

            // Update Bioware.
            if (objXmlKit["biowares"] != null)
            {
                XmlDocument objXmlBiowareDocument = XmlManager.Instance.Load("bioware.xml");

                pgbProgress.Visible = true;
                pgbProgress.Value = 0;
                pgbProgress.Maximum = objXmlKit.SelectNodes("biowares/bioware").Count;
                int i = 0;

                foreach (XmlNode objXmlBioware in objXmlKit.SelectNodes("biowares/bioware"))
                {
                    i++;
                    pgbProgress.Value = i;
                    Application.DoEvents();

                    List<Weapon> objWeapons = new List<Weapon>();
                    List<TreeNode> objWeaponNodes = new List<TreeNode>();
                    TreeNode objNode = new TreeNode();
                    Cyberware objCyberware = new Cyberware(_objCharacter);
                    Grade objGrade = objCyberware.ConvertToCyberwareGrade(objXmlBioware["grade"].InnerText, Improvement.ImprovementSource.Bioware);

                    int intRating = 0;
                    if (objXmlBioware["rating"] != null)
                        intRating = Convert.ToInt32(objXmlBioware["rating"].InnerText);

                    XmlNode objXmlBiowareNode = objXmlBiowareDocument.SelectSingleNode("/chummer/biowares/bioware[name = \"" + objXmlBioware["name"].InnerText + "\"]");
                    objCyberware.Create(objXmlBiowareNode, _objCharacter, objGrade, Improvement.ImprovementSource.Bioware, intRating, objNode, objWeapons, objWeaponNodes, true, blnCreateChildren);
                    _objCharacter.Cyberware.Add(objCyberware);

                    objNode.ContextMenuStrip = cmsBioware;
                    treCyberware.Nodes[1].Nodes.Add(objNode);
                    treCyberware.Nodes[1].Expand();

                    // Add any Weapons created by the Gear.
                    foreach (Weapon objWeapon in objWeapons)
                        _objCharacter.Weapons.Add(objWeapon);

                    foreach (TreeNode objWeaponNode in objWeaponNodes)
                    {
                        objWeaponNode.ContextMenuStrip = cmsWeapon;
                        treWeapons.Nodes[0].Nodes.Add(objWeaponNode);
                        treWeapons.Nodes[0].Expand();
                    }

                    Application.DoEvents();
                }

                treCyberware.SortCustom();
            }

            // Update Gear.
            if (objXmlKit["gears"] != null)
            {
                XmlDocument objXmlGearDocument = XmlManager.Instance.Load("gear.xml");

                pgbProgress.Visible = true;
                pgbProgress.Value = 0;
                pgbProgress.Maximum = objXmlKit.SelectNodes("gears/gear").Count;
                int i = 0;

                foreach (XmlNode objXmlGear in objXmlKit.SelectNodes("gears/gear"))
                {
                    i++;
                    pgbProgress.Value = i;
                    Application.DoEvents();

                    AddPACKSGear(objXmlGearDocument, objXmlGear, treGear.Nodes[0], _objCharacter, cmsGear, blnCreateChildren);

                    Application.DoEvents();
                }
            }

            // Update Vehicles.
            if (objXmlKit["vehicles"] != null)
            {
                XmlDocument objXmlVehicleDocument = XmlManager.Instance.Load("vehicles.xml");

                pgbProgress.Visible = true;
                pgbProgress.Value = 0;
                pgbProgress.Maximum = objXmlKit.SelectNodes("vehicles/vehicle").Count;
                int i = 0;

                foreach (XmlNode objXmlVehicle in objXmlKit.SelectNodes("vehicles/vehicle"))
                {
                    i++;
                    pgbProgress.Value = i;
                    Application.DoEvents();

                    Gear objDefaultSensor = new Gear(_objCharacter);

                    TreeNode objNode = new TreeNode();
                    Vehicle objVehicle = new Vehicle(_objCharacter);

                    XmlNode objXmlVehicleNode = objXmlVehicleDocument.SelectSingleNode("/chummer/vehicles/vehicle[name = \"" + objXmlVehicle["name"].InnerText + "\"]");
                    objVehicle.Create(objXmlVehicleNode, objNode, cmsVehicle, cmsVehicleGear, cmsVehicleWeapon, cmsVehicleWeaponAccessory, cmsVehicleWeaponMod, blnCreateChildren);
                    _objCharacter.Vehicles.Add(objVehicle);

                    // Grab the default Sensor that comes with the Vehicle.
                    foreach (Gear objSensorGear in objVehicle.Gear)
                    {
                        if (objSensorGear.Category == "Sensors" && objSensorGear.Cost == "0" && objSensorGear.Rating == 0)
                        {
                            objDefaultSensor = objSensorGear;
                            break;
                        }
                    }

                    // Add any Vehicle Mods.
                    if (objXmlVehicle["mods"] != null)
                    {
                        foreach (XmlNode objXmlMod in objXmlVehicle.SelectNodes("mods/mod"))
                        {
                            TreeNode objModNode = new TreeNode();
                            VehicleMod objMod = new VehicleMod(_objCharacter);

                            int intRating = 0;
                            if (objXmlMod["rating"] != null)
                                intRating = Convert.ToInt32(objXmlMod["rating"].InnerText);

                            XmlNode objXmlModNode = objXmlVehicleDocument.SelectSingleNode("/chummer/mods/mod[name = \"" + objXmlMod["name"].InnerText + "\"]");
                            objMod.Create(objXmlModNode, objModNode, intRating);
                            objVehicle.Mods.Add(objMod);

                            objNode.Nodes.Add(objModNode);
                            objNode.Expand();
                        }
                    }

                    // Add any Vehicle Gear.
                    if (objXmlVehicle["gears"] != null)
                    {
                        XmlDocument objXmlGearDocument = XmlManager.Instance.Load("gear.xml");

                        foreach (XmlNode objXmlGear in objXmlVehicle.SelectNodes("gears/gear"))
                        {
                            List<Weapon> objWeapons = new List<Weapon>();
                            List<TreeNode> objWeaponNodes = new List<TreeNode>();
                            TreeNode objGearNode = new TreeNode();
                            Gear objGear = new Gear(_objCharacter);
                            int intQty = 1;

                            int intRating = 0;
                            if (objXmlGear["rating"] != null)
                                intRating = Convert.ToInt32(objXmlGear["rating"].InnerText);
                            string strForceValue = "";
                            if (objXmlGear["name"].Attributes["select"] != null)
                                strForceValue = objXmlGear["name"].Attributes["select"].InnerText;
                            if (objXmlGear["qty"] != null)
                                intQty = Convert.ToInt32(objXmlGear["qty"].InnerText);

                            XmlNode objXmlGearNode = objXmlGearDocument.SelectSingleNode("/chummer/gears/gear[name = \"" + objXmlGear["name"].InnerText + "\"]");
                            objGear.Create(objXmlGearNode, _objCharacter, objGearNode, intRating, objWeapons, objWeaponNodes, strForceValue, false, false, false, blnCreateChildren, false);
                            objGear.Quantity = intQty;
                            objGearNode.Text = objGear.DisplayName;
                            objVehicle.Gear.Add(objGear);

                            // Look for child components.
                            if (objXmlGear["gears"] != null)
                            {
                                foreach (XmlNode objXmlChild in objXmlGear.SelectNodes("gears/gear"))
                                {
                                    AddPACKSGear(objXmlGearDocument, objXmlChild, objGearNode, objGear, cmsVehicleGear, blnCreateChildren);
                                }
                            }

                            objGearNode.Expand();
                            objGearNode.ContextMenuStrip = cmsVehicleGear;
                            objNode.Nodes.Add(objGearNode);
                            objNode.Expand();

                            // If this is a Sensor, it will replace the Vehicle's base sensor, so remove it.
                            if (objGear.Category == "Sensors" && objGear.Cost == "0" && objGear.Rating == 0)
                            {
                                objVehicle.Gear.Remove(objDefaultSensor);
                                foreach (TreeNode objSensorNode in objNode.Nodes)
                                {
                                    if (objSensorNode.Tag.ToString() == objDefaultSensor.InternalId)
                                    {
                                        objSensorNode.Remove();
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    // Add any Vehicle Weapons.
                    if (objXmlVehicle["weapons"] != null)
                    {
                        XmlDocument objXmlWeaponDocument = XmlManager.Instance.Load("weapons.xml");

                        foreach (XmlNode objXmlWeapon in objXmlVehicle.SelectNodes("weapons/weapon"))
                        {
                            TreeNode objWeaponNode = new TreeNode();
                            Weapon objWeapon = new Weapon(_objCharacter);

                            XmlNode objXmlWeaponNode = objXmlWeaponDocument.SelectSingleNode("/chummer/weapons/weapon[name = \"" + objXmlWeapon["name"].InnerText + "\"]");
                            objWeapon.Create(objXmlWeaponNode, _objCharacter, objWeaponNode, cmsVehicleWeapon, cmsVehicleWeaponAccessory, cmsVehicleWeaponMod, blnCreateChildren);
                            objWeapon.VehicleMounted = true;

                            // Find the first Weapon Mount in the Vehicle.
                            foreach (VehicleMod objMod in objVehicle.Mods)
                            {
                                if (objMod.Name.StartsWith("Weapon Mount") || objMod.Name.StartsWith("Heavy Weapon Mount"))
                                {
                                    objMod.Weapons.Add(objWeapon);
                                    foreach (TreeNode objModNode in objNode.Nodes)
                                    {
                                        if (objModNode.Tag.ToString() == objMod.InternalId)
                                        {
                                            objWeaponNode.ContextMenuStrip = cmsVehicleWeapon;
                                            objModNode.Nodes.Add(objWeaponNode);
                                            objModNode.Expand();
                                            break;
                                        }
                                    }
                                    break;
                                }
                            }

                            // Look for Weapon Accessories.
                            if (objXmlWeapon["accessories"] != null)
                            {
                                foreach (XmlNode objXmlAccessory in objXmlWeapon.SelectNodes("accessories/accessory"))
                                {
                                    XmlNode objXmlAccessoryNode = objXmlWeaponDocument.SelectSingleNode("/chummer/accessories/accessory[name = \"" + objXmlAccessory["name"].InnerText + "\"]");
                                    WeaponAccessory objMod = new WeaponAccessory(_objCharacter);
                                    TreeNode objModNode = new TreeNode();
                                    string strMount = "";
									int intRating = 0;
									if (objXmlAccessory["mount"] != null)
                                        strMount = objXmlAccessory["mount"].InnerText;
                                    objMod.Create(objXmlAccessoryNode, objModNode, strMount,intRating);
                                    objModNode.ContextMenuStrip = cmsWeaponAccessory;
                                    objMod.Parent = objWeapon;

                                    objWeapon.WeaponAccessories.Add(objMod);

                                    objWeaponNode.Nodes.Add(objModNode);
                                    objWeaponNode.Expand();
                                }
                            }

                            // Look for Weapon Mods.
                            if (objXmlWeapon["mods"] != null)
                            {
                                foreach (XmlNode objXmlMod in objXmlWeapon.SelectNodes("mods/mod"))
                                {
                                    XmlNode objXmlModNode = objXmlWeaponDocument.SelectSingleNode("/chummer/mods/mod[name = \"" + objXmlMod["name"].InnerText + "\"]");
                                    WeaponMod objMod = new WeaponMod(_objCharacter);
                                    TreeNode objModNode = new TreeNode();
                                    objMod.Create(objXmlModNode, objModNode);
                                    objModNode.ContextMenuStrip = cmsVehicleWeaponMod;
                                    objMod.Parent = objWeapon;

                                    objWeapon.WeaponMods.Add(objMod);

                                    objWeaponNode.Nodes.Add(objModNode);
                                    objWeaponNode.Expand();
                                }
                            }
                        }
                    }

                    objNode.ContextMenuStrip = cmsVehicle;
                    treVehicles.Nodes[0].Nodes.Add(objNode);
                    treVehicles.Nodes[0].Expand();

                    Application.DoEvents();
                }
            }

            pgbProgress.Visible = false;

            if (frmPickPACKSKit.AddAgain)
                AddPACKSKit();

            PopulateGearList();
            UpdateCharacterInfo();
        }
Example #20
0
        /// <summary>
        /// Create a Critter, put them into Career Mode, link them, and open the newly-created Critter.
        /// </summary>
        /// <param name="strCritterName">Name of the Critter's Metatype.</param>
        /// <param name="intForce">Critter's Force.</param>
        private void CreateCritter(string strCritterName, int intForce)
        {
            // The Critter should use the same settings file as the character.
            Character objCharacter = new Character();
            objCharacter.SettingsFile = _objSpirit.CharacterObject.SettingsFile;

            // Override the defaults for the setting.
            objCharacter.IgnoreRules = true;
            objCharacter.IsCritter = true;
            objCharacter.BuildMethod = CharacterBuildMethod.Karma;
            objCharacter.BuildPoints = 0;

            if (txtCritterName.Text != string.Empty)
                objCharacter.Name = txtCritterName.Text;

            // Make sure that Running Wild is one of the allowed source books since most of the Critter Powers come from this book.
            bool blnRunningWild = false;
            blnRunningWild = (objCharacter.Options.Books.Contains("RW"));

            if (!blnRunningWild)
            {
                MessageBox.Show(LanguageManager.Instance.GetString("Message_Main_RunningWild"), LanguageManager.Instance.GetString("MessageTitle_Main_RunningWild"), MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }

            // Ask the user to select a filename for the new character.
            string strForce = LanguageManager.Instance.GetString("String_Force");
            if (_objSpirit.EntityType == SpiritType.Sprite)
                strForce = LanguageManager.Instance.GetString("String_Rating");
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "Chummer5 Files (*.chum5)|*.chum5|All Files (*.*)|*.*";
            saveFileDialog.FileName = strCritterName + " (" + strForce + " " + _objSpirit.Force.ToString() + ").chum5";
            if (saveFileDialog.ShowDialog(this) == DialogResult.OK)
            {
                string strFileName = saveFileDialog.FileName;
                objCharacter.FileName = strFileName;
            }
            else
                return;

            // Code from frmMetatype.
            ImprovementManager objImprovementManager = new ImprovementManager(objCharacter);
            XmlDocument objXmlDocument = XmlManager.Instance.Load("critters.xml");

            XmlNode objXmlMetatype = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + strCritterName + "\"]");

            // If the Critter could not be found, show an error and get out of here.
            if (objXmlMetatype == null)
            {
                MessageBox.Show(LanguageManager.Instance.GetString("Message_UnknownCritterType").Replace("{0}", strCritterName), LanguageManager.Instance.GetString("MessageTitle_SelectCritterType"), MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // Set Metatype information.
            if (strCritterName == "Ally Spirit")
            {
                objCharacter.BOD.AssignLimits(ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["bodmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["bodaug"].InnerText, intForce, 0));
                objCharacter.AGI.AssignLimits(ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["agimax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["agiaug"].InnerText, intForce, 0));
                objCharacter.REA.AssignLimits(ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["reamax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["reaaug"].InnerText, intForce, 0));
                objCharacter.STR.AssignLimits(ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["strmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["straug"].InnerText, intForce, 0));
                objCharacter.CHA.AssignLimits(ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["chamax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["chaaug"].InnerText, intForce, 0));
                objCharacter.INT.AssignLimits(ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["intmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["intaug"].InnerText, intForce, 0));
                objCharacter.LOG.AssignLimits(ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["logmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["logaug"].InnerText, intForce, 0));
                objCharacter.WIL.AssignLimits(ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["wilmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["wilaug"].InnerText, intForce, 0));
                objCharacter.INI.AssignLimits(ExpressionToString(objXmlMetatype["inimin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["inimax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["iniaug"].InnerText, intForce, 0));
                objCharacter.MAG.AssignLimits(ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["magmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["magaug"].InnerText, intForce, 0));
                objCharacter.RES.AssignLimits(ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["resmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["resaug"].InnerText, intForce, 0));
                objCharacter.EDG.AssignLimits(ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["edgmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["edgaug"].InnerText, intForce, 0));
                objCharacter.ESS.AssignLimits(ExpressionToString(objXmlMetatype["essmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essaug"].InnerText, intForce, 0));
            }
            else
            {
                int intMinModifier = -3;
                if (objXmlMetatype["category"].InnerText == "Mutant Critters")
                    intMinModifier = 0;
                objCharacter.BOD.AssignLimits(ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, 3));
                objCharacter.AGI.AssignLimits(ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, 3));
                objCharacter.REA.AssignLimits(ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, 3));
                objCharacter.STR.AssignLimits(ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, 3));
                objCharacter.CHA.AssignLimits(ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, 3));
                objCharacter.INT.AssignLimits(ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, 3));
                objCharacter.LOG.AssignLimits(ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, 3));
                objCharacter.WIL.AssignLimits(ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, 3));
                objCharacter.INI.AssignLimits(ExpressionToString(objXmlMetatype["inimin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["inimax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["iniaug"].InnerText, intForce, 0));
                objCharacter.MAG.AssignLimits(ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, 3));
                objCharacter.RES.AssignLimits(ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, 3));
                objCharacter.EDG.AssignLimits(ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, intMinModifier), ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, 3), ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, 3));
                objCharacter.ESS.AssignLimits(ExpressionToString(objXmlMetatype["essmin"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essmax"].InnerText, intForce, 0), ExpressionToString(objXmlMetatype["essaug"].InnerText, intForce, 0));
            }

            // If we're working with a Critter, set the Attributes to their default values.
            objCharacter.BOD.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["bodmin"].InnerText, intForce, 0));
            objCharacter.AGI.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["agimin"].InnerText, intForce, 0));
            objCharacter.REA.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["reamin"].InnerText, intForce, 0));
            objCharacter.STR.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["strmin"].InnerText, intForce, 0));
            objCharacter.CHA.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["chamin"].InnerText, intForce, 0));
            objCharacter.INT.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["intmin"].InnerText, intForce, 0));
            objCharacter.LOG.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["logmin"].InnerText, intForce, 0));
            objCharacter.WIL.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["wilmin"].InnerText, intForce, 0));
            objCharacter.MAG.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["magmin"].InnerText, intForce, 0));
            objCharacter.RES.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["resmin"].InnerText, intForce, 0));
            objCharacter.EDG.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["edgmin"].InnerText, intForce, 0));
            objCharacter.ESS.Value = Convert.ToInt32(ExpressionToString(objXmlMetatype["essmax"].InnerText, intForce, 0));

            // Sprites can never have Physical Attributes or WIL.
            if (objXmlMetatype["category"].InnerText.EndsWith("Sprite"))
            {
                objCharacter.BOD.AssignLimits("0", "0", "0");
                objCharacter.AGI.AssignLimits("0", "0", "0");
                objCharacter.REA.AssignLimits("0", "0", "0");
                objCharacter.STR.AssignLimits("0", "0", "0");
                objCharacter.WIL.AssignLimits("0", "0", "0");
                objCharacter.INI.MetatypeMinimum = Convert.ToInt32(ExpressionToString(objXmlMetatype["inimax"].InnerText, intForce, 0));
                objCharacter.INI.MetatypeMaximum = Convert.ToInt32(ExpressionToString(objXmlMetatype["inimax"].InnerText, intForce, 0));
            }

            objCharacter.Metatype = strCritterName;
            objCharacter.MetatypeCategory = objXmlMetatype["category"].InnerText;
            objCharacter.Metavariant = "";
            objCharacter.MetatypeBP = 0;

            if (objXmlMetatype["movement"] != null)
                objCharacter.Movement = objXmlMetatype["movement"].InnerText;
            // Load the Qualities file.
            XmlDocument objXmlQualityDocument = XmlManager.Instance.Load("qualities.xml");

            // Determine if the Metatype has any bonuses.
            if (objXmlMetatype.InnerXml.Contains("bonus"))
                objImprovementManager.CreateImprovements(Improvement.ImprovementSource.Metatype, strCritterName, objXmlMetatype.SelectSingleNode("bonus"), false, 1, strCritterName);

            // Create the Qualities that come with the Metatype.
            foreach (XmlNode objXmlQualityItem in objXmlMetatype.SelectNodes("qualities/positive/quality"))
            {
                XmlNode objXmlQuality = objXmlQualityDocument.SelectSingleNode("/chummer/qualities/quality[name = \"" + objXmlQualityItem.InnerText + "\"]");
                TreeNode objNode = new TreeNode();
                List<Weapon> objWeapons = new List<Weapon>();
                List<TreeNode> objWeaponNodes = new List<TreeNode>();
                Quality objQuality = new Quality(objCharacter);
                string strForceValue = "";
                if (objXmlQualityItem.Attributes["select"] != null)
                    strForceValue = objXmlQualityItem.Attributes["select"].InnerText;
                QualitySource objSource = new QualitySource();
                objSource = QualitySource.Metatype;
                if (objXmlQualityItem.Attributes["removable"] != null)
                    objSource = QualitySource.MetatypeRemovable;
                objQuality.Create(objXmlQuality, objCharacter, objSource, objNode, objWeapons, objWeaponNodes, strForceValue);
                objCharacter.Qualities.Add(objQuality);

                // Add any created Weapons to the character.
                foreach (Weapon objWeapon in objWeapons)
                    objCharacter.Weapons.Add(objWeapon);
            }
            foreach (XmlNode objXmlQualityItem in objXmlMetatype.SelectNodes("qualities/negative/quality"))
            {
                XmlNode objXmlQuality = objXmlQualityDocument.SelectSingleNode("/chummer/qualities/quality[name = \"" + objXmlQualityItem.InnerText + "\"]");
                TreeNode objNode = new TreeNode();
                List<Weapon> objWeapons = new List<Weapon>();
                List<TreeNode> objWeaponNodes = new List<TreeNode>();
                Quality objQuality = new Quality(objCharacter);
                string strForceValue = "";
                if (objXmlQualityItem.Attributes["select"] != null)
                    strForceValue = objXmlQualityItem.Attributes["select"].InnerText;
                QualitySource objSource = new QualitySource();
                objSource = QualitySource.Metatype;
                if (objXmlQualityItem.Attributes["removable"] != null)
                    objSource = QualitySource.MetatypeRemovable;
                objQuality.Create(objXmlQuality, objCharacter, objSource, objNode, objWeapons, objWeaponNodes, strForceValue);
                objCharacter.Qualities.Add(objQuality);

                // Add any created Weapons to the character.
                foreach (Weapon objWeapon in objWeapons)
                    objCharacter.Weapons.Add(objWeapon);
            }

            // Add any Critter Powers the Metatype/Critter should have.
            XmlNode objXmlCritter = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + objCharacter.Metatype + "\"]");

            objXmlDocument = XmlManager.Instance.Load("critterpowers.xml");
            foreach (XmlNode objXmlPower in objXmlCritter.SelectNodes("powers/power"))
            {
                XmlNode objXmlCritterPower = objXmlDocument.SelectSingleNode("/chummer/powers/power[name = \"" + objXmlPower.InnerText + "\"]");
                TreeNode objNode = new TreeNode();
                CritterPower objPower = new CritterPower(objCharacter);
                string strForcedValue = "";
                int intRating = 0;

                if (objXmlPower.Attributes["rating"] != null)
                    intRating = Convert.ToInt32(objXmlPower.Attributes["rating"].InnerText);
                if (objXmlPower.Attributes["select"] != null)
                    strForcedValue = objXmlPower.Attributes["select"].InnerText;

                objPower.Create(objXmlCritterPower, objCharacter, objNode, intRating, strForcedValue);
                objCharacter.CritterPowers.Add(objPower);
            }

            // Set the Skill Ratings for the Critter.
            foreach (XmlNode objXmlSkill in objXmlCritter.SelectNodes("skills/skill"))
            {
                if (objXmlSkill.InnerText.Contains("Exotic"))
                {
                    Skill objExotic = new Skill(objCharacter);
                    objExotic.ExoticSkill = true;
                    objExotic.Attribute = "AGI";
                    if (objXmlSkill.Attributes["spec"] != null)
                    {
                        SkillSpecialization objSpec = new SkillSpecialization(objXmlSkill.Attributes["spec"].InnerText);
                        objExotic.Specializations.Add(objSpec);
                    }
                    if (Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0)) > 6)
                        objExotic.RatingMaximum = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0));
                    objExotic.Rating = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0));
                    objExotic.Name = objXmlSkill.InnerText;
                    objCharacter.Skills.Add(objExotic);
                }
                else
                {
                    foreach (Skill objSkill in objCharacter.Skills)
                    {
                        if (objSkill.Name == objXmlSkill.InnerText)
                        {
                            if (objXmlSkill.Attributes["spec"] != null)
                            {
                                SkillSpecialization objSpec = new SkillSpecialization(objXmlSkill.Attributes["spec"].InnerText);
                                objSkill.Specializations.Add(objSpec);
                            }
                            if (Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0)) > 6)
                                objSkill.RatingMaximum = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0));
                            objSkill.Rating = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0));
                            break;
                        }
                    }
                }
            }

            // Set the Skill Group Ratings for the Critter.
            foreach (XmlNode objXmlSkill in objXmlCritter.SelectNodes("skills/group"))
            {
                foreach (SkillGroup objSkill in objCharacter.SkillGroups)
                {
                    if (objSkill.Name == objXmlSkill.InnerText)
                    {
                        objSkill.RatingMaximum = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0));
                        objSkill.Rating = Convert.ToInt32(ExpressionToString(objXmlSkill.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0));
                        break;
                    }
                }
            }

            // Set the Knowledge Skill Ratings for the Critter.
            foreach (XmlNode objXmlSkill in objXmlCritter.SelectNodes("skills/knowledge"))
            {
                Skill objKnowledge = new Skill(objCharacter);
                objKnowledge.Name = objXmlSkill.InnerText;
                objKnowledge.KnowledgeSkill = true;
                if (objXmlSkill.Attributes["spec"] != null)
                {
                    SkillSpecialization objSpec = new SkillSpecialization(objXmlSkill.Attributes["spec"].InnerText);
                    objKnowledge.Specializations.Add(objSpec);
                }
                objKnowledge.SkillCategory = objXmlSkill.Attributes["category"].InnerText;
                if (Convert.ToInt32(objXmlSkill.Attributes["rating"].InnerText) > 6)
                    objKnowledge.RatingMaximum = Convert.ToInt32(objXmlSkill.Attributes["rating"].InnerText);
                objKnowledge.Rating = Convert.ToInt32(objXmlSkill.Attributes["rating"].InnerText);
                objCharacter.Skills.Add(objKnowledge);
            }

            // If this is a Critter with a Force (which dictates their Skill Rating/Maximum Skill Rating), set their Skill Rating Maximums.
            if (intForce > 0)
            {
                int intMaxRating = intForce;
                // Determine the highest Skill Rating the Critter has.
                foreach (Skill objSkill in objCharacter.Skills)
                {
                    if (objSkill.RatingMaximum > intMaxRating)
                        intMaxRating = objSkill.RatingMaximum;
                }

                // Now that we know the upper limit, set all of the Skill Rating Maximums to match.
                foreach (Skill objSkill in objCharacter.Skills)
                    objSkill.RatingMaximum = intMaxRating;
                foreach (SkillGroup objGroup in objCharacter.SkillGroups)
                    objGroup.RatingMaximum = intMaxRating;

                // Set the MaxSkillRating for the character so it can be used later when they add new Knowledge Skills or Exotic Skills.
                objCharacter.MaxSkillRating = intMaxRating;
            }

            // Add any Complex Forms the Critter comes with (typically Sprites)
            XmlDocument objXmlProgramDocument = XmlManager.Instance.Load("complexforms.xml");
            foreach (XmlNode objXmlComplexForm in objXmlCritter.SelectNodes("complexforms/complexform"))
            {
                string strForceValue = "";
                if (objXmlComplexForm.Attributes["select"] != null)
                    strForceValue = objXmlComplexForm.Attributes["select"].InnerText;
                XmlNode objXmlProgram = objXmlProgramDocument.SelectSingleNode("/chummer/complexforms/complexform[name = \"" + objXmlComplexForm.InnerText + "\"]");
                TreeNode objNode = new TreeNode();
                ComplexForm objProgram = new ComplexForm(objCharacter);
                objProgram.Create(objXmlProgram, objCharacter, objNode, strForceValue);
                objCharacter.ComplexForms.Add(objProgram);
            }

            // Add any Gear the Critter comes with (typically Programs for A.I.s)
            XmlDocument objXmlGearDocument = XmlManager.Instance.Load("gear.xml");
            foreach (XmlNode objXmlGear in objXmlCritter.SelectNodes("gears/gear"))
            {
                int intRating = 0;
                if (objXmlGear.Attributes["rating"] != null)
                    intRating = Convert.ToInt32(ExpressionToString(objXmlGear.Attributes["rating"].InnerText, Convert.ToInt32(nudForce.Value), 0));
                string strForceValue = "";
                if (objXmlGear.Attributes["select"] != null)
                    strForceValue = objXmlGear.Attributes["select"].InnerText;
                XmlNode objXmlGearItem = objXmlGearDocument.SelectSingleNode("/chummer/gears/gear[name = \"" + objXmlGear.InnerText + "\"]");
                TreeNode objNode = new TreeNode();
                Gear objGear = new Gear(objCharacter);
                List<Weapon> lstWeapons = new List<Weapon>();
                List<TreeNode> lstWeaponNodes = new List<TreeNode>();
                objGear.Create(objXmlGearItem, objCharacter, objNode, intRating, lstWeapons, lstWeaponNodes, strForceValue);
                objGear.Cost = "0";
                objGear.Cost3 = "0";
                objGear.Cost6 = "0";
                objGear.Cost10 = "0";
                objCharacter.Gear.Add(objGear);
            }

            // If this is a Mutant Critter, count up the number of Skill points they start with.
            if (objCharacter.MetatypeCategory == "Mutant Critters")
            {
                foreach (Skill objSkill in objCharacter.Skills)
                    objCharacter.MutantCritterBaseSkills += objSkill.Rating;
            }

            // Add the Unarmed Attack Weapon to the character.
            try
            {
                objXmlDocument = XmlManager.Instance.Load("weapons.xml");
                XmlNode objXmlWeapon = objXmlDocument.SelectSingleNode("/chummer/weapons/weapon[name = \"Unarmed Attack\"]");
                TreeNode objDummy = new TreeNode();
                Weapon objWeapon = new Weapon(objCharacter);
                objWeapon.Create(objXmlWeapon, objCharacter, objDummy, null, null, null);
                objCharacter.Weapons.Add(objWeapon);
            }
            catch
            {
            }

            objCharacter.Alias = strCritterName;
            objCharacter.Created = true;
            objCharacter.Save();

            string strOpenFile = objCharacter.FileName;
            objCharacter = null;

            // Link the newly-created Critter to the Spirit.
            _objSpirit.FileName = strOpenFile;
            if (_objSpirit.EntityType == SpiritType.Spirit)
                tipTooltip.SetToolTip(imgLink, LanguageManager.Instance.GetString("Tip_Spirit_OpenFile"));
            else
                tipTooltip.SetToolTip(imgLink, LanguageManager.Instance.GetString("Tip_Sprite_OpenFile"));
            FileNameChanged(this);

            GlobalOptions.Instance.MainForm.LoadCharacter(strOpenFile, true);
        }
Example #21
0
        private void cmdAddExoticSkill_Click(object sender, EventArgs e)
        {
            frmSelectExoticSkill frmPickExoticSkill = new frmSelectExoticSkill();
            frmPickExoticSkill.ShowDialog(this);

            if (frmPickExoticSkill.DialogResult == DialogResult.Cancel)
                return;

            XmlDocument objXmlDocument = XmlManager.Instance.Load("skills.xml");

            XmlNode nodSkill = objXmlDocument.SelectSingleNode("/chummer/skills/skill[name = \"" + frmPickExoticSkill.SelectedExoticSkill + "\"]");

            int i = panActiveSkills.Controls.Count;
            Skill objSkill = new Skill(_objCharacter);
            objSkill.Attribute = nodSkill["attribute"].InnerText;
			objSkill.Specialization = frmPickExoticSkill.SelectedExoticSkillSpecialisation;
            if (_objCharacter.MaxSkillRating > 0)
                objSkill.RatingMaximum = _objCharacter.MaxSkillRating;

            SkillControl objSkillControl = new SkillControl(_objCharacter);
            objSkillControl.SkillObject = objSkill;
            objSkillControl.Width = 510;

            // Attach an EventHandler for the RatingChanged and SpecializationChanged Events.
            objSkillControl.RatingChanged += objActiveSkill_RatingChanged;
            objSkillControl.SpecializationChanged += objSkill_SpecializationChanged;
            objSkillControl.SkillName = frmPickExoticSkill.SelectedExoticSkill;
            objSkillControl.BuyWithKarmaChanged += objActiveSkill_BuyWithKarmaChanged;
			objSkillControl.SkillSpec = frmPickExoticSkill.SelectedExoticSkillSpecialisation;
            objSkillControl.SkillCategory = nodSkill["category"].InnerText;
            if (nodSkill["default"].InnerText == "Yes")
                objSkill.Default = true;
            else
                objSkill.Default = false;

            objSkill.ExoticSkill = true;
            _objCharacter.Skills.Add(objSkill);

			// Populate the Skill's Specializations (if any).
			foreach (XmlNode objXmlSpecialization in nodSkill.SelectNodes("specs/spec"))
			{
				if (objXmlSpecialization.Attributes["translate"] != null)
					objSkillControl.AddSpec(objXmlSpecialization.Attributes["translate"].InnerText);
				else
					objSkillControl.AddSpec(objXmlSpecialization.InnerText);
			}

			// Look through the Weapons file and grab the names of items that are part of the appropriate Exotic Category or use the matching Exoctic Skill.
			XmlDocument objXmlWeaponDocument = XmlManager.Instance.Load("weapons.xml");
			XmlNodeList objXmlWeaponList = objXmlWeaponDocument.SelectNodes("/chummer/weapons/weapon[category = \"" + frmPickExoticSkill.SelectedExoticSkill + "s\" or useskill = \"" + frmPickExoticSkill.SelectedExoticSkill + "\"]");
			foreach (XmlNode objXmlWeapon in objXmlWeaponList)
			{
				if (objXmlWeapon["translate"] != null)
					objSkillControl.AddSpec(objXmlWeapon["translate"].InnerText);
				else
					objSkillControl.AddSpec(objXmlWeapon["name"].InnerText);
			}

			if (_objCharacter.IgnoreRules)
			{
				objSkillControl.SkillRatingMaximum = 12;
			}
			else
			{
				objSkillControl.SkillRatingMaximum = 6;
			}
            // Set the SkillControl's Location since scrolling the Panel causes it to actually change the child Controls' Locations.
            objSkillControl.Location = new Point(0, objSkillControl.Height * i + panActiveSkills.AutoScrollPosition.Y);
            panActiveSkills.Controls.Add(objSkillControl);

            _blnIsDirty = true;
            UpdateWindowTitle();
        }
Example #22
0
        public void WeaponTest()
        {
            // Create a new Human character.
            Character objCharacter = new Character();
            objCharacter.LoadMetatype(Guid.Parse("e28e7075-f635-4c02-937c-e4fc61c51602"));

            // Add a Combat Axe.
            Weapon objWeapon = new Weapon(objCharacter);
            objWeapon.Category = "Blades";
            objWeapon.WeaponType = "Melee";
            objWeapon.Spec = "Axes";
            objWeapon.Reach = 2;
            objWeapon.Damage = "(STR/2+9)P";
            objWeapon.AP = "-4";
            objWeapon.RC = "0";
            objWeapon.Accuracy = "4";
            objWeapon.Ammo = "0";
            objWeapon.Concealability = 0;
            objWeapon.Avail = "9R";
            objWeapon.Cost = 500;
            objWeapon.Source = "SR5";
            objWeapon.Page = "900";

            // Add the Weapon to the character.
            objCharacter.Weapons.Add(objWeapon);

            // Set the character's Blades Skill to 3.
            Skill objSkill = new Skill(objCharacter);
            objSkill = objCharacter.Skills.Find(o => o.DisplayName == "Blades");
            objSkill.Rating = 3;

            // Set the character's STR to 4 and make sure the Weapon attributes are calculated correctly.
            objCharacter.STR.Value = 4;
            Assert.AreEqual("11P", objWeapon.CalculatedDamage(), "Weapon DV does not match the expected value of 11P.");
            // Dice Pool should be 4 since the character has Blades 3 + AGI 1.
            Assert.AreEqual("4", objWeapon.DicePool, "Weapon Dice Pool does not match the expected value of 4.");
            // Add the Specialization to the Skill and check its value again. Should be 4 (6).
            objSkill.Specialization = "Axes";
            Assert.AreEqual("4 (6)", objWeapon.DicePool, "Weapon Dice Pool with Specialization does not match the expected value of 4 (6).");

            // Set the character's STR to 5 and make sure the Weapon attributes are calculated correctly. DV should be 12 since fractions are rounded up.
            objCharacter.STR.Value = 5;
            Assert.AreEqual("12P", objWeapon.CalculatedDamage(), "Weapon DV does not match the expected value of 11P.");
        }