PKHeX/PKHeX.Core/PKM/HOME/GameDataCore.cs
2023-12-17 16:41:15 -08:00

543 lines
32 KiB
C#

using System;
using System.Numerics;
using static System.Buffers.Binary.BinaryPrimitives;
namespace PKHeX.Core;
/// <summary>
/// Core game data storage, format 1.
/// </summary>
public sealed class GameDataCore : IHomeTrack, ISpeciesForm, ITrainerID, INature, IFatefulEncounter, IContestStats, IScaledSize, ITrainerMemories, IHandlerLanguage, IBattleVersion, IHyperTrain, IFormArgument, IFavorite,
IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetCommon6, IRibbonSetMemory6, IRibbonSetCommon7,
IRibbonSetCommon8, IRibbonSetMark8,
IRibbonSetCommon9, IRibbonSetMark9
{
// Internal Attributes set on creation
private readonly Memory<byte> Buffer; // Raw Storage
public int SerializedSize => Buffer.Length;
private Span<byte> Data => Buffer.Span;
public GameDataCore(Memory<byte> buffer)
{
ArgumentOutOfRangeException.ThrowIfNotEqual(buffer.Length, HomeCrypto.SIZE_CORE);
Buffer = buffer;
}
public int WriteTo(Span<byte> result)
{
var span = Data;
span.CopyTo(result);
return span.Length;
}
public ulong Tracker { get => ReadUInt64LittleEndian(Data); set => WriteUInt64LittleEndian(Data, value); }
public uint EncryptionConstant { get => ReadUInt32LittleEndian(Data[0x08..]); set => WriteUInt32LittleEndian(Data[0x08..], value); }
public bool IsBadEgg { get => Data[0x0C] != 0; set => Data[0x0C] = (byte)(value ? 1 : 0); }
public ushort Species { get => ReadUInt16LittleEndian(Data[0x0D..]); set => WriteUInt16LittleEndian(Data[0x0D..], value); }
public uint ID32 { get => ReadUInt32LittleEndian(Data[0x0F..]); set => WriteUInt32LittleEndian(Data[0x0F..], value); }
public ushort TID16 { get => ReadUInt16LittleEndian(Data[0x0F..]); set => WriteUInt16LittleEndian(Data[0x0F..], value); }
public ushort SID16 { get => ReadUInt16LittleEndian(Data[0x11..]); set => WriteUInt16LittleEndian(Data[0x11..], value); }
public uint EXP { get => ReadUInt32LittleEndian(Data[0x13..]); set => WriteUInt32LittleEndian(Data[0x13..], value); }
public bool IsFavorite { get => Data[0x17] != 0; set => Data[0x17] = (byte)(value ? 1 : 0); }
public int MarkValue { get => ReadUInt16LittleEndian(Data[0x18..]); set => WriteUInt16LittleEndian(Data[0x18..], (ushort)value); }
public uint PID { get => ReadUInt32LittleEndian(Data[0x1A..]); set => WriteUInt32LittleEndian(Data[0x1A..], value); }
public int Nature { get => Data[0x1E]; set => Data[0x1E] = (byte)value; }
public int StatNature { get => Data[0x1F]; set => Data[0x1F] = (byte)value; }
public bool FatefulEncounter { get => Data[0x20] != 0; set => Data[0x20] = (byte)(value ? 1 : 0); }
public int Gender { get => Data[0x21]; set => Data[0x21] = (byte)value; }
public byte Form { get => Data[0x22]; set => WriteUInt16LittleEndian(Data[0x22..], value); }
public int EV_HP { get => Data[0x24]; set => Data[0x24] = (byte)value; }
public int EV_ATK { get => Data[0x25]; set => Data[0x25] = (byte)value; }
public int EV_DEF { get => Data[0x26]; set => Data[0x26] = (byte)value; }
public int EV_SPE { get => Data[0x27]; set => Data[0x27] = (byte)value; }
public int EV_SPA { get => Data[0x28]; set => Data[0x28] = (byte)value; }
public int EV_SPD { get => Data[0x29]; set => Data[0x29] = (byte)value; }
public byte CNT_Cool { get => Data[0x2A]; set => Data[0x2A] = value; }
public byte CNT_Beauty { get => Data[0x2B]; set => Data[0x2B] = value; }
public byte CNT_Cute { get => Data[0x2C]; set => Data[0x2C] = value; }
public byte CNT_Smart { get => Data[0x2D]; set => Data[0x2D] = value; }
public byte CNT_Tough { get => Data[0x2E]; set => Data[0x2E] = value; }
public byte CNT_Sheen { get => Data[0x2F]; set => Data[0x2F] = value; }
private bool GetFlag(int offset, int bit) => FlagUtil.GetFlag(Data, offset, bit);
private void SetFlag(int offset, int bit, bool value) => FlagUtil.SetFlag(Data, offset, bit, value);
public bool RibbonChampionKalos { get => GetFlag(0x30, 0); set => SetFlag(0x30, 0, value); }
public bool RibbonChampionG3 { get => GetFlag(0x30, 1); set => SetFlag(0x30, 1, value); }
public bool RibbonChampionSinnoh { get => GetFlag(0x30, 2); set => SetFlag(0x30, 2, value); }
public bool RibbonBestFriends { get => GetFlag(0x30, 3); set => SetFlag(0x30, 3, value); }
public bool RibbonTraining { get => GetFlag(0x30, 4); set => SetFlag(0x30, 4, value); }
public bool RibbonBattlerSkillful { get => GetFlag(0x30, 5); set => SetFlag(0x30, 5, value); }
public bool RibbonBattlerExpert { get => GetFlag(0x30, 6); set => SetFlag(0x30, 6, value); }
public bool RibbonEffort { get => GetFlag(0x30, 7); set => SetFlag(0x30, 7, value); }
public bool RibbonAlert { get => GetFlag(0x31, 0); set => SetFlag(0x31, 0, value); }
public bool RibbonShock { get => GetFlag(0x31, 1); set => SetFlag(0x31, 1, value); }
public bool RibbonDowncast { get => GetFlag(0x31, 2); set => SetFlag(0x31, 2, value); }
public bool RibbonCareless { get => GetFlag(0x31, 3); set => SetFlag(0x31, 3, value); }
public bool RibbonRelax { get => GetFlag(0x31, 4); set => SetFlag(0x31, 4, value); }
public bool RibbonSnooze { get => GetFlag(0x31, 5); set => SetFlag(0x31, 5, value); }
public bool RibbonSmile { get => GetFlag(0x31, 6); set => SetFlag(0x31, 6, value); }
public bool RibbonGorgeous { get => GetFlag(0x31, 7); set => SetFlag(0x31, 7, value); }
public bool RibbonRoyal { get => GetFlag(0x32, 0); set => SetFlag(0x32, 0, value); }
public bool RibbonGorgeousRoyal { get => GetFlag(0x32, 1); set => SetFlag(0x32, 1, value); }
public bool RibbonArtist { get => GetFlag(0x32, 2); set => SetFlag(0x32, 2, value); }
public bool RibbonFootprint { get => GetFlag(0x32, 3); set => SetFlag(0x32, 3, value); }
public bool RibbonRecord { get => GetFlag(0x32, 4); set => SetFlag(0x32, 4, value); }
public bool RibbonLegend { get => GetFlag(0x32, 5); set => SetFlag(0x32, 5, value); }
public bool RibbonCountry { get => GetFlag(0x32, 6); set => SetFlag(0x32, 6, value); }
public bool RibbonNational { get => GetFlag(0x32, 7); set => SetFlag(0x32, 7, value); }
public bool RibbonEarth { get => GetFlag(0x33, 0); set => SetFlag(0x33, 0, value); }
public bool RibbonWorld { get => GetFlag(0x33, 1); set => SetFlag(0x33, 1, value); }
public bool RibbonClassic { get => GetFlag(0x33, 2); set => SetFlag(0x33, 2, value); }
public bool RibbonPremier { get => GetFlag(0x33, 3); set => SetFlag(0x33, 3, value); }
public bool RibbonEvent { get => GetFlag(0x33, 4); set => SetFlag(0x33, 4, value); }
public bool RibbonBirthday { get => GetFlag(0x33, 5); set => SetFlag(0x33, 5, value); }
public bool RibbonSpecial { get => GetFlag(0x33, 6); set => SetFlag(0x33, 6, value); }
public bool RibbonSouvenir { get => GetFlag(0x33, 7); set => SetFlag(0x33, 7, value); }
// ribbon u32
public bool RibbonWishing { get => GetFlag(0x34, 0); set => SetFlag(0x34, 0, value); }
public bool RibbonChampionBattle { get => GetFlag(0x34, 1); set => SetFlag(0x34, 1, value); }
public bool RibbonChampionRegional { get => GetFlag(0x34, 2); set => SetFlag(0x34, 2, value); }
public bool RibbonChampionNational { get => GetFlag(0x34, 3); set => SetFlag(0x34, 3, value); }
public bool RibbonChampionWorld { get => GetFlag(0x34, 4); set => SetFlag(0x34, 4, value); }
public bool HasContestMemoryRibbon { get => GetFlag(0x34, 5); set => SetFlag(0x34, 5, value); }
public bool HasBattleMemoryRibbon { get => GetFlag(0x34, 6); set => SetFlag(0x34, 6, value); }
public bool RibbonChampionG6Hoenn { get => GetFlag(0x34, 7); set => SetFlag(0x34, 7, value); }
public bool RibbonContestStar { get => GetFlag(0x35, 0); set => SetFlag(0x35, 0, value); }
public bool RibbonMasterCoolness { get => GetFlag(0x35, 1); set => SetFlag(0x35, 1, value); }
public bool RibbonMasterBeauty { get => GetFlag(0x35, 2); set => SetFlag(0x35, 2, value); }
public bool RibbonMasterCuteness { get => GetFlag(0x35, 3); set => SetFlag(0x35, 3, value); }
public bool RibbonMasterCleverness { get => GetFlag(0x35, 4); set => SetFlag(0x35, 4, value); }
public bool RibbonMasterToughness { get => GetFlag(0x35, 5); set => SetFlag(0x35, 5, value); }
public bool RibbonChampionAlola { get => GetFlag(0x35, 6); set => SetFlag(0x35, 6, value); }
public bool RibbonBattleRoyale { get => GetFlag(0x35, 7); set => SetFlag(0x35, 7, value); }
public bool RibbonBattleTreeGreat { get => GetFlag(0x36, 0); set => SetFlag(0x36, 0, value); }
public bool RibbonBattleTreeMaster { get => GetFlag(0x36, 1); set => SetFlag(0x36, 1, value); }
public bool RibbonChampionGalar { get => GetFlag(0x36, 2); set => SetFlag(0x36, 2, value); }
public bool RibbonTowerMaster { get => GetFlag(0x36, 3); set => SetFlag(0x36, 3, value); }
public bool RibbonMasterRank { get => GetFlag(0x36, 4); set => SetFlag(0x36, 4, value); }
public bool RibbonMarkLunchtime { get => GetFlag(0x36, 5); set => SetFlag(0x36, 5, value); }
public bool RibbonMarkSleepyTime { get => GetFlag(0x36, 6); set => SetFlag(0x36, 6, value); }
public bool RibbonMarkDusk { get => GetFlag(0x36, 7); set => SetFlag(0x36, 7, value); }
public bool RibbonMarkDawn { get => GetFlag(0x37, 0); set => SetFlag(0x37, 0, value); }
public bool RibbonMarkCloudy { get => GetFlag(0x37, 1); set => SetFlag(0x37, 1, value); }
public bool RibbonMarkRainy { get => GetFlag(0x37, 2); set => SetFlag(0x37, 2, value); }
public bool RibbonMarkStormy { get => GetFlag(0x37, 3); set => SetFlag(0x37, 3, value); }
public bool RibbonMarkSnowy { get => GetFlag(0x37, 4); set => SetFlag(0x37, 4, value); }
public bool RibbonMarkBlizzard { get => GetFlag(0x37, 5); set => SetFlag(0x37, 5, value); }
public bool RibbonMarkDry { get => GetFlag(0x37, 6); set => SetFlag(0x37, 6, value); }
public bool RibbonMarkSandstorm { get => GetFlag(0x37, 7); set => SetFlag(0x37, 7, value); }
public byte RibbonCountMemoryContest { get => Data[0x38]; set => HasContestMemoryRibbon = (Data[0x38] = value) != 0; }
public byte RibbonCountMemoryBattle { get => Data[0x39]; set => HasBattleMemoryRibbon = (Data[0x39] = value) != 0; }
// !!! no padding, unlike PKM formats!
// 0x3E Ribbon 3
public bool RibbonMarkMisty { get => GetFlag(0x3A, 0); set => SetFlag(0x3A, 0, value); }
public bool RibbonMarkDestiny { get => GetFlag(0x3A, 1); set => SetFlag(0x3A, 1, value); }
public bool RibbonMarkFishing { get => GetFlag(0x3A, 2); set => SetFlag(0x3A, 2, value); }
public bool RibbonMarkCurry { get => GetFlag(0x3A, 3); set => SetFlag(0x3A, 3, value); }
public bool RibbonMarkUncommon { get => GetFlag(0x3A, 4); set => SetFlag(0x3A, 4, value); }
public bool RibbonMarkRare { get => GetFlag(0x3A, 5); set => SetFlag(0x3A, 5, value); }
public bool RibbonMarkRowdy { get => GetFlag(0x3A, 6); set => SetFlag(0x3A, 6, value); }
public bool RibbonMarkAbsentMinded { get => GetFlag(0x3A, 7); set => SetFlag(0x3A, 7, value); }
public bool RibbonMarkJittery { get => GetFlag(0x3B, 0); set => SetFlag(0x3B, 0, value); }
public bool RibbonMarkExcited { get => GetFlag(0x3B, 1); set => SetFlag(0x3B, 1, value); }
public bool RibbonMarkCharismatic { get => GetFlag(0x3B, 2); set => SetFlag(0x3B, 2, value); }
public bool RibbonMarkCalmness { get => GetFlag(0x3B, 3); set => SetFlag(0x3B, 3, value); }
public bool RibbonMarkIntense { get => GetFlag(0x3B, 4); set => SetFlag(0x3B, 4, value); }
public bool RibbonMarkZonedOut { get => GetFlag(0x3B, 5); set => SetFlag(0x3B, 5, value); }
public bool RibbonMarkJoyful { get => GetFlag(0x3B, 6); set => SetFlag(0x3B, 6, value); }
public bool RibbonMarkAngry { get => GetFlag(0x3B, 7); set => SetFlag(0x3B, 7, value); }
public bool RibbonMarkSmiley { get => GetFlag(0x3C, 0); set => SetFlag(0x3C, 0, value); }
public bool RibbonMarkTeary { get => GetFlag(0x3C, 1); set => SetFlag(0x3C, 1, value); }
public bool RibbonMarkUpbeat { get => GetFlag(0x3C, 2); set => SetFlag(0x3C, 2, value); }
public bool RibbonMarkPeeved { get => GetFlag(0x3C, 3); set => SetFlag(0x3C, 3, value); }
public bool RibbonMarkIntellectual { get => GetFlag(0x3C, 4); set => SetFlag(0x3C, 4, value); }
public bool RibbonMarkFerocious { get => GetFlag(0x3C, 5); set => SetFlag(0x3C, 5, value); }
public bool RibbonMarkCrafty { get => GetFlag(0x3C, 6); set => SetFlag(0x3C, 6, value); }
public bool RibbonMarkScowling { get => GetFlag(0x3C, 7); set => SetFlag(0x3C, 7, value); }
public bool RibbonMarkKindly { get => GetFlag(0x3D, 0); set => SetFlag(0x3D, 0, value); }
public bool RibbonMarkFlustered { get => GetFlag(0x3D, 1); set => SetFlag(0x3D, 1, value); }
public bool RibbonMarkPumpedUp { get => GetFlag(0x3D, 2); set => SetFlag(0x3D, 2, value); }
public bool RibbonMarkZeroEnergy { get => GetFlag(0x3D, 3); set => SetFlag(0x3D, 3, value); }
public bool RibbonMarkPrideful { get => GetFlag(0x3D, 4); set => SetFlag(0x3D, 4, value); }
public bool RibbonMarkUnsure { get => GetFlag(0x3D, 5); set => SetFlag(0x3D, 5, value); }
public bool RibbonMarkHumble { get => GetFlag(0x3D, 6); set => SetFlag(0x3D, 6, value); }
public bool RibbonMarkThorny { get => GetFlag(0x3D, 7); set => SetFlag(0x3D, 7, value); }
public bool RibbonMarkVigor { get => GetFlag(0x3E, 0); set => SetFlag(0x3E, 0, value); }
public bool RibbonMarkSlump { get => GetFlag(0x3E, 1); set => SetFlag(0x3E, 1, value); }
public bool RibbonHisui { get => GetFlag(0x3E, 2); set => SetFlag(0x3E, 2, value); }
public bool RibbonTwinklingStar { get => GetFlag(0x3E, 3); set => SetFlag(0x3E, 3, value); }
public bool RibbonChampionPaldea { get => GetFlag(0x3E, 4); set => SetFlag(0x3E, 4, value); }
public bool RibbonMarkJumbo { get => GetFlag(0x3E, 5); set => SetFlag(0x3E, 5, value); }
public bool RibbonMarkMini { get => GetFlag(0x3E, 6); set => SetFlag(0x3E, 6, value); }
public bool RibbonMarkItemfinder { get => GetFlag(0x3E, 7); set => SetFlag(0x3E, 7, value); }
public bool RibbonMarkPartner { get => GetFlag(0x3F, 0); set => SetFlag(0x3F, 0, value); }
public bool RibbonMarkGourmand { get => GetFlag(0x3F, 1); set => SetFlag(0x3F, 1, value); }
public bool RibbonOnceInALifetime { get => GetFlag(0x3F, 2); set => SetFlag(0x3F, 2, value); }
public bool RibbonMarkAlpha { get => GetFlag(0x3F, 3); set => SetFlag(0x3F, 3, value); }
public bool RibbonMarkMightiest { get => GetFlag(0x3F, 4); set => SetFlag(0x3F, 4, value); }
public bool RibbonMarkTitan { get => GetFlag(0x3F, 5); set => SetFlag(0x3F, 5, value); }
public bool RibbonPartner { get => GetFlag(0x3F, 6); set => SetFlag(0x3F, 6, value); }
public bool RIB45_7 { get => GetFlag(0x3F, 7); set => SetFlag(0x3F, 7, value); }
public bool RIB46_0 { get => GetFlag(0x40, 0); set => SetFlag(0x40, 0, value); }
public bool RIB46_1 { get => GetFlag(0x40, 1); set => SetFlag(0x40, 1, value); }
public bool RIB46_2 { get => GetFlag(0x40, 2); set => SetFlag(0x40, 2, value); }
public bool RIB46_3 { get => GetFlag(0x40, 3); set => SetFlag(0x40, 3, value); }
public bool RIB46_4 { get => GetFlag(0x40, 4); set => SetFlag(0x40, 4, value); }
public bool RIB46_5 { get => GetFlag(0x40, 5); set => SetFlag(0x40, 5, value); }
public bool RIB46_6 { get => GetFlag(0x40, 6); set => SetFlag(0x40, 6, value); }
public bool RIB46_7 { get => GetFlag(0x40, 7); set => SetFlag(0x40, 7, value); }
public bool RIB47_0 { get => GetFlag(0x41, 0); set => SetFlag(0x41, 0, value); }
public bool RIB47_1 { get => GetFlag(0x41, 1); set => SetFlag(0x41, 1, value); }
public bool RIB47_2 { get => GetFlag(0x41, 2); set => SetFlag(0x41, 2, value); }
public bool RIB47_3 { get => GetFlag(0x41, 3); set => SetFlag(0x41, 3, value); }
public bool RIB47_4 { get => GetFlag(0x41, 4); set => SetFlag(0x41, 4, value); }
public bool RIB47_5 { get => GetFlag(0x41, 5); set => SetFlag(0x41, 5, value); }
public bool RIB47_6 { get => GetFlag(0x41, 6); set => SetFlag(0x41, 6, value); }
public bool RIB47_7 { get => GetFlag(0x41, 7); set => SetFlag(0x41, 7, value); }
public int RibbonCount => BitOperations.PopCount(ReadUInt64LittleEndian(Data[0x30..]) & 0b00000000_00011111__11111111_11111111__11111111_11111111__11111111_11111111)
+ BitOperations.PopCount(ReadUInt64LittleEndian(Data[0x3A..]) & 0b00000000_00000000__00000100_00011100__00000000_00000000__00000000_00000000);
public int MarkCount => BitOperations.PopCount(ReadUInt64LittleEndian(Data[0x30..]) & 0b11111111_11100000__00000000_00000000__00000000_00000000__00000000_00000000)
+ BitOperations.PopCount(ReadUInt64LittleEndian(Data[0x3A..]) & 0b00000000_00000000__00111011_11100011__11111111_11111111__11111111_11111111);
public int RibbonMarkCount => BitOperations.PopCount(ReadUInt64LittleEndian(Data[0x30..]) & 0b11111111_11111111__11111111_11111111__11111111_11111111__11111111_11111111)
+ BitOperations.PopCount(ReadUInt64LittleEndian(Data[0x3A..]) & 0b00000000_00000000__00111111_11111111__11111111_11111111__11111111_11111111);
public bool HasMarkEncounter8 => BitOperations.PopCount(ReadUInt64LittleEndian(Data[0x30..]) & 0b11111111_11100000__00000000_00000000__00000000_00000000__00000000_00000000)
+ BitOperations.PopCount(ReadUInt64LittleEndian(Data[0x3A..]) & 0b00000000_00000000__00000000_00000011__11111111_11111111__11111111_11111111) != 0;
public bool HasMarkEncounter9 => (Data[0x3F] & 0b00111000) != 0;
public byte HeightScalar { get => Data[0x42]; set => Data[0x42] = value; }
public byte WeightScalar { get => Data[0x43]; set => Data[0x43] = value; }
public Span<byte> Nickname_Trash => Data.Slice(0x44, 26);
public string Nickname
{
get => StringConverter8.GetString(Nickname_Trash);
set => StringConverter8.SetString(Nickname_Trash, value, 12, StringConverterOption.None);
}
public int Stat_HPCurrent { get => ReadUInt16LittleEndian(Data[0x5E..]); set => WriteUInt16LittleEndian(Data[0x5E..], (ushort)value); }
public int IV_HP { get => Data[0x60]; set => Data[0x60] = (byte)value; }
public int IV_ATK { get => Data[0x61]; set => Data[0x61] = (byte)value; }
public int IV_DEF { get => Data[0x62]; set => Data[0x62] = (byte)value; }
public int IV_SPE { get => Data[0x63]; set => Data[0x63] = (byte)value; }
public int IV_SPA { get => Data[0x64]; set => Data[0x64] = (byte)value; }
public int IV_SPD { get => Data[0x65]; set => Data[0x65] = (byte)value; }
public bool IsEgg { get => Data[0x66] != 0; set => Data[0x66] = (byte)(value ? 1 : 0); }
public bool IsNicknamed { get => Data[0x67] != 0; set => Data[0x67] = (byte)(value ? 1 : 0); }
public int Status_Condition { get => ReadInt32LittleEndian(Data[0x68..]); set => WriteInt32LittleEndian(Data[0x68..], value); }
public Span<byte> HT_Trash => Data.Slice(0x6C, 26);
public string HT_Name
{
get => StringConverter8.GetString(HT_Trash);
set => StringConverter8.SetString(HT_Trash, value, 12, StringConverterOption.None);
}
public int HT_Gender { get => Data[0x86]; set => Data[0x86] = (byte)value; }
public byte HT_Language { get => Data[0x87]; set => Data[0x87] = value; }
public int CurrentHandler { get => Data[0x88]; set => Data[0x88] = (byte)value; }
public int HT_TrainerID { get => ReadUInt16LittleEndian(Data[0x89..]); set => WriteUInt16LittleEndian(Data[0x89..], (ushort)value); } // unused?
public int HT_Friendship { get => Data[0x8B]; set => Data[0x8B] = (byte)value; }
public byte HT_Intensity { get => Data[0x8C]; set => Data[0x8C] = value; }
public byte HT_Memory { get => Data[0x8D]; set => Data[0x8D] = value; }
public byte HT_Feeling { get => Data[0x8E]; set => Data[0x8E] = value; }
public ushort HT_TextVar { get => ReadUInt16LittleEndian(Data[0x8F..]); set => WriteUInt16LittleEndian(Data[0x8F..], value); }
public int Version { get => Data[0x91]; set => Data[0x91] = (byte)value; }
public byte BattleVersion { get => Data[0x92]; set => Data[0x92] = value; }
public int Language { get => Data[0x93]; set => Data[0x93] = (byte)value; }
public uint FormArgument { get => ReadUInt32LittleEndian(Data[0x94..]); set => WriteUInt32LittleEndian(Data[0x94..], value); }
public byte FormArgumentRemain { get => (byte)FormArgument; set => FormArgument = (FormArgument & ~0xFFu) | value; }
public byte FormArgumentElapsed { get => (byte)(FormArgument >> 8); set => FormArgument = (FormArgument & ~0xFF00u) | (uint)(value << 8); }
public byte FormArgumentMaximum { get => (byte)(FormArgument >> 16); set => FormArgument = (FormArgument & ~0xFF0000u) | (uint)(value << 16); }
public sbyte AffixedRibbon { get => (sbyte)Data[0x98]; set => Data[0x98] = (byte)value; } // selected ribbon
public Span<byte> OT_Trash => Data.Slice(0x99, 26);
public string OT_Name
{
get => StringConverter8.GetString(OT_Trash);
set => StringConverter8.SetString(OT_Trash, value, 12, StringConverterOption.None);
}
public int OT_Friendship { get => Data[0xB3]; set => Data[0xB3] = (byte)value; }
public byte OT_Intensity { get => Data[0xB4]; set => Data[0xB4] = value; }
public byte OT_Memory { get => Data[0xB5]; set => Data[0xB5] = value; }
public ushort OT_TextVar { get => ReadUInt16LittleEndian(Data[0xB6..]); set => WriteUInt16LittleEndian(Data[0xB6..], value); }
public byte OT_Feeling { get => Data[0xB8]; set => Data[0xB8] = value; }
public int Egg_Year { get => Data[0xB9]; set => Data[0xB9] = (byte)value; }
public int Egg_Month { get => Data[0xBA]; set => Data[0xBA] = (byte)value; }
public int Egg_Day { get => Data[0xBB]; set => Data[0xBB] = (byte)value; }
public int Met_Year { get => Data[0xBC]; set => Data[0xBC] = (byte)value; }
public int Met_Month { get => Data[0xBD]; set => Data[0xBD] = (byte)value; }
public int Met_Day { get => Data[0xBE]; set => Data[0xBE] = (byte)value; }
public int Met_Level { get => Data[0xBF]; set => Data[0xBF] = (byte)value; }
public int OT_Gender { get => Data[0xC0]; set => Data[0xC0] = (byte)value; }
public byte HyperTrainFlags { get => Data[0xC1]; set => Data[0xC1] = value; }
public bool HT_HP { get => ((HyperTrainFlags >> 0) & 1) == 1; set => HyperTrainFlags = (byte)((HyperTrainFlags & ~(1 << 0)) | ((value ? 1 : 0) << 0)); }
public bool HT_ATK { get => ((HyperTrainFlags >> 1) & 1) == 1; set => HyperTrainFlags = (byte)((HyperTrainFlags & ~(1 << 1)) | ((value ? 1 : 0) << 1)); }
public bool HT_DEF { get => ((HyperTrainFlags >> 2) & 1) == 1; set => HyperTrainFlags = (byte)((HyperTrainFlags & ~(1 << 2)) | ((value ? 1 : 0) << 2)); }
public bool HT_SPA { get => ((HyperTrainFlags >> 3) & 1) == 1; set => HyperTrainFlags = (byte)((HyperTrainFlags & ~(1 << 3)) | ((value ? 1 : 0) << 3)); }
public bool HT_SPD { get => ((HyperTrainFlags >> 4) & 1) == 1; set => HyperTrainFlags = (byte)((HyperTrainFlags & ~(1 << 4)) | ((value ? 1 : 0) << 4)); }
public bool HT_SPE { get => ((HyperTrainFlags >> 5) & 1) == 1; set => HyperTrainFlags = (byte)((HyperTrainFlags & ~(1 << 5)) | ((value ? 1 : 0) << 5)); }
public int HeldItem { get => ReadUInt16LittleEndian(Data[0xC2..]); set => WriteUInt16LittleEndian(Data[0xC2..], (ushort)value); }
public int MarkingCount => 6;
public TrainerIDFormat TrainerIDDisplayFormat => ((GameVersion)Version).GetGeneration() >= 7 ? TrainerIDFormat.SixDigit : TrainerIDFormat.SixteenBit;
public int GetMarking(int index)
{
if ((uint)index >= MarkingCount)
throw new ArgumentOutOfRangeException(nameof(index));
return (MarkValue >> (index * 2)) & 3;
}
public void SetMarking(int index, int value)
{
if ((uint)index >= MarkingCount)
throw new ArgumentOutOfRangeException(nameof(index));
var shift = index * 2;
MarkValue = (MarkValue & ~(0b11 << shift)) | ((value & 3) << shift);
}
public void CopyFrom(PKM pk)
{
EncryptionConstant = pk.EncryptionConstant;
PID = pk.PID;
Species = pk.Species;
Form = pk.Form;
Gender = pk.Gender;
TID16 = pk.TID16;
SID16 = pk.SID16;
EXP = pk.EXP;
MarkValue = pk.MarkValue;
Nature = pk.Nature;
StatNature = pk.StatNature;
FatefulEncounter = pk.FatefulEncounter;
// HeldItem = pk.HeldItem;
IV_HP = pk.IV_HP;
IV_ATK = pk.IV_ATK;
IV_DEF = pk.IV_DEF;
IV_SPE = pk.IV_SPE;
IV_SPA = pk.IV_SPA;
IV_SPD = pk.IV_SPD;
IsEgg = pk.IsEgg;
IsNicknamed = pk.IsNicknamed;
EV_HP = pk.EV_HP;
EV_ATK = pk.EV_ATK;
EV_DEF = pk.EV_DEF;
EV_SPE = pk.EV_SPE;
EV_SPA = pk.EV_SPA;
EV_SPD = pk.EV_SPD;
HT_Gender = pk.HT_Gender;
CurrentHandler = pk.CurrentHandler;
// pk.HT_TrainerID
HT_Friendship = pk.HT_Friendship;
Version = pk.Version;
Language = pk.Language;
OT_Friendship = pk.OT_Friendship;
Egg_Year = pk.Egg_Year;
Egg_Month = pk.Egg_Month;
Egg_Day = pk.Egg_Day;
Met_Year = pk.Met_Year;
Met_Month = pk.Met_Month;
Met_Day = pk.Met_Day;
Met_Level = pk.Met_Level;
OT_Gender = pk.OT_Gender;
CopyConditionalInterfaceFrom(pk);
pk.OT_Trash.CopyTo(OT_Trash);
pk.Nickname_Trash.CopyTo(Nickname_Trash);
pk.HT_Trash.CopyTo(HT_Trash);
CopyConditionalRibbonMarkFrom(pk);
}
public void CopyTo(PKM pk)
{
pk.EncryptionConstant = EncryptionConstant;
pk.PID = PID;
pk.Species = Species;
pk.Form = Form;
pk.Gender = Gender;
pk.TID16 = TID16;
pk.SID16 = SID16;
pk.EXP = EXP;
pk.MarkValue = MarkValue;
pk.Nature = Nature;
pk.StatNature = StatNature;
pk.FatefulEncounter = FatefulEncounter;
pk.HeldItem = HeldItem;
pk.IV_HP = IV_HP;
pk.IV_ATK = IV_ATK;
pk.IV_DEF = IV_DEF;
pk.IV_SPE = IV_SPE;
pk.IV_SPA = IV_SPA;
pk.IV_SPD = IV_SPD;
pk.IsEgg = IsEgg;
pk.IsNicknamed = IsNicknamed;
pk.EV_HP = EV_HP;
pk.EV_ATK = EV_ATK;
pk.EV_DEF = EV_DEF;
pk.EV_SPE = EV_SPE;
pk.EV_SPA = EV_SPA;
pk.EV_SPD = EV_SPD;
pk.HT_Gender = HT_Gender;
pk.CurrentHandler = CurrentHandler;
// pk.HT_TrainerID
pk.HT_Friendship = HT_Friendship;
pk.Version = Version;
pk.Language = Language;
pk.OT_Friendship = OT_Friendship;
pk.Egg_Year = Egg_Year;
pk.Egg_Month = Egg_Month;
pk.Egg_Day = Egg_Day;
pk.Met_Year = Met_Year;
pk.Met_Month = Met_Month;
pk.Met_Day = Met_Day;
pk.Met_Level = Met_Level;
pk.OT_Gender = OT_Gender;
CopyConditionalInterfaceTo(pk);
OT_Trash.CopyTo(pk.OT_Trash);
Nickname_Trash.CopyTo(pk.Nickname_Trash);
HT_Trash.CopyTo(pk.HT_Trash);
CopyConditionalRibbonMarkTo(pk);
}
private void CopyConditionalInterfaceTo(PKM pk)
{
if (pk is IScaledSize ss)
{
ss.HeightScalar = HeightScalar;
ss.WeightScalar = WeightScalar;
}
if (pk is IMemoryOT ot)
{
ot.OT_Intensity = OT_Intensity;
ot.OT_Memory = OT_Memory;
ot.OT_TextVar = OT_TextVar;
ot.OT_Feeling = OT_Feeling;
}
if (pk is IMemoryHT hm)
{
hm.HT_Intensity = HT_Intensity;
hm.HT_Memory = HT_Memory;
hm.HT_Feeling = HT_Feeling;
hm.HT_TextVar = HT_TextVar;
}
if (pk is IHandlerLanguage hl)
hl.HT_Language = HT_Language;
if (pk is IContestStats cm)
this.CopyContestStatsTo(cm);
if (pk is IRibbonSetAffixed affix)
affix.AffixedRibbon = AffixedRibbon;
if (pk is IHyperTrain hy)
hy.HyperTrainFlags = HyperTrainFlags;
if (pk is IFormArgument fa)
fa.FormArgument = FormArgument;
if (pk is IBattleVersion bv)
bv.BattleVersion = BattleVersion;
if (pk is IFavorite fav)
fav.IsFavorite = IsFavorite;
if (pk is IHomeTrack home)
home.Tracker = Tracker;
}
private void CopyConditionalInterfaceFrom(PKM pk)
{
if (pk is IScaledSize ss)
{
HeightScalar = ss.HeightScalar;
WeightScalar = ss.WeightScalar;
}
if (pk is IMemoryOT ot)
{
OT_Intensity = ot.OT_Intensity;
OT_Memory = ot.OT_Memory;
OT_TextVar = ot.OT_TextVar;
OT_Feeling = ot.OT_Feeling;
}
if (pk is IMemoryHT ht)
{
HT_Intensity = ht.HT_Intensity;
HT_Memory = ht.HT_Memory;
HT_Feeling = ht.HT_Feeling;
HT_TextVar = ht.HT_TextVar;
}
if (pk is IHandlerLanguage hl)
HT_Language = hl.HT_Language;
if (pk is IContestStats cm)
cm.CopyContestStatsTo(this);
if (pk is IRibbonSetAffixed affix)
AffixedRibbon = affix.AffixedRibbon;
if (pk is IHyperTrain hy)
HyperTrainFlags = hy.HyperTrainFlags;
if (pk is IFormArgument fa)
FormArgument = fa.FormArgument;
if (pk is IBattleVersion bv)
BattleVersion = bv.BattleVersion;
if (pk is IFavorite fav)
IsFavorite = fav.IsFavorite;
if (pk is IHomeTrack home)
Tracker = home.Tracker;
}
private void CopyConditionalRibbonMarkTo(PKM pk)
{
if (pk is IRibbonSetEvent3 e3) this.CopyRibbonSetEvent3 (e3);
if (pk is IRibbonSetEvent4 e4) this.CopyRibbonSetEvent4 (e4);
if (pk is IRibbonSetCommon3 c3) this.CopyRibbonSetCommon3(c3);
if (pk is IRibbonSetCommon4 c4) this.CopyRibbonSetCommon4(c4);
if (pk is IRibbonSetCommon6 c6) this.CopyRibbonSetCommon6(c6);
if (pk is IRibbonSetMemory6 m6) this.CopyRibbonSetMemory6(m6);
if (pk is IRibbonSetCommon7 c7) this.CopyRibbonSetCommon7(c7);
if (pk is IRibbonSetCommon8 c8) this.CopyRibbonSetCommon8(c8);
if (pk is IRibbonSetMark8 m8) this.CopyRibbonSetMark8 (m8);
if (pk is IRibbonSetCommon9 c9) this.CopyRibbonSetCommon9(c9);
if (pk is IRibbonSetMark9 m9) this.CopyRibbonSetMark9 (m9);
}
private void CopyConditionalRibbonMarkFrom(PKM pk)
{
if (pk is IRibbonSetEvent3 e3) e3.CopyRibbonSetEvent3 (this);
if (pk is IRibbonSetEvent4 e4) e4.CopyRibbonSetEvent4 (this);
if (pk is IRibbonSetCommon3 c3) c3.CopyRibbonSetCommon3(this);
if (pk is IRibbonSetCommon4 c4) c4.CopyRibbonSetCommon4(this);
if (pk is IRibbonSetCommon6 c6) c6.CopyRibbonSetCommon6(this);
if (pk is IRibbonSetMemory6 m6) m6.CopyRibbonSetMemory6(this);
if (pk is IRibbonSetCommon7 c7) c7.CopyRibbonSetCommon7(this);
if (pk is IRibbonSetCommon8 c8) c8.CopyRibbonSetCommon8(this);
if (pk is IRibbonSetMark8 m8) m8.CopyRibbonSetMark8 (this);
if (pk is IRibbonSetCommon9 c9) c9.CopyRibbonSetCommon9(this);
if (pk is IRibbonSetMark9 m9) m9.CopyRibbonSetMark9 (this);
}
}