public void LoadFromHeroLab(XmlNode xmlStatBlockBaseNode) { Timekeeper.Start("load_char_attrib"); foreach (CharacterAttrib objAttribute in AttributeList.Concat(SpecialAttributeList)) { objAttribute.UnbindAttribute(); } AttributeList.Clear(); SpecialAttributeList.Clear(); XmlDocument objXmlDocument = XmlManager.Load(_objCharacter.IsCritter ? "critters.xml" : "metatypes.xml"); XmlNode xmlMetatypeNode = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + _objCharacter.Metatype + "\"]"); XmlNode xmlCharNode = xmlMetatypeNode?.SelectSingleNode("metavariants/metavariant[name = \"" + _objCharacter.Metavariant + "\"]") ?? xmlMetatypeNode; // We only want to remake attributes for shifters in career mode, because they only get their second set of attributes when exporting from create mode into career mode XmlNode xmlCharNodeAnimalForm = _objCharacter.MetatypeCategory == "Shapeshifter" && _objCharacter.Created ? xmlMetatypeNode : null; foreach (string strAttribute in AttributeStrings) { // First, remake the attribute CharacterAttrib objAttribute = null; switch (CharacterAttrib.ConvertToAttributeCategory(strAttribute)) { case CharacterAttrib.AttributeCategory.Special: objAttribute = new CharacterAttrib(_objCharacter, strAttribute, CharacterAttrib.AttributeCategory.Special); objAttribute = RemakeAttribute(objAttribute, xmlCharNode); SpecialAttributeList.Add(objAttribute); break; case CharacterAttrib.AttributeCategory.Standard: objAttribute = new CharacterAttrib(_objCharacter, strAttribute, CharacterAttrib.AttributeCategory.Standard); objAttribute = RemakeAttribute(objAttribute, xmlCharNode); AttributeList.Add(objAttribute); break; } if (xmlCharNodeAnimalForm != null) { switch (CharacterAttrib.ConvertToAttributeCategory(strAttribute)) { case CharacterAttrib.AttributeCategory.Special: objAttribute = new CharacterAttrib(_objCharacter, strAttribute, CharacterAttrib.AttributeCategory.Special); objAttribute = RemakeAttribute(objAttribute, xmlCharNodeAnimalForm); SpecialAttributeList.Add(objAttribute); break; case CharacterAttrib.AttributeCategory.Shapeshifter: objAttribute = new CharacterAttrib(_objCharacter, strAttribute, CharacterAttrib.AttributeCategory.Shapeshifter); objAttribute = RemakeAttribute(objAttribute, xmlCharNodeAnimalForm); AttributeList.Add(objAttribute); break; } } // Then load in attribute karma levels (we'll adjust these later if the character is in Create mode) if (strAttribute == "ESS") // Not Essence though, this will get modified automatically instead of having its value set to the one HeroLab displays { continue; } XmlNode xmlHeroLabAttributeNode = xmlStatBlockBaseNode.SelectSingleNode("attributes/attribute[@name = \"" + GetAttributeEnglishName(strAttribute) + "\"]"); XmlNode xmlAttributeBaseNode = xmlHeroLabAttributeNode?.SelectSingleNode("@base"); if (xmlAttributeBaseNode != null && int.TryParse(xmlAttributeBaseNode.InnerText, out int intHeroLabAttributeBaseValue)) { int intAttributeMinimumValue = GetAttributeByName(strAttribute).MetatypeMinimum; if (intHeroLabAttributeBaseValue == intAttributeMinimumValue) { continue; } if (objAttribute != null) { objAttribute.Karma = intHeroLabAttributeBaseValue - intAttributeMinimumValue; } } } if (!_objCharacter.Created && _objCharacter.BuildMethodHasSkillPoints) { // Allocate Attribute Points int intAttributePointCount = _objCharacter.TotalAttributes; CharacterAttrib objAttributeToPutPointsInto; // First loop through attributes where costs can be 100% covered with points do { objAttributeToPutPointsInto = null; int intAttributeToPutPointsIntoTotalKarmaCost = 0; foreach (CharacterAttrib objLoopAttribute in AttributeList) { if (objLoopAttribute.Karma == 0) { continue; } // Put points into the attribute with the highest total karma cost. // In case of ties, pick the one that would need more points to cover it (the other one will hopefully get picked up at a later cycle) int intLoopTotalKarmaCost = objLoopAttribute.TotalKarmaCost; if (objAttributeToPutPointsInto == null || (objLoopAttribute.Karma <= intAttributePointCount && (intLoopTotalKarmaCost > intAttributeToPutPointsIntoTotalKarmaCost || (intLoopTotalKarmaCost == intAttributeToPutPointsIntoTotalKarmaCost && objLoopAttribute.Karma > objAttributeToPutPointsInto.Karma)))) { objAttributeToPutPointsInto = objLoopAttribute; intAttributeToPutPointsIntoTotalKarmaCost = intLoopTotalKarmaCost; } } if (objAttributeToPutPointsInto != null) { objAttributeToPutPointsInto.Base = objAttributeToPutPointsInto.Karma; intAttributePointCount -= objAttributeToPutPointsInto.Karma; objAttributeToPutPointsInto.Karma = 0; } } while (objAttributeToPutPointsInto != null && intAttributePointCount > 0); // If any points left over, then put them all into the attribute with the highest karma cost if (intAttributePointCount > 0 && AttributeList.Any(x => x.Karma != 0)) { int intHighestTotalKarmaCost = 0; foreach (CharacterAttrib objLoopAttribute in AttributeList) { if (objLoopAttribute.Karma == 0) { continue; } // Put points into the attribute with the highest total karma cost. // In case of ties, pick the one that would need more points to cover it (the other one will hopefully get picked up at a later cycle) int intLoopTotalKarmaCost = objLoopAttribute.TotalKarmaCost; if (objAttributeToPutPointsInto == null || intLoopTotalKarmaCost > intHighestTotalKarmaCost || (intLoopTotalKarmaCost == intHighestTotalKarmaCost && objLoopAttribute.Karma > objAttributeToPutPointsInto.Karma)) { objAttributeToPutPointsInto = objLoopAttribute; intHighestTotalKarmaCost = intLoopTotalKarmaCost; } } if (objAttributeToPutPointsInto != null) { objAttributeToPutPointsInto.Base = intAttributePointCount; objAttributeToPutPointsInto.Karma -= intAttributePointCount; } } // Allocate Special Attribute Points intAttributePointCount = _objCharacter.TotalSpecial; // First loop through attributes where costs can be 100% covered with points do { objAttributeToPutPointsInto = null; int intAttributeToPutPointsIntoTotalKarmaCost = 0; foreach (CharacterAttrib objLoopAttribute in SpecialAttributeList) { if (objLoopAttribute.Karma == 0) { continue; } // Put points into the attribute with the highest total karma cost. // In case of ties, pick the one that would need more points to cover it (the other one will hopefully get picked up at a later cycle) int intLoopTotalKarmaCost = objLoopAttribute.TotalKarmaCost; if (objAttributeToPutPointsInto == null || (objLoopAttribute.Karma <= intAttributePointCount && (intLoopTotalKarmaCost > intAttributeToPutPointsIntoTotalKarmaCost || (intLoopTotalKarmaCost == intAttributeToPutPointsIntoTotalKarmaCost && objLoopAttribute.Karma > objAttributeToPutPointsInto.Karma)))) { objAttributeToPutPointsInto = objLoopAttribute; intAttributeToPutPointsIntoTotalKarmaCost = intLoopTotalKarmaCost; } } if (objAttributeToPutPointsInto != null) { objAttributeToPutPointsInto.Base = objAttributeToPutPointsInto.Karma; intAttributePointCount -= objAttributeToPutPointsInto.Karma; objAttributeToPutPointsInto.Karma = 0; } } while (objAttributeToPutPointsInto != null); // If any points left over, then put them all into the attribute with the highest karma cost if (intAttributePointCount > 0 && SpecialAttributeList.Any(x => x.Karma != 0)) { int intHighestTotalKarmaCost = 0; foreach (CharacterAttrib objLoopAttribute in SpecialAttributeList) { if (objLoopAttribute.Karma == 0) { continue; } // Put points into the attribute with the highest total karma cost. // In case of ties, pick the one that would need more points to cover it (the other one will hopefully get picked up at a later cycle) int intLoopTotalKarmaCost = objLoopAttribute.TotalKarmaCost; if (objAttributeToPutPointsInto == null || intLoopTotalKarmaCost > intHighestTotalKarmaCost || (intLoopTotalKarmaCost == intHighestTotalKarmaCost && objLoopAttribute.Karma > objAttributeToPutPointsInto.Karma)) { objAttributeToPutPointsInto = objLoopAttribute; intHighestTotalKarmaCost = intLoopTotalKarmaCost; } } if (objAttributeToPutPointsInto != null) { objAttributeToPutPointsInto.Base = intAttributePointCount; objAttributeToPutPointsInto.Karma -= intAttributePointCount; } } } ResetBindings(); _objCharacter.RefreshAttributeBindings(); Timekeeper.Finish("load_char_attrib"); }
public void Create(XmlNode charNode, int intValue, int intMinModifier = 0, int intMaxModifier = 0) { Timekeeper.Start("create_char_attrib"); foreach (CharacterAttrib objAttribute in AttributeList.Concat(SpecialAttributeList)) { objAttribute.UnbindAttribute(); } AttributeList.Clear(); SpecialAttributeList.Clear(); foreach (string strAttribute in AttributeStrings) { CharacterAttrib objAttribute; switch (CharacterAttrib.ConvertToAttributeCategory(strAttribute)) { case CharacterAttrib.AttributeCategory.Special: objAttribute = new CharacterAttrib(_objCharacter, strAttribute, CharacterAttrib.AttributeCategory.Special); SpecialAttributeList.Add(objAttribute); break; case CharacterAttrib.AttributeCategory.Standard: objAttribute = new CharacterAttrib(_objCharacter, strAttribute, CharacterAttrib.AttributeCategory.Standard); AttributeList.Add(objAttribute); break; } } _objCharacter.BOD.AssignLimits(CommonFunctions.ExpressionToString(charNode["bodmin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["bodmax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["bodaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.AGI.AssignLimits(CommonFunctions.ExpressionToString(charNode["agimin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["agimax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["agiaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.REA.AssignLimits(CommonFunctions.ExpressionToString(charNode["reamin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["reamax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["reaaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.STR.AssignLimits(CommonFunctions.ExpressionToString(charNode["strmin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["strmax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["straug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.CHA.AssignLimits(CommonFunctions.ExpressionToString(charNode["chamin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["chamax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["chaaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.INT.AssignLimits(CommonFunctions.ExpressionToString(charNode["intmin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["intmax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["intaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.LOG.AssignLimits(CommonFunctions.ExpressionToString(charNode["logmin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["logmax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["logaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.WIL.AssignLimits(CommonFunctions.ExpressionToString(charNode["wilmin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["wilmax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["wilaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.MAG.AssignLimits(CommonFunctions.ExpressionToString(charNode["magmin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["magmax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["magaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.RES.AssignLimits(CommonFunctions.ExpressionToString(charNode["resmin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["resmax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["resaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.EDG.AssignLimits(CommonFunctions.ExpressionToString(charNode["edgmin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["edgmax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["edgaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.DEP.AssignLimits(CommonFunctions.ExpressionToString(charNode["depmin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["depmax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["depaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.MAGAdept.AssignLimits(CommonFunctions.ExpressionToString(charNode["magmin"]?.InnerText, intValue, intMinModifier), CommonFunctions.ExpressionToString(charNode["magmax"]?.InnerText, intValue, intMaxModifier), CommonFunctions.ExpressionToString(charNode["magaug"]?.InnerText, intValue, intMaxModifier)); _objCharacter.ESS.AssignLimits(CommonFunctions.ExpressionToString(charNode["essmin"]?.InnerText, intValue, 0), CommonFunctions.ExpressionToString(charNode["essmax"]?.InnerText, intValue, 0), CommonFunctions.ExpressionToString(charNode["essaug"]?.InnerText, intValue, 0)); Attributes = new ObservableCollection <CharacterAttrib> { _objCharacter.BOD, _objCharacter.AGI, _objCharacter.REA, _objCharacter.STR, _objCharacter.CHA, _objCharacter.INT, _objCharacter.LOG, _objCharacter.WIL, _objCharacter.EDG }; if (_objCharacter.MAGEnabled) { Attributes.Add(_objCharacter.MAG); if (_objCharacter.Options.MysAdeptSecondMAGAttribute && _objCharacter.IsMysticAdept) { Attributes.Add(_objCharacter.MAGAdept); } } if (_objCharacter.RESEnabled) { Attributes.Add(_objCharacter.RES); } if (_objCharacter.DEPEnabled) { Attributes.Add(_objCharacter.DEP); } ResetBindings(); _objCharacter.RefreshAttributeBindings(); Timekeeper.Finish("create_char_attrib"); }
public void Load(XmlNode xmlSavedCharacterNode) { Timekeeper.Start("load_char_attrib"); foreach (CharacterAttrib objAttribute in AttributeList.Concat(SpecialAttributeList)) { objAttribute.UnbindAttribute(); } AttributeList.Clear(); SpecialAttributeList.Clear(); XmlDocument objXmlDocument = XmlManager.Load(_objCharacter.IsCritter ? "critters.xml" : "metatypes.xml"); XmlNode xmlMetatypeNode = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + _objCharacter.Metatype + "\"]"); XmlNode xmlCharNode = xmlMetatypeNode?.SelectSingleNode("metavariants/metavariant[name = \"" + _objCharacter.Metavariant + "\"]") ?? xmlMetatypeNode; // We only want to remake attributes for shifters in career mode, because they only get their second set of attributes when exporting from create mode into career mode XmlNode xmlCharNodeAnimalForm = _objCharacter.MetatypeCategory == "Shapeshifter" && _objCharacter.Created ? xmlMetatypeNode : null; foreach (string strAttribute in AttributeStrings) { XmlNodeList lstAttributeNodes = xmlSavedCharacterNode.SelectNodes("attributes/attribute[name = \"" + strAttribute + "\"]"); // Couldn't find the appopriate attribute in the loaded file, so regenerate it from scratch. if (lstAttributeNodes == null || lstAttributeNodes.Count == 0 || xmlCharNodeAnimalForm != null && _objCharacter.LastSavedVersion < new Version("5.200.25")) { CharacterAttrib objAttribute; switch (CharacterAttrib.ConvertToAttributeCategory(strAttribute)) { case CharacterAttrib.AttributeCategory.Special: objAttribute = new CharacterAttrib(_objCharacter, strAttribute, CharacterAttrib.AttributeCategory.Special); objAttribute = RemakeAttribute(objAttribute, xmlCharNode); SpecialAttributeList.Add(objAttribute); break; case CharacterAttrib.AttributeCategory.Standard: objAttribute = new CharacterAttrib(_objCharacter, strAttribute, CharacterAttrib.AttributeCategory.Standard); objAttribute = RemakeAttribute(objAttribute, xmlCharNode); AttributeList.Add(objAttribute); break; } if (xmlCharNodeAnimalForm == null) { continue; } objAttribute = new CharacterAttrib(_objCharacter, strAttribute, CharacterAttrib.AttributeCategory.Shapeshifter); objAttribute = RemakeAttribute(objAttribute, xmlCharNodeAnimalForm); switch (CharacterAttrib.ConvertToAttributeCategory(objAttribute.Abbrev)) { case CharacterAttrib.AttributeCategory.Special: SpecialAttributeList.Add(objAttribute); break; case CharacterAttrib.AttributeCategory.Shapeshifter: AttributeList.Add(objAttribute); break; } } else { foreach (XmlNode xmlAttributeNode in lstAttributeNodes) { CharacterAttrib objAttribute; switch (CharacterAttrib.ConvertToAttributeCategory(strAttribute)) { case CharacterAttrib.AttributeCategory.Special: objAttribute = new CharacterAttrib(_objCharacter, strAttribute, CharacterAttrib.AttributeCategory.Special); objAttribute.Load(xmlAttributeNode); SpecialAttributeList.Add(objAttribute); break; case CharacterAttrib.AttributeCategory.Standard: objAttribute = new CharacterAttrib(_objCharacter, strAttribute, CharacterAttrib.AttributeCategory.Standard); objAttribute.Load(xmlAttributeNode); AttributeList.Add(objAttribute); break; } } } } Attributes = new ObservableCollection <CharacterAttrib> { _objCharacter.BOD, _objCharacter.AGI, _objCharacter.REA, _objCharacter.STR, _objCharacter.CHA, _objCharacter.INT, _objCharacter.LOG, _objCharacter.WIL, _objCharacter.EDG }; if (_objCharacter.MAGEnabled) { Attributes.Add(_objCharacter.MAG); if (_objCharacter.Options.MysAdeptSecondMAGAttribute && _objCharacter.IsMysticAdept) { Attributes.Add(_objCharacter.MAGAdept); } } if (_objCharacter.RESEnabled) { Attributes.Add(_objCharacter.RES); } if (_objCharacter.DEPEnabled) { Attributes.Add(_objCharacter.DEP); } ResetBindings(); _objCharacter.RefreshAttributeBindings(); Timekeeper.Finish("load_char_attrib"); }
public AttributeControl(CharacterAttrib attribute) { if (attribute == null) { return; } _objAttribute = attribute; _objCharacter = attribute.CharacterObject; InitializeComponent(); this.UpdateLightDarkMode(); this.TranslateWinForm(); SuspendLayout(); _dataSource = _objCharacter.AttributeSection.GetAttributeBindingByName(AttributeName); _objCharacter.AttributeSection.PropertyChanged += AttributePropertyChanged; //Display lblName.DoOneWayDataBinding("Text", _dataSource, nameof(CharacterAttrib.DisplayNameFormatted)); lblValue.DoOneWayDataBinding("Text", _dataSource, nameof(CharacterAttrib.DisplayValue)); lblLimits.DoOneWayDataBinding("Text", _dataSource, nameof(CharacterAttrib.AugmentedMetatypeLimits)); lblValue.DoOneWayDataBinding("ToolTipText", _dataSource, nameof(CharacterAttrib.ToolTip)); if (_objCharacter.Created) { cmdImproveATT = new ButtonWithToolTip { Anchor = AnchorStyles.Right, AutoSize = true, AutoSizeMode = AutoSizeMode.GrowAndShrink, Image = Resources.add, Margin = new Padding(3, 0, 3, 0), MinimumSize = new Size(24, 24), Name = "cmdImproveATT", UseVisualStyleBackColor = true }; cmdImproveATT.Click += cmdImproveATT_Click; cmdImproveATT.DoOneWayDataBinding("ToolTipText", _dataSource, nameof(CharacterAttrib.UpgradeToolTip)); cmdImproveATT.DoOneWayDataBinding("Enabled", _dataSource, nameof(CharacterAttrib.CanUpgradeCareer)); cmdImproveATT.UpdateLightDarkMode(); cmdImproveATT.TranslateWinForm(); flpRight.Controls.Add(cmdImproveATT); if (AttributeName == "EDG") { cmdBurnEdge = new ButtonWithToolTip { Anchor = AnchorStyles.Right, AutoSize = true, AutoSizeMode = AutoSizeMode.GrowAndShrink, Image = Resources.fire, Margin = new Padding(3, 0, 3, 0), MinimumSize = new Size(24, 24), Name = "cmdBurnEdge", ToolTipText = LanguageManager.GetString("Tip_CommonBurnEdge"), UseVisualStyleBackColor = true }; cmdBurnEdge.Click += cmdBurnEdge_Click; cmdBurnEdge.UpdateLightDarkMode(); cmdBurnEdge.TranslateWinForm(); flpRight.Controls.Add(cmdBurnEdge); } } else { while (_objAttribute.KarmaMaximum < 0 && _objAttribute.Base > 0) { _objAttribute.Base -= 1; } // Very rough fix for when Karma values somehow exceed KarmaMaximum after loading in. This shouldn't happen in the first place, but this ad-hoc patch will help fix crashes. if (_objAttribute.Karma > _objAttribute.KarmaMaximum) { _objAttribute.Karma = _objAttribute.KarmaMaximum; } nudKarma = new NumericUpDownEx { Anchor = AnchorStyles.Right, AutoSize = true, InterceptMouseWheel = NumericUpDownEx.InterceptMouseWheelMode.WhenMouseOver, Margin = new Padding(3, 0, 3, 0), Maximum = new decimal(new[] { 99, 0, 0, 0 }), MinimumSize = new Size(35, 0), Name = "nudKarma" }; nudKarma.BeforeValueIncrement += nudKarma_BeforeValueIncrement; nudKarma.ValueChanged += nudKarma_ValueChanged; nudBase = new NumericUpDownEx { Anchor = AnchorStyles.Right, AutoSize = true, InterceptMouseWheel = NumericUpDownEx.InterceptMouseWheelMode.WhenMouseOver, Margin = new Padding(3, 0, 3, 0), Maximum = new decimal(new[] { 99, 0, 0, 0 }), MinimumSize = new Size(35, 0), Name = "nudBase" }; nudBase.BeforeValueIncrement += nudBase_BeforeValueIncrement; nudBase.ValueChanged += nudBase_ValueChanged; nudBase.DoOneWayDataBinding("Visible", _objCharacter, nameof(Character.EffectiveBuildMethodUsesPriorityTables)); nudBase.DoOneWayDataBinding("Maximum", _dataSource, nameof(CharacterAttrib.PriorityMaximum)); nudBase.DoDatabinding("Value", _dataSource, nameof(CharacterAttrib.Base)); nudBase.DoOneWayDataBinding("Enabled", _dataSource, nameof(CharacterAttrib.BaseUnlocked)); nudBase.InterceptMouseWheel = GlobalOptions.InterceptMode; nudKarma.DoOneWayDataBinding("Maximum", _dataSource, nameof(CharacterAttrib.KarmaMaximum)); nudKarma.DoDatabinding("Value", _dataSource, nameof(CharacterAttrib.Karma)); nudKarma.InterceptMouseWheel = GlobalOptions.InterceptMode; nudBase.UpdateLightDarkMode(); nudBase.TranslateWinForm(); nudKarma.UpdateLightDarkMode(); nudKarma.TranslateWinForm(); flpRight.Controls.Add(nudKarma); flpRight.Controls.Add(nudBase); } ResumeLayout(); }
public SkillControl(Skill objSkill) { if (objSkill == null) { return; } _objSkill = objSkill; _objAttributeActive = objSkill.AttributeObject; if (_objAttributeActive != null) { _objAttributeActive.PropertyChanged += Attribute_PropertyChanged; } InitializeComponent(); SuspendLayout(); pnlAttributes.SuspendLayout(); tlpMain.SuspendLayout(); tlpRight.SuspendLayout(); try { //Display _fntNormalName = lblName.Font; _fntItalicName = new Font(_fntNormalName, FontStyle.Italic); _fntNormal = btnAttribute.Font; _fntItalic = new Font(_fntNormal, FontStyle.Italic); if (!_objSkill.Default) { lblName.Font = _fntItalicName; } lblName.DoOneWayDataBinding("Text", objSkill, nameof(Skill.CurrentDisplayName)); lblName.DoOneWayDataBinding("ForeColor", objSkill, nameof(Skill.PreferredColor)); lblName.DoOneWayDataBinding("ToolTipText", objSkill, nameof(Skill.HtmlSkillToolTip)); btnAttribute.DoOneWayDataBinding("Text", objSkill, nameof(Skill.DisplayAttribute)); RefreshPoolTooltipAndDisplay(); // Creating controls outside of the designer saves on handles if the controls would be invisible anyway if (objSkill.AllowDelete) // For active skills, can only change by going from Create to Career mode, so no databinding necessary { cmdDelete = new Button { AutoSize = true, AutoSizeMode = AutoSizeMode.GrowAndShrink, Dock = DockStyle.Fill, Margin = new Padding(3, 0, 3, 0), Name = "cmdDelete", Tag = "String_Delete", Text = "Delete", UseVisualStyleBackColor = true }; cmdDelete.Click += cmdDelete_Click; tlpRight.Controls.Add(cmdDelete, 4, 0); } if (objSkill.CharacterObject.Created) { lblCareerRating = new Label { Anchor = AnchorStyles.Right, AutoSize = true, Margin = new Padding(3, 6, 3, 6), Name = "lblCareerRating", Text = "00", TextAlign = ContentAlignment.MiddleRight }; btnCareerIncrease = new ButtonWithToolTip { Anchor = AnchorStyles.Right, AutoSize = true, AutoSizeMode = AutoSizeMode.GrowAndShrink, ImageDpi96 = Resources.add, ImageDpi192 = Resources.add1, MinimumSize = new Size(24, 24), Name = "btnCareerIncrease", Padding = new Padding(1), UseVisualStyleBackColor = true }; btnCareerIncrease.Click += btnCareerIncrease_Click; lblCareerRating.DoOneWayDataBinding("Text", objSkill, nameof(Skill.Rating)); btnCareerIncrease.DoOneWayDataBinding("Enabled", objSkill, nameof(Skill.CanUpgradeCareer)); btnCareerIncrease.DoOneWayDataBinding("ToolTipText", objSkill, nameof(Skill.UpgradeToolTip)); tlpMain.Controls.Add(lblCareerRating, 2, 0); tlpMain.Controls.Add(btnCareerIncrease, 3, 0); btnAddSpec = new ButtonWithToolTip { Anchor = AnchorStyles.Right, AutoSize = true, AutoSizeMode = AutoSizeMode.GrowAndShrink, ImageDpi96 = Resources.add, ImageDpi192 = Resources.add1, MinimumSize = new Size(24, 24), Name = "btnAddSpec", Padding = new Padding(1), UseVisualStyleBackColor = true }; btnAddSpec.Click += btnAddSpec_Click; lblCareerSpec = new Label { Anchor = AnchorStyles.Left, AutoSize = true, Margin = new Padding(3, 6, 3, 6), Name = "lblCareerSpec", Text = "[Specializations]", TextAlign = ContentAlignment.MiddleLeft }; lblCareerSpec.DoOneWayDataBinding("Text", objSkill, nameof(Skill.CurrentDisplaySpecialization)); btnAddSpec.DoOneWayDataBinding("Enabled", objSkill, nameof(Skill.CanAffordSpecialization)); btnAddSpec.DoOneWayDataBinding("Visible", objSkill, nameof(Skill.CanHaveSpecs)); btnAddSpec.DoOneWayDataBinding("ToolTipText", objSkill, nameof(Skill.AddSpecToolTip)); tlpRight.Controls.Add(lblCareerSpec, 0, 0); tlpRight.Controls.Add(btnAddSpec, 1, 0); using (new FetchSafelyFromPool <List <ListItem> >(Utils.ListItemListPool, out List <ListItem> lstAttributeItems)) { foreach (string strLoopAttribute in AttributeSection.AttributeStrings) { if (strLoopAttribute == "MAGAdept") { if (!objSkill.CharacterObject.Settings.MysAdeptSecondMAGAttribute) { continue; } lstAttributeItems.Add(new ListItem(strLoopAttribute, LanguageManager.MAGAdeptString())); } else { string strAttributeShort = LanguageManager.GetString( "String_Attribute" + strLoopAttribute + "Short", GlobalSettings.Language, false); lstAttributeItems.Add(new ListItem(strLoopAttribute, !string.IsNullOrEmpty(strAttributeShort) ? strAttributeShort : strLoopAttribute)); } } cboSelectAttribute = new ElasticComboBox { Dock = DockStyle.Fill, DropDownStyle = ComboBoxStyle.DropDownList, FormattingEnabled = true, Margin = new Padding(3, 0, 3, 0), Name = "cboSelectAttribute" }; cboSelectAttribute.BeginUpdate(); cboSelectAttribute.PopulateWithListItems(lstAttributeItems); cboSelectAttribute.SelectedValue = _objSkill.AttributeObject.Abbrev; cboSelectAttribute.EndUpdate(); cboSelectAttribute.DropDownClosed += cboSelectAttribute_Closed; pnlAttributes.Controls.Add(cboSelectAttribute); } } else { nudSkill = new NumericUpDownEx { Anchor = AnchorStyles.Right, AutoSize = true, InterceptMouseWheel = NumericUpDownEx.InterceptMouseWheelMode.WhenMouseOver, Margin = new Padding(3, 2, 3, 2), Maximum = new decimal(new[] { 99, 0, 0, 0 }), Name = "nudSkill" }; nudKarma = new NumericUpDownEx { Anchor = AnchorStyles.Right, AutoSize = true, InterceptMouseWheel = NumericUpDownEx.InterceptMouseWheelMode.WhenMouseOver, Margin = new Padding(3, 2, 3, 2), Maximum = new decimal(new[] { 99, 0, 0, 0 }), Name = "nudKarma" }; // Trick to make it seem like the button is a label (+ onclick method not doing anything in Create mode) btnAttribute.FlatAppearance.MouseDownBackColor = Color.Transparent; btnAttribute.FlatAppearance.MouseOverBackColor = Color.Transparent; nudSkill.DoOneWayDataBinding("Visible", objSkill.CharacterObject, nameof(objSkill.CharacterObject.EffectiveBuildMethodUsesPriorityTables)); nudSkill.DoDataBinding("Value", objSkill, nameof(Skill.Base)); nudSkill.DoOneWayDataBinding("Enabled", objSkill, nameof(Skill.BaseUnlocked)); nudSkill.InterceptMouseWheel = GlobalSettings.InterceptMode; nudKarma.DoDataBinding("Value", objSkill, nameof(Skill.Karma)); nudKarma.DoOneWayDataBinding("Enabled", objSkill, nameof(Skill.KarmaUnlocked)); nudKarma.InterceptMouseWheel = GlobalSettings.InterceptMode; tlpMain.Controls.Add(nudSkill, 2, 0); tlpMain.Controls.Add(nudKarma, 3, 0); if (objSkill.IsExoticSkill) { lblCareerSpec = new Label { Anchor = AnchorStyles.Left, AutoSize = true, Margin = new Padding(3, 6, 3, 6), Name = "lblCareerSpec", Text = "[Specializations]", TextAlign = ContentAlignment.MiddleLeft }; lblCareerSpec.DoOneWayDataBinding("Text", objSkill, nameof(Skill.CurrentDisplaySpecialization)); tlpRight.Controls.Add(lblCareerSpec, 0, 0); } else { cboSpec = new ElasticComboBox { Anchor = AnchorStyles.Left | AnchorStyles.Right, AutoCompleteMode = AutoCompleteMode.Suggest, FormattingEnabled = true, Margin = new Padding(3, 0, 3, 0), Name = "cboSpec", Sorted = true, TabStop = false }; cboSpec.BeginUpdate(); cboSpec.PopulateWithListItems(objSkill.CGLSpecializations); cboSpec.EndUpdate(); cboSpec.DoOneWayDataBinding("Enabled", objSkill, nameof(Skill.CanHaveSpecs)); cboSpec.Text = objSkill.CurrentDisplaySpecialization; cboSpec.TextChanged += cboSpec_TextChanged; _blnUpdatingSpec = false; _tmrSpecChangeTimer = new Timer { Interval = 1000 }; _tmrSpecChangeTimer.Tick += SpecChangeTimer_Tick; chkKarma = new ColorableCheckBox(components) { Anchor = AnchorStyles.Left, AutoSize = true, DefaultColorScheme = true, Margin = new Padding(3, 4, 3, 4), Name = "chkKarma", UseVisualStyleBackColor = true }; chkKarma.DoOneWayDataBinding("Visible", objSkill.CharacterObject, nameof(objSkill.CharacterObject.EffectiveBuildMethodUsesPriorityTables)); chkKarma.DoDataBinding("Checked", objSkill, nameof(Skill.BuyWithKarma)); chkKarma.DoOneWayDataBinding("Enabled", objSkill, nameof(Skill.CanHaveSpecs)); tlpRight.Controls.Add(cboSpec, 0, 0); tlpRight.Controls.Add(chkKarma, 1, 0); // Hacky way of fixing a weird UI issue caused by items of a combobox only being populated from the DataSource after the combobox is added _blnUpdatingSpec = true; cboSpec.Text = objSkill.CurrentDisplaySpecialization; _blnUpdatingSpec = false; } } this.DoOneWayDataBinding("Enabled", objSkill, nameof(Skill.Enabled)); this.DoOneWayDataBinding("BackColor", objSkill, nameof(Skill.PreferredControlColor)); AdjustForDpi(); this.UpdateLightDarkMode(); this.TranslateWinForm(blnDoResumeLayout: false); foreach (ToolStripItem tssItem in cmsSkillLabel.Items) { tssItem.UpdateLightDarkMode(); tssItem.TranslateToolStripItemsRecursively(); } } finally { _blnLoading = false; tlpRight.ResumeLayout(); tlpMain.ResumeLayout(); pnlAttributes.ResumeLayout(); ResumeLayout(true); _objSkill.PropertyChanged += Skill_PropertyChanged; } }
public SkillControl2(Skill skill) { if (skill == null) { return; } _skill = skill; InitializeComponent(); SuspendLayout(); this.TranslateWinForm(); foreach (ToolStripItem tssItem in cmsSkillLabel.Items) { tssItem.TranslateToolStripItemsRecursively(); } this.DoDatabinding("Enabled", skill, nameof(Skill.Enabled)); //Display _normalName = lblName.Font; _italicName = new Font(lblName.Font, FontStyle.Italic); this.DoDatabinding("BackColor", skill, nameof(Skill.PreferredControlColor)); lblName.DoDatabinding("Text", skill, nameof(Skill.CurrentDisplayName)); lblName.DoDatabinding("ForeColor", skill, nameof(Skill.PreferredColor)); lblName.DoDatabinding("ToolTipText", skill, nameof(Skill.HtmlSkillToolTip)); lblModifiedRating.DoDatabinding("ToolTipText", skill, nameof(Skill.PoolToolTip)); lblModifiedRating.DoDatabinding("Text", skill, nameof(Skill.DisplayPool)); _attributeActive = skill.AttributeObject; _skill.PropertyChanged += Skill_PropertyChanged; nudSkill.Visible = !skill.CharacterObject.Created && skill.CharacterObject.BuildMethodHasSkillPoints; nudKarma.Visible = !skill.CharacterObject.Created; chkKarma.Visible = !skill.CharacterObject.Created; cboSpec.Visible = !skill.CharacterObject.Created; cboSelectAttribute.Visible = false; btnCareerIncrease.Visible = skill.CharacterObject.Created; lblCareerSpec.Visible = skill.CharacterObject.Created; btnAddSpec.Visible = skill.CharacterObject.Created; lblAttribute.Visible = skill.CharacterObject.Created; btnAttribute.Visible = skill.CharacterObject.Created; lblCareerRating.Visible = skill.CharacterObject.Created; _normal = btnAttribute.Font; _italic = new Font(_normal, FontStyle.Italic); if (skill.CharacterObject.Created) { lblModifiedRating.Location = new Point(256 - 13, 4); lblCareerRating.DoDatabinding("Text", skill, nameof(Skill.Rating)); btnCareerIncrease.DoDatabinding("Enabled", skill, nameof(Skill.CanUpgradeCareer)); btnCareerIncrease.DoDatabinding("ToolTipText", skill, nameof(Skill.UpgradeToolTip)); btnAddSpec.DoDatabinding("Enabled", skill, nameof(Skill.CanAffordSpecialization)); btnAddSpec.DoDatabinding("Visible", skill, nameof(Skill.CanHaveSpecs)); btnAddSpec.DoDatabinding("ToolTipText", skill, nameof(Skill.AddSpecToolTip)); lblCareerSpec.DoDatabinding("Text", skill, nameof(Skill.CurrentDisplaySpecialization)); lblAttribute.Visible = false; //Was true, cannot think it should be btnAttribute.DoDatabinding("Text", skill, nameof(Skill.DisplayAttribute)); btnAttribute.Visible = true; SetupDropdown(); } else { lblAttribute.DoDatabinding("Text", skill, nameof(Skill.DisplayAttribute)); //Up down boxes nudKarma.DoDatabinding("Value", skill, nameof(Skill.Karma)); nudSkill.DoDatabinding("Value", skill, nameof(Skill.Base)); nudSkill.DoDatabinding("Visible", skill.CharacterObject, nameof(skill.CharacterObject.BuildMethodHasSkillPoints)); nudSkill.DoDatabinding("Enabled", skill, nameof(Skill.BaseUnlocked)); nudSkill.DoDatabinding("InterceptMouseWheel", skill.CharacterObject.Options, nameof(CharacterOptions.InterceptMode)); nudKarma.DoDatabinding("Enabled", skill, nameof(Skill.KarmaUnlocked)); nudKarma.DoDatabinding("InterceptMouseWheel", skill.CharacterObject.Options, nameof(CharacterOptions.InterceptMode)); chkKarma.DoDatabinding("Visible", skill.CharacterObject, nameof(skill.CharacterObject.BuildMethodHasSkillPoints)); chkKarma.DoDatabinding("Checked", skill, nameof(Skill.BuyWithKarma)); chkKarma.DoDatabinding("Enabled", skill, nameof(Skill.CanHaveSpecs)); cboSpec.BeginUpdate(); if (skill.IsExoticSkill) { cboSpec.Enabled = false; cboSpec.DoDatabinding("Text", skill, nameof(Skill.CurrentDisplaySpecialization)); } else { //dropdown/spec cboSpec.DoDatabinding("Enabled", skill, nameof(Skill.CanHaveSpecs)); cboSpec.DataSource = skill.CGLSpecializations; cboSpec.DisplayMember = nameof(ListItem.Name); cboSpec.ValueMember = nameof(ListItem.Value); cboSpec.SelectedIndex = -1; cboSpec.DoDatabinding("Text", skill, nameof(Skill.Specialization)); } cboSpec.EndUpdate(); } //Delete button cmdDelete.Visible = skill.AllowDelete; if (skill.AllowDelete) { cmdDelete.Click += (sender, args) => { if (!skill.CharacterObject.ConfirmDelete(LanguageManager.GetString(skill.IsExoticSkill ? "Message_DeleteExoticSkill" : "Message_DeleteSkill", GlobalOptions.Language))) { return; } skill.UnbindSkill(); skill.CharacterObject.SkillsSection.Skills.Remove(skill); skill.CharacterObject.SkillsSection.SkillsDictionary.Remove(skill.IsExoticSkill ? skill.Name + " (" + skill.DisplaySpecialization(GlobalOptions.DefaultLanguage) + ')' : skill.Name); }; if (skill.CharacterObject.Created) { btnAddSpec.Location = new Point(btnAddSpec.Location.X - cmdDelete.Width, btnAddSpec.Location.Y); } } lblName.Font = !_skill.Default ? _italicName : _normalName; lblModifiedRating.Text = _skill.DisplayOtherAttribute(_attributeActive.TotalValue, _attributeActive.Abbrev); _blnLoading = false; ResumeLayout(); }
public static bool TestNodeRequirements(XmlNode node, Character character, out string name, string strIgnoreQuality = "", XmlDocument objMetatypeDocument = null, XmlDocument objCritterDocument = null, XmlDocument objQualityDocument = null) { XmlNode nameNode; string strNodeInnerText = node.InnerText; string strNodeName = node["name"]?.InnerText ?? string.Empty; switch (node.Name) { case "attribute": // Check to see if an Attribute meets a requirement. CharacterAttrib objAttribute = character.GetAttribute(strNodeName); int intTargetValue = Convert.ToInt32(node["total"].InnerText); name = $"\n\t{objAttribute.DisplayAbbrev} {intTargetValue}"; // Special cases for when we want to check if a special attribute is enabled if (intTargetValue == 1) { if (objAttribute.Abbrev == "MAG") { return(character.MAGEnabled); } if (objAttribute.Abbrev == "RES") { return(character.RESEnabled); } if (objAttribute.Abbrev == "DEP") { return(character.DEPEnabled); } } return(objAttribute.TotalValue >= intTargetValue); case "attributetotal": string strNodeAttributes = node["attributes"].InnerText; int intNodeVal = Convert.ToInt32(node["val"].InnerText); // Check if the character's Attributes add up to a particular total. string strAttributes = AttributeSection.AttributeStrings.Aggregate(strNodeAttributes, (current, strAttribute) => current.Replace(strAttribute, character.GetAttribute(strAttribute).DisplayAbbrev)); name = $"\n\t{strAttributes} {intNodeVal}"; strAttributes = AttributeSection.AttributeStrings.Aggregate(strNodeAttributes, (current, strAttribute) => current.Replace(strAttribute, character.GetAttribute(strAttribute).Value.ToString())); XmlDocument objXmlDocument = new XmlDocument(); XPathNavigator nav = objXmlDocument.CreateNavigator(); XPathExpression xprAttributes = nav.Compile(strAttributes); return(Convert.ToInt32(nav.Evaluate(xprAttributes)) >= intNodeVal); case "careerkarma": // Check Career Karma requirement. name = "\n\t" + LanguageManager.GetString("Message_SelectQuality_RequireKarma") .Replace("{0}", strNodeInnerText); return(character.CareerKarma >= Convert.ToInt32(strNodeInnerText)); case "critterpower": // Run through all of the Powers the character has and see if the current required item exists. if (character.CritterEnabled && character.CritterPowers != null) { CritterPower critterPower = character.CritterPowers.FirstOrDefault(p => p.Name == strNodeInnerText); if (critterPower != null) { name = critterPower.DisplayNameShort; return(true); } XmlDocument critterPowers = XmlManager.Load("critterpowers.xml"); nameNode = critterPowers.SelectSingleNode($"/chummer/powers/power[name = \"{strNodeInnerText}\"]"); name = nameNode["translate"] != null ? "\n\t" + nameNode["translate"].InnerText : "\n\t" + strNodeInnerText; name += $" ({LanguageManager.GetString("Tab_Critter")})"; return(false); } break; case "bioware": case "cyberware": { int count = Convert.ToInt32(node.Attributes?["count"]?.InnerText ?? "1"); name = null; name += node.Name == "cyberware" ? "\n\t" + LanguageManager.GetString("Label_Cyberware") + strNodeInnerText : "\n\t" + LanguageManager.GetString("Label_Bioware") + strNodeInnerText; string strWareNodeSelectAttribute = node.Attributes?["select"]?.InnerText ?? string.Empty; return(character.Cyberware.DeepCount(x => x.Children, objCyberware => objCyberware.Name == strNodeInnerText && string.IsNullOrEmpty(objCyberware.PlugsIntoModularMount) && (string.IsNullOrEmpty(strWareNodeSelectAttribute) || strWareNodeSelectAttribute == objCyberware.Extra)) >= count); } case "biowarecontains": case "cyberwarecontains": { int count = Convert.ToInt32(node.Attributes?["count"]?.InnerText ?? "1"); name = null; name += node.Name == "cyberware" ? "\n\t" + LanguageManager.GetString("Label_Cyberware") + strNodeInnerText : "\n\t" + LanguageManager.GetString("Label_Bioware") + strNodeInnerText; Improvement.ImprovementSource source = Improvement.ImprovementSource.Cyberware; if (node.Name == "biowarecontains") { source = Improvement.ImprovementSource.Bioware; } string strWareContainsNodeSelectAttribute = node.Attributes?["select"]?.InnerText ?? string.Empty; return(character.Cyberware.DeepCount(x => x.Children, objCyberware => objCyberware.SourceType == source && string.IsNullOrEmpty(objCyberware.PlugsIntoModularMount) && objCyberware.Name.Contains(strNodeInnerText) && (string.IsNullOrEmpty(strWareContainsNodeSelectAttribute) || strWareContainsNodeSelectAttribute == objCyberware.Extra)) >= count); } case "damageresistance": // Damage Resistance must be a particular value. name = "\n\t" + LanguageManager.GetString("String_DamageResistance"); return(character.BOD.TotalValue + ImprovementManager.ValueOf(character, Improvement.ImprovementType.DamageResistance) >= Convert.ToInt32(strNodeInnerText)); case "ess": string objEssNodeGradeAttributeText = node.Attributes?["grade"]?.InnerText ?? string.Empty; if (!string.IsNullOrEmpty(objEssNodeGradeAttributeText)) { decimal decGrade = character.Cyberware.Where( objCyberware => objCyberware.Grade.Name.Contains(objEssNodeGradeAttributeText)) .Sum(objCyberware => objCyberware.CalculatedESS()); if (strNodeInnerText.StartsWith('-')) { // Essence must be less than the value. name = "\n\t" + LanguageManager.GetString( "Message_SelectQuality_RequireESSGradeBelow") .Replace("{0}", strNodeInnerText) .Replace("{1}", objEssNodeGradeAttributeText) .Replace("{2}", decGrade.ToString(CultureInfo.InvariantCulture)); return(decGrade < Convert.ToDecimal(strNodeInnerText.TrimStart('-'), GlobalOptions.InvariantCultureInfo)); } // Essence must be equal to or greater than the value. name = "\n\t" + LanguageManager.GetString( "Message_SelectQuality_RequireESSGradeAbove") .Replace("{0}", strNodeInnerText) .Replace("{1}", objEssNodeGradeAttributeText) .Replace("{2}", decGrade.ToString(CultureInfo.InvariantCulture)); return(decGrade >= Convert.ToDecimal(strNodeInnerText, GlobalOptions.InvariantCultureInfo)); } // Check Essence requirement. if (strNodeInnerText.StartsWith('-')) { // Essence must be less than the value. name = "\n\t" + LanguageManager.GetString( "Message_SelectQuality_RequireESSBelow") .Replace("{0}", strNodeInnerText) .Replace("{1}", character.Essence.ToString(CultureInfo.InvariantCulture)); return(character.Essence < Convert.ToDecimal(strNodeInnerText.TrimStart('-'), GlobalOptions.InvariantCultureInfo)); } // Essence must be equal to or greater than the value. name = "\n\t" + LanguageManager.GetString( "Message_SelectQuality_RequireESSAbove") .Replace("{0}", strNodeInnerText) .Replace("{1}", character.Essence.ToString(CultureInfo.InvariantCulture)); return(character.Essence >= Convert.ToDecimal(strNodeInnerText, GlobalOptions.InvariantCultureInfo)); case "group": // Check that clustered options are present (Magical Tradition + Skill 6, for example) string result = string.Empty; if (node.ChildNodes.Cast <XmlNode>().Any(childNode => !TestNodeRequirements(childNode, character, out result, strIgnoreQuality, objMetatypeDocument, objCritterDocument, objQualityDocument))) { name = result; return(false); } name = result; return(true); case "initiategrade": // Character's initiate grade must be higher than or equal to the required value. name = "\n\t" + LanguageManager.GetString("String_InitiateGrade") + " >= " + strNodeInnerText; return(character.InitiateGrade >= Convert.ToInt32(strNodeInnerText)); case "martialtechnique": // Character needs a specific Martial Arts technique. XmlNode martialDoc = XmlManager.Load("martialarts.xml"); nameNode = martialDoc.SelectSingleNode($"/chummer/techniques/technique[name = \"{strNodeInnerText}\"]"); name = nameNode["translate"] != null ? "\n\t" + nameNode["translate"].InnerText : "\n\t" + strNodeInnerText; name += $" ({LanguageManager.GetString("String_MartialArt")})"; return(character.MartialArts.Any(martialart => martialart.Advantages.Any(technique => technique.Name == strNodeInnerText))); case "metamagic": XmlNode metamagicDoc = XmlManager.Load("metamagic.xml"); nameNode = metamagicDoc.SelectSingleNode($"/chummer/metamagics/metamagic[name = \"{strNodeInnerText}\"]"); name = nameNode["translate"] != null ? "\n\t" + nameNode["translate"].InnerText : "\n\t" + strNodeInnerText; name += $" ({LanguageManager.GetString("String_Metamagic")})"; return(character.Metamagics.Any(objMetamagic => objMetamagic.Name == strNodeInnerText)); case "metamagicart": case "art": XmlNode metamagicArtDoc = XmlManager.Load("metamagic.xml"); nameNode = metamagicArtDoc.SelectSingleNode($"/chummer/arts/art[name = \"{strNodeInnerText}\"]"); name = nameNode["translate"] != null ? "\n\t" + nameNode["translate"].InnerText : "\n\t" + strNodeInnerText; name += $" ({LanguageManager.GetString("String_Art")})"; if (character.Options.IgnoreArt) { if (node.Name == "art") { return(true); } foreach (Metamagic metamagic in character.Metamagics) { XmlNode metaNode = metamagicArtDoc.SelectSingleNode($"/chummer/metamagics/metamagic[name = \"{metamagic.Name}\"]/required"); if (metaNode?.InnerXml.Contains($"<art>{strNodeInnerText}</art>") == true) { return(metaNode.InnerXml.Contains($"<art>{strNodeInnerText}</art>")); } metaNode = metamagicArtDoc.SelectSingleNode($"/chummer/metamagics/metamagic[name = \"{metamagic.Name}\"]/forbidden"); if (metaNode?.InnerXml.Contains($"<art>{strNodeInnerText}</art>") == true) { return(metaNode.InnerXml.Contains($"<art>{strNodeInnerText}</art>")); } } return(false); } return(character.Arts.Any(art => art.Name == strNodeInnerText)); case "metatype": // Check the Metatype restriction. nameNode = objMetatypeDocument.SelectSingleNode($"/chummer/metatypes/metatype[name = \"{strNodeInnerText}\"]") ?? objCritterDocument.SelectSingleNode($"/chummer/metatypes/metatype[name = \"{strNodeInnerText}\"]"); name = nameNode["translate"] != null ? "\n\t" + nameNode["translate"].InnerText : "\n\t" + strNodeInnerText; name += $" ({LanguageManager.GetString("String_Metatype")})"; return(strNodeInnerText == character.Metatype); case "metatypecategory": // Check the Metatype Category restriction. nameNode = objMetatypeDocument.SelectSingleNode($"/chummer/categories/category[. = \"{strNodeInnerText}\"]") ?? objCritterDocument.SelectSingleNode($"/chummer/categories/category[. = \"{strNodeInnerText}\"]"); name = nameNode?.Attributes["translate"] != null ? "\n\t" + nameNode.Attributes["translate"]?.InnerText : "\n\t" + strNodeInnerText; name += LanguageManager.GetString("String_MetatypeCategory"); return(strNodeInnerText == character.MetatypeCategory); case "metavariant": // Check the Metavariant restriction. nameNode = objMetatypeDocument.SelectSingleNode($"/chummer/metavariants/metavariant[name = \"{strNodeInnerText}\"]") ?? objCritterDocument.SelectSingleNode($"/chummer/metavariants/metavariant[name = \"{strNodeInnerText}\"]"); name = nameNode["translate"] != null ? "\n\t" + nameNode["translate"].InnerText : "\n\t" + strNodeInnerText; name += $" ({LanguageManager.GetString("String_Metavariant")})"; return(strNodeInnerText == character.Metavariant); case "power": // Run through all of the Powers the character has and see if the current required item exists. Power power = character.Powers.FirstOrDefault(p => p.Name == strNodeInnerText); if (power != null) { name = power.DisplayNameShort; return(true); } XmlDocument xmlPowers = XmlManager.Load("powers.xml"); nameNode = xmlPowers.SelectSingleNode($"/chummer/powers/power[name = \"{strNodeInnerText}\"]"); name = nameNode["translate"] != null ? "\n\t" + nameNode["translate"].InnerText : "\n\t" + strNodeInnerText; name += $" ({LanguageManager.GetString("Tab_Adept")})"; return(false); case "quality": Quality quality = character.Qualities.FirstOrDefault(q => q.Name == strNodeInnerText && q.Name != strIgnoreQuality); if (quality != null) { name = quality.DisplayNameShort; return(true); } // ReSharper disable once RedundantIfElseBlock (Suppresses node warning) else { nameNode = objQualityDocument.SelectSingleNode($"/chummer/qualities/quality[name = \"{strNodeInnerText}\"]"); name = nameNode?["translate"] != null ? "\n\t" + nameNode["translate"].InnerText : "\n\t" + strNodeInnerText; name += $" ({LanguageManager.GetString("String_Quality")})"; return(false); } case "skill": // Check if the character has the required Skill. if (node["type"] != null) { KnowledgeSkill s = character.SkillsSection.KnowledgeSkills .Where(objSkill => objSkill.Name == strNodeName && (node["spec"] == null || objSkill.Specializations.Any(objSpec => objSpec.Name == node["spec"]?.InnerText))) .FirstOrDefault(objSkill => objSkill.TotalBaseRating >= Convert.ToInt32(node["val"]?.InnerText)); if (s != null) { name = s.DisplayName; if (node["spec"] != null && !character.Improvements.Any(objImprovement => objImprovement.ImproveType == Improvement.ImprovementType.DisableSpecializationEffects && objImprovement.UniqueName == s.Name && string.IsNullOrEmpty(objImprovement.Condition))) { name += $" ({node["spec"].InnerText})"; } if (node["val"] != null) { name += $" {node["val"].InnerText}"; } return(true); } } else { if (!string.IsNullOrEmpty(strNodeName)) { Skill s = character.SkillsSection.GetActiveSkill(strNodeName); // Exotic Skill if (s == null && node["spec"] != null) { s = character.SkillsSection.GetActiveSkill(strNodeName + " (" + node["spec"].InnerText + ")"); } if (s != null && (node["spec"] == null || s.Specializations.Any(objSpec => objSpec.Name == node["spec"]?.InnerText)) && s.TotalBaseRating >= Convert.ToInt32(node["val"]?.InnerText)) { name = s.DisplayName; if (node["spec"] != null && !character.Improvements.Any(objImprovement => objImprovement.ImproveType == Improvement.ImprovementType.DisableSpecializationEffects && objImprovement.UniqueName == s.Name && string.IsNullOrEmpty(objImprovement.Condition))) { name += $" ({node["spec"].InnerText})"; } if (node["val"] != null) { name += $" {node["val"].InnerText}"; } return(true); } } } XmlDocument xmlSkills = XmlManager.Load("skills.xml"); nameNode = xmlSkills.SelectSingleNode($"/chummer/skills/skill[name = \"{strNodeName}\"]"); name = nameNode?["translate"] != null ? "\n\t" + nameNode["translate"].InnerText : "\n\t" + strNodeName; if (node["spec"] != null) { name += $" ({node["spec"].InnerText})"; } if (node["val"] != null) { name += $" {node["val"].InnerText}"; } name += $" ({LanguageManager.GetString("Tab_Skills")})"; return(false); case "skillgrouptotal": { // Check if the total combined Ratings of Skill Groups adds up to a particular total. int intTotal = 0; var strGroups = node["skillgroups"].InnerText.Split('+'); string outString = "\n\t"; for (int i = 0; i <= strGroups.Length - 1; i++) { foreach (SkillGroup objGroup in character.SkillsSection.SkillGroups) { if (objGroup.Name == strGroups[i]) { outString += objGroup.DisplayName + ", "; intTotal += objGroup.Rating; break; } } } name = outString; name += $" ({LanguageManager.GetString("String_ExpenseSkillGroup")})"; return(intTotal >= Convert.ToInt32(node["val"].InnerText)); } case "spell": // Check for a specific Spell. XmlDocument xmlSpell = XmlManager.Load("spells.xml"); nameNode = xmlSpell.SelectSingleNode($"/chummer/spells/spell[name = \"{strNodeInnerText}\"]"); name = nameNode["translate"] != null ? "\n\t" + nameNode["translate"].InnerText : "\n\t" + strNodeInnerText; name += $" ({LanguageManager.GetString("String_DescSpell")})"; return(character.Spells.Any(spell => spell.Name == strNodeInnerText)); case "spellcategory": // Check for a specified amount of a particular Spell category. XmlDocument xmlSpells = XmlManager.Load("spells.xml"); nameNode = xmlSpells.SelectSingleNode($"/chummer/categories/category[. = \"{strNodeName}\"]"); name = nameNode["translate"] != null ? "\n\t" + nameNode["translate"].InnerText : "\n\t" + strNodeInnerText; name += $" ({LanguageManager.GetString("String_SpellCategory")})"; return(character.Spells.Count(objSpell => objSpell.Category == strNodeName) >= Convert.ToInt32(node["count"].InnerText)); case "spelldescriptor": // Check for a specified amount of a particular Spell Descriptor. name = "\n\t" + LanguageManager.GetString("Label_Descriptors") + " >= " + node["count"].InnerText; return(character.Spells.Count(objSpell => objSpell.Descriptors.Contains(strNodeName)) >= Convert.ToInt32(node["count"].InnerText)); case "streetcredvsnotoriety": // Street Cred must be higher than Notoriety. name = "\n\t" + LanguageManager.GetString("String_StreetCred") + " >= " + LanguageManager.GetString("String_Notoriety"); return(character.StreetCred >= character.Notoriety); case "tradition": // Character needs a specific Tradition. XmlDocument xmlTradition = XmlManager.Load("traditions.xml"); nameNode = xmlTradition.SelectSingleNode($"/chummer/traditions/tradition[name = \"{strNodeInnerText}\"]"); name = nameNode["translate"] != null ? "\n\t" + nameNode["translate"].InnerText : "\n\t" + strNodeInnerText; name += $" ({LanguageManager.GetString("String_Tradition")})"; return(character.MagicTradition == strNodeInnerText); default: Utils.BreakIfDebug(); break; } name = strNodeInnerText; return(false); }
public void Load(XmlNode xmlSavedCharacterNode) { Timekeeper.Start("load_char_attrib"); foreach (CharacterAttrib objAttribute in AttributeList.Concat(SpecialAttributeList)) { objAttribute.UnbindAttribute(); } AttributeList.Clear(); SpecialAttributeList.Clear(); XmlDocument objXmlDocument = XmlManager.Load(_objCharacter.IsCritter ? "critters.xml" : "metatypes.xml"); XmlNode xmlMetatypeNode = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + _objCharacter.Metatype + "\"]"); XmlNode xmlCharNode = xmlMetatypeNode?.SelectSingleNode("metavariants/metavariant[name = \"" + _objCharacter.Metavariant + "\"]") ?? xmlMetatypeNode; // We only want to remake attributes for shifters in career mode, because they only get their second set of attributes when exporting from create mode into career mode XmlNode xmlCharNodeAnimalForm = _objCharacter.MetatypeCategory == "Shapeshifter" && _objCharacter.Created ? xmlMetatypeNode : null; foreach (string strAttribute in AttributeStrings) { XmlNodeList lstAttributeNodes = xmlSavedCharacterNode.SelectNodes("attributes/attribute[name = \"" + strAttribute + "\"]"); // Couldn't find the appopriate attribute in the loaded file, so regenerate it from scratch. if (lstAttributeNodes == null || lstAttributeNodes.Count == 0) { CharacterAttrib objAttribute = new CharacterAttrib(_objCharacter, strAttribute); objAttribute = RemakeAttribute(objAttribute, xmlCharNode); switch (CharacterAttrib.ConvertToAttributeCategory(objAttribute.Abbrev)) { case CharacterAttrib.AttributeCategory.Special: SpecialAttributeList.Add(objAttribute); break; case CharacterAttrib.AttributeCategory.Standard: AttributeList.Add(objAttribute); break; } if (xmlCharNodeAnimalForm != null) { objAttribute = new CharacterAttrib(_objCharacter, strAttribute, CharacterAttrib.AttributeCategory.Shapeshifter); objAttribute = RemakeAttribute(objAttribute, xmlCharNodeAnimalForm); switch (CharacterAttrib.ConvertToAttributeCategory(objAttribute.Abbrev)) { case CharacterAttrib.AttributeCategory.Special: SpecialAttributeList.Add(objAttribute); break; case CharacterAttrib.AttributeCategory.Standard: AttributeList.Add(objAttribute); break; } } } else { foreach (XmlNode xmlAttributeNode in lstAttributeNodes) { CharacterAttrib att = new CharacterAttrib(_objCharacter, strAttribute); att.Load(xmlAttributeNode); switch (CharacterAttrib.ConvertToAttributeCategory(att.Abbrev)) { case CharacterAttrib.AttributeCategory.Special: SpecialAttributeList.Add(att); break; case CharacterAttrib.AttributeCategory.Standard: AttributeList.Add(att); break; } } } } ResetBindings(); Timekeeper.Finish("load_char_attrib"); }
public SkillControl2(Skill skill) { _skill = skill; InitializeComponent(); SuspendLayout(); DataBindings.Add("Enabled", skill, nameof(Skill.Enabled), false, DataSourceUpdateMode.OnPropertyChanged); //Display if (!skill.Default) { lblName.Font = new Font(lblName.Font, FontStyle.Italic); } if (!String.IsNullOrWhiteSpace(_skill.Notes)) { lblName.ForeColor = Color.SaddleBrown; } lblName.DataBindings.Add("Text", skill, nameof(Skill.DisplayName)); skill.PropertyChanged += Skill_PropertyChanged; _attributeActive = skill.AttributeObject; _attributeActive.PropertyChanged += AttributeActiveOnPropertyChanged; Skill_PropertyChanged(null, null); //if null it updates all _normal = btnAttribute.Font; _italic = new Font(_normal, FontStyle.Italic); if (skill.CharacterObject.Created) { lblModifiedRating.Location = new Point(256 - 13, 4); lblCareerRating.DataBindings.Add("Text", skill, nameof(Skill.Rating), false, DataSourceUpdateMode.OnPropertyChanged); lblCareerRating.Visible = true; btnCareerIncrease.Visible = true; btnCareerIncrease.DataBindings.Add("Enabled", skill, nameof(Skill.CanUpgradeCareer), false, DataSourceUpdateMode.OnPropertyChanged); nudSkill.Visible = false; nudKarma.Visible = false; chkKarma.Visible = false; cboSpec.Visible = false; lblCareerSpec.DataBindings.Add("Text", skill, nameof(skill.DisplaySpecialization), false, DataSourceUpdateMode.OnPropertyChanged); lblCareerSpec.Visible = true; lblAttribute.Visible = false; //Was true, cannot think it should be btnAttribute.DataBindings.Add("Text", skill, nameof(Skill.DisplayAttribute)); btnAttribute.Visible = true; SetupDropdown(); } else { lblAttribute.DataBindings.Add("Text", skill, nameof(Skill.DisplayAttribute)); //Up down boxes nudKarma.DataBindings.Add("Value", skill, nameof(Skill.Karma), false, DataSourceUpdateMode.OnPropertyChanged); nudSkill.DataBindings.Add("Value", skill, nameof(Skill.Base), false, DataSourceUpdateMode.OnPropertyChanged); nudSkill.DataBindings.Add("Enabled", skill, nameof(Skill.BaseUnlocked), false, DataSourceUpdateMode.OnPropertyChanged); nudKarma.DataBindings.Add("Enabled", skill, nameof(Skill.KarmaUnlocked), false, DataSourceUpdateMode.OnPropertyChanged); if (skill.CharacterObject.BuildMethod.HaveSkillPoints()) { chkKarma.DataBindings.Add("Checked", skill, nameof(Skill.BuyWithKarma), false, DataSourceUpdateMode.OnPropertyChanged); chkKarma.DataBindings.Add("Enabled", skill, nameof(Skill.CanHaveSpecs), false, DataSourceUpdateMode.OnPropertyChanged); } else { chkKarma.Visible = false; } cboSpec.BeginUpdate(); if (skill.IsExoticSkill) { cboSpec.Enabled = false; cboSpec.DataBindings.Add("Text", skill, nameof(Skill.DisplaySpecialization), false, DataSourceUpdateMode.OnPropertyChanged); } else { //dropdown/spec cboSpec.DisplayMember = nameof(ListItem.Name); cboSpec.ValueMember = nameof(ListItem.Value); cboSpec.DataBindings.Add("Enabled", skill, nameof(Skill.CanHaveSpecs), false, DataSourceUpdateMode.OnPropertyChanged); cboSpec.SelectedIndex = -1; cboSpec.DataSource = skill.CGLSpecializations; cboSpec.DataBindings.Add("Text", skill, nameof(Skill.Specialization), false, DataSourceUpdateMode.OnPropertyChanged); } cboSpec.EndUpdate(); } //Delete button if (skill.AllowDelete) { cmdDelete.Visible = true; cmdDelete.Click += (sender, args) => { skill.CharacterObject.SkillsSection.Skills.Remove(skill); }; if (skill.CharacterObject.Created) { btnAddSpec.Location = new Point(btnAddSpec.Location.X - cmdDelete.Width, btnAddSpec.Location.Y); } } ResumeLayout(); }
public void ResetBinding(CharacterAttrib attrib) { _dataSource.DataSource = attrib; }
public SkillControl2(Skill objSkill) { if (objSkill == null) { return; } _objSkill = objSkill; _objAttributeActive = objSkill.AttributeObject; InitializeComponent(); SkillControl2_DpiChangedAfterParent(null, EventArgs.Empty); this.UpdateLightDarkMode(); this.TranslateWinForm(); foreach (ToolStripItem tssItem in cmsSkillLabel.Items) { tssItem.UpdateLightDarkMode(); tssItem.TranslateToolStripItemsRecursively(); } SuspendLayout(); //Display _fntNormalName = lblName.Font; _fntItalicName = new Font(_fntNormalName, FontStyle.Italic); _fntNormal = btnAttribute.Font; _fntItalic = new Font(_fntNormal, FontStyle.Italic); if (!_objSkill.Default) { lblName.Font = _fntItalicName; } lblName.DoOneWayDataBinding("Text", objSkill, nameof(Skill.CurrentDisplayName)); lblName.DoOneWayDataBinding("ForeColor", objSkill, nameof(Skill.PreferredColor)); lblName.DoOneWayDataBinding("ToolTipText", objSkill, nameof(Skill.HtmlSkillToolTip)); btnAttribute.DoOneWayDataBinding("Text", objSkill, nameof(Skill.DisplayAttribute)); lblModifiedRating.Text = objSkill.DisplayOtherAttribute(_objAttributeActive.Abbrev); lblModifiedRating.ToolTipText = objSkill.CompileDicepoolTooltip(_objAttributeActive.Abbrev); // Creating controls outside of the designer saves on handles if the controls would be invisible anyway if (objSkill.AllowDelete) // For active skills, can only change by going from Create to Career mode, so no databinding necessary { cmdDelete = new Button { AutoSize = true, AutoSizeMode = AutoSizeMode.GrowAndShrink, Dock = DockStyle.Fill, Margin = new Padding(3, 0, 3, 0), Name = "cmdDelete", Tag = "String_Delete", Text = "Delete", UseVisualStyleBackColor = true }; cmdDelete.Click += cmdDelete_Click; cmdDelete.UpdateLightDarkMode(); cmdDelete.TranslateWinForm(); tlpRight.Controls.Add(cmdDelete, 4, 0); } int intMinimumSize; using (Graphics g = CreateGraphics()) intMinimumSize = (int)(25 * g.DpiX / 96.0f); if (objSkill.CharacterObject.Created) { lblCareerRating = new Label { Anchor = AnchorStyles.Right, AutoSize = true, MinimumSize = new Size(intMinimumSize, 0), Name = "lblCareerRating", Text = "00", TextAlign = ContentAlignment.MiddleRight }; btnCareerIncrease = new ButtonWithToolTip { Anchor = AnchorStyles.Right, AutoSize = true, AutoSizeMode = AutoSizeMode.GrowAndShrink, Image = Resources.add, Margin = new Padding(3, 0, 3, 0), Name = "btnCareerIncrease", Padding = new Padding(1), UseVisualStyleBackColor = true }; btnCareerIncrease.Click += btnCareerIncrease_Click; lblCareerRating.DoOneWayDataBinding("Text", objSkill, nameof(Skill.Rating)); btnCareerIncrease.DoOneWayDataBinding("Enabled", objSkill, nameof(Skill.CanUpgradeCareer)); btnCareerIncrease.DoOneWayDataBinding("ToolTipText", objSkill, nameof(Skill.UpgradeToolTip)); lblCareerRating.UpdateLightDarkMode(); lblCareerRating.TranslateWinForm(); btnCareerIncrease.UpdateLightDarkMode(); btnCareerIncrease.TranslateWinForm(); tlpMain.Controls.Add(lblCareerRating, 2, 0); tlpMain.Controls.Add(btnCareerIncrease, 3, 0); btnAddSpec = new ButtonWithToolTip { Anchor = AnchorStyles.Right, AutoSize = true, AutoSizeMode = AutoSizeMode.GrowAndShrink, Image = Resources.add, Margin = new Padding(3, 0, 3, 0), Name = "btnAddSpec", Padding = new Padding(1), UseVisualStyleBackColor = true }; btnAddSpec.Click += btnAddSpec_Click; lblCareerSpec = new Label { Anchor = AnchorStyles.Left, AutoSize = true, Name = "lblCareerSpec", Text = "[Specializations]", TextAlign = ContentAlignment.MiddleLeft }; lblCareerSpec.DoOneWayDataBinding("Text", objSkill, nameof(Skill.CurrentDisplaySpecialization)); btnAddSpec.DoOneWayDataBinding("Enabled", objSkill, nameof(Skill.CanAffordSpecialization)); btnAddSpec.DoOneWayDataBinding("Visible", objSkill, nameof(Skill.CanHaveSpecs)); btnAddSpec.DoOneWayDataBinding("ToolTipText", objSkill, nameof(Skill.AddSpecToolTip)); lblCareerSpec.UpdateLightDarkMode(); lblCareerSpec.TranslateWinForm(); btnAddSpec.UpdateLightDarkMode(); btnAddSpec.TranslateWinForm(); tlpRight.Controls.Add(lblCareerSpec, 0, 0); tlpRight.Controls.Add(btnAddSpec, 1, 0); List <ListItem> lstAttributeItems = new List <ListItem>(AttributeSection.AttributeStrings.Count); foreach (string strLoopAttribute in AttributeSection.AttributeStrings) { if (strLoopAttribute == "MAGAdept") { if (!objSkill.CharacterObject.Options.MysAdeptSecondMAGAttribute) { continue; } lstAttributeItems.Add(new ListItem(strLoopAttribute, LanguageManager.MAGAdeptString())); } else { string strAttributeShort = LanguageManager.GetString("String_Attribute" + strLoopAttribute + "Short", GlobalOptions.Language, false); lstAttributeItems.Add(new ListItem(strLoopAttribute, !string.IsNullOrEmpty(strAttributeShort) ? strAttributeShort : strLoopAttribute)); } } cboSelectAttribute = new ElasticComboBox { Anchor = AnchorStyles.Left | AnchorStyles.Right, DropDownStyle = ComboBoxStyle.DropDownList, FormattingEnabled = true, Margin = new Padding(3, 0, 3, 0), Name = "cboSelectAttribute" }; cboSelectAttribute.DropDownClosed += cboSelectAttribute_Closed; cboSelectAttribute.BeginUpdate(); cboSelectAttribute.DataSource = null; cboSelectAttribute.DataSource = lstAttributeItems; cboSelectAttribute.DisplayMember = nameof(ListItem.Name); cboSelectAttribute.ValueMember = nameof(ListItem.Value); cboSelectAttribute.SelectedValue = _objSkill.AttributeObject.Abbrev; cboSelectAttribute.EndUpdate(); cboSelectAttribute.UpdateLightDarkMode(); cboSelectAttribute.TranslateWinForm(); pnlAttributes.Controls.Add(cboSelectAttribute); } else { nudSkill = new NumericUpDownEx { Anchor = AnchorStyles.Right, AutoSize = true, InterceptMouseWheel = NumericUpDownEx.InterceptMouseWheelMode.WhenMouseOver, Margin = new Padding(3, 2, 3, 2), Maximum = new decimal(new[] { 99, 0, 0, 0 }), Name = "nudSkill" }; nudKarma = new NumericUpDownEx { Anchor = AnchorStyles.Right, AutoSize = true, InterceptMouseWheel = NumericUpDownEx.InterceptMouseWheelMode.WhenMouseOver, Margin = new Padding(3, 2, 3, 2), Maximum = new decimal(new[] { 99, 0, 0, 0 }), Name = "nudKarma" }; // Trick to make it seem like the button is a label (+ onclick method not doing anything in Create mode) btnAttribute.FlatAppearance.MouseDownBackColor = Color.Transparent; btnAttribute.FlatAppearance.MouseOverBackColor = Color.Transparent; nudSkill.DoOneWayDataBinding("Visible", objSkill.CharacterObject, nameof(objSkill.CharacterObject.EffectiveBuildMethodUsesPriorityTables)); nudSkill.DoDatabinding("Value", objSkill, nameof(Skill.Base)); nudSkill.DoOneWayDataBinding("Enabled", objSkill, nameof(Skill.BaseUnlocked)); nudSkill.InterceptMouseWheel = GlobalOptions.InterceptMode; nudKarma.DoDatabinding("Value", objSkill, nameof(Skill.Karma)); nudKarma.DoOneWayDataBinding("Enabled", objSkill, nameof(Skill.KarmaUnlocked)); nudKarma.InterceptMouseWheel = GlobalOptions.InterceptMode; nudSkill.UpdateLightDarkMode(); nudSkill.TranslateWinForm(); nudKarma.UpdateLightDarkMode(); nudKarma.TranslateWinForm(); tlpMain.Controls.Add(nudSkill, 2, 0); tlpMain.Controls.Add(nudKarma, 3, 0); if (objSkill.IsExoticSkill) { lblCareerSpec = new Label { Anchor = AnchorStyles.Left, AutoSize = true, Name = "lblCareerSpec", Text = "[Specializations]", TextAlign = ContentAlignment.MiddleLeft }; lblCareerSpec.DoOneWayDataBinding("Text", objSkill, nameof(Skill.CurrentDisplaySpecialization)); lblCareerSpec.UpdateLightDarkMode(); lblCareerSpec.TranslateWinForm(); tlpRight.Controls.Add(lblCareerSpec, 0, 0); } else { cboSpec = new ElasticComboBox { Anchor = AnchorStyles.Left | AnchorStyles.Right, AutoCompleteMode = AutoCompleteMode.Suggest, FormattingEnabled = true, Margin = new Padding(3, 0, 3, 0), Name = "cboSpec", Sorted = true, TabStop = false }; cboSpec.BeginUpdate(); cboSpec.DataSource = null; cboSpec.DataSource = objSkill.CGLSpecializations; cboSpec.DisplayMember = nameof(ListItem.Name); cboSpec.ValueMember = nameof(ListItem.Value); cboSpec.SelectedIndex = -1; cboSpec.DoDatabinding("Text", objSkill, nameof(Skill.Specialization)); cboSpec.DoOneWayDataBinding("Enabled", objSkill, nameof(Skill.CanHaveSpecs)); cboSpec.EndUpdate(); cboSpec.UpdateLightDarkMode(); cboSpec.TranslateWinForm(); chkKarma = new ColorableCheckBox(components) { Anchor = AnchorStyles.Left, AutoSize = true, DefaultColorScheme = true, Margin = new Padding(3, 0, 3, 0), Name = "chkKarma", UseVisualStyleBackColor = true }; chkKarma.DoOneWayDataBinding("Visible", objSkill.CharacterObject, nameof(objSkill.CharacterObject.EffectiveBuildMethodUsesPriorityTables)); chkKarma.DoDatabinding("Checked", objSkill, nameof(Skill.BuyWithKarma)); chkKarma.DoOneWayDataBinding("Enabled", objSkill, nameof(Skill.CanHaveSpecs)); chkKarma.UpdateLightDarkMode(); chkKarma.TranslateWinForm(); tlpRight.Controls.Add(cboSpec, 0, 0); tlpRight.Controls.Add(chkKarma, 1, 0); } } this.DoOneWayDataBinding("Enabled", objSkill, nameof(Skill.Enabled)); this.DoOneWayDataBinding("BackColor", objSkill, nameof(Skill.PreferredControlColor)); ResumeLayout(true); _blnLoading = false; _objSkill.PropertyChanged += Skill_PropertyChanged; }
public SkillControl2(Skill objSkill) { if (objSkill == null) { return; } _objSkill = objSkill; _objAttributeActive = objSkill.AttributeObject; InitializeComponent(); SuspendLayout(); this.TranslateWinForm(); foreach (ToolStripItem tssItem in cmsSkillLabel.Items) { tssItem.TranslateToolStripItemsRecursively(); } //Display _fntNormalName = lblName.Font; _fntItalicName = new Font(_fntNormalName, FontStyle.Italic); _fntNormal = btnAttribute.Font; _fntItalic = new Font(_fntNormal, FontStyle.Italic); if (!_objSkill.Default) { lblName.Font = _fntItalicName; } lblName.DoOneWayDataBinding("Text", objSkill, nameof(Skill.CurrentDisplayName)); lblName.DoOneWayDataBinding("ForeColor", objSkill, nameof(Skill.PreferredColor)); lblName.DoOneWayDataBinding("ToolTipText", objSkill, nameof(Skill.HtmlSkillToolTip)); btnAttribute.DoOneWayDataBinding("Text", objSkill, nameof(Skill.DisplayAttribute)); lblModifiedRating.Text = objSkill.DisplayOtherAttribute(_objAttributeActive.TotalValue, _objAttributeActive.Abbrev); lblModifiedRating.ToolTipText = objSkill.CompileDicepoolTooltip(_objAttributeActive.Abbrev); if (objSkill.AllowDelete) // For active skills, can only change by going from Create to Career mode, so no databinding necessary { cmdDelete.Visible = true; } if (objSkill.CharacterObject.Created) { flpButtonsCreate.Visible = false; tlpSpecsCreate.Visible = false; flpButtonsCareer.Dock = DockStyle.Fill; tlpSpecsCareer.Dock = DockStyle.Fill; lblCareerRating.DoOneWayDataBinding("Text", objSkill, nameof(Skill.Rating)); btnCareerIncrease.DoOneWayDataBinding("Enabled", objSkill, nameof(Skill.CanUpgradeCareer)); btnCareerIncrease.DoOneWayDataBinding("ToolTipText", objSkill, nameof(Skill.UpgradeToolTip)); lblCareerSpec.DoOneWayDataBinding("Text", objSkill, nameof(Skill.CurrentDisplaySpecialization)); btnAddSpec.DoOneWayDataBinding("Enabled", objSkill, nameof(Skill.CanAffordSpecialization)); btnAddSpec.DoOneWayDataBinding("Visible", objSkill, nameof(Skill.CanHaveSpecs)); btnAddSpec.DoOneWayDataBinding("ToolTipText", objSkill, nameof(Skill.AddSpecToolTip)); List <ListItem> lstAttributeItems = new List <ListItem>(AttributeSection.AttributeStrings.Count); foreach (string strLoopAttribute in AttributeSection.AttributeStrings) { string strAttributeShort = LanguageManager.GetString("String_Attribute" + strLoopAttribute + "Short", GlobalOptions.Language, false); lstAttributeItems.Add(new ListItem(strLoopAttribute, !string.IsNullOrEmpty(strAttributeShort) ? strAttributeShort : strLoopAttribute)); } cboSelectAttribute.BeginUpdate(); cboSelectAttribute.DataSource = null; cboSelectAttribute.DisplayMember = nameof(ListItem.Name); cboSelectAttribute.ValueMember = nameof(ListItem.Value); cboSelectAttribute.DataSource = lstAttributeItems; cboSelectAttribute.SelectedValue = _objSkill.AttributeObject.Abbrev; cboSelectAttribute.EndUpdate(); } else { flpButtonsCareer.Visible = false; flpButtonsCreate.Dock = DockStyle.Fill; // Trick to make it seem like the button is a label (+ onclick method not doing anything in Create mode) btnAttribute.FlatAppearance.MouseDownBackColor = btnAttribute.BackColor; btnAttribute.FlatAppearance.MouseOverBackColor = btnAttribute.BackColor; nudSkill.DoOneWayDataBinding("Visible", objSkill.CharacterObject, nameof(objSkill.CharacterObject.BuildMethodHasSkillPoints)); nudSkill.DoDatabinding("Value", objSkill, nameof(Skill.Base)); nudSkill.DoOneWayDataBinding("Enabled", objSkill, nameof(Skill.BaseUnlocked)); nudSkill.DoOneWayDataBinding("InterceptMouseWheel", objSkill.CharacterObject.Options, nameof(CharacterOptions.InterceptMode)); nudKarma.DoDatabinding("Value", objSkill, nameof(Skill.Karma)); nudKarma.DoOneWayDataBinding("Enabled", objSkill, nameof(Skill.KarmaUnlocked)); nudKarma.DoOneWayDataBinding("InterceptMouseWheel", objSkill.CharacterObject.Options, nameof(CharacterOptions.InterceptMode)); if (objSkill.IsExoticSkill) { tlpSpecsCreate.Visible = false; tlpSpecsCareer.Dock = DockStyle.Fill; btnAddSpec.Visible = false; lblCareerSpec.DoOneWayDataBinding("Text", objSkill, nameof(Skill.CurrentDisplaySpecialization)); } else { tlpSpecsCareer.Visible = false; tlpSpecsCreate.Dock = DockStyle.Fill; cboSpec.BeginUpdate(); cboSpec.DataSource = null; cboSpec.DisplayMember = nameof(ListItem.Name); cboSpec.ValueMember = nameof(ListItem.Value); cboSpec.DataSource = objSkill.CGLSpecializations; cboSpec.SelectedIndex = -1; cboSpec.DoDatabinding("Text", objSkill, nameof(Skill.Specialization)); cboSpec.DoOneWayDataBinding("Enabled", objSkill, nameof(Skill.CanHaveSpecs)); cboSpec.EndUpdate(); } chkKarma.DoOneWayDataBinding("Visible", objSkill.CharacterObject, nameof(objSkill.CharacterObject.BuildMethodHasSkillPoints)); chkKarma.DoDatabinding("Checked", objSkill, nameof(Skill.BuyWithKarma)); chkKarma.DoOneWayDataBinding("Enabled", objSkill, nameof(Skill.CanHaveSpecs)); } this.DoOneWayDataBinding("Enabled", objSkill, nameof(Skill.Enabled)); this.DoOneWayDataBinding("BackColor", objSkill, nameof(Skill.PreferredControlColor)); ResumeLayout(true); _blnLoading = false; _objSkill.PropertyChanged += Skill_PropertyChanged; }
public SkillControl2(Skill skill) { this._skill = skill; InitializeComponent(); DataBindings.Add("Enabled", skill, nameof(Skill.Enabled), false, DataSourceUpdateMode.OnPropertyChanged); //Display if (!skill.Default) { lblName.Font = new Font(lblName.Font, FontStyle.Italic); } if (!String.IsNullOrWhiteSpace(_skill.Notes)) { lblName.ForeColor = Color.SaddleBrown; } lblName.DataBindings.Add("Text", skill, nameof(Skill.DisplayName)); skill.PropertyChanged += Skill_PropertyChanged; _attributeActive = skill.AttributeObject; _attributeActive.PropertyChanged += AttributeActiveOnPropertyChanged; Skill_PropertyChanged(null, null); //if null it updates all _normal = btnAttribute.Font; _italic = new Font(_normal, FontStyle.Italic); if (skill.CharacterObject.Created) { lblModifiedRating.Location = new Point(256 - 13, 4); lblCareerRating.DataBindings.Add("Text", skill, nameof(Skill.Rating), false, DataSourceUpdateMode.OnPropertyChanged); lblCareerRating.Visible = true; btnCareerIncrease.Visible = true; btnCareerIncrease.DataBindings.Add("Enabled", skill, nameof(Skill.CanUpgradeCareer), false, DataSourceUpdateMode.OnPropertyChanged); nudSkill.Visible = false; nudKarma.Visible = false; chkKarma.Visible = false; cboSpec.Visible = false; lblCareerSpec.DataBindings.Add("Text", skill, nameof(skill.DisplaySpecialization), false, DataSourceUpdateMode.OnPropertyChanged); lblCareerSpec.Visible = true; lblAttribute.Visible = false; //Was true, cannot think it should be btnAttribute.DataBindings.Add("Text", skill, nameof(Skill.DisplayAttribute)); btnAttribute.Visible = true; SetupDropdown(); } else { lblAttribute.DataBindings.Add("Text", skill, nameof(Skill.DisplayAttribute)); //Up down boxes nudKarma.DataBindings.Add("Value", skill, nameof(Skill.Karma), false, DataSourceUpdateMode.OnPropertyChanged); nudSkill.DataBindings.Add("Value", skill, nameof(Skill.Base), false, DataSourceUpdateMode.OnPropertyChanged); nudSkill.DataBindings.Add("Enabled", skill, nameof(Skill.BaseUnlocked), false, DataSourceUpdateMode.OnPropertyChanged); nudKarma.DataBindings.Add("Enabled", skill, nameof(Skill.KarmaUnlocked), false, DataSourceUpdateMode.OnPropertyChanged); if (skill.CharacterObject.BuildMethod.HaveSkillPoints()) { chkKarma.DataBindings.Add("Checked", skill, nameof(Skill.BuyWithKarma), false, DataSourceUpdateMode.OnPropertyChanged); chkKarma.DataBindings.Add("Enabled", skill, nameof(Skill.CanHaveSpecs), false, DataSourceUpdateMode.OnPropertyChanged); } else { chkKarma.Visible = false; } if (skill.IsExoticSkill) { cboSpec.Enabled = false; cboSpec.DataBindings.Add("Text", skill, nameof(Skill.DisplaySpecialization), false, DataSourceUpdateMode.OnPropertyChanged); } else { //dropdown/spec cboSpec.DataSource = skill.CGLSpecializations; cboSpec.DisplayMember = nameof(ListItem.Name); cboSpec.ValueMember = nameof(ListItem.Value); cboSpec.DataBindings.Add("Enabled", skill, nameof(Skill.CanHaveSpecs), false, DataSourceUpdateMode.OnPropertyChanged); cboSpec.SelectedIndex = -1; cboSpec.DataBindings.Add("Text", skill, nameof(Skill.Specialization), false, DataSourceUpdateMode.OnPropertyChanged); } } //Delete button if (skill.AllowDelete) { cmdDelete.Visible = true; cmdDelete.Click += (sender, args) => { skill.CharacterObject.SkillsSection.Skills.Remove(skill); }; if (skill.CharacterObject.Created) { btnAddSpec.Location = new Point(btnAddSpec.Location.X - cmdDelete.Width, btnAddSpec.Location.Y); } } }
private void cboSelectAttribute_Closed(object sender, EventArgs e) { btnAttribute.Visible = true; cboSelectAttribute.Visible = false; _attributeActive.PropertyChanged -= AttributeActiveOnPropertyChanged; _attributeActive = _skill.CharacterObject.GetAttribute((string) cboSelectAttribute.SelectedValue); btnAttribute.Font = _attributeActive == _skill.AttributeObject ? _normal : _italic; btnAttribute.Text = cboSelectAttribute.Text; _attributeActive.PropertyChanged += AttributeActiveOnPropertyChanged; AttributeActiveOnPropertyChanged(null, null); CustomAttributeChanged?.Invoke(this, EventArgs.Empty); }
public SkillControl2(Skill skill) { _skill = skill; InitializeComponent(); SuspendLayout(); foreach (ToolStripItem objItem in cmsSkillLabel.Items) { LanguageManager.TranslateToolStripItemsRecursively(objItem, GlobalOptions.Language); } Utils.DoDatabinding(this, "Enabled", skill, nameof(Skill.Enabled)); //Display _normalName = lblName.Font; _italicName = new Font(lblName.Font, FontStyle.Italic); Utils.DoDatabinding(this, "BackColor", skill, nameof(Skill.PreferredControlColor)); Utils.DoDatabinding(lblName, "Text", skill, nameof(Skill.DisplayName)); Utils.DoDatabinding(lblName, "ForeColor", skill, nameof(Skill.PreferredColor)); Utils.DoDatabinding(lblName, "ToolTipText", skill, nameof(Skill.SkillToolTip)); Utils.DoDatabinding(lblModifiedRating, "ToolTipText", skill, nameof(Skill.PoolToolTip)); _attributeActive = skill.AttributeObject; _skill.PropertyChanged += Skill_PropertyChanged; _skill.CharacterObject.AttributeSection.PropertyChanged += AttributeSection_PropertyChanged; Skill_PropertyChanged(null, null); //if null it updates all nudSkill.Visible = !skill.CharacterObject.Created && skill.CharacterObject.BuildMethodHasSkillPoints; nudKarma.Visible = !skill.CharacterObject.Created; chkKarma.Visible = !skill.CharacterObject.Created; cboSpec.Visible = !skill.CharacterObject.Created; cboSelectAttribute.Visible = false; btnCareerIncrease.Visible = skill.CharacterObject.Created; lblCareerSpec.Visible = skill.CharacterObject.Created; btnAddSpec.Visible = skill.CharacterObject.Created; lblAttribute.Visible = skill.CharacterObject.Created; btnAttribute.Visible = skill.CharacterObject.Created; lblCareerRating.Visible = skill.CharacterObject.Created; _normal = btnAttribute.Font; _italic = new Font(_normal, FontStyle.Italic); if (skill.CharacterObject.Created) { lblModifiedRating.Location = new Point(256 - 13, 4); lblCareerRating.DataBindings.Add("Text", skill, nameof(Skill.Rating), false, DataSourceUpdateMode.OnPropertyChanged); btnCareerIncrease.DataBindings.Add("Enabled", skill, nameof(Skill.CanUpgradeCareer), false, DataSourceUpdateMode.OnPropertyChanged); btnCareerIncrease.DataBindings.Add("ToolTipText", skill, nameof(Skill.UpgradeToolTip), false, DataSourceUpdateMode.OnPropertyChanged); btnAddSpec.DataBindings.Add("Enabled", skill, nameof(Skill.CanAffordSpecialization), false, DataSourceUpdateMode.OnPropertyChanged); btnAddSpec.DataBindings.Add("Visible", skill, nameof(Skill.CanHaveSpecs), false, DataSourceUpdateMode.OnPropertyChanged); btnAddSpec.DataBindings.Add("ToolTipText", skill, nameof(Skill.AddSpecToolTip), false, DataSourceUpdateMode.OnPropertyChanged); lblCareerSpec.DataBindings.Add("Text", skill, nameof(Skill.DisplaySpecialization), false, DataSourceUpdateMode.OnPropertyChanged); lblAttribute.Visible = false; //Was true, cannot think it should be btnAttribute.DataBindings.Add("Text", skill, nameof(Skill.DisplayAttribute)); btnAttribute.Visible = true; SetupDropdown(); } else { lblAttribute.DataBindings.Add("Text", skill, nameof(Skill.DisplayAttribute)); //Up down boxes nudKarma.DataBindings.Add("Value", skill, nameof(Skill.Karma), false, DataSourceUpdateMode.OnPropertyChanged); nudSkill.DataBindings.Add("Value", skill, nameof(Skill.Base), false, DataSourceUpdateMode.OnPropertyChanged); nudSkill.DataBindings.Add("Visible", skill.CharacterObject, nameof(skill.CharacterObject.BuildMethodHasSkillPoints), false, DataSourceUpdateMode.OnPropertyChanged); nudSkill.DataBindings.Add("Enabled", skill, nameof(Skill.BaseUnlocked), false, DataSourceUpdateMode.OnPropertyChanged); nudSkill.DataBindings.Add("InterceptMouseWheel", skill.CharacterObject.Options, nameof(CharacterOptions.InterceptMode), false, DataSourceUpdateMode.OnPropertyChanged); nudKarma.DataBindings.Add("Enabled", skill, nameof(Skill.KarmaUnlocked), false, DataSourceUpdateMode.OnPropertyChanged); nudKarma.DataBindings.Add("InterceptMouseWheel", skill.CharacterObject.Options, nameof(CharacterOptions.InterceptMode), false, DataSourceUpdateMode.OnPropertyChanged); chkKarma.DataBindings.Add("Visible", skill.CharacterObject, nameof(skill.CharacterObject.BuildMethodHasSkillPoints), false, DataSourceUpdateMode.OnPropertyChanged); chkKarma.DataBindings.Add("Checked", skill, nameof(Skill.BuyWithKarma), false, DataSourceUpdateMode.OnPropertyChanged); chkKarma.DataBindings.Add("Enabled", skill, nameof(Skill.CanHaveSpecs), false, DataSourceUpdateMode.OnPropertyChanged); cboSpec.BeginUpdate(); if (skill.IsExoticSkill) { cboSpec.Enabled = false; cboSpec.DataBindings.Add("Text", skill, nameof(Skill.DisplaySpecialization), false, DataSourceUpdateMode.OnPropertyChanged); } else { //dropdown/spec cboSpec.DisplayMember = nameof(ListItem.Name); cboSpec.ValueMember = nameof(ListItem.Value); cboSpec.DataBindings.Add("Enabled", skill, nameof(Skill.CanHaveSpecs), false, DataSourceUpdateMode.OnPropertyChanged); cboSpec.SelectedIndex = -1; cboSpec.DataSource = skill.CGLSpecializations; cboSpec.DataBindings.Add("Text", skill, nameof(Skill.Specialization), false, DataSourceUpdateMode.OnPropertyChanged); } cboSpec.EndUpdate(); } //Delete button cmdDelete.Visible = skill.AllowDelete; if (skill.AllowDelete) { cmdDelete.Click += (sender, args) => { skill.UnbindSkill(); skill.CharacterObject.SkillsSection.Skills.Remove(skill); skill.CharacterObject.SkillsSection.SkillsDictionary.Remove(skill.IsExoticSkill ? skill.Name + " (" + skill.DisplaySpecializationMethod(GlobalOptions.Language) + ')' : skill.Name); }; if (skill.CharacterObject.Created) { btnAddSpec.Location = new Point(btnAddSpec.Location.X - cmdDelete.Width, btnAddSpec.Location.Y); } } ResumeLayout(); }
//TODO: Might be a better location for this; Class names are screwy. /// <summary> /// Evaluates requirements of a given node against a given Character object. /// </summary> /// <param name="objXmlNode">XmlNode of the object.</param> /// <param name="blnShowMessage">Should warning messages about whether the object has failed to validate be shown?</param> /// <param name="objCharacter">Character Object.</param> /// <param name="objQualityDocument"></param> /// <param name="strIgnoreQuality"> /// Name of a Quality that should be ignored. Typically used when swapping Qualities in /// career mode. /// </param> /// <param name="strLocalName"></param> /// <param name="objMetatypeDocument"></param> /// <param name="objCritterDocument"></param> /// <param name="strSourceName">Name of the improvement that called this (if it was called by an improvement adding it)</param> /// <returns></returns> public static bool RequirementsMet(XmlNode objXmlNode, bool blnShowMessage, Character objCharacter, XmlDocument objMetatypeDocument = null, XmlDocument objCritterDocument = null, XmlDocument objQualityDocument = null, string strIgnoreQuality = "", string strLocalName = "", string strSourceName = "", string strLocation = "") { // Ignore the rules. if (objCharacter.IgnoreRules) { return(true); } if (objXmlNode == null) { return(false); } if (objMetatypeDocument == null) { objMetatypeDocument = XmlManager.Load("metatypes.xml"); } if (objCritterDocument == null) { objCritterDocument = XmlManager.Load("critters.xml"); } if (objQualityDocument == null) { objQualityDocument = XmlManager.Load("qualities.xml"); } // See if the character is in career mode but would want to add a chargen-only Quality if (objCharacter.Created) { if (objXmlNode["chargenonly"] != null && objXmlNode["chargenonly"]?.InnerText != "no") { if (blnShowMessage) { MessageBox.Show(LanguageManager.GetString("Message_SelectGeneric_ChargenRestriction").Replace("{0}", strLocalName), LanguageManager.GetString("MessageTitle_SelectGeneric_Restriction").Replace("{0}", strLocalName), MessageBoxButtons.OK, MessageBoxIcon.Information); } return(false); } } // See if the character is using priority-based gen and is trying to add a Quality that can only be added through priorities else if ((objCharacter.BuildMethod == CharacterBuildMethod.Priority || objCharacter.BuildMethod == CharacterBuildMethod.SumtoTen) && objXmlNode["onlyprioritygiven"] != null && objXmlNode["onlyprioritygiven"]?.InnerText != "no") { if (blnShowMessage) { MessageBox.Show(LanguageManager.GetString("MessageTitle_SelectGeneric_PriorityRestriction").Replace("{0}", strLocalName), LanguageManager.GetString("MessageTitle_SelectGeneric_Restriction").Replace("{0}", strLocalName), MessageBoxButtons.OK, MessageBoxIcon.Information); } return(false); } // See if the character already has this Quality and whether or not multiple copies are allowed. string strLimitString = string.Empty; // If the limit at chargen is different from the actual limit, we need to make sure we fetch the former if the character is in Create mode string strChargenLimitString = objXmlNode["chargenlimit"]?.InnerText; if (!string.IsNullOrWhiteSpace(strChargenLimitString) && !objCharacter.Created) { strLimitString = strChargenLimitString; } else { strLimitString = objXmlNode["limit"]?.InnerText; // Default case is each quality can only be taken once if (string.IsNullOrWhiteSpace(strLimitString)) { if (objXmlNode.Name == "quality" || objXmlNode.Name == "cyberware" || objXmlNode.Name == "bioware") { strLimitString = "1"; } else { strLimitString = "no"; } } } if (strLimitString != "no") { XmlDocument objDummyDoc = new XmlDocument(); XPathNavigator objNavigator = objDummyDoc.CreateNavigator(); foreach (string strAttribute in AttributeSection.AttributeStrings) { CharacterAttrib objLoopAttribute = objCharacter.GetAttribute(strAttribute); strLimitString = strLimitString.Replace("{" + strAttribute + "}", objLoopAttribute.TotalValue.ToString()); strLimitString = strLimitString.Replace("{" + strAttribute + "Base}", objLoopAttribute.TotalBase.ToString()); } foreach (string strLimb in Character.LimbStrings) { int objLoopLimbCount = objCharacter.LimbCount(strLimb); if (!string.IsNullOrEmpty(strLocation)) { objLoopLimbCount /= 2; } strLimitString = strLimitString.Replace("{" + strLimb + "}", objLoopLimbCount.ToString()); } try { XPathExpression objExpression = objNavigator.Compile(strLimitString); strLimitString = objNavigator.Evaluate(objExpression).ToString(); } catch (XPathException) { strLimitString = "1"; } string limitTitle = LanguageManager.GetString("MessageTitle_SelectGeneric_Limit").Replace("{0}", strLocalName); string limitMessage = LanguageManager.GetString("Message_SelectGeneric_Limit").Replace("{0}", strLocalName); List <string> lstNamesIncludedInLimit = new List <string>(); if (objXmlNode["name"] != null) { lstNamesIncludedInLimit.Add(objXmlNode["name"].InnerText); } // We could set this to a list immediately, but I'd rather the pointer start at null so that no list ends up getting selected for the "default" case below IEnumerable <INamedItem> objListToCheck = null; bool blnCheckCyberwareChildren = false; switch (objXmlNode.Name) { case "quality": { objListToCheck = objCharacter.Qualities.Where(objQuality => objQuality.SourceName == strSourceName); break; } case "metamagic": { objListToCheck = objCharacter.Metamagics; break; } case "art": { objListToCheck = objCharacter.Arts; break; } case "enhancement": { objListToCheck = objCharacter.Enhancements; break; } case "power": { objListToCheck = objCharacter.Powers; break; } case "critterpower": { objListToCheck = objCharacter.CritterPowers; break; } case "cyberware": case "bioware": { blnCheckCyberwareChildren = true; break; } default: { Utils.BreakIfDebug(); break; } } int intLimit = Convert.ToInt32(strLimitString); int intExtendedLimit = intLimit; if (objXmlNode["limitwithinclusions"] != null) { intExtendedLimit = Convert.ToInt32(objXmlNode["limitwithinclusions"].InnerText); } int intCount = 0; int intExtendedCount = 0; if (objListToCheck != null || blnCheckCyberwareChildren) { if (blnCheckCyberwareChildren) { if (string.IsNullOrEmpty(strLocation)) { intCount = objCharacter.Cyberware.DeepCount(x => x.Children, x => x.Name != strIgnoreQuality && string.IsNullOrEmpty(x.PlugsIntoModularMount) && lstNamesIncludedInLimit.Any(strName => strName == x.Name)); } // We only want to check against 'ware that is on the same side as this one else { intCount = objCharacter.Cyberware.DeepCount(x => x.Children, x => x.Name != strIgnoreQuality && string.IsNullOrEmpty(x.PlugsIntoModularMount) && x.Location == strLocation && lstNamesIncludedInLimit.Any(strName => strName == x.Name)); } } else { intCount = objListToCheck.Count(objItem => objItem.Name != strIgnoreQuality && lstNamesIncludedInLimit.Any(objLimitName => objLimitName == objItem.Name)); } intExtendedCount = intCount; // In case one item is split up into multiple entries with different names, e.g. Indomitable quality, we need to be able to check all those entries against the limit if (objXmlNode["includeinlimit"] != null) { foreach (XmlNode objChildXml in objXmlNode["includeinlimit"].ChildNodes) { lstNamesIncludedInLimit.Add(objChildXml.InnerText); } if (blnCheckCyberwareChildren) { if (string.IsNullOrEmpty(strLocation)) { intExtendedCount = objCharacter.Cyberware.DeepCount(x => x.Children, objItem => objItem.Name != strIgnoreQuality && string.IsNullOrEmpty(objItem.PlugsIntoModularMount) && lstNamesIncludedInLimit.Any(objLimitName => objLimitName == objItem.Name)); } // We only want to check against 'ware that is on the same side as this one else { intExtendedCount = objCharacter.Cyberware.DeepCount(x => x.Children, x => x.Name != strIgnoreQuality && string.IsNullOrEmpty(x.PlugsIntoModularMount) && x.Location == strLocation && lstNamesIncludedInLimit.Any(strName => strName == x.Name)); } } else { intExtendedCount = objListToCheck.Count(objItem => objItem.Name != strIgnoreQuality && lstNamesIncludedInLimit.Any(objLimitName => objLimitName == objItem.Name)); } } } if (intCount >= intLimit || intExtendedCount >= intExtendedLimit) { if (blnShowMessage) { limitMessage = limitMessage.Replace("{1}", intLimit == 0 ? "1" : intLimit.ToString()); MessageBox.Show(limitMessage, limitTitle, MessageBoxButtons.OK, MessageBoxIcon.Information); } return(false); } } if (objXmlNode.InnerXml.Contains("forbidden")) { string forbiddenTitle = LanguageManager.GetString("MessageTitle_SelectGeneric_Restriction").Replace("{0}", strLocalName); string forbiddenMessage = LanguageManager.GetString("Message_SelectGeneric_Restriction").Replace("{0}", strLocalName); // Loop through the oneof requirements. XmlNodeList objXmlForbiddenList = objXmlNode.SelectNodes("forbidden/oneof"); if (objXmlForbiddenList != null) { foreach (XmlNode objXmlOneOf in objXmlForbiddenList) { XmlNodeList objXmlOneOfList = objXmlOneOf.ChildNodes; foreach (XmlNode objXmlForbidden in objXmlOneOfList) { // The character is not allowed to take the Quality, so display a message and uncheck the item. if (TestNodeRequirements(objXmlForbidden, objCharacter, out string name, strIgnoreQuality, objMetatypeDocument, objCritterDocument, objQualityDocument)) { if (blnShowMessage) { MessageBox.Show( forbiddenMessage + name, forbiddenTitle, MessageBoxButtons.OK, MessageBoxIcon.Information); } return(false); } } } } } if (objXmlNode.InnerXml.Contains("required")) { string requiredTitle = LanguageManager.GetString("MessageTitle_SelectGeneric_Requirement").Replace("{0}", strLocalName); string requiredMessage = LanguageManager.GetString("Message_SelectGeneric_Requirement").Replace("{0}", strLocalName); string strRequirement = string.Empty; bool blnRequirementMet = true; // Loop through the oneof requirements. XmlNodeList objXmlRequiredList = objXmlNode.SelectNodes("required/oneof"); foreach (XmlNode objXmlOneOf in objXmlRequiredList) { bool blnOneOfMet = false; string strThisRequirement = "\n" + LanguageManager.GetString("Message_SelectQuality_OneOf"); XmlNodeList objXmlOneOfList = objXmlOneOf.ChildNodes; foreach (XmlNode objXmlRequired in objXmlOneOfList) { blnOneOfMet = TestNodeRequirements(objXmlRequired, objCharacter, out string name, strIgnoreQuality, objMetatypeDocument, objCritterDocument, objQualityDocument); if (blnOneOfMet) { break; } strThisRequirement += name; } // Update the flag for requirements met. blnRequirementMet = blnRequirementMet && blnOneOfMet; strRequirement += strThisRequirement; } if (blnRequirementMet || blnShowMessage) { // Loop through the allof requirements. objXmlRequiredList = objXmlNode.SelectNodes("required/allof"); foreach (XmlNode objXmlAllOf in objXmlRequiredList) { bool blnAllOfMet = true; string strThisRequirement = "\n" + LanguageManager.GetString("Message_SelectQuality_AllOf"); XmlNodeList objXmlAllOfList = objXmlAllOf.ChildNodes; foreach (XmlNode objXmlRequired in objXmlAllOfList) { bool blnFound = TestNodeRequirements(objXmlRequired, objCharacter, out string name, strIgnoreQuality, objMetatypeDocument, objCritterDocument, objQualityDocument); // If this item was not found, fail the AllOfMet condition. if (!blnFound) { blnAllOfMet = false; if (blnShowMessage) { strThisRequirement += name; } else { break; } } } // Update the flag for requirements met. blnRequirementMet = blnRequirementMet && blnAllOfMet; strRequirement += strThisRequirement; } } // The character has not met the requirements, so display a message and uncheck the item. if (!blnRequirementMet) { requiredMessage += strRequirement; if (blnShowMessage) { MessageBox.Show(requiredMessage, requiredTitle, MessageBoxButtons.OK, MessageBoxIcon.Information); } return(false); } } return(true); }
public void addCharacter(CharacterAttrib obj) { characters.Add(obj); }
public void Load(XmlDocument xmlDoc) { Timekeeper.Start("load_char_attrib"); AttributeList.Clear(); SpecialAttributeList.Clear(); XmlDocument objXmlDocument = XmlManager.Load(_character.IsCritter ? "critters.xml" : "metatypes.xml"); XmlNode objCharNode = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + _character.Metatype + "\"]/metavariants/metavariant[name = \"" + _character.Metavariant + "\"]") ?? objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + _character.Metatype + "\"]"); XmlNode objCharNodeAnimalForm = null; // We only want to remake attributes for shifters in career mode, because they only get their second set of attributes when exporting from create mode into career mode if (_character.MetatypeCategory == "Shapeshifter" && _character.Created) { objCharNodeAnimalForm = objXmlDocument.SelectSingleNode("/chummer/metatypes/metatype[name = \"" + _character.Metatype + "\"]"); } foreach (string s in AttributeStrings) { XmlNodeList attNodeList = xmlDoc.SelectNodes("/character/attributes/attribute[name = \"" + s + "\"]"); // Couldn't find the appopriate attribute in the loaded file, so regenerate it from scratch. if (attNodeList.Count == 0) { CharacterAttrib att = new CharacterAttrib(_character, s); att = RemakeAttribute(att, objCharNode); switch (att.ConvertToAttributeCategory(att.Abbrev)) { case CharacterAttrib.AttributeCategory.Special: SpecialAttributeList.Add(att); break; case CharacterAttrib.AttributeCategory.Standard: AttributeList.Add(att); break; } if (objCharNodeAnimalForm != null) { att = new CharacterAttrib(_character, s, CharacterAttrib.AttributeCategory.Shapeshifter); att = RemakeAttribute(att, objCharNodeAnimalForm); switch (att.ConvertToAttributeCategory(att.Abbrev)) { case CharacterAttrib.AttributeCategory.Special: SpecialAttributeList.Add(att); break; case CharacterAttrib.AttributeCategory.Standard: AttributeList.Add(att); break; } } } else { foreach (XmlNode attNode in attNodeList) { CharacterAttrib att = new CharacterAttrib(_character, s); att.Load(attNode); switch (att.ConvertToAttributeCategory(att.Abbrev)) { case CharacterAttrib.AttributeCategory.Special: SpecialAttributeList.Add(att); break; case CharacterAttrib.AttributeCategory.Standard: AttributeList.Add(att); break; } } } } ResetBindings(); Timekeeper.Finish("load_char_attrib"); }