mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-26 05:50:22 +00:00
Update 22.12.01
This commit is contained in:
parent
f10c914eac
commit
2e67526db1
15 changed files with 354 additions and 31 deletions
|
@ -1,6 +1,6 @@
|
|||
<Project>
|
||||
<PropertyGroup>
|
||||
<Version>22.11.26</Version>
|
||||
<Version>22.12.01</Version>
|
||||
<LangVersion>10</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<NeutralLanguage>en</NeutralLanguage>
|
||||
|
|
|
@ -106,7 +106,8 @@ internal static class Encounters9
|
|||
|
||||
private static readonly EncounterTera9[] Tera = EncounterTera9.GetArray(Get("gem_paldea"));
|
||||
private static readonly EncounterDist9[] Dist = EncounterDist9.GetArray(Get("dist_paldea"));
|
||||
private static readonly EncounterMight9[] Might = EncounterMight9.GetArray(Get("might_paldea"));
|
||||
private static readonly EncounterFixed9[] Fixed = EncounterFixed9.GetArray(Get("fixed_paldea"));
|
||||
internal static readonly EncounterStatic[] StaticSL = ArrayUtil.ConcatAll<EncounterStatic>(GetEncounters(Encounter_SV, SL), Tera, Dist, Fixed);
|
||||
internal static readonly EncounterStatic[] StaticVL = ArrayUtil.ConcatAll<EncounterStatic>(GetEncounters(Encounter_SV, VL), Tera, Dist, Fixed);
|
||||
internal static readonly EncounterStatic[] StaticSL = ArrayUtil.ConcatAll<EncounterStatic>(GetEncounters(Encounter_SV, SL), Tera, Dist, Might, Fixed);
|
||||
internal static readonly EncounterStatic[] StaticVL = ArrayUtil.ConcatAll<EncounterStatic>(GetEncounters(Encounter_SV, VL), Tera, Dist, Might, Fixed);
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ public sealed record EncounterDist9 : EncounterStatic, ITeraRaid9
|
|||
public byte Index { get; private init; }
|
||||
public byte Stars { get; private init; }
|
||||
public byte RandRate { get; private init; } // weight chance of this encounter
|
||||
|
||||
|
||||
public ushort RandRate0MinScarlet { get; private init; }
|
||||
public ushort RandRate0MinViolet { get; private init; }
|
||||
public ushort RandRate0TotalScarlet { get; private init; }
|
||||
|
@ -138,7 +138,6 @@ public sealed record EncounterDist9 : EncounterStatic, ITeraRaid9
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
public static EncounterDist9[] GetArray(ReadOnlySpan<byte> data)
|
||||
{
|
||||
var count = data.Length / SerializedSize;
|
||||
|
|
|
@ -0,0 +1,289 @@
|
|||
using System;
|
||||
using static System.Buffers.Binary.BinaryPrimitives;
|
||||
|
||||
namespace PKHeX.Core;
|
||||
|
||||
public sealed record EncounterMight9 : EncounterStatic, ITeraRaid9
|
||||
{
|
||||
public override int Generation => 9;
|
||||
public override int Location => Locations.TeraCavern9;
|
||||
public override EntityContext Context => EntityContext.Gen9;
|
||||
public bool IsDistribution => Index != 0;
|
||||
public GemType TeraType { get; private init; }
|
||||
public byte Index { get; private init; }
|
||||
public byte Stars { get; private init; }
|
||||
public byte RandRate { get; private init; } // weight chance of this encounter
|
||||
public byte Scale { get; init; }
|
||||
|
||||
public ushort RandRate0MinScarlet { get; private init; }
|
||||
public ushort RandRate0MinViolet { get; private init; }
|
||||
public ushort RandRate0TotalScarlet { get; private init; }
|
||||
public ushort RandRate0TotalViolet { get; private init; }
|
||||
|
||||
public ushort RandRate1MinScarlet { get; private init; }
|
||||
public ushort RandRate1MinViolet { get; private init; }
|
||||
public ushort RandRate1TotalScarlet { get; private init; }
|
||||
public ushort RandRate1TotalViolet { get; private init; }
|
||||
|
||||
public ushort RandRate2MinScarlet { get; private init; }
|
||||
public ushort RandRate2MinViolet { get; private init; }
|
||||
public ushort RandRate2TotalScarlet { get; private init; }
|
||||
public ushort RandRate2TotalViolet { get; private init; }
|
||||
|
||||
public ushort RandRate3MinScarlet { get; private init; }
|
||||
public ushort RandRate3MinViolet { get; private init; }
|
||||
public ushort RandRate3TotalScarlet { get; private init; }
|
||||
public ushort RandRate3TotalViolet { get; private init; }
|
||||
|
||||
public ushort GetRandRateTotalScarlet(int stage) => stage switch
|
||||
{
|
||||
0 => RandRate0TotalScarlet,
|
||||
1 => RandRate1TotalScarlet,
|
||||
2 => RandRate2TotalScarlet,
|
||||
3 => RandRate3TotalScarlet,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(stage)),
|
||||
};
|
||||
|
||||
public ushort GetRandRateTotalViolet(int stage) => stage switch
|
||||
{
|
||||
0 => RandRate0TotalViolet,
|
||||
1 => RandRate1TotalViolet,
|
||||
2 => RandRate2TotalViolet,
|
||||
3 => RandRate3TotalViolet,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(stage)),
|
||||
};
|
||||
|
||||
public ushort GetRandRateMinScarlet(int stage) => stage switch
|
||||
{
|
||||
0 => RandRate0MinScarlet,
|
||||
1 => RandRate1MinScarlet,
|
||||
2 => RandRate2MinScarlet,
|
||||
3 => RandRate3MinScarlet,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(stage)),
|
||||
};
|
||||
|
||||
public ushort GetRandRateMinViolet(int stage) => stage switch
|
||||
{
|
||||
0 => RandRate0MinViolet,
|
||||
1 => RandRate1MinViolet,
|
||||
2 => RandRate2MinViolet,
|
||||
3 => RandRate3MinViolet,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(stage)),
|
||||
};
|
||||
|
||||
private const int StageCount = 4;
|
||||
private const int StageNone = -1;
|
||||
|
||||
public bool CanBeEncountered(uint seed) => GetProgressMaximum(seed) != StageNone;
|
||||
|
||||
public int ProgressStageMin
|
||||
{
|
||||
get
|
||||
{
|
||||
for (int stage = 0; stage < StageCount; stage++)
|
||||
{
|
||||
if (GetRandRateTotalScarlet(stage) != 0 || GetRandRateTotalViolet(stage) != 0)
|
||||
return stage;
|
||||
}
|
||||
return StageNone;
|
||||
}
|
||||
}
|
||||
|
||||
public int ProgressStageMax
|
||||
{
|
||||
get
|
||||
{
|
||||
for (int stage = StageCount - 1; stage >= 0; stage--)
|
||||
{
|
||||
if (GetRandRateTotalScarlet(stage) != 0 || GetRandRateTotalViolet(stage) != 0)
|
||||
return stage;
|
||||
}
|
||||
return StageNone;
|
||||
}
|
||||
}
|
||||
|
||||
public int GetProgressMaximum(uint seed)
|
||||
{
|
||||
// We loop from the highest progress, since that is where the majority of samples will be from.
|
||||
for (int i = StageCount - 1; i >= 0; i--)
|
||||
{
|
||||
if (GetIsPossibleSlot(seed, i))
|
||||
return i;
|
||||
}
|
||||
return StageNone;
|
||||
}
|
||||
|
||||
private bool GetIsPossibleSlot(uint seed, int stage)
|
||||
{
|
||||
var totalScarlet = GetRandRateTotalScarlet(stage);
|
||||
if (totalScarlet != 0)
|
||||
{
|
||||
var rand = new Xoroshiro128Plus(seed);
|
||||
_ = rand.NextInt(100);
|
||||
var val = rand.NextInt(totalScarlet);
|
||||
var min = GetRandRateMinScarlet(stage);
|
||||
if ((uint)((int)val - min) < RandRate)
|
||||
return true;
|
||||
}
|
||||
|
||||
var totalViolet = GetRandRateTotalViolet(stage);
|
||||
if (totalViolet != 0)
|
||||
{
|
||||
var rand = new Xoroshiro128Plus(seed);
|
||||
_ = rand.NextInt(100);
|
||||
var val = rand.NextInt(totalViolet);
|
||||
var min = GetRandRateMinViolet(stage);
|
||||
if ((uint)((int)val - min) < RandRate)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static EncounterMight9[] GetArray(ReadOnlySpan<byte> data)
|
||||
{
|
||||
var count = data.Length / SerializedSize;
|
||||
var result = new EncounterMight9[count];
|
||||
for (int i = 0; i < result.Length; i++)
|
||||
result[i] = ReadEncounter(data.Slice(i * SerializedSize, SerializedSize));
|
||||
return result;
|
||||
}
|
||||
|
||||
private EncounterMight9() : base(GameVersion.SV) { }
|
||||
|
||||
private const int SerializedSize = WeightStart + (sizeof(ushort) * 2 * 2 * 4) + 10;
|
||||
private const int WeightStart = 0x14;
|
||||
private static EncounterMight9 ReadEncounter(ReadOnlySpan<byte> data) => new()
|
||||
{
|
||||
Species = ReadUInt16LittleEndian(data),
|
||||
Form = data[0x02],
|
||||
Gender = (sbyte)(data[0x03] - 1),
|
||||
Ability = GetAbility(data[0x04]),
|
||||
FlawlessIVCount = data[5],
|
||||
Shiny = data[0x06] switch { 0 => Shiny.Random, 1 => Shiny.Never, 2 => Shiny.Always, _ => throw new ArgumentOutOfRangeException(nameof(data)) },
|
||||
Level = data[0x07],
|
||||
Moves = new Moveset(
|
||||
ReadUInt16LittleEndian(data[0x08..]),
|
||||
ReadUInt16LittleEndian(data[0x0A..]),
|
||||
ReadUInt16LittleEndian(data[0x0C..]),
|
||||
ReadUInt16LittleEndian(data[0x0E..])),
|
||||
TeraType = (GemType)data[0x10],
|
||||
Index = data[0x11],
|
||||
Stars = data[0x12],
|
||||
RandRate = data[0x13],
|
||||
|
||||
RandRate0MinScarlet = ReadUInt16LittleEndian(data[WeightStart..]),
|
||||
RandRate0MinViolet = ReadUInt16LittleEndian(data[(WeightStart + sizeof(ushort))..]),
|
||||
RandRate0TotalScarlet = ReadUInt16LittleEndian(data[(WeightStart + (sizeof(ushort) * 2))..]),
|
||||
RandRate0TotalViolet = ReadUInt16LittleEndian(data[(WeightStart + (sizeof(ushort) * 3))..]),
|
||||
|
||||
RandRate1MinScarlet = ReadUInt16LittleEndian(data[(WeightStart + (sizeof(ushort) * 4))..]),
|
||||
RandRate1MinViolet = ReadUInt16LittleEndian(data[(WeightStart + (sizeof(ushort) * 5))..]),
|
||||
RandRate1TotalScarlet = ReadUInt16LittleEndian(data[(WeightStart + (sizeof(ushort) * 6))..]),
|
||||
RandRate1TotalViolet = ReadUInt16LittleEndian(data[(WeightStart + (sizeof(ushort) * 7))..]),
|
||||
|
||||
RandRate2MinScarlet = ReadUInt16LittleEndian(data[(WeightStart + (sizeof(ushort) * 8))..]),
|
||||
RandRate2MinViolet = ReadUInt16LittleEndian(data[(WeightStart + (sizeof(ushort) * 9))..]),
|
||||
RandRate2TotalScarlet = ReadUInt16LittleEndian(data[(WeightStart + (sizeof(ushort) * 10))..]),
|
||||
RandRate2TotalViolet = ReadUInt16LittleEndian(data[(WeightStart + (sizeof(ushort) * 11))..]),
|
||||
|
||||
RandRate3MinScarlet = ReadUInt16LittleEndian(data[(WeightStart + (sizeof(ushort) * 12))..]),
|
||||
RandRate3MinViolet = ReadUInt16LittleEndian(data[(WeightStart + (sizeof(ushort) * 13))..]),
|
||||
RandRate3TotalScarlet = ReadUInt16LittleEndian(data[(WeightStart + (sizeof(ushort) * 14))..]),
|
||||
RandRate3TotalViolet = ReadUInt16LittleEndian(data[(WeightStart + (sizeof(ushort) * 15))..]),
|
||||
|
||||
Nature = (Nature)data[0x34],
|
||||
IVs = new IndividualValueSet((sbyte)data[0x35], (sbyte)data[0x36], (sbyte)data[0x37], (sbyte)data[0x38], (sbyte)data[0x39], (sbyte)data[0x3A], data[0x3B]),
|
||||
Scale = data[0x3C],
|
||||
};
|
||||
|
||||
private static AbilityPermission GetAbility(byte b) => b switch
|
||||
{
|
||||
0 => AbilityPermission.Any12,
|
||||
1 => AbilityPermission.Any12H,
|
||||
2 => AbilityPermission.OnlyFirst,
|
||||
3 => AbilityPermission.OnlySecond,
|
||||
4 => AbilityPermission.OnlyHidden,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(b), b, null),
|
||||
};
|
||||
|
||||
protected override EncounterMatchRating IsMatchDeferred(PKM pk)
|
||||
{
|
||||
if (Ability != AbilityPermission.Any12H)
|
||||
{
|
||||
// HA-Only is a strict match. Ability Capsule and Patch can potentially change these.
|
||||
var num = pk.AbilityNumber;
|
||||
if (num == 4)
|
||||
{
|
||||
if (Ability is not AbilityPermission.OnlyHidden && !AbilityVerifier.CanAbilityPatch(9, PersonalTable.SV.GetFormEntry(Species, Form), pk.Species))
|
||||
return EncounterMatchRating.DeferredErrors;
|
||||
}
|
||||
else if (Ability.IsSingleValue(out int index) && 1 << index != num) // Fixed regular ability
|
||||
{
|
||||
if (Ability is AbilityPermission.OnlyFirst or AbilityPermission.OnlySecond && !AbilityVerifier.CanAbilityCapsule(9, PersonalTable.SV.GetFormEntry(Species, Form)))
|
||||
return EncounterMatchRating.DeferredErrors;
|
||||
}
|
||||
}
|
||||
|
||||
return base.IsMatchDeferred(pk);
|
||||
}
|
||||
|
||||
protected override bool IsMatchPartial(PKM pk)
|
||||
{
|
||||
switch (Shiny)
|
||||
{
|
||||
case Shiny.Never when pk.IsShiny:
|
||||
case Shiny.Always when !pk.IsShiny:
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pk is IScaledSize3 s3 && s3.Scale != Scale)
|
||||
return true;
|
||||
if (IVs.IsSpecified && !Legal.GetIsFixedIVSequenceValidSkipRand(IVs, pk))
|
||||
return true;
|
||||
|
||||
var seed = Tera9RNG.GetOriginalSeed(pk);
|
||||
if (pk is ITeraType t && !Tera9RNG.IsMatchTeraType(seed, TeraType, Species, Form, (byte)t.TeraTypeOriginal))
|
||||
return true;
|
||||
if (!CanBeEncountered(seed))
|
||||
return true;
|
||||
|
||||
byte gender = GetGender();
|
||||
var param = new GenerateParam9(gender, FlawlessIVCount, 1, 0, 0, Scale, Ability, Shiny, Nature, IVs);
|
||||
if (!Encounter9RNG.IsMatch(pk, param, seed))
|
||||
return true;
|
||||
return base.IsMatchPartial(pk);
|
||||
}
|
||||
|
||||
protected override void ApplyDetails(ITrainerInfo tr, EncounterCriteria criteria, PKM pk)
|
||||
{
|
||||
base.ApplyDetails(tr, criteria, pk);
|
||||
var pk9 = (PK9)pk;
|
||||
pk9.Obedience_Level = (byte)pk9.Met_Level;
|
||||
pk9.RibbonMarkMightiest = true;
|
||||
}
|
||||
|
||||
protected override void SetPINGA(PKM pk, EncounterCriteria criteria)
|
||||
{
|
||||
var pk9 = (PK9)pk;
|
||||
|
||||
const byte rollCount = 1;
|
||||
const byte undefinedSize = 0;
|
||||
byte gender = GetGender();
|
||||
var param = new GenerateParam9(gender, FlawlessIVCount, rollCount,
|
||||
undefinedSize, undefinedSize, Scale,
|
||||
Ability, Shiny, Nature, IVs);
|
||||
|
||||
var init = Util.Rand.Rand64();
|
||||
var success = this.TryApply32(pk9, init, param, criteria);
|
||||
if (!success)
|
||||
this.TryApply32(pk9, init, param, EncounterCriteria.Unrestricted);
|
||||
}
|
||||
|
||||
private byte GetGender() => Gender switch
|
||||
{
|
||||
0 => PersonalInfo.RatioMagicMale,
|
||||
1 => PersonalInfo.RatioMagicFemale,
|
||||
2 => PersonalInfo.RatioMagicGenderless,
|
||||
_ => (byte)PersonalTable.SV.GetFormEntry(Species, Form).Gender,
|
||||
};
|
||||
}
|
|
@ -15,7 +15,7 @@ public static class Encounter9RNG
|
|||
uint seed = (uint)rand.NextInt(uint.MaxValue);
|
||||
if (!enc.CanBeEncountered(seed))
|
||||
continue;
|
||||
if (!GenerateData(pk, param, criteria, seed))
|
||||
if (!GenerateData(pk, param, criteria, seed, param.IVs.IsSpecified))
|
||||
continue;
|
||||
|
||||
var type = Tera9RNG.GetTeraType(seed, enc.TeraType, enc.Species, enc.Form);
|
||||
|
@ -78,24 +78,30 @@ public static class Encounter9RNG
|
|||
|
||||
const int UNSET = -1;
|
||||
Span<int> ivs = stackalloc[] { UNSET, UNSET, UNSET, UNSET, UNSET, UNSET };
|
||||
const int MAX = 31;
|
||||
for (int i = 0; i < enc.FlawlessIVs; i++)
|
||||
if (enc.IVs.IsSpecified)
|
||||
{
|
||||
int index;
|
||||
do { index = (int)rand.NextInt(6); }
|
||||
while (ivs[index] != UNSET);
|
||||
ivs[index] = MAX;
|
||||
enc.IVs.CopyToSpeedLast(ivs);
|
||||
}
|
||||
else
|
||||
{
|
||||
const int MAX = 31;
|
||||
for (int i = 0; i < enc.FlawlessIVs; i++)
|
||||
{
|
||||
int index;
|
||||
do { index = (int)rand.NextInt(6); }
|
||||
while (ivs[index] != UNSET);
|
||||
ivs[index] = MAX;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ignoreIVs && !criteria.IsIVsCompatible(ivs, 9))
|
||||
return false;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (ivs[i] == UNSET)
|
||||
ivs[i] = (int)rand.NextInt(32);
|
||||
}
|
||||
|
||||
if (!ignoreIVs && !criteria.IsIVsCompatible(ivs, 9))
|
||||
return false;
|
||||
|
||||
pk.IV_HP = ivs[0];
|
||||
pk.IV_ATK = ivs[1];
|
||||
pk.IV_DEF = ivs[2];
|
||||
|
@ -123,7 +129,7 @@ public static class Encounter9RNG
|
|||
return false;
|
||||
pk.Gender = gender;
|
||||
|
||||
byte nature = pk.Species == (int)Species.Toxtricity
|
||||
byte nature = enc.Nature != Nature.Random ? (byte)enc.Nature : pk.Species == (int)Species.Toxtricity
|
||||
? ToxtricityUtil.GetRandomNature(ref rand, pk.Form)
|
||||
: (byte)rand.NextInt(25);
|
||||
if (criteria.Nature != Nature.Random && nature != (int)criteria.Nature)
|
||||
|
@ -180,13 +186,20 @@ public static class Encounter9RNG
|
|||
|
||||
const int UNSET = -1;
|
||||
Span<int> ivs = stackalloc[] { UNSET, UNSET, UNSET, UNSET, UNSET, UNSET };
|
||||
const int MAX = 31;
|
||||
for (int i = 0; i < enc.FlawlessIVs; i++)
|
||||
if (enc.IVs.IsSpecified)
|
||||
{
|
||||
int index;
|
||||
do { index = (int)rand.NextInt(6); }
|
||||
while (ivs[index] != UNSET);
|
||||
ivs[index] = MAX;
|
||||
enc.IVs.CopyToSpeedLast(ivs);
|
||||
}
|
||||
else
|
||||
{
|
||||
const int MAX = 31;
|
||||
for (int i = 0; i < enc.FlawlessIVs; i++)
|
||||
{
|
||||
int index;
|
||||
do { index = (int)rand.NextInt(6); }
|
||||
while (ivs[index] != UNSET);
|
||||
ivs[index] = MAX;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
|
@ -226,7 +239,7 @@ public static class Encounter9RNG
|
|||
if (pk.Gender != gender)
|
||||
return false;
|
||||
|
||||
int nature = pk.Species == (int)Species.Toxtricity
|
||||
byte nature = enc.Nature != Nature.Random ? (byte)enc.Nature : pk.Species == (int)Species.Toxtricity
|
||||
? ToxtricityUtil.GetRandomNature(ref rand, pk.Form)
|
||||
: (byte)rand.NextInt(25);
|
||||
if (pk.Nature != nature)
|
||||
|
|
|
@ -11,5 +11,8 @@ namespace PKHeX.Core;
|
|||
/// <param name="Scale">Scale value to generate. If zero, full random.</param>
|
||||
/// <param name="Ability">Ability type to generate.</param>
|
||||
/// <param name="Shiny">PID generation type.</param>
|
||||
public readonly record struct GenerateParam9(byte GenderRatio, byte FlawlessIVs, byte RollCount, byte Height, byte Weight, byte Scale,
|
||||
AbilityPermission Ability = AbilityPermission.Any12, Shiny Shiny = Shiny.Random);
|
||||
/// <param name="Nature">Nature specification.</param>
|
||||
/// <param name="IVs">IV specification.</param>
|
||||
public readonly record struct GenerateParam9(byte GenderRatio, byte FlawlessIVs, byte RollCount, byte Height,
|
||||
byte Weight, byte Scale, AbilityPermission Ability = AbilityPermission.Any12, Shiny Shiny = Shiny.Random,
|
||||
Nature Nature = Nature.Random, IndividualValueSet IVs = default);
|
||||
|
|
|
@ -173,7 +173,6 @@ public sealed class MiscVerifier : Verifier
|
|||
|
||||
private static readonly HashSet<int> UnreleasedSV = new()
|
||||
{
|
||||
(int)Species.Charmander, // Charmander : distribution raids happening on Dec 1, 2022
|
||||
(int)Species.Raichu | (1 << 11), // Diglett-1
|
||||
(int)Species.Diglett | (1 << 11), // Diglett-1
|
||||
(int)Species.Meowth | (1 << 11), // Meowth-1
|
||||
|
|
|
@ -160,7 +160,7 @@ public static class MarkRules
|
|||
public static bool IsMarkPresentMightiest(IEncounterTemplate enc)
|
||||
{
|
||||
// 7 star raids only.
|
||||
return enc is EncounterTera9 { Stars: 7 };
|
||||
return enc is EncounterMight9 { Stars: 7 };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -312,7 +312,7 @@ public sealed class WC9 : DataMysteryGift, ILangNick, INature, ITeraType, IRibbo
|
|||
}
|
||||
|
||||
public int GetLanguage(int redeemLanguage) => Data[GetLanguageOffset(GetLanguageIndex(redeemLanguage))];
|
||||
private static int GetLanguageOffset(int index) => 0x30 + (index * 0x1C) + 0x1A;
|
||||
private static int GetLanguageOffset(int index) => 0x28 + (index * 0x1C) + 0x1A;
|
||||
|
||||
public bool GetHasOT(int language) => ReadUInt16LittleEndian(Data.AsSpan(GetOTOffset(language))) != 0;
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -119,4 +119,5 @@ public enum TeraRaidContentType : uint
|
|||
Base05,
|
||||
Black6,
|
||||
Distribution,
|
||||
Might7,
|
||||
}
|
||||
|
|
|
@ -19,8 +19,12 @@ public static class SaveUtil
|
|||
public const int SIZE_G9_0a = 0x31627C; // 1.0.0 after multiplayer
|
||||
public const int SIZE_G9_1 = 0x319DB3; // 1.0.1 fresh
|
||||
public const int SIZE_G9_1a = 0x319DC0; // 1.0.1 after multiplayer
|
||||
public const int SIZE_G9_3 = 0x319DC3; // 1.1.0 fresh
|
||||
public const int SIZE_G9_1Ba = 0x319DD0; // 1.0.1 -> 1.1.0
|
||||
public const int SIZE_G9_1A = 0x31A2C0; // 1.0.0 -> 1.0.1
|
||||
public const int SIZE_G9_1Aa = 0x31A2CD; // 1.0.1 -> 1.0.1 after multiplayer
|
||||
public const int SIZE_G9_1Aa = 0x31A2CD; // 1.0.0 -> 1.0.1 -> 1.0.1 after multiplayer
|
||||
public const int SIZE_G9_1Ab = 0x31A2DD; // 1.0.0 -> 1.0.1 -> 1.0.1 after multiplayer -> 1.1.0
|
||||
public const int SIZE_G9_2 = 0x31A2D0; // 1.0.0 -> 1.1.0
|
||||
|
||||
public const int SIZE_G8LA = 0x136DDE;
|
||||
public const int SIZE_G8LA_1 = 0x13AD06;
|
||||
|
@ -106,6 +110,8 @@ public static class SaveUtil
|
|||
SIZE_G9_0, SIZE_G9_0a,
|
||||
SIZE_G9_1, SIZE_G9_1a,
|
||||
SIZE_G9_1A, SIZE_G9_1Aa,
|
||||
SIZE_G9_1Ba, SIZE_G9_1Ab,
|
||||
SIZE_G9_2, SIZE_G9_3,
|
||||
};
|
||||
|
||||
private static readonly HashSet<int> SizesSWSH = new()
|
||||
|
|
|
@ -1,7 +1,19 @@
|
|||
PKHeX - By Kaphotics
|
||||
http://projectpokemon.org/pkhex/
|
||||
|
||||
22/11/26 - New Update:
|
||||
22/12/01 - New Update:
|
||||
- Added support for Scarlet & Violet 1.1.0.
|
||||
- Legality:
|
||||
- - Fixed: Gen9 banned species list updated.
|
||||
- - Fixed: Gen9 TR flags now check pre-evolutions if the current evolution does not have a required move flag.
|
||||
- - Fixed: Ability patch reverting check updated to account for single-evolution-chain cases.
|
||||
- Fixed: Showdown Set imports without a Tera Type will default to the species' first type.
|
||||
- Fixed: WC9 now generates with correct SID7. Thanks @Manu098vm !
|
||||
- Fixed: Associating a pk9 file to PKHeX.exe now starts up properly.
|
||||
- Fixed: Form argument suggestion for Mankey & Pawniard, when evolved to max evo stage, added.
|
||||
- Changed: Updated translation files. Thanks @easyworld, @Yarkis01
|
||||
|
||||
22/11/26 - New Update: (98776) [5755880]
|
||||
- Legality:
|
||||
- - Fixed: Encounter->PK9 small fixes added.
|
||||
- - Added: Distribution Raids (Eevee) now recognized.
|
||||
|
|
|
@ -16,6 +16,6 @@ public class MarshalTests
|
|||
Marshal.SizeOf(typeof(EvolutionMethod)).Should().Be(8);
|
||||
Marshal.SizeOf(typeof(Moveset)).Should().Be(8);
|
||||
Marshal.SizeOf(typeof(IndividualValueSet)).Should().BeLessOrEqualTo(8);
|
||||
Marshal.SizeOf(typeof(GenerateParam9)).Should().BeLessOrEqualTo(8);
|
||||
Marshal.SizeOf(typeof(GenerateParam9)).Should().BeLessOrEqualTo(16);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue