Refactoring some IEncounterable-type'd object initialization and original-generation evo chain (#2974)

This commit is contained in:
Kurt 2020-08-21 16:35:49 -07:00 committed by GitHub
parent 890f3375c9
commit a62324a5a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
101 changed files with 3059 additions and 2738 deletions

View file

@ -284,8 +284,8 @@ namespace PKHeX.Core
var enc = (Info.EncounterOriginalGB = EncounterMatch);
if (enc is EncounterInvalid)
return;
Info.EncounterMatch = EncounterStaticGenerator.GetVCStaticTransferEncounter(pkm);
if (!(Info.EncounterMatch is EncounterStatic s) || !EncounterStaticGenerator.IsVCStaticTransferEncounterValid(pkm, s))
var updated = Info.EncounterMatch = EncounterStaticGenerator.GetVCStaticTransferEncounter(pkm, enc);
if (!(updated is EncounterStatic s) || !EncounterStaticGenerator.IsVCStaticTransferEncounterValid(pkm, s))
{ AddLine(Severity.Invalid, LEncInvalid, CheckIdentifier.Encounter); return; }
foreach (var z in Transfer.VerifyVCEncounter(pkm, enc, s, Info.Moves))

View file

@ -1,13 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace PKHeX.Core
{
/// <summary>
/// Represents an Area where <see cref="PKM"/> can be encountered, which contains a Location ID and <see cref="EncounterSlot"/> data.
/// </summary>
public abstract class EncounterArea
public class EncounterArea
{
public int Location;
public EncounterSlot[] Slots = Array.Empty<EncounterSlot>();
@ -20,19 +19,21 @@ namespace PKHeX.Core
/// <param name="location">Location index of the encounter area.</param>
/// <param name="t">Encounter slot type of the encounter area.</param>
/// <returns>Encounter area with slots</returns>
public static T[] GetSimpleEncounterArea<T>(int[] species, int[] lvls, int location, SlotType t) where T : EncounterArea, new()
public static TArea[] GetSimpleEncounterArea<TArea, TSlot>(int[] species, int[] lvls, int location, SlotType t)
where TArea : EncounterArea, new()
where TSlot : EncounterSlot, new()
{
if ((lvls.Length & 1) != 0) // levels data not paired; expect multiple of 2
throw new ArgumentException(nameof(lvls));
var count = species.Length * (lvls.Length / 2);
var slots = new EncounterSlot[count];
var slots = new TSlot[count];
int ctr = 0;
foreach (var s in species)
{
for (int i = 0; i < lvls.Length;)
{
slots[ctr++] = new EncounterSlot
slots[ctr++] = new TSlot
{
LevelMin = lvls[i++],
LevelMax = lvls[i++],
@ -41,7 +42,7 @@ namespace PKHeX.Core
};
}
}
return new[] { new T { Location = location, Slots = slots } };
return new[] { new TArea { Location = location, Slots = slots } };
}
/// <summary>
@ -49,29 +50,26 @@ namespace PKHeX.Core
/// </summary>
/// <param name="pkm">Pokémon Data</param>
/// <param name="chain">Evolution lineage</param>
/// <param name="minLevel">Minimum level of the encounter</param>
/// <returns>Enumerable list of encounters</returns>
public virtual IEnumerable<EncounterSlot> GetMatchingSlots(PKM pkm, IReadOnlyList<DexLevel> chain, int minLevel = 0)
public virtual IEnumerable<EncounterSlot> GetMatchingSlots(PKM pkm, IReadOnlyList<EvoCriteria> chain)
{
if (minLevel == 0) // any
return Slots.Where(slot => chain.Any(evo => evo.Species == slot.Species));
foreach (var slot in Slots)
{
foreach (var evo in chain)
{
if (slot.Species != evo.Species)
continue;
var slots = GetMatchFromEvoLevel(pkm, chain, minLevel);
return GetFilteredSlots(pkm, slots, minLevel);
if (!slot.IsLevelWithinRange(pkm.Met_Level))
break;
if (slot.Form != evo.Form && !Legal.WildChangeFormAfter.Contains(slot.Species))
break;
yield return slot;
break;
}
protected virtual IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IReadOnlyList<DexLevel> chain, int minLevel)
{
var slots = Slots.Where(slot => chain.Any(evo => evo.Species == slot.Species && evo.Level >= slot.LevelMin));
// Get slots where pokemon can exist with respect to level constraints
return slots.Where(slot => slot.IsLevelWithinRange(minLevel));
}
protected virtual IEnumerable<EncounterSlot> GetFilteredSlots(PKM pkm, IEnumerable<EncounterSlot> slots, int minLevel)
{
return Legal.WildForms.Contains(pkm.Species)
? slots.Where(slot => slot.Form == pkm.AltForm)
: slots;
}
/// <summary>

View file

@ -106,30 +106,31 @@ namespace PKHeX.Core
return EncounterSlot1.ReadSlots(data, ref ofs, count, SlotType.Super_Rod, -1);
}
public override IEnumerable<EncounterSlot> GetMatchingSlots(PKM pkm, IReadOnlyList<DexLevel> chain, int minLevel = 0)
public override IEnumerable<EncounterSlot> GetMatchingSlots(PKM pkm, IReadOnlyList<EvoCriteria> chain)
{
if (minLevel == 0) // any
return Slots.Where(slot => chain.Any(evo => evo.Species == slot.Species));
var encounterSlots = GetMatchFromEvoLevel(pkm, chain, minLevel);
if (pkm is PK1 pk1 && pkm.Gen1_NotTradeback)
encounterSlots = FilterByCatchRate(encounterSlots, pk1.Catch_Rate);
return encounterSlots.OrderBy(slot => slot.LevelMin); // prefer lowest levels
}
protected override IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IReadOnlyList<DexLevel> chain, int minLevel)
int rate = pkm is PK1 pk1 && pkm.Gen1_NotTradeback ? pk1.Catch_Rate : -1;
foreach (var slot in Slots)
{
var slots = Slots.Where(slot => chain.Any(evo => evo.Species == slot.Species && evo.Level >= slot.LevelMin));
if (pkm.Format >= 7) // transferred to Gen7+
return slots.Where(slot => slot.LevelMin <= minLevel);
return slots.Where(s => s.IsLevelWithinRange(minLevel));
}
private static IEnumerable<EncounterSlot> FilterByCatchRate(IEnumerable<EncounterSlot> slots, int rate)
foreach (var evo in chain)
{
return slots.Where(z =>
rate == (z.Version == GameVersion.YW ? PersonalTable.Y : PersonalTable.RB)[z.Species].CatchRate);
if (slot.Species != evo.Species)
continue;
if (!slot.IsLevelWithinRange(evo.MinLevel, evo.Level))
break;
if (slot.Form != evo.Form)
break;
if (rate != -1)
{
var expect = (slot.Version == GameVersion.YW ? PersonalTable.Y : PersonalTable.RB)[slot.Species].CatchRate;
if (expect != rate)
break;
}
yield return slot;
break;
}
}
}
}
}

View file

@ -278,29 +278,65 @@ namespace PKHeX.Core
return head.Concat(rock);
}
public override IEnumerable<EncounterSlot> GetMatchingSlots(PKM pkm, IReadOnlyList<DexLevel> chain, int minLevel = 0)
public override IEnumerable<EncounterSlot> GetMatchingSlots(PKM pkm, IReadOnlyList<EvoCriteria> chain)
{
if (minLevel == 0) // any
return Slots.Where(slot => chain.Any(evo => evo.Species == slot.Species));
if (!(pkm is PK2 pk2) || pk2.CaughtData == 0)
return GetSlotsFuzzy(chain);
var encounterSlots = GetMatchFromEvoLevel(pkm, chain, minLevel);
return GetFilteredSlots(pkm, encounterSlots).OrderBy(slot => slot.LevelMin); // prefer lowest levels
if (pk2.Met_Location != Location)
return Array.Empty<EncounterSlot>();
return GetSlotsSpecificLevelTime(chain, pk2.Met_TimeOfDay, pk2.Met_Level);
}
private static IEnumerable<EncounterSlot> GetFilteredSlots(PKM pkm, IEnumerable<EncounterSlot> slots)
private IEnumerable<EncounterSlot> GetSlotsSpecificLevelTime(IReadOnlyList<EvoCriteria> chain, int time, int lvl)
{
if (pkm is PK2 pk2 && pk2.Met_TimeOfDay != 0)
return slots.Where(slot => ((EncounterSlot2)slot).Time.Contains(pk2.Met_TimeOfDay));
return slots;
}
protected override IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IReadOnlyList<DexLevel> chain, int minLevel)
foreach (var slot in Slots)
{
var slots = Slots.Where(slot => chain.Any(evo => evo.Species == slot.Species && evo.Level >= slot.LevelMin));
foreach (var evo in chain)
{
if (slot.Species != evo.Species)
continue;
if (pkm.Format >= 7 || !(pkm is PK2 pk2 && pk2.CaughtData != 0)) // transferred to Gen7+, or does not have Crystal met data
return slots.Where(slot => slot.LevelMin <= minLevel);
return slots.Where(s => s.IsLevelWithinRange(minLevel));
if (slot.Form != evo.Form)
{
if (slot.Species != (int)Species.Unown || evo.Form >= 26) // Don't yield !? forms
break;
}
if (!slot.IsLevelWithinRange(lvl))
break;
var expect = ((EncounterSlot2)slot).Time;
if (!expect.Contains(time))
break;
yield return slot;
break;
}
}
}
private IEnumerable<EncounterSlot> GetSlotsFuzzy(IReadOnlyList<EvoCriteria> chain)
{
foreach (var slot in Slots)
{
foreach (var evo in chain)
{
if (slot.Species != evo.Species)
continue;
if (slot.Form != evo.Form)
{
if (slot.Species != (int) Species.Unown || evo.Form >= 26) // Don't yield !? forms
break;
}
if (!slot.IsLevelWithinRange(evo.MinLevel, evo.Level))
break;
yield return slot;
break;
}
}
}
}
}

View file

@ -30,7 +30,7 @@ namespace PKHeX.Core
if (species <= 0)
continue;
slots.Add(new EncounterSlot
slots.Add(new EncounterSlot3
{
LevelMin = data[o + 2],
LevelMax = data[o + 3],
@ -60,7 +60,7 @@ namespace PKHeX.Core
if (Species <= 0)
continue;
var slot = new EncounterSlot
var slot = new EncounterSlot3
{
LevelMin = data[ofs + 2 + (i * 4)],
LevelMax = data[ofs + 3 + (i * 4)],
@ -125,20 +125,53 @@ namespace PKHeX.Core
return entries.Select(GetArea3).Where(Area => Area.Slots.Length != 0).ToArray();
}
protected override IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IReadOnlyList<DexLevel> chain, int minLevel)
public override IEnumerable<EncounterSlot> GetMatchingSlots(PKM pkm, IReadOnlyList<EvoCriteria> chain)
{
var slots = Slots.Where(slot => chain.Any(evo => evo.Species == slot.Species && evo.Level >= slot.LevelMin));
if (pkm.Format != 3) // transferred to Gen4+
return slots.Where(slot => slot.LevelMin <= minLevel);
return slots.Where(s => s.IsLevelWithinRange(minLevel));
if (pkm.Format != 3) // Met Location and Met Level are changed on PK3->PK4
return GetSlotsFuzzy(chain);
if (pkm.Met_Location != Location)
return Array.Empty<EncounterSlot>();
return GetSlotsMatching(chain, pkm.Met_Level);
}
protected override IEnumerable<EncounterSlot> GetFilteredSlots(PKM pkm, IEnumerable<EncounterSlot> slots, int minLevel)
private IEnumerable<EncounterSlot> GetSlotsMatching(IReadOnlyList<EvoCriteria> chain, int lvl)
{
if (pkm.Species == (int) Species.Unown)
return slots.Where(z => z.Form == pkm.AltForm);
return slots;
foreach (var slot in Slots)
{
foreach (var evo in chain)
{
if (slot.Species != evo.Species)
continue;
if (slot.Form != evo.Form)
break;
if (!slot.IsLevelWithinRange(lvl))
break;
yield return slot;
break;
}
}
}
private IEnumerable<EncounterSlot> GetSlotsFuzzy(IReadOnlyList<EvoCriteria> chain)
{
foreach (var slot in Slots)
{
foreach (var evo in chain)
{
if (slot.Species != evo.Species)
continue;
if (slot.Form != evo.Form)
break;
if (!slot.IsLevelWithinRange(evo.MinLevel, evo.Level))
break;
yield return slot;
break;
}
}
}
}
}

View file

@ -16,18 +16,20 @@ namespace PKHeX.Core
/// </summary>
/// <param name="entries">Simplified raw format of an Area</param>
/// <returns>Array of areas</returns>
public static T[] GetArray<T>(byte[][] entries) where T : EncounterArea32, new()
public static A[] GetArray<A, S>(byte[][] entries)
where A : EncounterArea32, new()
where S : EncounterSlot, new()
{
T[] data = new T[entries.Length];
var data = new A[entries.Length];
for (int i = 0; i < data.Length; i++)
{
var loc = data[i] = new T();
loc.LoadSlots(entries[i]);
var loc = data[i] = new A();
loc.LoadSlots<S>(entries[i]);
}
return data;
}
private void LoadSlots(byte[] areaData)
private void LoadSlots<S>(byte[] areaData) where S : EncounterSlot, new()
{
var count = (areaData.Length - 2) / 4;
Location = BitConverter.ToUInt16(areaData, 0);
@ -36,7 +38,7 @@ namespace PKHeX.Core
{
int ofs = 2 + (i * 4);
ushort SpecForm = BitConverter.ToUInt16(areaData, ofs);
Slots[i] = new EncounterSlot
Slots[i] = new S
{
Species = SpecForm & 0x7FF,
Form = SpecForm >> 11,
@ -47,13 +49,5 @@ namespace PKHeX.Core
foreach (var slot in Slots)
slot.Area = this;
}
protected static EncounterSlot GetPressureSlot(EncounterSlot s, PKM pkm)
{
var max = s.Clone();
max.Permissions.Pressure = true;
max.Form = pkm.AltForm;
return max;
}
}
}

View file

@ -22,9 +22,9 @@ namespace PKHeX.Core
/// <param name="ReplacedSlots">Slots from regular encounter table that end up replaced by in-game conditions</param>
/// <param name="slotnums">Slot indexes to replace with read species IDs</param>
/// <param name="t">Slot type of the special encounter</param>
protected static List<EncounterSlot> GetSlots4GrassSlotReplace(byte[] data, int ofs, int slotSize, EncounterSlot[] ReplacedSlots, int[] slotnums, SlotType t = SlotType.Grass)
protected static List<EncounterSlot4> GetSlots4GrassSlotReplace(byte[] data, int ofs, int slotSize, EncounterSlot[] ReplacedSlots, int[] slotnums, SlotType t = SlotType.Grass)
{
var slots = new List<EncounterSlot>();
var slots = new List<EncounterSlot4>();
int numslots = slotnums.Length;
for (int i = 0; i < numslots; i++)
@ -37,7 +37,7 @@ namespace PKHeX.Core
if (species <= 0 || baseSlot.Species == species) // Empty or duplicate
continue;
var slot = baseSlot.Clone();
var slot = (EncounterSlot4)baseSlot.Clone();
slot.Species = species;
slot.Type = t;
slot.SlotNumber = i;
@ -46,26 +46,66 @@ namespace PKHeX.Core
return slots;
}
protected static IEnumerable<EncounterSlot> MarkStaticMagnetExtras(IEnumerable<IEnumerable<List<EncounterSlot>>> product)
protected static IEnumerable<EncounterSlot4> MarkStaticMagnetExtras(IEnumerable<IEnumerable<List<EncounterSlot4>>> product)
{
var trackPermute = new List<EncounterSlot>();
var trackPermute = new List<EncounterSlot4>();
foreach (var p in product)
MarkStaticMagnetPermute(p.SelectMany(z => z), trackPermute);
return trackPermute;
}
protected static void MarkStaticMagnetPermute(IEnumerable<EncounterSlot> grp, List<EncounterSlot> trackPermute)
protected static void MarkStaticMagnetPermute(IEnumerable<EncounterSlot4> grp, List<EncounterSlot4> trackPermute)
{
EncounterUtil.MarkEncountersStaticMagnetPullPermutation(grp, PersonalTable.HGSS, trackPermute);
}
protected override IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IReadOnlyList<DexLevel> chain, int minLevel)
public override IEnumerable<EncounterSlot> GetMatchingSlots(PKM pkm, IReadOnlyList<EvoCriteria> chain)
{
var slots = Slots.Where(slot => chain.Any(evo => evo.Species == slot.Species && evo.Level >= slot.LevelMin));
if (pkm.Format != 4) // Met Location and Met Level are changed on PK4->PK5
return GetSlotsFuzzy(chain);
if (pkm.Met_Location != Location)
return Array.Empty<EncounterSlot>();
return GetSlotsMatching(chain, pkm.Met_Level);
}
if (pkm.Format != 4) // transferred to Gen5+
return slots.Where(slot => slot.LevelMin <= minLevel);
return slots.Where(s => s.IsLevelWithinRange(minLevel));
private IEnumerable<EncounterSlot> GetSlotsMatching(IReadOnlyList<EvoCriteria> chain, int lvl)
{
foreach (var slot in Slots)
{
foreach (var evo in chain)
{
if (slot.Species != evo.Species)
continue;
if (slot.Form != evo.Form && !Legal.WildChangeFormAfter.Contains(slot.Species))
break;
if (!slot.IsLevelWithinRange(lvl))
break;
yield return slot;
break;
}
}
}
private IEnumerable<EncounterSlot> GetSlotsFuzzy(IReadOnlyList<EvoCriteria> chain)
{
foreach (var slot in Slots)
{
foreach (var evo in chain)
{
if (slot.Species != evo.Species)
continue;
if (slot.Form != evo.Form && !Legal.WildChangeFormAfter.Contains(slot.Species))
break;
if (!slot.IsLevelWithinRange(evo.MinLevel, evo.Level))
break;
yield return slot;
break;
}
}
}
}
}

View file

@ -21,16 +21,16 @@ namespace PKHeX.Core
return entries.Select(z => GetArea4DPPt(z, pt)).Where(Area => Area.Slots.Length != 0).ToArray();
}
private static EncounterSlot[] GetSlots4GrassDPPt(byte[] data, int ofs, int numslots, SlotType t)
private static EncounterSlot4[] GetSlots4GrassDPPt(byte[] data, int ofs, int numslots, SlotType t)
{
var slots = new EncounterSlot[numslots];
var slots = new EncounterSlot4[numslots];
for (int i = 0; i < numslots; i++)
{
int o = ofs + (i * 8);
int level = data[o];
int species = BitConverter.ToInt32(data, o + 4);
slots[i] = new EncounterSlot
slots[i] = new EncounterSlot4
{
LevelMax = level,
LevelMin = level,
@ -42,9 +42,9 @@ namespace PKHeX.Core
return slots;
}
private static IEnumerable<EncounterSlot> GetSlots4WaterFishingDPPt(byte[] data, int ofs, int numslots, SlotType t)
private static IEnumerable<EncounterSlot4> GetSlots4WaterFishingDPPt(byte[] data, int ofs, int numslots, SlotType t)
{
var slots = new List<EncounterSlot>();
var slots = new List<EncounterSlot4>();
for (int i = 0; i < numslots; i++)
{
// max, min, unused, unused, [32bit species]
@ -53,7 +53,7 @@ namespace PKHeX.Core
continue;
// Fishing and Surf slots without a species ID are not added
// DPPt does not have fishing or surf swarms, and does not have any Rock Smash encounters.
slots.Add(new EncounterSlot
slots.Add(new EncounterSlot4
{
LevelMax = data[ofs + 0 + (i * 8)],
LevelMin = data[ofs + 1 + (i * 8)],
@ -74,7 +74,7 @@ namespace PKHeX.Core
var GrassRatio = BitConverter.ToInt32(data, 0x02);
if (GrassRatio > 0)
{
EncounterSlot[] GrassSlots = GetSlots4GrassDPPt(data, 0x06, 12, SlotType.Grass);
var GrassSlots = GetSlots4GrassDPPt(data, 0x06, 12, SlotType.Grass);
//Swarming slots replace slots 0 and 1
var swarm = GetSlots4GrassSlotReplace(data, 0x66, 4, GrassSlots, Legal.Slot4_Swarm, SlotType.Swarm);
//Morning and Night slots replace slots 2 and 3
@ -107,11 +107,11 @@ namespace PKHeX.Core
// Permute Static-Magnet Pull combinations
// [None/Swarm]-[None/Morning/Night]-[None/Radar]-[None/R/S/E/F/L] [None/TrophyGarden]
// 2 * 3 * 2 * 6 = 72 different combinations of slots (more with trophy garden)
var regular = new List<List<EncounterSlot>> { GrassSlots.Where(z => z.SlotNumber == 6 || z.SlotNumber == 7).ToList() }; // every other slot is in the product
var pair0 = new List<List<EncounterSlot>> { GrassSlots.Where(z => Legal.Slot4_Swarm.Contains(z.SlotNumber)).ToList() };
var pair1 = new List<List<EncounterSlot>> { GrassSlots.Where(z => Legal.Slot4_Time.Contains(z.SlotNumber)).ToList() };
var pair2 = new List<List<EncounterSlot>> { GrassSlots.Where(z => Legal.Slot4_Radar.Contains(z.SlotNumber)).ToList() };
var pair3 = new List<List<EncounterSlot>> { GrassSlots.Where(z => Legal.Slot4_Dual.Contains(z.SlotNumber)).ToList() };
var regular = new List<List<EncounterSlot4>> { GrassSlots.Where(z => z.SlotNumber == 6 || z.SlotNumber == 7).ToList() }; // every other slot is in the product
var pair0 = new List<List<EncounterSlot4>> { GrassSlots.Where(z => Legal.Slot4_Swarm.Contains(z.SlotNumber)).ToList() };
var pair1 = new List<List<EncounterSlot4>> { GrassSlots.Where(z => Legal.Slot4_Time.Contains(z.SlotNumber)).ToList() };
var pair2 = new List<List<EncounterSlot4>> { GrassSlots.Where(z => Legal.Slot4_Radar.Contains(z.SlotNumber)).ToList() };
var pair3 = new List<List<EncounterSlot4>> { GrassSlots.Where(z => Legal.Slot4_Dual.Contains(z.SlotNumber)).ToList() };
if (swarm.Count != 0) pair0.Add(swarm);
if (morning.Count != 0) pair1.Add(morning); if (night.Count != 0) pair1.Add(night);
if (radar.Count != 0) pair2.Add(radar);
@ -121,14 +121,14 @@ namespace PKHeX.Core
{
// Occupy Slots 6 & 7
var species = pt ? Encounters4.TrophyPt : Encounters4.TrophyDP;
var slots = new List<EncounterSlot>();
var slots = new List<EncounterSlot4>();
foreach (var s in species)
{
var slot = regular[0][0].Clone();
var slot = (EncounterSlot4)regular[0][0].Clone();
slot.Species = s;
slots.Add(slot);
slot = regular[0][1].Clone();
slot = (EncounterSlot4)regular[0][1].Clone();
slot.Species = s;
slots.Add(slot);
}
@ -138,7 +138,7 @@ namespace PKHeX.Core
for (int i = 0; i < trophy.Length; i++)
{
for (int j = i + 1; j < trophy.Length; j++)
regular.Add(new List<EncounterSlot> { trophy[i], trophy[j] });
regular.Add(new List<EncounterSlot4> { trophy[i], trophy[j] });
}
}

View file

@ -30,16 +30,16 @@ namespace PKHeX.Core
return entries.Select(GetArea4HeadbuttHGSS).Where(Area => Area.Slots.Length != 0).ToArray();
}
private static EncounterSlot[] GetSlots4GrassHGSS(byte[] data, int ofs, int numslots, SlotType t)
private static EncounterSlot4[] GetSlots4GrassHGSS(byte[] data, int ofs, int numslots, SlotType t)
{
var slots = new EncounterSlot[numslots * 3];
var slots = new EncounterSlot4[numslots * 3];
// 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
for (int i = 0; i < numslots; i++)
{
int level = data[ofs + i];
int species = BitConverter.ToUInt16(data, ofs + numslots + (i * 2));
slots[i] = new EncounterSlot
slots[i] = new EncounterSlot4
{
LevelMin = level,
LevelMax = level,
@ -47,10 +47,10 @@ namespace PKHeX.Core
SlotNumber = i,
Type = t
};
slots[numslots + i] = slots[i].Clone();
slots[numslots + i] = (EncounterSlot4)slots[i].Clone();
slots[numslots + i].Species = BitConverter.ToUInt16(data, ofs + (numslots * 3) + (i * 2));
slots[numslots + i].Type = t;
slots[(numslots * 2) + i] = slots[i].Clone();
slots[(numslots * 2) + i] = (EncounterSlot4)slots[i].Clone();
slots[(numslots * 2) + i].Species = BitConverter.ToUInt16(data, ofs + (numslots * 5) + (i * 2));
slots[(numslots * 2) + i].Type = t;
}
@ -58,9 +58,9 @@ namespace PKHeX.Core
return slots;
}
private static IEnumerable<EncounterSlot> GetSlots4WaterFishingHGSS(byte[] data, int ofs, int numslots, SlotType t)
private static IEnumerable<EncounterSlot4> GetSlots4WaterFishingHGSS(byte[] data, int ofs, int numslots, SlotType t)
{
var slots = new List<EncounterSlot>();
var slots = new List<EncounterSlot4>();
for (int i = 0; i < numslots; i++)
{
// min, max, [16bit species]
@ -70,7 +70,7 @@ namespace PKHeX.Core
// Fishing and surf Slots without a species ID are added too; these are needed for the swarm encounters.
// These empty slots will will be deleted after we add swarm slots.
slots.Add(new EncounterSlot
slots.Add(new EncounterSlot4
{
LevelMin = data[ofs + 0 + (i * 4)],
LevelMax = data[ofs + 1 + (i * 4)],
@ -85,7 +85,7 @@ namespace PKHeX.Core
private static EncounterArea4HGSS GetArea4HGSS(byte[] data)
{
var Slots = new List<EncounterSlot>();
var Slots = new List<EncounterSlot4>();
var GrassRatio = data[0x02];
var SurfRatio = data[0x03];
@ -120,13 +120,13 @@ namespace PKHeX.Core
{
// non radio
var regular = time.Where(z => !Legal.Slot4_Sound.Contains(z.SlotNumber)).ToList(); // every other slot is in the product
var radio = new List<List<EncounterSlot>> { time.Where(z => Legal.Slot4_Sound.Contains(z.SlotNumber)).ToList() };
var radio = new List<List<EncounterSlot4>> { time.Where(z => Legal.Slot4_Sound.Contains(z.SlotNumber)).ToList() };
if (hoenn.Count > 0)
radio.Add(hoenn);
if (sinnoh.Count > 0)
radio.Add(sinnoh);
var extra = new List<EncounterSlot>();
var extra = new List<EncounterSlot4>();
foreach (var t in radio)
MarkStaticMagnetPermute(regular.Concat(t), extra);
Slots.AddRange(extra);
@ -162,10 +162,10 @@ namespace PKHeX.Core
return Area4;
}
private static readonly EncounterSlot[] SlotsHGSS_Staryu =
private static readonly EncounterSlot4[] SlotsHGSS_Staryu =
{
new EncounterSlot { Species = 120, LevelMin = 20, LevelMax = 20, Type = SlotType.Good_Rod },
new EncounterSlot { Species = 120, LevelMin = 40, LevelMax = 40, Type = SlotType.Super_Rod },
new EncounterSlot4 { Species = 120, LevelMin = 20, LevelMax = 20, Type = SlotType.Good_Rod },
new EncounterSlot4 { Species = 120, LevelMin = 40, LevelMax = 40, Type = SlotType.Super_Rod },
};
private static EncounterArea4HGSS GetArea4HeadbuttHGSS(byte[] data)
@ -184,7 +184,7 @@ namespace PKHeX.Core
int Species = BitConverter.ToInt16(data, 6 + (i * 4));
if (Species <= 0)
continue;
Slots.Add(new EncounterSlot
Slots.Add(new EncounterSlot4
{
Species = Species,
LevelMin = data[8 + (i * 4)],

View file

@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Linq;
namespace PKHeX.Core
{
@ -13,51 +12,44 @@ namespace PKHeX.Core
private const int FluteBoostMax = 4; // Black Flute increases levels.
private const int DexNavBoost = 30; // Maximum DexNav chain
protected override IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IReadOnlyList<DexLevel> chain, int minLevel)
{
var slots = Slots.Where(slot => chain.Any(evo => evo.Species == slot.Species && evo.Level >= (slot.LevelMin - FluteBoostMax)));
private const int RandomForm = 31;
// note: it's probably possible to determine a reduced DexNav boost based on the flawless IV count (no flawless = not chained)
// if someone wants to implement that logic to have the below method return a calculated max DexNavBoost, send a pull request :)
static int getMaxLevelBoost(EncounterSlot s) => s.Type != SlotType.Rock_Smash ? DexNavBoost : FluteBoostMax; // DexNav encounters most likely
// Get slots where pokemon can exist with respect to level constraints
return slots.Where(s => s.IsLevelWithinRange(minLevel, minLevel, FluteBoostMin, getMaxLevelBoost(s)));
}
protected override IEnumerable<EncounterSlot> GetFilteredSlots(PKM pkm, IEnumerable<EncounterSlot> slots, int minLevel)
public override IEnumerable<EncounterSlot> GetMatchingSlots(PKM pkm, IReadOnlyList<EvoCriteria> chain)
{
EncounterSlot? slotMax = null;
foreach (EncounterSlot s in slots)
foreach (var slot in Slots)
{
if (Legal.WildForms.Contains(pkm.Species) && s.Form != pkm.AltForm)
foreach (var evo in chain)
{
CachePressureSlot(s);
if (slot.Species != evo.Species)
continue;
var boostMax = slot.Type != SlotType.Rock_Smash ? DexNavBoost : FluteBoostMax;
const int boostMin = FluteBoostMin;
if (!slot.IsLevelWithinRange(pkm.Met_Level, boostMin, boostMax))
break;
if (slot.Form != evo.Form && slot.Form != RandomForm)
break;
var clone = (EncounterSlot6AO)slot.Clone();
MarkSlotDetails(pkm, clone, evo);
yield return clone;
break;
}
}
bool nav = s.Permissions.AllowDexNav && (pkm.RelearnMove1 != 0 || pkm.AbilityNumber == 4);
EncounterSlot slot = s.Clone();
slot.Permissions.DexNav = nav;
if (slot.LevelMin > minLevel)
slot.Permissions.WhiteFlute = true;
if (slot.LevelMax + 1 <= minLevel && minLevel <= slot.LevelMax + FluteBoostMax)
slot.Permissions.BlackFlute = true;
if (slot.LevelMax != minLevel && slot.Permissions.AllowDexNav)
slot.Permissions.DexNav = true;
yield return slot;
CachePressureSlot(slot);
}
void CachePressureSlot(EncounterSlot s)
private static void MarkSlotDetails(PKM pkm, EncounterSlot6AO slot, EvoCriteria evo)
{
if (slotMax != null && s.LevelMax > slotMax.LevelMax)
slotMax = s;
}
// Pressure Slot
if (slotMax != null)
yield return GetPressureSlot(slotMax, pkm);
bool nav = slot.AllowDexNav && (pkm.RelearnMove1 != 0 || pkm.AbilityNumber == 4);
slot.DexNav = nav;
if (slot.LevelMin > evo.MinLevel)
slot.WhiteFlute = true;
if (slot.LevelMax + 1 <= evo.MinLevel && evo.MinLevel <= slot.LevelMax + FluteBoostMax)
slot.BlackFlute = true;
if (slot.LevelMax != evo.MinLevel && slot.AllowDexNav)
slot.DexNav = true;
}
}
}

View file

@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Linq;
namespace PKHeX.Core
{
@ -9,76 +8,61 @@ namespace PKHeX.Core
/// </summary>
public sealed class EncounterArea6XY : EncounterArea32
{
protected override IEnumerable<EncounterSlot> GetFilteredSlots(PKM pkm, IEnumerable<EncounterSlot> slots, int minLevel)
private const int RandomForm = 31;
private const int RandomFormVivillon = RandomForm - 1;
public override IEnumerable<EncounterSlot> GetMatchingSlots(PKM pkm, IReadOnlyList<EvoCriteria> chain)
{
EncounterSlot? slotMax = null;
void CachePressureSlot(EncounterSlot s)
foreach (var slot in Slots)
{
if (slotMax == null || s.LevelMax > slotMax.LevelMax)
slotMax = s;
foreach (var evo in chain)
{
if (slot.Species != evo.Species)
continue;
if (!slot.IsLevelWithinRange(pkm.Met_Level))
break;
if (slot.Form != evo.Form && slot.Form < RandomFormVivillon && !Legal.WildChangeFormAfter.Contains(slot.Species))
{
if (slot.Species != (int)Species.Flabébé)
break;
var maxLevel = slot.LevelMax;
if (!ExistsPressureSlot(evo, ref maxLevel))
break;
if (maxLevel != pkm.Met_Level)
break;
var clone = (EncounterSlot6XY)slot.Clone();
clone.Form = evo.Form;
clone.Pressure = true;
yield return clone;
break;
}
int species = pkm.Species;
int form = pkm.AltForm;
bool ShouldMatchSlotForm() => Legal.WildForms.Contains(species);
if (ShouldMatchSlotForm()) // match slot form
{
foreach (var slot in slots)
{
if (slot.Form == form)
yield return slot;
CachePressureSlot(slot);
break;
}
}
else
{
foreach (var slot in slots)
{
yield return slot; // no form checking
CachePressureSlot(slot);
}
}
// Filter for Form Specific
// Pressure Slot
if (slotMax == null)
yield break;
if (ShouldMatchSlotForm()) // match slot form
private bool ExistsPressureSlot(DexLevel evo, ref int level)
{
if (slotMax.Form == form)
yield return GetPressureSlot(slotMax, pkm);
}
else
bool existsForm = false;
foreach (var z in Slots)
{
yield return GetPressureSlot(slotMax, pkm);
if (z.Species != evo.Species)
continue;
if (z.Form == evo.Form)
continue;
if (z.LevelMax < level)
continue;
level = z.LevelMax;
existsForm = true;
}
}
public static bool WasFriendSafari(PKM pkm)
{
if (!pkm.XY)
return false;
if (pkm.Met_Location != 148)
return false;
if (pkm.Met_Level != 30)
return false;
if (pkm.Egg_Location != 0)
return false;
return true;
}
public static IEnumerable<EncounterSlot> GetValidFriendSafari(PKM pkm)
{
var chain = EvolutionChain.GetValidPreEvolutions(pkm);
return GetValidFriendSafari(chain);
}
public static IEnumerable<EncounterSlot> GetValidFriendSafari(IReadOnlyList<DexLevel> chain)
{
var valid = chain.Where(d => d.Level >= 30);
return valid.SelectMany(z => Encounters6.FriendSafari[z.Species]);
return existsForm;
}
}
}

View file

@ -0,0 +1,53 @@
using System.Collections.Generic;
using System.Linq;
namespace PKHeX.Core
{
public class EncounterArea6XYFriendSafari : EncounterArea
{
public static bool WasFriendSafari(PKM pkm)
{
if (!pkm.XY)
return false;
if (pkm.Met_Location != 148)
return false;
if (pkm.Met_Level != 30)
return false;
if (pkm.Egg_Location != 0)
return false;
return true;
}
public static ILookup<int, EncounterSlot6XY> GetArea()
{
var area = new EncounterArea6XYFriendSafari { Location = 148 };
EncounterSlot6XY FriendSafariSlot(int d)
{
return new EncounterSlot6XY
{
Area = area,
Species = d,
LevelMin = 30,
LevelMax = 30,
Form = 0,
Type = SlotType.FriendSafari,
Version = GameVersion.XY,
};
}
area.Slots = Legal.FriendSafari.Select(FriendSafariSlot).ToArray();
return area.Slots.Cast<EncounterSlot6XY>().ToLookup(s => s.Species);
}
public static IEnumerable<EncounterSlot> GetValidSafariEncounters(PKM pkm)
{
var chain = EvolutionChain.GetValidPreEvolutions(pkm);
return GetValidSafariEncounters(chain);
}
public static IEnumerable<EncounterSlot> GetValidSafariEncounters(IReadOnlyList<DexLevel> chain)
{
var valid = chain.Where(d => d.Level >= 30);
return valid.SelectMany(z => Encounters6.FriendSafari[z.Species]);
}
}
}

View file

@ -8,74 +8,28 @@ namespace PKHeX.Core
/// </summary>
public sealed class EncounterArea7 : EncounterArea32
{
protected override IEnumerable<EncounterSlot> GetFilteredSlots(PKM pkm, IEnumerable<EncounterSlot> slots, int minLevel)
public override IEnumerable<EncounterSlot> GetMatchingSlots(PKM pkm, IReadOnlyList<EvoCriteria> chain)
{
int species = pkm.Species;
int form = pkm.AltForm;
foreach (var slot in Slots)
{
foreach (var evo in chain)
{
if (slot.Species != evo.Species)
continue;
// Edge Case Handling
switch (species)
if (!slot.IsLevelWithinRange(pkm.Met_Level))
break;
if (slot.Form != evo.Form && !Legal.WildChangeFormAfter.Contains(slot.Species))
{
case 744 when form == 1: // Rockruff Event
case 745 when form == 2: // Lycanroc Event
yield break;
if (slot.Species != (int)Species.Minior) // Random Color, edge case
break;
}
EncounterSlot? slotMax = null;
void CachePressureSlot(EncounterSlot s)
{
if (slotMax != null && s.LevelMax > slotMax.LevelMax)
slotMax = s;
}
if (Legal.AlolanVariantEvolutions12.Contains(species) || Legal.GalarVariantFormEvolutions.Contains(species)) // match form if same species, else form 0.
{
foreach (var slot in slots)
{
if (species == slot.Species ? slot.Form == form : slot.Form == 0)
yield return slot;
CachePressureSlot(slot);
}
}
else if (ShouldMatchSlotForm()) // match slot form
{
foreach (var slot in slots)
{
if (slot.Form == form)
yield return slot;
CachePressureSlot(slot);
}
}
else
{
foreach (var slot in slots)
{
yield return slot; // no form checking
CachePressureSlot(slot);
}
}
// Filter for Form Specific
// Pressure Slot
if (slotMax == null)
yield break;
if (Legal.AlolanVariantEvolutions12.Contains(species) || Legal.GalarVariantFormEvolutions.Contains(species)) // match form if same species, else form 0.
{
if (species == slotMax.Species ? slotMax.Form == form : slotMax.Form == 0)
yield return GetPressureSlot(slotMax, pkm);
}
else if (ShouldMatchSlotForm()) // match slot form
{
if (slotMax.Form == form)
yield return GetPressureSlot(slotMax, pkm);
}
else
{
yield return GetPressureSlot(slotMax, pkm);
}
bool ShouldMatchSlotForm() => Legal.WildForms.Contains(species) || Legal.AlolanOriginForms.Contains(species) || FormConverter.IsTotemForm(species, form, 7);
break;
}
}
}
}
}

View file

@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Linq;
namespace PKHeX.Core
{
@ -11,17 +10,25 @@ namespace PKHeX.Core
{
private const int CatchComboBonus = 1;
protected override IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IReadOnlyList<DexLevel> chain, int minLevel)
public override IEnumerable<EncounterSlot> GetMatchingSlots(PKM pkm, IReadOnlyList<EvoCriteria> chain)
{
var slots = Slots.Where(slot => chain.Any(evo => evo.Species == slot.Species && evo.Form == slot.Form && evo.Level >= (slot.LevelMin - CatchComboBonus)));
// Get slots where pokemon can exist with respect to level constraints
return slots.Where(s => s.IsLevelWithinRange(minLevel, minLevel, 0, CatchComboBonus));
}
protected override IEnumerable<EncounterSlot> GetFilteredSlots(PKM pkm, IEnumerable<EncounterSlot> slots, int minLevel)
foreach (var slot in Slots)
{
return slots;
foreach (var evo in chain)
{
if (slot.Species != evo.Species)
continue;
var met = pkm.Met_Level;
if (!slot.IsLevelWithinRange(met, 0, CatchComboBonus))
break;
if (slot.Form != evo.Form)
break;
yield return slot;
break;
}
}
}
}
}

View file

@ -8,36 +8,22 @@ namespace PKHeX.Core
/// </summary>
public sealed class EncounterArea7g : EncounterArea32
{
protected override IEnumerable<EncounterSlot> GetFilteredSlots(PKM pkm, IEnumerable<EncounterSlot> slots, int minLevel)
public override IEnumerable<EncounterSlot> GetMatchingSlots(PKM pkm, IReadOnlyList<EvoCriteria> chain)
{
int species = pkm.Species;
if (species == (int) Species.MrRime || species == (int) Species.Sirfetchd)
yield break;
foreach (var slot in Slots)
{
foreach (var evo in chain)
{
if (slot.Species != evo.Species)
continue;
int form = pkm.AltForm;
if (!slot.IsLevelWithinRange(pkm.Met_Level))
break;
if (slot.Form != evo.Form)
break;
if (Legal.AlolanVariantEvolutions12.Contains(species) || Legal.GalarVariantFormEvolutions.Contains(species)) // match form if same species, else form 0.
{
foreach (var slot in slots)
{
if (species == slot.Species ? slot.Form == form : slot.Form == 0)
yield return slot;
}
}
else if (Legal.AlolanOriginForms.Contains(species)) // match slot form
{
foreach (var slot in slots)
{
if (slot.Form == form)
yield return slot;
}
}
else if (form == 0)
{
// enforce no form
foreach (var slot in slots)
{
yield return slot;
break;
}
}
}

View file

@ -27,36 +27,29 @@ namespace PKHeX.Core
return others.Contains((byte)location);
}
protected override IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IReadOnlyList<DexLevel> chain, int minLevel)
public override IEnumerable<EncounterSlot> GetMatchingSlots(PKM pkm, IReadOnlyList<EvoCriteria> chain)
{
var loc = Location;
if (IsWildArea8(loc) || IsWildArea8Armor(loc)) // wild area gets boosted up to level 60 post-game
bool canBoostTo60 = IsWildArea8(loc) || IsWildArea8Armor(loc); // wild area gets boosted up to level 60 post-game
bool isBoosted = canBoostTo60 && pkm.Met_Location == 60;
foreach (var slot in Slots)
{
const int boostTo = 60;
if (pkm.Met_Level == boostTo)
foreach (var evo in chain)
{
var boost = Slots.Where(slot => chain.Any(evo => IsMatch(evo, slot) && evo.Level >= boostTo));
return boost.Where(s => s.LevelMax < boostTo || s.IsLevelWithinRange(minLevel));
}
}
var slots = Slots.Where(slot => chain.Any(evo => IsMatch(evo, slot) && evo.Level >= slot.LevelMin));
if (slot.Species != evo.Species)
continue;
// Get slots where pokemon can exist with respect to level constraints
return slots.Where(s => s.IsLevelWithinRange(minLevel));
}
if (!slot.IsLevelWithinRange(pkm.Met_Level) && !isBoosted)
break;
private static bool IsMatch(DexLevel evo, EncounterSlot slot)
{
if (evo.Species != slot.Species)
return false;
if (evo.Form == slot.Form)
return true;
if (Legal.FormChange.Contains(evo.Species))
return true;
return false;
}
if (slot.Form != evo.Form && !Legal.WildChangeFormAfter.Contains(evo.Species))
break;
protected override IEnumerable<EncounterSlot> GetFilteredSlots(PKM pkm, IEnumerable<EncounterSlot> slots, int minLevel) => slots;
yield return slot;
break;
}
}
}
public static bool IsWildArea8(int loc) => 122 <= loc && loc <= 154; // Rolling Fields -> Lake of Outrage
public static bool IsWildArea8Armor(int loc) => 164 <= loc && loc <= 194; // Fields of Honor -> Honeycalm Island
@ -249,6 +242,7 @@ namespace PKHeX.Core
{
public readonly AreaWeather8 Weather;
public override string LongName => Weather == AreaWeather8.All ? wild : $"{wild} - {Weather.ToString().Replace("_", string.Empty)}";
public override int Generation => 8;
public EncounterSlot8(int specForm, int min, int max, AreaWeather8 weather)
{

View file

@ -1,5 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using System;
using System.Collections.Generic;
namespace PKHeX.Core
{
@ -9,10 +9,7 @@ namespace PKHeX.Core
/// </summary>
public sealed class EncounterAreaFake : EncounterArea
{
protected override IEnumerable<EncounterSlot> GetMatchFromEvoLevel(PKM pkm, IReadOnlyList<DexLevel> chain, int minLevel)
=> Enumerable.Empty<EncounterSlot>();
protected override IEnumerable<EncounterSlot> GetFilteredSlots(PKM pkm, IEnumerable<EncounterSlot> slots, int minLevel)
=> Enumerable.Empty<EncounterSlot>();
public override IEnumerable<EncounterSlot> GetMatchingSlots(PKM pkm, IReadOnlyList<EvoCriteria> chain) =>
Array.Empty<EncounterSlot>();
}
}

View file

@ -183,37 +183,6 @@ namespace PKHeX.Core
};
}
private static bool IsEvolvedFormChange(PKM pkm, int expected)
{
if (pkm.IsEgg)
return false;
if (pkm.Format >= 7 && (AlolanVariantEvolutions12.Contains(pkm.Species) || GalarVariantFormEvolutions.Contains(pkm.Species)))
return pkm.AltForm == 1;
if (pkm.Format >= 8)
{
if (GalarVariantFormEvolutions.Contains(pkm.Species))
return pkm.AltForm == 1;
if (GalarForm0Evolutions.TryGetValue(pkm.Species, out var orig))
return pkm.AltForm != orig; // bad compare?
if ((int) Species.Darmanitan == pkm.Species)
return pkm.AltForm == (expected == 1 ? 2 : 0);
if ((int) Species.MrMime == pkm.Species)
return pkm.AltForm == (expected == 0 ? 1 : 0);
if ((int) Species.Slowbro == pkm.Species)
return pkm.AltForm == (expected == 1 ? 2 : 0);
if ((int) Species.Toxtricity == pkm.Species)
return pkm.AltForm == EvolutionMethod.GetAmpLowKeyResult(pkm.Nature);
if ((int) Species.Alcremie == pkm.Species)
return true;
}
if ((pkm.Species == (int)Species.Meowstic || pkm.Species == (int)Species.Indeedee) && pkm.Gender == 1)
return pkm.AltForm == 1;
if (pkm.Species == (int)Species.Lycanroc)
return pkm.AltForm < 3;
return pkm.Species == (int)Species.Silvally;
}
internal static bool IsEvolutionValid(PKM pkm, int minSpecies = -1, int minLevel = -1)
{
var curr = EvolutionChain.GetValidPreEvolutions(pkm, minLevel: minLevel);
@ -295,16 +264,14 @@ namespace PKHeX.Core
}
/// <summary>Checks if the form may be different than the original encounter detail.</summary>
/// <param name="pkm">Pokémon</param>
/// <param name="species">Original species</param>
/// <param name="form">Original form</param>
internal static bool IsFormChangeable(PKM pkm, int species, int form)
/// <param name="format">Current format</param>
internal static bool IsFormChangeable(int species, int form, int format)
{
if (FormChange.Contains(species))
return true;
if (species != pkm.Species && IsEvolvedFormChange(pkm, form))
return true;
if (species == (int)Species.Zygarde && pkm.InhabitedGeneration(7) && pkm.AltForm > 1)
if (species == (int)Species.Zygarde && format >= 7 && form == 0)
return true;
return false;
}
@ -338,48 +305,6 @@ namespace PKHeX.Core
return MoveList.GetValidMoves(pkm, version, evos, generation, LVL: true, Relearn: true, Tutor: true, Machine: true).Contains(move);
}
private static int GetMaxLevelGeneration(PKM pkm)
{
return GetMaxLevelGeneration(pkm, pkm.GenNumber);
}
private static int GetMaxLevelGeneration(PKM pkm, int generation)
{
if (!pkm.InhabitedGeneration(generation))
return pkm.Met_Level;
if (pkm.Format <= 2)
{
if (generation == 1 && FutureEvolutionsGen1_Gen2LevelUp.Contains(pkm.Species))
return pkm.CurrentLevel - 1;
return pkm.CurrentLevel;
}
if (pkm.Species == (int)Species.Sylveon && generation == 5)
return pkm.CurrentLevel - 1;
if (pkm.Gen3 && pkm.Format > 4 && pkm.Met_Level == pkm.CurrentLevel && FutureEvolutionsGen3_LevelUpGen4.Contains(pkm.Species))
return pkm.Met_Level - 1;
if (!pkm.HasOriginalMetLocation)
return pkm.Met_Level;
return pkm.CurrentLevel;
}
internal static int GetMaxLevelEncounter(PKM pkm)
{
// Only for gen 3 pokemon in format 3, after transfer to gen 4 it should return transfer level
if (pkm.Format == 3 && pkm.WasEgg)
return 5;
// Only for gen 4 pokemon in format 4, after transfer to gen 5 it should return transfer level
if (pkm.Format == 4 && pkm.Gen4 && pkm.WasEgg)
return 1;
return pkm.HasOriginalMetLocation ? pkm.Met_Level : GetMaxLevelGeneration(pkm);
}
internal static bool IsCatchRateHeldItem(int rate) => ParseSettings.AllowGen1Tradeback && HeldItems_GSC.Contains((ushort) rate);
internal const GameVersion NONE = GameVersion.Invalid;

View file

@ -14,7 +14,7 @@ namespace PKHeX.Core
/// <param name="source">Table of valid encounters that appear for the game pairing</param>
/// <param name="game">Game to filter for</param>
/// <returns>Array of encounter objects that can be encountered in the input game</returns>
internal static EncounterStatic[] GetStaticEncounters(IEnumerable<EncounterStatic> source, GameVersion game)
internal static T[] GetEncounters<T>(IEnumerable<T> source, GameVersion game) where T : IVersion
{
return source.Where(s => s.Version.Contains(game)).ToArray();
}
@ -25,10 +25,12 @@ namespace PKHeX.Core
/// <param name="ident">Unpacking identification ASCII characters (first two bytes of binary)</param>
/// <param name="resource">Resource name (will be prefixed with "encounter_"</param>
/// <returns>Array of encounter areas</returns>
internal static T[] GetEncounterTables<T>(string ident, string resource) where T : EncounterArea32, new()
internal static A[] GetEncounterTables<A, S>(string ident, string resource)
where A : EncounterArea32, new()
where S : EncounterSlot, new()
{
byte[] mini = Util.GetBinaryResource($"encounter_{resource}.pkl");
return EncounterArea32.GetArray<T>(BinLinker.Unpack(mini, ident));
return EncounterArea32.GetArray<A, S>(BinLinker.Unpack(mini, ident));
}
/// <summary>
@ -63,78 +65,82 @@ namespace PKHeX.Core
/// <remarks>Magnet Pull attracts Steel type slots, and Static attracts Electric</remarks>
/// <param name="areas">Encounter Area array for game</param>
/// <param name="t">Personal data for use with a given species' type</param>
internal static void MarkEncountersStaticMagnetPull(IEnumerable<EncounterArea> areas, PersonalTable t)
internal static void MarkEncountersStaticMagnetPull<T>(IEnumerable<EncounterArea> areas, PersonalTable t)
where T : EncounterSlot, IMagnetStatic
{
foreach (EncounterArea area in areas)
{
foreach (var grp in area.Slots.GroupBy(z => z.Type))
foreach (var grp in area.Slots.Cast<T>().GroupBy(z => z.Type))
MarkEncountersStaticMagnetPull(grp, t);
}
}
internal static void MarkEncountersStaticMagnetPull(IEnumerable<EncounterSlot> grp, PersonalTable t)
internal static void MarkEncountersStaticMagnetPull<T>(IEnumerable<T> grp, PersonalTable t)
where T : EncounterSlot, IMagnetStatic
{
GetStaticMagnet(t, grp, out List<EncounterSlot> s, out List<EncounterSlot> m);
GetStaticMagnet(t, grp, out List<T> s, out List<T> m);
for (var i = 0; i < s.Count; i++)
{
var slot = s[i];
slot.Permissions.StaticIndex = i;
slot.Permissions.StaticCount = s.Count;
slot.StaticIndex = i;
slot.StaticCount = s.Count;
}
for (var i = 0; i < m.Count; i++)
{
var slot = m[i];
slot.Permissions.MagnetPullIndex = i;
slot.Permissions.MagnetPullCount = m.Count;
slot.MagnetPullIndex = i;
slot.MagnetPullCount = m.Count;
}
}
internal static void MarkEncountersStaticMagnetPullPermutation(IEnumerable<EncounterSlot> grp, PersonalTable t, List<EncounterSlot> permuted)
internal static void MarkEncountersStaticMagnetPullPermutation<T>(IEnumerable<T> grp, PersonalTable t, List<T> permuted)
where T : EncounterSlot, IMagnetStatic, INumberedSlot
{
GetStaticMagnet(t, grp, out List<EncounterSlot> s, out List<EncounterSlot> m);
GetStaticMagnet(t, grp, out List<T> s, out List<T> m);
// Apply static/magnet values; if any permutation has a unique slot combination, add it to the slot list.
for (int i = 0; i < s.Count; i++)
{
var slot = s[i];
if (slot.Permissions.StaticIndex >= 0) // already has unique data
if (slot.StaticIndex >= 0) // already has unique data
{
if (slot.IsMatchStatic(i, s.Count))
continue; // same values, no permutation
if (permuted.Any(z => z.SlotNumber == slot.SlotNumber && z.IsMatchStatic(i, s.Count) && z.Species == slot.Species))
continue; // same values, previously permuted
s[i] = slot = slot.Clone();
s[i] = slot = (T)slot.Clone();
permuted.Add(slot);
}
slot.Permissions.StaticIndex = i;
slot.Permissions.StaticCount = s.Count;
slot.StaticIndex = i;
slot.StaticCount = s.Count;
}
for (int i = 0; i < m.Count; i++)
{
var slot = m[i];
if (slot.Permissions.MagnetPullIndex >= 0) // already has unique data
if (slot.MagnetPullIndex >= 0) // already has unique data
{
if (slot.IsMatchStatic(i, m.Count))
continue; // same values, no permutation
if (permuted.Any(z => z.SlotNumber == slot.SlotNumber && z.IsMatchMagnet(i, m.Count) && z.Species == slot.Species))
continue; // same values, previously permuted
m[i] = slot = slot.Clone();
m[i] = slot = (T)slot.Clone();
permuted.Add(slot);
}
slot.Permissions.MagnetPullIndex = i;
slot.Permissions.MagnetPullCount = m.Count;
slot.MagnetPullIndex = i;
slot.MagnetPullCount = m.Count;
}
}
private static void GetStaticMagnet(PersonalTable t, IEnumerable<EncounterSlot> grp, out List<EncounterSlot> s, out List<EncounterSlot> m)
private static void GetStaticMagnet<T>(PersonalTable t, IEnumerable<T> grp, out List<T> s, out List<T> m)
where T : EncounterSlot, IMagnetStatic
{
const int steel = (int)MoveType.Steel;
const int electric = (int)MoveType.Electric + 1; // offset by 1 in gen3/4 for the ??? type
s = new List<EncounterSlot>();
m = new List<EncounterSlot>();
foreach (EncounterSlot Slot in grp)
s = new List<T>();
m = new List<T>();
foreach (T Slot in grp)
{
var p = t[Slot.Species];
if (p.IsType(steel))
@ -170,20 +176,6 @@ namespace PKHeX.Core
MarkEncountersGeneration(generation, table);
}
/// <summary>
/// Sets the <see cref="IGenerationSet.Generation"/> value, for use in determining split-generation origins.
/// </summary>
/// <param name="generation">Generation number to set</param>
/// <param name="areas">In-game encounter data</param>
internal static void MarkEncountersGeneration(int generation, params IEnumerable<EncounterArea>[] areas)
{
foreach (var table in areas)
{
foreach (var area in table)
MarkEncountersGeneration(generation, area.Slots);
}
}
private static void MarkEncountersGeneration(int generation, IEnumerable<IGenerationSet> encounters)
{
foreach (var enc in encounters)
@ -228,23 +220,23 @@ namespace PKHeX.Core
return result;
}
internal static EncounterStatic[] Clone(this EncounterStatic s, int[] locations)
internal static T[] Clone<T>(this T s, int[] locations) where T : EncounterStatic
{
EncounterStatic[] Encounters = new EncounterStatic[locations.Length];
var Encounters = new T[locations.Length];
for (int i = 0; i < locations.Length; i++)
Encounters[i] = s.Clone(locations[i]);
Encounters[i] = (T)s.Clone(locations[i]);
return Encounters;
}
internal static IEnumerable<EncounterStatic> DreamRadarClone(this EncounterStatic s)
internal static IEnumerable<EncounterStatic5> DreamRadarClone(this EncounterStatic5 s)
{
for (int i = 0; i < 8; i++)
yield return s.DreamRadarClone((5 * i) + 5); // Level from 5->40 depends on the number of badges
}
private static EncounterStatic DreamRadarClone(this EncounterStatic s, int level)
private static EncounterStatic5 DreamRadarClone(this EncounterStatic5 s, int level)
{
var result = s.Clone(level);
var result = (EncounterStatic5)(s.Clone(level));
result.Level = level;
result.Location = 30015;// Pokemon Dream Radar
result.Gift = true; // Only

View file

@ -16,7 +16,6 @@ namespace PKHeX.Core
{
StaticRBY = Encounter_RBY;
SlotsRBY = GetAreas();
MarkEncountersGeneration(1, SlotsRBY);
MarkEncountersGeneration(1, StaticRBY, TradeGift_RBY_NoTradeback, TradeGift_RBY_Tradeback);
var trades = ArrayUtil.ConcatAll(TradeGift_RBY_NoTradeback, TradeGift_RBY_Tradeback);

View file

@ -25,7 +25,6 @@ namespace PKHeX.Core
ReduceAreasSize(ref SlotsGS);
ReduceAreasSize(ref SlotsC);
ReduceAreasSize(ref SlotsGSC);
MarkEncountersGeneration(2, SlotsGS, SlotsC, SlotsGSC);
MarkEncountersGeneration(2, StaticGS, StaticC, StaticGSC, TradeGift_GSC);
MarkEncounterTradeStrings(TradeGift_GSC, TradeGift_GSC_OTs);

View file

@ -12,19 +12,19 @@ namespace PKHeX.Core
{
internal static readonly EncounterArea3[] SlotsR, SlotsS, SlotsE;
internal static readonly EncounterArea3[] SlotsFR, SlotsLG;
internal static readonly EncounterStatic[] StaticR, StaticS, StaticE;
internal static readonly EncounterStatic[] StaticFR, StaticLG;
internal static readonly EncounterStatic3[] StaticR, StaticS, StaticE;
internal static readonly EncounterStatic3[] StaticFR, StaticLG;
private const int SafariLocation_RSE = 57;
private const int SafariLocation_FRLG = 136;
static Encounters3()
{
StaticR = GetStaticEncounters(Encounter_RSE, GameVersion.R);
StaticS = GetStaticEncounters(Encounter_RSE, GameVersion.S);
StaticE = GetStaticEncounters(Encounter_RSE, GameVersion.E);
StaticFR = GetStaticEncounters(Encounter_FRLG, GameVersion.FR);
StaticLG = GetStaticEncounters(Encounter_FRLG, GameVersion.LG);
StaticR = GetEncounters(Encounter_RSE, GameVersion.R);
StaticS = GetEncounters(Encounter_RSE, GameVersion.S);
StaticE = GetEncounters(Encounter_RSE, GameVersion.E);
StaticFR = GetEncounters(Encounter_FRLG, GameVersion.FR);
StaticLG = GetEncounters(Encounter_FRLG, GameVersion.LG);
static EncounterArea3[] get(string resource, string ident)
=> EncounterArea3.GetArray3(BinLinker.Unpack(Util.GetBinaryResource($"encounter_{resource}.pkl"), ident));
@ -49,7 +49,7 @@ namespace PKHeX.Core
MarkG3SlotsSafariZones(ref FR_Slots, SafariLocation_FRLG);
MarkG3SlotsSafariZones(ref LG_Slots, SafariLocation_FRLG);
MarkEncountersStaticMagnetPull(E_Slots, PersonalTable.SM);
MarkEncountersStaticMagnetPull<EncounterSlot3>(E_Slots, PersonalTable.E);
SlotsR = AddExtraTableSlots(R_Slots, SlotsRSEAlt);
SlotsS = AddExtraTableSlots(S_Slots, SlotsRSEAlt);
@ -57,7 +57,6 @@ namespace PKHeX.Core
SlotsFR = AddExtraTableSlots(FR_Slots, SlotsFRLGUnown);
SlotsLG = AddExtraTableSlots(LG_Slots, SlotsFRLGUnown);
MarkEncountersGeneration(3, SlotsR, SlotsS, SlotsE, SlotsFR, SlotsLG, SlotsXD);
MarkEncountersGeneration(3, StaticR, StaticS, StaticE, StaticFR, StaticLG, Encounter_CXD, TradeGift_RSE, TradeGift_FRLG);
MarkEncounterTradeStrings(TradeGift_RSE, TradeRSE);
@ -117,122 +116,122 @@ namespace PKHeX.Core
46, 47, 48, 49,
};
private static readonly EncounterStatic[] Encounter_RSE_Roam =
private static readonly EncounterStatic3[] Encounter_RSE_Roam =
{
new EncounterStatic { Species = 380, Level = 40, Version = GameVersion.S, Roaming = true }, // Latias
new EncounterStatic { Species = 380, Level = 40, Version = GameVersion.E, Roaming = true }, // Latias
new EncounterStatic { Species = 381, Level = 40, Version = GameVersion.R, Roaming = true }, // Latios
new EncounterStatic { Species = 381, Level = 40, Version = GameVersion.E, Roaming = true }, // Latios
new EncounterStatic3 { Species = 380, Level = 40, Version = GameVersion.S, Roaming = true }, // Latias
new EncounterStatic3 { Species = 380, Level = 40, Version = GameVersion.E, Roaming = true }, // Latias
new EncounterStatic3 { Species = 381, Level = 40, Version = GameVersion.R, Roaming = true }, // Latios
new EncounterStatic3 { Species = 381, Level = 40, Version = GameVersion.E, Roaming = true }, // Latios
};
private static readonly EncounterStatic[] Encounter_RSE_Regular =
private static readonly EncounterStatic3[] Encounter_RSE_Regular =
{
// Starters
new EncounterStatic { Gift = true, Species = 152, Level = 05, Location = 000, Version = GameVersion.E, }, // Chikorita @ Littleroot Town
new EncounterStatic { Gift = true, Species = 155, Level = 05, Location = 000, Version = GameVersion.E, }, // Cyndaquil
new EncounterStatic { Gift = true, Species = 158, Level = 05, Location = 000, Version = GameVersion.E, }, // Totodile
new EncounterStatic { Gift = true, Species = 252, Level = 05, Location = 016, }, // Treecko @ Route 101
new EncounterStatic { Gift = true, Species = 255, Level = 05, Location = 016, }, // Torchic
new EncounterStatic { Gift = true, Species = 258, Level = 05, Location = 016, }, // Mudkip
new EncounterStatic3 { Gift = true, Species = 152, Level = 05, Location = 000, Version = GameVersion.E, }, // Chikorita @ Littleroot Town
new EncounterStatic3 { Gift = true, Species = 155, Level = 05, Location = 000, Version = GameVersion.E, }, // Cyndaquil
new EncounterStatic3 { Gift = true, Species = 158, Level = 05, Location = 000, Version = GameVersion.E, }, // Totodile
new EncounterStatic3 { Gift = true, Species = 252, Level = 05, Location = 016, }, // Treecko @ Route 101
new EncounterStatic3 { Gift = true, Species = 255, Level = 05, Location = 016, }, // Torchic
new EncounterStatic3 { Gift = true, Species = 258, Level = 05, Location = 016, }, // Mudkip
// Fossil @ Rustboro City
new EncounterStatic { Gift = true, Species = 345, Level = 20, Location = 010, }, // Lileep
new EncounterStatic { Gift = true, Species = 347, Level = 20, Location = 010, }, // Anorith
new EncounterStatic3 { Gift = true, Species = 345, Level = 20, Location = 010, }, // Lileep
new EncounterStatic3 { Gift = true, Species = 347, Level = 20, Location = 010, }, // Anorith
// Gift
new EncounterStatic { Gift = true, Species = 351, Level = 25, Location = 034, }, // Castform @ Weather Institute
new EncounterStatic { Gift = true, Species = 374, Level = 05, Location = 013, }, // Beldum @ Mossdeep City
new EncounterStatic { Gift = true, Species = 360, Level = 05, EggLocation = 253}, // Wynaut Egg
new EncounterStatic3 { Gift = true, Species = 351, Level = 25, Location = 034, }, // Castform @ Weather Institute
new EncounterStatic3 { Gift = true, Species = 374, Level = 05, Location = 013, }, // Beldum @ Mossdeep City
new EncounterStatic3 { Gift = true, Species = 360, Level = 05, EggLocation = 253}, // Wynaut Egg
// Stationary
new EncounterStatic { Species = 352, Level = 30, Location = 034, }, // Kecleon @ Route 119
new EncounterStatic { Species = 352, Level = 30, Location = 035, }, // Kecleon @ Route 120
new EncounterStatic { Species = 101, Level = 30, Location = 066, Version = GameVersion.RS, }, // Electrode @ Hideout (R:Magma Hideout/S:Aqua Hideout)
new EncounterStatic { Species = 101, Level = 30, Location = 197, Version = GameVersion.E, }, // Electrode @ Aqua Hideout
new EncounterStatic { Species = 185, Level = 40, Location = 058, Version = GameVersion.E, }, // Sudowoodo @ Battle Frontier
new EncounterStatic3 { Species = 352, Level = 30, Location = 034, }, // Kecleon @ Route 119
new EncounterStatic3 { Species = 352, Level = 30, Location = 035, }, // Kecleon @ Route 120
new EncounterStatic3 { Species = 101, Level = 30, Location = 066, Version = GameVersion.RS, }, // Electrode @ Hideout (R:Magma Hideout/S:Aqua Hideout)
new EncounterStatic3 { Species = 101, Level = 30, Location = 197, Version = GameVersion.E, }, // Electrode @ Aqua Hideout
new EncounterStatic3 { Species = 185, Level = 40, Location = 058, Version = GameVersion.E, }, // Sudowoodo @ Battle Frontier
// Stationary Lengendary
new EncounterStatic { Species = 377, Level = 40, Location = 082, }, // Regirock @ Desert Ruins
new EncounterStatic { Species = 378, Level = 40, Location = 081, }, // Regice @ Island Cave
new EncounterStatic { Species = 379, Level = 40, Location = 083, }, // Registeel @ Ancient Tomb
new EncounterStatic { Species = 380, Level = 50, Location = 073, Version = GameVersion.R }, // Latias @ Southern Island
new EncounterStatic { Species = 380, Level = 50, Location = 073, Version = GameVersion.E, Fateful = true }, // Latias @ Southern Island
new EncounterStatic { Species = 381, Level = 50, Location = 073, Version = GameVersion.S }, // Latios @ Southern Island
new EncounterStatic { Species = 381, Level = 50, Location = 073, Version = GameVersion.E, Fateful = true }, // Latios @ Southern Island
new EncounterStatic { Species = 382, Level = 45, Location = 072, Version = GameVersion.S, }, // Kyogre @ Cave of Origin
new EncounterStatic { Species = 382, Level = 70, Location = 203, Version = GameVersion.E, }, // Kyogre @ Marine Cave
new EncounterStatic { Species = 383, Level = 45, Location = 072, Version = GameVersion.R, }, // Groudon @ Cave of Origin
new EncounterStatic { Species = 383, Level = 70, Location = 205, Version = GameVersion.E, }, // Groudon @ Terra Cave
new EncounterStatic { Species = 384, Level = 70, Location = 085, }, // Rayquaza @ Sky Pillar
new EncounterStatic3 { Species = 377, Level = 40, Location = 082, }, // Regirock @ Desert Ruins
new EncounterStatic3 { Species = 378, Level = 40, Location = 081, }, // Regice @ Island Cave
new EncounterStatic3 { Species = 379, Level = 40, Location = 083, }, // Registeel @ Ancient Tomb
new EncounterStatic3 { Species = 380, Level = 50, Location = 073, Version = GameVersion.R }, // Latias @ Southern Island
new EncounterStatic3 { Species = 380, Level = 50, Location = 073, Version = GameVersion.E, Fateful = true }, // Latias @ Southern Island
new EncounterStatic3 { Species = 381, Level = 50, Location = 073, Version = GameVersion.S }, // Latios @ Southern Island
new EncounterStatic3 { Species = 381, Level = 50, Location = 073, Version = GameVersion.E, Fateful = true }, // Latios @ Southern Island
new EncounterStatic3 { Species = 382, Level = 45, Location = 072, Version = GameVersion.S, }, // Kyogre @ Cave of Origin
new EncounterStatic3 { Species = 382, Level = 70, Location = 203, Version = GameVersion.E, }, // Kyogre @ Marine Cave
new EncounterStatic3 { Species = 383, Level = 45, Location = 072, Version = GameVersion.R, }, // Groudon @ Cave of Origin
new EncounterStatic3 { Species = 383, Level = 70, Location = 205, Version = GameVersion.E, }, // Groudon @ Terra Cave
new EncounterStatic3 { Species = 384, Level = 70, Location = 085, }, // Rayquaza @ Sky Pillar
// Event
new EncounterStatic { Species = 151, Level = 30, Location = 201, Version = GameVersion.E, Fateful = true }, // Mew @ Faraway Island (Unreleased outside of Japan)
new EncounterStatic { Species = 249, Level = 70, Location = 211, Version = GameVersion.E, Fateful = true }, // Lugia @ Navel Rock
new EncounterStatic { Species = 250, Level = 70, Location = 211, Version = GameVersion.E, Fateful = true }, // Ho-Oh @ Navel Rock
new EncounterStatic { Species = 386, Level = 30, Location = 200, Version = GameVersion.E, Fateful = true, Form = 3 }, // Deoxys @ Birth Island
new EncounterStatic3 { Species = 151, Level = 30, Location = 201, Version = GameVersion.E, Fateful = true }, // Mew @ Faraway Island (Unreleased outside of Japan)
new EncounterStatic3 { Species = 249, Level = 70, Location = 211, Version = GameVersion.E, Fateful = true }, // Lugia @ Navel Rock
new EncounterStatic3 { Species = 250, Level = 70, Location = 211, Version = GameVersion.E, Fateful = true }, // Ho-Oh @ Navel Rock
new EncounterStatic3 { Species = 386, Level = 30, Location = 200, Version = GameVersion.E, Fateful = true, Form = 3 }, // Deoxys @ Birth Island
};
private static readonly EncounterStatic[] Encounter_FRLG_Roam =
private static readonly EncounterStatic3[] Encounter_FRLG_Roam =
{
new EncounterStatic { Species = 243, Level = 50, Roaming = true, }, // Raikou
new EncounterStatic { Species = 244, Level = 50, Roaming = true, }, // Entei
new EncounterStatic { Species = 245, Level = 50, Roaming = true, }, // Suicune
new EncounterStatic3 { Species = 243, Level = 50, Roaming = true, }, // Raikou
new EncounterStatic3 { Species = 244, Level = 50, Roaming = true, }, // Entei
new EncounterStatic3 { Species = 245, Level = 50, Roaming = true, }, // Suicune
};
private static readonly EncounterStatic[] Encounter_FRLG_Stationary =
private static readonly EncounterStatic3[] Encounter_FRLG_Stationary =
{
// Starters @ Pallet Town
new EncounterStatic { Gift = true, Species = 1, Level = 05, Location = 088, }, // Bulbasaur
new EncounterStatic { Gift = true, Species = 4, Level = 05, Location = 088, }, // Charmander
new EncounterStatic { Gift = true, Species = 7, Level = 05, Location = 088, }, // Squirtle
new EncounterStatic3 { Gift = true, Species = 1, Level = 05, Location = 088, }, // Bulbasaur
new EncounterStatic3 { Gift = true, Species = 4, Level = 05, Location = 088, }, // Charmander
new EncounterStatic3 { Gift = true, Species = 7, Level = 05, Location = 088, }, // Squirtle
// Fossil @ Cinnabar Island
new EncounterStatic { Gift = true, Species = 138, Level = 05, Location = 096, }, // Omanyte
new EncounterStatic { Gift = true, Species = 140, Level = 05, Location = 096, }, // Kabuto
new EncounterStatic { Gift = true, Species = 142, Level = 05, Location = 096, }, // Aerodactyl
new EncounterStatic3 { Gift = true, Species = 138, Level = 05, Location = 096, }, // Omanyte
new EncounterStatic3 { Gift = true, Species = 140, Level = 05, Location = 096, }, // Kabuto
new EncounterStatic3 { Gift = true, Species = 142, Level = 05, Location = 096, }, // Aerodactyl
// Gift
new EncounterStatic { Gift = true, Species = 106, Level = 25, Location = 098, }, // Hitmonlee @ Saffron City
new EncounterStatic { Gift = true, Species = 107, Level = 25, Location = 098, }, // Hitmonchan @ Saffron City
new EncounterStatic { Gift = true, Species = 129, Level = 05, Location = 099, }, // Magikarp @ Route 4
new EncounterStatic { Gift = true, Species = 131, Level = 25, Location = 134, }, // Lapras @ Silph Co.
new EncounterStatic { Gift = true, Species = 133, Level = 25, Location = 094, }, // Eevee @ Celadon City
new EncounterStatic { Gift = true, Species = 175, Level = 05, EggLocation = 253 }, // Togepi Egg
new EncounterStatic3 { Gift = true, Species = 106, Level = 25, Location = 098, }, // Hitmonlee @ Saffron City
new EncounterStatic3 { Gift = true, Species = 107, Level = 25, Location = 098, }, // Hitmonchan @ Saffron City
new EncounterStatic3 { Gift = true, Species = 129, Level = 05, Location = 099, }, // Magikarp @ Route 4
new EncounterStatic3 { Gift = true, Species = 131, Level = 25, Location = 134, }, // Lapras @ Silph Co.
new EncounterStatic3 { Gift = true, Species = 133, Level = 25, Location = 094, }, // Eevee @ Celadon City
new EncounterStatic3 { Gift = true, Species = 175, Level = 05, EggLocation = 253 }, // Togepi Egg
// Celadon City Game Corner
new EncounterStatic { Gift = true, Species = 063, Level = 09, Location = 94, Version = GameVersion.FR }, // Abra
new EncounterStatic { Gift = true, Species = 035, Level = 08, Location = 94, Version = GameVersion.FR }, // Clefairy
new EncounterStatic { Gift = true, Species = 123, Level = 25, Location = 94, Version = GameVersion.FR }, // Scyther
new EncounterStatic { Gift = true, Species = 147, Level = 18, Location = 94, Version = GameVersion.FR }, // Dratini
new EncounterStatic { Gift = true, Species = 137, Level = 26, Location = 94, Version = GameVersion.FR }, // Porygon
new EncounterStatic3 { Gift = true, Species = 063, Level = 09, Location = 94, Version = GameVersion.FR }, // Abra
new EncounterStatic3 { Gift = true, Species = 035, Level = 08, Location = 94, Version = GameVersion.FR }, // Clefairy
new EncounterStatic3 { Gift = true, Species = 123, Level = 25, Location = 94, Version = GameVersion.FR }, // Scyther
new EncounterStatic3 { Gift = true, Species = 147, Level = 18, Location = 94, Version = GameVersion.FR }, // Dratini
new EncounterStatic3 { Gift = true, Species = 137, Level = 26, Location = 94, Version = GameVersion.FR }, // Porygon
new EncounterStatic { Gift = true, Species = 063, Level = 07, Location = 94, Version = GameVersion.LG }, // Abra
new EncounterStatic { Gift = true, Species = 035, Level = 12, Location = 94, Version = GameVersion.LG }, // Clefairy
new EncounterStatic { Gift = true, Species = 127, Level = 18, Location = 94, Version = GameVersion.LG }, // Pinsir
new EncounterStatic { Gift = true, Species = 147, Level = 24, Location = 94, Version = GameVersion.LG }, // Dratini
new EncounterStatic { Gift = true, Species = 137, Level = 18, Location = 94, Version = GameVersion.LG }, // Porygon
new EncounterStatic3 { Gift = true, Species = 063, Level = 07, Location = 94, Version = GameVersion.LG }, // Abra
new EncounterStatic3 { Gift = true, Species = 035, Level = 12, Location = 94, Version = GameVersion.LG }, // Clefairy
new EncounterStatic3 { Gift = true, Species = 127, Level = 18, Location = 94, Version = GameVersion.LG }, // Pinsir
new EncounterStatic3 { Gift = true, Species = 147, Level = 24, Location = 94, Version = GameVersion.LG }, // Dratini
new EncounterStatic3 { Gift = true, Species = 137, Level = 18, Location = 94, Version = GameVersion.LG }, // Porygon
// Stationary
new EncounterStatic { Species = 143, Level = 30, Location = 112, }, // Snorlax @ Route 12
new EncounterStatic { Species = 143, Level = 30, Location = 116, }, // Snorlax @ Route 16
new EncounterStatic { Species = 101, Level = 34, Location = 142, }, // Electrode @ Power Plant
new EncounterStatic { Species = 097, Level = 30, Location = 176, }, // Hypno @ Berry Forest
new EncounterStatic3 { Species = 143, Level = 30, Location = 112, }, // Snorlax @ Route 12
new EncounterStatic3 { Species = 143, Level = 30, Location = 116, }, // Snorlax @ Route 16
new EncounterStatic3 { Species = 101, Level = 34, Location = 142, }, // Electrode @ Power Plant
new EncounterStatic3 { Species = 097, Level = 30, Location = 176, }, // Hypno @ Berry Forest
// Stationary Legendary
new EncounterStatic { Species = 144, Level = 50, Location = 139, }, // Articuno @ Seafoam Islands
new EncounterStatic { Species = 145, Level = 50, Location = 142, }, // Zapdos @ Power Plant
new EncounterStatic { Species = 146, Level = 50, Location = 175, }, // Moltres @ Mt. Ember.
new EncounterStatic { Species = 150, Level = 70, Location = 141, }, // Mewtwo @ Cerulean Cave
new EncounterStatic3 { Species = 144, Level = 50, Location = 139, }, // Articuno @ Seafoam Islands
new EncounterStatic3 { Species = 145, Level = 50, Location = 142, }, // Zapdos @ Power Plant
new EncounterStatic3 { Species = 146, Level = 50, Location = 175, }, // Moltres @ Mt. Ember.
new EncounterStatic3 { Species = 150, Level = 70, Location = 141, }, // Mewtwo @ Cerulean Cave
// Event
new EncounterStatic { Species = 249, Level = 70, Location = 174, Fateful = true }, // Lugia @ Navel Rock
new EncounterStatic { Species = 250, Level = 70, Location = 174, Fateful = true }, // Ho-Oh @ Navel Rock
new EncounterStatic { Species = 386, Level = 30, Location = 187, Version = GameVersion.FR, Form = 1, Fateful = true }, // Deoxys @ Birth Island
new EncounterStatic { Species = 386, Level = 30, Location = 187, Version = GameVersion.LG, Form = 2, Fateful = true }, // Deoxys @ Birth Island
new EncounterStatic3 { Species = 249, Level = 70, Location = 174, Fateful = true }, // Lugia @ Navel Rock
new EncounterStatic3 { Species = 250, Level = 70, Location = 174, Fateful = true }, // Ho-Oh @ Navel Rock
new EncounterStatic3 { Species = 386, Level = 30, Location = 187, Version = GameVersion.FR, Form = 1, Fateful = true }, // Deoxys @ Birth Island
new EncounterStatic3 { Species = 386, Level = 30, Location = 187, Version = GameVersion.LG, Form = 2, Fateful = true }, // Deoxys @ Birth Island
};
private static readonly EncounterStatic[] Encounter_RSE = Encounter_RSE_Roam.SelectMany(e => e.Clone(Roaming_MetLocation_RSE)).Concat(Encounter_RSE_Regular).ToArray();
private static readonly EncounterStatic[] Encounter_FRLG = Encounter_FRLG_Roam.SelectMany(e => e.Clone(Roaming_MetLocation_FRLG)).Concat(Encounter_FRLG_Stationary).ToArray();
private static readonly EncounterStatic3[] Encounter_RSE = Encounter_RSE_Roam.SelectMany(e => e.Clone(Roaming_MetLocation_RSE)).Concat(Encounter_RSE_Regular).ToArray();
private static readonly EncounterStatic3[] Encounter_FRLG = Encounter_FRLG_Roam.SelectMany(e => e.Clone(Roaming_MetLocation_FRLG)).Concat(Encounter_FRLG_Stationary).ToArray();
private static readonly int[] TradeContest_Cool = { 30, 05, 05, 05, 05, 10 };
private static readonly int[] TradeContest_Beauty = { 05, 30, 05, 05, 05, 10 };
@ -240,32 +239,32 @@ namespace PKHeX.Core
private static readonly int[] TradeContest_Clever = { 05, 05, 05, 30, 05, 10 };
private static readonly int[] TradeContest_Tough = { 05, 05, 05, 05, 30, 10 };
internal static readonly EncounterTrade[] TradeGift_RSE =
internal static readonly EncounterTrade3[] TradeGift_RSE =
{
new EncounterTradePID(0x00009C40) { Species = 296, Ability = 2, TID = 49562, SID = 00000, OTGender = 0, Gender = 0, IVs = new[] {5,5,4,4,4,4}, Level = 05, Contest = TradeContest_Tough, Version = GameVersion.RS, }, // Slakoth (Level 5 Breeding) -> Makuhita
new EncounterTradePID(0x498A2E17) { Species = 300, Ability = 1, TID = 02259, SID = 00000, OTGender = 1, Gender = 1, IVs = new[] {5,4,4,5,4,4}, Level = 03, Contest = TradeContest_Cute, Version = GameVersion.RS, }, // Pikachu (Level 3 Viridiam Forest) -> Skitty
new EncounterTradePID(0x4C970B7F) { Species = 222, Ability = 2, TID = 50183, SID = 00000, OTGender = 1, Gender = 1, IVs = new[] {4,4,5,4,4,5}, Level = 21, Contest = TradeContest_Beauty, Version = GameVersion.RS, }, // Bellossom (Level 21 Odish -> Gloom -> Bellossom) -> Corsola
new EncounterTradePID(0x00000084) { Species = 273, Ability = 2, TID = 38726, SID = 00000, OTGender = 0, Gender = 0, IVs = new[] {5,4,5,4,4,4}, Level = 04, Contest = TradeContest_Cool, Version = GameVersion.E, }, // Ralts (Level 4 Route 102) -> Seedot
new EncounterTradePID(0x0000006F) { Species = 311, Ability = 1, TID = 08460, SID = 00001, OTGender = 0, Gender = 1, IVs = new[] {4,4,4,5,5,4}, Level = 05, Contest = TradeContest_Cute, Version = GameVersion.E, }, // Volbeat (Level 5 Breeding) -> Plusle
new EncounterTradePID(0x0000007F) { Species = 116, Ability = 1, TID = 46285, SID = 00000, OTGender = 0, Gender = 0, IVs = new[] {5,4,4,4,5,4}, Level = 05, Contest = TradeContest_Tough, Version = GameVersion.E, }, // Bagon (Level 5 Breeding) -> Horsea*
new EncounterTradePID(0x0000008B) { Species = 052, Ability = 1, TID = 25945, SID = 00001, OTGender = 1, Gender = 0, IVs = new[] {4,5,4,5,4,4}, Level = 03, Contest = TradeContest_Clever, Version = GameVersion.E, }, // Skitty (Level 3 Trade)-> Meowth*
new EncounterTrade3(0x00009C40) { Species = 296, Ability = 2, TID = 49562, SID = 00000, OTGender = 0, Gender = 0, IVs = new[] {5,5,4,4,4,4}, Level = 05, Contest = TradeContest_Tough, Version = GameVersion.RS, }, // Slakoth (Level 5 Breeding) -> Makuhita
new EncounterTrade3(0x498A2E17) { Species = 300, Ability = 1, TID = 02259, SID = 00000, OTGender = 1, Gender = 1, IVs = new[] {5,4,4,5,4,4}, Level = 03, Contest = TradeContest_Cute, Version = GameVersion.RS, }, // Pikachu (Level 3 Viridiam Forest) -> Skitty
new EncounterTrade3(0x4C970B7F) { Species = 222, Ability = 2, TID = 50183, SID = 00000, OTGender = 1, Gender = 1, IVs = new[] {4,4,5,4,4,5}, Level = 21, Contest = TradeContest_Beauty, Version = GameVersion.RS, }, // Bellossom (Level 21 Odish -> Gloom -> Bellossom) -> Corsola
new EncounterTrade3(0x00000084) { Species = 273, Ability = 2, TID = 38726, SID = 00000, OTGender = 0, Gender = 0, IVs = new[] {5,4,5,4,4,4}, Level = 04, Contest = TradeContest_Cool, Version = GameVersion.E, }, // Ralts (Level 4 Route 102) -> Seedot
new EncounterTrade3(0x0000006F) { Species = 311, Ability = 1, TID = 08460, SID = 00001, OTGender = 0, Gender = 1, IVs = new[] {4,4,4,5,5,4}, Level = 05, Contest = TradeContest_Cute, Version = GameVersion.E, }, // Volbeat (Level 5 Breeding) -> Plusle
new EncounterTrade3(0x0000007F) { Species = 116, Ability = 1, TID = 46285, SID = 00000, OTGender = 0, Gender = 0, IVs = new[] {5,4,4,4,5,4}, Level = 05, Contest = TradeContest_Tough, Version = GameVersion.E, }, // Bagon (Level 5 Breeding) -> Horsea*
new EncounterTrade3(0x0000008B) { Species = 052, Ability = 1, TID = 25945, SID = 00001, OTGender = 1, Gender = 0, IVs = new[] {4,5,4,5,4,4}, Level = 03, Contest = TradeContest_Clever, Version = GameVersion.E, }, // Skitty (Level 3 Trade)-> Meowth*
// If Pokémon with * is evolved in a Generation IV or V game, its Ability will become its second Ability.
};
internal static readonly EncounterTrade[] TradeGift_FRLG =
internal static readonly EncounterTrade3[] TradeGift_FRLG =
{
new EncounterTradePID(0x00009CAE) { Species = 122, Ability = 1, TID = 01985, SID = 00000, OTGender = 0, Gender = 0, IVs = new[] {20,15,17,24,23,22}, Level = 05, Contest = TradeContest_Clever, }, // Abra (Level 5 Breeding) -> Mr. Mime
new EncounterTradePID(0x4C970B89) { Species = 029, Ability = 1, TID = 63184, SID = 00000, OTGender = 1, Gender = 1, IVs = new[] {22,18,25,19,15,22}, Level = 05, Contest = TradeContest_Tough, Version = GameVersion.FR, }, // Nidoran♀
new EncounterTradePID(0x4C970B9E) { Species = 032, Ability = 1, TID = 63184, SID = 00000, OTGender = 1, Gender = 0, IVs = new[] {19,25,18,22,22,15}, Level = 05, Contest = TradeContest_Cool, Version = GameVersion.LG, }, // Nidoran♂ *
new EncounterTradePID(0x00EECA15) { Species = 030, Ability = 1, TID = 13637, SID = 00000, OTGender = 0, Gender = 1, IVs = new[] {22,25,18,19,22,15}, Level = 16, Contest = TradeContest_Cute, Version = GameVersion.FR,}, // Nidorina *
new EncounterTradePID(0x00EECA19) { Species = 033, Ability = 1, TID = 13637, SID = 00000, OTGender = 0, Gender = 0, IVs = new[] {19,18,25,22,15,22}, Level = 16, Contest = TradeContest_Tough, Version = GameVersion.LG,}, // Nidorino *
new EncounterTradePID(0x451308AB) { Species = 108, Ability = 1, TID = 01239, SID = 00000, OTGender = 0, Gender = 0, IVs = new[] {24,19,21,15,23,21}, Level = 25, Contest = TradeContest_Tough, Version = GameVersion.FR, }, // Golduck (Level 25) -> Lickitung *
new EncounterTradePID(0x451308AB) { Species = 108, Ability = 1, TID = 01239, SID = 00000, OTGender = 0, Gender = 0, IVs = new[] {24,19,21,15,23,21}, Level = 25, Contest = TradeContest_Tough, Version = GameVersion.LG, }, // Slowbro (Level 25) -> Lickitung *
new EncounterTradePID(0x498A2E1D) { Species = 124, Ability = 1, TID = 36728, SID = 00000, OTGender = 0, Gender = 1, IVs = new[] {18,17,18,22,25,21}, Level = 20, Contest = TradeContest_Beauty, }, // Poliwhirl (Level 20) -> Jynx
new EncounterTradePID(0x151943D7) { Species = 083, Ability = 1, TID = 08810, SID = 00000, OTGender = 0, Gender = 0, IVs = new[] {20,25,21,24,15,20}, Level = 03, Contest = TradeContest_Cool, }, // Spearow (Level 3 Capture) -> Farfetch'd
new EncounterTradePID(0x06341016) { Species = 101, Ability = 2, TID = 50298, SID = 00000, OTGender = 0, Gender = 2, IVs = new[] {19,16,18,25,25,19}, Level = 03, Contest = TradeContest_Cool, }, // Raichu (Level 3) -> Electrode
new EncounterTradePID(0x5C77ECFA) { Species = 114, Ability = 1, TID = 60042, SID = 00000, OTGender = 1, Gender = 0, IVs = new[] {22,17,25,16,23,20}, Level = 05, Contest = TradeContest_Cute, }, // Venonat (Level 5 Breeding) -> Tangela
new EncounterTradePID(0x482CAC89) { Species = 086, Ability = 1, TID = 09853, SID = 00000, OTGender = 0, Gender = 0, IVs = new[] {24,15,22,16,23,22}, Level = 05, Contest = TradeContest_Tough, }, // Ponyta (Level 5 Breeding) -> Seel *
new EncounterTrade3(0x00009CAE) { Species = 122, Ability = 1, TID = 01985, SID = 00000, OTGender = 0, Gender = 0, IVs = new[] {20,15,17,24,23,22}, Level = 05, Contest = TradeContest_Clever, }, // Abra (Level 5 Breeding) -> Mr. Mime
new EncounterTrade3(0x4C970B89) { Species = 029, Ability = 1, TID = 63184, SID = 00000, OTGender = 1, Gender = 1, IVs = new[] {22,18,25,19,15,22}, Level = 05, Contest = TradeContest_Tough, Version = GameVersion.FR, }, // Nidoran♀
new EncounterTrade3(0x4C970B9E) { Species = 032, Ability = 1, TID = 63184, SID = 00000, OTGender = 1, Gender = 0, IVs = new[] {19,25,18,22,22,15}, Level = 05, Contest = TradeContest_Cool, Version = GameVersion.LG, }, // Nidoran♂ *
new EncounterTrade3(0x00EECA15) { Species = 030, Ability = 1, TID = 13637, SID = 00000, OTGender = 0, Gender = 1, IVs = new[] {22,25,18,19,22,15}, Level = 16, Contest = TradeContest_Cute, Version = GameVersion.FR,}, // Nidorina *
new EncounterTrade3(0x00EECA19) { Species = 033, Ability = 1, TID = 13637, SID = 00000, OTGender = 0, Gender = 0, IVs = new[] {19,18,25,22,15,22}, Level = 16, Contest = TradeContest_Tough, Version = GameVersion.LG,}, // Nidorino *
new EncounterTrade3(0x451308AB) { Species = 108, Ability = 1, TID = 01239, SID = 00000, OTGender = 0, Gender = 0, IVs = new[] {24,19,21,15,23,21}, Level = 25, Contest = TradeContest_Tough, Version = GameVersion.FR, }, // Golduck (Level 25) -> Lickitung *
new EncounterTrade3(0x451308AB) { Species = 108, Ability = 1, TID = 01239, SID = 00000, OTGender = 0, Gender = 0, IVs = new[] {24,19,21,15,23,21}, Level = 25, Contest = TradeContest_Tough, Version = GameVersion.LG, }, // Slowbro (Level 25) -> Lickitung *
new EncounterTrade3(0x498A2E1D) { Species = 124, Ability = 1, TID = 36728, SID = 00000, OTGender = 0, Gender = 1, IVs = new[] {18,17,18,22,25,21}, Level = 20, Contest = TradeContest_Beauty, }, // Poliwhirl (Level 20) -> Jynx
new EncounterTrade3(0x151943D7) { Species = 083, Ability = 1, TID = 08810, SID = 00000, OTGender = 0, Gender = 0, IVs = new[] {20,25,21,24,15,20}, Level = 03, Contest = TradeContest_Cool, }, // Spearow (Level 3 Capture) -> Farfetch'd
new EncounterTrade3(0x06341016) { Species = 101, Ability = 2, TID = 50298, SID = 00000, OTGender = 0, Gender = 2, IVs = new[] {19,16,18,25,25,19}, Level = 03, Contest = TradeContest_Cool, }, // Raichu (Level 3) -> Electrode
new EncounterTrade3(0x5C77ECFA) { Species = 114, Ability = 1, TID = 60042, SID = 00000, OTGender = 1, Gender = 0, IVs = new[] {22,17,25,16,23,20}, Level = 05, Contest = TradeContest_Cute, }, // Venonat (Level 5 Breeding) -> Tangela
new EncounterTrade3(0x482CAC89) { Species = 086, Ability = 1, TID = 09853, SID = 00000, OTGender = 0, Gender = 0, IVs = new[] {24,15,22,16,23,22}, Level = 05, Contest = TradeContest_Tough, }, // Ponyta (Level 5 Breeding) -> Seel *
// If Pokémon with * is evolved in a Generation IV or V game, its Ability will become its second Ability.
};
@ -327,7 +326,7 @@ namespace PKHeX.Core
Location = 34, // Route 119
Slots = new[]
{
new EncounterSlot { Species = 349, LevelMin = 20, LevelMax = 25, Type = SlotType.Swarm } // Feebas with any Rod (50%)
new EncounterSlot3 { Species = 349, LevelMin = 20, LevelMax = 25, Type = SlotType.Swarm } // Feebas with any Rod (50%)
},},
};
@ -347,7 +346,7 @@ namespace PKHeX.Core
return new EncounterArea3
{
Location = location,
Slots = SlotForms.Select((_, i) => new EncounterSlot
Slots = SlotForms.Select((_, i) => new EncounterSlot3
{
Species = 201, LevelMin = 25, LevelMax = 25, Type = SlotType.Grass,
SlotNumber = i,
@ -358,11 +357,11 @@ namespace PKHeX.Core
#endregion
#region Colosseum
private static readonly EncounterStatic[] Encounter_Colo =
private static readonly EncounterStatic3[] Encounter_Colo =
{
// Colosseum Starters: Gender locked to male
new EncounterStatic { Gift = true, Species = 196, Level = 25, Location = 254, Gender = 0 }, // Espeon
new EncounterStatic { Gift = true, Species = 197, Level = 26, Location = 254, Gender = 0, Moves = new[] {044} }, // Umbreon (Bite)
new EncounterStatic3 { Gift = true, Species = 196, Level = 25, Location = 254, Gender = 0 }, // Espeon
new EncounterStatic3 { Gift = true, Species = 197, Level = 26, Location = 254, Gender = 0, Moves = new[] {044} }, // Umbreon (Bite)
new EncounterStaticShadow(ColoMakuhita) { Species = 296, Level = 30, Gauge = 03000, Moves = new[] {193,116,233,238}, Location = 005 }, // Makuhita: Miror B.Peon Trudly @ Phenac City
@ -475,12 +474,12 @@ namespace PKHeX.Core
059, // Realgam Tower
};
private static readonly EncounterStatic[] Encounter_XD = new[]
private static readonly EncounterStatic3[] Encounter_XD = new[]
{
new EncounterStatic { Fateful = true, Gift = true, Species = 133, Level = 10, Location = 000, Moves = new[] {044} }, // Eevee (Bite)
new EncounterStatic { Fateful = true, Gift = true, Species = 152, Level = 05, Location = 016, Moves = new[] {246,033,045,338} }, // Chikorita
new EncounterStatic { Fateful = true, Gift = true, Species = 155, Level = 05, Location = 016, Moves = new[] {179,033,043,307} }, // Cyndaquil
new EncounterStatic { Fateful = true, Gift = true, Species = 158, Level = 05, Location = 016, Moves = new[] {242,010,043,308} }, // Totodile
new EncounterStatic3 { Fateful = true, Gift = true, Species = 133, Level = 10, Location = 000, Moves = new[] {044} }, // Eevee (Bite)
new EncounterStatic3 { Fateful = true, Gift = true, Species = 152, Level = 05, Location = 016, Moves = new[] {246,033,045,338} }, // Chikorita
new EncounterStatic3 { Fateful = true, Gift = true, Species = 155, Level = 05, Location = 016, Moves = new[] {179,033,043,307} }, // Cyndaquil
new EncounterStatic3 { Fateful = true, Gift = true, Species = 158, Level = 05, Location = 016, Moves = new[] {242,010,043,308} }, // Totodile
new EncounterStaticShadow { Fateful = true, Species = 216, Level = 11, Gauge = 03000, Moves = new[] {216,287,122,232}, Location = 143 }, // Teddiursa: Cipher Peon Naps @ Pokémon HQ Lab
new EncounterStaticShadow { Fateful = true, Species = 228, Level = 17, Gauge = 01500, Moves = new[] {185,204,052,046}, Location = 011, }, // Houndour: Cipher Peon Resix @ Cipher Lab
@ -604,34 +603,36 @@ namespace PKHeX.Core
{
new EncounterArea3 { Location = 090, Slots = new[] // Rock
{
new EncounterSlot {Species = 027, LevelMin = 10, LevelMax = 23, SlotNumber = 0}, // Sandshrew
new EncounterSlot {Species = 207, LevelMin = 10, LevelMax = 20, SlotNumber = 1}, // Gligar
new EncounterSlot {Species = 328, LevelMin = 10, LevelMax = 20, SlotNumber = 2}, // Trapinch
new EncounterSlot3PokeSpot(027, 10, 23, 0), // Sandshrew
new EncounterSlot3PokeSpot(207, 10, 20, 1), // Gligar
new EncounterSlot3PokeSpot(328, 10, 20, 2), // Trapinch
}
},
new EncounterArea3 { Location = 091, Slots = new[] // Oasis
{
new EncounterSlot {Species = 187, LevelMin = 10, LevelMax = 20, SlotNumber = 0}, // Hoppip
new EncounterSlot {Species = 231, LevelMin = 10, LevelMax = 20, SlotNumber = 1}, // Phanpy
new EncounterSlot {Species = 283, LevelMin = 10, LevelMax = 20, SlotNumber = 2}, // Surskit
new EncounterSlot3PokeSpot(187, 10, 20, 0), // Hoppip
new EncounterSlot3PokeSpot(231, 10, 20, 1), // Phanpy
new EncounterSlot3PokeSpot(283, 10, 20, 2), // Surskit
}
},
new EncounterArea3 { Location = 092, Slots = new[] // Cave
{
new EncounterSlot {Species = 041, LevelMin = 10, LevelMax = 21, SlotNumber = 0}, // Zubat
new EncounterSlot {Species = 304, LevelMin = 10, LevelMax = 21, SlotNumber = 1}, // Aron
new EncounterSlot {Species = 194, LevelMin = 10, LevelMax = 21, SlotNumber = 2}, // Wooper
new EncounterSlot3PokeSpot(041, 10, 21, 0), // Zubat
new EncounterSlot3PokeSpot(304, 10, 21, 1), // Aron
new EncounterSlot3PokeSpot(194, 10, 21, 2), // Wooper
}
},
};
internal static readonly EncounterStatic[] Encounter_CXD = ArrayUtil.ConcatAll(Encounter_Colo, Encounter_XD);
internal static readonly EncounterStatic3[] Encounter_CXD = ArrayUtil.ConcatAll(Encounter_Colo, Encounter_XD);
private static IEnumerable<EncounterStatic> CloneMirorB(EncounterStatic arg)
private static IEnumerable<EncounterStatic3> CloneMirorB(EncounterStatic3 arg)
{
yield return arg;
if (!(arg is EncounterStaticShadow s))
yield break;
foreach (int loc in MirorBXDLocations)
yield return arg.Clone(loc);
yield return (EncounterStatic3)s.Clone(loc);
}
#endregion

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -12,32 +12,31 @@ namespace PKHeX.Core
internal static readonly EncounterArea6XY[] SlotsX, SlotsY;
internal static readonly EncounterArea6AO[] SlotsA, SlotsO;
internal static readonly EncounterStatic[] StaticX, StaticY, StaticA, StaticO;
internal static readonly ILookup<int, EncounterSlot> FriendSafari;
internal static readonly ILookup<int, EncounterSlot6XY> FriendSafari;
static Encounters6()
{
StaticX = GetStaticEncounters(Encounter_XY, GameVersion.X);
StaticY = GetStaticEncounters(Encounter_XY, GameVersion.Y);
StaticA = GetStaticEncounters(Encounter_AO, GameVersion.AS);
StaticO = GetStaticEncounters(Encounter_AO, GameVersion.OR);
StaticX = GetEncounters(Encounter_XY, GameVersion.X);
StaticY = GetEncounters(Encounter_XY, GameVersion.Y);
StaticA = GetEncounters(Encounter_AO, GameVersion.AS);
StaticO = GetEncounters(Encounter_AO, GameVersion.OR);
var XSlots = GetEncounterTables<EncounterArea6XY>("xy", "x");
var YSlots = GetEncounterTables<EncounterArea6XY>("xy", "y");
var XSlots = GetEncounterTables<EncounterArea6XY, EncounterSlot6XY>("xy", "x");
var YSlots = GetEncounterTables<EncounterArea6XY, EncounterSlot6XY>("xy", "y");
MarkG6XYSlots(ref XSlots);
MarkG6XYSlots(ref YSlots);
MarkEncounterAreaArray(SlotsXYAlt);
SlotsX = AddExtraTableSlots(XSlots, SlotsXYAlt);
SlotsY = AddExtraTableSlots(YSlots, SlotsXYAlt);
SlotsA = GetEncounterTables<EncounterArea6AO>("ao", "a");
SlotsO = GetEncounterTables<EncounterArea6AO>("ao", "o");
SlotsA = GetEncounterTables<EncounterArea6AO, EncounterSlot6AO>("ao", "a");
SlotsO = GetEncounterTables<EncounterArea6AO, EncounterSlot6AO>("ao", "o");
MarkG6AOSlots(ref SlotsA);
MarkG6AOSlots(ref SlotsO);
MarkEncountersGeneration(6, SlotsX, SlotsY, SlotsA, SlotsO);
MarkEncountersGeneration(6, StaticX, StaticY, StaticA, StaticO, TradeGift_XY, TradeGift_AO);
FriendSafari = GetFriendSafariArea();
FriendSafari = EncounterArea6XYFriendSafari.GetArea();
MarkEncounterTradeStrings(TradeGift_XY, TradeXY);
MarkEncounterTradeStrings(TradeGift_AO, TradeAO);
@ -52,27 +51,6 @@ namespace PKHeX.Core
TradeGift_AO.SetVersion(GameVersion.ORAS);
}
private static ILookup<int, EncounterSlot> GetFriendSafariArea()
{
var area = new EncounterAreaFake { Location = 148 };
EncounterSlot FriendSafariSlot(int d)
{
return new EncounterSlot
{
Area = area,
Generation = 6,
Species = d,
LevelMin = 30,
LevelMax = 30,
Form = 0,
Type = SlotType.FriendSafari,
Version = GameVersion.XY,
};
}
area.Slots = Legal.FriendSafari.Select(FriendSafariSlot).ToArray();
return area.Slots.ToLookup(s => s.Species);
}
private static void MarkG6XYSlots(ref EncounterArea6XY[] Areas)
{
foreach (var area in Areas)
@ -95,7 +73,7 @@ namespace PKHeX.Core
area.Slots[i].Type = SlotType.Horde;
for (int i = 0; i < slotct; i++)
area.Slots[i].Permissions.AllowDexNav = area.Slots[i].Type != SlotType.Rock_Smash;
((EncounterSlot6AO)area.Slots[i]).AllowDexNav = area.Slots[i].Type != SlotType.Rock_Smash;
}
ReduceAreasSize(ref Areas);
}
@ -113,66 +91,66 @@ namespace PKHeX.Core
Slots = new[]
{
// Drops
new EncounterSlot { Species = 075, LevelMin = 57, LevelMax = 57, Form = 0 }, // Graveler
new EncounterSlot { Species = 168, LevelMin = 58, LevelMax = 59, Form = 0 }, // Ariados
new EncounterSlot { Species = 714, LevelMin = 57, LevelMax = 59, Form = 0 }, // Noibat
new EncounterSlot6XY { Species = 075, LevelMin = 57, LevelMax = 57, Form = 0 }, // Graveler
new EncounterSlot6XY { Species = 168, LevelMin = 58, LevelMax = 59, Form = 0 }, // Ariados
new EncounterSlot6XY { Species = 714, LevelMin = 57, LevelMax = 59, Form = 0 }, // Noibat
// Swoops
new EncounterSlot { Species = 022, LevelMin = 57, LevelMax = 59, Form = 0 }, // Fearow
new EncounterSlot { Species = 227, LevelMin = 57, LevelMax = 59, Form = 0 }, // Skarmory
new EncounterSlot { Species = 635, LevelMin = 59, LevelMax = 59, Form = 0 }, // Hydreigon
new EncounterSlot6XY { Species = 022, LevelMin = 57, LevelMax = 59, Form = 0 }, // Fearow
new EncounterSlot6XY { Species = 227, LevelMin = 57, LevelMax = 59, Form = 0 }, // Skarmory
new EncounterSlot6XY { Species = 635, LevelMin = 59, LevelMax = 59, Form = 0 }, // Hydreigon
},},
new EncounterArea6XY {
Location = 34, // Route 6
Slots = new[]
{
// Rustling Bush
new EncounterSlot { Species = 543, LevelMin = 10, LevelMax = 12, Form = 0 }, // Venipede
new EncounterSlot { Species = 531, LevelMin = 10, LevelMax = 12, Form = 0 }, // Audino
new EncounterSlot6XY { Species = 543, LevelMin = 10, LevelMax = 12, Form = 0 }, // Venipede
new EncounterSlot6XY { Species = 531, LevelMin = 10, LevelMax = 12, Form = 0 }, // Audino
},},
new EncounterArea6XY { Location = 38, // Route 7
Slots = new[]
{
// Berry Field
new EncounterSlot { Species = 165, LevelMin = 14, LevelMax = 15, Form = 0 }, // Ledyba
new EncounterSlot { Species = 313, LevelMin = 14, LevelMax = 15, Form = 0 }, // Volbeat
new EncounterSlot { Species = 314, LevelMin = 14, LevelMax = 15, Form = 0 }, // Illumise
new EncounterSlot { Species = 412, LevelMin = 14, LevelMax = 15, Form = 0 }, // Burmy
new EncounterSlot { Species = 415, LevelMin = 14, LevelMax = 15, Form = 0 }, // Combee
new EncounterSlot { Species = 665, LevelMin = 14, LevelMax = 15, Form = 0 }, // Spewpa
new EncounterSlot6XY { Species = 165, LevelMin = 14, LevelMax = 15, Form = 0 }, // Ledyba
new EncounterSlot6XY { Species = 313, LevelMin = 14, LevelMax = 15, Form = 0 }, // Volbeat
new EncounterSlot6XY { Species = 314, LevelMin = 14, LevelMax = 15, Form = 0 }, // Illumise
new EncounterSlot6XY { Species = 412, LevelMin = 14, LevelMax = 15, Form = 0 }, // Burmy
new EncounterSlot6XY { Species = 415, LevelMin = 14, LevelMax = 15, Form = 0 }, // Combee
new EncounterSlot6XY { Species = 665, LevelMin = 14, LevelMax = 15, Form = 30 }, // Spewpa
},},
new EncounterArea6XY { Location = 88, // Route 18
Slots = new[]
{
// Rustling Bush
new EncounterSlot { Species = 632, LevelMin = 44, LevelMax = 46, Form = 0 }, // Durant
new EncounterSlot { Species = 631, LevelMin = 45, LevelMax = 45, Form = 0 }, // Heatmor
new EncounterSlot6XY { Species = 632, LevelMin = 44, LevelMax = 46, Form = 0 }, // Durant
new EncounterSlot6XY { Species = 631, LevelMin = 45, LevelMax = 45, Form = 0 }, // Heatmor
},},
new EncounterArea6XY { Location = 132, // Glittering Cave
Slots = new[]
{
// Drops
new EncounterSlot { Species = 527, LevelMin = 15, LevelMax = 17, Form = 0 }, // Woobat
new EncounterSlot { Species = 597, LevelMin = 15, LevelMax = 17, Form = 0 }, // Ferroseed
new EncounterSlot6XY { Species = 527, LevelMin = 15, LevelMax = 17, Form = 0 }, // Woobat
new EncounterSlot6XY { Species = 597, LevelMin = 15, LevelMax = 17, Form = 0 }, // Ferroseed
},},
new EncounterArea6XY { Location = 56, // Reflection Cave
Slots = new[]
{
// Drops
new EncounterSlot { Species = 527, LevelMin = 21, LevelMax = 23, Form = 0 }, // Woobat
new EncounterSlot { Species = 597, LevelMin = 21, LevelMax = 23, Form = 0 }, // Ferroseed
new EncounterSlot6XY { Species = 527, LevelMin = 21, LevelMax = 23, Form = 0 }, // Woobat
new EncounterSlot6XY { Species = 597, LevelMin = 21, LevelMax = 23, Form = 0 }, // Ferroseed
},},
new EncounterArea6XY { Location = 140, // Terminus Cave
Slots = new[]
{
// Drops
new EncounterSlot { Species = 168, LevelMin = 44, LevelMax = 46, Form = 0 }, // Ariados
new EncounterSlot { Species = 714, LevelMin = 44, LevelMax = 46, Form = 0 }, // Noibat
new EncounterSlot6XY { Species = 168, LevelMin = 44, LevelMax = 46, Form = 0 }, // Ariados
new EncounterSlot6XY { Species = 714, LevelMin = 44, LevelMax = 46, Form = 0 }, // Noibat
},},
};
#endregion
@ -276,7 +254,7 @@ namespace PKHeX.Core
// Gift
new EncounterStatic { Species = 374, Level = 01, Location = 196, Ability = 1, IVs = new[] {-1,-1,31,-1,-1,31}, Gift = true }, // Beldum
new EncounterStatic { Species = 351, Level = 30, Location = 240, Ability = 1, IVs = new[] {-1,-1,-1,-1,31,-1}, Contest = new[] {0,100,0,0,0,0}, Gender = 1, Nature = Nature.Lax, Gift = true }, // Castform
new EncounterStatic6 { Species = 351, Level = 30, Location = 240, Ability = 1, IVs = new[] {-1,-1,-1,-1,31,-1}, Contest = new[] {0,100,0,0,0,0}, Gender = 1, Nature = Nature.Lax, Gift = true }, // Castform
new EncounterStatic { Species = 319, Level = 40, Location = 318, Ability = 1, Gender = 1, Nature = Nature.Adamant, Gift = true }, // Sharpedo
new EncounterStatic { Species = 323, Level = 40, Location = 318, Ability = 1, Gender = 1, Nature = Nature.Quiet, Gift = true }, // Camerupt
new EncounterStatic { Species = 380, Level = 30, Location = 320, Ability = 1, Version = GameVersion.AS, Gift = true, FlawlessIVCount = 3 }, // Latias
@ -346,7 +324,7 @@ namespace PKHeX.Core
private static IEnumerable<EncounterStatic> PermuteCosplayPikachu()
{
var CosplayPikachu = new EncounterStatic
var CosplayPikachu = new EncounterStatic6
{
Species = 25, Level = 20, Gender = 1, Ability = 4, FlawlessIVCount = 3,
Contest = new[] { 70, 70, 70, 70, 70, 0 }, Gift = true, Shiny = Shiny.Never

View file

@ -9,19 +9,19 @@ namespace PKHeX.Core
internal static class Encounters7
{
internal static readonly EncounterArea7[] SlotsSN, SlotsMN, SlotsUS, SlotsUM;
internal static readonly EncounterStatic[] StaticSN, StaticMN, StaticUS, StaticUM;
internal static readonly EncounterStatic7[] StaticSN, StaticMN, StaticUS, StaticUM;
static Encounters7()
{
StaticSN = GetStaticEncounters(Encounter_SM, GameVersion.SN);
StaticMN = GetStaticEncounters(Encounter_SM, GameVersion.MN);
StaticUS = GetStaticEncounters(Encounter_USUM, GameVersion.US);
StaticUM = GetStaticEncounters(Encounter_USUM, GameVersion.UM);
StaticSN = GetEncounters(Encounter_SM, GameVersion.SN);
StaticMN = GetEncounters(Encounter_SM, GameVersion.MN);
StaticUS = GetEncounters(Encounter_USUM, GameVersion.US);
StaticUM = GetEncounters(Encounter_USUM, GameVersion.UM);
var REG_SN = GetEncounterTables<EncounterArea7>("sm", "sn");
var REG_MN = GetEncounterTables<EncounterArea7>("sm", "mn");
var SOS_SN = GetEncounterTables<EncounterArea7>("sm", "sn_sos");
var SOS_MN = GetEncounterTables<EncounterArea7>("sm", "mn_sos");
var REG_SN = GetEncounterTables<EncounterArea7, EncounterSlot7>("sm", "sn");
var REG_MN = GetEncounterTables<EncounterArea7, EncounterSlot7>("sm", "mn");
var SOS_SN = GetEncounterTables<EncounterArea7, EncounterSlot7>("sm", "sn_sos");
var SOS_MN = GetEncounterTables<EncounterArea7, EncounterSlot7>("sm", "mn_sos");
MarkG7REGSlots(ref REG_SN);
MarkG7REGSlots(ref REG_MN);
MarkG7SMSlots(ref SOS_SN);
@ -32,10 +32,10 @@ namespace PKHeX.Core
SlotsSN = AddExtraTableSlots(REG_SN, SOS_SN, p_sn);
SlotsMN = AddExtraTableSlots(REG_MN, SOS_MN, p_mn);
var REG_US = GetEncounterTables<EncounterArea7>("uu", "us");
var REG_UM = GetEncounterTables<EncounterArea7>("uu", "um");
var SOS_US = GetEncounterTables<EncounterArea7>("uu", "us_sos");
var SOS_UM = GetEncounterTables<EncounterArea7>("uu", "um_sos");
var REG_US = GetEncounterTables<EncounterArea7, EncounterSlot7>("uu", "us");
var REG_UM = GetEncounterTables<EncounterArea7, EncounterSlot7>("uu", "um");
var SOS_US = GetEncounterTables<EncounterArea7, EncounterSlot7>("uu", "us_sos");
var SOS_UM = GetEncounterTables<EncounterArea7, EncounterSlot7> ("uu", "um_sos");
MarkG7REGSlots(ref REG_US);
MarkG7REGSlots(ref REG_UM);
MarkG7SMSlots(ref SOS_US);
@ -47,7 +47,6 @@ namespace PKHeX.Core
p_sn, p_mn,
p_us, p_um);
MarkEncountersGeneration(7, SlotsSN, SlotsMN, SlotsUS, SlotsUM);
MarkEncountersGeneration(7, StaticSN, StaticMN, StaticUS, StaticUM, TradeGift_SM, TradeGift_USUM);
MarkEncounterTradeStrings(TradeGift_SM, TradeSM);
@ -75,107 +74,107 @@ namespace PKHeX.Core
ReduceAreasSize(ref Areas);
}
private static readonly EncounterStatic[] Encounter_SM = // @ a\1\5\5
private static readonly EncounterStatic7[] Encounter_SM = // @ a\1\5\5
{
// Gifts - 0.bin
new EncounterStatic { Gift = true, Species = 722, Level = 5, Location = 24, }, // Rowlet
new EncounterStatic { Gift = true, Species = 725, Level = 5, Location = 24, }, // Litten
new EncounterStatic { Gift = true, Species = 728, Level = 5, Location = 24, }, // Popplio
new EncounterStatic { Gift = true, Species = 138, Level = 15, Location = 58, }, // Omanyte
new EncounterStatic { Gift = true, Species = 140, Level = 15, Location = 58, }, // Kabuto
// new EncounterStatic { Gift = true, Species = 142, Level = 15, Location = 58, }, // Aerodactyl
new EncounterStatic { Gift = true, Species = 345, Level = 15, Location = 58, }, // Lileep
new EncounterStatic { Gift = true, Species = 347, Level = 15, Location = 58, }, // Anorith
new EncounterStatic { Gift = true, Species = 408, Level = 15, Location = 58, }, // Cranidos
new EncounterStatic { Gift = true, Species = 410, Level = 15, Location = 58, }, // Shieldon
new EncounterStatic { Gift = true, Species = 564, Level = 15, Location = 58, }, // Tirtouga
new EncounterStatic { Gift = true, Species = 566, Level = 15, Location = 58, }, // Archen
new EncounterStatic { Gift = true, Species = 696, Level = 15, Location = 58, }, // Tyrunt
new EncounterStatic { Gift = true, Species = 698, Level = 15, Location = 58, }, // Amaura
new EncounterStatic { Gift = true, Species = 133, Level = 1, EggLocation = 60002, }, // Eevee @ Nursery helpers
new EncounterStatic { Gift = true, Species = 137, Level = 30, Location = 116, }, // Porygon @ Route 15
new EncounterStatic { Gift = true, Species = 772, Level = 40, Location = 188, FlawlessIVCount = 3, }, // Type: Null
new EncounterStatic { Gift = true, Species = 789, Level = 5, Location = 142, Shiny = Shiny.Never, Ability = 2, FlawlessIVCount = 3, Version = GameVersion.SN }, // Cosmog
new EncounterStatic { Gift = true, Species = 789, Level = 5, Location = 144, Shiny = Shiny.Never, Ability = 2, FlawlessIVCount = 3, Version = GameVersion.MN }, // Cosmog
new EncounterStatic { Gift = true, Species = 142, Level = 40, Location = 172, }, // Aerodactyl @ Seafolk Village
new EncounterStatic7 { Gift = true, Species = 722, Level = 5, Location = 24, }, // Rowlet
new EncounterStatic7 { Gift = true, Species = 725, Level = 5, Location = 24, }, // Litten
new EncounterStatic7 { Gift = true, Species = 728, Level = 5, Location = 24, }, // Popplio
new EncounterStatic7 { Gift = true, Species = 138, Level = 15, Location = 58, }, // Omanyte
new EncounterStatic7 { Gift = true, Species = 140, Level = 15, Location = 58, }, // Kabuto
// new EncounterStatic7 { Gift = true, Species = 142, Level = 15, Location = 58, }, // Aerodactyl
new EncounterStatic7 { Gift = true, Species = 345, Level = 15, Location = 58, }, // Lileep
new EncounterStatic7 { Gift = true, Species = 347, Level = 15, Location = 58, }, // Anorith
new EncounterStatic7 { Gift = true, Species = 408, Level = 15, Location = 58, }, // Cranidos
new EncounterStatic7 { Gift = true, Species = 410, Level = 15, Location = 58, }, // Shieldon
new EncounterStatic7 { Gift = true, Species = 564, Level = 15, Location = 58, }, // Tirtouga
new EncounterStatic7 { Gift = true, Species = 566, Level = 15, Location = 58, }, // Archen
new EncounterStatic7 { Gift = true, Species = 696, Level = 15, Location = 58, }, // Tyrunt
new EncounterStatic7 { Gift = true, Species = 698, Level = 15, Location = 58, }, // Amaura
new EncounterStatic7 { Gift = true, Species = 133, Level = 1, EggLocation = 60002, }, // Eevee @ Nursery helpers
new EncounterStatic7 { Gift = true, Species = 137, Level = 30, Location = 116, }, // Porygon @ Route 15
new EncounterStatic7 { Gift = true, Species = 772, Level = 40, Location = 188, FlawlessIVCount = 3, }, // Type: Null
new EncounterStatic7 { Gift = true, Species = 789, Level = 5, Location = 142, Shiny = Shiny.Never, Ability = 2, FlawlessIVCount = 3, Version = GameVersion.SN }, // Cosmog
new EncounterStatic7 { Gift = true, Species = 789, Level = 5, Location = 144, Shiny = Shiny.Never, Ability = 2, FlawlessIVCount = 3, Version = GameVersion.MN }, // Cosmog
new EncounterStatic7 { Gift = true, Species = 142, Level = 40, Location = 172, }, // Aerodactyl @ Seafolk Village
new EncounterStatic { Gift = true, Species = 718, Form = 0, Level = 30, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde
new EncounterStatic { Gift = true, Species = 718, Form = 1, Level = 30, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde
new EncounterStatic { Gift = true, Species = 718, Form = 2, Level = 30, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde
new EncounterStatic { Gift = true, Species = 718, Form = 3, Level = 30, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde
new EncounterStatic7 { Gift = true, Species = 718, Form = 0, Level = 30, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde
new EncounterStatic7 { Gift = true, Species = 718, Form = 1, Level = 30, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde
new EncounterStatic7 { Gift = true, Species = 718, Form = 2, Level = 30, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde
new EncounterStatic7 { Gift = true, Species = 718, Form = 3, Level = 30, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde
new EncounterStatic { Gift = true, Species = 718, Form = 0, Level = 50, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde
new EncounterStatic { Gift = true, Species = 718, Form = 1, Level = 50, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde
new EncounterStatic { Gift = true, Species = 718, Form = 2, Level = 50, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde
new EncounterStatic { Gift = true, Species = 718, Form = 3, Level = 50, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde
new EncounterStatic7 { Gift = true, Species = 718, Form = 0, Level = 50, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde
new EncounterStatic7 { Gift = true, Species = 718, Form = 1, Level = 50, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde
new EncounterStatic7 { Gift = true, Species = 718, Form = 2, Level = 50, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde
new EncounterStatic7 { Gift = true, Species = 718, Form = 3, Level = 50, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde
new EncounterStatic // Magearna (Bottle Cap) 00 FF
new EncounterStatic7 // Magearna (Bottle Cap) 00 FF
{
Gift = true, Species = 801, Level = 50, Location = 40001, Shiny = Shiny.Never, FlawlessIVCount = 3, HeldItem = 795, Ability = 2,
Fateful = true, RibbonWishing = true, Relearn = new [] {705, 430, 381, 270}, Ball = 0x10, // Cherish
},
// Static Encounters - 1.bin
new EncounterStatic { Species = 791, Level = 55, Relearn = new[]{713, 322, 242, 428}, Shiny = Shiny.Never, Ability = 1, Location = 176, FlawlessIVCount = 3, Version = GameVersion.SN }, // Solgaleo
new EncounterStatic { Species = 792, Level = 55, Relearn = new[]{714, 322, 539, 247}, Shiny = Shiny.Never, Ability = 1, Location = 178, FlawlessIVCount = 3, Version = GameVersion.MN }, // Lunala
new EncounterStatic7 { Species = 791, Level = 55, Relearn = new[]{713, 322, 242, 428}, Shiny = Shiny.Never, Ability = 1, Location = 176, FlawlessIVCount = 3, Version = GameVersion.SN }, // Solgaleo
new EncounterStatic7 { Species = 792, Level = 55, Relearn = new[]{714, 322, 539, 247}, Shiny = Shiny.Never, Ability = 1, Location = 178, FlawlessIVCount = 3, Version = GameVersion.MN }, // Lunala
new EncounterStatic { Species = 746, Level = 17, Shiny = Shiny.Never, Ability = 1, Location = 86, }, // Wishiwashi
new EncounterStatic { Species = 746, Level = 18, Shiny = Shiny.Never, Ability = 1, Location = 86, }, // Wishiwashi
new EncounterStatic7 { Species = 746, Level = 17, Shiny = Shiny.Never, Ability = 1, Location = 86, }, // Wishiwashi
new EncounterStatic7 { Species = 746, Level = 18, Shiny = Shiny.Never, Ability = 1, Location = 86, }, // Wishiwashi
new EncounterStatic { Species = 793, Level = 55, Shiny = Shiny.Never, Ability = 1, Location = 082, FlawlessIVCount = 3, }, // Nihilego @ Wela Volcano Park
new EncounterStatic { Species = 793, Level = 55, Shiny = Shiny.Never, Ability = 1, Location = 100, FlawlessIVCount = 3, }, // Nihilego @ Digletts Tunnel
new EncounterStatic { Species = 794, Level = 65, Shiny = Shiny.Never, Ability = 1, Location = 040, FlawlessIVCount = 3, Version = GameVersion.SN }, // Buzzwole @ Melemele Meadow
new EncounterStatic { Species = 795, Level = 60, Shiny = Shiny.Never, Ability = 1, Location = 046, FlawlessIVCount = 3, Version = GameVersion.MN }, // Pheromosa @ Verdant Cavern (Trial Site)
new EncounterStatic { Species = 796, Level = 65, Shiny = Shiny.Never, Ability = 1, Location = 090, FlawlessIVCount = 3, }, // Xurkitree @ Lush Jungle
new EncounterStatic { Species = 796, Level = 65, Shiny = Shiny.Never, Ability = 1, Location = 076, FlawlessIVCount = 3, }, // Xurkitree @ Memorial Hill
new EncounterStatic { Species = 798, Level = 60, Shiny = Shiny.Never, Ability = 1, Location = 134, FlawlessIVCount = 3, Version = GameVersion.SN }, // Kartana @ Malie Garden
new EncounterStatic { Species = 798, Level = 60, Shiny = Shiny.Never, Ability = 1, Location = 120, FlawlessIVCount = 3, Version = GameVersion.SN }, // Kartana @ Route 17
new EncounterStatic { Species = 797, Level = 65, Shiny = Shiny.Never, Ability = 1, Location = 124, FlawlessIVCount = 3, Version = GameVersion.MN }, // Celesteela @ Haina Desert
new EncounterStatic { Species = 797, Level = 65, Shiny = Shiny.Never, Ability = 1, Location = 134, FlawlessIVCount = 3, Version = GameVersion.MN }, // Celesteela @ Malie Garden
new EncounterStatic { Species = 799, Level = 70, Shiny = Shiny.Never, Ability = 1, Location = 182, FlawlessIVCount = 3, }, // Guzzlord @ Resolution Cave
new EncounterStatic { Species = 800, Level = 75, Shiny = Shiny.Never, Ability = 1, Location = 036, FlawlessIVCount = 3, }, // Necrozma @ Ten Carat Hill (Farthest Hollow)
new EncounterStatic7 { Species = 793, Level = 55, Shiny = Shiny.Never, Ability = 1, Location = 082, FlawlessIVCount = 3, }, // Nihilego @ Wela Volcano Park
new EncounterStatic7 { Species = 793, Level = 55, Shiny = Shiny.Never, Ability = 1, Location = 100, FlawlessIVCount = 3, }, // Nihilego @ Digletts Tunnel
new EncounterStatic7 { Species = 794, Level = 65, Shiny = Shiny.Never, Ability = 1, Location = 040, FlawlessIVCount = 3, Version = GameVersion.SN }, // Buzzwole @ Melemele Meadow
new EncounterStatic7 { Species = 795, Level = 60, Shiny = Shiny.Never, Ability = 1, Location = 046, FlawlessIVCount = 3, Version = GameVersion.MN }, // Pheromosa @ Verdant Cavern (Trial Site)
new EncounterStatic7 { Species = 796, Level = 65, Shiny = Shiny.Never, Ability = 1, Location = 090, FlawlessIVCount = 3, }, // Xurkitree @ Lush Jungle
new EncounterStatic7 { Species = 796, Level = 65, Shiny = Shiny.Never, Ability = 1, Location = 076, FlawlessIVCount = 3, }, // Xurkitree @ Memorial Hill
new EncounterStatic7 { Species = 798, Level = 60, Shiny = Shiny.Never, Ability = 1, Location = 134, FlawlessIVCount = 3, Version = GameVersion.SN }, // Kartana @ Malie Garden
new EncounterStatic7 { Species = 798, Level = 60, Shiny = Shiny.Never, Ability = 1, Location = 120, FlawlessIVCount = 3, Version = GameVersion.SN }, // Kartana @ Route 17
new EncounterStatic7 { Species = 797, Level = 65, Shiny = Shiny.Never, Ability = 1, Location = 124, FlawlessIVCount = 3, Version = GameVersion.MN }, // Celesteela @ Haina Desert
new EncounterStatic7 { Species = 797, Level = 65, Shiny = Shiny.Never, Ability = 1, Location = 134, FlawlessIVCount = 3, Version = GameVersion.MN }, // Celesteela @ Malie Garden
new EncounterStatic7 { Species = 799, Level = 70, Shiny = Shiny.Never, Ability = 1, Location = 182, FlawlessIVCount = 3, }, // Guzzlord @ Resolution Cave
new EncounterStatic7 { Species = 800, Level = 75, Shiny = Shiny.Never, Ability = 1, Location = 036, FlawlessIVCount = 3, }, // Necrozma @ Ten Carat Hill (Farthest Hollow)
// QR Scan: Su/M/Tu/W/Th/F/Sa
// Melemele Island
new EncounterStatic { Species = 155, Level = 12, Relearn = new[]{024, 052, 108, 043}, Location = 010, }, // Cyndaquil @ Route 3
new EncounterStatic { Species = 158, Level = 12, Relearn = new[]{232, 099, 055, 043}, Location = 042, }, // Totodile @ Seaward Cave
new EncounterStatic { Species = 633, Level = 13, Relearn = new[]{372, 029, 044, 116}, Location = 034, }, // Deino @ Ten Carat Hill
new EncounterStatic { Species = 116, Level = 18, Relearn = new[]{225, 239, 055, 043}, Location = 014, }, // Horsea @ Kala'e Bay
new EncounterStatic { Species = 599, Level = 08, Relearn = new[]{268, 011, 000, 000}, Location = 020, }, // Klink @ Hau'oli City
new EncounterStatic { Species = 152, Level = 10, Relearn = new[]{073, 077, 075, 045}, Location = 012, }, // Chikorita @ Route 2
new EncounterStatic { Species = 607, Level = 10, Relearn = new[]{051, 109, 083, 123}, Location = 038, }, // Litwick @ Hau'oli Cemetery
new EncounterStatic7 { Species = 155, Level = 12, Relearn = new[]{024, 052, 108, 043}, Location = 010, }, // Cyndaquil @ Route 3
new EncounterStatic7 { Species = 158, Level = 12, Relearn = new[]{232, 099, 055, 043}, Location = 042, }, // Totodile @ Seaward Cave
new EncounterStatic7 { Species = 633, Level = 13, Relearn = new[]{372, 029, 044, 116}, Location = 034, }, // Deino @ Ten Carat Hill
new EncounterStatic7 { Species = 116, Level = 18, Relearn = new[]{225, 239, 055, 043}, Location = 014, }, // Horsea @ Kala'e Bay
new EncounterStatic7 { Species = 599, Level = 08, Relearn = new[]{268, 011, 000, 000}, Location = 020, }, // Klink @ Hau'oli City
new EncounterStatic7 { Species = 152, Level = 10, Relearn = new[]{073, 077, 075, 045}, Location = 012, }, // Chikorita @ Route 2
new EncounterStatic7 { Species = 607, Level = 10, Relearn = new[]{051, 109, 083, 123}, Location = 038, }, // Litwick @ Hau'oli Cemetery
// Akala Island
new EncounterStatic { Species = 574, Level = 17, Relearn = new[]{399, 060, 003, 313}, Location = 054, }, // Gothita @ Route 6
new EncounterStatic { Species = 363, Level = 19, Relearn = new[]{392, 362, 301, 227}, Location = 056, }, // Spheal @ Route 7
new EncounterStatic { Species = 404, Level = 20, Relearn = new[]{598, 044, 209, 268}, Location = 058, }, // Luxio @ Route 8
new EncounterStatic { Species = 679, Level = 23, Relearn = new[]{194, 332, 425, 475}, Location = 094, }, // Honedge @ Akala Outskirts
new EncounterStatic { Species = 543, Level = 14, Relearn = new[]{390, 228, 103, 040}, Location = 050, }, // Venipede @ Route 4
new EncounterStatic { Species = 069, Level = 16, Relearn = new[]{491, 077, 079, 035}, Location = 052, }, // Bellsprout @ Route 5
new EncounterStatic { Species = 183, Level = 17, Relearn = new[]{453, 270, 061, 205}, Location = 086, }, // Marill @ Brooklet Hill
new EncounterStatic7 { Species = 574, Level = 17, Relearn = new[]{399, 060, 003, 313}, Location = 054, }, // Gothita @ Route 6
new EncounterStatic7 { Species = 363, Level = 19, Relearn = new[]{392, 362, 301, 227}, Location = 056, }, // Spheal @ Route 7
new EncounterStatic7 { Species = 404, Level = 20, Relearn = new[]{598, 044, 209, 268}, Location = 058, }, // Luxio @ Route 8
new EncounterStatic7 { Species = 679, Level = 23, Relearn = new[]{194, 332, 425, 475}, Location = 094, }, // Honedge @ Akala Outskirts
new EncounterStatic7 { Species = 543, Level = 14, Relearn = new[]{390, 228, 103, 040}, Location = 050, }, // Venipede @ Route 4
new EncounterStatic7 { Species = 069, Level = 16, Relearn = new[]{491, 077, 079, 035}, Location = 052, }, // Bellsprout @ Route 5
new EncounterStatic7 { Species = 183, Level = 17, Relearn = new[]{453, 270, 061, 205}, Location = 086, }, // Marill @ Brooklet Hill
// Ula'ula Island
new EncounterStatic { Species = 111, Level = 30, Relearn = new[]{130, 350, 498, 523}, Location = 138, }, // Rhyhorn @ Blush Mountain
new EncounterStatic { Species = 220, Level = 31, Relearn = new[]{573, 036, 420, 196}, Location = 114, }, // Swinub @ Tapu Village
new EncounterStatic { Species = 578, Level = 33, Relearn = new[]{101, 248, 283, 473}, Location = 118, }, // Duosion @ Route 16
new EncounterStatic { Species = 315, Level = 34, Relearn = new[]{437, 275, 230, 390}, Location = 128, }, // Roselia @ Ula'ula Meadow
new EncounterStatic { Species = 397, Level = 27, Relearn = new[]{355, 018, 283, 104}, Location = 106, }, // Staravia @ Route 10
new EncounterStatic { Species = 288, Level = 27, Relearn = new[]{359, 498, 163, 203}, Location = 108, }, // Vigoroth @ Route 11
new EncounterStatic { Species = 610, Level = 28, Relearn = new[]{231, 337, 206, 163}, Location = 136, }, // Axew @ Mount Hokulani
new EncounterStatic7 { Species = 111, Level = 30, Relearn = new[]{130, 350, 498, 523}, Location = 138, }, // Rhyhorn @ Blush Mountain
new EncounterStatic7 { Species = 220, Level = 31, Relearn = new[]{573, 036, 420, 196}, Location = 114, }, // Swinub @ Tapu Village
new EncounterStatic7 { Species = 578, Level = 33, Relearn = new[]{101, 248, 283, 473}, Location = 118, }, // Duosion @ Route 16
new EncounterStatic7 { Species = 315, Level = 34, Relearn = new[]{437, 275, 230, 390}, Location = 128, }, // Roselia @ Ula'ula Meadow
new EncounterStatic7 { Species = 397, Level = 27, Relearn = new[]{355, 018, 283, 104}, Location = 106, }, // Staravia @ Route 10
new EncounterStatic7 { Species = 288, Level = 27, Relearn = new[]{359, 498, 163, 203}, Location = 108, }, // Vigoroth @ Route 11
new EncounterStatic7 { Species = 610, Level = 28, Relearn = new[]{231, 337, 206, 163}, Location = 136, }, // Axew @ Mount Hokulani
// Poni Island
new EncounterStatic { Species = 604, Level = 55, Relearn = new[]{435, 051, 029, 306}, Location = 164, }, // Eelektross @ Poni Grove
new EncounterStatic { Species = 534, Level = 57, Relearn = new[]{409, 276, 264, 444}, Location = 166, }, // Conkeldurr @ Poni Plains
new EncounterStatic { Species = 468, Level = 59, Relearn = new[]{248, 403, 396, 245}, Location = 170, }, // Togekiss @ Poni Gauntlet
new EncounterStatic { Species = 542, Level = 57, Relearn = new[]{382, 437, 014, 494}, Location = 156, }, // Leavanny @ Poni Meadow
new EncounterStatic { Species = 497, Level = 43, Relearn = new[]{137, 489, 348, 021}, Location = 184, }, // Serperior @ Exeggutor Island
new EncounterStatic { Species = 503, Level = 43, Relearn = new[]{362, 227, 453, 279}, Location = 158, }, // Samurott @ Poni Wilds
new EncounterStatic { Species = 500, Level = 43, Relearn = new[]{276, 053, 372, 535}, Location = 160, }, // Emboar @ Ancient Poni Path
new EncounterStatic7 { Species = 604, Level = 55, Relearn = new[]{435, 051, 029, 306}, Location = 164, }, // Eelektross @ Poni Grove
new EncounterStatic7 { Species = 534, Level = 57, Relearn = new[]{409, 276, 264, 444}, Location = 166, }, // Conkeldurr @ Poni Plains
new EncounterStatic7 { Species = 468, Level = 59, Relearn = new[]{248, 403, 396, 245}, Location = 170, }, // Togekiss @ Poni Gauntlet
new EncounterStatic7 { Species = 542, Level = 57, Relearn = new[]{382, 437, 014, 494}, Location = 156, }, // Leavanny @ Poni Meadow
new EncounterStatic7 { Species = 497, Level = 43, Relearn = new[]{137, 489, 348, 021}, Location = 184, }, // Serperior @ Exeggutor Island
new EncounterStatic7 { Species = 503, Level = 43, Relearn = new[]{362, 227, 453, 279}, Location = 158, }, // Samurott @ Poni Wilds
new EncounterStatic7 { Species = 500, Level = 43, Relearn = new[]{276, 053, 372, 535}, Location = 160, }, // Emboar @ Ancient Poni Path
new EncounterStatic { Species = 785, Level = 60, Shiny = Shiny.Never, Ability = 1, Location = 030, FlawlessIVCount = 3, }, // Tapu Koko
new EncounterStatic { Species = 786, Level = 60, Shiny = Shiny.Never, Ability = 1, Location = 092, FlawlessIVCount = 3, }, // Tapu Lele
new EncounterStatic { Species = 787, Level = 60, Shiny = Shiny.Never, Ability = 1, Location = 140, FlawlessIVCount = 3, }, // Tapu Bulu
new EncounterStatic { Species = 788, Level = 60, Shiny = Shiny.Never, Ability = 1, Location = 180, FlawlessIVCount = 3, }, // Tapu Fini
new EncounterStatic7 { Species = 785, Level = 60, Shiny = Shiny.Never, Ability = 1, Location = 030, FlawlessIVCount = 3, }, // Tapu Koko
new EncounterStatic7 { Species = 786, Level = 60, Shiny = Shiny.Never, Ability = 1, Location = 092, FlawlessIVCount = 3, }, // Tapu Lele
new EncounterStatic7 { Species = 787, Level = 60, Shiny = Shiny.Never, Ability = 1, Location = 140, FlawlessIVCount = 3, }, // Tapu Bulu
new EncounterStatic7 { Species = 788, Level = 60, Shiny = Shiny.Never, Ability = 1, Location = 180, FlawlessIVCount = 3, }, // Tapu Fini
};
internal static readonly EncounterTrade[] TradeGift_SM = // @ a\1\5\5
@ -190,206 +189,206 @@ namespace PKHeX.Core
new EncounterTrade7 { Species = 663, Form = 0, Level = 59, Ability = 4, TID = 56734, SID = 00008, IVs = new[] {-1,-1,-1,31,-1,-1}, OTGender = 0, Gender = 0, Nature = Nature.Jolly, }, // Talonflame
};
private static readonly EncounterStatic[] Encounter_USUM =
private static readonly EncounterStatic7[] Encounter_USUM =
{
new EncounterStatic { Gift = true, Species = 722, Level = 05, Location = 008, }, // Rowlet
new EncounterStatic { Gift = true, Species = 725, Level = 05, Location = 008, }, // Litten
new EncounterStatic { Gift = true, Species = 728, Level = 05, Location = 008, }, // Popplio
new EncounterStatic { Gift = true, Species = 138, Level = 15, Location = 058, }, // Omanyte
new EncounterStatic { Gift = true, Species = 140, Level = 15, Location = 058, }, // Kabuto
// new EncounterStatic { Gift = true, Species = 142, Level = 15, Location = 058, }, // Aerodactyl
new EncounterStatic { Gift = true, Species = 345, Level = 15, Location = 058, }, // Lileep
new EncounterStatic { Gift = true, Species = 347, Level = 15, Location = 058, }, // Anorith
new EncounterStatic { Gift = true, Species = 408, Level = 15, Location = 058, }, // Cranidos
new EncounterStatic { Gift = true, Species = 410, Level = 15, Location = 058, }, // Shieldon
new EncounterStatic { Gift = true, Species = 564, Level = 15, Location = 058, }, // Tirtouga
new EncounterStatic { Gift = true, Species = 566, Level = 15, Location = 058, }, // Archen
new EncounterStatic { Gift = true, Species = 696, Level = 15, Location = 058, }, // Tyrunt
new EncounterStatic { Gift = true, Species = 698, Level = 15, Location = 058, }, // Amaura
new EncounterStatic { Gift = true, Species = 133, Level = 01, EggLocation = 60002, }, // Eevee @ Nursery helpers
new EncounterStatic { Gift = true, Species = 137, Level = 30, Location = 116, }, // Porygon @ Route 15
new EncounterStatic { Gift = true, Species = 772, Level = 60, Location = 188, FlawlessIVCount = 3, }, // Type: Null @ Aether Paradise
new EncounterStatic { Gift = true, Species = 772, Level = 60, Location = 160, FlawlessIVCount = 3, }, // Type: Null @ Ancient Poni Path
new EncounterStatic { Gift = true, Species = 789, Level = 05, Location = 142, FlawlessIVCount = 3, Shiny = Shiny.Never, Ability = 2, Version = GameVersion.US }, // Cosmog @ Lake of the Sunne
new EncounterStatic { Gift = true, Species = 789, Level = 05, Location = 144, FlawlessIVCount = 3, Shiny = Shiny.Never, Ability = 2, Version = GameVersion.UM }, // Cosmog @ Lake of the Moone
new EncounterStatic { Gift = true, Species = 142, Level = 40, Location = 172, }, // Aerodactyl @ Seafolk Village
new EncounterStatic { Gift = true, Species = 025, Level = 40, Location = 070, FlawlessIVCount = 3, HeldItem = 796, Relearn = new[] {57,0,0,0} }, // Pikachu @ Heahea City
new EncounterStatic { Gift = true, Species = 803, Level = 40, Location = 208, FlawlessIVCount = 3,}, // Poipole @ Megalo Tower
new EncounterStatic { Gift = true, Species = 803, Level = 40, Location = 206, FlawlessIVCount = 3,}, // Poipole @ Ultra Megalopolis
new EncounterStatic7 { Gift = true, Species = 722, Level = 05, Location = 008, }, // Rowlet
new EncounterStatic7 { Gift = true, Species = 725, Level = 05, Location = 008, }, // Litten
new EncounterStatic7 { Gift = true, Species = 728, Level = 05, Location = 008, }, // Popplio
new EncounterStatic7 { Gift = true, Species = 138, Level = 15, Location = 058, }, // Omanyte
new EncounterStatic7 { Gift = true, Species = 140, Level = 15, Location = 058, }, // Kabuto
// new EncounterStatic7 { Gift = true, Species = 142, Level = 15, Location = 058, }, // Aerodactyl
new EncounterStatic7 { Gift = true, Species = 345, Level = 15, Location = 058, }, // Lileep
new EncounterStatic7 { Gift = true, Species = 347, Level = 15, Location = 058, }, // Anorith
new EncounterStatic7 { Gift = true, Species = 408, Level = 15, Location = 058, }, // Cranidos
new EncounterStatic7 { Gift = true, Species = 410, Level = 15, Location = 058, }, // Shieldon
new EncounterStatic7 { Gift = true, Species = 564, Level = 15, Location = 058, }, // Tirtouga
new EncounterStatic7 { Gift = true, Species = 566, Level = 15, Location = 058, }, // Archen
new EncounterStatic7 { Gift = true, Species = 696, Level = 15, Location = 058, }, // Tyrunt
new EncounterStatic7 { Gift = true, Species = 698, Level = 15, Location = 058, }, // Amaura
new EncounterStatic7 { Gift = true, Species = 133, Level = 01, EggLocation = 60002, }, // Eevee @ Nursery helpers
new EncounterStatic7 { Gift = true, Species = 137, Level = 30, Location = 116, }, // Porygon @ Route 15
new EncounterStatic7 { Gift = true, Species = 772, Level = 60, Location = 188, FlawlessIVCount = 3, }, // Type: Null @ Aether Paradise
new EncounterStatic7 { Gift = true, Species = 772, Level = 60, Location = 160, FlawlessIVCount = 3, }, // Type: Null @ Ancient Poni Path
new EncounterStatic7 { Gift = true, Species = 789, Level = 05, Location = 142, FlawlessIVCount = 3, Shiny = Shiny.Never, Ability = 2, Version = GameVersion.US }, // Cosmog @ Lake of the Sunne
new EncounterStatic7 { Gift = true, Species = 789, Level = 05, Location = 144, FlawlessIVCount = 3, Shiny = Shiny.Never, Ability = 2, Version = GameVersion.UM }, // Cosmog @ Lake of the Moone
new EncounterStatic7 { Gift = true, Species = 142, Level = 40, Location = 172, }, // Aerodactyl @ Seafolk Village
new EncounterStatic7 { Gift = true, Species = 025, Level = 40, Location = 070, FlawlessIVCount = 3, HeldItem = 796, Relearn = new[] {57,0,0,0} }, // Pikachu @ Heahea City
new EncounterStatic7 { Gift = true, Species = 803, Level = 40, Location = 208, FlawlessIVCount = 3,}, // Poipole @ Megalo Tower
new EncounterStatic7 { Gift = true, Species = 803, Level = 40, Location = 206, FlawlessIVCount = 3,}, // Poipole @ Ultra Megalopolis
// Totem-Sized Gifts @ Heahea Beach
new EncounterStatic { Gift = true, Species = 735, Level = 20, Ability = 4, Location = 202, Form = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Version = GameVersion.US }, // Gumshoos
new EncounterStatic { Gift = true, Species = 020, Level = 20, Ability = 4, Location = 202, Form = 2, Shiny = Shiny.Never, FlawlessIVCount = 3, Version = GameVersion.UM }, // Raticate
new EncounterStatic { Gift = true, Species = 105, Level = 25, Ability = 4, Location = 202, Form = 2, Shiny = Shiny.Never, FlawlessIVCount = 3, Version = GameVersion.US }, // Marowak
new EncounterStatic { Gift = true, Species = 752, Level = 25, Ability = 1, Location = 202, Form = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Version = GameVersion.UM }, // Araquanid
new EncounterStatic { Gift = true, Species = 754, Level = 30, Ability = 2, Location = 202, Form = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Version = GameVersion.US }, // Lurantis
new EncounterStatic { Gift = true, Species = 758, Level = 30, Ability = 1, Location = 202, Form = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Version = GameVersion.UM }, // Salazzle
new EncounterStatic { Gift = true, Species = 738, Level = 35, Ability = 1, Location = 202, Form = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Version = GameVersion.US }, // Vikavolt
new EncounterStatic { Gift = true, Species = 777, Level = 35, Ability = 4, Location = 202, Form = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Version = GameVersion.UM }, // Togedemaru
new EncounterStatic { Gift = true, Species = 778, Level = 40, Ability = 1, Location = 202, Form = 2, Shiny = Shiny.Never, FlawlessIVCount = 3, }, // Mimikyu
new EncounterStatic { Gift = true, Species = 743, Level = 50, Ability = 4, Location = 202, Form = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Version = GameVersion.US }, // Ribombee
new EncounterStatic { Gift = true, Species = 784, Level = 50, Ability = 4, Location = 202, Form = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Version = GameVersion.UM }, // Kommo-o
new EncounterStatic7 { Gift = true, Species = 735, Level = 20, Ability = 4, Location = 202, Form = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Version = GameVersion.US }, // Gumshoos
new EncounterStatic7 { Gift = true, Species = 020, Level = 20, Ability = 4, Location = 202, Form = 2, Shiny = Shiny.Never, FlawlessIVCount = 3, Version = GameVersion.UM }, // Raticate
new EncounterStatic7 { Gift = true, Species = 105, Level = 25, Ability = 4, Location = 202, Form = 2, Shiny = Shiny.Never, FlawlessIVCount = 3, Version = GameVersion.US }, // Marowak
new EncounterStatic7 { Gift = true, Species = 752, Level = 25, Ability = 1, Location = 202, Form = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Version = GameVersion.UM }, // Araquanid
new EncounterStatic7 { Gift = true, Species = 754, Level = 30, Ability = 2, Location = 202, Form = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Version = GameVersion.US }, // Lurantis
new EncounterStatic7 { Gift = true, Species = 758, Level = 30, Ability = 1, Location = 202, Form = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Version = GameVersion.UM }, // Salazzle
new EncounterStatic7 { Gift = true, Species = 738, Level = 35, Ability = 1, Location = 202, Form = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Version = GameVersion.US }, // Vikavolt
new EncounterStatic7 { Gift = true, Species = 777, Level = 35, Ability = 4, Location = 202, Form = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Version = GameVersion.UM }, // Togedemaru
new EncounterStatic7 { Gift = true, Species = 778, Level = 40, Ability = 1, Location = 202, Form = 2, Shiny = Shiny.Never, FlawlessIVCount = 3, }, // Mimikyu
new EncounterStatic7 { Gift = true, Species = 743, Level = 50, Ability = 4, Location = 202, Form = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Version = GameVersion.US }, // Ribombee
new EncounterStatic7 { Gift = true, Species = 784, Level = 50, Ability = 4, Location = 202, Form = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Version = GameVersion.UM }, // Kommo-o
new EncounterStatic { Gift = true, Species = 718, Level = 63, Ability = 1, Location = 118, Form = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, }, // Zygarde (10%) @ Route 16
new EncounterStatic7 { Gift = true, Species = 718, Level = 63, Ability = 1, Location = 118, Form = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, }, // Zygarde (10%) @ Route 16
new EncounterStatic // Magearna (Bottle Cap)
new EncounterStatic7 // Magearna (Bottle Cap)
{
Gift = true, Species = 801, Level = 50, Location = 40001, Shiny = Shiny.Never, FlawlessIVCount = 3, HeldItem = 795, Ability = 2,
Fateful = true, RibbonWishing = true, Relearn = new [] {705, 430, 381, 270}, Ball = 0x10, // Cherish
},
new EncounterStatic { Gift = true, Species = 718, Form = 0, Level = 50, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde (50%)
new EncounterStatic { Gift = true, Species = 718, Form = 1, Level = 50, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde (10%)
new EncounterStatic { Gift = true, Species = 718, Form = 2, Level = 50, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde (10%-C)
new EncounterStatic { Gift = true, Species = 718, Form = 3, Level = 50, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde (50%-C)
new EncounterStatic7 { Gift = true, Species = 718, Form = 0, Level = 50, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde (50%)
new EncounterStatic7 { Gift = true, Species = 718, Form = 1, Level = 50, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde (10%)
new EncounterStatic7 { Gift = true, Species = 718, Form = 2, Level = 50, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde (10%-C)
new EncounterStatic7 { Gift = true, Species = 718, Form = 3, Level = 50, Shiny = Shiny.Never, Location = 118, FlawlessIVCount = 3, }, // Zygarde (50%-C)
new EncounterStatic { Species = 791, Level = 60, Location = 028, Ability = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Relearn = new[] {713,322,242,428}, Version = GameVersion.US }, // Solgaleo @ Mahalo Trail (Plank Bridge)
new EncounterStatic { Species = 792, Level = 60, Location = 028, Ability = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Relearn = new[] {714,322,539,585}, Version = GameVersion.UM }, // Lunala @ Mahalo Trail (Plank Bridge)
new EncounterStatic7 { Species = 791, Level = 60, Location = 028, Ability = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Relearn = new[] {713,322,242,428}, Version = GameVersion.US }, // Solgaleo @ Mahalo Trail (Plank Bridge)
new EncounterStatic7 { Species = 792, Level = 60, Location = 028, Ability = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Relearn = new[] {714,322,539,585}, Version = GameVersion.UM }, // Lunala @ Mahalo Trail (Plank Bridge)
// QR Scan: Su/M/Tu/W/Th/F/Sa
// Melemele Island
new EncounterStatic { Species = 004, Level = 12, Location = 010, Relearn = new[] {068,108,052,010}, }, // Charmander @ Route 3
new EncounterStatic { Species = 007, Level = 12, Location = 042, Relearn = new[] {453,110,055,033}, }, // Squirtle @ Seaward Cave
new EncounterStatic { Species = 095, Level = 14, Location = 034, Relearn = new[] {563,099,317,088}, }, // Onix @ Ten Carat Hill
new EncounterStatic { Species = 116, Level = 18, Location = 014, Relearn = new[] {352,239,055,043}, }, // Horsea @ Kala'e Bay
new EncounterStatic { Species = 664, Level = 09, Location = 020, Relearn = new[] {476,081,078,033}, SkipFormCheck = true, }, // Scatterbug @ Hau'oli City
new EncounterStatic { Species = 001, Level = 10, Location = 012, Relearn = new[] {580,022,045,033}, }, // Bulbasaur @ Route 2
new EncounterStatic { Species = 607, Level = 09, Location = 038, Relearn = new[] {203,052,083,123}, }, // Litwick @ Hau'oli Cemetery
new EncounterStatic7 { Species = 004, Level = 12, Location = 010, Relearn = new[] {068,108,052,010}, }, // Charmander @ Route 3
new EncounterStatic7 { Species = 007, Level = 12, Location = 042, Relearn = new[] {453,110,055,033}, }, // Squirtle @ Seaward Cave
new EncounterStatic7 { Species = 095, Level = 14, Location = 034, Relearn = new[] {563,099,317,088}, }, // Onix @ Ten Carat Hill
new EncounterStatic7 { Species = 116, Level = 18, Location = 014, Relearn = new[] {352,239,055,043}, }, // Horsea @ Kala'e Bay
new EncounterStatic7 { Species = 664, Level = 09, Location = 020, Relearn = new[] {476,081,078,033}, SkipFormCheck = true, }, // Scatterbug @ Hau'oli City
new EncounterStatic7 { Species = 001, Level = 10, Location = 012, Relearn = new[] {580,022,045,033}, }, // Bulbasaur @ Route 2
new EncounterStatic7 { Species = 607, Level = 09, Location = 038, Relearn = new[] {203,052,083,123}, }, // Litwick @ Hau'oli Cemetery
// Akala Island
new EncounterStatic { Species = 280, Level = 17, Location = 054, Relearn = new[] {581,345,381,574}, }, // Ralts @ Route 6
new EncounterStatic { Species = 363, Level = 19, Location = 056, Relearn = new[] {187,362,301,227}, }, // Spheal @ Route 7
new EncounterStatic { Species = 256, Level = 20, Location = 058, Relearn = new[] {067,488,064,028}, }, // Combusken @ Route 8
new EncounterStatic { Species = 679, Level = 24, Location = 094, Relearn = new[] {469,332,425,475}, }, // Honedge @ Akala Outskirts
new EncounterStatic { Species = 015, Level = 14, Location = 050, Relearn = new[] {099,031,041,000}, }, // Beedrill @ Route 4
new EncounterStatic { Species = 253, Level = 16, Location = 052, Relearn = new[] {580,072,098,071}, }, // Grovyle @ Route 5
new EncounterStatic { Species = 259, Level = 17, Location = 086, Relearn = new[] {068,193,189,055}, }, // Marshtomp @ Brooklet Hill
new EncounterStatic7 { Species = 280, Level = 17, Location = 054, Relearn = new[] {581,345,381,574}, }, // Ralts @ Route 6
new EncounterStatic7 { Species = 363, Level = 19, Location = 056, Relearn = new[] {187,362,301,227}, }, // Spheal @ Route 7
new EncounterStatic7 { Species = 256, Level = 20, Location = 058, Relearn = new[] {067,488,064,028}, }, // Combusken @ Route 8
new EncounterStatic7 { Species = 679, Level = 24, Location = 094, Relearn = new[] {469,332,425,475}, }, // Honedge @ Akala Outskirts
new EncounterStatic7 { Species = 015, Level = 14, Location = 050, Relearn = new[] {099,031,041,000}, }, // Beedrill @ Route 4
new EncounterStatic7 { Species = 253, Level = 16, Location = 052, Relearn = new[] {580,072,098,071}, }, // Grovyle @ Route 5
new EncounterStatic7 { Species = 259, Level = 17, Location = 086, Relearn = new[] {068,193,189,055}, }, // Marshtomp @ Brooklet Hill
// Ula'ula Island
new EncounterStatic { Species = 111, Level = 32, Location = 138, Relearn = new[] {470,350,498,523}, }, // Rhyhorn @ Blush Mountain
new EncounterStatic { Species = 220, Level = 33, Location = 114, Relearn = new[] {333,036,420,196}, }, // Swinub @ Tapu Village
new EncounterStatic { Species = 394, Level = 35, Location = 118, Relearn = new[] {681,362,031,117}, }, // Prinplup @ Route 16
new EncounterStatic { Species = 388, Level = 36, Location = 128, Relearn = new[] {484,073,072,044}, }, // Grotle @ Ula'ula Meadow
new EncounterStatic { Species = 018, Level = 29, Location = 106, Relearn = new[] {211,297,239,098}, }, // Pidgeot @ Route 10
new EncounterStatic { Species = 391, Level = 29, Location = 108, Relearn = new[] {612,172,154,259}, }, // Monferno @ Route 11
new EncounterStatic { Species = 610, Level = 30, Location = 136, Relearn = new[] {068,337,206,163}, }, // Axew @ Mount Hokulani
new EncounterStatic7 { Species = 111, Level = 32, Location = 138, Relearn = new[] {470,350,498,523}, }, // Rhyhorn @ Blush Mountain
new EncounterStatic7 { Species = 220, Level = 33, Location = 114, Relearn = new[] {333,036,420,196}, }, // Swinub @ Tapu Village
new EncounterStatic7 { Species = 394, Level = 35, Location = 118, Relearn = new[] {681,362,031,117}, }, // Prinplup @ Route 16
new EncounterStatic7 { Species = 388, Level = 36, Location = 128, Relearn = new[] {484,073,072,044}, }, // Grotle @ Ula'ula Meadow
new EncounterStatic7 { Species = 018, Level = 29, Location = 106, Relearn = new[] {211,297,239,098}, }, // Pidgeot @ Route 10
new EncounterStatic7 { Species = 391, Level = 29, Location = 108, Relearn = new[] {612,172,154,259}, }, // Monferno @ Route 11
new EncounterStatic7 { Species = 610, Level = 30, Location = 136, Relearn = new[] {068,337,206,163}, }, // Axew @ Mount Hokulani
// Poni Island
new EncounterStatic { Species = 604, Level = 55, Location = 164, Relearn = new[] {242,435,029,306}, }, // Eelektross @ Poni Grove
new EncounterStatic { Species = 306, Level = 57, Location = 166, Relearn = new[] {179,484,038,334}, }, // Aggron @ Poni Plains
new EncounterStatic { Species = 479, Level = 61, Location = 170, Relearn = new[] {268,506,486,164}, }, // Rotom @ Poni Gauntlet
new EncounterStatic { Species = 542, Level = 57, Location = 156, Relearn = new[] {580,437,014,494}, }, // Leavanny @ Poni Meadow
new EncounterStatic { Species = 652, Level = 45, Location = 184, Relearn = new[] {191,341,402,596}, }, // Chesnaught @ Exeggutor Island
new EncounterStatic { Species = 658, Level = 44, Location = 158, Relearn = new[] {516,164,185,594}, }, // Greninja @ Poni Wilds
new EncounterStatic { Species = 655, Level = 44, Location = 160, Relearn = new[] {273,473,113,595}, }, // Delphox @ Ancient Poni Path
new EncounterStatic7 { Species = 604, Level = 55, Location = 164, Relearn = new[] {242,435,029,306}, }, // Eelektross @ Poni Grove
new EncounterStatic7 { Species = 306, Level = 57, Location = 166, Relearn = new[] {179,484,038,334}, }, // Aggron @ Poni Plains
new EncounterStatic7 { Species = 479, Level = 61, Location = 170, Relearn = new[] {268,506,486,164}, }, // Rotom @ Poni Gauntlet
new EncounterStatic7 { Species = 542, Level = 57, Location = 156, Relearn = new[] {580,437,014,494}, }, // Leavanny @ Poni Meadow
new EncounterStatic7 { Species = 652, Level = 45, Location = 184, Relearn = new[] {191,341,402,596}, }, // Chesnaught @ Exeggutor Island
new EncounterStatic7 { Species = 658, Level = 44, Location = 158, Relearn = new[] {516,164,185,594}, }, // Greninja @ Poni Wilds
new EncounterStatic7 { Species = 655, Level = 44, Location = 160, Relearn = new[] {273,473,113,595}, }, // Delphox @ Ancient Poni Path
new EncounterStatic { Species = 785, Level = 60, Location = 030, Ability = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, }, // Tapu Koko @ Ruins of Conflict
new EncounterStatic { Species = 786, Level = 60, Location = 092, Ability = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, }, // Tapu Lele @ Ruins of Life
new EncounterStatic { Species = 787, Level = 60, Location = 140, Ability = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, }, // Tapu Bulu @ Ruins of Abundance
new EncounterStatic { Species = 788, Level = 60, Location = 180, Ability = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, }, // Tapu Fini @ Ruins of Hope
new EncounterStatic7 { Species = 785, Level = 60, Location = 030, Ability = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, }, // Tapu Koko @ Ruins of Conflict
new EncounterStatic7 { Species = 786, Level = 60, Location = 092, Ability = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, }, // Tapu Lele @ Ruins of Life
new EncounterStatic7 { Species = 787, Level = 60, Location = 140, Ability = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, }, // Tapu Bulu @ Ruins of Abundance
new EncounterStatic7 { Species = 788, Level = 60, Location = 180, Ability = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, }, // Tapu Fini @ Ruins of Hope
new EncounterStatic { Species = 023, Level = 10, Location = 012, Ability = 1, }, // Ekans @ Route 2
new EncounterStatic7 { Species = 023, Level = 10, Location = 012, Ability = 1, }, // Ekans @ Route 2
new EncounterStatic { Species = 127, Level = 42, Location = 184, Shiny = Shiny.Never, }, // Pinsir @ Exeggutor Island
new EncounterStatic { Species = 127, Level = 43, Location = 184, Shiny = Shiny.Never, }, // Pinsir @ Exeggutor Island
new EncounterStatic { Species = 800, Level = 65, Location = 146, Ability = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Relearn = new[] {722,334,408,400}, HeldItem = 923, }, // Necrozma @ Mount Lanakila
new EncounterStatic7 { Species = 127, Level = 42, Location = 184, Shiny = Shiny.Never, }, // Pinsir @ Exeggutor Island
new EncounterStatic7 { Species = 127, Level = 43, Location = 184, Shiny = Shiny.Never, }, // Pinsir @ Exeggutor Island
new EncounterStatic7 { Species = 800, Level = 65, Location = 146, Ability = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Relearn = new[] {722,334,408,400}, HeldItem = 923, }, // Necrozma @ Mount Lanakila
// Legendaries
new EncounterStatic { Species = 144, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {246,573,115,258}, }, // Articuno
new EncounterStatic { Species = 145, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {246,435,365,240}, }, // Zapdos
new EncounterStatic { Species = 146, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {246,053,403,241}, }, // Moltres
new EncounterStatic { Species = 150, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {094,105,129,427}, }, // Mewtwo
new EncounterStatic { Species = 243, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.US }, // Raikou
new EncounterStatic { Species = 244, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {023,044,207,436}, Version = GameVersion.UM }, // Entei
new EncounterStatic { Species = 245, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {061,062,054,240}, }, // Suicune
new EncounterStatic { Species = 249, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {285,177,326,246}, Version = GameVersion.UM }, // Lugia
new EncounterStatic { Species = 250, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {682,221,326,246}, HeldItem = 044, Version = GameVersion.US }, // Ho-Oh
new EncounterStatic { Species = 377, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, }, // Regirock
new EncounterStatic { Species = 378, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, }, // Regice
new EncounterStatic { Species = 379, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, }, // Registeel
new EncounterStatic { Species = 380, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {296,406,375,273}, Gender = 1, Version = GameVersion.UM }, // Latias
new EncounterStatic { Species = 381, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {295,406,375,225}, Gender = 0, Version = GameVersion.US }, // Latios
new EncounterStatic { Species = 382, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {058,618,347,330}, Version = GameVersion.UM }, // Kyogre
new EncounterStatic { Species = 383, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {089,619,339,076}, Version = GameVersion.US }, // Groudon
new EncounterStatic { Species = 384, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, }, // Rayquaza
new EncounterStatic { Species = 480, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {326,281,133,129}, }, // Uxie
new EncounterStatic { Species = 481, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {326,204,248,129}, }, // Mesprit
new EncounterStatic { Species = 482, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {326,417,253,129}, }, // Azelf
new EncounterStatic { Species = 483, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.US }, // Dialga
new EncounterStatic { Species = 484, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.UM }, // Palkia
new EncounterStatic { Species = 485, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.US }, // Heatran
new EncounterStatic { Species = 486, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {428,279,146,109}, Version = GameVersion.UM }, // Regigigas
new EncounterStatic { Species = 487, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {467,396,414,337}, }, // Giratina
new EncounterStatic { Species = 488, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Gender = 1, }, // Cresselia
new EncounterStatic { Species = 638, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {533,014,098,442}, }, // Cobalion
new EncounterStatic { Species = 639, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {533,014,157,444}, }, // Terrakion
new EncounterStatic { Species = 640, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {533,014,202,348}, }, // Virizion
new EncounterStatic { Species = 641, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Gender = 0, Version = GameVersion.US }, // Tornadus
new EncounterStatic { Species = 642, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Gender = 0, Version = GameVersion.UM }, // Thundurus
new EncounterStatic { Species = 643, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.US }, // Reshiram
new EncounterStatic { Species = 644, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.UM }, // Zekrom
new EncounterStatic { Species = 645, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Gender = 0, }, // Landorus
new EncounterStatic { Species = 646, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, }, // Kyurem
new EncounterStatic { Species = 716, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {601,532,400,585}, Version = GameVersion.US }, // Xerneas
new EncounterStatic { Species = 717, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {613,399,566,094}, Version = GameVersion.UM }, // Yveltal
new EncounterStatic { Species = 718, Level = 60, Location = 182, Ability = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Relearn = new[] {616,137,219,225}, }, // Zygarde @ Resolution Cave
new EncounterStatic7 { Species = 144, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {246,573,115,258}, }, // Articuno
new EncounterStatic7 { Species = 145, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {246,435,365,240}, }, // Zapdos
new EncounterStatic7 { Species = 146, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {246,053,403,241}, }, // Moltres
new EncounterStatic7 { Species = 150, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {094,105,129,427}, }, // Mewtwo
new EncounterStatic7 { Species = 243, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.US }, // Raikou
new EncounterStatic7 { Species = 244, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {023,044,207,436}, Version = GameVersion.UM }, // Entei
new EncounterStatic7 { Species = 245, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {061,062,054,240}, }, // Suicune
new EncounterStatic7 { Species = 249, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {285,177,326,246}, Version = GameVersion.UM }, // Lugia
new EncounterStatic7 { Species = 250, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {682,221,326,246}, HeldItem = 044, Version = GameVersion.US }, // Ho-Oh
new EncounterStatic7 { Species = 377, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, }, // Regirock
new EncounterStatic7 { Species = 378, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, }, // Regice
new EncounterStatic7 { Species = 379, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, }, // Registeel
new EncounterStatic7 { Species = 380, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {296,406,375,273}, Gender = 1, Version = GameVersion.UM }, // Latias
new EncounterStatic7 { Species = 381, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {295,406,375,225}, Gender = 0, Version = GameVersion.US }, // Latios
new EncounterStatic7 { Species = 382, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {058,618,347,330}, Version = GameVersion.UM }, // Kyogre
new EncounterStatic7 { Species = 383, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {089,619,339,076}, Version = GameVersion.US }, // Groudon
new EncounterStatic7 { Species = 384, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, }, // Rayquaza
new EncounterStatic7 { Species = 480, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {326,281,133,129}, }, // Uxie
new EncounterStatic7 { Species = 481, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {326,204,248,129}, }, // Mesprit
new EncounterStatic7 { Species = 482, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {326,417,253,129}, }, // Azelf
new EncounterStatic7 { Species = 483, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.US }, // Dialga
new EncounterStatic7 { Species = 484, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.UM }, // Palkia
new EncounterStatic7 { Species = 485, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.US }, // Heatran
new EncounterStatic7 { Species = 486, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {428,279,146,109}, Version = GameVersion.UM }, // Regigigas
new EncounterStatic7 { Species = 487, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {467,396,414,337}, }, // Giratina
new EncounterStatic7 { Species = 488, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Gender = 1, }, // Cresselia
new EncounterStatic7 { Species = 638, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {533,014,098,442}, }, // Cobalion
new EncounterStatic7 { Species = 639, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {533,014,157,444}, }, // Terrakion
new EncounterStatic7 { Species = 640, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {533,014,202,348}, }, // Virizion
new EncounterStatic7 { Species = 641, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Gender = 0, Version = GameVersion.US }, // Tornadus
new EncounterStatic7 { Species = 642, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Gender = 0, Version = GameVersion.UM }, // Thundurus
new EncounterStatic7 { Species = 643, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.US }, // Reshiram
new EncounterStatic7 { Species = 644, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.UM }, // Zekrom
new EncounterStatic7 { Species = 645, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Gender = 0, }, // Landorus
new EncounterStatic7 { Species = 646, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, }, // Kyurem
new EncounterStatic7 { Species = 716, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {601,532,400,585}, Version = GameVersion.US }, // Xerneas
new EncounterStatic7 { Species = 717, Level = 60, Location = 222, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {613,399,566,094}, Version = GameVersion.UM }, // Yveltal
new EncounterStatic7 { Species = 718, Level = 60, Location = 182, Ability = 1, Shiny = Shiny.Never, FlawlessIVCount = 3, Relearn = new[] {616,137,219,225}, }, // Zygarde @ Resolution Cave
// Ultra Space Wilds
new EncounterStatic { Species = 334, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Altaria
new EncounterStatic { Species = 469, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Yanmega
new EncounterStatic { Species = 561, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Sigilyph
new EncounterStatic { Species = 581, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Swanna
new EncounterStatic { Species = 277, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Swellow
new EncounterStatic { Species = 452, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Drapion
new EncounterStatic { Species = 531, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Audino
new EncounterStatic { Species = 695, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Heliolisk
new EncounterStatic { Species = 274, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Nuzleaf
new EncounterStatic { Species = 326, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Grumpig
new EncounterStatic { Species = 460, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Abomasnow
new EncounterStatic { Species = 308, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Medicham
new EncounterStatic { Species = 450, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Hippowdon
new EncounterStatic { Species = 558, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Crustle
new EncounterStatic { Species = 219, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Magcargo
new EncounterStatic { Species = 689, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Barbaracle
new EncounterStatic { Species = 271, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Lombre
new EncounterStatic { Species = 618, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Stunfisk
new EncounterStatic { Species = 419, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Floatzel
new EncounterStatic { Species = 195, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Quagsire
new EncounterStatic7 { Species = 334, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Altaria
new EncounterStatic7 { Species = 469, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Yanmega
new EncounterStatic7 { Species = 561, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Sigilyph
new EncounterStatic7 { Species = 581, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Swanna
new EncounterStatic7 { Species = 277, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Swellow
new EncounterStatic7 { Species = 452, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Drapion
new EncounterStatic7 { Species = 531, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Audino
new EncounterStatic7 { Species = 695, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Heliolisk
new EncounterStatic7 { Species = 274, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Nuzleaf
new EncounterStatic7 { Species = 326, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Grumpig
new EncounterStatic7 { Species = 460, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Abomasnow
new EncounterStatic7 { Species = 308, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Medicham
new EncounterStatic7 { Species = 450, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Hippowdon
new EncounterStatic7 { Species = 558, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Crustle
new EncounterStatic7 { Species = 219, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Magcargo
new EncounterStatic7 { Species = 689, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Barbaracle
new EncounterStatic7 { Species = 271, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Lombre
new EncounterStatic7 { Species = 618, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Stunfisk
new EncounterStatic7 { Species = 419, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Floatzel
new EncounterStatic7 { Species = 195, Level = 60, Location = 222, FlawlessIVCount = 3, }, // Quagsire
// Ultra Beasts
new EncounterStatic { Species = 793, Level = 60, Location = 190, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {408,491,446,243}, }, // Nihilego @ Ultra Deep Sea
new EncounterStatic { Species = 794, Level = 60, Location = 218, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.US }, // Buzzwole @ Ultra Jungle
new EncounterStatic { Species = 795, Level = 60, Location = 214, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.UM }, // Pheromosa @ Ultra Desert
new EncounterStatic { Species = 796, Level = 60, Location = 210, Ability = 1, FlawlessIVCount = 3, }, // Xurkitree @ Ultra Plant
new EncounterStatic { Species = 797, Level = 60, Location = 212, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.UM }, // Celesteela @ Ultra Crater
new EncounterStatic { Species = 798, Level = 60, Location = 216, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.US }, // Kartana @ Ultra Forest
new EncounterStatic { Species = 799, Level = 60, Location = 220, Ability = 1, FlawlessIVCount = 3, }, // Guzzlord @ Ultra Ruin
new EncounterStatic { Species = 805, Level = 60, Location = 164, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.UM }, // Stakataka @ Poni Grove
new EncounterStatic { Species = 806, Level = 60, Location = 164, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.US }, // Blacephalon @ Poni Grove
new EncounterStatic7 { Species = 793, Level = 60, Location = 190, Ability = 1, FlawlessIVCount = 3, Relearn = new[] {408,491,446,243}, }, // Nihilego @ Ultra Deep Sea
new EncounterStatic7 { Species = 794, Level = 60, Location = 218, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.US }, // Buzzwole @ Ultra Jungle
new EncounterStatic7 { Species = 795, Level = 60, Location = 214, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.UM }, // Pheromosa @ Ultra Desert
new EncounterStatic7 { Species = 796, Level = 60, Location = 210, Ability = 1, FlawlessIVCount = 3, }, // Xurkitree @ Ultra Plant
new EncounterStatic7 { Species = 797, Level = 60, Location = 212, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.UM }, // Celesteela @ Ultra Crater
new EncounterStatic7 { Species = 798, Level = 60, Location = 216, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.US }, // Kartana @ Ultra Forest
new EncounterStatic7 { Species = 799, Level = 60, Location = 220, Ability = 1, FlawlessIVCount = 3, }, // Guzzlord @ Ultra Ruin
new EncounterStatic7 { Species = 805, Level = 60, Location = 164, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.UM }, // Stakataka @ Poni Grove
new EncounterStatic7 { Species = 806, Level = 60, Location = 164, Ability = 1, FlawlessIVCount = 3, Version = GameVersion.US }, // Blacephalon @ Poni Grove
// Ditto Five
new EncounterStatic { Species = 132, Level = 29, Location = 060, IVs = new[] {-1,-1,31,00,30,-1}, Nature = Nature.Bold }, // Ditto @ Route 9
new EncounterStatic { Species = 132, Level = 29, Location = 072, IVs = new[] {-1,-1,30,31,30,-1}, Nature = Nature.Jolly }, // Ditto @ Konikoni City
new EncounterStatic { Species = 132, Level = 29, Location = 072, IVs = new[] {-1,31,30,30,-1,-1}, Nature = Nature.Adamant }, // Ditto @ Konikoni City
new EncounterStatic { Species = 132, Level = 29, Location = 072, IVs = new[] {-1,00,-1,-1,31,30}, Nature = Nature.Modest }, // Ditto @ Konikoni City
new EncounterStatic { Species = 132, Level = 29, Location = 072, IVs = new[] {-1,30,-1,31,-1,30}, Nature = Nature.Timid }, // Ditto @ Konikoni City
new EncounterStatic7 { Species = 132, Level = 29, Location = 060, IVs = new[] {-1,-1,31,00,30,-1}, Nature = Nature.Bold }, // Ditto @ Route 9
new EncounterStatic7 { Species = 132, Level = 29, Location = 072, IVs = new[] {-1,-1,30,31,30,-1}, Nature = Nature.Jolly }, // Ditto @ Konikoni City
new EncounterStatic7 { Species = 132, Level = 29, Location = 072, IVs = new[] {-1,31,30,30,-1,-1}, Nature = Nature.Adamant }, // Ditto @ Konikoni City
new EncounterStatic7 { Species = 132, Level = 29, Location = 072, IVs = new[] {-1,00,-1,-1,31,30}, Nature = Nature.Modest }, // Ditto @ Konikoni City
new EncounterStatic7 { Species = 132, Level = 29, Location = 072, IVs = new[] {-1,30,-1,31,-1,30}, Nature = Nature.Timid }, // Ditto @ Konikoni City
// Miscellaneous Static
new EncounterStatic { Species = 760, Level = 28, Location = 020, Shiny = Shiny.Never, }, // Bewear @ Hauoli City (Shopping District)
new EncounterStatic { Species = 097, Level = 29, Location = 020, Shiny = Shiny.Never, Relearn = new[] {095,171,139,029}, }, // Hypno @ Hau'oli City Police Station
new EncounterStatic { Species = 097, Level = 29, Location = 020, Shiny = Shiny.Never, Relearn = new[] {417,060,050,139}, }, // Hypno @ Hau'oli City Police Station
new EncounterStatic { Species = 097, Level = 29, Location = 020, Shiny = Shiny.Never, Relearn = new[] {093,050,001,096}, }, // Hypno @ Hau'oli City Police Station
new EncounterStatic { Species = 092, Level = 19, Location = 230, Shiny = Shiny.Never, Relearn = new[] {174,109,122,101}, }, // Gastly @ Route 1 (Trainers School)
new EncounterStatic { Species = 425, Level = 19, Location = 230, Shiny = Shiny.Never, Relearn = new[] {310,132,016,371}, }, // Drifloon @ Route 1 (Trainers School)
new EncounterStatic { Species = 769, Level = 30, Location = 116, Shiny = Shiny.Never, Relearn = new[] {310,523,072,328}, Version = GameVersion.UM, }, // Sandygast @ Route 15
new EncounterStatic { Species = 592, Level = 34, Location = 126, Shiny = Shiny.Never, Gender = 1, }, // Frillish @ Route 14
new EncounterStatic { Species = 101, Level = 60, Location = 224, Ability = 1, Shiny = Shiny.Never, }, // Electrode @ Team Rocket's Castle
new EncounterStatic7 { Species = 760, Level = 28, Location = 020, Shiny = Shiny.Never, }, // Bewear @ Hauoli City (Shopping District)
new EncounterStatic7 { Species = 097, Level = 29, Location = 020, Shiny = Shiny.Never, Relearn = new[] {095,171,139,029}, }, // Hypno @ Hau'oli City Police Station
new EncounterStatic7 { Species = 097, Level = 29, Location = 020, Shiny = Shiny.Never, Relearn = new[] {417,060,050,139}, }, // Hypno @ Hau'oli City Police Station
new EncounterStatic7 { Species = 097, Level = 29, Location = 020, Shiny = Shiny.Never, Relearn = new[] {093,050,001,096}, }, // Hypno @ Hau'oli City Police Station
new EncounterStatic7 { Species = 092, Level = 19, Location = 230, Shiny = Shiny.Never, Relearn = new[] {174,109,122,101}, }, // Gastly @ Route 1 (Trainers School)
new EncounterStatic7 { Species = 425, Level = 19, Location = 230, Shiny = Shiny.Never, Relearn = new[] {310,132,016,371}, }, // Drifloon @ Route 1 (Trainers School)
new EncounterStatic7 { Species = 769, Level = 30, Location = 116, Shiny = Shiny.Never, Relearn = new[] {310,523,072,328}, Version = GameVersion.UM, }, // Sandygast @ Route 15
new EncounterStatic7 { Species = 592, Level = 34, Location = 126, Shiny = Shiny.Never, Gender = 1, }, // Frillish @ Route 14
new EncounterStatic7 { Species = 101, Level = 60, Location = 224, Ability = 1, Shiny = Shiny.Never, }, // Electrode @ Team Rocket's Castle
// Crabrawler in Berry Piles
new EncounterStatic { Species = 739, Level = 25, Location = 106, }, // Route 10
new EncounterStatic { Species = 739, Level = 28, Location = 110, }, // Ula'ula Beach
new EncounterStatic { Species = 739, Level = 31, Location = 118, }, // Route 16
new EncounterStatic { Species = 739, Level = 32, Location = 120, }, // Route 17
new EncounterStatic7 { Species = 739, Level = 25, Location = 106, }, // Route 10
new EncounterStatic7 { Species = 739, Level = 28, Location = 110, }, // Ula'ula Beach
new EncounterStatic7 { Species = 739, Level = 31, Location = 118, }, // Route 16
new EncounterStatic7 { Species = 739, Level = 32, Location = 120, }, // Route 17
};
internal static readonly EncounterTrade[] TradeGift_USUM =
@ -447,7 +446,7 @@ namespace PKHeX.Core
Location = 30016,
Slots = species.SelectMany((_, i) =>
species.Take(1 + i).SelectMany(z => // grab current row & above
z.Select(s => new EncounterSlot // get slot data for each species
z.Select(s => new EncounterSlot7 // get slot data for each species
{
Species = s,
LevelMin = min[i],

View file

@ -7,15 +7,15 @@ namespace PKHeX.Core
{
internal static class Encounters7b
{
internal static readonly EncounterArea7b[] SlotsGP = GetEncounterTables<EncounterArea7b>("gg", "gp");
internal static readonly EncounterArea7b[] SlotsGE = GetEncounterTables<EncounterArea7b>("gg", "ge");
internal static readonly EncounterArea7b[] SlotsGP = GetEncounterTables<EncounterArea7b, EncounterSlot7b>("gg", "gp");
internal static readonly EncounterArea7b[] SlotsGE = GetEncounterTables<EncounterArea7b, EncounterSlot7b>("gg", "ge");
internal static readonly EncounterStatic[] StaticGP, StaticGE;
internal static readonly EncounterArea7g[] SlotsGO_GG = GetGoParkArea();
static Encounters7b()
{
StaticGP = GetStaticEncounters(Encounter_GG, GameVersion.GP);
StaticGE = GetStaticEncounters(Encounter_GG, GameVersion.GE);
StaticGP = GetEncounters(Encounter_GG, GameVersion.GP);
StaticGE = GetEncounters(Encounter_GG, GameVersion.GE);
ManuallyAddRareSpawns(SlotsGP);
ManuallyAddRareSpawns(SlotsGE);
@ -23,7 +23,6 @@ namespace PKHeX.Core
SlotsGE.SetVersion(GameVersion.GE);
Encounter_GG.SetVersion(GameVersion.GG);
TradeGift_GG.SetVersion(GameVersion.GG);
MarkEncountersGeneration(7, SlotsGP, SlotsGE);
MarkEncountersGeneration(7, StaticGP, StaticGE, TradeGift_GG);
}
@ -72,16 +71,16 @@ namespace PKHeX.Core
internal static readonly EncounterTrade[] TradeGift_GG =
{
// Random candy values! They can be zero so no impact on legality even though statistically rare.
new EncounterTrade { Species = 019, Level = 12, Form = 1, TrainerNames = T1, TID7 = 121106, OTGender = 1, Shiny = Shiny.Random, IVs = new[] {31,31,-1,-1,-1,-1}, IsNicknamed = false }, // Rattata @ Cerulean City, AV rand [0-5)
new EncounterTrade { Species = 027, Level = 27, Form = 1, TrainerNames = T2, TID7 = 703019, OTGender = 0, Shiny = Shiny.Random, IVs = new[] {-1,31,31,-1,-1,-1}, IsNicknamed = false, Version = GameVersion.GP }, // Sandshrew @ Celadon City, AV rand [0-5)
new EncounterTrade { Species = 037, Level = 27, Form = 1, TrainerNames = T2, TID7 = 703019, OTGender = 0, Shiny = Shiny.Random, IVs = new[] {-1,-1,-1,31,31,-1}, IsNicknamed = false, Version = GameVersion.GE }, // Vulpix @ Celadon City, AV rand [0-5)
new EncounterTrade { Species = 050, Level = 25, Form = 1, TrainerNames = T3, TID7 = 520159, OTGender = 1, Shiny = Shiny.Random, IVs = new[] {-1,31,-1,31,-1,-1}, IsNicknamed = false }, // Diglett @ Lavender Town, AV rand [0-5)
new EncounterTrade { Species = 052, Level = 44, Form = 1, TrainerNames = T4, TID7 = 000219, OTGender = 0, Shiny = Shiny.Random, IVs = new[] {31,-1,-1,31,-1,-1}, IsNicknamed = false, Version = GameVersion.GE }, // Meowth @ Cinnabar Island, AV rand [0-10)
new EncounterTrade { Species = 088, Level = 44, Form = 1, TrainerNames = T4, TID7 = 000219, OTGender = 0, Shiny = Shiny.Random, IVs = new[] {31,31,-1,-1,-1,-1}, IsNicknamed = false, Version = GameVersion.GP }, // Grimer @ Cinnabar Island, AV rand [0-10)
new EncounterTrade { Species = 026, Level = 30, Form = 1, TrainerNames = T5, TID7 = 940711, OTGender = 1, Shiny = Shiny.Random, IVs = new[] {-1,-1,-1,31,31,-1}, IsNicknamed = false }, // Raichu @ Saffron City, AV rand [0-10)
new EncounterTrade { Species = 105, Level = 38, Form = 1, TrainerNames = T6, TID7 = 102595, OTGender = 0, Shiny = Shiny.Random, IVs = new[] {-1,31,31,-1,-1,-1}, IsNicknamed = false }, // Marowak @ Fuchsia City, AV rand [0-10)
new EncounterTrade { Species = 103, Level = 46, Form = 1, TrainerNames = T7, TID7 = 060310, OTGender = 0, Shiny = Shiny.Random, IVs = new[] {-1,31,-1,-1,31,-1}, IsNicknamed = false }, // Exeggutor @ Indigo Plateau, AV rand [0-15)
new EncounterTrade { Species = 074, Level = 16, Form = 1, TrainerNames = T8, TID7 = 551873, OTGender = 0, Shiny = Shiny.Random, IVs = new[] {31,31,-1,-1,-1,-1}, IsNicknamed = false }, // Geodude @ Vermilion City, AV rand [0-5)
new EncounterTrade7b { Species = 019, Level = 12, Form = 1, TrainerNames = T1, TID7 = 121106, OTGender = 1, Shiny = Shiny.Random, IVs = new[] {31,31,-1,-1,-1,-1}, IsNicknamed = false }, // Rattata @ Cerulean City, AV rand [0-5)
new EncounterTrade7b { Species = 027, Level = 27, Form = 1, TrainerNames = T2, TID7 = 703019, OTGender = 0, Shiny = Shiny.Random, IVs = new[] {-1,31,31,-1,-1,-1}, IsNicknamed = false, Version = GameVersion.GP }, // Sandshrew @ Celadon City, AV rand [0-5)
new EncounterTrade7b { Species = 037, Level = 27, Form = 1, TrainerNames = T2, TID7 = 703019, OTGender = 0, Shiny = Shiny.Random, IVs = new[] {-1,-1,-1,31,31,-1}, IsNicknamed = false, Version = GameVersion.GE }, // Vulpix @ Celadon City, AV rand [0-5)
new EncounterTrade7b { Species = 050, Level = 25, Form = 1, TrainerNames = T3, TID7 = 520159, OTGender = 1, Shiny = Shiny.Random, IVs = new[] {-1,31,-1,31,-1,-1}, IsNicknamed = false }, // Diglett @ Lavender Town, AV rand [0-5)
new EncounterTrade7b { Species = 052, Level = 44, Form = 1, TrainerNames = T4, TID7 = 000219, OTGender = 0, Shiny = Shiny.Random, IVs = new[] {31,-1,-1,31,-1,-1}, IsNicknamed = false, Version = GameVersion.GE }, // Meowth @ Cinnabar Island, AV rand [0-10)
new EncounterTrade7b { Species = 088, Level = 44, Form = 1, TrainerNames = T4, TID7 = 000219, OTGender = 0, Shiny = Shiny.Random, IVs = new[] {31,31,-1,-1,-1,-1}, IsNicknamed = false, Version = GameVersion.GP }, // Grimer @ Cinnabar Island, AV rand [0-10)
new EncounterTrade7b { Species = 026, Level = 30, Form = 1, TrainerNames = T5, TID7 = 940711, OTGender = 1, Shiny = Shiny.Random, IVs = new[] {-1,-1,-1,31,31,-1}, IsNicknamed = false }, // Raichu @ Saffron City, AV rand [0-10)
new EncounterTrade7b { Species = 105, Level = 38, Form = 1, TrainerNames = T6, TID7 = 102595, OTGender = 0, Shiny = Shiny.Random, IVs = new[] {-1,31,31,-1,-1,-1}, IsNicknamed = false }, // Marowak @ Fuchsia City, AV rand [0-10)
new EncounterTrade7b { Species = 103, Level = 46, Form = 1, TrainerNames = T7, TID7 = 060310, OTGender = 0, Shiny = Shiny.Random, IVs = new[] {-1,31,-1,-1,31,-1}, IsNicknamed = false }, // Exeggutor @ Indigo Plateau, AV rand [0-15)
new EncounterTrade7b { Species = 074, Level = 16, Form = 1, TrainerNames = T8, TID7 = 551873, OTGender = 0, Shiny = Shiny.Random, IVs = new[] {31,31,-1,-1,-1,-1}, IsNicknamed = false }, // Geodude @ Vermilion City, AV rand [0-5)
};
private static EncounterArea7g[] GetGoParkArea()
@ -89,10 +88,9 @@ namespace PKHeX.Core
var area = new EncounterArea7g { Location = 50 };
EncounterSlot GetSlot(int species, int form)
{
return new EncounterSlot
return new EncounterSlot7GO
{
Area = area,
Generation = 7,
Species = species,
LevelMin = 1,
LevelMax = 40,
@ -190,7 +188,7 @@ namespace PKHeX.Core
var slots = table.Slots;
var first = slots[0];
var extra = species
.Select(z => new EncounterSlot
.Select(z => new EncounterSlot7b
{
Area = table,
Species = z,

View file

@ -46,14 +46,13 @@ namespace PKHeX.Core
Crystal_SWSH.SetVersion(SWSH);
MarkEncounterTradeStrings(TradeGift_SWSH, TradeSWSH);
StaticSW = GetStaticEncounters(Encounter_SWSH, SW);
StaticSH = GetStaticEncounters(Encounter_SWSH, SH);
StaticSW = GetEncounters(Encounter_SWSH, SW);
StaticSH = GetEncounters(Encounter_SWSH, SH);
// Include Nest Tables for both versions -- online play can share them across versions! In the IsMatch method we check if it's a valid share.
StaticSW = ArrayUtil.ConcatAll(Nest_Common, Nest_SW, Nest_SH, Dist_Common, Dist_SW, Dist_SH, GetStaticEncounters(Crystal_SWSH, SW), StaticSW);
StaticSH = ArrayUtil.ConcatAll(Nest_Common, Nest_SW, Nest_SH, Dist_Common, Dist_SW, Dist_SH, GetStaticEncounters(Crystal_SWSH, SH), StaticSH);
StaticSW = ArrayUtil.ConcatAll(Nest_Common, Nest_SW, Nest_SH, Dist_Common, Dist_SW, Dist_SH, GetEncounters(Crystal_SWSH, SW), StaticSW);
StaticSH = ArrayUtil.ConcatAll(Nest_Common, Nest_SW, Nest_SH, Dist_Common, Dist_SW, Dist_SH, GetEncounters(Crystal_SWSH, SH), StaticSH);
MarkEncountersGeneration(8, SlotsSW, SlotsSH);
MarkEncountersGeneration(8, StaticSW, StaticSH, TradeGift_SWSH);
CopyBerryTreeFromBridgeFieldToStony(SlotsSW_Hidden, 26);

View file

@ -5,18 +5,29 @@ namespace PKHeX.Core
/// <summary>
/// Wild Encounter Slot data
/// </summary>
public class EncounterSlot : IEncounterable, IGenerationSet, ILocation, IVersionSet
public abstract class EncounterSlot : IEncounterable, ILocation, IVersionSet
{
public int Species { get; set; }
public int Form { get; set; }
public int LevelMin { get; set; }
public int LevelMax { get; set; }
public GameVersion Version { get; set; }
public int Generation { get; set; } = -1;
internal EncounterArea? Area { private get; set; }
public int Location { get => Area?.Location ?? 0; set { } }
public abstract int Generation { get; }
public bool EggEncounter => false;
public int EggLocation { get => 0; set { } }
public override string ToString() => $"{(Species) Species} @ {LevelMin}-{LevelMax}";
internal EncounterArea? Area { get; set; }
public int Location { get => Area?.Location ?? 0; set { } }
public SlotType Type { get; set; } = SlotType.Any;
public EncounterSlot Clone() => (EncounterSlot)MemberwiseClone();
public bool FixedLevel => LevelMin == LevelMax;
private protected const string wild = "Wild Encounter";
public string Name => wild;
/// <summary>
/// Gets if the specified level inputs are within range of the <see cref="LevelMin"/> and <see cref="LevelMax"/>
@ -31,7 +42,7 @@ namespace PKHeX.Core
/// <param name="min">Highest value the low end of levels can be</param>
/// <param name="max">Lowest value the high end of levels can be</param>
/// <returns>True if within slot's range, false if impossible.</returns>
public bool IsLevelWithinRange(int min, int max) => LevelMin <= min && max <= LevelMax;
public bool IsLevelWithinRange(int min, int max) => LevelMin <= max && min <= LevelMax;
/// <summary>
/// Gets if the specified level inputs are within range of the <see cref="LevelMin"/> and <see cref="LevelMax"/>
@ -50,29 +61,7 @@ namespace PKHeX.Core
/// <param name="minDecrease">Highest value the low end of levels can be</param>
/// <param name="maxIncrease">Lowest value the high end of levels can be</param>
/// <returns>True if within slot's range, false if impossible.</returns>
public bool IsLevelWithinRange(int min, int max, int minDecrease, int maxIncrease) => LevelMin - minDecrease <= min && max <= LevelMax + maxIncrease;
public SlotType Type { get; set; } = SlotType.Any;
public EncounterType TypeEncounter { get; set; } = EncounterType.None;
public int SlotNumber { get; set; }
private EncounterSlotPermissions? _perm;
public EncounterSlotPermissions Permissions => _perm ??= new EncounterSlotPermissions();
public EncounterSlot Clone()
{
var slot = (EncounterSlot) MemberwiseClone();
if (_perm != null)
slot._perm = Permissions.Clone();
return slot;
}
public bool FixedLevel => LevelMin == LevelMax;
public bool IsMatchStatic(int index, int count) => index == Permissions.StaticIndex && count == Permissions.StaticCount;
public bool IsMatchMagnet(int index, int count) => index == Permissions.MagnetPullIndex && count == Permissions.MagnetPullCount;
private protected const string wild = "Wild Encounter";
public string Name => wild;
public bool IsLevelWithinRange(int min, int max, int minDecrease, int maxIncrease) => LevelMin - minDecrease <= max && min <= LevelMax + maxIncrease;
public virtual string LongName
{
@ -122,36 +111,16 @@ namespace PKHeX.Core
pk.SetRandomEC();
}
private void SetEncounterMoves(PKM pk, GameVersion version, int level)
protected virtual void SetEncounterMoves(PKM pk, GameVersion version, int level)
{
var moves = this is IMoveset m ? m.Moves : MoveLevelUp.GetEncounterMoves(pk, level, version);
var moves = MoveLevelUp.GetEncounterMoves(pk, level, version);
pk.SetMoves(moves);
pk.SetMaximumPPCurrent(moves);
}
private void SetFormatSpecificData(PKM pk)
{
if (pk is XK3 xk3)
{
xk3.FatefulEncounter = true; // PokeSpot
}
else if (pk is PK4 pk4)
{
pk4.EncounterType = TypeEncounter.GetIndex();
}
else if (pk is PK6 pk6)
{
if (Permissions.IsDexNav)
{
var eggMoves = MoveEgg.GetEggMoves(pk, Species, Form, Version);
if (eggMoves.Length > 0)
pk6.RelearnMove1 = eggMoves[Util.Rand.Next(eggMoves.Length)];
}
pk6.SetRandomMemory6();
}
}
protected virtual void SetFormatSpecificData(PKM pk) { }
private void SetPINGA(PKM pk, EncounterCriteria criteria)
protected virtual void SetPINGA(PKM pk, EncounterCriteria criteria)
{
int gender = criteria.GetGender(-1, pk.PersonalInfo);
int nature = (int)criteria.GetNature(Nature.Random);
@ -160,11 +129,7 @@ namespace PKHeX.Core
if (Type == SlotType.HiddenGrotto) // don't force hidden for DexNav
ability = 2;
var pidtype = GetPIDType();
if (pidtype == PIDType.PokeSpot)
PIDGenerator.SetRandomPokeSpotPID(pk, nature, gender, ability, SlotNumber);
else
PIDGenerator.SetRandomWildPID(pk, pk.Format, nature, ability, gender, pidtype);
PIDGenerator.SetRandomWildPID(pk, pk.Format, nature, ability, gender);
pk.Gender = gender;
pk.StatNature = nature;
}
@ -201,11 +166,10 @@ namespace PKHeX.Core
return 0;
}
private PIDType GetPIDType()
public virtual string GetConditionString(out bool valid)
{
if (Version == GameVersion.XD)
return PIDType.PokeSpot;
return PIDType.None; // depends on format, let the program auto-detect.
valid = true;
return LegalityCheckStrings.LEncCondition;
}
}
}

View file

@ -3,8 +3,11 @@
/// <summary>
/// Generation 1 Wild Encounter Slot data
/// </summary>
public sealed class EncounterSlot1 : EncounterSlot
public sealed class EncounterSlot1 : EncounterSlot, INumberedSlot
{
public override int Generation => 1;
public int SlotNumber { get; set; }
public readonly int Rate;
public EncounterSlot1(int species, int min, int max, int rate, SlotType type, int slot)

View file

@ -6,8 +6,11 @@
/// <remarks>
/// Contains Time data which is present in <see cref="GameVersion.C"/> origin data.
/// </remarks>
public sealed class EncounterSlot2 : EncounterSlot
public sealed class EncounterSlot2 : EncounterSlot, INumberedSlot
{
public override int Generation => 2;
public int SlotNumber { get; set; }
public int Rate;
internal EncounterTime Time;

View file

@ -0,0 +1,14 @@
namespace PKHeX.Core
{
public class EncounterSlot3 : EncounterSlot, IMagnetStatic, INumberedSlot
{
public override int Generation => 3;
public int StaticIndex { get; set; } = -1;
public int MagnetPullIndex { get; set; } = -1;
public int StaticCount { get; set; }
public int MagnetPullCount { get; set; }
public int SlotNumber { get; set; }
}
}

View file

@ -0,0 +1,30 @@
namespace PKHeX.Core
{
public sealed class EncounterSlot3PokeSpot : EncounterSlot, INumberedSlot
{
public override int Generation => 3;
public int SlotNumber { get; set; }
public EncounterSlot3PokeSpot(int species, int min, int max, int slot)
{
Species = species;
LevelMin = min;
LevelMax = max;
SlotNumber = slot;
}
// PokeSpot encounters always have Fateful Encounter set.
protected override void SetFormatSpecificData(PKM pk) => pk.FatefulEncounter = true;
protected override void SetPINGA(PKM pk, EncounterCriteria criteria)
{
int gender = criteria.GetGender(-1, pk.PersonalInfo);
int nature = (int)criteria.GetNature(Nature.Random);
int ability = Util.Rand.Next(2);
PIDGenerator.SetRandomPokeSpotPID(pk, nature, gender, ability, SlotNumber);
pk.Gender = gender;
pk.StatNature = nature;
}
}
}

View file

@ -2,10 +2,18 @@ using System.Collections.Generic;
namespace PKHeX.Core
{
internal sealed class EncounterSlot3Swarm : EncounterSlot, IMoveset
internal sealed class EncounterSlot3Swarm : EncounterSlot3, IMoveset
{
public override int Generation => 3;
public IReadOnlyList<int> Moves { get; }
public EncounterSlot3Swarm(int[] moves) => Moves = moves;
public EncounterSlot3Swarm(IReadOnlyList<int> moves) => Moves = moves;
protected override void SetEncounterMoves(PKM pk, GameVersion version, int level)
{
var moves = Moves;
pk.SetMoves(moves);
pk.SetMaximumPPCurrent(moves);
}
}
}

View file

@ -0,0 +1,17 @@
namespace PKHeX.Core
{
public sealed class EncounterSlot4 : EncounterSlot, IMagnetStatic, INumberedSlot
{
public override int Generation => 4;
public EncounterType TypeEncounter { get; set; } = EncounterType.None;
public int StaticIndex { get; set; } = -1;
public int MagnetPullIndex { get; set; } = -1;
public int StaticCount { get; set; }
public int MagnetPullCount { get; set; }
public int SlotNumber { get; set; }
protected override void SetFormatSpecificData(PKM pk) => ((PK4)pk).EncounterType = TypeEncounter.GetIndex();
}
}

View file

@ -0,0 +1,7 @@
namespace PKHeX.Core
{
public sealed class EncounterSlot5 : EncounterSlot
{
public override int Generation => 5;
}
}

View file

@ -0,0 +1,40 @@
namespace PKHeX.Core
{
public sealed class EncounterSlot6AO : EncounterSlot
{
public override int Generation => 6;
public bool Pressure { get; set; }
public bool AllowDexNav { get; set; }
public bool DexNav { get; set; }
public bool WhiteFlute { get; set; }
public bool BlackFlute { get; set; }
private bool IsDexNav => AllowDexNav && DexNav;
protected override void SetFormatSpecificData(PKM pk)
{
var pk6 = (PK6)pk;
if (IsDexNav)
{
var eggMoves = MoveEgg.GetEggMoves(pk, Species, Form, Version);
if (eggMoves.Length > 0)
pk6.RelearnMove1 = eggMoves[Util.Rand.Next(eggMoves.Length)];
}
pk6.SetRandomMemory6();
}
public override string GetConditionString(out bool valid)
{
valid = true;
if (WhiteFlute) // Decreased Level Encounters
return Pressure ? LegalityCheckStrings.LEncConditionWhiteLead : LegalityCheckStrings.LEncConditionWhite;
if (BlackFlute) // Increased Level Encounters
return Pressure ? LegalityCheckStrings.LEncConditionBlackLead : LegalityCheckStrings.LEncConditionBlack;
if (DexNav)
return LegalityCheckStrings.LEncConditionDexNav;
return Pressure ? LegalityCheckStrings.LEncConditionLead : LegalityCheckStrings.LEncCondition;
}
}
}

View file

@ -0,0 +1,20 @@
namespace PKHeX.Core
{
public sealed class EncounterSlot6XY : EncounterSlot
{
public override int Generation => 6;
public bool Pressure { get; set; }
protected override void SetFormatSpecificData(PKM pk)
{
var pk6 = (PK6)pk;
pk6.SetRandomMemory6();
}
public override string GetConditionString(out bool valid)
{
valid = true;
return Pressure ? LegalityCheckStrings.LEncConditionLead : LegalityCheckStrings.LEncCondition;
}
}
}

View file

@ -0,0 +1,8 @@
namespace PKHeX.Core
{
public sealed class EncounterSlot7 : EncounterSlot
{
public override int Generation => 7;
public bool Pressure { get; set; }
}
}

View file

@ -0,0 +1,7 @@
namespace PKHeX.Core
{
public sealed class EncounterSlot7GO : EncounterSlot
{
public override int Generation => 7;
}
}

View file

@ -0,0 +1,7 @@
namespace PKHeX.Core
{
public sealed class EncounterSlot7b : EncounterSlot
{
public override int Generation => 7;
}
}

View file

@ -1,19 +0,0 @@
namespace PKHeX.Core
{
public sealed class EncounterSlotPermissions
{
public int StaticIndex { get; set; } = -1;
public int MagnetPullIndex { get; set; } = -1;
public int StaticCount { get; set; }
public int MagnetPullCount { get; set; }
public bool AllowDexNav { get; set; }
public bool Pressure { get; set; }
public bool DexNav { get; set; }
public bool WhiteFlute { get; set; }
public bool BlackFlute { get; set; }
public bool IsNormalLead => !(WhiteFlute || BlackFlute || DexNav);
public bool IsDexNav => AllowDexNav && DexNav;
public EncounterSlotPermissions Clone() => (EncounterSlotPermissions)MemberwiseClone();
}
}

View file

@ -0,0 +1,17 @@
namespace PKHeX.Core
{
public interface IMagnetStatic
{
int StaticIndex { get; set; }
int MagnetPullIndex { get; set; }
int StaticCount { get; set; }
int MagnetPullCount { get; set; }
}
public static class MagnetStaticExtensions
{
public static bool IsMatchStatic(this IMagnetStatic slot, int index, int count) => index == slot.StaticIndex && count == slot.StaticCount;
public static bool IsMatchMagnet(this IMagnetStatic slot, int index, int count) => index == slot.MagnetPullIndex && count == slot.MagnetPullCount;
}
}

View file

@ -0,0 +1,7 @@
namespace PKHeX.Core
{
public interface INumberedSlot
{
int SlotNumber { get; set; }
}
}

View file

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace PKHeX.Core
{
@ -10,7 +9,7 @@ namespace PKHeX.Core
/// <remarks>
/// Static Encounters are fixed position encounters with properties that are not subject to Wild Encounter conditions.
/// </remarks>
public class EncounterStatic : IEncounterable, IMoveset, IGenerationSet, ILocation, IContestStats, IRelearn, IVersionSet
public class EncounterStatic : IEncounterable, IMoveset, IGenerationSet, ILocation, IVersionSet
{
public int Species { get; set; }
public IReadOnlyList<int> Moves { get; set; } = Array.Empty<int>();
@ -23,7 +22,6 @@ namespace PKHeX.Core
public int Ability { get; set; }
public int Form { get; set; }
public virtual Shiny Shiny { get; set; } = Shiny.Random;
public IReadOnlyList<int> Relearn { get; set; } = Array.Empty<int>();
public int Gender { get; set; } = -1;
public int EggLocation { get; set; }
public Nature Nature { get; set; } = Nature.Random;
@ -33,21 +31,11 @@ namespace PKHeX.Core
public IReadOnlyList<int> IVs { get; set; } = Array.Empty<int>();
public int FlawlessIVCount { get; set; }
internal IReadOnlyList<int> Contest { set => this.SetContestStats(value); }
public int CNT_Cool { get; set; }
public int CNT_Beauty { get; set; }
public int CNT_Cute { get; set; }
public int CNT_Smart { get; set; }
public int CNT_Tough { get; set; }
public int CNT_Sheen { get; set; }
public int HeldItem { get; set; }
public int EggCycles { get; set; }
public bool Fateful { get; set; }
public bool RibbonWishing { get; set; }
public bool SkipFormCheck { get; set; }
public bool Roaming { get; set; }
public bool EggEncounter => EggLocation > 0;
internal EncounterStatic Clone() => (EncounterStatic)MemberwiseClone();
@ -102,19 +90,21 @@ namespace PKHeX.Core
break;
}
if (RibbonWishing && pk is IRibbonSetEvent4 e4)
if (this is EncounterStatic7 s7 && s7.RibbonWishing && pk is IRibbonSetEvent4 e4)
e4.RibbonWishing = true;
if (this is EncounterStatic5N n)
n.SetNPokemonData((PK5)pk, lang);
if (pk is IContestStats s)
this.CopyContestStatsTo(s);
if (this is EncounterStatic6 s6 && pk is IContestStats s)
s6.CopyContestStatsTo(s);
if (Fateful)
pk.FatefulEncounter = true;
if (pk.Format < 6)
return pk;
pk.SetRelearnMoves(Relearn);
if (this is IRelearn relearn)
pk.SetRelearnMoves(relearn.Relearn);
sav.ApplyHandlingTrainerInfo(pk);
pk.SetRandomEC();
@ -219,7 +209,7 @@ namespace PKHeX.Core
{
switch (Generation)
{
case 3 when Roaming && Version != GameVersion.E: // Roamer IV glitch was fixed in Emerald
case 3 when this is EncounterStatic3 s3 && s3.Roaming && Version != GameVersion.E: // Roamer IV glitch was fixed in Emerald
return PIDType.Method_1_Roamer;
case 4 when Shiny == Shiny.Always: // Lake of Rage Gyarados
return PIDType.ChainShiny;
@ -233,32 +223,25 @@ namespace PKHeX.Core
}
}
public virtual bool IsMatch(PKM pkm, int lvl)
public virtual bool IsMatch(PKM pkm, DexLevel evo)
{
if (Nature != Nature.Random && pkm.Nature != (int) Nature)
return false;
if (Generation > 3 && pkm.Format > 3 && pkm.WasEgg != EggEncounter && pkm.Egg_Location == 0 && !pkm.IsEgg)
return false;
if (!IsMatchEggLocation(pkm, ref lvl))
if (!IsMatchEggLocation(pkm))
return false;
if (!IsMatchLocation(pkm))
return false;
if (!IsMatchLevel(pkm, lvl))
if (!IsMatchLevel(pkm, evo))
return false;
if (!IsMatchGender(pkm))
return false;
if (!IsMatchForm(pkm))
if (!IsMatchForm(pkm, evo))
return false;
if (EggLocation == Locations.Daycare5 && Relearn.Count == 0 && pkm.RelearnMoves.Any(z => z != 0)) // gen7 eevee edge case
return false;
if (!IsMatchIVs(pkm))
return false;
if (pkm is IContestStats s && s.IsContestBelow(this))
if (this is IContestStats es && pkm is IContestStats s && s.IsContestBelow(es))
return false;
// Defer to EC/PID check
@ -282,65 +265,27 @@ namespace PKHeX.Core
return Legal.GetIsFixedIVSequenceValidSkipRand(IVs, pkm);
}
private bool IsMatchForm(PKM pkm)
protected virtual bool IsMatchForm(PKM pkm, DexLevel evo)
{
if (SkipFormCheck)
return true;
if (FormConverter.IsTotemForm(Species, Form, Generation))
{
var expectForm = pkm.Format == 7 ? Form : FormConverter.GetTotemBaseForm(Species, Form);
return expectForm == pkm.AltForm;
}
return Form == pkm.AltForm || Legal.IsFormChangeable(pkm, Species, Form);
return Form == evo.Form || Legal.IsFormChangeable(Species, Form, pkm.Format);
}
protected virtual bool IsMatchEggLocation(PKM pkm, ref int lvl)
{
if (Generation == 3 && EggLocation != 0) // Gen3 Egg
{
if (pkm.Format == 3 && pkm.IsEgg && EggLocation != pkm.Met_Location)
return false;
}
else if (EggLocation != pkm.Egg_Location)
protected virtual bool IsMatchEggLocation(PKM pkm)
{
if (pkm.IsEgg) // unhatched
{
if (EggLocation != pkm.Met_Location)
return false;
if (pkm.Egg_Location != 0)
return false;
}
else if (Generation == 4)
{
if (pkm.Egg_Location != Locations.LinkTrade4) // Link Trade
{
// check Pt/HGSS data
if (pkm.Format <= 4)
return false;
if (!Locations.IsPtHGSSLocationEgg(EggLocation)) // non-Pt/HGSS egg gift
return false;
// transferring 4->5 clears pt/hgss location value and keeps Faraway Place
if (pkm.Egg_Location != Locations.Faraway4) // Faraway Place
return false;
}
}
else
{
if (!EggEncounter || pkm.Egg_Location != Locations.LinkTrade6) // Link Trade
return false;
}
}
else if (EggLocation != 0 && Generation == 4)
{
// Check the inverse scenario for 4->5 eggs
if (Locations.IsPtHGSSLocationEgg(EggLocation)) // egg gift
{
if (pkm.Format > 4)
return false;
}
return pkm.Egg_Location == 0;
}
if (EggLocation == pkm.Egg_Location)
return true;
// Only way to mismatch is to be a Link Traded egg.
return EggEncounter && pkm.Egg_Location == Locations.LinkTrade6;
}
private bool IsMatchGender(PKM pkm)
@ -365,24 +310,27 @@ namespace PKHeX.Core
return Location == pkm.Met_Location;
}
protected virtual bool IsMatchLevel(PKM pkm, int lvl)
protected virtual bool IsMatchLevel(PKM pkm, DexLevel evo)
{
if (!pkm.HasOriginalMetLocation)
return lvl >= Level;
return lvl == Level || IsGen3EggEncounter(pkm, lvl);
return pkm.Met_Level == Level;
}
// met level 0, origin level 5
private bool IsGen3EggEncounter(PKM pkm, int lvl) => pkm.Format == 3 && EggEncounter && lvl == 0;
public virtual bool IsMatchDeferred(PKM pkm)
{
if (pkm.FatefulEncounter != Fateful)
return true;
if (Ability == 4 && pkm.AbilityNumber != 4) // BW/2 Jellicent collision with wild surf slot, resolved by duplicating the encounter with any abil
return true;
return false;
}
}
public sealed class EncounterStatic6 : EncounterStatic, IContestStats
{
internal IReadOnlyList<int> Contest { set => this.SetContestStats(value); }
public int CNT_Cool { get; set; }
public int CNT_Beauty { get; set; }
public int CNT_Cute { get; set; }
public int CNT_Smart { get; set; }
public int CNT_Tough { get; set; }
public int CNT_Sheen { get; set; }
}
}

View file

@ -14,5 +14,15 @@
Level = level;
Version = ver;
}
protected override bool IsMatchLevel(PKM pkm, DexLevel evo)
{
return Level <= evo.Level;
}
protected override bool IsMatchLocation(PKM pkm)
{
return true;
}
}
}

View file

@ -13,7 +13,7 @@ namespace PKHeX.Core
Level = level;
}
protected override bool IsMatchEggLocation(PKM pkm, ref int lvl)
protected override bool IsMatchEggLocation(PKM pkm)
{
if (pkm.Format > 2)
return true;
@ -40,9 +40,6 @@ namespace PKHeX.Core
}
}
if (pkm.Met_Level == 1) // Gen2 Eggs are met at 1, and hatch at level 5.
lvl = 5;
return true;
}
@ -53,6 +50,25 @@ namespace PKHeX.Core
if (Version == GameVersion.C && pk is PK2 pk2)
pk2.Met_TimeOfDay = EncounterTime.Any.RandomValidTime();
}
protected override bool IsMatchLevel(PKM pkm, DexLevel evo)
{
if (pkm is PK2 pk2 && pk2.CaughtData != 0)
return pkm.Met_Level == (EggEncounter ? 1 : Level);
return Level <= evo.Level;
}
protected override bool IsMatchLocation(PKM pkm)
{
if (EggEncounter)
return true;
if (Location == 0)
return true;
if (pkm is PK2 pk2 && pk2.CaughtData != 0)
return Location == pkm.Met_Location;
return true;
}
}
public sealed class EncounterStatic2Odd : EncounterStatic2
@ -68,7 +84,7 @@ namespace PKHeX.Core
EggCycles = 20;
}
public override bool IsMatch(PKM pkm, int lvl)
public override bool IsMatch(PKM pkm, DexLevel evo)
{
// Let it get picked up as regular EncounterEgg under other conditions.
if (pkm.Format > 2)
@ -77,7 +93,7 @@ namespace PKHeX.Core
return false;
if (pkm.IsEgg && pkm.EXP != 125)
return false;
return base.IsMatch(pkm, lvl);
return base.IsMatch(pkm, evo);
}
}

View file

@ -0,0 +1,36 @@
namespace PKHeX.Core
{
public class EncounterStatic3 : EncounterStatic
{
public bool Roaming { get; set; }
protected override bool IsMatchEggLocation(PKM pkm)
{
if (pkm.Format == 3)
return !pkm.IsEgg || EggLocation == 0 || EggLocation == pkm.Met_Location;
return pkm.Egg_Location == 0;
}
protected override bool IsMatchLevel(PKM pkm, DexLevel evo)
{
if (pkm.Format != 3) // Met Level lost on PK3=>PK4
return Level <= evo.Level;
if (EggEncounter)
return pkm.Met_Level == 0 && pkm.CurrentLevel >= 5; // met level 0, origin level 5
return pkm.Met_Level == Level;
}
protected override bool IsMatchLocation(PKM pkm)
{
if (EggEncounter)
return true;
if (Location == 0)
return true;
if (pkm.Format == 3)
return Location == pkm.Met_Location;
return true; // transfer location verified later
}
}
}

View file

@ -0,0 +1,59 @@
namespace PKHeX.Core
{
public class EncounterStatic4 : EncounterStatic
{
protected sealed override bool IsMatchEggLocation(PKM pkm)
{
if (pkm.Egg_Location == EggLocation)
{
if (EggLocation == 0)
return true;
// Check the inverse scenario for 4->5 eggs
if (!Locations.IsPtHGSSLocationEgg(EggLocation))
return true;
return pkm.Format == 4;
}
if (pkm.IsEgg) // unhatched
{
if (EggLocation != pkm.Met_Location)
return false;
return pkm.Egg_Location == 0;
}
// Only way to mismatch is to be a Link Traded egg, or traded to Pt/HG/SS and hatched there.
if (pkm.Egg_Location == Locations.LinkTrade4)
return true;
// check Pt/HGSS data
if (pkm.Format == 4)
return false;
if (!Locations.IsPtHGSSLocationEgg(EggLocation)) // non-Pt/HG/SS egg gift
return false;
// transferring 4->5 clears Pt/HG/SS location value and keeps Faraway Place
return pkm.Egg_Location == Locations.Faraway4;
}
protected sealed override bool IsMatchLevel(PKM pkm, DexLevel evo)
{
if (pkm.Format != 4) // Met Level lost on PK3=>PK4
return Level <= evo.Level;
return pkm.Met_Level == (EggEncounter ? 0 : Level);
}
protected override bool IsMatchLocation(PKM pkm)
{
if (EggEncounter)
return true;
if (Location == 0)
return true;
if (pkm.Format == 4)
return Location == pkm.Met_Location;
return true; // transfer location verified later
}
}
}

View file

@ -0,0 +1,16 @@
namespace PKHeX.Core
{
public class EncounterStatic5 : EncounterStatic
{
public bool Roaming { get; set; }
public sealed override bool IsMatchDeferred(PKM pkm)
{
if (pkm.FatefulEncounter != Fateful)
return true;
if (Ability == 4 && pkm.AbilityNumber != 4) // BW/2 Jellicent collision with wild surf slot, resolved by duplicating the encounter with any abil
return true;
return false;
}
}
}

View file

@ -1,13 +1,14 @@
namespace PKHeX.Core
{
internal class EncounterStaticPID : EncounterStatic
internal sealed class EncounterStatic5N : EncounterStatic5
{
public readonly uint PID;
public sealed override Shiny Shiny { get; set; } = Shiny.FixedValue;
public override Shiny Shiny { get; set; } = Shiny.FixedValue;
public const bool NSparkle = true;
internal EncounterStaticPID(uint pid) => PID = pid;
internal EncounterStatic5N(uint pid) => PID = pid;
protected sealed override void SetPINGA(PKM pk, EncounterCriteria criteria)
protected override void SetPINGA(PKM pk, EncounterCriteria criteria)
{
int gender = criteria.GetGender(PKX.GetGenderFromPID(Species, PID), pk.PersonalInfo);
int nature = (int)(PID % 25);
@ -22,19 +23,12 @@
pk.RefreshAbility(ability >> 1);
}
public override bool IsMatch(PKM pkm, int lvl)
public override bool IsMatch(PKM pkm, DexLevel evo)
{
if (PID != pkm.PID)
return false;
return base.IsMatch(pkm, lvl);
return base.IsMatch(pkm, evo);
}
}
internal sealed class EncounterStatic5N : EncounterStaticPID
{
public const bool NSparkle = true;
public EncounterStatic5N(uint pid) : base(pid) { }
internal void SetNPokemonData(PK5 pk5, int lang)
{

View file

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
namespace PKHeX.Core
{
public sealed class EncounterStatic7 : EncounterStatic, IRelearn
{
public IReadOnlyList<int> Relearn { get; set; } = Array.Empty<int>();
public bool RibbonWishing { get; set; }
protected override bool IsMatchLocation(PKM pkm)
{
if (EggLocation == Locations.Daycare5 && Relearn.Count == 0 && pkm.RelearnMove1 != 0) // Gift Eevee edge case
return false;
return base.IsMatchLocation(pkm);
}
protected override bool IsMatchForm(PKM pkm, DexLevel evo)
{
if (SkipFormCheck)
return true;
if (FormConverter.IsTotemForm(Species, Form, Generation))
{
var expectForm = pkm.Format == 7 ? Form : FormConverter.GetTotemBaseForm(Species, Form);
return expectForm == evo.Form;
}
return Form == evo.Form || Legal.IsFormChangeable(Species, Form, pkm.Format);
}
}
}

View file

@ -2,12 +2,13 @@
{
public class EncounterStatic8 : EncounterStatic
{
protected override bool IsMatchLevel(PKM pkm, int lvl)
protected override bool IsMatchLevel(PKM pkm, DexLevel evo)
{
if (lvl == Level)
var met = pkm.Met_Level;
if (met == Level)
return true;
if (EncounterArea8.IsWildArea8(Location) || EncounterArea8.IsWildArea8Armor(Location))
return lvl == 60;
return met == 60;
return false;
}
}

View file

@ -38,7 +38,7 @@ namespace PKHeX.Core
55, 60, // 4
};
protected override bool IsMatchLevel(PKM pkm, int lvl)
protected override bool IsMatchLevel(PKM pkm, DexLevel evo)
{
var met = pkm.Met_Level;
var metLevel = met - 15;
@ -80,12 +80,12 @@ namespace PKHeX.Core
return loc == SharedNest || (loc <= 255 && NestLocations.Contains((byte)loc));
}
public override bool IsMatch(PKM pkm, int lvl)
public override bool IsMatch(PKM pkm, DexLevel evo)
{
if (pkm.FlawlessIVCount < FlawlessIVCount)
return false;
return base.IsMatch(pkm, lvl);
return base.IsMatch(pkm, evo);
}
}
}

View file

@ -20,12 +20,12 @@ namespace PKHeX.Core
return loc == SharedNest || EncounterArea8.IsWildArea8(loc) || EncounterArea8.IsWildArea8Armor(loc);
}
public override bool IsMatch(PKM pkm, int lvl)
public override bool IsMatch(PKM pkm, DexLevel evo)
{
if (pkm.FlawlessIVCount < FlawlessIVCount)
return false;
return base.IsMatch(pkm, lvl);
return base.IsMatch(pkm, evo);
}
}
}

View file

@ -12,8 +12,9 @@ namespace PKHeX.Core
public byte DynamaxLevel { get; set; }
public override int Location { get => SharedNest; set { } }
protected override bool IsMatchLevel(PKM pkm, int lvl)
protected override bool IsMatchLevel(PKM pkm, DexLevel evo)
{
var lvl = pkm.Met_Level;
if (lvl == Level)
return true;
@ -25,7 +26,7 @@ namespace PKHeX.Core
return lvl % 5 == 0;
}
public override bool IsMatch(PKM pkm, int lvl)
public override bool IsMatch(PKM pkm, DexLevel evo)
{
if (pkm is IDynamaxLevel d && d.DynamaxLevel < DynamaxLevel)
return false;
@ -36,7 +37,7 @@ namespace PKHeX.Core
if (VerifyCorrelation != null && !VerifyCorrelation(pkm, (T)this))
return false;
return base.IsMatch(pkm, lvl);
return base.IsMatch(pkm, evo);
}
public override bool IsMatchDeferred(PKM pkm)

View file

@ -5,7 +5,7 @@ namespace PKHeX.Core
/// <summary>
/// Shadow Pokémon Encounter found in <see cref="GameVersion.CXD"/>
/// </summary>
public sealed class EncounterStaticShadow : EncounterStatic
public sealed class EncounterStaticShadow : EncounterStatic3
{
/// <summary>
/// Team Specification with required <see cref="Species"/>, <see cref="Nature"/> and Gender.

View file

@ -1,7 +1,9 @@
namespace PKHeX.Core
{
public sealed class EncounterStaticTyped : EncounterStatic
public sealed class EncounterStaticTyped : EncounterStatic4
{
public bool Roaming { get; set; }
/// <summary>
/// <see cref="PK4.EncounterType"/> values permitted for the encounter.
/// </summary>

View file

@ -10,7 +10,7 @@ namespace PKHeX.Core
/// <remarks>
/// Trade data is fixed level in all cases except for the first few generations of games.
/// </remarks>
public class EncounterTrade : IEncounterable, IGenerationSet, IMoveset, ILocation, IContestStats, IVersionSet
public abstract class EncounterTrade : IEncounterable, IGenerationSet, IMoveset, ILocation, IContestStats, IVersionSet
{
public int Species { get; set; }
public IReadOnlyList<int> Moves { get; set; } = Array.Empty<int>();
@ -225,7 +225,7 @@ namespace PKHeX.Core
}
}
public virtual bool IsMatch(PKM pkm, DexLevel evo, int lvl)
public virtual bool IsMatch(PKM pkm, DexLevel evo)
{
if (IVs.Count != 0)
{
@ -240,13 +240,13 @@ namespace PKHeX.Core
if (SID != pkm.SID)
return false;
if (!IsMatchLevel(pkm, lvl))
if (!IsMatchLevel(pkm, evo))
return false;
if (CurrentLevel != -1 && CurrentLevel > pkm.CurrentLevel)
return false;
if (Form != evo.Form && !Legal.IsFormChangeable(pkm, Species, Form))
if (Form != evo.Form && !Legal.IsFormChangeable(Species, Form, pkm.Format))
return false;
if (OTGender != -1 && OTGender != pkm.OT_Gender)
return false;
@ -263,30 +263,19 @@ namespace PKHeX.Core
return true;
}
private bool IsMatchLevel(PKM pkm, int lvl)
{
if (pkm.HasOriginalMetLocation)
private bool IsMatchLevel(PKM pkm, DexLevel evo)
{
if (!pkm.HasOriginalMetLocation)
return Level <= evo.Level;
var loc = Location > 0 ? Location : DefaultMetLocation[Generation - 1];
if (loc != pkm.Met_Location)
return false;
if (pkm.Format < 5)
{
if (Level > lvl)
return false;
}
else if (Level != lvl)
{
return false;
}
}
else if (Level > lvl)
{
return false;
}
return Level <= evo.Level;
return true;
return Level == pkm.Met_Level;
}
protected virtual bool IsMatchNatureGenderShiny(PKM pkm)

View file

@ -0,0 +1,34 @@
namespace PKHeX.Core
{
public sealed class EncounterTrade3 : EncounterTrade
{
/// <summary>
/// Fixed <see cref="PKM.PID"/> value the encounter must have.
/// </summary>
public readonly uint PID;
public EncounterTrade3(uint pid) => PID = pid;
public override Shiny Shiny { get; set; } = Shiny.FixedValue;
protected override void SetPINGA(PKM pk, EncounterCriteria criteria)
{
var pi = pk.PersonalInfo;
int gender = criteria.GetGender(PKX.GetGenderFromPID(Species, PID), pi);
int nature = (int)criteria.GetNature(Nature);
int ability = criteria.GetAbilityFromNumber(Ability, pi);
pk.PID = PID;
pk.Nature = nature;
pk.Gender = gender;
pk.RefreshAbility(ability);
SetIVs(pk);
}
protected override bool IsMatchNatureGenderShiny(PKM pkm)
{
return PID == pkm.EncryptionConstant;
}
}
}

View file

@ -0,0 +1,38 @@
namespace PKHeX.Core
{
public sealed class EncounterTrade4PID : EncounterTrade
{
/// <summary>
/// Fixed <see cref="PKM.PID"/> value the encounter must have.
/// </summary>
public readonly uint PID;
public EncounterTrade4PID(uint pid) => PID = pid;
public override Shiny Shiny { get; set; } = Shiny.FixedValue;
protected override void SetPINGA(PKM pk, EncounterCriteria criteria)
{
var pi = pk.PersonalInfo;
int gender = criteria.GetGender(PKX.GetGenderFromPID(Species, PID), pi);
int nature = (int)criteria.GetNature(Nature);
int ability = criteria.GetAbilityFromNumber(Ability, pi);
pk.PID = PID;
pk.Nature = nature;
pk.Gender = gender;
pk.RefreshAbility(ability);
SetIVs(pk);
}
protected override bool IsMatchNatureGenderShiny(PKM pkm)
{
return PID == pkm.EncryptionConstant;
}
}
public sealed class EncounterTrade4 : EncounterTrade
{
}
}

View file

@ -1,16 +1,17 @@
namespace PKHeX.Core
{
/// <summary>
/// Trade Encounter data with a fixed PID.
/// </summary>
public sealed class EncounterTradePID : EncounterTrade
public sealed class EncounterTrade5 : EncounterTrade
{
}
public sealed class EncounterTrade5PID : EncounterTrade
{
/// <summary>
/// Fixed <see cref="PKM.PID"/> value the encounter must have.
/// </summary>
public readonly uint PID;
public EncounterTradePID(uint pid) => PID = pid;
public EncounterTrade5PID(uint pid) => PID = pid;
public override Shiny Shiny { get; set; } = Shiny.FixedValue;

View file

@ -0,0 +1,6 @@
namespace PKHeX.Core
{
public sealed class EncounterTrade7b : EncounterTrade
{
}
}

View file

@ -24,13 +24,13 @@ namespace PKHeX.Core
OT_Intensity = i;
}
public override bool IsMatch(PKM pkm, DexLevel evo, int lvl)
public override bool IsMatch(PKM pkm, DexLevel evo)
{
if (pkm is IDynamaxLevel d && d.DynamaxLevel < DynamaxLevel)
return false;
if (pkm.FlawlessIVCount < FlawlessIVCount)
return false;
return base.IsMatch(pkm, evo, lvl);
return base.IsMatch(pkm, evo);
}
protected override void ApplyDetails(ITrainerInfo sav, EncounterCriteria criteria, PKM pk)

View file

@ -98,7 +98,7 @@ namespace PKHeX.Core
/// </summary>
internal static class EncounterEggGenerator2
{
public static IEnumerable<IEncounterable> GenerateEggs(PKM pkm, List<EvoCriteria> chain)
public static IEnumerable<IEncounterable> GenerateEggs(PKM pkm, IReadOnlyList<EvoCriteria> chain)
{
var canBeEgg = GetCanBeEgg(pkm);
if (!canBeEgg)

View file

@ -62,7 +62,7 @@ namespace PKHeX.Core
{
if (pkm.Version == (int)GameVersion.CXD) // C/XD
{
if (z is EncounterSlot w)
if (z is EncounterSlot3PokeSpot w)
{
var seeds = MethodFinder.GetPokeSpotSeeds(pkm, w.SlotNumber).FirstOrDefault();
info.PIDIV = seeds ?? info.PIDIV;
@ -140,7 +140,7 @@ namespace PKHeX.Core
// Since encounter matching is super weak due to limited stored data in the structure
// Calculate all 3 at the same time and pick the best result (by species).
// Favor special event move gifts as Static Encounters when applicable
var chain = EvolutionChain.GetOriginChain(pkm, game);
var chain = EncounterOrigin.GetOriginChain12(pkm, game);
var deferred = new List<IEncounterable>();
foreach (var t in GetValidEncounterTrades(pkm, chain, game))
@ -259,7 +259,7 @@ namespace PKHeX.Core
case EncounterTrade2 _:
return GBEncounterPriority.TradeEncounterG2;
case EncounterStatic s:
if (s.Moves.Count != 0 && s.Moves[0] != 0 && pkm.Moves.Contains(s.Moves[0]))
if (s.Moves.Count != 0 && s.Moves[0] != 0 && pkm.HasMove(s.Moves[0]))
return GBEncounterPriority.SpecialEncounter;
return GBEncounterPriority.StaticEncounter;
case EncounterSlot _:
@ -287,9 +287,10 @@ namespace PKHeX.Core
{
int ctr = 0;
var chain = EncounterOrigin.GetOriginChain(pkm);
if (pkm.WasEvent || pkm.WasEventEgg || pkm.WasLink)
{
foreach (var z in GetValidGifts(pkm))
foreach (var z in GetValidGifts(pkm, chain))
{ yield return z; ++ctr; }
if (ctr != 0) yield break;
}
@ -301,21 +302,21 @@ namespace PKHeX.Core
if (ctr == 0) yield break;
}
foreach (var z in GetValidStaticEncounter(pkm))
foreach (var z in GetValidStaticEncounter(pkm, chain))
{ yield return z; ++ctr; }
if (ctr != 0) yield break;
if (EncounterArea6XY.WasFriendSafari(pkm))
if (EncounterArea6XYFriendSafari.WasFriendSafari(pkm))
{
foreach (var z in EncounterArea6XY.GetValidFriendSafari(pkm))
foreach (var z in EncounterArea6XYFriendSafari.GetValidSafariEncounters(pkm))
{ yield return z; ++ctr; }
if (ctr != 0) yield break;
}
foreach (var z in GetValidWildEncounters(pkm))
foreach (var z in GetValidWildEncounters(pkm, chain))
{ yield return z; ++ctr; }
if (ctr != 0) yield break;
foreach (var z in GetValidEncounterTrades(pkm))
foreach (var z in GetValidEncounterTrades(pkm, chain))
{ yield return z; ++ctr; }
}
@ -324,9 +325,10 @@ namespace PKHeX.Core
// Static Encounters can collide with wild encounters (close match); don't break if a Static Encounter is yielded.
int ctr = 0;
var chain = EncounterOrigin.GetOriginChain(pkm);
if (pkm.WasEvent || pkm.WasEventEgg)
{
foreach (var z in GetValidGifts(pkm))
foreach (var z in GetValidGifts(pkm, chain))
{ yield return z; ++ctr; }
if (ctr != 0) yield break;
}
@ -338,24 +340,25 @@ namespace PKHeX.Core
if (ctr == 0) yield break;
}
foreach (var z in GetValidStaticEncounter(pkm))
foreach (var z in GetValidStaticEncounter(pkm, chain))
{ yield return z; ++ctr; }
// if (ctr != 0) yield break;
foreach (var z in GetValidWildEncounters(pkm))
foreach (var z in GetValidWildEncounters(pkm, chain))
{ yield return z; ++ctr; }
if (ctr != 0) yield break;
foreach (var z in GetValidEncounterTrades(pkm))
foreach (var z in GetValidEncounterTrades(pkm, chain))
{ yield return z; ++ctr; }
}
private static IEnumerable<IEncounterable> GenerateRawEncounters4(PKM pkm, LegalInfo info)
{
bool wasEvent = pkm.WasEvent || pkm.WasEventEgg; // egg events?
var chain = EncounterOrigin.GetOriginChain(pkm);
if (wasEvent)
{
int ctr = 0;
foreach (var z in GetValidGifts(pkm))
foreach (var z in GetValidGifts(pkm, chain))
{ yield return z; ++ctr; }
if (ctr != 0) yield break;
}
@ -364,7 +367,7 @@ namespace PKHeX.Core
foreach (var z in GenerateEggs(pkm))
yield return z;
}
foreach (var z in GetValidEncounterTrades(pkm))
foreach (var z in GetValidEncounterTrades(pkm, chain))
yield return z;
var deferIncompat = new Queue<IEncounterable>();
@ -373,7 +376,7 @@ namespace PKHeX.Core
bool safariSport = safari || sport;
if (!safariSport)
{
foreach (var z in GetValidStaticEncounter(pkm))
foreach (var z in GetValidStaticEncounter(pkm, chain))
{
if (z.Gift && pkm.Ball != 4)
deferIncompat.Enqueue(z);
@ -386,10 +389,10 @@ namespace PKHeX.Core
var deferNoFrame = new Queue<IEncounterable>();
var deferFrame = new Queue<IEncounterable>();
var slots = FrameFinder.GetFrames(info.PIDIV, pkm).ToList();
foreach (var z in GetValidWildEncounters34(pkm))
foreach (var z in GetValidWildEncounters34(pkm, chain))
{
bool defer = z.IsDeferred4(species, pkm, safari, sport);
var frame = slots.Find(s => s.IsSlotCompatibile(z, pkm));
var frame = slots.Find(s => s.IsSlotCompatibile((EncounterSlot4)z, pkm));
if (defer)
{
if (frame != null)
@ -419,22 +422,23 @@ namespace PKHeX.Core
// do static encounters if they were deferred to end, spit out any possible encounters for invalid pkm
if (!safariSport)
yield break;
foreach (var z in GetValidStaticEncounter(pkm))
foreach (var z in GetValidStaticEncounter(pkm, chain))
yield return z;
}
private static IEnumerable<IEncounterable> GenerateRawEncounters3(PKM pkm, LegalInfo info)
{
foreach (var z in GetValidGifts(pkm))
var chain = EncounterOrigin.GetOriginChain(pkm);
foreach (var z in GetValidGifts(pkm, chain))
yield return z;
foreach (var z in GetValidEncounterTrades(pkm))
foreach (var z in GetValidEncounterTrades(pkm, chain))
yield return z;
var deferIncompat = new Queue<IEncounterable>();
bool safari = pkm.Ball == 0x05; // never static encounters
if (!safari)
{
foreach (var z in GetValidStaticEncounter(pkm))
foreach (var z in GetValidStaticEncounter(pkm, chain))
{
if (z.Gift && pkm.Ball != 4)
deferIncompat.Enqueue(z);
@ -447,10 +451,10 @@ namespace PKHeX.Core
var deferNoFrame = new Queue<IEncounterable>();
var deferFrame = new Queue<IEncounterable>();
var slots = FrameFinder.GetFrames(info.PIDIV, pkm).ToList();
foreach (var z in GetValidWildEncounters34(pkm))
foreach (var z in GetValidWildEncounters34(pkm, chain))
{
bool defer = z.IsDeferred3(species, pkm, safari);
var frame = slots.Find(s => s.IsSlotCompatibile(z, pkm));
var frame = slots.Find(s => s.IsSlotCompatibile((EncounterSlot3)z, pkm));
if (defer)
{
if (frame != null)
@ -485,7 +489,7 @@ namespace PKHeX.Core
// do static encounters if they were deferred to end, spit out any possible encounters for invalid pkm
if (!safari)
yield break;
foreach (var z in GetValidStaticEncounter(pkm))
foreach (var z in GetValidStaticEncounter(pkm, chain))
yield return z;
}
@ -495,7 +499,7 @@ namespace PKHeX.Core
return e switch
{
EncounterStaticTyped t => t.TypeEncounter.Contains(type),
EncounterSlot w => w.TypeEncounter.Contains(type),
EncounterSlot4 w => w.TypeEncounter.Contains(type),
_ => (type == 0)
};
}

View file

@ -118,30 +118,30 @@ namespace PKHeX.Core
{
pk.Version = (int)version;
var et = EvolutionTree.GetEvolutionTree(pk.Format);
var dl = et.GetValidPreEvolutions(pk, maxLevel: 100, skipChecks: true);
int[] needs = GetNeededMoves(pk, moves, dl);
var chain = et.GetValidPreEvolutions(pk, maxLevel: 100, skipChecks: true);
int[] needs = GetNeededMoves(pk, moves, chain);
return PriorityList.SelectMany(type => GetPossibleOfType(pk, needs, version, type));
return PriorityList.SelectMany(type => GetPossibleOfType(pk, needs, version, type, chain));
}
private static int[] GetNeededMoves(PKM pk, IEnumerable<int> moves, IReadOnlyList<EvoCriteria> dl)
private static int[] GetNeededMoves(PKM pk, IEnumerable<int> moves, IReadOnlyList<EvoCriteria> chain)
{
if (pk.Species == (int)Species.Smeargle)
return moves.Intersect(Legal.InvalidSketch).ToArray(); // Can learn anything
var gens = VerifyCurrentMoves.GetGenMovesCheckOrder(pk);
var canlearn = gens.SelectMany(z => GetMovesForGeneration(pk, dl, z));
var canlearn = gens.SelectMany(z => GetMovesForGeneration(pk, chain, z));
return moves.Except(canlearn).ToArray();
}
private static IEnumerable<int> GetMovesForGeneration(PKM pk, IReadOnlyList<EvoCriteria> dl, int generation)
private static IEnumerable<int> GetMovesForGeneration(PKM pk, IReadOnlyList<EvoCriteria> chain, int generation)
{
IEnumerable<int> moves = MoveList.GetValidMoves(pk, dl, generation);
IEnumerable<int> moves = MoveList.GetValidMoves(pk, chain, generation);
if (pk.Format >= 8)
{
// Shared Egg Moves via daycare
// Any egg move can be obtained
var evo = dl[dl.Count - 1];
var evo = chain[chain.Count - 1];
var shared = MoveEgg.GetEggMoves(8, evo.Species, evo.Form, GameVersion.SW);
if (shared.Length != 0)
moves = moves.Concat(shared);
@ -159,15 +159,15 @@ namespace PKHeX.Core
return moves;
}
private static IEnumerable<IEncounterable> GetPossibleOfType(PKM pk, IReadOnlyCollection<int> needs, GameVersion version, EncounterOrder type)
private static IEnumerable<IEncounterable> GetPossibleOfType(PKM pk, IReadOnlyCollection<int> needs, GameVersion version, EncounterOrder type, IReadOnlyList<EvoCriteria> chain)
{
return type switch
{
EncounterOrder.Egg => GetEggs(pk, needs, version),
EncounterOrder.Mystery => GetGifts(pk, needs),
EncounterOrder.Static => GetStatic(pk, needs),
EncounterOrder.Trade => GetTrades(pk, needs),
EncounterOrder.Slot => GetSlots(pk, needs),
EncounterOrder.Mystery => GetGifts(pk, needs, chain),
EncounterOrder.Static => GetStatic(pk, needs, chain),
EncounterOrder.Trade => GetTrades(pk, needs, chain),
EncounterOrder.Slot => GetSlots(pk, needs, chain),
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
};
}
@ -206,10 +206,11 @@ namespace PKHeX.Core
/// </summary>
/// <param name="pk">Rough Pokémon data which contains the requested species, gender, and form.</param>
/// <param name="needs">Moves which cannot be taught by the player.</param>
/// <param name="chain">Origin possible evolution chain</param>
/// <returns>A consumable <see cref="IEncounterable"/> list of possible encounters.</returns>
private static IEnumerable<MysteryGift> GetGifts(PKM pk, IReadOnlyCollection<int> needs)
private static IEnumerable<MysteryGift> GetGifts(PKM pk, IReadOnlyCollection<int> needs, IReadOnlyList<EvoCriteria> chain)
{
var gifts = MysteryGiftGenerator.GetPossible(pk);
var gifts = MysteryGiftGenerator.GetPossible(pk, chain);
foreach (var gift in gifts)
{
if (gift is WC3 wc3 && wc3.NotDistributed)
@ -230,10 +231,11 @@ namespace PKHeX.Core
/// </summary>
/// <param name="pk">Rough Pokémon data which contains the requested species, gender, and form.</param>
/// <param name="needs">Moves which cannot be taught by the player.</param>
/// <param name="chain">Origin possible evolution chain</param>
/// <returns>A consumable <see cref="IEncounterable"/> list of possible encounters.</returns>
private static IEnumerable<EncounterStatic> GetStatic(PKM pk, IReadOnlyCollection<int> needs)
private static IEnumerable<EncounterStatic> GetStatic(PKM pk, IReadOnlyCollection<int> needs, IReadOnlyList<EvoCriteria> chain)
{
var encounters = EncounterStaticGenerator.GetPossible(pk);
var encounters = EncounterStaticGenerator.GetPossible(pk, chain);
foreach (var enc in encounters)
{
if (enc.IsUnobtainable(pk))
@ -245,7 +247,9 @@ namespace PKHeX.Core
}
// Some rare encounters have special moves hidden in the Relearn section (Gen7 Wormhole Ho-Oh). Include relearn moves
var em = enc.Moves.Concat(enc.Relearn);
IEnumerable<int> em = enc.Moves;
if (enc is IRelearn r)
em = em.Concat(r.Relearn);
if (!needs.Except(em).Any())
yield return enc;
}
@ -256,10 +260,11 @@ namespace PKHeX.Core
/// </summary>
/// <param name="pk">Rough Pokémon data which contains the requested species, gender, and form.</param>
/// <param name="needs">Moves which cannot be taught by the player.</param>
/// <param name="chain">Origin possible evolution chain</param>
/// <returns>A consumable <see cref="IEncounterable"/> list of possible encounters.</returns>
private static IEnumerable<EncounterTrade> GetTrades(PKM pk, IReadOnlyCollection<int> needs)
private static IEnumerable<EncounterTrade> GetTrades(PKM pk, IReadOnlyCollection<int> needs, IReadOnlyList<EvoCriteria> chain)
{
var trades = EncounterTradeGenerator.GetPossible(pk);
var trades = EncounterTradeGenerator.GetPossible(pk, chain);
foreach (var trade in trades)
{
if (needs.Count == 0)
@ -278,10 +283,11 @@ namespace PKHeX.Core
/// </summary>
/// <param name="pk">Rough Pokémon data which contains the requested species, gender, and form.</param>
/// <param name="needs">Moves which cannot be taught by the player.</param>
/// <param name="chain">Origin possible evolution chain</param>
/// <returns>A consumable <see cref="IEncounterable"/> list of possible encounters.</returns>
private static IEnumerable<EncounterSlot> GetSlots(PKM pk, IReadOnlyCollection<int> needs)
private static IEnumerable<EncounterSlot> GetSlots(PKM pk, IReadOnlyCollection<int> needs, IReadOnlyList<EvoCriteria> chain)
{
var slots = EncounterSlotGenerator.GetPossible(pk);
var slots = EncounterSlotGenerator.GetPossible(pk, chain);
foreach (var slot in slots)
{
if (slot.IsUnobtainable(pk))

View file

@ -16,19 +16,13 @@ namespace PKHeX.Core
{
public static class EncounterSlotGenerator
{
public static IEnumerable<EncounterSlot> GetPossible(PKM pkm, GameVersion gameSource = GameVersion.Any)
{
var chain = EvolutionChain.GetOriginChain(pkm, gameSource);
return GetPossible(pkm, chain, gameSource);
}
public static IEnumerable<EncounterSlot> GetPossible(PKM pkm, IReadOnlyList<DexLevel> chain, GameVersion gameSource = GameVersion.Any)
{
var possibleAreas = GetEncounterSlots(pkm, gameSource);
return possibleAreas.SelectMany(area => area.Slots).Where(z => chain.Any(v => v.Species == z.Species));
}
private static IEnumerable<EncounterSlot> GetRawEncounterSlots(PKM pkm, int lvl, IReadOnlyList<EvoCriteria> chain, GameVersion gameSource)
private static IEnumerable<EncounterSlot> GetRawEncounterSlots(PKM pkm, IReadOnlyList<EvoCriteria> chain, GameVersion gameSource)
{
if (pkm.Egg_Location != 0)
yield break;
@ -36,37 +30,28 @@ namespace PKHeX.Core
var possibleAreas = GetEncounterAreas(pkm, gameSource);
foreach (var area in possibleAreas)
{
var slots = area.GetMatchingSlots(pkm, chain, lvl);
var slots = area.GetMatchingSlots(pkm, chain);
foreach (var s in slots)
yield return s;
}
}
public static IEnumerable<EncounterSlot> GetValidWildEncounters34(PKM pkm, GameVersion gameSource = GameVersion.Any)
public static IEnumerable<EncounterSlot> GetValidWildEncounters34(PKM pkm, IReadOnlyList<EvoCriteria> chain, GameVersion gameSource = GameVersion.Any)
{
int lvl = GetMaxLevelEncounter(pkm);
if (lvl <= 0)
return Enumerable.Empty<EncounterSlot>();
if (gameSource == GameVersion.Any)
gameSource = (GameVersion)pkm.Version;
var chain = EvolutionChain.GetOriginChain(pkm);
var slots = GetRawEncounterSlots(pkm, lvl, chain, gameSource);
var slots = GetRawEncounterSlots(pkm, chain, gameSource);
return slots; // defer deferrals to the method consuming this collection
}
public static IEnumerable<EncounterSlot> GetValidWildEncounters12(PKM pkm, IReadOnlyList<EvoCriteria> chain, GameVersion gameSource = GameVersion.Any)
{
int lvl = GetMaxLevelEncounter(pkm);
if (lvl <= 0)
return Enumerable.Empty<EncounterSlot>();
if (gameSource == GameVersion.Any)
gameSource = (GameVersion)pkm.Version;
return GetRawEncounterSlots(pkm, lvl, chain, gameSource);
return GetRawEncounterSlots(pkm, chain, gameSource);
}
public static IEnumerable<EncounterSlot> GetValidWildEncounters(PKM pkm, IReadOnlyList<EvoCriteria> chain, GameVersion gameSource = GameVersion.Any)
@ -74,10 +59,7 @@ namespace PKHeX.Core
if (gameSource == GameVersion.Any)
gameSource = (GameVersion)pkm.Version;
int lvl = GetMaxLevelEncounter(pkm);
if (lvl <= 0)
return Enumerable.Empty<EncounterSlot>();
var s = GetRawEncounterSlots(pkm, lvl, chain, gameSource);
var s = GetRawEncounterSlots(pkm, chain, gameSource);
bool IsSafariBall = pkm.Ball == (int)Ball.Safari;
bool IsSportBall = pkm.Ball == (int)Ball.Sport;
@ -87,12 +69,6 @@ namespace PKHeX.Core
return s.DeferByBoolean(slot => slot.IsDeferred(species, pkm, IsSafariBall, IsSportBall, IsHidden)); // non-deferred first
}
public static IEnumerable<EncounterSlot> GetValidWildEncounters(PKM pkm, GameVersion gameSource = GameVersion.Any)
{
var chain = EvolutionChain.GetOriginChain(pkm);
return GetValidWildEncounters(pkm, chain, gameSource);
}
public static bool IsDeferred3(this EncounterSlot slot, int currentSpecies, PKM pkm, bool IsSafariBall)
{
return slot.IsDeferredWurmple(currentSpecies, pkm)
@ -119,11 +95,11 @@ namespace PKHeX.Core
private static bool IsDeferredSport(this EncounterSlot slot, bool IsSportBall) => IsSportBall != ((slot.Type & SlotType.BugContest) != 0);
private static bool IsDeferredHiddenAbility(this EncounterSlot slot, bool IsHidden) => IsHidden != slot.IsHiddenAbilitySlot();
private static IEnumerable<EncounterSlot> GetValidEncounterSlots(PKM pkm, EncounterArea loc, IReadOnlyList<EvoCriteria> chain, int lvl)
private static IEnumerable<EncounterSlot> GetValidEncounterSlots(PKM pkm, EncounterArea loc, IReadOnlyList<EvoCriteria> chain)
{
if (pkm.Egg_Location != 0)
return Enumerable.Empty<EncounterSlot>();
return loc.GetMatchingSlots(pkm, chain, lvl);
return loc.GetMatchingSlots(pkm, chain);
}
public static IEnumerable<EncounterArea> GetEncounterSlots(PKM pkm, GameVersion gameSource = GameVersion.Any)
@ -149,14 +125,14 @@ namespace PKHeX.Core
private static bool IsHiddenAbilitySlot(this EncounterSlot slot)
{
return slot.Permissions.DexNav || slot.Type == SlotType.FriendSafari || slot.Type == SlotType.Horde || slot.Type == SlotType.SOS;
return (slot is EncounterSlot6AO ao && ao.DexNav) || slot.Type == SlotType.FriendSafari || slot.Type == SlotType.Horde || slot.Type == SlotType.SOS;
}
internal static EncounterArea? GetCaptureLocation(PKM pkm)
{
var chain = EvolutionChain.GetOriginChain(pkm);
var chain = EvolutionChain.GetValidPreEvolutions(pkm, maxLevel: 100, skipChecks: true);
return (from area in GetEncounterSlots(pkm)
let slots = GetValidEncounterSlots(pkm, area, chain, lvl: 0).ToArray()
let slots = GetValidEncounterSlots(pkm, area, chain).ToArray()
where slots.Length != 0
select new EncounterAreaFake
{

View file

@ -16,12 +16,6 @@ namespace PKHeX.Core
{
public static class EncounterStaticGenerator
{
public static IEnumerable<EncounterStatic> GetPossible(PKM pkm, GameVersion gameSource = GameVersion.Any)
{
var dl = EvolutionChain.GetOriginChain(pkm);
return GetPossible(pkm, dl, gameSource);
}
public static IEnumerable<EncounterStatic> GetPossible(PKM pkm, IReadOnlyList<DexLevel> chain, GameVersion gameSource = GameVersion.Any)
{
if (gameSource == GameVersion.Any)
@ -33,51 +27,39 @@ namespace PKHeX.Core
return encounters.Where(e => !GameVersion.GBCartEraOnly.Contains(e.Version));
}
public static IEnumerable<EncounterStatic> GetValidStaticEncounter(PKM pkm, GameVersion gameSource = GameVersion.Any)
{
var poss = GetPossible(pkm, gameSource: gameSource);
int lvl = GetMaxLevelEncounter(pkm);
if (lvl < 0)
return Enumerable.Empty<EncounterStatic>();
// Back Check against pkm
return GetMatchingStaticEncounters(pkm, poss, lvl);
}
public static IEnumerable<EncounterStatic> GetValidStaticEncounter(PKM pkm, IReadOnlyList<DexLevel> chain, GameVersion gameSource)
public static IEnumerable<EncounterStatic> GetValidStaticEncounter(PKM pkm, IReadOnlyList<DexLevel> chain, GameVersion gameSource = GameVersion.Any)
{
var poss = GetPossible(pkm, chain, gameSource: gameSource);
int lvl = GetMaxLevelEncounter(pkm);
if (lvl < 0)
return Enumerable.Empty<EncounterStatic>();
// Back Check against pkm
return GetMatchingStaticEncounters(pkm, poss, lvl);
return GetMatchingStaticEncounters(pkm, poss, chain);
}
private static IEnumerable<EncounterStatic> GetMatchingStaticEncounters(PKM pkm, IEnumerable<EncounterStatic> poss, int lvl)
private static IEnumerable<EncounterStatic> GetMatchingStaticEncounters(PKM pkm, IEnumerable<EncounterStatic> poss, IReadOnlyList<DexLevel> evos)
{
// check for petty rejection scenarios that will be flagged by other legality checks
var deferred = new List<EncounterStatic>();
foreach (EncounterStatic e in poss)
{
if (!GetIsMatchStatic(pkm, e, lvl))
foreach (var dl in evos)
{
if (!GetIsMatchStatic(pkm, e, dl))
continue;
if (e.IsMatchDeferred(pkm))
deferred.Add(e);
else
yield return e;
break;
}
}
foreach (var e in deferred)
yield return e;
}
private static bool GetIsMatchStatic(PKM pkm, EncounterStatic e, int lvl)
private static bool GetIsMatchStatic(PKM pkm, EncounterStatic e, DexLevel evo)
{
if (!e.IsMatch(pkm, lvl))
if (!e.IsMatch(pkm, evo))
return false;
if (pkm is PK1 pk1 && pk1.Gen1_NotTradeback && !IsValidCatchRatePK1(e, pk1))
@ -98,12 +80,12 @@ namespace PKHeX.Core
return table.Where(e => dl.Any(d => d.Species == e.Species));
}
internal static IEncounterable GetVCStaticTransferEncounter(PKM pkm)
internal static IEncounterable GetVCStaticTransferEncounter(PKM pkm, IEncounterable enc)
{
if (pkm.VC1)
return GetRBYStaticTransfer(pkm.Species, pkm.Met_Level);
return GetRBYStaticTransfer(pkm.Species > MaxSpeciesID_1 ? enc.Species : pkm.Species, pkm.Met_Level);
if (pkm.VC2)
return GetGSStaticTransfer(pkm.Species, pkm.Met_Level);
return GetGSStaticTransfer(pkm.Species > MaxSpeciesID_2 ? enc.Species : pkm.Species, pkm.Met_Level);
return new EncounterInvalid(pkm);
}

View file

@ -7,12 +7,6 @@ namespace PKHeX.Core
{
public static class EncounterTradeGenerator
{
public static IEnumerable<EncounterTrade> GetPossible(PKM pkm, GameVersion gameSource = GameVersion.Any)
{
var p = EvolutionChain.GetOriginChain(pkm);
return GetPossible(pkm, p, gameSource);
}
public static IEnumerable<EncounterTrade> GetPossible(PKM pkm, IReadOnlyList<DexLevel> chain, GameVersion gameSource = GameVersion.Any)
{
if (gameSource == GameVersion.Any)
@ -23,26 +17,22 @@ namespace PKHeX.Core
return GetPossibleNonVC(pkm, chain, gameSource);
}
public static IEnumerable<EncounterTrade> GetValidEncounterTrades(PKM pkm, GameVersion gameSource = GameVersion.Any)
{
var p = EvolutionChain.GetOriginChain(pkm);
return GetValidEncounterTrades(pkm, p, gameSource);
}
public static IEnumerable<EncounterTrade> GetValidEncounterTrades(PKM pkm, IReadOnlyList<DexLevel> chain, GameVersion gameSource = GameVersion.Any)
{
if (GetIsFromGB(pkm))
return GetValidEncounterTradesVC(pkm, chain, gameSource);
int lvl = IsNotTrade(pkm);
if (lvl <= 0)
int lang = pkm.Language;
if (lang == (int)LanguageID.UNUSED_6) // invalid language
return Array.Empty<EncounterTrade>();
if (lang == (int)LanguageID.Hacked && !IsValidMissingLanguage(pkm)) // Japanese trades in BW have no language ID
return Array.Empty<EncounterTrade>();
var poss = GetPossibleNonVC(pkm, chain, gameSource);
return GetValidEncounterTrades(pkm, chain, poss, lvl);
return GetValidEncounterTrades(pkm, chain, poss);
}
private static IEnumerable<EncounterTrade> GetValidEncounterTrades(PKM pkm, IReadOnlyList<DexLevel> chain, IEnumerable<EncounterTrade> poss, int lvl)
private static IEnumerable<EncounterTrade> GetValidEncounterTrades(PKM pkm, IReadOnlyList<DexLevel> chain, IEnumerable<EncounterTrade> poss)
{
foreach (var p in poss)
{
@ -50,7 +40,7 @@ namespace PKHeX.Core
{
if (evo.Species != p.Species)
continue;
if (p.IsMatch(pkm, evo, lvl))
if (p.IsMatch(pkm, evo))
yield return p;
break;
}
@ -105,16 +95,5 @@ namespace PKHeX.Core
}
private static bool GetIsFromGB(PKM pkm) => pkm.VC || pkm.Format <= 2;
private static int IsNotTrade(PKM pkm)
{
int lang = pkm.Language;
if (lang == (int)LanguageID.UNUSED_6) // invalid language
return 0;
if (lang == (int)LanguageID.Hacked && !IsValidMissingLanguage(pkm)) // Japanese trades in BW have no language ID
return 0;
return GetMaxLevelEncounter(pkm);
}
}
}

View file

@ -7,12 +7,6 @@ namespace PKHeX.Core
{
public static class MysteryGiftGenerator
{
public static IEnumerable<MysteryGift> GetPossible(PKM pkm)
{
var chain = EvolutionChain.GetOriginChain(pkm);
return GetPossible(pkm, chain);
}
public static IEnumerable<MysteryGift> GetPossible(PKM pkm, IReadOnlyList<DexLevel> chain)
{
// Ranger Manaphy is a PGT and is not in the PCD[] for gen4. Check manually.
@ -26,16 +20,16 @@ namespace PKHeX.Core
yield return enc;
}
public static IEnumerable<MysteryGift> GetValidGifts(PKM pkm)
public static IEnumerable<MysteryGift> GetValidGifts(PKM pkm, IReadOnlyList<DexLevel> chain)
{
int gen = pkm.GenNumber;
if (pkm.IsEgg && pkm.Format != gen) // transferred
return Array.Empty<MysteryGift>();
if (gen == 4) // check for Manaphy gift
return GetMatchingPCD(pkm, MGDB_G4);
return GetMatchingPCD(pkm, MGDB_G4, chain);
var table = GetTable(gen, pkm);
return GetMatchingGifts(pkm, table);
return GetMatchingGifts(pkm, table, chain);
}
private static IReadOnlyList<MysteryGift> GetTable(int generation, PKM pkm)
@ -52,7 +46,7 @@ namespace PKHeX.Core
};
}
private static IEnumerable<MysteryGift> GetMatchingPCD(PKM pkm, IReadOnlyList<PCD> DB)
private static IEnumerable<MysteryGift> GetMatchingPCD(PKM pkm, IReadOnlyList<PCD> DB, IReadOnlyList<DexLevel> chain)
{
if (PGT.IsRangerManaphy(pkm))
{
@ -60,16 +54,10 @@ namespace PKHeX.Core
yield break;
}
foreach (var g in GetMatchingGifts(pkm, DB))
foreach (var g in GetMatchingGifts(pkm, DB, chain))
yield return g;
}
private static IEnumerable<MysteryGift> GetMatchingGifts(PKM pkm, IReadOnlyList<MysteryGift> DB)
{
var chain = EvolutionChain.GetOriginChain(pkm);
return GetMatchingGifts(pkm, DB, chain);
}
private static IEnumerable<MysteryGift> GetMatchingGifts(PKM pkm, IReadOnlyList<MysteryGift> DB, IReadOnlyList<DexLevel> chain)
{
var deferred = new List<MysteryGift>();

View file

@ -30,7 +30,7 @@ namespace PKHeX.Core
{
EncounterEgg _ => VerifyEncounterEgg(pkm),
EncounterTrade t => VerifyEncounterTrade(pkm, t),
EncounterSlot w => VerifyEncounterWild(pkm, w),
EncounterSlot w => VerifyEncounterWild(w),
EncounterStatic s => VerifyEncounterStatic(pkm, s),
MysteryGift g => VerifyEncounterEvent(pkm, g),
_ => new CheckResult(Severity.Invalid, LEncInvalid, CheckIdentifier.Encounter)
@ -255,10 +255,10 @@ namespace PKHeX.Core
}
// Other
private static CheckResult VerifyEncounterWild(PKM pkm, EncounterSlot slot)
private static CheckResult VerifyEncounterWild(EncounterSlot slot)
{
// Check for Unreleased Encounters / Collisions
switch (pkm.GenNumber)
switch (slot.Generation)
{
case 4:
if (slot.Location == 193 && slot.Type == SlotType.Surf) // surfing in Johto Route 45
@ -266,33 +266,8 @@ namespace PKHeX.Core
break;
}
if (slot.Permissions.IsNormalLead)
{
return slot.Permissions.Pressure
? new CheckResult(Severity.Valid, LEncConditionLead, CheckIdentifier.Encounter)
: new CheckResult(Severity.Valid, LEncCondition, CheckIdentifier.Encounter);
}
// Decreased Level Encounters
if (slot.Permissions.WhiteFlute)
{
return slot.Permissions.Pressure
? new CheckResult(Severity.Valid, LEncConditionWhiteLead, CheckIdentifier.Encounter)
: new CheckResult(Severity.Valid, LEncConditionWhite, CheckIdentifier.Encounter);
}
// Increased Level Encounters
if (slot.Permissions.BlackFlute)
{
return slot.Permissions.Pressure
? new CheckResult(Severity.Valid, LEncConditionBlackLead, CheckIdentifier.Encounter)
: new CheckResult(Severity.Valid, LEncConditionBlack, CheckIdentifier.Encounter);
}
if (slot.Permissions.Pressure)
return new CheckResult(Severity.Valid, LEncConditionLead, CheckIdentifier.Encounter);
return new CheckResult(Severity.Valid, LEncConditionDexNav, CheckIdentifier.Encounter);
var summary = slot.GetConditionString(out bool valid);
return new CheckResult(valid ? Severity.Valid : Severity.Invalid, summary, CheckIdentifier.Encounter);
}
private static CheckResult VerifyEncounterStatic(PKM pkm, EncounterStatic s)

View file

@ -50,21 +50,5 @@ namespace PKHeX.Core
return true;
}
public static bool IsEvolvedChangedFormValid(int species, int currentForm, int originalForm)
{
switch (currentForm)
{
case 0 when Legal.GalarForm0Evolutions.TryGetValue(species, out var val):
return originalForm == val;
case 1 when Legal.AlolanVariantEvolutions12.Contains(species):
case 1 when Legal.GalarVariantFormEvolutions.Contains(species):
return originalForm == 0;
case 2 when species == (int)Species.Darmanitan:
return originalForm == 1;
default:
return false;
}
}
}
}

View file

@ -177,8 +177,6 @@ namespace PKHeX.Core
{
var res = new CheckMoveResult[4];
var G1Encounter = info.EncounterMatch;
if (G1Encounter == null)
return ParseMovesSpecialMoveset(pkm, currentMoves, info);
var InitialMoves = Array.Empty<int>();
var SpecialMoves = GetSpecialMoves(info.EncounterMatch);
var games = info.EncounterMatch.Generation == 1 ? GBRestrictions.GetGen1Versions(info) : GBRestrictions.GetGen2Versions(info, pkm.Korean);

View file

@ -22,7 +22,7 @@ namespace PKHeX.Core
{
IRelearn s when s.Relearn.Count > 0 => VerifyRelearnSpecifiedMoveset(pkm, info, s.Relearn),
EncounterEgg e => VerifyRelearnEggBase(pkm, info, e),
EncounterSlot z when pkm.RelearnMove1 != 0 && z.Permissions.DexNav => VerifyRelearnDexNav(pkm, info),
EncounterSlot6AO z when pkm.RelearnMove1 != 0 && z.DexNav => VerifyRelearnDexNav(pkm, info),
_ => VerifyRelearnNone(pkm, info)
};
}

View file

@ -0,0 +1,183 @@
using System;
using System.Collections.Generic;
using System.Linq;
using static PKHeX.Core.Species;
namespace PKHeX.Core
{
/// <summary>
/// Contains logic that calculates the evolution chain of a <see cref="PKM"/>, only considering the generation it originated in.
/// </summary>
public static class EncounterOrigin
{
/// <summary>
/// Gets possible evolution details for the input <see cref="pkm"/>
/// </summary>
/// <param name="pkm">Current state of the Pokémon</param>
/// <returns>Possible origin species-form-levels to match against encounter data.</returns>
/// <remarks>Use <see cref="GetOriginChain12"/> if the <see cref="pkm"/> originated from Generation 1 or 2.</remarks>
public static IReadOnlyList<EvoCriteria> GetOriginChain(PKM pkm)
{
bool hasOriginMet = pkm.HasOriginalMetLocation;
var maxLevel = GetLevelOriginMax(pkm, hasOriginMet);
var minLevel = GetLevelOriginMin(pkm, hasOriginMet);
return GetOriginChain(pkm, -1, maxLevel, minLevel, hasOriginMet);
}
/// <summary>
/// Gets possible evolution details for the input <see cref="pkm"/> originating from Generation 1 or 2.
/// </summary>
/// <param name="pkm">Current state of the Pokémon</param>
/// <param name="gameSource">Game/group the <see cref="pkm"/> originated from. If <see cref="GameVersion.RBY"/>, it assumes Gen 1, otherwise Gen 2.</param>
/// <returns>Possible origin species-form-levels to match against encounter data.</returns>
public static IReadOnlyList<EvoCriteria> GetOriginChain12(PKM pkm, GameVersion gameSource)
{
bool rby = gameSource == GameVersion.RBY;
var maxSpecies = rby ? Legal.MaxSpeciesID_1 : Legal.MaxSpeciesID_2;
bool hasOriginMet;
int maxLevel, minLevel;
if (pkm is PK2 pk2)
{
hasOriginMet = pk2.CaughtData != 0;
maxLevel = rby && Future_LevelUp2.Contains(pk2.Species) ? pkm.CurrentLevel - 1 : pkm.CurrentLevel;
minLevel = !hasOriginMet ? 2 : pkm.IsEgg ? 5 : pkm.Met_Level;
}
else if (pkm is PK1 pk1)
{
hasOriginMet = false;
maxLevel = pk1.CurrentLevel;
minLevel = 2;
}
else if (rby)
{
hasOriginMet = false;
maxLevel = Future_LevelUp2.Contains(pkm.Species) ? pkm.CurrentLevel - 1 : GetLevelOriginMaxTransfer(pkm, pkm.Met_Level, 1);
minLevel = 2;
}
else // GSC
{
hasOriginMet = false;
maxLevel = GetLevelOriginMaxTransfer(pkm, pkm.Met_Level, 2);
minLevel = 2;
}
return GetOriginChain(pkm, maxSpecies, maxLevel, minLevel, hasOriginMet);
}
private static IReadOnlyList<EvoCriteria> GetOriginChain(PKM pkm, int maxSpecies, int maxLevel, int minLevel, bool hasOriginMet)
{
if (maxLevel < minLevel)
return Array.Empty<EvoCriteria>();
if (hasOriginMet)
return EvolutionChain.GetValidPreEvolutions(pkm, maxSpecies, maxLevel, minLevel);
// Permit the maximum to be all the way up to Current Level; we'll trim these impossible evolutions out later.
var tempMax = pkm.CurrentLevel;
var chain = EvolutionChain.GetValidPreEvolutions(pkm, maxSpecies, tempMax, minLevel);
for (int i = chain.Count - 1; i >= 0; i--)
{
var evo = chain[i];
if (evo.MinLevel > maxLevel)
{
chain.RemoveAt(i);
if (chain.Any(z => z.Level >= maxLevel))
continue;
chain.Clear();
break;
}
if (evo.Level > maxLevel)
evo.Level = maxLevel;
}
return chain;
}
private static int GetLevelOriginMin(PKM pkm, bool hasMet)
{
if (pkm.Format == 3)
{
if (pkm.IsEgg)
return 5;
return Math.Max(2, pkm.Met_Level);
}
if (!hasMet)
return 1;
return Math.Max(1, pkm.Met_Level);
}
private static int GetLevelOriginMax(PKM pkm, bool hasMet)
{
var met = pkm.Met_Level;
if (hasMet)
return pkm.CurrentLevel;
int generation = pkm.GenNumber;
if (generation >= 4)
return met;
return GetLevelOriginMaxTransfer(pkm, met, generation);
}
private static int GetLevelOriginMaxTransfer(PKM pkm, int met, int generation)
{
var species = pkm.Species;
if (Future_LevelUp.TryGetValue(species | (pkm.AltForm << 11), out var delta))
return met - delta;
if (generation < 4 && Future_LevelUp4.Contains(species))
return met - 1;
return met;
}
/// <summary>
/// Species introduced in Generation 2 that require a level up to evolve into from a specimen that originated in a previous generation.
/// </summary>
private static readonly HashSet<int> Future_LevelUp2 = new HashSet<int>
{
(int)Crobat,
(int)Espeon,
(int)Umbreon,
(int)Blissey,
};
/// <summary>
/// Species introduced in Generation 4 that require a level up to evolve into from a specimen that originated in a previous generation.
/// </summary>
private static readonly HashSet<int> Future_LevelUp4 = new HashSet<int>
{
(int)Ambipom,
(int)Weavile,
(int)Magnezone,
(int)Lickilicky,
(int)Tangrowth,
(int)Yanmega,
(int)Leafeon,
(int)Glaceon,
(int)Mamoswine,
(int)Gliscor,
(int)Probopass,
};
/// <summary>
/// Species introduced in Generation 6+ that require a level up to evolve into from a specimen that originated in a previous generation.
/// </summary>
private static readonly Dictionary<int, int> Future_LevelUp = new Dictionary<int, int>
{
// Gen6
{(int)Sylveon, 1},
// Gen7
{(int)Marowak | (1 << 11), 1},
// Gen8
{(int)Weezing | (1 << 11), 1},
{(int)MrMime | (1 << 11), 1},
{(int)MrRime, 2},
};
}
}

View file

@ -234,37 +234,6 @@ namespace PKHeX.Core
}
}
internal static List<EvoCriteria> GetOriginChain(PKM pkm, GameVersion gameSource)
{
var max = GetMaxSpecies(gameSource);
return GetOriginChain(pkm, maxspeciesorigin: max);
}
private static int GetMaxSpecies(GameVersion gameSource)
{
if (gameSource == GameVersion.RBY)
return MaxSpeciesID_1;
if (GameVersion.GSC.Contains(gameSource))
return MaxSpeciesID_2;
return -1;
}
internal static List<EvoCriteria> GetOriginChain(PKM pkm, int maxspeciesorigin = -1, int lvl = -1, int minLevel = 1, bool skipChecks = false)
{
var chain = GetValidPreEvolutions(pkm, maxspeciesorigin, lvl, minLevel, skipChecks);
if (!pkm.HasOriginalMetLocation)
{
var maxLevel = Legal.GetMaxLevelEncounter(pkm);
if (maxLevel < 0)
{
chain.Clear();
return chain;
}
foreach (var c in chain)
c.Level = Math.Min(maxLevel, c.Level);
}
return chain;
}
internal static List<EvoCriteria> GetValidPreEvolutions(PKM pkm, int maxspeciesorigin = -1, int maxLevel = -1, int minLevel = 1, bool skipChecks = false)
{

View file

@ -213,12 +213,12 @@ namespace PKHeX.Core
}
// Shedinja's evolution case can be a little tricky; hard-code handling.
if (pkm.Species == (int)Species.Shedinja && maxLevel >= 20 && (!pkm.HasOriginalMetLocation || pkm.Met_Level + 1 <= maxLevel))
if (pkm.Species == (int)Species.Shedinja && maxLevel >= 20 && (!pkm.HasOriginalMetLocation || minLevel < maxLevel))
{
return new List<EvoCriteria>(2)
{
new EvoCriteria((int)Species.Shedinja, 0) { Level = maxLevel, MinLevel = 20 },
new EvoCriteria((int)Species.Nincada, 0) { Level = maxLevel, MinLevel = 1 },
new EvoCriteria((int)Species.Nincada, 0) { Level = maxLevel, MinLevel = minLevel },
};
}

View file

@ -40,7 +40,7 @@
/// <param name="slot">Slot Data</param>
/// <param name="pkm">Ancillary pkm data for determining how to check level.</param>
/// <returns>Slot number for this frame &amp; lead value.</returns>
public bool IsSlotCompatibile(EncounterSlot slot, PKM pkm)
public bool IsSlotCompatibile<T>(T slot, PKM pkm) where T : EncounterSlot, IMagnetStatic, INumberedSlot
{
bool usesLevel = !slot.FixedLevel;
if (FrameType != FrameType.MethodH && (Lead & LeadRequired.UsesLevelCall) != 0 != usesLevel)
@ -74,7 +74,7 @@
/// </summary>
/// <param name="slot">Slot Data</param>
/// <returns>Slot number for this frame &amp; lead value.</returns>
private int GetSlot(EncounterSlot slot)
private int GetSlot<T>(T slot) where T : EncounterSlot, IMagnetStatic, INumberedSlot
{
// Static and Magnet Pull do a slot search rather than slot mapping 0-99.
return Lead != LeadRequired.StaticMagnet

View file

@ -188,18 +188,18 @@ namespace PKHeX.Core
/// <param name="slot">Slot Data</param>
/// <param name="ESV">Rand16 value for the call</param>
/// <returns>Slot number from the slot data if the slot is selected on this frame, else an invalid slot value.</returns>
internal static int GetSlotStaticMagnet(EncounterSlot slot, uint ESV)
internal static int GetSlotStaticMagnet<T>(T slot, uint ESV) where T : EncounterSlot, IMagnetStatic, INumberedSlot
{
if (slot.Permissions.StaticIndex >= 0)
if (slot.StaticCount > 0 && slot.StaticIndex >= 0)
{
var index = ESV % slot.Permissions.StaticCount;
if (index == slot.Permissions.StaticIndex)
var index = ESV % slot.StaticCount;
if (index == slot.StaticIndex)
return slot.SlotNumber;
}
if (slot.Permissions.MagnetPullIndex >= 0)
if (slot.MagnetPullCount > 0 && slot.MagnetPullIndex >= 0)
{
var index = ESV % slot.Permissions.MagnetPullCount;
if (index == slot.Permissions.MagnetPullIndex)
var index = ESV % slot.MagnetPullCount;
if (index == slot.MagnetPullIndex)
return slot.SlotNumber;
}
return -1;

View file

@ -818,7 +818,7 @@ namespace PKHeX.Core
return true;
// forced shiny eggs, when hatched, can lose their detectable correlation.
return g.IsEgg && !pkm.IsEgg && val == PIDType.None && (g.Method == PIDType.BACD_R_S || g.Method == PIDType.BACD_U_S);
case EncounterStatic s:
case EncounterStatic3 s:
switch (pkm.Version)
{
case (int)GameVersion.CXD: return val == PIDType.CXD || val == PIDType.CXD_ColoStarter || val == PIDType.CXDAnti;
@ -864,7 +864,7 @@ namespace PKHeX.Core
if (val == PIDType.CuteCharm && IsCuteCharm4Valid(encounter, pkm))
return true;
return val == PIDType.Method_1;
case EncounterSlot sl:
case EncounterSlot4 sl:
if (val == PIDType.Method_1)
return true;
if (val == PIDType.CuteCharm && IsCuteCharm4Valid(encounter, pkm))

View file

@ -16,11 +16,12 @@ namespace PKHeX.Core
public static readonly HashSet<int> LightBall = new HashSet<int> { 25, 26, 172 };
public static readonly int[] RotomMoves = { 0, 315, 056, 059, 403, 437 };
public static readonly HashSet<int> WildForms = new HashSet<int>
public static readonly HashSet<int> WildChangeFormAfter = new HashSet<int>
{
422, 423, // Shellos
550, // Basculin
669, 670, 671 // Flabébé
412, // Burmy
479, // Rotom
676, // Furfrou
741, // Oricorio
};
public static readonly HashSet<int> SplitBreed = new HashSet<int>
@ -37,12 +38,9 @@ namespace PKHeX.Core
358, // Chimecho
};
public static readonly HashSet<int> FormChange = new HashSet<int> // Pokémon that can change form and retain it
public static readonly HashSet<int> FormChange = new HashSet<int>(WildChangeFormAfter) // Pokémon that can change between all forms
{
386, // Deoxys
412, // Burmy
421, // Cherrim
479, // Rotom
487, // Giratina
492, // Shaymin
493, // Arceus
@ -52,13 +50,9 @@ namespace PKHeX.Core
646, // Kyurem
647, // Keldeo
649, // Genesect
676, // Furfrou
720, // Hoopa
741, // Oricorio
773, // Silvally
800, // Necrozma
891, // Urshifu
};
public static readonly HashSet<int> FormChangeMoves = new HashSet<int>
@ -335,6 +329,7 @@ namespace PKHeX.Core
473, // Mamoswine (Piloswine with Ancient Power)
700, // Sylveon (Eevee with Fairy Move)
763, // Tsareena (Steenee with Stomp)
(int)Species.Grapploct // (Clobbopus with Taunt)
};
internal static readonly int[] FairyMoves =
@ -362,6 +357,13 @@ namespace PKHeX.Core
698, // Guardian of Alola
705, // Fleur Cannon
717, // Nature's Madness
726, // Let's Snuggle Forever
740, // Sparkly Swirl
767, // Max Starfall
777, // Decorate
789, // Spirit Break
790, // Strange Steam
802, // Misty Explosion
};
// Moves that trigger the evolution by move
@ -376,6 +378,7 @@ namespace PKHeX.Core
new [] { 246 }, // Mamoswine (Piloswine with Ancient Power)
FairyMoves, // Sylveon (Eevee with Fairy Move)
new [] { 023 }, // Tsareena (Steenee with Stomp)
new [] { 269 }, // Grapploct (Clobbopus with Taunt)
};
// Min level for any species for every generation to learn the move for evolution by move
@ -400,6 +403,8 @@ namespace PKHeX.Core
new [] { 0, 0, 0, 0, 0, 29, 9, 2, 2 },
// Tsareena (Steenee with Stomp)
new [] { 0, 0, 0, 0, 0, 0, 0, 2, 28 },
// Grapploct (Clobbopus with Taunt)
new [] { 0, 0, 0, 0, 0, 0, 0, 0, 35 },
};
// True -> the pokemon could hatch from an egg with the move for evolution as an egg move
@ -423,6 +428,8 @@ namespace PKHeX.Core
new [] { false, false, true, true, true, true, true, true, true },
// Tsareena (Steenee with Stomp)
new [] { false, false, false, false, false, false, false, false, false },
// Grapploct (Clobbopus with Taunt)
new [] { false, false, false, false, false, false, false, false, true },
};
internal static readonly HashSet<int> MixedGenderBreeding = new HashSet<int>

View file

@ -61,11 +61,5 @@ namespace PKHeX.Core
{
169,182,186,196,197,199,208,212,230,233,242,462,463,464,465,466,467,470,471,474,700
};
internal static readonly HashSet<int> FutureEvolutionsGen1_Gen2LevelUp = new HashSet<int>
{
// Crobat Espeon Umbreon Blissey
169,196,197,242
};
}
}

View file

@ -110,13 +110,6 @@ namespace PKHeX.Core
407,424,429,430,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,478,700
};
internal static readonly HashSet<int> FutureEvolutionsGen3_LevelUpGen4 = new HashSet<int>
{
// Ambipom Weavile Magnezone Lickilicky Tangrowth
// Yanmega Leafeon Glaceon Mamoswine Gliscor Probopass
424, 461, 462, 463, 465, 469, 470, 471, 472, 473, 476
};
internal static readonly int[] UnreleasedItems_3 =
{
005, // Safari Ball

View file

@ -115,7 +115,7 @@ namespace PKHeX.Core
internal static readonly int[] FutureEvolutionsGen5 =
{
700
(int)Species.Sylveon,
};
internal static readonly HashSet<int> UnreleasedItems_5 = new HashSet<int>

View file

@ -279,8 +279,6 @@ namespace PKHeX.Core
{(int)Species.Cursola, 1},
};
internal static readonly HashSet<int> EvolveToGalarForms = new HashSet<int>(GalarVariantFormEvolutions.Concat(GalarOriginForms));
internal static readonly int[] EggLocations8 = {Locations.Daycare5, Locations.LinkTrade6};
internal static readonly HashSet<int> ValidMet_SWSH = new HashSet<int>

View file

@ -275,7 +275,7 @@ namespace PKHeX.Core
var EncounterMatch = data.EncounterMatch;
if (EncounterMatch is EncounterSlot slot)
{
bool valid = slot.Permissions.DexNav || slot.Type == SlotType.FriendSafari || slot.Type == SlotType.Horde;
bool valid = (slot is EncounterSlot6AO ao && ao.DexNav) || slot.Type == SlotType.FriendSafari || slot.Type == SlotType.Horde;
if (!valid)
return GetInvalid(LAbilityMismatchHordeSafari);
}

View file

@ -20,15 +20,15 @@ namespace PKHeX.Core
{
// Encounter type data is only stored for gen 4 encounters
// All eggs have encounter type none, even if they are from static encounters
if (!pkm.Gen4 || pkm.Egg_Location != 0)
if (enc.Generation != 4 || pkm.Egg_Location != 0)
return EncounterType.None;
if (enc is EncounterSlot w)
return w.TypeEncounter;
if (enc is EncounterStaticTyped s)
return s.TypeEncounter;
return EncounterType.None;
return enc switch
{
EncounterSlot4 w => w.TypeEncounter,
EncounterStaticTyped s => s.TypeEncounter,
_ => EncounterType.None
};
}
}
}

View file

@ -24,19 +24,6 @@ namespace PKHeX.Core
if (pkm.Nature >= 25) // out of range
data.AddLine(GetInvalid(LPIDNatureMismatch));
var Info = data.Info;
if ((Info.Generation >= 6 || (Info.Generation < 3 && pkm.Format >= 7)) && pkm.PID == pkm.EncryptionConstant)
{
if (Info.EncounterMatch is WC8 wc8 && wc8.PID == 0 &&wc8.EncryptionConstant == 0)
{
// We'll allow this to pass.
}
else
{
data.AddLine(GetInvalid(LPIDEqualsEC)); // better to flag than 1:2^32 odds since RNG is not feasible to yield match
}
}
VerifyShiny(data);
}
@ -51,14 +38,20 @@ namespace PKHeX.Core
if (!s.Shiny.IsValid(pkm))
data.AddLine(GetInvalid(LEncStaticPIDShiny, CheckIdentifier.Shiny));
// gen5 correlation
if (Info.Generation != 5)
if (s.Generation != 5)
break;
// Generation 5 has a correlation for wild captures.
// Certain static encounter types are just generated straightforwardly.
if (s.Location == 75) // Entree Forest
break;
if (s.Gift || s.Roaming || s.Ability != 4)
// Not wild / forced ability
if (s.Gift || s.Ability == 4)
break;
if (s is EncounterStatic5N)
// Forced PID or generated without an encounter
if (s is EncounterStatic5N || (s is EncounterStatic5 s5 && s5.Roaming) || s.Shiny == Shiny.Never)
break;
VerifyG5PID_IDCorrelation(data);
break;
@ -98,7 +91,8 @@ namespace PKHeX.Core
{
// Indicate what it will evolve into
uint evoVal = WurmpleUtil.GetWurmpleEvoVal(pkm.EncryptionConstant);
var spec = evoVal == 0 ? LegalityAnalysis.SpeciesStrings[267] : LegalityAnalysis.SpeciesStrings[269];
var evolvesTo = evoVal == 0 ? (int)Species.Beautifly : (int)Species.Dustox;
var spec = LegalityAnalysis.SpeciesStrings[evolvesTo];
var msg = string.Format(L_XWurmpleEvo_0, spec);
data.AddLine(GetValid(msg, CheckIdentifier.EC));
}
@ -114,16 +108,31 @@ namespace PKHeX.Core
var Info = data.Info;
if (pkm.EncryptionConstant == 0)
{
if (Info.EncounterMatch is WC8 wc8 && wc8.PID == 0 && wc8.EncryptionConstant == 0)
return; // HOME Gifts
data.AddLine(Get(LPIDEncryptZero, Severity.Fishy, CheckIdentifier.EC));
}
// Gen3-5 => Gen6 have PID==EC with an edge case exception.
if (3 <= Info.Generation && Info.Generation <= 5)
{
VerifyTransferEC(data);
return;
}
else
// Gen1-2, Gen6+ should have PID != EC
if (pkm.PID == pkm.EncryptionConstant)
{
data.AddLine(GetInvalid(LPIDEqualsEC)); // better to flag than 1:2^32 odds since RNG is not feasible to yield match
return;
}
// Check for Gen3-5 => Gen6 edge case being incorrectly applied here.
if ((pkm.PID ^ 0x80000000) == pkm.EncryptionConstant)
{
int xor = pkm.TSV ^ pkm.PSV;
if (xor < 16 && xor >= 8 && (pkm.PID ^ 0x80000000) == pkm.EncryptionConstant)
if (xor >> 3 == 1) // 8 <= x <= 15
data.AddLine(Get(LTransferPIDECXor, Severity.Fishy, CheckIdentifier.EC));
}
}

View file

@ -466,7 +466,7 @@ namespace PKHeX.Core
var sb = set2.RibbonBits();
var eb = encounterContent is IRibbonSetEvent4 e4 ? e4.RibbonBits() : new bool[sb.Length];
if (encounterContent is EncounterStatic s && s.RibbonWishing)
if (encounterContent is EncounterStatic7 s && s.RibbonWishing)
eb[1] = true; // require Wishing Ribbon
for (int i = 0; i < sb.Length; i++)

View file

@ -161,7 +161,7 @@ namespace PKHeX.Core
return false;
}
if (wc.AltForm != evo.Form && !Legal.IsFormChangeable(pkm, Species, wc.AltForm))
if (wc.AltForm != evo.Form && !Legal.IsFormChangeable(wc.Species, wc.AltForm, pkm.Format))
return false;
if (wc.Ball != pkm.Ball) return false;

View file

@ -369,7 +369,7 @@ namespace PKHeX.Core
return false;
}
if (Form != evo.Form && !Legal.IsFormChangeable(pkm, Species, Form))
if (Form != evo.Form && !Legal.IsFormChangeable(Species, Form, pkm.Format))
return false;
if (Level != pkm.Met_Level) return false;

View file

@ -471,7 +471,7 @@ namespace PKHeX.Core
if (EncryptionConstant != 0 && EncryptionConstant != pkm.EncryptionConstant) return false;
}
if (Form != evo.Form && !Legal.IsFormChangeable(pkm, Species, Form))
if (Form != evo.Form && !Legal.IsFormChangeable(Species, Form, pkm.Format))
return false;
if (IsEgg)

View file

@ -238,7 +238,7 @@ namespace PKHeX.Core
}
}
if (Form != evo.Form && !Legal.IsFormChangeable(pkm, Species, Form))
if (Form != evo.Form && !Legal.IsFormChangeable(Species, Form, pkm.Format))
return false;
if (Language != -1 && Language != pkm.Language) return false;

View file

@ -487,7 +487,7 @@ namespace PKHeX.Core
if (EncryptionConstant != 0 && EncryptionConstant != pkm.EncryptionConstant) return false;
if (Language != 0 && Language != pkm.Language) return false;
}
if (Form != evo.Form && !Legal.IsFormChangeable(pkm, Species, Form))
if (Form != evo.Form && !Legal.IsFormChangeable(Species, Form, pkm.Format))
return false;
if (IsEgg)

View file

@ -518,7 +518,7 @@ namespace PKHeX.Core
if (Language != 0 && Language != pkm.Language) return false;
}
if (Form != evo.Form && !Legal.IsFormChangeable(pkm, Species, Form))
if (Form != evo.Form && !Legal.IsFormChangeable(Species, Form, pkm.Format))
return false;
if (IsEgg)

View file

@ -557,7 +557,7 @@ namespace PKHeX.Core
}
}
if (Form != pkm.AltForm && !Legal.IsFormChangeable(pkm, Species, Form))
if (Form != pkm.AltForm && !Legal.IsFormChangeable(Species, Form, pkm.Format))
return false;
if (IsEgg)

View file

@ -67,7 +67,9 @@ namespace PKHeX.Tests.Legality
var fn = Path.Combine(fi.Directory.Name, fi.Name);
if (isValid)
{
var invalid = legality.Results.Where(z => !z.Valid);
var info = legality.Info;
var result = legality.Results.Concat(info.Moves).Concat(info.Relearn);
var invalid = result.Where(z => !z.Valid);
var msg = string.Join(Environment.NewLine, invalid.Select(z => z.Comment));
legality.Valid.Should().BeTrue($"because the file '{fn}' should be Valid, but found:{Environment.NewLine}{msg}");
}