diff --git a/Legality/Analysis.cs b/Legality/Analysis.cs index 2f0337990..d2af0c807 100644 --- a/Legality/Analysis.cs +++ b/Legality/Analysis.cs @@ -29,7 +29,7 @@ public class LegalityAnalysis public LegalityCheck EC, Nickname, PID, IDs, IVs, EVs; public int[] ValidMoves => Legal.getValidMoves(pk6.Species, pk6.CurrentLevel); public int[] ValidRelearnMoves => Legal.getValidRelearn(pk6.Species); - public bool DexNav => Legal.getDexNavValid(pk6.Species, pk6.Met_Location, pk6.CurrentLevel); + public bool DexNav => Legal.getDexNavValid(pk6.Species, pk6.Met_Location, pk6.Met_Level, pk6.Version); public string Report => getLegalityReport(); private readonly PK6 pk6; @@ -71,16 +71,21 @@ public bool[] getRelearnValidity(int[] Moves) if (!pk6.Gen6) goto noRelearn; - bool egg = pk6.Egg_Location > 1000 || pk6.Egg_Location == 318; - bool evnt = pk6.Met_Location > 40000 || pk6.Egg_Location > 40000; + bool egg = Legal.EggLocations.Contains(pk6.Egg_Location) && pk6.Met_Level == 1; + bool evnt = pk6.FatefulEncounter && pk6.Met_Location > 40000; + bool eventEgg = pk6.FatefulEncounter && (pk6.Egg_Location > 40000 || pk6.Egg_Location == 30002) && pk6.Met_Level == 1; int[] relearnMoves = ValidRelearnMoves; - if (evnt) + if (evnt || eventEgg) { // Check Event Info // Not Implemented } else if (egg) { + if (new[] {25, 26, 172}.Contains(pk6.Species)) // + { + relearnMoves = relearnMoves.Concat(new[] {344}).ToArray(); + } for (int i = 0; i < 4; i++) res[i] &= relearnMoves.Contains(Moves[i]); return res; @@ -88,7 +93,7 @@ public bool[] getRelearnValidity(int[] Moves) else if (Moves[0] != 0) // DexNav only? { // Check DexNav - for (int i = 1; i < 4; i++) + for (int i = 0; i < 4; i++) res[i] &= Moves[i] == 0; if (DexNav) res[0] = relearnMoves.Contains(Moves[0]); diff --git a/Legality/Core.cs b/Legality/Core.cs index e628304ab..8541b3730 100644 --- a/Legality/Core.cs +++ b/Legality/Core.cs @@ -14,11 +14,29 @@ public static partial class Legal private static readonly EggMoves[] EggMoveAO = EggMoves.getArray(Util.unpackMini(Properties.Resources.eggmove_ao, "ao")); private static readonly Learnset[] LevelUpAO = Learnset.getArray(Util.unpackMini(Properties.Resources.lvlmove_ao, "ao")); private static readonly Evolutions[] Evolves = Evolutions.getArray(Util.unpackMini(Properties.Resources.evos_ao, "ao")); - private static readonly DexNavLocations[] DexNavAO = DexNavLocations.getArray(Util.unpackMini(Properties.Resources.dexnav_ao, "ao")); - - internal static bool getDexNavValid(int species, int location, int level) + private static readonly EncounterArea[] SlotsA = EncounterArea.getArray(Util.unpackMini(Properties.Resources.encounter_a, "ao")); + private static readonly EncounterArea[] SlotsO = EncounterArea.getArray(Util.unpackMini(Properties.Resources.encounter_o, "ao")); + private static readonly EncounterArea[] SlotsX = EncounterArea.getArray(Util.unpackMini(Properties.Resources.encounter_x, "xy")); + private static readonly EncounterArea[] SlotsY = EncounterArea.getArray(Util.unpackMini(Properties.Resources.encounter_y, "xy")); + private static readonly EncounterArea[] DexNavA = getDexNavSlots(SlotsA); + private static readonly EncounterArea[] DexNavO = getDexNavSlots(SlotsO); + private static EncounterArea[] getDexNavSlots(EncounterArea[] GameSlots) { - DexNavLocations[] locs = DexNavAO.Where(l => l.Location == location).ToArray(); + EncounterArea[] eA = new EncounterArea[GameSlots.Length]; + for (int i = 0; i < eA.Length; i++) + { + eA[i] = GameSlots[i]; + eA[i].Slots = eA[i].Slots.Take(20).Concat(eA[i].Slots.Skip(25)).ToArray(); // Skip 5 Rock Smash slots. + } + return eA; + } + + internal static bool getDexNavValid(int species, int location, int level, int Version) + { + bool alpha = Version == 26; + if (!alpha && Version != 27) + return false; + EncounterArea[] locs = (alpha ? DexNavA : DexNavO).Where(l => l.Location == location).ToArray(); return locs.Any(loc => loc.Slots.Any(slot => slot.Species == species && slot.LevelMin <= level)); } @@ -55,7 +73,6 @@ internal static int[] getValidRelearn(int species) moves = moves.Concat(getEggMoves(species)).ToArray(); moves = moves.Concat(getLVLMoves(species, 100)).ToArray(); return moves.Concat(new int[1]).Distinct().ToArray(); - // Not implemented: DexNav exclusive moves, Wonder Cards } private static int[] getEggMoves(int species) diff --git a/Legality/Data.cs b/Legality/Data.cs index 25d799f10..4a0d0b103 100644 --- a/Legality/Data.cs +++ b/Legality/Data.cs @@ -91,27 +91,31 @@ public static Evolutions[] getArray(byte[][] entries) } } - public class DexNavLocations + public class EncounterArea { public readonly int Location; - public readonly EncounterSlot[] Slots = new EncounterSlot[3]; - public DexNavLocations(byte[] data) + public EncounterSlot[] Slots; + public EncounterArea(byte[] data) { Location = BitConverter.ToUInt16(data, 0); + Slots = new EncounterSlot[(data.Length-2)/4]; for (int i = 0; i < Slots.Length; i++) { + ushort SpecForm = BitConverter.ToUInt16(data, 2 + i*4); Slots[i] = new EncounterSlot { - Species = BitConverter.ToUInt16(data, 2 + i*4), - LevelMin = BitConverter.ToUInt16(data, 4 + i*4) + Species = SpecForm & 0x7FF, + Form = SpecForm >> 11, + LevelMin = data[4 + i*4], + LevelMax = data[5 + i*4], }; } } - public static DexNavLocations[] getArray(byte[][] entries) + public static EncounterArea[] getArray(byte[][] entries) { - DexNavLocations[] data = new DexNavLocations[entries.Length]; + EncounterArea[] data = new EncounterArea[entries.Length]; for (int i = 0; i < data.Length; i++) - data[i] = new DexNavLocations(entries[i]); + data[i] = new EncounterArea(entries[i]); return data; } } diff --git a/Legality/Tables.cs b/Legality/Tables.cs index 80b952f1c..97b1b925d 100644 --- a/Legality/Tables.cs +++ b/Legality/Tables.cs @@ -209,5 +209,6 @@ public static partial class Legal internal static readonly int Struggle = 165; internal static readonly int Chatter = 448; internal static readonly int[] InvalidSketch = {Struggle, Chatter}; + internal static readonly int[] EggLocations = {318, 60002, 30002}; } } diff --git a/PKHeX.csproj b/PKHeX.csproj index 548746b86..d23e061f4 100644 --- a/PKHeX.csproj +++ b/PKHeX.csproj @@ -363,6 +363,12 @@ + + + + + + diff --git a/PKX/f1-Main.cs b/PKX/f1-Main.cs index 0845f7865..51f973353 100644 --- a/PKX/f1-Main.cs +++ b/PKX/f1-Main.cs @@ -1854,6 +1854,8 @@ private void updateOriginGame(object sender, EventArgs e) CB_EncounterType.SelectedValue = 0; setMarkings(); // Set/Remove KB marking + pk6.Met_Location = Util.getIndex(CB_MetLocation); + pk6.Egg_Location = Util.getIndex(CB_EggLocation); updateValidMoves(); } private void updateExtraByteValue(object sender, EventArgs e) diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs index ba5648511..3988cad2b 100644 --- a/Properties/Resources.Designer.cs +++ b/Properties/Resources.Designer.cs @@ -9786,16 +9786,6 @@ internal class Resources { } } - /// - /// Looks up a localized resource of type System.Byte[]. - /// - internal static byte[] dexnav_ao { - get { - object obj = ResourceManager.GetObject("dexnav_ao", resourceCulture); - return ((byte[])(obj)); - } - } - /// /// Looks up a localized resource of type System.Drawing.Bitmap. /// @@ -9866,6 +9856,46 @@ internal class Resources { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] encounter_a { + get { + object obj = ResourceManager.GetObject("encounter_a", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] encounter_o { + get { + object obj = ResourceManager.GetObject("encounter_o", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] encounter_x { + get { + object obj = ResourceManager.GetObject("encounter_x", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] encounter_y { + get { + object obj = ResourceManager.GetObject("encounter_y", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// diff --git a/Properties/Resources.resx b/Properties/Resources.resx index ea6718095..fb1d958fd 100644 --- a/Properties/Resources.resx +++ b/Properties/Resources.resx @@ -5761,7 +5761,16 @@ ..\Resources\img\warn.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\byte\dexnav_ao.pkl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\Resources\byte\encounter_a.pkl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\byte\encounter_o.pkl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\byte\encounter_x.pkl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\byte\encounter_y.pkl;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 \ No newline at end of file diff --git a/Resources/byte/dexnav_ao.pkl b/Resources/byte/dexnav_ao.pkl deleted file mode 100644 index b89834619..000000000 Binary files a/Resources/byte/dexnav_ao.pkl and /dev/null differ diff --git a/Resources/byte/encounter_a.pkl b/Resources/byte/encounter_a.pkl new file mode 100644 index 000000000..f7b359e18 Binary files /dev/null and b/Resources/byte/encounter_a.pkl differ diff --git a/Resources/byte/encounter_o.pkl b/Resources/byte/encounter_o.pkl new file mode 100644 index 000000000..ac34096cd Binary files /dev/null and b/Resources/byte/encounter_o.pkl differ diff --git a/Resources/byte/encounter_x.pkl b/Resources/byte/encounter_x.pkl new file mode 100644 index 000000000..514be6e1d Binary files /dev/null and b/Resources/byte/encounter_x.pkl differ diff --git a/Resources/byte/encounter_y.pkl b/Resources/byte/encounter_y.pkl new file mode 100644 index 000000000..856d80fb9 Binary files /dev/null and b/Resources/byte/encounter_y.pkl differ