diff --git a/VeekunImport/Program.cs b/VeekunImport/Program.cs
index 9d63e501..6b5e69a6 100644
--- a/VeekunImport/Program.cs
+++ b/VeekunImport/Program.cs
@@ -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);
diff --git a/library/Library.csproj b/library/Library.csproj
index b84e536f..70a031f8 100644
--- a/library/Library.csproj
+++ b/library/Library.csproj
@@ -76,12 +76,20 @@
+
+
+
+
+
+
+
+
diff --git a/library/Pokedex/FormStats.cs b/library/Pokedex/FormStats.cs
index e68bead1..8f7945ef 100644
--- a/library/Pokedex/FormStats.cs
+++ b/library/Pokedex/FormStats.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(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 m_form_pair;
private LazyKeyValuePair m_type1_pair;
diff --git a/library/Structures/BattleSubwayPokemon5.cs b/library/Structures/BattleSubwayPokemon5.cs
index 5223114a..c4997b33 100644
--- a/library/Structures/BattleSubwayPokemon5.cs
+++ b/library/Structures/BattleSubwayPokemon5.cs
@@ -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;
diff --git a/library/Structures/BattleTowerPokemon4.cs b/library/Structures/BattleTowerPokemon4.cs
index 0dc59ddf..712c5e37 100644
--- a/library/Structures/BattleTowerPokemon4.cs
+++ b/library/Structures/BattleTowerPokemon4.cs
@@ -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;
diff --git a/library/Structures/BinarySerializableBase.cs b/library/Structures/BinarySerializableBase.cs
index 857ade67..93c0b017 100644
--- a/library/Structures/BinarySerializableBase.cs
+++ b/library/Structures/BinarySerializableBase.cs
@@ -12,6 +12,8 @@ namespace PkmnFoundations.Structures
///
public abstract class BinarySerializableBase : ISerializable
{
+ // xxx: ISerializable may be useless or even non-idiomatic on this class.
+
public BinarySerializableBase()
{
}
diff --git a/library/Structures/ByteStatValues.cs b/library/Structures/ByteStatValues.cs
new file mode 100644
index 00000000..29064495
--- /dev/null
+++ b/library/Structures/ByteStatValues.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace PkmnFoundations.Structures
+{
+ public class ByteStatValues : StatValues
+ {
+ 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)
+ {
+
+ }
+ }
+}
diff --git a/library/Structures/ContestStatValues.cs b/library/Structures/ContestStatValues.cs
new file mode 100644
index 00000000..e3040f9a
--- /dev/null
+++ b/library/Structures/ContestStatValues.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace PkmnFoundations.Structures
+{
+ public class ConditionValues : StatValuesBase
+ {
+ 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;
+ }
+ }
+ }
+}
diff --git a/library/Structures/Enums.cs b/library/Structures/Enums.cs
index 1fddf235..079b0e1e 100644
--- a/library/Structures/Enums.cs
+++ b/library/Structures/Enums.cs
@@ -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
+ }
}
diff --git a/library/Structures/IntStatValues.cs b/library/Structures/IntStatValues.cs
new file mode 100644
index 00000000..c62bdc18
--- /dev/null
+++ b/library/Structures/IntStatValues.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace PkmnFoundations.Structures
+{
+ public class IntStatValues : StatValues
+ {
+ 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)
+ {
+ }
+
+
+ }
+}
diff --git a/library/Structures/IvStatValues.cs b/library/Structures/IvStatValues.cs
new file mode 100644
index 00000000..8aed1a94
--- /dev/null
+++ b/library/Structures/IvStatValues.cs
@@ -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;
+ }
+ }
+}
diff --git a/library/Structures/MoveSlot.cs b/library/Structures/MoveSlot.cs
new file mode 100644
index 00000000..6aa96c8f
--- /dev/null
+++ b/library/Structures/MoveSlot.cs
@@ -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; } }
+ }
+}
diff --git a/library/Structures/Pokemon4.cs b/library/Structures/Pokemon4.cs
new file mode 100644
index 00000000..c2a77210
--- /dev/null
+++ b/library/Structures/Pokemon4.cs
@@ -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 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; }
+ }
+ }
+}
diff --git a/library/Structures/PokemonBase.cs b/library/Structures/PokemonBase.cs
new file mode 100644
index 00000000..7806bad7
--- /dev/null
+++ b/library/Structures/PokemonBase.cs
@@ -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 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 remaining = Enumerable.Range(0, x).ToList();
+ List result = new List(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 Invert(List arg)
+ {
+ // todo: this is of general utility and should go in a utility class.
+ int max = arg.Max();
+ List result = new List(max);
+
+ for (int x = 0; x < max; x++)
+ result.Add(arg.IndexOf(x));
+
+ return result;
+ }
+ }
+}
diff --git a/library/Structures/StatValues.cs b/library/Structures/StatValues.cs
index c00dc5c3..54f0016e 100644
--- a/library/Structures/StatValues.cs
+++ b/library/Structures/StatValues.cs
@@ -5,83 +5,45 @@ using System.Text;
namespace PkmnFoundations.Structures
{
- public struct StatValues
+ public class StatValues : StatValuesBase 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 };
- }
}
}
diff --git a/library/Structures/StatValuesBase.cs b/library/Structures/StatValuesBase.cs
new file mode 100644
index 00000000..2539c795
--- /dev/null
+++ b/library/Structures/StatValuesBase.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace PkmnFoundations.Structures
+{
+ public abstract class StatValuesBase 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();
+ }
+ }
+}