From 296fec2bd78ea060d7f96213b5c17f144b8718b6 Mon Sep 17 00:00:00 2001 From: Greg Edwards Date: Mon, 22 Nov 2021 01:24:24 -0500 Subject: [PATCH] =?UTF-8?q?Populate=20moveset=20interfaces=20on=20Battle?= =?UTF-8?q?=20Tower=20Pok=C3=A9mon.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- library/Data/DataMysql.cs | 97 +++++++++----------- library/Data/Database.cs | 5 + library/Structures/BattleSubwayPokemon5.cs | 48 ++++++---- library/Structures/BattleSubwayProfile5.cs | 2 +- library/Structures/BattleSubwayRecord5.cs | 4 +- library/Structures/BattleTowerPokemon4.cs | 62 ++++++------- library/Structures/BattleTowerPokemonBase.cs | 56 ++++++++++- library/Structures/BattleTowerProfile4.cs | 2 +- library/Structures/BattleTowerRecord4.cs | 4 +- library/Structures/MoveSlot.cs | 9 +- 10 files changed, 178 insertions(+), 111 deletions(-) diff --git a/library/Data/DataMysql.cs b/library/Data/DataMysql.cs index e2d9ad06..f9373772 100644 --- a/library/Data/DataMysql.cs +++ b/library/Data/DataMysql.cs @@ -741,15 +741,15 @@ namespace PkmnFoundations.Data List result = new List(15); result.Add(new MySqlParameter("@species", pokemon.SpeciesID)); result.Add(new MySqlParameter("@held_item", pokemon.HeldItemID)); - result.Add(new MySqlParameter("@move1", pokemon.Moveset[0])); - result.Add(new MySqlParameter("@move2", pokemon.Moveset[1])); - result.Add(new MySqlParameter("@move3", pokemon.Moveset[2])); - result.Add(new MySqlParameter("@move4", pokemon.Moveset[3])); + result.Add(new MySqlParameter("@move1", (ushort)pokemon.Moves[0].MoveID)); + result.Add(new MySqlParameter("@move2", (ushort)pokemon.Moves[1].MoveID)); + result.Add(new MySqlParameter("@move3", (ushort)pokemon.Moves[2].MoveID)); + result.Add(new MySqlParameter("@move4", (ushort)pokemon.Moves[3].MoveID)); result.Add(new MySqlParameter("@trainer_id", pokemon.TrainerID)); result.Add(new MySqlParameter("@personality", pokemon.Personality)); result.Add(new MySqlParameter("@ivs", pokemon.IVs.ToInt32() | (int)pokemon.IvFlags)); result.Add(new MySqlParameter("@evs", pokemon.EVs.ToArray())); - result.Add(new MySqlParameter("@unknown1", pokemon.Unknown1)); + result.Add(new MySqlParameter("@unknown1", pokemon.GetPpUps())); result.Add(new MySqlParameter("@language", (byte)pokemon.Language)); result.Add(new MySqlParameter("@ability", pokemon.AbilityID)); result.Add(new MySqlParameter("@happiness", pokemon.Happiness)); @@ -926,26 +926,23 @@ namespace PkmnFoundations.Data private BattleTowerPokemon4 BattleTowerPokemon4FromReader(MySqlDataReader reader, Pokedex.Pokedex pokedex) { - BattleTowerPokemon4 result = new BattleTowerPokemon4(pokedex); - result.SpeciesID = reader.GetUInt16(2); - result.HeldItemID = reader.GetUInt16(3); - result.Moveset = new ushort[4]; - result.Moveset[0] = reader.GetUInt16(4); - result.Moveset[1] = reader.GetUInt16(5); - result.Moveset[2] = reader.GetUInt16(6); - result.Moveset[3] = reader.GetUInt16(7); - result.TrainerID = reader.GetUInt32(8); - result.Personality = reader.GetUInt32(9); - result.IVs = new IvStatValues((int)(reader.GetUInt32(10) & 0x3fffffff)); - result.IvFlags = reader.GetUInt32(10) & 0xc0000000u; - result.EVs = new ByteStatValues(reader.GetByteArray(11, 6)); - result.Unknown1 = reader.GetByte(12); - result.Language = (Languages)reader.GetByte(13); - result.AbilityID = reader.GetByte(14); - result.Happiness = reader.GetByte(15); - result.NicknameEncoded = new EncodedString4(reader.GetByteArray(16, 22)); - - return result; + return new BattleTowerPokemon4(pokedex, + Database.Cast(reader["Species"]), + Database.Cast(reader["HeldItem"]), + Database.Cast(reader["Move1"]), + Database.Cast(reader["Move2"]), + Database.Cast(reader["Move3"]), + Database.Cast(reader["Move4"]), + Database.Cast(reader["TrainerID"]), + Database.Cast(reader["Personality"]), + Database.Cast(reader["IVs"]), + Database.Cast(reader["EVs"]), + Database.Cast(reader["Unknown1"]), + (Languages)Database.Cast(reader["Language"]), + Database.Cast(reader["Ability"]), + Database.Cast(reader["Happiness"]), + new EncodedString4(Database.Cast(reader["Nickname"]), 0, 22) + ); } public BattleTowerProfile4[] BattleTowerGetLeaders4(MySqlTransaction tran, Pokedex.Pokedex pokedex, byte rank, byte roomNum) @@ -1745,15 +1742,15 @@ namespace PkmnFoundations.Data List result = new List(15); result.Add(new MySqlParameter("@species", pokemon.SpeciesID)); result.Add(new MySqlParameter("@held_item", pokemon.HeldItemID)); - result.Add(new MySqlParameter("@move1", pokemon.Moveset[0])); - result.Add(new MySqlParameter("@move2", pokemon.Moveset[1])); - result.Add(new MySqlParameter("@move3", pokemon.Moveset[2])); - result.Add(new MySqlParameter("@move4", pokemon.Moveset[3])); + result.Add(new MySqlParameter("@move1", pokemon.Moves[0].MoveID)); + result.Add(new MySqlParameter("@move2", pokemon.Moves[1].MoveID)); + result.Add(new MySqlParameter("@move3", pokemon.Moves[2].MoveID)); + result.Add(new MySqlParameter("@move4", pokemon.Moves[3].MoveID)); result.Add(new MySqlParameter("@trainer_id", pokemon.TrainerID)); result.Add(new MySqlParameter("@personality", pokemon.Personality)); result.Add(new MySqlParameter("@ivs", pokemon.IVs.ToInt32() | (int)pokemon.IvFlags)); result.Add(new MySqlParameter("@evs", pokemon.EVs.ToArray())); - result.Add(new MySqlParameter("@unknown1", pokemon.Unknown1)); + result.Add(new MySqlParameter("@unknown1", pokemon.GetPpUps())); result.Add(new MySqlParameter("@language", (byte)pokemon.Language)); result.Add(new MySqlParameter("@ability", pokemon.AbilityID)); result.Add(new MySqlParameter("@happiness", pokemon.Happiness)); @@ -1933,28 +1930,24 @@ namespace PkmnFoundations.Data private BattleSubwayPokemon5 BattleSubwayPokemon5FromReader(MySqlDataReader reader, Pokedex.Pokedex pokedex) { - // xxx: Don't use ordinals - BattleSubwayPokemon5 result = new BattleSubwayPokemon5(pokedex); - result.SpeciesID = reader.GetUInt16(2); - result.HeldItemID = reader.GetUInt16(3); - result.Moveset = new ushort[4]; - result.Moveset[0] = reader.GetUInt16(4); - result.Moveset[1] = reader.GetUInt16(5); - result.Moveset[2] = reader.GetUInt16(6); - result.Moveset[3] = reader.GetUInt16(7); - result.TrainerID = reader.GetUInt32(8); - result.Personality = reader.GetUInt32(9); - result.IVs = new IvStatValues((int)(reader.GetUInt32(10) & 0x3fffffff)); - result.IvFlags = reader.GetUInt32(10) & 0xc0000000u; - result.EVs = new ByteStatValues(reader.GetByteArray(11, 6)); - result.Unknown1 = reader.GetByte(12); - result.Language = (Languages)reader.GetByte(13); - result.AbilityID = reader.GetByte(14); - result.Happiness = reader.GetByte(15); - result.NicknameEncoded = new EncodedString5(reader.GetByteArray(16, 22)); - result.Unknown2 = reader.GetUInt32(17); - - return result; + return new BattleSubwayPokemon5(pokedex, + Database.Cast(reader["Species"]), + Database.Cast(reader["HeldItem"]), + Database.Cast(reader["Move1"]), + Database.Cast(reader["Move2"]), + Database.Cast(reader["Move3"]), + Database.Cast(reader["Move4"]), + Database.Cast(reader["TrainerID"]), + Database.Cast(reader["Personality"]), + Database.Cast(reader["IVs"]), + Database.Cast(reader["EVs"]), + Database.Cast(reader["Unknown1"]), + (Languages)Database.Cast(reader["Language"]), + Database.Cast(reader["Ability"]), + Database.Cast(reader["Happiness"]), + new EncodedString5(Database.Cast(reader["Nickname"]), 0, 22), + Database.Cast(reader["Unknown2"]) + ); } public override BattleSubwayProfile5[] BattleSubwayGetLeaders5(Pokedex.Pokedex pokedex, byte rank, byte roomNum) diff --git a/library/Data/Database.cs b/library/Data/Database.cs index 7bc1d64f..38c91e4b 100644 --- a/library/Data/Database.cs +++ b/library/Data/Database.cs @@ -58,6 +58,11 @@ namespace PkmnFoundations.Data #endregion #region Utility + public static T Cast(object value) + { + if (value is DBNull) value = null; + return (T)value; // Allow InvalidCastException to escape. + } #endregion #region GTS 4 diff --git a/library/Structures/BattleSubwayPokemon5.cs b/library/Structures/BattleSubwayPokemon5.cs index 04fd45e1..0ca7385e 100644 --- a/library/Structures/BattleSubwayPokemon5.cs +++ b/library/Structures/BattleSubwayPokemon5.cs @@ -14,7 +14,7 @@ namespace PkmnFoundations.Structures } public BattleSubwayPokemon5(Pokedex.Pokedex pokedex, ushort species, ushort held_item, ushort[] moveset, - uint ot, uint personality, uint ivs, byte[] evs, byte unknown1, + uint ot, uint personality, uint ivs, byte[] evs, byte pp_ups, Languages language, byte ability, byte happiness, EncodedString5 nickname, uint unknown2) : base(pokedex) { if (moveset == null) throw new ArgumentNullException("moveset"); @@ -26,13 +26,12 @@ namespace PkmnFoundations.Structures SpeciesID = species; HeldItemID = held_item; - Moveset = moveset.ToArray(); + GetMovesFromArray(Moves, pokedex, moveset, pp_ups); TrainerID = ot; Personality = personality; IVs = new IvStatValues((int)ivs & 0x3fffffff); IvFlags = ivs & 0xc0000000u; EVs = new ByteStatValues(evs); - Unknown1 = unknown1; Language = language; AbilityID = ability; Happiness = happiness; @@ -40,6 +39,15 @@ namespace PkmnFoundations.Structures Unknown2 = unknown2; } + public BattleSubwayPokemon5(Pokedex.Pokedex pokedex, ushort species, ushort held_item, + ushort move1, ushort move2, ushort move3, ushort move4, uint ot, uint personality, + uint ivs, byte[] evs, byte pp_ups, Languages language, byte ability, byte happiness, + EncodedString5 nickname, uint unknown2) : + this(pokedex, species, held_item, new ushort[] { move1, move2, move3, move4 }, + ot, personality, ivs, evs, pp_ups, language, ability, happiness, nickname, unknown2) + { + } + public BattleSubwayPokemon5(Pokedex.Pokedex pokedex, BinaryReader data) : base(pokedex) { Load(data); @@ -73,25 +81,22 @@ namespace PkmnFoundations.Structures } } - [Obsolete("Use IVs[] indexer.")] - public byte IV(Stats stat) - { - return IVs[stat]; - } - protected override void Save(BinaryWriter writer) { writer.Write((ushort)SpeciesID); writer.Write((ushort)HeldItemID); - for (int x = 0; x < 4; x++) + + ushort[] moveset = GetArrayFromMoves(Moves); + for (int i = 0; i < 4; i++) { - writer.Write(Moveset[x]); + writer.Write(moveset[i]); } + writer.Write(TrainerID); writer.Write(Personality); writer.Write(IVs.ToInt32() | (int)IvFlags); writer.Write(EVs.ToArray(), 0, 6); - writer.Write(Unknown1); + writer.Write(GetPpUpsFromMoves(Moves)); writer.Write((byte)Language); writer.Write((byte)AbilityID); writer.Write(Happiness); @@ -105,11 +110,13 @@ namespace PkmnFoundations.Structures { SpeciesID = reader.ReadUInt16(); HeldItemID = reader.ReadUInt16(); - Moveset = new ushort[4]; - for (int x = 0; x < 4; x++) + + ushort[] moveset = new ushort[4]; + for (int i = 0; i < 4; i++) { - Moveset[x] = reader.ReadUInt16(); + moveset[i] = reader.ReadUInt16(); } + TrainerID = reader.ReadUInt32(); Personality = reader.ReadUInt32(); uint ivs = reader.ReadUInt32(); @@ -117,7 +124,9 @@ namespace PkmnFoundations.Structures IvFlags = ivs & 0xc0000000u; EVs = new ByteStatValues(reader.ReadBytes(6)); - Unknown1 = reader.ReadByte(); + byte ppUps = reader.ReadByte(); + GetMovesFromArray(Moves, m_pokedex, moveset, ppUps); + Language = (Languages)reader.ReadByte(); AbilityID = reader.ReadByte(); Happiness = reader.ReadByte(); @@ -128,9 +137,12 @@ namespace PkmnFoundations.Structures public BattleSubwayPokemon5 Clone() { uint ivsField = (uint)(IVs.ToInt32() & 0x3fffffffu) | (IvFlags & 0xc0000000u); + ushort[] moveset = GetArrayFromMoves(Moves); + byte ppUps = GetPpUpsFromMoves(Moves); + BattleSubwayPokemon5 result = new BattleSubwayPokemon5(m_pokedex, - (ushort)SpeciesID, (ushort)HeldItemID, Moveset.ToArray(), - TrainerID, Personality, ivsField, EVs.ToArray(), Unknown1, + (ushort)SpeciesID, (ushort)HeldItemID, moveset, + TrainerID, Personality, ivsField, EVs.ToArray(), ppUps, Language, (byte)AbilityID, Happiness, NicknameEncoded, Unknown2); return result; diff --git a/library/Structures/BattleSubwayProfile5.cs b/library/Structures/BattleSubwayProfile5.cs index 21151f3d..cc68d2e1 100644 --- a/library/Structures/BattleSubwayProfile5.cs +++ b/library/Structures/BattleSubwayProfile5.cs @@ -52,7 +52,7 @@ namespace PkmnFoundations.Structures public TrendyPhrase5 PhraseLeader; // Different from GTS, 0 = male, 2 = female, 1 = Plato???? public byte Gender; - public byte Unknown; + public byte Unknown; // Probably trainer class. public byte[] Save() { diff --git a/library/Structures/BattleSubwayRecord5.cs b/library/Structures/BattleSubwayRecord5.cs index 42d68793..1d30a175 100644 --- a/library/Structures/BattleSubwayRecord5.cs +++ b/library/Structures/BattleSubwayRecord5.cs @@ -39,8 +39,8 @@ namespace PkmnFoundations.Structures public byte Rank; public byte RoomNum; public byte BattlesWon; - public byte[] Unknown4; // 5 bytes - public ulong Unknown5; + public byte[] Unknown4; // 5 bytes, appears to always be 00 00 00 00 00? + public ulong Unknown5; // Appears to be zero on AdmiralCurtiss's scraped data, but is very big ints on data being uploaded. public int PID; public byte[] Save() diff --git a/library/Structures/BattleTowerPokemon4.cs b/library/Structures/BattleTowerPokemon4.cs index 90d1d0eb..bde23df0 100644 --- a/library/Structures/BattleTowerPokemon4.cs +++ b/library/Structures/BattleTowerPokemon4.cs @@ -14,7 +14,7 @@ namespace PkmnFoundations.Structures } public BattleTowerPokemon4(Pokedex.Pokedex pokedex, ushort species, ushort held_item, ushort[] moveset, - uint ot, uint personality, uint ivs, byte[] evs, byte unknown1, + uint ot, uint personality, uint ivs, byte[] evs, byte pp_ups, Languages language, byte ability, byte happiness, EncodedString4 nickname) : base(pokedex) { if (moveset == null) throw new ArgumentNullException("moveset"); @@ -26,19 +26,27 @@ namespace PkmnFoundations.Structures SpeciesID = species; HeldItemID = held_item; - Moveset = moveset.ToArray(); + GetMovesFromArray(Moves, pokedex, moveset, pp_ups); TrainerID = ot; Personality = personality; IVs = new IvStatValues((int)ivs & 0x3fffffff); IvFlags = ivs & 0xc0000000u; EVs = new ByteStatValues(evs); - Unknown1 = unknown1; Language = language; AbilityID = ability; Happiness = happiness; NicknameEncoded = nickname; // todo: clone } + public BattleTowerPokemon4(Pokedex.Pokedex pokedex, ushort species, ushort held_item, + ushort move1, ushort move2, ushort move3, ushort move4, uint ot, uint personality, + uint ivs, byte[] evs, byte pp_ups, Languages language, byte ability, byte happiness, + EncodedString4 nickname) : + this(pokedex, species, held_item, new ushort[] { move1, move2, move3, move4 }, + ot, personality, ivs, evs, pp_ups, language, ability, happiness, nickname) + { + } + public BattleTowerPokemon4(Pokedex.Pokedex pokedex, BinaryReader data) : base(pokedex) { Load(data); @@ -70,25 +78,22 @@ namespace PkmnFoundations.Structures } } - [Obsolete("Use IVs[] indexer.")] - public byte IV(Stats stat) - { - return IVs[stat]; - } - protected override void Save(BinaryWriter writer) { writer.Write((ushort)SpeciesID); writer.Write((ushort)HeldItemID); - for (int x = 0; x < 4; x++) + + ushort[] moveset = GetArrayFromMoves(Moves); + for (int i = 0; i < 4; i++) { - writer.Write(Moveset[x]); + writer.Write(moveset[i]); } + writer.Write(TrainerID); writer.Write(Personality); writer.Write(IVs.ToInt32() | (int)IvFlags); writer.Write(EVs.ToArray(), 0, 6); - writer.Write(Unknown1); + writer.Write(GetPpUpsFromMoves(Moves)); writer.Write((byte)Language); writer.Write((byte)AbilityID); writer.Write(Happiness); @@ -101,11 +106,13 @@ namespace PkmnFoundations.Structures { SpeciesID = reader.ReadUInt16(); HeldItemID = reader.ReadUInt16(); - Moveset = new ushort[4]; - for (int x = 0; x < 4; x++) + + ushort[] moveset = new ushort[4]; + for (int i = 0; i < 4; i++) { - Moveset[x] = reader.ReadUInt16(); + moveset[i] = reader.ReadUInt16(); } + TrainerID = reader.ReadUInt32(); Personality = reader.ReadUInt32(); uint ivs = reader.ReadUInt32(); @@ -113,7 +120,9 @@ namespace PkmnFoundations.Structures IvFlags = ivs & 0xc0000000u; EVs = new ByteStatValues(reader.ReadBytes(6)); - Unknown1 = reader.ReadByte(); + byte ppUps = reader.ReadByte(); + GetMovesFromArray(Moves, m_pokedex, moveset, ppUps); + Language = (Languages)reader.ReadByte(); AbilityID = reader.ReadByte(); Happiness = reader.ReadByte(); @@ -123,9 +132,12 @@ namespace PkmnFoundations.Structures public BattleTowerPokemon4 Clone() { uint ivsField = (uint)(IVs.ToInt32() & 0x3fffffffu) | (IvFlags & 0xc0000000u); + ushort[] moveset = GetArrayFromMoves(Moves); + byte ppUps = GetPpUpsFromMoves(Moves); + BattleTowerPokemon4 result = new BattleTowerPokemon4(m_pokedex, - (ushort)SpeciesID, (ushort)HeldItemID, Moveset.ToArray(), - TrainerID, Personality, ivsField, EVs.ToArray(), Unknown1, + (ushort)SpeciesID, (ushort)HeldItemID, moveset, + TrainerID, Personality, ivsField, EVs.ToArray(), ppUps, Language, (byte)AbilityID, Happiness, NicknameEncoded); return result; @@ -146,19 +158,5 @@ namespace PkmnFoundations.Structures return 56; } } - - // todo: move me to the actual pokemon class once it's made. - [Obsolete("Use IvStatValues.UnpackIV or IvStatValues indexer, depending on context.")] - public static byte UnpackIV(uint ivs, Stats stat) - { - return IvStatValues.UnpackIV(ivs, stat); - } - - [Obsolete("Use IvStatValues.PackIVs")] - // todo: Move to IVs class - public static uint PackIVs(byte HP, byte Attack, byte Defense, byte Speed, byte SpAttack, byte SpDefense) - { - return IvStatValues.PackIVs(HP, Attack, Defense, Speed, SpAttack, SpDefense); - } } } diff --git a/library/Structures/BattleTowerPokemonBase.cs b/library/Structures/BattleTowerPokemonBase.cs index 5116ac72..73b989ee 100644 --- a/library/Structures/BattleTowerPokemonBase.cs +++ b/library/Structures/BattleTowerPokemonBase.cs @@ -15,8 +15,6 @@ namespace PkmnFoundations.Structures } - public ushort[] Moveset; - public byte Unknown1; // probably a bitmask of applied PP ups // In the main PKM structure, the remaining 2 bits on the IVs field // represents whether it's nicknamed and if it's an egg. Clearly, eggs // shouldn't be brought into Battle Tower. @@ -35,5 +33,59 @@ namespace PkmnFoundations.Structures throw new NotSupportedException(); } } + + internal static void GetMovesFromArray(IList result, Pokedex.Pokedex pokedex, ushort[] moves, byte ppUps) + { + if (moves.Length != 4) throw new ArgumentException("moves"); + if (result.Count != 4) throw new ArgumentException("movesOut"); + + for (int i = 0; i < 4; i++) + { + result[i] = MoveFromValues(pokedex, moves[i], (byte)(ppUps & 0x03)); + + ppUps >>= 2; + } + } + + internal static MoveSlot MoveFromValues(Pokedex.Pokedex pokedex, ushort move, byte ppUps) + { + MoveSlot result = new MoveSlot(pokedex, move, ppUps, 0); + result.RemainingPP = (byte)result.PP; + return result; + } + + internal static ushort[] GetArrayFromMoves(IList moves) + { + if (moves.Count != 4) throw new ArgumentException("moves"); + ushort[] result = new ushort[4]; + + for (int i = 0; i < 4; i++) + { + result[i] = (ushort)moves[i].MoveID; + } + return result; + } + + internal static byte GetPpUpsFromMoves(IList moves) + { + // The first move uses the least significant bits, moving up from there. + // [1, 3, 0, 0] -> 0x0d + byte ppUps = 0; + for (int i = 0; i < 4; i++) + { + ppUps |= (byte)(moves[i].PPUps << (i * 2)); + } + return ppUps; + } + + public ushort[] GetMoveIds() + { + return GetArrayFromMoves(Moves); + } + + public byte GetPpUps() + { + return GetPpUpsFromMoves(Moves); + } } } diff --git a/library/Structures/BattleTowerProfile4.cs b/library/Structures/BattleTowerProfile4.cs index f278018c..6c2dfd52 100644 --- a/library/Structures/BattleTowerProfile4.cs +++ b/library/Structures/BattleTowerProfile4.cs @@ -50,7 +50,7 @@ namespace PkmnFoundations.Structures public uint OT; public TrendyPhrase4 PhraseLeader; // Different from GTS, 0 = male, 2 = female, 1 = Plato???? - public byte Gender; + public byte Gender; // Probably trainer class. // 3: Lass // 6: Bug Catcher diff --git a/library/Structures/BattleTowerRecord4.cs b/library/Structures/BattleTowerRecord4.cs index 6e395766..45c4ff6e 100644 --- a/library/Structures/BattleTowerRecord4.cs +++ b/library/Structures/BattleTowerRecord4.cs @@ -34,12 +34,12 @@ namespace PkmnFoundations.Structures public TrendyPhrase4 PhraseChallenged; public TrendyPhrase4 PhraseWon; public TrendyPhrase4 PhraseLost; - public ushort Unknown3; + public ushort Unknown3; // Seems to be some sort of Elo rating. Goes up to about 8000. public byte Rank; public byte RoomNum; public byte BattlesWon; - public ulong Unknown5; + public ulong Unknown5; // Appears to be zero on AdmiralCurtiss's scraped data, but is very big ints on data being uploaded. public int PID; public byte[] Save() diff --git a/library/Structures/MoveSlot.cs b/library/Structures/MoveSlot.cs index bff38992..da63162e 100644 --- a/library/Structures/MoveSlot.cs +++ b/library/Structures/MoveSlot.cs @@ -40,6 +40,13 @@ namespace PkmnFoundations.Structures public byte PPUps { get; set; } // todo: validate range public byte RemainingPP { get; set; } // todo: validate range (against pokedex data and pp ups) - public int PP { get { return Move.PP * (5 + PPUps) / 5; } } + + public int PP + { + get + { + return Move == null ? 0 : Move.PP * (5 + PPUps) / 5; + } + } } }