/// <summary> /// Convert Force, 1D6, or 2D6 into a usable value. /// </summary> /// <param name="strIn">Expression to convert.</param> /// <param name="intForce">Force value to use.</param> /// <param name="intOffset">Dice offset.</param> /// <returns></returns> public static int ExpressionToInt(string strIn, int intForce, int intOffset) { if (string.IsNullOrWhiteSpace(strIn)) { return(intOffset); } int intValue = 1; string strForce = intForce.ToString(); // This statement is wrapped in a try/catch since trying 1 div 2 results in an error with XSLT. object objProcess = CommonFunctions.EvaluateInvariantXPath(strIn.Replace("/", " div ").Replace("F", strForce).Replace("1D6", strForce).Replace("2D6", strForce), out bool blnIsSuccess); if (blnIsSuccess) { intValue = Convert.ToInt32(Math.Ceiling((double)objProcess)); } intValue += intOffset; if (intForce > 0) { if (intValue < 1) { return(1); } } else if (intValue < 0) { return(0); } return(intValue); }
/// <summary> /// Convert Force, 1D6, or 2D6 into a usable value. /// </summary> /// <param name="strIn">Expression to convert.</param> /// <param name="intForce">Force value to use.</param> /// <param name="intOffset">Dice offset.</param> /// <returns></returns> public static string ExpressionToString(string strIn, int intForce, int intOffset) { int intValue = 0; string strForce = intForce.ToString(); // This statement is wrapped in a try/catch since trying 1 div 2 results in an error with XSLT. try { intValue = Convert.ToInt32(Math.Ceiling((double)CommonFunctions.EvaluateInvariantXPath(strIn.Replace("/", " div ").Replace("F", strForce).Replace("1D6", strForce).Replace("2D6", strForce)))); } catch (XPathException) { } catch (OverflowException) { } // Result is text and not a double catch (InvalidCastException) { } // Result is text and not a double intValue += intOffset; if (intForce > 0) { if (intValue < 1) { intValue = 1; } } else if (intValue < 0) { intValue = 0; } return(intValue.ToString()); }
public AvailabilityValue(int intRating, string strInput, int intBonus = 0, bool blnIncludedInParent = false) { string strAvailExpr = strInput; if (strAvailExpr.StartsWith("FixedValues(")) { string[] strValues = strAvailExpr.TrimStartOnce("FixedValues(", true).TrimEndOnce(')').Split(','); strAvailExpr = strValues[(int)Math.Max(Math.Min(intRating, strValues.Length) - 1, 0)]; } Suffix = strAvailExpr[strAvailExpr.Length - 1]; AddToParent = strAvailExpr.StartsWith('+') || strAvailExpr.StartsWith('-'); IncludedInParent = blnIncludedInParent; if (Suffix == 'F' || Suffix == 'R') { strAvailExpr = strAvailExpr.Substring(0, strAvailExpr.Length - 1); } object objProcess = CommonFunctions.EvaluateInvariantXPath(strAvailExpr.Replace("Rating", intRating.ToString(GlobalOptions.InvariantCultureInfo)), out bool blnIsSuccess); Value = blnIsSuccess ? Convert.ToInt32(objProcess) : 0; Value += intBonus; if (Value < 0) { Value = 0; } }
/// <summary> /// Convert Force, 1D6, or 2D6 into a usable value. /// </summary> /// <param name="strIn">Expression to convert.</param> /// <param name="intForce">Force value to use.</param> /// <param name="intOffset">Dice offset.</param> /// <returns></returns> public static int ExpressionToInt(string strIn, int intForce, int intOffset) { if (string.IsNullOrWhiteSpace(strIn)) { return(intOffset); } int intValue = 1; string strForce = intForce.ToString(); // This statement is wrapped in a try/catch since trying 1 div 2 results in an error with XSLT. try { intValue = Convert.ToInt32(CommonFunctions.EvaluateInvariantXPath(strIn.Replace("/", " div ").Replace("F", strForce).Replace("1D6", strForce).Replace("2D6", strForce))); } catch (XPathException) { } intValue += intOffset; if (intForce > 0) { if (intValue < 1) { return(1); } } else if (intValue < 0) { return(0); } return(intValue); }
public AvailabilityValue(int intRating, string strInput, int intBonus = 0, bool blnIncludedInParent = false) { if (!string.IsNullOrEmpty(strInput)) { string strAvailExpr = strInput; if (strAvailExpr.StartsWith("FixedValues(", StringComparison.Ordinal)) { string[] strValues = strAvailExpr.TrimStartOnce("FixedValues(", true).TrimEndOnce(')').Split(',', StringSplitOptions.RemoveEmptyEntries); strAvailExpr = strValues[Math.Max(Math.Min(intRating, strValues.Length) - 1, 0)]; } Suffix = strAvailExpr[strAvailExpr.Length - 1]; AddToParent = strAvailExpr.StartsWith('+') || strAvailExpr.StartsWith('-'); if (Suffix == 'F' || Suffix == 'R') { strAvailExpr = strAvailExpr.Substring(0, strAvailExpr.Length - 1); } object objProcess = CommonFunctions.EvaluateInvariantXPath(strAvailExpr.Replace("Rating", intRating.ToString(GlobalOptions.InvariantCultureInfo)), out bool blnIsSuccess); Value = blnIsSuccess ? ((double)objProcess).StandardRound() : 0; } else { Value = 0; Suffix = 'Z'; AddToParent = false; } IncludedInParent = blnIncludedInParent; Value += intBonus; if (Value < 0) { Value = 0; } }
/// <summary> /// Convert Force, 1D6, or 2D6 into a usable value. /// </summary> /// <param name="strIn">Expression to convert.</param> /// <param name="intForce">Force value to use.</param> /// <param name="intOffset">Dice offset.</param> /// <returns></returns> public static int ExpressionToInt(string strIn, int intForce, int intOffset) { if (string.IsNullOrEmpty(strIn)) { return(0); } int intValue = 0; string strForce = intForce.ToString(GlobalOptions.InvariantCultureInfo); // This statement is wrapped in a try/catch since trying 1 div 2 results in an error with XSLT. try { object objProcess = CommonFunctions.EvaluateInvariantXPath(strIn.Replace("/", " div ").Replace("F", strForce).Replace("1D6", strForce).Replace("2D6", strForce), out bool blnIsSuccess); if (blnIsSuccess) { intValue = Convert.ToInt32(Math.Ceiling((double)objProcess)); } } catch (OverflowException) { } // Result is text and not a double catch (InvalidCastException) { } // Result is text and not a double intValue += intOffset; if (intForce > 0) { if (intValue < 1) { return(1); } } else if (intValue < 0) { return(0); } return(intValue); }
/// <summary> /// Processes the string strDrain into a calculated Drain dicepool and appropriate display attributes and labels. /// </summary> /// <param name="strDrain"></param> /// <param name="objImprovementManager"></param> /// <param name="drain"></param> /// <param name="attributeText"></param> /// <param name="valueText"></param> /// <param name="tooltip"></param> public void CalculateTraditionDrain(string strDrain, Improvement.ImprovementType drain, Label attributeText = null, Label valueText = null, ToolTip tooltip = null) { if (string.IsNullOrWhiteSpace(strDrain) || (attributeText == null && valueText == null && tooltip == null)) { return; } StringBuilder objDrain = valueText != null ? new StringBuilder(strDrain) : null; StringBuilder objDisplayDrain = attributeText != null ? new StringBuilder(strDrain) : null; StringBuilder objTip = tooltip != null ? new StringBuilder(strDrain) : null; int intDrain = 0; // Update the Fading CharacterAttribute Value. foreach (string strAttribute in AttributeSection.AttributeStrings) { CharacterAttrib objAttrib = _objCharacter.GetAttribute(strAttribute); if (strDrain.Contains(objAttrib.Abbrev)) { string strAttribTotalValue = objAttrib.TotalValue.ToString(); objDrain?.Replace(objAttrib.Abbrev, strAttribTotalValue); objDisplayDrain?.Replace(objAttrib.Abbrev, objAttrib.DisplayAbbrev); objTip?.Replace(objAttrib.Abbrev, objAttrib.DisplayAbbrev + " (" + strAttribTotalValue + ")"); } } if (objDrain != null) { try { intDrain = Convert.ToInt32(Math.Ceiling((double)CommonFunctions.EvaluateInvariantXPath(objDrain.ToString()))); } catch (XPathException) { } catch (OverflowException) { } // Result is text and not a double catch (InvalidCastException) { } // Result is text and not a double } if (valueText != null || tooltip != null) { int intBonusDrain = ImprovementManager.ValueOf(_objCharacter, drain); if (intBonusDrain != 0) { intDrain += intBonusDrain; objTip?.Append(" + " + LanguageManager.GetString("Tip_Modifiers") + " (" + intBonusDrain.ToString() + ")"); } } if (attributeText != null) { attributeText.Text = objDisplayDrain.ToString(); } if (valueText != null) { valueText.Text = intDrain.ToString(); } if (tooltip != null) { tooltip.SetToolTip(valueText, objTip.ToString()); } }
//someday this should parse into an abstract syntax tree, but this hack //have worked for a few years, and will work a few years more public static bool TryFloat(string number, out float parsed, Dictionary <string, float> keywords) { //parse to base math string Regex regex = new Regex(string.Join("|", keywords.Keys)); number = regex.Replace(number, m => keywords[m.Value].ToString(GlobalOptions.InvariantCultureInfo)); try { // Treat this as a decimal value so any fractions can be rounded down. This is currently only used by the Boosted Reflexes Cyberware from SR2050. if (float.TryParse(CommonFunctions.EvaluateInvariantXPath(number)?.ToString(), out parsed)) { return(true); } } catch (XPathException ex) { Log.Exception(ex); } parsed = 0; return(false); }
private void lstDrug_SelectedIndexChanged(object sender, EventArgs e) { if (_blnLoading) { return; } _blnLoading = true; XPathNavigator xmlDrug = null; string strSelectedId = lstDrug.SelectedValue?.ToString(); if (!string.IsNullOrEmpty(strSelectedId)) { // Retrieve the information for the selected piece of Drug. xmlDrug = _xmlBaseDrugDataNode.SelectSingleNode(_strNodeXPath + "[id = \"" + strSelectedId + "\"]"); } string strForceGrade; if (xmlDrug != null) { strForceGrade = xmlDrug.SelectSingleNode("forcegrade")?.Value; // If the piece has a Rating value, enable the Rating control, otherwise, disable it and set its value to 0. XPathNavigator xmlRatingNode = xmlDrug.SelectSingleNode("rating"); if (xmlRatingNode != null) { string strMinRating = xmlDrug.SelectSingleNode("minrating")?.Value; int intMinRating = 1; // Not a simple integer, so we need to start mucking around with strings if (!string.IsNullOrEmpty(strMinRating) && !int.TryParse(strMinRating, out intMinRating)) { strMinRating = strMinRating.CheapReplace("MaximumSTR", () => (ParentVehicle != null ? Math.Max(1, ParentVehicle.TotalBody * 2) : _objCharacter.STR.TotalMaximum).ToString()) .CheapReplace("MaximumAGI", () => (ParentVehicle != null ? Math.Max(1, ParentVehicle.Pilot * 2) : _objCharacter.AGI.TotalMaximum).ToString()) .CheapReplace("MinimumSTR", () => (ParentVehicle?.TotalBody ?? 3).ToString()) .CheapReplace("MinimumAGI", () => (ParentVehicle?.Pilot ?? 3).ToString()); object objProcess = CommonFunctions.EvaluateInvariantXPath(strMinRating, out bool blnIsSuccess); intMinRating = blnIsSuccess ? Convert.ToInt32(objProcess) : 1; } nudRating.Minimum = intMinRating; string strMaxRating = xmlRatingNode.Value; int intMaxRating = 0; // Not a simple integer, so we need to start mucking around with strings if (!string.IsNullOrEmpty(strMaxRating) && !int.TryParse(strMaxRating, out intMaxRating)) { strMaxRating = strMaxRating.CheapReplace("MaximumSTR", () => (ParentVehicle != null ? Math.Max(1, ParentVehicle.TotalBody * 2) : _objCharacter.STR.TotalMaximum).ToString()) .CheapReplace("MaximumAGI", () => (ParentVehicle != null ? Math.Max(1, ParentVehicle.Pilot * 2) : _objCharacter.AGI.TotalMaximum).ToString()) .CheapReplace("MinimumSTR", () => (ParentVehicle?.TotalBody ?? 3).ToString()) .CheapReplace("MinimumAGI", () => (ParentVehicle?.Pilot ?? 3).ToString()); object objProcess = CommonFunctions.EvaluateInvariantXPath(strMaxRating, out bool blnIsSuccess); intMaxRating = blnIsSuccess ? Convert.ToInt32(objProcess) : 1; } nudRating.Maximum = intMaxRating; if (chkHideOverAvailLimit.Checked) { int intAvailModifier = strForceGrade == "None" ? 0 : _intAvailModifier; while (nudRating.Maximum > intMinRating && !SelectionShared.CheckAvailRestriction(xmlDrug, _objCharacter, decimal.ToInt32(nudRating.Maximum), intAvailModifier)) { nudRating.Maximum -= 1; } } if (chkShowOnlyAffordItems.Checked && !chkFree.Checked) { decimal decCostMultiplier = 1 + (nudMarkup.Value / 100.0m); if (chkBlackMarketDiscount.Checked) { decCostMultiplier *= 0.9m; } while (nudRating.Maximum > intMinRating && !SelectionShared.CheckNuyenRestriction(xmlDrug, _objCharacter.Nuyen, decCostMultiplier, decimal.ToInt32(nudRating.Maximum))) { nudRating.Maximum -= 1; } } nudRating.Value = nudRating.Minimum; nudRating.Enabled = nudRating.Minimum != nudRating.Maximum; nudRating.Visible = true; lblRatingNALabel.Visible = false; lblRatingLabel.Visible = true; } else { lblRatingLabel.Visible = true; lblRatingNALabel.Visible = true; nudRating.Minimum = 0; nudRating.Value = 0; nudRating.Visible = false; } string strSource = xmlDrug.SelectSingleNode("source")?.Value ?? LanguageManager.GetString("String_Unknown", GlobalOptions.Language); string strPage = xmlDrug.SelectSingleNode("altpage")?.Value ?? xmlDrug.SelectSingleNode("page")?.Value ?? LanguageManager.GetString("String_Unknown", GlobalOptions.Language); string strSpaceCharacter = LanguageManager.GetString("String_Space", GlobalOptions.Language); lblSource.Text = CommonFunctions.LanguageBookShort(strSource, GlobalOptions.Language) + strSpaceCharacter + strPage; lblSource.SetToolTip(CommonFunctions.LanguageBookLong(strSource, GlobalOptions.Language) + strSpaceCharacter + LanguageManager.GetString("String_Page", GlobalOptions.Language) + ' ' + strPage); lblSourceLabel.Visible = !string.IsNullOrEmpty(lblSource.Text); Grade objForcedGrade = null; if (!string.IsNullOrEmpty(strForceGrade)) { // Force the Drug to be a particular Grade. if (cboGrade.Enabled) { cboGrade.Enabled = false; } objForcedGrade = _lstGrades.FirstOrDefault(x => x.Name == strForceGrade); strForceGrade = objForcedGrade?.SourceId.ToString("D"); } else { cboGrade.Enabled = !_blnLockGrade; if (_blnLockGrade) { strForceGrade = _objForcedGrade?.SourceId.ToString("D") ?? cboGrade.SelectedValue?.ToString(); objForcedGrade = _objForcedGrade ?? _lstGrades.FirstOrDefault(x => x.SourceId.ToString("D") == strForceGrade); } } chkBlackMarketDiscount.Enabled = _objCharacter.BlackMarketDiscount; if (!chkBlackMarketDiscount.Checked) { chkBlackMarketDiscount.Checked = GlobalOptions.AssumeBlackMarket && _setBlackMarketMaps.Contains(xmlDrug.SelectSingleNode("category") ?.Value); } else if (!_setBlackMarketMaps.Contains(xmlDrug.SelectSingleNode("category")?.Value)) { //Prevent chkBlackMarketDiscount from being checked if the gear category doesn't match. chkBlackMarketDiscount.Checked = false; } // We may need to rebuild the Grade list since Cultured Bioware is not allowed to select Standard (Second-Hand) as Grade and ForceGrades can change. PopulateGrades(xmlDrug.SelectSingleNode("nosecondhand") != null || (!cboGrade.Enabled && objForcedGrade?.SecondHand != true), false, strForceGrade, chkHideBannedGrades.Checked); /* * string strNotes = xmlDrug.SelectSingleNode("altnotes")?.Value ?? xmlDrug.SelectSingleNode("notes")?.Value; * if (!string.IsNullOrEmpty(strNotes)) * { * lblDrugNotes.Visible = true; * lblDrugNotesLabel.Visible = true; * lblDrugNotes.Text = strNotes; * } * else * { * lblDrugNotes.Visible = false; * lblDrugNotesLabel.Visible = false; * }*/ } else { lblRatingLabel.Visible = false; lblRatingNALabel.Visible = false; nudRating.Minimum = 0; nudRating.Value = 0; nudRating.Visible = false; cboGrade.Enabled = !_blnLockGrade; strForceGrade = string.Empty; Grade objForcedGrade = null; if (_blnLockGrade) { strForceGrade = _objForcedGrade?.SourceId.ToString("D") ?? cboGrade.SelectedValue?.ToString(); objForcedGrade = _objForcedGrade ?? _lstGrades.FirstOrDefault(x => x.SourceId.ToString("D") == strForceGrade); } PopulateGrades(_blnLockGrade && objForcedGrade?.SecondHand != true, false, strForceGrade, chkHideBannedGrades.Checked); chkBlackMarketDiscount.Checked = false; lblSourceLabel.Visible = false; lblSource.Text = string.Empty; lblSource.SetToolTip(string.Empty); } _blnLoading = false; UpdateDrugInfo(); }
/// <summary> /// Print the object's XML to the XmlWriter. /// </summary> /// <param name="objWriter">XmlTextWriter to write with.</param> /// <param name="objCulture">Culture in which to print numbers.</param> /// <param name="strLanguageToPrint">Language in which to print.</param> public void Print(XmlTextWriter objWriter, CultureInfo objCulture, string strLanguageToPrint) { // Translate the Critter name if applicable. string strName = Name; XmlNode objXmlCritterNode = GetNode(strLanguageToPrint); if (strLanguageToPrint != GlobalOptions.DefaultLanguage) { strName = objXmlCritterNode?["translate"]?.InnerText ?? Name; } objWriter.WriteStartElement("spirit"); objWriter.WriteElementString("name", strName); objWriter.WriteElementString("name_english", Name); objWriter.WriteElementString("crittername", CritterName); objWriter.WriteElementString("fettered", Fettered.ToString(GlobalOptions.InvariantCultureInfo)); objWriter.WriteElementString("bound", Bound.ToString(GlobalOptions.InvariantCultureInfo)); objWriter.WriteElementString("services", ServicesOwed.ToString(objCulture)); objWriter.WriteElementString("force", Force.ToString(objCulture)); if (objXmlCritterNode != null) { //Attributes for spirits, named differently as to not confuse <attribtue> Dictionary <string, int> dicAttributes = new Dictionary <string, int>(); objWriter.WriteStartElement("spiritattributes"); foreach (string strAttribute in new[] { "bod", "agi", "rea", "str", "cha", "int", "wil", "log", "ini" }) { string strInner = string.Empty; if (objXmlCritterNode.TryGetStringFieldQuickly(strAttribute, ref strInner)) { object objProcess = CommonFunctions.EvaluateInvariantXPath(strInner.Replace("F", _intForce.ToString()), out bool blnIsSuccess); int intValue = Math.Max(blnIsSuccess ? Convert.ToInt32(objProcess) : _intForce, 1); objWriter.WriteElementString(strAttribute, intValue.ToString(objCulture)); dicAttributes[strAttribute] = intValue; } } objWriter.WriteEndElement(); //Dump skills, (optional)powers if present to output XmlDocument objXmlPowersDocument = XmlManager.Load("spiritpowers.xml", strLanguageToPrint); XmlNode xmlPowersNode = objXmlCritterNode["powers"]; if (xmlPowersNode != null) { objWriter.WriteStartElement("powers"); foreach (XmlNode objXmlPowerNode in xmlPowersNode.ChildNodes) { PrintPowerInfo(objWriter, objXmlPowersDocument, objXmlPowerNode.InnerText, GlobalOptions.Language); } objWriter.WriteEndElement(); } xmlPowersNode = objXmlCritterNode["optionalpowers"]; if (xmlPowersNode != null) { objWriter.WriteStartElement("optionalpowers"); foreach (XmlNode objXmlPowerNode in xmlPowersNode.ChildNodes) { PrintPowerInfo(objWriter, objXmlPowersDocument, objXmlPowerNode.InnerText, GlobalOptions.Language); } objWriter.WriteEndElement(); } xmlPowersNode = objXmlCritterNode["skills"]; if (xmlPowersNode != null) { objWriter.WriteStartElement("skills"); foreach (XmlNode xmlSkillNode in xmlPowersNode.ChildNodes) { string strAttrName = xmlSkillNode.Attributes?["attr"]?.Value ?? string.Empty; if (!dicAttributes.TryGetValue(strAttrName, out int intAttrValue)) { intAttrValue = _intForce; } int intDicepool = intAttrValue + _intForce; objWriter.WriteStartElement("skill"); objWriter.WriteElementString("name", xmlSkillNode.InnerText); objWriter.WriteElementString("attr", strAttrName); objWriter.WriteElementString("pool", intDicepool.ToString(objCulture)); objWriter.WriteEndElement(); } objWriter.WriteEndElement(); } xmlPowersNode = objXmlCritterNode["weaknesses"]; if (xmlPowersNode != null) { objWriter.WriteStartElement("weaknesses"); foreach (XmlNode objXmlPowerNode in xmlPowersNode.ChildNodes) { PrintPowerInfo(objWriter, objXmlPowersDocument, objXmlPowerNode.InnerText, GlobalOptions.Language); } objWriter.WriteEndElement(); } //Page in book for reference string strSource = string.Empty; string strPage = string.Empty; if (objXmlCritterNode.TryGetStringFieldQuickly("source", ref strSource)) { objWriter.WriteElementString("source", CommonFunctions.LanguageBookShort(strSource, strLanguageToPrint)); } if (objXmlCritterNode.TryGetStringFieldQuickly("altpage", ref strPage) || objXmlCritterNode.TryGetStringFieldQuickly("page", ref strPage)) { objWriter.WriteElementString("page", strPage); } } objWriter.WriteElementString("bound", Bound.ToString()); objWriter.WriteElementString("type", EntityType.ToString()); if (_objCharacter.Options.PrintNotes) { objWriter.WriteElementString("notes", Notes); } PrintMugshots(objWriter); objWriter.WriteEndElement(); }
/// <summary> /// Calculate the LP value for the selected items. /// </summary> private void CalculateValues(bool blnIncludePercentage = true) { if (_blnSkipRefresh) { return; } decimal decBaseCost = 0; decimal decCost = 0; decimal decMod = 0; // Get the base cost of the lifestyle string strSelectedId = cboLifestyle.SelectedValue?.ToString(); if (strSelectedId != null) { XmlNode objXmlAspect = _objXmlDocument.SelectSingleNode("/chummer/lifestyles/lifestyle[id = \"" + strSelectedId + "\"]"); if (objXmlAspect != null) { decBaseCost += Convert.ToDecimal(objXmlAspect["cost"]?.InnerText, GlobalOptions.InvariantCultureInfo); string strSource = objXmlAspect["source"]?.InnerText; string strPage = objXmlAspect["altpage"]?.InnerText ?? objXmlAspect["page"]?.InnerText; if (!string.IsNullOrEmpty(strSource) && !string.IsNullOrEmpty(strPage)) { string strSpaceCharacter = LanguageManager.GetString("String_Space", GlobalOptions.Language); lblSource.Text = CommonFunctions.LanguageBookShort(strSource, GlobalOptions.Language) + strSpaceCharacter + strPage; lblSource.SetToolTip(CommonFunctions.LanguageBookLong(strSource, GlobalOptions.Language) + strSpaceCharacter + LanguageManager.GetString("String_Page", GlobalOptions.Language) + strSpaceCharacter + strPage); } else { lblSource.Text = LanguageManager.GetString("String_Unknown", GlobalOptions.Language); lblSource.SetToolTip(LanguageManager.GetString("String_Unknown", GlobalOptions.Language)); } lblSourceLabel.Visible = !string.IsNullOrEmpty(lblSource.Text); // Add the flat costs from qualities foreach (TreeNode objNode in treQualities.Nodes) { if (objNode.Checked) { string strCost = _objXmlDocument.SelectSingleNode($"/chummer/qualities/quality[id = \"{objNode.Tag}\"]/cost")?.InnerText; if (!string.IsNullOrEmpty(strCost)) { object objProcess = CommonFunctions.EvaluateInvariantXPath(strCost, out bool blnIsSuccess); if (blnIsSuccess) { decCost += Convert.ToDecimal(objProcess, GlobalOptions.InvariantCultureInfo); } } } } decimal decBaseMultiplier = 0; if (blnIncludePercentage) { // Add the modifiers from qualities foreach (TreeNode objNode in treQualities.Nodes) { if (!objNode.Checked) { continue; } objXmlAspect = _objXmlDocument.SelectSingleNode($"/chummer/qualities/quality[id = \"{objNode.Tag}\"]"); if (objXmlAspect == null) { continue; } string strMultiplier = objXmlAspect["multiplier"]?.InnerText; if (!string.IsNullOrEmpty(strMultiplier)) { decMod += Convert.ToDecimal(strMultiplier, GlobalOptions.InvariantCultureInfo) / 100.0m; } strMultiplier = objXmlAspect["multiplierbaseonly"]?.InnerText; if (!string.IsNullOrEmpty(strMultiplier)) { decBaseMultiplier += Convert.ToDecimal(strMultiplier, GlobalOptions.InvariantCultureInfo) / 100.0m; } } // Check for modifiers in the improvements decimal decModifier = Convert.ToDecimal(ImprovementManager.ValueOf(_objCharacter, Improvement.ImprovementType.LifestyleCost), GlobalOptions.InvariantCultureInfo); decMod += decModifier / 100.0m; } decBaseCost += decBaseCost * decBaseMultiplier; if (nudRoommates.Value > 0) { decimal d = nudRoommates.Value * 10; d += 100M; d = Math.Max(d / 100, 0); decBaseCost *= (d); } } } decimal decNuyen = decBaseCost + decBaseCost * decMod + decCost; lblCost.Text = decNuyen.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + '¥'; if (nudPercentage.Value != 100 || (nudRoommates.Value > 0 && !chkPrimaryTenant.Checked)) { decimal decDiscount = decNuyen; decDiscount *= (nudPercentage.Value / 100); decDiscount /= (nudRoommates.Value); lblCost.Text += LanguageManager.GetString("String_Space", GlobalOptions.Language) + '(' + decDiscount.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + "¥)"; } lblCostLabel.Visible = !string.IsNullOrEmpty(lblCost.Text); }
private void frmSelectLifestyle_Load(object sender, EventArgs e) { string strSelectedId = string.Empty; // Populate the Lifestyle ComboBoxes. List <ListItem> lstLifestyle = new List <ListItem>(); using (XmlNodeList xmlLifestyleList = _objXmlDocument.SelectNodes("/chummer/lifestyles/lifestyle[" + _objCharacter.Options.BookXPath() + "]")) if (xmlLifestyleList?.Count > 0) { foreach (XmlNode objXmlLifestyle in xmlLifestyleList) { string strLifeStyleId = objXmlLifestyle["id"]?.InnerText; if (!string.IsNullOrEmpty(strLifeStyleId) && !strLifeStyleId.IsEmptyGuid()) { string strName = objXmlLifestyle["name"]?.InnerText ?? LanguageManager.GetString("String_Unknown", GlobalOptions.Language); if (strName == _objSourceLifestyle?.BaseLifestyle) { strSelectedId = strLifeStyleId; } lstLifestyle.Add(new ListItem(strLifeStyleId, objXmlLifestyle["translate"]?.InnerText ?? strName)); } } } cboLifestyle.BeginUpdate(); cboLifestyle.ValueMember = "Value"; cboLifestyle.DisplayMember = "Name"; cboLifestyle.DataSource = lstLifestyle; if (!string.IsNullOrEmpty(strSelectedId)) { cboLifestyle.SelectedValue = strSelectedId; } if (cboLifestyle.SelectedIndex == -1) { cboLifestyle.SelectedIndex = 0; } cboLifestyle.EndUpdate(); string strSpaceCharacter = LanguageManager.GetString("String_Space", GlobalOptions.Language); // Fill the Options list. using (XmlNodeList xmlLifestyleOptionsList = _objXmlDocument.SelectNodes("/chummer/qualities/quality[(source = \"" + "SR5" + "\" or category = \"" + "Contracts" + "\") and (" + _objCharacter.Options.BookXPath() + ")]")) if (xmlLifestyleOptionsList?.Count > 0) { foreach (XmlNode objXmlOption in xmlLifestyleOptionsList) { string strOptionName = objXmlOption["name"]?.InnerText; if (string.IsNullOrEmpty(strOptionName)) { continue; } TreeNode nodOption = new TreeNode(); XmlNode nodMultiplier = objXmlOption["multiplier"]; string strBaseString = string.Empty; if (nodMultiplier == null) { nodMultiplier = objXmlOption["multiplierbaseonly"]; strBaseString = strSpaceCharacter + LanguageManager.GetString("Label_Base", GlobalOptions.Language); } nodOption.Tag = objXmlOption["id"]?.InnerText; if (nodMultiplier != null && int.TryParse(nodMultiplier.InnerText, out int intCost)) { nodOption.Text = intCost > 0 ? $"{objXmlOption["translate"]?.InnerText ?? strOptionName} [+{intCost}{strBaseString}%]" : $"{objXmlOption["translate"]?.InnerText ?? strOptionName} [{intCost}{strBaseString}%]"; } else { string strCost = objXmlOption["cost"]?.InnerText; object objProcess = CommonFunctions.EvaluateInvariantXPath(strCost, out bool blnIsSuccess); decimal decCost = blnIsSuccess ? Convert.ToDecimal((double)objProcess) : 0; nodOption.Text = $"{objXmlOption["translate"]?.InnerText ?? strOptionName} [{decCost.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo)}¥]"; } treQualities.Nodes.Add(nodOption); } } SortTree(treQualities); if (_objSourceLifestyle != null) { txtLifestyleName.Text = _objSourceLifestyle.Name; nudRoommates.Value = _objSourceLifestyle.Roommates; nudPercentage.Value = _objSourceLifestyle.Percentage; foreach (LifestyleQuality objQuality in _objSourceLifestyle.LifestyleQualities) { TreeNode objNode = treQualities.FindNode(objQuality.SourceIDString); if (objNode != null) { objNode.Checked = true; } } chkPrimaryTenant.Checked = _objSourceLifestyle.PrimaryTenant; } _blnSkipRefresh = false; CalculateValues(); }
/// <summary> /// Update the information for the selected Armor Mod. /// </summary> private void UpdateSelectedArmor() { // Retireve the information for the selected Accessory. XmlNode objXmlMod = _objXmlDocument.SelectSingleNode("/chummer/mods/mod[name = \"" + lstMod.SelectedValue + "\"]"); // Extract the Avil and Cost values from the Cyberware info since these may contain formulas and/or be based off of the Rating. // This is done using XPathExpression. lblA.Text = objXmlMod["armor"].InnerText; nudRating.Maximum = Convert.ToDecimal(objXmlMod["maxrating"].InnerText, GlobalOptions.InvariantCultureInfo); if (chkHideOverAvailLimit.Checked) { while (nudRating.Maximum > 1 && !Backend.SelectionShared.CheckAvailRestriction(objXmlMod, _objCharacter, decimal.ToInt32(nudRating.Maximum))) { nudRating.Maximum -= 1; } } if (nudRating.Maximum <= 1) { nudRating.Enabled = false; } else { nudRating.Enabled = true; if (nudRating.Minimum == 0) { nudRating.Value = 1; nudRating.Minimum = 1; } } string strAvail = string.Empty; string strAvailExpr = string.Empty; strAvailExpr = objXmlMod["avail"].InnerText; if (strAvailExpr.EndsWith('F', 'R')) { strAvail = strAvailExpr.Substring(strAvailExpr.Length - 1, 1); if (strAvail == "R") { strAvail = LanguageManager.GetString("String_AvailRestricted", GlobalOptions.Language); } else if (strAvail == "F") { strAvail = LanguageManager.GetString("String_AvailForbidden", GlobalOptions.Language); } // Remove the trailing character if it is "F" or "R". strAvailExpr = strAvailExpr.Substring(0, strAvailExpr.Length - 1); } try { lblAvail.Text = Convert.ToInt32(CommonFunctions.EvaluateInvariantXPath(strAvailExpr.Replace("Rating", nudRating.Value.ToString(GlobalOptions.InvariantCultureInfo)))).ToString() + strAvail; } catch (XPathException) { lblAvail.Text = strAvailExpr + strAvail; } // Cost. chkBlackMarketDiscount.Checked = _setBlackMarketMaps.Contains(objXmlMod["category"]?.InnerText); if (chkFreeItem.Checked) { lblCost.Text = 0.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + '¥'; } else { string strCostElement = objXmlMod["cost"]?.InnerText ?? string.Empty; if (strCostElement.StartsWith("Variable(")) { decimal decMin = 0; decimal decMax = decimal.MaxValue; string strCost = strCostElement.TrimStart("Variable(", true).TrimEnd(')'); if (strCost.Contains('-')) { string[] strValues = strCost.Split('-'); decMin = Convert.ToDecimal(strValues[0], GlobalOptions.InvariantCultureInfo); decMax = Convert.ToDecimal(strValues[1], GlobalOptions.InvariantCultureInfo); } else { decMin = Convert.ToDecimal(strCost.FastEscape('+'), GlobalOptions.InvariantCultureInfo); } if (decMax == decimal.MaxValue) { lblCost.Text = decMin.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + "¥+"; } else { lblCost.Text = decMin.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + " - " + decMax.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + '¥'; } } else { string strCost = strCostElement.Replace("Rating", nudRating.Value.ToString(GlobalOptions.InvariantCultureInfo)); strCost = strCost.Replace("Armor Cost", _decArmorCost.ToString(GlobalOptions.InvariantCultureInfo)); // Apply any markup. decimal decCost = Convert.ToDecimal(CommonFunctions.EvaluateInvariantXPath(strCost), GlobalOptions.InvariantCultureInfo); decCost *= 1 + (nudMarkup.Value / 100.0m); lblCost.Text = decCost.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + '¥'; lblTest.Text = _objCharacter.AvailTest(decCost, lblAvail.Text); } } // Capacity. // XPathExpression cannot evaluate while there are square brackets, so remove them if necessary. string strCapacity = objXmlMod["armorcapacity"].InnerText; // Handle YNT Softweave if (strCapacity.Contains("Capacity")) { lblCapacity.Text = "+50%"; } else { if (strCapacity.StartsWith("FixedValues(")) { string[] strValues = strCapacity.TrimStart("FixedValues(", true).TrimEnd(')').Split(','); strCapacity = strValues[decimal.ToInt32(nudRating.Value) - 1]; } strCapacity = strCapacity.Substring(1, strCapacity.Length - 2); if (_eCapacityStyle == CapacityStyle.Zero) { lblCapacity.Text = "[0]"; } else { lblCapacity.Text = '[' + CommonFunctions.EvaluateInvariantXPath(strCapacity.CheapReplace("Rating", () => nudRating.Value.ToString(GlobalOptions.InvariantCultureInfo))).ToString() + ']'; } } string strBook = CommonFunctions.LanguageBookShort(objXmlMod["source"].InnerText, GlobalOptions.Language); string strPage = objXmlMod["altpage"]?.InnerText ?? objXmlMod["page"].InnerText; lblSource.Text = strBook + ' ' + strPage; tipTooltip.SetToolTip(lblSource, CommonFunctions.LanguageBookLong(objXmlMod["source"].InnerText, GlobalOptions.Language) + ' ' + LanguageManager.GetString("String_Page", GlobalOptions.Language) + ' ' + strPage); }
private void UpdateGearInfo() { // Retrieve the information for the selected Accessory. XmlNode objXmlAccessory = _objXmlDocument.SelectSingleNode("/chummer/accessories/accessory[name = \"" + lstAccessory.SelectedValue + "\"]"); if (objXmlAccessory == null) { return; } if (objXmlAccessory.InnerXml.Contains("<rc>")) { lblRC.Visible = true; lblRCLabel.Visible = true; lblRC.Text = objXmlAccessory["rc"]?.InnerText; } else { lblRC.Visible = false; lblRCLabel.Visible = false; } if (int.TryParse(objXmlAccessory["rating"]?.InnerText, out int intMaxRating) && intMaxRating > 0) { nudRating.Enabled = true; nudRating.Visible = true; lblRatingLabel.Visible = true; nudRating.Maximum = intMaxRating; if (chkHideOverAvailLimit.Checked) { while (nudRating.Maximum > nudRating.Minimum && !Backend.SelectionShared.CheckAvailRestriction(objXmlAccessory, _objCharacter, decimal.ToInt32(nudRating.Maximum))) { nudRating.Maximum -= 1; } } } else { nudRating.Enabled = false; nudRating.Visible = false; lblRatingLabel.Visible = false; } List <string> strMounts = new List <string>(); foreach (string strItem in objXmlAccessory["mount"]?.InnerText?.Split('/')) { strMounts.Add(strItem); } strMounts.Add("None"); List <string> strAllowed = new List <string>(); foreach (string strItem in _strAllowedMounts.Split('/')) { strAllowed.Add(strItem); } strAllowed.Add("None"); cboMount.Items.Clear(); foreach (string strCurrentMount in strMounts) { if (!string.IsNullOrEmpty(strCurrentMount)) { foreach (string strAllowedMount in strAllowed) { if (strCurrentMount == strAllowedMount) { cboMount.Items.Add(strCurrentMount); } } } } if (cboMount.Items.Count <= 1) { cboMount.Enabled = false; } else { cboMount.Enabled = true; } cboMount.SelectedIndex = 0; List <string> strExtraMounts = new List <string>(); if (objXmlAccessory.InnerXml.Contains("<extramount>")) { foreach (string strItem in objXmlAccessory["extramount"]?.InnerText?.Split('/')) { strExtraMounts.Add(strItem); } } strExtraMounts.Add("None"); cboExtraMount.Items.Clear(); foreach (string strCurrentMount in strExtraMounts) { if (!string.IsNullOrEmpty(strCurrentMount)) { foreach (string strAllowedMount in strAllowed) { if (strCurrentMount == strAllowedMount) { cboExtraMount.Items.Add(strCurrentMount); } } } } if (cboExtraMount.Items.Count <= 1) { cboExtraMount.Enabled = false; } else { cboExtraMount.Enabled = true; } cboExtraMount.SelectedIndex = 0; if (cboMount.SelectedItem.ToString() != "None" && cboExtraMount.SelectedItem.ToString() != "None" && cboMount.SelectedItem.ToString() == cboExtraMount.SelectedItem.ToString()) { cboExtraMount.SelectedIndex += 1; } // Avail. // If avail contains "F" or "R", remove it from the string so we can use the expression. string strAvail = string.Empty; string strAvailExpr = objXmlAccessory["avail"]?.InnerText; if (!string.IsNullOrWhiteSpace(strAvailExpr)) { lblAvail.Text = strAvailExpr; if (strAvailExpr.EndsWith('F', 'R')) { strAvail = strAvailExpr.Substring(strAvailExpr.Length - 1, 1); if (strAvail == "R") { strAvail = LanguageManager.GetString("String_AvailRestricted", GlobalOptions.Language); } else if (strAvail == "F") { strAvail = LanguageManager.GetString("String_AvailForbidden", GlobalOptions.Language); } // Remove the trailing character if it is "F" or "R". strAvailExpr = strAvailExpr.Substring(0, strAvailExpr.Length - 1); } try { lblAvail.Text = Convert.ToInt32(CommonFunctions.EvaluateInvariantXPath(strAvailExpr.Replace("Rating", nudRating.Value.ToString(GlobalOptions.CultureInfo)))).ToString() + strAvail; } catch (XPathException) { lblAvail.Text = strAvailExpr + strAvail; } } else { lblAvail.Text = string.Empty; } if (!chkFreeItem.Checked) { string strCost = "0"; if (objXmlAccessory.TryGetStringFieldQuickly("cost", ref strCost)) { strCost = strCost.Replace("Weapon Cost", _decWeaponCost.ToString(GlobalOptions.InvariantCultureInfo)) .Replace("Rating", nudRating.Value.ToString(GlobalOptions.CultureInfo)); } if (strCost.StartsWith("Variable(")) { decimal decMin = 0; decimal decMax = decimal.MaxValue; strCost = strCost.TrimStart("Variable(", true).TrimEnd(')'); if (strCost.Contains('-')) { string[] strValues = strCost.Split('-'); decimal.TryParse(strValues[0], NumberStyles.Any, GlobalOptions.InvariantCultureInfo, out decMin); decimal.TryParse(strValues[1], NumberStyles.Any, GlobalOptions.InvariantCultureInfo, out decMax); } else { decimal.TryParse(strCost.FastEscape('+'), NumberStyles.Any, GlobalOptions.InvariantCultureInfo, out decMin); } if (decMax == decimal.MaxValue) { lblCost.Text = decMin.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + "¥+"; } else { lblCost.Text = decMin.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + " - " + decMax.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + '¥'; } lblTest.Text = _objCharacter.AvailTest(decMax, lblAvail.Text); } else { decimal decCost = 0.0m; try { decCost = Convert.ToDecimal(CommonFunctions.EvaluateInvariantXPath(strCost), GlobalOptions.InvariantCultureInfo); } catch (XPathException) { } // Apply any markup. decCost *= 1 + (nudMarkup.Value / 100.0m); lblCost.Text = decCost.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + '¥'; lblTest.Text = _objCharacter.AvailTest(decCost, lblAvail.Text); } } else { lblCost.Text = 0.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + '¥'; lblTest.Text = _objCharacter.AvailTest(0, lblAvail.Text); } /*TODO: Accessories don't use a category mapping, so this doesn't work. * if (_blackMarketMaps != null) * chkBlackMarketDiscount.Checked = * _blackMarketMaps.Contains(objXmlAccessory["category"]?.InnerText); */ string strBookCode = objXmlAccessory["source"]?.InnerText; string strBook = CommonFunctions.LanguageBookShort(strBookCode, GlobalOptions.Language); string strPage = objXmlAccessory["altpage"]?.InnerText ?? objXmlAccessory["page"]?.InnerText; lblSource.Text = strBook + ' ' + strPage; tipTooltip.SetToolTip(lblSource, CommonFunctions.LanguageBookLong(strBookCode, GlobalOptions.Language) + ' ' + LanguageManager.GetString("String_Page", GlobalOptions.Language) + ' ' + strPage); }
/// <summary> /// Update the Mod's information based on the Mod selected and current Rating. /// </summary> private void UpdateGearInfo() { if (_blnSkipUpdate) { return; } _blnSkipUpdate = true; if (!string.IsNullOrEmpty(lstMod.Text)) { // Retireve the information for the selected Mod. // Filtering is also done on the Category in case there are non-unique names across categories. XmlNode objXmlMod = _objXmlDocument.SelectSingleNode("/chummer/mods/mod[id = \"" + lstMod.SelectedValue + "\"]"); // Extract the Avil and Cost values from the Gear info since these may contain formulas and/or be based off of the Rating. // This is done using XPathExpression. int intMinRating = 1; if (objXmlMod["minrating"]?.InnerText.Length > 0) { string strMinRating = ReplaceStrings(objXmlMod["minrating"]?.InnerText); intMinRating = Convert.ToInt32(CommonFunctions.EvaluateInvariantXPath(strMinRating)); } // If the rating is "qty", we're looking at Tires instead of actual Rating, so update the fields appropriately. if (objXmlMod["rating"].InnerText == "qty") { nudRating.Enabled = true; nudRating.Maximum = 20; while (nudRating.Maximum > intMinRating && !Backend.Shared_Methods.SelectionShared.CheckAvailRestriction(objXmlMod, _objCharacter, chkHideOverAvailLimit.Checked, decimal.ToInt32(nudRating.Maximum))) { nudRating.Maximum -= 1; } nudRating.Minimum = intMinRating; lblRatingLabel.Text = LanguageManager.GetString("Label_Qty"); } //Used for the Armor modifications. else if (objXmlMod["rating"].InnerText.ToLower() == "body") { nudRating.Maximum = _objVehicle.Body; while (nudRating.Maximum > intMinRating && !Backend.Shared_Methods.SelectionShared.CheckAvailRestriction(objXmlMod, _objCharacter, chkHideOverAvailLimit.Checked, decimal.ToInt32(nudRating.Maximum))) { nudRating.Maximum -= 1; } nudRating.Minimum = intMinRating; nudRating.Enabled = true; lblRatingLabel.Text = LanguageManager.GetString("Label_Body"); } //Used for Metahuman Adjustments. else if (objXmlMod["rating"].InnerText.ToLower() == "seats") { nudRating.Maximum = _objVehicle.TotalSeats; while (nudRating.Maximum > intMinRating && !Backend.Shared_Methods.SelectionShared.CheckAvailRestriction(objXmlMod, _objCharacter, chkHideOverAvailLimit.Checked, decimal.ToInt32(nudRating.Maximum))) { nudRating.Maximum -= 1; } nudRating.Minimum = intMinRating; nudRating.Enabled = true; lblRatingLabel.Text = LanguageManager.GetString("Label_Qty"); } else { if (Convert.ToInt32(objXmlMod["rating"].InnerText) > 0) { nudRating.Maximum = Convert.ToInt32(objXmlMod["rating"].InnerText); while (nudRating.Maximum > intMinRating && !Backend.Shared_Methods.SelectionShared.CheckAvailRestriction(objXmlMod, _objCharacter, chkHideOverAvailLimit.Checked, decimal.ToInt32(nudRating.Maximum))) { nudRating.Maximum -= 1; } nudRating.Minimum = intMinRating; nudRating.Enabled = true; lblRatingLabel.Text = LanguageManager.GetString("Label_Rating"); } else { nudRating.Minimum = 0; nudRating.Maximum = 0; nudRating.Enabled = false; lblRatingLabel.Text = LanguageManager.GetString("Label_Rating"); } } // Avail. // If avail contains "F" or "R", remove it from the string so we can use the expression. string strAvail = string.Empty; string strAvailExpr = objXmlMod["avail"].InnerText; if (strAvailExpr.StartsWith("FixedValues")) { int intRating = decimal.ToInt32(nudRating.Value - 1); strAvailExpr = strAvailExpr.TrimStart("FixedValues", true).Trim("()".ToCharArray()); string[] strValues = strAvailExpr.Split(','); if (intRating > strValues.Length || intRating < 0) { intRating = strValues.Length - 1; } strAvailExpr = strValues[intRating]; } if (strAvailExpr.EndsWith('F') || strAvailExpr.EndsWith('R')) { strAvail = strAvailExpr.Substring(strAvailExpr.Length - 1, 1); // Translate the Avail string. if (strAvail == "R") { strAvail = LanguageManager.GetString("String_AvailRestricted"); } else if (strAvail == "F") { strAvail = LanguageManager.GetString("String_AvailForbidden"); } // Remove the trailing character if it is "F" or "R". strAvailExpr = strAvailExpr.Substring(0, strAvailExpr.Length - 1); } try { lblAvail.Text = Convert.ToInt32(CommonFunctions.EvaluateInvariantXPath(ReplaceStrings(strAvailExpr))).ToString(); } catch (XPathException) { lblAvail.Text = objXmlMod["avail"].InnerText; } lblAvail.Text = lblAvail.Text + strAvail; // Cost. decimal decItemCost = 0; if (objXmlMod["cost"].InnerText.StartsWith("Variable")) { decimal decMin = 0; decimal decMax = decimal.MaxValue; string strCost = objXmlMod["cost"].InnerText; strCost = strCost.TrimStart("Variable", true).Trim("()".ToCharArray()); if (strCost.Contains('-')) { string[] strValues = strCost.Split('-'); decMin = Convert.ToDecimal(strValues[0], GlobalOptions.InvariantCultureInfo); decMax = Convert.ToDecimal(strValues[1], GlobalOptions.InvariantCultureInfo); } else { decMin = Convert.ToDecimal(strCost.FastEscape('+'), GlobalOptions.InvariantCultureInfo); } if (decMax == decimal.MaxValue) { lblCost.Text = decMin.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + "¥+"; } else { lblCost.Text = decMin.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + " - " + decMax.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + '¥'; } decItemCost = decMin; } else { string strCost = string.Empty; if (chkFreeItem.Checked) { strCost = "0"; } else { strCost = objXmlMod["cost"].InnerText; if (strCost.StartsWith("FixedValues")) { int intRating = decimal.ToInt32(nudRating.Value) - 1; strCost = strCost.TrimStart("FixedValues", true).Trim("()".ToCharArray()); string[] strValues = strCost.Split(','); if (intRating < 0 || intRating > strValues.Length) { intRating = 0; } strCost = strValues[intRating]; } strCost = ReplaceStrings(strCost); } decItemCost = Convert.ToDecimal(CommonFunctions.EvaluateInvariantXPath(strCost), GlobalOptions.InvariantCultureInfo); decItemCost *= _intModMultiplier; // Apply any markup. decItemCost *= 1 + (nudMarkup.Value / 100.0m); if (chkBlackMarketDiscount.Checked) { decItemCost *= 0.9m; } lblCost.Text = decItemCost.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + '¥'; } // Update the Avail Test Label. lblTest.Text = _objCharacter.AvailTest(decItemCost, lblAvail.Text); // Slots. string strSlots = string.Empty; if (objXmlMod["slots"].InnerText.StartsWith("FixedValues")) { string[] strValues = objXmlMod["slots"].InnerText.TrimStart("FixedValues", true).Trim("()".ToCharArray()).Split(','); strSlots = strValues[decimal.ToInt32(nudRating.Value) - 1]; } else { strSlots = objXmlMod["slots"].InnerText; } strSlots = ReplaceStrings(strSlots); lblSlots.Text = CommonFunctions.EvaluateInvariantXPath(strSlots).ToString(); if (objXmlMod["category"].InnerText != null) { if (_arrCategories.Contains(objXmlMod["category"].InnerText)) { lblVehicleCapacityLabel.Visible = true; lblVehicleCapacity.Visible = true; lblVehicleCapacity.Text = GetRemainingModCapacity(objXmlMod["category"].InnerText, Convert.ToInt32(lblSlots.Text)); tipTooltip.SetToolTip(lblVehicleCapacityLabel, LanguageManager.GetString("Tip_RemainingVehicleModCapacity")); } else { lblVehicleCapacityLabel.Visible = false; lblVehicleCapacity.Visible = false; } lblCategory.Text = objXmlMod["category"].InnerText; if (objXmlMod["category"].InnerText == "Weapon Mod") { lblCategory.Text = LanguageManager.GetString("String_WeaponModification"); } // Translate the Category if possible. else if (GlobalOptions.Language != GlobalOptions.DefaultLanguage) { XmlNode objXmlCategory = _objXmlDocument.SelectSingleNode("/chummer/modcategories/category[. = \"" + objXmlMod["category"].InnerText + "\"]"); if (objXmlCategory?.Attributes["translate"] != null) { lblCategory.Text = objXmlCategory.Attributes["translate"].InnerText; } } } if (objXmlMod["limit"] != null) { // Translate the Limit if possible. if (GlobalOptions.Language != GlobalOptions.DefaultLanguage) { XmlNode objXmlLimit = _objXmlDocument.SelectSingleNode("/chummer/limits/limit[. = \"" + objXmlMod["limit"].InnerText + "\"]"); lblLimit.Text = objXmlLimit.Attributes["translate"] != null ? " (" + objXmlLimit.Attributes["translate"].InnerText + ")" : " (" + objXmlMod["limit"].InnerText + ")"; } else { lblLimit.Text = " (" + objXmlMod["limit"].InnerText + ")"; } } else { lblLimit.Text = string.Empty; } string strBook = _objCharacter.Options.LanguageBookShort(objXmlMod["source"].InnerText); string strPage = objXmlMod["page"].InnerText; if (objXmlMod["altpage"] != null) { strPage = objXmlMod["altpage"].InnerText; } lblSource.Text = strBook + " " + strPage; tipTooltip.SetToolTip(lblSource, _objCharacter.Options.LanguageBookLong(objXmlMod["source"].InnerText) + " " + LanguageManager.GetString("String_Page") + " " + strPage); } _blnSkipUpdate = false; }
/// <summary> /// Calculate the LP value for the selected items. /// </summary> private async ValueTask CalculateValues(bool blnIncludePercentage = true) { if (_blnSkipRefresh) { return; } decimal decRoommates = await nudRoommates.DoThreadSafeFuncAsync(x => x.Value); decimal decBaseCost = 0; decimal decCost = 0; decimal decMod = 0; string strBaseLifestyle = string.Empty; // Get the base cost of the lifestyle string strSelectedId = await cboLifestyle.DoThreadSafeFuncAsync(x => x.SelectedValue?.ToString()); if (!string.IsNullOrEmpty(strSelectedId)) { XmlNode objXmlAspect = _objXmlDocument.SelectSingleNode("/chummer/lifestyles/lifestyle[id = " + strSelectedId.CleanXPath() + ']'); if (objXmlAspect != null) { objXmlAspect.TryGetStringFieldQuickly("name", ref strBaseLifestyle); decimal decTemp = 0; if (objXmlAspect.TryGetDecFieldQuickly("cost", ref decTemp)) { decBaseCost += decTemp; } string strSource = objXmlAspect["source"]?.InnerText; string strPage = objXmlAspect["altpage"]?.InnerText ?? objXmlAspect["page"]?.InnerText; if (!string.IsNullOrEmpty(strSource) && !string.IsNullOrEmpty(strPage)) { SourceString objSource = await SourceString.GetSourceStringAsync(strSource, strPage, GlobalSettings.Language, GlobalSettings.CultureInfo, _objCharacter); await objSource.SetControlAsync(lblSource); await lblSourceLabel.DoThreadSafeAsync(x => x.Visible = true); } else { lblSource.Text = string.Empty; await lblSource.SetToolTipAsync(string.Empty); await lblSourceLabel.DoThreadSafeAsync(x => x.Visible = false); } // Add the flat costs from qualities foreach (TreeNode objNode in await treQualities.DoThreadSafeFuncAsync(x => x.Nodes)) { if (objNode.Checked) { string strCost = _objXmlDocument.SelectSingleNode("/chummer/qualities/quality[id = " + objNode.Tag.ToString().CleanXPath() + "]/cost")?.InnerText; if (!string.IsNullOrEmpty(strCost)) { object objProcess = CommonFunctions.EvaluateInvariantXPath(strCost, out bool blnIsSuccess); if (blnIsSuccess) { decCost += Convert.ToDecimal(objProcess, GlobalSettings.InvariantCultureInfo); } } } } decimal decBaseMultiplier = 0; if (blnIncludePercentage) { // Add the modifiers from qualities foreach (TreeNode objNode in await treQualities.DoThreadSafeFuncAsync(x => x.Nodes)) { if (!objNode.Checked) { continue; } objXmlAspect = _objXmlDocument.SelectSingleNode("/chummer/qualities/quality[id = " + objNode.Tag.ToString().CleanXPath() + ']'); if (objXmlAspect == null) { continue; } if (objXmlAspect.TryGetDecFieldQuickly("multiplier", ref decTemp)) { decMod += decTemp / 100.0m; } if (objXmlAspect.TryGetDecFieldQuickly("multiplierbaseonly", ref decTemp)) { decBaseMultiplier += decTemp / 100.0m; } } // Check for modifiers in the improvements decMod += await ImprovementManager.ValueOfAsync(_objCharacter, Improvement.ImprovementType.LifestyleCost) / 100.0m; } decBaseCost += decBaseCost * decBaseMultiplier; if (decRoommates > 0) { decBaseCost *= 1.0m + Math.Max(decRoommates / 10.0m, 0); } } else { await lblSourceLabel.DoThreadSafeAsync(x => x.Visible = false); } } else { await lblSourceLabel.DoThreadSafeAsync(x => x.Visible = false); } decimal decNuyen = decBaseCost + decBaseCost * decMod + decCost; await lblCost.DoThreadSafeAsync(x => x.Text = decNuyen.ToString(_objCharacter.Settings.NuyenFormat, GlobalSettings.CultureInfo) + '¥'); decimal decPercentage = await nudPercentage.DoThreadSafeFuncAsync(x => x.Value); if (decPercentage != 100 || decRoommates != 0 && !await chkPrimaryTenant.DoThreadSafeFuncAsync(x => x.Checked)) { decimal decDiscount = decNuyen; decDiscount *= decPercentage / 100; if (decRoommates != 0) { decDiscount /= decRoommates; } string strSpace = await LanguageManager.GetStringAsync("String_Space"); await lblCost.DoThreadSafeAsync(x => x.Text += strSpace + '(' + decDiscount.ToString(_objCharacter.Settings.NuyenFormat, GlobalSettings.CultureInfo) + "¥)"); } await lblCost.DoThreadSafeFuncAsync(x => x.Text) .ContinueWith( y => lblCostLabel.DoThreadSafeAsync(x => x.Visible = !string.IsNullOrEmpty(y.Result))) .Unwrap(); // Characters with the Trust Fund Quality can have the lifestyle discounted. if (Lifestyle.StaticIsTrustFundEligible(_objCharacter, strBaseLifestyle)) { bool blnTrustFund = _objSourceLifestyle?.TrustFund ?? !await _objCharacter.Lifestyles.AnyAsync(x => x.TrustFund); await chkTrustFund.DoThreadSafeAsync(x => { x.Visible = true; x.Checked = blnTrustFund; }); } else { await chkTrustFund.DoThreadSafeAsync(x => { x.Checked = false; x.Visible = false; }); } }
/// <summary> /// Calculate the LP value for the selected items. /// </summary> private void CalculateValues(bool blnIncludePercentage = true) { if (_blnSkipRefresh) { return; } decimal decBaseCost = 0; decimal decCost = 0; decimal decMod = 0; string strBaseLifestyle = string.Empty; // Get the base cost of the lifestyle string strSelectedId = cboLifestyle.SelectedValue?.ToString(); if (strSelectedId != null) { XmlNode objXmlAspect = _objXmlDocument.SelectSingleNode("/chummer/lifestyles/lifestyle[id = " + strSelectedId.CleanXPath() + ']'); if (objXmlAspect != null) { objXmlAspect.TryGetStringFieldQuickly("name", ref strBaseLifestyle); decimal decTemp = 0; if (objXmlAspect.TryGetDecFieldQuickly("cost", ref decTemp)) { decBaseCost += decTemp; } string strSource = objXmlAspect["source"]?.InnerText; string strPage = objXmlAspect["altpage"]?.InnerText ?? objXmlAspect["page"]?.InnerText; if (!string.IsNullOrEmpty(strSource) && !string.IsNullOrEmpty(strPage)) { SourceString objSource = new SourceString(strSource, strPage, GlobalSettings.Language, GlobalSettings.CultureInfo, _objCharacter); lblSource.Text = objSource.ToString(); lblSource.SetToolTip(objSource.LanguageBookTooltip); } else { lblSource.Text = LanguageManager.GetString("String_Unknown"); lblSource.SetToolTip(LanguageManager.GetString("String_Unknown")); } lblSourceLabel.Visible = !string.IsNullOrEmpty(lblSource.Text); // Add the flat costs from qualities foreach (TreeNode objNode in treQualities.Nodes) { if (objNode.Checked) { string strCost = _objXmlDocument.SelectSingleNode("/chummer/qualities/quality[id = " + objNode.Tag.ToString().CleanXPath() + "]/cost")?.InnerText; if (!string.IsNullOrEmpty(strCost)) { object objProcess = CommonFunctions.EvaluateInvariantXPath(strCost, out bool blnIsSuccess); if (blnIsSuccess) { decCost += Convert.ToDecimal(objProcess, GlobalSettings.InvariantCultureInfo); } } } } decimal decBaseMultiplier = 0; if (blnIncludePercentage) { // Add the modifiers from qualities foreach (TreeNode objNode in treQualities.Nodes) { if (!objNode.Checked) { continue; } objXmlAspect = _objXmlDocument.SelectSingleNode("/chummer/qualities/quality[id = " + objNode.Tag.ToString().CleanXPath() + ']'); if (objXmlAspect == null) { continue; } if (objXmlAspect.TryGetDecFieldQuickly("multiplier", ref decTemp)) { decMod += decTemp / 100.0m; } if (objXmlAspect.TryGetDecFieldQuickly("multiplierbaseonly", ref decTemp)) { decBaseMultiplier += decTemp / 100.0m; } } // Check for modifiers in the improvements decMod += ImprovementManager.ValueOf(_objCharacter, Improvement.ImprovementType.LifestyleCost) / 100.0m; } decBaseCost += decBaseCost * decBaseMultiplier; if (nudRoommates.Value > 0) { decBaseCost *= 1.0m + Math.Max(nudRoommates.Value / 10.0m, 0); } } } decimal decNuyen = decBaseCost + decBaseCost * decMod + decCost; lblCost.Text = decNuyen.ToString(_objCharacter.Settings.NuyenFormat, GlobalSettings.CultureInfo) + '¥'; if (nudPercentage.Value != 100 || nudRoommates.Value != 0 && !chkPrimaryTenant.Checked) { decimal decDiscount = decNuyen; decDiscount *= nudPercentage.Value / 100; if (nudRoommates.Value != 0) { decDiscount /= nudRoommates.Value; } lblCost.Text += LanguageManager.GetString("String_Space") + '(' + decDiscount.ToString(_objCharacter.Settings.NuyenFormat, GlobalSettings.CultureInfo) + "¥)"; } lblCostLabel.Visible = !string.IsNullOrEmpty(lblCost.Text); // Characters with the Trust Fund Quality can have the lifestyle discounted. if (Lifestyle.StaticIsTrustFundEligible(_objCharacter, strBaseLifestyle)) { chkTrustFund.Visible = true; chkTrustFund.Checked = _objSourceLifestyle?.TrustFund ?? !_objCharacter.Lifestyles.Any(x => x.TrustFund); } else { chkTrustFund.Checked = false; chkTrustFund.Visible = false; } }
private void frmSelectLifestyle_Load(object sender, EventArgs e) { _blnSkipRefresh = true; foreach (Label objLabel in Controls.OfType <Label>()) { if (objLabel.Text.StartsWith('[')) { objLabel.Text = string.Empty; } } // Populate the Lifestyle ComboBoxes. List <ListItem> lstLifestyle = (from XmlNode objXmlLifestyle in _objXmlDocument.SelectNodes("/chummer/lifestyles/lifestyle[" + _objCharacter.Options.BookXPath() + "]") let strLifeStyleName = objXmlLifestyle["name"]?.InnerText where !string.IsNullOrEmpty(strLifeStyleName) && strLifeStyleName != "ID ERROR. Re-add life style to fix" && _objCharacter.Options.Books.Contains(objXmlLifestyle["source"]?.InnerText) select new ListItem { Value = strLifeStyleName, Name = objXmlLifestyle["translate"]?.InnerText ?? strLifeStyleName }).ToList(); cboLifestyle.BeginUpdate(); cboLifestyle.ValueMember = "Value"; cboLifestyle.DisplayMember = "Name"; cboLifestyle.DataSource = lstLifestyle; if (_objSourceLifestyle != null) { cboLifestyle.SelectedValue = _objLifestyle.BaseLifestyle; } if (cboLifestyle.SelectedIndex == -1) { cboLifestyle.SelectedIndex = 0; } cboLifestyle.EndUpdate(); // Fill the Options list. foreach (XmlNode objXmlOption in _objXmlDocument.SelectNodes("/chummer/qualities/quality[(source = \"" + "SR5" + "\" or category = \"" + "Contracts" + "\") and (" + _objCharacter.Options.BookXPath() + ")]")) { TreeNode nodOption = new TreeNode(); string strOptionName = objXmlOption["name"]?.InnerText; if (string.IsNullOrEmpty(strOptionName)) { continue; } XmlNode nodMultiplier = objXmlOption["multiplier"]; string strBaseString = string.Empty; if (nodMultiplier == null) { nodMultiplier = objXmlOption["multiplierbaseonly"]; strBaseString = " " + LanguageManager.GetString("Label_Base"); } nodOption.Tag = nodOption.Tag = objXmlOption["id"]?.InnerText; if (nodMultiplier != null && int.TryParse(nodMultiplier.InnerText, out int intCost)) { nodOption.Text = intCost > 0 ? $"{objXmlOption["translate"]?.InnerText ?? strOptionName} [+{intCost}{strBaseString}%]" : $"{objXmlOption["translate"]?.InnerText ?? strOptionName} [{intCost}{strBaseString}%]"; } else { string strCost = objXmlOption["cost"]?.InnerText ?? string.Empty; decimal decCost = 0.0m; if (!decimal.TryParse(strCost, out decCost)) { try { decCost = Convert.ToDecimal(CommonFunctions.EvaluateInvariantXPath(strCost)); } catch (XPathException) { decCost = 0.0m; } } nodOption.Text = $"{objXmlOption["translate"]?.InnerText ?? strOptionName} [{decCost.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo)}¥]"; } treQualities.Nodes.Add(nodOption); } SortTree(treQualities); if (_objSourceLifestyle != null) { txtLifestyleName.Text = _objSourceLifestyle.Name; if (!string.IsNullOrEmpty(_objSourceLifestyle.BaseLifestyle)) { cboLifestyle.SelectedValue = _objSourceLifestyle.BaseLifestyle; } nudRoommates.Value = _objSourceLifestyle.Roommates; nudPercentage.Value = _objSourceLifestyle.Percentage; foreach (LifestyleQuality objQuality in _objSourceLifestyle.LifestyleQualities) { foreach (TreeNode objNode in treQualities.Nodes) { if (objNode.Tag.ToString() == objQuality.SourceID) { objNode.Checked = true; break; } } } } _blnSkipRefresh = false; CalculateValues(); }
/// <summary> /// Calculate the LP value for the selected items. /// </summary> private decimal CalculateValues(bool blnIncludePercentage = true) { if (_blnSkipRefresh) { return(0); } decimal decBaseCost = 0; decimal decCost = 0; decimal baseMultiplier = 0; // Get the base cost of the lifestyle XmlNode objXmlAspect = _objXmlDocument.SelectSingleNode("/chummer/lifestyles/lifestyle[name = \"" + cboLifestyle.SelectedValue + "\"]"); decBaseCost += Convert.ToDecimal(objXmlAspect["cost"].InnerText, GlobalOptions.InvariantCultureInfo); lblSource.Text = objXmlAspect["source"].InnerText + " " + objXmlAspect["page"].InnerText; // Add the flat costs from qualities foreach (TreeNode objNode in treQualities.Nodes) { if (objNode.Checked) { XmlNode objXmlQuality = _objXmlDocument.SelectSingleNode($"/chummer/qualities/quality[id = \"{objNode.Tag}\"]"); if (!string.IsNullOrEmpty(objXmlQuality["cost"]?.InnerText)) { decimal decLoopCost = 0.0m; if (!decimal.TryParse(objXmlQuality["cost"].InnerText, out decLoopCost)) { try { decLoopCost = Convert.ToDecimal(CommonFunctions.EvaluateInvariantXPath(objXmlQuality["cost"].InnerText)); } catch (XPathException) { decLoopCost = 0.0m; } } decCost += decLoopCost; } } } decimal decMod = 0; if (blnIncludePercentage) { // Add the modifiers from qualities foreach (TreeNode objNode in treQualities.Nodes) { if (!objNode.Checked) { continue; } objXmlAspect = _objXmlDocument.SelectSingleNode($"/chummer/qualities/quality[id = \"{objNode.Tag}\"]"); if (!string.IsNullOrEmpty(objXmlAspect?["multiplier"]?.InnerText)) { decMod += Convert.ToDecimal(objXmlAspect["multiplier"].InnerText, GlobalOptions.InvariantCultureInfo) / 100.0m; } if (!string.IsNullOrEmpty(objXmlAspect?["multiplierbaseonly"]?.InnerText)) { baseMultiplier += Convert.ToDecimal(objXmlAspect["multiplierbaseonly"].InnerText, GlobalOptions.InvariantCultureInfo) / 100.0m; } } // Check for modifiers in the improvements decimal decModifier = Convert.ToDecimal(ImprovementManager.ValueOf(_objCharacter, Improvement.ImprovementType.LifestyleCost), GlobalOptions.InvariantCultureInfo); decMod += decModifier / 100.0m; } decBaseCost += decBaseCost * baseMultiplier; decimal decNuyen = decBaseCost + decBaseCost * decMod + decCost; lblCost.Text = decNuyen.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + '¥'; if (nudPercentage.Value != 100) { decimal decDiscount = decNuyen; decDiscount = decDiscount * (nudPercentage.Value / 100); lblCost.Text += " (" + decDiscount.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + '¥' + ")"; } return(decNuyen); }
private void SelectLifestyle_Load(object sender, EventArgs e) { string strSelectedId = string.Empty; // Populate the Lifestyle ComboBoxes. using (new FetchSafelyFromPool <List <ListItem> >(Utils.ListItemListPool, out List <ListItem> lstLifestyle)) { using (XmlNodeList xmlLifestyleList = _objXmlDocument.SelectNodes("/chummer/lifestyles/lifestyle[" + _objCharacter.Settings.BookXPath() + ']')) { if (xmlLifestyleList?.Count > 0) { foreach (XmlNode objXmlLifestyle in xmlLifestyleList) { string strLifeStyleId = objXmlLifestyle["id"]?.InnerText; if (!string.IsNullOrEmpty(strLifeStyleId) && !strLifeStyleId.IsEmptyGuid()) { string strName = objXmlLifestyle["name"]?.InnerText ?? LanguageManager.GetString("String_Unknown"); if (strName == _objSourceLifestyle?.BaseLifestyle) { strSelectedId = strLifeStyleId; } lstLifestyle.Add(new ListItem(strLifeStyleId, objXmlLifestyle["translate"]?.InnerText ?? strName)); } } } } cboLifestyle.BeginUpdate(); cboLifestyle.PopulateWithListItems(lstLifestyle); if (!string.IsNullOrEmpty(strSelectedId)) { cboLifestyle.SelectedValue = strSelectedId; } if (cboLifestyle.SelectedIndex == -1) { cboLifestyle.SelectedIndex = 0; } cboLifestyle.EndUpdate(); } // Populate the City ComboBox using (new FetchSafelyFromPool <List <ListItem> >(Utils.ListItemListPool, out List <ListItem> lstCity)) { using (XmlNodeList xmlCityList = _objXmlDocument.SelectNodes("/chummer/cities/city")) { if (xmlCityList?.Count > 0) { foreach (XmlNode objXmlCity in xmlCityList) { string strName = objXmlCity["name"]?.InnerText ?? LanguageManager.GetString("String_Unknown"); lstCity.Add(new ListItem(strName, objXmlCity["translate"]?.InnerText ?? strName)); } } } cboCity.BeginUpdate(); cboCity.PopulateWithListItems(lstCity); cboCity.EndUpdate(); } //Populate District and Borough ComboBox for the first time RefreshDistrictList(); RefreshBoroughList(); string strSpace = LanguageManager.GetString("String_Space"); // Fill the Options list. using (XmlNodeList xmlLifestyleOptionsList = _objXmlDocument.SelectNodes("/chummer/qualities/quality[(source = \"SR5\" or category = \"Contracts\") and (" + _objCharacter.Settings.BookXPath() + ")]")) { if (xmlLifestyleOptionsList?.Count > 0) { foreach (XmlNode objXmlOption in xmlLifestyleOptionsList) { string strOptionName = objXmlOption["name"]?.InnerText; if (string.IsNullOrEmpty(strOptionName)) { continue; } XmlNode nodMultiplier = objXmlOption["multiplier"]; string strBaseString = string.Empty; if (nodMultiplier == null) { nodMultiplier = objXmlOption["multiplierbaseonly"]; strBaseString = strSpace + LanguageManager.GetString("Label_Base"); } TreeNode nodOption = new TreeNode { Tag = objXmlOption["id"]?.InnerText }; if (nodMultiplier != null && int.TryParse(nodMultiplier.InnerText, out int intCost)) { nodOption.Text = (objXmlOption["translate"]?.InnerText ?? strOptionName) + strSpace + (intCost > 0 ? "[+" : "[") + intCost.ToString(GlobalSettings.CultureInfo) + strBaseString + "%]"; } else { string strCost = objXmlOption["cost"]?.InnerText; object objProcess = CommonFunctions.EvaluateInvariantXPath(strCost, out bool blnIsSuccess); decimal decCost = blnIsSuccess ? Convert.ToDecimal((double)objProcess) : 0; nodOption.Text = (objXmlOption["translate"]?.InnerText ?? strOptionName) + strSpace + '[' + decCost.ToString(_objCharacter.Settings.NuyenFormat, GlobalSettings.CultureInfo) + "¥]"; } treQualities.Nodes.Add(nodOption); } } } SortTree(treQualities); if (_objSourceLifestyle != null) { txtLifestyleName.Text = _objSourceLifestyle.Name; nudRoommates.Value = _objSourceLifestyle.Roommates; nudPercentage.Value = _objSourceLifestyle.Percentage; foreach (LifestyleQuality objQuality in _objSourceLifestyle.LifestyleQualities) { TreeNode objNode = treQualities.FindNode(objQuality.SourceIDString); if (objNode != null) { objNode.Checked = true; } } chkPrimaryTenant.Checked = _objSourceLifestyle.PrimaryTenant; chkTrustFund.Checked = _objSourceLifestyle.TrustFund; } _blnSkipRefresh = false; CalculateValues(); }
private async void lstDrug_SelectedIndexChanged(object sender, EventArgs e) { if (_blnLoading) { return; } _blnLoading = true; XPathNavigator xmlDrug = null; string strSelectedId = await lstDrug.DoThreadSafeFuncAsync(x => x.SelectedValue?.ToString()); if (!string.IsNullOrEmpty(strSelectedId)) { // Retrieve the information for the selected piece of Drug. xmlDrug = _xmlBaseDrugDataNode.SelectSingleNode(_strNodeXPath + "[id = " + strSelectedId.CleanXPath() + ']'); } string strForceGrade; if (xmlDrug != null) { strForceGrade = xmlDrug.SelectSingleNode("forcegrade")?.Value; // If the piece has a Rating value, enable the Rating control, otherwise, disable it and set its value to 0. XPathNavigator xmlRatingNode = xmlDrug.SelectSingleNode("rating"); if (xmlRatingNode != null) { string strMinRating = xmlDrug.SelectSingleNode("minrating")?.Value; int intMinRating = 1; // Not a simple integer, so we need to start mucking around with strings if (!string.IsNullOrEmpty(strMinRating) && !int.TryParse(strMinRating, out intMinRating)) { strMinRating = await strMinRating .CheapReplaceAsync("MaximumSTR", () => (ParentVehicle != null ? Math.Max(1, ParentVehicle.TotalBody * 2) : _objCharacter.STR.TotalMaximum) .ToString(GlobalSettings.InvariantCultureInfo)) .CheapReplaceAsync("MaximumAGI", () => (ParentVehicle != null ? Math.Max(1, ParentVehicle.Pilot * 2) : _objCharacter.AGI.TotalMaximum) .ToString(GlobalSettings.InvariantCultureInfo)) .CheapReplaceAsync("MinimumSTR", () => (ParentVehicle?.TotalBody ?? 3).ToString( GlobalSettings.InvariantCultureInfo)) .CheapReplaceAsync("MinimumAGI", () => (ParentVehicle?.Pilot ?? 3).ToString( GlobalSettings.InvariantCultureInfo)); object objProcess = CommonFunctions.EvaluateInvariantXPath(strMinRating, out bool blnIsSuccess); intMinRating = blnIsSuccess ? ((double)objProcess).StandardRound() : 1; } await nudRating.DoThreadSafeAsync(x => x.Minimum = intMinRating); string strMaxRating = xmlRatingNode.Value; int intMaxRating = 0; // Not a simple integer, so we need to start mucking around with strings if (!string.IsNullOrEmpty(strMaxRating) && !int.TryParse(strMaxRating, out intMaxRating)) { strMaxRating = await strMaxRating .CheapReplaceAsync("MaximumSTR", () => (ParentVehicle != null ? Math.Max(1, ParentVehicle.TotalBody * 2) : _objCharacter.STR.TotalMaximum) .ToString(GlobalSettings.InvariantCultureInfo)) .CheapReplaceAsync("MaximumAGI", () => (ParentVehicle != null ? Math.Max(1, ParentVehicle.Pilot * 2) : _objCharacter.AGI.TotalMaximum) .ToString(GlobalSettings.InvariantCultureInfo)) .CheapReplaceAsync("MinimumSTR", () => (ParentVehicle?.TotalBody ?? 3).ToString( GlobalSettings.InvariantCultureInfo)) .CheapReplaceAsync("MinimumAGI", () => (ParentVehicle?.Pilot ?? 3).ToString( GlobalSettings.InvariantCultureInfo)); object objProcess = CommonFunctions.EvaluateInvariantXPath(strMaxRating, out bool blnIsSuccess); intMaxRating = blnIsSuccess ? ((double)objProcess).StandardRound() : 1; } await nudRating.DoThreadSafeAsync(x => x.Maximum = intMaxRating); if (await chkHideOverAvailLimit.DoThreadSafeFuncAsync(x => x.Checked)) { int intAvailModifier = strForceGrade == "None" ? 0 : _intAvailModifier; await nudRating.DoThreadSafeAsync(x => { while (x.Maximum > intMinRating && !xmlDrug.CheckAvailRestriction(_objCharacter, x.MaximumAsInt, intAvailModifier)) { --x.Maximum; } }); } if (await chkShowOnlyAffordItems.DoThreadSafeFuncAsync(x => x.Checked) && !await chkFree.DoThreadSafeFuncAsync(x => x.Checked)) { decimal decCostMultiplier = 1 + nudMarkup.Value / 100.0m; if (await chkBlackMarketDiscount.DoThreadSafeFuncAsync(x => x.Checked)) { decCostMultiplier *= 0.9m; } await nudRating.DoThreadSafeAsync(x => { while (x.Maximum > intMinRating && !xmlDrug.CheckNuyenRestriction(_objCharacter.Nuyen, decCostMultiplier, x.MaximumAsInt)) { --x.Maximum; } }); } await nudRating.DoThreadSafeAsync(x => { x.Value = x.Minimum; x.Enabled = x.Minimum != x.Maximum; x.Visible = true; }); await lblRatingNALabel.DoThreadSafeAsync(x => x.Visible = false); await lblRatingLabel.DoThreadSafeAsync(x => x.Visible = true); } else { await lblRatingLabel.DoThreadSafeAsync(x => x.Visible = true); await lblRatingNALabel.DoThreadSafeAsync(x => x.Visible = true); await nudRating.DoThreadSafeAsync(x => { x.Minimum = 0; x.Value = 0; x.Visible = false; }); } string strSource = xmlDrug.SelectSingleNode("source")?.Value ?? await LanguageManager.GetStringAsync("String_Unknown"); string strPage = (await xmlDrug.SelectSingleNodeAndCacheExpressionAsync("altpage"))?.Value ?? xmlDrug.SelectSingleNode("page")?.Value ?? await LanguageManager.GetStringAsync("String_Unknown"); SourceString objSource = await SourceString.GetSourceStringAsync(strSource, strPage, GlobalSettings.Language, GlobalSettings.CultureInfo, _objCharacter); await objSource.SetControlAsync(lblSource); await lblSourceLabel.DoThreadSafeAsync(x => x.Visible = !string.IsNullOrEmpty(objSource.ToString())); Grade objForcedGrade = null; if (!string.IsNullOrEmpty(strForceGrade)) { // Force the Drug to be a particular Grade. await cboGrade.DoThreadSafeAsync(x => { if (x.Enabled) { x.Enabled = false; } }); objForcedGrade = _lstGrades.Find(x => x.Name == strForceGrade); strForceGrade = objForcedGrade?.SourceId.ToString("D", GlobalSettings.InvariantCultureInfo); } else { await cboGrade.DoThreadSafeAsync(x => x.Enabled = !_blnLockGrade); if (_blnLockGrade) { strForceGrade = _objForcedGrade?.SourceId.ToString("D", GlobalSettings.InvariantCultureInfo) ?? cboGrade.SelectedValue?.ToString(); objForcedGrade = _objForcedGrade ?? _lstGrades.Find(x => x.SourceId.ToString("D", GlobalSettings.InvariantCultureInfo) == strForceGrade); } } bool blnCanBlackMarketDiscount = _setBlackMarketMaps.Contains(xmlDrug.SelectSingleNode("category")?.Value); await chkBlackMarketDiscount.DoThreadSafeAsync(x => { x.Enabled = blnCanBlackMarketDiscount; if (!x.Checked) { x.Checked = GlobalSettings.AssumeBlackMarket && blnCanBlackMarketDiscount; } else if (!blnCanBlackMarketDiscount) { //Prevent chkBlackMarketDiscount from being checked if the category doesn't match. x.Checked = false; } }); // We may need to rebuild the Grade list since Cultured Bioware is not allowed to select Standard (Second-Hand) as Grade and ForceGrades can change. await PopulateGrades(xmlDrug.SelectSingleNode("nosecondhand") != null || !await cboGrade.DoThreadSafeFuncAsync(x => x.Enabled) && objForcedGrade?.SecondHand != true, false, strForceGrade); /* * string strNotes = xmlDrug.SelectSingleNode("altnotes")?.Value ?? xmlDrug.SelectSingleNode("notes")?.Value; * if (!string.IsNullOrEmpty(strNotes)) * { * await lblDrugNotesLabel.DoThreadSafeAsync(x => x.Visible = true); * await lblDrugNotes.DoThreadSafeAsync(x => * { * x.Text = strNotes; * x.Visible = true; * }); * } * else * { * await lblDrugNotes.DoThreadSafeAsync(x => x.Visible = false); * await lblDrugNotesLabel.DoThreadSafeAsync(x => x.Visible = false); * }*/ await tlpRight.DoThreadSafeAsync(x => x.Visible = true); } else { await tlpRight.DoThreadSafeAsync(x => x.Visible = false); await cboGrade.DoThreadSafeAsync(x => x.Enabled = !_blnLockGrade); strForceGrade = string.Empty; Grade objForcedGrade = null; if (_blnLockGrade) { strForceGrade = _objForcedGrade?.SourceId.ToString("D", GlobalSettings.InvariantCultureInfo) ?? await cboGrade.DoThreadSafeFuncAsync(x => x.SelectedValue?.ToString()); objForcedGrade = _objForcedGrade ?? _lstGrades.Find(x => x.SourceId.ToString("D", GlobalSettings.InvariantCultureInfo) == strForceGrade); } await PopulateGrades(_blnLockGrade && objForcedGrade?.SecondHand != true, false, strForceGrade); await chkBlackMarketDiscount.DoThreadSafeAsync(x => x.Checked = false); } _blnLoading = false; await UpdateDrugInfo(); }
private void UpdateGearInfo(bool blnUpdateMountCBOs = true) { if (_blnLoading) { return; } XPathNavigator xmlAccessory = null; string strSelectedId = lstAccessory.SelectedValue?.ToString(); // Retrieve the information for the selected Accessory. if (!string.IsNullOrEmpty(strSelectedId)) { xmlAccessory = _xmlBaseChummerNode.SelectSingleNode("accessories/accessory[id = " + strSelectedId.CleanXPath() + "]"); } if (xmlAccessory == null) { lblRC.Visible = false; lblRCLabel.Visible = false; nudRating.Enabled = false; nudRating.Visible = false; lblRatingLabel.Visible = false; lblRatingNALabel.Visible = false; lblMountLabel.Visible = false; cboMount.Visible = false; cboMount.Items.Clear(); lblExtraMountLabel.Visible = false; cboExtraMount.Visible = false; cboExtraMount.Items.Clear(); lblAvailLabel.Visible = false; lblAvail.Text = string.Empty; lblCostLabel.Visible = false; lblCost.Text = string.Empty; lblTestLabel.Visible = false; lblTest.Text = string.Empty; lblSourceLabel.Visible = false; lblSource.Text = string.Empty; lblSource.SetToolTip(string.Empty); return; } string strSpace = LanguageManager.GetString("String_Space"); string strRC = xmlAccessory.SelectSingleNode("rc")?.Value; if (!string.IsNullOrEmpty(strRC)) { lblRC.Visible = true; lblRCLabel.Visible = true; lblRC.Text = strRC; } else { lblRC.Visible = false; lblRCLabel.Visible = false; } if (int.TryParse(xmlAccessory.SelectSingleNode("rating")?.Value, out int intMaxRating) && intMaxRating > 0) { nudRating.Maximum = intMaxRating; if (chkHideOverAvailLimit.Checked) { while (nudRating.Maximum > nudRating.Minimum && !xmlAccessory.CheckAvailRestriction(_objCharacter, nudRating.MaximumAsInt)) { nudRating.Maximum -= 1; } } if (chkShowOnlyAffordItems.Checked && !chkFreeItem.Checked) { decimal decCostMultiplier = 1 + (nudMarkup.Value / 100.0m); if (_setBlackMarketMaps.Contains(xmlAccessory.SelectSingleNode("category")?.Value)) { decCostMultiplier *= 0.9m; } while (nudRating.Maximum > nudRating.Minimum && !xmlAccessory.CheckNuyenRestriction(_objCharacter.Nuyen, decCostMultiplier, nudRating.MaximumAsInt)) { nudRating.Maximum -= 1; } } nudRating.Enabled = nudRating.Maximum != nudRating.Minimum; nudRating.Visible = true; lblRatingLabel.Visible = true; lblRatingNALabel.Visible = false; } else { lblRatingNALabel.Visible = true; nudRating.Enabled = false; nudRating.Visible = false; lblRatingLabel.Visible = true; } if (blnUpdateMountCBOs) { string strDataMounts = xmlAccessory.SelectSingleNode("mount")?.Value; List <string> strMounts = new List <string>(); if (!string.IsNullOrEmpty(strDataMounts)) { strMounts.AddRange(strDataMounts.SplitNoAlloc('/', StringSplitOptions.RemoveEmptyEntries)); } strMounts.Add("None"); List <string> strAllowed = new List <string>(_lstAllowedMounts) { "None" }; cboMount.Visible = true; cboMount.Items.Clear(); foreach (string strCurrentMount in strMounts) { if (!string.IsNullOrEmpty(strCurrentMount)) { foreach (string strAllowedMount in strAllowed) { if (strCurrentMount == strAllowedMount) { cboMount.Items.Add(strCurrentMount); } } } } cboMount.Enabled = cboMount.Items.Count > 1; cboMount.SelectedIndex = 0; lblMountLabel.Visible = true; List <string> strExtraMounts = new List <string>(); string strExtraMount = xmlAccessory.SelectSingleNode("extramount")?.Value; if (!string.IsNullOrEmpty(strExtraMount)) { foreach (string strItem in strExtraMount.SplitNoAlloc('/', StringSplitOptions.RemoveEmptyEntries)) { strExtraMounts.Add(strItem); } } strExtraMounts.Add("None"); cboExtraMount.Items.Clear(); foreach (string strCurrentMount in strExtraMounts) { if (!string.IsNullOrEmpty(strCurrentMount)) { foreach (string strAllowedMount in strAllowed) { if (strCurrentMount == strAllowedMount) { cboExtraMount.Items.Add(strCurrentMount); } } } } cboExtraMount.Enabled = cboExtraMount.Items.Count > 1; cboExtraMount.SelectedIndex = 0; if (cboMount.SelectedItem.ToString() != "None" && cboExtraMount.SelectedItem.ToString() != "None" && cboMount.SelectedItem.ToString() == cboExtraMount.SelectedItem.ToString()) { cboExtraMount.SelectedIndex += 1; } cboExtraMount.Visible = cboExtraMount.Enabled && cboExtraMount.SelectedItem.ToString() != "None"; lblExtraMountLabel.Visible = cboExtraMount.Visible; } // Avail. // If avail contains "F" or "R", remove it from the string so we can use the expression. lblAvail.Text = new AvailabilityValue(Convert.ToInt32(nudRating.Value), xmlAccessory.SelectSingleNode("avail")?.Value).ToString(); lblAvailLabel.Visible = !string.IsNullOrEmpty(lblAvail.Text); if (!chkFreeItem.Checked) { string strCost = "0"; if (xmlAccessory.TryGetStringFieldQuickly("cost", ref strCost)) { strCost = strCost.CheapReplace("Weapon Cost", () => _objParentWeapon.OwnCost.ToString(GlobalOptions.InvariantCultureInfo)) .CheapReplace("Weapon Total Cost", () => _objParentWeapon.MultipliableCost(null).ToString(GlobalOptions.InvariantCultureInfo)) .Replace("Rating", nudRating.Value.ToString(GlobalOptions.CultureInfo)); } if (strCost.StartsWith("Variable(", StringComparison.Ordinal)) { decimal decMin; decimal decMax = decimal.MaxValue; strCost = strCost.TrimStartOnce("Variable(", true).TrimEndOnce(')'); if (strCost.Contains('-')) { string[] strValues = strCost.Split('-'); decimal.TryParse(strValues[0], NumberStyles.Any, GlobalOptions.InvariantCultureInfo, out decMin); decimal.TryParse(strValues[1], NumberStyles.Any, GlobalOptions.InvariantCultureInfo, out decMax); } else { decimal.TryParse(strCost.FastEscape('+'), NumberStyles.Any, GlobalOptions.InvariantCultureInfo, out decMin); } if (decMax == decimal.MaxValue) { lblCost.Text = decMin.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + "¥+"; } else { lblCost.Text = decMin.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + strSpace + '-' + strSpace + decMax.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + '¥'; } lblTest.Text = _objCharacter.AvailTest(decMax, lblAvail.Text); } else { object objProcess = CommonFunctions.EvaluateInvariantXPath(strCost, out bool blnIsSuccess); decimal decCost = blnIsSuccess ? Convert.ToDecimal(objProcess, GlobalOptions.InvariantCultureInfo) : 0; // Apply any markup. decCost *= 1 + (nudMarkup.Value / 100.0m); if (chkBlackMarketDiscount.Checked) { decCost *= 0.9m; } decCost *= _objParentWeapon.AccessoryMultiplier; if (!string.IsNullOrEmpty(_objParentWeapon.DoubledCostModificationSlots)) { string[] astrParentDoubledCostModificationSlots = _objParentWeapon.DoubledCostModificationSlots.Split('/', StringSplitOptions.RemoveEmptyEntries); if (astrParentDoubledCostModificationSlots.Contains(cboMount.SelectedItem?.ToString()) || astrParentDoubledCostModificationSlots.Contains(cboExtraMount.SelectedItem?.ToString())) { decCost *= 2; } } lblCost.Text = decCost.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + '¥'; lblTest.Text = _objCharacter.AvailTest(decCost, lblAvail.Text); } } else { lblCost.Text = (0.0m).ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + '¥'; lblTest.Text = _objCharacter.AvailTest(0, lblAvail.Text); } lblRatingLabel.Text = xmlAccessory.SelectSingleNode("ratinglabel") != null ? string.Format(GlobalOptions.CultureInfo, LanguageManager.GetString("Label_RatingFormat"), LanguageManager.GetString(xmlAccessory.SelectSingleNode("ratinglabel").Value)) : LanguageManager.GetString("Label_Rating"); lblCostLabel.Visible = !string.IsNullOrEmpty(lblCost.Text); lblTestLabel.Visible = !string.IsNullOrEmpty(lblTest.Text); if (!chkBlackMarketDiscount.Checked) { chkBlackMarketDiscount.Checked = GlobalOptions.AssumeBlackMarket && _blnIsParentWeaponBlackMarketAllowed; } else if (!_blnIsParentWeaponBlackMarketAllowed) { //Prevent chkBlackMarketDiscount from being checked if the gear category doesn't match. chkBlackMarketDiscount.Checked = false; } chkBlackMarketDiscount.Enabled = _blnIsParentWeaponBlackMarketAllowed; string strSource = xmlAccessory.SelectSingleNode("source")?.Value ?? LanguageManager.GetString("String_Unknown"); string strPage = xmlAccessory.SelectSingleNode("altpage")?.Value ?? xmlAccessory.SelectSingleNode("page")?.Value ?? LanguageManager.GetString("String_Unknown"); SourceString objSourceString = new SourceString(strSource, strPage, GlobalOptions.Language, GlobalOptions.CultureInfo, _objCharacter); objSourceString.SetControl(lblSource); lblSourceLabel.Visible = !string.IsNullOrEmpty(lblSource.Text); }
private void UpdateArmorInfo() { // Get the information for the selected piece of Armor. XmlNode objXmlArmor = _objXmlDocument.SelectSingleNode("/chummer/armors/armor[id = \"" + lstArmor.SelectedValue + "\"]"); if (objXmlArmor == null) { return; } // Create the Armor so we can show its Total Avail (some Armor includes Chemical Seal which adds +6 which wouldn't be factored in properly otherwise). Armor objArmor = new Armor(_objCharacter); TreeNode objNode = new TreeNode(); List <Weapon> lstWeapons = new List <Weapon>(); objArmor.Create(objXmlArmor, objNode, null, null, 0, lstWeapons, true, true, true); // Check for a Variable Cost. XmlElement xmlCostElement = objXmlArmor["cost"]; if (xmlCostElement != null) { decimal decItemCost = 0.0m; if (chkFreeItem.Checked) { lblCost.Text = 0.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + '¥'; decItemCost = 0; } else if (xmlCostElement.InnerText.StartsWith("Variable")) { decimal decMin; decimal decMax = decimal.MaxValue; string strCost = xmlCostElement.InnerText.TrimStart("Variable", true).Trim("()".ToCharArray()); if (strCost.Contains('-')) { string[] strValues = strCost.Split('-'); decMin = Convert.ToDecimal(strValues[0], GlobalOptions.InvariantCultureInfo); decMax = Convert.ToDecimal(strValues[1], GlobalOptions.InvariantCultureInfo); } else { decMin = Convert.ToDecimal(strCost.FastEscape('+'), GlobalOptions.InvariantCultureInfo); } if (decMax == decimal.MaxValue) { lblCost.Text = decMin.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + "¥+"; } else { lblCost.Text = decMin.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + " - " + decMax.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + '¥'; } decItemCost = decMin; } else if (xmlCostElement.InnerText.Contains("Rating")) { decItemCost = Convert.ToDecimal(CommonFunctions.EvaluateInvariantXPath(xmlCostElement.InnerText.Replace("Rating", nudRating.Value.ToString(GlobalOptions.InvariantCultureInfo))), GlobalOptions.InvariantCultureInfo); decItemCost *= 1 + (nudMarkup.Value / 100.0m); if (chkBlackMarketDiscount.Checked) { decItemCost *= 0.9m; } lblCost.Text = decItemCost.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + '¥'; } else { decItemCost = Convert.ToDecimal(xmlCostElement.InnerText, GlobalOptions.InvariantCultureInfo); decItemCost *= 1 + (nudMarkup.Value / 100.0m); if (chkBlackMarketDiscount.Checked) { decItemCost *= 0.9m; } lblCost.Text = decItemCost.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + '¥'; } lblCapacity.Text = objXmlArmor["armorcapacity"]?.InnerText; lblTest.Text = _objCharacter.AvailTest(decItemCost, lblAvail.Text); string strBook = _objCharacter.Options.LanguageBookShort(objXmlArmor["source"]?.InnerText, GlobalOptions.Language); string strPage = objXmlArmor["page"]?.InnerText; if (objXmlArmor["altpage"] != null) { strPage = objXmlArmor["altpage"].InnerText; } lblSource.Text = strBook + " " + strPage; tipTooltip.SetToolTip(lblSource, _objCharacter.Options.LanguageBookLong(objXmlArmor["source"]?.InnerText, GlobalOptions.Language) + " " + LanguageManager.GetString("String_Page", GlobalOptions.Language) + " " + strPage); } }
private void UpdateGearInfo() { if (_blnLoading) { return; } XPathNavigator xmlAccessory = null; string strSelectedId = lstAccessory.SelectedValue?.ToString(); // Retrieve the information for the selected Accessory. if (!string.IsNullOrEmpty(strSelectedId)) { xmlAccessory = _xmlBaseChummerNode.SelectSingleNode("accessories/accessory[id = \"" + strSelectedId + "\"]"); } if (xmlAccessory == null) { lblRC.Visible = false; lblRCLabel.Visible = false; nudRating.Enabled = false; nudRating.Visible = false; lblRatingLabel.Visible = false; lblRatingNALabel.Visible = false; lblMountLabel.Visible = false; cboMount.Visible = false; cboMount.Items.Clear(); lblExtraMountLabel.Visible = false; cboExtraMount.Visible = false; cboExtraMount.Items.Clear(); lblAvailLabel.Visible = false; lblAvail.Text = string.Empty; lblCostLabel.Visible = false; lblCost.Text = string.Empty; lblTestLabel.Visible = false; lblTest.Text = string.Empty; lblSourceLabel.Visible = false; lblSource.Text = string.Empty; lblSource.SetToolTip(string.Empty); return; } string strRC = xmlAccessory.SelectSingleNode("rc")?.Value; if (!string.IsNullOrEmpty(strRC)) { lblRC.Visible = true; lblRCLabel.Visible = true; lblRC.Text = strRC; } else { lblRC.Visible = false; lblRCLabel.Visible = false; } if (int.TryParse(xmlAccessory.SelectSingleNode("rating")?.Value, out int intMaxRating) && intMaxRating > 0) { nudRating.Maximum = intMaxRating; if (chkHideOverAvailLimit.Checked) { while (nudRating.Maximum > nudRating.Minimum && !SelectionShared.CheckAvailRestriction(xmlAccessory, _objCharacter, decimal.ToInt32(nudRating.Maximum))) { nudRating.Maximum -= 1; } } if (chkShowOnlyAffordItems.Checked && !chkFreeItem.Checked) { decimal decCostMultiplier = 1 + (nudMarkup.Value / 100.0m); if (_setBlackMarketMaps.Contains(xmlAccessory.SelectSingleNode("category")?.Value)) { decCostMultiplier *= 0.9m; } while (nudRating.Maximum > nudRating.Minimum && !SelectionShared.CheckNuyenRestriction(xmlAccessory, _objCharacter.Nuyen, decCostMultiplier, decimal.ToInt32(nudRating.Maximum))) { nudRating.Maximum -= 1; } } nudRating.Enabled = nudRating.Maximum != nudRating.Minimum; nudRating.Visible = true; lblRatingLabel.Visible = true; lblRatingNALabel.Visible = false; } else { lblRatingNALabel.Visible = true; nudRating.Enabled = false; nudRating.Visible = false; lblRatingLabel.Visible = true; } string[] astrDataMounts = xmlAccessory.SelectSingleNode("mount")?.Value.Split('/'); List <string> strMounts = new List <string>(); if (astrDataMounts != null) { strMounts.AddRange(astrDataMounts); } strMounts.Add("None"); List <string> strAllowed = new List <string>(_lstAllowedMounts) { "None" }; cboMount.Visible = true; cboMount.Items.Clear(); foreach (string strCurrentMount in strMounts) { if (!string.IsNullOrEmpty(strCurrentMount)) { foreach (string strAllowedMount in strAllowed) { if (strCurrentMount == strAllowedMount) { cboMount.Items.Add(strCurrentMount); } } } } cboMount.Enabled = cboMount.Items.Count > 1; cboMount.SelectedIndex = 0; lblMountLabel.Visible = true; List <string> strExtraMounts = new List <string>(); string strExtraMount = xmlAccessory.SelectSingleNode("extramount")?.Value; if (!string.IsNullOrEmpty(strExtraMount)) { foreach (string strItem in strExtraMount.Split('/')) { strExtraMounts.Add(strItem); } } strExtraMounts.Add("None"); cboExtraMount.Items.Clear(); foreach (string strCurrentMount in strExtraMounts) { if (!string.IsNullOrEmpty(strCurrentMount)) { foreach (string strAllowedMount in strAllowed) { if (strCurrentMount == strAllowedMount) { cboExtraMount.Items.Add(strCurrentMount); } } } } cboExtraMount.Enabled = cboExtraMount.Items.Count > 1; cboExtraMount.SelectedIndex = 0; if (cboMount.SelectedItem.ToString() != "None" && cboExtraMount.SelectedItem.ToString() != "None" && cboMount.SelectedItem.ToString() == cboExtraMount.SelectedItem.ToString()) { cboExtraMount.SelectedIndex += 1; } cboExtraMount.Visible = cboExtraMount.Enabled && cboExtraMount.SelectedItem.ToString() != "None"; lblExtraMountLabel.Visible = cboExtraMount.Visible; // Avail. // If avail contains "F" or "R", remove it from the string so we can use the expression. string strSuffix = string.Empty; string strAvail = xmlAccessory.SelectSingleNode("avail")?.Value; if (!string.IsNullOrWhiteSpace(strAvail)) { char chrLastAvailChar = strAvail[strAvail.Length - 1]; if (chrLastAvailChar == 'F') { strSuffix = LanguageManager.GetString("String_AvailForbidden", GlobalOptions.Language); strAvail = strAvail.Substring(0, strAvail.Length - 1); } else if (chrLastAvailChar == 'R') { strSuffix = LanguageManager.GetString("String_AvailRestricted", GlobalOptions.Language); strAvail = strAvail.Substring(0, strAvail.Length - 1); } object objProcess = CommonFunctions.EvaluateInvariantXPath(strAvail.Replace("Rating", nudRating.Value.ToString(GlobalOptions.CultureInfo)), out bool blnIsSuccess); lblAvail.Text = blnIsSuccess ? Convert.ToInt32(objProcess).ToString() : strAvail + strSuffix; } else { lblAvail.Text = "0"; } lblAvailLabel.Visible = !string.IsNullOrEmpty(lblAvail.Text); if (!chkFreeItem.Checked) { string strCost = "0"; if (xmlAccessory.TryGetStringFieldQuickly("cost", ref strCost)) { strCost = strCost.CheapReplace("Weapon Cost", () => _objParentWeapon.OwnCost.ToString(GlobalOptions.InvariantCultureInfo)) .Replace("Rating", nudRating.Value.ToString(GlobalOptions.CultureInfo)); } if (strCost.StartsWith("Variable(")) { decimal decMin; decimal decMax = decimal.MaxValue; strCost = strCost.TrimStartOnce("Variable(", true).TrimEndOnce(')'); if (strCost.Contains('-')) { string[] strValues = strCost.Split('-'); decimal.TryParse(strValues[0], NumberStyles.Any, GlobalOptions.InvariantCultureInfo, out decMin); decimal.TryParse(strValues[1], NumberStyles.Any, GlobalOptions.InvariantCultureInfo, out decMax); } else { decimal.TryParse(strCost.FastEscape('+'), NumberStyles.Any, GlobalOptions.InvariantCultureInfo, out decMin); } if (decMax == decimal.MaxValue) { lblCost.Text = decMin.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + "¥+"; } else { lblCost.Text = decMin.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + " - " + decMax.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + '¥'; } lblTest.Text = _objCharacter.AvailTest(decMax, lblAvail.Text); } else { object objProcess = CommonFunctions.EvaluateInvariantXPath(strCost, out bool blnIsSuccess); decimal decCost = blnIsSuccess ? Convert.ToDecimal(objProcess, GlobalOptions.InvariantCultureInfo) : 0; // Apply any markup. decCost *= 1 + (nudMarkup.Value / 100.0m); if (chkBlackMarketDiscount.Checked) { decCost *= 0.9m; } lblCost.Text = decCost.ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + '¥'; lblTest.Text = _objCharacter.AvailTest(decCost, lblAvail.Text); } } else { lblCost.Text = (0.0m).ToString(_objCharacter.Options.NuyenFormat, GlobalOptions.CultureInfo) + '¥'; lblTest.Text = _objCharacter.AvailTest(0, lblAvail.Text); } lblCostLabel.Visible = !string.IsNullOrEmpty(lblCost.Text); lblTestLabel.Visible = !string.IsNullOrEmpty(lblTest.Text); chkBlackMarketDiscount.Checked = _blnIsParentWeaponBlackMarketAllowed; string strSource = xmlAccessory.SelectSingleNode("source")?.Value ?? LanguageManager.GetString("String_Unknown", GlobalOptions.Language); string strPage = xmlAccessory.SelectSingleNode("altpage")?.Value ?? xmlAccessory.SelectSingleNode("page")?.Value ?? LanguageManager.GetString("String_Unknown", GlobalOptions.Language); string strSpaceCharacter = LanguageManager.GetString("String_Space", GlobalOptions.Language); lblSource.Text = CommonFunctions.LanguageBookShort(strSource, GlobalOptions.Language) + strSpaceCharacter + strPage; lblSource.SetToolTip(CommonFunctions.LanguageBookLong(strSource, GlobalOptions.Language) + strSpaceCharacter + LanguageManager.GetString("String_Page", GlobalOptions.Language) + strSpaceCharacter + strPage); lblSourceLabel.Visible = !string.IsNullOrEmpty(lblSource.Text); }
private async ValueTask UpdateGearInfo(bool blnUpdateMountComboBoxes = true) { if (_blnLoading) { return; } XPathNavigator xmlAccessory = null; string strSelectedId = await lstAccessory.DoThreadSafeFuncAsync(x => x.SelectedValue?.ToString()); // Retrieve the information for the selected Accessory. if (!string.IsNullOrEmpty(strSelectedId)) { xmlAccessory = _xmlBaseChummerNode.SelectSingleNode("accessories/accessory[id = " + strSelectedId.CleanXPath() + ']'); } if (xmlAccessory == null) { await tlpRight.DoThreadSafeAsync(x => x.Visible = false); return; } string strRC = xmlAccessory.SelectSingleNode("rc")?.Value; if (!string.IsNullOrEmpty(strRC)) { await lblRCLabel.DoThreadSafeAsync(x => x.Visible = true); await lblRC.DoThreadSafeAsync(x => { x.Visible = true; x.Text = strRC; }); } else { await lblRC.DoThreadSafeAsync(x => x.Visible = false); await lblRCLabel.DoThreadSafeAsync(x => x.Visible = false); } if (int.TryParse(xmlAccessory.SelectSingleNode("rating")?.Value, out int intMaxRating) && intMaxRating > 0) { await nudRating.DoThreadSafeAsync(x => x.Maximum = intMaxRating); if (await chkHideOverAvailLimit.DoThreadSafeFuncAsync(x => x.Checked)) { await nudRating.DoThreadSafeAsync(x => { while (x.Maximum > x.Minimum && !xmlAccessory.CheckAvailRestriction(_objCharacter, x.MaximumAsInt)) { --x.Maximum; } }); } if (await chkShowOnlyAffordItems.DoThreadSafeFuncAsync(x => x.Checked) && !await chkFreeItem.DoThreadSafeFuncAsync(x => x.Checked)) { decimal decCostMultiplier = 1 + (await nudMarkup.DoThreadSafeFuncAsync(x => x.Value) / 100.0m); if (_setBlackMarketMaps.Contains(xmlAccessory.SelectSingleNode("category")?.Value)) { decCostMultiplier *= 0.9m; } await nudRating.DoThreadSafeAsync(x => { while (x.Maximum > x.Minimum && !xmlAccessory.CheckNuyenRestriction(_objCharacter.Nuyen, decCostMultiplier, x.MaximumAsInt)) { --x.Maximum; } }); } await nudRating.DoThreadSafeAsync(x => { x.Enabled = nudRating.Maximum != nudRating.Minimum; x.Visible = true; }); await lblRatingLabel.DoThreadSafeAsync(x => x.Visible = true); await lblRatingNALabel.DoThreadSafeAsync(x => x.Visible = false); } else { await lblRatingNALabel.DoThreadSafeAsync(x => x.Visible = true); await nudRating.DoThreadSafeAsync(x => { x.Enabled = false; x.Visible = false; }); await lblRatingLabel.DoThreadSafeAsync(x => x.Visible = true); } if (blnUpdateMountComboBoxes) { string strDataMounts = xmlAccessory.SelectSingleNode("mount")?.Value; List <string> strMounts = new List <string>(1); if (!string.IsNullOrEmpty(strDataMounts)) { strMounts.AddRange(strDataMounts.SplitNoAlloc('/', StringSplitOptions.RemoveEmptyEntries)); } strMounts.Add("None"); List <string> strAllowed = new List <string>(_lstAllowedMounts) { "None" }; string strSelectedMount = await cboMount.DoThreadSafeFuncAsync(x => { x.Visible = true; x.Items.Clear(); foreach (string strCurrentMount in strMounts) { if (!string.IsNullOrEmpty(strCurrentMount)) { foreach (string strAllowedMount in strAllowed) { if (strCurrentMount == strAllowedMount) { x.Items.Add(strCurrentMount); } } } } x.Enabled = x.Items.Count > 1; x.SelectedIndex = 0; return(x.SelectedItem.ToString()); }); await lblMountLabel.DoThreadSafeAsync(x => x.Visible = true); List <string> strExtraMounts = new List <string>(1); string strExtraMount = xmlAccessory.SelectSingleNode("extramount")?.Value; if (!string.IsNullOrEmpty(strExtraMount)) { foreach (string strItem in strExtraMount.SplitNoAlloc('/', StringSplitOptions.RemoveEmptyEntries)) { strExtraMounts.Add(strItem); } } strExtraMounts.Add("None"); await cboExtraMount.DoThreadSafeFuncAsync(x => { x.Items.Clear(); foreach (string strCurrentMount in strExtraMounts) { if (!string.IsNullOrEmpty(strCurrentMount)) { foreach (string strAllowedMount in strAllowed) { if (strCurrentMount == strAllowedMount) { x.Items.Add(strCurrentMount); } } } } x.Enabled = x.Items.Count > 1; x.SelectedIndex = 0; if (strSelectedMount != "None" && x.SelectedItem.ToString() != "None" && strSelectedMount == x.SelectedItem.ToString()) { ++x.SelectedIndex; } x.Visible = x.Enabled && x.SelectedItem.ToString() != "None"; return(x.Visible); }).ContinueWith(y => lblExtraMountLabel.DoThreadSafeAsync(x => x.Visible = y.Result)).Unwrap(); } int intRating = await nudRating.DoThreadSafeFuncAsync(x => x.ValueAsInt); // Avail. // If avail contains "F" or "R", remove it from the string so we can use the expression. string strAvail = new AvailabilityValue(intRating, xmlAccessory.SelectSingleNode("avail")?.Value) .ToString(); await lblAvail.DoThreadSafeAsync(x => x.Text = strAvail); await lblAvailLabel.DoThreadSafeAsync(x => x.Visible = !string.IsNullOrEmpty(strAvail)); if (!await chkFreeItem.DoThreadSafeFuncAsync(x => x.Checked)) { string strCost = "0"; if (xmlAccessory.TryGetStringFieldQuickly("cost", ref strCost)) { strCost = (await strCost.CheapReplaceAsync("Weapon Cost", () => _objParentWeapon.OwnCost.ToString(GlobalSettings.InvariantCultureInfo)) .CheapReplaceAsync("Weapon Total Cost", () => _objParentWeapon.MultipliableCost(null) .ToString(GlobalSettings.InvariantCultureInfo))) .Replace("Rating", intRating.ToString(GlobalSettings.CultureInfo)); } if (strCost.StartsWith("Variable(", StringComparison.Ordinal)) { decimal decMin; decimal decMax = decimal.MaxValue; strCost = strCost.TrimStartOnce("Variable(", true).TrimEndOnce(')'); if (strCost.Contains('-')) { string[] strValues = strCost.Split('-'); decimal.TryParse(strValues[0], NumberStyles.Any, GlobalSettings.InvariantCultureInfo, out decMin); decimal.TryParse(strValues[1], NumberStyles.Any, GlobalSettings.InvariantCultureInfo, out decMax); } else { decimal.TryParse(strCost.FastEscape('+'), NumberStyles.Any, GlobalSettings.InvariantCultureInfo, out decMin); } if (decMax == decimal.MaxValue) { await lblCost.DoThreadSafeAsync( x => x.Text = decMin.ToString(_objCharacter.Settings.NuyenFormat, GlobalSettings.CultureInfo) + "¥+"); } else { string strSpace = await LanguageManager.GetStringAsync("String_Space"); await lblCost.DoThreadSafeAsync( x => x.Text = decMin.ToString(_objCharacter.Settings.NuyenFormat, GlobalSettings.CultureInfo) + strSpace + '-' + strSpace + decMax.ToString(_objCharacter.Settings.NuyenFormat, GlobalSettings.CultureInfo) + '¥'); } await lblTest.DoThreadSafeAsync(x => x.Text = _objCharacter.AvailTest(decMax, strAvail)); } else { object objProcess = CommonFunctions.EvaluateInvariantXPath(strCost, out bool blnIsSuccess); decimal decCost = blnIsSuccess ? Convert.ToDecimal(objProcess, GlobalSettings.InvariantCultureInfo) : 0; // Apply any markup. decCost *= 1 + (await nudMarkup.DoThreadSafeFuncAsync(x => x.Value) / 100.0m); if (await chkBlackMarketDiscount.DoThreadSafeFuncAsync(x => x.Checked)) { decCost *= 0.9m; } decCost *= _objParentWeapon.AccessoryMultiplier; if (!string.IsNullOrEmpty(_objParentWeapon.DoubledCostModificationSlots)) { string[] astrParentDoubledCostModificationSlots = _objParentWeapon.DoubledCostModificationSlots.Split('/', StringSplitOptions.RemoveEmptyEntries); if (astrParentDoubledCostModificationSlots.Contains(await cboMount.DoThreadSafeFuncAsync(x => x.SelectedItem?.ToString())) || astrParentDoubledCostModificationSlots.Contains(await cboExtraMount.DoThreadSafeFuncAsync(x => x.SelectedItem?.ToString()))) { decCost *= 2; } } await lblCost.DoThreadSafeAsync(x => x.Text = decCost.ToString(_objCharacter.Settings.NuyenFormat, GlobalSettings.CultureInfo) + '¥'); await lblTest.DoThreadSafeAsync(x => x.Text = _objCharacter.AvailTest(decCost, strAvail)); } } else { await lblCost.DoThreadSafeAsync(x => x.Text = (0.0m).ToString(_objCharacter.Settings.NuyenFormat, GlobalSettings.CultureInfo) + '¥'); await lblTest.DoThreadSafeAsync(x => x.Text = _objCharacter.AvailTest(0, strAvail)); } XPathNavigator xmlAccessoryRatingLabel = xmlAccessory.SelectSingleNode("ratinglabel"); string strRatingLabel = xmlAccessoryRatingLabel != null ? string.Format(GlobalSettings.CultureInfo, await LanguageManager.GetStringAsync("Label_RatingFormat"), await LanguageManager.GetStringAsync(xmlAccessoryRatingLabel.Value)) : await LanguageManager.GetStringAsync("Label_Rating"); await lblRatingLabel.DoThreadSafeAsync(x => x.Text = strRatingLabel); await lblCost.DoThreadSafeFuncAsync(x => x.Text) .ContinueWith(y => lblCostLabel.DoThreadSafeAsync(x => x.Visible = !string.IsNullOrEmpty(y.Result))) .Unwrap(); await lblTest.DoThreadSafeFuncAsync(x => x.Text) .ContinueWith(y => lblTestLabel.DoThreadSafeAsync(x => x.Visible = !string.IsNullOrEmpty(y.Result))) .Unwrap(); await chkBlackMarketDiscount.DoThreadSafeAsync(x => { x.Enabled = _blnIsParentWeaponBlackMarketAllowed; if (!x.Checked) { x.Checked = GlobalSettings.AssumeBlackMarket && _blnIsParentWeaponBlackMarketAllowed; } else if (!_blnIsParentWeaponBlackMarketAllowed) { //Prevent chkBlackMarketDiscount from being checked if the gear category doesn't match. x.Checked = false; } }); string strSource = xmlAccessory.SelectSingleNode("source")?.Value ?? await LanguageManager.GetStringAsync("String_Unknown"); string strPage = (await xmlAccessory.SelectSingleNodeAndCacheExpressionAsync("altpage"))?.Value ?? xmlAccessory.SelectSingleNode("page")?.Value ?? await LanguageManager.GetStringAsync("String_Unknown"); SourceString objSourceString = await SourceString.GetSourceStringAsync(strSource, strPage, GlobalSettings.Language, GlobalSettings.CultureInfo, _objCharacter); await objSourceString.SetControlAsync(lblSource); await lblSourceLabel.DoThreadSafeAsync(x => x.Visible = !string.IsNullOrEmpty(objSourceString.ToString())); await tlpRight.DoThreadSafeAsync(x => x.Visible = true); }