mirror of
https://github.com/mm201/pkmn-classic-framework.git
synced 2026-08-26 20:24:09 -05:00
First draft of Gen4 pkm parsing.
This commit is contained in:
@@ -252,18 +252,18 @@ namespace VeekunImport
|
||||
|
||||
int[] fieldsInt = fields.Select(s => Convert.ToInt32(s)).ToArray();
|
||||
FormStats f = new FormStats(null, fieldsInt[0], (Generations)generation, fieldsInt[1], fieldsInt[2],
|
||||
new StatValues(fieldsInt[3],
|
||||
new IntStatValues(fieldsInt[3],
|
||||
fieldsInt[4],
|
||||
fieldsInt[5],
|
||||
fieldsInt[6],
|
||||
fieldsInt[7],
|
||||
fieldsInt[8]),
|
||||
new StatValues(fieldsInt[9],
|
||||
fieldsInt[10],
|
||||
fieldsInt[11],
|
||||
fieldsInt[12],
|
||||
fieldsInt[13],
|
||||
fieldsInt[14])
|
||||
new ByteStatValues((byte)fieldsInt[9],
|
||||
(byte)fieldsInt[10],
|
||||
(byte)fieldsInt[11],
|
||||
(byte)fieldsInt[12],
|
||||
(byte)fieldsInt[13],
|
||||
(byte)fieldsInt[14])
|
||||
);
|
||||
|
||||
db.PokedexInsertFormStats(f);
|
||||
|
||||
@@ -76,12 +76,20 @@
|
||||
<Compile Include="Structures\BattleVideoRecord5.cs" />
|
||||
<Compile Include="Structures\BinarySerializableBase.cs" />
|
||||
<Compile Include="Structures\BoxRecord4.cs" />
|
||||
<Compile Include="Structures\ByteStatValues.cs" />
|
||||
<Compile Include="Structures\ContestStatValues.cs" />
|
||||
<Compile Include="Structures\DressupRecord4.cs" />
|
||||
<Compile Include="Structures\GtsRecord5.cs" />
|
||||
<Compile Include="Structures\Enums.cs" />
|
||||
<Compile Include="Structures\GtsRecord4.cs" />
|
||||
<Compile Include="Structures\IvStatValues.cs" />
|
||||
<Compile Include="Structures\MoveSlot.cs" />
|
||||
<Compile Include="Structures\MusicalRecord5.cs" />
|
||||
<Compile Include="Structures\Pokemon4.cs" />
|
||||
<Compile Include="Structures\PokemonBase.cs" />
|
||||
<Compile Include="Structures\IntStatValues.cs" />
|
||||
<Compile Include="Structures\StatValues.cs" />
|
||||
<Compile Include="Structures\StatValuesBase.cs" />
|
||||
<Compile Include="Structures\TrainerProfile4.cs" />
|
||||
<Compile Include="Structures\TrainerProfile5.cs" />
|
||||
<Compile Include="Support\AssertHelper.cs" />
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace PkmnFoundations.Pokedex
|
||||
public class FormStats : PokedexRecordBase
|
||||
{
|
||||
public FormStats(Pokedex pokedex, int form_id, Generations min_generation,
|
||||
int type1, int type2, StatValues base_stats, StatValues reward_evs)
|
||||
int type1, int type2, IntStatValues base_stats, ByteStatValues reward_evs)
|
||||
: base(pokedex)
|
||||
{
|
||||
m_form_pair = new LazyKeyValuePair<int, Form>(k => k == 0 ? null : m_pokedex.Forms(k), v => v.Value);
|
||||
@@ -36,7 +36,7 @@ namespace PkmnFoundations.Pokedex
|
||||
(Generations)Convert.ToInt32(reader["MinGeneration"]),
|
||||
Convert.ToInt32(reader["Type1"]),
|
||||
Convert.ToInt32(reader["Type2"]),
|
||||
new StatValues(
|
||||
new IntStatValues(
|
||||
Convert.ToInt32(reader["BaseHP"]),
|
||||
Convert.ToInt32(reader["BaseAttack"]),
|
||||
Convert.ToInt32(reader["BaseDefense"]),
|
||||
@@ -44,21 +44,21 @@ namespace PkmnFoundations.Pokedex
|
||||
Convert.ToInt32(reader["BaseSpAttack"]),
|
||||
Convert.ToInt32(reader["BaseSpDefense"])
|
||||
),
|
||||
new StatValues(
|
||||
Convert.ToInt32(reader["RewardHP"]),
|
||||
Convert.ToInt32(reader["RewardAttack"]),
|
||||
Convert.ToInt32(reader["RewardDefense"]),
|
||||
Convert.ToInt32(reader["RewardSpeed"]),
|
||||
Convert.ToInt32(reader["RewardSpAttack"]),
|
||||
Convert.ToInt32(reader["RewardSpDefense"])
|
||||
new ByteStatValues(
|
||||
Convert.ToByte(reader["RewardHP"]),
|
||||
Convert.ToByte(reader["RewardAttack"]),
|
||||
Convert.ToByte(reader["RewardDefense"]),
|
||||
Convert.ToByte(reader["RewardSpeed"]),
|
||||
Convert.ToByte(reader["RewardSpAttack"]),
|
||||
Convert.ToByte(reader["RewardSpDefense"])
|
||||
)
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public Generations MinGeneration { get; private set; }
|
||||
public StatValues BaseStats { get; private set; }
|
||||
public StatValues RewardEvs { get; private set; }
|
||||
public IntStatValues BaseStats { get; private set; }
|
||||
public ByteStatValues RewardEvs { get; private set; }
|
||||
|
||||
private LazyKeyValuePair<int, Form> m_form_pair;
|
||||
private LazyKeyValuePair<int, PkmnFoundations.Pokedex.Type> m_type1_pair;
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace PkmnFoundations.Structures
|
||||
public uint Personality;
|
||||
public uint IVs;
|
||||
public byte[] EVs;
|
||||
public byte Unknown1;
|
||||
public byte Unknown1; // probably a bitmask of applied PP ups
|
||||
public Languages Language;
|
||||
public byte Ability;
|
||||
public byte Happiness;
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace PkmnFoundations.Structures
|
||||
public uint Personality;
|
||||
public uint IVs;
|
||||
public byte[] EVs;
|
||||
public byte Unknown1;
|
||||
public byte Unknown1; // probably a bitmask of applied PP ups
|
||||
public Languages Language;
|
||||
public byte Ability;
|
||||
public byte Happiness;
|
||||
|
||||
@@ -12,6 +12,8 @@ namespace PkmnFoundations.Structures
|
||||
/// </summary>
|
||||
public abstract class BinarySerializableBase : ISerializable
|
||||
{
|
||||
// xxx: ISerializable may be useless or even non-idiomatic on this class.
|
||||
|
||||
public BinarySerializableBase()
|
||||
{
|
||||
}
|
||||
|
||||
20
library/Structures/ByteStatValues.cs
Normal file
20
library/Structures/ByteStatValues.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace PkmnFoundations.Structures
|
||||
{
|
||||
public class ByteStatValues : StatValues<byte>
|
||||
{
|
||||
public ByteStatValues(byte hp, byte attack, byte defense, byte speed, byte special_attack, byte special_defense)
|
||||
: base(hp, attack, defense, special_attack, special_attack, special_defense)
|
||||
{
|
||||
}
|
||||
|
||||
protected ByteStatValues(byte[] s) : base(s)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
44
library/Structures/ContestStatValues.cs
Normal file
44
library/Structures/ContestStatValues.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace PkmnFoundations.Structures
|
||||
{
|
||||
public class ConditionValues : StatValuesBase<byte>
|
||||
{
|
||||
public ConditionValues(byte cool, byte beauty, byte cute, byte smart, byte tough, byte sheen)
|
||||
: base(cool, beauty, cute, smart, tough, sheen)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public byte Cool { get { return Stats[0]; } set { Stats[0] = value; } }
|
||||
public byte Beauty { get { return Stats[1]; } set { Stats[1] = value; } }
|
||||
public byte Cute { get { return Stats[2]; } set { Stats[2] = value; } }
|
||||
public byte Smart { get { return Stats[3]; } set { Stats[3] = value; } }
|
||||
public byte Tough { get { return Stats[4]; } set { Stats[4] = value; } }
|
||||
public byte Sheen { get { return Stats[5]; } set { Stats[5] = value; } }
|
||||
|
||||
public static int ConditionsIndex(Conditions condition)
|
||||
{
|
||||
return (int)condition - 1;
|
||||
}
|
||||
|
||||
public virtual byte this[Conditions stat]
|
||||
{
|
||||
get
|
||||
{
|
||||
int index = ConditionsIndex(stat);
|
||||
if (index < 0 || index >= 6) throw new ArgumentException();
|
||||
return Stats[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
int index = ConditionsIndex(stat);
|
||||
if (index < 0 || index >= 6) throw new ArgumentException();
|
||||
Stats[index] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -91,6 +91,16 @@ namespace PkmnFoundations.Structures
|
||||
SpecialDefense = 6
|
||||
}
|
||||
|
||||
public enum Conditions
|
||||
{
|
||||
Cool = 1,
|
||||
Beauty = 2,
|
||||
Cute = 3,
|
||||
Smart = 4,
|
||||
Tough = 5,
|
||||
Sheen = 6,
|
||||
}
|
||||
|
||||
public enum DamageClass
|
||||
{
|
||||
None = 0,
|
||||
@@ -173,4 +183,13 @@ namespace PkmnFoundations.Structures
|
||||
UserAndAllies = 13,
|
||||
AllPokemon = 14
|
||||
}
|
||||
|
||||
public enum Natures : uint
|
||||
{
|
||||
Hardy = 0, Lonely = 1, Brave = 2, Adamant = 3, Naughty = 4,
|
||||
Bold = 5, Docile = 6, Relaxed = 7, Impish = 8, Lax = 9,
|
||||
Timid = 10, Hasty = 11, Serious = 12, Jolly = 13, Naive = 14,
|
||||
Modest = 15, Mild = 16, Quiet = 17, Bashful = 18, Rash = 19,
|
||||
Calm = 20, Gentle = 21, Sassy = 22, Careful = 23, Quirky = 24
|
||||
}
|
||||
}
|
||||
|
||||
17
library/Structures/IntStatValues.cs
Normal file
17
library/Structures/IntStatValues.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace PkmnFoundations.Structures
|
||||
{
|
||||
public class IntStatValues : StatValues<int>
|
||||
{
|
||||
public IntStatValues(int hp, int attack, int defense, int speed, int special_attack, int special_defense)
|
||||
: base(hp, attack, defense, special_attack, special_attack, special_defense)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
49
library/Structures/IvStatValues.cs
Normal file
49
library/Structures/IvStatValues.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace PkmnFoundations.Structures
|
||||
{
|
||||
public class IvStatValues : ByteStatValues
|
||||
{
|
||||
public IvStatValues(byte hp, byte attack, byte defense, byte speed, byte special_attack, byte special_defense)
|
||||
: base(hp, attack, defense, special_attack, special_attack, special_defense)
|
||||
{
|
||||
}
|
||||
|
||||
public IvStatValues(int ivs) : base(new byte[6])
|
||||
{
|
||||
for (int x = 0; x < 6; x++)
|
||||
{
|
||||
Stats[x] = (byte)(ivs & 31);
|
||||
ivs >>= 5;
|
||||
}
|
||||
}
|
||||
|
||||
public override byte this[Stats stat]
|
||||
{
|
||||
get
|
||||
{
|
||||
return base[stat];
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value > 31) throw new ArgumentOutOfRangeException();
|
||||
base[stat] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int ToInt32()
|
||||
{
|
||||
int shift = 0;
|
||||
int result = 0;
|
||||
foreach (byte iv in Stats)
|
||||
{
|
||||
result |= iv << shift;
|
||||
shift += 5;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
29
library/Structures/MoveSlot.cs
Normal file
29
library/Structures/MoveSlot.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using PkmnFoundations.Pokedex;
|
||||
|
||||
namespace PkmnFoundations.Structures
|
||||
{
|
||||
public struct MoveSlot
|
||||
{
|
||||
public MoveSlot(Pokedex.Pokedex pokedex, int moveId, byte ppUps, byte remainingPp) : this()
|
||||
{
|
||||
m_pokedex = pokedex;
|
||||
MoveID = moveId;
|
||||
PPUps = ppUps;
|
||||
RemainingPP = remainingPp;
|
||||
}
|
||||
|
||||
private Pokedex.Pokedex m_pokedex;
|
||||
|
||||
public int MoveID { get; set; }
|
||||
public byte PPUps { get; set; } // todo: validate range
|
||||
public byte RemainingPP { get; set; } // todo: validate range (against pokedex data and pp ups)
|
||||
|
||||
// todo: should have a MoveID/Move LazyKeyValuePair.
|
||||
public Move Move { get { return m_pokedex.Moves(MoveID); } }
|
||||
public int PP { get { return Move.PP * (5 + PPUps) / 5; } }
|
||||
}
|
||||
}
|
||||
260
library/Structures/Pokemon4.cs
Normal file
260
library/Structures/Pokemon4.cs
Normal file
@@ -0,0 +1,260 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using PkmnFoundations.Support;
|
||||
|
||||
namespace PkmnFoundations.Structures
|
||||
{
|
||||
public class Pokemon4 : PokemonBase
|
||||
{
|
||||
public Pokemon4(Pokedex.Pokedex pokedex) : base(pokedex)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Pokemon4(Pokedex.Pokedex pokedex, BinaryReader data) : base(pokedex, data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Pokemon4(Pokedex.Pokedex pokedex, byte[] data) : base(pokedex, data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Pokemon4(Pokedex.Pokedex pokedex, byte[] data, int offset) : base(pokedex, data, offset)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void Load(BinaryReader reader)
|
||||
{
|
||||
// header (unencrypted)
|
||||
Personality = reader.ReadUInt32();
|
||||
ushort zero = reader.ReadUInt16();
|
||||
ushort checksum = reader.ReadUInt16();
|
||||
|
||||
// read out the main payload, apply xor decryption
|
||||
byte[][] blocks = new byte[4][];
|
||||
int rand = (int)checksum;
|
||||
|
||||
for (int x = 0; x < 4; x++)
|
||||
{
|
||||
byte[] block = blocks[x] = reader.ReadBytes(32);
|
||||
// todo: extract
|
||||
for (int pos = 0; pos < 32; pos += 2)
|
||||
{
|
||||
rand = DecryptRNG(rand);
|
||||
block[pos] ^= (byte)(rand >> 24);
|
||||
block[pos + 1] ^= (byte)(rand >> 16);
|
||||
}
|
||||
}
|
||||
|
||||
// shuffle blocks to their correct order
|
||||
List<int> blockSequence = Invert(BlockScramble(Personality));
|
||||
AssertHelper.Equals(blockSequence.Count, 4);
|
||||
{
|
||||
byte[][] blocks2 = new byte[4][];
|
||||
for (int x = 0; x < 4; x++)
|
||||
blocks2[x] = blocks[blockSequence[x]];
|
||||
blocks = blocks2;
|
||||
}
|
||||
|
||||
int ribbons1, ribbons2, ribbons3;
|
||||
|
||||
{
|
||||
byte[] block = blocks[0];
|
||||
|
||||
SpeciesID = BitConverter.ToUInt16(block, 0);
|
||||
HeldItemID = BitConverter.ToUInt16(block, 2);
|
||||
TrainerID = BitConverter.ToUInt32(block, 4);
|
||||
Experience = BitConverter.ToInt32(block, 8);
|
||||
Happiness = block[12];
|
||||
AbilityID = block[13];
|
||||
Markings = (Markings)block[14];
|
||||
Language = (Languages)block[15];
|
||||
EVs = new ByteStatValues(block[16],
|
||||
block[17],
|
||||
block[18],
|
||||
block[19],
|
||||
block[20],
|
||||
block[21]);
|
||||
ContestStats = new ConditionValues(block[22],
|
||||
block[23],
|
||||
block[24],
|
||||
block[25],
|
||||
block[26],
|
||||
block[27]);
|
||||
|
||||
ribbons1 = BitConverter.ToInt32(block, 28);
|
||||
}
|
||||
|
||||
{
|
||||
byte[] block = blocks[1];
|
||||
|
||||
Moves[0] = new MoveSlot(m_pokedex, BitConverter.ToUInt16(block, 0), block[8], block[12]);
|
||||
Moves[1] = new MoveSlot(m_pokedex, BitConverter.ToUInt16(block, 2), block[9], block[13]);
|
||||
Moves[2] = new MoveSlot(m_pokedex, BitConverter.ToUInt16(block, 4), block[10], block[14]);
|
||||
Moves[3] = new MoveSlot(m_pokedex, BitConverter.ToUInt16(block, 6), block[11], block[15]);
|
||||
|
||||
int ivs = BitConverter.ToInt32(block, 16);
|
||||
IVs = new IvStatValues(ivs & 0x3fffffff);
|
||||
IsEgg = (ivs & 0x40000000) != 0;
|
||||
HasNickname = (ivs & 0x80000000) != 0;
|
||||
|
||||
ribbons2 = BitConverter.ToInt32(block, 20);
|
||||
|
||||
byte forme = block[24];
|
||||
FatefulEncounter = (forme & 0x01) != 0;
|
||||
Female = (forme & 0x02) != 0;
|
||||
Genderless = (forme & 0x04) != 0;
|
||||
FormID = forme >> 3;
|
||||
|
||||
// todo: parse this in a meaningful way.
|
||||
ShinyLeaves = block[25];
|
||||
Unknown1 = BitConverter.ToUInt16(block, 26);
|
||||
|
||||
// todo: doing trainer memos the right way is a pretty large task
|
||||
// involving new database work.
|
||||
TrainerMemoExtended = BitConverter.ToInt32(block, 28);
|
||||
}
|
||||
|
||||
{
|
||||
byte[] block = blocks[2];
|
||||
|
||||
NicknameEncoded = new EncodedString4(block, 0, 22);
|
||||
Unknown2 = block[22];
|
||||
Version = (Versions)block[23];
|
||||
ribbons3 = BitConverter.ToInt32(block, 24);
|
||||
Unknown3 = BitConverter.ToInt32(block, 28);
|
||||
}
|
||||
|
||||
{
|
||||
byte[] block = blocks[3];
|
||||
|
||||
TrainerNameEncoded = new EncodedString4(block, 0, 16);
|
||||
|
||||
// todo: parse dates
|
||||
EggDate = new byte[3];
|
||||
Array.Copy(block, 16, EggDate, 0, 3);
|
||||
Date = new byte[3];
|
||||
Array.Copy(block, 19, Date, 0, 3);
|
||||
|
||||
TrainerMemo = BitConverter.ToInt32(block, 22);
|
||||
PokerusStatus = block[26];
|
||||
PokeBallID_DP = block[27];
|
||||
|
||||
byte encounter_level = block[28];
|
||||
EncounterLevel = (byte)(encounter_level & 0x7f);
|
||||
TrainerFemale = (encounter_level & 0x80) != 0;
|
||||
|
||||
EncounterType = block[29];
|
||||
PokeBallID = block[30];
|
||||
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 >> 24);
|
||||
block[pos + 1] ^= (byte)(rand >> 16);
|
||||
}
|
||||
|
||||
StatusAffliction = block[0];
|
||||
Unknown5 = block[1];
|
||||
Unknown6 = BitConverter.ToUInt16(block, 2);
|
||||
Level = block[4];
|
||||
CapsuleIndex = block[5];
|
||||
HP = BitConverter.ToUInt16(block, 6);
|
||||
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);
|
||||
}
|
||||
|
||||
Ribbons1 = ribbons1;
|
||||
Ribbons2 = ribbons2;
|
||||
Ribbons3 = ribbons3;
|
||||
}
|
||||
|
||||
protected override void Save(BinaryWriter writer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int Experience { get; set; }
|
||||
public Markings Markings { get; set; }
|
||||
public ConditionValues ContestStats { get; set; }
|
||||
public bool IsEgg { get; set; }
|
||||
public bool HasNickname { get; set; }
|
||||
public bool FatefulEncounter { get; set; } // aka. obedience flag
|
||||
public bool Female { get; set; } // only part of gender calculations
|
||||
public bool Genderless { get; set; }
|
||||
public byte ShinyLeaves { get; set; }
|
||||
public ushort Unknown1 { get; set; }
|
||||
public int TrainerMemoExtended { get; set; } // trainer memo for PtHGSS
|
||||
public EncodedString4 NicknameEncoded { get; set; }
|
||||
public override string Nickname
|
||||
{
|
||||
get
|
||||
{
|
||||
return (NicknameEncoded == null) ? null : NicknameEncoded.Text;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (NicknameEncoded == null) NicknameEncoded = new EncodedString4(value, 22);
|
||||
else NicknameEncoded.Text = value;
|
||||
}
|
||||
}
|
||||
public byte Unknown2 { get; set; }
|
||||
public Versions Version { get; set; }
|
||||
public int Unknown3 { get; set; }
|
||||
public EncodedString4 TrainerNameEncoded { get; set; }
|
||||
public byte[] EggDate { get; set; }
|
||||
public byte[] Date { get; set; }
|
||||
public int TrainerMemo { get; set; }
|
||||
public byte PokerusStatus { get; set; }
|
||||
public byte PokeBallID_DP { get; set; }
|
||||
public byte PokeBallID { get; set; }
|
||||
public byte EncounterLevel { get; set; }
|
||||
public bool TrainerFemale { get; set; }
|
||||
public byte EncounterType { get; set; }
|
||||
public byte Unknown4 { get; set; }
|
||||
|
||||
public int Ribbons1 { get; set; }
|
||||
public int Ribbons2 { get; set; }
|
||||
public int Ribbons3 { get; set; }
|
||||
|
||||
public byte StatusAffliction { get; set; }
|
||||
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; }
|
||||
public byte[] Seals { get; set; }
|
||||
|
||||
private static int DecryptRNG(int prev)
|
||||
{
|
||||
return prev * 0x41c64e6d + 0x6073;
|
||||
}
|
||||
|
||||
public override int Size
|
||||
{
|
||||
get { return 236; }
|
||||
}
|
||||
}
|
||||
}
|
||||
94
library/Structures/PokemonBase.cs
Normal file
94
library/Structures/PokemonBase.cs
Normal file
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace PkmnFoundations.Structures
|
||||
{
|
||||
public abstract class PokemonBase : BinarySerializableBase
|
||||
{
|
||||
public PokemonBase(Pokedex.Pokedex pokedex)
|
||||
: base()
|
||||
{
|
||||
m_pokedex = pokedex;
|
||||
}
|
||||
|
||||
public PokemonBase(Pokedex.Pokedex pokedex, BinaryReader data)
|
||||
: base(data)
|
||||
{
|
||||
m_pokedex = pokedex;
|
||||
}
|
||||
|
||||
public PokemonBase(Pokedex.Pokedex pokedex, byte[] data)
|
||||
: base(data)
|
||||
{
|
||||
m_pokedex = pokedex;
|
||||
}
|
||||
|
||||
public PokemonBase(Pokedex.Pokedex pokedex, byte[] data, int offset)
|
||||
: base(data, offset)
|
||||
{
|
||||
m_pokedex = pokedex;
|
||||
}
|
||||
|
||||
protected Pokedex.Pokedex m_pokedex;
|
||||
private MoveSlot[] m_moves = new MoveSlot[4];
|
||||
|
||||
// todo: use LazyKeyValuePairs for the ID fields.
|
||||
public int SpeciesID { get; set; }
|
||||
public int FormID { get; set; }
|
||||
public int HeldItemID { get; set; }
|
||||
public MoveSlot[] Moves { get { return m_moves; } }
|
||||
public uint TrainerID { get; set; }
|
||||
public uint Personality { get; set; }
|
||||
public Natures Nature { get { return (Natures)(Personality % 25u); } }
|
||||
public byte Level { get; set; }
|
||||
public byte Happiness { get; set; }
|
||||
public int AbilityID { get; set; }
|
||||
public Languages Language { get; set; }
|
||||
public IvStatValues IVs { get; set; }
|
||||
public ByteStatValues EVs { get; set; }
|
||||
public abstract String Nickname { get; set; }
|
||||
|
||||
protected static List<int> BlockScramble(uint personality)
|
||||
{
|
||||
int x = 4; // todo: this can be an argument but YAGNI
|
||||
int xFactorial = 24;
|
||||
|
||||
//if (x < 0) throw new ArgumentOutOfRangeException();
|
||||
//if (x == 0) return new int[0];
|
||||
|
||||
int index;
|
||||
|
||||
List<int> remaining = Enumerable.Range(0, x).ToList();
|
||||
List<int> result = new List<int>(x);
|
||||
|
||||
while (x > 0)
|
||||
{
|
||||
int xMinusOneFactorial = xFactorial / x;
|
||||
|
||||
index = (int)((personality % xFactorial) / xMinusOneFactorial);
|
||||
result.Add(remaining[index]);
|
||||
remaining.RemoveAt(index);
|
||||
|
||||
x--;
|
||||
xFactorial = xMinusOneFactorial;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected static List<int> Invert(List<int> arg)
|
||||
{
|
||||
// todo: this is of general utility and should go in a utility class.
|
||||
int max = arg.Max();
|
||||
List<int> result = new List<int>(max);
|
||||
|
||||
for (int x = 0; x < max; x++)
|
||||
result.Add(arg.IndexOf(x));
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,83 +5,45 @@ using System.Text;
|
||||
|
||||
namespace PkmnFoundations.Structures
|
||||
{
|
||||
public struct StatValues
|
||||
public class StatValues<T> : StatValuesBase<T> where T : struct
|
||||
{
|
||||
public StatValues(int hp, int attack, int defense, int speed, int special_attack, int special_defense) : this()
|
||||
public StatValues(T hp, T attack, T defense, T speed, T special_attack, T special_defense)
|
||||
: base(hp, attack, defense, speed, special_attack, special_defense)
|
||||
{
|
||||
Hp = hp;
|
||||
Attack = attack;
|
||||
Defense = defense;
|
||||
Speed = speed;
|
||||
SpecialAttack = special_attack;
|
||||
SpecialDefense = special_defense;
|
||||
|
||||
}
|
||||
|
||||
public int Hp { get; set; }
|
||||
public int Attack { get; set; }
|
||||
public int Defense { get; set; }
|
||||
public int Speed { get; set; }
|
||||
public int SpecialAttack { get; set; }
|
||||
public int SpecialDefense { get; set; }
|
||||
protected StatValues(T[] s) : base(s)
|
||||
{
|
||||
if (s.Length != 6) throw new ArgumentException();
|
||||
}
|
||||
|
||||
public int this[Stats stat]
|
||||
public T Hp { get { return Stats[0]; } set { Stats[0] = value; } }
|
||||
public T Attack { get { return Stats[1]; } set { Stats[1] = value; } }
|
||||
public T Defense { get { return Stats[2]; } set { Stats[2] = value; } }
|
||||
public T Speed { get { return Stats[3]; } set { Stats[3] = value; } }
|
||||
public T SpecialAttack { get { return Stats[4]; } set { Stats[4] = value; } }
|
||||
public T SpecialDefense { get { return Stats[5]; } set { Stats[5] = value; } }
|
||||
|
||||
public static int StatsIndex(Stats stat)
|
||||
{
|
||||
return (int)stat - 1;
|
||||
}
|
||||
|
||||
public virtual T this[Stats stat]
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (stat)
|
||||
{
|
||||
case Stats.Hp:
|
||||
return Hp;
|
||||
case Stats.Attack:
|
||||
return Attack;
|
||||
case Stats.Defense:
|
||||
return Defense;
|
||||
case Stats.Speed:
|
||||
return Speed;
|
||||
case Stats.SpecialAttack:
|
||||
return SpecialAttack;
|
||||
case Stats.SpecialDefense:
|
||||
return SpecialDefense;
|
||||
default:
|
||||
throw new ArgumentException();
|
||||
}
|
||||
int index = StatsIndex(stat);
|
||||
if (index < 0 || index >= 6) throw new ArgumentException();
|
||||
return Stats[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
switch (stat)
|
||||
{
|
||||
case Stats.Hp:
|
||||
Hp = value;
|
||||
break;
|
||||
case Stats.Attack:
|
||||
Attack = value;
|
||||
break;
|
||||
case Stats.Defense:
|
||||
Defense = value;
|
||||
break;
|
||||
case Stats.Speed:
|
||||
Speed = value;
|
||||
break;
|
||||
case Stats.SpecialAttack:
|
||||
SpecialAttack = value;
|
||||
break;
|
||||
case Stats.SpecialDefense:
|
||||
SpecialDefense = value;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException();
|
||||
}
|
||||
int index = StatsIndex(stat);
|
||||
if (index < 0 || index >= 6) throw new ArgumentException();
|
||||
Stats[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int[] ToArray()
|
||||
{
|
||||
return new int[] { Hp, Attack, Defense, Speed, SpecialAttack, SpecialDefense };
|
||||
}
|
||||
|
||||
public byte[] ToByteArray()
|
||||
{
|
||||
return new byte[] { (byte)Hp, (byte)Attack, (byte)Defense, (byte)Speed, (byte)SpecialAttack, (byte)SpecialDefense };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
27
library/Structures/StatValuesBase.cs
Normal file
27
library/Structures/StatValuesBase.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace PkmnFoundations.Structures
|
||||
{
|
||||
public abstract class StatValuesBase<T> where T : struct
|
||||
{
|
||||
protected StatValuesBase(T[] s)
|
||||
{
|
||||
Stats = s;
|
||||
}
|
||||
|
||||
protected StatValuesBase(T s0, T s1, T s2, T s3, T s4, T s5)
|
||||
: this(new T[6] { s0, s1, s2, s3, s4, s5 })
|
||||
{
|
||||
}
|
||||
|
||||
protected T[] Stats { get; private set; }
|
||||
|
||||
public T[] ToArray()
|
||||
{
|
||||
return Stats.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user