mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-04-24 15:47:15 -05:00
Refactor out legality settings, add more settings
Extract PP verifier Add disabling of wordfilter for formats < 6 Add context-specific bypasses for nickname/handler checks
This commit is contained in:
parent
94f93d41c5
commit
bb6e45db60
|
|
@ -667,7 +667,7 @@ private void ParseSpeciesNickname(ReadOnlySpan<char> line)
|
|||
{
|
||||
nickname = line[..index].TrimEnd();
|
||||
species = line[(index + 1)..];
|
||||
if (species.Length > 0 && species[^1] == ')')
|
||||
if (species.Length != 0 && species[^1] == ')')
|
||||
species = species[..^1];
|
||||
}
|
||||
else // parenthesis value before: (Species) Nickname, incorrect
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ public sealed class BulkAnalysis
|
|||
public readonly Dictionary<ulong, SlotCache> Trackers = [];
|
||||
public readonly bool Valid;
|
||||
|
||||
public readonly IBulkAnalysisSettings Settings;
|
||||
public readonly BulkAnalysisSettings Settings;
|
||||
private readonly bool[] CloneFlags;
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -28,7 +28,7 @@ public sealed class BulkAnalysis
|
|||
/// </summary>
|
||||
public bool SetIsClone(int entryIndex, bool value = true) => CloneFlags[entryIndex] = value;
|
||||
|
||||
public BulkAnalysis(SaveFile sav, IBulkAnalysisSettings settings)
|
||||
public BulkAnalysis(SaveFile sav, BulkAnalysisSettings settings)
|
||||
{
|
||||
Trainer = sav;
|
||||
Settings = settings;
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ internal static class Encounters8Nest
|
|||
internal static bool IsInaccessibleRank12Nest(byte nestID, byte location)
|
||||
{
|
||||
var noNest = GetInaccessibleRank12Nests(location);
|
||||
return noNest.Length > 0 && noNest.Contains(nestID);
|
||||
return noNest.Length != 0 && noNest.Contains(nestID);
|
||||
}
|
||||
|
||||
private static ReadOnlySpan<byte> GetInaccessibleRank12Nests(byte location) => location switch
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ public static void FindVerifiedEncounter(PKM pk, LegalInfo info)
|
|||
|
||||
// Looks like we might have a good enough match. Check if this is really a good match.
|
||||
info.EncounterMatch = enc;
|
||||
if (e.Comment.Length > 0)
|
||||
if (e.Comment.Length != 0)
|
||||
info.Parse.Add(e);
|
||||
if (!VerifySecondaryChecks(pk, info, encounter))
|
||||
continue;
|
||||
|
|
@ -71,7 +71,7 @@ public static void FindVerifiedEncounter(PKM pk, LegalInfo info)
|
|||
if (manual != EncounterYieldFlag.None)
|
||||
{
|
||||
if (!info.FrameMatches) // if false, all valid RNG frame matches have already been consumed
|
||||
info.Parse.Add(new CheckResult(info.Generation == 3 ? ParseSettings.RNGFrameNotFound3 : ParseSettings.RNGFrameNotFound4, CheckIdentifier.PID, LEncConditionBadRNGFrame));
|
||||
info.Parse.Add(new CheckResult(ParseSettings.Settings.FramePattern.GetSeverity(info.Generation), CheckIdentifier.PID, LEncConditionBadRNGFrame));
|
||||
else if (!info.PIDIVMatches) // if false, all valid PIDIV matches have already been consumed
|
||||
info.Parse.Add(new CheckResult(Severity.Invalid, CheckIdentifier.PID, LPIDTypeMismatch));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ public static IEnumerable<IEncounterable> GenerateEncounters(PKM pk, ReadOnlyMem
|
|||
if (!IsSane(pk, moves.Span))
|
||||
yield break;
|
||||
|
||||
if (versions.Length > 0)
|
||||
if (versions.Length != 0)
|
||||
{
|
||||
foreach (var enc in GenerateEncounters(pk, moves, (IReadOnlyList<GameVersion>)versions))
|
||||
yield return enc;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ public sealed record EncounterTrade3XD : IEncounterable, IEncounterMatch, IEncou
|
|||
public bool FatefulEncounter => true;
|
||||
|
||||
public bool IsFixedTrainer => true;
|
||||
public bool IsFixedNickname => Nicknames.Length > 0;
|
||||
public bool IsFixedNickname => Nicknames.Length != 0;
|
||||
public ushort Species { get; }
|
||||
public byte Level { get; }
|
||||
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ public bool IsMatchExact(PKM pk, EvoCriteria evo)
|
|||
// Must match level exactly.
|
||||
if (!this.IsLevelWithinRange(pk.MetLevel))
|
||||
{
|
||||
if ((Type is not Grass || pk.MetLevel != PressureLevel) || ParseSettings.RNGFrameNotFound4 != Severity.Invalid)
|
||||
if ((Type is not Grass || pk.MetLevel != PressureLevel) || ParseSettings.Settings.FramePattern.RNGFrameNotFound4 != Severity.Invalid)
|
||||
return false; // Only allow Pressure Slots through if they'll be checked by the later Lead verification.
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ public PK6 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
|||
if (CanDexNav)
|
||||
{
|
||||
var eggMoves = GetDexNavMoves();
|
||||
if (eggMoves.Length > 0)
|
||||
if (eggMoves.Length != 0)
|
||||
pk.RelearnMove1 = eggMoves[Util.Rand.Next(eggMoves.Length)];
|
||||
}
|
||||
pk.SetRandomMemory6();
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ public sealed record EncounterTrade9
|
|||
public bool IsShiny => false;
|
||||
public ushort EggLocation => 0;
|
||||
public bool IsFixedTrainer => true;
|
||||
public bool IsFixedNickname => Nicknames.Length > 0;
|
||||
public bool IsFixedNickname => Nicknames.Length != 0;
|
||||
public GameVersion Version { get; }
|
||||
|
||||
private string[] TrainerNames { get; }
|
||||
|
|
|
|||
|
|
@ -191,6 +191,7 @@ private void ParsePK1()
|
|||
Level.VerifyG1(this);
|
||||
Trainer.VerifyOTGB(this);
|
||||
MiscValues.VerifyMiscG1(this);
|
||||
MovePP.Verify(this);
|
||||
if (Entity.Format == 2)
|
||||
Item.Verify(this);
|
||||
}
|
||||
|
|
@ -298,6 +299,7 @@ private void UpdateChecks()
|
|||
BallIndex.Verify(this);
|
||||
FormValues.Verify(this);
|
||||
MiscValues.Verify(this);
|
||||
MovePP.Verify(this);
|
||||
GenderValues.Verify(this);
|
||||
Item.Verify(this);
|
||||
Contest.Verify(this);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ internal static class LegalityAnalyzers
|
|||
public static readonly HistoryVerifier History = new();
|
||||
public static readonly ContestStatVerifier Contest = new();
|
||||
public static readonly MarkingVerifier Marking = new();
|
||||
public static readonly MovePPVerifier MovePP = new();
|
||||
|
||||
public static readonly TrainerNameVerifier Trainer = new();
|
||||
public static readonly TrainerIDVerifier TrainerID = new();
|
||||
|
|
|
|||
19
PKHeX.Core/Legality/Settings/LegalitySettings.cs
Normal file
19
PKHeX.Core/Legality/Settings/LegalitySettings.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
using System.ComponentModel;
|
||||
|
||||
namespace PKHeX.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Settings object to contain all parameters that can be configured for legality checks.
|
||||
/// </summary>
|
||||
[TypeConverter(typeof(ExpandableObjectConverter))]
|
||||
public sealed class LegalitySettings
|
||||
{
|
||||
public BulkAnalysisSettings Bulk { get; set; } = new();
|
||||
public FramePatternSettings FramePattern { get; set; } = new();
|
||||
public GameSpecificSettings Game { get; set; } = new();
|
||||
public HandlerSettings Handler { get; set; } = new();
|
||||
public HOMETransferSettings HOMETransfer { get; set; } = new();
|
||||
public NicknameSettings Nickname { get; set; } = new();
|
||||
public TradebackSettings Tradeback { get; set; } = new();
|
||||
public WordFilterSettings WordFilter { get; set; } = new();
|
||||
}
|
||||
86
PKHeX.Core/Legality/Settings/ParseSettings.cs
Normal file
86
PKHeX.Core/Legality/Settings/ParseSettings.cs
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace PKHeX.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Settings for Parsing Legality
|
||||
/// </summary>
|
||||
/// <remarks><see cref="LegalityAnalysis"/></remarks>
|
||||
public static class ParseSettings
|
||||
{
|
||||
internal static ITrainerInfo ActiveTrainer { get; set; } = new SimpleTrainerInfo(GameVersion.Any) { OT = string.Empty, Language = -1 };
|
||||
|
||||
/// <summary>
|
||||
/// Master settings configuration for legality analysis.
|
||||
/// </summary>
|
||||
/// <remarks>Allows configuring severities away from the default settings for users who want to deviate.</remarks>
|
||||
public static LegalitySettings Settings { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Setting to specify if an analysis should permit data sourced from the physical cartridge era of Game Boy games.
|
||||
/// </summary>
|
||||
/// <remarks>If false, indicates to use Virtual Console rules (which are transferable to Gen7+)</remarks>
|
||||
public static bool AllowGBCartEra { private get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Setting to specify if an analysis should permit trading a Generation 1 origin file to Generation 2, then back. Useful for checking RBY Metagame rules.
|
||||
/// </summary>
|
||||
public static bool AllowGen1Tradeback => Settings.Tradeback.AllowGen1Tradeback;
|
||||
|
||||
public static void Initialize(LegalitySettings settings)
|
||||
{
|
||||
Settings = settings;
|
||||
}
|
||||
|
||||
public static IReadOnlyList<string> MoveStrings { get; private set; } = Util.GetMovesList(GameLanguage.DefaultLanguage);
|
||||
public static IReadOnlyList<string> SpeciesStrings { get; private set; } = Util.GetSpeciesList(GameLanguage.DefaultLanguage);
|
||||
public static string GetMoveName(ushort move) => move >= MoveStrings.Count ? LegalityCheckStrings.L_AError : MoveStrings[move];
|
||||
|
||||
public static void ChangeLocalizationStrings(IReadOnlyList<string> moves, IReadOnlyList<string> species)
|
||||
{
|
||||
SpeciesStrings = species;
|
||||
MoveStrings = moves;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if Crystal is available to visit/originate from.
|
||||
/// </summary>
|
||||
/// <param name="pk">Data being checked</param>
|
||||
/// <returns>True if Crystal data is allowed</returns>
|
||||
public static bool AllowGen2Crystal(PKM pk) => !pk.Korean;
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if the Move Reminder (Relearner) is available.
|
||||
/// </summary>
|
||||
/// <remarks> Pokémon Stadium 2 was never released in Korea.</remarks>
|
||||
/// <param name="pk">Data being checked</param>
|
||||
/// <returns>True if Crystal data is allowed</returns>
|
||||
public static bool AllowGen2MoveReminder(PKM pk) => !pk.Korean && AllowGBStadium2;
|
||||
|
||||
public static bool AllowGen2OddEgg(PKM pk) => !pk.Japanese || AllowGBCartEra;
|
||||
|
||||
public static bool AllowGBVirtualConsole3DS => !AllowGBCartEra;
|
||||
public static bool AllowGBEraEvents => AllowGBCartEra;
|
||||
public static bool AllowGBStadium2 => AllowGBCartEra;
|
||||
|
||||
internal static bool IsFromActiveTrainer(PKM pk) => ActiveTrainer.IsFromTrainer(pk);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes certain settings
|
||||
/// </summary>
|
||||
/// <param name="sav">Newly loaded save file</param>
|
||||
/// <returns>Save file is Physical GB cartridge save file (not Virtual Console)</returns>
|
||||
public static bool InitFromSaveFileData(SaveFile sav)
|
||||
{
|
||||
ActiveTrainer = sav;
|
||||
return AllowGBCartEra = sav switch
|
||||
{
|
||||
SAV1 { IsVirtualConsole: true } => false,
|
||||
SAV2 { IsVirtualConsole: true } => false,
|
||||
{ Generation: 1 or 2 } => true,
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
||||
internal static bool IgnoreTransferIfNoTracker => Settings.HOMETransfer.HOMETransferTrackerNotPresent == Severity.Invalid;
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
using System.ComponentModel;
|
||||
|
||||
namespace PKHeX.Core;
|
||||
|
||||
[TypeConverter(typeof(ExpandableObjectConverter))]
|
||||
public sealed class BulkAnalysisSettings
|
||||
{
|
||||
[LocalizedDescription("Checks the save file data and Current Handler state to determine if the Pokémon's Current Handler does not match the expected value.")]
|
||||
public bool CheckActiveHandler { get; set; } = true;
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
using System.ComponentModel;
|
||||
|
||||
namespace PKHeX.Core;
|
||||
|
||||
[TypeConverter(typeof(ExpandableObjectConverter))]
|
||||
public sealed class FramePatternSettings
|
||||
{
|
||||
[LocalizedDescription("Severity to flag a Legality Check if the RNG Frame Checking logic does not find a match for Generation 3 encounters.")]
|
||||
public Severity RNGFrameNotFound3 { get; set; } = Severity.Fishy;
|
||||
|
||||
[LocalizedDescription("Severity to flag a Legality Check if the RNG Frame Checking logic does not find a match for Generation 4 encounters.")]
|
||||
public Severity RNGFrameNotFound4 { get; set; } = Severity.Invalid;
|
||||
|
||||
public Severity GetSeverity(byte generation) => generation == 3 ? RNGFrameNotFound3 : RNGFrameNotFound4;
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
using System.ComponentModel;
|
||||
|
||||
namespace PKHeX.Core;
|
||||
|
||||
[TypeConverter(typeof(ExpandableObjectConverter))]
|
||||
public sealed class GameSpecificSettings
|
||||
{
|
||||
public GameSpecificSettings7 Gen7 { get; set; } = new();
|
||||
public GameSpecificSettings8 Gen8 { get; set; } = new();
|
||||
}
|
||||
|
||||
[TypeConverter(typeof(ExpandableObjectConverter))]
|
||||
public sealed class GameSpecificSettings7
|
||||
{
|
||||
[LocalizedDescription("Severity to flag a Legality Check if Pokémon from Gen1/2 has a Star Shiny PID.")]
|
||||
public Severity Gen7TransferStarPID { get; set; } = Severity.Fishy;
|
||||
}
|
||||
|
||||
[TypeConverter(typeof(ExpandableObjectConverter))]
|
||||
public sealed class GameSpecificSettings8
|
||||
{
|
||||
[LocalizedDescription("Severity to flag a Legality Check if a Gen8 Memory is missing for the Handling Trainer.")]
|
||||
public Severity Gen8MemoryMissingHT { get; set; } = Severity.Fishy;
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
using System.ComponentModel;
|
||||
|
||||
namespace PKHeX.Core;
|
||||
|
||||
[TypeConverter(typeof(ExpandableObjectConverter))]
|
||||
public sealed class HOMETransferSettings
|
||||
{
|
||||
[LocalizedDescription("Severity to flag a Legality Check if the HOME Tracker is Missing")]
|
||||
public Severity HOMETransferTrackerNotPresent { get; set; } = Severity.Invalid;
|
||||
|
||||
[LocalizedDescription("Severity to flag a Legality Check if Pokémon has a zero value for both Height and Weight.")]
|
||||
public Severity ZeroHeightWeight { get; set; } = Severity.Fishy;
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
using System.ComponentModel;
|
||||
|
||||
namespace PKHeX.Core;
|
||||
|
||||
[TypeConverter(typeof(ExpandableObjectConverter))]
|
||||
public sealed class HandlerSettings
|
||||
{
|
||||
[LocalizedDescription("Severity to flag a Legality Check if Pokémon's Current Handler does not match the expected value.")]
|
||||
public Severity CurrentHandlerMismatch { get; set; } = Severity.Invalid;
|
||||
|
||||
[LocalizedDescription("Checks the save file data and Current Handler state to determine if the Pokémon's Current Handler does not match the expected value.")]
|
||||
public bool CheckActiveHandler { get; set; } = true;
|
||||
|
||||
public HandlerRestrictions Restrictions { get; set; } = new();
|
||||
}
|
||||
|
||||
[TypeConverter(typeof(ExpandableObjectConverter))]
|
||||
public sealed record HandlerRestrictions
|
||||
{
|
||||
public bool AllowHandleOTGen6 { get; set; }
|
||||
public bool AllowHandleOTGen7 { get; set; }
|
||||
public bool AllowHandleOTGen8 { get; set; }
|
||||
public bool AllowHandleOTGen8a { get; set; }
|
||||
public bool AllowHandleOTGen8b { get; set; }
|
||||
public bool AllowHandleOTGen9 { get; set; }
|
||||
|
||||
public bool GetCanOTHandle(EntityContext encContext) => encContext switch
|
||||
{
|
||||
EntityContext.Gen6 => AllowHandleOTGen6,
|
||||
EntityContext.Gen7 => AllowHandleOTGen7,
|
||||
EntityContext.Gen8 => AllowHandleOTGen8,
|
||||
EntityContext.Gen8a => AllowHandleOTGen8a,
|
||||
EntityContext.Gen8b => AllowHandleOTGen8b,
|
||||
EntityContext.Gen9 => AllowHandleOTGen9,
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
using System.ComponentModel;
|
||||
|
||||
namespace PKHeX.Core;
|
||||
|
||||
public sealed record NicknameSettings
|
||||
{
|
||||
[LocalizedDescription("Severity to flag a Legality Check if Pokémon has a Nickname matching another Species.")]
|
||||
public Severity NicknamedAnotherSpecies { get; set; } = Severity.Fishy;
|
||||
|
||||
[LocalizedDescription("Nickname rules for Generation 1 and 2.")]
|
||||
public NicknameRestriction Nickname12 { get; set; } = new();
|
||||
|
||||
[LocalizedDescription("Nickname rules for Generation 3.")]
|
||||
public NicknameRestriction Nickname3 { get; set; } = new();
|
||||
|
||||
[LocalizedDescription("Nickname rules for Generation 4.")]
|
||||
public NicknameRestriction Nickname4 { get; set; } = new();
|
||||
|
||||
[LocalizedDescription("Nickname rules for Generation 5.")]
|
||||
public NicknameRestriction Nickname5 { get; set; } = new();
|
||||
|
||||
[LocalizedDescription("Nickname rules for Generation 6.")]
|
||||
public NicknameRestriction Nickname6 { get; set; } = new();
|
||||
|
||||
[LocalizedDescription("Nickname rules for Generation 7.")]
|
||||
public NicknameRestriction Nickname7 { get; set; } = new();
|
||||
|
||||
[LocalizedDescription("Nickname rules for Generation 8.")]
|
||||
public NicknameRestriction Nickname8 { get; set; } = new();
|
||||
|
||||
[LocalizedDescription("Nickname rules for Generation 8a.")]
|
||||
public NicknameRestriction Nickname8a { get; set; } = new();
|
||||
|
||||
[LocalizedDescription("Nickname rules for Generation 8b.")]
|
||||
public NicknameRestriction Nickname8b { get; set; } = new();
|
||||
|
||||
[LocalizedDescription("Nickname rules for Generation 9.")]
|
||||
public NicknameRestriction Nickname9 { get; set; } = new();
|
||||
|
||||
public Severity NicknamedMysteryGift(EntityContext encContext) => encContext switch
|
||||
{
|
||||
EntityContext.Gen1 => Nickname12.NicknamedMysteryGift,
|
||||
EntityContext.Gen2 => Nickname12.NicknamedMysteryGift,
|
||||
EntityContext.Gen3 => Nickname3.NicknamedMysteryGift,
|
||||
EntityContext.Gen4 => Nickname4.NicknamedMysteryGift,
|
||||
EntityContext.Gen5 => Nickname5.NicknamedMysteryGift,
|
||||
EntityContext.Gen6 => Nickname6.NicknamedMysteryGift,
|
||||
EntityContext.Gen7 => Nickname7.NicknamedMysteryGift,
|
||||
EntityContext.Gen8 => Nickname8.NicknamedMysteryGift,
|
||||
EntityContext.Gen8a => Nickname8a.NicknamedMysteryGift,
|
||||
EntityContext.Gen8b => Nickname8b.NicknamedMysteryGift,
|
||||
EntityContext.Gen9 => Nickname9.NicknamedMysteryGift,
|
||||
_ => Severity.Valid,
|
||||
};
|
||||
|
||||
public Severity NicknamedTrade(EntityContext encContext) => encContext switch
|
||||
{
|
||||
EntityContext.Gen1 => Nickname12.NicknamedTrade,
|
||||
EntityContext.Gen2 => Nickname12.NicknamedTrade,
|
||||
EntityContext.Gen3 => Nickname3.NicknamedTrade,
|
||||
EntityContext.Gen4 => Nickname4.NicknamedTrade,
|
||||
EntityContext.Gen5 => Nickname5.NicknamedTrade,
|
||||
EntityContext.Gen6 => Nickname6.NicknamedTrade,
|
||||
EntityContext.Gen7 => Nickname7.NicknamedTrade,
|
||||
EntityContext.Gen8 => Nickname8.NicknamedTrade,
|
||||
EntityContext.Gen9 => Nickname9.NicknamedTrade,
|
||||
_ => Severity.Valid,
|
||||
};
|
||||
}
|
||||
|
||||
[TypeConverter(typeof(ExpandableObjectConverter))]
|
||||
public sealed record NicknameRestriction
|
||||
{
|
||||
[LocalizedDescription("Severity to flag a Legality Check if it is a nicknamed In-Game Trade the player cannot normally nickname.")]
|
||||
public Severity NicknamedTrade { get; set; } = Severity.Invalid;
|
||||
|
||||
[LocalizedDescription("Severity to flag a Legality Check if it is a nicknamed Mystery Gift the player cannot normally nickname.")]
|
||||
public Severity NicknamedMysteryGift { get; set; } = Severity.Invalid;
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
using System.ComponentModel;
|
||||
|
||||
namespace PKHeX.Core;
|
||||
|
||||
[TypeConverter(typeof(ExpandableObjectConverter))]
|
||||
public sealed class TradebackSettings
|
||||
{
|
||||
[LocalizedDescription("GB: Allow Generation 2 tradeback learnsets for PK1 formats. Disable when checking RBY Metagame rules.")]
|
||||
public bool AllowGen1Tradeback { get; set; } = true;
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
using System.ComponentModel;
|
||||
|
||||
namespace PKHeX.Core;
|
||||
|
||||
[TypeConverter(typeof(ExpandableObjectConverter))]
|
||||
public sealed class WordFilterSettings
|
||||
{
|
||||
[LocalizedDescription("Checks player given Nicknames and Trainer Names for profanity. Bad words will be flagged using the 3DS console's regex lists.")]
|
||||
public bool CheckWordFilter { get; set; } = true;
|
||||
|
||||
[LocalizedDescription("Disables the Word Filter check for formats prior to 3DS-era.")]
|
||||
public bool DisableWordFilterPastGen { get; set; }
|
||||
|
||||
public bool IsEnabled(int gen) => CheckWordFilter && (!DisableWordFilterPastGen || gen >= 6);
|
||||
}
|
||||
|
|
@ -56,7 +56,7 @@ private void VerifyHandlerState(LegalityAnalysis data, bool neverOT)
|
|||
var Info = data.Info;
|
||||
|
||||
// HT Flag
|
||||
if (ParseSettings.CheckActiveHandler)
|
||||
if (ParseSettings.Settings.Handler.CheckActiveHandler)
|
||||
{
|
||||
var tr = ParseSettings.ActiveTrainer;
|
||||
var withOT = tr.IsFromTrainer(pk);
|
||||
|
|
@ -214,21 +214,31 @@ public static bool GetCanOTHandle(IEncounterTemplate enc, PKM pk, byte generatio
|
|||
if (generation < 6)
|
||||
return generation >= 3;
|
||||
|
||||
return enc switch
|
||||
{
|
||||
IFixedTrainer { IsFixedTrainer: true } => false,
|
||||
EncounterSlot8GO => false,
|
||||
WC6 { OriginalTrainerName.Length: > 0 } => false,
|
||||
WC7 { OriginalTrainerName.Length: > 0, TID16: not 18075 } => false, // Ash Pikachu QR Gift doesn't set Current Handler
|
||||
WB7 wb7 when wb7.GetHasOT(pk.Language) => false,
|
||||
WC8 wc8 when wc8.GetHasOT(pk.Language) => false,
|
||||
WB8 wb8 when wb8.GetHasOT(pk.Language) => false,
|
||||
WA8 wa8 when wa8.GetHasOT(pk.Language) => false,
|
||||
WC8 {IsHOMEGift: true} => false,
|
||||
_ => true,
|
||||
};
|
||||
if (GetCanOTHandle(enc, pk))
|
||||
return true;
|
||||
|
||||
if (ParseSettings.Settings.Handler.Restrictions.GetCanOTHandle(enc.Context))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool GetCanOTHandle(IEncounterTemplate enc, PKM pk) => enc switch
|
||||
{
|
||||
IFixedTrainer { IsFixedTrainer: true } => false,
|
||||
EncounterSlot8GO => false,
|
||||
WC6 { OriginalTrainerName.Length: > 0 } => false,
|
||||
WC7 { OriginalTrainerName.Length: > 0, TID16: not 18075 } => false, // Ash Pikachu QR Gift doesn't set Current Handler
|
||||
WB7 wb7 when wb7.GetHasOT(pk.Language) => false,
|
||||
WC8 wc8 when wc8.GetHasOT(pk.Language) => false,
|
||||
WB8 wb8 when wb8.GetHasOT(pk.Language) => false,
|
||||
WA8 wa8 when wa8.GetHasOT(pk.Language) => false,
|
||||
WC9 wc9 when wc9.GetHasOT(pk.Language) => false,
|
||||
WC8 {IsHOMEGift: true} => false,
|
||||
WC9 {IsHOMEGift: true} => false,
|
||||
_ => true,
|
||||
};
|
||||
|
||||
private static int GetBaseFriendship(IEncounterTemplate enc) => enc switch
|
||||
{
|
||||
IFixedOTFriendship f => f.OriginalTrainerFriendship,
|
||||
|
|
|
|||
|
|
@ -297,12 +297,18 @@ private void VerifyOTMemory(LegalityAnalysis data)
|
|||
switch (data.EncounterMatch)
|
||||
{
|
||||
case WC6 {IsEgg: false} g when g.OTGender != 3:
|
||||
if (g.OriginalTrainerMemory is not 0 && ParseSettings.Settings.Handler.Restrictions.AllowHandleOTGen6)
|
||||
break;
|
||||
VerifyOTMemoryIs(data, g.OriginalTrainerMemory, g.OriginalTrainerMemoryIntensity, g.OriginalTrainerMemoryVariable, g.OriginalTrainerMemoryFeeling);
|
||||
return;
|
||||
case WC7 {IsEgg: false} g when g.OTGender != 3:
|
||||
if (g.OriginalTrainerMemory is not 0 && ParseSettings.Settings.Handler.Restrictions.AllowHandleOTGen7)
|
||||
break;
|
||||
VerifyOTMemoryIs(data, g.OriginalTrainerMemory, g.OriginalTrainerMemoryIntensity, g.OriginalTrainerMemoryVariable, g.OriginalTrainerMemoryFeeling);
|
||||
return;
|
||||
case WC8 {IsEgg: false} g when g.OTGender != 3:
|
||||
if (g.OriginalTrainerMemory is not 0 && ParseSettings.Settings.Handler.Restrictions.AllowHandleOTGen8)
|
||||
break;
|
||||
VerifyOTMemoryIs(data, g.OriginalTrainerMemory, g.OriginalTrainerMemoryIntensity, g.OriginalTrainerMemoryVariable, g.OriginalTrainerMemoryFeeling);
|
||||
return;
|
||||
|
||||
|
|
@ -429,7 +435,7 @@ private void VerifyHTMemory(LegalityAnalysis data, EntityContext memoryGen)
|
|||
var severity = mc.Context switch
|
||||
{
|
||||
Gen8 when pk is not PK8 && !pk.SWSH => Severity.Valid,
|
||||
Gen8 => ParseSettings.Gen8MemoryMissingHT,
|
||||
Gen8 => ParseSettings.Settings.Game.Gen8.Gen8MemoryMissingHT,
|
||||
_ => Severity.Invalid,
|
||||
};
|
||||
if (severity != Severity.Valid)
|
||||
|
|
|
|||
|
|
@ -41,10 +41,6 @@ public override void Verify(LegalityAnalysis data)
|
|||
if (pk is IHomeTrack { HasTracker: true })
|
||||
data.AddLine(GetInvalid(LTransferTrackerShouldBeZero));
|
||||
}
|
||||
else
|
||||
{
|
||||
VerifyMiscMovePP(data);
|
||||
}
|
||||
|
||||
switch (pk)
|
||||
{
|
||||
|
|
@ -198,8 +194,8 @@ private void VerifySVStats(LegalityAnalysis data, PK9 pk9)
|
|||
{
|
||||
if (enc.Generation < 8 && !data.Info.EvoChainsAllGens.HasVisitedPLA && enc is not IPogoSlot) // <=Gen8 rerolls height/weight, never zero.
|
||||
data.AddLine(Get(LStatInvalidHeightWeight, Severity.Invalid, Encounter));
|
||||
else if (CheckHeightWeightOdds(enc) && ParseSettings.ZeroHeightWeight != Severity.Valid)
|
||||
data.AddLine(Get(LStatInvalidHeightWeight, ParseSettings.ZeroHeightWeight, Encounter));
|
||||
else if (CheckHeightWeightOdds(enc) && ParseSettings.Settings.HOMETransfer.ZeroHeightWeight != Severity.Valid)
|
||||
data.AddLine(Get(LStatInvalidHeightWeight, ParseSettings.Settings.HOMETransfer.ZeroHeightWeight, Encounter));
|
||||
}
|
||||
|
||||
if (enc is EncounterEgg { Context: EntityContext.Gen9 } g)
|
||||
|
|
@ -443,50 +439,9 @@ private static void VerifyMiscFatefulEncounter(LegalityAnalysis data)
|
|||
data.AddLine(GetInvalid(LFatefulInvalid, Fateful));
|
||||
}
|
||||
|
||||
private static void VerifyMiscMovePP(LegalityAnalysis data)
|
||||
{
|
||||
var pk = data.Entity;
|
||||
|
||||
if (!Legal.IsPPUpAvailable(pk)) // No PP Ups for format
|
||||
{
|
||||
if (pk.Move1_PPUps is not 0)
|
||||
data.AddLine(GetInvalid(string.Format(LMovePPUpsTooHigh_0, 1), CurrentMove));
|
||||
if (pk.Move2_PPUps is not 0)
|
||||
data.AddLine(GetInvalid(string.Format(LMovePPUpsTooHigh_0, 2), CurrentMove));
|
||||
if (pk.Move3_PPUps is not 0)
|
||||
data.AddLine(GetInvalid(string.Format(LMovePPUpsTooHigh_0, 3), CurrentMove));
|
||||
if (pk.Move4_PPUps is not 0)
|
||||
data.AddLine(GetInvalid(string.Format(LMovePPUpsTooHigh_0, 4), CurrentMove));
|
||||
}
|
||||
else // Check specific move indexes
|
||||
{
|
||||
if (!Legal.IsPPUpAvailable(pk.Move1) && pk.Move1_PPUps is not 0)
|
||||
data.AddLine(GetInvalid(string.Format(LMovePPUpsTooHigh_0, 1), CurrentMove));
|
||||
if (!Legal.IsPPUpAvailable(pk.Move2) && pk.Move2_PPUps is not 0)
|
||||
data.AddLine(GetInvalid(string.Format(LMovePPUpsTooHigh_0, 2), CurrentMove));
|
||||
if (!Legal.IsPPUpAvailable(pk.Move3) && pk.Move3_PPUps is not 0)
|
||||
data.AddLine(GetInvalid(string.Format(LMovePPUpsTooHigh_0, 3), CurrentMove));
|
||||
if (!Legal.IsPPUpAvailable(pk.Move4) && pk.Move4_PPUps is not 0)
|
||||
data.AddLine(GetInvalid(string.Format(LMovePPUpsTooHigh_0, 4), CurrentMove));
|
||||
}
|
||||
|
||||
if (pk.Move1_PP > pk.GetMovePP(pk.Move1, pk.Move1_PPUps))
|
||||
data.AddLine(GetInvalid(string.Format(LMovePPTooHigh_0, 1), CurrentMove));
|
||||
if (pk.Move2_PP > pk.GetMovePP(pk.Move2, pk.Move2_PPUps))
|
||||
data.AddLine(GetInvalid(string.Format(LMovePPTooHigh_0, 2), CurrentMove));
|
||||
if (pk.Move3_PP > pk.GetMovePP(pk.Move3, pk.Move3_PPUps))
|
||||
data.AddLine(GetInvalid(string.Format(LMovePPTooHigh_0, 3), CurrentMove));
|
||||
if (pk.Move4_PP > pk.GetMovePP(pk.Move4, pk.Move4_PPUps))
|
||||
data.AddLine(GetInvalid(string.Format(LMovePPTooHigh_0, 4), CurrentMove));
|
||||
}
|
||||
|
||||
private static void VerifyMiscEggCommon(LegalityAnalysis data)
|
||||
{
|
||||
var pk = data.Entity;
|
||||
if (pk.Move1_PPUps != 0 || pk.Move2_PPUps != 0 || pk.Move3_PPUps != 0 || pk.Move4_PPUps != 0)
|
||||
data.AddLine(GetInvalid(LEggPPUp, Egg));
|
||||
if (!IsZeroMovePP(pk))
|
||||
data.AddLine(GetInvalid(LEggPP, Egg));
|
||||
|
||||
var enc = data.EncounterMatch;
|
||||
if (!EggStateLegality.GetIsEggHatchCyclesValid(pk, enc))
|
||||
|
|
@ -517,19 +472,6 @@ private static void VerifyMiscEggCommon(LegalityAnalysis data)
|
|||
}
|
||||
}
|
||||
|
||||
private static bool IsZeroMovePP(PKM pk)
|
||||
{
|
||||
if (pk.Move1_PP != pk.GetMovePP(pk.Move1, 0))
|
||||
return false;
|
||||
if (pk.Move2_PP != pk.GetMovePP(pk.Move2, 0))
|
||||
return false;
|
||||
if (pk.Move3_PP != pk.GetMovePP(pk.Move3, 0))
|
||||
return false;
|
||||
if (pk.Move4_PP != pk.GetMovePP(pk.Move4, 0))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool MovesMatchRelearn(PKM pk)
|
||||
{
|
||||
if (pk.Move1 != pk.RelearnMove1)
|
||||
|
|
@ -720,8 +662,8 @@ private void VerifySWSHStats(LegalityAnalysis data, PK8 pk8)
|
|||
data.AddLine(GetInvalid(LStatDynamaxInvalid));
|
||||
}
|
||||
|
||||
if (CheckHeightWeightOdds(data.EncounterMatch) && pk8 is { HeightScalar: 0, WeightScalar: 0 } && ParseSettings.ZeroHeightWeight != Severity.Valid)
|
||||
data.AddLine(Get(LStatInvalidHeightWeight, ParseSettings.ZeroHeightWeight, Encounter));
|
||||
if (CheckHeightWeightOdds(data.EncounterMatch) && pk8 is { HeightScalar: 0, WeightScalar: 0 } && ParseSettings.Settings.HOMETransfer.ZeroHeightWeight != Severity.Valid)
|
||||
data.AddLine(Get(LStatInvalidHeightWeight, ParseSettings.Settings.HOMETransfer.ZeroHeightWeight, Encounter));
|
||||
|
||||
VerifyTechRecordSWSH(data, pk8);
|
||||
}
|
||||
|
|
@ -748,8 +690,8 @@ private void VerifyPLAStats(LegalityAnalysis data, PA8 pa8)
|
|||
if (pa8.GetMoveRecordFlagAny() && !pa8.IsEgg) // already checked for eggs
|
||||
data.AddLine(GetInvalid(LEggRelearnFlags));
|
||||
|
||||
if (CheckHeightWeightOdds(data.EncounterMatch) && pa8 is { HeightScalar: 0, WeightScalar: 0 } && ParseSettings.ZeroHeightWeight != Severity.Valid)
|
||||
data.AddLine(Get(LStatInvalidHeightWeight, ParseSettings.ZeroHeightWeight, Encounter));
|
||||
if (CheckHeightWeightOdds(data.EncounterMatch) && pa8 is { HeightScalar: 0, WeightScalar: 0 } && ParseSettings.Settings.HOMETransfer.ZeroHeightWeight != Severity.Valid)
|
||||
data.AddLine(Get(LStatInvalidHeightWeight, ParseSettings.Settings.HOMETransfer.ZeroHeightWeight, Encounter));
|
||||
|
||||
VerifyTechRecordSWSH(data, pa8);
|
||||
}
|
||||
|
|
@ -781,8 +723,8 @@ private void VerifyBDSPStats(LegalityAnalysis data, PB8 pb8)
|
|||
if (pb8.GetMoveRecordFlagAny() && !pb8.IsEgg) // already checked for eggs
|
||||
data.AddLine(GetInvalid(LEggRelearnFlags));
|
||||
|
||||
if (CheckHeightWeightOdds(data.EncounterMatch) && pb8 is { HeightScalar: 0, WeightScalar: 0 } && ParseSettings.ZeroHeightWeight != Severity.Valid)
|
||||
data.AddLine(Get(LStatInvalidHeightWeight, ParseSettings.ZeroHeightWeight, Encounter));
|
||||
if (CheckHeightWeightOdds(data.EncounterMatch) && pb8 is { HeightScalar: 0, WeightScalar: 0 } && ParseSettings.Settings.HOMETransfer.ZeroHeightWeight != Severity.Valid)
|
||||
data.AddLine(Get(LStatInvalidHeightWeight, ParseSettings.Settings.HOMETransfer.ZeroHeightWeight, Encounter));
|
||||
|
||||
VerifyTechRecordSWSH(data, pb8);
|
||||
}
|
||||
|
|
|
|||
73
PKHeX.Core/Legality/Verifiers/MovePPVerifier.cs
Normal file
73
PKHeX.Core/Legality/Verifiers/MovePPVerifier.cs
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
using System;
|
||||
using static PKHeX.Core.LegalityCheckStrings;
|
||||
|
||||
namespace PKHeX.Core;
|
||||
|
||||
public sealed class MovePPVerifier : Verifier
|
||||
{
|
||||
protected override CheckIdentifier Identifier => CheckIdentifier.CurrentMove;
|
||||
|
||||
public override void Verify(LegalityAnalysis data)
|
||||
{
|
||||
if (data.Entity.IsEgg)
|
||||
{
|
||||
VerifyEgg(data);
|
||||
return;
|
||||
}
|
||||
|
||||
VerifyEntity(data);
|
||||
}
|
||||
|
||||
private void VerifyEgg(LegalityAnalysis data)
|
||||
{
|
||||
var pk = data.Entity;
|
||||
if (pk.Move1_PPUps != 0 || pk.Move2_PPUps != 0 || pk.Move3_PPUps != 0 || pk.Move4_PPUps != 0)
|
||||
data.AddLine(GetInvalid(LEggPPUp, CheckIdentifier.Egg));
|
||||
if (!IsZeroMovePP(pk))
|
||||
data.AddLine(GetInvalid(LEggPP, CheckIdentifier.Egg));
|
||||
}
|
||||
|
||||
private static bool IsZeroMovePP(PKM pk)
|
||||
{
|
||||
if (pk.Move1_PP != pk.GetBasePP(pk.Move1))
|
||||
return false;
|
||||
if (pk.Move2_PP != pk.GetBasePP(pk.Move2))
|
||||
return false;
|
||||
if (pk.Move3_PP != pk.GetBasePP(pk.Move3))
|
||||
return false;
|
||||
if (pk.Move4_PP != pk.GetBasePP(pk.Move4))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void VerifyEntity(LegalityAnalysis data)
|
||||
{
|
||||
var pk = data.Entity;
|
||||
ReadOnlySpan<int> ups = [pk.Move1_PPUps, pk.Move2_PPUps, pk.Move3_PPUps, pk.Move4_PPUps];
|
||||
ReadOnlySpan<ushort> moves = [pk.Move1, pk.Move2, pk.Move3, pk.Move4];
|
||||
ReadOnlySpan<int> pp = [pk.Move1_PP, pk.Move2_PP, pk.Move3_PP, pk.Move4_PP];
|
||||
|
||||
if (!Legal.IsPPUpAvailable(pk)) // No PP Ups for format
|
||||
{
|
||||
for (int i = 0; i < ups.Length; i++)
|
||||
{
|
||||
if (ups[i] != 0)
|
||||
data.AddLine(GetInvalid(string.Format(LMovePPUpsTooHigh_0, i + 1)));
|
||||
}
|
||||
}
|
||||
else // Check specific move indexes
|
||||
{
|
||||
for (int i = 0; i < ups.Length; i++)
|
||||
{
|
||||
if (!Legal.IsPPUpAvailable(moves[i]) && ups[i] != 0)
|
||||
data.AddLine(GetInvalid(string.Format(LMovePPUpsTooHigh_0, i + 1)));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < pp.Length; i++)
|
||||
{
|
||||
if (pp[i] > pk.GetMovePP(moves[i], ups[i]))
|
||||
data.AddLine(GetInvalid(string.Format(LMovePPTooHigh_0, i + 1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -43,7 +43,7 @@ public override void Verify(LegalityAnalysis data)
|
|||
if (pk.VC)
|
||||
VerifyG1NicknameWithinBounds(data, nickname);
|
||||
else if (enc is MysteryGift {IsEgg: false})
|
||||
data.AddLine(Get(LEncGiftNicknamed, ParseSettings.NicknamedMysteryGift));
|
||||
data.AddLine(Get(LEncGiftNicknamed, ParseSettings.Settings.Nickname.NicknamedMysteryGift(enc.Context)));
|
||||
}
|
||||
|
||||
if (enc is IFixedTrainer t)
|
||||
|
|
@ -63,7 +63,7 @@ public override void Verify(LegalityAnalysis data)
|
|||
return;
|
||||
|
||||
// Non-nicknamed strings have already been checked.
|
||||
if (ParseSettings.CheckWordFilter && pk.IsNicknamed)
|
||||
if (ParseSettings.Settings.WordFilter.IsEnabled(pk.Format) && pk.IsNicknamed)
|
||||
{
|
||||
if (WordFilter.IsFiltered(nickname, out var badPattern))
|
||||
data.AddLine(GetInvalid($"Word Filter: {badPattern}"));
|
||||
|
|
@ -163,7 +163,7 @@ private bool VerifyUnNicknamedEncounter(LegalityAnalysis data, PKM pk, ReadOnlyS
|
|||
if (!SpeciesName.TryGetSpecies(nickname, language, out var species))
|
||||
continue;
|
||||
var msg = species == pk.Species && language != pk.Language ? LNickMatchNoOthersFail : LNickMatchLanguageFlag;
|
||||
data.AddLine(Get(msg, ParseSettings.NicknamedAnotherSpecies));
|
||||
data.AddLine(Get(msg, ParseSettings.Settings.Nickname.NicknamedAnotherSpecies));
|
||||
return true;
|
||||
}
|
||||
if (pk.Format <= 7 && StringConverter.HasEastAsianScriptCharacters(nickname) && pk is not PB7) // East Asian Scripts
|
||||
|
|
@ -403,7 +403,7 @@ private static void VerifyNickname(LegalityAnalysis data, IFixedNickname fn, int
|
|||
var pk = data.Entity;
|
||||
var result = fn.IsNicknameMatch(pk, pk.Nickname, language)
|
||||
? GetValid(LEncTradeUnchanged, CheckIdentifier.Nickname)
|
||||
: Get(LEncTradeChangedNickname, ParseSettings.NicknamedTrade, CheckIdentifier.Nickname);
|
||||
: Get(LEncTradeChangedNickname, ParseSettings.Settings.Nickname.NicknamedTrade(data.EncounterOriginal.Context), CheckIdentifier.Nickname);
|
||||
data.AddLine(result);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,140 +0,0 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace PKHeX.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Settings for Parsing Legality
|
||||
/// </summary>
|
||||
/// <remarks><see cref="LegalityAnalysis"/></remarks>
|
||||
public static class ParseSettings
|
||||
{
|
||||
internal static ITrainerInfo ActiveTrainer { get; set; } = new SimpleTrainerInfo(GameVersion.Any) { OT = string.Empty, Language = -1 };
|
||||
|
||||
/// <summary>
|
||||
/// Toggles whether the word filter should be used when checking the data.
|
||||
/// </summary>
|
||||
public static bool CheckWordFilter { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Setting to specify if an analysis should permit data sourced from the physical cartridge era of Game Boy games.
|
||||
/// </summary>
|
||||
/// <remarks>If false, indicates to use Virtual Console rules (which are transferable to Gen7+)</remarks>
|
||||
public static bool AllowGBCartEra { private get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Setting to specify if an analysis should permit trading a Generation 1 origin file to Generation 2, then back. Useful for checking RBY Metagame rules.
|
||||
/// </summary>
|
||||
public static bool AllowGen1Tradeback { get; set; } = true;
|
||||
|
||||
public static Severity NicknamedTrade { get; private set; } = Severity.Invalid;
|
||||
public static Severity NicknamedMysteryGift { get; private set; } = Severity.Fishy;
|
||||
public static Severity RNGFrameNotFound3 { get; private set; } = Severity.Fishy;
|
||||
public static Severity RNGFrameNotFound4 { get; private set; } = Severity.Invalid;
|
||||
public static Severity Gen7TransferStarPID { get; private set; } = Severity.Fishy;
|
||||
public static Severity Gen8MemoryMissingHT { get; private set; } = Severity.Fishy;
|
||||
public static Severity HOMETransferTrackerNotPresent { get; private set; } = Severity.Fishy;
|
||||
public static Severity NicknamedAnotherSpecies { get; private set; } = Severity.Fishy;
|
||||
public static Severity ZeroHeightWeight { get; private set; } = Severity.Fishy;
|
||||
public static Severity CurrentHandlerMismatch { get; private set; } = Severity.Invalid;
|
||||
public static bool CheckActiveHandler { get; set; }
|
||||
|
||||
public static IReadOnlyList<string> MoveStrings { get; private set; } = Util.GetMovesList(GameLanguage.DefaultLanguage);
|
||||
public static IReadOnlyList<string> SpeciesStrings { get; private set; } = Util.GetSpeciesList(GameLanguage.DefaultLanguage);
|
||||
public static string GetMoveName(ushort move) => move >= MoveStrings.Count ? LegalityCheckStrings.L_AError : MoveStrings[move];
|
||||
|
||||
public static void ChangeLocalizationStrings(IReadOnlyList<string> moves, IReadOnlyList<string> species)
|
||||
{
|
||||
SpeciesStrings = species;
|
||||
MoveStrings = moves;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if Crystal is available to visit/originate from.
|
||||
/// </summary>
|
||||
/// <remarks>Pokémon Crystal was never released in Korea.</remarks>
|
||||
/// <param name="Korean">Korean data being checked</param>
|
||||
/// <returns>True if Crystal data is allowed</returns>
|
||||
public static bool AllowGen2Crystal(bool Korean) => !Korean;
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if Crystal is available to visit/originate from.
|
||||
/// </summary>
|
||||
/// <param name="pk">Data being checked</param>
|
||||
/// <returns>True if Crystal data is allowed</returns>
|
||||
public static bool AllowGen2Crystal(PKM pk) => !pk.Korean;
|
||||
|
||||
/// <summary>
|
||||
/// Checks to see if the Move Reminder (Relearner) is available.
|
||||
/// </summary>
|
||||
/// <remarks> Pokémon Stadium 2 was never released in Korea.</remarks>
|
||||
/// <param name="pk">Data being checked</param>
|
||||
/// <returns>True if Crystal data is allowed</returns>
|
||||
public static bool AllowGen2MoveReminder(PKM pk) => !pk.Korean && AllowGBStadium2;
|
||||
|
||||
public static bool AllowGen2OddEgg(PKM pk) => !pk.Japanese || AllowGBCartEra;
|
||||
|
||||
public static bool AllowGBVirtualConsole3DS => !AllowGBCartEra;
|
||||
public static bool AllowGBEraEvents => AllowGBCartEra;
|
||||
public static bool AllowGBStadium2 => AllowGBCartEra;
|
||||
|
||||
internal static bool IsFromActiveTrainer(PKM pk) => ActiveTrainer.IsFromTrainer(pk);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes certain settings
|
||||
/// </summary>
|
||||
/// <param name="sav">Newly loaded save file</param>
|
||||
/// <returns>Save file is Physical GB cartridge save file (not Virtual Console)</returns>
|
||||
public static bool InitFromSaveFileData(SaveFile sav)
|
||||
{
|
||||
ActiveTrainer = sav;
|
||||
return AllowGBCartEra = sav switch
|
||||
{
|
||||
SAV1 { IsVirtualConsole: true } => false,
|
||||
SAV2 { IsVirtualConsole: true } => false,
|
||||
{ Generation: 1 or 2 } => true,
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
||||
internal static bool IgnoreTransferIfNoTracker => HOMETransferTrackerNotPresent == Severity.Invalid;
|
||||
|
||||
public static void InitFromSettings(IParseSettings settings)
|
||||
{
|
||||
CheckWordFilter = settings.CheckWordFilter;
|
||||
AllowGen1Tradeback = settings.AllowGen1Tradeback;
|
||||
NicknamedTrade = settings.NicknamedTrade;
|
||||
NicknamedMysteryGift = settings.NicknamedMysteryGift;
|
||||
RNGFrameNotFound3 = settings.RNGFrameNotFound3;
|
||||
RNGFrameNotFound4 = settings.RNGFrameNotFound4;
|
||||
Gen7TransferStarPID = settings.Gen7TransferStarPID;
|
||||
HOMETransferTrackerNotPresent = settings.HOMETransferTrackerNotPresent;
|
||||
Gen8MemoryMissingHT = settings.Gen8MemoryMissingHT;
|
||||
NicknamedAnotherSpecies = settings.NicknamedAnotherSpecies;
|
||||
ZeroHeightWeight = settings.ZeroHeightWeight;
|
||||
CurrentHandlerMismatch = settings.CurrentHandlerMismatch;
|
||||
CheckActiveHandler = settings.CheckActiveHandler;
|
||||
}
|
||||
}
|
||||
|
||||
public interface IParseSettings
|
||||
{
|
||||
bool CheckWordFilter { get; }
|
||||
bool CheckActiveHandler { get; }
|
||||
bool AllowGen1Tradeback { get; }
|
||||
|
||||
Severity NicknamedTrade { get; }
|
||||
Severity NicknamedMysteryGift { get; }
|
||||
Severity RNGFrameNotFound3 { get; }
|
||||
Severity RNGFrameNotFound4 { get; }
|
||||
Severity Gen7TransferStarPID { get; }
|
||||
Severity Gen8MemoryMissingHT { get; }
|
||||
Severity HOMETransferTrackerNotPresent { get; }
|
||||
Severity NicknamedAnotherSpecies { get; }
|
||||
Severity ZeroHeightWeight { get; }
|
||||
Severity CurrentHandlerMismatch { get; }
|
||||
}
|
||||
|
||||
public interface IBulkAnalysisSettings
|
||||
{
|
||||
bool CheckActiveHandler { get; }
|
||||
}
|
||||
|
|
@ -42,7 +42,7 @@ public override void Verify(LegalityAnalysis data)
|
|||
data.AddLine(Get(LOTLong, Severity.Invalid));
|
||||
}
|
||||
|
||||
if (ParseSettings.CheckWordFilter)
|
||||
if (ParseSettings.Settings.WordFilter.IsEnabled(pk.Format))
|
||||
{
|
||||
if (WordFilter.IsFiltered(ot, out var badPattern))
|
||||
data.AddLine(GetInvalid($"Word Filter: {badPattern}"));
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ private static void VerifyVCShinyXorIfShiny(LegalityAnalysis data)
|
|||
// (15:65536, ~1:4096) odds on a given shiny transfer!
|
||||
var xor = data.Entity.ShinyXor;
|
||||
if (xor is <= 15 and not 0)
|
||||
data.AddLine(Get(LEncStaticPIDShiny, ParseSettings.Gen7TransferStarPID, CheckIdentifier.PID));
|
||||
data.AddLine(Get(LEncStaticPIDShiny, ParseSettings.Settings.Game.Gen7.Gen7TransferStarPID, CheckIdentifier.PID));
|
||||
}
|
||||
|
||||
private static void VerifyVCGeolocation(LegalityAnalysis data)
|
||||
|
|
@ -190,7 +190,7 @@ private void VerifyHOMETracker(LegalityAnalysis data, PKM pk)
|
|||
// Can't validate the actual values (we aren't the server), so we can only check against zero.
|
||||
if (pk is IHomeTrack { HasTracker: false })
|
||||
{
|
||||
data.AddLine(Get(LTransferTrackerMissing, ParseSettings.HOMETransferTrackerNotPresent));
|
||||
data.AddLine(Get(LTransferTrackerMissing, ParseSettings.Settings.HOMETransfer.HOMETransferTrackerNotPresent));
|
||||
// To the reader: It seems like the best course of action for setting a tracker is:
|
||||
// - Transfer a 0-Tracker pk to HOME to get assigned a valid Tracker
|
||||
// - Don't make one up.
|
||||
|
|
|
|||
|
|
@ -172,7 +172,7 @@ public override void GetIVs(Span<int> value)
|
|||
value[5] = IV_SPD;
|
||||
}
|
||||
|
||||
public bool IsNicknamed => Nickname.Length > 0;
|
||||
public bool IsNicknamed => Nickname.Length != 0;
|
||||
public override bool IsShiny => PIDType == 2;
|
||||
public override Moveset Moves => new(Move1, Move2, Move3, Move4);
|
||||
public override bool IsEntity { get => CardType == 1; set { if (value) CardType = 1; } }
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ public int[] EVs
|
|||
}
|
||||
}
|
||||
|
||||
public bool IsNicknamed => Nickname.Length > 0;
|
||||
public bool IsNicknamed => Nickname.Length != 0;
|
||||
|
||||
public override Moveset Moves
|
||||
{
|
||||
|
|
@ -325,11 +325,11 @@ public override PK6 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
|||
ContestTough = ContestTough,
|
||||
ContestSheen = ContestSheen,
|
||||
|
||||
OriginalTrainerName = OriginalTrainerName.Length > 0 ? OriginalTrainerName : tr.OT,
|
||||
OriginalTrainerName = OriginalTrainerName.Length != 0 ? OriginalTrainerName : tr.OT,
|
||||
OriginalTrainerGender = OTGender != 3 ? (byte)(OTGender % 2) : tr.Gender,
|
||||
HandlingTrainerName = OriginalTrainerName.Length > 0 ? tr.OT : string.Empty,
|
||||
HandlingTrainerGender = OriginalTrainerName.Length > 0 ? tr.Gender : default,
|
||||
CurrentHandler = OriginalTrainerName.Length > 0 ? (byte)1 : (byte)0,
|
||||
HandlingTrainerName = OriginalTrainerName.Length != 0 ? tr.OT : string.Empty,
|
||||
HandlingTrainerGender = OriginalTrainerName.Length != 0 ? tr.Gender : default,
|
||||
CurrentHandler = OriginalTrainerName.Length != 0 ? (byte)1 : (byte)0,
|
||||
|
||||
EXP = Experience.GetEXP(Level, pi.EXPGrowth),
|
||||
|
||||
|
|
|
|||
|
|
@ -328,7 +328,7 @@ public int[] EVs
|
|||
}
|
||||
}
|
||||
|
||||
public bool IsNicknamed => Nickname.Length > 0 || IsEgg;
|
||||
public bool IsNicknamed => Nickname.Length != 0 || IsEgg;
|
||||
|
||||
public override Moveset Moves
|
||||
{
|
||||
|
|
@ -390,11 +390,11 @@ public override PK7 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
|||
ContestTough = ContestTough,
|
||||
ContestSheen = ContestSheen,
|
||||
|
||||
OriginalTrainerName = OriginalTrainerName.Length > 0 ? OriginalTrainerName : tr.OT,
|
||||
OriginalTrainerName = OriginalTrainerName.Length != 0 ? OriginalTrainerName : tr.OT,
|
||||
OriginalTrainerGender = OTGender != 3 ? (byte)(OTGender % 2) : tr.Gender,
|
||||
HandlingTrainerName = OriginalTrainerName.Length > 0 ? tr.OT : string.Empty,
|
||||
HandlingTrainerGender = OriginalTrainerName.Length > 0 ? tr.Gender : default,
|
||||
CurrentHandler = OriginalTrainerName.Length > 0 ? (byte)1 : (byte)0,
|
||||
HandlingTrainerName = OriginalTrainerName.Length != 0 ? tr.OT : string.Empty,
|
||||
HandlingTrainerGender = OriginalTrainerName.Length != 0 ? tr.Gender : default,
|
||||
CurrentHandler = OriginalTrainerName.Length != 0 ? (byte)1 : (byte)0,
|
||||
|
||||
EXP = Experience.GetEXP(currentLevel, pi.EXPGrowth),
|
||||
|
||||
|
|
|
|||
|
|
@ -824,7 +824,7 @@ protected void SetLinkTradeEgg(int day, int month, int year, ushort location)
|
|||
/// </summary>
|
||||
/// <param name="move">Move ID</param>
|
||||
/// <returns>Amount of PP the move has by default (no PP Ups).</returns>
|
||||
private int GetBasePP(ushort move) => MoveInfo.GetPP(Context, move);
|
||||
public int GetBasePP(ushort move) => MoveInfo.GetPP(Context, move);
|
||||
|
||||
/// <summary>
|
||||
/// Applies a shiny <see cref="PID"/> to the <see cref="PKM"/>.
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ public SCBlockMetadata(SCBlockAccessor accessor, IEnumerable<string> extraKeyNam
|
|||
BlockList = aType.GetAllPropertiesOfType<IDataIndirect>(accessor);
|
||||
ValueList = aType.GetAllConstantsOfType<uint>();
|
||||
AddExtraKeyNames(ValueList, extraKeyNames);
|
||||
if (exclusions.Length > 0)
|
||||
if (exclusions.Length != 0)
|
||||
ValueList = ValueList.Where(z => !exclusions.Any(z.Value.Contains)).ToDictionary();
|
||||
Accessor = accessor;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,9 +53,9 @@ public sealed record SaveFileMetadata(SaveFile SAV)
|
|||
/// <returns>Final save file data.</returns>
|
||||
public byte[] Finalize(byte[] data, BinaryExportSetting setting)
|
||||
{
|
||||
if (Footer.Length > 0 && setting.HasFlag(BinaryExportSetting.IncludeFooter))
|
||||
if (Footer.Length != 0 && setting.HasFlag(BinaryExportSetting.IncludeFooter))
|
||||
data = [..data, ..Footer];
|
||||
if (Header.Length > 0 && setting.HasFlag(BinaryExportSetting.IncludeHeader))
|
||||
if (Header.Length != 0 && setting.HasFlag(BinaryExportSetting.IncludeHeader))
|
||||
data = [..Header, ..data];
|
||||
if (setting != BinaryExportSetting.None)
|
||||
Handler?.Finalize(data);
|
||||
|
|
|
|||
|
|
@ -686,7 +686,7 @@ private void ClickGT(object? sender, EventArgs e)
|
|||
byte handler = 0;
|
||||
if (sender == GB_OT)
|
||||
handler = 0;
|
||||
else if (TB_HT.Text.Length > 0)
|
||||
else if (TB_HT.Text.Length != 0)
|
||||
handler = 1;
|
||||
UpdateHandlerSelected(handler);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -871,7 +871,7 @@ private void ClickVerifyCHK(object sender, EventArgs e)
|
|||
|
||||
private void ClickVerifyStoredEntities(object sender, EventArgs e)
|
||||
{
|
||||
var bulk = new Core.Bulk.BulkAnalysis(SAV, Main.Settings.Bulk);
|
||||
var bulk = new Core.Bulk.BulkAnalysis(SAV, Main.Settings.Legality.Bulk);
|
||||
if (bulk.Valid)
|
||||
{
|
||||
WinFormsUtil.Alert("Clean!");
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ private static (string Detail, string Encounter) GetStatsString(PKM pk, Legality
|
|||
if (remaining[^1] == ')')
|
||||
remaining = remaining[..^3]; // lop off gender
|
||||
var item = remaining.Trim();
|
||||
if (item.Length > 0)
|
||||
if (item.Length != 0)
|
||||
sb.AppendLine($"Held Item: {item}");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ private static void FormLoadConfig(out bool BAKprompt, out bool showChangelog)
|
|||
showChangelog = false;
|
||||
|
||||
// Version Check
|
||||
if (Settings.Startup.Version.Length > 0 && Settings.Startup.ShowChangelogOnUpdate) // already run on system
|
||||
if (Settings.Startup.Version.Length != 0 && Settings.Startup.ShowChangelogOnUpdate) // already run on system
|
||||
{
|
||||
bool parsed = Version.TryParse(Settings.Startup.Version, out var lastrev);
|
||||
showChangelog = parsed && lastrev < Program.CurrentVersion;
|
||||
|
|
@ -422,7 +422,7 @@ private void ReloadProgramSettings(PKHeXSettings settings)
|
|||
CommonEdits.ShowdownSetBehaviorNature = settings.Import.ApplyNature;
|
||||
C_SAV.FlagIllegal = settings.Display.FlagIllegal;
|
||||
C_SAV.M.Hover.GlowHover = settings.Hover.HoverSlotGlowEdges;
|
||||
ParseSettings.InitFromSettings(settings.Legality);
|
||||
ParseSettings.Initialize(settings.Legality);
|
||||
PKME_Tabs.HideSecretValues = C_SAV.HideSecretDetails = settings.Privacy.HideSecretDetails;
|
||||
WinFormsUtil.DetectSaveFileOnFileOpen = settings.Startup.TryDetectRecentSave;
|
||||
SelectablePictureBox.FocusBorderDeflate = GenderToggle.FocusBorderDeflate = settings.Display.FocusBorderDeflate;
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ public sealed class PKHeXSettings
|
|||
public EntityDatabaseSettings EntityDb { get; set; } = new();
|
||||
public EncounterDatabaseSettings EncounterDb { get; set; } = new();
|
||||
public MysteryGiftDatabaseSettings MysteryDb { get; set; } = new();
|
||||
public BulkAnalysisSettings Bulk { get; set; } = new();
|
||||
|
||||
[Browsable(false)]
|
||||
public SlotExportSettings SlotExport { get; set; } = new();
|
||||
|
|
@ -204,48 +203,6 @@ public enum PluginLoadSetting
|
|||
UnsafeMerged,
|
||||
}
|
||||
|
||||
public sealed class LegalitySettings : IParseSettings
|
||||
{
|
||||
[LocalizedDescription("Checks player given Nicknames and Trainer Names for profanity. Bad words will be flagged using the 3DS console's regex lists.")]
|
||||
public bool CheckWordFilter { get; set; } = true;
|
||||
|
||||
[LocalizedDescription("Checks the last loaded player save file data and Current Handler state to determine if the Pokémon's Current Handler does not match the expected value.")]
|
||||
public bool CheckActiveHandler { get; set; }
|
||||
|
||||
[LocalizedDescription("GB: Allow Generation 2 tradeback learnsets for PK1 formats. Disable when checking RBY Metagame rules.")]
|
||||
public bool AllowGen1Tradeback { get; set; } = true;
|
||||
|
||||
[LocalizedDescription("Severity to flag a Legality Check if it is a nicknamed In-Game Trade the player cannot normally nickname.")]
|
||||
public Severity NicknamedTrade { get; set; } = Severity.Invalid;
|
||||
|
||||
[LocalizedDescription("Severity to flag a Legality Check if it is a nicknamed Mystery Gift the player cannot normally nickname.")]
|
||||
public Severity NicknamedMysteryGift { get; set; } = Severity.Fishy;
|
||||
|
||||
[LocalizedDescription("Severity to flag a Legality Check if the RNG Frame Checking logic does not find a match for Generation 3 encounters.")]
|
||||
public Severity RNGFrameNotFound3 { get; set; } = Severity.Fishy;
|
||||
|
||||
[LocalizedDescription("Severity to flag a Legality Check if the RNG Frame Checking logic does not find a match for Generation 4 encounters.")]
|
||||
public Severity RNGFrameNotFound4 { get; set; } = Severity.Invalid;
|
||||
|
||||
[LocalizedDescription("Severity to flag a Legality Check if Pokémon from Gen1/2 has a Star Shiny PID.")]
|
||||
public Severity Gen7TransferStarPID { get; set; } = Severity.Fishy;
|
||||
|
||||
[LocalizedDescription("Severity to flag a Legality Check if a Gen8 Memory is missing for the Handling Trainer.")]
|
||||
public Severity Gen8MemoryMissingHT { get; set; } = Severity.Fishy;
|
||||
|
||||
[LocalizedDescription("Severity to flag a Legality Check if the HOME Tracker is Missing")]
|
||||
public Severity HOMETransferTrackerNotPresent { get; set; } = Severity.Invalid;
|
||||
|
||||
[LocalizedDescription("Severity to flag a Legality Check if Pokémon has a Nickname matching another Species.")]
|
||||
public Severity NicknamedAnotherSpecies { get; set; } = Severity.Fishy;
|
||||
|
||||
[LocalizedDescription("Severity to flag a Legality Check if Pokémon has a zero value for both Height and Weight.")]
|
||||
public Severity ZeroHeightWeight { get; set; } = Severity.Fishy;
|
||||
|
||||
[LocalizedDescription("Severity to flag a Legality Check if Pokémon's Current Handler does not match the expected value.")]
|
||||
public Severity CurrentHandlerMismatch { get; set; } = Severity.Invalid;
|
||||
}
|
||||
|
||||
public sealed class EntityConverterSettings
|
||||
{
|
||||
[LocalizedDescription("Allow PKM file conversion paths that are not possible via official methods. Individual properties will be copied sequentially.")]
|
||||
|
|
@ -508,12 +465,6 @@ public void Apply()
|
|||
}
|
||||
}
|
||||
|
||||
public sealed class BulkAnalysisSettings : IBulkAnalysisSettings
|
||||
{
|
||||
[LocalizedDescription("Checks the save file data and Current Handler state to determine if the Pokémon's Current Handler does not match the expected value.")]
|
||||
public bool CheckActiveHandler { get; set; } = true;
|
||||
}
|
||||
|
||||
public sealed class SlotExportSettings
|
||||
{
|
||||
[LocalizedDescription("Settings to use for box exports.")]
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ private void B_Add_Click(object sender, EventArgs e)
|
|||
// If we already have text, add a new line (except if the last line is blank).
|
||||
var tb = RTB_Instructions;
|
||||
var batchText = tb.Text;
|
||||
if (batchText.Length > 0 && !batchText.EndsWith('\n'))
|
||||
if (batchText.Length != 0 && !batchText.EndsWith('\n'))
|
||||
tb.AppendText(Environment.NewLine);
|
||||
RTB_Instructions.AppendText(s);
|
||||
}
|
||||
|
|
@ -111,7 +111,7 @@ private void RunBackgroundWorker()
|
|||
{ WinFormsUtil.Error(MsgBEInstructionNone); return; }
|
||||
|
||||
var emptyVal = sets.SelectMany(s => s.Instructions.Where(z => string.IsNullOrWhiteSpace(z.PropertyValue))).ToArray();
|
||||
if (emptyVal.Length > 0)
|
||||
if (emptyVal.Length != 0)
|
||||
{
|
||||
string props = string.Join(", ", emptyVal.Select(z => z.PropertyName));
|
||||
string invalid = MsgBEPropertyEmpty + Environment.NewLine + props;
|
||||
|
|
|
|||
|
|
@ -593,11 +593,11 @@ private async void B_Search_Click(object sender, EventArgs e)
|
|||
var search = SearchDatabase();
|
||||
|
||||
bool legalSearch = Menu_SearchLegal.Checked ^ Menu_SearchIllegal.Checked;
|
||||
bool wordFilter = ParseSettings.CheckWordFilter;
|
||||
bool wordFilter = ParseSettings.Settings.WordFilter.CheckWordFilter;
|
||||
if (wordFilter && legalSearch && WinFormsUtil.Prompt(MessageBoxButtons.YesNo, MsgDBSearchLegalityWordfilter) == DialogResult.No)
|
||||
ParseSettings.CheckWordFilter = false;
|
||||
ParseSettings.Settings.WordFilter.CheckWordFilter = false;
|
||||
var results = await Task.Run(() => search.ToList()).ConfigureAwait(true);
|
||||
ParseSettings.CheckWordFilter = wordFilter;
|
||||
ParseSettings.Settings.WordFilter.CheckWordFilter = wordFilter;
|
||||
|
||||
if (results.Count == 0)
|
||||
{
|
||||
|
|
@ -783,7 +783,7 @@ private void B_Add_Click(object sender, EventArgs e)
|
|||
// If we already have text, add a new line (except if the last line is blank).
|
||||
var tb = RTB_Instructions;
|
||||
var batchText = tb.Text;
|
||||
if (batchText.Length > 0 && !batchText.EndsWith('\n'))
|
||||
if (batchText.Length != 0 && !batchText.EndsWith('\n'))
|
||||
tb.AppendText(Environment.NewLine);
|
||||
tb.AppendText(s);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -283,7 +283,7 @@ private IEnumerable<IEncounterInfo> SearchDatabase(CancellationToken token)
|
|||
return results;
|
||||
|
||||
ReadOnlySpan<char> batchText = RTB_Instructions.Text;
|
||||
if (batchText.Length > 0 && !StringInstructionSet.HasEmptyLine(batchText))
|
||||
if (batchText.Length != 0 && !StringInstructionSet.HasEmptyLine(batchText))
|
||||
{
|
||||
var filters = StringInstruction.GetFilters(batchText);
|
||||
BatchEditing.ScreenStrings(filters);
|
||||
|
|
@ -503,8 +503,8 @@ private void B_Add_Click(object sender, EventArgs e)
|
|||
// If we already have text, add a new line (except if the last line is blank).
|
||||
var tb = RTB_Instructions;
|
||||
var batchText = tb.Text;
|
||||
if (batchText.Length > 0 && !batchText.EndsWith('\n'))
|
||||
if (batchText.Length != 0 && !batchText.EndsWith('\n'))
|
||||
tb.AppendText(Environment.NewLine);
|
||||
RTB_Instructions.AppendText(s);
|
||||
tb.AppendText(s);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -342,7 +342,7 @@ private void B_Search_Click(object sender, EventArgs e)
|
|||
slotSelected = -1; // reset the slot last viewed
|
||||
|
||||
ReadOnlySpan<char> batchText = RTB_Instructions.Text;
|
||||
if (batchText.Length > 0 && !StringInstructionSet.HasEmptyLine(batchText))
|
||||
if (batchText.Length != 0 && !StringInstructionSet.HasEmptyLine(batchText))
|
||||
{
|
||||
var filters = StringInstruction.GetFilters(batchText);
|
||||
BatchEditing.ScreenStrings(filters);
|
||||
|
|
@ -472,8 +472,8 @@ private void B_Add_Click(object sender, EventArgs e)
|
|||
// If we already have text, add a new line (except if the last line is blank).
|
||||
var tb = RTB_Instructions;
|
||||
var batchText = tb.Text;
|
||||
if (batchText.Length > 0 && !batchText.EndsWith('\n'))
|
||||
if (batchText.Length != 0 && !batchText.EndsWith('\n'))
|
||||
tb.AppendText(Environment.NewLine);
|
||||
RTB_Instructions.AppendText(s);
|
||||
tb.AppendText(s);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ static string Format(ReadOnlySpan<ushort> items, ReadOnlySpan<string> names)
|
|||
var sbAdd = new StringBuilder();
|
||||
foreach (var item in items)
|
||||
{
|
||||
if (sbAdd.Length > 0)
|
||||
if (sbAdd.Length != 0)
|
||||
sbAdd.Append(", ");
|
||||
sbAdd.Append(names[item]);
|
||||
}
|
||||
|
|
@ -170,7 +170,7 @@ static string Format(ReadOnlySpan<ushort> items, ReadOnlySpan<string> names)
|
|||
}
|
||||
var added = Format(missing, itemlist);
|
||||
var addmsg = $"Add the following items?{Environment.NewLine}{added}";
|
||||
if (have.Length > 0)
|
||||
if (have.Length != 0)
|
||||
{
|
||||
string had = Format(have, itemlist);
|
||||
var havemsg = $"Already have:{Environment.NewLine}{had}";
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ private void SetEntry()
|
|||
}
|
||||
|
||||
var forms = SAV.Dex.GetForms(species);
|
||||
if (forms.Length > 0)
|
||||
if (forms.Length != 0)
|
||||
{
|
||||
var items = LB_Form.Items;
|
||||
Span<byte> arr = stackalloc byte[items.Count];
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ private void ChangeBoxDetails(object sender, EventArgs e)
|
|||
|
||||
private void B_Save_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (flagArr.Length > 0)
|
||||
if (flagArr.Length != 0)
|
||||
SAV.BoxFlags = Array.ConvertAll(flagArr, i => (byte)i.Value);
|
||||
if (CB_Unlocked.Visible)
|
||||
SAV.BoxesUnlocked = CB_Unlocked.SelectedIndex;
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ private void FillTrainingBags()
|
|||
{
|
||||
foreach (string t in trba)
|
||||
{
|
||||
if (t.Length > 0)
|
||||
if (t.Length != 0)
|
||||
dgvBag.Items.Add(t);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@ private void B_Save_Click(object sender, EventArgs e)
|
|||
|
||||
private void ChangeSAV()
|
||||
{
|
||||
if (TB_NewSAV.Text.Length > 0 && TB_OldSAV.Text.Length > 0)
|
||||
if (TB_NewSAV.Text.Length != 0 && TB_OldSAV.Text.Length != 0)
|
||||
DiffSaves();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ private void ChangeCustomConst(object sender, EventArgs e)
|
|||
|
||||
private void ChangeSAV(object sender, EventArgs e)
|
||||
{
|
||||
if (TB_NewSAV.Text.Length > 0 && TB_OldSAV.Text.Length > 0)
|
||||
if (TB_NewSAV.Text.Length != 0 && TB_OldSAV.Text.Length != 0)
|
||||
DiffSaves();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ private void ChangeCustomConst(object sender, EventArgs e)
|
|||
|
||||
private void ChangeSAV(object sender, EventArgs e)
|
||||
{
|
||||
if (TB_NewSAV.Text.Length > 0 && TB_OldSAV.Text.Length > 0)
|
||||
if (TB_NewSAV.Text.Length != 0 && TB_OldSAV.Text.Length != 0)
|
||||
DiffSaves();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ private void ChangeConstantIndex(object sender, EventArgs e)
|
|||
|
||||
private void ChangeSAV()
|
||||
{
|
||||
if (TB_NewSAV.Text.Length > 0 && TB_OldSAV.Text.Length > 0)
|
||||
if (TB_NewSAV.Text.Length != 0 && TB_OldSAV.Text.Length != 0)
|
||||
DiffSaves();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -179,9 +179,9 @@ private void LoadAllBags()
|
|||
var outOfBounds = Array.FindAll(invalid, item => item.Index >= itemlist.Length);
|
||||
var incorrectPouch = Array.FindAll(invalid, item => item.Index < itemlist.Length);
|
||||
|
||||
if (outOfBounds.Length > 0)
|
||||
if (outOfBounds.Length != 0)
|
||||
WinFormsUtil.Error(MsgItemPouchUnknown, $"Item ID(s): {string.Join(", ", outOfBounds.Select(item => item.Index))}");
|
||||
if (!Main.HaX && incorrectPouch.Length > 0)
|
||||
if (!Main.HaX && incorrectPouch.Length != 0)
|
||||
WinFormsUtil.Alert(string.Format(MsgItemPouchRemoved, pouch.Type), string.Join(", ", incorrectPouch.Select(item => itemlist[item.Index])), MsgItemPouchWarning);
|
||||
|
||||
pouch.Sanitize(itemlist.Length - 1, Main.HaX);
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ private static void VerifyAll(string folder, string subFolder, bool isValid, boo
|
|||
|
||||
var dn = fi.DirectoryName ?? string.Empty;
|
||||
ParseSettings.AllowGBCartEra = dn.Contains("GBCartEra");
|
||||
ParseSettings.AllowGen1Tradeback = dn.Contains("1 Tradeback");
|
||||
ParseSettings.Settings.Tradeback.AllowGen1Tradeback = dn.Contains("1 Tradeback");
|
||||
var pk = EntityFormat.GetFromBytes(data, prefer);
|
||||
pk.Should().NotBeNull($"the PKM '{new FileInfo(file).Name}' should have been loaded");
|
||||
if (pk == null)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ public static string GetRepoPath()
|
|||
|
||||
public static void InitializeLegality()
|
||||
{
|
||||
ParseSettings.Settings.Handler.CheckActiveHandler = false; // not checking in context of saves
|
||||
lock (InitLock)
|
||||
{
|
||||
if (IsInitialized)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user