Handle Seven Star Raids Change From Teal Mask Update (#4119)

* Handle Seven Star Raids Change From Teal Mask Update

* Refer To RaidSevenStarCaptured9.CountAll Rather Than Recalculate It

* Fix Wrong SevenStarRaid Size Variable Referenced

While they are the same value correcting the mistake so that there isn't confusion while looking at the code.
This commit is contained in:
Jonathan Herbert 2023-12-21 14:51:09 -04:00 committed by GitHub
parent 3ce726087c
commit 24a5b05fcb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 96 additions and 9 deletions

View file

@ -66,7 +66,12 @@ public sealed class SaveBlockAccessor9SV : SCBlockAccessor, ISaveBlock9Main
RaidKitakami = new RaidSpawnList9(sav, fake, default, RaidSpawnList9.RaidCountLegal_T1, false);
RaidBlueberry = new RaidSpawnList9(sav, fake, default, RaidSpawnList9.RaidCountLegal_T2, false);
}
RaidSevenStar = new RaidSevenStar9(sav, GetBlock(KSevenStarRaidsCapture));
if (TryGetBlock(KSevenStarRaidsDefeat, out var kSevenStarDefeated))
RaidSevenStar = new RaidSevenStar9(sav, GetBlock(KSevenStarRaidsCapture), kSevenStarDefeated);
else
RaidSevenStar = new RaidSevenStar9(sav, GetBlock(KSevenStarRaidsCapture), GetFakeBlock());
EnrollmentDate = new Epoch1900Value(GetBlock(KEnrollmentDate));
BlueberryQuestRecord = new BlueberryQuestRecord9(sav, GetBlockSafe(KBlueberryQuestRecords));
}

View file

@ -5,11 +5,14 @@ using static System.Buffers.Binary.BinaryPrimitives;
namespace PKHeX.Core;
public sealed class RaidSevenStar9(SAV9SV sav, SCBlock block) : SaveBlock<SAV9SV>(sav, block.Data)
public sealed class RaidSevenStar9(SAV9SV sav, SCBlock captureBlock, SCBlock defeatedBlock)
{
public readonly int CountAll = block.Data.Length / SevenStarRaidDetail.SIZE;
public readonly RaidSevenStarCaptured9 Captured = new(sav, captureBlock);
public readonly RaidSevenStarDefeated9 Defeated = new(sav, defeatedBlock);
public SevenStarRaidDetail GetRaid(int entry) => new(Data, 0x00 + (entry * SevenStarRaidDetail.SIZE));
public int CountAll => Captured.CountAll;
public SevenStarRaidDetail GetRaid(int entry) => new(Captured.GetRaid(entry), Defeated.GetRaid(entry));
public SevenStarRaidDetail[] GetAllRaids()
{
@ -20,27 +23,71 @@ public sealed class RaidSevenStar9(SAV9SV sav, SCBlock block) : SaveBlock<SAV9SV
}
}
public sealed class SevenStarRaidDetail(byte[] Data, int Offset)
public sealed class SevenStarRaidDetail(SevenStarRaidCapturedDetail captured, SevenStarRaidDefeatedDetail? defeated)
{
public const int SIZE = 0x08;
private const string General = nameof(General);
[Category(General), Description("Identifier used for this 7 Star Raid. Matches the date this raid was first distributed.")]
public uint Identifier
{
get => captured.Identifier;
set {
captured.Identifier = value;
if (defeated != null) defeated.Identifier = value;
}
}
[Category(General), Description("Indicates if this Tera Raid Boss has been captured by the player.")]
public bool Captured
{
get => captured.Captured;
set => captured.Captured = value;
}
[Category(General), Description("Indicates if this Tera Raid Boss has been defeated at least once by the player.")]
public bool Defeated
{
get => defeated != null ? defeated.Defeated : captured.Defeated;
set {
if (defeated != null)
defeated.Defeated = value;
else
captured.Defeated = value;
}
}
}
public sealed class RaidSevenStarCaptured9(SAV9SV sav, SCBlock block) : SaveBlock<SAV9SV>(sav, block.Data)
{
public readonly int CountAll = block.Data.Length / SevenStarRaidCapturedDetail.SIZE;
public SevenStarRaidCapturedDetail GetRaid(int entry) => new(Data, 0x00 + (entry * SevenStarRaidCapturedDetail.SIZE));
public SevenStarRaidCapturedDetail[] GetAllRaids()
{
var result = new SevenStarRaidCapturedDetail[CountAll];
for (int i = 0; i < result.Length; i++)
result[i] = GetRaid(i);
return result;
}
}
public sealed class SevenStarRaidCapturedDetail(byte[] Data, int Offset)
{
public const int SIZE = 0x08;
public uint Identifier
{
get => ReadUInt32LittleEndian(Data.AsSpan(Offset + 0x00));
set => WriteUInt32LittleEndian(Data.AsSpan(Offset + 0x00), value);
}
[Category(General), Description("Indicates if this Tera Raid Boss has been captured by the player.")]
public bool Captured
{
get => Data[Offset + 0x04] == 1;
set => Data[Offset + 0x04] = (byte)(value ? 1 : 0);
}
[Category(General), Description("Indicates if this Tera Raid Boss has been defeated at least once by the player.")]
public bool Defeated
{
get => Data[Offset + 0x05] == 1;
@ -49,3 +96,38 @@ public sealed class SevenStarRaidDetail(byte[] Data, int Offset)
// 0x06 - 0x07 padding
}
public sealed class RaidSevenStarDefeated9(SAV9SV sav, SCBlock block) : SaveBlock<SAV9SV>(sav, block.Data)
{
// Structure matches the RaidSevenStarCapture9 but there are 4 bytes at the front to indicate if the copy of previous defeated flags happened when updating save
public readonly int CountAll = (block.Data.Length - 0x04) / SevenStarRaidDefeatedDetail.SIZE;
public SevenStarRaidDefeatedDetail? GetRaid(int entry) => block.Type != SCTypeCode.None ? new(Data, 0x04 + (entry * SevenStarRaidDefeatedDetail.SIZE)) : null;
public SevenStarRaidDefeatedDetail?[] GetAllRaids()
{
var result = new SevenStarRaidDefeatedDetail?[CountAll];
for (int i = 0; i < result.Length; i++)
result[i] = GetRaid(i);
return result;
}
}
public sealed class SevenStarRaidDefeatedDetail(byte[] Data, int Offset)
{
public const int SIZE = 0x08;
public uint Identifier
{
get => ReadUInt32LittleEndian(Data.AsSpan(Offset + 0x00));
set => WriteUInt32LittleEndian(Data.AsSpan(Offset + 0x00), value);
}
public bool Defeated
{
get => Data[Offset + 0x04] == 1;
set => Data[Offset + 0x04] = (byte)(value ? 1 : 0);
}
// 0x05 - 0x07 padding
}