S/V 1.2.0 Support (#3819)

This commit is contained in:
Kurt 2023-02-27 19:12:27 -08:00 committed by GitHub
parent 353ca40f42
commit 0f1fba86f7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
45 changed files with 132 additions and 68 deletions

View file

@ -880,8 +880,8 @@ public enum Move
AquaStep,
RagingBull,
MakeItRain,
_875,
_876,
Psyblade,
HydroSteam,
Ruination,
CollisionCourse,
ElectroDrift,

View file

@ -1014,7 +1014,7 @@ public enum Species : ushort
IronValiant,
Koraidon,
Miraidon,
_980,
_987,
WalkingWake,
IronLeaves,
MAX_COUNT,
}

View file

@ -8,7 +8,7 @@ namespace PKHeX.Core;
public static class GeoLocation
{
private static readonly string[]?[] CountryList = GetCountryList();
internal static readonly string[] lang_geo = { "ja", "en", "fr", "de", "it", "es", "zh", "ko", "zh2" };
private static readonly string[] lang_geo = { "ja", "en", "fr", "de", "it", "es", "zh", "ko", "zh2" };
private static readonly string[]?[]?[] RegionList = new string[CountryList.Length][][];
/// <summary>
@ -58,7 +58,7 @@ public static class GeoLocation
if ((uint)country >= CountryList.Length)
return INVALID;
var countryNames = CountryList[country];
if (countryNames is not null && l < countryNames.Length)
if (countryNames is not null && (uint)l < countryNames.Length)
return countryNames[l + 1];
return INVALID;
}
@ -73,7 +73,7 @@ public static class GeoLocation
if ((uint)region >= regionNames.Length)
return INVALID;
var localized = regionNames[region];
if (localized is not null && l < localized.Length)
if (localized is not null && (uint)l < localized.Length)
return localized[l + 1];
return INVALID;
}

View file

@ -60,7 +60,7 @@ public sealed record EncounterArea9 : EncounterArea
{
if (slot.Species != evo.Species)
continue;
if (slot.Form != evo.Form && slot.Species is not ((int)Species.Rotom or (int)Species.Deerling or (int)Species.Sawsbuck or (int)Species.Oricorio))
if (slot.Form != evo.Form && !IsFormOkayWild(slot.Species, evo.Form))
break;
if (slot.Gender != -1 && pk.Gender != slot.Gender)
break;
@ -80,4 +80,13 @@ public sealed record EncounterArea9 : EncounterArea
}
}
}
private static bool IsFormOkayWild(ushort species, byte form) => species switch
{
(int)Species.Rotom => true,
(int)Species.Deerling or (int)Species.Sawsbuck => true,
(int)Species.Scatterbug or (int)Species.Spewpa or (int)Species.Vivillon => form < Vivillon3DS.FancyFormID, // GO Postcard
(int)Species.Oricorio => true,
_ => false,
};
}

View file

@ -191,8 +191,8 @@ public static class Breeding
// Gen9
(int)Gimmighoul, (int)Gholdengo,
(int)GreatTusk, (int)BruteBonnet, (int)_980, (int)SandyShocks, (int)ScreamTail, (int)FlutterMane, (int)SlitherWing, (int)RoaringMoon,
(int)IronTreads, (int)_987, (int)IronMoth, (int)IronHands, (int)IronJugulis, (int)IronThorns, (int)IronBundle, (int)IronValiant,
(int)GreatTusk, (int)BruteBonnet, (int)WalkingWake, (int)SandyShocks, (int)ScreamTail, (int)FlutterMane, (int)SlitherWing, (int)RoaringMoon,
(int)IronTreads, (int)IronLeaves, (int)IronMoth, (int)IronHands, (int)IronJugulis, (int)IronThorns, (int)IronBundle, (int)IronValiant,
(int)TingLu, (int)ChienPao, (int)WoChien, (int)ChiYu,
(int)Koraidon, (int)Miraidon,
};

View file

@ -108,5 +108,6 @@ public static class EncounterServerDate
{0001, (new(2022, 11, 17), Never)}, // PokéCenter Flabébé
{0006, (new(2022, 12, 16), new(2023, 02, 01))}, // Jump Festa Gyarados
{0501, (new(2023, 02, 16), new(2023, 02, 21))}, // Jiseok's Garganacl
{1513, (new(2023, 02, 27), new(2024, 03, 01))}, // Hisuian Zoroark DLC Purchase Gift
};
}

View file

@ -14,6 +14,11 @@ public sealed record EncounterDist9 : EncounterStatic, ITeraRaid9
public byte Stars { get; private init; }
public byte RandRate { get; private init; } // weight chance of this encounter
/// <summary> Indicates how the <see cref="Scale"/> value is used, if at all. </summary>
public SizeType9 ScaleType { get; private init; }
/// <summary> Used only for <see cref="ScaleType"/> == <see cref="SizeType9.VALUE"/> </summary>
public byte Scale { get; private init; }
public ushort RandRate0MinScarlet { get; private init; }
public ushort RandRate0MinViolet { get; private init; }
public ushort RandRate0TotalScarlet { get; private init; }
@ -149,7 +154,7 @@ public sealed record EncounterDist9 : EncounterStatic, ITeraRaid9
private EncounterDist9() : base(GameVersion.SV) { }
private const int SerializedSize = WeightStart + (sizeof(ushort) * 2 * 2 * 4);
private const int SerializedSize = WeightStart + (sizeof(ushort) * 2 * 2 * 4) + 2;
private const int WeightStart = 0x14;
private static EncounterDist9 ReadEncounter(ReadOnlySpan<byte> data) => new()
{
@ -189,6 +194,9 @@ public sealed record EncounterDist9 : EncounterStatic, ITeraRaid9
RandRate3MinViolet = ReadUInt16LittleEndian(data[(WeightStart + (sizeof(ushort) * 13))..]),
RandRate3TotalScarlet = ReadUInt16LittleEndian(data[(WeightStart + (sizeof(ushort) * 14))..]),
RandRate3TotalViolet = ReadUInt16LittleEndian(data[(WeightStart + (sizeof(ushort) * 15))..]),
ScaleType = (SizeType9)data[0x34],
Scale = data[0x35],
};
private static AbilityPermission GetAbility(byte b) => b switch
@ -238,7 +246,7 @@ public sealed record EncounterDist9 : EncounterStatic, ITeraRaid9
return true;
var pi = PersonalTable.SV.GetFormEntry(Species, Form);
var param = new GenerateParam9(Species, pi.Gender, FlawlessIVCount, 1, 0, 0, 0, 0, Ability, Shiny);
var param = new GenerateParam9(Species, pi.Gender, FlawlessIVCount, 1, 0, 0, ScaleType, Scale, Ability, Shiny);
if (!Encounter9RNG.IsMatch(pk, param, seed))
return true;
return base.IsMatchPartial(pk);
@ -259,7 +267,7 @@ public sealed record EncounterDist9 : EncounterStatic, ITeraRaid9
const byte undefinedSize = 0;
var pi = PersonalTable.SV.GetFormEntry(Species, Form);
var param = new GenerateParam9(Species, pi.Gender, FlawlessIVCount, rollCount,
undefinedSize, undefinedSize, undefinedSize, undefinedSize,
undefinedSize, undefinedSize, ScaleType, Scale,
Ability, Shiny);
var init = Util.Rand.Rand64();

View file

@ -4,7 +4,7 @@ namespace PKHeX.Core;
public static partial class Legal
{
internal const int MaxSpeciesID_9 = (int)Species.Miraidon;
internal const int MaxSpeciesID_9 = (int)Species.IronLeaves;
internal const int MaxMoveID_9 = (int)Move.MagicalTorque;
internal const int MaxItemID_9 = 2400; // Yellow Dish
internal const int MaxAbilityID_9 = (int)Ability.MyceliumMight;

View file

@ -22,6 +22,10 @@ public sealed class MarkVerifier : Verifier
VerifyMarksPresent(data, m);
VerifyAffixedRibbonMark(data, m);
// temp logic to catch this case; in the future we will need more robust checks for encounters
if (data.EncounterMatch is WC9 { RibbonMarkCharismatic: true} && pk is IRibbonSetMark8 { RibbonMarkCharismatic: false})
data.AddLine(GetInvalid(string.Format(LRibbonMarkingFInvalid_0, GetRibbonNameSafe(MarkCharismatic))));
}
private void VerifyNoMarksPresent(LegalityAnalysis data, IRibbonIndex m)

View file

@ -192,7 +192,6 @@ public sealed class MiscVerifier : Verifier
(int)Species.Sneasel | (1 << 11), // Sneasel-1
(int)Species.Oshawott, // Oshawott
(int)Species.Basculin | (2 << 11), // Basculin-2
(int)Species.Zorua | (1 << 11), // Zorua-1
(int)Species.Chespin, // Chespin
(int)Species.Fennekin, // Fennekin
(int)Species.Carbink, // Carbink

View file

@ -34,6 +34,7 @@ public static class MarkRules
{
EncounterSlot8 or EncounterStatic8 { Gift: false, ScriptedNoMarks: false } => IsMarkAllowedSpecific8(mark, pk, enc),
EncounterSlot9 s => IsMarkAllowedSpecific9(mark, s),
WC9 wc9 => wc9.GetRibbonIndex(mark),
_ => false,
};

View file

@ -53,7 +53,7 @@ internal static class MoveInfo9
10, 10, 05, 20, 20, 10, 10, 05, 05, 05, 40, 10, 20, 10, 10, 10, 10, 05, 05, 15,
05, 10, 10, 10, 05, 05, 05, 15, 10, 10, 15, 05, 10, 10, 10, 05, 10, 10, 05, 10,
10, 10, 10, 10, 15, 15, 10, 10, 10, 05, 15, 10, 10, 10, 10, 10, 10, 15, 15, 05,
10, 15, 05, 01, 15, 10, 15, 10, 10, 10, 10, 10, 10, 10, 05, 35, 35, 10, 05, 05,
10, 15, 05, 01, 15, 10, 15, 10, 10, 10, 10, 10, 10, 10, 05, 15, 15, 10, 05, 05,
10, 10, 10, 10, 20, 20, 20, 05, 10, 10, 05, 10, 05, 05, 10, 20, 10, 10, 10, 10,
10,
};

View file

@ -873,8 +873,8 @@ Loderlied
Wogentanz
Rasender Stier
Goldrausch
WAZA_SAIKOBUREIDO
WAZA_HAIDOROSUTIIMU
Psychoschneide
Hydrodampf
Verderben
Kollisionskurs
Blitztour

View file

@ -1007,5 +1007,5 @@ Donnersichel
Eisenkrieger
Koraidon
Miraidon
AKETUBAN
BKETUBAN
Windewoge
Eisenblatt

View file

@ -873,8 +873,8 @@ Torch Song
Aqua Step
Raging Bull
Make It Rain
WAZA_SAIKOBUREIDO
WAZA_HAIDOROSUTIIMU
Psyblade
Hydro Steam
Ruination
Collision Course
Electro Drift

View file

@ -1007,5 +1007,5 @@ Roaring Moon
Iron Valiant
Koraidon
Miraidon
AKETUBAN
BKETUBAN
Walking Wake
Iron Leaves

View file

@ -873,8 +873,8 @@ Canto Ardiente
Danza Acuática
Furia Taurina
Fiebre Dorada
WAZA_SAIKOBUREIDO
WAZA_HAIDOROSUTIIMU
Psicohojas
Hidrovapor
Calamidad
Nitrochoque
Electroderrape

View file

@ -1007,5 +1007,5 @@ Bramaluna
Ferropaladín
Koraidon
Miraidon
AKETUBAN
BKETUBAN
Ondulagua
Ferroverdor

View file

@ -873,8 +873,8 @@ Chant Flamboyant
Danse Aquatique
Taurogne
Ruée dOr
WAZA_SAIKOBUREIDO
WAZA_HAIDOROSUTIIMU
Lame Psychique
Hydrovapeur
Cataclysme
Nitro Crash
Turbo Volt

View file

@ -1007,5 +1007,5 @@ Rugit-Lune
Garde-de-Fer
Koraidon
Miraidon
AKETUBAN
BKETUBAN
Serpente-Eau
Vert-de-Fer

View file

@ -873,8 +873,8 @@ Canzone Ardente
Idroballetto
Scatenatoro
Corsa allOro
WAZA_SAIKOBUREIDO
WAZA_HAIDOROSUTIIMU
Psicolama
Idrovapore
Catastrofe
Turboschianto
Fulmiscatto

View file

@ -1007,5 +1007,5 @@ Lunaruggente
Eroeferreo
Koraidon
Miraidon
AKETUBAN
BKETUBAN
Acquecrespe
Fogliaferrea

View file

@ -873,8 +873,8 @@
アクアステップ
レイジングブル
ゴールドラッシュ
WAZA_SAIKOBUREIDO
WAZA_HAIDOROSUTIIMU
サイコブレイド
ハイドロスチーム
カタストロフィ
アクセルブレイク
イナズマドライブ

View file

@ -1007,5 +1007,5 @@
テツノブジン
コライドン
ミライドン
AKETUBAN
BKETUBAN
ウネルミナモ
テツノイサハ

View file

@ -873,8 +873,8 @@ G의힘
아쿠아스텝
레이징불
골드러시
WAZA_SAIKOBUREIDO
WAZA_HAIDOROSUTIIMU
사이코블레이드
하이드로스팀
카타스트로피
액셀브레이크
라이트닝드라이브

View file

@ -1007,5 +1007,5 @@
무쇠무인
코라이돈
미라이돈
AKETUBAN
BKETUBAN
굽이치는물결
무쇠잎새

View file

@ -873,8 +873,8 @@
流水旋舞
怒牛
淘金潮
WAZA_SAIKOBUREIDO
WAZA_HAIDOROSUTIIMU
精神剑
水蒸气
大灾难
全开猛撞
闪电猛冲

View file

@ -873,8 +873,8 @@
流水旋舞
怒牛
淘金潮
WAZA_SAIKOBUREIDO
WAZA_HAIDOROSUTIIMU
精神劍
水蒸氣
大災難
全開猛撞
閃電猛衝

View file

@ -1007,5 +1007,5 @@
铁武者
故勒顿
密勒顿
AKETUBAN
BKETUBAN
波荡水
铁斑叶

View file

@ -1007,5 +1007,5 @@
鐵武者
故勒頓
密勒頓
AKETUBAN
BKETUBAN
波盪水
鐵斑葉

View file

@ -566,6 +566,10 @@ public sealed class SaveBlockAccessor9SV : SCBlockAccessor, ISaveBlock9Main
private const uint FSYS_RAID_DIFFICTLTY6_SURVEY = 0xAD1DC231;
private const uint FSYS_NETCONTENTS_OFF = 0x9AB093F2;
private const uint FSYS_VIVILLON = 0x22F70BCF; // real name todo
private const uint FSYS_GO_LINK_ENABLED = 0x3ABC21E3; // real name todo
private const uint KGoTransfer = 0x7EE0A576;
#endregion
#region FEVT

View file

@ -26,6 +26,14 @@ public static class SaveUtil
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
// 1.2.0: add 0x2C9F; clean upgrade (1.1.0->1.2.0 is same as *1.2.0)
public const int SIZE_G9_3A0 = 0x31CF7C; // 1.0.0 -> 1.0.1 -> 1.1.0 -> 1.2.0 AM
public const int SIZE_G9_3A1 = 0x31CA6F; // 1.0.1 -> 1.1.0 -> 1.2.0 AM
public const int SIZE_G9_3B0 = SIZE_G9_3A0 - 0xD; // BM
public const int SIZE_G9_3B1 = SIZE_G9_3A1 - 0xD; // BM
public const int SIZE_G9_3G0 = SIZE_G9_3A0 + 0x5; // GO
public const int SIZE_G9_3G1 = SIZE_G9_3A1 + 0x5; // GO
public const int SIZE_G8LA = 0x136DDE;
public const int SIZE_G8LA_1 = 0x13AD06;
@ -112,6 +120,10 @@ public static class SaveUtil
SIZE_G9_1A, SIZE_G9_1Aa,
SIZE_G9_1Ba, SIZE_G9_1Ab,
SIZE_G9_2, SIZE_G9_3,
SIZE_G9_3A0, SIZE_G9_3A1,
SIZE_G9_3B0, SIZE_G9_3B1,
SIZE_G9_3G0, SIZE_G9_3G1,
};
private static readonly HashSet<int> SizesSWSH = new()

View file

@ -640,6 +640,16 @@ namespace PKHeX.Drawing.PokeSprite.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
public static System.Drawing.Bitmap a_1009 {
get {
object obj = ResourceManager.GetObject("a_1009", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
@ -660,6 +670,16 @@ namespace PKHeX.Drawing.PokeSprite.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
public static System.Drawing.Bitmap a_1010 {
get {
object obj = ResourceManager.GetObject("a_1010", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>

View file

@ -1357,12 +1357,18 @@
<data name="a_1008_4" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\img\Artwork Pokemon Sprites\a_1008-4.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="a_1009" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\img\Artwork Pokemon Sprites\a_1009.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="a_100_1" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\img\Artwork Pokemon Sprites\a_100-1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="a_101" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\img\Artwork Pokemon Sprites\a_101.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="a_1010" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\img\Artwork Pokemon Sprites\a_1010.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="a_101_1" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\img\Artwork Pokemon Sprites\a_101-1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View file

@ -37,14 +37,14 @@ public class SpeciesConverterTests
[Theory]
[InlineData(0)]
[InlineData(934, Palafin)]
[InlineData(980, _980)]
[InlineData(987, _987)]
[InlineData(980, WalkingWake)]
[InlineData(987, IronLeaves)]
public void GetNational9(ushort raw, Species national = 0) => ((Species)SpeciesConverter.GetNational9(raw)).Should().Be(national);
[Theory]
[InlineData(0)]
[InlineData(934, Palafin)]
[InlineData(980, _980)]
[InlineData(987, _987)]
[InlineData(980, WalkingWake)]
[InlineData(987, IronLeaves)]
public void GetInternal9(ushort raw, Species national = 0) => SpeciesConverter.GetInternal9((ushort)national).Should().Be(raw);
}