private double?ParseDataReferenceString(string dRef) { dRef = GetPrecision(dRef, out int?precision); dRef = GetPlayer(dRef, out _); dRef = ParseValues(dRef.AsMemory()); if (string.IsNullOrEmpty(Regex.Replace(dRef, @"[/*+\-()]", string.Empty))) { return(null); } // extract the scaling string scalingText = GetScalingText(dRef, out _); if (!string.IsNullOrEmpty(scalingText)) { dRef = dRef.Replace(scalingText, string.Empty); } double number = HeroesMathEval.CalculatePathEquation(dRef); if (precision.HasValue) { return(Math.Round(number, precision.Value)); } else { return(Math.Round(number, 0)); } }
public void CalculatePathEquationTest() { Assert.AreEqual(100, HeroesMathEval.CalculatePathEquation("(12 + 6.000000) * (0.1875 + 0.062500) - (12 * 0.1875) / (12 * 0.1875) * 100")); Assert.AreEqual(50, HeroesMathEval.CalculatePathEquation("17 / 34 * 100")); Assert.AreEqual(70, HeroesMathEval.CalculatePathEquation("(57.8 / 34) * 100 - 100")); Assert.AreEqual(40, HeroesMathEval.CalculatePathEquation("-100*(1-1.400000)")); Assert.AreEqual(100, HeroesMathEval.CalculatePathEquation("--100")); Assert.AreEqual(15, HeroesMathEval.CalculatePathEquation("-100*-0.15")); Assert.AreEqual(150, HeroesMathEval.CalculatePathEquation("-100 * (0.225/-0.15)")); Assert.AreEqual(40, HeroesMathEval.CalculatePathEquation("(1+(-0.6)*100)")); Assert.AreEqual(30, HeroesMathEval.CalculatePathEquation("-(-0.6--0.3)*100")); Assert.AreEqual(70, HeroesMathEval.CalculatePathEquation("- (-0.7*100)")); Assert.AreEqual(-0.5, HeroesMathEval.CalculatePathEquation("-0.5")); Assert.AreEqual(0, HeroesMathEval.CalculatePathEquation("0")); Assert.AreEqual(100, HeroesMathEval.CalculatePathEquation("1+0*100")); Assert.AreEqual(100, HeroesMathEval.CalculatePathEquation("(1+0*100)")); Assert.AreEqual(60, HeroesMathEval.CalculatePathEquation("((5) + (3) / 5 - 1) * 100")); Assert.AreEqual(5, HeroesMathEval.CalculatePathEquation("(30/20)-1*10)")); // missing a (left) parenthesis Assert.AreEqual(9, HeroesMathEval.CalculatePathEquation("--100*-0.09")); }
private string ParseGameString(string tooltip, string splitter, bool nestedTooltip) { if (nestedTooltip) { tooltip = tooltip.Replace("'", "\""); } string[] parts = Regex.Split(tooltip, splitter); for (int i = 0; i < parts.Length; i++) { if (nestedTooltip) { if (!parts[i].Contains("[d ref=")) { continue; } } else { if (!parts[i].Contains("<d ref=") && !parts[i].Contains("<d const=")) { continue; } } string pathLookup = parts[i]; // get and remove precision pathLookup = GetPrecision(pathLookup, out int?precision); // remove the player pathLookup = GetPlayer(pathLookup, out _); // perform xml data lookup to find values string mathPath = ParseValues(pathLookup.AsMemory()); if (string.IsNullOrEmpty(Regex.Replace(mathPath, @"[/*+\-()]", string.Empty))) { return(string.Empty); } // extract the scaling and the amount string scalingText = GetScalingText(mathPath, out int numOfScalingTexts); if (!string.IsNullOrEmpty(scalingText)) { mathPath = mathPath.Replace(scalingText, string.Empty); } double number = HeroesMathEval.CalculatePathEquation(mathPath.Trim('/')); if (precision.HasValue) { parts[i] = Math.Round(number, precision.Value).ToString(); } else { parts[i] = Math.Round(number, 0).ToString(); } if (!string.IsNullOrEmpty(scalingText)) { // only add the scaling in certain cases if (numOfScalingTexts == 1 || (numOfScalingTexts > 1 && !mathPath.Contains('/'))) { ReadOnlySpan <char> nextPart = parts[i + 1]; nextPart = nextPart.TrimStart(); if (nextPart.StartsWith("%")) { parts[i] += $"%{scalingText}"; parts[i + 1] = parts[i + 1].ReplaceFirst("%", string.Empty); } else { parts[i] += $"{scalingText}"; } } } } if (nestedTooltip) { return(string.Join(string.Empty, parts)); } else { string joinDesc = string.Join(string.Empty, parts); foreach (Match match in Regex.Matches(joinDesc, @"[a-z]+""[a-z]+")) { joinDesc = joinDesc.Replace(match.Value, match.Value.Replace("\"", "'")); } return(DescriptionValidator.Validate(joinDesc)); } }