mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-08-26 01:25:09 -05:00
Misc tweaks
Make nick/trainer'd encounters use RoM instead of string[] to truly make them readonly records, and skip 1 dereference on access add some xmldoc fix open file suggesting main from another folder
This commit is contained in:
@@ -124,10 +124,12 @@ public static void SetRecordFlagsAll(this ITechRecord pk, ReadOnlySpan<EvoCriter
|
||||
_ => false,
|
||||
};
|
||||
|
||||
/// <inheritdoc cref="SetRecordFlags(ITechRecord, PKM, TechnicalRecordApplicatorOption, LegalityAnalysis)"/>
|
||||
public static void SetRecordFlags<T>(this T pk, TechnicalRecordApplicatorOption option)
|
||||
where T : PKM, ITechRecord
|
||||
=> SetRecordFlags(pk, pk, option);
|
||||
|
||||
/// <inheritdoc cref="SetRecordFlags(ITechRecord, PKM, TechnicalRecordApplicatorOption, LegalityAnalysis)"/>
|
||||
public static void SetRecordFlags(this ITechRecord record, PKM pk, TechnicalRecordApplicatorOption option)
|
||||
{
|
||||
record.ClearRecordFlags();
|
||||
@@ -142,6 +144,13 @@ public static void SetRecordFlags(this ITechRecord record, PKM pk, TechnicalReco
|
||||
SetRecordFlagsInternal(record, pk, option, la);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies the Technical Record flags based on the <see cref="option"/>.
|
||||
/// </summary>
|
||||
/// <param name="record">Object to apply to.</param>
|
||||
/// <param name="pk">Object to apply to, but base type for other logic.</param>
|
||||
/// <param name="option">Option to apply.</param>
|
||||
/// <param name="la">Legality analysis to use for the option.</param>
|
||||
public static void SetRecordFlags(this ITechRecord record, PKM pk, TechnicalRecordApplicatorOption option, LegalityAnalysis la)
|
||||
{
|
||||
record.ClearRecordFlags();
|
||||
@@ -172,10 +181,28 @@ private static void SetRecordFlagsInternal(ITechRecord record, PKM pk, Technical
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Options for applying Technical Record flags.
|
||||
/// </summary>
|
||||
public enum TechnicalRecordApplicatorOption
|
||||
{
|
||||
/// <summary>
|
||||
/// Do not apply any flags. Clear all flags.
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// Apply all flags, regardless of legality.
|
||||
/// </summary>
|
||||
ForceAll,
|
||||
|
||||
/// <summary>
|
||||
/// Apply legal flags based on the current moves.
|
||||
/// </summary>
|
||||
LegalCurrent,
|
||||
|
||||
/// <summary>
|
||||
/// Apply legal flags based on all moves able to learn in the game it resides in.
|
||||
/// </summary>
|
||||
LegalAll,
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace PKHeX.Core;
|
||||
|
||||
@@ -25,17 +27,12 @@ public sealed class TrainerDatabase
|
||||
return GetTrainerFromGroup(version, language);
|
||||
|
||||
if (Database.TryGetValue(version, out var list))
|
||||
return GetRandomChoice(list);
|
||||
return list[GetRandomIndex(list.Count)];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static T GetRandomChoice<T>(IReadOnlyList<T> list)
|
||||
{
|
||||
if (list.Count == 1)
|
||||
return list[0];
|
||||
return list[Util.Rand.Next(list.Count)];
|
||||
}
|
||||
private static int GetRandomIndex(int count) => count == 1 ? 0 : Util.Rand.Next(count);
|
||||
|
||||
/// <summary>
|
||||
/// Fetches an appropriate trainer based on the requested <see cref="version"/> group.
|
||||
@@ -57,7 +54,8 @@ private static T GetRandomChoice<T>(IReadOnlyList<T> list)
|
||||
return new KeyValuePair<GameVersion, List<ITrainerInfo>>(z.Key, filtered);
|
||||
}).Where(z => z.Value.Count != 0).ToList();
|
||||
}
|
||||
return GetRandomTrainer(possible);
|
||||
var span = CollectionsMarshal.AsSpan(possible);
|
||||
return GetRandomTrainer(span);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -80,15 +78,17 @@ private static T GetRandomChoice<T>(IReadOnlyList<T> list)
|
||||
return new KeyValuePair<GameVersion, List<ITrainerInfo>>(z.Key, filtered);
|
||||
}).Where(z => z.Value.Count != 0).ToList();
|
||||
}
|
||||
return GetRandomTrainer(possible);
|
||||
var span = CollectionsMarshal.AsSpan(possible);
|
||||
return GetRandomTrainer(span);
|
||||
}
|
||||
|
||||
private static ITrainerInfo? GetRandomTrainer(IReadOnlyList<KeyValuePair<GameVersion, List<ITrainerInfo>>> possible)
|
||||
private static ITrainerInfo? GetRandomTrainer(ReadOnlySpan<KeyValuePair<GameVersion, List<ITrainerInfo>>> possible)
|
||||
{
|
||||
if (possible.Count == 0)
|
||||
if (possible.Length == 0)
|
||||
return null;
|
||||
var group = GetRandomChoice(possible);
|
||||
return GetRandomChoice(group.Value);
|
||||
var group = possible[GetRandomIndex(possible.Length)];
|
||||
var span = group.Value;
|
||||
return span[GetRandomIndex(span.Count)];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -723,6 +723,7 @@ private string[] GetItemStrings9()
|
||||
|
||||
static void InsertZero(Span<string> arr, string insert)
|
||||
{
|
||||
// TM #'s are always ending with ##, so insert before the last 2 characters
|
||||
foreach (ref var str in arr)
|
||||
str = str.Insert(str.Length - 2, insert);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace PKHeX.Core.Bulk;
|
||||
|
||||
@@ -36,7 +37,7 @@ public BulkAnalysis(SaveFile sav, BulkAnalysisSettings settings)
|
||||
SlotInfoLoader.AddFromSaveFile(sav, list);
|
||||
list.RemoveAll(IsEmptyData);
|
||||
AllData = list;
|
||||
AllAnalysis = GetIndividualAnalysis(list);
|
||||
AllAnalysis = GetIndividualAnalysis(CollectionsMarshal.AsSpan(list));
|
||||
CloneFlags = new bool[AllData.Count];
|
||||
|
||||
ScanAll();
|
||||
@@ -95,12 +96,12 @@ public void AddLine(SlotCache first, string msg, CheckIdentifier i, Severity s =
|
||||
Parse.Add(chk);
|
||||
}
|
||||
|
||||
private static LegalityAnalysis[] GetIndividualAnalysis(IReadOnlyList<SlotCache> pkms)
|
||||
private static LegalityAnalysis[] GetIndividualAnalysis(ReadOnlySpan<SlotCache> list)
|
||||
{
|
||||
var results = new LegalityAnalysis[pkms.Count];
|
||||
for (int i = 0; i < pkms.Count; i++)
|
||||
results[i] = Get(pkms[i]);
|
||||
return results;
|
||||
var result = new LegalityAnalysis[list.Length];
|
||||
for (int i = 0; i < list.Length; i++)
|
||||
result[i] = Get(list[i]);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static LegalityAnalysis Get(SlotCache cache) => new(cache.Entity, cache.SAV.Personal, cache.Source.Type);
|
||||
|
||||
@@ -8,13 +8,13 @@ internal static class Encounters1GBEra
|
||||
|
||||
private static EncounterGift1[] GetGifts(ReadOnlySpan<byte> bin)
|
||||
{
|
||||
const int Size = EncounterGift1.SerializedSize;
|
||||
var result = new EncounterGift1[bin.Length / Size];
|
||||
const int size = EncounterGift1.SerializedSize;
|
||||
var result = new EncounterGift1[bin.Length / size];
|
||||
for (int i = 0; i < result.Length; i++)
|
||||
{
|
||||
var data = bin[..Size];
|
||||
var data = bin[..size];
|
||||
result[i] = new EncounterGift1(data);
|
||||
bin = bin[Size..];
|
||||
bin = bin[size..];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -8,13 +8,13 @@ internal static class Encounters2GBEra
|
||||
|
||||
private static EncounterGift2[] GetGifts(ReadOnlySpan<byte> bin)
|
||||
{
|
||||
const int Size = EncounterGift2.SerializedSize;
|
||||
var result = new EncounterGift2[bin.Length / Size];
|
||||
const int size = EncounterGift2.SerializedSize;
|
||||
var result = new EncounterGift2[bin.Length / size];
|
||||
for (int i = 0; i < result.Length; i++)
|
||||
{
|
||||
var data = bin[..Size];
|
||||
var data = bin[..size];
|
||||
result[i] = new EncounterGift2(data);
|
||||
bin = bin[Size..];
|
||||
bin = bin[size..];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace PKHeX.Core;
|
||||
/// Generation 3 <see cref="EncounterGift3"/> Gifts
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Generation 3 has a wide range of PIDIV types and other restrictions, and was never consistently stored in raw bytes.
|
||||
/// Generation 3 has a wide range of PID/IV types and other restrictions, and was never consistently stored in raw bytes.
|
||||
/// Normally we'd just load the data from a binary, but without raw data... hard-code everything by hand.
|
||||
/// </remarks>
|
||||
internal static class EncountersWC3
|
||||
|
||||
@@ -72,7 +72,7 @@ public static void FindVerifiedEncounter(PKM pk, LegalInfo info)
|
||||
{
|
||||
if (!info.FrameMatches) // if false, all valid RNG frame matches have already been consumed
|
||||
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
|
||||
else if (!info.PIDIVMatches) // if false, all valid PID/IV matches have already been consumed
|
||||
info.Parse.Add(new CheckResult(Severity.Invalid, CheckIdentifier.PID, LPIDTypeMismatch));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,7 +300,7 @@ public bool IsWithinDistributionWindow(DateOnly date)
|
||||
return this.IsWithinStartEnd(stamp);
|
||||
}
|
||||
|
||||
private bool IsFormArgIncorrect(ISpeciesForm pk) => Species switch
|
||||
private bool IsFormArgIncorrect<T>(T pk) where T : ISpeciesForm => Species switch
|
||||
{
|
||||
// Evolved without Form Argument changing from default
|
||||
(int)Yamask when pk.Species != Species && Form == 1 => pk is IFormArgument { FormArgument: 0 },
|
||||
|
||||
@@ -23,7 +23,7 @@ public sealed record EncounterTrade1 : IEncounterable, IEncounterMatch, IFixedTr
|
||||
public bool IsFixedTrainer => true;
|
||||
public bool IsFixedNickname => true;
|
||||
|
||||
private string[] Nicknames { get; }
|
||||
private readonly ReadOnlyMemory<string> Nicknames;
|
||||
public ushort Species { get; }
|
||||
public byte Form => 0;
|
||||
public bool EvolveOnTrade { get; init; }
|
||||
@@ -61,7 +61,7 @@ private bool IsNicknameValid(PKM pk, ReadOnlySpan<char> nick)
|
||||
// Special consideration for Hiragana strings that are transferred
|
||||
if (Version == GameVersion.YW && Species == (int)Core.Species.Dugtrio)
|
||||
return nick is "ぐりお";
|
||||
return nick.SequenceEqual(Nicknames[1]);
|
||||
return nick.SequenceEqual(Nicknames.Span[(int)LanguageID.Japanese]);
|
||||
}
|
||||
|
||||
return GetNicknameIndex(nick) >= 2;
|
||||
@@ -83,7 +83,7 @@ private static bool IsTrainerNameValid(PKM pk)
|
||||
return trainer.SequenceEqual(expect);
|
||||
}
|
||||
|
||||
private int GetNicknameIndex(ReadOnlySpan<char> nickname) => GetIndex(nickname, Nicknames);
|
||||
private int GetNicknameIndex(ReadOnlySpan<char> nickname) => GetIndex(nickname, Nicknames.Span);
|
||||
|
||||
private static int GetIndex(ReadOnlySpan<char> name, ReadOnlySpan<string> arr)
|
||||
{
|
||||
@@ -125,7 +125,7 @@ public PK1 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
CatchRate = pi.CatchRate,
|
||||
DV16 = EncounterUtil.GetRandomDVs(Util.Rand),
|
||||
|
||||
Nickname = Nicknames[lang],
|
||||
Nickname = Nicknames.Span[lang],
|
||||
TID16 = tr.TID16,
|
||||
Type1 = pi.Type1,
|
||||
Type2 = pi.Type2,
|
||||
@@ -145,7 +145,7 @@ public PK1 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
#region Matching
|
||||
public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int language) => IsTrainerNameValid(pk);
|
||||
public bool IsNicknameMatch(PKM pk, ReadOnlySpan<char> nickname, int language) => IsNicknameValid(pk, nickname);
|
||||
public string GetNickname(int language) => (uint)language < Nicknames.Length ? Nicknames[language] : Nicknames[0];
|
||||
public string GetNickname(int language) => Nicknames.Span[(uint)language < Nicknames.Length ? language : 0];
|
||||
|
||||
public EncounterMatchRating GetMatchRating(PKM pk)
|
||||
{
|
||||
|
||||
@@ -256,7 +256,7 @@ private static bool IsTrainerName(PKM pk, [ConstantExpected] string name)
|
||||
return ot[..len].SequenceEqual(name);
|
||||
}
|
||||
|
||||
private bool IsTrainerIDValid(ITrainerID16 pk) => Trainer switch
|
||||
private bool IsTrainerIDValid<T>(T pk) where T : ITrainerID16 => Trainer switch
|
||||
{
|
||||
Recipient => true,
|
||||
GiftStadiumJPN => pk.TID16 == TrainerIDStadiumJPN,
|
||||
|
||||
@@ -29,8 +29,8 @@ public sealed record EncounterTrade2 : IEncounterable, IEncounterMatch, IFixedTr
|
||||
public byte LevelMin => Level;
|
||||
public byte LevelMax => 100;
|
||||
|
||||
private string[] TrainerNames { get; }
|
||||
private string[] Nicknames { get; }
|
||||
private readonly ReadOnlyMemory<string> TrainerNames;
|
||||
private readonly ReadOnlyMemory<string> Nicknames;
|
||||
|
||||
public byte Gender { get; init; }
|
||||
public byte OTGender { get; init; }
|
||||
@@ -66,8 +66,8 @@ public PK2 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
|
||||
MetLocation = Location,
|
||||
|
||||
Nickname = Nicknames[lang],
|
||||
OriginalTrainerName = TrainerNames[lang],
|
||||
Nickname = Nicknames.Span[lang],
|
||||
OriginalTrainerName = TrainerNames.Span[lang],
|
||||
OriginalTrainerFriendship = pi.BaseFriendship,
|
||||
};
|
||||
|
||||
@@ -151,17 +151,17 @@ private int DetectLanguage(PKM pk, ReadOnlySpan<char> trainer, ReadOnlySpan<char
|
||||
{
|
||||
if (pk.Japanese)
|
||||
{
|
||||
if (!nickname.SequenceEqual(Nicknames[(int)LanguageID.Japanese]))
|
||||
if (!nickname.SequenceEqual(Nicknames.Span[(int)LanguageID.Japanese]))
|
||||
return -1;
|
||||
if (!trainer.SequenceEqual(TrainerNames[(int)LanguageID.Japanese]))
|
||||
if (!trainer.SequenceEqual(TrainerNames.Span[(int)LanguageID.Japanese]))
|
||||
return -1;
|
||||
return (int)LanguageID.Japanese;
|
||||
}
|
||||
if (pk.Korean)
|
||||
{
|
||||
if (!nickname.SequenceEqual(Nicknames[(int)LanguageID.Korean]))
|
||||
if (!nickname.SequenceEqual(Nicknames.Span[(int)LanguageID.Korean]))
|
||||
return -1;
|
||||
if (!trainer.SequenceEqual(TrainerNames[(int)LanguageID.Korean]))
|
||||
if (!trainer.SequenceEqual(TrainerNames.Span[(int)LanguageID.Korean]))
|
||||
return -1;
|
||||
return (int)LanguageID.Korean;
|
||||
}
|
||||
@@ -170,7 +170,7 @@ private int DetectLanguage(PKM pk, ReadOnlySpan<char> trainer, ReadOnlySpan<char
|
||||
{
|
||||
if (i == (int)LanguageID.UNUSED_6)
|
||||
continue;
|
||||
if (!nickname.SequenceEqual(Nicknames[i]))
|
||||
if (!nickname.SequenceEqual(Nicknames.Span[i]))
|
||||
continue;
|
||||
if (IsTrainerMatchExact(pk, trainer, i))
|
||||
return i;
|
||||
@@ -180,24 +180,25 @@ private int DetectLanguage(PKM pk, ReadOnlySpan<char> trainer, ReadOnlySpan<char
|
||||
|
||||
private int DetectLanguageNickname(PKM pk, ReadOnlySpan<char> nickname)
|
||||
{
|
||||
var names = Nicknames.Span;
|
||||
if (pk.Japanese)
|
||||
{
|
||||
if (!nickname.SequenceEqual(Nicknames[(int)LanguageID.Japanese]))
|
||||
if (!nickname.SequenceEqual(names[(int)LanguageID.Japanese]))
|
||||
return -1;
|
||||
return (int)LanguageID.Japanese;
|
||||
}
|
||||
if (pk.Korean)
|
||||
{
|
||||
if (!nickname.SequenceEqual(Nicknames[(int)LanguageID.Korean]))
|
||||
if (!nickname.SequenceEqual(names[(int)LanguageID.Korean]))
|
||||
return -1;
|
||||
return (int)LanguageID.Korean;
|
||||
}
|
||||
|
||||
for (int i = 2; i < Nicknames.Length; i++)
|
||||
for (int i = 2; i < names.Length; i++)
|
||||
{
|
||||
if (i == (int)LanguageID.UNUSED_6)
|
||||
continue;
|
||||
if (nickname.SequenceEqual(Nicknames[i]))
|
||||
if (nickname.SequenceEqual(names[i]))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
@@ -205,20 +206,21 @@ private int DetectLanguageNickname(PKM pk, ReadOnlySpan<char> nickname)
|
||||
|
||||
private int DetectLanguageTrainer(PKM pk, ReadOnlySpan<char> trainer)
|
||||
{
|
||||
var names = TrainerNames.Span;
|
||||
if (pk.Japanese)
|
||||
{
|
||||
if (!trainer.SequenceEqual(TrainerNames[(int)LanguageID.Japanese]))
|
||||
if (!trainer.SequenceEqual(names[(int)LanguageID.Japanese]))
|
||||
return -1;
|
||||
return (int)LanguageID.Japanese;
|
||||
}
|
||||
if (pk.Korean)
|
||||
{
|
||||
if (!trainer.SequenceEqual(TrainerNames[(int)LanguageID.Korean]))
|
||||
if (!trainer.SequenceEqual(names[(int)LanguageID.Korean]))
|
||||
return -1;
|
||||
return (int)LanguageID.Korean;
|
||||
}
|
||||
|
||||
for (int i = 2; i < TrainerNames.Length; i++)
|
||||
for (int i = 2; i < names.Length; i++)
|
||||
{
|
||||
if (i == (int)LanguageID.UNUSED_6)
|
||||
continue;
|
||||
@@ -230,7 +232,7 @@ private int DetectLanguageTrainer(PKM pk, ReadOnlySpan<char> trainer)
|
||||
|
||||
private bool IsTrainerMatchExact(PKM pk, ReadOnlySpan<char> trainer, int language)
|
||||
{
|
||||
var expect = pk.Format < 7 ? TrainerNames[language] : GetExpectedOT(Species, language, pk.Language);
|
||||
var expect = pk.Format < 7 ? TrainerNames.Span[language] : GetExpectedOT(Species, language, pk.Language);
|
||||
return trainer.SequenceEqual(expect);
|
||||
}
|
||||
|
||||
@@ -239,7 +241,7 @@ private bool IsTrainerMatchExact(PKM pk, ReadOnlySpan<char> trainer, int languag
|
||||
// Can't transfer verbatim with Spanish origin glyphs to French VC.
|
||||
(int)Voltorb when language == (int)LanguageID.Spanish && pkLanguage == (int)LanguageID.French => "FALCçN", // FALCÁN
|
||||
(int)Shuckle when language == (int)LanguageID.Spanish && pkLanguage == (int)LanguageID.French => "MANôA", // MANÍA
|
||||
_ => TrainerNames[language],
|
||||
_ => TrainerNames.Span[language],
|
||||
};
|
||||
|
||||
// Already required for encounter matching.
|
||||
@@ -275,7 +277,7 @@ public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int _)
|
||||
return lang != -1;
|
||||
}
|
||||
|
||||
public string GetNickname(int language) => (uint)language < Nicknames.Length ? Nicknames[language] : Nicknames[0];
|
||||
public string GetNickname(int language) => Nicknames.Span[(uint)language < Nicknames.Length ? language : 0];
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ public sealed record EncounterGift3Colo : IEncounterable, IEncounterMatch, IEnco
|
||||
public bool IsFixedTrainer => true;
|
||||
public bool IsJapaneseBonusDisk => Version == GameVersion.R;
|
||||
|
||||
private readonly string[] TrainerNames;
|
||||
private readonly ReadOnlyMemory<string> TrainerNames;
|
||||
public ushort Species { get; }
|
||||
public byte Level { get; }
|
||||
public required byte Location { get; init; }
|
||||
@@ -29,7 +29,7 @@ public sealed record EncounterGift3Colo : IEncounterable, IEncounterMatch, IEnco
|
||||
public required ushort TID16 { get; init; }
|
||||
public required byte OriginalTrainerGender { get; init; }
|
||||
|
||||
public EncounterGift3Colo(ushort species, byte level, string[] trainers, GameVersion game)
|
||||
public EncounterGift3Colo(ushort species, byte level, ReadOnlyMemory<string> trainers, GameVersion game)
|
||||
{
|
||||
Species = species;
|
||||
Level = level;
|
||||
@@ -63,7 +63,7 @@ public CK3 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
Ball = (byte)Ball.Poke,
|
||||
|
||||
Language = lang,
|
||||
OriginalTrainerName = TrainerNames[lang],
|
||||
OriginalTrainerName = TrainerNames.Span[lang],
|
||||
OriginalTrainerGender = OriginalTrainerGender,
|
||||
ID32 = TID16,
|
||||
Nickname = SpeciesName.GetSpeciesNameGeneration(Species, lang, Generation),
|
||||
@@ -166,7 +166,7 @@ public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int language)
|
||||
if ((uint)language >= TrainerNames.Length)
|
||||
return false;
|
||||
|
||||
var expect = TrainerNames[language].AsSpan();
|
||||
var expect = TrainerNames.Span[language].AsSpan();
|
||||
if (pk is CK3 && expect.SequenceEqual(trainer))
|
||||
return true; // not yet transferred to mainline Gen3
|
||||
|
||||
|
||||
@@ -196,8 +196,8 @@ public bool IsCompatible(PIDType type, PKM pk)
|
||||
|
||||
private static bool IsRoamerPIDIV(PIDType val, PKM pk)
|
||||
{
|
||||
// Roamer PIDIV is always Method 1.
|
||||
// M1 is checked before M1R. A M1R PIDIV can also be a M1 PIDIV, so check that collision.
|
||||
// Roamer PID/IV is always Method 1.
|
||||
// M1 is checked before M1R. A M1R PID/IV can also be a M1 PID/IV, so check that collision.
|
||||
if (PIDType.Method_1_Roamer == val)
|
||||
return true;
|
||||
if (PIDType.Method_1 != val)
|
||||
|
||||
@@ -20,8 +20,8 @@ public sealed record EncounterTrade3 : IEncounterable, IEncounterMatch, IFixedTr
|
||||
public bool IsFixedNickname => true;
|
||||
public Nature Nature => (Nature)(PID % 25);
|
||||
|
||||
private string[] TrainerNames { get; }
|
||||
private string[] Nicknames { get; }
|
||||
private readonly ReadOnlyMemory<string> TrainerNames;
|
||||
private readonly ReadOnlyMemory<string> Nicknames;
|
||||
|
||||
public required AbilityPermission Ability { get; init; }
|
||||
public required byte Gender { get; init; }
|
||||
@@ -108,8 +108,8 @@ public PK3 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
// Italian LG Jynx untranslated from English name
|
||||
if (Species == (int)Core.Species.Jynx && version == GameVersion.LG && lang == (int)LanguageID.Italian)
|
||||
lang = 2;
|
||||
pk.Nickname = Nicknames[lang];
|
||||
pk.OriginalTrainerName = TrainerNames[lang];
|
||||
pk.Nickname = Nicknames.Span[lang];
|
||||
pk.OriginalTrainerName = TrainerNames.Span[lang];
|
||||
|
||||
EncounterUtil.SetEncounterMoves(pk, Version, Level);
|
||||
SetPINGA(pk, criteria);
|
||||
@@ -164,9 +164,11 @@ public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int language)
|
||||
{
|
||||
if (Species == (int)Core.Species.Jynx && pk.Version == GameVersion.LG && language == (int)LanguageID.Italian)
|
||||
language = 2;
|
||||
if (language == 0 || (uint)language >= TrainerNames.Length)
|
||||
|
||||
var names = TrainerNames.Span;
|
||||
if (language == 0 || (uint)language >= names.Length)
|
||||
return false;
|
||||
var name = TrainerNames[language];
|
||||
var name = names[language];
|
||||
if (pk.Context == EntityContext.Gen3)
|
||||
return trainer.SequenceEqual(name);
|
||||
|
||||
@@ -179,9 +181,11 @@ public bool IsNicknameMatch(PKM pk, ReadOnlySpan<char> nickname, int language)
|
||||
{
|
||||
if (Species == (int)Core.Species.Jynx && pk.Version == GameVersion.LG && language == (int)LanguageID.Italian)
|
||||
language = 2;
|
||||
if (language == 0 || (uint)language >= TrainerNames.Length)
|
||||
|
||||
var names = Nicknames.Span;
|
||||
if (language == 0 || (uint)language >= names.Length)
|
||||
return false;
|
||||
var name = Nicknames[language];
|
||||
var name = names[language];
|
||||
if (pk.Context == EntityContext.Gen3)
|
||||
return nickname.SequenceEqual(name);
|
||||
|
||||
@@ -192,7 +196,7 @@ public bool IsNicknameMatch(PKM pk, ReadOnlySpan<char> nickname, int language)
|
||||
return nickname.SequenceEqual(tmp);
|
||||
}
|
||||
|
||||
public string GetNickname(int language) => (uint)language < Nicknames.Length ? Nicknames[language] : Nicknames[0];
|
||||
public string GetNickname(int language) => Nicknames.Span[(uint)language < Nicknames.Length ? language : 0];
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -32,13 +32,13 @@ public sealed record EncounterTrade3XD : IEncounterable, IEncounterMatch, IEncou
|
||||
public required ushort TID16 { get; init; }
|
||||
// SID: Based on player ID
|
||||
|
||||
private readonly string[] TrainerNames;
|
||||
private readonly ReadOnlyMemory<string> TrainerNames;
|
||||
|
||||
private readonly string[] Nicknames;
|
||||
private readonly ReadOnlyMemory<string> Nicknames;
|
||||
|
||||
public EncounterTrade3XD(ushort species, byte level, string[] trainer) : this(species, level, trainer, []) { }
|
||||
public EncounterTrade3XD(ushort species, byte level, ReadOnlyMemory<string> trainer) : this(species, level, trainer, ReadOnlyMemory<string>.Empty) { }
|
||||
|
||||
public EncounterTrade3XD(ushort species, byte level, string[] trainer, string[] nicknames)
|
||||
public EncounterTrade3XD(ushort species, byte level, ReadOnlyMemory<string> trainer, ReadOnlyMemory<string> nicknames)
|
||||
{
|
||||
Species = species;
|
||||
Level = level;
|
||||
@@ -72,7 +72,7 @@ public XK3 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
Ball = (byte)Ball.Poke,
|
||||
FatefulEncounter = FatefulEncounter,
|
||||
Language = lang,
|
||||
OriginalTrainerName = TrainerNames[lang],
|
||||
OriginalTrainerName = TrainerNames.Span[lang],
|
||||
OriginalTrainerGender = 0,
|
||||
TID16 = TID16,
|
||||
SID16 = tr.SID16,
|
||||
@@ -179,7 +179,7 @@ public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int language)
|
||||
return false;
|
||||
if (language == 0 || (uint)language >= TrainerNames.Length)
|
||||
return false;
|
||||
var name = TrainerNames[language];
|
||||
var name = TrainerNames.Span[language];
|
||||
if (pk.Context == EntityContext.Gen3)
|
||||
return trainer.SequenceEqual(name);
|
||||
if (IsSpanishDuking(language)) // Gen4+
|
||||
@@ -195,7 +195,7 @@ public bool IsNicknameMatch(PKM pk, ReadOnlySpan<char> nickname, int language)
|
||||
return true;
|
||||
if (language == 0 || (uint)language >= Nicknames.Length)
|
||||
return false;
|
||||
var name = Nicknames[language];
|
||||
var name = Nicknames.Span[language];
|
||||
if (pk.Context == EntityContext.Gen3)
|
||||
return nickname.SequenceEqual(name);
|
||||
|
||||
@@ -204,5 +204,5 @@ public bool IsNicknameMatch(PKM pk, ReadOnlySpan<char> nickname, int language)
|
||||
return nickname.SequenceEqual(tmp);
|
||||
}
|
||||
|
||||
public string GetNickname(int language) => (uint)language < Nicknames.Length ? Nicknames[language] : Nicknames[0];
|
||||
public string GetNickname(int language) => Nicknames.Span[(uint)language < Nicknames.Length ? language : 0];
|
||||
}
|
||||
|
||||
@@ -21,8 +21,8 @@ public sealed record EncounterTrade4PID
|
||||
public byte LevelMax => IsMetUnset ? Level : (byte)100;
|
||||
public ushort Location => IsMetUnset ? Locations.LinkTrade4NPC : MetLocation;
|
||||
|
||||
private readonly string[] TrainerNames;
|
||||
private readonly string[] Nicknames;
|
||||
private readonly ReadOnlyMemory<string> TrainerNames;
|
||||
private readonly ReadOnlyMemory<string> Nicknames;
|
||||
|
||||
public ushort Species { get; }
|
||||
public byte Level { get; }
|
||||
@@ -96,12 +96,12 @@ public PK4 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
Version = version,
|
||||
Language = GetReceivedLanguage(lang, version),
|
||||
OriginalTrainerGender = OTGender,
|
||||
OriginalTrainerName = TrainerNames[lang],
|
||||
OriginalTrainerName = TrainerNames.Span[lang],
|
||||
|
||||
OriginalTrainerFriendship = pi.BaseFriendship,
|
||||
|
||||
IsNicknamed = true,
|
||||
Nickname = Nicknames[lang],
|
||||
Nickname = Nicknames.Span[lang],
|
||||
|
||||
HandlingTrainerName = tr.OT,
|
||||
HandlingTrainerGender = tr.Gender,
|
||||
@@ -148,9 +148,9 @@ private int GetLanguageDPPt(int lang, GameVersion game)
|
||||
|
||||
#region Matching
|
||||
|
||||
public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int language) => (uint)language < TrainerNames.Length && trainer.SequenceEqual(TrainerNames[language]);
|
||||
public bool IsNicknameMatch(PKM pk, ReadOnlySpan<char> nickname, int language) => (uint)language < Nicknames.Length && nickname.SequenceEqual(Nicknames[language]);
|
||||
public string GetNickname(int language) => (uint)language < Nicknames.Length ? Nicknames[language] : Nicknames[0];
|
||||
public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int language) => (uint)language < TrainerNames.Length && trainer.SequenceEqual(TrainerNames.Span[language]);
|
||||
public bool IsNicknameMatch(PKM pk, ReadOnlySpan<char> nickname, int language) => (uint)language < Nicknames.Length && nickname.SequenceEqual(Nicknames.Span[language]);
|
||||
public string GetNickname(int language) => Nicknames.Span[(uint)language < Nicknames.Length ? language : 0];
|
||||
|
||||
public bool IsMatchExact(PKM pk, EvoCriteria evo)
|
||||
{
|
||||
@@ -235,7 +235,7 @@ public int DetectOriginalLanguage(PKM pk)
|
||||
var len = pk.LoadString(pk.OriginalTrainerTrash, trainer);
|
||||
trainer = trainer[..len];
|
||||
|
||||
var expect = TrainerNames[1];
|
||||
var expect = TrainerNames.Span[(int)LanguageID.Japanese];
|
||||
var match = trainer.SequenceEqual(expect);
|
||||
if (!match)
|
||||
return 2; // verify strings with English locale instead.
|
||||
@@ -255,7 +255,8 @@ private int DetectTradeLanguageG4MeisterMagikarp(PKM pk, int currentLanguageID)
|
||||
var len = pk.LoadString(pk.NicknameTrash, nickname);
|
||||
nickname = nickname[..len];
|
||||
|
||||
return nickname.SequenceEqual(Nicknames[(int)LanguageID.French]) ? (int)LanguageID.French : (int)LanguageID.Spanish; // Spanish is same as English
|
||||
var french = Nicknames.Span[(int)LanguageID.French];
|
||||
return nickname.SequenceEqual(french) ? (int)LanguageID.French : (int)LanguageID.Spanish; // Spanish is same as English
|
||||
}
|
||||
|
||||
return lang;
|
||||
@@ -274,7 +275,8 @@ private int DetectTradeLanguageG4SurgePikachu(PKM pk, int currentLanguageID)
|
||||
var len = pk.LoadString(pk.NicknameTrash, nickname);
|
||||
nickname = nickname[..len];
|
||||
|
||||
return nickname.SequenceEqual(Nicknames[(int)LanguageID.Italian]) ? (int)LanguageID.Italian : (int)LanguageID.Spanish;
|
||||
var italian = Nicknames.Span[(int)LanguageID.Italian];
|
||||
return nickname.SequenceEqual(italian) ? (int)LanguageID.Italian : (int)LanguageID.Spanish;
|
||||
}
|
||||
|
||||
return lang;
|
||||
@@ -282,7 +284,7 @@ private int DetectTradeLanguageG4SurgePikachu(PKM pk, int currentLanguageID)
|
||||
|
||||
private int DetectTradeLanguage(ReadOnlySpan<char> actual, int currentLanguageID)
|
||||
{
|
||||
var names = TrainerNames;
|
||||
var names = TrainerNames.Span;
|
||||
for (int lang = 1; lang < names.Length; lang++)
|
||||
{
|
||||
var expect = names[lang];
|
||||
|
||||
@@ -31,8 +31,8 @@ public sealed record EncounterTrade5B2W2 : IEncounterable, IEncounterMatch, IFix
|
||||
public IndividualValueSet IVs { get; init; }
|
||||
public Nature Nature { get; init; } = Nature.Random;
|
||||
|
||||
private readonly string[] TrainerNames;
|
||||
private readonly string[] Nicknames;
|
||||
private readonly ReadOnlyMemory<string> TrainerNames;
|
||||
private readonly ReadOnlyMemory<string> Nicknames;
|
||||
|
||||
private const string _name = "In-game Trade";
|
||||
public string Name => _name;
|
||||
@@ -54,7 +54,7 @@ public EncounterTrade5B2W2(string[] names, GameVersion version)
|
||||
Version = version;
|
||||
Gender = FixedGenderUtil.GenderRandom;
|
||||
Nature = Nature.Random;
|
||||
Nicknames = [];
|
||||
Nicknames = ReadOnlyMemory<string>.Empty;
|
||||
TrainerNames = names;
|
||||
IsFixedNickname = false;
|
||||
}
|
||||
@@ -86,12 +86,12 @@ public PK5 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
Version = version,
|
||||
Language = lang,
|
||||
OriginalTrainerGender = OTGender,
|
||||
OriginalTrainerName = TrainerNames[lang],
|
||||
OriginalTrainerName = TrainerNames.Span[lang],
|
||||
|
||||
OriginalTrainerFriendship = pi.BaseFriendship,
|
||||
|
||||
IsNicknamed = IsFixedNickname,
|
||||
Nickname = IsFixedNickname ? Nicknames[lang] : SpeciesName.GetSpeciesNameGeneration(Species, lang, Generation),
|
||||
Nickname = IsFixedNickname ? Nicknames.Span[lang] : SpeciesName.GetSpeciesNameGeneration(Species, lang, Generation),
|
||||
};
|
||||
|
||||
EncounterUtil.SetEncounterMoves(pk, version, Level);
|
||||
@@ -116,9 +116,9 @@ private void SetPINGA(PK5 pk, EncounterCriteria criteria, PersonalInfo5B2W2 pi)
|
||||
|
||||
#region Matching
|
||||
|
||||
public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int language) => (uint)language < TrainerNames.Length && trainer.SequenceEqual(TrainerNames[language]);
|
||||
public bool IsNicknameMatch(PKM pk, ReadOnlySpan<char> nickname, int language) => (uint)language < Nicknames.Length && nickname.SequenceEqual(Nicknames[language]);
|
||||
public string GetNickname(int language) => (uint)language < Nicknames.Length ? Nicknames[language] : Nicknames[0];
|
||||
public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int language) => (uint)language < TrainerNames.Length && trainer.SequenceEqual(TrainerNames.Span[language]);
|
||||
public bool IsNicknameMatch(PKM pk, ReadOnlySpan<char> nickname, int language) => (uint)language < Nicknames.Length && nickname.SequenceEqual(Nicknames.Span[language]);
|
||||
public string GetNickname(int language) => Nicknames.Span[(uint)language < Nicknames.Length ? language : 0];
|
||||
|
||||
public bool IsMatchExact(PKM pk, EvoCriteria evo)
|
||||
{
|
||||
|
||||
@@ -19,8 +19,8 @@ public sealed record EncounterTrade5BW : IEncounterable, IEncounterMatch, IFixed
|
||||
public byte LevelMin => Level;
|
||||
public byte LevelMax => Level;
|
||||
|
||||
private string[] TrainerNames { get; }
|
||||
private string[] Nicknames { get; }
|
||||
private readonly ReadOnlyMemory<string> TrainerNames;
|
||||
private readonly ReadOnlyMemory<string> Nicknames;
|
||||
|
||||
public required ushort Species { get; init; }
|
||||
public required byte Level { get; init; }
|
||||
@@ -86,12 +86,12 @@ public PK5 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
Version = version,
|
||||
Language = lang == 1 ? 0 : lang, // Trades for JPN games have language ID of 0, not 1.
|
||||
OriginalTrainerGender = OTGender,
|
||||
OriginalTrainerName = TrainerNames[lang],
|
||||
OriginalTrainerName = TrainerNames.Span[lang],
|
||||
|
||||
OriginalTrainerFriendship = pi.BaseFriendship,
|
||||
|
||||
IsNicknamed = IsFixedNickname,
|
||||
Nickname = IsFixedNickname ? Nicknames[lang] : SpeciesName.GetSpeciesNameGeneration(Species, lang, Generation),
|
||||
Nickname = IsFixedNickname ? Nicknames.Span[lang] : SpeciesName.GetSpeciesNameGeneration(Species, lang, Generation),
|
||||
};
|
||||
|
||||
EncounterUtil.SetEncounterMoves(pk, version, Level);
|
||||
@@ -106,9 +106,9 @@ public PK5 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
|
||||
#region Matching
|
||||
|
||||
public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int language) => (uint)language < TrainerNames.Length && trainer.SequenceEqual(TrainerNames[language]);
|
||||
public bool IsNicknameMatch(PKM pk, ReadOnlySpan<char> nickname, int language) => (uint)language < Nicknames.Length && nickname.SequenceEqual(Nicknames[language]);
|
||||
public string GetNickname(int language) => (uint)language < Nicknames.Length ? Nicknames[language] : Nicknames[0];
|
||||
public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int language) => (uint)language < TrainerNames.Length && trainer.SequenceEqual(TrainerNames.Span[language]);
|
||||
public bool IsNicknameMatch(PKM pk, ReadOnlySpan<char> nickname, int language) => (uint)language < Nicknames.Length && nickname.SequenceEqual(Nicknames.Span[language]);
|
||||
public string GetNickname(int language) => Nicknames.Span[(uint)language < Nicknames.Length ? language : 0];
|
||||
|
||||
public bool IsMatchExact(PKM pk, EvoCriteria evo)
|
||||
{
|
||||
|
||||
@@ -18,8 +18,8 @@ public sealed record EncounterTrade6 : IEncounterable, IEncounterMatch, IFixedTr
|
||||
public bool IsFixedTrainer => true;
|
||||
public bool IsFixedNickname { get; init; } = true;
|
||||
|
||||
private string[] TrainerNames { get; }
|
||||
private string[] Nicknames { get; }
|
||||
private readonly ReadOnlyMemory<string> TrainerNames;
|
||||
private readonly ReadOnlyMemory<string> Nicknames;
|
||||
|
||||
public required Nature Nature { get; init; }
|
||||
public required ushort ID32 { get; init; }
|
||||
@@ -84,7 +84,7 @@ public PK6 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
Version = version,
|
||||
Language = lang,
|
||||
OriginalTrainerGender = OTGender,
|
||||
OriginalTrainerName = TrainerNames[lang],
|
||||
OriginalTrainerName = TrainerNames.Span[lang],
|
||||
|
||||
OriginalTrainerMemory = OriginalTrainerMemory,
|
||||
OriginalTrainerMemoryIntensity = OriginalTrainerMemoryIntensity,
|
||||
@@ -93,7 +93,7 @@ public PK6 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
OriginalTrainerFriendship = pi.BaseFriendship,
|
||||
|
||||
IsNicknamed = IsFixedNickname,
|
||||
Nickname = IsFixedNickname ? Nicknames[lang] : SpeciesName.GetSpeciesNameGeneration(Species, lang, Generation),
|
||||
Nickname = IsFixedNickname ? Nicknames.Span[lang] : SpeciesName.GetSpeciesNameGeneration(Species, lang, Generation),
|
||||
|
||||
HandlingTrainerName = tr.OT,
|
||||
HandlingTrainerGender = tr.Gender,
|
||||
@@ -119,14 +119,14 @@ public PK6 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
|
||||
#region Matching
|
||||
|
||||
public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int language) => (uint)language < TrainerNames.Length && trainer.SequenceEqual(TrainerNames[language]);
|
||||
public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int language) => (uint)language < TrainerNames.Length && trainer.SequenceEqual(TrainerNames.Span[language]);
|
||||
public bool IsNicknameMatch(PKM pk, ReadOnlySpan<char> nickname, int language)
|
||||
{
|
||||
if (Species is (ushort)Core.Species.Farfetchd && nickname is "Quacklin’" or "Quacklin'")
|
||||
return true;
|
||||
return (uint)language < Nicknames.Length && nickname.SequenceEqual(Nicknames[language]);
|
||||
return (uint)language < Nicknames.Length && nickname.SequenceEqual(Nicknames.Span[language]);
|
||||
}
|
||||
public string GetNickname(int language) => (uint)language < Nicknames.Length ? Nicknames[language] : Nicknames[0];
|
||||
public string GetNickname(int language) => Nicknames.Span[(uint)language < Nicknames.Length ? language : 0];
|
||||
|
||||
public bool IsMatchExact(PKM pk, EvoCriteria evo)
|
||||
{
|
||||
|
||||
@@ -22,8 +22,8 @@ public sealed record EncounterTrade7 : IEncounterable, IEncounterMatch, IFixedTr
|
||||
public bool IsFixedTrainer => true;
|
||||
public bool IsFixedNickname => true;
|
||||
|
||||
private string[] TrainerNames { get; }
|
||||
private string[] Nicknames { get; }
|
||||
private readonly ReadOnlyMemory<string> TrainerNames;
|
||||
private readonly ReadOnlyMemory<string> Nicknames;
|
||||
|
||||
public required Nature Nature { get; init; }
|
||||
public required uint ID32 { get; init; }
|
||||
@@ -83,7 +83,7 @@ public PK7 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
Version = version,
|
||||
Language = lang,
|
||||
OriginalTrainerGender = OTGender,
|
||||
OriginalTrainerName = TrainerNames[lang],
|
||||
OriginalTrainerName = TrainerNames.Span[lang],
|
||||
|
||||
OriginalTrainerMemory = OriginalTrainerMemory,
|
||||
OriginalTrainerMemoryIntensity = OriginalTrainerMemoryIntensity,
|
||||
@@ -92,7 +92,7 @@ public PK7 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
OriginalTrainerFriendship = pi.BaseFriendship,
|
||||
|
||||
IsNicknamed = true,
|
||||
Nickname = Nicknames[lang],
|
||||
Nickname = Nicknames.Span[lang],
|
||||
|
||||
HandlingTrainerName = tr.OT,
|
||||
HandlingTrainerGender = tr.Gender,
|
||||
@@ -121,9 +121,9 @@ public PK7 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
|
||||
#region Matching
|
||||
|
||||
public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int language) => (uint)language < TrainerNames.Length && trainer.SequenceEqual(TrainerNames[language]);
|
||||
public bool IsNicknameMatch(PKM pk, ReadOnlySpan<char> nickname, int language) => (uint)language < Nicknames.Length && nickname.SequenceEqual(Nicknames[language]);
|
||||
public string GetNickname(int language) => (uint)language < Nicknames.Length ? Nicknames[language] : Nicknames[0];
|
||||
public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int language) => (uint)language < TrainerNames.Length && trainer.SequenceEqual(TrainerNames.Span[language]);
|
||||
public bool IsNicknameMatch(PKM pk, ReadOnlySpan<char> nickname, int language) => (uint)language < Nicknames.Length && nickname.SequenceEqual(Nicknames.Span[language]);
|
||||
public string GetNickname(int language) => Nicknames.Span[(uint)language < Nicknames.Length ? language : 0];
|
||||
|
||||
public bool IsMatchExact(PKM pk, EvoCriteria evo)
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@ public sealed record EncounterTrade7b(GameVersion Version) : IEncounterable, IEn
|
||||
public bool IsFixedTrainer => true;
|
||||
public AbilityPermission Ability => AbilityPermission.Any12;
|
||||
|
||||
public required string[] TrainerNames { get; init; }
|
||||
public required ReadOnlyMemory<string> TrainerNames { get; init; }
|
||||
|
||||
public required uint ID32 { get; init; }
|
||||
public required byte OTGender { get; init; }
|
||||
@@ -60,7 +60,7 @@ public PB7 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
Version = version,
|
||||
Language = lang,
|
||||
OriginalTrainerGender = OTGender,
|
||||
OriginalTrainerName = TrainerNames[lang],
|
||||
OriginalTrainerName = TrainerNames.Span[lang],
|
||||
|
||||
OriginalTrainerFriendship = pi.BaseFriendship,
|
||||
|
||||
@@ -100,7 +100,7 @@ private void SetPINGA(PB7 pk, EncounterCriteria criteria, PersonalInfo7GG pi)
|
||||
|
||||
#region Matching
|
||||
|
||||
public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int language) => (uint)language < TrainerNames.Length && trainer.SequenceEqual(TrainerNames[language]);
|
||||
public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int language) => (uint)language < TrainerNames.Length && trainer.SequenceEqual(TrainerNames.Span[language]);
|
||||
|
||||
public bool IsMatchExact(PKM pk, EvoCriteria evo)
|
||||
{
|
||||
|
||||
@@ -70,6 +70,6 @@ protected override void SetTrainerName(ReadOnlySpan<char> name, PK8 pk)
|
||||
(int)LanguageID.Korean => "연구원",
|
||||
(int)LanguageID.ChineseS => "研究员",
|
||||
(int)LanguageID.ChineseT => "研究員",
|
||||
_ => ReadOnlySpan<char>.Empty,
|
||||
_ => [],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ public sealed record EncounterTrade8 : IEncounterable, IEncounterMatch, IFixedTr
|
||||
public bool IsFixedTrainer => true;
|
||||
public bool IsFixedNickname { get; }
|
||||
|
||||
private string[] TrainerNames { get; }
|
||||
private string[] Nicknames { get; }
|
||||
private readonly ReadOnlyMemory<string> TrainerNames;
|
||||
private readonly ReadOnlyMemory<string> Nicknames;
|
||||
|
||||
public Nature Nature { get; init; } // always set by either constructor or initializer
|
||||
public required uint ID32 { get; init; }
|
||||
@@ -68,10 +68,10 @@ public EncounterTrade8(ReadOnlySpan<string[]> names, byte index, GameVersion gam
|
||||
}
|
||||
|
||||
[SetsRequiredMembers]
|
||||
public EncounterTrade8(string[] trainerNames, GameVersion game, ushort species, byte level, byte memory, ushort arg, byte feel, byte intensity)
|
||||
public EncounterTrade8(ReadOnlyMemory<string> trainerNames, GameVersion game, ushort species, byte level, byte memory, ushort arg, byte feel, byte intensity)
|
||||
{
|
||||
Version = game;
|
||||
Nicknames = [];
|
||||
Nicknames = ReadOnlyMemory<string>.Empty;
|
||||
TrainerNames = trainerNames;
|
||||
Species = species;
|
||||
Level = level;
|
||||
@@ -116,7 +116,7 @@ public PK8 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
Version = version,
|
||||
Language = lang,
|
||||
OriginalTrainerGender = OTGender,
|
||||
OriginalTrainerName = TrainerNames[lang],
|
||||
OriginalTrainerName = TrainerNames.Span[lang],
|
||||
|
||||
OriginalTrainerMemory = OriginalTrainerMemory,
|
||||
OriginalTrainerMemoryIntensity = OriginalTrainerMemoryIntensity,
|
||||
@@ -125,7 +125,7 @@ public PK8 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
OriginalTrainerFriendship = pi.BaseFriendship,
|
||||
|
||||
IsNicknamed = IsFixedNickname,
|
||||
Nickname = IsFixedNickname ? Nicknames[lang] : SpeciesName.GetSpeciesNameGeneration(Species, lang, Generation),
|
||||
Nickname = IsFixedNickname ? Nicknames.Span[lang] : SpeciesName.GetSpeciesNameGeneration(Species, lang, Generation),
|
||||
DynamaxLevel = DynamaxLevel,
|
||||
HandlingTrainerName = tr.OT,
|
||||
HandlingTrainerGender = tr.Gender,
|
||||
@@ -163,9 +163,9 @@ private void SetPINGA(PK8 pk, EncounterCriteria criteria, PersonalInfo8SWSH pi)
|
||||
|
||||
#region Matching
|
||||
|
||||
public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int language) => (uint)language < TrainerNames.Length && trainer.SequenceEqual(TrainerNames[language]);
|
||||
public bool IsNicknameMatch(PKM pk, ReadOnlySpan<char> nickname, int language) => (uint)language < Nicknames.Length && nickname.SequenceEqual(Nicknames[language]);
|
||||
public string GetNickname(int language) => (uint)language < Nicknames.Length ? Nicknames[language] : Nicknames[0];
|
||||
public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int language) => (uint)language < TrainerNames.Length && trainer.SequenceEqual(TrainerNames.Span[language]);
|
||||
public bool IsNicknameMatch(PKM pk, ReadOnlySpan<char> nickname, int language) => (uint)language < Nicknames.Length && nickname.SequenceEqual(Nicknames.Span[language]);
|
||||
public string GetNickname(int language) => Nicknames.Span[(uint)language < Nicknames.Length ? language : 0];
|
||||
|
||||
public bool IsMatchExact(PKM pk, EvoCriteria evo)
|
||||
{
|
||||
|
||||
@@ -19,8 +19,8 @@ public sealed record EncounterTrade8b : IEncounterable, IEncounterMatch, IFixedT
|
||||
public bool IsFixedNickname => true;
|
||||
public GameVersion Version { get; }
|
||||
|
||||
private string[] TrainerNames { get; }
|
||||
private string[] Nicknames { get; }
|
||||
private readonly ReadOnlyMemory<string> TrainerNames;
|
||||
private readonly ReadOnlyMemory<string> Nicknames;
|
||||
|
||||
public required Nature Nature { get; init; }
|
||||
public required ushort ID32 { get; init; }
|
||||
@@ -91,12 +91,12 @@ public PB8 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
Version = version,
|
||||
Language = lang,
|
||||
OriginalTrainerGender = OTGender,
|
||||
OriginalTrainerName = TrainerNames[lang],
|
||||
OriginalTrainerName = TrainerNames.Span[lang],
|
||||
|
||||
OriginalTrainerFriendship = OriginalTrainerFriendship,
|
||||
|
||||
IsNicknamed = IsFixedNickname,
|
||||
Nickname = IsFixedNickname ? Nicknames[lang] : SpeciesName.GetSpeciesNameGeneration(Species, lang, Generation),
|
||||
Nickname = IsFixedNickname ? Nicknames.Span[lang] : SpeciesName.GetSpeciesNameGeneration(Species, lang, Generation),
|
||||
HeightScalar = HeightScalar,
|
||||
WeightScalar = WeightScalar,
|
||||
HandlingTrainerName = tr.OT,
|
||||
@@ -121,9 +121,9 @@ public PB8 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
|
||||
#region Matching
|
||||
|
||||
public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int language) => (uint)language < TrainerNames.Length && trainer.SequenceEqual(TrainerNames[language]);
|
||||
public bool IsNicknameMatch(PKM pk, ReadOnlySpan<char> nickname, int language) => (uint)language < Nicknames.Length && nickname.SequenceEqual(Nicknames[language]);
|
||||
public string GetNickname(int language) => (uint)language < Nicknames.Length ? Nicknames[language] : Nicknames[0];
|
||||
public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int language) => (uint)language < TrainerNames.Length && trainer.SequenceEqual(TrainerNames.Span[language]);
|
||||
public bool IsNicknameMatch(PKM pk, ReadOnlySpan<char> nickname, int language) => (uint)language < Nicknames.Length && nickname.SequenceEqual(Nicknames.Span[language]);
|
||||
public string GetNickname(int language) => Nicknames.Span[(uint)language < Nicknames.Length ? language : 0];
|
||||
|
||||
public EncounterMatchRating GetMatchRating(PKM pk) => EncounterMatchRating.Match;
|
||||
|
||||
@@ -202,11 +202,13 @@ public int DetectMeisterMagikarpLanguage(ReadOnlySpan<char> nick, ReadOnlySpan<c
|
||||
if (currentLanguageID is not ((int)LanguageID.Japanese or (int)LanguageID.German))
|
||||
return -1;
|
||||
|
||||
var nicknames = Nicknames.Span;
|
||||
var trainers = TrainerNames.Span;
|
||||
for (int i = 1; i < (int)LanguageID.ChineseT; i++)
|
||||
{
|
||||
if (!nick.SequenceEqual(Nicknames[i]))
|
||||
if (!nick.SequenceEqual(nicknames[i]))
|
||||
continue;
|
||||
if (!ot.SequenceEqual(TrainerNames[i]))
|
||||
if (!ot.SequenceEqual(trainers[i]))
|
||||
continue;
|
||||
|
||||
// Language gets flipped to another language ID; can't be equal.
|
||||
|
||||
@@ -20,8 +20,8 @@ public sealed record EncounterTrade9
|
||||
public bool IsFixedNickname => Nicknames.Length != 0;
|
||||
public GameVersion Version { get; }
|
||||
|
||||
private string[] TrainerNames { get; }
|
||||
private string[] Nicknames { get; }
|
||||
private readonly ReadOnlyMemory<string> TrainerNames;
|
||||
private readonly ReadOnlyMemory<string> Nicknames;
|
||||
|
||||
public required Nature Nature { get; init; }
|
||||
public required uint ID32 { get; init; }
|
||||
@@ -89,12 +89,12 @@ public PK9 ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
|
||||
Version = version,
|
||||
Language = lang,
|
||||
OriginalTrainerGender = OTGender,
|
||||
OriginalTrainerName = TrainerNames[lang],
|
||||
OriginalTrainerName = TrainerNames.Span[lang],
|
||||
|
||||
OriginalTrainerFriendship = pi.BaseFriendship,
|
||||
|
||||
IsNicknamed = IsFixedNickname,
|
||||
Nickname = IsFixedNickname ? Nicknames[lang] : SpeciesName.GetSpeciesNameGeneration(Species, lang, Generation),
|
||||
Nickname = IsFixedNickname ? Nicknames.Span[lang] : SpeciesName.GetSpeciesNameGeneration(Species, lang, Generation),
|
||||
|
||||
HeightScalar = PokeSizeUtil.GetRandomScalar(rnd),
|
||||
WeightScalar = Weight.GetSizeValue(Weight != SizeType9.RANDOM ? FixedValueScale : default, ref xoro),
|
||||
@@ -147,9 +147,9 @@ private MoveType GetOriginalTeraType()
|
||||
|
||||
#region Matching
|
||||
|
||||
public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int language) => (uint)language < TrainerNames.Length && trainer.SequenceEqual(TrainerNames[language]);
|
||||
public bool IsNicknameMatch(PKM pk, ReadOnlySpan<char> nickname, int language) => (uint)language < Nicknames.Length && nickname.SequenceEqual(Nicknames[language]);
|
||||
public string GetNickname(int language) => (uint)language < Nicknames.Length ? Nicknames[language] : Nicknames[0];
|
||||
public bool IsTrainerMatch(PKM pk, ReadOnlySpan<char> trainer, int language) => (uint)language < TrainerNames.Length && trainer.SequenceEqual(TrainerNames.Span[language]);
|
||||
public bool IsNicknameMatch(PKM pk, ReadOnlySpan<char> nickname, int language) => (uint)language < Nicknames.Length && nickname.SequenceEqual(Nicknames.Span[language]);
|
||||
public string GetNickname(int language) => Nicknames.Span[(uint)language < Nicknames.Length ? language : 0];
|
||||
|
||||
private bool IsMatchNatureGenderShiny(PKM pk)
|
||||
{
|
||||
|
||||
@@ -88,7 +88,7 @@ public static void AddEncounterInfo(LegalityAnalysis la, List<string> lines)
|
||||
if (enc.Generation <= 2)
|
||||
lines.Add(string.Format(L_F0_1, nameof(GameVersion), enc.Version));
|
||||
|
||||
// PIDIV
|
||||
// PID/IV
|
||||
AddEncounterInfoPIDIV(la, lines);
|
||||
}
|
||||
|
||||
|
||||
@@ -77,7 +77,10 @@ public MoveLearnInfo GetCanLearn(PKM pk, PersonalInfo4 pi, EvoCriteria evo, usho
|
||||
return default;
|
||||
}
|
||||
|
||||
private static bool GetIsEnhancedTutor(EvoCriteria evo, ISpeciesForm current, ushort move, LearnOption option) => evo.Species is (int)Species.Rotom && move switch
|
||||
private static bool GetIsEnhancedTutor<T1, T2>(T1 evo, T2 current, ushort move, LearnOption option)
|
||||
where T1 : ISpeciesForm
|
||||
where T2 : ISpeciesForm
|
||||
=> evo.Species is (int)Species.Rotom && move switch
|
||||
{
|
||||
(int)Move.Overheat => option.IsPast() || current.Form == 1,
|
||||
(int)Move.HydroPump => option.IsPast() || current.Form == 2,
|
||||
|
||||
@@ -75,7 +75,10 @@ public MoveLearnInfo GetCanLearn(PKM pk, PersonalInfo4 pi, EvoCriteria evo, usho
|
||||
return default;
|
||||
}
|
||||
|
||||
private static bool GetIsEnhancedTutor(EvoCriteria evo, ISpeciesForm current, ushort move, LearnOption option) => evo.Species is (int)Species.Rotom && move switch
|
||||
private static bool GetIsEnhancedTutor<T1, T2>(T1 evo, T2 current, ushort move, LearnOption option)
|
||||
where T1 : ISpeciesForm
|
||||
where T2 : ISpeciesForm
|
||||
=> evo.Species is (int)Species.Rotom && move switch
|
||||
{
|
||||
(int)Move.Overheat => option.IsPast() || current.Form == 1,
|
||||
(int)Move.HydroPump => option.IsPast() || current.Form == 2,
|
||||
|
||||
@@ -69,7 +69,10 @@ public MoveLearnInfo GetCanLearn(PKM pk, PersonalInfo5B2W2 pi, EvoCriteria evo,
|
||||
return default;
|
||||
}
|
||||
|
||||
private static bool GetIsEnhancedTutor(EvoCriteria evo, ISpeciesForm current, ushort move, LearnOption option) => evo.Species switch
|
||||
private static bool GetIsEnhancedTutor<T1, T2>(T1 evo, T2 current, ushort move, LearnOption option)
|
||||
where T1 : ISpeciesForm
|
||||
where T2 : ISpeciesForm
|
||||
=> evo.Species switch
|
||||
{
|
||||
(int)Species.Keldeo => move is (int)Move.SecretSword,
|
||||
(int)Species.Meloetta => move is (int)Move.RelicSong,
|
||||
@@ -101,7 +104,7 @@ private static bool GetIsTM(PersonalInfo5B2W2 info, ushort move)
|
||||
return info.GetIsLearnTM(index);
|
||||
}
|
||||
|
||||
public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceType types = MoveSourceType.All)
|
||||
public void GetAllMoves(Span<bool> result, PKM _, EvoCriteria evo, MoveSourceType types = MoveSourceType.All)
|
||||
{
|
||||
if (!TryGetPersonal(evo.Species, evo.Form, out var pi))
|
||||
return;
|
||||
|
||||
@@ -66,7 +66,10 @@ public MoveLearnInfo GetCanLearn(PKM pk, PersonalInfo5BW pi, EvoCriteria evo, us
|
||||
return default;
|
||||
}
|
||||
|
||||
private static bool GetIsEnhancedTutor(EvoCriteria evo, ISpeciesForm current, ushort move, LearnOption option) => evo.Species switch
|
||||
private static bool GetIsEnhancedTutor<T1, T2>(T1 evo, T2 current, ushort move, LearnOption option)
|
||||
where T1 : ISpeciesForm
|
||||
where T2 : ISpeciesForm
|
||||
=> evo.Species switch
|
||||
{
|
||||
(int)Species.Keldeo => move is (int)Move.SecretSword,
|
||||
(int)Species.Meloetta => move is (int)Move.RelicSong,
|
||||
@@ -98,7 +101,7 @@ private static bool GetIsTM(PersonalInfo5BW info, ushort move)
|
||||
return info.GetIsLearnTM(index) && index != 94; // TM95 not available in this game
|
||||
}
|
||||
|
||||
public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceType types = MoveSourceType.All)
|
||||
public void GetAllMoves(Span<bool> result, PKM _, EvoCriteria evo, MoveSourceType types = MoveSourceType.All)
|
||||
{
|
||||
if (!TryGetPersonal(evo.Species, evo.Form, out var pi))
|
||||
return;
|
||||
|
||||
@@ -70,7 +70,10 @@ public MoveLearnInfo GetCanLearn(PKM pk, PersonalInfo6AO pi, EvoCriteria evo, us
|
||||
return default;
|
||||
}
|
||||
|
||||
private static bool GetIsEnhancedTutor(EvoCriteria evo, ISpeciesForm current, ushort move, LearnOption option) => evo.Species switch
|
||||
private static bool GetIsEnhancedTutor<T1, T2>(T1 evo, T2 current, ushort move, LearnOption option)
|
||||
where T1 : ISpeciesForm
|
||||
where T2 : ISpeciesForm
|
||||
=> evo.Species switch
|
||||
{
|
||||
(int)Species.Keldeo => move is (int)Move.SecretSword,
|
||||
(int)Species.Meloetta => move is (int)Move.RelicSong,
|
||||
@@ -92,7 +95,7 @@ private static bool GetIsTM(PersonalInfo6AO info, ushort move)
|
||||
return info.GetIsLearnTM(index);
|
||||
}
|
||||
|
||||
public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceType types = MoveSourceType.All)
|
||||
public void GetAllMoves(Span<bool> result, PKM _, EvoCriteria evo, MoveSourceType types = MoveSourceType.All)
|
||||
{
|
||||
if (!TryGetPersonal(evo.Species, evo.Form, out var pi))
|
||||
return;
|
||||
|
||||
@@ -67,7 +67,10 @@ public MoveLearnInfo GetCanLearn(PKM pk, PersonalInfo6XY pi, EvoCriteria evo, us
|
||||
return default;
|
||||
}
|
||||
|
||||
private static bool GetIsEnhancedTutor(EvoCriteria evo, ISpeciesForm current, ushort move, LearnOption option) => evo.Species switch
|
||||
private static bool GetIsEnhancedTutor<T1, T2>(T1 evo, T2 current, ushort move, LearnOption option)
|
||||
where T1 : ISpeciesForm
|
||||
where T2 : ISpeciesForm
|
||||
=> evo.Species switch
|
||||
{
|
||||
(int)Species.Keldeo => move is (int)Move.SecretSword,
|
||||
(int)Species.Meloetta => move is (int)Move.RelicSong,
|
||||
@@ -83,7 +86,7 @@ public MoveLearnInfo GetCanLearn(PKM pk, PersonalInfo6XY pi, EvoCriteria evo, us
|
||||
_ => false,
|
||||
};
|
||||
|
||||
public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceType types = MoveSourceType.All)
|
||||
public void GetAllMoves(Span<bool> result, PKM _, EvoCriteria evo, MoveSourceType types = MoveSourceType.All)
|
||||
{
|
||||
if (!TryGetPersonal(evo.Species, evo.Form, out var pi))
|
||||
return;
|
||||
|
||||
@@ -58,7 +58,7 @@ private static bool GetIsEnhancedTutor(ushort species, byte form, ushort move)
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceType types = MoveSourceType.All)
|
||||
public void GetAllMoves(Span<bool> result, PKM _, EvoCriteria evo, MoveSourceType types = MoveSourceType.All)
|
||||
{
|
||||
if (!TryGetPersonal(evo.Species, evo.Form, out var pi))
|
||||
return;
|
||||
|
||||
@@ -69,7 +69,10 @@ public MoveLearnInfo GetCanLearn(PKM pk, PersonalInfo7 pi, EvoCriteria evo, usho
|
||||
return default;
|
||||
}
|
||||
|
||||
private static bool GetIsEnhancedTutor(EvoCriteria evo, ISpeciesForm current, ushort move, LearnOption option) => evo.Species switch
|
||||
private static bool GetIsEnhancedTutor<T1, T2>(T1 evo, T2 current, ushort move, LearnOption option)
|
||||
where T1 : ISpeciesForm
|
||||
where T2 : ISpeciesForm
|
||||
=> evo.Species switch
|
||||
{
|
||||
(int)Species.Pikachu or (int)Species.Raichu => move is (int)Move.VoltTackle,
|
||||
(int)Species.Necrozma => move switch
|
||||
@@ -93,7 +96,7 @@ public MoveLearnInfo GetCanLearn(PKM pk, PersonalInfo7 pi, EvoCriteria evo, usho
|
||||
_ => false,
|
||||
};
|
||||
|
||||
public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceType types = MoveSourceType.All)
|
||||
public void GetAllMoves(Span<bool> result, PKM _, EvoCriteria evo, MoveSourceType types = MoveSourceType.All)
|
||||
{
|
||||
if (!TryGetPersonal(evo.Species, evo.Form, out var pi))
|
||||
return;
|
||||
@@ -132,9 +135,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
|
||||
result[(int)Move.SecretSword] = true;
|
||||
else if (species is (int)Species.Meloetta)
|
||||
result[(int)Move.RelicSong] = true;
|
||||
else if (species is (int)Species.Necrozma && pk.Form is 1) // Sun
|
||||
else if (species is (int)Species.Necrozma && evo.Form is 1) // Sun
|
||||
result[(int)Move.SunsteelStrike] = true;
|
||||
else if (species is (int)Species.Necrozma && pk.Form is 2) // Moon
|
||||
else if (species is (int)Species.Necrozma && evo.Form is 2) // Moon
|
||||
result[(int)Move.MoongeistBeam] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,10 @@ public MoveLearnInfo GetCanLearn(PKM pk, PersonalInfo7 pi, EvoCriteria evo, usho
|
||||
return default;
|
||||
}
|
||||
|
||||
private static bool GetIsEnhancedTutor(EvoCriteria evo, ISpeciesForm current, ushort move, LearnOption option) => evo.Species switch
|
||||
private static bool GetIsEnhancedTutor<T1, T2>(T1 evo, T2 current, ushort move, LearnOption option)
|
||||
where T1 : ISpeciesForm
|
||||
where T2 : ISpeciesForm
|
||||
=> evo.Species switch
|
||||
{
|
||||
(int)Species.Pikachu or (int)Species.Raichu => move is (int)Move.VoltTackle,
|
||||
(int)Species.Necrozma => move switch
|
||||
@@ -96,7 +99,7 @@ public MoveLearnInfo GetCanLearn(PKM pk, PersonalInfo7 pi, EvoCriteria evo, usho
|
||||
_ => false,
|
||||
};
|
||||
|
||||
public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceType types = MoveSourceType.All)
|
||||
public void GetAllMoves(Span<bool> result, PKM _, EvoCriteria evo, MoveSourceType types = MoveSourceType.All)
|
||||
{
|
||||
if (!TryGetPersonal(evo.Species, evo.Form, out var pi))
|
||||
return;
|
||||
@@ -139,9 +142,9 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
|
||||
result[(int)Move.SecretSword] = true;
|
||||
else if (species is (int)Species.Meloetta)
|
||||
result[(int)Move.RelicSong] = true;
|
||||
else if (species is (int)Species.Necrozma && pk.Form is 1) // Sun
|
||||
else if (species is (int)Species.Necrozma && evo.Form is 1) // Sun
|
||||
result[(int)Move.SunsteelStrike] = true;
|
||||
else if (species is (int)Species.Necrozma && pk.Form is 2) // Moon
|
||||
else if (species is (int)Species.Necrozma && evo.Form is 2) // Moon
|
||||
result[(int)Move.MoongeistBeam] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,10 @@ public MoveLearnInfo GetCanLearn(PKM pk, PersonalInfo8BDSP pi, EvoCriteria evo,
|
||||
return default;
|
||||
}
|
||||
|
||||
private static bool GetIsEnhancedTutor(EvoCriteria evo, ISpeciesForm current, ushort move, LearnOption option) => evo.Species is (int)Species.Rotom && move switch
|
||||
private static bool GetIsEnhancedTutor<T1, T2>(T1 evo, T2 current, ushort move, LearnOption option)
|
||||
where T1 : ISpeciesForm
|
||||
where T2 : ISpeciesForm
|
||||
=> evo.Species is (int)Species.Rotom && move switch
|
||||
{
|
||||
(int)Move.Overheat => option.IsPast() || current.Form == 1,
|
||||
(int)Move.HydroPump => option.IsPast() || current.Form == 2,
|
||||
@@ -89,7 +92,7 @@ private bool GetIsSharedEggMove(PersonalInfo8BDSP pi, ushort move)
|
||||
return GetEggMoves(baseSpecies, baseForm).Contains(move);
|
||||
}
|
||||
|
||||
public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceType types = MoveSourceType.All)
|
||||
public void GetAllMoves(Span<bool> result, PKM _, EvoCriteria evo, MoveSourceType types = MoveSourceType.All)
|
||||
{
|
||||
if (!TryGetPersonal(evo.Species, evo.Form, out var pi))
|
||||
return;
|
||||
|
||||
@@ -56,7 +56,10 @@ public MoveLearnInfo GetCanLearn(PKM pk, PersonalInfo8LA pi, EvoCriteria evo, us
|
||||
return default;
|
||||
}
|
||||
|
||||
private static bool GetIsEnhancedTutor(EvoCriteria evo, ISpeciesForm current, ushort move, LearnOption option) => evo.Species is (int)Species.Rotom && move switch
|
||||
private static bool GetIsEnhancedTutor<T1, T2>(T1 evo, T2 current, ushort move, LearnOption option)
|
||||
where T1 : ISpeciesForm
|
||||
where T2 : ISpeciesForm
|
||||
=> evo.Species is (int)Species.Rotom && move switch
|
||||
{
|
||||
(int)Move.Overheat => option.IsPast() || current.Form == 1,
|
||||
(int)Move.HydroPump => option.IsPast() || current.Form == 2,
|
||||
@@ -66,7 +69,7 @@ public MoveLearnInfo GetCanLearn(PKM pk, PersonalInfo8LA pi, EvoCriteria evo, us
|
||||
_ => false,
|
||||
};
|
||||
|
||||
public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceType types = MoveSourceType.All)
|
||||
public void GetAllMoves(Span<bool> result, PKM _, EvoCriteria evo, MoveSourceType types = MoveSourceType.All)
|
||||
{
|
||||
if (!TryGetPersonal(evo.Species, evo.Form, out var pi))
|
||||
return;
|
||||
|
||||
@@ -74,7 +74,10 @@ public MoveLearnInfo GetCanLearn(PKM pk, PersonalInfo8SWSH pi, EvoCriteria evo,
|
||||
return default;
|
||||
}
|
||||
|
||||
private static bool GetIsEnhancedTutor(EvoCriteria evo, ISpeciesForm current, ushort move, LearnOption option) => evo.Species switch
|
||||
private static bool GetIsEnhancedTutor<T1, T2>(T1 evo, T2 current, ushort move, LearnOption option)
|
||||
where T1 : ISpeciesForm
|
||||
where T2 : ISpeciesForm
|
||||
=> evo.Species switch
|
||||
{
|
||||
(int)Species.Necrozma => move switch
|
||||
{
|
||||
@@ -128,7 +131,7 @@ private static bool GetIsTR(PersonalInfo8SWSH info, PKM pk, EvoCriteria evo, ush
|
||||
return false;
|
||||
}
|
||||
|
||||
public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceType types = MoveSourceType.All)
|
||||
public void GetAllMoves(Span<bool> result, PKM _, EvoCriteria evo, MoveSourceType types = MoveSourceType.All)
|
||||
{
|
||||
if (!TryGetPersonal(evo.Species, evo.Form, out var pi))
|
||||
return;
|
||||
@@ -167,11 +170,11 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
|
||||
if (types.HasFlag(MoveSourceType.EnhancedTutor))
|
||||
{
|
||||
var species = evo.Species;
|
||||
if (species is (int)Species.Rotom && pk.Form is not 0)
|
||||
if (species is (int)Species.Rotom && evo.Form is not 0)
|
||||
result[MoveTutor.GetRotomFormMove(evo.Form)] = true;
|
||||
else if (species is (int)Species.Necrozma && pk.Form is 1) // Sun
|
||||
else if (species is (int)Species.Necrozma && evo.Form is 1) // Sun
|
||||
result[(int)Move.SunsteelStrike] = true;
|
||||
else if (species is (int)Species.Necrozma && pk.Form is 2) // Moon
|
||||
else if (species is (int)Species.Necrozma && evo.Form is 2) // Moon
|
||||
result[(int)Move.MoongeistBeam] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +122,10 @@ private static bool GetIsTM(PersonalInfo9SV info, PKM pk, ushort move, LearnOpti
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool GetIsEnhancedTutor(EvoCriteria evo, ISpeciesForm current, ushort move, LearnOption option) => evo.Species switch
|
||||
private static bool GetIsEnhancedTutor<T1, T2>(T1 evo, T2 current, ushort move, LearnOption option)
|
||||
where T1 : ISpeciesForm
|
||||
where T2 : ISpeciesForm
|
||||
=> evo.Species switch
|
||||
{
|
||||
(int)Species.Necrozma => move switch
|
||||
{
|
||||
@@ -149,7 +152,7 @@ private bool GetIsSharedEggMove(PersonalInfo9SV pi, ushort move)
|
||||
return GetEggMoves(baseSpecies, baseForm).Contains(move);
|
||||
}
|
||||
|
||||
public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceType types = MoveSourceType.All)
|
||||
public void GetAllMoves(Span<bool> result, PKM _, EvoCriteria evo, MoveSourceType types = MoveSourceType.All)
|
||||
{
|
||||
if (!TryGetPersonal(evo.Species, evo.Form, out var pi))
|
||||
return;
|
||||
@@ -184,11 +187,11 @@ public void GetAllMoves(Span<bool> result, PKM pk, EvoCriteria evo, MoveSourceTy
|
||||
if (types.HasFlag(MoveSourceType.EnhancedTutor))
|
||||
{
|
||||
var species = evo.Species;
|
||||
if (species is (int)Species.Rotom && pk.Form is not 0)
|
||||
if (species is (int)Species.Rotom && evo.Form is not 0)
|
||||
result[MoveTutor.GetRotomFormMove(evo.Form)] = true;
|
||||
else if (species is (int)Species.Necrozma && pk.Form is 1) // Sun
|
||||
else if (species is (int)Species.Necrozma && evo.Form is 1) // Sun
|
||||
result[(int)Move.SunsteelStrike] = true;
|
||||
else if (species is (int)Species.Necrozma && pk.Form is 2) // Moon
|
||||
else if (species is (int)Species.Necrozma && evo.Form is 2) // Moon
|
||||
result[(int)Move.MoongeistBeam] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
namespace PKHeX.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Class containing logic to obtain a PKM's PIDIV method.
|
||||
/// Class containing logic to obtain a PKM's PID/IV method.
|
||||
/// </summary>
|
||||
public static class MethodFinder
|
||||
{
|
||||
/// <summary>
|
||||
/// Analyzes a <see cref="PKM"/> to find a matching PIDIV method.
|
||||
/// Analyzes a <see cref="PKM"/> to find a matching PID/IV method.
|
||||
/// </summary>
|
||||
/// <param name="pk">Input <see cref="PKM"/>.</param>
|
||||
/// <returns><see cref="PIDIV"/> object containing seed and method info.</returns>
|
||||
|
||||
@@ -239,7 +239,7 @@ private static bool GetIsHeightWeightMatch(PKM pk, Xoroshiro128Plus8b xoro)
|
||||
return s.HeightScalar == height && s.WeightScalar == weight;
|
||||
}
|
||||
|
||||
private static uint GetRevisedPID(uint fakeTID, uint pid, ITrainerID32 tr)
|
||||
private static uint GetRevisedPID<T>(uint fakeTID, uint pid, T tr) where T : ITrainerID32
|
||||
{
|
||||
var xor = GetShinyXor(pid, fakeTID);
|
||||
var newXor = GetShinyXor(pid, tr.ID32);
|
||||
|
||||
@@ -142,7 +142,7 @@ public static bool TryApplyFromSeed(PKM pk, EncounterCriteria criteria, Shiny sh
|
||||
return true;
|
||||
}
|
||||
|
||||
private static uint GetRevisedPID(uint fakeTID, uint pid, ITrainerID32 tr)
|
||||
private static uint GetRevisedPID<T>(uint fakeTID, uint pid, T tr) where T : ITrainerID32
|
||||
{
|
||||
var xor = GetShinyXor(pid, fakeTID);
|
||||
var newXor = GetShinyXor(pid, tr.ID32);
|
||||
|
||||
@@ -70,22 +70,19 @@ public static byte GetTeraType(in ulong seed, GemType gem, in ushort species, in
|
||||
return type;
|
||||
|
||||
var rand = new Xoroshiro128Plus(seed);
|
||||
if (gem == GemType.Default)
|
||||
{
|
||||
var pivot = rand.NextInt(2);
|
||||
return GetTeraTypeFromPersonal(species, form, pivot);
|
||||
}
|
||||
if (gem == GemType.Random)
|
||||
{
|
||||
return (byte)rand.NextInt(TeraTypeCount);
|
||||
}
|
||||
throw new ArgumentOutOfRangeException(nameof(gem), gem, null);
|
||||
if (gem != GemType.Default)
|
||||
throw new ArgumentOutOfRangeException(nameof(gem), gem, null);
|
||||
var pivot = rand.NextInt(2);
|
||||
return GetTeraTypeFromPersonal(species, form, pivot);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the original Tera Type matches either of the Personal Info types.
|
||||
/// </summary>
|
||||
private static bool IsMatchType(IPersonalType pi, in byte original) => original == pi.Type1 || original == pi.Type2;
|
||||
private static bool IsMatchType<T>(T pi, in byte original) where T : IPersonalType
|
||||
=> original == pi.Type1 || original == pi.Type2;
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the original Tera Type matches the Personal Info type for the specified form.
|
||||
@@ -102,7 +99,7 @@ public static byte GetTeraType(in ulong seed, GemType gem, in ushort species, in
|
||||
? IsMatchTeraTypePersonalAnyForm(species, original)
|
||||
: IsMatchTeraTypePersonal(species, form, original);
|
||||
|
||||
/// <inheritdoc cref="IsMatchType"/>
|
||||
/// <inheritdoc cref="IsMatchType{T}"/>
|
||||
public static bool IsMatchTeraTypePersonal(in ushort species, in byte form, in byte original) => IsMatchType(PersonalTable.SV[species, form], original);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace PKHeX.Core;
|
||||
/// <summary>The RNG seed which immediately generates the PID/IV (starting with PID or IVs, whichever comes first)</summary>
|
||||
[field: FieldOffset(0)] public ulong Seed64 { get; }
|
||||
|
||||
/// <summary>Type of PIDIV correlation</summary>
|
||||
/// <summary>Type of PID/IV correlation</summary>
|
||||
[field: FieldOffset(8)] public PIDType Type { get; }
|
||||
[field: FieldOffset(9)] public LeadRequired Lead { get; init; }
|
||||
[field: FieldOffset(9)] public PIDType Mutated { get; init; }
|
||||
|
||||
@@ -560,7 +560,7 @@ private void SetPINGA(PA8 pk, EncounterCriteria criteria)
|
||||
_ => AbilityPermission.Any12H,
|
||||
};
|
||||
|
||||
private uint GetPID(ITrainerID32 tr, ShinyType8 type) => type switch
|
||||
private uint GetPID<T>(T tr, ShinyType8 type) where T : ITrainerID32 => type switch
|
||||
{
|
||||
ShinyType8.Never => GetAntishiny(tr), // Random, Never Shiny
|
||||
ShinyType8.Random => Util.Rand32(), // Random, Any
|
||||
|
||||
@@ -31,7 +31,7 @@ public SCBlockCompare(SCBlockAccessor s1, SCBlockAccessor s2, IEnumerable<string
|
||||
LoadChanged(s1, s2, hs1);
|
||||
}
|
||||
|
||||
private void LoadAddRemove(SCBlockAccessor s1, SCBlockAccessor s2, ICollection<uint> hs1, IEnumerable<uint> hs2)
|
||||
private void LoadAddRemove(SCBlockAccessor s1, SCBlockAccessor s2, HashSet<uint> hs1, HashSet<uint> hs2)
|
||||
{
|
||||
var unique = new HashSet<uint>(hs1);
|
||||
unique.SymmetricExceptWith(hs2);
|
||||
@@ -51,7 +51,7 @@ private void LoadAddRemove(SCBlockAccessor s1, SCBlockAccessor s2, ICollection<u
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadChanged(SCBlockAccessor s1, SCBlockAccessor s2, IEnumerable<uint> shared)
|
||||
private void LoadChanged(SCBlockAccessor s1, SCBlockAccessor s2, IReadOnlySet<uint> shared)
|
||||
{
|
||||
foreach (var k in shared)
|
||||
{
|
||||
|
||||
@@ -67,7 +67,7 @@ public GeonetPoint GetCountrySubregion(byte country, byte subregion)
|
||||
{
|
||||
int index = ((country - 1) * 16) + (subregion / 4);
|
||||
int shift = 2 * (subregion % 4);
|
||||
return (GeonetPoint)(((Data[index] & 0b11 << shift) >> shift));
|
||||
return (GeonetPoint)((Data[index] & 0b11 << shift) >> shift);
|
||||
}
|
||||
|
||||
public void SetCountrySubregion(byte country, byte subregion, GeonetPoint point)
|
||||
|
||||
@@ -113,10 +113,11 @@ private bool[] GetFlags()
|
||||
result[i] = GetFlag(i);
|
||||
return result;
|
||||
}
|
||||
private void SetFlags(IReadOnlyList<bool> value)
|
||||
|
||||
private void SetFlags(ReadOnlySpan<bool> value)
|
||||
{
|
||||
ArgumentOutOfRangeException.ThrowIfNotEqual(value.Count, FlagSize);
|
||||
for (int i = 0; i < value.Count; i++)
|
||||
ArgumentOutOfRangeException.ThrowIfNotEqual(value.Length, FlagSize);
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
SetFlag(i, value[i]);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -24,7 +24,7 @@ private static int GetPoffinOffset(int index)
|
||||
{
|
||||
if ((uint)index >= COUNT_POFFIN)
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
return (index * Poffin8b.SIZE);
|
||||
return index * Poffin8b.SIZE;
|
||||
}
|
||||
|
||||
private Memory<byte> GetPoffinSpan(int index) => Raw.Slice(GetPoffinOffset(index), Poffin8b.SIZE);
|
||||
|
||||
@@ -500,9 +500,9 @@ public override void SetDex(PKM pk)
|
||||
|
||||
public override void SeenNone()
|
||||
{
|
||||
Array.Clear(Galar.Data, 0, Galar.Data.Length);
|
||||
Array.Clear(Rigel1.Data, 0, Rigel1.Data.Length);
|
||||
Array.Clear(Rigel2.Data, 0, Rigel2.Data.Length);
|
||||
Galar .Data.AsSpan().Clear();
|
||||
Rigel1.Data.AsSpan().Clear();
|
||||
Rigel2.Data.AsSpan().Clear();
|
||||
}
|
||||
|
||||
public override void CaughtNone()
|
||||
|
||||
@@ -9,7 +9,7 @@ public static partial class Util
|
||||
{
|
||||
public static List<ComboItem> GetCountryRegionList(string textFile, string lang)
|
||||
{
|
||||
string[] inputCSV = GetStringList(textFile);
|
||||
var inputCSV = GetStringList(textFile);
|
||||
int index = GeoLocation.GetLanguageIndex(lang);
|
||||
var list = GetCBListFromCSV(inputCSV, index);
|
||||
if (list.Count > 1)
|
||||
|
||||
@@ -8,6 +8,6 @@ public static partial class Util
|
||||
public static Random Rand => Random.Shared;
|
||||
|
||||
public static uint Rand32() => Rand32(Rand);
|
||||
public static uint Rand32(this Random rnd) => ((uint)rnd.Next(1 << 30) << 2) | (uint)rnd.Next(1 << 2);
|
||||
public static uint Rand32(this Random rnd) => (uint)rnd.NextInt64();
|
||||
public static ulong Rand64(this Random rnd) => rnd.Rand32() | ((ulong)rnd.Rand32() << 32);
|
||||
}
|
||||
|
||||
@@ -685,21 +685,21 @@ private void ReadSubway()
|
||||
CHK_SWNPCMet.Checked = sw.NPCMet;
|
||||
|
||||
// Current Run Checks
|
||||
CHK_SingleSet.Checked = sw.SingleSet == (sw.SinglePast / 7 + 1);
|
||||
CHK_SingleSet.Checked = sw.SingleSet == ((sw.SinglePast / 7) + 1);
|
||||
L_SinglePast.Text = CHK_SingleSet.Checked ? "Current" : "Past";
|
||||
CHK_DoubleSet.Checked = sw.DoubleSet == (sw.DoublePast / 7 + 1);
|
||||
CHK_DoubleSet.Checked = sw.DoubleSet == ((sw.DoublePast / 7) + 1);
|
||||
L_DoublePast.Text = CHK_DoubleSet.Checked ? "Current" : "Past";
|
||||
CHK_MultiNPCSet.Checked = sw.MultiNPCSet == (sw.MultiNPCPast / 7 + 1);
|
||||
CHK_MultiNPCSet.Checked = sw.MultiNPCSet == ((sw.MultiNPCPast / 7) + 1);
|
||||
L_MultiNpcPast.Text = CHK_MultiNPCSet.Checked ? "Current" : "Past";
|
||||
CHK_MultiFriendsSet.Checked = sw.MultiFriendsSet == (sw.MultiFriendsPast / 7 + 1);
|
||||
CHK_MultiFriendsSet.Checked = sw.MultiFriendsSet == ((sw.MultiFriendsPast / 7) + 1);
|
||||
L_MultiFriendsPast.Text = CHK_MultiFriendsSet.Checked ? "Current" : "Past";
|
||||
CHK_SuperSingleSet.Checked = sw.SuperSingleSet == (sw.SuperSinglePast / 7 + 1);
|
||||
CHK_SuperSingleSet.Checked = sw.SuperSingleSet == ((sw.SuperSinglePast / 7) + 1);
|
||||
L_SSinglePast.Text = CHK_SuperSingleSet.Checked ? "Current" : "Past";
|
||||
CHK_SuperDoubleSet.Checked = sw.SuperDoubleSet == (sw.SuperDoublePast / 7 + 1);
|
||||
CHK_SuperDoubleSet.Checked = sw.SuperDoubleSet == ((sw.SuperDoublePast / 7) + 1);
|
||||
L_SDoublePast.Text = CHK_SuperDoubleSet.Checked ? "Current" : "Past";
|
||||
CHK_SuperMultiNPCSet.Checked = sw.SuperMultiNPCSet == (sw.SuperMultiNPCPast / 7 + 1);
|
||||
CHK_SuperMultiNPCSet.Checked = sw.SuperMultiNPCSet == ((sw.SuperMultiNPCPast / 7) + 1);
|
||||
L_SMultiNpcPast.Text = CHK_SuperMultiNPCSet.Checked ? "Current" : "Past";
|
||||
CHK_SuperMultiFriendsSet.Checked = sw.SuperMultiFriendsSet == (sw.SuperMultiFriendsPast / 7 + 1);
|
||||
CHK_SuperMultiFriendsSet.Checked = sw.SuperMultiFriendsSet == ((sw.SuperMultiFriendsPast / 7) + 1);
|
||||
L_SMultiFriendsPast.Text = CHK_SuperMultiFriendsSet.Checked ? "Current" : "Past";
|
||||
|
||||
// Normal
|
||||
@@ -793,14 +793,14 @@ private void SaveSubway()
|
||||
sw.SuperMultiFriendsRecord = (int)NUD_SMultiFriendsRecord.Value;
|
||||
|
||||
// Current Run Checks
|
||||
sw.SingleSet = (CHK_SingleSet.Checked ? sw.SinglePast / 7 + 1 : 0);
|
||||
sw.DoubleSet = (CHK_DoubleSet.Checked ? sw.DoublePast / 7 + 1 : 0);
|
||||
sw.MultiNPCSet = (CHK_MultiNPCSet.Checked ? sw.MultiNPCPast / 7 + 1 : 0);
|
||||
sw.MultiFriendsSet = (CHK_MultiFriendsSet.Checked ? sw.MultiFriendsPast / 7 + 1 : 0);
|
||||
sw.SuperSingleSet = (CHK_SuperSingleSet.Checked ? sw.SuperSinglePast / 7 + 1 : 0);
|
||||
sw.SuperDoubleSet = (CHK_SuperDoubleSet.Checked ? sw.SuperDoublePast / 7 + 1 : 0);
|
||||
sw.SuperMultiNPCSet = (CHK_SuperMultiNPCSet.Checked ? sw.SuperMultiNPCPast / 7 + 1 : 0);
|
||||
sw.SuperMultiFriendsSet = (CHK_SuperMultiFriendsSet.Checked ? sw.SuperMultiFriendsPast / 7 + 1 : 0);
|
||||
sw.SingleSet = (CHK_SingleSet.Checked ? (sw.SinglePast / 7) + 1 : 0);
|
||||
sw.DoubleSet = (CHK_DoubleSet.Checked ? (sw.DoublePast / 7) + 1 : 0);
|
||||
sw.MultiNPCSet = (CHK_MultiNPCSet.Checked ? (sw.MultiNPCPast / 7) + 1 : 0);
|
||||
sw.MultiFriendsSet = (CHK_MultiFriendsSet.Checked ? (sw.MultiFriendsPast / 7) + 1 : 0);
|
||||
sw.SuperSingleSet = (CHK_SuperSingleSet.Checked ? (sw.SuperSinglePast / 7) + 1 : 0);
|
||||
sw.SuperDoubleSet = (CHK_SuperDoubleSet.Checked ? (sw.SuperDoublePast / 7) + 1 : 0);
|
||||
sw.SuperMultiNPCSet = (CHK_SuperMultiNPCSet.Checked ? (sw.SuperMultiNPCPast / 7) + 1 : 0);
|
||||
sw.SuperMultiFriendsSet = (CHK_SuperMultiFriendsSet.Checked ? (sw.SuperMultiFriendsPast / 7) + 1 : 0);
|
||||
}
|
||||
|
||||
private const string ForestCityBinFilter = "Forest City Bin|*.fc5";
|
||||
|
||||
@@ -264,7 +264,6 @@ public static bool OpenSAVPKMDialog(IEnumerable<string> extensions, out string?
|
||||
var sb = new StringBuilder(128);
|
||||
foreach (var type in extensions)
|
||||
sb.Append($"*.{type};");
|
||||
sb.Append("*.pk");
|
||||
|
||||
string supported = sb.ToString();
|
||||
using var ofd = new OpenFileDialog();
|
||||
@@ -275,23 +274,7 @@ public static bool OpenSAVPKMDialog(IEnumerable<string> extensions, out string?
|
||||
"|Binary File|*.bin" +
|
||||
"|Backup File|*.bak";
|
||||
|
||||
// Detect main
|
||||
SaveFile? sav = null;
|
||||
if (DetectSaveFileOnFileOpen)
|
||||
{
|
||||
try
|
||||
{
|
||||
sav = SaveFinder.FindMostRecentSaveFile();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Error(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
if (sav != null)
|
||||
ofd.FileName = sav.Metadata.FileName;
|
||||
|
||||
ofd.FileName = SuggestInitialFileName();
|
||||
if (ofd.ShowDialog() != DialogResult.OK)
|
||||
{
|
||||
path = null;
|
||||
@@ -302,6 +285,23 @@ public static bool OpenSAVPKMDialog(IEnumerable<string> extensions, out string?
|
||||
return true;
|
||||
}
|
||||
|
||||
private static string? SuggestInitialFileName()
|
||||
{
|
||||
if (DetectSaveFileOnFileOpen)
|
||||
{
|
||||
try
|
||||
{
|
||||
var sav = SaveFinder.FindMostRecentSaveFile();
|
||||
return sav?.Metadata.FilePath;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Error(ex.Message);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Opens a dialog to save a <see cref="PKM"/> file.
|
||||
/// </summary>
|
||||
@@ -312,7 +312,7 @@ public static bool SavePKMDialog(PKM pk)
|
||||
string pkx = pk.Extension;
|
||||
bool allowEncrypted = pk.Format >= 3 && pkx.StartsWith('p');
|
||||
var genericFilter = $"Decrypted PKM File|*.{pkx}" +
|
||||
(allowEncrypted ? $"|Encrypted PKM File|*.e{pkx[1..]}" : string.Empty) +
|
||||
(allowEncrypted ? $"|Encrypted PKM File|*.e{pkx.AsSpan(1)}" : string.Empty) +
|
||||
"|Binary File|*.bin" +
|
||||
"|All Files|*.*";
|
||||
using var sfd = new SaveFileDialog();
|
||||
@@ -326,11 +326,11 @@ public static bool SavePKMDialog(PKM pk)
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void SavePKM(PKM pk, string path, string pkx)
|
||||
private static void SavePKM(PKM pk, string path, ReadOnlySpan<char> pkx)
|
||||
{
|
||||
SaveBackup(path);
|
||||
string ext = Path.GetExtension(path);
|
||||
var data = $".{pkx}" == ext ? pk.DecryptedPartyData : pk.EncryptedPartyData;
|
||||
var ext = Path.GetExtension(path);
|
||||
var data = ext == $".{pkx}" ? pk.DecryptedPartyData : pk.EncryptedPartyData;
|
||||
File.WriteAllBytes(path, data);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user