mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-09-13 19:56:01 -05:00
More generator updates
all the way up to nidorina extract some reusable methods exclude invalid headbutt encounters use built in randomgender
This commit is contained in:
@@ -2191,9 +2191,15 @@ internal static bool IsOutsider(PKM pkm)
|
||||
return Outsider;
|
||||
}
|
||||
|
||||
internal static TreesArea GetCrystalTreeArea(EncounterSlot Slot)
|
||||
internal static TreeEncounterAvailable GetGSCHeadbuttAvailability(EncounterSlot encounter, int TID)
|
||||
{
|
||||
return HeadbuttTreesC.FirstOrDefault(a => a.Location == Slot.Location);
|
||||
var Area = HeadbuttTreesC.FirstOrDefault(a => a.Location == encounter.Location);
|
||||
if (Area == null) // Failsafe, every area with headbutt encounters has a tree area
|
||||
return TreeEncounterAvailable.Impossible;
|
||||
|
||||
var table = Area.GetTrees(encounter.Type);
|
||||
var trainerpivot = TID % 10;
|
||||
return table[trainerpivot];
|
||||
}
|
||||
|
||||
public static int[] GetEncounterMoves(PKM pk, int level, GameVersion version)
|
||||
|
||||
@@ -250,19 +250,19 @@ private static EncounterArea[] GetSlots_C(EncounterArea[] f)
|
||||
|
||||
internal static readonly EncounterTrade[] TradeGift_GSC =
|
||||
{
|
||||
new EncounterTrade { Species = 095, Level = 03, Location = 126, Gender = 0, TID = 48926, IVs = new[] {08, 09, 06, 06, 06, 06} }, // Onix @ Violet City for Bellsprout [wild]
|
||||
new EncounterTrade { Species = 066, Level = 05, Location = 126, Gender = 1, TID = 37460, IVs = new[] {12, 03, 07, 06, 06, 06} }, // Machop @ Goldenrod City for Drowzee [wild 9, hatched egg 5]
|
||||
new EncounterTrade { Species = 100, Level = 05, Location = 126, Gender = 2, TID = 29189, IVs = new[] {08, 09, 08, 08, 08, 08} }, // Voltorb @ Olivine City for Krabby [egg]
|
||||
new EncounterTrade { Species = 112, Level = 10, Location = 126, Gender = 1, TID = 00283, IVs = new[] {12, 07, 07, 06, 06, 06} }, // Rhydon @ Blackthorn City for Dragonair [wild]
|
||||
new EncounterTrade { Species = 142, Level = 05, Location = 126, Gender = 0, TID = 26491, IVs = new[] {08, 09, 06, 06, 06, 06} }, // Aerodactyl @ Route 14 for Chansey [egg]
|
||||
new EncounterTrade { Species = 078, Level = 14, Location = 126, Gender = 0, TID = 15616, IVs = new[] {08, 09, 06, 06, 06, 06} }, // Rapidash @ Pewter City for Gloom [wild]
|
||||
new EncounterTrade { Species = 095, Level = 03, Gender = 0, TID = 48926, IVs = new[] {08, 09, 06, 06, 06, 06} }, // Onix @ Violet City for Bellsprout [wild]
|
||||
new EncounterTrade { Species = 066, Level = 05, Gender = 1, TID = 37460, IVs = new[] {12, 03, 07, 06, 06, 06} }, // Machop @ Goldenrod City for Drowzee [wild 9, hatched egg 5]
|
||||
new EncounterTrade { Species = 100, Level = 05, Gender = 2, TID = 29189, IVs = new[] {08, 09, 08, 08, 08, 08} }, // Voltorb @ Olivine City for Krabby [egg]
|
||||
new EncounterTrade { Species = 112, Level = 10, Gender = 1, TID = 00283, IVs = new[] {12, 07, 07, 06, 06, 06} }, // Rhydon @ Blackthorn City for Dragonair [wild]
|
||||
new EncounterTrade { Species = 142, Level = 05, Gender = 0, TID = 26491, IVs = new[] {08, 09, 06, 06, 06, 06} }, // Aerodactyl @ Route 14 for Chansey [egg]
|
||||
new EncounterTrade { Species = 078, Level = 14, Gender = 0, TID = 15616, IVs = new[] {08, 09, 06, 06, 06, 06} }, // Rapidash @ Pewter City for Gloom [wild]
|
||||
|
||||
new EncounterTrade { Species = 085, Level = 10, Location = 126, Gender = 1, TID = 00283, IVs = new[] {12, 07, 07, 06, 06, 06} }, // Dodrio @ Blackthorn City for Dragonair [wild]
|
||||
new EncounterTrade { Species = 178, Level = 15, Location = 126, Gender = 0, TID = 15616, IVs = new[] {08, 09, 06, 08, 06, 06} }, // Xatu @ Pewter City for Haunter [wild]
|
||||
new EncounterTrade { Species = 082, Level = 05, Location = 126, Gender = 2, TID = 50082, IVs = new[] {08, 09, 06, 06, 06, 06} }, // Magneton @ Power Plant for Dugtrio [traded for Lickitung]
|
||||
new EncounterTrade { Species = 085, Level = 10, Gender = 1, TID = 00283, IVs = new[] {12, 07, 07, 06, 06, 06} }, // Dodrio @ Blackthorn City for Dragonair [wild]
|
||||
new EncounterTrade { Species = 178, Level = 15, Gender = 0, TID = 15616, IVs = new[] {08, 09, 06, 08, 06, 06} }, // Xatu @ Pewter City for Haunter [wild]
|
||||
new EncounterTrade { Species = 082, Level = 05, Gender = 2, TID = 50082, IVs = new[] {08, 09, 06, 06, 06, 06} }, // Magneton @ Power Plant for Dugtrio [traded for Lickitung]
|
||||
|
||||
new EncounterTrade { Species = 021, Level = 10, Location = 126, TID = 01001, Moves = new[] {64,45,43} }, // Spearow @ Goldenrod City for free
|
||||
new EncounterTrade { Species = 213, Level = 15, Location = 126, TID = 00518 }, // Shuckle @ Cianwood City for free
|
||||
new EncounterTrade { Species = 021, Level = 10, TID = 01001, Moves = new[] {64,45,43} }, // Spearow @ Goldenrod City for free
|
||||
new EncounterTrade { Species = 213, Level = 15, TID = 00518 }, // Shuckle @ Cianwood City for free
|
||||
};
|
||||
internal static readonly string[][] TradeGift_GSC_OTs =
|
||||
{
|
||||
|
||||
@@ -79,6 +79,8 @@ byte[][] get(string resource, string ident)
|
||||
|
||||
MarkEncounterTradeStrings(TradeGift_DPPt, TradeDPPt);
|
||||
MarkEncounterTradeStrings(TradeGift_HGSS, TradeHGSS);
|
||||
foreach (var t in RanchGifts)
|
||||
t.TrainerNames = RanchOTNames;
|
||||
|
||||
DP_GreatMarshAlt.SetVersion(GameVersion.DP);
|
||||
DPPt_Unown.SetVersion(GameVersion.DPPt);
|
||||
|
||||
@@ -53,14 +53,15 @@ public PKM ConvertToPKM(ITrainerInfo SAV)
|
||||
|
||||
pk.Ball = 4;
|
||||
|
||||
int gender = Util.Rand.Next(2);
|
||||
int gender = pk.PersonalInfo.RandomGender;
|
||||
int nature = Util.Rand.Next(25);
|
||||
|
||||
gender = pk.GetSaneGender(gender);
|
||||
if (pk.Format <= 5)
|
||||
{
|
||||
pk.SetPIDGender(gender);
|
||||
pk.Gender = gender;
|
||||
pk.SetPIDNature(nature);
|
||||
pk.Nature = nature;
|
||||
pk.RefreshAbility(pk.PIDAbility);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -71,19 +71,17 @@ public PKM ConvertToPKM(ITrainerInfo SAV)
|
||||
int lang = (int)Legal.GetSafeLanguage(Generation, (LanguageID)SAV.Language);
|
||||
int level = LevelMin;
|
||||
var pk = PKMConverter.GetBlank(Generation);
|
||||
int gender = Util.Rand.Next(2);
|
||||
int nature = Util.Rand.Next(25);
|
||||
SAV.ApplyToPKM(pk);
|
||||
|
||||
pk.EncryptionConstant = Util.Rand32();
|
||||
pk.Species = Species;
|
||||
int gender = pk.PersonalInfo.RandomGender;
|
||||
pk.Language = lang;
|
||||
pk.CurrentLevel = level;
|
||||
pk.Version = (int)version;
|
||||
pk.AltForm = Form;
|
||||
pk.Nickname = PKX.GetSpeciesNameGeneration(Species, lang, Generation);
|
||||
pk.Ball = GetBall();
|
||||
gender = pk.GetSaneGender(gender);
|
||||
|
||||
if (pk.Format > 2 || Version == GameVersion.C)
|
||||
{
|
||||
@@ -97,8 +95,12 @@ public PKM ConvertToPKM(ITrainerInfo SAV)
|
||||
}
|
||||
pk.Language = lang;
|
||||
|
||||
var ability = Util.Rand.Next(0, 2);
|
||||
var pidtype = GetPIDType();
|
||||
PIDGenerator.SetRandomWildPID(pk, pk.Format, nature, Util.Rand.Next(0, 2), gender, pidtype);
|
||||
if (pidtype == PIDType.PokeSpot)
|
||||
PIDGenerator.SetRandomPokeSpotPID(pk, nature, gender, ability, SlotNumber);
|
||||
else
|
||||
PIDGenerator.SetRandomWildPID(pk, pk.Format, nature, ability, gender, pidtype);
|
||||
|
||||
if (Permissions.IsDexNav)
|
||||
{
|
||||
@@ -128,6 +130,8 @@ public PKM ConvertToPKM(ITrainerInfo SAV)
|
||||
var moves = this is EncounterSlotMoves m ? m.Moves : Legal.GetEncounterMoves(pk, level, version);
|
||||
if (pk.Format == 1 && moves.All(z => z == 0))
|
||||
moves = ((PersonalInfoG1)PersonalTable.RB[Species]).Moves;
|
||||
else if (Version == GameVersion.XD)
|
||||
pk.FatefulEncounter = true;
|
||||
pk.Moves = moves;
|
||||
pk.SetMaximumPPCurrent(moves);
|
||||
pk.OT_Friendship = pk.PersonalInfo.BaseFriendship;
|
||||
|
||||
@@ -73,13 +73,13 @@ public PKM ConvertToPKM(ITrainerInfo SAV)
|
||||
int lang = (int)Legal.GetSafeLanguage(Generation, (LanguageID)SAV.Language);
|
||||
int level = LevelMin;
|
||||
var pk = PKMConverter.GetBlank(Generation);
|
||||
int gender = Gender < 0 ? Util.Rand.Next(2) : Gender;
|
||||
int nature = Nature == Nature.Random ? Util.Rand.Next(25) : (int)Nature;
|
||||
var today = DateTime.Today;
|
||||
SAV.ApplyToPKM(pk);
|
||||
|
||||
pk.EncryptionConstant = Util.Rand32();
|
||||
pk.Species = Species;
|
||||
int gender = Gender < 0 ? pk.PersonalInfo.RandomGender : Gender;
|
||||
pk.Language = lang;
|
||||
pk.CurrentLevel = level;
|
||||
pk.Version = (int)version;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
@@ -48,8 +49,8 @@ public class EncounterTrade : IEncounterable, IMoveset, IGeneration, ILocation,
|
||||
|
||||
public string[] Nicknames { get; internal set; }
|
||||
public string[] TrainerNames { get; internal set; }
|
||||
public string GetNickname(int language) => Nicknames?.Length < language ? Nicknames[language] : null;
|
||||
public string GetOT(int language) => TrainerNames?.Length < language ? TrainerNames[language] : null;
|
||||
public string GetNickname(int language) => Nicknames?.Length > language ? Nicknames[language] : null;
|
||||
public string GetOT(int language) => TrainerNames?.Length > language ? TrainerNames[language] : null;
|
||||
|
||||
public static readonly int[] DefaultMetLocation =
|
||||
{
|
||||
@@ -61,33 +62,34 @@ public PKM ConvertToPKM(ITrainerInfo SAV)
|
||||
var version = this.GetCompatibleVersion((GameVersion)SAV.Game);
|
||||
int lang = (int)Legal.GetSafeLanguage(Generation, (LanguageID)SAV.Language);
|
||||
int level = CurrentLevel > 0 ? CurrentLevel : LevelMin;
|
||||
if (level == 0)
|
||||
level = 25; // avoid some cases
|
||||
var pk = PKMConverter.GetBlank(Generation);
|
||||
|
||||
pk.EncryptionConstant = Util.Rand32();
|
||||
pk.Species = Species;
|
||||
pk.Language = lang;
|
||||
pk.CurrentLevel = level;
|
||||
pk.Version = (int)version;
|
||||
pk.PID = Util.Rand32();
|
||||
pk.PID = this is EncounterTradePID p ? p.PID : Util.Rand32();
|
||||
pk.Ball = Ball;
|
||||
if (pk.Format != 2 || version == GameVersion.C)
|
||||
{
|
||||
pk.Met_Level = LevelMin;
|
||||
pk.Met_Location = Location;
|
||||
pk.Met_Level = level;
|
||||
pk.Met_Location = Location > 0 ? Location : DefaultMetLocation[Generation - 1];
|
||||
}
|
||||
pk.MetDate = DateTime.Today;
|
||||
|
||||
SAV.ApplyToPKM(pk);
|
||||
int nature = Nature == Nature.Random ? Util.Rand.Next(25) : (int)Nature;
|
||||
pk.Nature = nature;
|
||||
int gender = Gender < 0 ? Util.Rand.Next(2) : Gender;
|
||||
pk.Gender = pk.GetSaneGender(gender);
|
||||
pk.Version = (int)version;
|
||||
pk.Gender = Gender < 0 ? pk.PersonalInfo.RandomGender : Gender;
|
||||
pk.AltForm = Form;
|
||||
|
||||
SAV.ApplyToPKM(pk);
|
||||
pk.Language = lang;
|
||||
pk.TID = TID;
|
||||
pk.SID = SID;
|
||||
pk.OT_Name = GetOT(lang) ?? SAV.OT;
|
||||
pk.OT_Gender = GetOT(lang) != null ? OTGender : SAV.Gender;
|
||||
pk.OT_Gender = GetOT(lang) != null ? Math.Max(0, OTGender) : SAV.Gender;
|
||||
pk.SetNickname(GetNickname(lang));
|
||||
pk.Language = lang;
|
||||
|
||||
@@ -107,6 +109,8 @@ public PKM ConvertToPKM(ITrainerInfo SAV)
|
||||
this.CopyContestStatsTo(pk);
|
||||
|
||||
var moves = Moves ?? Legal.GetEncounterMoves(pk, level, version);
|
||||
if (pk.Format == 1 && moves.All(z => z == 0))
|
||||
moves = ((PersonalInfoG1)PersonalTable.RB[Species]).Moves;
|
||||
pk.Moves = moves;
|
||||
pk.SetMaximumPPCurrent(moves);
|
||||
pk.OT_Friendship = pk.PersonalInfo.BaseFriendship;
|
||||
@@ -119,7 +123,50 @@ public PKM ConvertToPKM(ITrainerInfo SAV)
|
||||
SAV.ApplyHandlingTrainerInfo(pk);
|
||||
pk.SetRandomEC();
|
||||
|
||||
if (pk.Format == 7)
|
||||
SetSMOTMemory(pk);
|
||||
|
||||
return pk;
|
||||
}
|
||||
|
||||
private void UpdateEdgeCase(PKM pkm)
|
||||
{
|
||||
switch (Generation)
|
||||
{
|
||||
case 3 when Species == 124 && pkm.Version == (int) GameVersion.LG && pkm.Language == (int) LanguageID.Italian:
|
||||
// Italian LG Jynx untranslated from English name
|
||||
pkm.OT_Name = GetOT(2);
|
||||
pkm.SetNickname(GetNickname(2));
|
||||
break;
|
||||
|
||||
case 4 when Version == GameVersion.DPPt && Species == 129: // Meister Magikarp
|
||||
// Has German Language ID for all except German origin, which is English
|
||||
pkm.Language = (int)(pkm.Language == (int)LanguageID.German ? LanguageID.English : LanguageID.German);
|
||||
break;
|
||||
|
||||
case 4 when Version == GameVersion.DPPt && (pkm.Version == (int)GameVersion.D || pkm.Version == (int)GameVersion.P):
|
||||
// DP English origin are Japanese lang
|
||||
pkm.Language = 1;
|
||||
break;
|
||||
|
||||
case 4 when Version == GameVersion.HGSS && Species == 25: // Pikachu
|
||||
// Has English Language ID for all except English origin, which is French
|
||||
pkm.Language = (int)(pkm.Language == (int)LanguageID.English ? LanguageID.French : LanguageID.English);
|
||||
break;
|
||||
|
||||
case 5 when Version == GameVersion.BW && pkm.Language == 1:
|
||||
// Trades for JPN games have language ID of 0, not 1.
|
||||
pkm.Language = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetSMOTMemory(PKM pk)
|
||||
{
|
||||
pk.OT_Memory = 1;
|
||||
pk.OT_Intensity = 3;
|
||||
pk.OT_TextVar = 40;
|
||||
pk.OT_Feeling = 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ public static class EncounterMovesetGenerator
|
||||
/// <returns>A consumable <see cref="PKM"/> list of possible results.</returns>
|
||||
public static IEnumerable<PKM> GeneratePKMs(PKM pk, ITrainerInfo info, int[] moves = null, params GameVersion[] versions)
|
||||
{
|
||||
pk.TID = info.TID;
|
||||
var m = moves ?? pk.Moves;
|
||||
var vers = versions?.Length >= 1 ? versions : Versions.Where(z => z <= (GameVersion) pk.MaxGameID);
|
||||
foreach (var ver in vers)
|
||||
@@ -254,6 +255,11 @@ private static IEnumerable<EncounterSlot> GetSlots(PKM pk, IReadOnlyCollection<i
|
||||
var slots = EncounterSlotGenerator.GetPossible(pk);
|
||||
foreach (var slot in slots)
|
||||
{
|
||||
if (slot.Generation == 2 && slot.Type.HasFlag(SlotType.Headbutt))
|
||||
{
|
||||
if (Legal.GetGSCHeadbuttAvailability(slot, pk.TID) != TreeEncounterAvailable.ValidTree)
|
||||
continue;
|
||||
}
|
||||
if (needs.Count == 0)
|
||||
{
|
||||
yield return slot;
|
||||
|
||||
@@ -100,15 +100,10 @@ private static CheckResult VerifyWildEncounterCrystal(PKM pkm, EncounterSlot enc
|
||||
|
||||
return new CheckResult(Severity.Valid, V68, CheckIdentifier.Encounter);
|
||||
}
|
||||
private static CheckResult VerifyWildEncounterCrystalHeadbutt(PKM pkm, EncounterSlot encounter)
|
||||
private static CheckResult VerifyWildEncounterCrystalHeadbutt(ITrainerID tr, EncounterSlot encounter)
|
||||
{
|
||||
var Area = Legal.GetCrystalTreeArea(encounter);
|
||||
if (Area == null) // Failsafe, every area with headbutt encounters has a tree area
|
||||
return new CheckResult(Severity.Invalid, V605, CheckIdentifier.Encounter);
|
||||
|
||||
var table = Area.GetTrees(encounter.Type);
|
||||
var trainerpivot = pkm.TID % 10;
|
||||
switch (table[trainerpivot])
|
||||
var tree = Legal.GetGSCHeadbuttAvailability(encounter, tr.TID);
|
||||
switch (tree)
|
||||
{
|
||||
case TreeEncounterAvailable.ValidTree:
|
||||
return new CheckResult(Severity.Valid, V604, CheckIdentifier.Encounter);
|
||||
|
||||
@@ -424,33 +424,8 @@ private static bool GetPokewalkerMatch(PKM pk, uint oldpid, out PIDIV pidiv)
|
||||
if (nature == 24) // impossible nature
|
||||
return GetNonMatch(out pidiv);
|
||||
|
||||
uint pid = (uint)((pk.TID ^ pk.SID) >> 8 ^ 0xFF) << 24; // the most significant byte of the PID is chosen so the Pokémon can never be shiny.
|
||||
// Ensure nature is set to required nature without affecting shininess
|
||||
pid += nature - pid % 25;
|
||||
uint pid = PIDGenerator.GetPokeWalkerPID(pk.TID, pk.SID, nature, pk.Gender, pk.PersonalInfo.Gender);
|
||||
|
||||
// Ensure Gender is set to required gender without affecting other properties
|
||||
// If Gender is modified, modify the ability if appropriate
|
||||
int currentGender = pk.Gender;
|
||||
if (currentGender != 2) // either m/f
|
||||
{
|
||||
var gr = pk.PersonalInfo.Gender;
|
||||
var pidGender = (pid & 0xFF) < gr ? 1 : 0;
|
||||
if (currentGender != pidGender)
|
||||
{
|
||||
if (currentGender == 0) // Male
|
||||
{
|
||||
pid += (uint) (((gr - (pid & 0xFF)) / 25 + 1) * 25);
|
||||
if ((nature & 1) != (pid & 1))
|
||||
pid += 25;
|
||||
}
|
||||
else
|
||||
{
|
||||
pid -= (uint) ((((pid & 0xFF) - gr) / 25 + 1) * 25);
|
||||
if ((nature & 1) != (pid & 1))
|
||||
pid -= 25;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pid != oldpid)
|
||||
return GetNonMatch(out pidiv);
|
||||
pidiv = new PIDIV {NoSeed = true, RNG = RNG.LCRNG, Type = PIDType.Pokewalker};
|
||||
@@ -646,36 +621,42 @@ public static IEnumerable<PIDIV> GetPokeSpotSeeds(PKM pkm, int slot)
|
||||
foreach (var seed in seeds)
|
||||
{
|
||||
// check for valid encounter slot info
|
||||
var esv = (seed>>16)%100;
|
||||
switch (slot)
|
||||
{
|
||||
case 0:
|
||||
if (esv < 50) break; // valid
|
||||
continue;
|
||||
case 1:
|
||||
if (esv >= 50 && esv < 85) break; // valid
|
||||
continue;
|
||||
case 2:
|
||||
if (esv >= 85) break;
|
||||
continue;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
// check for valid activation
|
||||
var s = RNG.XDRNG.Prev(seed);
|
||||
if ((s>>16)%3 != 0)
|
||||
{
|
||||
if ((s>>16)%100 < 10) // can't fail a munchlax/bonsly encounter check
|
||||
continue;
|
||||
s = RNG.XDRNG.Prev(s);
|
||||
if ((s>>16)%3 != 0) // can't activate even if generous
|
||||
continue;
|
||||
}
|
||||
if (!IsPokeSpotActivation(slot, seed, out uint s))
|
||||
continue;
|
||||
yield return new PIDIV {OriginSeed = s, RNG = RNG.XDRNG, Type = PIDType.PokeSpot};
|
||||
}
|
||||
}
|
||||
public static bool IsPokeSpotActivation(int slot, uint seed, out uint s)
|
||||
{
|
||||
s = seed;
|
||||
var esv = (seed >> 16) % 100;
|
||||
switch (slot)
|
||||
{
|
||||
case 0:
|
||||
if (esv < 50) break; // valid
|
||||
return false;
|
||||
case 1:
|
||||
if (esv >= 50 && esv < 85) break; // valid
|
||||
return false;
|
||||
case 2:
|
||||
if (esv >= 85) break;
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
// check for valid activation
|
||||
s = RNG.XDRNG.Prev(seed);
|
||||
if ((s >> 16) % 3 != 0)
|
||||
{
|
||||
if ((s >> 16) % 100 < 10) // can't fail a munchlax/bonsly encounter check
|
||||
return false;
|
||||
s = RNG.XDRNG.Prev(s);
|
||||
if ((s >> 16) % 3 != 0) // can't activate even if generous
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
public static bool IsCompatible3(this PIDType val, IEncounterable encounter, PKM pkm)
|
||||
{
|
||||
switch (encounter)
|
||||
|
||||
@@ -153,6 +153,27 @@ public static void SetValuesFromSeed(PKM pk, PIDType type, uint seed)
|
||||
return (pk, seed) => { };
|
||||
}
|
||||
|
||||
public static void SetRandomPokeSpotPID(PKM pk, int nature, int gender, int ability, int slot)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var seed = Util.Rand32();
|
||||
if (!MethodFinder.IsPokeSpotActivation(slot, seed, out var _))
|
||||
continue;
|
||||
|
||||
var rng = RNG.XDRNG;
|
||||
var D = rng.Next(seed); // PID
|
||||
var E = rng.Next(D); // PID
|
||||
|
||||
pk.PID = D & 0xFFFF0000 | E >> 16;
|
||||
if (!IsValidCriteria4(pk, nature, ability, gender))
|
||||
continue;
|
||||
|
||||
pk.SetRandomIVs();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public static uint GetMG5ShinyPID(uint gval, uint av, int TID, int SID)
|
||||
{
|
||||
uint PID = (uint)((TID ^ SID ^ gval) << 16 | gval);
|
||||
@@ -172,24 +193,25 @@ public static uint GetPokeWalkerPID(int TID, int SID, uint nature, int gender, i
|
||||
// Ensure Gender is set to required gender without affecting other properties
|
||||
// If Gender is modified, modify the ability if appropriate
|
||||
int currentGender = gender;
|
||||
if (currentGender != 2) // either m/f
|
||||
if (currentGender == 2)
|
||||
return pid;
|
||||
|
||||
// either m/f
|
||||
var pidGender = (pid & 0xFF) < gr ? 1 : 0;
|
||||
if (currentGender == pidGender)
|
||||
return pid;
|
||||
|
||||
if (currentGender == 0) // Male
|
||||
{
|
||||
var pidGender = (pid & 0xFF) < gr ? 1 : 0;
|
||||
if (currentGender != pidGender)
|
||||
{
|
||||
if (currentGender == 0) // Male
|
||||
{
|
||||
pid += (uint)(((gr - (pid & 0xFF)) / 25 + 1) * 25);
|
||||
if ((nature & 1) != (pid & 1))
|
||||
pid += 25;
|
||||
}
|
||||
else
|
||||
{
|
||||
pid -= (uint)((((pid & 0xFF) - gr) / 25 + 1) * 25);
|
||||
if ((nature & 1) != (pid & 1))
|
||||
pid -= 25;
|
||||
}
|
||||
}
|
||||
pid += (uint)(((gr - (pid & 0xFF)) / 25 + 1) * 25);
|
||||
if ((nature & 1) != (pid & 1))
|
||||
pid += 25;
|
||||
}
|
||||
else
|
||||
{
|
||||
pid -= (uint)((((pid & 0xFF) - gr) / 25 + 1) * 25);
|
||||
if ((nature & 1) != (pid & 1))
|
||||
pid -= 25;
|
||||
}
|
||||
return pid;
|
||||
}
|
||||
@@ -250,19 +272,26 @@ private static void SetRandomWildPID4(PKM pk, int nature, int ability, int gende
|
||||
while (true)
|
||||
{
|
||||
method(pk, Util.Rand32());
|
||||
|
||||
if (pk.GetSaneGender(gender) != gender)
|
||||
continue;
|
||||
|
||||
if (pk.Nature != nature)
|
||||
continue;
|
||||
|
||||
if ((pk.PID & 1) != ability)
|
||||
if (!IsValidCriteria4(pk, nature, ability, gender))
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsValidCriteria4(PKM pk, int nature, int ability, int gender)
|
||||
{
|
||||
if (pk.GetSaneGender(gender) != gender)
|
||||
return false;
|
||||
|
||||
if (pk.Nature != nature)
|
||||
return false;
|
||||
|
||||
if ((pk.PID & 1) != ability)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static PIDType GetPIDType(PKM pk, PIDType specific)
|
||||
{
|
||||
if (specific != PIDType.None)
|
||||
|
||||
@@ -957,6 +957,8 @@ public int[] SetRandomIVs(int[] template, int? flawless = null)
|
||||
for (int i = 0; i < 6; i++)
|
||||
ivs[i] = template[i] < 0 ? (int) (Util.Rand32() & MaxIV) : template[i];
|
||||
} while (ivs.Count(z => z == MaxIV) < count);
|
||||
|
||||
IVs = ivs;
|
||||
return ivs;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user