/// Create an Initiation Grade from an XmlNode. /// <param name="intGrade">Grade number.</param> /// <param name="blnTechnomancer">Whether or not the character is a Technomancer.</param> /// <param name="blnGroup">Whether or not a Group was used.</param> /// <param name="blnOrdeal">Whether or not an Ordeal was used.</param> /// <param name="blnSchooling">Whether or not Schooling was used.</param> public void Create(int intGrade, bool blnTechnomancer, bool blnGroup, bool blnOrdeal, bool blnSchooling) { _intGrade = intGrade; _blnTechnomancer = blnTechnomancer; _blnGroup = blnGroup; _blnOrdeal = blnOrdeal; _blnSchooling = blnSchooling; //TODO: I'm not happy with this. //KC 90: a Cyberadept who has Submerged may restore Resonance that has been lost to cyberware (and only cyberware) by an amount equal to half their Submersion Grade(rounded up). //To handle this, we ceiling the CyberwareEssence value up, as a non-zero loss of Essence removes a point of Resonance, and cut the submersion grade in half. //Whichever value is lower becomes the value of the improvement. if (intGrade > 0 && blnTechnomancer && _objCharacter.RESEnabled && !_objCharacter.Settings.SpecialKarmaCostBasedOnShownValue && ImprovementManager.GetCachedImprovementListForValueOf(_objCharacter, Improvement.ImprovementType.CyberadeptDaemon).Count > 0) { decimal decNonCyberwareEssence = _objCharacter.BiowareEssence + _objCharacter.EssenceHole; int intResonanceRecovered = Math.Min(intGrade.DivAwayFromZero(2), (int)( Math.Ceiling(decNonCyberwareEssence) == Math.Floor(decNonCyberwareEssence) ? Math.Ceiling(_objCharacter.CyberwareEssence) : Math.Floor(_objCharacter.CyberwareEssence))); // Cannot increase RES to be more than what it would be without any Essence loss. intResonanceRecovered = _objCharacter.Settings.ESSLossReducesMaximumOnly ? Math.Min(intResonanceRecovered, _objCharacter.RES.MaximumNoEssenceLoss() - intGrade - _objCharacter.RES.TotalMaximum) // +1 compared to normal because this Grade's effect has not been processed yet. : Math.Min(intResonanceRecovered, _objCharacter.RES.MaximumNoEssenceLoss() - intGrade + 1 - _objCharacter.RES.Value); ImprovementManager.CreateImprovement(_objCharacter, "RESBase", Improvement.ImprovementSource.CyberadeptDaemon, InternalId, Improvement.ImprovementType.Attribute, string.Empty, 0, intResonanceRecovered, 0, 1, 1); ImprovementManager.Commit(_objCharacter); } }
public SelectVehicle(Character objCharacter) { if (objCharacter == null) { throw new ArgumentNullException(nameof(objCharacter)); } InitializeComponent(); this.UpdateLightDarkMode(); this.TranslateWinForm(); lblMarkupLabel.Visible = objCharacter.Created; nudMarkup.Visible = objCharacter.Created; lblMarkupPercentLabel.Visible = objCharacter.Created; _objCharacter = objCharacter; // Load the Vehicle information. _xmlBaseVehicleDataNode = _objCharacter.LoadDataXPath("vehicles.xml").SelectSingleNodeAndCacheExpression("/chummer"); _setBlackMarketMaps.AddRange(_objCharacter.GenerateBlackMarketMappings(_xmlBaseVehicleDataNode)); if (_objCharacter.DealerConnectionDiscount) { foreach (Improvement objImprovement in ImprovementManager.GetCachedImprovementListForValueOf(_objCharacter, Improvement.ImprovementType.DealerConnection)) { _setDealerConnectionMaps.Add(objImprovement.UniqueName); } } }
public SelectMetamagic(Character objCharacter, InitiationGrade objGrade) { _objCharacter = objCharacter ?? throw new ArgumentNullException(nameof(objCharacter)); if (objGrade == null) { throw new ArgumentNullException(nameof(objGrade)); } InitializeComponent(); this.UpdateLightDarkMode(); this.TranslateWinForm(); int intMyGrade = objGrade.Grade; foreach (Improvement imp in ImprovementManager .GetCachedImprovementListForValueOf( _objCharacter, Improvement.ImprovementType.MetamagicLimit) .Where(imp => imp.Rating == intMyGrade)) { _lstMetamagicLimits.Add(imp.ImprovedName); } // Load the Metamagic information. if (objGrade.Technomancer) { _strRootXPath = "/chummer/echoes/echo"; _objXmlDocument = _objCharacter.LoadDataXPath("echoes.xml"); _strType = LanguageManager.GetString("String_Echo"); } else { _strRootXPath = "/chummer/metamagics/metamagic"; _objXmlDocument = _objCharacter.LoadDataXPath("metamagic.xml"); _strType = LanguageManager.GetString("String_Metamagic"); } }
private void SelectCritterPower_Load(object sender, EventArgs e) { // Populate the Category list. foreach (XPathNavigator objXmlCategory in _xmlBaseCritterPowerDataNode.SelectAndCacheExpression("categories/category")) { string strInnerText = objXmlCategory.Value; if (ImprovementManager .GetCachedImprovementListForValueOf(_objCharacter, Improvement.ImprovementType.AllowCritterPowerCategory) .Any(imp => strInnerText.Contains(imp.ImprovedName)) && objXmlCategory.SelectSingleNodeAndCacheExpression("@whitelist")?.Value == bool.TrueString || ImprovementManager .GetCachedImprovementListForValueOf(_objCharacter, Improvement.ImprovementType.LimitCritterPowerCategory) .Any(imp => strInnerText.Contains(imp.ImprovedName))) { _lstCategory.Add(new ListItem(strInnerText, objXmlCategory.SelectSingleNodeAndCacheExpression("@translate")?.Value ?? strInnerText)); continue; } if (ImprovementManager .GetCachedImprovementListForValueOf(_objCharacter, Improvement.ImprovementType.LimitCritterPowerCategory) .Any(imp => !strInnerText.Contains(imp.ImprovedName))) { continue; } _lstCategory.Add(new ListItem(strInnerText, objXmlCategory.SelectSingleNodeAndCacheExpression("@translate")?.Value ?? strInnerText)); } _lstCategory.Sort(CompareListItems.CompareNames); if (_lstCategory.Count > 0) { _lstCategory.Insert(0, new ListItem("Show All", LanguageManager.GetString("String_ShowAll"))); } cboCategory.BeginUpdate(); cboCategory.PopulateWithListItems(_lstCategory); cboCategory.EndUpdate(); // Select the first Category in the list. if (string.IsNullOrEmpty(_strSelectCategory)) { cboCategory.SelectedIndex = 0; } else if (cboCategory.Items.Contains(_strSelectCategory)) { cboCategory.SelectedValue = _strSelectCategory; } if (cboCategory.SelectedIndex == -1) { cboCategory.SelectedIndex = 0; } }
// Rebuild the list of Spirits/Sprites based on the character's selected Tradition/Stream. public void RebuildSpiritList(Tradition objTradition) { if (objTradition == null) { return; } string strCurrentValue = cboSpiritName.SelectedValue?.ToString() ?? _objSpirit.Name; XPathNavigator objXmlDocument = _objSpirit.CharacterObject.LoadDataXPath(_objSpirit.EntityType == SpiritType.Spirit ? "traditions.xml" : "streams.xml"); using (new FetchSafelyFromPool <HashSet <string> >(Utils.StringHashSetPool, out HashSet <string> setLimitCategories)) { foreach (Improvement objImprovement in ImprovementManager.GetCachedImprovementListForValueOf( _objSpirit.CharacterObject, Improvement.ImprovementType.LimitSpiritCategory)) { setLimitCategories.Add(objImprovement.ImprovedName); } using (new FetchSafelyFromPool <List <ListItem> >(Utils.ListItemListPool, out List <ListItem> lstCritters)) { if (objTradition.IsCustomTradition) { string strSpiritCombat = objTradition.SpiritCombat; string strSpiritDetection = objTradition.SpiritDetection; string strSpiritHealth = objTradition.SpiritHealth; string strSpiritIllusion = objTradition.SpiritIllusion; string strSpiritManipulation = objTradition.SpiritManipulation; if ((setLimitCategories.Count == 0 || setLimitCategories.Contains(strSpiritCombat)) && !string.IsNullOrWhiteSpace(strSpiritCombat)) { XPathNavigator objXmlCritterNode = objXmlDocument.SelectSingleNode( "/chummer/spirits/spirit[name = " + strSpiritCombat.CleanXPath() + ']'); lstCritters.Add(new ListItem(strSpiritCombat, objXmlCritterNode ?.SelectSingleNodeAndCacheExpression("translate") ?.Value ?? strSpiritCombat)); } if ((setLimitCategories.Count == 0 || setLimitCategories.Contains(strSpiritDetection)) && !string.IsNullOrWhiteSpace(strSpiritDetection)) { XPathNavigator objXmlCritterNode = objXmlDocument.SelectSingleNode( "/chummer/spirits/spirit[name = " + strSpiritDetection.CleanXPath() + ']'); lstCritters.Add(new ListItem(strSpiritDetection, objXmlCritterNode ?.SelectSingleNodeAndCacheExpression("translate") ?.Value ?? strSpiritDetection)); } if ((setLimitCategories.Count == 0 || setLimitCategories.Contains(strSpiritHealth)) && !string.IsNullOrWhiteSpace(strSpiritHealth)) { XPathNavigator objXmlCritterNode = objXmlDocument.SelectSingleNode( "/chummer/spirits/spirit[name = " + strSpiritHealth.CleanXPath() + ']'); lstCritters.Add(new ListItem(strSpiritHealth, objXmlCritterNode ?.SelectSingleNodeAndCacheExpression("translate") ?.Value ?? strSpiritHealth)); } if ((setLimitCategories.Count == 0 || setLimitCategories.Contains(strSpiritIllusion)) && !string.IsNullOrWhiteSpace(strSpiritIllusion)) { XPathNavigator objXmlCritterNode = objXmlDocument.SelectSingleNode( "/chummer/spirits/spirit[name = " + strSpiritIllusion.CleanXPath() + ']'); lstCritters.Add(new ListItem(strSpiritIllusion, objXmlCritterNode ?.SelectSingleNodeAndCacheExpression("translate") ?.Value ?? strSpiritIllusion)); } if ((setLimitCategories.Count == 0 || setLimitCategories.Contains(strSpiritManipulation)) && !string.IsNullOrWhiteSpace(strSpiritManipulation)) { XPathNavigator objXmlCritterNode = objXmlDocument.SelectSingleNode( "/chummer/spirits/spirit[name = " + strSpiritManipulation.CleanXPath() + ']'); lstCritters.Add(new ListItem(strSpiritManipulation, objXmlCritterNode ?.SelectSingleNodeAndCacheExpression("translate") ?.Value ?? strSpiritManipulation)); } } else { if (objTradition.GetNodeXPath()?.SelectSingleNode("spirits/spirit[. = \"All\"]") != null) { if (setLimitCategories.Count == 0) { foreach (XPathNavigator objXmlCritterNode in objXmlDocument.SelectAndCacheExpression( "/chummer/spirits/spirit")) { string strSpiritName = objXmlCritterNode.SelectSingleNodeAndCacheExpression("name") ?.Value; lstCritters.Add(new ListItem(strSpiritName, objXmlCritterNode .SelectSingleNodeAndCacheExpression("translate") ?.Value ?? strSpiritName)); } } else { foreach (string strSpiritName in setLimitCategories) { XPathNavigator objXmlCritterNode = objXmlDocument.SelectSingleNode( "/chummer/spirits/spirit[name = " + strSpiritName.CleanXPath() + ']'); lstCritters.Add(new ListItem(strSpiritName, objXmlCritterNode ?.SelectSingleNodeAndCacheExpression("translate") ?.Value ?? strSpiritName)); } } } else { XPathNodeIterator xmlSpiritList = objTradition.GetNodeXPath()?.Select("spirits/*"); if (xmlSpiritList != null) { foreach (XPathNavigator objXmlSpirit in xmlSpiritList) { string strSpiritName = objXmlSpirit.Value; if (setLimitCategories.Count == 0 || setLimitCategories.Contains(strSpiritName)) { XPathNavigator objXmlCritterNode = objXmlDocument.SelectSingleNode( "/chummer/spirits/spirit[name = " + strSpiritName.CleanXPath() + ']'); lstCritters.Add(new ListItem(strSpiritName, objXmlCritterNode ?.SelectSingleNodeAndCacheExpression( "translate")?.Value ?? strSpiritName)); } } } } } // Add any additional Spirits and Sprites the character has Access to through improvements. if (_objSpirit.CharacterObject.MAGEnabled) { foreach (Improvement objImprovement in ImprovementManager.GetCachedImprovementListForValueOf( _objSpirit.CharacterObject, Improvement.ImprovementType.AddSpirit)) { string strImprovedName = objImprovement.ImprovedName; if (!string.IsNullOrEmpty(strImprovedName)) { lstCritters.Add(new ListItem(strImprovedName, objXmlDocument .SelectSingleNode( "/chummer/spirits/spirit[name = " + strImprovedName.CleanXPath() + "]/translate") ?.Value ?? strImprovedName)); } } } if (_objSpirit.CharacterObject.RESEnabled) { foreach (Improvement objImprovement in ImprovementManager.GetCachedImprovementListForValueOf( _objSpirit.CharacterObject, Improvement.ImprovementType.AddSprite)) { string strImprovedName = objImprovement.ImprovedName; if (!string.IsNullOrEmpty(strImprovedName)) { lstCritters.Add(new ListItem(strImprovedName, objXmlDocument .SelectSingleNode( "/chummer/spirits/spirit[name = " + strImprovedName.CleanXPath() + "]/translate") ?.Value ?? strImprovedName)); } } } cboSpiritName.BeginUpdate(); cboSpiritName.PopulateWithListItems(lstCritters); // Set the control back to its original value. cboSpiritName.SelectedValue = strCurrentValue; cboSpiritName.EndUpdate(); } } }
private void InitializeTable() { _table = new TableView <Power> { Dock = DockStyle.Top, ToolTip = _tipTooltip }; // create columns TableColumn <Power> nameColumn = new TableColumn <Power>(() => new TextTableCell()) { Text = "Power", Extractor = (power => power.CurrentDisplayName), Tag = "String_Power", Sorter = (name1, name2) => string.Compare((string)name1, (string)name2, GlobalSettings.CultureInfo, CompareOptions.Ordinal) }; nameColumn.AddDependency(nameof(Power.CurrentDisplayName)); TableColumn <Power> actionColumn = new TableColumn <Power>(() => new TextTableCell()) { Text = "Action", Extractor = (power => power.DisplayAction), Tag = "ColumnHeader_Action", Sorter = (action1, action2) => string.Compare((string)action1, (string)action2, GlobalSettings.CultureInfo, CompareOptions.Ordinal) }; actionColumn.AddDependency(nameof(Power.DisplayAction)); TableColumn <Power> ratingColumn = new TableColumn <Power>(() => new SpinnerTableCell <Power>(_table) { EnabledExtractor = (p => p.LevelsEnabled), MaxExtractor = (p => Math.Max(p.TotalMaximumLevels - p.FreeLevels, 0)), ValueUpdater = (p, newRating) => { int delta = ((int)newRating) - p.Rating; if (delta != 0) { p.Rating += delta; } }, MinExtractor = (p => 0), ValueGetter = (p => p.Rating) }) { Text = "Rating", Tag = "String_Rating", Sorter = (o1, o2) => { if (o1 is Power objPower1 && o2 is Power objPower2) { return(objPower1.Rating - objPower2.Rating); } string strMessage = "Can't sort an Object of Type " + o1.GetType() + " against another one of Type " + o2.GetType() + " in the ratingColumn." + Environment.NewLine + "Both objects SHOULD be of the type \"Power\"."; throw new ArgumentException(strMessage, nameof(o1)); } }; ratingColumn.AddDependency(nameof(Power.LevelsEnabled)); ratingColumn.AddDependency(nameof(Power.FreeLevels)); ratingColumn.AddDependency(nameof(Power.TotalMaximumLevels)); ratingColumn.AddDependency(nameof(Power.TotalRating)); TableColumn <Power> totalRatingColumn = new TableColumn <Power>(() => new TextTableCell()) { Text = "Total Rating", Extractor = (power => power.TotalRating), Tag = "String_TotalRating", Sorter = (o1, o2) => { if (o1 is Power objPower1 && o2 is Power objPower2) { return(objPower1.TotalRating - objPower2.TotalRating); } string strMessage = "Can't sort an Object of Type " + o1.GetType() + " against another one of Type " + o2.GetType() + " in the totalRatingColumn." + Environment.NewLine + "Both objects SHOULD be of the type \"Power\"."; throw new ArgumentException(strMessage, nameof(o1)); } }; totalRatingColumn.AddDependency(nameof(Power.TotalRating)); TableColumn <Power> powerPointsColumn = new TableColumn <Power>(() => new TextTableCell()) { Text = "Power Points", Extractor = (power => power.DisplayPoints), Tag = "ColumnHeader_Power_Points", ToolTipExtractor = (item => item.ToolTip) }; powerPointsColumn.AddDependency(nameof(Power.DisplayPoints)); powerPointsColumn.AddDependency(nameof(Power.ToolTip)); TableColumn <Power> sourceColumn = new TableColumn <Power>(() => new TextTableCell { Cursor = Cursors.Hand }) { Text = "Source", Extractor = (power => power.SourceDetail), Tag = "Label_Source", ToolTipExtractor = (item => item.SourceDetail.LanguageBookTooltip) }; powerPointsColumn.AddDependency(nameof(Power.Source)); TableColumn <Power> adeptWayColumn = new TableColumn <Power>(() => new CheckBoxTableCell <Power> { ValueGetter = p => p.DiscountedAdeptWay, ValueUpdater = (p, check) => p.DiscountedAdeptWay = check, VisibleExtractor = p => p.AdeptWayDiscountEnabled, EnabledExtractor = p => p.CharacterObject.AllowAdeptWayPowerDiscount || p.DiscountedAdeptWay, Alignment = Alignment.Center }) { Text = "Adept Way", Tag = "Checkbox_Power_AdeptWay" }; adeptWayColumn.AddDependency(nameof(Power.DiscountedAdeptWay)); adeptWayColumn.AddDependency(nameof(Power.AdeptWayDiscountEnabled)); adeptWayColumn.AddDependency(nameof(Character.AllowAdeptWayPowerDiscount)); adeptWayColumn.AddDependency(nameof(Power.Rating)); /* * TableColumn<Power> geasColumn = new TableColumn<Power>(() => new CheckBoxTableCell<Power>() * { * ValueGetter = (p => p.DiscountedGeas), * ValueUpdater = (p, check) => p.DiscountedGeas = check, * Alignment = Alignment.Center * }) * { * Text = "Geas", * Tag = "Checkbox_Power_Geas" * }; * geasColumn.AddDependency(nameof(Power.DiscountedGeas)); */ TableColumn <Power> noteColumn = new TableColumn <Power>(() => new ButtonTableCell <Power>(new PictureBox { Image = Resources.note_edit, Size = GetImageSize(Resources.note_edit) }) { ClickHandler = async p => { using (EditNotes frmPowerNotes = new EditNotes(p.Notes, p.NotesColor)) { await frmPowerNotes.ShowDialogSafeAsync(this); if (frmPowerNotes.DialogResult == DialogResult.OK) { p.Notes = frmPowerNotes.Notes; } } }, Alignment = Alignment.Center }) { Text = "Notes", Tag = "ColumnHeader_Notes", ToolTipExtractor = (p => { string strTooltip = LanguageManager.GetString("Tip_Power_EditNotes"); if (!string.IsNullOrEmpty(p.Notes)) { strTooltip += Environment.NewLine + Environment.NewLine + p.Notes.RtfToPlainText(); } return(strTooltip.WordWrap()); }) }; noteColumn.AddDependency(nameof(Power.Notes)); TableColumn <Power> deleteColumn = new TableColumn <Power>(() => new ButtonTableCell <Power>(new Button { Text = LanguageManager.GetString("String_Delete"), Tag = "String_Delete", Dock = DockStyle.Fill }) { ClickHandler = p => { //Cache the parentform prior to deletion, otherwise the relationship is broken. Form frmParent = ParentForm; if (p.FreeLevels > 0) { string strExtra = p.Extra; string strImprovementSourceName = ImprovementManager.GetCachedImprovementListForValueOf(p.CharacterObject, Improvement.ImprovementType.AdeptPowerFreePoints, p.Name) .Find(x => x.UniqueName == strExtra)?.SourceName; if (!string.IsNullOrWhiteSpace(strImprovementSourceName)) { Gear objGear = p.CharacterObject.Gear.FindById(strImprovementSourceName); if (objGear?.Bonded == true) { objGear.Equipped = false; objGear.Extra = string.Empty; } } } p.DeletePower(); p.UnbindPower(); if (frmParent is CharacterShared objParent) { objParent.IsCharacterUpdateRequested = true; } return(Task.CompletedTask); }, EnabledExtractor = (p => p.FreeLevels == 0) });