mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-27 06:20:25 +00:00
Add daycare reader, show playtime in backup filename
This commit is contained in:
parent
d56d675868
commit
9d5cff5221
4 changed files with 86 additions and 5 deletions
|
@ -207,9 +207,6 @@ namespace PKHeX.Core
|
||||||
{
|
{
|
||||||
return new()
|
return new()
|
||||||
{
|
{
|
||||||
new SlotInfoMisc(sav.Data, 0, 0x96080, true) { Type = StorageSlotType.Daycare },
|
|
||||||
new SlotInfoMisc(sav.Data, 1, 0x96080 + PokeCrypto.SIZE_8PARTY, true) { Type = StorageSlotType.Daycare },
|
|
||||||
|
|
||||||
new SlotInfoMisc(sav.Data, 0, 0x9A8E8 + (0 * PokeCrypto.SIZE_8PARTY), true) { Type = StorageSlotType.Misc },
|
new SlotInfoMisc(sav.Data, 0, 0x9A8E8 + (0 * PokeCrypto.SIZE_8PARTY), true) { Type = StorageSlotType.Misc },
|
||||||
new SlotInfoMisc(sav.Data, 1, 0x9A8E8 + (1 * PokeCrypto.SIZE_8PARTY), true) { Type = StorageSlotType.Misc },
|
new SlotInfoMisc(sav.Data, 1, 0x9A8E8 + (1 * PokeCrypto.SIZE_8PARTY), true) { Type = StorageSlotType.Misc },
|
||||||
new SlotInfoMisc(sav.Data, 2, 0x9A8E8 + (2 * PokeCrypto.SIZE_8PARTY), true) { Type = StorageSlotType.Misc },
|
new SlotInfoMisc(sav.Data, 2, 0x9A8E8 + (2 * PokeCrypto.SIZE_8PARTY), true) { Type = StorageSlotType.Misc },
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace PKHeX.Core
|
||||||
public class SAV8BS : SaveFile, ISaveFileRevision, ITrainerStatRecord
|
public class SAV8BS : SaveFile, ISaveFileRevision, ITrainerStatRecord
|
||||||
{
|
{
|
||||||
// Save Data Attributes
|
// Save Data Attributes
|
||||||
protected internal override string ShortSummary => $"{OT} ({Version})";
|
protected internal override string ShortSummary => $"{OT} ({Version}) - {Played.LastSavedTime}";
|
||||||
public override string Extension => string.Empty;
|
public override string Extension => string.Empty;
|
||||||
|
|
||||||
public override IReadOnlyList<string> PKMExtensions => Array.FindAll(PKM.Extensions, f =>
|
public override IReadOnlyList<string> PKMExtensions => Array.FindAll(PKM.Extensions, f =>
|
||||||
|
@ -30,8 +30,11 @@ namespace PKHeX.Core
|
||||||
// 0x7D3E0 - Trainer Battle Data (bool,bool)[707]
|
// 0x7D3E0 - Trainer Battle Data (bool,bool)[707]
|
||||||
// 0x7E9F8 - Menu selections (TopMenuItemTypeInt32, bool IsNew)[8], TopMenuItemTypeInt32 LastSelected
|
// 0x7E9F8 - Menu selections (TopMenuItemTypeInt32, bool IsNew)[8], TopMenuItemTypeInt32 LastSelected
|
||||||
// 0x7EA3C - _FIELDOBJ_SAVE Objects[1000] (sizeof (0x44, 17 int fields), total size 0x109A0
|
// 0x7EA3C - _FIELDOBJ_SAVE Objects[1000] (sizeof (0x44, 17 int fields), total size 0x109A0
|
||||||
Records = new Record8b(this, 0x8F3DC);
|
Records = new Record8b(this, 0x8F3DC); // size: 0x78
|
||||||
|
// 0x8F454 - ENC_SV_DATA
|
||||||
|
|
||||||
|
Daycare = new Daycare8b(this, 0x96080); // 0x2C0
|
||||||
|
// 0x96340 - _DENDOU_SAVEDATA
|
||||||
Initialize();
|
Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +46,7 @@ namespace PKHeX.Core
|
||||||
Party = PartyInfo.Offset;
|
Party = PartyInfo.Offset;
|
||||||
PokeDex = Zukan.PokeDex;
|
PokeDex = Zukan.PokeDex;
|
||||||
BoxLayout.LoadBattleTeams();
|
BoxLayout.LoadBattleTeams();
|
||||||
|
DaycareOffset = Daycare.Offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool HasEvents => true;
|
public override bool HasEvents => true;
|
||||||
|
@ -146,6 +150,7 @@ namespace PKHeX.Core
|
||||||
// public Misc8 Misc { get; }
|
// public Misc8 Misc { get; }
|
||||||
public Zukan8b Zukan { get; }
|
public Zukan8b Zukan { get; }
|
||||||
public Record8b Records { get; }
|
public Record8b Records { get; }
|
||||||
|
public Daycare8b Daycare { get; }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public override GameVersion Version => Game switch
|
public override GameVersion Version => Game switch
|
||||||
|
@ -260,5 +265,24 @@ namespace PKHeX.Core
|
||||||
public int GetRecordOffset(int recordID) => Records.GetRecordOffset(recordID);
|
public int GetRecordOffset(int recordID) => Records.GetRecordOffset(recordID);
|
||||||
public int GetRecordMax(int recordID) => Record8b.RecordMaxValue;
|
public int GetRecordMax(int recordID) => Record8b.RecordMaxValue;
|
||||||
public void SetRecord(int recordID, int value) => Records.SetRecord(recordID, value);
|
public void SetRecord(int recordID, int value) => Records.SetRecord(recordID, value);
|
||||||
|
|
||||||
|
#region Daycare
|
||||||
|
public override int DaycareSeedSize => 16; // 8byte
|
||||||
|
public override int GetDaycareSlotOffset(int loc, int slot) => Daycare.GetParentSlotOffset(slot);
|
||||||
|
public override uint? GetDaycareEXP(int loc, int slot) => (uint)Daycare.EggStepCount;
|
||||||
|
public override bool? IsDaycareOccupied(int loc, int slot) => Daycare.GetDaycareSlotOccupied(slot);
|
||||||
|
public override bool? IsDaycareHasEgg(int loc) => Daycare.IsEggAvailable;
|
||||||
|
public override void SetDaycareEXP(int loc, int slot, uint EXP) => Daycare.EggStepCount = (int)EXP;
|
||||||
|
public override void SetDaycareOccupied(int loc, int slot, bool occupied) { }
|
||||||
|
public override void SetDaycareHasEgg(int loc, bool hasEgg) => Daycare.IsEggAvailable = hasEgg;
|
||||||
|
|
||||||
|
public override string GetDaycareRNGSeed(int loc)
|
||||||
|
{
|
||||||
|
var data = BitConverter.GetBytes(Daycare.DaycareSeed);
|
||||||
|
Array.Reverse(data);
|
||||||
|
return BitConverter.ToString(data).Replace("-", string.Empty);
|
||||||
|
}
|
||||||
|
public override void SetDaycareRNGSeed(int loc, string seed) => Daycare.DaycareSeed = BitConverter.ToUInt64(Util.GetBytesFromHexString(seed), 0);
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
59
PKHeX.Core/Saves/Substructures/Gen8/BS/Daycare8b.cs
Normal file
59
PKHeX.Core/Saves/Substructures/Gen8/BS/Daycare8b.cs
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace PKHeX.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Storage for the in-game daycare structure.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>size: 0x2C0</remarks>
|
||||||
|
[TypeConverter(typeof(ExpandableObjectConverter))]
|
||||||
|
public sealed class Daycare8b : SaveBlock
|
||||||
|
{
|
||||||
|
public Daycare8b(SaveFile sav, int offset) : base(sav) => Offset = offset;
|
||||||
|
|
||||||
|
// BLOCK STRUCTURE
|
||||||
|
// PB8[2] Parents;
|
||||||
|
// bool32 eggExist;
|
||||||
|
// ulong eggSeed; -- setter puts only 32 bits!
|
||||||
|
// int32 eggStepCount;
|
||||||
|
|
||||||
|
private const int SlotCount = 2;
|
||||||
|
private const int ExtraDataOffset = PokeCrypto.SIZE_8PARTY * SlotCount;
|
||||||
|
|
||||||
|
public bool GetDaycareSlotOccupied(int slot) => GetSlot(slot).Species != 0;
|
||||||
|
|
||||||
|
public int GetParentSlotOffset(int slot)
|
||||||
|
{
|
||||||
|
if ((uint)slot >= SlotCount)
|
||||||
|
throw new IndexOutOfRangeException(nameof(slot));
|
||||||
|
|
||||||
|
return Offset + (slot * PokeCrypto.SIZE_8PARTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PB8 GetSlot(int slot)
|
||||||
|
{
|
||||||
|
var offset = GetParentSlotOffset(slot);
|
||||||
|
var data = Data.AsSpan(offset, PokeCrypto.SIZE_8PARTY).ToArray();
|
||||||
|
return new PB8(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEggAvailable
|
||||||
|
{
|
||||||
|
get => BitConverter.ToUInt32(Data, Offset + ExtraDataOffset) == 1;
|
||||||
|
set => BitConverter.GetBytes(value ? 1u : 0).CopyTo(Data, Offset + ExtraDataOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong DaycareSeed
|
||||||
|
{
|
||||||
|
get => BitConverter.ToUInt64(Data, Offset + ExtraDataOffset + 4);
|
||||||
|
set => SAV.SetData(Data, BitConverter.GetBytes(value), Offset + ExtraDataOffset + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int EggStepCount
|
||||||
|
{
|
||||||
|
get => BitConverter.ToInt32(Data, Offset + ExtraDataOffset + 4 + 8);
|
||||||
|
set => BitConverter.GetBytes(value).CopyTo(Data, Offset + ExtraDataOffset + 4 + 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,5 +19,6 @@ namespace PKHeX.Core
|
||||||
|
|
||||||
public byte PlayedMinutes { get => Data[Offset + 2]; set => Data[Offset + 2] = value; }
|
public byte PlayedMinutes { get => Data[Offset + 2]; set => Data[Offset + 2] = value; }
|
||||||
public byte PlayedSeconds { get => Data[Offset + 3]; set => Data[Offset + 3] = value; }
|
public byte PlayedSeconds { get => Data[Offset + 3]; set => Data[Offset + 3] = value; }
|
||||||
|
public string LastSavedTime => $"{PlayedHours:0000}ː{PlayedMinutes:00}ː{PlayedSeconds:00}"; // not :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue