2018-12-26 06:56:32 +00:00
|
|
|
|
using System;
|
|
|
|
|
|
|
|
|
|
namespace PKHeX.Core
|
|
|
|
|
{
|
|
|
|
|
/// <summary> Generation 6 <see cref="PKM"/> format. </summary>
|
2019-10-26 19:42:33 +00:00
|
|
|
|
public abstract class G6PKM : PKM
|
2018-12-26 06:56:32 +00:00
|
|
|
|
{
|
2020-01-04 22:48:39 +00:00
|
|
|
|
public override int SIZE_PARTY => PokeCrypto.SIZE_6PARTY;
|
|
|
|
|
public override int SIZE_STORED => PokeCrypto.SIZE_6STORED;
|
2020-09-26 19:09:02 +00:00
|
|
|
|
protected G6PKM(byte[] data) : base(data) { }
|
|
|
|
|
protected G6PKM(int size) : base(size) { }
|
2018-12-26 06:56:32 +00:00
|
|
|
|
|
|
|
|
|
// Trash Bytes
|
2021-06-30 03:58:06 +00:00
|
|
|
|
public sealed override Span<byte> Nickname_Trash { get => Data.AsSpan(0x40, 24); set { if (value.Length == 24) value.CopyTo(Data.AsSpan(0x40)); } }
|
|
|
|
|
public sealed override Span<byte> HT_Trash { get => Data.AsSpan(0x78, 24); set { if (value.Length == 24) value.CopyTo(Data.AsSpan(0x78)); } }
|
|
|
|
|
public sealed override Span<byte> OT_Trash { get => Data.AsSpan(0xB0, 24); set { if (value.Length == 24) value.CopyTo(Data.AsSpan(0xB0)); } }
|
2018-12-26 06:56:32 +00:00
|
|
|
|
|
2020-09-07 20:51:13 +00:00
|
|
|
|
protected sealed override ushort CalculateChecksum()
|
2018-12-26 06:56:32 +00:00
|
|
|
|
{
|
|
|
|
|
ushort chk = 0;
|
2020-01-04 22:48:39 +00:00
|
|
|
|
for (int i = 8; i < PokeCrypto.SIZE_6STORED; i += 2) // don't use SIZE_STORED property; pb7 overrides stored size
|
2018-12-26 06:56:32 +00:00
|
|
|
|
chk += BitConverter.ToUInt16(Data, i);
|
|
|
|
|
return chk;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Simple Generated Attributes
|
2020-09-07 20:51:13 +00:00
|
|
|
|
public sealed override int CurrentFriendship
|
2018-12-26 06:56:32 +00:00
|
|
|
|
{
|
|
|
|
|
get => CurrentHandler == 0 ? OT_Friendship : HT_Friendship;
|
|
|
|
|
set { if (CurrentHandler == 0) OT_Friendship = value; else HT_Friendship = value; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int OppositeFriendship
|
|
|
|
|
{
|
|
|
|
|
get => CurrentHandler == 1 ? OT_Friendship : HT_Friendship;
|
|
|
|
|
set { if (CurrentHandler == 1) OT_Friendship = value; else HT_Friendship = value; }
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-07 20:51:13 +00:00
|
|
|
|
public sealed override int PSV => (int)((PID >> 16 ^ (PID & 0xFFFF)) >> 4);
|
|
|
|
|
public sealed override int TSV => (TID ^ SID) >> 4;
|
2020-12-11 04:42:30 +00:00
|
|
|
|
public sealed override bool IsUntraded => Data[0x78] == 0 && Data[0x78 + 1] == 0 && Format == Generation; // immediately terminated HT_Name data (\0)
|
2018-12-26 06:56:32 +00:00
|
|
|
|
|
|
|
|
|
// Complex Generated Attributes
|
2020-09-07 20:51:13 +00:00
|
|
|
|
public sealed override int Characteristic
|
2018-12-26 06:56:32 +00:00
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2019-01-05 18:51:41 +00:00
|
|
|
|
int pm6 = (int)(EncryptionConstant % 6);
|
|
|
|
|
int maxIV = MaximumIV;
|
2018-12-26 06:56:32 +00:00
|
|
|
|
int pm6stat = 0;
|
|
|
|
|
for (int i = 0; i < 6; i++)
|
|
|
|
|
{
|
2019-01-05 18:51:41 +00:00
|
|
|
|
pm6stat = (pm6 + i) % 6;
|
|
|
|
|
if (GetIV(pm6stat) == maxIV)
|
2018-12-26 06:56:32 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return (pm6stat * 5) + (maxIV % 5);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Methods
|
2020-09-07 20:51:13 +00:00
|
|
|
|
protected sealed override byte[] Encrypt()
|
2018-12-26 06:56:32 +00:00
|
|
|
|
{
|
|
|
|
|
RefreshChecksum();
|
2020-01-04 22:48:39 +00:00
|
|
|
|
return PokeCrypto.EncryptArray6(Data);
|
2018-12-26 06:56:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// General User-error Fixes
|
|
|
|
|
public void FixRelearn()
|
|
|
|
|
{
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
if (RelearnMove4 != 0 && RelearnMove3 == 0)
|
|
|
|
|
{
|
|
|
|
|
RelearnMove3 = RelearnMove4;
|
|
|
|
|
RelearnMove4 = 0;
|
|
|
|
|
}
|
|
|
|
|
if (RelearnMove3 != 0 && RelearnMove2 == 0)
|
|
|
|
|
{
|
|
|
|
|
RelearnMove2 = RelearnMove3;
|
|
|
|
|
RelearnMove3 = 0;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (RelearnMove2 != 0 && RelearnMove1 == 0)
|
|
|
|
|
{
|
|
|
|
|
RelearnMove1 = RelearnMove2;
|
|
|
|
|
RelearnMove2 = 0;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Synthetic Trading Logic
|
2019-03-31 05:05:28 +00:00
|
|
|
|
public void Trade(ITrainerInfo tr, int Day = 1, int Month = 1, int Year = 2015)
|
2018-12-26 06:56:32 +00:00
|
|
|
|
{
|
2019-03-31 05:05:28 +00:00
|
|
|
|
if (IsEgg)
|
|
|
|
|
{
|
|
|
|
|
// Eggs do not have any modifications done if they are traded
|
|
|
|
|
// Apply link trade data, only if it left the OT (ignore if dumped & imported, or cloned, etc)
|
|
|
|
|
if ((tr.OT != OT_Name) || (tr.TID != TID) || (tr.SID != SID) || (tr.Gender != OT_Gender))
|
2019-05-11 03:46:49 +00:00
|
|
|
|
SetLinkTradeEgg(Day, Month, Year, Locations.LinkTrade6);
|
2019-03-31 05:05:28 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-26 06:56:32 +00:00
|
|
|
|
// Process to the HT if the OT of the Pokémon does not match the SAV's OT info.
|
2019-03-31 05:05:28 +00:00
|
|
|
|
if (!TradeOT(tr))
|
|
|
|
|
TradeHT(tr);
|
2018-12-26 06:56:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-03-31 05:05:28 +00:00
|
|
|
|
protected abstract bool TradeOT(ITrainerInfo tr);
|
|
|
|
|
protected abstract void TradeHT(ITrainerInfo tr);
|
Track a PKM's Box,Slot,StorageFlags,Identifier metadata separately (#3222)
* Track a PKM's Box,Slot,StorageFlags,Identifier metadata separately
Don't store within the object, track the slot origin data separately.
Batch editing now pre-filters if using Box/Slot/Identifier logic; split up mods/filters as they're starting to get pretty hefty.
- Requesting a Box Data report now shows all slots in the save file (party, misc)
- Can now exclude backup saves from database search via toggle (separate from settings preventing load entirely)
- Replace some linq usages with direct code
* Remove WasLink virtual in PKM
Inline any logic, since we now have encounter objects to indicate matching, rather than the proto-legality logic checking properties of a PKM.
* Use Fateful to directly check gen5 mysterygift origins
No other encounter types in gen5 apply Fateful
* Simplify double ball comparison
Used to be separate for deferral cases, now no longer needed to be separate.
* Grab move/relearn reference and update locally
Fix relearn move identifier
* Inline defog HM transfer preference check
HasMove is faster than getting moves & checking contains. Skips allocation by setting values directly.
* Extract more met location metadata checks: WasBredEgg
* Replace Console.Write* with Debug.Write*
There's no console output UI, so don't include them in release builds.
* Inline WasGiftEgg, WasEvent, and WasEventEgg logic
Adios legality tags that aren't entirely correct for the specific format. Just put the computations in EncounterFinder.
2021-06-23 03:23:48 +00:00
|
|
|
|
|
2018-12-26 06:56:32 +00:00
|
|
|
|
// Maximums
|
2020-09-07 20:51:13 +00:00
|
|
|
|
public sealed override int MaxIV => 31;
|
|
|
|
|
public sealed override int MaxEV => 252;
|
|
|
|
|
public sealed override int OTLength => 12;
|
|
|
|
|
public sealed override int NickLength => 12;
|
2018-12-26 06:56:32 +00:00
|
|
|
|
}
|
2019-09-21 03:55:36 +00:00
|
|
|
|
|
|
|
|
|
public interface ISuperTrain
|
|
|
|
|
{
|
|
|
|
|
uint SuperTrainBitFlags { get; set; }
|
|
|
|
|
bool SecretSuperTrainingUnlocked { get; set; }
|
|
|
|
|
bool SecretSuperTrainingComplete { get; set; }
|
|
|
|
|
int SuperTrainingMedalCount(int maxCount = 30);
|
|
|
|
|
}
|
2018-12-26 06:56:32 +00:00
|
|
|
|
}
|