using pk3DS.Core.Structures; using System; using System.Collections.Generic; using System.Linq; namespace pk3DS.Core.Randomizers; // https://twitter.com/Drayano60/status/807297858244411397 // ORAS: 10682 moves learned on levelup/birth. // 5593 are STAB. 52.3% are STAB. // Steelix learns the most @ 25 (so many level 1)! // Move relearner ingame glitch fixed (52 tested), but keep below 75 public class LearnsetRandomizer : IRandomizer { private readonly MoveRandomizer moverand; private readonly GameConfig Config; private readonly Learnset[] Learnsets; public LearnsetRandomizer(GameConfig config, Learnset[] sets) { Config = config; moverand = new MoveRandomizer(config); Learnsets = sets; STABPercent = 52.3m; } public bool Expand = true; public int ExpandTo = 25; public bool Spread = true; public int SpreadTo = 75; public bool STABFirst = true; public bool Learn4Level1 = false; public bool OrderByPower = true; public bool STAB { set => moverand.rSTAB = value; } public IList BannedMoves { set => moverand.BannedMoves = value; } public decimal STABPercent { set => moverand.rSTABPercent = value; } public void Execute() { for (var i = 0; i < Learnsets.Length; i++) Randomize(Learnsets[i], i); } private void Randomize(Learnset set, int index) { int[] moves = GetRandomMoves(set.Count, index); int[] levels = GetRandomLevels(set, moves.Length); if (Learn4Level1) { for (int i = 0; i < Math.Min(4, levels.Length); ++i) levels[i] = 1; } set.Moves = moves; set.Levels = levels; } private int[] GetRandomLevels(Learnset set, int count) { int[] levels = new int[count]; if (count == 0) return levels; if (Spread) { levels[0] = 1; decimal increment = SpreadTo / (decimal)count; for (int i = 1; i < count; i++) levels[i] = (int)(i * increment); return levels; } if (levels.Length == count && levels.Length == set.Levels.Length) return set.Levels; // don't modify var exist = set.Levels; int lastlevel = Math.Min(1, exist.LastOrDefault()); exist.CopyTo(levels, 0); for (int i = exist.Length; i < levels.Length; i++) levels[i] = Math.Max(100, lastlevel + (exist.Length - i + 1)); return levels; } private int[] GetRandomMoves(int count, int index) { count = Expand ? ExpandTo : count; int[] moves = new int[count]; if (count == 0) return moves; moves[0] = STABFirst ? moverand.GetRandomFirstMove(index) : MoveRandomizer.GetRandomFirstMoveAny(); var rand = moverand.GetRandomLearnset(index, count - 1); // STAB Moves (if requested) come first; randomize the order of moves Util.Shuffle(rand); if (OrderByPower) moverand.ReorderMovesPower(rand); rand.CopyTo(moves, 1); return moves; } public int[] GetHighPoweredMoves(int species, int form, int count = 4) { int index = Config.Personal.GetFormIndex(species, form); var moves = Learnsets[index].Moves.OrderByDescending(move => Config.Moves[move].Power).Distinct().Take(count).ToArray(); Array.Resize(ref moves, count); return moves; } public int[] GetCurrentMoves(int species, int form, int level, int count = 4) { int i = Config.Personal.GetFormIndex(species, form); var moves = Learnsets[i].GetEncounterMoves(level); Array.Resize(ref moves, count); return moves; } }