level int -> byte

Might refactor the learnset level get to byte later as a TryGet so -1 is never returned.
This commit is contained in:
Kurt 2025-05-17 14:45:49 -05:00
parent 6b7938fea1
commit 7442e86d65
43 changed files with 142 additions and 142 deletions

View File

@ -61,7 +61,7 @@ public static void SetMoveShopFlagsAll(this IMoveShop8Mastery shop, PKM pk)
/// <summary>
/// Sets all possible move shop flags for the requested entity.
/// </summary>
public static void SetMoveShopFlagsAll(this IMoveShop8Mastery shop, Learnset learn, Learnset mastery, int level)
public static void SetMoveShopFlagsAll(this IMoveShop8Mastery shop, Learnset learn, Learnset mastery, byte level)
{
var permit = shop.Permit;
var possible = permit.RecordPermitIndexes;
@ -79,7 +79,7 @@ public static void SetMoveShopFlagsAll(this IMoveShop8Mastery shop, Learnset lea
/// <summary>
/// Sets all move shop flags for the currently known moves.
/// </summary>
public static void SetMoveShopFlags(this IMoveShop8Mastery shop, ReadOnlySpan<ushort> moves, Learnset learn, Learnset mastery, int level)
public static void SetMoveShopFlags(this IMoveShop8Mastery shop, ReadOnlySpan<ushort> moves, Learnset learn, Learnset mastery, byte level)
{
var permit = shop.Permit;
var possible = permit.RecordPermitIndexes;
@ -97,7 +97,7 @@ public static void SetMoveShopFlags(this IMoveShop8Mastery shop, ReadOnlySpan<us
/// <summary>
/// Sets the "mastered" move shop flag for the requested move.
/// </summary>
public static void SetMasteredFlag(this IMoveShop8Mastery shop, Learnset learn, Learnset mastery, int level, int index, ushort move)
public static void SetMasteredFlag(this IMoveShop8Mastery shop, Learnset learn, Learnset mastery, byte level, int index, ushort move)
{
if (shop.GetMasteredRecordFlag(index))
return;
@ -116,7 +116,7 @@ public static void SetMasteredFlag(this IMoveShop8Mastery shop, Learnset learn,
/// <summary>
/// Sets the "mastered" move shop flag for the encounter.
/// </summary>
public static void SetEncounterMasteryFlags(this IMoveShop8Mastery shop, ReadOnlySpan<ushort> moves, Learnset mastery, int level)
public static void SetEncounterMasteryFlags(this IMoveShop8Mastery shop, ReadOnlySpan<ushort> moves, Learnset mastery, byte level)
{
var permit = shop.Permit;
var possible = permit.RecordPermitIndexes;
@ -143,7 +143,6 @@ public static void SetEncounterMasteryFlags(this IMoveShop8Mastery shop, ReadOnl
public static void SetPurchasedFlagsAll(this IMoveShop8Mastery shop)
{
var permit = shop.Permit;
var possible = permit.RecordPermitIndexes;
for (int index = 0; index < permit.RecordCountUsed; index++)
{
var allowed = permit.IsRecordPermitted(index);

View File

@ -9,7 +9,7 @@ namespace PKHeX.Core;
/// </summary>
public static class EntitySuggestionUtil
{
public static List<string> GetMetLocationSuggestionMessage(PKM pk, int level, ushort location, int minimumLevel, IEncounterable? enc)
public static List<string> GetMetLocationSuggestionMessage(PKM pk, byte level, ushort location, int minimumLevel, IEncounterable? enc)
{
var suggestion = new List<string> { MsgPKMSuggestionStart };
if (pk.Format >= 3)

View File

@ -13,17 +13,8 @@ public static class GameInfo
public static readonly IReadOnlyList<string> GenderSymbolUnicode = ["♂", "♀", "-"];
public static readonly IReadOnlyList<string> GenderSymbolASCII = ["M", "F", "-"];
private static GameStrings _strings = GetStrings(CurrentLanguage);
public static GameStrings GetStrings(string lang)
{
int index = GameLanguage.GetLanguageIndex(lang);
return GetStrings(index);
}
public static GameStrings GetStrings(int index)
{
return Languages[index] ??= new GameStrings(GameLanguage.LanguageCode(index));
}
public static GameDataSource Sources { get; private set; } = new(_strings);
public static FilteredGameDataSource FilteredSources { get; set; } = new(FakeSaveFile.Default, Sources);
public static GameStrings Strings
{
@ -31,8 +22,11 @@ public static GameStrings Strings
set => Sources = new GameDataSource(_strings = value);
}
public static GameDataSource Sources { get; private set; } = new(_strings);
public static FilteredGameDataSource FilteredSources { get; set; } = new(FakeSaveFile.Default, Sources);
public static GameStrings GetStrings(string lang)
{
int index = GameLanguage.GetLanguageIndex(lang);
return Languages[index] ??= new GameStrings(lang);
}
public static string GetVersionName(GameVersion version)
{

View File

@ -9,7 +9,10 @@ namespace PKHeX.Core;
public static class GameLanguage
{
public const string DefaultLanguage = "en"; // English
public static int DefaultLanguageIndex => Array.IndexOf(LanguageCodes, DefaultLanguage);
public const int DefaultLanguageIndex = 1;
private static readonly string[] LanguageCodes = ["ja", "en", "fr", "it", "de", "es", "ko", "zh-Hans", "zh-Hant"];
public static string LanguageCode(int lang) => (uint)lang >= LanguageCodes.Length ? DefaultLanguage : LanguageCodes[lang];
public static int LanguageCount => LanguageCodes.Length;
@ -24,6 +27,20 @@ public static int GetLanguageIndex(string lang)
return l < 0 ? DefaultLanguageIndex : l;
}
public static LanguageID GetLanguage(string lang) => lang switch
{
"ja" => LanguageID.Japanese,
"en" => LanguageID.English,
"fr" => LanguageID.French,
"it" => LanguageID.Italian,
"de" => LanguageID.German,
"es" => LanguageID.Spanish,
"ko" => LanguageID.Korean,
"zh-Hans" => LanguageID.ChineseS,
"zh-Hant" => LanguageID.ChineseT,
_ => LanguageID.English,
};
/// <summary>
/// Checks whether the language code is supported.
/// </summary>
@ -37,28 +54,6 @@ public static int GetLanguageIndex(string lang)
/// <see cref="ProgramLanguage"/>
public static ReadOnlySpan<string> AllSupportedLanguages => LanguageCodes;
private static readonly string[] LanguageCodes = ["ja", "en", "fr", "it", "de", "es", "ko", "zh-Hans", "zh-Hant"];
/// <summary>
/// Pokétransporter location names, ordered per index of <see cref="LanguageCodes"/>
/// </summary>
private static readonly string[] ptransp = ["ポケシフター", "Poké Transfer", "Poké Fret", "Pokétrasporto", "Poképorter", "Pokétransfer", "포케시프터", "宝可传送", "寶可傳送"];
/// <summary>
/// Gets the Met Location display name for the Pokétransporter.
/// </summary>
/// <param name="language">Language Index from <see cref="LanguageCodes"/></param>
public static string GetTransporterName(int language)
{
if ((uint)language >= ptransp.Length)
language = 2;
return ptransp[language];
}
/// <inheritdoc cref="GetTransporterName(int)"/>
/// <param name="lang">Language name from <see cref="LanguageCodes"/></param>
public static string GetTransporterName(string lang) => GetTransporterName(GetLanguageIndex(lang));
/// <summary>
/// Gets a list of strings for the specified language and file type.
/// </summary>

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using static PKHeX.Core.LanguageID;
namespace PKHeX.Core;
@ -26,9 +27,9 @@ public sealed class GameStrings : IBasicStrings
public readonly string[] wallpapernames, puffs, walkercourses;
public readonly string[] uggoods, ugspheres, ugtraps, ugtreasures;
public readonly string[] seals, accessories, backdrops, poketchapps;
private readonly string lang;
private readonly int LanguageIndex;
private readonly string LanguageFilePrefix;
public LanguageID Language { get; }
public string EggName { get; }
public IReadOnlyList<string> Species => specieslist;
public IReadOnlyList<string> Item => itemlist;
@ -37,7 +38,7 @@ public sealed class GameStrings : IBasicStrings
public IReadOnlyList<string> Types => types;
public IReadOnlyList<string> Natures => natures;
private string[] Get(string ident) => GameLanguage.GetStrings(ident, lang);
private string[] Get(string ident) => GameLanguage.GetStrings(ident, LanguageFilePrefix);
private const string NPC = "NPC";
private const string EmptyIndex = "---";
@ -53,10 +54,10 @@ public sealed class GameStrings : IBasicStrings
1712, 1713, 1746, 1747, 1748, 1749, 1750, 1771,
];
internal GameStrings(string l)
internal GameStrings(string langFilePrefix)
{
lang = l;
LanguageIndex = GameLanguage.GetLanguageIndex(l);
Language = GameLanguage.GetLanguage(LanguageFilePrefix = langFilePrefix);
ribbons = Get("ribbons");
// Past Generation strings
@ -75,7 +76,7 @@ internal GameStrings(string l)
AppendLocationIndex(CXD.Met0.AsSpan(0, 227));
// Current Generation strings
natures = Util.GetNaturesList(l);
natures = Util.GetNaturesList(langFilePrefix);
types = Get("types");
abilitylist = Get("abilities");
@ -275,13 +276,13 @@ private void SanitizeItemNames()
SanitizeItemsLA(itemlist);
SanitizeItemsSV(itemlist);
if (lang is "fr")
if (Language is LanguageID.French)
{
itemlist[1681] += " (LA)"; // Galet Noir dup with 617 (Dark Stone | Black Tumblestone)
itemlist[1262] += " (G8)"; // Nouilles dup with 1934 (Instant Noodles | Rice)
itemlist[1263] += " (G8)"; // Steak Haché dup with 1925 (Precooked Burger | Herbed Sausage)
}
else if (lang is "ja")
else if (Language is LanguageID.Japanese)
{
itemlist[1693] += " (LA)"; // むしよけスプレー dup with 79 (Repel)
itemlist[1716] += " (LA)"; // ビビリだま dup with 847 (Adrenaline Orb | Scatter Bang)
@ -390,7 +391,7 @@ private void SanitizeMetLocations()
SanitizeMetGen8b(Gen8b);
SanitizeMetGen9(Gen9);
if (lang is "es" or "it")
if (Language is Italian or Spanish)
{
// Campeonato Mundial duplicates
for (int i = 28; i < 35; i++)
@ -402,7 +403,7 @@ private void SanitizeMetLocations()
Gen7b.Met4[27] += " (-)";
}
if (lang == "ko")
if (Language is Korean)
{
// Pokémon Ranger duplicate (should be Ranger Union)
Gen5.Met4[71] += " (-)";
@ -444,7 +445,7 @@ private void SanitizeMetGen5(LocationSet6 set)
set.Met4[i] += $" ({i - 97})";
// Localize the Poketransfer to the language (30001)
set.Met3[1] = GameLanguage.GetTransporterName(LanguageIndex);
set.Met3[1] = GetTransporterName(Language);
set.Met3[2] += $" ({NPC})"; // Anything from an NPC
set.Met3[3] += $" ({EggName})"; // Link Trade (Egg)
@ -600,7 +601,7 @@ private void SanitizeMetGen8a(LocationSet6 set)
for (int i = 55; i <= 60; i++) // distinguish second set of YYYY Event from the first
set.Met4[i] += " (-)";
if (lang is "en" or "es" or "de" or "it" or "fr")
if (Language is English or Spanish or German or Italian or French)
{
// Final four locations are not nouns, rather the same location reference (at the...) as prior entries.
set.Met0[152] += " (152)"; // Galaxy Hall
@ -756,7 +757,7 @@ private string[] GetItemStrings9()
// in Generation 9, TM #'s are padded to 3 digits; format them appropriately here
var clone = (string[])itemlist.Clone();
var span = clone.AsSpan();
var zero = lang is "ja" or "zh-Hans" or "zh-Hant" ? "" : "0";
var zero = Language is Japanese or ChineseS or ChineseT ? "" : "0";
InsertZero(span[328..420], zero); // 01-92
InsertZero(span[618..621], zero); // 93-95
InsertZero(span[690..694], zero); // 96-99
@ -866,4 +867,21 @@ public ReadOnlySpan<string> GetLocationNames(byte generation, GameVersion versio
return [];
return set.GetLocationNames(bankID);
}
/// <summary>
/// Gets the Met Location display name for the Pokétransporter.
/// </summary>
public static string GetTransporterName(LanguageID language) => language switch
{
Japanese => "ポケシフター", // ja
French => "Poké Fret", // fr
Italian => "Pokétrasporto", // it
German => "Poképorter", // de
Spanish => "Pokétransfer", // es
Korean => "포케시프터", // ko
ChineseS => "宝可传送", // zh-Hans
ChineseT => "寶可傳送", // zh-Hant
_ => "Poké Transfer", // en
};
}

View File

@ -22,7 +22,7 @@ internal static class Encounters3Colo
internal static readonly EncounterGift3Colo[] Gifts =
[
// In-Game without Bonus Disk
new(311, 13, TrainerNameDuking, GameVersion.CXD) { Location = 254, TID16 = 37149, OriginalTrainerGender = 0, Moves = new(045, 086, 098, 270) }, // Plusle @ Ingame Trade
new(311, 13, TrainerNameDuking, GameVersion.CXD) { Location = 254, TID16 = 37149, OriginalTrainerGender = 0, Moves = new(045, 086, 098, 270) }, // Plusle @ In-game Trade
];
internal static readonly EncounterShadow3Colo[] Shadow =

View File

@ -107,7 +107,7 @@ private void SetPINGA(PB7 pk, EncounterCriteria criteria)
}
}
private void SetEncounterMoves(PB7 pk, int level)
private void SetEncounterMoves(PB7 pk, byte level)
{
Span<ushort> moves = stackalloc ushort[4];
var source = LearnSource7GG.Instance;

View File

@ -196,14 +196,14 @@ private void SetPINGA(PKM pk, EncounterCriteria criteria)
}
}
private void SetEncounterMoves(PKM pk, int level)
private void SetEncounterMoves(PKM pk, byte level)
{
Span<ushort> moves = stackalloc ushort[4];
GetInitialMoves(level, moves);
pk.SetMoves(moves);
}
public void GetInitialMoves(int level, Span<ushort> moves)
public void GetInitialMoves(byte level, Span<ushort> moves)
{
var source = GameData.GetLearnSource(OriginGroup);
source.SetEncounterMoves(Species, Form, level, moves);

View File

@ -174,7 +174,7 @@ public bool IsMatchExact(PKM pk, EvoCriteria evo)
return true;
}
private bool IsMatchLevel(PKM pk, int lvl)
private bool IsMatchLevel(PKM pk, byte lvl)
{
if (pk is not PK1 || CanObtainMinGSC())
return lvl >= LevelMinGSC;

View File

@ -118,9 +118,9 @@ private void SetPINGA(PK6 pk, EncounterCriteria criteria, PersonalInfo6AO pi)
#region Matching
private const int FluteBoostMin = 4; // White Flute decreases levels.
private const int FluteBoostMax = 4; // Black Flute increases levels.
private const int DexNavBoost = 29 + FluteBoostMax; // Maximum DexNav chain (95) and Flute.
private const byte FluteBoostMin = 4; // White Flute decreases levels.
private const byte FluteBoostMax = 4; // Black Flute increases levels.
private const byte DexNavBoost = 29 + FluteBoostMax; // Maximum DexNav chain (95) and Flute.
public byte GetDownleveledMin() => (byte)(LevelMin - FluteBoostMin);

View File

@ -117,7 +117,7 @@ private OverworldParam8a GetParams(PersonalInfo8LA pi) => new()
_ => 0,
});
private void SetEncounterMoves(PA8 pk, int level)
private void SetEncounterMoves(PA8 pk, byte level)
{
Span<ushort> moves = stackalloc ushort[4];
var (learn, mastery) = GetLevelUpInfo();
@ -128,7 +128,7 @@ private void SetEncounterMoves(PA8 pk, int level)
pk.SetMasteryFlagMove(pk.AlphaMove);
}
public void LoadInitialMoveset(PA8 pa8, Span<ushort> moves, Learnset learn, int level)
public void LoadInitialMoveset(PA8 pa8, Span<ushort> moves, Learnset learn, byte level)
{
if (pa8.AlphaMove != 0)
{

View File

@ -127,7 +127,7 @@ public void GenerateSeed64(PKM pk, ulong seed)
Finalize(pa8, slotSeed);
}
private void SetEncounterMoves(PA8 pk, int level)
private void SetEncounterMoves(PA8 pk, byte level)
{
Span<ushort> moves = stackalloc ushort[4];
var (learn, mastery) = GetLevelUpInfo();
@ -140,7 +140,7 @@ private void SetEncounterMoves(PA8 pk, int level)
public (Learnset Learn, Learnset Mastery) GetLevelUpInfo() => LearnSource8LA.GetLearnsetAndMastery(Species, Form);
public void LoadInitialMoveset(PA8 pa8, Span<ushort> moves, Learnset learn, int level)
public void LoadInitialMoveset(PA8 pa8, Span<ushort> moves, Learnset learn, byte level)
{
if (Moves.HasMoves)
Moves.CopyTo(moves);

View File

@ -8,7 +8,7 @@ namespace PKHeX.Core;
public interface IMasteryInitialMoveShop8
{
(Learnset Learn, Learnset Mastery) GetLevelUpInfo();
void LoadInitialMoveset(PA8 pa8, Span<ushort> moves, Learnset learn, int level);
void LoadInitialMoveset(PA8 pa8, Span<ushort> moves, Learnset learn, byte level);
bool IsForcedMasteryCorrect(PKM pk);
void SetInitialMastery(PKM pk)
{

View File

@ -27,12 +27,12 @@ public static class LevelRangeExtensions
/// <param name="r">Range reference</param>
/// <param name="lvl">Single level</param>
/// <returns>True if within slot's range, false if impossible.</returns>
public static bool IsLevelWithinRange(this ILevelRange r, int lvl) => r.LevelMin <= lvl && lvl <= r.LevelMax;
public static bool IsLevelWithinRange(this ILevelRange r, byte lvl) => r.LevelMin <= lvl && lvl <= r.LevelMax;
/// <inheritdoc cref="IsLevelWithinRange(ILevelRange,int)"/>
public static bool IsLevelWithinRange(int level, int min, int max) => min <= level && level <= max;
/// <inheritdoc cref="IsLevelWithinRange(ILevelRange,byte)"/>
public static bool IsLevelWithinRange(byte level, byte min, byte max) => min <= level && level <= max;
/// <inheritdoc cref="IsLevelWithinRange(ILevelRange,int)"/>
/// <inheritdoc cref="IsLevelWithinRange(ILevelRange,byte)"/>
public static bool IsLevelWithinRange<T>(this ILevelRange r, T other) where T : ILevelRange => IsLevelWithinRange(r, other.LevelMin, other.LevelMax);
/// <summary>
@ -52,7 +52,7 @@ public static class LevelRangeExtensions
/// <param name="minDecrease">Highest value the low end of levels can be</param>
/// <param name="maxIncrease">Lowest value the high end of levels can be</param>
/// <returns>True if within slot's range, false if impossible.</returns>
public static bool IsLevelWithinRange(this ILevelRange r, int lvl, int minDecrease, int maxIncrease) => r.LevelMin - minDecrease <= lvl && lvl <= r.LevelMax + maxIncrease;
public static bool IsLevelWithinRange(this ILevelRange r, byte lvl, byte minDecrease, byte maxIncrease) => r.LevelMin - minDecrease <= lvl && lvl <= r.LevelMax + maxIncrease;
/// <summary>
/// Gets if the specified level inputs are within range of the <see cref="ILevelRange.LevelMin"/> and <see cref="ILevelRange.LevelMax"/>
@ -63,5 +63,5 @@ public static class LevelRangeExtensions
/// <param name="minDecrease">Highest value the low end of levels can be</param>
/// <param name="maxIncrease">Lowest value the high end of levels can be</param>
/// <returns>True if within slot's range, false if impossible.</returns>
public static bool IsLevelWithinRange(this ILevelRange r, byte min, byte max, int minDecrease, int maxIncrease) => r.LevelMin - minDecrease <= max && min <= r.LevelMax + maxIncrease;
public static bool IsLevelWithinRange(this ILevelRange r, byte min, byte max, int minDecrease, byte maxIncrease) => r.LevelMin - minDecrease <= max && min <= r.LevelMax + maxIncrease;
}

View File

@ -97,7 +97,7 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
}
}
public void SetEncounterMoves(ushort species, byte form, int level, Span<ushort> init)
public void SetEncounterMoves(ushort species, byte form, byte level, Span<ushort> init)
{
if (!TryGetPersonal(species, 0, out var personal))
return;

View File

@ -97,7 +97,7 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
}
}
public void SetEncounterMoves(ushort species, byte form, int level, Span<ushort> init)
public void SetEncounterMoves(ushort species, byte form, byte level, Span<ushort> init)
{
if (!TryGetPersonal(species, 0, out var personal))
return;

View File

@ -24,7 +24,7 @@ public interface ILearnSource
/// <param name="form">Entity form</param>
public Learnset GetLearnset(ushort species, byte form);
public void SetEncounterMoves(ushort species, byte form, int level, Span<ushort> init)
public void SetEncounterMoves(ushort species, byte form, byte level, Span<ushort> init)
{
var start = (init.LastIndexOfAnyExcept<ushort>(0) + 1) & 3;
var learn = GetLearnset(species, form);

View File

@ -21,7 +21,7 @@ public sealed class Learnset(ushort[] Moves, byte[] Levels)
public ReadOnlySpan<ushort> GetAllMoves() => Moves;
public ReadOnlySpan<ushort> GetMoveRange(int maxLevel, int minLevel = 0)
public ReadOnlySpan<ushort> GetMoveRange(byte maxLevel, byte minLevel = 0)
{
if (minLevel <= 1 && maxLevel >= 100)
return Moves;
@ -38,7 +38,7 @@ public ReadOnlySpan<ushort> GetMoveRange(int maxLevel, int minLevel = 0)
return Moves.AsSpan(start, length);
}
private int FindGrq(int level, int start = 0)
private int FindGrq(byte level, int start = 0)
{
var levels = Levels;
for (int i = start; i < levels.Length; i++)
@ -49,7 +49,7 @@ private int FindGrq(int level, int start = 0)
return -1;
}
private int FindGr(int level, int start)
private int FindGr(byte level, int start)
{
var levels = Levels;
for (int i = start; i < levels.Length; i++)
@ -60,7 +60,7 @@ private int FindGr(int level, int start)
return -1;
}
private int FindLastLeq(int level, int end = 0)
private int FindLastLeq(byte level, int end = 0)
{
var levels = Levels;
for (int i = levels.Length - 1; i >= end; i--)
@ -77,7 +77,7 @@ private int FindLastLeq(int level, int end = 0)
/// <param name="moves">Move array to write to</param>
/// <param name="ctr">Starting index to begin overwriting at</param>
/// <returns>Array of Move IDs</returns>
public void SetEncounterMoves(int level, Span<ushort> moves, int ctr = 0)
public void SetEncounterMoves(byte level, Span<ushort> moves, int ctr = 0)
{
for (int i = 0; i < Moves.Length; i++)
{
@ -115,7 +115,7 @@ private static void RectifyOrderShift(Span<ushort> moves, int ctr)
}
}
public void SetEncounterMovesBackwards(int level, Span<ushort> moves, int ctr = 0)
public void SetEncounterMovesBackwards(byte level, Span<ushort> moves, int ctr = 0)
{
int index = FindLastLeq(level);
@ -145,7 +145,7 @@ public void SetEncounterMovesBackwards(int level, Span<ushort> moves, int ctr =
}
/// <summary>Adds the learned moves by level up to the specified level.</summary>
public void SetLevelUpMoves(int startLevel, int endLevel, Span<ushort> moves, int ctr = 0)
public void SetLevelUpMoves(byte startLevel, byte endLevel, Span<ushort> moves, int ctr = 0)
{
int startIndex = FindGrq(startLevel);
if (startIndex == -1)
@ -176,7 +176,7 @@ public void SetEvolutionMoves(Span<ushort> moves, int ctr = 0)
}
/// <summary>Adds the learned moves by level up to the specified level.</summary>
public void SetLevelUpMoves(int startLevel, int endLevel, Span<ushort> moves, ReadOnlySpan<ushort> ignore, int ctr = 0)
public void SetLevelUpMoves(byte startLevel, byte endLevel, Span<ushort> moves, ReadOnlySpan<ushort> ignore, int ctr = 0)
{
int startIndex = FindGrq(startLevel);
if (startIndex == -1)

View File

@ -12,7 +12,7 @@ namespace PKHeX.Core;
/// <remarks>Refer to <see cref="EggSource2"/> for inheritance ordering.</remarks>
public static class MoveBreed2
{
private const int level = 5;
private const byte Level = EncounterEgg2.Level;
/// <inheritdoc cref="MoveBreed.Validate"/>
public static bool Validate(ushort species, GameVersion version, ReadOnlySpan<ushort> moves, Span<byte> origins)
@ -34,7 +34,7 @@ public static bool Validate(ushort species, GameVersion version, ReadOnlySpan<us
var actual = MemoryMarshal.Cast<byte, EggSource2>(origins);
Span<byte> possible = stackalloc byte[count];
var value = new BreedInfo<EggSource2>(actual, possible, learnset, moves, level);
var value = new BreedInfo<EggSource2>(actual, possible, learnset, moves, Level);
bool inherit = Breeding.GetCanInheritMoves(species);
MarkMovesForOrigin(value, eggMoves, count, inherit, pi, version);

View File

@ -13,7 +13,7 @@ namespace PKHeX.Core;
/// <remarks>Refer to <see cref="EggSource34"/> for inheritance ordering.</remarks>
public static class MoveBreed3
{
private const int level = 5;
private const byte Level = EncounterEgg3.Level;
/// <inheritdoc cref="MoveBreed.Validate"/>
public static bool Validate(ushort species, GameVersion version, ReadOnlySpan<ushort> moves, Span<byte> origins)
@ -39,7 +39,7 @@ public static bool Validate(ushort species, GameVersion version, ReadOnlySpan<us
var learnset = ls.GetLearnset(species, 0);
var actual = MemoryMarshal.Cast<byte, EggSource34>(origins);
Span<byte> possible = stackalloc byte[count];
var value = new BreedInfo<EggSource34>(actual, possible, learnset, moves, level);
var value = new BreedInfo<EggSource34>(actual, possible, learnset, moves, Level);
if (species is (int)Species.Pichu && moves[count - 1] is (int)Move.VoltTackle && version == E)
actual[--count] = VoltTackle;

View File

@ -13,7 +13,7 @@ namespace PKHeX.Core;
/// <remarks>Refer to <see cref="EggSource34"/> for inheritance ordering.</remarks>
public static class MoveBreed4
{
private const int level = 1;
private const byte Level = EncounterEgg4.Level;
/// <inheritdoc cref="MoveBreed.Validate"/>
public static bool Validate(ushort species, GameVersion version, ReadOnlySpan<ushort> moves, Span<byte> origins)
@ -40,7 +40,7 @@ public static bool Validate(ushort species, GameVersion version, ReadOnlySpan<us
var actual = MemoryMarshal.Cast<byte, EggSource34>(origins);
Span<byte> possible = stackalloc byte[count];
var value = new BreedInfo<EggSource34>(actual, possible, learnset, moves, level);
var value = new BreedInfo<EggSource34>(actual, possible, learnset, moves, Level);
if (species is (int)Species.Pichu && moves[count - 1] is (int)Move.VoltTackle)
actual[--count] = VoltTackle;

View File

@ -11,7 +11,7 @@ namespace PKHeX.Core;
/// <remarks>Refer to <see cref="EggSource5"/> for inheritance ordering.</remarks>
public static class MoveBreed5
{
private const int level = 1;
private const byte Level = EncounterEgg5.Level;
/// <inheritdoc cref="MoveBreed.Validate"/>
public static bool Validate(ushort species, GameVersion version, ReadOnlySpan<ushort> moves, Span<byte> origins)
@ -35,7 +35,7 @@ public static bool Validate(ushort species, GameVersion version, ReadOnlySpan<us
var actual = MemoryMarshal.Cast<byte, EggSource5>(origins);
Span<byte> possible = stackalloc byte[count];
var value = new BreedInfo<EggSource5>(actual, possible, learnset, moves, level);
var value = new BreedInfo<EggSource5>(actual, possible, learnset, moves, Level);
if (species is (int)Species.Pichu && moves[count - 1] is (int)Move.VoltTackle)
actual[--count] = VoltTackle;

View File

@ -11,7 +11,7 @@ namespace PKHeX.Core;
/// <remarks>Refer to <see cref="EggSource6"/> for inheritance ordering.</remarks>
public static class MoveBreed6
{
private const int level = 1;
private const byte Level = EncounterEgg6.Level;
/// <inheritdoc cref="MoveBreed.Validate"/>
public static bool Validate(byte generation, ushort species, byte form, GameVersion version, ReadOnlySpan<ushort> moves, Span<byte> origins)
@ -27,7 +27,7 @@ public static bool Validate(byte generation, ushort species, byte form, GameVers
var actual = MemoryMarshal.Cast<byte, EggSource6>(origins);
Span<byte> possible = stackalloc byte[count];
var value = new BreedInfo<EggSource6>(actual, possible, learnset, moves, level);
var value = new BreedInfo<EggSource6>(actual, possible, learnset, moves, Level);
if (species is (int)Species.Pichu && moves[count - 1] is (int)Move.VoltTackle)
actual[--count] = VoltTackle;

View File

@ -606,7 +606,7 @@ private static bool IsOriginalLevelValid(byte min, byte max, byte format, uint l
{
if (format == Format && min > 1)
return level == min; // Met Level matches
return LevelRangeExtensions.IsLevelWithinRange((int)level, min, max);
return LevelRangeExtensions.IsLevelWithinRange((byte)level, min, max);
}
public static uint GetRandomLevel<T>(T enc, uint u16LevelRand, LeadRequired lead) where T : ILevelRange => lead switch

View File

@ -474,7 +474,7 @@ private static bool IsOriginalLevelValid(byte min, byte max, byte format, uint l
{
if (format == Format && min > 1)
return level == min; // Met Level matches
return LevelRangeExtensions.IsLevelWithinRange((int)level, min, max);
return LevelRangeExtensions.IsLevelWithinRange((byte)level, min, max);
}
public static uint GetRandomLevel<T>(T enc, uint seed, LeadRequired lead) where T : IEncounterSlot4

View File

@ -501,7 +501,7 @@ private static bool IsOriginalLevelValid(byte min, byte max, byte format, uint l
{
if (format == Format && min > 1)
return level == min; // Met Level matches
return LevelRangeExtensions.IsLevelWithinRange((int)level, min, max);
return LevelRangeExtensions.IsLevelWithinRange((byte)level, min, max);
}
public static uint GetRandomLevel<T>(T enc, uint seed, LeadRequired lead) where T : IEncounterSlot4

View File

@ -138,7 +138,7 @@ private static void LoadPurchasedMoves(PA8 pa, Span<ushort> result)
}
}
private static int AddMasteredMissing(PA8 pa, Span<ushort> current, int ctr, Learnset baseLearn, Learnset currentLearn, int level)
private static int AddMasteredMissing(PA8 pa, Span<ushort> current, int ctr, Learnset baseLearn, Learnset currentLearn, byte level)
{
var purchased = pa.Permit.RecordPermitIndexes;
for (int i = 0; i < purchased.Length; i++)
@ -234,7 +234,7 @@ private static bool CanLearnMoveByLevelUp(LegalityAnalysis data, PA8 pa, int i,
continue; // cannot learn via level up
level = Math.Min(lvl, level);
}
return pa.CurrentLevel >= level;
return level <= pa.CurrentLevel;
}
private void VerifyAlphaMove(LegalityAnalysis data, PA8 pa, ushort alphaMove, IPermitRecord permit)

View File

@ -80,14 +80,13 @@ public void VerifyG1(LegalityAnalysis data)
var enc = data.EncounterMatch;
if (pk.IsEgg)
{
const int elvl = 5;
if (elvl != pk.CurrentLevel)
data.AddLine(GetInvalid(string.Format(LEggFMetLevel_0, elvl)));
if (pk.CurrentLevel != EncounterEgg2.Level)
data.AddLine(GetInvalid(string.Format(LEggFMetLevel_0, EncounterEgg2.Level)));
return;
}
if (pk.MetLocation != 0) // crystal
{
int lvl = pk.CurrentLevel;
var lvl = pk.CurrentLevel;
if (lvl < pk.MetLevel)
data.AddLine(GetInvalid(LLevelMetBelow));
}

View File

@ -484,7 +484,7 @@ private static void VerifyMiscFatefulEncounter(LegalityAnalysis data)
VerifyReceivability(data, g);
VerifyFatefulMysteryGift(data, g);
return;
case IFatefulEncounterReadOnly {FatefulEncounter: true}: // ingame fateful
case IFatefulEncounterReadOnly {FatefulEncounter: true}: // in-game fateful
VerifyFatefulIngameActive(data);
return;
}

View File

@ -144,7 +144,7 @@ public string OT
set => StringConverter6.SetString(OriginalTrainerTrash, value, 12, Language, StringConverterOption.ClearZero);
}
public int Level { get => Data[0x68]; set => Data[0x68] = (byte)value; }
public byte Level { get => Data[0x68]; set => Data[0x68] = value; }
public bool IsEgg { get => Data[0x69] == 1; set => Data[0x69] = value ? (byte)1 : (byte)0; }
public uint PID { get => ReadUInt32LittleEndian(Data[0x6C..]); set => WriteUInt32LittleEndian(Data[0x6C..], value); }
public ushort RelearnMove1 { get => ReadUInt16LittleEndian(Data[0x70..]); set => WriteUInt16LittleEndian(Data[0x70..], value); }

View File

@ -108,7 +108,7 @@ public static void CopyFrom(this IGameDataSide data, PKM pk)
/// <summary>
/// Resets the moves using the <see cref="source"/> for the given level.
/// </summary>
public static void ResetMoves(this IGameDataSide data, ushort species, byte form, int level, ILearnSource source, EntityContext context)
public static void ResetMoves(this IGameDataSide data, ushort species, byte form, byte level, ILearnSource source, EntityContext context)
{
var learn = source.GetLearnset(species, form);
Span<ushort> moves = stackalloc ushort[4];

View File

@ -61,7 +61,7 @@ public interface IMoveShop8Mastery : IMoveShop8
public static class MoveShop8MasteryExtensions
{
public static bool IsValidPurchasedEncounter(this IMoveShop8 shop, Learnset learn, int level, ushort alpha, bool allowPurchasedAlpha)
public static bool IsValidPurchasedEncounter(this IMoveShop8 shop, Learnset learn, byte level, ushort alpha, bool allowPurchasedAlpha)
{
var permit = shop.Permit.RecordPermitIndexes;
var current = shop.Permit;

View File

@ -512,7 +512,7 @@ public ulong Tracker
public override void LoadStats(IBaseStat p, Span<ushort> stats)
{
int level = CurrentLevel;
var level = CurrentLevel;
var nature = StatNature;
stats[0] = (ushort)(GetGanbaruStat(p.HP, HT_HP ? 31 : IV_HP, GV_HP, level) + GetStatHp(p.HP, level));
@ -523,7 +523,7 @@ public override void LoadStats(IBaseStat p, Span<ushort> stats)
stats[5] = (ushort)(GetGanbaruStat(p.SPD, HT_SPD ? 31 : IV_SPD, GV_SPD, level) + GetStat(p.SPD, level, nature, 3));
}
public static int GetGanbaruStat(int baseStat, int iv, byte gv, int level)
public static int GetGanbaruStat(int baseStat, int iv, byte gv, byte level)
{
var mul = GanbaruExtensions.GetGanbaruMultiplier(gv, iv);
double step1 = Math.Abs(Math.Sqrt(baseStat)) * mul; // The game does abs after sqrt; should be before. It's fine because baseStat is never negative.
@ -531,12 +531,12 @@ public static int GetGanbaruStat(int baseStat, int iv, byte gv, int level)
return (int)Math.Round(result, MidpointRounding.AwayFromZero);
}
public static int GetStatHp(int baseStat, int level)
public static int GetStatHp(int baseStat, byte level)
{
return (int)((((level / 100.0f) + 1.0f) * baseStat) + level);
}
public static int GetStat(int baseStat, int level, Nature nature, int statIndex)
public static int GetStat(int baseStat, byte level, Nature nature, int statIndex)
{
var initial = (int)((((level / 50.0f) + 1.0f) * baseStat) / 1.5f);
return NatureAmp.AmplifyStat(nature, statIndex, initial);

View File

@ -514,7 +514,7 @@ public void FixMemories()
public override void LoadStats(IBaseStat p, Span<ushort> stats)
{
int level = CurrentLevel;
var level = CurrentLevel;
var nature = Nature;
int friend = CurrentFriendship; // stats +10% depending on friendship!
int scalar = (int)(((friend / 255.0f / 10.0f) + 1.0f) * 100.0f);
@ -533,7 +533,7 @@ public override void LoadStats(IBaseStat p, Span<ushort> stats)
/// <param name="iv">Current IV, already accounted for Hyper Training</param>
/// <param name="level">Current Level</param>
/// <returns>Initial Stat</returns>
private static int GetStat(int baseStat, int iv, int level) => (iv + (2 * baseStat)) * level / 100;
private static int GetStat(int baseStat, int iv, byte level) => (iv + (2 * baseStat)) * level / 100;
/// <summary>
/// Gets the initial stat value with nature amplification applied. Used for all stats except HP.
@ -544,7 +544,7 @@ public override void LoadStats(IBaseStat p, Span<ushort> stats)
/// <param name="nature"><see cref="PKM.Nature"/></param>
/// <param name="statIndex">Stat amp index in the nature amp table</param>
/// <returns>Initial Stat with nature amplification applied.</returns>
private static int GetStat(int baseStat, int iv, int level, Nature nature, int statIndex)
private static int GetStat(int baseStat, int iv, byte level, Nature nature, int statIndex)
{
int initial = GetStat(baseStat, iv, level) + 5;
return NatureAmp.AmplifyStat(nature, statIndex, initial);
@ -557,7 +557,7 @@ public int BaseCP
get
{
var p = PersonalInfo;
int level = CurrentLevel;
var level = CurrentLevel;
var nature = Nature;
int scalar = CPScalar;

View File

@ -703,7 +703,7 @@ public ushort[] GetStats(IBaseStat p)
public virtual void LoadStats(IBaseStat p, Span<ushort> stats)
{
int level = CurrentLevel; // recalculate instead of checking Stat_Level
var level = CurrentLevel; // recalculate instead of checking Stat_Level
if (this is IHyperTrain t)
LoadStats(stats, p, t, level);
else
@ -713,7 +713,7 @@ public virtual void LoadStats(IBaseStat p, Span<ushort> stats)
NatureAmp.ModifyStatsForNature(stats, StatNature);
}
private void LoadStats(Span<ushort> stats, IBaseStat p, IHyperTrain t, int level)
private void LoadStats(Span<ushort> stats, IBaseStat p, IHyperTrain t, byte level)
{
stats[0] = (ushort)(p.HP == 1 ? 1 : (((t.HT_HP ? 31 : IV_HP) + (2 * p.HP) + (EV_HP / 4) + 100) * level / 100) + 10);
stats[1] = (ushort)((((t.HT_ATK ? 31 : IV_ATK) + (2 * p.ATK) + (EV_ATK / 4)) * level / 100) + 5);
@ -723,7 +723,7 @@ private void LoadStats(Span<ushort> stats, IBaseStat p, IHyperTrain t, int level
stats[3] = (ushort)((((t.HT_SPE ? 31 : IV_SPE) + (2 * p.SPE) + (EV_SPE / 4)) * level / 100) + 5);
}
private void LoadStats(Span<ushort> stats, IBaseStat p, int level)
private void LoadStats(Span<ushort> stats, IBaseStat p, byte level)
{
stats[0] = (ushort)(p.HP == 1 ? 1 : ((IV_HP + (2 * p.HP) + (EV_HP / 4) + 100) * level / 100) + 10);
stats[1] = (ushort)(((IV_ATK + (2 * p.ATK) + (EV_ATK / 4)) * level / 100) + 5);

View File

@ -27,7 +27,7 @@ public sealed class SearchSettings
public bool? SearchLegal { get; set; }
public bool? SearchEgg { get; set; }
public int? ESV { get; set; }
public int? Level { get; init; }
public byte? Level { get; init; }
public int IVType { get; init; }
public int EVType { get; init; }

View File

@ -27,7 +27,7 @@ public static class SearchUtil
_ => pk.Generation == generation,
};
public static bool SatisfiesFilterLevel(PKM pk, SearchComparison option, int level) => option switch
public static bool SatisfiesFilterLevel(PKM pk, SearchComparison option, byte level) => option switch
{
SearchComparison.LessThanEquals => pk.Stat_Level <= level,
SearchComparison.Equals => pk.Stat_Level == level,

View File

@ -237,7 +237,7 @@ public override void LoadStats(IBaseStat p, Span<ushort> stats)
stats[5] = GetStat(p.SPD, IV_SPD, EV_SPD, lv);
}
protected static ushort GetStat(int baseStat, int iv, int effort, int level)
protected static ushort GetStat(int baseStat, int iv, int effort, byte level)
{
// The games store a precomputed ushort[256] i^2 table for all ushort->byte square root calculations.
// The game then iterates to find the lowest index with a value >= input (effort).

View File

@ -914,7 +914,7 @@ private void UpdateEXPLevel(object sender, EventArgs e)
var expInput = Util.ToUInt32(TB_EXP.Text);
var expCalc = expInput;
var gr = Entity.PersonalInfo.EXPGrowth;
int lvlExp = Experience.GetLevel(expInput, gr);
var lvlExp = Experience.GetLevel(expInput, gr);
if (lvlExp == 100)
expCalc = Experience.GetEXP(100, gr);

View File

@ -564,7 +564,7 @@ private SearchSettings GetSearchSettings()
BatchInstructions = RTB_Instructions.Text,
Level = int.TryParse(TB_Level.Text, out var lvl) ? lvl : null,
Level = byte.TryParse(TB_Level.Text, out var lvl) ? lvl : null,
SearchLevel = (SearchComparison)CB_Level.SelectedIndex,
EVType = CB_EVTrain.SelectedIndex,
IVType = CB_IV.SelectedIndex,

View File

@ -468,16 +468,17 @@ private void HexTextBox_TextChanged(object sender, EventArgs e)
}
if (sender == TB_UsedFlags)
{
f[entry].UsedFlags = Convert.ToUInt32(t, 16);
f[entry].UsedFlags = Util.GetHexValue(t);
}
else if (sender == TB_UsedStats)
{
f[entry].UsedRandStat = Convert.ToUInt32(t, 16);
f[entry].UsedRandStat = Util.GetHexValue(t);
}
else if (sender == TB_FacilityID)
{
var updated = Util.GetBytesFromHexString(t.PadLeft(24, '0'));
updated.CopyTo(f[entry].TrainerFesID);
var dest = f[entry].TrainerFesID;
dest.Clear();
Util.GetBytesFromHexString(t, dest);
}
}

View File

@ -367,7 +367,7 @@ private static void SaveBackup(string path)
/// Opens a dialog to save a <see cref="SaveFile"/> file.
/// </summary>
/// <param name="sav"><see cref="SaveFile"/> to be saved.</param>
/// <param name="currentBox">Box the player will be greeted with when accessing the PC ingame.</param>
/// <param name="currentBox">Box the player will be greeted with when accessing the PC in-game.</param>
/// <returns>True if the file was saved.</returns>
public static bool ExportSAVDialog(SaveFile sav, int currentBox = 0)
{
@ -406,16 +406,10 @@ private static void ExportSAV(SaveFile sav, string path)
}
catch (Exception x)
{
switch (x)
{
case UnauthorizedAccessException:
case FileNotFoundException:
case IOException:
Error(MsgFileWriteFail + Environment.NewLine + x.Message, MsgFileWriteProtectedAdvice);
break;
default:
throw;
}
if (x is UnauthorizedAccessException or FileNotFoundException or IOException)
Error(MsgFileWriteFail + Environment.NewLine + x.Message, MsgFileWriteProtectedAdvice);
else // Don't know what threw, but it wasn't I/O related.
throw;
}
}

View File

@ -59,8 +59,8 @@ public void CalcStatsGBPidgeot()
ushort effort = 63001;
effort = (ushort)(Math.Min((ushort)255, (ushort)Math.Ceiling(Math.Sqrt(effort))) >> 2);
const byte level = 100;
const int iv = 15;
const int level = 100;
const int baseStat = 91;
var expect = (ushort)((((2 * (baseStat + iv)) + effort) * level / 100) + 5);
expect.Should().Be(279);
@ -81,7 +81,7 @@ public class BelugaTests
{
[Theory]
[InlineData(41, 25, 91)]
public void CalculateCP(int level, int statSum, int expect)
public void CalculateCP(byte level, int statSum, int expect)
{
var result1 = (((level * 4.0f / 100.0f) + 2.0f) * (statSum & 0xFFFF));
var result2 = (int)result1;