public static int CalculateLevel(int speciesId, int exp) { var datarate = PokemonDatabase.GetData(speciesId).GrowthRate; switch (datarate) { case "Erratic": if (exp <= GrowthRatesLookup.Erratic[100]) { return(GrowthRatesLookup.Erratic.FindIndex(x => x <= exp)); } else { for (var i = 101; i <= 120; i++) { var expneeded = Math.Floor((Math.Pow(i, 3)) * (i * 6f / 10f / (100d * 1.0))); if (exp < expneeded) { return(i - 1); } } } break; case "Fast": if (exp <= GrowthRatesLookup.Fast[100]) { return(GrowthRatesLookup.Fast.FindIndex(x => x <= exp)); } else { return((int)Math.Floor(Math.Pow(((exp * 5f) / 4f), 1d / 3d))); } case "Medium": if (exp <= GrowthRatesLookup.Medium[100]) { return(GrowthRatesLookup.Medium.FindIndex(x => x <= exp)); } else { return((int)Math.Floor(Math.Pow(exp, 1d / 3d))); } case "Parabolic": if (exp <= GrowthRatesLookup.Parabolic[100]) { return(GrowthRatesLookup.Parabolic.FindIndex(x => x <= exp)); } else { for (var i = 101; i <= 120; i++) { var expneeded = Math.Floor(6 * (Math.Pow(i, 3) / 5) - 15 * (Math.Pow(i, 2)) + 100 * i - 140); if (exp < expneeded) { return(i - 1); } } } break; case "Slow": if (exp <= GrowthRatesLookup.Slow[100]) { return(GrowthRatesLookup.Slow.FindIndex(x => x <= exp)); } else { return((int)Math.Floor(Math.Pow((((float)exp * 4) / 5), 1d / 3d))); } case "Fluctuating": if (exp <= GrowthRatesLookup.Fluctuating[100]) { return(GrowthRatesLookup.Fluctuating.FindIndex(x => x <= exp)); } else { for (var i = 101; i <= 120; i++) { var rate = (i - 100) / 2; if (rate < 40) { rate = 40; } var expneeded = ((Math.Pow(i, 3)) * (((float)i * rate / 100) / 50.0)); if (exp < expneeded) { return(i - 1); } } } break; } return(120); }