private void SetFinalPokemon(int index)
        {
            uint       gainedExp = GetGainedExperience(index);
            GBAPokemon original  = originalPokemon[index];
            GBAPokemon output    = (GBAPokemon)original.Clone();

            output.PokeContainer = this;

            output.Experience += gainedExp;
            output.RecalculateStats();

            ushort[] moves = PokemonDatabase.GetMovesLearnedAtLevelRange(original, (byte)(original.Level + 1), output.Level);

            // Teach the Pokemon all the new moves
            // Push the moves up just like the game does it to make room for the new move. Even HMs can be removed.
            foreach (ushort moveID in moves)
            {
                if (!PokemonDatabase.PokemonHasMove(output, moveID))
                {
                    if (output.NumMoves < 4)
                    {
                        output.SetMoveAt(output.NumMoves, new Move(moveID));
                    }
                    else
                    {
                        for (int i = 0; i < 3; i++)
                        {
                            output.SetMoveAt(i, output.GetMoveAt(i + 1));
                        }
                        output.SetMoveAt(3, new Move(moveID));
                    }
                }
            }
            finalPokemon[index] = output;
        }
        public override void GenerateReward(IGameSave gameSave)
        {
            Random      random      = new Random((int)DateTime.Now.Ticks);
            PokemonData pokemonData = PokemonDatabase.GetPokemonFromDexID(DexID);
            GBAPokemon  pkm         = new GBAPokemon();

            pkm.DexID            = DexID;
            pkm.Personality      = (Personality.HasValue ? Personality.Value : (uint)random.Next());
            pkm.Experience       = PokemonDatabase.GetExperienceFromLevel(pokemonData.ExperienceGroup, (IsEgg ? (byte)5 : Level));
            pkm.IsSecondAbility2 = (IsSecondAbility.HasValue ? IsSecondAbility.Value : (!pokemonData.CanOnlyHaveFirstAbility && random.Next(2) == 1));
            pkm.Nickname         = (Nickname != null ? Nickname : pokemonData.Name.ToUpper());
            pkm.BallCaughtID     = 4;
            pkm.MetLocationID    = 255;
            if (DexID == 151 || DexID == 386)
            {
                pkm.IsFatefulEncounter = true;
            }
            pkm.LevelMet   = (IsEgg ? (byte)0 : Level);
            pkm.Language   = Languages.English;
            pkm.Friendship = (byte)(IsEgg ? 10 : 70);

            // Ownership
            pkm.TrainerName   = (TrainerName != null ? TrainerName : PokeManager.ManagerGameSave.TrainerName);
            pkm.TrainerGender = (TrainerGender.HasValue ? TrainerGender.Value : PokeManager.ManagerGameSave.TrainerGender);
            pkm.TrainerID     = (TrainerID.HasValue ? TrainerID.Value : PokeManager.ManagerGameSave.TrainerID);
            pkm.SecretID      = (SecretID.HasValue ? SecretID.Value : PokeManager.ManagerGameSave.SecretID);
            if (TrainerGender.HasValue && TrainerGender.Value == Genders.Genderless)
            {
                pkm.TrainerGender = (random.Next(2) == 1 ? Genders.Female : Genders.Male);
            }

            if (!Personality.HasValue)
            {
                GeneratePID(pkm, random);
            }

            if (HeldItem != null)
            {
                pkm.HeldItemID = HeldItem[random.Next(HeldItem.Length)];
            }

            if (Conditions != null)
            {
                pkm.Coolness  = Conditions[0];
                pkm.Beauty    = Conditions[1];
                pkm.Cuteness  = Conditions[2];
                pkm.Smartness = Conditions[3];
                pkm.Toughness = Conditions[4];
                pkm.Feel      = Conditions[5];
            }

            pkm.HPIV        = (IVs != null ? IVs[0] : (byte)random.Next(32));
            pkm.AttackIV    = (IVs != null ? IVs[1] : (byte)random.Next(32));
            pkm.DefenseIV   = (IVs != null ? IVs[2] : (byte)random.Next(32));
            pkm.SpAttackIV  = (IVs != null ? IVs[3] : (byte)random.Next(32));
            pkm.SpDefenseIV = (IVs != null ? IVs[4] : (byte)random.Next(32));
            pkm.SpeedIV     = (IVs != null ? IVs[5] : (byte)random.Next(32));

            if (HiddenPowerDamage.HasValue)
            {
                pkm.SetHiddenPowerDamage(HiddenPowerDamage.Value);
            }
            if (HiddenPowerType.HasValue)
            {
                pkm.SetHiddenPowerType(HiddenPowerType.Value);
            }

            // Teach the Pokemon all of it's default moves
            ushort[] moves = PokemonDatabase.GetMovesLearnedAtLevelRange(pkm, 1, (IsEgg ? (byte)5 : Level));
            foreach (ushort moveID in moves)
            {
                if (!PokemonDatabase.PokemonHasMove(pkm, moveID))
                {
                    if (pkm.NumMoves < 4)
                    {
                        pkm.SetMoveAt(pkm.NumMoves, new Move(moveID));
                    }
                    else
                    {
                        for (int i = 0; i < 3; i++)
                        {
                            pkm.SetMoveAt(i, pkm.GetMoveAt(i + 1));
                        }
                        pkm.SetMoveAt(3, new Move(moveID));
                    }
                }
            }
            if (Move1ID.HasValue)
            {
                pkm.SetMoveAt(0, new Move(Move1ID.Value));
            }
            if (Move2ID.HasValue)
            {
                pkm.SetMoveAt(1, new Move(Move2ID.Value));
            }
            if (Move3ID.HasValue)
            {
                pkm.SetMoveAt(2, new Move(Move3ID.Value));
            }
            if (Move4ID.HasValue)
            {
                pkm.SetMoveAt(3, new Move(Move4ID.Value));
            }

            GameTypes gameType = gameSave.GameType;

            if (gameType == GameTypes.Ruby)
            {
                pkm.GameOrigin = GameOrigins.Ruby;
            }
            else if (gameType == GameTypes.Sapphire)
            {
                pkm.GameOrigin = GameOrigins.Sapphire;
            }
            else if (gameType == GameTypes.Emerald)
            {
                pkm.GameOrigin = GameOrigins.Emerald;
            }
            else if (gameType == GameTypes.FireRed)
            {
                pkm.GameOrigin = GameOrigins.FireRed;
            }
            else if (gameType == GameTypes.LeafGreen)
            {
                pkm.GameOrigin = GameOrigins.LeafGreen;
            }
            else if (gameType == GameTypes.Colosseum ||
                     gameType == GameTypes.XD)
            {
                pkm.GameOrigin = GameOrigins.ColosseumXD;
            }
            else
            {
                pkm.GameOrigin = GameOrigins.Emerald;
            }

            pkm.GameType = gameType;
            pkm.Checksum = pkm.CalculateChecksum();
            pkm.RecalculateStats();
            reward = pkm;
        }
        public override void GenerateReward(IGameSave gameSave)
        {
            Random random = new Random((int)DateTime.Now.Ticks);
            PokemonData pokemonData = PokemonDatabase.GetPokemonFromDexID(DexID);
            GBAPokemon pkm = new GBAPokemon();

            pkm.DexID = DexID;
            pkm.Personality = (Personality.HasValue ? Personality.Value : (uint)random.Next());
            pkm.Experience = PokemonDatabase.GetExperienceFromLevel(pokemonData.ExperienceGroup, (IsEgg ? (byte)5 : Level));
            pkm.IsSecondAbility2 = (IsSecondAbility.HasValue ? IsSecondAbility.Value : (!pokemonData.CanOnlyHaveFirstAbility && random.Next(2) == 1));
            pkm.Nickname = (Nickname != null ? Nickname : pokemonData.Name.ToUpper());
            pkm.BallCaughtID = 4;
            pkm.MetLocationID = 255;
            if (DexID == 151 || DexID == 386)
                pkm.IsFatefulEncounter = true;
            pkm.LevelMet = (IsEgg ? (byte)0 : Level);
            pkm.Language = Languages.English;
            pkm.Friendship = (byte)(IsEgg ? 10 : 70);

            // Ownership
            pkm.TrainerName = (TrainerName != null ? TrainerName : PokeManager.ManagerGameSave.TrainerName);
            pkm.TrainerGender = (TrainerGender.HasValue ? TrainerGender.Value : PokeManager.ManagerGameSave.TrainerGender);
            pkm.TrainerID = (TrainerID.HasValue ? TrainerID.Value : PokeManager.ManagerGameSave.TrainerID);
            pkm.SecretID = (SecretID.HasValue ? SecretID.Value : PokeManager.ManagerGameSave.SecretID);
            if (TrainerGender.HasValue && TrainerGender.Value == Genders.Genderless)
                pkm.TrainerGender = (random.Next(2) == 1 ? Genders.Female : Genders.Male);

            if (!Personality.HasValue)
                GeneratePID(pkm, random);

            if (HeldItem != null) pkm.HeldItemID = HeldItem[random.Next(HeldItem.Length)];

            if (Conditions != null) {
                pkm.Coolness	= Conditions[0];
                pkm.Beauty		= Conditions[1];
                pkm.Cuteness	= Conditions[2];
                pkm.Smartness	= Conditions[3];
                pkm.Toughness	= Conditions[4];
                pkm.Feel		= Conditions[5];
            }

            pkm.HPIV		= (IVs != null ? IVs[0] : (byte)random.Next(32));
            pkm.AttackIV	= (IVs != null ? IVs[1] : (byte)random.Next(32));
            pkm.DefenseIV	= (IVs != null ? IVs[2] : (byte)random.Next(32));
            pkm.SpAttackIV	= (IVs != null ? IVs[3] : (byte)random.Next(32));
            pkm.SpDefenseIV	= (IVs != null ? IVs[4] : (byte)random.Next(32));
            pkm.SpeedIV		= (IVs != null ? IVs[5] : (byte)random.Next(32));

            if (HiddenPowerDamage.HasValue)	pkm.SetHiddenPowerDamage(HiddenPowerDamage.Value);
            if (HiddenPowerType.HasValue) pkm.SetHiddenPowerType(HiddenPowerType.Value);

            // Teach the Pokemon all of it's default moves
            ushort[] moves = PokemonDatabase.GetMovesLearnedAtLevelRange(pkm, 1, (IsEgg ? (byte)5 : Level));
            foreach (ushort moveID in moves) {
                if (!PokemonDatabase.PokemonHasMove(pkm, moveID)) {
                    if (pkm.NumMoves < 4) {
                        pkm.SetMoveAt(pkm.NumMoves, new Move(moveID));
                    }
                    else {
                        for (int i = 0; i < 3; i++) {
                            pkm.SetMoveAt(i, pkm.GetMoveAt(i + 1));
                        }
                        pkm.SetMoveAt(3, new Move(moveID));
                    }
                }
            }
            if (Move1ID.HasValue) pkm.SetMoveAt(0, new Move(Move1ID.Value));
            if (Move2ID.HasValue) pkm.SetMoveAt(1, new Move(Move2ID.Value));
            if (Move3ID.HasValue) pkm.SetMoveAt(2, new Move(Move3ID.Value));
            if (Move4ID.HasValue) pkm.SetMoveAt(3, new Move(Move4ID.Value));

            GameTypes gameType = gameSave.GameType;
            if (gameType == GameTypes.Ruby)				pkm.GameOrigin = GameOrigins.Ruby;
            else if (gameType == GameTypes.Sapphire)	pkm.GameOrigin = GameOrigins.Sapphire;
            else if (gameType == GameTypes.Emerald)		pkm.GameOrigin = GameOrigins.Emerald;
            else if (gameType == GameTypes.FireRed)		pkm.GameOrigin = GameOrigins.FireRed;
            else if (gameType == GameTypes.LeafGreen)	pkm.GameOrigin = GameOrigins.LeafGreen;
            else if (gameType == GameTypes.Colosseum ||
                     gameType == GameTypes.XD)			pkm.GameOrigin = GameOrigins.ColosseumXD;
            else										pkm.GameOrigin = GameOrigins.Emerald;

            pkm.GameType = gameType;
            pkm.Checksum = pkm.CalculateChecksum();
            pkm.RecalculateStats();
            reward = pkm;
        }