Exemple #1
0
        public void Camouflage_Fails()
        {
            #region Setup
            PBERandom.SetSeed(0);
            PBESettings settings = PBESettings.DefaultSettings;

            var p0 = new TestPokemonCollection(1);
            p0[0] = new TestPokemon(settings, PBESpecies.Staryu, 0, 100, PBEMove.Camouflage);

            var p1 = new TestPokemonCollection(1);
            p1[0] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 100, PBEMove.Splash);

            var battle = new PBEBattle(PBEBattleFormat.Single, settings, new PBETrainerInfo(p0, "Trainer 0"), new PBETrainerInfo(p1, "Trainer 1"), battleTerrain: PBEBattleTerrain.Water);
            battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler;
            battle.Begin();

            PBETrainer       t0       = battle.Trainers[0];
            PBETrainer       t1       = battle.Trainers[1];
            PBEBattlePokemon staryu   = t0.Party[0];
            PBEBattlePokemon magikarp = t1.Party[0];
            #endregion

            #region Use Camouflage and check
            Assert.True(PBEBattle.SelectActionsIfValid(t0, new PBETurnAction(staryu, PBEMove.Camouflage, PBETurnTarget.AllyCenter)));
            Assert.True(PBEBattle.SelectActionsIfValid(t1, new PBETurnAction(magikarp, PBEMove.Splash, PBETurnTarget.AllyCenter)));

            battle.RunTurn();

            Assert.True(battle.VerifyMoveResultHappened(staryu, staryu, PBEResult.InvalidConditions));
            #endregion

            #region Cleanup
            battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler;
            #endregion
        }
Exemple #2
0
        public void Camouflage_Works(PBEBattleTerrain battleTerrain, PBEType expectedType, PBESpecies species)
        {
            #region Setup
            PBERandom.SetSeed(0);
            PBESettings settings = PBESettings.DefaultSettings;

            var p0 = new TestPokemonCollection(1);
            p0[0] = new TestPokemon(settings, species, 0, 100, PBEMove.Camouflage);

            var p1 = new TestPokemonCollection(1);
            p1[0] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 100, PBEMove.Splash);

            var battle = new PBEBattle(PBEBattleFormat.Single, settings, new PBETrainerInfo(p0, "Trainer 0"), new PBETrainerInfo(p1, "Trainer 1"), battleTerrain: battleTerrain);
            battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler;
            battle.Begin();

            PBETrainer       t0          = battle.Trainers[0];
            PBETrainer       t1          = battle.Trainers[1];
            PBEBattlePokemon camouflager = t0.Party[0];
            PBEBattlePokemon magikarp    = t1.Party[0];
            #endregion

            #region Use Camouflage and check
            Assert.True(PBEBattle.SelectActionsIfValid(t0, new PBETurnAction(camouflager, PBEMove.Camouflage, PBETurnTarget.AllyCenter)));
            Assert.True(PBEBattle.SelectActionsIfValid(t1, new PBETurnAction(magikarp, PBEMove.Splash, PBETurnTarget.AllyCenter)));

            battle.RunTurn();

            Assert.True(camouflager.Type1 == expectedType && camouflager.Type2 == PBEType.None);
            #endregion

            #region Cleanup
            battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler;
            #endregion
        }
        public void Fainted_Pkmn_Not_Sent_Out_Double()
        {
            #region Setup
            PBEDataProvider.GlobalRandom.Seed = 0;
            PBESettings settings = PBESettings.DefaultSettings;

            var p0 = new TestPartyPokemonCollection(3);
            p0[0] = new TestPartyPokemon(settings, PBESpecies.Magikarp, 0, 100, PBEMove.Splash);
            p0[1] = new TestPartyPokemon(settings, PBESpecies.Absol, 0, 100, PBEMove.Splash)
            {
                HP = 0
            };
            p0[2] = new TestPartyPokemon(settings, PBESpecies.Feebas, 0, 100, PBEMove.Splash);

            var p1 = new TestPokemonCollection(1);
            p1[0] = new TestPokemon(settings, PBESpecies.Darkrai, 0, 100, PBEMove.Splash);

            var battle = PBEBattle.CreateTrainerBattle(PBEBattleFormat.Double, settings, new PBETrainerInfo(p0, "Trainer 0", false), new PBETrainerInfo(p1, "Trainer 1", false));

            PBETrainer       t0       = battle.Trainers[0];
            PBEBattlePokemon magikarp = t0.Party[0];
            PBEBattlePokemon absol    = t0.Party[1];
            PBEBattlePokemon feebas   = t0.Party[2];

            battle.Begin();
            #endregion

            #region Check
            Assert.True(magikarp.FieldPosition == PBEFieldPosition.Left &&
                        absol.FieldPosition == PBEFieldPosition.None &&
                        feebas.FieldPosition == PBEFieldPosition.Right);
            #endregion
        }
        public void Illusion_Does_Not_Copy_Same_Species()
        {
            #region Setup
            PBERandom.SetSeed(0);
            PBESettings settings = PBESettings.DefaultSettings;

            var p0 = new TestPokemonCollection(1);
            p0[0] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 100, PBEMove.Splash);

            var p1 = new TestPokemonCollection(2);
            p1[0] = p1[1] = new TestPokemon(settings, PBESpecies.Zoroark, 0, 100, PBEMove.Splash)
            {
                Ability = PBEAbility.Illusion
            };

            var battle = new PBEBattle(PBEBattleFormat.Single, settings, new PBETrainerInfo(p0, "Trainer 0"), new PBETrainerInfo(p1, "Trainer 1"));
            battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler;
            battle.Begin();

            PBETrainer       t1       = battle.Trainers[1];
            PBEBattlePokemon zoroark1 = t1.Party[0];
            #endregion

            #region Check
            Assert.True(zoroark1.DisguisedAsPokemon == null);
            #endregion

            #region Cleanup
            battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler;
            #endregion
        }
Exemple #5
0
        public static void Main(string[] args)
        {
            Console.WriteLine("----- Pokémon Battle Engine Test -----");

            PBESettings settings = PBESettings.DefaultSettings;

            PBEPokemonShell[] team0Party = PBECompetitivePokemonShells.CreateRandomTeam(settings.MaxPartySize).ToArray();
            PBEPokemonShell[] team1Party = PBECompetitivePokemonShells.CreateRandomTeam(settings.MaxPartySize).ToArray();
            PBEBattle         battle     = new PBEBattle(PBEBattleFormat.Triple, settings, team0Party, team1Party);

            battle.Teams[0].TrainerName = "Team 1";
            battle.Teams[1].TrainerName = "Team 2";
            battle.OnNewEvent          += PBEBattle.ConsoleBattleEventHandler;
            battle.OnStateChanged      += Battle_OnStateChanged;
            try
            {
                writer = new StreamWriter(new FileStream(logFile, FileMode.Create, FileAccess.Write));
            }
            catch (Exception e)
            {
                Console.WriteLine($"Cannot open \"{logFile}\" for writing.");
                Console.WriteLine(e.Message);
                return;
            }
            oldWriter = Console.Out;
            Console.SetOut(writer);
            battle.Begin();
        }
        public void TeamProtection_Works(PBEMove move, PBEMove move2, PBETeamStatus teamStatus)
        {
            #region Setup
            PBERandom.SetSeed(0);
            PBESettings settings = PBESettings.DefaultSettings;

            var p0 = new TestPokemonCollection(1);
            p0[0] = new TestPokemon(settings, PBESpecies.Mienshao, 0, 100, move);

            var p1 = new TestPokemonCollection(1);
            p1[0] = new TestPokemon(settings, PBESpecies.Lucario, 0, 100, move2);

            var battle = new PBEBattle(PBEBattleFormat.Single, settings, new PBETrainerInfo(p0, "Trainer 0"), new PBETrainerInfo(p1, "Trainer 1"));
            battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler;
            battle.Begin();

            PBETrainer       t0       = battle.Trainers[0];
            PBETrainer       t1       = battle.Trainers[1];
            PBEBattlePokemon mienshao = t0.Party[0];
            PBEBattlePokemon lucario  = t1.Party[0];
            #endregion

            #region Use move and check
            Assert.True(PBEBattle.SelectActionsIfValid(t0, new PBETurnAction(mienshao, move, PBETurnTarget.AllyCenter)));
            Assert.True(PBEBattle.SelectActionsIfValid(t1, new PBETurnAction(lucario, move2, PBETurnTarget.FoeCenter)));

            battle.RunTurn();

            Assert.True(battle.VerifyTeamStatusHappened(t0.Team, teamStatus, PBETeamStatusAction.Damage, damageVictim: mienshao) && !t0.Team.TeamStatus.HasFlag(teamStatus));
            #endregion

            #region Cleanup
            battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler;
            #endregion
        }
        public void Wild_Pkmn_Positions_Set_Before_Begin()
        {
            #region Setup
            PBEDataProvider.GlobalRandom.Seed = 0;
            PBESettings settings = PBESettings.DefaultSettings;

            var p0 = new TestPokemonCollection(1);
            p0[0] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 100, PBEMove.Splash);

            var p1 = new TestPokemonCollection(1);
            p1[0] = new TestPokemon(settings, PBESpecies.Darkrai, 0, 100, PBEMove.Splash)
            {
                CaughtBall = PBEItem.None
            };

            var battle = PBEBattle.CreateWildBattle(PBEBattleFormat.Single, settings, new PBETrainerInfo(p0, "Trainer 0", false), new PBEWildInfo(p1));

            PBETrainer       t1      = battle.Trainers[1];
            PBEBattlePokemon darkrai = t1.Party[0];
            #endregion

            #region Check
            Assert.True(darkrai.FieldPosition == PBEFieldPosition.Center &&
                        battle.ActiveBattlers.Single() == darkrai);
            #endregion
        }
        public void Illusion_Does_Copy_Active_Trainer_Teammate()
        {
            #region Setup
            PBEDataProvider.GlobalRandom.Seed = 0;
            PBESettings settings = PBESettings.DefaultSettings;

            var p0 = new TestPokemonCollection(1);
            p0[0] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 100, PBEMove.Splash);

            var p1 = new TestPokemonCollection(2);
            p1[0] = new TestPokemon(settings, PBESpecies.Zoroark, 0, 100, PBEMove.Splash)
            {
                Ability = PBEAbility.Illusion
            };
            p1[1] = p0[0];

            var battle = PBEBattle.CreateTrainerBattle(PBEBattleFormat.Double, settings, new PBETrainerInfo(p0, "Trainer 0", false), new PBETrainerInfo(p1, "Trainer 1", false));
            battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler;

            PBETrainer       t1      = battle.Trainers[1];
            PBEBattlePokemon zoroark = t1.Party[0];

            battle.Begin();
            #endregion

            #region Check
            Assert.True(zoroark.Status2.HasFlag(PBEStatus2.Disguised));
            #endregion

            #region Cleanup
            battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler;
            #endregion
        }
            public async Task Challenge(SocketUser battler1)
            {
                if (battler1.Id == Context.User.Id)
                {
                    //
                }
                else if (BattleContext.GetBattleContext(Context.User) != null)
                {
                    await Context.Channel.SendMessageAsync($"{Context.User.Username} is already participating in a battle.");
                }
                else if (BattleContext.GetBattleContext(battler1) != null)
                {
                    await Context.Channel.SendMessageAsync($"{battler1.Username} is already participating in a battle.");
                }
                else
                {
                    PBESettings       settings = PBESettings.DefaultSettings;
                    PBEPokemonShell[] team0Party, team1Party;
                    // Completely Randomized Pokémon
                    team0Party = PBEUtils.CreateCompletelyRandomTeam(settings, true);
                    team1Party = PBEUtils.CreateCompletelyRandomTeam(settings, true);

                    var battle = new PBEBattle(PBEBattleFormat.Single, settings, team0Party, team1Party);
                    battle.Teams[0].TrainerName = Context.User.Username;
                    battle.Teams[1].TrainerName = battler1.Username;
                    var battleContext = new BattleContext(battle, Context.User, battler1, Context.Channel);
                }
            }
Exemple #10
0
 public PBEBattle(PBEBattleFormat battleFormat, PBESettings settings, IEnumerable <PBEPokemonShell> team0Party, IEnumerable <PBEPokemonShell> team1Party)
 {
     if (battleFormat >= PBEBattleFormat.MAX)
     {
         throw new ArgumentOutOfRangeException(nameof(battleFormat));
     }
     if (team0Party == null)
     {
         throw new ArgumentNullException(nameof(team0Party));
     }
     if (team1Party == null)
     {
         throw new ArgumentNullException(nameof(team1Party));
     }
     if (team0Party.Count() == 0 || team0Party.Count() > settings.MaxPartySize)
     {
         throw new ArgumentOutOfRangeException(nameof(team0Party));
     }
     if (team1Party.Count() == 0 || team1Party.Count() > settings.MaxPartySize)
     {
         throw new ArgumentOutOfRangeException(nameof(team1Party));
     }
     BattleFormat = battleFormat;
     Settings     = settings;
     Teams[0]     = new PBETeam(this, 0, team0Party, ref pkmnIdCounter);
     Teams[1]     = new PBETeam(this, 1, team1Party, ref pkmnIdCounter);
     CheckForReadiness();
 }
        private PBEBattle(BinaryReader r)
        {
            ushort version = r.ReadUInt16();

            Settings = new PBESettings(r);
            Settings.MakeReadOnly();
            BattleFormat = (PBEBattleFormat)r.ReadByte();
            Teams        = new PBETeams(this);

            var packetProcessor = new PBEPacketProcessor(this);
            int numEvents       = r.ReadInt32();

            for (int i = 0; i < numEvents; i++)
            {
                INetPacket packet = packetProcessor.CreatePacket(r.ReadBytes(r.ReadInt16()));
                switch (packet)
                {
                case PBEWinnerPacket wp:
                {
                    Winner = wp.WinningTeam;
                    break;
                }
                }
                Events.Add(packet);
            }

            BattleState = PBEBattleState.Ended;
            OnStateChanged?.Invoke(this);
        }
Exemple #12
0
 public static void ValidateLevel(byte value, PBESettings settings)
 {
     if (value < settings.MinLevel || value > settings.MaxLevel)
     {
         throw new ArgumentOutOfRangeException(nameof(value), $"{nameof(value)} must be at least {nameof(settings.MinLevel)} ({settings.MinLevel}) and cannot exceed {nameof(settings.MaxLevel)} ({settings.MaxLevel}).");
     }
 }
        public void Wild_Battle_Throws_For_Illegal_Party_Size(PBEBattleFormat format, int count, bool expectException)
        {
            #region Setup and check
            PBEDataProvider.GlobalRandom.Seed = 0;
            PBESettings settings = PBESettings.DefaultSettings;

            var p0 = new TestPokemonCollection(1);
            p0[0] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 100, PBEMove.Splash);

            var p1 = new TestPokemonCollection(count);
            p1[0] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 100, PBEMove.Splash)
            {
                CaughtBall = PBEItem.None
            };
            for (int i = 1; i < count; i++)
            {
                p1[i] = p1[0];
            }

            if (expectException)
            {
                Assert.Throws <ArgumentException>(() => new PBEBattle(format, settings, new PBETrainerInfo(p0, "Trainer 0"), new PBEWildInfo(p1)));
            }
            #endregion
        }
Exemple #14
0
        public void Intimidate_Does_Not_Announce_If_No_Foes()
        {
            #region Setup
            PBERandom.SetSeed(0);
            PBESettings settings = PBESettings.DefaultSettings;

            var p0 = new TestPokemonCollection(1);
            p0[0] = new TestPokemon(settings, PBESpecies.Shuckle, 0, 100, PBEMove.Splash);

            var p1 = new TestPokemonCollection(2);
            p1[0] = new TestPokemon(settings, PBESpecies.Luxray, 0, 100, PBEMove.Splash)
            {
                Ability = PBEAbility.Intimidate
            };
            p1[1] = new TestPokemon(settings, PBESpecies.Skitty, 0, 100, PBEMove.Splash);

            var battle = new PBEBattle(PBEBattleFormat.Triple, settings, new PBETrainerInfo(p0, "Trainer 0"), new PBETrainerInfo(p1, "Trainer 1"));
            battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler;
            battle.Begin();

            PBETrainer       t0      = battle.Trainers[0];
            PBETrainer       t1      = battle.Trainers[1];
            PBEBattlePokemon shuckle = t0.Party[0];
            PBEBattlePokemon luxray  = t1.Party[0];
            PBEBattlePokemon skitty  = t1.Party[1];
            #endregion

            #region Check
            Assert.True(!battle.VerifyAbilityHappened(luxray, luxray, PBEAbility.Intimidate, PBEAbilityAction.Stats)); // Did not activate
            #endregion

            #region Cleanup
            battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler;
            #endregion
        }
Exemple #15
0
        public void Basic_Actions()
        {
            #region Setup
            PBERandom.SetSeed(0);
            PBESettings settings = PBESettings.DefaultSettings;

            var p0 = new TestPokemonCollection(2);
            p0[0] = new TestPokemon(settings, PBESpecies.Koffing, 0, 100, PBEMove.Selfdestruct);
            p0[1] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 100, PBEMove.Splash);

            var p1 = new TestPokemonCollection(1);
            p1[0] = new TestPokemon(settings, PBESpecies.Darkrai, 0, 100, PBEMove.Protect);

            var battle = new PBEBattle(PBEBattleFormat.Single, settings, new PBETrainerInfo(p0, "Trainer 0"), new PBETrainerInfo(p1, "Trainer 1"));
            battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler;
            battle.Begin();

            PBETrainer       t0       = battle.Trainers[0];
            PBETrainer       t1       = battle.Trainers[1];
            PBEBattlePokemon koffing  = t0.Party[0];
            PBEBattlePokemon magikarp = t0.Party[1];
            PBEBattlePokemon darkrai  = t1.Party[0];
            #endregion

            #region Darkrai uses Protect, Koffing uses Selfdestruct and faints
            var a = new PBETurnAction(koffing, PBEMove.Selfdestruct, PBETurnTarget.FoeCenter);
            Assert.Throws <ArgumentNullException>(() => PBEBattle.SelectActionsIfValid(null, a));                                   // Throw for null team
            Assert.Throws <ArgumentNullException>(() => PBEBattle.SelectActionsIfValid(t0, (IReadOnlyList <PBETurnAction>)null));   // Throw for null collection
            Assert.Throws <ArgumentNullException>(() => PBEBattle.SelectActionsIfValid(t0, new PBETurnAction[] { null }));          // Throw for null elements
            Assert.False(PBEBattle.SelectActionsIfValid(t0, a, a));                                                                 // False for too many actions
            Assert.True(PBEBattle.SelectActionsIfValid(t0, a));                                                                     // True for good actions
                                                                                                                                    // TODO: bad field position to switch into, bad move, bad targets, bad targets with templockedmove, battle status, bad pkmn id, wrong team pkmn id, duplicate pkmn id, can't switch out but tried, invalid switch mon (null hp pos), duplicate switch mon
            Assert.False(PBEBattle.SelectActionsIfValid(t0, a));                                                                    // False because actions were already submitted
            Assert.False(PBEBattle.SelectActionsIfValid(t0, Array.Empty <PBETurnAction>()));                                        // False for 0 despite us now needing 0 additional actions

            Assert.True(PBEBattle.SelectActionsIfValid(t1, new PBETurnAction(darkrai, PBEMove.Protect, PBETurnTarget.AllyCenter))); // True for good actions

            battle.RunTurn();
            #endregion

            #region More checks
            var s = new PBESwitchIn(magikarp, PBEFieldPosition.Center);
            Assert.Throws <ArgumentNullException>(() => PBEBattle.SelectSwitchesIfValid(null, s));                               // Throw for null team
            Assert.Throws <ArgumentNullException>(() => PBEBattle.SelectSwitchesIfValid(t0, (IReadOnlyList <PBESwitchIn>)null)); // Throw for null collection
            Assert.Throws <ArgumentNullException>(() => PBEBattle.SelectSwitchesIfValid(t0, new PBESwitchIn[] { null }));        // Throw for null elements
            Assert.False(PBEBattle.SelectSwitchesIfValid(t0, s, s));                                                             // False for too many
            Assert.True(PBEBattle.SelectSwitchesIfValid(t0, s));                                                                 // True for good switches

            // Below two wouldn't work because of battle status lol
            //Assert.False(PBEBattle.SelectSwitchesIfValid(t0, s)); // False because switches were already submitted
            //Assert.False(PBEBattle.SelectSwitchesIfValid(t0, Array.Empty<PBESwitchIn>())); // False for 0 despite us now needing 0 additional actions

            //battle.RunSwitches();
            #endregion

            #region Cleanup
            battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler;
            #endregion
        }
Exemple #16
0
 /// <summary>Returns a random <see cref="byte"/> value that is between <paramref name="settings"/>'s <see cref="PBESettings.MinLevel"/> and <see cref="PBESettings.MaxLevel"/>.</summary>
 /// <param name="settings">The <see cref="PBESettings"/> object to use.</param>
 /// <exception cref="ArgumentNullException">Thrown when <paramref name="settings"/> is null.</exception>
 public static byte RandomLevel(PBESettings settings)
 {
     if (settings == null)
     {
         throw new ArgumentNullException(nameof(settings));
     }
     return((byte)RandomInt(settings.MinLevel, settings.MaxLevel));
 }
Exemple #17
0
        internal PBELegalPartyResponsePacket(byte[] data, EndianBinaryReader r)
        {
            Data = new ReadOnlyCollection <byte>(data);
            var s = new PBESettings(r);

            s.MakeReadOnly();
            Party = new PBELegalPokemonCollection(s, r);
        }
Exemple #18
0
        public void CastformCherrim_Interacts_With_AirLock(PBESpecies species, PBEAbility ability, PBEForm form)
        {
            #region Setup
            PBEDataProvider.GlobalRandom.Seed = 0;
            PBESettings settings = PBESettings.DefaultSettings;

            var p0 = new TestPokemonCollection(2);
            p0[0] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 100, PBEMove.Splash);
            p0[1] = new TestPokemon(settings, PBESpecies.Rayquaza, 0, 100, PBEMove.Splash)
            {
                Ability = PBEAbility.AirLock
            };

            var p1 = new TestPokemonCollection(1);
            p1[0] = new TestPokemon(settings, species, 0, 100, PBEMove.Splash)
            {
                Ability = ability
            };

            var battle = new PBEBattle(PBEBattleFormat.Single, settings, new PBETrainerInfo(p0, "Trainer 0"), new PBETrainerInfo(p1, "Trainer 1"),
                                       weather: PBEWeather.HarshSunlight);
            battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler;

            PBETrainer       t0              = battle.Trainers[0];
            PBETrainer       t1              = battle.Trainers[1];
            PBEBattlePokemon magikarp        = t0.Party[0];
            PBEBattlePokemon rayquaza        = t0.Party[1];
            PBEBattlePokemon castformCherrim = t1.Party[0];

            battle.Begin();
            #endregion

            #region Check Castform/Cherrim for correct form
            Assert.True(battle.Weather == PBEWeather.HarshSunlight && castformCherrim.Form == form);
            #endregion

            #region Swap Magikarp for Rayquaza and check for no form
            Assert.Null(t0.SelectActionsIfValid(new PBETurnAction(magikarp, rayquaza)));
            Assert.Null(t1.SelectActionsIfValid(new PBETurnAction(castformCherrim, PBEMove.Splash, PBETurnTarget.AllyCenter)));

            battle.RunTurn();

            Assert.True(battle.Weather == PBEWeather.HarshSunlight && castformCherrim.Form == 0);
            #endregion

            #region Swap Rayquaza for Magikarp and check for correct form
            Assert.Null(t0.SelectActionsIfValid(new PBETurnAction(rayquaza, magikarp)));
            Assert.Null(t1.SelectActionsIfValid(new PBETurnAction(castformCherrim, PBEMove.Splash, PBETurnTarget.AllyCenter)));

            battle.RunTurn();

            Assert.True(battle.Weather == PBEWeather.HarshSunlight && castformCherrim.Form == form);
            #endregion

            #region Cleanup
            battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler;
            #endregion
        }
        public void Illusion_Works_Wild()
        {
            #region Setup
            PBEDataProvider.GlobalRandom.Seed = 0;
            PBESettings settings = PBESettings.DefaultSettings;

            var p0 = new TestPokemonCollection(1);
            p0[0] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 1, PBEMove.Tackle);

            var p1 = new TestPokemonCollection(1);
            p1[0] = new TestPokemon(settings, PBESpecies.Zoroark, 0, 100, PBEMove.Splash)
            {
                Ability    = PBEAbility.Illusion,
                CaughtBall = PBEItem.None
            };

            var battle = PBEBattle.CreateWildBattle(PBEBattleFormat.Single, settings, new PBETrainerInfo(p0, "Trainer 0", false), new PBEWildInfo(p1));
            battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler;

            PBETrainer       t0       = battle.Trainers[0];
            PBETrainer       t1       = battle.Trainers[1];
            PBEBattlePokemon magikarp = t0.Party[0];
            PBEBattlePokemon zoroark  = t1.Party[0];

            zoroark.Status2        |= PBEStatus2.Disguised;
            zoroark.KnownGender     = PBEGender.Genderless;
            zoroark.KnownCaughtBall = PBEItem.None;
            zoroark.KnownShiny      = false;
            zoroark.KnownSpecies    = PBESpecies.Entei;
            zoroark.KnownForm       = 0;
            zoroark.KnownNickname   = zoroark.KnownSpecies.ToString();
            IPBEPokemonData pData = PBEDataProvider.Instance.GetPokemonData(zoroark.KnownSpecies, zoroark.KnownForm);
            zoroark.KnownType1 = pData.Type1;
            zoroark.KnownType2 = pData.Type2;

            battle.Begin();
            #endregion

            #region Check that the disguise works
            Assert.True(zoroark.Status2.HasFlag(PBEStatus2.Disguised) &&
                        ((PBEWildPkmnAppearedPacket)battle.Events.Single(p => p is PBEWildPkmnAppearedPacket)).Pokemon[0].IsDisguised);
            #endregion

            #region Break the disguise and check
            Assert.True(t0.SelectActionsIfValid(out _, new PBETurnAction(magikarp, PBEMove.Tackle, PBETurnTarget.FoeCenter)));
            Assert.True(t1.SelectActionsIfValid(out _, new PBETurnAction(zoroark, PBEMove.Splash, PBETurnTarget.AllyCenter)));

            battle.RunTurn();

            Assert.True(!zoroark.Status2.HasFlag(PBEStatus2.Disguised) &&
                        zoroark.KnownSpecies == PBESpecies.Zoroark);
            #endregion

            #region Cleanup
            battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler;
            #endregion
        }
        public void Basic_Actions()
        {
            #region Setup
            PBEDataProvider.GlobalRandom.Seed = 0;
            PBESettings settings = PBESettings.DefaultSettings;

            var p0 = new TestPokemonCollection(2);
            p0[0] = new TestPokemon(settings, PBESpecies.Koffing, 0, 100, PBEMove.Selfdestruct);
            p0[1] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 100, PBEMove.Splash);

            var p1 = new TestPokemonCollection(1);
            p1[0] = new TestPokemon(settings, PBESpecies.Darkrai, 0, 100, PBEMove.Protect);

            var battle = new PBEBattle(PBEBattleFormat.Single, settings, new PBETrainerInfo(p0, "Trainer 0"), new PBETrainerInfo(p1, "Trainer 1"));
            battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler;

            PBETrainer       t0       = battle.Trainers[0];
            PBETrainer       t1       = battle.Trainers[1];
            PBEBattlePokemon koffing  = t0.Party[0];
            PBEBattlePokemon magikarp = t0.Party[1];
            PBEBattlePokemon darkrai  = t1.Party[0];

            battle.Begin();
            #endregion

            #region Darkrai uses Protect, Koffing uses Selfdestruct and faints
            var a = new PBETurnAction(koffing, PBEMove.Selfdestruct, PBETurnTarget.FoeCenter);
            Assert.Throws <ArgumentNullException>(() => t0.SelectActionsIfValid((IReadOnlyList <PBETurnAction>)null));   // Throw for null collection
            Assert.Throws <ArgumentNullException>(() => t0.SelectActionsIfValid(new PBETurnAction[] { null }));          // Throw for null elements
            Assert.NotNull(t0.SelectActionsIfValid(a, a));                                                               // Too many actions
            Assert.Null(t0.SelectActionsIfValid(a));                                                                     // Good actions
            Assert.NotNull(t0.SelectActionsIfValid(a));                                                                  // Actions were already submitted
            Assert.NotNull(t0.SelectActionsIfValid(Array.Empty <PBETurnAction>()));                                      // 0 despite us now needing 0 additional actions

            Assert.Null(t1.SelectActionsIfValid(new PBETurnAction(darkrai, PBEMove.Protect, PBETurnTarget.AllyCenter))); // True for good actions

            battle.RunTurn();
            #endregion

            #region More checks
            var s = new PBESwitchIn(magikarp, PBEFieldPosition.Center);
            Assert.Throws <ArgumentNullException>(() => t0.SelectSwitchesIfValid((IReadOnlyList <PBESwitchIn>)null)); // Throw for null collection
            Assert.Throws <ArgumentNullException>(() => t0.SelectSwitchesIfValid(new PBESwitchIn[] { null }));        // Throw for null elements
            Assert.NotNull(t0.SelectSwitchesIfValid(s, s));                                                           // Too many
            Assert.Null(t0.SelectSwitchesIfValid(s));                                                                 // Good switches

            // Below two wouldn't work because of battle status lol
            //Assert.NotNull(t0.SelectSwitchesIfValid(s)); // Switches were already submitted
            //Assert.NotNull(t0.SelectSwitchesIfValid(Array.Empty<PBESwitchIn>())); // 0 despite us now needing 0 additional switches

            //battle.RunSwitches();
            #endregion

            #region Cleanup
            battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler;
            #endregion
        }
Exemple #21
0
        public void Gem_Does_Not_Activate__Effectiveness()
        {
            #region Setup
            PBEDataProvider.GlobalRandom.Seed = 0;
            PBESettings settings = PBESettings.DefaultSettings;

            var p0 = new TestPokemonCollection(2);
            p0[0] = new TestPokemon(settings, PBESpecies.Excadrill, 0, 100, PBEMove.Earthquake)
            {
                Item = PBEItem.GroundGem
            };
            p0[1] = new TestPokemon(settings, PBESpecies.Starly, 0, 1, PBEMove.Splash);

            var p1 = new TestPokemonCollection(2);
            p1[0] = new TestPokemon(settings, PBESpecies.Rotom, 0, 1, PBEMove.Splash)
            {
                Ability = PBEAbility.Levitate
            };
            p1[1] = new TestPokemon(settings, PBESpecies.Shedinja, 0, 1, PBEMove.Splash)
            {
                Ability = PBEAbility.WonderGuard
            };

            var battle = PBEBattle.CreateTrainerBattle(PBEBattleFormat.Double, settings, new PBETrainerInfo(p0, "Trainer 0", false), new PBETrainerInfo(p1, "Trainer 1", false));
            battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler;

            PBETrainer       t0        = battle.Trainers[0];
            PBETrainer       t1        = battle.Trainers[1];
            PBEBattlePokemon excadrill = t0.Party[0];
            PBEBattlePokemon starly    = t0.Party[1];
            PBEBattlePokemon rotom     = t1.Party[0];
            PBEBattlePokemon shedinja  = t1.Party[1];

            battle.Begin();
            #endregion

            #region Use and check
            Assert.True(t0.SelectActionsIfValid(out _,
                                                new PBETurnAction(excadrill, PBEMove.Earthquake, PBETurnTarget.AllyRight | PBETurnTarget.FoeLeft | PBETurnTarget.FoeRight),
                                                new PBETurnAction(starly, PBEMove.Splash, PBETurnTarget.AllyRight)));
            Assert.True(t1.SelectActionsIfValid(out _,
                                                new PBETurnAction(rotom, PBEMove.Splash, PBETurnTarget.AllyLeft),
                                                new PBETurnAction(shedinja, PBEMove.Splash, PBETurnTarget.AllyRight)));

            battle.RunTurn();

            Assert.True(battle.VerifyMoveResultHappened(excadrill, starly, PBEResult.Ineffective_Type) && starly.HPPercentage == 1 && // Doesn't affect Flying
                        battle.VerifyMoveResultHappened(excadrill, rotom, PBEResult.Ineffective_Ability) && rotom.HPPercentage == 1 && // Doesn't affect Levitate
                        battle.VerifyMoveResultHappened(excadrill, shedinja, PBEResult.Ineffective_Ability) && shedinja.HPPercentage == 1 && // Doesn't affect WonderGuard
                        excadrill.Item == PBEItem.GroundGem); // Gem not consumed
            #endregion

            #region Cleanup
            battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler;
            #endregion
        }
        /// <summary>Creates an array of <see cref="PBEPokemonShell"/>s each with completely random properties. The amount to create is <see cref="PBESettings.MaxPartySize"/>.</summary>
        /// <param name="settings">The settings to use.</param>
        /// <param name="setToMaxLevel">True if <see cref="PBEPokemonShell.Level"/> will be set to <see cref="PBESettings.MaxLevel"/>.</param>
        public static PBEPokemonShell[] CreateCompletelyRandomTeam(PBESettings settings, bool setToMaxLevel)
        {
            var team = new PBEPokemonShell[settings.MaxPartySize];

            for (int i = 0; i < settings.MaxPartySize; i++)
            {
                team[i] = new PBEPokemonShell(RandomSpecies(), setToMaxLevel ? settings.MaxLevel : (byte)RandomInt(settings.MinLevel, settings.MaxLevel), settings);
            }
            return(team);
        }
Exemple #23
0
        public void Gem_Does_Not_Activate__Miss()
        {
            #region Setup
            PBEDataProvider.GlobalRandom.Seed = 2; // Seed ensures all miss
            PBESettings settings = PBESettings.DefaultSettings;

            var p0 = new TestPokemonCollection(2);
            p0[0] = new TestPokemon(settings, PBESpecies.Corsola, 0, 100, PBEMove.Earthquake)
            {
                Ability = PBEAbility.Hustle,
                Item    = PBEItem.GroundGem
            };
            p0[1] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 1, PBEMove.Splash);

            var p1 = new TestPokemonCollection(2);
            p1[0] = new TestPokemon(settings, PBESpecies.Happiny, 0, 1, PBEMove.Splash);
            p1[1] = new TestPokemon(settings, PBESpecies.Qwilfish, 0, 1, PBEMove.Splash);

            var battle = PBEBattle.CreateTrainerBattle(PBEBattleFormat.Double, settings, new PBETrainerInfo(p0, "Trainer 0", false), new PBETrainerInfo(p1, "Trainer 1", false));
            battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler;

            PBETrainer       t0       = battle.Trainers[0];
            PBETrainer       t1       = battle.Trainers[1];
            PBEBattlePokemon corsola  = t0.Party[0];
            PBEBattlePokemon magikarp = t0.Party[1];
            PBEBattlePokemon happiny  = t1.Party[0];
            PBEBattlePokemon qwilfish = t1.Party[1];
            corsola.AccuracyChange = (sbyte)-settings.MaxStatChange;
            magikarp.EvasionChange = settings.MaxStatChange;
            happiny.EvasionChange  = settings.MaxStatChange;
            qwilfish.EvasionChange = settings.MaxStatChange;

            battle.Begin();
            #endregion

            #region Use and check
            Assert.True(t0.SelectActionsIfValid(out _,
                                                new PBETurnAction(corsola, PBEMove.Earthquake, PBETurnTarget.AllyRight | PBETurnTarget.FoeLeft | PBETurnTarget.FoeRight),
                                                new PBETurnAction(magikarp, PBEMove.Splash, PBETurnTarget.AllyRight)));
            Assert.True(t1.SelectActionsIfValid(out _,
                                                new PBETurnAction(happiny, PBEMove.Splash, PBETurnTarget.AllyLeft),
                                                new PBETurnAction(qwilfish, PBEMove.Splash, PBETurnTarget.AllyRight)));

            battle.RunTurn();

            Assert.True(battle.VerifyMoveResultHappened(corsola, magikarp, PBEResult.Missed) && magikarp.HPPercentage == 1 && // Miss everyone
                        battle.VerifyMoveResultHappened(corsola, happiny, PBEResult.Missed) && happiny.HPPercentage == 1 &&
                        battle.VerifyMoveResultHappened(corsola, qwilfish, PBEResult.Missed) && qwilfish.HPPercentage == 1 &&
                        corsola.Item == PBEItem.GroundGem); // Gem not consumed
            #endregion

            #region Cleanup
            battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler;
            #endregion
        }
        [InlineData(PBESpecies.Gyarados, false)]                    // Flying dual-type-secondary
        public void Roost_Works(PBESpecies species, bool swapTypes) // Swap types around since there's no primary flying-type
        {
            #region Setup
            PBEDataProvider.GlobalRandom.Seed = 0;
            PBESettings settings = PBESettings.DefaultSettings;

            var p0 = new TestPokemonCollection(1);
            p0[0] = new TestPokemon(settings, PBESpecies.Lucario, 0, 50, PBEMove.Earthquake, PBEMove.VacuumWave);

            var p1 = new TestPokemonCollection(1);
            p1[0] = new TestPokemon(settings, species, 0, 100, PBEMove.Roost, PBEMove.Splash);

            var battle = new PBEBattle(PBEBattleFormat.Single, settings, new PBETrainerInfo(p0, "Trainer 0"), new PBETrainerInfo(p1, "Trainer 1"));
            battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler;

            PBETrainer       t0      = battle.Trainers[0];
            PBETrainer       t1      = battle.Trainers[1];
            PBEBattlePokemon lucario = t0.Party[0];
            PBEBattlePokemon rooster = t1.Party[0];
            PBEType          type1   = rooster.Type1;
            PBEType          type2   = rooster.Type2;
            if (swapTypes)
            {
                rooster.Type1      = type2;
                rooster.Type2      = type1;
                rooster.KnownType1 = type2;
                rooster.KnownType2 = type1;
            }

            battle.Begin();
            #endregion

            #region Use VacuumWave to lower HP
            Assert.Null(t0.SelectActionsIfValid(new PBETurnAction(lucario, PBEMove.VacuumWave, PBETurnTarget.FoeCenter)));
            Assert.Null(t1.SelectActionsIfValid(new PBETurnAction(rooster, PBEMove.Splash, PBETurnTarget.AllyCenter)));

            battle.RunTurn();
            #endregion

            #region Use Roost and check
            Assert.Null(t0.SelectActionsIfValid(new PBETurnAction(lucario, PBEMove.Earthquake, PBETurnTarget.FoeCenter)));
            Assert.Null(t1.SelectActionsIfValid(new PBETurnAction(rooster, PBEMove.Roost, PBETurnTarget.AllyCenter)));

            battle.RunTurn();

            Assert.True(!battle.VerifyMoveResultHappened(lucario, rooster, PBEResult.Ineffective_Type) && // Earthquake hit
                        !rooster.Status2.HasFlag(PBEStatus2.Roost) && // Roost ended properly
                        rooster.Type1 == type1 && rooster.Type2 == type2 && // Types restored properly
                        rooster.KnownType1 == type1 && rooster.KnownType2 == type2);
            #endregion

            #region Cleanup
            battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler;
            #endregion
        }
        public static void Test()
        {
            Console.WriteLine("----- Pokémon Battle Engine Test -----");

            var settings = new PBESettings {
                NumMoves = 12
            };

            PBEPokemonShell[] team0Party, team1Party;

            // Completely Randomized Pokémon
            team0Party = PBEUtils.CreateCompletelyRandomTeam(settings, true);
            team1Party = PBEUtils.CreateCompletelyRandomTeam(settings, true);

            // Predefined Pokémon

            /*team0Party = new PBEPokemonShell[]
             * {
             *  PBECompetitivePokemonShells.Zoroark_VGC,
             *  PBECompetitivePokemonShells.Volcarona_VGC,
             *  PBECompetitivePokemonShells.Vaporeon_VGC,
             *  PBECompetitivePokemonShells.Thundurus_VGC,
             *  PBECompetitivePokemonShells.Vanilluxe_VGC,
             *  PBECompetitivePokemonShells.Chandelure_VGC
             * };
             * team1Party = new PBEPokemonShell[]
             * {
             *  PBECompetitivePokemonShells.Arceus_Uber,
             *  PBECompetitivePokemonShells.Darkrai_Uber,
             *  PBECompetitivePokemonShells.Kyurem_White_Uber,
             *  PBECompetitivePokemonShells.Latias_VGC,
             *  PBECompetitivePokemonShells.Metagross_VGC,
             *  PBECompetitivePokemonShells.Victini_Uber
             * };*/

            var battle = new PBEBattle(PBEBattleFormat.Double, settings, team0Party, team1Party);

            battle.Teams[0].TrainerName = "Team 1";
            battle.Teams[1].TrainerName = "Team 2";
            battle.OnNewEvent          += PBEBattle.ConsoleBattleEventHandler;
            battle.OnStateChanged      += Battle_OnStateChanged;
            try
            {
                writer = new StreamWriter(new FileStream(LogFile, FileMode.Create, FileAccess.Write));
            }
            catch (Exception e)
            {
                Console.WriteLine($"Cannot open \"{LogFile}\" for writing.");
                Console.WriteLine(e.Message);
                return;
            }
            oldWriter = Console.Out;
            Console.SetOut(writer);
            battle.Begin();
        }
 public TestPokemon(PBESettings settings, PBESpecies species, PBEForm form, byte level, params PBEMove[] moves)
 {
     Species          = species;
     Form             = form;
     Level            = level;
     Nickname         = species.ToString();
     Gender           = PBERandom.RandomGender(PBEPokemonData.GetData(species, form).GenderRatio);
     EffortValues     = new PBEStatCollection(0, 0, 0, 0, 0, 0);
     IndividualValues = new PBEStatCollection(0, 0, 0, 0, 0, 0);
     Moveset          = new TestMoveset(settings, moves);
 }
        public void Whirlwind_Succeeds_WildDoubleBattle()
        {
            #region Setup
            PBEDataProvider.GlobalRandom.Seed = 0;
            PBESettings settings = PBESettings.DefaultSettings;

            var p0 = new TestPokemonCollection(3);
            p0[0] = new TestPokemon(settings, PBESpecies.Diglett, 0, 1, PBEMove.Splash);
            p0[1] = new TestPokemon(settings, PBESpecies.Geodude, 0, 1, PBEMove.Splash);
            p0[2] = new TestPokemon(settings, PBESpecies.Trubbish, 0, 1, PBEMove.Splash);

            var p1 = new TestPokemonCollection(2);
            p1[0] = new TestPokemon(settings, PBESpecies.Starly, 0, 100, PBEMove.Whirlwind)
            {
                CaughtBall = PBEItem.None
            };
            p1[1] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 100, PBEMove.Splash)
            {
                CaughtBall = PBEItem.None
            };

            var battle = new PBEBattle(PBEBattleFormat.Double, settings, new PBETrainerInfo(p0, "Trainer 0"), new PBEWildInfo(p1));
            battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler;

            PBETrainer       t0       = battle.Trainers[0];
            PBETrainer       t1       = battle.Trainers[1];
            PBEBattlePokemon diglett  = t0.Party[0];
            PBEBattlePokemon geodude  = t0.Party[1];
            PBEBattlePokemon trubbish = t0.Party[2];
            PBEBattlePokemon starly   = t1.Party[0];
            PBEBattlePokemon magikarp = t1.Party[1];

            battle.Begin();
            #endregion

            #region Use Whirlwind and check
            Assert.Null(t0.SelectActionsIfValid(
                            new PBETurnAction(diglett, PBEMove.Splash, PBETurnTarget.AllyLeft),
                            new PBETurnAction(geodude, PBEMove.Splash, PBETurnTarget.AllyRight)));
            Assert.Null(t1.SelectActionsIfValid(
                            new PBETurnAction(starly, PBEMove.Whirlwind, PBETurnTarget.FoeLeft),
                            new PBETurnAction(magikarp, PBEMove.Splash, PBETurnTarget.AllyRight)));

            battle.RunTurn();

            Assert.True(!battle.VerifyMoveResultHappened(starly, diglett, PBEResult.InvalidConditions) && // No fail
                        diglett.FieldPosition == PBEFieldPosition.None && trubbish.FieldPosition == PBEFieldPosition.Left && // Properly swapped
                        !battle.BattleResult.HasValue); // Did not flee
            #endregion

            #region Cleanup
            battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler;
            #endregion
        }
Exemple #28
0
 static PkmnConstants()
 {
     PBESettings = new PBESettings
     {
         MaxPartySize = PartyCapacity,
         NumMoves     = NumMoves,
         MinLevel     = MinLevel,
         MaxLevel     = MaxLevel,
     };
     PBESettings.MakeReadOnly();
 }
Exemple #29
0
 public static void ValidateNickname(string value, PBESettings settings)
 {
     if (string.IsNullOrWhiteSpace(value))
     {
         throw new ArgumentOutOfRangeException(nameof(value));
     }
     if (value.Length > settings.MaxPokemonNameLength)
     {
         throw new ArgumentOutOfRangeException(nameof(value), $"{nameof(value)} cannot have more than {nameof(settings.MaxPokemonNameLength)} ({settings.MaxPokemonNameLength}) characters.");
     }
 }
        //[InlineData(PBEMove.SkyDrop, PBEStatus2.Airborne)]
        public void HelpingHand_HitsSemiInvulnerable(PBEMove move, PBEStatus2 status2)
        {
            #region Setup
            PBEDataProvider.GlobalRandom.Seed = 0;
            PBESettings settings = PBESettings.DefaultSettings;

            var p0 = new TestPokemonCollection(2);
            p0[0] = new TestPokemon(settings, PBESpecies.Minun, 0, 100, PBEMove.HelpingHand, PBEMove.Splash);
            p0[1] = new TestPokemon(settings, PBESpecies.Giratina, 0, 1, move);

            var p1 = new TestPokemonCollection(1);
            p1[0] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 100, PBEMove.Splash);

            var battle = PBEBattle.CreateTrainerBattle(PBEBattleFormat.Double, settings, new PBETrainerInfo(p0, "Trainer 0", false), new PBETrainerInfo(p1, "Trainer 1", false));
            battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler;

            PBETrainer       t0       = battle.Trainers[0];
            PBETrainer       t1       = battle.Trainers[1];
            PBEBattlePokemon minun    = t0.Party[0];
            PBEBattlePokemon giratina = t0.Party[1];
            PBEBattlePokemon magikarp = t1.Party[0];

            battle.Begin();
            #endregion

            #region Use Shadow Force
            Assert.True(t0.SelectActionsIfValid(out _,
                                                new PBETurnAction(minun, PBEMove.Splash, PBETurnTarget.AllyLeft),
                                                new PBETurnAction(giratina, move, PBETurnTarget.FoeLeft)));
            Assert.True(t1.SelectActionsIfValid(out _,
                                                new PBETurnAction(magikarp, PBEMove.Splash, PBETurnTarget.AllyLeft)));

            battle.RunTurn();

            Assert.True(giratina.Status2.HasFlag(status2));
            #endregion

            #region Use Helping Hand and check
            Assert.True(t0.SelectActionsIfValid(out _,
                                                new PBETurnAction(minun, PBEMove.HelpingHand, PBETurnTarget.AllyRight),
                                                new PBETurnAction(giratina, move, PBETurnTarget.FoeLeft)));
            Assert.True(t1.SelectActionsIfValid(out _,
                                                new PBETurnAction(magikarp, PBEMove.Splash, PBETurnTarget.AllyLeft)));

            battle.RunTurn();

            Assert.True(battle.VerifyStatus2Happened(giratina, minun, PBEStatus2.HelpingHand, PBEStatusAction.Added));
            #endregion

            #region Cleanup
            battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler;
            #endregion
        }