internal PBEBattlePokemonInfo(PBEBattlePokemon pkmn) { Id = pkmn.Id; Species = pkmn.OriginalSpecies; Form = pkmn.OriginalForm; Nickname = pkmn.Nickname; Level = pkmn.OriginalLevel; EXP = pkmn.OriginalEXP; Friendship = pkmn.Friendship; Shiny = pkmn.Shiny; Pokerus = pkmn.Pokerus; Ability = pkmn.OriginalAbility; Nature = pkmn.Nature; Gender = pkmn.Gender; Item = pkmn.OriginalItem; CaughtBall = pkmn.OriginalCaughtBall; Status1 = pkmn.OriginalStatus1; EffortValues = pkmn.OriginalEffortValues !; IndividualValues = pkmn.IndividualValues !; Moveset = pkmn.OriginalMoveset !; }
public void Feint_And_QuickGuard(bool ally) { #region Setup PBERandom.SetSeed(0); PBESettings settings = PBESettings.DefaultSettings; var p0 = new TestPokemonCollection(2); p0[0] = new TestPokemon(settings, PBESpecies.Lucario, 0, 100, PBEMove.Feint); p0[1] = new TestPokemon(settings, PBESpecies.Mienshao, 0, 100, PBEMove.QuickGuard); var p1 = new TestPokemonCollection(1); p1[0] = new TestPokemon(settings, PBESpecies.MrMime, 0, 100, PBEMove.QuickGuard); var battle = new PBEBattle(PBEBattleFormat.Double, 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 lucario = t0.Party[0]; PBEBattlePokemon mienshao = t0.Party[1]; PBEBattlePokemon mrmime = t1.Party[0]; #endregion #region Use move and check Assert.True(PBEBattle.SelectActionsIfValid(t0, new PBETurnAction(lucario, PBEMove.Feint, ally ? PBETurnTarget.AllyRight : PBETurnTarget.FoeLeft), new PBETurnAction(mienshao, PBEMove.QuickGuard, PBETurnTarget.AllyLeft | PBETurnTarget.AllyRight))); Assert.True(PBEBattle.SelectActionsIfValid(t1, new PBETurnAction(mrmime, PBEMove.QuickGuard, PBETurnTarget.AllyLeft | PBETurnTarget.AllyRight))); battle.RunTurn(); Assert.True(battle.VerifyTeamStatusHappened((ally ? t0 : t1).Team, PBETeamStatus.QuickGuard, PBETeamStatusAction.Damage, damageVictim: ally ? mienshao : mrmime) == ally); #endregion #region Cleanup battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler; #endregion }
public void Gem_Works(PBEMove move, PBEItem item) { #region Setup PBERandom.SetSeed(1); // Seed ensures all moves do not miss PBESettings settings = PBESettings.DefaultSettings; var p0 = new TestPokemonCollection(1); p0[0] = new TestPokemon(settings, PBESpecies.Mew, 0, 1, move) { Item = item }; 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")); battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler; battle.Begin(); PBETrainer t0 = battle.Trainers[0]; PBETrainer t1 = battle.Trainers[1]; PBEBattlePokemon mew = t0.Party[0]; PBEBattlePokemon magikarp = t1.Party[0]; #endregion #region Use and check Assert.True(PBEBattle.SelectActionsIfValid(t0, new PBETurnAction(mew, move, PBETurnTarget.FoeCenter))); Assert.True(PBEBattle.SelectActionsIfValid(t1, new PBETurnAction(magikarp, PBEMove.Splash, PBETurnTarget.AllyCenter))); battle.RunTurn(); Assert.True(!battle.VerifyMoveResultHappened(mew, magikarp, PBEResult.Missed) && // Did not miss battle.VerifyItemHappened(mew, mew, item, PBEItemAction.Consumed) && // Gem consumed mew.Item == PBEItem.None); // Properly removed #endregion #region Cleanup battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler; #endregion }
public void Intimidate_Works() { #region Setup PBERandom.SetSeed(0); PBESettings settings = PBESettings.DefaultSettings; var p0 = new TestPokemonCollection(3); p0[0] = new TestPokemon(settings, PBESpecies.Shuckle, 0, 100, PBEMove.Splash); p0[1] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 100, PBEMove.Splash); p0[2] = new TestPokemon(settings, PBESpecies.Happiny, 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 magikarp = t0.Party[1]; PBEBattlePokemon happiny = t0.Party[2]; PBEBattlePokemon luxray = t1.Party[0]; PBEBattlePokemon skitty = t1.Party[1]; #endregion #region Check Assert.True(battle.VerifyAbilityHappened(luxray, luxray, PBEAbility.Intimidate, PBEAbilityAction.Stats) && // Activated happiny.AttackChange < 0 && magikarp.AttackChange < 0 && shuckle.AttackChange == 0 && skitty.AttackChange == 0); // Hit only surrounding foes #endregion #region Cleanup battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler; #endregion }
private void PlayPkmnCry() { PBESpecies species; PBEForm form; double hpPercentage; if (_pPkmn is not null) { if (_pPkmn.IsEgg) { return; } species = _pPkmn.Species; form = _pPkmn.Form; hpPercentage = _pPkmn.HP / _pPkmn.MaxHP; } else if (_pcPkmn is not null) { if (_pcPkmn.IsEgg) { return; } species = _pcPkmn.Species; form = _pcPkmn.Form; hpPercentage = 1; } else { PartyPokemon pPkmn = _bPkmn.PartyPkmn; if (pPkmn.IsEgg) { return; } PBEBattlePokemon bPkmn = _bPkmn.Pkmn; species = pPkmn.Species; form = bPkmn.RevertForm; hpPercentage = bPkmn.HPPercentage; } SoundControl.PlayCry(species, form, hpPercentage); }
public void HPDrain_And_LiquidOoze() { #region Setup PBEDataProvider.GlobalRandom.Seed = 0; PBESettings settings = PBESettings.DefaultSettings; var p0 = new TestPokemonCollection(1); p0[0] = new TestPokemon(settings, PBESpecies.Deoxys, PBEForm.Deoxys_Attack, 100, PBEMove.DrainPunch); var p1 = new TestPokemonCollection(1); p1[0] = new TestPokemon(settings, PBESpecies.Blissey, 0, 100, PBEMove.Splash) { Ability = PBEAbility.LiquidOoze }; 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 deoxys = t0.Party[0]; PBEBattlePokemon blissey = t1.Party[0]; battle.Begin(); #endregion #region Use DrainPunch and check Assert.Null(t0.SelectActionsIfValid(new PBETurnAction(deoxys, PBEMove.DrainPunch, PBETurnTarget.FoeCenter))); Assert.Null(t1.SelectActionsIfValid(new PBETurnAction(blissey, PBEMove.Splash, PBETurnTarget.AllyCenter))); battle.RunTurn(); Assert.True(deoxys.HP == 0 && blissey.HP == 0 && // Both fainted battle.BattleResult == PBEBattleResult.Team1Win); // Blissey's team wins #endregion #region Cleanup battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler; #endregion }
public void Gem_Does_Not_Activate__Fail() { #region Setup PBEDataProvider.GlobalRandom.Seed = 0; PBESettings settings = PBESettings.DefaultSettings; var p0 = new TestPokemonCollection(1); p0[0] = new TestPokemon(settings, PBESpecies.Spiritomb, 0, 100, PBEMove.SuckerPunch) { Item = PBEItem.DarkGem }; var p1 = new TestPokemonCollection(1); p1[0] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 1, PBEMove.Splash); var battle = PBEBattle.CreateTrainerBattle(PBEBattleFormat.Single, 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 spiritomb = t0.Party[0]; PBEBattlePokemon magikarp = t1.Party[0]; battle.Begin(); #endregion #region Use and check Assert.True(t0.SelectActionsIfValid(out _, new PBETurnAction(spiritomb, PBEMove.SuckerPunch, PBETurnTarget.FoeCenter))); Assert.True(t1.SelectActionsIfValid(out _, new PBETurnAction(magikarp, PBEMove.Splash, PBETurnTarget.AllyCenter))); battle.RunTurn(); Assert.True(battle.VerifyMoveResultHappened(spiritomb, magikarp, PBEResult.InvalidConditions) && magikarp.HPPercentage == 1 && // Fail spiritomb.Item == PBEItem.DarkGem); // Gem not consumed #endregion #region Cleanup battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler; #endregion }
public void ColorChange_Does_Not_Activate() { #region Setup PBERandom.SetSeed(0); PBESettings settings = PBESettings.DefaultSettings; var p0 = new TestPokemonCollection(1); p0[0] = new TestPokemon(settings, PBESpecies.Conkeldurr, 0, 50, PBEMove.CloseCombat); var p1 = new TestPokemonCollection(1); p1[0] = new TestPokemon(settings, PBESpecies.Kecleon, 0, 100, PBEMove.Substitute) { Ability = PBEAbility.ColorChange }; 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 conkeldurr = t0.Party[0]; PBEBattlePokemon kecleon = t1.Party[0]; #endregion #region Use and check Assert.True(PBEBattle.SelectActionsIfValid(t0, new PBETurnAction(conkeldurr, PBEMove.CloseCombat, PBETurnTarget.FoeCenter))); Assert.True(PBEBattle.SelectActionsIfValid(t1, new PBETurnAction(kecleon, PBEMove.Substitute, PBETurnTarget.AllyCenter))); battle.RunTurn(); Assert.True(battle.VerifyStatus2Happened(kecleon, kecleon, PBEStatus2.Substitute, PBEStatusAction.Added) && // Substitute added !kecleon.Status2.HasFlag(PBEStatus2.Substitute) && // Substitute broke kecleon.Type1 == PBEType.Normal && kecleon.Type2 == PBEType.None); // ColorChange not activated #endregion #region Cleanup battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler; #endregion }
public void Teleport_Works() { #region Setup PBEDataProvider.GlobalRandom.Seed = 0; PBESettings settings = PBESettings.DefaultSettings; var p0 = new TestPokemonCollection(1); p0[0] = new TestPokemon(settings, PBESpecies.Abra, 0, 100, PBEMove.Teleport); var p1 = new TestPokemonCollection(1); p1[0] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 1, PBEMove.Splash) { 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 abra = t0.Party[0]; PBEBattlePokemon magikarp = t1.Party[0]; battle.Begin(); #endregion #region Use Teleport and check Assert.True(t0.SelectActionsIfValid(out _, new PBETurnAction(abra, PBEMove.Teleport, PBETurnTarget.AllyCenter))); Assert.True(t1.SelectActionsIfValid(out _, new PBETurnAction(magikarp, PBEMove.Splash, PBETurnTarget.AllyCenter))); battle.RunTurn(); Assert.True(!battle.VerifyMoveResultHappened(abra, abra, PBEResult.InvalidConditions) && // No fail battle.BattleResult == PBEBattleResult.WildEscape); // Escaped #endregion #region Cleanup battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler; #endregion }
public void Whirlwind_FailsLevel_WildSingleBattle() { #region Setup PBEDataProvider.GlobalRandom.Seed = 0; PBESettings settings = PBESettings.DefaultSettings; var p0 = new TestPokemonCollection(1); p0[0] = new TestPokemon(settings, PBESpecies.Tropius, 0, 1, PBEMove.Whirlwind); var p1 = new TestPokemonCollection(1); p1[0] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 100, PBEMove.Splash) { CaughtBall = PBEItem.None }; var battle = new PBEBattle(PBEBattleFormat.Single, settings, new PBETrainerInfo(p0, "Trainer 0"), new PBEWildInfo(p1)); battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler; PBETrainer t0 = battle.Trainers[0]; PBETrainer t1 = battle.Trainers[1]; PBEBattlePokemon tropius = t0.Party[0]; PBEBattlePokemon magikarp = t1.Party[0]; battle.Begin(); #endregion #region Use Whirlwind and check Assert.Null(t0.SelectActionsIfValid(new PBETurnAction(tropius, PBEMove.Whirlwind, PBETurnTarget.FoeCenter))); Assert.Null(t1.SelectActionsIfValid(new PBETurnAction(magikarp, PBEMove.Splash, PBETurnTarget.AllyCenter))); battle.RunTurn(); Assert.True(battle.VerifyMoveResultHappened(tropius, magikarp, PBEResult.Ineffective_Level) && // Fail !battle.BattleResult.HasValue); // Did not flee #endregion #region Cleanup battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler; #endregion }
private void LoadPkmnImage() { PBESpecies species; PBEForm form; PBEGender gender; bool shiny; uint pid; bool egg; if (_pPkmn is not null) { species = _pPkmn.Species; form = _pPkmn.Form; gender = _pPkmn.Gender; shiny = _pPkmn.Shiny; pid = _pPkmn.PID; egg = _pPkmn.IsEgg; } else if (_pcPkmn is not null) { species = _pcPkmn.Species; form = _pcPkmn.Form; gender = _pcPkmn.Gender; shiny = _pcPkmn.Shiny; pid = _pcPkmn.PID; egg = _pcPkmn.IsEgg; } else { PartyPokemon pPkmn = _bPkmn.PartyPkmn; PBEBattlePokemon bPkmn = _bPkmn.Pkmn; species = pPkmn.Species; form = bPkmn.RevertForm; gender = pPkmn.Gender; shiny = pPkmn.Shiny; pid = pPkmn.PID; egg = pPkmn.IsEgg; } _pkmnImage = PokemonImageUtils.GetPokemonImage(species, form, gender, shiny, false, false, pid, egg); }
public void Recoil_User_Wins() { #region Setup PBEDataProvider.GlobalRandom.Seed = 0; PBESettings settings = PBESettings.DefaultSettings; var p0 = new TestPokemonCollection(1); p0[0] = new TestPokemon(settings, PBESpecies.Bouffalant, 0, 100, PBEMove.HeadCharge); var p1 = new TestPokemonCollection(1); p1[0] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 1, 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 bouffalant = t0.Party[0]; PBEBattlePokemon magikarp = t1.Party[0]; bouffalant.HP = 1; bouffalant.UpdateHPPercentage(); battle.Begin(); #endregion #region Use HeadCharge and check Assert.Null(t0.SelectActionsIfValid(new PBETurnAction(bouffalant, PBEMove.HeadCharge, PBETurnTarget.FoeCenter))); Assert.Null(t1.SelectActionsIfValid(new PBETurnAction(magikarp, PBEMove.Splash, PBETurnTarget.AllyCenter))); battle.RunTurn(); Assert.True(bouffalant.HP == 0 && magikarp.HP == 0 && // Both fainted battle.BattleResult == PBEBattleResult.Team0Win); // Bouffalant's team wins #endregion #region Cleanup battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler; #endregion }
/// <summary>Creates valid actions for a battle turn for a specific team.</summary> /// <exception cref="InvalidOperationException">Thrown when <see name="Trainer"/> has no active battlers or <see name="Trainer"/>'s <see cref="PBETrainer.Battle"/>'s <see cref="PBEBattle.BattleState"/> is not <see cref="PBEBattleState.WaitingForActions"/>.</exception> /// <exception cref="ArgumentOutOfRangeException">Thrown when a Pokémon has no moves, the AI tries to use a move with invalid targets, or <see name="Trainer"/>'s <see cref="PBETrainer.Battle"/>'s <see cref="PBEBattle.BattleFormat"/> is invalid.</exception> public void CreateActions() { if (Trainer.Battle.BattleState != PBEBattleState.WaitingForActions) { throw new InvalidOperationException($"{nameof(Trainer.Battle.BattleState)} must be {PBEBattleState.WaitingForActions} to create actions."); } int count = Trainer.ActionsRequired.Count; var actions = new List <PBETurnAction>(count); var standBy = new List <PBEBattlePokemon>(); for (int i = 0; i < count; i++) { PBEBattlePokemon user = Trainer.ActionsRequired[i]; // If a Pokémon is forced to struggle, it is best that it just stays in until it faints if (user.IsForcedToStruggle()) { actions.Add(new PBETurnAction(user, PBEMove.Struggle, PBEBattleUtils.GetPossibleTargets(user, user.GetMoveTargets(PBEMove.Struggle))[0])); continue; } // If a Pokémon has a temp locked move (Dig, Dive, ShadowForce) it must be used else if (user.TempLockedMove != PBEMove.None) { actions.Add(new PBETurnAction(user, user.TempLockedMove, user.TempLockedTargets)); continue; } // The Pokémon is free to switch or fight (unless it cannot switch due to Magnet Pull etc) PBETurnAction a = DecideAction(user, actions, standBy); // Action was chosen, finish up for this Pokémon if (a.Decision == PBETurnDecision.SwitchOut) { standBy.Add(Trainer.GetPokemon(a.SwitchPokemonId)); } actions.Add(a); } if (!Trainer.SelectActionsIfValid(actions, out string?valid)) { throw new Exception("AI created bad actions. - " + valid); } }
public void SkillLink_Works__2To5(PBEAbility ability, byte numHits) { #region Setup PBEDataProvider.GlobalRandom.Seed = 1230; // Seed ensures hits would normally not be 5 PBESettings settings = PBESettings.DefaultSettings; var p0 = new TestPokemonCollection(1); p0[0] = new TestPokemon(settings, PBESpecies.Cinccino, 0, 1, PBEMove.TailSlap) { Ability = ability }; var p1 = new TestPokemonCollection(1); p1[0] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 100, PBEMove.Splash); var battle = PBEBattle.CreateTrainerBattle(PBEBattleFormat.Single, 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 cinccino = t0.Party[0]; PBEBattlePokemon magikarp = t1.Party[0]; battle.Begin(); #endregion #region Use and check Assert.True(t0.SelectActionsIfValid(out _, new PBETurnAction(cinccino, PBEMove.TailSlap, PBETurnTarget.FoeCenter))); Assert.True(t1.SelectActionsIfValid(out _, new PBETurnAction(magikarp, PBEMove.Splash, PBETurnTarget.AllyCenter))); battle.RunTurn(); Assert.True(battle.VerifySpecialMessageHappened(PBESpecialMessage.MultiHit, numHits)); // Correct number of hits #endregion #region Cleanup battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler; #endregion }
public void Immunity_Works() { #region Setup PBEDataProvider.GlobalRandom.Seed = 0; // Seed prevents Toxic from missing PBESettings settings = PBESettings.DefaultSettings; var p0 = new TestPokemonCollection(1); p0[0] = new TestPokemon(settings, PBESpecies.Seviper, 0, 100, PBEMove.Toxic); var p1 = new TestPokemonCollection(1); p1[0] = new TestPokemon(settings, PBESpecies.Zangoose, 0, 100, PBEMove.Splash) { Ability = PBEAbility.Immunity }; var battle = PBEBattle.CreateTrainerBattle(PBEBattleFormat.Single, 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 seviper = t0.Party[0]; PBEBattlePokemon zangoose = t1.Party[0]; battle.Begin(); #endregion #region Badly Poison Zangoose and check Assert.True(t0.SelectActionsIfValid(out _, new PBETurnAction(seviper, PBEMove.Toxic, PBETurnTarget.FoeCenter))); Assert.True(t1.SelectActionsIfValid(out _, new PBETurnAction(zangoose, PBEMove.Splash, PBETurnTarget.AllyCenter))); battle.RunTurn(); Assert.True(battle.VerifyMoveResultHappened(seviper, zangoose, PBEResult.Ineffective_Ability)); #endregion #region Cleanup battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler; #endregion }
internal static bool IsFleeValid(PBETrainer trainer, [NotNullWhen(false)] out string?invalidReason) { if (trainer.Battle.BattleType != PBEBattleType.Wild) { throw new InvalidOperationException($"{nameof(BattleType)} must be {PBEBattleType.Wild} to flee."); } switch (trainer.Battle._battleState) { case PBEBattleState.WaitingForActions: { if (trainer.ActionsRequired.Count == 0) { invalidReason = "Actions were already submitted"; return(false); } PBEBattlePokemon pkmn = trainer.ActiveBattlersOrdered.First(); if (pkmn.TempLockedMove != PBEMove.None) { invalidReason = $"Pokémon {pkmn.Id} must use {pkmn.TempLockedMove}"; return(false); } break; } case PBEBattleState.WaitingForSwitchIns: { if (trainer.SwitchInsRequired == 0) { invalidReason = "Switches were already submitted"; return(false); } break; } default: throw new InvalidOperationException($"{nameof(BattleState)} must be {PBEBattleState.WaitingForActions} or {PBEBattleState.WaitingForSwitchIns} to flee."); } invalidReason = null; return(true); }
internal PBEPkmnFormChangedPacket(PBEBattlePokemon pokemon, bool isRevertForm) { using (var ms = new MemoryStream()) using (var w = new EndianBinaryWriter(ms, encoding: EncodingType.UTF16)) { w.Write(Code); w.Write((PokemonTrainer = pokemon.Trainer).Id); w.Write(Pokemon = pokemon.FieldPosition); w.Write(NewAttack = pokemon.Attack); w.Write(NewDefense = pokemon.Defense); w.Write(NewSpAttack = pokemon.SpAttack); w.Write(NewSpDefense = pokemon.SpDefense); w.Write(NewSpeed = pokemon.Speed); w.Write(NewAbility = pokemon.Ability); w.Write(NewKnownAbility = pokemon.KnownAbility); w.Write(NewForm = pokemon.Form); w.Write(NewType1 = pokemon.Type1); w.Write(NewType2 = pokemon.Type2); w.Write(NewWeight = pokemon.Weight); w.Write(IsRevertForm = isRevertForm); Data = new ReadOnlyCollection <byte>(ms.ToArray()); } }
public void Explosion_User_Loses_Single() { #region Setup PBEDataProvider.GlobalRandom.Seed = 0; PBESettings settings = PBESettings.DefaultSettings; var p0 = new TestPokemonCollection(1); p0[0] = new TestPokemon(settings, PBESpecies.Golem, 0, 100, PBEMove.Explosion); var p1 = new TestPokemonCollection(1); p1[0] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 1, 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 golem = t0.Party[0]; PBEBattlePokemon magikarp = t1.Party[0]; battle.Begin(); #endregion #region Use move and check Assert.Null(t0.SelectActionsIfValid(new PBETurnAction(golem, PBEMove.Explosion, PBETurnTarget.FoeCenter))); Assert.Null(t1.SelectActionsIfValid(new PBETurnAction(magikarp, PBEMove.Splash, PBETurnTarget.AllyCenter))); battle.RunTurn(); Assert.True(golem.HP == 0 && magikarp.HP == 0 && // All faint battle.BattleResult == PBEBattleResult.Team1Win); // Golem's team loses #endregion #region Cleanup battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler; #endregion }
private static void AddStatChanges(PBEBattlePokemon pkmn, StringBuilder sb) { PBEStat[] statChanges = pkmn.GetChangedStats(); if (statChanges.Length > 0) { var statStrs = new List <string>(7); if (Array.IndexOf(statChanges, PBEStat.Attack) != -1) { statStrs.Add($"[A] x{PBEBattle.GetStatChangeModifier(pkmn.AttackChange, false):0.00}"); } if (Array.IndexOf(statChanges, PBEStat.Defense) != -1) { statStrs.Add($"[D] x{PBEBattle.GetStatChangeModifier(pkmn.DefenseChange, false):0.00}"); } if (Array.IndexOf(statChanges, PBEStat.SpAttack) != -1) { statStrs.Add($"[SA] x{PBEBattle.GetStatChangeModifier(pkmn.SpAttackChange, false):0.00}"); } if (Array.IndexOf(statChanges, PBEStat.SpDefense) != -1) { statStrs.Add($"[SD] x{PBEBattle.GetStatChangeModifier(pkmn.SpDefenseChange, false):0.00}"); } if (Array.IndexOf(statChanges, PBEStat.Speed) != -1) { statStrs.Add($"[S] x{PBEBattle.GetStatChangeModifier(pkmn.SpeedChange, false):0.00}"); } if (Array.IndexOf(statChanges, PBEStat.Accuracy) != -1) { statStrs.Add($"[AC] x{PBEBattle.GetStatChangeModifier(pkmn.AccuracyChange, true):0.00}"); } if (Array.IndexOf(statChanges, PBEStat.Evasion) != -1) { statStrs.Add($"[E] x{PBEBattle.GetStatChangeModifier(pkmn.EvasionChange, true):0.00}"); } sb.AppendLine($"**Stat changes:** {string.Join(", ", statStrs)}"); } }
public void FinalGambit_User_Loses() { #region Setup PBEDataProvider.GlobalRandom.Seed = 0; PBESettings settings = PBESettings.DefaultSettings; var p0 = new TestPokemonCollection(1); p0[0] = new TestPokemon(settings, PBESpecies.Staraptor, 0, 100, PBEMove.FinalGambit); var p1 = new TestPokemonCollection(1); p1[0] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 1, PBEMove.Splash); var battle = PBEBattle.CreateTrainerBattle(PBEBattleFormat.Single, 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 staraptor = t0.Party[0]; PBEBattlePokemon magikarp = t1.Party[0]; battle.Begin(); #endregion #region Use FinalGambit and check Assert.True(t0.SelectActionsIfValid(out _, new PBETurnAction(staraptor, PBEMove.FinalGambit, PBETurnTarget.FoeCenter))); Assert.True(t1.SelectActionsIfValid(out _, new PBETurnAction(magikarp, PBEMove.Splash, PBETurnTarget.AllyCenter))); battle.RunTurn(); Assert.True(staraptor.HP == 0 && magikarp.HP == 0 && // Both fainted battle.BattleResult == PBEBattleResult.Team1Win); // Magikarp's team wins #endregion #region Cleanup battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler; #endregion }
public void Camouflage_Fails() { #region Setup PBEDataProvider.GlobalRandom.Seed = 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 = PBEBattle.CreateTrainerBattle(PBEBattleFormat.Single, settings, new PBETrainerInfo(p0, "Trainer 0", false), new PBETrainerInfo(p1, "Trainer 1", false), battleTerrain: PBEBattleTerrain.Water); battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler; PBETrainer t0 = battle.Trainers[0]; PBETrainer t1 = battle.Trainers[1]; PBEBattlePokemon staryu = t0.Party[0]; PBEBattlePokemon magikarp = t1.Party[0]; battle.Begin(); #endregion #region Use Camouflage and check Assert.True(t0.SelectActionsIfValid(out _, new PBETurnAction(staryu, PBEMove.Camouflage, PBETurnTarget.AllyCenter))); Assert.True(t1.SelectActionsIfValid(out _, 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 }
public void Camouflage_Works(PBEBattleTerrain battleTerrain, PBEType expectedType, PBESpecies species) { #region Setup PBEDataProvider.GlobalRandom.Seed = 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 = PBEBattle.CreateTrainerBattle(PBEBattleFormat.Single, settings, new PBETrainerInfo(p0, "Trainer 0", false), new PBETrainerInfo(p1, "Trainer 1", false), battleTerrain: battleTerrain); battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler; PBETrainer t0 = battle.Trainers[0]; PBETrainer t1 = battle.Trainers[1]; PBEBattlePokemon camouflager = t0.Party[0]; PBEBattlePokemon magikarp = t1.Party[0]; battle.Begin(); #endregion #region Use Camouflage and check Assert.True(t0.SelectActionsIfValid(out _, new PBETurnAction(camouflager, PBEMove.Camouflage, PBETurnTarget.AllyCenter))); Assert.True(t1.SelectActionsIfValid(out _, 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 HelpingHand_Fails_If_Self() { #region Setup PBEDataProvider.GlobalRandom.Seed = 0; PBESettings settings = PBESettings.DefaultSettings; var p0 = new TestPokemonCollection(1); p0[0] = new TestPokemon(settings, PBESpecies.Minun, 0, 100, PBEMove.HelpingHand); var p1 = new TestPokemonCollection(1); p1[0] = new TestPokemon(settings, PBESpecies.Magikarp, 0, 100, PBEMove.Splash); var battle = PBEBattle.CreateTrainerBattle(PBEBattleFormat.Single, 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 magikarp = t1.Party[0]; battle.Begin(); #endregion #region Use Helping Hand and check Assert.True(t0.SelectActionsIfValid(out _, new PBETurnAction(minun, PBEMove.HelpingHand, PBETurnTarget.AllyCenter))); Assert.True(t1.SelectActionsIfValid(out _, new PBETurnAction(magikarp, PBEMove.Splash, PBETurnTarget.AllyCenter))); battle.RunTurn(); Assert.True(battle.VerifyMoveResultHappened(minun, minun, PBEResult.NoTarget) && // Fail !minun.Status2.HasFlag(PBEStatus2.HelpingHand)); // No status #endregion #region Cleanup battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler; #endregion }
public void TeamProtection_Works(PBEMove move, PBEMove move2, PBETeamStatus teamStatus) { #region Setup PBEDataProvider.GlobalRandom.Seed = 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 = PBEBattle.CreateTrainerBattle(PBEBattleFormat.Single, 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 mienshao = t0.Party[0]; PBEBattlePokemon lucario = t1.Party[0]; battle.Begin(); #endregion #region Use move and check Assert.True(t0.SelectActionsIfValid(out _, new PBETurnAction(mienshao, move, PBETurnTarget.AllyCenter))); Assert.True(t1.SelectActionsIfValid(out _, new PBETurnAction(lucario, move2, PBETurnTarget.FoeCenter))); battle.RunTurn(); Assert.True(battle.VerifyTeamStatusDamageHappened(t0.Team, teamStatus, mienshao) && !t0.Team.TeamStatus.HasFlag(teamStatus)); #endregion #region Cleanup battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler; #endregion }
public void Cannot_Switch_In_Egg() { #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, 1, PBEMove.Splash) { PBEIgnore = true }; var p1 = new TestPokemonCollection(1); p1[0] = new TestPokemon(settings, PBESpecies.Darkrai, 0, 100, PBEMove.Protect); var battle = PBEBattle.CreateTrainerBattle(PBEBattleFormat.Single, 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 koffing = t0.Party[0]; PBEBattlePokemon magikarp = t0.Party[1]; PBEBattlePokemon darkrai = t1.Party[0]; battle.Begin(); #endregion #region Check Assert.False(t0.SelectActionsIfValid(out _, new PBETurnAction(koffing, magikarp))); #endregion #region Cleanup battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler; #endregion }
// TODO: TripleKick miss logic private void Hit_GetVictims(PBEBattlePokemon user, PBEBattlePokemon[] targets, IPBEMoveData mData, PBEType moveType, out List <PBEAttackVictim> victims, Func <PBEBattlePokemon, PBEResult>?failFunc = null) { victims = new List <PBEAttackVictim>(targets.Length); foreach (PBEBattlePokemon target in targets) { if (!AttackTypeCheck(user, target, moveType, out PBEResult result, out float typeEffectiveness)) { continue; } // Verified: These fails are after type effectiveness (So SuckerPunch will not affect Ghost types due to Normalize before it fails due to invalid conditions) if (failFunc is not null && failFunc.Invoke(target) != PBEResult.Success) { continue; } victims.Add(new PBEAttackVictim(target, result, typeEffectiveness)); } if (victims.Count == 0) { return; } victims.RemoveAll(t => MissCheck(user, t.Pkmn, mData)); return; }
public void UserProtection_Works() { #region Setup PBEDataProvider.GlobalRandom.Seed = 0; PBESettings settings = PBESettings.DefaultSettings; var p0 = new TestPokemonCollection(1); p0[0] = new TestPokemon(settings, PBESpecies.Lucario, 0, 100, PBEMove.Tackle); var p1 = new TestPokemonCollection(1); p1[0] = new TestPokemon(settings, PBESpecies.Mienshao, 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 lucario = t0.Party[0]; PBEBattlePokemon mienshao = t1.Party[0]; battle.Begin(); #endregion #region Use move and check Assert.Null(t0.SelectActionsIfValid(new PBETurnAction(lucario, PBEMove.Tackle, PBETurnTarget.FoeCenter))); Assert.Null(t1.SelectActionsIfValid(new PBETurnAction(mienshao, PBEMove.Protect, PBETurnTarget.AllyCenter))); battle.RunTurn(); Assert.True(battle.VerifyStatus2Happened(mienshao, lucario, PBEStatus2.Protected, PBEStatusAction.Damage) && !mienshao.Status2.HasFlag(PBEStatus2.Protected)); #endregion #region Cleanup battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler; #endregion }
internal PBETransformPacket(PBEBattlePokemon user, PBEBattlePokemon target) { using (var ms = new MemoryStream()) using (var w = new EndianBinaryWriter(ms, encoding: EncodingType.UTF16)) { w.Write(Code); w.Write((UserTrainer = user.Trainer).Id); w.Write(User = user.FieldPosition); w.Write((TargetTrainer = target.Trainer).Id); w.Write(Target = target.FieldPosition); w.Write(TargetAttack = target.Attack); w.Write(TargetDefense = target.Defense); w.Write(TargetSpAttack = target.SpAttack); w.Write(TargetSpDefense = target.SpDefense); w.Write(TargetSpeed = target.Speed); w.Write(TargetAttackChange = target.AttackChange); w.Write(TargetDefenseChange = target.DefenseChange); w.Write(TargetSpAttackChange = target.SpAttackChange); w.Write(TargetSpDefenseChange = target.SpDefenseChange); w.Write(TargetSpeedChange = target.SpeedChange); w.Write(TargetAccuracyChange = target.AccuracyChange); w.Write(TargetEvasionChange = target.EvasionChange); w.Write(TargetAbility = target.Ability); w.Write(TargetSpecies = target.Species); w.Write(TargetForm = target.Form); w.Write(TargetType1 = target.Type1); w.Write(TargetType2 = target.Type2); w.Write(TargetWeight = target.Weight); TargetMoves = target.Moves.ForTransformPacket(); for (int i = 0; i < TargetMoves.Count; i++) { w.Write(TargetMoves[i]); } Data = new ReadOnlyCollection <byte>(ms.ToArray()); } }
public void Intimidate_Does_Not_Announce_If_No_Foes() { #region Setup PBEDataProvider.GlobalRandom.Seed = 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; 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]; battle.Begin(); #endregion #region Check Assert.True(!battle.VerifyAbilityHappened(luxray, luxray, PBEAbility.Intimidate, PBEAbilityAction.Stats)); // Did not activate #endregion #region Cleanup battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler; #endregion }
public void Illusion_Copies_Shaymin_Reversion() { #region Setup PBERandom.SetSeed(0); // Seed ensures SecretPower freezes PBESettings settings = PBESettings.DefaultSettings; var p0 = new TestPokemonCollection(1); p0[0] = new TestPokemon(settings, PBESpecies.Happiny, 0, 100, PBEMove.SecretPower, PBEMove.Splash) { Ability = PBEAbility.SereneGrace }; var p1 = new TestPokemonCollection(3); p1[0] = new TestPokemon(settings, PBESpecies.Shaymin, PBEForm.Shaymin_Sky, 100, PBEMove.Splash); p1[1] = new TestPokemon(settings, PBESpecies.Zoroark, 0, 100, PBEMove.Splash) { Ability = PBEAbility.Illusion }; p1[2] = 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.Snow); battle.OnNewEvent += PBEBattle.ConsoleBattleEventHandler; battle.Begin(); PBETrainer t0 = battle.Trainers[0]; PBETrainer t1 = battle.Trainers[1]; PBEBattlePokemon happiny = t0.Party[0]; PBEBattlePokemon shaymin = t1.Party[0]; PBEBattlePokemon zoroark = t1.Party[1]; PBEBattlePokemon magikarp = t1.Party[2]; #endregion #region Freeze Shaymin Assert.True(PBEBattle.SelectActionsIfValid(t0, new PBETurnAction(happiny, PBEMove.SecretPower, PBETurnTarget.FoeCenter))); Assert.True(PBEBattle.SelectActionsIfValid(t1, new PBETurnAction(shaymin, PBEMove.Splash, PBETurnTarget.AllyCenter))); battle.RunTurn(); Assert.True(shaymin.Status1 == PBEStatus1.Frozen && shaymin.Form == PBEForm.Shaymin); #endregion #region Swap Shaymin for Magikarp Assert.True(PBEBattle.SelectActionsIfValid(t0, new PBETurnAction(happiny, PBEMove.Splash, PBETurnTarget.AllyCenter))); Assert.True(PBEBattle.SelectActionsIfValid(t1, new PBETurnAction(shaymin, magikarp))); battle.RunTurn(); Assert.True(t1.Party[2] == shaymin); #endregion #region Swap Magikarp for Zoroark and check Assert.True(PBEBattle.SelectActionsIfValid(t0, new PBETurnAction(happiny, PBEMove.Splash, PBETurnTarget.AllyCenter))); Assert.True(PBEBattle.SelectActionsIfValid(t1, new PBETurnAction(magikarp, zoroark))); battle.RunTurn(); Assert.True(zoroark.DisguisedAsPokemon == shaymin && zoroark.KnownForm == PBEForm.Shaymin); #endregion #region Cleanup battle.OnNewEvent -= PBEBattle.ConsoleBattleEventHandler; #endregion }