diff --git a/pk3DS.Core/Game/GameConfig.cs b/pk3DS.Core/Game/GameConfig.cs index 8a32be6..752caea 100644 --- a/pk3DS.Core/Game/GameConfig.cs +++ b/pk3DS.Core/Game/GameConfig.cs @@ -122,6 +122,7 @@ public void InitializeAll() InitializeLearnset(); InitializeGameText(); InitializeMoves(); + InitializeEvos(); InitializeGameInfo(); } @@ -167,6 +168,20 @@ public void InitializeMoves() break; } } + public void InitializeEvos() + { + var g = GetGARCData("evolution"); + byte[][] d = g.Files; + switch (Generation) + { + case 6: + Evolutions = d.Select(z => new EvolutionSet6(z)).ToArray(); + break; + case 7: + Evolutions = d.Select(z => new EvolutionSet7(z)).ToArray(); + break; + } + } private void InitializeGameInfo() { @@ -247,6 +262,7 @@ public string GetGARCFileName(string requestedGARC) public Learnset[] Learnsets { get; private set; } public string[][] GameTextStrings { get; private set; } public Move[] Moves { get; private set; } + public EvolutionSet[] Evolutions { get; private set; } public bool XY => Version == GameVersion.XY; public bool ORAS => Version == GameVersion.ORAS || Version == GameVersion.ORASDEMO; diff --git a/pk3DS.Core/Randomizers/PersonalRandomizer.cs b/pk3DS.Core/Randomizers/PersonalRandomizer.cs index 71d6e3c..78ef1fe 100644 --- a/pk3DS.Core/Randomizers/PersonalRandomizer.cs +++ b/pk3DS.Core/Randomizers/PersonalRandomizer.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using pk3DS.Core.Structures; using pk3DS.Core.Structures.PersonalInfo; namespace pk3DS.Core.Randomizers @@ -41,6 +42,14 @@ public class PersonalRandomizer : IRandomizer public bool ModifyEggGroup = true; public decimal SameEggGroupChance = 50; + private const bool Advanced = false; + private const bool TMInheritance = false; + private const bool ModifyLearnsetSmartly = false; + + public ushort[] MoveIDsTMs { private get; set; } + public Move[] Moves => Game.Moves; + public EvolutionSet[] Evos => Game.Evolutions; + public PersonalRandomizer(PersonalInfo[] table, GameConfig game) { Game = game; @@ -56,15 +65,72 @@ public PersonalRandomizer(PersonalInfo[] table, GameConfig game) public void Execute() { - for (var i = 0; i < Table.Length; i++) + for (var i = 1; i < Table.Length; i++) Randomize(Table[i], i); + + if (TMInheritance) + PropagateTMs(Table, Evos); + } + + private void PropagateTMs(PersonalInfo[] table, EvolutionSet[] evos) + { + int specCount = Game.MaxSpeciesID; + var HandledIndexes = new HashSet(); + + for (int species = 1; species <= specCount; species++) + { + var entry = table[species]; + PropagateDown(entry, species, 0); + for (int form = 0; form < entry.FormeCount; form++) + PropagateDown(entry, species, form); + } + + void PropagateDown(PersonalInfo pi, int species, int form) + { + int index = pi.FormeIndex(species, form); + if (index == species && form != 0) + return; + + if (index >= evos.Length) + index = species; + PropagateDownIndex(pi, index); + } + + void PropagateDownIndex(PersonalInfo pi, int index) + { + if (HandledIndexes.Contains(index)) + return; + + var evoList = evos[index]; + foreach (var evo in evoList.PossibleEvolutions.Where(z => z.Species != 0)) + { + var espec = evo.Species; + var eform = evo.Form; + var evoIndex = table[espec].FormeIndex(espec, eform); + if (evoIndex >= table.Length) + continue; + + if (!HandledIndexes.Contains(evoIndex)) + table[evoIndex].TMHM = pi.TMHM; + else // pre-evolution encountered! take the higher evolution's TM's since they have been propagated up already... + pi.TMHM = table[evoIndex].TMHM; + + HandledIndexes.Add(evoIndex); + PropagateDownIndex(pi, evoIndex); // recurse for the rest of the evo chain + } + } } public void Randomize(PersonalInfo z, int index) { // Fiddle with Learnsets if (ModifyLearnsetTM || ModifyLearnsetHM) - RandomizeTMHM(z); + { + if (!ModifyLearnsetSmartly) + RandomizeTMHMSimple(z); + else + RandomizeTMHMAdvanced(z); + } if (ModifyLearnsetTypeTutors) RandomizeTypeTutors(z, index); if (ModifyLearnsetMoveTutors) @@ -85,7 +151,42 @@ public void Randomize(PersonalInfo z, int index) z.CatchRate = rnd.Next(3, 251); // Random Catch Rate between 3 and 250. } - private void RandomizeTMHM(PersonalInfo z) + private void RandomizeTMHMAdvanced(PersonalInfo z) + { + var tms = z.TMHM; + var types = z.Types; + + bool CanLearn(Move m) + { + var type = m.Type; + bool typeMatch = types.Any(t => t == type); + // todo: how do I learn move? + return rnd.Next(0, 100) < LearnTMPercent; + } + + if (ModifyLearnsetTM) + { + for (int j = 0; j < tmcount; j++) + { + var moveID = MoveIDsTMs[j]; + var move = Moves[moveID]; + tms[j] = CanLearn(move); + } + } + if (ModifyLearnsetHM) + { + for (int j = tmcount; j < tms.Length; j++) + { + var moveID = MoveIDsTMs[j]; + var move = Moves[moveID]; + tms[j] = CanLearn(move); + } + } + + z.TMHM = tms; + } + + private void RandomizeTMHMSimple(PersonalInfo z) { var tms = z.TMHM; diff --git a/pk3DS/Main.cs b/pk3DS/Main.cs index a728f61..327e24a 100644 --- a/pk3DS/Main.cs +++ b/pk3DS/Main.cs @@ -757,6 +757,7 @@ private void B_Evolution_Click(object sender, EventArgs e) break; } g.Files = d; + Config.InitializeEvos(); g.Save(); }).Start(); } diff --git a/pk3DS/Subforms/Gen6/EggMoveEditor6.cs b/pk3DS/Subforms/Gen6/EggMoveEditor6.cs index 677cd71..103f1a3 100644 --- a/pk3DS/Subforms/Gen6/EggMoveEditor6.cs +++ b/pk3DS/Subforms/Gen6/EggMoveEditor6.cs @@ -108,7 +108,7 @@ private void B_RandAll_Click(object sender, EventArgs e) ushort[] HMs = { 15, 19, 57, 70, 127, 249, 291 }; ushort[] TMs = { }; if (CHK_HMs.Checked && Main.ExeFSPath != null) - TMHMEditor6.getTMHMList(Main.Config.ORAS, ref TMs, ref HMs); + TMHMEditor6.getTMHMList(Main.Config.ORAS, out TMs, out HMs); List banned = new List { 165, 621 }; // Struggle, Hyperspace Fury if (!CHK_HMs.Checked) diff --git a/pk3DS/Subforms/Gen6/LevelUpEditor6.cs b/pk3DS/Subforms/Gen6/LevelUpEditor6.cs index ae55f2d..2cfd328 100644 --- a/pk3DS/Subforms/Gen6/LevelUpEditor6.cs +++ b/pk3DS/Subforms/Gen6/LevelUpEditor6.cs @@ -133,7 +133,7 @@ private void B_RandAll_Click(object sender, EventArgs e) ushort[] HMs = { 15, 19, 57, 70, 127, 249, 291 }; ushort[] TMs = {}; if (CHK_HMs.Checked && Main.ExeFSPath != null) - TMHMEditor6.getTMHMList(Main.Config.ORAS, ref TMs, ref HMs); + TMHMEditor6.getTMHMList(Main.Config.ORAS, out TMs, out HMs); List banned = new List {165, 621}; // Struggle, Hyperspace Fury if (!CHK_HMs.Checked) diff --git a/pk3DS/Subforms/Gen6/PersonalEditor6.cs b/pk3DS/Subforms/Gen6/PersonalEditor6.cs index 784b91d..ba2f17b 100644 --- a/pk3DS/Subforms/Gen6/PersonalEditor6.cs +++ b/pk3DS/Subforms/Gen6/PersonalEditor6.cs @@ -35,6 +35,7 @@ public PersonalEditor6(byte[][] infiles) abilities[0] = items[0] = moves[0] = ""; string[][] AltForms = Main.Config.Personal.getFormList(species, Main.Config.MaxSpeciesID); species = Main.Config.Personal.getPersonalEntryList(AltForms, species, Main.Config.MaxSpeciesID, out baseForms, out formVal); + TMHMEditor6.getTMHMList(Main.Config.ORAS, out TMs, out HMs); Setup(); //Turn string resources into arrays CB_Species.SelectedIndex = 1; @@ -78,13 +79,11 @@ public PersonalEditor6(byte[][] infiles) private readonly ushort[] tutor4 = { 380, 388, 180, 495, 270, 271, 478, 472, 283, 200, 278, 289, 446, 214, 285 }; private readonly int[] baseForms, formVal; + private readonly ushort[] TMs, HMs; int entry = -1; #endregion private void Setup() { - ushort[] TMs = new ushort[0]; - ushort[] HMs = new ushort[0]; - TMHMEditor6.getTMHMList(Main.Config.ORAS, ref TMs, ref HMs); CLB_TMHM.Items.Clear(); int hmcount = Main.Config.ORAS ? 7 : 5; @@ -364,7 +363,8 @@ private void B_Randomize_Click(object sender, EventArgs e) SameTypeChance = NUD_TypePercent.Value, SameEggGroupChance = NUD_Egg.Value, StatDeviation = NUD_StatDev.Value, - AllowWonderGuard = CHK_WGuard.Checked + AllowWonderGuard = CHK_WGuard.Checked, + MoveIDsTMs = TMs, }; rnd.Execute(); Main.SpeciesStat.Select(z => z.Write()).ToArray().CopyTo(files, 0); diff --git a/pk3DS/Subforms/Gen6/TMHMEditor6.cs b/pk3DS/Subforms/Gen6/TMHMEditor6.cs index 68b859e..e27d533 100644 --- a/pk3DS/Subforms/Gen6/TMHMEditor6.cs +++ b/pk3DS/Subforms/Gen6/TMHMEditor6.cs @@ -203,8 +203,10 @@ private void B_RandomTM_Click(object sender, EventArgs e) WinFormsUtil.Alert("Randomized!"); } - internal static void getTMHMList(bool oras, ref ushort[] TMs, ref ushort[] HMs) + internal static void getTMHMList(bool oras, out ushort[] TMs, out ushort[] HMs) { + TMs = new ushort[0]; + HMs = new ushort[0]; if (Main.ExeFSPath == null) return; string[] files = Directory.GetFiles(Main.ExeFSPath); if (!File.Exists(files[0]) || !Path.GetFileNameWithoutExtension(files[0]).Contains("code")) return; diff --git a/pk3DS/Subforms/Gen7/PersonalEditor7.cs b/pk3DS/Subforms/Gen7/PersonalEditor7.cs index 821ae66..950752e 100644 --- a/pk3DS/Subforms/Gen7/PersonalEditor7.cs +++ b/pk3DS/Subforms/Gen7/PersonalEditor7.cs @@ -30,7 +30,8 @@ public PersonalEditor7(byte[][] infiles) abilities[0] = items[0] = moves[0] = ""; var altForms = Main.Config.Personal.getFormList(species, Main.Config.MaxSpeciesID); entryNames = Main.Config.Personal.getPersonalEntryList(altForms, species, Main.Config.MaxSpeciesID, out baseForms, out formVal); - + TMs = TMEditor7.getTMHMList(); + Setup(); CB_Species.SelectedIndex = 1; RandSettings.GetFormSettings(this, TP_Randomizer.Controls); @@ -72,12 +73,11 @@ public PersonalEditor7(byte[][] infiles) }; private readonly int[] baseForms, formVal; + private readonly ushort[] TMs; int entry = -1; #endregion private void Setup() { - ushort[] TMs = new ushort[0]; - TMEditor7.getTMHMList(ref TMs); CLB_TM.Items.Clear(); if (TMs.Length == 0) // No ExeFS to grab TMs from. @@ -350,6 +350,7 @@ private void B_Randomize_Click(object sender, EventArgs e) StatDeviation = NUD_StatDev.Value, AllowWonderGuard = CHK_WGuard.Checked }; + rnd.Execute(); Main.SpeciesStat.Select(z => z.Write()).ToArray().CopyTo(files, 0); diff --git a/pk3DS/Subforms/Gen7/TMEditor7.cs b/pk3DS/Subforms/Gen7/TMEditor7.cs index 2b9f02d..6ed7b16 100644 --- a/pk3DS/Subforms/Gen7/TMEditor7.cs +++ b/pk3DS/Subforms/Gen7/TMEditor7.cs @@ -133,14 +133,17 @@ private void B_RandomTM_Click(object sender, EventArgs e) WinFormsUtil.Alert("Randomized!"); } - internal static void getTMHMList(ref ushort[] TMs) + internal static ushort[] getTMHMList() { - if (Main.ExeFSPath == null) return; + if (Main.ExeFSPath == null) + return new ushort[0]; string[] files = Directory.GetFiles(Main.ExeFSPath); - if (!File.Exists(files[0]) || !Path.GetFileNameWithoutExtension(files[0]).Contains("code")) return; + if (!File.Exists(files[0]) || !Path.GetFileNameWithoutExtension(files[0]).Contains("code")) + return new ushort[0]; byte[] data = File.ReadAllBytes(files[0]); int dataoffset = Util.IndexOfBytes(data, Signature, 0x400000, 0) + Signature.Length; - if (data.Length % 0x200 != 0) return; + if (data.Length % 0x200 != 0) + return new ushort[0]; if (Main.Config.USUM) dataoffset += 0x22; @@ -148,7 +151,7 @@ internal static void getTMHMList(ref ushort[] TMs) for (int i = 0; i < 100; i++) // TMs stored sequentially tms.Add(BitConverter.ToUInt16(data, dataoffset + (2 * i))); - TMs = tms.ToArray(); + return tms.ToArray(); } } } \ No newline at end of file