/** * Grasscutter Tools * Copyright (C) 2022 jie65535 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * **/ using System; using System.Collections.Generic; using System.Linq; namespace GrasscutterTools.Utils { internal class SubstatSumEquality : IEqualityComparer>> { public bool Equals(List> left, List> right) { if (sum_substat(left) == sum_substat(right)) return true; else return false; } public int GetHashCode(List> dict) { return sum_substat(dict).GetHashCode(); } public static double sum_substat(List> dict) { double sum = 0; foreach (KeyValuePair kvp in dict) { sum += kvp.Value; } return sum; } } internal class ArtifactUtils { public static Dictionary substats_rolls = new Dictionary { { "hp", new double[][] { new double[] {23.9, 29.88}, new double[] {50.19, 60.95, 71.7}, new double[] {100.38, 114.72, 129.06, 143.4}, new double[] {167.3, 191.2, 215.1, 239}, new double[] {209.13, 239, 268.88, 298.75} } }, { "hp_", new double[][] { new double[] {1.17, 1.46}, new double[] {1.63, 1.98, 2.33}, new double[] {2.45, 2.8, 3.15, 3.5}, new double[] {3.26, 3.73, 4.2, 4.66}, new double[] {4.08, 4.66, 5.25, 5.83} } }, { "atk", new double[][] { new double[] {1.56, 1.95}, new double[] {3.27, 3.97, 4.67}, new double[] {6.54, 7.47, 8.4, 9.34}, new double[] {10.89, 12.45, 14, 15.56}, new double[] {13.62, 15.56, 17.51, 19.45 } } }, { "atk_", new double[][] { new double[] {1.17, 1.46}, new double[] {1.63, 1.98, 2.33}, new double[] {2.45, 2.8, 3.15, 3.5}, new double[] {3.26, 3.73, 4.2, 4.66}, new double[] {4.08, 4.66, 5.25, 5.83} } }, { "def", new double[][] { new double[] {1.85, 2.31}, new double[] {3.89, 4.72, 5.56}, new double[] {10, 11.11, 7.78, 8.89}, new double[] {12.96, 14.82, 16.67, 18.52}, new double[] {16.2, 18.52, 20.83, 23.15} } }, { "def_", new double[][] { new double[] {1.46, 1.82}, new double[] {2.04, 2.48, 2.91}, new double[] {3.06, 3.5, 3.93, 4.37}, new double[] {4.08, 4.66, 5.25, 5.83}, new double[] {5.1, 5.83, 6.56, 7.29} } }, { "critRate_", new double[][] { new double[] {.78, .97}, new double[] {1.09, 1.32, 1.55}, new double[] {1.63, 1.86, 2.1, 2.33}, new double[] {2.18, 2.49, 2.8, 3.11}, new double[] {2.72, 3.11, 3.5, 3.89} } }, { "critDMG_", new double[][] { new double[] {1.55, 1.94}, new double[] {2.18, 2.64, 3.11}, new double[] {3.26, 3.73, 4.2, 4.66}, new double[] {4.35, 4.97, 5.6, 6.22}, new double[] {5.44, 6.22, 6.99, 7.77} } }, { "eleMas", new double[][] { new double[] {4.66, 5.83}, new double[] {6.53, 7.93, 9.33}, new double[] {11.19, 12.59, 13.99, 9.79}, new double[] {13.06, 14.92, 16.79, 18.65}, new double[] {16.32, 18.65, 20.98, 23.31} } }, { "enerRech_", new double[][] { new double[] {1.3, 1.62}, new double[] {1.81, 2.2, 2.59}, new double[] {2.72, 3.11, 3.5, 3.89}, new double[] {3.63, 4.14, 4.66, 5.18}, new double[] {4.53, 5.18, 5.83, 6.48} } } }; // ArtifactSub -> Rarity -> Stat value -> Stat index list public static Dictionary>>> substats_dict; public static int[] SplitSubstats(string type, int rarity, double value) { if (!substats_initiated) { InitSubstats(); substats_initiated = true; } double last_stat_diff = 99999; int[] last_stat_list = { 4, 4, 4, 4, 4, 4 }; foreach (KeyValuePair value_to_list in substats_dict[type][rarity]) { if (Math.Abs(value - value_to_list.Key) >= last_stat_diff) { return last_stat_list; } last_stat_diff = value - value_to_list.Key; last_stat_list = value_to_list.Value; } // Default, should never happen return last_stat_list; } private static void InitSubstats() { substats_dict = new Dictionary>>>(); foreach (KeyValuePair stat_block_info in substats_rolls) { string stat_name = stat_block_info.Key; substats_dict[stat_name] = new Dictionary>>(); for (int rarity_index = 0; rarity_index < stat_block_info.Value.Length; rarity_index++) { var substat_options = new List>(); // Substat index == 0 means no substat upgrade substat_options.Add(new KeyValuePair(0, 0)); for (int substat_index = 0; substat_index < substats_rolls[stat_name][rarity_index].Length; substat_index++) { substat_options.Add(new KeyValuePair(substat_index + 1, substats_rolls[stat_name][rarity_index][substat_index])); } var substat_sum_data = (from s1 in substat_options from s2 in substat_options from s3 in substat_options from s4 in substat_options from s5 in substat_options from s6 in substat_options select new { s1, s2, s3, s4, s5, s6 }) .Select(x => new List> { x.s1, x.s2, x.s3, x.s4, x.s5, x.s6 }) .Distinct(new SubstatSumEquality()); var stats_map = new List>(); foreach (List> val in substat_sum_data.ToArray().OrderBy(list => SubstatSumEquality.sum_substat(list))) { var index_list = new List(); foreach (KeyValuePair pair in val) { if (pair.Key != 0) index_list.Add(pair.Key); } stats_map.Add(new KeyValuePair(SubstatSumEquality.sum_substat(val), index_list.ToArray())); } substats_dict[stat_name][rarity_index + 1] = stats_map; } } } private static bool substats_initiated = false; } }