2016-06-20 04:22:43 +00:00
|
|
|
|
using System;
|
2020-01-19 00:46:38 +00:00
|
|
|
|
using System.Collections.Generic;
|
2016-06-20 04:22:43 +00:00
|
|
|
|
using System.Linq;
|
|
|
|
|
|
2017-01-08 07:54:09 +00:00
|
|
|
|
namespace PKHeX.Core
|
2016-06-20 04:22:43 +00:00
|
|
|
|
{
|
2017-10-23 22:45:58 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Generation 4 Mystery Gift Template File (Inner Gift Data, no card data)
|
|
|
|
|
/// </summary>
|
2020-09-18 23:23:17 +00:00
|
|
|
|
public sealed class PGT : DataMysteryGift, IRibbonSetEvent3, IRibbonSetEvent4
|
2016-06-20 04:22:43 +00:00
|
|
|
|
{
|
2017-03-19 23:19:59 +00:00
|
|
|
|
public const int Size = 0x104; // 260
|
2016-09-04 17:38:53 +00:00
|
|
|
|
public override int Format => 4;
|
2018-08-10 04:53:39 +00:00
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
public override int Level
|
|
|
|
|
{
|
2020-08-10 03:02:28 +00:00
|
|
|
|
get => IsManaphyEgg ? 1 : IsPokémon ? PK.Met_Level : 0;
|
2016-10-23 19:48:49 +00:00
|
|
|
|
set { if (IsPokémon) PK.Met_Level = value; }
|
|
|
|
|
}
|
2018-08-10 04:53:39 +00:00
|
|
|
|
|
2016-10-23 19:48:49 +00:00
|
|
|
|
public override int Ball
|
|
|
|
|
{
|
2017-05-13 03:32:36 +00:00
|
|
|
|
get => IsPokémon ? PK.Ball : 0;
|
2016-10-23 19:48:49 +00:00
|
|
|
|
set { if (IsPokémon) PK.Ball = value; }
|
|
|
|
|
}
|
2016-06-20 04:22:43 +00:00
|
|
|
|
|
|
|
|
|
private enum GiftType
|
|
|
|
|
{
|
|
|
|
|
Pokémon = 1,
|
|
|
|
|
PokémonEgg = 2,
|
|
|
|
|
Item = 3,
|
|
|
|
|
Rule = 4,
|
|
|
|
|
Seal = 5,
|
|
|
|
|
Accessory = 6,
|
|
|
|
|
ManaphyEgg = 7,
|
|
|
|
|
MemberCard = 8,
|
|
|
|
|
OaksLetter = 9,
|
|
|
|
|
AzureFlute = 10,
|
|
|
|
|
PokétchApp = 11,
|
|
|
|
|
Ribbon = 12,
|
|
|
|
|
PokéWalkerArea = 14
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-13 03:32:36 +00:00
|
|
|
|
public override string CardTitle { get => "Raw Gift (PGT)"; set { } }
|
|
|
|
|
public override int CardID { get => -1; set { } }
|
|
|
|
|
public override bool GiftUsed { get => false; set { } }
|
2016-06-20 04:22:43 +00:00
|
|
|
|
|
PKHeX.Core Nullable cleanup (#2401)
* Handle some nullable cases
Refactor MysteryGift into a second abstract class (backed by a byte array, or fake data)
Make some classes have explicit constructors instead of { } initialization
* Handle bits more obviously without null
* Make SaveFile.BAK explicitly readonly again
* merge constructor methods to have readonly fields
* Inline some properties
* More nullable handling
* Rearrange box actions
define straightforward classes to not have any null properties
* Make extrabyte reference array immutable
* Move tooltip creation to designer
* Rearrange some logic to reduce nesting
* Cache generated fonts
* Split mystery gift album purpose
* Handle more tooltips
* Disallow null setters
* Don't capture RNG object, only type enum
* Unify learnset objects
Now have readonly properties which are never null
don't new() empty learnsets (>800 Learnset objects no longer created,
total of 2400 objects since we also new() a move & level array)
optimize g1/2 reader for early abort case
* Access rewrite
Initialize blocks in a separate object, and get via that object
removes a couple hundred "might be null" warnings since blocks are now readonly getters
some block references have been relocated, but interfaces should expose all that's needed
put HoF6 controls in a groupbox, and disable
* Readonly personal data
* IVs non nullable for mystery gift
* Explicitly initialize forced encounter moves
* Make shadow objects readonly & non-null
Put murkrow fix in binary data resource, instead of on startup
* Assign dex form fetch on constructor
Fixes legality parsing edge cases
also handle cxd parse for valid; exit before exception is thrown in FrameGenerator
* Remove unnecessary null checks
* Keep empty value until init
SetPouch sets the value to an actual one during load, but whatever
* Readonly team lock data
* Readonly locks
Put locked encounters at bottom (favor unlocked)
* Mail readonly data / offset
Rearrange some call flow and pass defaults
Add fake classes for SaveDataEditor mocking
Always party size, no need to check twice in stat editor
use a fake save file as initial data for savedata editor, and for
gamedata (wow i found a usage)
constrain eventwork editor to struct variable types (uint, int, etc),
thus preventing null assignment errors
2019-10-17 01:47:31 +00:00
|
|
|
|
public PGT() : this(new byte[Size]) { }
|
|
|
|
|
public PGT(byte[] data) : base(data) { }
|
2016-06-20 04:22:43 +00:00
|
|
|
|
|
2017-05-13 03:32:36 +00:00
|
|
|
|
public byte CardType { get => Data[0]; set => Data[0] = value; }
|
2016-06-20 04:22:43 +00:00
|
|
|
|
// Unused 0x01
|
2017-05-13 03:32:36 +00:00
|
|
|
|
public byte Slot { get => Data[2]; set => Data[2] = value; }
|
|
|
|
|
public byte Detail { get => Data[3]; set => Data[3] = value; }
|
2017-06-18 01:37:19 +00:00
|
|
|
|
public override int ItemID { get => BitConverter.ToUInt16(Data, 0x4); set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x4); }
|
2016-06-20 04:22:43 +00:00
|
|
|
|
|
2017-01-21 05:43:59 +00:00
|
|
|
|
public PK4 PK
|
2016-06-20 04:22:43 +00:00
|
|
|
|
{
|
2020-04-16 20:11:27 +00:00
|
|
|
|
get => _pk ??= new PK4(Data.Slice(8, PokeCrypto.SIZE_4PARTY));
|
2017-01-21 05:43:59 +00:00
|
|
|
|
set
|
|
|
|
|
{
|
2020-04-16 19:58:48 +00:00
|
|
|
|
_pk = value;
|
2020-06-17 02:46:22 +00:00
|
|
|
|
var data = value.Data.All(z => z == 0)
|
2017-01-21 05:43:59 +00:00
|
|
|
|
? value.Data
|
2020-01-04 22:48:39 +00:00
|
|
|
|
: PokeCrypto.EncryptArray45(value.Data);
|
2020-06-17 02:46:22 +00:00
|
|
|
|
data.CopyTo(Data, 8);
|
2017-01-21 05:43:59 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2018-08-10 04:53:39 +00:00
|
|
|
|
|
2019-12-25 07:24:28 +00:00
|
|
|
|
public override byte[] Write()
|
|
|
|
|
{
|
|
|
|
|
// Ensure PGT content is encrypted
|
|
|
|
|
var clone = (PGT)Clone();
|
|
|
|
|
clone.VerifyPKEncryption();
|
|
|
|
|
return clone.Data;
|
|
|
|
|
}
|
|
|
|
|
|
PKHeX.Core Nullable cleanup (#2401)
* Handle some nullable cases
Refactor MysteryGift into a second abstract class (backed by a byte array, or fake data)
Make some classes have explicit constructors instead of { } initialization
* Handle bits more obviously without null
* Make SaveFile.BAK explicitly readonly again
* merge constructor methods to have readonly fields
* Inline some properties
* More nullable handling
* Rearrange box actions
define straightforward classes to not have any null properties
* Make extrabyte reference array immutable
* Move tooltip creation to designer
* Rearrange some logic to reduce nesting
* Cache generated fonts
* Split mystery gift album purpose
* Handle more tooltips
* Disallow null setters
* Don't capture RNG object, only type enum
* Unify learnset objects
Now have readonly properties which are never null
don't new() empty learnsets (>800 Learnset objects no longer created,
total of 2400 objects since we also new() a move & level array)
optimize g1/2 reader for early abort case
* Access rewrite
Initialize blocks in a separate object, and get via that object
removes a couple hundred "might be null" warnings since blocks are now readonly getters
some block references have been relocated, but interfaces should expose all that's needed
put HoF6 controls in a groupbox, and disable
* Readonly personal data
* IVs non nullable for mystery gift
* Explicitly initialize forced encounter moves
* Make shadow objects readonly & non-null
Put murkrow fix in binary data resource, instead of on startup
* Assign dex form fetch on constructor
Fixes legality parsing edge cases
also handle cxd parse for valid; exit before exception is thrown in FrameGenerator
* Remove unnecessary null checks
* Keep empty value until init
SetPouch sets the value to an actual one during load, but whatever
* Readonly team lock data
* Readonly locks
Put locked encounters at bottom (favor unlocked)
* Mail readonly data / offset
Rearrange some call flow and pass defaults
Add fake classes for SaveDataEditor mocking
Always party size, no need to check twice in stat editor
use a fake save file as initial data for savedata editor, and for
gamedata (wow i found a usage)
constrain eventwork editor to struct variable types (uint, int, etc),
thus preventing null assignment errors
2019-10-17 01:47:31 +00:00
|
|
|
|
private PK4? _pk;
|
2017-01-21 05:43:59 +00:00
|
|
|
|
|
2017-12-11 18:13:08 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Double checks the encryption of the gift data for Pokemon data.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>True if data was encrypted, false if the data was not modified.</returns>
|
|
|
|
|
public bool VerifyPKEncryption()
|
|
|
|
|
{
|
|
|
|
|
if (!IsPokémon || BitConverter.ToUInt32(Data, 0x64 + 8) != 0)
|
|
|
|
|
return false;
|
|
|
|
|
EncryptPK();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2018-07-27 02:34:27 +00:00
|
|
|
|
|
2017-12-11 18:13:08 +00:00
|
|
|
|
private void EncryptPK()
|
|
|
|
|
{
|
2020-01-04 22:48:39 +00:00
|
|
|
|
byte[] ekdata = new byte[PokeCrypto.SIZE_4PARTY];
|
2017-12-11 18:13:08 +00:00
|
|
|
|
Array.Copy(Data, 8, ekdata, 0, ekdata.Length);
|
2020-01-04 22:48:39 +00:00
|
|
|
|
ekdata = PokeCrypto.EncryptArray45(ekdata);
|
2017-12-11 18:13:08 +00:00
|
|
|
|
ekdata.CopyTo(Data, 8);
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-13 03:32:36 +00:00
|
|
|
|
private GiftType PGTGiftType { get => (GiftType)Data[0]; set => Data[0] = (byte)value; }
|
2016-08-25 21:44:02 +00:00
|
|
|
|
public bool IsHatched => PGTGiftType == GiftType.Pokémon;
|
2020-01-13 07:00:32 +00:00
|
|
|
|
public override bool IsEgg { get => PGTGiftType == GiftType.PokémonEgg || IsManaphyEgg; set { if (value) { PGTGiftType = GiftType.PokémonEgg; PK.IsEgg = true; } } }
|
2017-05-13 03:32:36 +00:00
|
|
|
|
public bool IsManaphyEgg { get => PGTGiftType == GiftType.ManaphyEgg; set { if (value) PGTGiftType = GiftType.ManaphyEgg; } }
|
2020-01-13 07:00:32 +00:00
|
|
|
|
public override bool EggEncounter => IsEgg;
|
2017-05-13 03:32:36 +00:00
|
|
|
|
public override bool IsItem { get => PGTGiftType == GiftType.Item; set { if (value) PGTGiftType = GiftType.Item; } }
|
|
|
|
|
public override bool IsPokémon { get => PGTGiftType == GiftType.Pokémon || PGTGiftType == GiftType.PokémonEgg || PGTGiftType == GiftType.ManaphyEgg; set { } }
|
2016-06-20 04:22:43 +00:00
|
|
|
|
|
2017-05-13 03:32:36 +00:00
|
|
|
|
public override int Species { get => IsManaphyEgg ? 490 : PK.Species; set => PK.Species = value; }
|
2020-01-19 00:46:38 +00:00
|
|
|
|
public override IReadOnlyList<int> Moves { get => PK.Moves; set => PK.SetMoves(value); }
|
2017-05-13 03:32:36 +00:00
|
|
|
|
public override int HeldItem { get => PK.HeldItem; set => PK.HeldItem = value; }
|
2016-09-04 17:38:53 +00:00
|
|
|
|
public override bool IsShiny => PK.IsShiny;
|
2017-11-18 19:34:23 +00:00
|
|
|
|
public override int Gender { get => PK.Gender; set => PK.Gender = value; }
|
|
|
|
|
public override int Form { get => PK.AltForm; set => PK.AltForm = value; }
|
|
|
|
|
public override int TID { get => (ushort)PK.TID; set => PK.TID = value; }
|
|
|
|
|
public override int SID { get => (ushort)PK.SID; set => PK.SID = value; }
|
|
|
|
|
public override string OT_Name { get => PK.OT_Name; set => PK.OT_Name = value; }
|
2018-01-02 20:00:41 +00:00
|
|
|
|
public override int Location { get => PK.Met_Location; set => PK.Met_Location = value; }
|
|
|
|
|
public override int EggLocation { get => PK.Egg_Location; set => PK.Egg_Location = value; }
|
2016-09-04 17:38:53 +00:00
|
|
|
|
|
2020-06-17 02:46:22 +00:00
|
|
|
|
public override PKM ConvertToPKM(ITrainerInfo sav, EncounterCriteria criteria)
|
2016-06-20 04:22:43 +00:00
|
|
|
|
{
|
|
|
|
|
if (!IsPokémon)
|
PKHeX.Core Nullable cleanup (#2401)
* Handle some nullable cases
Refactor MysteryGift into a second abstract class (backed by a byte array, or fake data)
Make some classes have explicit constructors instead of { } initialization
* Handle bits more obviously without null
* Make SaveFile.BAK explicitly readonly again
* merge constructor methods to have readonly fields
* Inline some properties
* More nullable handling
* Rearrange box actions
define straightforward classes to not have any null properties
* Make extrabyte reference array immutable
* Move tooltip creation to designer
* Rearrange some logic to reduce nesting
* Cache generated fonts
* Split mystery gift album purpose
* Handle more tooltips
* Disallow null setters
* Don't capture RNG object, only type enum
* Unify learnset objects
Now have readonly properties which are never null
don't new() empty learnsets (>800 Learnset objects no longer created,
total of 2400 objects since we also new() a move & level array)
optimize g1/2 reader for early abort case
* Access rewrite
Initialize blocks in a separate object, and get via that object
removes a couple hundred "might be null" warnings since blocks are now readonly getters
some block references have been relocated, but interfaces should expose all that's needed
put HoF6 controls in a groupbox, and disable
* Readonly personal data
* IVs non nullable for mystery gift
* Explicitly initialize forced encounter moves
* Make shadow objects readonly & non-null
Put murkrow fix in binary data resource, instead of on startup
* Assign dex form fetch on constructor
Fixes legality parsing edge cases
also handle cxd parse for valid; exit before exception is thrown in FrameGenerator
* Remove unnecessary null checks
* Keep empty value until init
SetPouch sets the value to an actual one during load, but whatever
* Readonly team lock data
* Readonly locks
Put locked encounters at bottom (favor unlocked)
* Mail readonly data / offset
Rearrange some call flow and pass defaults
Add fake classes for SaveDataEditor mocking
Always party size, no need to check twice in stat editor
use a fake save file as initial data for savedata editor, and for
gamedata (wow i found a usage)
constrain eventwork editor to struct variable types (uint, int, etc),
thus preventing null assignment errors
2019-10-17 01:47:31 +00:00
|
|
|
|
throw new ArgumentException(nameof(IsPokémon));
|
2016-06-20 04:22:43 +00:00
|
|
|
|
|
2019-02-09 19:37:20 +00:00
|
|
|
|
// template is already filled out, only minor mutations required
|
|
|
|
|
PK4 pk4 = new PK4((byte[])PK.Data.Clone()) { Sanity = 0 };
|
2016-06-20 04:22:43 +00:00
|
|
|
|
if (!IsHatched && Detail == 0)
|
|
|
|
|
{
|
2020-06-17 02:46:22 +00:00
|
|
|
|
pk4.OT_Name = sav.OT;
|
|
|
|
|
pk4.TID = sav.TID;
|
|
|
|
|
pk4.SID = sav.SID;
|
|
|
|
|
pk4.OT_Gender = sav.Gender;
|
|
|
|
|
pk4.Language = sav.Language;
|
2016-06-20 04:22:43 +00:00
|
|
|
|
}
|
2018-07-25 14:34:48 +00:00
|
|
|
|
|
2016-06-20 04:22:43 +00:00
|
|
|
|
if (IsManaphyEgg)
|
2020-09-06 18:34:50 +00:00
|
|
|
|
SetDefaultManaphyEggDetails(pk4, sav);
|
2019-02-09 19:37:20 +00:00
|
|
|
|
|
|
|
|
|
SetPINGA(pk4, criteria);
|
2020-06-17 02:46:22 +00:00
|
|
|
|
SetMetData(pk4, sav);
|
2019-02-09 19:37:20 +00:00
|
|
|
|
|
|
|
|
|
var pi = pk4.PersonalInfo;
|
|
|
|
|
pk4.CurrentFriendship = pk4.IsEgg ? pi.HatchCycles : pi.BaseFriendship;
|
|
|
|
|
|
|
|
|
|
pk4.RefreshChecksum();
|
|
|
|
|
return pk4;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SetMetData(PK4 pk4, ITrainerInfo trainer)
|
|
|
|
|
{
|
|
|
|
|
if (!EggEncounter)
|
2016-06-20 04:22:43 +00:00
|
|
|
|
{
|
2019-02-09 19:37:20 +00:00
|
|
|
|
pk4.Met_Location = pk4.Egg_Location + 3000;
|
|
|
|
|
pk4.Egg_Location = 0;
|
|
|
|
|
pk4.MetDate = DateTime.Now;
|
|
|
|
|
pk4.IsEgg = false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pk4.Egg_Location += 3000;
|
|
|
|
|
if (trainer.Generation == 4)
|
|
|
|
|
SetUnhatchedEggDetails(pk4);
|
|
|
|
|
else
|
|
|
|
|
SetHatchedEggDetails(pk4);
|
2016-06-20 04:22:43 +00:00
|
|
|
|
}
|
2019-02-09 19:37:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-09-06 18:34:50 +00:00
|
|
|
|
private static void SetDefaultManaphyEggDetails(PK4 pk4, ITrainerInfo trainer)
|
2019-02-09 19:37:20 +00:00
|
|
|
|
{
|
|
|
|
|
// Since none of this data is populated, fill in default info.
|
2020-09-05 20:11:16 +00:00
|
|
|
|
pk4.Species = (int)Core.Species.Manaphy;
|
2019-02-09 19:37:20 +00:00
|
|
|
|
pk4.Gender = 2;
|
|
|
|
|
// Level 1 Moves
|
2020-09-05 20:11:16 +00:00
|
|
|
|
pk4.Move1 = 294; pk4.Move1_PP = 20;
|
|
|
|
|
pk4.Move2 = 145; pk4.Move2_PP = 30;
|
|
|
|
|
pk4.Move3 = 346; pk4.Move3_PP = 15;
|
|
|
|
|
pk4.Ability = (int)Ability.Hydration;
|
2019-02-09 19:37:20 +00:00
|
|
|
|
pk4.FatefulEncounter = true;
|
2020-09-05 20:11:16 +00:00
|
|
|
|
pk4.Ball = (int)Core.Ball.Poke;
|
2020-09-06 18:34:50 +00:00
|
|
|
|
pk4.Version = GameVersion.Gen4.Contains(trainer.Game) ? trainer.Game : (int)GameVersion.D;
|
|
|
|
|
pk4.Language = trainer.Language < (int)LanguageID.Korean ? trainer.Language : (int)LanguageID.English;
|
2019-02-09 19:37:20 +00:00
|
|
|
|
pk4.Egg_Location = 1; // Ranger (will be +3000 later)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SetPINGA(PK4 pk4, EncounterCriteria criteria)
|
|
|
|
|
{
|
|
|
|
|
// Ability is forced already, can't force anything
|
|
|
|
|
// todo: loop force the Nature/Gender
|
2016-06-20 04:22:43 +00:00
|
|
|
|
|
|
|
|
|
// Generate IV
|
2019-02-09 19:37:20 +00:00
|
|
|
|
uint seed = Util.Rand32();
|
|
|
|
|
if (pk4.PID == 1 || IsManaphyEgg) // Create Nonshiny
|
2018-07-25 14:34:48 +00:00
|
|
|
|
seed = GeneratePID(seed, pk4);
|
2016-06-20 04:22:43 +00:00
|
|
|
|
|
2017-06-16 01:34:03 +00:00
|
|
|
|
if (!IsManaphyEgg)
|
2017-06-18 01:37:19 +00:00
|
|
|
|
seed = Util.Rand32(); // reseed, do not have method 1 correlation
|
2016-06-20 04:22:43 +00:00
|
|
|
|
|
|
|
|
|
// Generate IVs
|
2020-09-03 21:28:51 +00:00
|
|
|
|
if (pk4.IV32 == 0) // Ignore Nickname/Egg flag bits; none are set for varied-IV gifts.
|
2016-06-20 04:22:43 +00:00
|
|
|
|
{
|
2019-03-16 23:25:25 +00:00
|
|
|
|
uint iv1 = ((seed = RNG.LCRNG.Next(seed)) >> 16) & 0x7FFF;
|
2019-09-11 05:07:50 +00:00
|
|
|
|
uint iv2 = ((RNG.LCRNG.Next(seed)) >> 16) & 0x7FFF;
|
2017-06-16 01:34:03 +00:00
|
|
|
|
pk4.IV32 = iv1 | iv2 << 15;
|
2016-06-20 04:22:43 +00:00
|
|
|
|
}
|
2019-02-09 19:37:20 +00:00
|
|
|
|
}
|
2016-06-20 04:22:43 +00:00
|
|
|
|
|
2019-02-09 19:37:20 +00:00
|
|
|
|
private static void SetHatchedEggDetails(PK4 pk4)
|
|
|
|
|
{
|
|
|
|
|
pk4.IsEgg = false;
|
2020-09-05 20:11:16 +00:00
|
|
|
|
// Met Location & Date is modified when transferred to pk5; don't worry about it.
|
2019-02-09 19:37:20 +00:00
|
|
|
|
pk4.EggMetDate = DateTime.Now;
|
|
|
|
|
}
|
2016-07-28 23:30:48 +00:00
|
|
|
|
|
2019-02-09 19:37:20 +00:00
|
|
|
|
private void SetUnhatchedEggDetails(PK4 pk4)
|
|
|
|
|
{
|
|
|
|
|
pk4.IsEgg = true;
|
|
|
|
|
pk4.IsNicknamed = false;
|
2019-09-19 02:58:23 +00:00
|
|
|
|
pk4.Nickname = SpeciesName.GetSpeciesNameGeneration(0, pk4.Language, Format);
|
2020-09-05 20:11:16 +00:00
|
|
|
|
pk4.EggMetDate = DateTime.Now;
|
2016-06-20 04:22:43 +00:00
|
|
|
|
}
|
2018-07-25 14:34:48 +00:00
|
|
|
|
|
|
|
|
|
private static uint GeneratePID(uint seed, PK4 pk4)
|
|
|
|
|
{
|
|
|
|
|
do
|
|
|
|
|
{
|
2019-03-16 23:25:25 +00:00
|
|
|
|
uint pid1 = (seed = RNG.LCRNG.Next(seed)) >> 16; // low
|
|
|
|
|
uint pid2 = (seed = RNG.LCRNG.Next(seed)) & 0xFFFF0000; // hi
|
|
|
|
|
pk4.PID = pid2 | pid1;
|
2018-07-25 14:34:48 +00:00
|
|
|
|
// sanity check gender for non-genderless PID cases
|
|
|
|
|
} while (!pk4.IsGenderValid());
|
|
|
|
|
|
|
|
|
|
while (pk4.IsShiny) // Call the ARNG to change the PID
|
|
|
|
|
pk4.PID = RNG.ARNG.Next(pk4.PID);
|
|
|
|
|
return seed;
|
|
|
|
|
}
|
2018-12-27 09:00:08 +00:00
|
|
|
|
|
2019-11-28 18:42:24 +00:00
|
|
|
|
public static bool IsRangerManaphy(PKM pkm)
|
|
|
|
|
{
|
|
|
|
|
var egg = pkm.Egg_Location;
|
|
|
|
|
if (!pkm.IsEgg) // Link Trade Egg or Ranger
|
|
|
|
|
return egg == Locations.LinkTrade4 || egg == Locations.Ranger4;
|
|
|
|
|
if (egg != Locations.Ranger4)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (pkm.Language == (int)LanguageID.Korean) // never korean
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
var met = pkm.Met_Location;
|
|
|
|
|
return met == Locations.LinkTrade4 || met == 0;
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-18 18:29:16 +00:00
|
|
|
|
protected override bool IsMatchExact(PKM pkm, DexLevel evo) => false;
|
2018-12-27 09:00:08 +00:00
|
|
|
|
protected override bool IsMatchDeferred(PKM pkm) => false;
|
2020-09-18 23:23:17 +00:00
|
|
|
|
public bool RibbonEarth { get => PK.RibbonEarth; set => PK.RibbonEarth = value; }
|
|
|
|
|
public bool RibbonNational { get => PK.RibbonNational; set => PK.RibbonNational = value; }
|
|
|
|
|
public bool RibbonCountry { get => PK.RibbonCountry; set => PK.RibbonCountry = value; }
|
|
|
|
|
public bool RibbonChampionBattle { get => PK.RibbonChampionBattle; set => PK.RibbonChampionBattle = value; }
|
|
|
|
|
public bool RibbonChampionRegional { get => PK.RibbonChampionRegional; set => PK.RibbonChampionRegional = value; }
|
|
|
|
|
public bool RibbonChampionNational { get => PK.RibbonChampionNational; set => PK.RibbonChampionNational = value; }
|
|
|
|
|
public bool RibbonClassic { get => PK.RibbonClassic; set => PK.RibbonClassic = value; }
|
|
|
|
|
public bool RibbonWishing { get => PK.RibbonWishing; set => PK.RibbonWishing = value; }
|
|
|
|
|
public bool RibbonPremier { get => PK.RibbonPremier; set => PK.RibbonPremier = value; }
|
|
|
|
|
public bool RibbonEvent { get => PK.RibbonEvent; set => PK.RibbonEvent = value; }
|
|
|
|
|
public bool RibbonBirthday { get => PK.RibbonBirthday; set => PK.RibbonBirthday = value; }
|
|
|
|
|
public bool RibbonSpecial { get => PK.RibbonSpecial; set => PK.RibbonSpecial = value; }
|
|
|
|
|
public bool RibbonWorld { get => PK.RibbonWorld; set => PK.RibbonWorld = value; }
|
|
|
|
|
public bool RibbonChampionWorld { get => PK.RibbonChampionWorld; set => PK.RibbonChampionWorld = value; }
|
|
|
|
|
public bool RibbonSouvenir { get => PK.RibbonSouvenir; set => PK.RibbonSouvenir = value; }
|
2016-06-20 04:22:43 +00:00
|
|
|
|
}
|
|
|
|
|
}
|