diff --git a/pkNX.Game/GameManagerSWSH.cs b/pkNX.Game/GameManagerSWSH.cs index c9485f51..908ad1dc 100644 --- a/pkNX.Game/GameManagerSWSH.cs +++ b/pkNX.Game/GameManagerSWSH.cs @@ -1,4 +1,5 @@ -using System.IO; +using System; +using System.IO; using System.Linq; using pkNX.Containers; using pkNX.Structures; @@ -35,12 +36,15 @@ protected override void Initialize() var learn = this[GameFile.Learnsets][0]; var splitLearn = learn.Split(0x104); Learn = new FakeContainer(splitLearn); + + var move = this[GameFile.MoveStats]; + ((FolderContainer)move).Initialize(); Data = new GameData { - MoveData = new DataCache(this[GameFile.MoveStats]) // mini + MoveData = new DataCache(move) { - Create = z => new Move7(z), - Write = z => z.Write(), + Create = Waza8Reader.ReadPlaceholder, + Write = _ => throw new ArgumentException(), }, LevelUpData = new DataCache(Learn) { @@ -58,6 +62,8 @@ protected override void Initialize() }; } + public void ResetMoves() => GetFilteredFolder(GameFile.MoveStats); + public void ResetText() { GetFilteredFolder(GameFile.GameText, z => Path.GetExtension(z) == ".dat"); diff --git a/pkNX.Structures/Move/Flatbuffers/Waza8.cs b/pkNX.Structures/Move/Flatbuffers/Waza8.cs index 25b165b1..482f4364 100644 --- a/pkNX.Structures/Move/Flatbuffers/Waza8.cs +++ b/pkNX.Structures/Move/Flatbuffers/Waza8.cs @@ -1,3 +1,5 @@ +using System; + namespace pkNX.Structures { public class Waza8 @@ -34,7 +36,7 @@ public class Waza8 public byte Stat1Percent { get; set; } public byte Stat2Percent { get; set; } public byte Stat3Percent { get; set; } - public byte GigantimaxPower { get; set; } + public byte GigantamaxPower { get; set; } public bool Flag_MakesContact { get; set; } public bool Flag_Charge { get; set; } public bool Flag_Recharge { get; set; } @@ -72,4 +74,109 @@ public MoveTarget Target set => RawTarget = (byte)value; } } + + /// + /// Manual Flatbuffer reader for + /// + public static class Waza8Reader + { + private const int Version = 4; + private const int MoveID = 6; + private const int CanUseMove = 8; + private const int Type = 10; + private const int Quality = 12; + private const int Category = 14; + private const int Power = 16; + private const int Accuracy = 18; + private const int PP = 20; + private const int Priority = 22; + private const int HitMin = 24; + private const int HitMax = 26; + private const int Inflict = 28; + private const int InflictPercent = 30; + private const int RawInflictCount = 32; + private const int TurnMin = 34; + private const int TurnMax = 36; + private const int CritStage = 38; + private const int Flinch = 40; + private const int EffectSequence = 42; + private const int Recoil = 44; + private const int RawHealing = 46; + private const int RawTarget = 48; + private const int Stat1 = 50; + private const int Stat2 = 52; + private const int Stat3 = 54; + private const int Stat1Stage = 56; + private const int Stat2Stage = 58; + private const int Stat3Stage = 60; + private const int Stat1Percent = 62; + private const int Stat2Percent = 64; + private const int Stat3Percent = 66; + private const int GigantamaxPower = 68; + private const int FlagMakesContact = 70; + private const int FlagCharge = 72; + private const int FlagRecharge = 74; + private const int FlagProtect = 76; + private const int FlagReflectable = 78; + private const int FlagSnatch = 80; + private const int FlagMirror = 82; + private const int FlagPunch = 84; + private const int FlagSound = 86; + private const int FlagGravity = 88; + private const int FlagDefrost = 90; + private const int FlagDistanceTriple = 92; + private const int FlagHeal = 94; + private const int FlagIgnoreSubstitute = 96; + private const int FlagFailSkyBattle = 98; + private const int FlagAnimateAlly = 100; + private const int FlagDance = 102; + private const int Flag18 = 104; + + public static Move8Fake ReadPlaceholder(byte[] data) + { + var result = new Move8Fake(); + var root = BitConverter.ToInt32(data, 0); + var vtable = BitConverter.ToInt32(data, root); + var vOfs = root - vtable; + var vLength = BitConverter.ToUInt16(data, vOfs); + + result.Version = ReadU16(vOfs, Version); // u32 meh + result.MoveID = ReadU16(vOfs, MoveID); // u32 meh + result.CanUseMove = ReadB8(vOfs, CanUseMove); + result.Type = ReadU8(vOfs, Type); + result.Quality = ReadU8(vOfs, Quality); + result.Category = ReadU8(vOfs, Category); + result.Power = ReadU8(vOfs, Power); + + // that's enough for reading, gets us all the properties we need for randomization + return result; + + byte ReadU8(int v, int o) + { + var vptr = v + o; + if (vptr > vLength) + return default; + var rofs = BitConverter.ToUInt16(data, vptr); + return data[root + rofs]; + } + + ushort ReadU16(int v, int o) + { + var vptr = v + o; + if (vptr > vLength) + return default; + var rofs = BitConverter.ToUInt16(data, vptr); + return BitConverter.ToUInt16(data, root + rofs); + } + + bool ReadB8(int v, int o) + { + var vptr = v + o; + if (vptr > vLength) + return default; + var rofs = BitConverter.ToUInt16(data, vptr); + return data[root + rofs] == 1; + } + } + } } diff --git a/pkNX.Structures/Move/Move7.cs b/pkNX.Structures/Move/Move7.cs index 494f5937..8b76309c 100644 --- a/pkNX.Structures/Move/Move7.cs +++ b/pkNX.Structures/Move/Move7.cs @@ -47,4 +47,11 @@ public class Move7 : Move public MoveFlag7 Flags { get => (MoveFlag7)BitConverter.ToUInt32(Data, 0x24); set => BitConverter.GetBytes((uint)value).CopyTo(Data, 0x24); } } + + public class Move8Fake : Move7 + { + public uint Version { get; set; } + public uint MoveID { get; set; } + public bool CanUseMove { get; set; } + } } diff --git a/pkNX.WinForms/Resources/Flatbuffers/Waza8.fbs b/pkNX.WinForms/Resources/Flatbuffers/Waza8.fbs index e42bd5d2..4aa2c811 100644 --- a/pkNX.WinForms/Resources/Flatbuffers/Waza8.fbs +++ b/pkNX.WinForms/Resources/Flatbuffers/Waza8.fbs @@ -70,7 +70,7 @@ table Waza8 { Stat2Percent:ubyte; Stat3Percent:ubyte; - GigantimaxPower:ubyte; + GigantamaxPower:ubyte; // Flags Flag_MakesContact:bool;