Misc tweaks

showdownset: contains char instead of string
gameinfo: static readonly array instead of redefining new on update
legality: order of operation / value reuse / simplification / comments
pkx: compare char instead of single character string
header/footer: move assignment into method as an out instead of ref
This commit is contained in:
Kurt 2019-01-20 21:55:28 -08:00
parent 3f759058ce
commit 8652677a79
12 changed files with 71 additions and 60 deletions

View file

@ -433,7 +433,7 @@ namespace PKHeX.Core
}
// Nickname Detection
if (line.Contains("(") && line.Contains(")"))
if (line.Contains('(') && line.Contains(')'))
ParseSpeciesNickname(line);
else
ParseSpeciesForm(line);
@ -693,7 +693,7 @@ namespace PKHeX.Core
/// 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>
/// <returns>Consumable list of <see cref="Text"/> lines.</returns>
public static IEnumerable<string> GetShowdownSets(IEnumerable<PKM> data) => data.Where(p => p.Species != 0).Select(GetShowdownText);
/// <summary>
@ -701,7 +701,7 @@ namespace PKHeX.Core
/// </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>
/// <returns>Single string containing all <see cref="Text"/> lines.</returns>
public static string GetShowdownSets(IEnumerable<PKM> data, string separator) => string.Join(separator, GetShowdownSets(data));
}
}

View file

@ -13,6 +13,9 @@ namespace PKHeX.Core
public static string Language2Char(uint lang) => lang > lang_val.Length ? DefaultLanguage : lang_val[lang];
private static readonly GameStrings[] Languages = new GameStrings[lang_val.Length];
public static readonly IReadOnlyList<string> GenderSymbolUnicode = new[] {"♂", "♀", "-"};
public static readonly IReadOnlyList<string> GenderSymbolASCII = new[] {"M", "F", "-"};
// Lazy fetch implementation
private static int DefaultLanguageIndex => Array.IndexOf(lang_val, DefaultLanguage);

View file

@ -364,23 +364,16 @@ namespace PKHeX.Core
internal static int GetEggHatchLevel(PKM pkm) => GetEggHatchLevel(pkm.Format);
internal static int GetEggHatchLevel(int gen) => gen <= 3 ? 5 : 1;
internal static ICollection<int> GetSplitBreedGeneration(PKM pkm)
{
return GetSplitBreedGeneration(pkm.GenNumber);
}
private static ICollection<int> GetSplitBreedGeneration(int generation)
internal static ICollection<int> GetSplitBreedGeneration(int generation)
{
switch (generation)
{
case 1:
case 2: return Empty;
case 3: return SplitBreed_3;
case 4:
case 5:
case 6:
case 7: return SplitBreed;
default: return Empty;
default: return Array.Empty<int>();
}
}
@ -408,7 +401,7 @@ namespace PKHeX.Core
}
}
internal static IEnumerable<int> GetFutureGenEvolutions(int generation)
internal static ICollection<int> GetFutureGenEvolutions(int generation)
{
switch (generation)
{
@ -417,7 +410,7 @@ namespace PKHeX.Core
case 3: return FutureEvolutionsGen3;
case 4: return FutureEvolutionsGen4;
case 5: return FutureEvolutionsGen5;
default: return Enumerable.Empty<int>();
default: return Array.Empty<int>();
}
}
@ -481,10 +474,10 @@ namespace PKHeX.Core
private static bool IsHeldItemAllowed(int item, int generation)
{
if (item < 0)
return false;
if (item == 0)
return true;
if (item < 0)
return false;
var items = GetReleasedHeldItems(generation);
return items.Length > item && items[item];
@ -520,7 +513,8 @@ namespace PKHeX.Core
int last = poss.FindLastIndex(z => z.Species == minSpecies);
return curr.Count >= last;
}
if (GetSplitBreedGeneration(pkm).Contains(GetBaseSpecies(pkm, poss, 1)))
int gen = pkm.GenNumber;
if (gen >= 3 && GetSplitBreedGeneration(gen).Contains(GetBaseSpecies(pkm, poss, 1)))
return curr.Count >= poss.Count - 1;
return curr.Count >= poss.Count;
}
@ -658,16 +652,16 @@ namespace PKHeX.Core
return GetBaseSpecies(pkm, evos, skipOption);
}
internal static int GetBaseSpecies(PKM pkm, IReadOnlyList<DexLevel> evos, int skipOption = 0)
internal static int GetBaseSpecies(PKM pkm, IReadOnlyList<DexLevel> evos, int skipOption = 0) => GetBaseSpecies(pkm.Species, evos, skipOption);
internal static int GetBaseSpecies(int species, IReadOnlyList<DexLevel> evos, int skipOption = 0)
{
if (pkm.Species == 292) // Shedinja
if (species == 292) // Shedinja
return 290; // Nincada
switch (skipOption)
{
case -1: return pkm.Species;
case 1: return evos.Count <= 1 ? pkm.Species : evos[evos.Count - 2].Species;
default: return evos.Count <= 0 ? pkm.Species : evos[evos.Count - 1].Species;
}
// skip n from end, return species if invalid index
int index = evos.Count - 1 - skipOption;
return (uint)index >= evos.Count ? species : evos[index].Species;
}
private static int GetMaxLevelGeneration(PKM pkm)
@ -736,16 +730,16 @@ namespace PKHeX.Core
return r;
int species = pkm.Species;
// Special Type Tutors Availability
bool moveTutor = Tutor || MoveReminder; // Usually true, except when called for move suggestions (no tutored moves)
if (FormChangeMoves.Contains(species)) // Deoxys & Shaymin & Giratina (others don't have extra but whatever)
{
int formcount = pkm.PersonalInfo.FormeCount;
// These don't evolve, so don't bother iterating for all entries in the evolution chain (should always be count==1).
int formcount;
// In gen 3 deoxys has different forms depending on the current game, in the PersonalInfo there is no alternate form info
if (species == 386 && pkm.Format == 3)
if (pkm.Format == 3 && species == 386)
formcount = 4;
else
formcount = pkm.PersonalInfo.FormeCount;
for (int i = 0; i < formcount; i++)
r.AddRange(GetMoves(pkm, species, minLvLG1, minLvLG2, vs[0].Level, i, Tutor, Version, LVL, Tutor, Machine, MoveReminder, RemoveTransferHM, Generation));
@ -754,6 +748,9 @@ namespace PKHeX.Core
return r.Distinct();
}
// Special Type Tutors Availability
bool moveTutor = Tutor || MoveReminder; // Usually true, except when called for move suggestions (no tutored moves)
for (var i = 0; i < vs.Count; i++)
{
var evo = vs[i];
@ -783,12 +780,14 @@ namespace PKHeX.Core
return GetMoves(pkm, evo.Species, minlvlevo1, minlvlevo2, maxLevel, pkm.AltForm, Tutor, Version, LVL, moveTutor, Machine, MoveReminder, RemoveTransferHM, Generation);
}
/// <summary>
/// Returns the minimum level the move can be learned at based on the species encounter level.
/// </summary>
private static int GetEvoMoveMinLevel1(PKM pkm, int Generation, int minLvLG1, EvoCriteria evo)
{
// Return moves from minLvLG1 if species if the species encounters
// For evolutions return moves using evolution min level as min level
if (Generation != 1)
return 1;
// For evolutions, return the lower of the two; current level should legally be >=
if (evo.MinLevel > 1)
return Math.Min(pkm.CurrentLevel, evo.MinLevel);
return minLvLG1;
@ -798,6 +797,7 @@ namespace PKHeX.Core
{
if (Generation != 2 || ParseSettings.AllowGen2MoveReminder(pkm))
return 1;
// For evolutions, return the lower of the two; current level should legally be >=
if (evo.MinLevel > 1)
return Math.Min(pkm.CurrentLevel, evo.MinLevel);
return minLvLG2;

View file

@ -17,20 +17,22 @@ namespace PKHeX.Core
public static IEnumerable<EncounterEgg> GenerateEggs(PKM pkm, IReadOnlyList<DexLevel> vs, bool all = false)
{
if (NoHatchFromEgg.Contains(pkm.Species))
int species = pkm.Species;
if (NoHatchFromEgg.Contains(species))
yield break;
if (FormConverter.IsTotemForm(pkm.Species, pkm.AltForm, pkm.GenNumber))
yield break; // no totem eggs
int gen = pkm.GenNumber;
if (gen <= 1)
yield break; // can't get eggs
if (FormConverter.IsTotemForm(species, pkm.AltForm, gen))
yield break; // no totem eggs
// version is a true indicator for all generation 3-5 origins
var ver = (GameVersion)pkm.Version;
int lvl = GetEggHatchLevel(gen);
int max = GetMaxSpeciesOrigin(gen);
var baseSpecies = GetBaseSpecies(pkm, vs, 0);
int lvl = GetEggHatchLevel(gen);
var baseSpecies = GetBaseSpecies(species, vs, 0);
if (baseSpecies <= max)
{
yield return new EncounterEgg { Version = ver, Level = lvl, Species = baseSpecies };
@ -38,10 +40,10 @@ namespace PKHeX.Core
yield return new EncounterEgg { Version = GetOtherTradePair(ver), Level = lvl, Species = baseSpecies };
}
if (!GetSplitBreedGeneration(pkm).Contains(pkm.Species))
if (!GetSplitBreedGeneration(gen).Contains(species))
yield break; // no other possible species
var other = GetBaseSpecies(pkm, vs, 1);
var other = GetBaseSpecies(species, vs, 1);
if (other <= max)
{
yield return new EncounterEggSplit { Version = ver, Level = lvl, Species = other, OtherSpecies = baseSpecies };

View file

@ -5,8 +5,6 @@ namespace PKHeX.Core
{
public static partial class Legal
{
public static readonly HashSet<int> Empty = new HashSet<int>();
public static readonly int[] Items_Ball =
{
000, 001, 002, 003, 004, 005, 006, 007, 008, 009, 010, 011, 012,

View file

@ -239,11 +239,14 @@ namespace PKHeX.Core
/// <returns>Gender integer</returns>
public static int GetGenderFromString(string s)
{
if (s == "♂" || s == "M")
return 0;
if (s == "♀" || s == "F")
return 1;
if (s.Length != 1)
return 2;
switch (s[0])
{
case '♂': case 'M': return 0;
case '♀': case 'F': return 1;
default: return 2;
}
}
/// <summary>

View file

@ -11,7 +11,7 @@ namespace PKHeX.Core
{
// Save Data Attributes
protected override string BAKText => $"{OT} ({(GameVersion)Game}) - {PlayTimeString}";
public override string Filter => (Footer.Length > 0 ? "DeSmuME DSV|*.dsv|" : "") + "SAV File|*.sav|All Files|*.*";
public override string Filter => (Footer.Length != 0 ? "DeSmuME DSV|*.dsv|" : "") + "SAV File|*.sav|All Files|*.*";
public override string Extension => ".sav";
public SAV5(byte[] data = null, GameVersion versionOverride = GameVersion.Any)

View file

@ -96,8 +96,8 @@ namespace PKHeX.Core
public string Nickname => Util.TrimFromZero(Encoding.ASCII.GetString(Data, 0x12D, 0x20)); // dunno length
public static readonly string[] Genders = {"M", "F", "-"};
public string GenderString => (uint) Gender >= Genders.Length ? string.Empty : Genders[Gender];
public static readonly IReadOnlyList<string> Genders = GameInfo.GenderSymbolASCII;
public string GenderString => (uint) Gender >= Genders.Count ? string.Empty : Genders[Gender];
public string ShinyString => IsShiny ? "★ " : string.Empty;
public string FormString => AltForm != 0 ? $"-{AltForm}" : string.Empty;
private string NickStr => string.IsNullOrWhiteSpace(Nickname) ? PKX.GetSpeciesNameGeneration(Species, (int)LanguageID.English, 7) : Nickname;

View file

@ -466,8 +466,7 @@ namespace PKHeX.Core
public static SaveFile GetVariantSAV(byte[] data)
{
// Pre-check for header/footer signatures
byte[] header = Array.Empty<byte>(), footer = Array.Empty<byte>();
CheckHeaderFooter(ref data, ref header, ref footer);
CheckHeaderFooter(ref data, out var header, out var footer);
var sav = GetVariantSAVInternal(data);
if (sav == null)
return null;
@ -511,9 +510,8 @@ namespace PKHeX.Core
{
// Pre-check for header/footer signatures
SaveFile sav;
byte[] header = Array.Empty<byte>(), footer = Array.Empty<byte>();
byte[] data = MC.SelectedSaveData;
CheckHeaderFooter(ref data, ref header, ref footer);
CheckHeaderFooter(ref data, out var header, out var footer);
switch (MC.SelectedGameVersion)
{
@ -789,8 +787,15 @@ namespace PKHeX.Core
/// <returns>Checksum</returns>
public static ushort CRC32(byte[] data, uint initial = 0) => CRC32(data, 0, data.Length, initial);
private static void CheckHeaderFooter(ref byte[] input, ref byte[] header, ref byte[] footer)
/// <summary>
/// Checks the provided <see cref="input"/> and pulls out any <see cref="header"/> and/or <see cref="footer"/> arrays.
/// </summary>
/// <param name="input">Input byte array to strip</param>
/// <param name="header">Header data</param>
/// <param name="footer">Footer data</param>
private static void CheckHeaderFooter(ref byte[] input, out byte[] header, out byte[] footer)
{
header = Array.Empty<byte>(); footer = Array.Empty<byte>();
if (input.Length > SIZE_G4RAW) // DeSmuME Gen4/5 DSV
{
if (input.Length == 0x800A4) // Action Replay

View file

@ -111,7 +111,7 @@ namespace PKHeX.WinForms.Controls
private Action GetFieldsfromPKM;
private Func<PKM> GetPKMfromFields;
private LegalityAnalysis Legality;
private string[] gendersymbols = { "♂", "♀", "-" };
private IReadOnlyList<string> gendersymbols = GameInfo.GenderSymbolUnicode;
private readonly Image mixedHighlight = ImageUtil.ChangeOpacity(Resources.slotSet, 0.5);
private HashSet<int> AllowedMoves = new HashSet<int>();
@ -321,7 +321,7 @@ namespace PKHeX.WinForms.Controls
c.SelectedValue = index;
}
public void UpdateUnicode(string[] symbols)
public void UpdateUnicode(IReadOnlyList<string> symbols)
{
gendersymbols = symbols;
if (!Unicode)

View file

@ -78,11 +78,11 @@ namespace PKHeX.WinForms
private set
{
_unicode = value;
GenderSymbols = value ? new[] {"♂", "♀", "-"} : new[] {"M", "F", "-"};
GenderSymbols = value ? GameInfo.GenderSymbolUnicode : GameInfo.GenderSymbolASCII;
}
}
public static string[] GenderSymbols { get; private set; } = { "♂", "♀", "-" };
public static IReadOnlyList<string> GenderSymbols { get; private set; } = GameInfo.GenderSymbolUnicode;
public static bool HaX { get; private set; }
private readonly string[] main_langlist = Enum.GetNames(typeof(ProgramLanguage));

View file

@ -57,7 +57,7 @@ namespace PKHeX.WinForms
private bool editing;
private readonly string[] gendersymbols = Main.GenderSymbols;
private readonly IReadOnlyList<string> gendersymbols = Main.GenderSymbols;
private readonly byte[] data = new byte[0x1B40];
private readonly Control[] editor_spec;
@ -189,7 +189,7 @@ namespace PKHeX.WinForms
string nickname = Util.TrimFromZero(Encoding.Unicode.GetString(data, offset + 0x18, 24));
string OTname = Util.TrimFromZero(Encoding.Unicode.GetString(data, offset + 0x30, 24));
string genderstr = gendersymbols[gender];
string genderstr = gendersymbols[(int)gender];
string shinystr = shiny == 1 ? "Yes" : "No";
string[] movelist = GameInfo.Strings.movelist;