private static double CalculatePerLevel(string parameter, int?op, int?op_param, string stat) { var para = Utility.ToNullableInt(parameter); if (!para.HasValue) { throw ItemStatCostException.Create($"Could not calculate per level, as parameter '{parameter}' is not a valid integer"); } var val = para.Value / 8d; return(val); }
public string PropertyString(int?value, int?value2, string parameter, int itemLevel) { string lstValue; var valueString = GetValueString(value, value2); if (DescriptonStringPositive == null) { lstValue = Stat; } else if (value2.HasValue && value2.Value < 0) { lstValue = DescriptionStringNegative; } else { lstValue = DescriptonStringPositive; } if (DescriptionFunction.HasValue) { if (DescriptionFunction.Value >= 1 && DescriptionFunction.Value <= 4 && lstValue.Contains("%d")) { valueString = lstValue.Replace("%d", valueString); DescriptionValue = 3; } else { switch (DescriptionFunction.Value) { case 1: valueString = $"+{valueString}"; break; case 2: valueString = $"{valueString}%"; break; case 3: valueString = $"{valueString}"; break; case 4: valueString = $"+{valueString}%"; break; case 5: if (value.HasValue) { value = value * 100 / 128; } if (value2.HasValue) { value2 = value2 * 100 / 128; } valueString = GetValueString(value, value2); valueString = $"{valueString}%"; break; case 6: double val1 = 0; double val2 = 0; if (value.HasValue && value2.HasValue) { val1 = CalculatePerLevel(value.Value.ToString(), Op, OpParam, Stat); val2 = CalculatePerLevel(value2.Value.ToString(), Op, OpParam, Stat); } else { val1 = CalculatePerLevel(parameter, Op, OpParam, Stat); val2 = CalculatePerLevel(parameter, Op, OpParam, Stat); } valueString = GetValueString(val1, val2); lstValue = DescriptonStringPositive; DescriptionValue = 3; valueString = $"+({valueString} Per Character Level) {Math.Floor(val1).ToString(CultureInfo.InvariantCulture)}-{Math.Floor(val2 * 99).ToString(CultureInfo.InvariantCulture)} {lstValue} (Based on Character Level)"; break; case 7: val1 = 0; val2 = 0; if (value.HasValue && value2.HasValue) { val1 = CalculatePerLevel(value.Value.ToString(), Op, OpParam, Stat); val2 = CalculatePerLevel(value2.Value.ToString(), Op, OpParam, Stat); } else { val1 = CalculatePerLevel(parameter, Op, OpParam, Stat); val2 = CalculatePerLevel(parameter, Op, OpParam, Stat); } valueString = GetValueString(val1, val2); lstValue = DescriptonStringPositive; DescriptionValue = 3; valueString = $"({valueString}% Per Character Level) {Math.Floor(val1).ToString(CultureInfo.InvariantCulture)}-{Math.Floor(val2 * 99).ToString(CultureInfo.InvariantCulture)}% {lstValue} (Based on Character Level)"; break; case 8: val1 = 0; val2 = 0; if (value.HasValue && value2.HasValue) { val1 = CalculatePerLevel(value.Value.ToString(), Op, OpParam, Stat); val2 = CalculatePerLevel(value2.Value.ToString(), Op, OpParam, Stat); } else { val1 = CalculatePerLevel(parameter, Op, OpParam, Stat); val2 = CalculatePerLevel(parameter, Op, OpParam, Stat); } valueString = GetValueString(val1, val2); lstValue = DescriptonStringPositive; DescriptionValue = 3; valueString = $"+({valueString} Per Character Level) {Math.Floor(val1).ToString(CultureInfo.InvariantCulture)}-{Math.Floor(val2 * 99).ToString(CultureInfo.InvariantCulture)} {lstValue} (Based on Character Level)"; break; case 9: val1 = 0; val2 = 0; if (value.HasValue && value2.HasValue) { val1 = CalculatePerLevel(value.Value.ToString(), Op, OpParam, Stat); val2 = CalculatePerLevel(value2.Value.ToString(), Op, OpParam, Stat); } else { val1 = CalculatePerLevel(parameter, Op, OpParam, Stat); val2 = CalculatePerLevel(parameter, Op, OpParam, Stat); } valueString = GetValueString(val1, val2); lstValue = DescriptonStringPositive; DescriptionValue = 3; valueString = $"{lstValue} {Math.Floor(val1).ToString(CultureInfo.InvariantCulture)}-{Math.Floor(val2 * 99).ToString(CultureInfo.InvariantCulture)} ({valueString} Per Character Level)"; break; case 11: valueString = lstValue.Replace("%d", $"{((double)(Utility.ToNullableInt(parameter).Value / 100f)).ToString(CultureInfo.InvariantCulture)}"); DescriptionValue = 3; break; case 12: valueString = $"+{valueString}"; break; case 13: var classReplace = ""; valueString = $"+{valueString}"; var regex = Regex.Match(parameter, @"randclassskill(\d+)"); // Work with custom randclasskill(digit) if (regex.Success) { classReplace = "(Random Class)"; valueString = $"+{regex.Groups[1].Value}"; } else if (parameter == "randclassskill") { classReplace = "(Random Class)"; valueString = "+3"; } else { if (!CharStat.CharStats.ContainsKey(parameter)) { throw ItemStatCostException.Create($"Could not find character class '{parameter}'\nNote: if you have made a custom version of 'randclassskill' to support different amount of skills change them to 'randclassskill<d>' for example 'randclassskill5' is supported."); } classReplace = CharStat.CharStats[parameter].Class; } lstValue = lstValue.Replace("%d", classReplace); break; case 14: var par = Utility.ToNullableInt(parameter); if (!par.HasValue) { throw ItemStatCostException.Create($"Could not convert parameter '{parameter}' to a valid integer"); } if (!CharStat.SkillTabs.ContainsKey(par.Value)) { throw ItemStatCostException.Create($"Could not find skill tab with id {par.Value}"); } var skillTab = CharStat.SkillTabs[par.Value]; var className = CharStat.CharStats.Values.First(x => x.StrSkillTab1 == skillTab || x.StrSkillTab2 == skillTab || x.StrSkillTab3 == skillTab).Class; if (!Table.Tables.ContainsKey(skillTab)) { throw ItemStatCostException.Create($"Could not find translation key '{skillTab}' in any .tbl file"); } lstValue = Table.Tables[skillTab]; valueString = $"{lstValue.Replace("%d", valueString)} ({className} only)"; break; case 15: valueString = value2.Value.ToString(); var skill = Skill.GetSkill(parameter); if (value2.Value == 0) { val1 = Math.Min(Math.Ceiling((itemLevel - (skill.RequiredLevel - 1)) / 3.9), 20); val2 = Math.Min(Math.Round((99 - (skill.RequiredLevel - 1)) / 3.9), 20); valueString = GetValueString(val1, val2); } valueString = lstValue.Replace("%d%", value.Value.ToString()) .Replace("%d", valueString) .Replace("%s", skill.SkillDesc); if (string.IsNullOrEmpty(skill.SkillDesc)) { throw ItemStatCostException.Create($"Skill for property has missing 'skilldesc' in Skills.txt: name: '{skill.Name}', id: '{skill.Id}'"); } break; case 16: valueString = lstValue.Replace("%d", valueString) .Replace("%s", Skill.GetSkill(parameter).Name); DescriptionValue = 3; break; case 20: valueString = $"{GetValueString(value * -1, value2 * -1)}%"; break; case 23: if (!MonStat.MonStats.ContainsKey(parameter)) { throw ItemStatCostException.Create($"Could not find monster with id '{parameter}' in MonStats.txt"); } valueString = $"{valueString}% {lstValue} {MonStat.MonStats[parameter].NameStr}"; DescriptionValue = 3; break; case 24: valueString = $"Level {value2} {Skill.GetSkill(parameter).Name} ({value} Charges)"; break; case 27: var charClass = Skill.GetSkill(parameter).CharClass; var reqString = ""; if (!string.IsNullOrEmpty(charClass)) { // Add requirement if one is there if (!CharStat.CharStats.ContainsKey(Skill.GetSkill(parameter).CharClass)) { throw ItemStatCostException.Create($"Could not find character skill tab '{Skill.GetSkill(parameter).CharClass}' property"); } reqString = $" ({CharStat.CharStats[Skill.GetSkill(parameter).CharClass].Class} Only)"; } valueString = $"+{valueString} to {Skill.GetSkill(parameter).Name}{reqString}"; break; case 28: valueString = $"+{valueString} to {Skill.GetSkill(parameter).Name}"; break; case 29: // Custom for sockets if (string.IsNullOrEmpty(valueString)) { valueString = parameter; } valueString = $"{lstValue} ({valueString})"; break; case 30: // Custom for elemental damage valueString = lstValue.Replace("%d", valueString).Replace("%s", parameter); break; default: // Not implemented function valueString = UnimplementedFunction(value, value2, parameter, Op, OpParam, DescriptionFunction.Value); DescriptionValue = 3; break; } } } // Remove +- in case it happens valueString = valueString.Replace("+-", "-"); if (DescriptionValue.HasValue && !string.IsNullOrEmpty(lstValue)) { switch (DescriptionValue.Value) { case 0: valueString = lstValue; break; case 1: valueString = $"{valueString} {lstValue}"; break; case 2: valueString = $"{lstValue} {valueString}"; break; case 3: // Used if the value already contain all information break; } } // Trim whitespace and remove trailing newline as we sometimes see those in the properties valueString = valueString.Trim().Replace("\\n", ""); return(valueString); }