2016-06-20 04:22:43 +00:00
|
|
|
|
using System;
|
2016-09-04 06:14:05 +00:00
|
|
|
|
using System.Collections.Generic;
|
2016-06-20 04:22:43 +00:00
|
|
|
|
using System.Linq;
|
|
|
|
|
|
2017-01-08 07:54:09 +00:00
|
|
|
|
namespace PKHeX.Core
|
2016-06-20 04:22:43 +00:00
|
|
|
|
{
|
2017-10-24 06:12:58 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Logic for exporting and importing <see cref="PKM"/> data in Pokémon Showdown's text format.
|
|
|
|
|
/// </summary>
|
2016-06-20 04:22:43 +00:00
|
|
|
|
public class ShowdownSet
|
|
|
|
|
{
|
|
|
|
|
// String to Values
|
2017-12-27 00:29:35 +00:00
|
|
|
|
private static readonly string[] genders = {"M", "F", ""};
|
2018-01-30 01:20:12 +00:00
|
|
|
|
private static readonly string[] genderForms = {"", "F", ""};
|
2018-07-14 02:13:25 +00:00
|
|
|
|
private static readonly string[] StatNames = { "HP", "Atk", "Def", "SpA", "SpD", "Spe" };
|
2018-07-14 16:55:22 +00:00
|
|
|
|
private static readonly string[] Splitters = {"\r\n", "\n"};
|
2018-07-22 02:20:11 +00:00
|
|
|
|
private static readonly string[] StatSplitters = { " / ", " " };
|
2018-07-14 16:55:22 +00:00
|
|
|
|
private static readonly string[] LineSplit = {": "};
|
2018-07-22 02:20:11 +00:00
|
|
|
|
private static readonly string[] ItemSplit = {" @ "};
|
2018-07-25 22:53:02 +00:00
|
|
|
|
private static readonly int[] DashedSpecies = {782, 783, 784, 250, 032, 029}; // Kommo-o, Ho-Oh, Nidoran-M, Nidoran-F
|
2018-07-14 02:13:25 +00:00
|
|
|
|
private static int MAX_SPECIES => PKX.Personal.MaxSpeciesID;
|
2017-06-18 01:37:19 +00:00
|
|
|
|
private const string Language = "en";
|
2018-07-14 02:13:25 +00:00
|
|
|
|
private const int DefaultLanguageID = 2;
|
|
|
|
|
private static readonly GameStrings DefaultStrings = GameInfo.GetStrings(Language);
|
|
|
|
|
|
2018-07-14 16:55:22 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// <see cref="PKM.Species"/> of the Set entity.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public int Species { get; private set; } = -1;
|
2016-06-20 04:22:43 +00:00
|
|
|
|
|
2018-07-14 16:55:22 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// <see cref="PKM.Format"/> of the Set entity it is specific to.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public int Format { get; } = PKMConverter.Format;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <see cref="PKM.Nickname"/> of the Set entity.
|
|
|
|
|
/// </summary>
|
2016-09-20 05:59:15 +00:00
|
|
|
|
public string Nickname { get; set; }
|
2018-07-14 16:55:22 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <see cref="PKM.Gender"/> name of the Set entity.
|
|
|
|
|
/// </summary>
|
2016-09-20 05:59:15 +00:00
|
|
|
|
public string Gender { get; private set; }
|
2018-07-14 16:55:22 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <see cref="PKM.HeldItem"/> of the Set entity.
|
|
|
|
|
/// </summary>
|
2017-06-18 01:37:19 +00:00
|
|
|
|
public int HeldItem { get; private set; }
|
2018-07-14 16:55:22 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <see cref="PKM.Ability"/> of the Set entity.
|
|
|
|
|
/// </summary>
|
2018-04-26 01:45:31 +00:00
|
|
|
|
public int Ability { get; private set; } = -1;
|
2018-07-14 16:55:22 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <see cref="PKM.CurrentLevel"/> of the Set entity.
|
|
|
|
|
/// </summary>
|
2016-09-20 05:59:15 +00:00
|
|
|
|
public int Level { get; private set; } = 100;
|
2018-07-14 16:55:22 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <see cref="PKM.CurrentLevel"/> of the Set entity.
|
|
|
|
|
/// </summary>
|
2016-09-20 05:59:15 +00:00
|
|
|
|
public bool Shiny { get; private set; }
|
2018-07-14 16:55:22 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <see cref="PKM.CurrentFriendship"/> of the Set entity.
|
|
|
|
|
/// </summary>
|
2016-09-20 05:59:15 +00:00
|
|
|
|
public int Friendship { get; private set; } = 255;
|
2018-07-14 16:55:22 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <see cref="PKM.Nature"/> of the Set entity.
|
|
|
|
|
/// </summary>
|
2018-05-21 02:29:19 +00:00
|
|
|
|
public int Nature { get; set; }
|
2018-07-14 16:55:22 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <see cref="PKM.AltForm"/> name of the Set entity.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Form { get; private set; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <see cref="PKM.AltForm"/> of the Set entity.
|
|
|
|
|
/// </summary>
|
2018-01-30 01:20:12 +00:00
|
|
|
|
public int FormIndex { get; private set; }
|
2018-07-14 16:55:22 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <see cref="PKM.EVs"/> of the Set entity.
|
|
|
|
|
/// </summary>
|
2016-09-20 05:59:15 +00:00
|
|
|
|
public int[] EVs { get; private set; } = {00, 00, 00, 00, 00, 00};
|
2018-07-14 16:55:22 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <see cref="PKM.IVs"/> of the Set entity.
|
|
|
|
|
/// </summary>
|
2016-09-20 05:59:15 +00:00
|
|
|
|
public int[] IVs { get; private set; } = {31, 31, 31, 31, 31, 31};
|
2018-07-14 16:55:22 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// <see cref="PKM.Moves"/> of the Set entity.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public int[] Moves { get; } = {0, 0, 0, 0};
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Any lines that failed to be parsed.
|
|
|
|
|
/// </summary>
|
2016-09-10 02:13:48 +00:00
|
|
|
|
public readonly List<string> InvalidLines = new List<string>();
|
2016-06-20 04:22:43 +00:00
|
|
|
|
|
2018-07-14 16:55:22 +00:00
|
|
|
|
private GameStrings Strings { get; set; } = DefaultStrings;
|
|
|
|
|
private int LanguageID { get; set; } = DefaultLanguageID;
|
|
|
|
|
|
2016-09-20 05:59:15 +00:00
|
|
|
|
private int[] IVsSpeedFirst => new[] {IVs[0], IVs[1], IVs[2], IVs[5], IVs[3], IVs[4]};
|
|
|
|
|
private int[] IVsSpeedLast => new[] {IVs[0], IVs[1], IVs[2], IVs[4], IVs[5], IVs[3]};
|
|
|
|
|
private int[] EVsSpeedFirst => new[] {EVs[0], EVs[1], EVs[2], EVs[5], EVs[3], EVs[4]};
|
|
|
|
|
private int[] EVsSpeedLast => new[] {EVs[0], EVs[1], EVs[2], EVs[4], EVs[5], EVs[3]};
|
2016-09-18 05:10:27 +00:00
|
|
|
|
|
2018-07-14 16:55:22 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Loads a new <see cref="ShowdownSet"/> from the input string. If no string is provided, a blank set is returned.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="input">Single-line string which will be split before loading.</param>
|
2016-06-20 04:22:43 +00:00
|
|
|
|
public ShowdownSet(string input = null)
|
|
|
|
|
{
|
|
|
|
|
if (input == null)
|
|
|
|
|
return;
|
|
|
|
|
|
2018-07-14 16:55:22 +00:00
|
|
|
|
string[] lines = input.Split(Splitters, StringSplitOptions.None);
|
2018-03-11 18:39:58 +00:00
|
|
|
|
LoadLines(lines);
|
|
|
|
|
}
|
2018-07-14 16:55:22 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Loads a new <see cref="ShowdownSet"/> from the input string. If no string is provided, a blank set is returned.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="lines">Enumerable list of lines.</param>
|
2018-03-11 18:39:58 +00:00
|
|
|
|
public ShowdownSet(IEnumerable<string> lines)
|
|
|
|
|
{
|
|
|
|
|
if (lines == null)
|
2017-11-18 06:19:23 +00:00
|
|
|
|
return;
|
2018-03-11 18:39:58 +00:00
|
|
|
|
LoadLines(lines);
|
|
|
|
|
}
|
2018-07-14 16:55:22 +00:00
|
|
|
|
|
2018-03-11 18:39:58 +00:00
|
|
|
|
private void LoadLines(IEnumerable<string> lines)
|
|
|
|
|
{
|
2018-05-22 04:36:10 +00:00
|
|
|
|
lines = lines.Select(z => z.Replace("'", "’").Replace("–", "-").Trim()); // Sanitize apostrophes & dashes
|
2018-03-11 18:39:58 +00:00
|
|
|
|
lines = lines.Where(z => z.Length > 2);
|
2016-06-20 04:22:43 +00:00
|
|
|
|
|
2018-03-11 18:39:58 +00:00
|
|
|
|
ParseLines(lines);
|
2016-09-20 05:59:15 +00:00
|
|
|
|
|
2018-03-11 18:39:58 +00:00
|
|
|
|
// Showdown Quirks
|
|
|
|
|
Form = ConvertFormFromShowdown(Form, Species, Ability);
|
|
|
|
|
// Set Form
|
2018-07-14 02:13:25 +00:00
|
|
|
|
string[] formStrings = PKX.GetFormList(Species, Strings.Types, Strings.forms, genderForms);
|
2018-06-30 16:59:48 +00:00
|
|
|
|
FormIndex = string.IsNullOrWhiteSpace(Form) ? 0 : Math.Max(0, Array.FindIndex(formStrings, z => z.Contains(Form)));
|
2018-03-11 18:39:58 +00:00
|
|
|
|
}
|
2018-07-29 19:47:38 +00:00
|
|
|
|
|
2018-03-11 18:39:58 +00:00
|
|
|
|
private void ParseLines(IEnumerable<string> lines)
|
|
|
|
|
{
|
2016-06-20 04:22:43 +00:00
|
|
|
|
int movectr = 0;
|
2018-06-16 03:30:23 +00:00
|
|
|
|
var e = lines.GetEnumerator();
|
|
|
|
|
if (!e.MoveNext())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
ParseFirstLine(e.Current);
|
|
|
|
|
while (e.MoveNext())
|
2016-06-20 04:22:43 +00:00
|
|
|
|
{
|
2018-06-16 03:30:23 +00:00
|
|
|
|
var line = e.Current;
|
2016-09-20 05:59:15 +00:00
|
|
|
|
if (line.StartsWith("-"))
|
2016-06-20 04:22:43 +00:00
|
|
|
|
{
|
2017-06-18 01:37:19 +00:00
|
|
|
|
string moveString = ParseLineMove(line);
|
2018-07-14 02:13:25 +00:00
|
|
|
|
int move = Array.IndexOf(Strings.movelist, moveString);
|
2016-09-18 05:10:27 +00:00
|
|
|
|
if (move < 0)
|
|
|
|
|
InvalidLines.Add($"Unknown Move: {moveString}");
|
|
|
|
|
else
|
|
|
|
|
Moves[movectr++] = move;
|
|
|
|
|
|
2016-06-20 04:22:43 +00:00
|
|
|
|
if (movectr == 4)
|
2018-03-11 18:39:58 +00:00
|
|
|
|
return; // End of moves, end of set data
|
2016-06-20 04:22:43 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-14 16:55:22 +00:00
|
|
|
|
string[] brokenline = line.Split(LineSplit, StringSplitOptions.None);
|
2018-06-16 03:30:23 +00:00
|
|
|
|
var piece1 = brokenline[0].Trim();
|
|
|
|
|
var piece2 = brokenline.Length == 1 ? string.Empty : brokenline[1].Trim();
|
|
|
|
|
if (!ParseEntry(piece1, piece2))
|
|
|
|
|
InvalidLines.Add(line);
|
2016-06-20 04:22:43 +00:00
|
|
|
|
}
|
2018-06-16 03:30:23 +00:00
|
|
|
|
e.Dispose();
|
2016-06-20 04:22:43 +00:00
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
|
2018-06-16 03:30:23 +00:00
|
|
|
|
private bool ParseEntry(string first, string second)
|
2018-04-26 01:45:31 +00:00
|
|
|
|
{
|
2018-06-16 03:30:23 +00:00
|
|
|
|
switch (first)
|
2018-04-26 01:45:31 +00:00
|
|
|
|
{
|
2018-07-14 02:13:25 +00:00
|
|
|
|
case "Trait": case "Ability": return (Ability = Array.IndexOf(Strings.abilitylist, second)) >= 0;
|
2018-06-16 03:30:23 +00:00
|
|
|
|
case "Shiny": return Shiny = second.Trim() == "Yes";
|
2018-07-14 02:13:25 +00:00
|
|
|
|
case "Nature": return (Nature = Array.IndexOf(Strings.natures, second)) >= 0;
|
2018-06-16 03:30:23 +00:00
|
|
|
|
case "EV": case "EVs": ParseLineEVs(second); return true;
|
|
|
|
|
case "IV": case "IVs": ParseLineIVs(second); return true;
|
|
|
|
|
case "Level":
|
|
|
|
|
{
|
|
|
|
|
if (!int.TryParse(second.Trim(), out int val))
|
|
|
|
|
return false;
|
|
|
|
|
Level = val;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
case "Happiness": case "Friendship":
|
|
|
|
|
{
|
|
|
|
|
if (!int.TryParse(second.Trim(), out int val))
|
|
|
|
|
return false;
|
|
|
|
|
Friendship = val;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
if (first.EndsWith("Nature")) // XXX Nature
|
|
|
|
|
{
|
|
|
|
|
string naturestr = first.Split(' ')[0].Trim();
|
2018-07-14 02:13:25 +00:00
|
|
|
|
return (Nature = Array.IndexOf(Strings.natures, naturestr)) >= 0;
|
2018-06-16 03:30:23 +00:00
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2018-04-26 01:45:31 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-14 16:55:22 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the standard Text representation of the set details.
|
|
|
|
|
/// </summary>
|
2017-06-18 01:37:19 +00:00
|
|
|
|
public string Text => GetText();
|
2018-07-14 16:55:22 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the localized Text representation of the set details.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="lang">2 character language code</param>
|
2018-07-14 02:13:25 +00:00
|
|
|
|
public string LocalizedText(string lang) => LocalizedText(GameInfo.Language(lang));
|
2018-07-14 16:55:22 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets the localized Text representation of the set details.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="lang">Language ID</param>
|
2018-07-29 19:47:38 +00:00
|
|
|
|
private string LocalizedText(int lang)
|
|
|
|
|
{
|
|
|
|
|
var strings = GameInfo.GetStrings(lang);
|
|
|
|
|
lang += lang >= 5 ? 2 : 1; // shift from array index to LanguageID
|
|
|
|
|
LanguageID = lang;
|
|
|
|
|
return GetText(strings);
|
|
|
|
|
}
|
2018-07-14 16:55:22 +00:00
|
|
|
|
|
2018-07-14 02:13:25 +00:00
|
|
|
|
private string GetText(GameStrings strings = null)
|
2016-06-20 04:22:43 +00:00
|
|
|
|
{
|
2018-07-13 00:09:39 +00:00
|
|
|
|
if (Species <= 0 || Species > MAX_SPECIES)
|
2017-11-18 06:19:23 +00:00
|
|
|
|
return string.Empty;
|
2016-06-20 04:22:43 +00:00
|
|
|
|
|
2018-07-14 02:13:25 +00:00
|
|
|
|
if (strings != null)
|
|
|
|
|
Strings = strings;
|
|
|
|
|
|
2017-06-18 20:02:02 +00:00
|
|
|
|
var result = new List<string>();
|
|
|
|
|
|
|
|
|
|
// First Line: Name, Nickname, Gender, Item
|
2017-09-02 15:26:51 +00:00
|
|
|
|
string form = ConvertFormToShowdown(Form, Species);
|
2017-06-18 20:02:02 +00:00
|
|
|
|
result.Add(GetStringFirstLine(form));
|
|
|
|
|
|
|
|
|
|
// IVs
|
|
|
|
|
if (GetStringStats(out IEnumerable<string> ivstr, IVsSpeedLast, 31))
|
|
|
|
|
result.Add($"IVs: {string.Join(" / ", ivstr)}");
|
|
|
|
|
|
|
|
|
|
// EVs
|
|
|
|
|
if (GetStringStats(out IEnumerable<string> evstr, EVsSpeedLast, 0))
|
|
|
|
|
result.Add($"EVs: {string.Join(" / ", evstr)}");
|
|
|
|
|
|
|
|
|
|
// Secondary Stats
|
2018-07-14 02:13:25 +00:00
|
|
|
|
if (Ability > -1 && Ability < Strings.Ability.Count)
|
|
|
|
|
result.Add($"Ability: {Strings.Ability[Ability]}");
|
2018-05-12 04:44:09 +00:00
|
|
|
|
if (Level != 100)
|
|
|
|
|
result.Add($"Level: {Level}");
|
2017-06-18 20:02:02 +00:00
|
|
|
|
if (Shiny)
|
|
|
|
|
result.Add("Shiny: Yes");
|
|
|
|
|
|
|
|
|
|
if (Nature > -1)
|
2018-07-14 02:13:25 +00:00
|
|
|
|
result.Add($"{Strings.Natures[Nature]} Nature");
|
2017-06-18 20:02:02 +00:00
|
|
|
|
|
|
|
|
|
// Moves
|
|
|
|
|
result.AddRange(GetStringMoves());
|
|
|
|
|
|
|
|
|
|
return string.Join(Environment.NewLine, result);
|
|
|
|
|
}
|
2018-07-29 19:47:38 +00:00
|
|
|
|
|
2017-06-18 20:02:02 +00:00
|
|
|
|
private string GetStringFirstLine(string form)
|
|
|
|
|
{
|
2018-07-14 02:13:25 +00:00
|
|
|
|
string specForm = Strings.Species[Species];
|
2016-12-23 23:37:56 +00:00
|
|
|
|
if (!string.IsNullOrWhiteSpace(form))
|
2017-09-30 05:58:25 +00:00
|
|
|
|
specForm += $"-{form.Replace("Mega ", "Mega-")}";
|
2016-10-04 02:24:46 +00:00
|
|
|
|
|
2018-07-29 19:47:38 +00:00
|
|
|
|
string result = GetSpeciesNickname(specForm);
|
2016-09-18 05:10:27 +00:00
|
|
|
|
if (!string.IsNullOrEmpty(Gender))
|
|
|
|
|
result += $" ({Gender})";
|
2018-04-26 01:45:31 +00:00
|
|
|
|
if (HeldItem > 0)
|
|
|
|
|
{
|
2018-07-14 02:13:25 +00:00
|
|
|
|
var items = Strings.GetItemStrings(Format);
|
|
|
|
|
if (HeldItem < items.Count)
|
|
|
|
|
result += $" @ {items[HeldItem]}";
|
2018-04-26 01:45:31 +00:00
|
|
|
|
}
|
2017-06-18 20:02:02 +00:00
|
|
|
|
return result;
|
|
|
|
|
}
|
2018-07-29 19:47:38 +00:00
|
|
|
|
|
|
|
|
|
private string GetSpeciesNickname(string specForm)
|
|
|
|
|
{
|
|
|
|
|
if (Nickname == null)
|
|
|
|
|
return specForm;
|
|
|
|
|
var name = PKX.GetSpeciesNameGeneration(Species, LanguageID, Format);
|
|
|
|
|
if (name == Nickname)
|
|
|
|
|
return specForm;
|
|
|
|
|
return $"{Nickname} ({specForm})";
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-18 20:02:02 +00:00
|
|
|
|
private static bool GetStringStats(out IEnumerable<string> result, int[] stats, int ignore)
|
|
|
|
|
{
|
|
|
|
|
var list = new List<string>();
|
|
|
|
|
for (int i = 0; i < stats.Length; i++)
|
2016-06-20 04:22:43 +00:00
|
|
|
|
{
|
2017-06-18 20:02:02 +00:00
|
|
|
|
if (stats[i] == ignore) continue; // ignore unused EVs
|
|
|
|
|
list.Add($"{stats[i]} {StatNames[i]}");
|
2016-06-20 04:22:43 +00:00
|
|
|
|
}
|
2017-06-18 20:02:02 +00:00
|
|
|
|
result = list;
|
|
|
|
|
return list.Count > 0;
|
|
|
|
|
}
|
2018-07-29 19:47:38 +00:00
|
|
|
|
|
2017-06-18 20:02:02 +00:00
|
|
|
|
private IEnumerable<string> GetStringMoves()
|
|
|
|
|
{
|
2018-07-14 02:13:25 +00:00
|
|
|
|
foreach (int move in Moves.Where(move => move != 0 && move < Strings.Move.Count))
|
2016-06-20 04:22:43 +00:00
|
|
|
|
{
|
2018-07-14 02:13:25 +00:00
|
|
|
|
var str = $"- {Strings.Move[move]}";
|
2016-06-28 05:26:39 +00:00
|
|
|
|
if (move == 237) // Hidden Power
|
2018-07-14 02:13:25 +00:00
|
|
|
|
str += $" [{Strings.Types[1+HiddenPower.GetType(IVs, Format)]}]";
|
2017-06-29 05:09:26 +00:00
|
|
|
|
yield return str;
|
2016-06-20 04:22:43 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-06-18 20:02:02 +00:00
|
|
|
|
|
2017-12-27 00:29:35 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Converts the <see cref="PKM"/> data into an importable set format for Pokémon Showdown.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pkm">PKM to convert to string</param>
|
|
|
|
|
/// <returns>Multi line set data</returns>
|
2017-06-18 01:37:19 +00:00
|
|
|
|
public static string GetShowdownText(PKM pkm)
|
2016-06-20 04:22:43 +00:00
|
|
|
|
{
|
2017-11-18 06:19:23 +00:00
|
|
|
|
if (pkm.Species == 0)
|
|
|
|
|
return string.Empty;
|
2018-05-21 01:33:38 +00:00
|
|
|
|
return new ShowdownSet(pkm).Text;
|
|
|
|
|
}
|
2018-07-14 16:55:22 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Converts the <see cref="PKM"/> data into an importable set format for Pokémon Showdown.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="pkm">PKM to convert to string</param>
|
|
|
|
|
/// <returns>New ShowdownSet object representing the input <see cref="pkm"/></returns>
|
2018-05-21 01:33:38 +00:00
|
|
|
|
public ShowdownSet(PKM pkm)
|
|
|
|
|
{
|
2018-05-21 02:29:19 +00:00
|
|
|
|
if (pkm.Species <= 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Nickname = pkm.Nickname;
|
|
|
|
|
Species = pkm.Species;
|
|
|
|
|
HeldItem = pkm.HeldItem;
|
|
|
|
|
Ability = pkm.Ability;
|
|
|
|
|
EVs = pkm.EVs;
|
|
|
|
|
IVs = pkm.IVs;
|
|
|
|
|
Moves = pkm.Moves;
|
|
|
|
|
Nature = pkm.Nature;
|
|
|
|
|
Gender = genders[pkm.Gender < 2 ? pkm.Gender : 2];
|
|
|
|
|
Friendship = pkm.CurrentFriendship;
|
|
|
|
|
Level = PKX.GetLevel(pkm.Species, pkm.EXP);
|
|
|
|
|
Shiny = pkm.IsShiny;
|
|
|
|
|
|
|
|
|
|
FormIndex = pkm.AltForm;
|
2018-07-14 02:13:25 +00:00
|
|
|
|
string[] Forms = PKX.GetFormList(Species, Strings.Types, Strings.forms, genderForms, pkm.Format);
|
2018-05-21 02:29:19 +00:00
|
|
|
|
Form = pkm.AltForm > 0 && pkm.AltForm < Forms.Length ? Forms[pkm.AltForm] : string.Empty;
|
|
|
|
|
Format = pkm.Format;
|
2016-06-20 04:22:43 +00:00
|
|
|
|
}
|
2018-06-16 03:30:23 +00:00
|
|
|
|
|
|
|
|
|
private void ParseFirstLine(string first)
|
|
|
|
|
{
|
|
|
|
|
if (first.Contains(" @ "))
|
|
|
|
|
{
|
2018-07-22 02:20:11 +00:00
|
|
|
|
string[] pieces = first.Split(ItemSplit, StringSplitOptions.None);
|
2018-06-16 03:30:23 +00:00
|
|
|
|
string itemstr = pieces.Last().Trim();
|
|
|
|
|
|
|
|
|
|
ParseItemStr(itemstr);
|
|
|
|
|
ParseFirstLineNoItem(pieces[0]);
|
|
|
|
|
}
|
|
|
|
|
else
|
2018-07-29 19:47:38 +00:00
|
|
|
|
{
|
2018-06-16 03:30:23 +00:00
|
|
|
|
ParseFirstLineNoItem(first.Trim());
|
2018-07-29 19:47:38 +00:00
|
|
|
|
}
|
2018-06-16 03:30:23 +00:00
|
|
|
|
}
|
2018-07-29 19:47:38 +00:00
|
|
|
|
|
2018-06-16 03:30:23 +00:00
|
|
|
|
private void ParseItemStr(string itemstr)
|
|
|
|
|
{
|
2018-07-14 02:13:25 +00:00
|
|
|
|
if (tryGetItem(Format))
|
2018-06-16 03:30:23 +00:00
|
|
|
|
return;
|
2018-07-14 02:13:25 +00:00
|
|
|
|
if (tryGetItem(3))
|
|
|
|
|
return;
|
|
|
|
|
if (tryGetItem(2))
|
|
|
|
|
return;
|
|
|
|
|
InvalidLines.Add($"Unknown Item: {itemstr}");
|
|
|
|
|
|
|
|
|
|
bool tryGetItem(int format)
|
2018-06-16 03:30:23 +00:00
|
|
|
|
{
|
2018-07-14 02:13:25 +00:00
|
|
|
|
var items = (string[])Strings.GetItemStrings(format); // ireadonlylist->string[] must be possible for the provided strings
|
|
|
|
|
int item = Array.IndexOf(items, itemstr);
|
|
|
|
|
if (item < 0)
|
|
|
|
|
return false;
|
2018-06-16 03:30:23 +00:00
|
|
|
|
HeldItem = item;
|
2018-07-14 02:13:25 +00:00
|
|
|
|
return true;
|
2018-06-16 03:30:23 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2018-07-29 19:47:38 +00:00
|
|
|
|
|
2018-06-16 03:30:23 +00:00
|
|
|
|
private void ParseFirstLineNoItem(string line)
|
2016-09-20 05:59:15 +00:00
|
|
|
|
{
|
|
|
|
|
// Gender Detection
|
|
|
|
|
string last3 = line.Substring(line.Length - 3);
|
|
|
|
|
if (last3 == "(M)" || last3 == "(F)")
|
|
|
|
|
{
|
|
|
|
|
Gender = last3.Substring(1, 1);
|
|
|
|
|
line = line.Substring(0, line.Length - 3);
|
|
|
|
|
}
|
2018-07-14 02:13:25 +00:00
|
|
|
|
else if (line.Contains(Strings.Species[678])) // Meowstic Edge Case with no gender provided
|
2018-07-29 19:47:38 +00:00
|
|
|
|
{
|
2018-04-22 16:53:52 +00:00
|
|
|
|
Gender = "M";
|
2018-07-29 19:47:38 +00:00
|
|
|
|
}
|
2018-05-12 15:13:39 +00:00
|
|
|
|
|
2016-09-20 05:59:15 +00:00
|
|
|
|
// Nickname Detection
|
2018-02-13 01:36:15 +00:00
|
|
|
|
if (line.Contains("(") && line.Contains(")"))
|
|
|
|
|
ParseSpeciesNickname(line);
|
|
|
|
|
else
|
|
|
|
|
ParseSpeciesForm(line);
|
|
|
|
|
}
|
2018-07-29 19:47:38 +00:00
|
|
|
|
|
2018-02-13 01:36:15 +00:00
|
|
|
|
private bool ParseSpeciesForm(string spec)
|
|
|
|
|
{
|
2016-09-20 05:59:15 +00:00
|
|
|
|
spec = spec.Trim();
|
2018-07-14 02:13:25 +00:00
|
|
|
|
if ((Species = Array.IndexOf(Strings.specieslist, spec)) >= 0) // success, nothing else!
|
2018-02-13 01:36:15 +00:00
|
|
|
|
return true;
|
2016-09-20 05:59:15 +00:00
|
|
|
|
|
2018-01-31 00:18:39 +00:00
|
|
|
|
// Forme string present.
|
|
|
|
|
int end = spec.LastIndexOf('-');
|
|
|
|
|
if (end < 0)
|
2018-02-13 01:36:15 +00:00
|
|
|
|
return false;
|
2016-09-20 05:59:15 +00:00
|
|
|
|
|
2018-07-14 02:13:25 +00:00
|
|
|
|
Species = Array.IndexOf(Strings.specieslist, spec.Substring(0, end).Trim());
|
2018-02-04 17:44:19 +00:00
|
|
|
|
Form = spec.Substring(end + 1);
|
2017-12-01 02:24:31 +00:00
|
|
|
|
|
2018-02-13 01:36:15 +00:00
|
|
|
|
if (Species >= 0)
|
2018-02-16 02:59:38 +00:00
|
|
|
|
return true;
|
2018-02-13 01:36:15 +00:00
|
|
|
|
|
|
|
|
|
// failure to parse, check edge cases
|
2018-07-22 02:20:11 +00:00
|
|
|
|
foreach (var e in DashedSpecies)
|
2017-12-01 02:24:31 +00:00
|
|
|
|
{
|
2018-07-14 02:13:25 +00:00
|
|
|
|
if (!spec.StartsWith(Strings.Species[e].Replace("♂", "-M").Replace("♀", "-F")))
|
2018-02-13 01:36:15 +00:00
|
|
|
|
continue;
|
|
|
|
|
Species = e;
|
2018-07-14 02:13:25 +00:00
|
|
|
|
Form = spec.Substring(Strings.Species[e].Length);
|
2018-02-16 02:59:38 +00:00
|
|
|
|
return true;
|
2017-12-01 02:24:31 +00:00
|
|
|
|
}
|
2018-02-13 01:36:15 +00:00
|
|
|
|
|
|
|
|
|
// Version Megas
|
|
|
|
|
end = spec.LastIndexOf('-', Math.Max(0, end - 1));
|
|
|
|
|
if (end < 0)
|
|
|
|
|
return false;
|
2018-07-14 02:13:25 +00:00
|
|
|
|
Species = Array.IndexOf(Strings.specieslist, spec.Substring(0, end).Trim());
|
2018-02-13 01:36:15 +00:00
|
|
|
|
Form = spec.Substring(end + 1);
|
|
|
|
|
|
|
|
|
|
return Species >= 0;
|
2016-09-20 05:59:15 +00:00
|
|
|
|
}
|
2018-07-29 19:47:38 +00:00
|
|
|
|
|
2018-02-13 01:36:15 +00:00
|
|
|
|
private void ParseSpeciesNickname(string line)
|
2016-09-20 05:59:15 +00:00
|
|
|
|
{
|
|
|
|
|
int index = line.LastIndexOf("(", StringComparison.Ordinal);
|
|
|
|
|
string n1, n2;
|
2017-03-20 07:03:31 +00:00
|
|
|
|
if (index > 1) // correct format
|
2016-09-20 05:59:15 +00:00
|
|
|
|
{
|
|
|
|
|
n1 = line.Substring(0, index - 1);
|
|
|
|
|
n2 = line.Substring(index).Trim();
|
2017-10-24 06:12:58 +00:00
|
|
|
|
n2 = ReplaceAll(n2, string.Empty, "[", "]", "(", ")"); // Trim out excess data
|
2016-09-20 05:59:15 +00:00
|
|
|
|
}
|
|
|
|
|
else // nickname first (manually created set, incorrect)
|
|
|
|
|
{
|
|
|
|
|
int end = line.IndexOf(")", StringComparison.Ordinal);
|
|
|
|
|
n2 = line.Substring(index + 1, end - 1);
|
|
|
|
|
n1 = line.Substring(end + 2);
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-13 01:36:15 +00:00
|
|
|
|
if (ParseSpeciesForm(n2))
|
|
|
|
|
{
|
|
|
|
|
// successful parse on n2=>Species/Form, n1 is nickname
|
|
|
|
|
Nickname = n1;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
// other case is possibly true (or both invalid).
|
|
|
|
|
Nickname = n2;
|
|
|
|
|
ParseSpeciesForm(n1);
|
2016-09-20 05:59:15 +00:00
|
|
|
|
}
|
2018-07-29 19:47:38 +00:00
|
|
|
|
|
2017-06-18 01:37:19 +00:00
|
|
|
|
private string ParseLineMove(string line)
|
2016-09-20 05:59:15 +00:00
|
|
|
|
{
|
|
|
|
|
string moveString = line.Substring(line[1] == ' ' ? 2 : 1);
|
2018-07-14 02:13:25 +00:00
|
|
|
|
if (!moveString.Contains(Strings.Move[237])) // Hidden Power
|
2016-09-20 05:59:15 +00:00
|
|
|
|
return moveString;
|
|
|
|
|
|
2018-07-29 19:47:38 +00:00
|
|
|
|
if (moveString.Length <= 13)
|
|
|
|
|
return Strings.Move[237];
|
|
|
|
|
|
2016-09-20 05:59:15 +00:00
|
|
|
|
// Defined Hidden Power
|
2018-07-29 19:47:38 +00:00
|
|
|
|
string type = moveString.Remove(0, 13);
|
|
|
|
|
type = ReplaceAll(type, string.Empty, "[", "]", "(", ")"); // Trim out excess data
|
|
|
|
|
int hpVal = Array.IndexOf(Strings.types, type) - 1; // Get HP Type
|
2018-07-14 02:13:25 +00:00
|
|
|
|
|
2018-07-29 19:47:38 +00:00
|
|
|
|
if (IVs.Any(z => z != 31))
|
|
|
|
|
{
|
|
|
|
|
if (!HiddenPower.SetIVsForType(hpVal, IVs, Format))
|
|
|
|
|
InvalidLines.Add($"Invalid IVs for Hidden Power Type: {type}");
|
|
|
|
|
}
|
|
|
|
|
else if (hpVal >= 0)
|
|
|
|
|
{
|
|
|
|
|
IVs = PKX.SetHPIVs(hpVal, IVs, Format); // Get IVs
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
InvalidLines.Add($"Invalid Hidden Power Type: {type}");
|
2016-09-20 05:59:15 +00:00
|
|
|
|
}
|
2018-07-14 02:13:25 +00:00
|
|
|
|
return Strings.Move[237];
|
2016-09-20 05:59:15 +00:00
|
|
|
|
}
|
2018-07-29 19:47:38 +00:00
|
|
|
|
|
2017-06-18 01:37:19 +00:00
|
|
|
|
private void ParseLineEVs(string line)
|
2016-09-20 05:59:15 +00:00
|
|
|
|
{
|
2018-07-22 02:20:11 +00:00
|
|
|
|
var evlist = SplitLineStats(line);
|
2017-01-29 08:32:02 +00:00
|
|
|
|
if (evlist.Length == 1)
|
|
|
|
|
InvalidLines.Add("Unknown EV input.");
|
2016-09-20 05:59:15 +00:00
|
|
|
|
for (int i = 0; i < evlist.Length / 2; i++)
|
|
|
|
|
{
|
2018-07-22 02:20:11 +00:00
|
|
|
|
int pos = i * 2;
|
|
|
|
|
bool valid = ushort.TryParse(evlist[pos + 0], out ushort EV);
|
|
|
|
|
int index = Array.IndexOf(StatNames, evlist[pos + 1]);
|
2017-06-18 20:02:02 +00:00
|
|
|
|
if (valid && index > -1)
|
2016-09-20 05:59:15 +00:00
|
|
|
|
EVs[index] = EV;
|
|
|
|
|
else
|
2018-07-22 02:20:11 +00:00
|
|
|
|
InvalidLines.Add($"Unknown EV Type input: {evlist[pos]}");
|
2016-09-20 05:59:15 +00:00
|
|
|
|
}
|
2018-02-08 02:28:56 +00:00
|
|
|
|
EVs = EVsSpeedFirst;
|
2016-09-20 05:59:15 +00:00
|
|
|
|
}
|
2018-07-29 19:47:38 +00:00
|
|
|
|
|
2017-06-18 01:37:19 +00:00
|
|
|
|
private void ParseLineIVs(string line)
|
2016-09-20 05:59:15 +00:00
|
|
|
|
{
|
2017-06-18 01:37:19 +00:00
|
|
|
|
string[] ivlist = SplitLineStats(line);
|
2017-01-29 08:32:02 +00:00
|
|
|
|
if (ivlist.Length == 1)
|
|
|
|
|
InvalidLines.Add("Unknown IV input.");
|
2016-09-20 05:59:15 +00:00
|
|
|
|
for (int i = 0; i < ivlist.Length / 2; i++)
|
|
|
|
|
{
|
2018-07-29 19:47:38 +00:00
|
|
|
|
var pos = i * 2;
|
|
|
|
|
bool valid = byte.TryParse(ivlist[pos + 0], out byte IV);
|
|
|
|
|
int index = Array.IndexOf(StatNames, ivlist[pos + 1]);
|
2017-06-18 20:02:02 +00:00
|
|
|
|
if (valid && index > -1)
|
2016-09-20 05:59:15 +00:00
|
|
|
|
IVs[index] = IV;
|
|
|
|
|
else
|
2018-07-29 19:47:38 +00:00
|
|
|
|
InvalidLines.Add($"Unknown IV Type input: {ivlist[pos]}");
|
2016-09-20 05:59:15 +00:00
|
|
|
|
}
|
2018-02-08 02:28:56 +00:00
|
|
|
|
IVs = IVsSpeedFirst;
|
2016-09-20 05:59:15 +00:00
|
|
|
|
}
|
2018-07-29 19:47:38 +00:00
|
|
|
|
|
2017-09-02 15:26:51 +00:00
|
|
|
|
private static string ConvertFormToShowdown(string form, int spec)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrWhiteSpace(form))
|
|
|
|
|
{
|
|
|
|
|
if (spec == 774) // Minior
|
|
|
|
|
form = "Meteor";
|
|
|
|
|
return form;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (spec)
|
|
|
|
|
{
|
|
|
|
|
case 550 when form == "Blue":
|
2018-05-07 01:46:51 +00:00
|
|
|
|
return "Blue-Striped";
|
2017-09-02 15:26:51 +00:00
|
|
|
|
case 666 when form == "Poké Ball":
|
|
|
|
|
return "Pokeball"; // Vivillon
|
|
|
|
|
case 718: // Zygarde
|
2017-11-18 03:14:27 +00:00
|
|
|
|
form = form.Replace("-C", string.Empty);
|
|
|
|
|
form = form.Replace("50%", string.Empty);
|
2017-09-02 15:26:51 +00:00
|
|
|
|
return form.Replace("100%", "Complete");
|
|
|
|
|
case 774: // Minior
|
|
|
|
|
if (form.StartsWith("M-"))
|
|
|
|
|
return "Meteor";
|
2017-11-18 03:14:27 +00:00
|
|
|
|
return form.Replace("C-", string.Empty);
|
|
|
|
|
case 800 when form == "Dusk": // Necrozma
|
|
|
|
|
return $"{form}-Mane";
|
|
|
|
|
case 800 when form == "Dawn": // Necrozma
|
|
|
|
|
return $"{form}-Wings";
|
2017-09-02 15:26:51 +00:00
|
|
|
|
|
2017-11-18 03:14:27 +00:00
|
|
|
|
case 676: // Furfrou
|
|
|
|
|
case 658: // Greninja
|
|
|
|
|
case 744: // Rockruff
|
|
|
|
|
return string.Empty;
|
2017-09-02 15:26:51 +00:00
|
|
|
|
default:
|
2017-11-18 03:14:27 +00:00
|
|
|
|
if (Legal.Totem_USUM.Contains(spec) && form == "Large")
|
2018-05-12 00:44:27 +00:00
|
|
|
|
return Legal.Totem_Alolan.Contains(spec) && spec != 778 ? "Alola-Totem" : "Totem";
|
2018-05-07 01:46:51 +00:00
|
|
|
|
return form.Replace(" ", "-");
|
2017-09-02 15:26:51 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2018-07-29 19:47:38 +00:00
|
|
|
|
|
2017-09-02 15:26:51 +00:00
|
|
|
|
private static string ConvertFormFromShowdown(string form, int spec, int ability)
|
|
|
|
|
{
|
2018-05-12 04:09:39 +00:00
|
|
|
|
form = form?.Replace(" ", "-"); // inconsistencies are great
|
2017-09-02 15:26:51 +00:00
|
|
|
|
switch (spec)
|
|
|
|
|
{
|
2018-05-07 01:46:51 +00:00
|
|
|
|
case 550 when form == "Blue-Striped": // Basculin
|
2017-09-02 15:26:51 +00:00
|
|
|
|
return "Blue";
|
|
|
|
|
case 658 when ability == 210: // Greninja
|
|
|
|
|
return "Ash"; // Battle Bond
|
|
|
|
|
case 666 when form == "Pokeball": // Vivillon
|
|
|
|
|
return "Poké Ball";
|
|
|
|
|
|
|
|
|
|
// Zygarde
|
2017-10-18 18:45:45 +00:00
|
|
|
|
case 718 when string.IsNullOrWhiteSpace(form) && ability == 211:
|
|
|
|
|
return "50%-C";
|
2017-09-02 15:26:51 +00:00
|
|
|
|
case 718 when string.IsNullOrWhiteSpace(form):
|
|
|
|
|
return "50%";
|
|
|
|
|
case 718 when form == "Complete":
|
|
|
|
|
return "100%";
|
|
|
|
|
case 718 when ability == 211:
|
|
|
|
|
return "-C"; // Power Construct
|
|
|
|
|
|
2017-11-18 03:14:27 +00:00
|
|
|
|
case 744 when ability == 020: // Rockruff-1
|
|
|
|
|
return "Dusk";
|
|
|
|
|
|
2017-09-02 15:26:51 +00:00
|
|
|
|
// Minior
|
|
|
|
|
case 774 when !string.IsNullOrWhiteSpace(form) && form != "Meteor":
|
2017-09-30 05:58:25 +00:00
|
|
|
|
return $"C-{form}";
|
2017-09-02 15:26:51 +00:00
|
|
|
|
|
2017-11-18 03:14:27 +00:00
|
|
|
|
// Necrozma
|
2018-02-22 04:40:06 +00:00
|
|
|
|
case 800 when form == "Dusk-Mane":
|
2017-11-18 03:14:27 +00:00
|
|
|
|
return "Dusk";
|
2018-02-22 04:40:06 +00:00
|
|
|
|
case 800 when form == "Dawn-Wings":
|
2017-11-18 03:14:27 +00:00
|
|
|
|
return "Dawn";
|
|
|
|
|
|
2017-09-02 15:26:51 +00:00
|
|
|
|
default:
|
2018-05-12 15:41:23 +00:00
|
|
|
|
if (Legal.Totem_USUM.Contains(spec) && form?.EndsWith("Totem") == true)
|
2017-11-18 04:38:43 +00:00
|
|
|
|
return "Large";
|
2017-09-02 15:26:51 +00:00
|
|
|
|
return form;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-09-20 05:59:15 +00:00
|
|
|
|
|
2017-06-18 01:37:19 +00:00
|
|
|
|
private static string[] SplitLineStats(string line)
|
2016-09-20 05:59:15 +00:00
|
|
|
|
{
|
|
|
|
|
// Because people think they can type sets out...
|
|
|
|
|
return line
|
|
|
|
|
.Replace("SAtk", "SpA").Replace("Sp Atk", "SpA")
|
|
|
|
|
.Replace("SDef", "SpD").Replace("Sp Def", "SpD")
|
2018-07-22 02:20:11 +00:00
|
|
|
|
.Replace("Spd", "Spe").Replace("Speed", "Spe").Split(StatSplitters, StringSplitOptions.None);
|
2016-09-20 05:59:15 +00:00
|
|
|
|
}
|
2018-07-29 19:47:38 +00:00
|
|
|
|
|
2017-10-24 06:12:58 +00:00
|
|
|
|
private static string ReplaceAll(string original, string to, params string[] toBeReplaced)
|
2016-09-20 05:59:15 +00:00
|
|
|
|
{
|
2017-10-24 06:12:58 +00:00
|
|
|
|
return toBeReplaced.Aggregate(original, (current, v) => current.Replace(v, to));
|
2016-09-20 05:59:15 +00:00
|
|
|
|
}
|
2018-03-11 18:39:58 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Fetches <see cref="ShowdownSet"/> data from the input <see cref="lines"/>.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="lines">Raw lines containing numerous multi-line set data.</param>
|
|
|
|
|
/// <returns><see cref="ShowdownSet"/> objects until <see cref="lines"/> is consumed.</returns>
|
|
|
|
|
public static IEnumerable<ShowdownSet> GetShowdownSets(IEnumerable<string> lines)
|
|
|
|
|
{
|
|
|
|
|
var setLines = new List<string>(8);
|
|
|
|
|
foreach (var line in lines)
|
|
|
|
|
{
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(line))
|
|
|
|
|
{
|
|
|
|
|
setLines.Add(line);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2018-06-09 15:12:47 +00:00
|
|
|
|
if (setLines.Count == 0)
|
|
|
|
|
continue;
|
2018-03-11 18:39:58 +00:00
|
|
|
|
yield return new ShowdownSet(setLines);
|
|
|
|
|
setLines.Clear();
|
|
|
|
|
}
|
2018-06-09 15:12:47 +00:00
|
|
|
|
if (setLines.Count != 0)
|
|
|
|
|
yield return new ShowdownSet(setLines);
|
2018-03-11 18:39:58 +00:00
|
|
|
|
}
|
2018-05-20 03:48:03 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Fetches ShowdownSet lines from the input <see cref="PKM"/> data.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="data">Pokémon data to summarize.</param>
|
|
|
|
|
/// <returns>Consumable list of <see cref="ShowdownSet.Text"/> lines.</returns>
|
2018-06-17 04:46:43 +00:00
|
|
|
|
public static IEnumerable<string> GetShowdownSets(IEnumerable<PKM> data) => data.Where(p => p.Species != 0).Select(GetShowdownText);
|
2018-05-20 03:48:03 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Fetches ShowdownSet lines from the input <see cref="PKM"/> data, and combines it into one string.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="data">Pokémon data to summarize.</param>
|
|
|
|
|
/// <param name="separator">Splitter between each set.</param>
|
|
|
|
|
/// <returns>Single string containing all <see cref="ShowdownSet.Text"/> lines.</returns>
|
2018-06-17 04:46:43 +00:00
|
|
|
|
public static string GetShowdownSets(IEnumerable<PKM> data, string separator) => string.Join(separator, GetShowdownSets(data));
|
2016-06-20 04:22:43 +00:00
|
|
|
|
}
|
|
|
|
|
}
|