From 222f8eba89a2c8d69fd83c274593cbf8541dd6a1 Mon Sep 17 00:00:00 2001 From: Greg Edwards Date: Tue, 14 Apr 2015 21:23:50 -0400 Subject: [PATCH] Split Pokemon4 class into separate box/party versions. --- library/Library.csproj | 1 + library/Structures/Pokemon4.cs | 54 +--------------- library/Structures/PokemonParty4.cs | 97 +++++++++++++++++++++++++++++ web/gts/Pokemon.aspx.cs | 8 +-- 4 files changed, 104 insertions(+), 56 deletions(-) create mode 100644 library/Structures/PokemonParty4.cs diff --git a/library/Library.csproj b/library/Library.csproj index aa9c0d29..b7dbc0d4 100644 --- a/library/Library.csproj +++ b/library/Library.csproj @@ -96,6 +96,7 @@ + diff --git a/library/Structures/Pokemon4.cs b/library/Structures/Pokemon4.cs index 7c5413d3..834aa699 100644 --- a/library/Structures/Pokemon4.cs +++ b/library/Structures/Pokemon4.cs @@ -166,36 +166,6 @@ namespace PkmnFoundations.Structures Unknown4 = block[31]; } - // todo: split this class into separate box/party versions. - { - rand = (int)Personality; - byte[] block = reader.ReadBytes(100); - for (int pos = 0; pos < 100; pos += 2) - { - rand = DecryptRNG(rand); - block[pos] ^= (byte)(rand >> 16); - block[pos + 1] ^= (byte)(rand >> 24); - } - - StatusAffliction = block[0]; - Unknown5 = block[1]; - Unknown6 = BitConverter.ToUInt16(block, 2); - Level = block[4]; - CapsuleIndex = block[5]; - HP = BitConverter.ToUInt16(block, 6); - m_stats = new IntStatValues(BitConverter.ToUInt16(block, 8), - BitConverter.ToUInt16(block, 10), - BitConverter.ToUInt16(block, 12), - BitConverter.ToUInt16(block, 14), - BitConverter.ToUInt16(block, 16), - BitConverter.ToUInt16(block, 18)); - - Unknown7 = new byte[56]; - Array.Copy(block, 20, Unknown7, 0, 56); - Seals = new byte[24]; - Array.Copy(block, 76, Seals, 0, 24); - } - byte[] ribbons = new byte[12]; Array.Copy(BitConverter.GetBytes(ribbons1), 0, ribbons, 0, 4); Array.Copy(BitConverter.GetBytes(ribbons2), 0, ribbons, 4, 4); @@ -349,34 +319,14 @@ namespace PkmnFoundations.Structures /// public HashSet UnknownRibbons { get; private set; } - // party-only stuff. (todo: put in derived class) - public byte StatusAffliction { get; set; } - // todo: ball seals - public byte Unknown5 { get; set; } - public ushort Unknown6 { get; set; } - public byte CapsuleIndex { get; set; } - public ushort HP { get; set; } - //public IntStatValues Stats { get; set; } // cached stats (only refreshes per level on gen4) - public byte[] Unknown7 { get; set; } // 56 bytes - public byte[] Seals { get; set; } - - private IntStatValues m_stats; - - // todo: this should go into the derived class. - // the implementation here should auto-calculate the stats. (as in GenV) - public override IntStatValues Stats - { - get { return m_stats; } - } - - private static int DecryptRNG(int prev) + protected static int DecryptRNG(int prev) { return prev * 0x41c64e6d + 0x6073; } public override int Size { - get { return 236; } + get { return 136; } } } } diff --git a/library/Structures/PokemonParty4.cs b/library/Structures/PokemonParty4.cs new file mode 100644 index 00000000..57e51c9d --- /dev/null +++ b/library/Structures/PokemonParty4.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace PkmnFoundations.Structures +{ + public class PokemonParty4 : Pokemon4 + { + public PokemonParty4(Pokedex.Pokedex pokedex) : base(pokedex) + { + Initialize(); + } + + public PokemonParty4(Pokedex.Pokedex pokedex, BinaryReader data) : base(pokedex) + { + Initialize(); + Load(data); + } + + public PokemonParty4(Pokedex.Pokedex pokedex, byte[] data) : base(pokedex) + { + Initialize(); + Load(data); + } + + public PokemonParty4(Pokedex.Pokedex pokedex, byte[] data, int offset) + : base(pokedex) + { + Initialize(); + Load(data, offset); + } + + private void Initialize() + { + } + + protected override void Load(BinaryReader reader) + { + base.Load(reader); + + { + int rand = (int)Personality; + byte[] block = reader.ReadBytes(100); + for (int pos = 0; pos < 100; pos += 2) + { + rand = DecryptRNG(rand); + block[pos] ^= (byte)(rand >> 16); + block[pos + 1] ^= (byte)(rand >> 24); + } + + StatusAffliction = block[0]; + Unknown5 = block[1]; + Unknown6 = BitConverter.ToUInt16(block, 2); + Level = block[4]; + CapsuleIndex = block[5]; + HP = BitConverter.ToUInt16(block, 6); + m_stats = new IntStatValues(BitConverter.ToUInt16(block, 8), + BitConverter.ToUInt16(block, 10), + BitConverter.ToUInt16(block, 12), + BitConverter.ToUInt16(block, 14), + BitConverter.ToUInt16(block, 16), + BitConverter.ToUInt16(block, 18)); + + Unknown7 = new byte[56]; + Array.Copy(block, 20, Unknown7, 0, 56); + Seals = new byte[24]; + Array.Copy(block, 76, Seals, 0, 24); + } + } + + // todo: parse status afflictions (enum + sleep turns) + public byte StatusAffliction { get; set; } + // todo: Parse ball seals + public byte Unknown5 { get; set; } + public ushort Unknown6 { get; set; } + public byte CapsuleIndex { get; set; } + public ushort HP { get; set; } // remaining hp + public byte[] Unknown7 { get; set; } // 56 bytes + public byte[] Seals { get; set; } // 24 bytes + + // cached stats on the party structure. This gives rise to the + // "box trick" on Gens 1-4 whereby putting the pokemon into the box + // recalculates its stats. + private IntStatValues m_stats; + public override IntStatValues Stats + { + get { return m_stats; } + } + + public override int Size + { + get { return 236; } + } + } +} diff --git a/web/gts/Pokemon.aspx.cs b/web/gts/Pokemon.aspx.cs index 6add6371..b285c537 100644 --- a/web/gts/Pokemon.aspx.cs +++ b/web/gts/Pokemon.aspx.cs @@ -19,7 +19,7 @@ namespace PkmnFoundations.Web.gts protected void Page_Load(object sender, EventArgs e) { m_pokedex = (Pokedex.Pokedex)Application["pkmncfPokedex"]; - Pokemon4 pkmn = null; + PokemonParty4 pkmn = null; if (Request.QueryString.Count == 0 || Request.QueryString.Count > 2) throw new WebException(400); if (Request.QueryString["offer"] != null || @@ -55,13 +55,13 @@ namespace PkmnFoundations.Web.gts case "4": { GtsRecord4 record = Database.Instance.GtsGetRecord4(tradeId, isExchanged, true); - if (record != null) pkmn = new Pokemon4(m_pokedex, record.Data); + if (record != null) pkmn = new PokemonParty4(m_pokedex, record.Data); } break; case "5": { GtsRecord5 record = Database.Instance.GtsGetRecord5(tradeId, isExchanged, true); - if (record != null) pkmn = new Pokemon4(m_pokedex, record.Data); + if (record != null) pkmn = new PokemonParty4(m_pokedex, record.Data); } break; default: @@ -81,7 +81,7 @@ namespace PkmnFoundations.Web.gts Bind(pkmn); } - private void Bind(Pokemon4 pkmn) + private void Bind(PokemonParty4 pkmn) { litNickname.Text = pkmn.Nickname; bool shiny = pkmn.IsShiny;