using System; using System.Linq; using FluentAssertions; using PKHeX.Core; using Xunit; namespace PKHeX.Tests.Simulator { public class ShowdownSetTests { static ShowdownSetTests() { if (!EncounterEvent.Initialized) EncounterEvent.RefreshMGDB(); } [Fact] public void SimulatorGetParse() { foreach (var setstr in Sets) { var set = new ShowdownSet(setstr).Text; var lines = set.Split('\n').Select(z => z.Trim()); Assert.True(lines.All(z => setstr.Contains(z)), setstr); } } [Fact] public void SimulatorGetEncounters() { var set = new ShowdownSet(SetGlaceonUSUMTutor); var pk7 = new PK7 {Species = set.Species, Form = set.Form, Moves = set.Moves}; var encounters = EncounterMovesetGenerator.GenerateEncounters(pk7, set.Moves, GameVersion.MN); Assert.True(!encounters.Any()); pk7.HT_Name = "PKHeX"; encounters = EncounterMovesetGenerator.GenerateEncounters(pk7, set.Moves, GameVersion.MN); var first = encounters.FirstOrDefault(); Assert.NotNull(first); var egg = (EncounterEgg)first!; var info = new SimpleTrainerInfo(GameVersion.SN); var pk = egg.ConvertToPKM(info); Assert.True(pk.Species != set.Species); var la = new LegalityAnalysis(pk); Assert.True(la.Valid); var test = EncounterMovesetGenerator.GenerateEncounters(pk7, info).ToList(); foreach (var t in test) { var convert = t.ConvertToPKM(info); var la2 = new LegalityAnalysis(convert); Assert.True(la2.Valid); } } [Fact] public void SimulatorGetWC3() { var set = new ShowdownSet(SetROCKSMetang); var pk3 = new PK3 { Species = set.Species, Form = set.Form, Moves = set.Moves }; var encs = EncounterMovesetGenerator.GenerateEncounters(pk3, set.Moves, GameVersion.R); Assert.True(encs.Any()); encs = EncounterMovesetGenerator.GenerateEncounters(pk3, set.Moves, GameVersion.R); var first = encs.FirstOrDefault(); Assert.NotNull(first); var wc3 = (WC3)first!; var info = new SimpleTrainerInfo(GameVersion.R); var pk = wc3.ConvertToPKM(info); var la = new LegalityAnalysis(pk); Assert.True(la.Valid); } [Fact] public void SimulatorGetCelebi() { var set = new ShowdownSet(SetCelebi); var pk7 = new PK7 { Species = set.Species, Form = set.Form, Moves = set.Moves }; var encs = EncounterMovesetGenerator.GenerateEncounters(pk7, set.Moves, GameVersion.X); Assert.True(encs.Any()); encs = EncounterMovesetGenerator.GenerateEncounters(pk7, set.Moves, GameVersion.X); var first = encs.FirstOrDefault(); Assert.NotNull(first); var enc = first!; var info = new SimpleTrainerInfo(GameVersion.SN); var pk = enc.ConvertToPKM(info); var la = new LegalityAnalysis(pk); Assert.True(la.Valid); } [Fact] public void SimulatorGetSplitBreed() { var set = new ShowdownSet(SetMunchSnorLax); var pk7 = new PK7 { Species = set.Species, Form = set.Form, Moves = set.Moves, HT_Name = "PKHeX" }; // !! specify the HT name, we need tutors for this one var encs = EncounterMovesetGenerator.GenerateEncounters(pk7, set.Moves, GameVersion.SN).ToList(); Assert.True(encs.Count > 0); Assert.True(encs.All(z => z.Species > 150)); var info = new SimpleTrainerInfo(GameVersion.SN); var enc = encs[0]; var pk = enc.ConvertToPKM(info); var la = new LegalityAnalysis(pk); Assert.True(la.Valid); } [Fact] public void SimulatorGetVCEgg1() { var set = new ShowdownSet(SetSlowpoke12); var pk7 = new PK7 { Species = set.Species, Form = set.Form, Moves = set.Moves, HT_Name = "PKHeX" }; var encs = EncounterMovesetGenerator.GenerateEncounters(pk7, set.Moves, GameVersion.GD).ToList(); Assert.True(encs.Count > 0); var info = new SimpleTrainerInfo(GameVersion.SN); var enc = encs[0]; var pk = enc.ConvertToPKM(info); var la = new LegalityAnalysis(pk); Assert.True(la.Valid); } [Fact] public void SimulatorGetSmeargle() { var set = new ShowdownSet(SetSmeargle); var pk7 = new PK7 { Species = set.Species, Form = set.Form, Moves = set.Moves }; var encs = EncounterMovesetGenerator.GenerateEncounters(pk7, set.Moves, GameVersion.MN); Assert.True(encs.Any()); encs = EncounterMovesetGenerator.GenerateEncounters(pk7, set.Moves, GameVersion.MN); var first = encs.FirstOrDefault(); Assert.NotNull(first); var enc = first!; var info = new SimpleTrainerInfo(GameVersion.SN); var pk = enc.ConvertToPKM(info); var la = new LegalityAnalysis(pk); Assert.True(la.Valid); } [Fact] public void SimulatorParseMultiple() { var text = string.Join("\r\n\r\n", Sets); var lines = text.Split(new[] {"\r\n", "\n"}, StringSplitOptions.None); var sets = ShowdownParsing.GetShowdownSets(lines); Assert.True(sets.Count() == Sets.Length); sets = ShowdownParsing.GetShowdownSets(Enumerable.Empty()); Assert.True(!sets.Any()); sets = ShowdownParsing.GetShowdownSets(new [] {"", " ", " "}); Assert.True(!sets.Any()); } [Theory] [InlineData(SetDuplicateMoves, 3)] public void SimulatorParseDuplicate(string text, int moveCount) { var set = new ShowdownSet(text); var actual = set.Moves.Count(z => z != 0); actual.Should().Be(moveCount); } [Theory] [InlineData(LowLevelElectrode)] public void SimulatorParseEncounter(string text) { var set = new ShowdownSet(text); var pk7 = new PK7 { Species = set.Species, Form = set.Form, Moves = set.Moves, CurrentLevel = set.Level }; var encs = EncounterMovesetGenerator.GenerateEncounters(pk7, set.Moves); var tr3 = encs.First(z => z is EncounterTrade3); var pk3 = tr3.ConvertToPKM(new SAV3FRLG()); var la = new LegalityAnalysis(pk3); la.Valid.Should().BeTrue(); } private const string LowLevelElectrode = @"BOLICHI (Electrode) IVs: 19 HP / 16 Atk / 18 Def / 25 SpA / 19 SpD / 25 Spe Ability: Static Level: 3 Hasty Nature - Charge - Tackle - Screech - Sonic Boom"; private const string SetDuplicateMoves = @"Kingler-Gmax @ Master Ball Ability: Sheer Force Shiny: Yes EVs: 252 Atk / 4 SpD / 252 Spe Jolly Nature - Crabhammer - Rock Slide - Rock Slide - X-Scissor"; private const string SetROCKSMetang = @"Metang IVs: 20 HP / 3 Atk / 26 Def / 1 SpA / 6 SpD / 8 Spe Ability: Clear Body Level: 30 Adamant Nature - Take Down - Confusion - Metal Claw - Refresh"; private const string SetGlaceonUSUMTutor = @"Glaceon (F) @ Assault Vest IVs: 0 Atk EVs: 252 HP / 252 SpA / 4 SpD Ability: Ice Body Level: 100 Shiny: Yes Modest Nature - Blizzard - Water Pulse - Shadow Ball - Hyper Voice"; private const string SetSmeargle = @"Smeargle @ Focus Sash Ability: Own Tempo EVs: 248 HP / 8 Def / 252 Spe Jolly Nature - Sticky Web - Nuzzle - Taunt - Whirlwind"; private const string SetCelebi = @"Celebi @ Toxic Orb Ability: Natural Cure Jolly Nature - Recover - Heal Bell - Safeguard - Hold Back"; private const string SetNicknamedTypeNull = @"Reliance (Type: Null) @ Eviolite EVs: 252 HP / 4 Def / 252 SpD Ability: Battle Armor Careful Nature - Facade - Swords Dance - Sleep Talk - Rest"; private const string SetMunchSnorLax = @"Snorlax @ Choice Band Ability: Thick Fat Level: 50 EVs: 84 HP / 228 Atk / 180 Def / 12 SpD / 4 Spe Adamant Nature - Double-Edge - High Horsepower - Self-Destruct - Fire Punch"; private const string SetSlowpoke12 = @"Threat (Slowpoke) @ Eviolite Ability: Regenerator Shiny: Yes EVs: 248 HP / 252 Atk / 8 SpD Adamant Nature - Body Slam - Earthquake - Belly Drum - Iron Tail"; private static readonly string[] Sets = { SetGlaceonUSUMTutor, SetNicknamedTypeNull, SetMunchSnorLax, @"Greninja @ Choice Specs Ability: Battle Bond EVs: 252 SpA / 4 SpD / 252 Spe Timid Nature - Hydro Pump - Spikes - Water Shuriken - Dark Pulse", }; } }