// Parsing Utility public ShowdownSet(string input = null) { if (input == null) { return; } string[] lines = input.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None); for (int i = 0; i < lines.Length; i++) { lines[i] = lines[i].Replace("'", "’").Trim(); // Sanitize apostrophes } lines = lines.Where(line => line.Length > 2).ToArray(); if (lines.Length < 3) { return; } // Seek for start of set int start = Array.FindIndex(lines, line => line.Contains(" @ ")); if (start != -1) // Has Item -- skip to start. { lines = lines.Skip(start).Take(lines.Length - start).ToArray(); } else // Has no Item -- try parsing the first line anyway. { ParseFirstLine(lines[0]); if (Species < -1) { return; // Abort if no text is found } lines = lines.Skip(1).Take(lines.Length - 1).ToArray(); } int movectr = 0; // Detect relevant data foreach (string line in lines) { if (line.StartsWith("-")) { string moveString = ParseLineMove(line); int move = Array.IndexOf(moves, moveString); if (move < 0) { InvalidLines.Add($"Unknown Move: {moveString}"); } else { Moves[movectr++] = move; } if (movectr == 4) { break; // End of moves } continue; } string[] brokenline = line.Split(new[] { ": " }, StringSplitOptions.None); if (brokenline.Length == 1) { brokenline = new[] { brokenline[0], "" } } ; switch (brokenline[0]) { case "Trait": case "Ability": { Ability = Array.IndexOf(abilities, brokenline[1].Trim()); break; } case "Level": { Level = Util.ToInt32(brokenline[1].Trim()); break; } case "Shiny": { Shiny = brokenline[1].Trim() == "Yes"; break; } case "Happiness": { Friendship = Util.ToInt32(brokenline[1].Trim()); break; } case "Nature": { Nature = Array.IndexOf(natures, brokenline[1].Trim()); break; } case "EV": case "EVs": { ParseLineEVs(brokenline[1].Trim()); break; } case "IV": case "IVs": { ParseLineIVs(brokenline[1].Trim()); break; } case "Type": { brokenline = new[] { line }; goto default; } // Type: Null edge case default: { // Either Nature or Gender ItemSpecies if (brokenline[0].Contains(" @ ")) { string[] pieces = line.Split(new[] { " @ " }, StringSplitOptions.None); string itemstr = pieces.Last().Trim(); int item = Array.IndexOf(items, itemstr); if (item < 0) { InvalidLines.Add($"Unknown Item: {itemstr}"); } else { HeldItem = item; } ParseFirstLine(pieces[0]); } else if (brokenline[0].Contains("Nature")) { string naturestr = line.Split(' ')[0].Trim(); int nature = Array.IndexOf(natures, naturestr); if (nature < 0) { InvalidLines.Add($"Unknown Nature: {naturestr}"); } else { Nature = nature; } } else // Fallback { string speciesstr = line.Split('(')[0].Trim(); int spec = Array.IndexOf(species, speciesstr); if (spec < 1) { InvalidLines.Add(speciesstr); } else { Species = spec; } } break; } } } IVs = IVsSpeedFirst; EVs = EVsSpeedFirst; // Showdown Quirks switch (Species) { case 658: // Greninja if (Ability == 210) { Form = "Ash"; // Battle Bond } break; case 666: // Vivillon if (Form == "Pokeball") { Form = "Poké Ball"; } break; case 718: // Zygarde if (string.IsNullOrEmpty(Form)) { Form = "50%"; } else if (Form == "Complete") { Form = "100%"; } if (Ability == 211) { Form += "-C"; // Power Construct } break; case 774: // Minior if (!string.IsNullOrWhiteSpace(Form) && Form != "Meteor") { Form = "C-" + Form; } break; } }