mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-03-21 17:48:28 -05:00
parent
cd12962a50
commit
48024f1245
|
|
@ -15,5 +15,6 @@ public interface ISaveBlock5BW
|
|||
BattleSubway5 BattleSubway { get; }
|
||||
Entralink5 Entralink { get; }
|
||||
Musical5 Musical { get; }
|
||||
Encount5 Encount { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ public SaveBlockAccessor5B2W2(SAV5B2W2 sav)
|
|||
Misc = new Misc5B2W2(sav, 0x21100);
|
||||
Entralink = new Entralink5B2W2(sav, 0x21200);
|
||||
Zukan = new Zukan5(sav, 0x21400, 0x328); // form flags size is + 8 from bw with new forms (therians)
|
||||
Encount = new Encount5B2W2(sav, 0x21900);
|
||||
BattleSubway = new BattleSubway5(sav, 0x21B00);
|
||||
PWT = new PWTBlock5(sav, 0x23700);
|
||||
Festa = new FestaBlock5(sav, 0x25900);
|
||||
|
|
@ -114,5 +115,6 @@ public SaveBlockAccessor5B2W2(SAV5B2W2 sav)
|
|||
public Entralink5 Entralink { get; }
|
||||
public FestaBlock5 Festa { get; }
|
||||
public Musical5 Musical { get; }
|
||||
public Encount5 Encount { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ public SaveBlockAccessor5BW(SAV5BW sav)
|
|||
Misc = new Misc5BW(sav, 0x21200);
|
||||
Entralink = new Entralink5BW(sav, 0x21300);
|
||||
Zukan = new Zukan5(sav, 0x21600, 0x320);
|
||||
Encount = new Encount5BW(sav, 0x21B00);
|
||||
BattleSubway = new BattleSubway5(sav, 0x21D00);
|
||||
}
|
||||
|
||||
|
|
@ -106,5 +107,6 @@ public SaveBlockAccessor5BW(SAV5BW sav)
|
|||
public BattleSubway5 BattleSubway { get; }
|
||||
public Entralink5 Entralink { get; }
|
||||
public Musical5 Musical { get; }
|
||||
public Encount5 Encount { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,6 +154,12 @@ public DecorationInventory3 Decorations
|
|||
set => SetData(Large, value.ToBytes(), 0x2734);
|
||||
}
|
||||
|
||||
public Swarm3 Swarm
|
||||
{
|
||||
get => Large.Slice(0x2B90, Swarm3.SIZE).ToClass<Swarm3>();
|
||||
set => SetData(Large, value.ToBytesClass(), 0x2B90);
|
||||
}
|
||||
|
||||
protected override int MailOffset => 0x2BE0;
|
||||
|
||||
protected override int GetDaycareEXPOffset(int slot) => GetDaycareSlotOffset(0, slot + 1) - 4; // @ end of each pkm slot
|
||||
|
|
|
|||
|
|
@ -117,6 +117,12 @@ public DecorationInventory3 Decorations
|
|||
set => SetData(Large, value.ToBytes(), 0x26A0);
|
||||
}
|
||||
|
||||
public Swarm3 Swarm
|
||||
{
|
||||
get => Large.Slice(0x2AFC, Swarm3.SIZE).ToClass<Swarm3>();
|
||||
set => SetData(Large, value.ToBytesClass(), 0x2AFC);
|
||||
}
|
||||
|
||||
protected override int MailOffset => 0x2B4C;
|
||||
|
||||
protected override int GetDaycareEXPOffset(int slot) => GetDaycareSlotOffset(0, 2) + (2 * 0x38) + (4 * slot); // consecutive vals, after both consecutive slots & 2 mail
|
||||
|
|
|
|||
|
|
@ -534,5 +534,19 @@ public Mail4 GetMail(int mailIndex)
|
|||
int ofs = GetMailOffset(mailIndex);
|
||||
return new Mail4(GetMailData(ofs), ofs);
|
||||
}
|
||||
|
||||
public abstract uint SwarmSeed { get; set; }
|
||||
public abstract uint SwarmMaxCountModulo { get; }
|
||||
|
||||
public uint SwarmIndex
|
||||
{
|
||||
get => SwarmSeed % SwarmMaxCountModulo;
|
||||
set
|
||||
{
|
||||
value %= SwarmMaxCountModulo;
|
||||
while (SwarmIndex != value)
|
||||
++SwarmSeed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -148,5 +148,9 @@ private void SetActiveGiftFlags(IReadOnlyList<MysteryGift> gifts)
|
|||
public override int X2 { get => BitConverter.ToUInt16(General, 0x25FA); set => BitConverter.GetBytes((ushort)value).CopyTo(General, 0x25FA); }
|
||||
public override int Y2 { get => BitConverter.ToUInt16(General, 0x25FE); set => BitConverter.GetBytes((ushort)value).CopyTo(General, 0x25FE); }
|
||||
public override int Z { get => BitConverter.ToUInt16(General, 0x2602); set => BitConverter.GetBytes((ushort)value).CopyTo(General, 0x2602); }
|
||||
|
||||
public override uint SafariSeed { get => BitConverter.ToUInt32(General, 0x72D0); set => BitConverter.GetBytes(value).CopyTo(General, 0x72D0); }
|
||||
public override uint SwarmSeed { get => BitConverter.ToUInt32(General, 0x72D4); set => BitConverter.GetBytes(value).CopyTo(General, 0x72D4); }
|
||||
public override uint SwarmMaxCountModulo => 28;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -234,5 +234,8 @@ public void PokeGearUnlockAllCallersNoTrainers()
|
|||
public void SetPokewalkerCoursesUnlocked(bool[] value) => ArrayUtil.SetBitFlagArray(General, OFS_WALKER + 0x8, value);
|
||||
|
||||
public void PokewalkerCoursesSetAll(uint value = 0x07FF_FFFFu) => SetData(General, BitConverter.GetBytes(value), OFS_WALKER + 0x8);
|
||||
|
||||
public override uint SwarmSeed { get => BitConverter.ToUInt32(General, 0x68A8); set => BitConverter.GetBytes(value).CopyTo(General, 0x68A8); }
|
||||
public override uint SwarmMaxCountModulo => 20;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,5 +114,9 @@ public override IReadOnlyList<InventoryPouch> Inventory
|
|||
public override int X2 { get => BitConverter.ToUInt16(General, 0x287E); set => BitConverter.GetBytes((ushort)value).CopyTo(General, 0x287E); }
|
||||
public override int Y2 { get => BitConverter.ToUInt16(General, 0x2882); set => BitConverter.GetBytes((ushort)value).CopyTo(General, 0x2882); }
|
||||
public override int Z { get => BitConverter.ToUInt16(General, 0x2886); set => BitConverter.GetBytes((ushort)value).CopyTo(General, 0x2886); }
|
||||
|
||||
public override uint SafariSeed { get => BitConverter.ToUInt32(General, 0x72D4); set => BitConverter.GetBytes(value).CopyTo(General, 0x72D4); }
|
||||
public override uint SwarmSeed { get => BitConverter.ToUInt32(General, 0x72D8); set => BitConverter.GetBytes(value).CopyTo(General, 0x72D8); }
|
||||
public override uint SwarmMaxCountModulo => 22;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -182,6 +182,10 @@ private static int[] CalculateMunchlaxTrees(int tid, int sid)
|
|||
public void SetUGI_Spheres(byte[] value) => SetData(General, value, OFS_UG_Items + 0x78);
|
||||
|
||||
#endregion
|
||||
|
||||
public abstract uint SafariSeed { get; set; }
|
||||
public uint GetSafariIndex(int slot) => (SafariSeed >> (slot * 5)) & 0x1F;
|
||||
public void SetSafariIndex(int slot, uint value) => SafariSeed = (SafariSeed & ~(0x1Fu << (slot * 5))) | (value << (slot * 5));
|
||||
}
|
||||
|
||||
public enum PoketchColor
|
||||
|
|
|
|||
|
|
@ -206,6 +206,7 @@ public EntreeForest EntreeData
|
|||
public abstract BattleSubway5 BattleSubway { get; }
|
||||
public abstract Entralink5 Entralink { get; }
|
||||
public abstract Musical5 Musical { get; }
|
||||
public abstract Encount5 Encount { get; }
|
||||
|
||||
public static int GetMailOffset(int index) => (index * Mail5.SIZE) + 0x1DD00;
|
||||
public byte[] GetMailData(int offset) => GetData(offset, Mail5.SIZE);
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ private void Initialize()
|
|||
public override BattleSubway5 BattleSubway => Blocks.BattleSubway;
|
||||
public override Entralink5 Entralink => Blocks.Entralink;
|
||||
public override Musical5 Musical => Blocks.Musical;
|
||||
public override Encount5 Encount => Blocks.Encount;
|
||||
public FestaBlock5 Festa => Blocks.Festa;
|
||||
public PWTBlock5 PWT => Blocks.PWT;
|
||||
public override int Fused => 0x1FA00 + sizeof(uint);
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ private void Initialize()
|
|||
public override BattleSubway5 BattleSubway => Blocks.BattleSubway;
|
||||
public override Entralink5 Entralink => Blocks.Entralink;
|
||||
public override Musical5 Musical => Blocks.Musical;
|
||||
public override Encount5 Encount => Blocks.Encount;
|
||||
public override int Fused => int.MinValue;
|
||||
public override int GTS => 0x20500;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ public interface IGen3Hoenn
|
|||
RTC3 ClockElapsed { get; set; }
|
||||
PokeBlock3Case PokeBlocks { get; set; }
|
||||
DecorationInventory3 Decorations { get; set; }
|
||||
Swarm3 Swarm { get; set; }
|
||||
bool HasReceivedWishmkrJirachi { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
internal static class StructConverter
|
||||
public static class StructConverter
|
||||
{
|
||||
public static T ToStructure<T>(this byte[] bytes) where T : struct
|
||||
{
|
||||
|
|
|
|||
23
PKHeX.Core/Saves/Substructures/Gen3/Swarm3.cs
Normal file
23
PKHeX.Core/Saves/Substructures/Gen3/Swarm3.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = SIZE)]
|
||||
public sealed class Swarm3
|
||||
{
|
||||
public const int SIZE = 0x14;
|
||||
|
||||
public ushort Species { get; set; }
|
||||
public byte MapNum { get; set; }
|
||||
public byte MapGroup { get; set; }
|
||||
public byte Level { get; set; }
|
||||
// 3byte align
|
||||
public ushort Move1 { get; set; }
|
||||
public ushort Move2 { get; set; }
|
||||
public ushort Move3 { get; set; }
|
||||
public ushort Move4 { get; set; }
|
||||
public byte Zero { get; set; }
|
||||
public byte EncounterProbability { get; set; }
|
||||
public ushort DaysLeft { get; set; }
|
||||
}
|
||||
}
|
||||
39
PKHeX.Core/Saves/Substructures/Gen5/Encount5.cs
Normal file
39
PKHeX.Core/Saves/Substructures/Gen5/Encount5.cs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
public abstract class Encount5 : SaveBlock
|
||||
{
|
||||
protected Encount5(SAV5 SAV, int offset) : base(SAV) => Offset = offset;
|
||||
|
||||
public abstract uint SwarmSeed { get; set; }
|
||||
public abstract uint SwarmMaxCountModulo { get; }
|
||||
|
||||
public uint SwarmIndex
|
||||
{
|
||||
get => SwarmSeed % SwarmMaxCountModulo;
|
||||
set
|
||||
{
|
||||
value %= SwarmMaxCountModulo;
|
||||
while (SwarmIndex != value)
|
||||
++SwarmSeed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class Encount5BW : Encount5
|
||||
{
|
||||
public Encount5BW(SAV5BW SAV, int offset) : base(SAV, offset) { }
|
||||
|
||||
public override uint SwarmSeed { get => BitConverter.ToUInt32(Data, Offset + 0x30); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x30); }
|
||||
public override uint SwarmMaxCountModulo => 17;
|
||||
}
|
||||
|
||||
public sealed class Encount5B2W2 : Encount5
|
||||
{
|
||||
public Encount5B2W2(SAV5B2W2 SAV, int offset) : base(SAV, offset) { }
|
||||
|
||||
public override uint SwarmSeed { get => BitConverter.ToUInt32(Data, Offset + 0x2C); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x2C); }
|
||||
public override uint SwarmMaxCountModulo => 19;
|
||||
}
|
||||
}
|
||||
|
|
@ -19,37 +19,6 @@ public ushort BlackCityLevel
|
|||
}
|
||||
}
|
||||
|
||||
public sealed class Musical5 : SaveBlock
|
||||
{
|
||||
public Musical5(SAV5BW SAV, int offset) : base(SAV) => Offset = offset;
|
||||
public Musical5(SAV5B2W2 SAV, int offset) : base(SAV) => Offset = offset;
|
||||
|
||||
private const int PropOffset = 0x258;
|
||||
|
||||
public void UnlockAllMusicalProps()
|
||||
{
|
||||
// 101 props, which is 12.X bytes of bitflags.
|
||||
var bitFieldOffset = Offset + PropOffset;
|
||||
for (int i = 0; i < 0xC; i++)
|
||||
Data[bitFieldOffset + i] = 0xFF;
|
||||
Data[bitFieldOffset + 0xC] = 0x1F; // top 3 bits unset, to complete multiple of 8 (101=>104 bits).
|
||||
}
|
||||
|
||||
public bool GetHasProp(int prop)
|
||||
{
|
||||
var bitFieldOffset = Offset + PropOffset;
|
||||
var bitOffset = prop >> 3;
|
||||
return SAV.GetFlag(bitFieldOffset + bitOffset, prop & 7);
|
||||
}
|
||||
|
||||
public void SetHasProp(int prop, bool value = true)
|
||||
{
|
||||
var bitFieldOffset = Offset + PropOffset;
|
||||
var bitOffset = prop >> 3;
|
||||
SAV.SetFlag(bitFieldOffset + bitOffset, prop & 7, value);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class Entralink5BW : Entralink5
|
||||
{
|
||||
public Entralink5BW(SAV5BW SAV, int offset) : base(SAV, offset) { }
|
||||
|
|
|
|||
33
PKHeX.Core/Saves/Substructures/Gen5/Musical5.cs
Normal file
33
PKHeX.Core/Saves/Substructures/Gen5/Musical5.cs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
namespace PKHeX.Core
|
||||
{
|
||||
public sealed class Musical5 : SaveBlock
|
||||
{
|
||||
public Musical5(SAV5BW SAV, int offset) : base(SAV) => Offset = offset;
|
||||
public Musical5(SAV5B2W2 SAV, int offset) : base(SAV) => Offset = offset;
|
||||
|
||||
private const int PropOffset = 0x258;
|
||||
|
||||
public void UnlockAllMusicalProps()
|
||||
{
|
||||
// 101 props, which is 12.X bytes of bitflags.
|
||||
var bitFieldOffset = Offset + PropOffset;
|
||||
for (int i = 0; i < 0xC; i++)
|
||||
Data[bitFieldOffset + i] = 0xFF;
|
||||
Data[bitFieldOffset + 0xC] = 0x1F; // top 3 bits unset, to complete multiple of 8 (101=>104 bits).
|
||||
}
|
||||
|
||||
public bool GetHasProp(int prop)
|
||||
{
|
||||
var bitFieldOffset = Offset + PropOffset;
|
||||
var bitOffset = prop >> 3;
|
||||
return SAV.GetFlag(bitFieldOffset + bitOffset, prop & 7);
|
||||
}
|
||||
|
||||
public void SetHasProp(int prop, bool value = true)
|
||||
{
|
||||
var bitFieldOffset = Offset + PropOffset;
|
||||
var bitOffset = prop >> 3;
|
||||
SAV.SetFlag(bitFieldOffset + bitOffset, prop & 7, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
21
Tests/PKHeX.Core.Tests/General/MarshalTests.cs
Normal file
21
Tests/PKHeX.Core.Tests/General/MarshalTests.cs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
using FluentAssertions;
|
||||
using PKHeX.Core;
|
||||
using Xunit;
|
||||
|
||||
namespace PKHeX.Tests.General
|
||||
{
|
||||
public class MarshalTests
|
||||
{
|
||||
[Fact]
|
||||
public void MarshalStructure()
|
||||
{
|
||||
new DecorationInventory3().ToBytes().Length.Should().Be(DecorationInventory3.SIZE);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MarshalClass()
|
||||
{
|
||||
new Swarm3().ToBytesClass().Length.Should().Be(Swarm3.SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user