diff --git a/pkNX.Structures.FlatBuffers.SV/pkNX.Structures.FlatBuffers.SV.Shared/Gen9/PokeData/PokeDataBattle.cs b/pkNX.Structures.FlatBuffers.SV/pkNX.Structures.FlatBuffers.SV.Shared/Gen9/PokeData/PokeDataBattle.cs index 6221dab3..5f178ebb 100644 --- a/pkNX.Structures.FlatBuffers.SV/pkNX.Structures.FlatBuffers.SV.Shared/Gen9/PokeData/PokeDataBattle.cs +++ b/pkNX.Structures.FlatBuffers.SV/pkNX.Structures.FlatBuffers.SV.Shared/Gen9/PokeData/PokeDataBattle.cs @@ -27,7 +27,7 @@ public void SerializePKHeX(BinaryWriter bw, sbyte captureLv, RaidSerializationFo byte form = species switch { //(ushort)Species.Vivillon or (ushort)Species.Spewpa or (ushort)Species.Scatterbug => 30, - (ushort)Species.Minior when FormId == 0 => 31, + //(ushort)Species.Minior when FormId == 0 => 31, -- nope, actually form 0 _ => (byte)FormId, }; diff --git a/pkNX.Structures.FlatBuffers.SV/pkNX.Structures.FlatBuffers.SV.Trinity/Scene/SceneDumper.cs b/pkNX.Structures.FlatBuffers.SV/pkNX.Structures.FlatBuffers.SV.Trinity/Scene/SceneDumper.cs index 71d3a975..29bb68ed 100644 --- a/pkNX.Structures.FlatBuffers.SV/pkNX.Structures.FlatBuffers.SV.Trinity/Scene/SceneDumper.cs +++ b/pkNX.Structures.FlatBuffers.SV/pkNX.Structures.FlatBuffers.SV.Trinity/Scene/SceneDumper.cs @@ -55,6 +55,15 @@ private static void Dump(TrinitySceneObjectTemplate scene, TextWriter tw, int de Write(tw, depth, $"{nameof(scene.Objects)}: {scene.Objects.Count}"); } + private static void AddToBucket(Span data, string type) + { + var hash = FnvHash.HashFnv1a_64(data); + var dir = Path.Combine(Bucket, type); + var path = Path.Combine(dir, hash.ToString("X16")); + Directory.CreateDirectory(dir); + File.WriteAllBytes(path, data.ToArray()); + } + private static void Dump(Memory data, string type, TextWriter tw, int depth) { const string UnknownType = "Unknown Type"; @@ -120,6 +129,8 @@ private static void DumpPEFlatbuffersDataComponent(Memory data, TextWriter { var props = FlatBufferConverter.DeserializeFrom(data); Write(tw, depth, $"{nameof(props.Field00)}: {props.Field00}"); + if (props.Field01 == null) + return; foreach (var obj in props.Field01) { Write(tw, depth+1, $"{nameof(obj.Field00)}: {obj.Field00}"); @@ -145,15 +156,6 @@ private static void DumpPEAudioGeneratorComponent(Memory data, TextWriter Write(tw, depth, $"{nameof(props.Field01)}: {props.Field01}"); } - private static void AddToBucket(Span data, string type) - { - var hash = FnvHash.HashFnv1a_64(data); - var dir = Path.Combine(Bucket, type); - var path = Path.Combine(dir, hash.ToString("X16")); - Directory.CreateDirectory(dir); - File.WriteAllBytes(path, data.ToArray()); - } - private static void DumpTIDynamicExclusionComponent(Memory data, TextWriter tw, int depth) { var props = FlatBufferConverter.DeserializeFrom(data); @@ -240,44 +242,6 @@ private static void DumpCollisionComponent(Memory data, TextWriter tw, int } } - private static void DumpCollision(Sphere shape, TextWriter tw, int depth) - { - Write(tw, depth, $"v3f: {GetV3F(shape.Field00)}"); - } - - private static void DumpCollision(Box shape, TextWriter tw, int depth) - { - Write(tw, depth, $"v3f: {GetV3F(shape.Field01)}"); - Write(tw, depth, $"v3f: {GetV3F(shape.Field02)}"); - Write(tw, depth, $"v3f: {GetV3F(shape.Field03)}"); - } - - private static void DumpCollision(Capsule shape, TextWriter tw, int depth) - { - Write(tw, depth, $"v3f: {GetV3F(shape.Field00)}"); - Write(tw, depth, $"v3f: {shape.Field01}"); - Write(tw, depth, $"v3f: {shape.Field02}"); - Write(tw, depth, $"v3f: {GetV3F(shape.Field03)}"); - } - - private static void DumpCollision(Havok shape, TextWriter tw, int depth) - { - Write(tw, depth, $"{nameof(shape.TrcolFilePath)}: {shape.TrcolFilePath}"); - Write(tw, depth, $"v3f: {GetV3F(shape.Field01)}"); - Write(tw, depth, $"v3f: {GetV3F(shape.Field02)}"); - Write(tw, depth, $"v3f: {GetV3F(shape.Field03)}"); - } - - private static string GetV3F(Vec3f props) - { - return $"({props.X}, {props.Y}, {props.Z})"; - } - - private static string GetV3F(PackedVec3f props) - { - return $"({props.X}, {props.Y}, {props.Z})"; - } - private static void DumpModelComponent(Memory data, TextWriter tw, int depth) { var props = FlatBufferConverter.DeserializeFrom(data); @@ -318,35 +282,25 @@ private static void DumpObjectSwitcher(Memory data, TextWriter tw, int dep private static void DumpObjectTemplate(Memory data, TextWriter tw, int depth) { - var entry = FlatBufferConverter.DeserializeFrom(data); - Write(tw, depth, $"{nameof(entry.ObjectTemplateName)}: {entry.ObjectTemplateName}"); - Write(tw, depth, $"{nameof(entry.ObjectTemplatePath)}: {entry.ObjectTemplatePath}"); - Write(tw, depth, $"{nameof(entry.ObjectTemplateExtra)}: {entry.ObjectTemplateExtra}"); - Write(tw, depth, $"{nameof(entry.Field03)}: {entry.Field03}"); - Dump(entry.Data, entry.Type, tw, ++depth); + var props = FlatBufferConverter.DeserializeFrom(data); + Write(tw, depth, $"{nameof(props.ObjectTemplateName)}: {props.ObjectTemplateName}"); + Write(tw, depth, $"{nameof(props.ObjectTemplatePath)}: {props.ObjectTemplatePath}"); + Write(tw, depth, $"{nameof(props.ObjectTemplateExtra)}: {props.ObjectTemplateExtra}"); + Write(tw, depth, $"{nameof(props.Field03)}: {props.Field03}"); + Dump(props.Data, props.Type, tw, ++depth); } private static void DumpScenePoint(Memory data, TextWriter tw, int depth) { var props = FlatBufferConverter.DeserializeFrom(data); - Dump(props, tw, depth + 1); - } - - private static void Dump(TrinityScenePoint pt, TextWriter tw, int depth) - { - Write(tw, depth, $"{nameof(pt.Name)}: {pt.Name}"); - Write(tw, depth, $"{nameof(pt.Position)}: {pt.Position}"); - Write(tw, depth, $"{nameof(pt.Field02)}: {pt.Field02}"); + Write(tw, depth, $"{nameof(props.Name)}: {props.Name}"); + Write(tw, depth, $"{nameof(props.Position)}: {props.Position}"); + Write(tw, depth, $"{nameof(props.Field02)}: {props.Field02}"); } private static void DumpSceneObject(Memory data, TextWriter tw, int depth) { var props = FlatBufferConverter.DeserializeFrom(data); - Dump(props, tw, depth); - } - - private static void Dump(TrinitySceneObject props, TextWriter tw, int depth) - { Write(tw, depth, $"{nameof(props.ObjectName)}: {props.ObjectName}"); Write(tw, depth, $"{nameof(props.ObjectPosition)}:"); Dump(props.ObjectPosition, tw, depth + 1); @@ -359,6 +313,37 @@ private static void Dump(TrinitySceneObject props, TextWriter tw, int depth) Dump(props.Field08, tw, depth, nameof(props.Field08)); } + private static void DumpCollision(Sphere shape, TextWriter tw, int depth) + { + Write(tw, depth, $"v3f: {GetV3F(shape.Field00)}"); + } + + private static void DumpCollision(Box shape, TextWriter tw, int depth) + { + Write(tw, depth, $"v3f: {GetV3F(shape.Field01)}"); + Write(tw, depth, $"v3f: {GetV3F(shape.Field02)}"); + Write(tw, depth, $"v3f: {GetV3F(shape.Field03)}"); + } + + private static void DumpCollision(Capsule shape, TextWriter tw, int depth) + { + Write(tw, depth, $"v3f: {GetV3F(shape.Field00)}"); + Write(tw, depth, $"v3f: {shape.Field01}"); + Write(tw, depth, $"v3f: {shape.Field02}"); + Write(tw, depth, $"v3f: {GetV3F(shape.Field03)}"); + } + + private static void DumpCollision(Havok shape, TextWriter tw, int depth) + { + Write(tw, depth, $"{nameof(shape.TrcolFilePath)}: {shape.TrcolFilePath}"); + Write(tw, depth, $"v3f: {GetV3F(shape.Field01)}"); + Write(tw, depth, $"v3f: {GetV3F(shape.Field02)}"); + Write(tw, depth, $"v3f: {GetV3F(shape.Field03)}"); + } + + private static string GetV3F(Vec3f props) => $"({props.X}, {props.Y}, {props.Z})"; + private static string GetV3F(PackedVec3f props) => $"({props.X}, {props.Y}, {props.Z})"; + private static void Dump(IList arr, TextWriter tw, int depth, string name) { Write(tw, depth, $"{name}:"); @@ -376,6 +361,9 @@ private static void Dump(TrinitySceneObjectPosition p, TextWriter tw, int depth) private static void DumpPropertySheet(Memory data, TextWriter tw, int depth) { var props = FlatBufferConverter.DeserializeFrom(data); + Write(tw, depth, $"{nameof(props.Name)}: {props.Name}"); + if (!string.IsNullOrWhiteSpace(props.Extra)) + Write(tw, depth, $"{nameof(props.Extra)}: {props.Extra}"); foreach (var p in props.Properties) { foreach (var f in p.Fields) diff --git a/pkNX.WinForms/Dumping/SV/PaldeaFixedSymbolModel.cs b/pkNX.WinForms/Dumping/SV/PaldeaFixedSymbolModel.cs index ee705fa6..d99e8f2e 100644 --- a/pkNX.WinForms/Dumping/SV/PaldeaFixedSymbolModel.cs +++ b/pkNX.WinForms/Dumping/SV/PaldeaFixedSymbolModel.cs @@ -1,18 +1,26 @@ using System; using System.Collections.Generic; +using System.Linq; using pkNX.Containers; using pkNX.Structures.FlatBuffers; +using pkNX.Structures.FlatBuffers.SV; using pkNX.Structures.FlatBuffers.SV.Trinity; namespace pkNX.WinForms; public class PaldeaFixedSymbolModel { - public readonly List[] scarletPoints = new List[] { new(), new(), new() }; - public readonly List[] violetPoints = new List[] { new(), new(), new() }; + public readonly List[] scarletPoints = [new(), new(), new()]; + public readonly List[] violetPoints = [new(), new(), new()]; + + public readonly Dictionary MultiSpawner; public PaldeaFixedSymbolModel(IFileInternal ROM) { + var gemLottery = FlatBufferConverter.DeserializeFrom( + ROM.GetPackedFile("world/data/field/fixed_symbol/gem_symbol_lottery_table/gem_symbol_lottery_table_array.bin")).Table; + MultiSpawner = gemLottery.ToDictionary(z => z.LotteryKey, GetTableGetKeys); + // Paldea var p0Data = ROM.GetPackedFile("world/scene/parts/field/streaming_event/world_fixed_placement_symbol_/world_fixed_placement_symbol_0.trscn"); var p1Data = ROM.GetPackedFile("world/scene/parts/field/streaming_event/world_fixed_placement_symbol_/world_fixed_placement_symbol_1.trscn"); @@ -44,6 +52,22 @@ public PaldeaFixedSymbolModel(IFileInternal ROM) violetPoints[(int)PaldeaFieldIndex.Terarium].AddRange(GetObjectTemplateSymbolPoints(b1)); } + private static string[] GetTableGetKeys(GemSymbolLotteryTable entry) + { + var list = new List(); + if (!string.IsNullOrWhiteSpace(entry.TableKey0)) list.Add(entry.TableKey0); + if (!string.IsNullOrWhiteSpace(entry.TableKey1)) list.Add(entry.TableKey1); + if (!string.IsNullOrWhiteSpace(entry.TableKey2)) list.Add(entry.TableKey2); + if (!string.IsNullOrWhiteSpace(entry.TableKey3)) list.Add(entry.TableKey3); + if (!string.IsNullOrWhiteSpace(entry.TableKey4)) list.Add(entry.TableKey4); + if (!string.IsNullOrWhiteSpace(entry.TableKey5)) list.Add(entry.TableKey5); + if (!string.IsNullOrWhiteSpace(entry.TableKey6)) list.Add(entry.TableKey6); + if (!string.IsNullOrWhiteSpace(entry.TableKey7)) list.Add(entry.TableKey7); + if (!string.IsNullOrWhiteSpace(entry.TableKey8)) list.Add(entry.TableKey8); + if (!string.IsNullOrWhiteSpace(entry.TableKey9)) list.Add(entry.TableKey9); + return [.. list]; + } + private IEnumerable GetObjectTemplateSymbolPoints(TrinitySceneObjectTemplate template) { foreach (var obj in template.Objects) @@ -73,7 +97,7 @@ private IEnumerable GetObjectTemplateSymbolPoints(Trinit } } - private static IEnumerable GetScenePointSymbolPoints(TrinityScenePoint scenePoint, IList subObjects) + private IEnumerable GetScenePointSymbolPoints(TrinityScenePoint scenePoint, IList subObjects) { // Handle SubObjects for (var i = 0; i < subObjects.Count; i++) @@ -89,7 +113,16 @@ private static IEnumerable GetScenePointSymbolPoints(Tri var tableKey = GetTableKey(propSheet); if (!string.IsNullOrEmpty(tableKey)) { - yield return new PaldeaFixedSymbolPoint(tableKey, scenePoint.Position); + if (MultiSpawner.TryGetValue(tableKey, out var others)) + { + // Can spawn multiple fixed encounters. + foreach (var other in others) + yield return new PaldeaFixedSymbolPoint(other, scenePoint.Position); + } + else + { + yield return new PaldeaFixedSymbolPoint(tableKey, scenePoint.Position); + } } } break;