private async void SelectCritterPower_Load(object sender, EventArgs e) { // Populate the Category list. foreach (XPathNavigator objXmlCategory in await _xmlBaseCritterPowerDataNode.SelectAndCacheExpressionAsync("categories/category")) { string strInnerText = objXmlCategory.Value; if ((await ImprovementManager .GetCachedImprovementListForValueOfAsync(_objCharacter, Improvement.ImprovementType.AllowCritterPowerCategory)) .Any(imp => strInnerText.Contains(imp.ImprovedName)) && (await objXmlCategory.SelectSingleNodeAndCacheExpressionAsync("@whitelist"))?.Value == bool.TrueString || (await ImprovementManager .GetCachedImprovementListForValueOfAsync(_objCharacter, Improvement.ImprovementType.LimitCritterPowerCategory)) .Any(imp => strInnerText.Contains(imp.ImprovedName))) { _lstCategory.Add(new ListItem(strInnerText, (await objXmlCategory.SelectSingleNodeAndCacheExpressionAsync("@translate"))?.Value ?? strInnerText)); continue; } if ((await ImprovementManager .GetCachedImprovementListForValueOfAsync(_objCharacter, Improvement.ImprovementType.LimitCritterPowerCategory)) .Any(imp => !strInnerText.Contains(imp.ImprovedName))) { continue; } _lstCategory.Add(new ListItem(strInnerText, (await objXmlCategory.SelectSingleNodeAndCacheExpressionAsync("@translate"))?.Value ?? strInnerText)); } _lstCategory.Sort(CompareListItems.CompareNames); if (_lstCategory.Count > 0) { _lstCategory.Insert(0, new ListItem("Show All", await LanguageManager.GetStringAsync("String_ShowAll"))); } await cboCategory.PopulateWithListItemsAsync(_lstCategory); // 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 async ValueTask RebuildSpiritList(Tradition objTradition) { if (objTradition == null) { return; } string strCurrentValue = await cboSpiritName.DoThreadSafeFuncAsync(x => x.SelectedValue?.ToString()) ?? _objSpirit.Name; XPathNavigator objXmlDocument = await _objSpirit.CharacterObject.LoadDataXPathAsync(_objSpirit.EntityType == SpiritType.Spirit ? "traditions.xml" : "streams.xml"); using (new FetchSafelyFromPool <HashSet <string> >(Utils.StringHashSetPool, out HashSet <string> setLimitCategories)) { foreach (Improvement objImprovement in await ImprovementManager.GetCachedImprovementListForValueOfAsync( _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() + ']'); string strTranslatedName = objXmlCritterNode != null ? (await objXmlCritterNode.SelectSingleNodeAndCacheExpressionAsync("translate"))?.Value ?? strSpiritCombat : strSpiritCombat; lstCritters.Add(new ListItem(strSpiritCombat, strTranslatedName)); } if ((setLimitCategories.Count == 0 || setLimitCategories.Contains(strSpiritDetection)) && !string.IsNullOrWhiteSpace(strSpiritDetection)) { XPathNavigator objXmlCritterNode = objXmlDocument.SelectSingleNode( "/chummer/spirits/spirit[name = " + strSpiritDetection.CleanXPath() + ']'); string strTranslatedName = objXmlCritterNode != null ? (await objXmlCritterNode.SelectSingleNodeAndCacheExpressionAsync("translate"))?.Value ?? strSpiritDetection : strSpiritDetection; lstCritters.Add(new ListItem(strSpiritDetection, strTranslatedName)); } if ((setLimitCategories.Count == 0 || setLimitCategories.Contains(strSpiritHealth)) && !string.IsNullOrWhiteSpace(strSpiritHealth)) { XPathNavigator objXmlCritterNode = objXmlDocument.SelectSingleNode( "/chummer/spirits/spirit[name = " + strSpiritHealth.CleanXPath() + ']'); string strTranslatedName = objXmlCritterNode != null ? (await objXmlCritterNode.SelectSingleNodeAndCacheExpressionAsync("translate"))?.Value ?? strSpiritHealth : strSpiritHealth; lstCritters.Add(new ListItem(strSpiritHealth, strTranslatedName)); } if ((setLimitCategories.Count == 0 || setLimitCategories.Contains(strSpiritIllusion)) && !string.IsNullOrWhiteSpace(strSpiritIllusion)) { XPathNavigator objXmlCritterNode = objXmlDocument.SelectSingleNode( "/chummer/spirits/spirit[name = " + strSpiritIllusion.CleanXPath() + ']'); string strTranslatedName = objXmlCritterNode != null ? (await objXmlCritterNode.SelectSingleNodeAndCacheExpressionAsync("translate"))?.Value ?? strSpiritIllusion : strSpiritIllusion; lstCritters.Add(new ListItem(strSpiritIllusion, strTranslatedName)); } if ((setLimitCategories.Count == 0 || setLimitCategories.Contains(strSpiritManipulation)) && !string.IsNullOrWhiteSpace(strSpiritManipulation)) { XPathNavigator objXmlCritterNode = objXmlDocument.SelectSingleNode( "/chummer/spirits/spirit[name = " + strSpiritManipulation.CleanXPath() + ']'); string strTranslatedName = objXmlCritterNode != null ? (await objXmlCritterNode.SelectSingleNodeAndCacheExpressionAsync("translate"))?.Value ?? strSpiritManipulation : strSpiritManipulation; lstCritters.Add(new ListItem(strSpiritManipulation, strTranslatedName)); } } else { if ((await objTradition.GetNodeXPathAsync())?.SelectSingleNode("spirits/spirit[. = \"All\"]") != null) { if (setLimitCategories.Count == 0) { foreach (XPathNavigator objXmlCritterNode in await objXmlDocument.SelectAndCacheExpressionAsync( "/chummer/spirits/spirit")) { string strSpiritName = (await objXmlCritterNode.SelectSingleNodeAndCacheExpressionAsync("name")) ?.Value; lstCritters.Add(new ListItem(strSpiritName, (await objXmlCritterNode .SelectSingleNodeAndCacheExpressionAsync("translate")) ?.Value ?? strSpiritName)); } } else { foreach (string strSpiritName in setLimitCategories) { XPathNavigator objXmlCritterNode = objXmlDocument.SelectSingleNode( "/chummer/spirits/spirit[name = " + strSpiritName.CleanXPath() + ']'); string strTranslatedName = objXmlCritterNode != null ? (await objXmlCritterNode.SelectSingleNodeAndCacheExpressionAsync("translate"))?.Value ?? strSpiritName : strSpiritName; lstCritters.Add(new ListItem(strSpiritName, strTranslatedName)); } } } else { XPathNodeIterator xmlSpiritList = (await objTradition.GetNodeXPathAsync())?.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() + ']'); string strTranslatedName = objXmlCritterNode != null ? (await objXmlCritterNode.SelectSingleNodeAndCacheExpressionAsync("translate"))?.Value ?? strSpiritName : strSpiritName; lstCritters.Add(new ListItem(strSpiritName, strTranslatedName)); } } } } } // Add any additional Spirits and Sprites the character has Access to through improvements. if (_objSpirit.CharacterObject.MAGEnabled) { foreach (Improvement objImprovement in await ImprovementManager.GetCachedImprovementListForValueOfAsync( _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 await ImprovementManager.GetCachedImprovementListForValueOfAsync( _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)); } } } await cboSpiritName.PopulateWithListItemsAsync(lstCritters); // Set the control back to its original value. await cboSpiritName.DoThreadSafeAsync(x => x.SelectedValue = strCurrentValue); } } }