diff --git a/PKHeX/Legality/Core.cs b/PKHeX/Legality/Core.cs index 6d11414d0..4dcb9b257 100644 --- a/PKHeX/Legality/Core.cs +++ b/PKHeX/Legality/Core.cs @@ -507,10 +507,7 @@ private static EncounterArea[] getTables2(GameVersion Version) var D_HoneyTrees_Slots = SlotsD_HoneyTree.Clone(HoneyTreesLocation); var P_HoneyTrees_Slots = SlotsP_HoneyTree.Clone(HoneyTreesLocation); var Pt_HoneyTrees_Slots = SlotsPt_HoneyTree.Clone(HoneyTreesLocation); - - MarkG4SwarmSlots(ref D_Slots, SlotsDP_Swarm); - MarkG4SwarmSlots(ref P_Slots, SlotsDP_Swarm); - MarkG4SwarmSlots(ref Pt_Slots, SlotsPt_Swarm); + MarkG4SwarmSlots(ref HG_Slots, SlotsHG_Swarm); MarkG4SwarmSlots(ref SS_Slots, SlotsSS_Swarm); diff --git a/PKHeX/Legality/Structures/EncounterArea.cs b/PKHeX/Legality/Structures/EncounterArea.cs index 2f38c368b..f2e811d50 100644 --- a/PKHeX/Legality/Structures/EncounterArea.cs +++ b/PKHeX/Legality/Structures/EncounterArea.cs @@ -313,7 +313,7 @@ private static IEnumerable getSlots3_F(byte[] data, ref int ofs, return slots; } - private static EncounterSlot[] getSlots4_DPPt_G(byte[] data, ref int ofs, int numslots, SlotType t) + private static EncounterSlot[] getSlots4_DPPt_G(byte[] data, int ofs, int numslots, SlotType t) { var slots = new EncounterSlot[numslots]; @@ -330,11 +330,9 @@ private static EncounterSlot[] getSlots4_DPPt_G(byte[] data, ref int ofs, int nu Type = t }; } - - ofs += numslots * 8; return slots; } - private static EncounterSlot[] getSlots4_HGSS_G(byte[] data, ref int ofs, int numslots, SlotType t) + private static EncounterSlot[] getSlots4_HGSS_G(byte[] data, int ofs, int numslots, SlotType t) { var slots = new EncounterSlot[numslots * 3]; // First 36 slots are morning, day and night grass slots @@ -351,24 +349,17 @@ private static EncounterSlot[] getSlots4_HGSS_G(byte[] data, ref int ofs, int nu SlotNumber = i, Type = t }; - } - for (int i = 0; i < numslots; i++) - { slots[numslots + i] = slots[i].Clone(); slots[numslots + i].Species = BitConverter.ToUInt16(data, ofs + numslots * 3 + i * 2); slots[numslots + i].Type = t; - } - for (int i = 0; i < numslots; i++) - { slots[numslots * 2 + i] = slots[i].Clone(); slots[numslots * 2 + i].Species = BitConverter.ToUInt16(data, ofs + numslots * 5 + i * 2); slots[numslots * 2 + i].Type = t; } - ofs += numslots * 7; return slots; } - private static IEnumerable getSlots4_G_Replace(byte[] data, ref int ofs, int slotSize, EncounterSlot[] ReplacedSlots, int[] slotnums, SlotType t = SlotType.Grass) + private static IEnumerable getSlots4_G_Replace(byte[] data, int ofs, int slotSize, EncounterSlot[] ReplacedSlots, int[] slotnums, SlotType t = SlotType.Grass) { //Special slots like GBA Dual Slot. Those slot only contain the info of species id, the level is copied from one of the first grass slots //for dppt slotSize = 4, for hgss slotSize = 2 @@ -382,7 +373,7 @@ private static IEnumerable getSlots4_G_Replace(byte[] data, ref i continue; int species = BitConverter.ToUInt16(data, ofs + i / (4 / slotSize) * slotSize); - if (species <= 0) + if (species <= 0 || baseSlot.Species == species) // Empty or duplicate continue; var slot = baseSlot.Clone(); @@ -390,38 +381,9 @@ private static IEnumerable getSlots4_G_Replace(byte[] data, ref i slot.Type = t; slots.Add(slot); } - - ofs += numslots * slotSize * slotSize / 4; return slots; } - - private static IEnumerable getSlots4_G_TimeReplace(byte[] data, ref int ofs, EncounterSlot[] GrassSlots, SlotType t, int[] slotnums) - { - var slots = new List(); - // Slots for day, morning and night slots in DPPt. Only contain species data, level is copy from grass slot - for (int i = 0; i < 3; i++) - { - for (int j = 0; j < 2; j++) - { - int species = BitConverter.ToInt32(data, ofs + j * 4); - if (species <= 0) - continue; - - var slot = GrassSlots[slotnums[j]].Clone(); - slot.Species = species; - slot.Type = t; - slots.Add(slot); - } - ofs += 8; - } - - // Even if the three time replacer slots overwrite the original grass slot it still possible for that encounter to happen - // Original encounter should not be removed - - // Grass slots with species = 0 are added too, it is needed for the swarm encounters, it will be deleted after add swarms - return GrassSlots.Concat(slots); - } - private static IEnumerable getSlots4DPPt_WFR(byte[] data, ref int ofs, int numslots, SlotType t) + private static IEnumerable getSlots4DPPt_WFR(byte[] data, int ofs, int numslots, SlotType t) { var slots = new List(); for (int i = 0; i < numslots; i++) @@ -439,12 +401,10 @@ private static IEnumerable getSlots4DPPt_WFR(byte[] data, ref int Species = Species, Type = t }); - } - ofs += numslots * 8; return slots; } - private static IEnumerable getSlots4HGSS_WFR(byte[] data, ref int ofs, int numslots, SlotType t) + private static IEnumerable getSlots4HGSS_WFR(byte[] data, int ofs, int numslots, SlotType t) { var slots = new List(); for (int i = 0; i < numslots; i++) @@ -464,7 +424,6 @@ private static IEnumerable getSlots4HGSS_WFR(byte[] data, ref int Type = t }); } - ofs += numslots * 4; return slots; } @@ -498,61 +457,51 @@ private static EncounterArea getArea3(byte[] data) private static EncounterArea getArea4DPPt(byte[] data) { EncounterArea Area4 = new EncounterArea(); - if (data.Length != 426) + if (data.Length != 0x1AA) // 426 Bytes { Area4.Location = 0; Area4.Slots = new EncounterSlot[0]; return Area4; } var Slots = new List(); - Area4.Location = BitConverter.ToUInt16(data, 0); + Area4.Location = BitConverter.ToUInt16(data, 0x00); - var GrassRatio = BitConverter.ToInt32(data, 2); - var ofs = 6; + var GrassRatio = BitConverter.ToInt32(data, 0x02); if (GrassRatio > 0) { - EncounterSlot[] GrassSlots = getSlots4_DPPt_G(data, ref ofs, 12, SlotType.Grass); - //Morning, Day and Night slots replace slots 2 and 3 - Slots.AddRange(getSlots4_G_TimeReplace(data, ref ofs, GrassSlots, SlotType.Grass, Legal.Slot4_Time)); - //Pokéradar slots replace slots 6,7,10 and 11 + EncounterSlot[] GrassSlots = getSlots4_DPPt_G(data, 0x06, 12, SlotType.Grass); + Slots.AddRange(GrassSlots); + //Swarming slots replace slots 0 and 1 + Slots.AddRange(getSlots4_G_Replace(data, 0x66, 4, GrassSlots, Legal.Slot4_Swarm, SlotType.Swarm)); + //Morning and Night slots replace slots 2 and 3 + Slots.AddRange(getSlots4_G_Replace(data, 0x6E, 4, GrassSlots, Legal.Slot4_Time)); // Morning + Slots.AddRange(getSlots4_G_Replace(data, 0x76, 4, GrassSlots, Legal.Slot4_Time)); // Night + //Pokéradar slots replace slots 4,5,10 and 11 //Pokéradar is marked with different slot type because it have different PID-IV generationn - Slots.AddRange(getSlots4_G_Replace(data, ref ofs, 4, GrassSlots, Legal.Slot4_Radar, SlotType.Pokeradar)); - ofs += 24; //24 bytes padding + Slots.AddRange(getSlots4_G_Replace(data, 0x7E, 4, GrassSlots, Legal.Slot4_Radar, SlotType.Pokeradar)); + //24 bytes padding //Dual Slots replace slots 8 and 9 - Slots.AddRange(getSlots4_G_Replace(data, ref ofs, 4, GrassSlots, Legal.Slot4_Dual)); // Ruby - Slots.AddRange(getSlots4_G_Replace(data, ref ofs, 4, GrassSlots, Legal.Slot4_Dual)); // Sapphire - Slots.AddRange(getSlots4_G_Replace(data, ref ofs, 4, GrassSlots, Legal.Slot4_Dual)); // Emerald - Slots.AddRange(getSlots4_G_Replace(data, ref ofs, 4, GrassSlots, Legal.Slot4_Dual)); // FireRed - Slots.AddRange(getSlots4_G_Replace(data, ref ofs, 4, GrassSlots, Legal.Slot4_Dual)); // LeafGreen + Slots.AddRange(getSlots4_G_Replace(data, 0xA6, 4, GrassSlots, Legal.Slot4_Dual)); // Ruby + Slots.AddRange(getSlots4_G_Replace(data, 0xAE, 4, GrassSlots, Legal.Slot4_Dual)); // Sapphire + Slots.AddRange(getSlots4_G_Replace(data, 0xB6, 4, GrassSlots, Legal.Slot4_Dual)); // Emerald + Slots.AddRange(getSlots4_G_Replace(data, 0xBE, 4, GrassSlots, Legal.Slot4_Dual)); // FireRed + Slots.AddRange(getSlots4_G_Replace(data, 0xC6, 4, GrassSlots, Legal.Slot4_Dual)); // LeafGreen } - else - ofs = 206; - var SurfRatio = BitConverter.ToInt32(data, ofs); - ofs += 4; + var SurfRatio = BitConverter.ToInt32(data, 0xCE); if (SurfRatio > 0) - Slots.AddRange(getSlots4DPPt_WFR(data, ref ofs, 5, SlotType.Surf)); - else - ofs += 40; + Slots.AddRange(getSlots4DPPt_WFR(data, 0xD2, 5, SlotType.Surf)); - ofs += 44; //44 bytes padding - var OldRodRatio = BitConverter.ToInt32(data, 294); - ofs += 4; + //44 bytes padding + + var OldRodRatio = BitConverter.ToInt32(data, 0x126); if (OldRodRatio > 0) - Slots.AddRange(getSlots4DPPt_WFR(data, ref ofs, 5, SlotType.Old_Rod)); - else - ofs += 40; + Slots.AddRange(getSlots4DPPt_WFR(data, 0x12A, 5, SlotType.Old_Rod)); - var GoodRodRatio = BitConverter.ToInt32(data, 338); - ofs += 4; + var GoodRodRatio = BitConverter.ToInt32(data, 0x152); if (GoodRodRatio > 0) - Slots.AddRange(getSlots4DPPt_WFR(data, ref ofs, 5, SlotType.Good_Rod)); - else - ofs += 40; + Slots.AddRange(getSlots4DPPt_WFR(data, 0x156, 5, SlotType.Good_Rod)); - var SuperRodRatio = BitConverter.ToInt32(data, 382); - ofs += 4; + var SuperRodRatio = BitConverter.ToInt32(data, 0x17E); if (SuperRodRatio > 0) - Slots.AddRange(getSlots4DPPt_WFR(data, ref ofs, 5, SlotType.Super_Rod)); - else - ofs += 40; + Slots.AddRange(getSlots4DPPt_WFR(data, 0x182, 5, SlotType.Super_Rod)); Area4.Slots = Slots.ToArray(); return Area4; @@ -561,62 +510,50 @@ private static EncounterArea getArea4DPPt(byte[] data) private static EncounterArea getArea4HGSS(byte[] data) { EncounterArea Area4 = new EncounterArea(); - if (data.Length != 198) + if (data.Length != 0xC6) { Area4.Location = 0; Area4.Slots = new EncounterSlot[0]; return Area4; } var Slots = new List(); - Area4.Location = BitConverter.ToUInt16(data, 0); + Area4.Location = BitConverter.ToUInt16(data, 0x00); - var GrassRatio = data[2]; - var SurfRatio = data[3]; - var RockSmashRatio = data[4]; - var OldRodRatio = data[5]; - var GoodRodRatio = data[6]; - var SuperRodRatio = data[7]; + var GrassRatio = data[0x02]; + var SurfRatio = data[0x03]; + var RockSmashRatio = data[0x04]; + var OldRodRatio = data[0x05]; + var GoodRodRatio = data[0x06]; + var SuperRodRatio = data[0x07]; // 2 bytes padding - var ofs = 10; if (GrassRatio > 0) { // First 36 slots are morning, day and night grass slots // The order is 12 level values, 12 morning species, 12 day species and 12 night species - var GrassSlots = getSlots4_HGSS_G(data, ref ofs, 12, SlotType.Grass); + var GrassSlots = getSlots4_HGSS_G(data, 0x0A, 12, SlotType.Grass); //Grass slots with species = 0 are added too, it is needed for the swarm encounters, it will be deleted after add swarms Slots.AddRange(GrassSlots); // Hoenn Sound and Sinnoh Sound replace slots 4 and 5 - Slots.AddRange(getSlots4_G_Replace(data, ref ofs, 2, GrassSlots, Legal.Slot4_Sound)); // Hoenn - Slots.AddRange(getSlots4_G_Replace(data, ref ofs, 2, GrassSlots, Legal.Slot4_Sound)); // Sinnoh + Slots.AddRange(getSlots4_G_Replace(data, 0x5E, 2, GrassSlots, Legal.Slot4_Sound)); // Hoenn + Slots.AddRange(getSlots4_G_Replace(data, 0x62, 2, GrassSlots, Legal.Slot4_Sound)); // Sinnoh } - else - ofs = 102; if (SurfRatio > 0) - Slots.AddRange(getSlots4HGSS_WFR(data, ref ofs, 5, SlotType.Surf)); - else - ofs += 20; + Slots.AddRange(getSlots4HGSS_WFR(data, 0x66, 5, SlotType.Surf)); if (RockSmashRatio > 0) - Slots.AddRange(getSlots4HGSS_WFR(data, ref ofs, 2, SlotType.Rock_Smash)); - else - ofs += 8; + Slots.AddRange(getSlots4HGSS_WFR(data, 0x7A, 2, SlotType.Rock_Smash)); if (OldRodRatio > 0) - Slots.AddRange(getSlots4HGSS_WFR(data, ref ofs, 5, SlotType.Old_Rod)); - else - ofs += 20; + Slots.AddRange(getSlots4HGSS_WFR(data, 0x82, 5, SlotType.Old_Rod)); if (GoodRodRatio > 0) - Slots.AddRange(getSlots4HGSS_WFR(data, ref ofs, 5, SlotType.Good_Rod)); - else - ofs += 20; + Slots.AddRange(getSlots4HGSS_WFR(data, 0x96, 5, SlotType.Good_Rod)); if (SuperRodRatio > 0) - Slots.AddRange(getSlots4HGSS_WFR(data, ref ofs, 5, SlotType.Super_Rod)); - else - ofs += 20; + Slots.AddRange(getSlots4HGSS_WFR(data, 0xAA, 5, SlotType.Super_Rod)); - if (data[194] == 120) //Location = 182, 127, 130, 132, 167, 188, 210 + // Last 6 bytes only have species ID info + if (data[0xC2] == 120) // Location = 182, 127, 130, 132, 167, 188, 210 Slots.AddRange(SlotsHGSS_Staryu); Area4.Slots = Slots.ToArray(); diff --git a/PKHeX/Legality/Tables4.cs b/PKHeX/Legality/Tables4.cs index f43be8608..f7d49c5d7 100644 --- a/PKHeX/Legality/Tables4.cs +++ b/PKHeX/Legality/Tables4.cs @@ -570,9 +570,10 @@ public static partial class Legal #endregion // Encounter Slots that are replaced + internal static readonly int[] Slot4_Swarm = {0, 1}; internal static readonly int[] Slot4_Time = {2, 3}; internal static readonly int[] Slot4_Sound = {2, 3, 4, 5}; - internal static readonly int[] Slot4_Radar = {6, 7, 10, 11}; + internal static readonly int[] Slot4_Radar = {4, 5, 10, 11}; internal static readonly int[] Slot4_Dual = {8, 9}; #region Alt Slots internal static readonly int[] SafariZoneLocation_4 = @@ -1075,48 +1076,6 @@ public static partial class Legal 58, // Floaroma Meadow }; - private static readonly EncounterArea[] SlotsDPPT_Swarm = - { - //reference http://bulbapedia.bulbagarden.net/wiki/Pokémon_outbreak - new EncounterArea {Location = 016, Slots = new[]{new EncounterSlot {Species = 084, Type = SlotType.Grass }, },},// Doduo @ Route 201 - new EncounterArea {Location = 017, Slots = new[]{new EncounterSlot {Species = 263, Type = SlotType.Grass }, },},// Zigzagoon @ Route 202 - new EncounterArea {Location = 018, Slots = new[]{new EncounterSlot {Species = 104, Type = SlotType.Grass }, },},// Cubone @ Route 203 - new EncounterArea {Location = 022, Slots = new[]{new EncounterSlot {Species = 231, Type = SlotType.Grass }, },},// Phanpy @ Route 207 - new EncounterArea {Location = 023, Slots = new[]{new EncounterSlot {Species = 206, Type = SlotType.Grass }, },},// Dunsparce @ Route 208 - new EncounterArea {Location = 024, Slots = new[]{new EncounterSlot {Species = 209, Type = SlotType.Grass }, },},// Snubbull @ Route 209 - new EncounterArea {Location = 029, Slots = new[]{new EncounterSlot {Species = 325, Type = SlotType.Grass }, },},// Spoink @ Route 214 - new EncounterArea {Location = 030, Slots = new[]{new EncounterSlot {Species = 096, Type = SlotType.Grass }, },},// Drowzee @ Route 215 - new EncounterArea {Location = 033, Slots = new[]{new EncounterSlot {Species = 100, Type = SlotType.Grass }, },},// Voltorb @ Route 218 - new EncounterArea {Location = 036, Slots = new[]{new EncounterSlot {Species = 083, Type = SlotType.Grass }, },},// Farfetch'd @ Route 221 - new EncounterArea {Location = 037, Slots = new[]{new EncounterSlot {Species = 300, Type = SlotType.Grass }, },},// Skitty @ Route 222 - new EncounterArea {Location = 039, Slots = new[]{new EncounterSlot {Species = 177, Type = SlotType.Grass }, },},// Natu @ Route 224 - new EncounterArea {Location = 040, Slots = new[]{new EncounterSlot {Species = 296, Type = SlotType.Grass }, },},// Makuhita @ Route 225 - new EncounterArea {Location = 041, Slots = new[]{new EncounterSlot {Species = 098, Type = SlotType.Grass }, },},// Krabby @ Route 226 - new EncounterArea {Location = 042, Slots = new[]{new EncounterSlot {Species = 327, Type = SlotType.Grass }, },},// Spinda @ Route 227 - new EncounterArea {Location = 043, Slots = new[]{new EncounterSlot {Species = 374, Type = SlotType.Grass }, },},// Beldum @ Route 228 - new EncounterArea {Location = 045, Slots = new[]{new EncounterSlot {Species = 222, Type = SlotType.Grass }, },},// Corsola @ Route 230 - new EncounterArea {Location = 047, Slots = new[]{new EncounterSlot {Species = 309, Type = SlotType.Grass }, },},// Electrike @ Valley Windworks - new EncounterArea {Location = 048, Slots = new[]{new EncounterSlot {Species = 287, Type = SlotType.Grass }, },},// Slakoth @ Eterna Forest - }; - - private static readonly EncounterArea[] SlotsDP_Swarm = SlotsDPPT_Swarm.Concat(new[] { - new EncounterArea {Location = 021, Slots = new[]{new EncounterSlot {Species = 299, Type = SlotType.Grass }, },},// Nosepass @ Route 206 - new EncounterArea {Location = 028, Slots = new[]{new EncounterSlot {Species = 359, Type = SlotType.Grass }, },},// Absol @ Route 213 - new EncounterArea {Location = 031, Slots = new[]{new EncounterSlot {Species = 225, Type = SlotType.Grass }, },},// Delibird @ Route 216 - new EncounterArea {Location = 032, Slots = new[]{new EncounterSlot {Species = 220, Type = SlotType.Grass }, },},// Swinub @ Route 217 - new EncounterArea {Location = 044, Slots = new[]{new EncounterSlot {Species = 016, Type = SlotType.Grass }, },},// Pidgey @ Route 229 - new EncounterArea {Location = 049, Slots = new[]{new EncounterSlot {Species = 081, Type = SlotType.Grass }, },},// Magnemite @ Fuego Ironworks - new EncounterArea {Location = 076, Slots = new[]{new EncounterSlot {Species = 283, Type = SlotType.Grass }, },},// Surskit @ Lake Verity - new EncounterArea {Location = 077, Slots = new[]{new EncounterSlot {Species = 108, Type = SlotType.Grass }, },},// Lickitung @ Lake Valor - new EncounterArea {Location = 078, Slots = new[]{new EncounterSlot {Species = 238, Type = SlotType.Grass }, },},// Smoochum @ Lake Acuity - }).ToArray(); - - private static readonly EncounterArea[] SlotsPt_Swarm = SlotsDPPT_Swarm.Concat(new[] { - new EncounterArea {Location = 021, Slots = new[]{new EncounterSlot {Species = 246, Type = SlotType.Grass }, },},// Larvitar @ Route 206 - new EncounterArea {Location = 032, Slots = new[]{new EncounterSlot {Species = 225, Type = SlotType.Grass }, },},// Delibird @ Route 217 - new EncounterArea {Location = 044, Slots = new[]{new EncounterSlot {Species = 127, Type = SlotType.Grass }, },},// Pinsir @ Route 229 - }).ToArray(); - private static readonly EncounterArea[] SlotsHGSS_Swarm = { new EncounterArea {Location = 128, Slots = new[]{new EncounterSlot {Species = 340, Type = SlotType.Old_Rod },