Fix gen4 mystery gift misalignment

indicate the card type in the preview pane
This commit is contained in:
Kurt 2024-03-14 02:32:20 -05:00
parent 2f08a35a5c
commit 9c6f030861
7 changed files with 40 additions and 30 deletions

View file

@ -72,6 +72,13 @@ public static class MysteryUtil
result.Add($"Bean ID: {w7bean.Bean}"); result.Add($"Bean ID: {w7bean.Bean}");
result.Add($"Quantity: {w7bean.Quantity}"); result.Add($"Quantity: {w7bean.Quantity}");
break; break;
case PCD pcd:
result.Add($"{pcd.GiftType}");
result.Add($"Collected: {pcd.GiftUsed}");
break;
case PGT pgt:
result.Add($"{pgt.GiftType}");
break;
default: default:
result.Add(MsgMysteryGiftParseTypeUnknown); result.Add(MsgMysteryGiftParseTypeUnknown);
break; break;

View file

@ -51,6 +51,7 @@ public sealed class PCD(byte[] Data)
} }
private PGT? _gift; private PGT? _gift;
public GiftType4 GiftType => Gift.GiftType;
public Span<byte> GetMetadata() => Data.AsSpan(PGT.Size); public Span<byte> GetMetadata() => Data.AsSpan(PGT.Size);
public void SetMetadata(ReadOnlySpan<byte> data) => data.CopyTo(Data.AsSpan(PGT.Size)); public void SetMetadata(ReadOnlySpan<byte> data) => data.CopyTo(Data.AsSpan(PGT.Size));

View file

@ -1,5 +1,6 @@
using System; using System;
using static System.Buffers.Binary.BinaryPrimitives; using static System.Buffers.Binary.BinaryPrimitives;
using static PKHeX.Core.GiftType4;
namespace PKHeX.Core; namespace PKHeX.Core;
@ -30,23 +31,6 @@ public sealed class PGT(byte[] Data) : DataMysteryGift(Data), IRibbonSetEvent3,
public override AbilityPermission Ability => IsManaphyEgg ? AbilityPermission.Any12 : (int)(PK.PID & 1) == 1 ? AbilityPermission.OnlySecond : AbilityPermission.OnlyFirst; public override AbilityPermission Ability => IsManaphyEgg ? AbilityPermission.Any12 : (int)(PK.PID & 1) == 1 ? AbilityPermission.OnlySecond : AbilityPermission.OnlyFirst;
private enum GiftType
{
Pokémon = 1,
PokémonEgg = 2,
Item = 3,
Rule = 4,
Seal = 5,
Accessory = 6,
ManaphyEgg = 7,
MemberCard = 8,
OaksLetter = 9,
AzureFlute = 10,
PokétchApp = 11,
Ribbon = 12,
PokéWalkerArea = 14,
}
public override string CardTitle { get => "Raw Gift (PGT)"; set { } } public override string CardTitle { get => "Raw Gift (PGT)"; set { } }
public override int CardID { get => -1; set { } } public override int CardID { get => -1; set { } }
public override bool GiftUsed { get => false; set { } } public override bool GiftUsed { get => false; set { } }
@ -88,7 +72,7 @@ public sealed class PGT(byte[] Data) : DataMysteryGift(Data), IRibbonSetEvent3,
/// <returns>True if data was encrypted, false if the data was not modified.</returns> /// <returns>True if data was encrypted, false if the data was not modified.</returns>
public bool VerifyPKEncryption() public bool VerifyPKEncryption()
{ {
if (PGTGiftType is not (GiftType.Pokémon or GiftType.PokémonEgg)) if (GiftType is not (Pokémon or PokémonEgg))
return false; // not encrypted return false; // not encrypted
if (ReadUInt32LittleEndian(Data.AsSpan(0x64 + 8)) != 0) if (ReadUInt32LittleEndian(Data.AsSpan(0x64 + 8)) != 0)
return false; // already encrypted (unused PK4 field, zero) return false; // already encrypted (unused PK4 field, zero)
@ -103,13 +87,13 @@ public sealed class PGT(byte[] Data) : DataMysteryGift(Data), IRibbonSetEvent3,
ekdata.CopyTo(span); ekdata.CopyTo(span);
} }
private GiftType PGTGiftType { get => (GiftType)Data[0]; set => Data[0] = (byte)value; } public GiftType4 GiftType { get => (GiftType4)Data[0]; set => Data[0] = (byte)value; }
public bool IsHatched => PGTGiftType == GiftType.Pokémon; public bool IsHatched => GiftType == Pokémon;
public override bool IsEgg { get => PGTGiftType == GiftType.PokémonEgg || IsManaphyEgg; set { if (value) { PGTGiftType = GiftType.PokémonEgg; PK.IsEgg = true; } } } public override bool IsEgg { get => GiftType == PokémonEgg || IsManaphyEgg; set { if (value) { GiftType = PokémonEgg; PK.IsEgg = true; } } }
public bool IsManaphyEgg { get => PGTGiftType == GiftType.ManaphyEgg; set { if (value) PGTGiftType = GiftType.ManaphyEgg; } } public bool IsManaphyEgg { get => GiftType == ManaphyEgg; set { if (value) GiftType = ManaphyEgg; } }
public override bool EggEncounter => IsEgg; public override bool EggEncounter => IsEgg;
public override bool IsItem { get => PGTGiftType == GiftType.Item; set { if (value) PGTGiftType = GiftType.Item; } } public override bool IsItem { get => GiftType == Item; set { if (value) GiftType = Item; } }
public override bool IsEntity { get => PGTGiftType is GiftType.Pokémon or GiftType.PokémonEgg or GiftType.ManaphyEgg; set { } } public override bool IsEntity { get => GiftType is Pokémon or PokémonEgg or ManaphyEgg; set { } }
public override ushort Species { get => IsManaphyEgg ? (ushort)490 : PK.Species; set => PK.Species = value; } public override ushort Species { get => IsManaphyEgg ? (ushort)490 : PK.Species; set => PK.Species = value; }
public override Moveset Moves { get => new(PK.Move1, PK.Move2, PK.Move3, PK.Move4); set => PK.SetMoves(value); } public override Moveset Moves { get => new(PK.Move1, PK.Move2, PK.Move3, PK.Move4); set => PK.SetMoves(value); }
@ -335,3 +319,21 @@ public sealed class PGT(byte[] Data) : DataMysteryGift(Data), IRibbonSetEvent3,
return val == PIDType.G4MGAntiShiny; return val == PIDType.G4MGAntiShiny;
} }
} }
public enum GiftType4 : byte
{
None = 0,
Pokémon = 1,
PokémonEgg = 2,
Item = 3,
Rule = 4,
Seal = 5,
Accessory = 6,
ManaphyEgg = 7,
MemberCard = 8,
OaksLetter = 9,
AzureFlute = 10,
PokétchApp = 11,
Ribbon = 12,
PokéWalkerArea = 14,
}

View file

@ -369,20 +369,20 @@ public abstract class SAV4 : SaveFile, IEventFlag37, IDaycareStorage, IDaycareRa
public int DaycareSlotCount => 2; public int DaycareSlotCount => 2;
private const int DaycareSlotSize = PokeCrypto.SIZE_4PARTY; private const int DaycareSlotSize = PokeCrypto.SIZE_4PARTY;
protected abstract int DaycareOffset { get; } protected abstract int DaycareOffset { get; }
public Memory<byte> GetDaycareSlot(int slot) => GeneralBuffer.Slice(DaycareOffset + (slot * DaycareSlotSize), DaycareSlotSize); public Memory<byte> GetDaycareSlot(int slot) => GeneralBuffer.Slice(DaycareOffset + (slot * DaycareSlotSize), PokeCrypto.SIZE_4STORED);
// EXP: Last 4 bytes of each slot // EXP: Last 4 bytes of each slot
public uint GetDaycareEXP(int index) public uint GetDaycareEXP(int index)
{ {
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, 2u); ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, 2u);
int ofs = DaycareOffset + DaycareSlotSize - 4; int ofs = DaycareOffset + DaycareSlotSize - 4 + (index * DaycareSlotSize);
return ReadUInt32LittleEndian(General[ofs..]); return ReadUInt32LittleEndian(General[ofs..]);
} }
public void SetDaycareEXP(int index, uint value) public void SetDaycareEXP(int index, uint value)
{ {
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, 2u); ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, 2u);
int ofs = DaycareOffset + DaycareSlotSize - 4; int ofs = DaycareOffset + DaycareSlotSize - 4 + (index * DaycareSlotSize);
WriteUInt32LittleEndian(General[ofs..], value); WriteUInt32LittleEndian(General[ofs..], value);
} }

View file

@ -23,7 +23,7 @@ public sealed class SAV4DP : SAV4Sinnoh
Dex = new Zukan4(this, GeneralBuffer[PokeDex..]); Dex = new Zukan4(this, GeneralBuffer[PokeDex..]);
} }
private const int OffsetMystery = 0xA7FC; private const int OffsetMystery = 0xA6D0;
private const int PokeDex = 0x12DC; private const int PokeDex = 0x12DC;
public override Zukan4 Dex { get; } public override Zukan4 Dex { get; }
public override MysteryBlock4DP Mystery { get; } public override MysteryBlock4DP Mystery { get; }

View file

@ -53,7 +53,7 @@ public sealed class SAV4HGSS : SAV4, IBoxDetailName, IBoxDetailWallpaper
GetSAVOffsets(); GetSAVOffsets();
} }
private const int OffsetMystery = 0x9E3C; private const int OffsetMystery = 0x9D3C; // Flags and Gifts
protected override int EventWork => 0xDE4; protected override int EventWork => 0xDE4;
protected override int EventFlag => 0x10C4; protected override int EventFlag => 0x10C4;
protected override int DaycareOffset => 0x15FC; protected override int DaycareOffset => 0x15FC;

View file

@ -50,7 +50,7 @@ public sealed class SAV4Pt : SAV4Sinnoh
protected override int EventWork => 0xDAC; protected override int EventWork => 0xDAC;
protected override int EventFlag => 0xFEC; protected override int EventFlag => 0xFEC;
private const int OffsetMystery = 0xB5C0; private const int OffsetMystery = 0xB4C0;
protected override int DaycareOffset => 0x1654; protected override int DaycareOffset => 0x1654;
public override BattleFrontierFacility4 MaxFacility => BattleFrontierFacility4.Arcade; public override BattleFrontierFacility4 MaxFacility => BattleFrontierFacility4.Arcade;