Update for SV 3.0.0

This commit is contained in:
Kurt 2023-12-17 17:57:24 -08:00
parent 6b7e81eaf4
commit 9d5aa0aa06
61 changed files with 1531 additions and 139 deletions

View File

@ -92,6 +92,7 @@ private static GameVersion GetGameFromPath(string romfs, string? exefs)
private const int FILECOUNT_SV_120 = 26; // Ver. 1.2.0 (Paradox x2)
private const int FILECOUNT_SV_130 = 27; // Ver. 1.3.0 (Paradox x2 Bad Egg fix)
private const int FILECOUNT_SV_201 = 28; // Ver. 2.0.1 (Teal Mask)
private const int FILECOUNT_SV_300 = 30; // Ver. 3.0.0 (Indigo Disk)
private static GameVersion GetGameFromCount(int fileCount, string romfs, string? exefs)
{
@ -151,6 +152,7 @@ private static GameVersion GetGameFromCount(int fileCount, string romfs, string?
case FILECOUNT_SV_120:
case FILECOUNT_SV_130:
case FILECOUNT_SV_201:
case FILECOUNT_SV_300:
{
if (exefs == null)
return GameVersion.SV;

View File

@ -0,0 +1,18 @@
include "Shared/ItemID.fbs";
namespace pkNX.Structures.FlatBuffers.SV;
attribute "fs_serializer";
table LegendPokeTable (fs_serializer) {
StateWorkName:string;
ReleaseItemId:ItemID;
ReactionMessage:string;
EscapeMessage:string;
BattleEnemyId:string;
BattlePlayerPosName:string;
BattlePokePosName:string;
DisableGrounding:bool;
ReleaseBgmFlagName:string;
}
root_type LegendPokeTable;

View File

@ -0,0 +1,22 @@
include "Shared/DevID.fbs";
include "Shared/ItemID.fbs";
namespace pkNX.Structures.FlatBuffers.SV;
attribute "fs_serializer";
table ReleasePokeTableArray (fs_serializer) {
Table:[ReleasePokeTable];
}
table ReleasePokeTable {
EventId:int;
StateWorkName:string;
ReleasePokeId:DevID;
ReleaseItemId:ItemID;
MissionA:bool;
MissionB:bool;
TeamMissionA:bool;
TeamMissionB:bool;
}
root_type ReleasePokeTableArray;

View File

@ -7,6 +7,7 @@ attribute "fs_serializer";
table SeriItemTable {
SeriItemTableId:int;
ItemId:ItemID = ITEMID_NONE;
DressupId:int;
MinPrice:int;
BasePrice:int;
MinItemNum:int;
@ -16,6 +17,7 @@ table SeriItemTable {
Venue2Probability:int;
Venue3Probability:int;
Venue4Probability:int;
Venue5Probability:int;
BarkerMessageLabelName:string (required);
ItemObjectName:string (required);
BoxObjectName:string (required);

View File

@ -12,6 +12,7 @@ table SeriVenueTable {
SeriVenueTableId:int;
IsEventOnly:bool;
IsLegend:bool;
IsNpcSelectAll:bool;
VenueType:VenueType;
McName:string (required);
BarkerMessageLabelName:string (required);

View File

@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
#nullable disable // meh
namespace pkNX.Structures.FlatBuffers.SV;
@ -21,30 +20,7 @@ public class PersonalDumperSV
public IReadOnlyList<string> ZukanA { private get; init; }
public IReadOnlyList<string> ZukanB { private get; init; }
public static readonly ushort[] TMIndexes =
{
005, 036, 204, 313, 097, 189, 184, 182, 424, 422,
423, 352, 067, 491, 512, 522, 060, 109, 168, 574,
885, 884, 886, 451, 083, 263, 342, 332, 523, 506,
555, 232, 129, 345, 196, 341, 317, 577, 488, 490,
314, 500, 101, 374, 525, 474, 419, 203, 521, 241,
240, 201, 883, 684, 473, 091, 331, 206, 280, 428,
369, 421, 492, 706, 339, 403, 034, 007, 009, 008,
214, 402, 486, 409, 115, 113, 350, 127, 337, 605,
118, 447, 086, 398, 707, 156, 157, 269, 014, 776,
191, 390, 286, 430, 399, 141, 598, 019, 285, 442,
349, 408, 441, 164, 334, 404, 529, 261, 242, 271,
710, 202, 396, 366, 247, 406, 446, 304, 257, 412,
094, 484, 227, 057, 861, 053, 085, 583, 133, 347,
270, 676, 226, 414, 179, 058, 604, 580, 678, 581,
417, 126, 056, 059, 519, 518, 520, 528, 188, 089,
444, 566, 416, 307, 308, 338, 200, 315, 411, 437,
542, 433, 405, 063, 413, 394, 087, 370, 076, 434,
796, 851, 046, 268, 114, 092, 328, 180, 356, 479,
360, 282, 450, 162, 410, 679, 667, 333, 503, 535,
669, 253, 264, 311, 803, 807, 812, 814, 809, 808,
799, 802,
};
public static ushort[] TMIndexes => PersonalInfo9SV.TMIndexes;
private static readonly string[] AbilitySuffix = { " (1)", " (2)", " (H)" };
@ -211,7 +187,7 @@ private string GetArgTypeDisplayValue(EvolutionType type, ushort value)
EvolutionTypeArgumentType.Species => GetSpeciesName(value),
EvolutionTypeArgumentType.Type => Types[value],
EvolutionTypeArgumentType.Stat => value.ToString(),
//EvolutionTypeArgumentType.Version => expr,
EvolutionTypeArgumentType.Version => value.ToString(),
_ => throw new ArgumentOutOfRangeException(nameof(argType), argType, null),
};
@ -277,14 +253,14 @@ public static class Plib9
{ 0008, 0108 }, // Dusk Stone
{ 0009, 0110 }, // Oval Stone
{ 0010, 1779 }, // Griseous Core
{ 0011, 0000 }, //
{ 0012, 0000 }, //
{ 0013, 0000 }, //
{ 0014, 0000 }, //
{ 0011, 0000 },
{ 0012, 0000 },
{ 0013, 0000 },
{ 0014, 0000 },
{ 0015, 0229 }, // Everstone
{ 0016, 0236 }, // Light Ball
{ 0017, 0000 }, //
{ 0018, 0000 }, //
{ 0017, 0000 },
{ 0018, 0000 },
{ 0019, 0280 }, // Destiny Knot
{ 0020, 0289 }, // Power Bracer
{ 0021, 0290 }, // Power Belt
@ -308,43 +284,43 @@ public static class Plib9
{ 0039, 0311 }, // Draco Plate
{ 0040, 0312 }, // Dread Plate
{ 0041, 0313 }, // Iron Plate
{ 0042, 0000 }, //
{ 0043, 0000 }, //
{ 0044, 0000 }, //
{ 0045, 0000 }, //
{ 0046, 0000 }, //
{ 0047, 0000 }, //
{ 0048, 0000 }, //
{ 0042, 0000 },
{ 0043, 0000 },
{ 0044, 0000 },
{ 0045, 0000 },
{ 0046, 0000 },
{ 0047, 0000 },
{ 0048, 0000 },
{ 0049, 0326 }, // Razor Claw
{ 0050, 0327 }, // Razor Fang
{ 0051, 0644 }, // Pixie Plate
{ 0052, 0849 }, // Ice Stone
{ 0053, 0000 }, //
{ 0054, 0000 }, //
{ 0055, 0000 }, //
{ 0056, 0000 }, //
{ 0057, 0000 }, //
{ 0058, 0000 }, //
{ 0059, 0000 }, //
{ 0060, 0000 }, //
{ 0061, 0000 }, //
{ 0062, 0000 }, //
{ 0063, 0000 }, //
{ 0064, 0000 }, //
{ 0065, 0000 }, //
{ 0066, 0000 }, //
{ 0067, 0000 }, //
{ 0068, 0000 }, //
{ 0069, 0000 }, //
{ 0053, 0000 },
{ 0054, 0000 },
{ 0055, 0000 },
{ 0056, 0000 },
{ 0057, 0000 },
{ 0058, 0000 },
{ 0059, 0000 },
{ 0060, 0000 },
{ 0061, 0000 },
{ 0062, 0000 },
{ 0063, 0000 },
{ 0064, 0000 },
{ 0065, 0000 },
{ 0066, 0000 },
{ 0067, 0000 },
{ 0068, 0000 },
{ 0069, 0000 },
{ 0070, 1103 }, // Rusted Sword
{ 0071, 1104 }, // Rusted Shield
{ 0072, 0000 }, //
{ 0073, 0000 }, //
{ 0074, 0000 }, //
{ 0075, 0000 }, //
{ 0076, 0000 }, //
{ 0077, 0000 }, //
{ 0078, 0000 }, //
{ 0072, 1109 }, // Strawberry Sweet
{ 0073, 1110 }, // Love Sweet
{ 0074, 1111 }, // Berry Sweet
{ 0075, 1112 }, // Clover Sweet
{ 0076, 1113 }, // Flower Sweet
{ 0077, 1114 }, // Star Sweet
{ 0078, 1115 }, // Ribbon Sweet
{ 0079, 1116 }, // Sweet Apple
{ 0080, 1117 }, // Tart Apple
{ 0081, 1253 }, // Cracked Pot
@ -356,8 +332,8 @@ public static class Plib9
{ 0087, 2345 }, // Leaders Crest
{ 0088, 1857 }, // Scroll of Darkness
{ 0089, 1858 }, // Scroll of Waters
{ 0090, 0000 }, //
{ 0091, 0000 }, //
{ 0090, 0000 },
{ 0091, 0000 },
{ 0092, 0218 }, // Soothe Bell
{ 0093, 0109 }, // Dawn Stone
{ 0094, 2403 }, // Unremarkable Teacup
@ -365,5 +341,12 @@ public static class Plib9
{ 0096, 2402 }, // Syrupy Apple
{ 0111, 0537 }, // Prism Scale
{ 0112, 0325 }, // Reaper Cloth
{ 0113, 0252 }, // Upgrade
{ 0114, 0324 }, // Dubious Disc
{ 0115, 0322 }, // Electirizer
{ 0116, 0323 }, // Magmarizer
{ 0117, 0321 }, // Protector
{ 0118, 0235 }, // Dragon Scale
{ 0119, 2482 }, // Metal Alloy
};
}

View File

@ -164,6 +164,8 @@ public void Write(BinaryWriter bw)
796, 851, 046, 268, 114, 092, 328, 180, 356, 479,
360, 282, 450, 162, 410, 679, 667, 333, 503, 535,
669, 253, 264, 311, 803, 807, 812, 814, 809, 808,
799, 802,
799, 802, 220, 244, 038, 283, 572, 915, 250, 330,
916, 527, 813, 811, 482, 815, 297, 248, 797, 806,
800, 675, 784, 319, 174, 912, 913, 914, 917, 918,
};
}

View File

@ -65,12 +65,10 @@ public static ushort GetNational9(ushort raw)
029, -53, -65, 025, -06, -03, -07, -04, -04, -08,
-04, 001, -03, -03, -06, -04, -47, -47, -47, -23,
-23, -05, -07, -09, -07, -20, -13, -09, -09, -29,
-23, 001, 012, 012, 000, 000, 000, -06, UNK, UNK,
UNK, UNK, UNK, UNK, UNK, UNK,
-23, 001, 012, 012, 000, 000, 000, -06, 005, -06,
-03, -03, -02, -04, -03, -03,
};
private const sbyte UNK = 111;
/// <summary>
/// Difference of Gen9 Species IDs (index) and the associated National Dex IDs (value)
/// </summary>
@ -86,8 +84,7 @@ public static ushort GetNational9(ushort raw)
029, 008, 003, 004, 004, 020, 004, 023, 006, 003,
003, 004, -01, 013, 009, 007, 005, 007, 009, 009,
-43, -43, -43, -68, -68, -68, -58, -58, -25, -29,
-31, 006, -01, UNK, 000, 000, 000, UNK, UNK, UNK,
UNK, UNK, UNK, UNK, -12, -12,
-31, 006, -01, 006, 000, 000, 000, 003, 003, 004,
002, 003, 003, -05, -12, -12,
};
}

View File

@ -1015,9 +1015,17 @@ enum DevID : ushort {
DEV_MANKII3 = 1010,
DEV_KAMENONI = 1011,
DEV_KAZITTYU2 = 1012,
DEV_KAZITTYU3 = 1013,
DEV_DOKUINU = 1014,
DEV_DOKUZARU = 1015,
DEV_DOKUKIZI = 1016,
DEV_AENTEI = 1017,
DEV_ARAIKOU = 1018,
DEV_BKOBARUON = 1019,
DEV_BTERAKION = 1020,
DEV_KODAIGAME = 1021,
DEV_DOKUTAROU = 1022,
DEV_ZYURARUDO2 = 1023,
DEV_MATCHA1 = 1024,
DEV_MATCHA2 = 1025,
}

View File

@ -906,4 +906,19 @@ enum WazaID : ushort {
WAZA_SHAKASHAKAHO = 902,
WAZA_MITSUAMEKOTO = 903,
WAZA_ONIKANABOO = 904,
WAZA_TYOUDENGIHOU = 905,
WAZA_TERAKURASUTAA = 906,
WAZA_KIMAGUREEZAA = 907,
WAZA_KAZANNOFURIRU = 908,
WAZA_SEITENHEKIREKI = 909,
WAZA_ROKKUKUREIMOA = 910,
WAZA_METARUSXYOOTERU = 911,
WAZA_HAADOPURESU = 912,
WAZA_WOOKURAI = 913,
WAZA_TENSHINOSOPURANO = 914,
WAZA_YAKETUPATI = 915,
WAZA_INAZUMADAIBU = 916,
WAZA_SAIKONOIZU = 917,
WAZA_HAYATEGAESHI = 918,
WAZA_KUSARIENN = 919,
}

View File

@ -0,0 +1,452 @@
using System;
using System.Collections.Generic;
using System.IO;
using pkNX.Containers;
namespace pkNX.Structures.FlatBuffers.SV.Trinity;
public static class SceneDumper
{
private const char PadChar = '\t';
private static void Write(TextWriter tw, int depth, string str) => tw.WriteLine(new string(PadChar, depth) + str);
public static string Bucket { get; set; } = "";
public static bool ThrowOnUnknownType { get; set; } = false;
public static TrinitySceneObjectTemplate Dump(string path) => Dump(path, Console.Out);
public static TrinitySceneObjectTemplate Dump(string path, TextWriter tw)
{
var data = File.ReadAllBytes(path);
var scene = FlatBufferConverter.DeserializeFrom<TrinitySceneObjectTemplate>(data);
Dump(scene, tw);
return scene;
}
private static void Dump(TrinitySceneObjectTemplate scene, TextWriter tw)
{
const int depth = 0;
Dump(scene, tw, depth);
foreach (var obj in scene.Objects)
Dump(obj, tw, depth + 1);
}
private static void Dump(TrinitySceneObjectTemplateEntry scene, TextWriter tw, int depth)
{
Dump(scene.Data, scene.Type, tw, depth);
Dump(scene.SubObjects, tw, depth);
}
private static void Dump(IList<TrinitySceneObjectTemplateEntry> arr, TextWriter tw, int depth)
{
foreach (var obj in arr)
{
Dump(obj.Data, obj.Type, tw, depth + 1);
Dump(obj.SubObjects, tw, depth + 1);
}
}
private static void Dump(TrinitySceneObjectTemplate scene, TextWriter tw, int depth)
{
Write(tw, depth, $"{nameof(scene.ObjectTemplateName)}: {scene.ObjectTemplateName}");
Write(tw, depth, $"{nameof(scene.Field02)}: {scene.Field02}");
Write(tw, depth, $"{nameof(scene.Field03)}: {scene.Field03}");
Dump(scene.Field05, tw, depth, nameof(scene.Field05));
Write(tw, depth, $"{nameof(scene.Objects)}: {scene.Objects.Count}");
}
private static void Dump(Memory<byte> data, string type, TextWriter tw, int depth)
{
const string UnknownType = "Unknown Type";
Write(tw, depth++, type);
try
{
switch (type)
{
case "SubScene": DumpSubScene(data, tw, depth); break;
case "trinity_PropertySheet": DumpPropertySheet(data, tw, depth); break;
case "trinity_SceneObject": DumpSceneObject(data, tw, depth); break;
case "trinity_ScenePoint": DumpScenePoint(data, tw, depth); break;
case "trinity_ObjectTemplate": DumpObjectTemplate(data, tw, depth); break;
case "trinity_ScriptComponent": DumpScriptComponent(data, tw, depth); break;
case "trinity_ObjectSwitcher": DumpObjectSwitcher(data, tw, depth); break;
case "trinity_ModelComponent": DumpModelComponent(data, tw, depth); break;
case "trinity_CollisionComponent": DumpCollisionComponent(data, tw, depth); break;
case "trinity_ParticleComponent": DumpParticleComponent(data, tw, depth); break;
case "trinity_GroundPlaceComponent": DumpGroundPlaceComponent(data, tw, depth); break;
case "ti_AIPerceptualComponent": DumpTIAIPerceptualComponent(data, tw, depth); break;
case "ti_ModelDitherFadeComponent": DumpTIModelDitherFadeComponent(data, tw, depth); break;
case "ti_DynamicExclusionComponent": DumpTIDynamicExclusionComponent(data, tw, depth); break;
case "ti_FieldComponent": DumpTIFieldComponent(data, tw, depth); break;
case "ti_FieldAttributePickerComponent": DumpTIFieldAttributePickerComponent(data, tw, depth); break;
case "ti_PokemonModelComponent": DumpTIPokemonModelComponent(data, tw, depth); break;
case "pe_AudioGeneratorComponent": DumpPEAudioGeneratorComponent(data, tw, depth); break;
case "trinity_CollisionEventTriggerComponent": DumpCollisionEventTriggerComponent(data, tw, depth); break;
case "trinity_EnvironmentParameter": DumpTrinityEnvironmentParameter(data, tw, depth); break;
case "trinity_OverrideSensorData": DumpTrinityOverrideSensorData(data, tw, depth); break;
case "pe_FlatbuffersDataComponent": DumpPEFlatbuffersDataComponent(data, tw, depth); break;
default:
if (ThrowOnUnknownType)
throw new ArgumentOutOfRangeException(nameof(type), type, null);
Write(tw, depth, $"{UnknownType}: {type}");
break;
}
}
catch (Exception ex) when (!ex.Message.StartsWith(UnknownType))
{
Write(tw, depth, $"Error Parsing ({ex.GetType().Name}): {ex.Message}");
}
if (Bucket.Length != 0)
AddToBucket(data.Span, type);
}
private static void DumpTrinityOverrideSensorData(Memory<byte> data, TextWriter tw, int depth)
{
var props = FlatBufferConverter.DeserializeFrom<TrinityOverrideSensorData>(data);
Write(tw, depth, $"{nameof(props.Field00)}: {props.Field00}");
Write(tw, depth, $"{nameof(props.Field01)}: {props.Field01}");
Write(tw, depth, $"{nameof(props.Field02)}: {props.Field02}");
Write(tw, depth, $"{nameof(props.Field03)}: {props.Field03}");
}
private static void DumpTrinityEnvironmentParameter(Memory<byte> data, TextWriter tw, int depth)
{
var props = FlatBufferConverter.DeserializeFrom<TrinityEnvironmentParameter>(data);
Write(tw, depth, $"{nameof(props.Field00)}: {props.Field00}");
Write(tw, depth, $"{nameof(props.Field01)}: {props.Field01}");
}
private static void DumpPEFlatbuffersDataComponent(Memory<byte> data, TextWriter tw, int depth)
{
var props = FlatBufferConverter.DeserializeFrom<PEFlatbuffersDataComponent>(data);
Write(tw, depth, $"{nameof(props.Field00)}: {props.Field00}");
foreach (var obj in props.Field01)
{
Write(tw, depth+1, $"{nameof(obj.Field00)}: {obj.Field00}");
Write(tw, depth+1, $"{nameof(obj.Field01)}: {obj.Field01}");
}
}
private static void DumpCollisionEventTriggerComponent(Memory<byte> data, TextWriter tw, int depth)
{
var props = FlatBufferConverter.DeserializeFrom<TrinityCollisionEventTriggerComponent>(data);
Write(tw, depth, $"{nameof(props.Field00)}: {props.Field00}");
Write(tw, depth, $"{nameof(props.Field01)}: {props.Field01}");
Write(tw, depth, $"{nameof(props.Field02)}: {props.Field02}");
Write(tw, depth, $"{nameof(props.Field03)}: {props.Field03}");
Write(tw, depth, $"{nameof(props.Field04)}: {props.Field04}");
Write(tw, depth, $"{nameof(props.Field05)}: {props.Field05}");
}
private static void DumpPEAudioGeneratorComponent(Memory<byte> data, TextWriter tw, int depth)
{
var props = FlatBufferConverter.DeserializeFrom<PEAudioGeneratorComponent>(data);
Write(tw, depth, $"{nameof(props.Field00)}: {props.Field00}");
Write(tw, depth, $"{nameof(props.Field01)}: {props.Field01}");
}
private static void AddToBucket(Span<byte> 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<byte> data, TextWriter tw, int depth)
{
var props = FlatBufferConverter.DeserializeFrom<TIDynamicExclusionComponent>(data);
Write(tw, depth, $"{nameof(props.Field00)}: {props.Field00}");
}
private static void DumpTIModelDitherFadeComponent(Memory<byte> data, TextWriter tw, int depth)
{
var props = FlatBufferConverter.DeserializeFrom<TIModelDitherFadeComponent>(data);
Write(tw, depth, $"{nameof(props.Field00)}: {props.Field00}");
Write(tw, depth, $"{nameof(props.Field01)}: {props.Field01}");
Write(tw, depth, $"{nameof(props.Field02)}: {props.Field02}");
Write(tw, depth, $"{nameof(props.Field03)}: {props.Field03}");
Write(tw, depth, $"{nameof(props.Field04)}: {props.Field04}");
}
private static void DumpTIFieldComponent(Memory<byte> data, TextWriter tw, int depth)
{
var props = FlatBufferConverter.DeserializeFrom<TIFieldComponent>(data);
Write(tw, depth, $"{nameof(props.Field00)}: {props.Field00}");
Write(tw, depth, $"{nameof(props.Field01)}: {props.Field01}");
Write(tw, depth, $"{nameof(props.Field02)}: {props.Field02}");
Write(tw, depth, $"{nameof(props.Field03)}: {props.Field03}");
Write(tw, depth, $"{nameof(props.Field04)}: {props.Field04}");
}
private static void DumpTIFieldAttributePickerComponent(Memory<byte> data, TextWriter tw, int depth)
{
var props = FlatBufferConverter.DeserializeFrom<TIFieldAttributePickerComponent>(data);
Write(tw, depth, $"{nameof(props.Field00)}: {props.Field00}");
Write(tw, depth, $"{nameof(props.Field01)}: {props.Field01}");
Write(tw, depth, $"{nameof(props.Field02)}: {props.Field02}");
Write(tw, depth, $"{nameof(props.Field03)}: {props.Field03}");
}
private static void DumpTIPokemonModelComponent(Memory<byte> data, TextWriter tw, int depth)
{
var props = FlatBufferConverter.DeserializeFrom<TIPokemonModelComponent>(data);
Write(tw, depth, $"{nameof(props.Field00)}: {props.Field00}");
Write(tw, depth, $"{nameof(props.Field01)}: {props.Field01}");
Write(tw, depth, $"{nameof(props.Field02)}: {props.Field02}");
Write(tw, depth, $"{nameof(props.Field03)}: {props.Field03}");
Write(tw, depth, $"{nameof(props.Field04)}: {props.Field04}");
Write(tw, depth, $"{nameof(props.Field05)}: {props.Field05}");
Write(tw, depth, $"{nameof(props.Field06)}: {props.Field06}");
Write(tw, depth, $"{nameof(props.Field07)}: {props.Field07}");
Write(tw, depth, $"{nameof(props.Field08)}: {props.Field08}");
}
private static void DumpTIAIPerceptualComponent(Memory<byte> data, TextWriter tw, int depth)
{
var props = FlatBufferConverter.DeserializeFrom<TIAIPerceptualComponent>(data);
Write(tw, depth, $"{nameof(props.Value)}: {props.Value}");
}
private static void DumpGroundPlaceComponent(Memory<byte> data, TextWriter tw, int depth)
{
var props = FlatBufferConverter.DeserializeFrom<TrinityGroundPlaceComponent>(data);
Write(tw, depth, $"{nameof(props.Index)}: {props.Index}");
}
private static void DumpParticleComponent(Memory<byte> data, TextWriter tw, int depth)
{
var props = FlatBufferConverter.DeserializeFrom<TrinityParticleComponent>(data);
Write(tw, depth, $"{nameof(props.ParticleFile)}: {props.ParticleFile}");
Write(tw, depth, $"{nameof(props.ParticleName)}: {props.ParticleName}");
Write(tw, depth, $"{nameof(props.ParticleParent)}: {props.ParticleParent}");
}
private static void DumpCollisionComponent(Memory<byte> data, TextWriter tw, int depth)
{
var props = FlatBufferConverter.DeserializeFrom<TrinityComponent>(data);
var shape = props.Component.CollisionComponent.Shape;
Write(tw, depth, $"{nameof(props.Component.CollisionComponent.Shape)}: {shape.Kind}");
Write(tw, depth, $"v3f: {GetV3F(props.Component.CollisionComponent.Field08)}");
depth++;
switch (shape.Kind)
{
case CollisionUnion.ItemKind.Sphere: DumpCollision(shape.Sphere, tw, depth); break;
case CollisionUnion.ItemKind.Box: DumpCollision(shape.Box, tw, depth); break;
case CollisionUnion.ItemKind.Capsule: DumpCollision(shape.Capsule, tw, depth); break;
case CollisionUnion.ItemKind.Havok: DumpCollision(shape.Havok, tw, depth); break;
default: throw new ArgumentOutOfRangeException();
}
}
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<byte> data, TextWriter tw, int depth)
{
var props = FlatBufferConverter.DeserializeFrom<TrinityModelComponent>(data);
Write(tw, depth, $"{nameof(props.Field00)}: {props.Field00}");
Write(tw, depth, $"{nameof(props.Field01)}: {props.Field01}");
Write(tw, depth, $"{nameof(props.Field02)}: {props.Field02}");
Write(tw, depth, $"{nameof(props.Field03)}: {props.Field03}");
Write(tw, depth, $"{nameof(props.Field05)}: {props.Field05}");
Write(tw, depth, $"{nameof(props.Field06)}: {props.Field06}");
Write(tw, depth, $"{nameof(props.Field07)}: {props.Field07}");
Write(tw, depth, $"{nameof(props.Field19)}: {props.Field19}");
Write(tw, depth, $"{nameof(props.Field20)}: {props.Field20}");
Write(tw, depth, $"{nameof(props.Field21)}: {props.Field21}");
Write(tw, depth, $"{nameof(props.Field22)}: {props.Field22}");
}
private static void DumpScriptComponent(Memory<byte> data, TextWriter tw, int depth)
{
var props = FlatBufferConverter.DeserializeFrom<TrinityScriptComponent>(data);
Write(tw, depth, $"{nameof(props.ScriptFileName)}: {props.ScriptFileName}");
Write(tw, depth, $"{nameof(props.ScriptFileNameHash)}: {props.ScriptFileNameHash}");
Write(tw, depth, $"{nameof(props.ScriptFileClass)}: {props.ScriptFileClass}");
}
private static void DumpSubScene(Memory<byte> data, TextWriter tw, int depth)
{
var props = FlatBufferConverter.DeserializeFrom<SubScene>(data);
Write(tw, depth, $"{nameof(props.Field00)}: {props.Field00}");
Write(tw, depth, $"{nameof(props.Field01)}: {props.Field01}");
}
private static void DumpObjectSwitcher(Memory<byte> data, TextWriter tw, int depth)
{
var props = FlatBufferConverter.DeserializeFrom<TrinityObjectSwitcher>(data);
Write(tw, depth, $"{nameof(props.Field00)}: {props.Field00}");
Write(tw, depth, $"{nameof(props.Field01)}: {props.Field01}");
}
private static void DumpObjectTemplate(Memory<byte> data, TextWriter tw, int depth)
{
var entry = FlatBufferConverter.DeserializeFrom<TrinitySceneObjectTemplateData>(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);
}
private static void DumpScenePoint(Memory<byte> data, TextWriter tw, int depth)
{
var props = FlatBufferConverter.DeserializeFrom<TrinityScenePoint>(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}");
}
private static void DumpSceneObject(Memory<byte> data, TextWriter tw, int depth)
{
var props = FlatBufferConverter.DeserializeFrom<TrinitySceneObject>(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);
Write(tw, depth, $"{nameof(props.Field02)}: {props.Field02}");
Write(tw, depth, $"{nameof(props.Field03)}: {props.Field03}");
Write(tw, depth, $"{nameof(props.Field04)}: {props.Field04}");
Write(tw, depth, $"{nameof(props.Field05)}: {props.Field05}");
Write(tw, depth, $"{nameof(props.Field06)}: {props.Field06}");
Write(tw, depth, $"{nameof(props.Field07)}: {props.Field07}");
Dump(props.Field08, tw, depth, nameof(props.Field08));
}
private static void Dump<T>(IList<T> arr, TextWriter tw, int depth, string name)
{
Write(tw, depth, $"{name}:");
for (var i = 0; i < arr.Count; i++)
Write(tw, depth + 1, $"[{i}]: {arr[i]}");
}
private static void Dump(TrinitySceneObjectPosition p, TextWriter tw, int depth)
{
Write(tw, depth, $"{nameof(p.Field00)}: {p.Field00}");
Write(tw, depth, $"{nameof(p.Field01)}: {p.Field01}");
Write(tw, depth, $"{nameof(p.Field02)}: {p.Field02}");
}
private static void DumpPropertySheet(Memory<byte> data, TextWriter tw, int depth)
{
var props = FlatBufferConverter.DeserializeFrom<TrinityPropertySheet>(data);
foreach (var p in props.Properties)
{
foreach (var f in p.Fields)
Dump(f, tw, depth + 1);
}
}
private static void Dump(TrinityPropertySheetField f, TextWriter tw, int depth)
{
Write(tw, depth, $"{nameof(f.Name)}: {f.Name}");
//Write(tw, depth, $"{nameof(f.Data.Discriminator)}: {f.Data.Discriminator}");
Dump(f.Data, tw, depth);
}
private static void Dump(TrinityPropertySheetValue v, TextWriter tw, int depth)
{
switch (v.Discriminator)
{
case 1: Dump(v.Item1, tw, depth); break;
case 2: Dump(v.Item2, tw, depth); break;
case 3: Dump(v.Item3, tw, depth); break;
case 4: Dump(v.Item4, tw, depth); break;
case 5: Dump(v.Item5, tw, depth); break;
case 6: Dump(v.Item6, tw, depth); break;
case 7: Dump(v.Item7, tw, depth); break;
case 8: Dump(v.Item8, tw, depth); break;
case 9: Dump(v.Item9, tw, depth); break;
default: throw new ArgumentOutOfRangeException(nameof(v.Discriminator), v.Discriminator, null);
}
}
private static void Dump(TrinityPropertySheetField1 item, TextWriter tw, int depth)
{
Write(tw, depth, $"{nameof(item.Value)}: {item.Value}");
//Write(tw, depth, $"{nameof(item.FieldType)}: {item.FieldType}");
}
private static void Dump(TrinityPropertySheetField2 item, TextWriter tw, int depth)
{
Write(tw, depth, $"{nameof(item.Value)}: {item.Value}");
//Write(tw, depth, $"{nameof(item.FieldType)}: {item.FieldType}");
}
private static void Dump(TrinityPropertySheetFieldStringValue item, TextWriter tw, int depth)
{
Write(tw, depth, $"{nameof(item.Value)}: {item.Value}");
}
private static void Dump(TrinityPropertySheetField4 item, TextWriter tw, int depth) =>
Write(tw, depth, $"UNDOCUMENTED {nameof(TrinityPropertySheetField4)}");
private static void Dump(TrinityPropertySheetField5 item, TextWriter tw, int depth) =>
Write(tw, depth, $"UNDOCUMENTED {nameof(TrinityPropertySheetField5)}");
private static void Dump(TrinityPropertySheetField6 item, TextWriter tw, int depth) =>
Write(tw, depth, $"UNDOCUMENTED {nameof(TrinityPropertySheetField6)}");
private static void Dump(TrinityPropertySheetFieldEnumName item, TextWriter tw, int depth)
{
Write(tw, depth, $"{nameof(item.Value)}: {item.Value}");
}
private static void Dump(TrinityPropertySheetObjectArray item, TextWriter tw, int depth)
{
foreach (var obj in item.Value)
Dump(obj, tw, depth + 1);
}
private static void Dump(TrinityPropertySheetObject item, TextWriter tw, int depth)
{
foreach (var f in item.Fields)
Dump(f, tw, depth + 1);
}
}

View File

@ -0,0 +1,8 @@
namespace pkNX.Structures.FlatBuffers.SV.Trinity;
attribute "fs_serializer";
table TIAIPerceptualComponent (fs_serializer) {
Value:byte; // not a bool
}
root_type TIAIPerceptualComponent;

View File

@ -0,0 +1,8 @@
namespace pkNX.Structures.FlatBuffers.SV.Trinity;
attribute "fs_serializer";
table TIDynamicExclusionComponent (fs_serializer) {
Field_00:byte;
}
root_type TIDynamicExclusionComponent;

View File

@ -0,0 +1,12 @@
namespace pkNX.Structures.FlatBuffers.SV.Trinity;
attribute "fs_serializer";
table TIModelDitherFadeComponent (fs_serializer) {
Field_00:byte; //unknown
Field_01:float;
Field_02:float;
Field_03:float;
Field_04:float;
}
root_type TIModelDitherFadeComponent;

View File

@ -5,10 +5,7 @@ namespace pkNX.Structures.FlatBuffers.SV.Trinity;
attribute "fs_serializer";
table Sphere {
TrcolFilePath:string (required);
Field_01:PackedVec3f (required);
Field_02:PackedVec3f (required);
Field_03:PackedVec3f (required);
Field_00:PackedVec3f;
}
table Box {
@ -19,9 +16,9 @@ table Box {
}
table Capsule {
TrcolFilePath:string (required);
Field_01:PackedVec3f (required);
Field_02:PackedVec3f (required);
Field_00:PackedVec3f (required);
Field_01:float;
Field_02:float;
Field_03:PackedVec3f (required);
}
@ -32,23 +29,17 @@ table Havok {
Field_03:PackedVec3f (required);
}
table Vec3f {
X:float;
Y:float;
Z:float;
}
union CollisionUnion {Sphere, Box, Capsule, Havok}
table CollisionComponent (fs_serializer) {
Shape:CollisionUnion (required);
// field 01 is the object ptr for ^
Field_02:uint;
Field_02:uint; //unknown
Field_03:byte;
Field_04:uint;
Field_05:uint;
Field_04:uint; //unknown
Field_05:uint; //unknown
Field_06:uint;
Field_07:uint;
Field_07:uint; //unknown
Field_08:Vec3f (required);
Field_09:string (required);
Field_0A:uint;

View File

@ -0,0 +1,9 @@
namespace pkNX.Structures.FlatBuffers.SV.Trinity;
attribute "fs_serializer";
table TrinityEnvironmentParameter (fs_serializer) {
Field_00:string (required);
Field_01:float;
}
root_type TrinityEnvironmentParameter;

View File

@ -0,0 +1,8 @@
namespace pkNX.Structures.FlatBuffers.SV.Trinity;
attribute "fs_serializer";
table TrinityGroundPlaceComponent (fs_serializer) {
Index:uint;
}
root_type TrinityGroundPlaceComponent;

View File

@ -0,0 +1,30 @@
namespace pkNX.Structures.FlatBuffers.SV.Trinity;
attribute "fs_serializer";
table TrinityModelComponent (fs_serializer) {
Field_00:string (required);
Field_01:string (required);
Field_02:string (required);
Field_03:string (required);
Field_04:ubyte; // unknown
Field_05:float;
Field_06:float;
Field_07:float;
Field_08:ubyte; // unknown
Field_09:ubyte; // unknown
Field_10:ubyte; // unknown
Field_11:ubyte; // unknown
Field_12:ubyte; // unknown
Field_13:ubyte; // unknown
Field_14:ubyte; // unknown
Field_15:ubyte; // unknown
Field_16:ubyte; // unknown
Field_17:ubyte; // unknown
Field_18:ubyte; // unknown
Field_19:string (required);
Field_20:string (required);
Field_21:bool;
Field_22:string (required);
}
root_type TrinityModelComponent;

View File

@ -0,0 +1,11 @@
namespace pkNX.Structures.FlatBuffers.SV.Trinity;
attribute "fs_serializer";
table TrinityOverrideSensorData (fs_serializer) {
Field_00:float;
Field_01:float;
Field_02:float;
Field_03:float;
}
root_type TrinityOverrideSensorData;

View File

@ -0,0 +1,12 @@
namespace pkNX.Structures.FlatBuffers.SV.Trinity;
attribute "fs_serializer";
table TrinityParticleComponent (fs_serializer) {
ParticleFile:string (required);
Field_01:string (required);
Field_02:bool;
ParticleName:string (required);
ParticleParent:string (required);
}
root_type TrinityParticleComponent;

View File

@ -7,8 +7,7 @@ table TrinityPropertySheetFieldStringValue { Value:string (required); }
table TrinityPropertySheetField4 { }
table TrinityPropertySheetField5 { }
table TrinityPropertySheetField6 { }
table TrinityPropertySheetField7 { }
table TrinityPropertySheetField8 { }
table TrinityPropertySheetFieldEnumName { Value:string (required); }
/// Recursive!
table TrinityPropertySheetObject { Fields:[TrinityPropertySheetField] (required); }
@ -20,11 +19,13 @@ union TrinityPropertySheetValue {
TrinityPropertySheetField4,
TrinityPropertySheetField5,
TrinityPropertySheetField6,
TrinityPropertySheetField7,
TrinityPropertySheetField8,
TrinityPropertySheetFieldEnumName,
TrinityPropertySheetObjectArray,
TrinityPropertySheetObject
}
table TrinityPropertySheetObjectArray { Value:[TrinityPropertySheetValue] (required); }
table TrinityPropertySheetField {
Name:string (required);
Data:TrinityPropertySheetValue (required);

View File

@ -3,6 +3,87 @@ include "Math/PackedVec3f.fbs";
namespace pkNX.Structures.FlatBuffers.SV.Trinity;
attribute "fs_serializer";
table SubScene (fs_serializer) {
Field_00:string (required);
Field_01:string (required);
}
table TIFieldComponent (fs_serializer) {
Field_00:uint;
Field_01:uint;
Field_02:uint;
Field_03:uint;
Field_04:uint;
}
table TIPokemonModelComponent (fs_serializer) {
Field_00:ushort;
Field_01:ushort;
Field_02:byte; // unknown
Field_03:byte; // unknown
Field_04:byte; // unknown
Field_05:byte; // unknown
Field_06:byte; // unknown
Field_07:byte; // unknown
Field_08:bool;
}
table TIFieldAttributePickerComponent (fs_serializer) {
Field_00:float;
Field_01:bool;
Field_02:float;
Field_03:float;
}
table PEAudioGeneratorComponent (fs_serializer) {
Field_00:string (required);
Field_01:string (required);
Field_02:byte; // unknown
Field_03:byte; // unknown
Field_04:byte; // unknown
Field_05:byte; // unknown
Field_06:float;
Field_07:uint;
Field_08:byte; // unknown -- probably an object[]? of some sort
Field_09:[float]; // not required
Field_10:byte; // unknown
Field_11:byte; // unknown
Field_12:string (required);
}
table TrinityCollisionEventTriggerComponent (fs_serializer) {
Field_00:string (required);
Field_01:string (required);
Field_02:byte; // unknown
Field_03:uint; // unknown
Field_04:string (required);
Field_05:string (required);
}
table PEFlatbuffersDataComponentInner (fs_serializer) {
Field_00:string (required);
Field_01:string (required);
}
table PEFlatbuffersDataComponent (fs_serializer) {
Field_00:string (required);
Field_01:[PEFlatbuffersDataComponentInner];
}
table TrinityObjectSwitcher (fs_serializer) {
Field_00:string (required);
Field_01:string (required);
}
table TrinityScriptComponent (fs_serializer) {
ScriptFileName:string (required);
ScriptFileNameHash:string (required);
Field_02:uint;
Field_03:uint;
Field_04:uint;
ScriptFileClass:string (required);
}
table TrinitySceneObjectPosition {
Field_00:PackedVec3f (required);
Field_01:PackedVec3f (required);

View File

@ -18,11 +18,11 @@ table TrinitySceneObjectTemplateEntry {
table TrinitySceneObjectTemplate (fs_serializer) {
ObjectTemplateName:string (required);
ObjectTemplateExtra:string (required);
ObjectTemplateExtra:string;
Field_02:uint;
Field_03:uint;
Objects:[TrinitySceneObjectTemplateEntry] (required);
Field_05:[uint] (required);
Field_05:[string] (required);
Field_06:ubyte;
}

View File

@ -0,0 +1,25 @@
namespace pkNX.Structures.FlatBuffers.SV;
attribute "fs_serializer";
struct EffectData {
Default:ubyte;
Gold:ubyte;
Rainbow:ubyte;
Fluctuation:ubyte;
}
struct ProductionPercent {
Default:[EffectData:5];
Special:[EffectData:5];
Bonus:[EffectData:5];
}
table EffectTable {
Param:ProductionPercent (required);
}
table EffectTableArray (fs_serializer) {
Table:[EffectTable] (required);
}
root_type EffectTableArray;

View File

@ -0,0 +1,28 @@
include "Shared/ItemID.fbs";
namespace pkNX.Structures.FlatBuffers.SV;
attribute "fs_serializer";
struct LotteryItemData {
ItemId:ItemID;
ProductionPriority:ubyte;
EmergePercent:ushort;
LotteryItemNumMin:ubyte;
LotteryItemNumMax:ubyte;
}
table LotteryItemDataWithFlag {
FlagName:string;
Value:LotteryItemData;
}
table ItemMachineItemTable {
Param:LotteryItemDataWithFlag (required);
}
table ItemMachineItemTableArray (fs_serializer) {
Table:[ItemMachineItemTable] (required);
}
root_type ItemMachineItemTableArray;

View File

@ -0,0 +1,22 @@
namespace pkNX.Structures.FlatBuffers.SV;
attribute "fs_serializer";
struct ItemMachineLotteryRateData {
DefaultRate:uint;
BonusRate:uint;
SpecialRate:uint;
}
struct ItemMachineLotteryRateArray {
Table:[ItemMachineLotteryRateData:3];
}
table ItemMachineLotteryTable {
Param:ItemMachineLotteryRateArray;
}
table ItemMachineLotteryTableArray (fs_serializer) {
Table:[ItemMachineLotteryTable] (required);
}
root_type ItemMachineLotteryTableArray;

View File

@ -0,0 +1,26 @@
include "Shared/ItemID.fbs";
namespace pkNX.Structures.FlatBuffers.SV;
attribute "fs_serializer";
struct SpecialItemData {
ItemId:ItemID;
EmergePercent:ushort;
Num:ubyte;
ProductionPriority:ubyte;
}
struct SpecialItemDataArray {
Table:[SpecialItemData:25];
}
table ItemMachineSpecialTable {
Param:SpecialItemDataArray (required);
}
table ItemMachineSpecialTableArray (fs_serializer) {
Table:[ItemMachineSpecialTable] (required);
}
root_type ItemMachineSpecialTableArray;

View File

@ -0,0 +1,27 @@
namespace pkNX.Structures.FlatBuffers.SV;
attribute "fs_serializer";
struct RankupBonusInfo {
BPDownRate:[ubyte:4];
MaterialPointUpRate:[ubyte:4];
}
struct NeedRankupInfo {
LotteryCount:[uint:3];
NeedBP:[uint:3];
}
table MaterialBaseParam {
NeedLotteryBP:uint;
MaterialPointPercent:ubyte;
NeedRankupInfos:NeedRankupInfo;
RankupBonusInfos:RankupBonusInfo;
FluctuationCount:ubyte;
}
table MaterialBaseParamArray (fs_serializer) {
Table:[MaterialBaseParam] (required);
}
root_type MaterialBaseParamArray;

View File

@ -78,6 +78,7 @@ table Waza {
Unused_69:bool;
Unused_70:bool;
Flag_CantUseTwice:bool;
Flag_NoSketch:bool; // new in SV DLC 2 (introduction of Smeargle)
}
table WazaTable (fs_serializer) {

View File

@ -0,0 +1,67 @@
namespace pkNX.Structures.FlatBuffers.SV;
attribute "fs_serializer";
attribute "fs_valueStruct";
enum ClubRewardType : byte
{
NONE = -1,
ITEM = 0,
ROTOM_DRESS = 1,
DRESSUP = 2,
EMOTE = 3,
}
enum ClubRoomCoach : byte
{
NONE = -1,
GYM_MUSHI = 0,
GYM_KUSA = 1,
GYM_DENKI = 2,
GYM_MIZU = 3,
GYM_NORMAL = 4,
GYM_GHOST = 5,
GYM_ESPER = 6,
GYM_KOORI = 7,
CHAMP_JIMEN = 8,
CHAMP_HAGANE = 9,
TEACHER_HEAD = 10,
TEACHER_BIOLOGY = 11,
TEACHER_HISTORY = 12,
TEACHER_MATH = 13,
TEACHER_LANGUAGE = 14,
TEACHER_ATHLETIC = 15,
TEACHER_ART = 16,
TEACHER_HOME = 17,
TEACHER_HEALTH = 18,
CHAMP_TOP = 19,
RIVAL = 20,
FRIEND = 21,
BOTAN = 22,
KING_HONOO = 23,
KING_HAGANE = 24,
KING_FAIRY = 25,
KING_DRAGON = 26,
SYSTER = 27,
BROTHER = 28,
BB_TEACHER_TOP = 29,
}
struct ClubNpcRewardInfo (fs_valueStruct) {
RewardType:ClubRewardType;
RewardId:int;
RewardIdF:int;
Count:int;
}
table ClubNpcRewardList {
Coach:ClubRoomCoach;
Reward_01:ClubNpcRewardInfo (required);
Reward_02:ClubNpcRewardInfo (required);
Reward_03:ClubNpcRewardInfo (required);
}
table ClubNpcRewardListArray (fs_serializer) {
Table:[ClubNpcRewardList] (required);
}
root_type ClubNpcRewardListArray;

View File

@ -0,0 +1,82 @@
namespace pkNX.Structures.FlatBuffers.SV;
attribute "fs_serializer";
enum ClubRoomBoardInfoType : byte
{
ReleaseThrowForm = 0,
ThrowForm1 = 1,
ThrowForm2 = 2,
ThrowForm3 = 3,
ChangeForm = 4,
ReleaseItemMachine = 5,
ReleasePhotoDeco = 6,
PhotoDeco1 = 7,
PhotoDeco2 = 8,
PhotoMachineLerning = 9,
PhotoScan = 10,
ReleaseRoomChange = 11,
RoomChange = 12,
RoomChange1 = 13,
RoomChange2 = 14,
RoomChange3 = 15,
ReleaseBgmChange = 16,
Bgm1 = 17,
Bgm2 = 18,
Bgm3 = 19,
Bgm4 = 20,
Bgm5 = 21,
DoomEncount1 = 22,
DoomEncount2 = 23,
DoomEncount3 = 24,
DoomEncount4 = 25,
BBSchoolHead = 26,
Max = 27,
}
enum ClubRoomBoardLockType : byte
{
None = 0,
Released = 1,
ClubAll = 2,
BgmKitakamiLock = 3,
All = 4,
Boss = 5,
}
enum ClubRoomBoardLockViewType : byte
{
None = 0,
Invisible = 1,
LockIcon = 2,
}
enum ClubType : byte
{
BASEBALL = 0,
PHOTO = 1,
SCIENCE = 2,
ART = 3,
MUSIC = 4,
DOME = 5,
BOSS = 6,
}
table ClubRoomBoardInfo {
InfoType:ClubRoomBoardInfoType;
NameLabel:string (required);
ClubType:ClubType;
LockType:ClubRoomBoardLockType;
LockedBoard:ClubRoomBoardInfoType;
LockViewType:ClubRoomBoardLockViewType;
Bp:int;
ContentsLabel:string (required);
RewardLabel:string (required);
Once:bool;
SortIndex:byte;
}
table ClubRoomBoardInfoArray (fs_serializer) {
Table:[ClubRoomBoardInfo] (required);
}
root_type ClubRoomBoardInfoArray;

View File

@ -0,0 +1,21 @@
namespace pkNX.Structures.FlatBuffers.SV;
attribute "fs_serializer";
table MetamonBlockInfo (fs_serializer) {
Fetch:float;
Release:float;
PopNumEasy:int;
GetMiniEasy:int;
GetMaxEasy:int;
PopNumNormal:int;
GetMiniNormal:int;
GetMaxNormal:int;
PopNumHard:int;
GetMiniHard:int;
GetMaxHard:int;
ChangeAnimationMin:float;
ChangeAnimationMax:float;
RareMetamonRate:int;
}
root_type MetamonBlockInfo;

View File

@ -0,0 +1,8 @@
namespace pkNX.Structures.FlatBuffers.SV;
enum MissionDifficulty : byte
{
Beginner = 0,
Intermediate = 1,
Advanced = 2,
}

View File

@ -0,0 +1,11 @@
include "MissionDifficulty.fbs";
namespace pkNX.Structures.FlatBuffers.SV;
attribute "fs_serializer";
table MissionDifficultyWeight (fs_serializer) {
Difficulty:MissionDifficulty;
Weight:byte;
}
root_type MissionDifficultyWeight;

View File

@ -0,0 +1,49 @@
include "MissionDifficulty.fbs";
include "MissionType.fbs";
namespace pkNX.Structures.FlatBuffers.SV;
attribute "fs_serializer";
enum MissionCategory : byte
{
None = 0,
Battle = 1,
Field = 2,
Camera = 3,
Max = 4,
}
enum MissionGrade : byte
{
Normal = 0,
Bonus = 1,
Team = 2,
}
enum MissionReleaseType : int
{
NONE = 0,
}
struct MissionInfo {
MissionCategory:MissionCategory;
MissionType:MissionType;
MissionId:int;
Goal:short;
RewardBp:int;
ReloadBp:int;
MissionReleaseType:MissionReleaseType;
MissionGrade:MissionGrade;
Difficulty:MissionDifficulty;
Weight:float;
}
table MissionInfos {
Mission_Info:MissionInfo (required);
}
table MissionInfosArray (fs_serializer) {
Table:[MissionInfos] (required);
}
root_type MissionInfosArray;

View File

@ -0,0 +1,16 @@
include "MissionType.fbs";
namespace pkNX.Structures.FlatBuffers.SV;
attribute "fs_serializer";
table MissionSettingsArray (fs_serializer) {
Table:[MissionSettings];
}
table MissionSettings {
MissionType:MissionType;
Variation:int;
Text:string;
}
root_type MissionSettingsArray;

View File

@ -0,0 +1,40 @@
namespace pkNX.Structures.FlatBuffers.SV;
enum MissionType : int
{
NONE = 0,
ITTEKOI = 1,
MOVE = 2,
TAKE_SELFIE = 3,
COOK_3STAR = 4,
COOK_4STAR = 5,
SANDWICH = 6,
INGREDIENT_COUNT = 7,
POKE_WASH = 8,
BACKATTACK = 9,
EGG_EVOLUTION = 10,
ITEM_GET = 11,
BATTLE_WON = 12,
BAD_STATUS = 13,
QUIZ = 14,
METAMON_BLOCK = 15,
RAID_STAR4 = 16,
RAID_STAR5 = 17,
RAID_STAR6 = 18,
TAKE_PICTURE_SIZE_POKE = 19,
TAKE_PICTURE_WILD_POKE = 20,
TAKE_PICTURE_POKE_TYPE = 21,
TAKE_PICTURE_POKE_FLY = 22,
TAKE_PICTURE_POKE_SWIM = 23,
TAKE_PICTURE_POKE_SLEEP = 24,
TAKE_PICTURE_WITH = 25,
TAKE_PICTURE_PLAYER_WITH_POKE_TYPE = 26,
RAID = 27,
EVOLUTION = 28,
MAKE_WAZAMACHINE = 29,
BATTLE_WITH_TERASTALED = 30,
USE_TERASTAL = 31,
GOT_POKEMON = 32,
TAKE_PICTURE_POKE_PLAYER_AREA = 33,
GOT_ANYPOKEMON = 34,
}

View File

@ -3,12 +3,12 @@ namespace pkNX.Structures;
public static partial class Legal
{
// todo sv
public const int MaxSpeciesID_9 = 1017;
public const int MaxMoveID_9 = (int)Move.MagicalTorque;
public const int MaxItemID_9 = 2400; // Yellow Dish
public const int MaxSpeciesID_9 = 1025;
public const int MaxMoveID_9 = (int)Move.MalignantChain;
public const int MaxItemID_9 = 2557; // Briar's Book
public const int MaxBallID_9 = (int)Ball.LAOrigin;
public const int MaxGameID_9 = (int)GameVersion.VL;
public const int MaxAbilityID_9 = 298; // Mycelium Might
public const int MaxAbilityID_9 = 310; // Poison Puppeteer
#region Inventory Pouch
internal static readonly ushort[] Pouch_Medicine_SV =

View File

@ -906,5 +906,24 @@ public enum Move
NoxiousTorque,
CombatTorque,
MagicalTorque,
BloodMoon,
MatchaGotcha,
SyrupBomb,
IvyCudgel,
ElectroShot,
TeraStarstorm,
FickleBeam,
BurningBulwark,
Thunderclap,
MightyCleave,
TachyonCutter,
HardPress,
DragonCheer,
AlluringVoice,
TemperFlare,
SupercellSlam,
PsychicNoise,
UpperHand,
MalignantChain,
MAX_COUNT,
}

View File

@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Description>Ensuring functionality works as intended</Description>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="System.Memory" Version="4.5.5" />
<PackageReference Include="xunit" Version="2.6.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\pkNX.Containers\pkNX.Containers.csproj" />
<ProjectReference Include="..\..\pkNX.Randomization\pkNX.Randomization.csproj" />
<ProjectReference Include="..\..\pkNX.Structures\pkNX.Structures.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,37 @@
using System;
using System.IO;
using pkNX.Structures.FlatBuffers.SV.Trinity;
using Xunit;
namespace pkNX.Tests;
public class SceneTests
{
[Fact]
public void TestSceneDump()
{
const string file = @"";
if (!File.Exists(file))
return;
SceneDumper.Dump(file);
}
[Fact]
public void TestFolderDump()
{
const string dir = @""; // input
SceneDumper.Bucket = @""; // output
SceneDumper.ThrowOnUnknownType = false;
var files = Directory.EnumerateFiles(dir, "*", SearchOption.AllDirectories);
foreach (var file in files)
{
if (!IsTrinityType(file))
continue;
try { SceneDumper.Dump(file); } catch { }
}
}
private static bool IsTrinityType(ReadOnlySpan<char> file) => file.Contains("trscn", StringComparison.Ordinal)
|| file.Contains("trsog", StringComparison.Ordinal);
}

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
@ -18,9 +18,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\pkNX.Containers\pkNX.Containers.csproj" />
<ProjectReference Include="..\pkNX.Randomization\pkNX.Randomization.csproj" />
<ProjectReference Include="..\pkNX.Structures\pkNX.Structures.csproj" />
<ProjectReference Include="..\..\pkNX.Structures.FlatBuffers.SV\pkNX.Structures.FlatBuffers.SV.Trinity\pkNX.Structures.FlatBuffers.SV.Trinity.csproj" />
</ItemGroup>
</Project>

View File

@ -442,6 +442,7 @@ static byte[] Write(IList<PersonalInfoMove> fbLearnset)
public void DumpMisc()
{
DumpItemMachine();
DumpBalloon();
DumpBattle();
DumpEncount();
@ -462,6 +463,7 @@ public void DumpMisc()
DumpNetBattle();
DumpTrades();
DumpShopDress();
DumpClubroom();
}
private void DumpGrow()
@ -543,14 +545,18 @@ private void DumpEncount()
Dump<PointDataArray, PointData>("world/data/encount/point_data/point_data/encount_data_atlantis.bfbs", z => z.Table);
Dump<PointDataArray, PointData>("world/data/encount/point_data/point_data/encount_data_100000.bfbs", z => z.Table);
Dump<PointDataArray, PointData>("world/data/encount/point_data/point_data/encount_data_su1.bfbs", z => z.Table);
Dump<PointDataArray, PointData>("world/data/encount/point_data/point_data/encount_data_su2.bfbs", z => z.Table);
Dump<OutbreakPointArray, OutbreakPointData>("world/data/encount/point_data/outbreak_point_data/outbreak_point_main.bfbs", z => z.Table);
Dump<OutbreakPointArray, OutbreakPointData>("world/data/encount/point_data/outbreak_point_data/outbreak_point_su1.bfbs", z => z.Table);
Dump<OutbreakPointArray, OutbreakPointData>("world/data/encount/point_data/outbreak_point_data/outbreak_point_su2.bfbs", z => z.Table);
Dump<EncountPokeDataArray, EncountPokeData>("world/data/encount/pokedata/pokedata/pokedata_array.bfbs", z => z.Table);
Dump<EncountPokeDataArray, EncountPokeData>("world/data/encount/pokedata/pokedata_su1/pokedata_su1_array.bfbs", z => z.Table);
Dump<EncountPokeDataArray, EncountPokeData>("world/data/encount/pokedata/pokedata_su2/pokedata_su2_array.bfbs", z => z.Table);
DumpJson<SettingData>("world/data/encount/setting/setting/data.bfbs");
Dump<RaidDifficultyLotteryTableArray, RaidDifficultyLotteryTable>("world/data/encount/setting/raid_difficulty_lottery/raid_difficulty_lottery_array.bfbs", z => z.Table);
DumpJson<RaidGemSetting>("world/data/encount/setting/raid_gem_setting/raid_gem_setting.bfbs");
DumpJson<RaidGemSetting>("world/data/encount/setting/raid_gem_setting/su1_raid_gem_setting.bfbs");
DumpJson<RaidGemSetting>("world/data/encount/setting/raid_gem_setting/su2_raid_gem_setting.bfbs");
DumpJson<OutbreakSetting>("world/data/encount/setting/outbreak_setting/data.bfbs");
Dump<FieldDungeonAreaArray, FieldDungeonArea>("world/data/field/area/field_dungeon_area/field_dungeon_area_array.bfbs", z => z.Table);
Dump<FieldInsideAreaArray, FieldInsideArea>("world/data/field/area/field_inside_area/field_inside_area_array.bfbs", z => z.Table);
@ -562,10 +568,20 @@ private void DumpEncount()
Dump<FieldLocationArray, FieldLocation>("world/data/field/area_su1/field_location_su1/field_location_su1_array.bfbs", z => z.Table);
Dump<FieldMainAreaArray, FieldMainArea>("world/data/field/area_su1/field_main_area_su1/field_main_area_su1_array.bfbs", z => z.Table);
Dump<FieldSubAreaArray, FieldSubArea>("world/data/field/area_su1/field_sub_area_su1/field_sub_area_su1_array.bfbs", z => z.Table);
Dump<FieldDungeonAreaArray, FieldDungeonArea>("world/data/field/area_su2/field_dungeon_area_su2/field_dungeon_area_su2_array.bfbs", z => z.Table);
Dump<FieldInsideAreaArray, FieldInsideArea>("world/data/field/area_su2/field_inside_area_su2/field_inside_area_su2_array.bfbs", z => z.Table);
//Dump<FieldLocationArray, FieldLocation>("world/data/field/area_su2/field_location_su2/field_location_su2_array.bfbs", z => z.Table);
Dump<FieldMainAreaArray, FieldMainArea>("world/data/field/area_su2/field_main_area_su2/field_main_area_su2_array.bfbs", z => z.Table);
Dump<FieldSubAreaArray, FieldSubArea>("world/data/field/area_su2/field_sub_area_su2/field_sub_area_su2_array.bfbs", z => z.Table);
const string gifts = "world/data/event/event_add_pokemon/eventAddPokemon/eventAddPokemon_array.bfbs";
Dump<EventAddPokemonArray, EventAddPokemon>(gifts, z => z.Table);
DumpSel<EventAddPokemonArray, PokeDataFull>(gifts, z => z.Table.Select(x => x.PokeData));
for (int i = 13; i <= 37; i++)
DumpJson<LegendPokeTable>($"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_{i:000}_legend_poke.bfbs");
Dump<ReleasePokeTableArray, ReleasePokeTable>("world/data/event/s2_sub_012_legend_poke/release_poke/release_poke_array.bfbs", z => z.Table);
}
private void DumpDLC()
@ -605,7 +621,11 @@ private void DumpJunk()
Dump<TipsDataArray, TipsData>("world/data/ui/tips/tips_data/tips_data_array.bfbs", z => z.Table);
Dump<NpcDestinationDataTableArray, NpcDestinationDataTable>("world/data/ui/ymap/yamp_npc_navigation_data/yamp_npc_navigation_data_array.bfbs", z => z.Table);
Dump<DestinationDataTableArray, DestinationDataTable>("world/data/ui/ymap/ymap_destination_data/ymap_destination_data_array.bfbs", z => z.Table);
Dump<DestinationDataTableArray, DestinationDataTable>("world/data/ui/ymap/ymap_destination_dlc1_data/ymap_destination_dlc1_data_array.bfbs", z => z.Table);
Dump<DestinationDataTableArray, DestinationDataTable>("world/data/ui/ymap/ymap_destination_dlc2_data/ymap_destination_dlc2_data_array.bfbs", z => z.Table);
Dump<PlaceNameDataTableArray, PlaceNameDataTable>("world/data/ui/ymap/ymap_place_name_data/ymap_place_name_data_array.bfbs", z => z.Table);
Dump<PlaceNameDataTableArray, PlaceNameDataTable>("world/data/ui/ymap/ymap_place_name_dlc1_data/ymap_place_name_dlc1_data_array.bfbs", z => z.Table);
Dump<PlaceNameDataTableArray, PlaceNameDataTable>("world/data/ui/ymap/ymap_place_name_dlc2_data/ymap_place_name_dlc2_data_array.bfbs", z => z.Table);
}
public void DumpBalloon()
@ -670,8 +690,16 @@ public void DumpRaid()
"world/data/raid/su1_raid_enemy_05/su1_raid_enemy_05_array.bfbs",
"world/data/raid/su1_raid_enemy_06/su1_raid_enemy_06_array.bfbs",
};
foreach (var f in mainRaids.Concat(su1Raids))
var su2Raids = new[]
{
"world/data/raid/su2_raid_enemy_01/su2_raid_enemy_01_array.bfbs",
"world/data/raid/su2_raid_enemy_02/su2_raid_enemy_02_array.bfbs",
"world/data/raid/su2_raid_enemy_03/su2_raid_enemy_03_array.bfbs",
"world/data/raid/su2_raid_enemy_04/su2_raid_enemy_04_array.bfbs",
"world/data/raid/su2_raid_enemy_05/su2_raid_enemy_05_array.bfbs",
"world/data/raid/su2_raid_enemy_06/su2_raid_enemy_06_array.bfbs",
};
foreach (var f in (string[])[.. mainRaids, .. su1Raids, .. su2Raids])
{
Dump<RaidEnemyTableArray, RaidEnemyTable>(f, z => z.Table);
static IEnumerable<PokeDataBattle> sel(RaidEnemyTableArray z) => z.Table.Select(x => x.Info.BossPokePara);
@ -681,6 +709,7 @@ public void DumpRaid()
var outPath = GetPath("pkhex");
TeraRaidRipper.DumpRaids(ROM, mainRaids, outPath, "raidTotal.txt", "encounter_gem_paldea.pkl");
TeraRaidRipper.DumpRaids(ROM, su1Raids, outPath, "raidTotalKitakami.txt", "encounter_gem_kitakami.pkl");
TeraRaidRipper.DumpRaids(ROM, su2Raids, outPath, "raidTotalBlueberry.txt", "encounter_gem_blueberry.pkl");
}
public void DumpMoves()
@ -697,16 +726,27 @@ public void DumpMoves()
File.WriteAllText(Path.Combine(outPath, "move_type.txt"), string.Join(',', types));
}
private void DumpItemMachine()
{
Dump<ItemMachineItemTableArray, ItemMachineItemTable>("world/data/ui/item_machine/item_table/item_table_array.bfbs", z => z.Table);
Dump<ItemMachineLotteryTableArray, ItemMachineLotteryTable>("world/data/ui/item_machine/lottery_rate/lottery_rate_array.bfbs", z => z.Table);
Dump<ItemMachineSpecialTableArray, ItemMachineSpecialTable>("world/data/ui/item_machine/special_item_table/special_item_table_array.bfbs", z => z.Table);
Dump<EffectTableArray, EffectTable>("world/data/ui/item_machine/effect_table/effect_table_array.bfbs", z => z.Table);
Dump<MaterialBaseParamArray, MaterialBaseParam>("world/data/ui/item_machine/base_param/base_param_array.bfbs", z => z.Table);
}
private void DumpItems()
{
Dump<RummagingItemDataTableArray, RummagingItemDataTable>("world/data/item/rummagingItemDataTable/rummagingItemDataTable_array.bfbs", z => z.Table);
Dump<ItemPointTypeBiomeTableArray, ItemPointTypeBiomeTable>("world/data/item/itemPointTypeBiomeTable/itemPointTypeBiomeTable_array.bfbs", z => z.Table);
Dump<HiddenItemBiomeTableArray, HiddenItemBiomeTable>("world/data/item/hiddenItemBiomeTable/hiddenItemBiomeTable_array.bfbs", z => z.Table);
Dump<HiddenItemBiomeTableArray, HiddenItemBiomeTable>("world/data/item/hiddenItemBiomeTable_su1/hiddenItemBiomeTable_su1_array.bfbs", z => z.Table);
Dump<HiddenItemBiomeTableArray, HiddenItemBiomeTable>("world/data/item/hiddenItemBiomeTable_su2/hiddenItemBiomeTable_su2_array.bfbs", z => z.Table);
Dump<DropItemDataArray, DropItemData>("world/data/item/dropitemdata/dropitemdata_array.bfbs", z => z.Table);
Dump<ItemDataArray, ItemData>("world/data/item/itemdata/itemdata_array.bfbs", z => z.Table);
Dump<HiddenItemDataTableArray, HiddenItemDataTable>("world/data/item/hiddenItemDataTable/hiddenItemDataTable_array.bfbs", z => z.Table);
Dump<HiddenItemDataTableArray, HiddenItemDataTable>("world/data/item/hiddenItemDataTable_su1/hiddenItemDataTable_su1_array.bfbs", z => z.Table);
Dump<HiddenItemDataTableArray, HiddenItemDataTable>("world/data/item/hiddenItemDataTable_su2/hiddenItemDataTable_su2_array.bfbs", z => z.Table);
Dump<MonohiroiItemArray, MonohiroiItem>("world/data/item/monohiroiItemData/monohiroiItemData_array.bfbs", z => z.Table);
}
@ -755,15 +795,19 @@ private void DumpPokeDex()
{
Dump<BlacklistArray, Blacklist>("world/data/ui/pokedex/blacklist/blacklist_array.bfbs", z => z.Table);
Dump<BlacklistArray, Blacklist>("world/data/ui/pokedex/blacklist_dlc1/blacklist_dlc1_array.bfbs", z => z.Table);
Dump<BlacklistArray, Blacklist>("world/data/ui/pokedex/blacklist_dlc2/blacklist_dlc2_array.bfbs", z => z.Table);
Dump<MemoPokeTableArray, MemoPokeTable>("world/data/ui/pokedex/memo_poke_data/memo_poke_data_array.bfbs", z => z.Table);
Dump<MemoPokeTableArray, MemoPokeTable>("world/data/ui/pokedex/memo_poke_data_dlc1/memo_poke_data_dlc1_array.bfbs", z => z.Table);
Dump<MemoPokeTableArray, MemoPokeTable>("world/data/ui/pokedex/memo_poke_data_dlc2/memo_poke_data_dlc2_array.bfbs", z => z.Table);
Dump<RewardDataArray, RewardData>("world/data/ui/pokedex/reward_data/reward_data_array.bfbs", z => z.Table);
Dump<RewardDataArray, RewardData>("world/data/ui/pokedex/reward_data_dlc1/reward_data_dlc1_array.bfbs", z => z.Table);
Dump<RewardDataArray, RewardData>("world/data/ui/pokedex/reward_data_dlc2/reward_data_dlc2_array.bfbs", z => z.Table);
DumpX<DistributionRootArray, DistributionRoot, DistributionData>("world/data/ui/pokedex/distribution_data/distribution_data_array.bfbs", z => z.Table, z => z.Table);
DumpX<DistributionRootArray, DistributionRoot, DistributionData>("world/data/ui/pokedex/distribution_data_dlc1/distribution_data_dlc1_array.bfbs", z => z.Table, z => z.Table);
DumpX<DistributionRootArray, DistributionRoot, DistributionData>("world/data/ui/pokedex/distribution_data_dlc2/distribution_data_dlc2_array.bfbs", z => z.Table, z => z.Table);
}
private void DumpUI()
@ -878,12 +922,36 @@ private void DumpTrades()
z => z.Table.Select(x => x.PokeData));
}
private void DumpClubroom()
{
Dump<MissionInfosArray, MissionInfos>("world/data/club/MissionInfo/MissionInfo_array.bfbs", z => z.Table);
Dump<MissionSettingsArray, MissionSettings>("world/data/club/MissionSettings/MissionSettings_array.bfbs", z => z.Table);
Dump<ClubRoomBoardInfoArray, ClubRoomBoardInfo>("world/data/club/ClubRoomBoardInfo/ClubRoomBoardInfo_array.bfbs", z => z.Table);
Dump<ClubNpcRewardListArray, ClubNpcRewardList>("world/data/club/ClubNpcRewardList/ClubNpcRewardList_array.bfbs", z => z.Table);
DumpJson<MetamonBlockInfo>("world/data/club/MetamonBlockInfo/metamonBlockInfoData.bfbs");
}
private void Dump<TTable, TEntry>(ulong hash, Func<TTable, IList<TEntry>> sel)
where TTable : class, IFlatBufferSerializable<TTable>
where TEntry : notnull
{
var flat = Get<TTable>(hash);
var path = GetPath(hash.ToString("X16"));
Dump(sel, flat, path);
}
private void Dump<TTable, TEntry>(string f, Func<TTable, IList<TEntry>> sel)
where TTable : class, IFlatBufferSerializable<TTable>
where TEntry : notnull
{
var flat = Get<TTable>(f);
var path = GetPath("raw", f.Replace('/', Path.DirectorySeparatorChar));
Dump(sel, flat, path);
}
private static void Dump<TTable, TEntry>(Func<TTable, IList<TEntry>> sel, TTable flat, string path)
where TTable : class, IFlatBufferSerializable<TTable> where TEntry : notnull
{
DumpJson(flat, path);
var table = sel(flat);
var dump = TableUtil.GetTable(table);
@ -892,23 +960,38 @@ private void DumpTrades()
File.WriteAllText(fileName, dump);
}
private TTable Get<TTable>(ulong hash)
where TTable : class, IFlatBufferSerializable<TTable>
{
var bin = ROM.GetPackedFile(hash);
return Get<TTable>(bin);
}
private TTable Get<TTable>(string f)
where TTable : class, IFlatBufferSerializable<TTable>
{
var bin = ROM.GetPackedFile(f.Replace("bfbs", "bin"));
return FlatBufferConverter.DeserializeFrom<TTable>(bin);
return Get<TTable>(bin);
}
private static TTable Get<TTable>(Memory<byte> bin) where TTable : class, IFlatBufferSerializable<TTable> => FlatBufferConverter.DeserializeFrom<TTable>(bin);
private void DumpSel<TTable, TEntry>(string f, Func<TTable, IEnumerable<TEntry>> sel, string prefix = "sel")
where TTable : class, IFlatBufferSerializable<TTable>
where TEntry : notnull
{
var bin = ROM.GetPackedFile(f.Replace("bfbs", "bin"));
var path = GetPath("raw", f.Replace('/', Path.DirectorySeparatorChar));
DumpSel(sel, prefix, bin, path);
}
private static void DumpSel<TTable, TEntry>(Func<TTable, IEnumerable<TEntry>> sel, string prefix, Memory<byte> bin, string path)
where TTable : class, IFlatBufferSerializable<TTable> where TEntry : notnull
{
var flat = FlatBufferConverter.DeserializeFrom<TTable>(bin);
var table = sel(flat);
var dump = TableUtil.GetTable(table);
var path = GetPath("raw", f.Replace('/', Path.DirectorySeparatorChar));
var fileName = Path.ChangeExtension(path, $".{prefix}.txt");
File.WriteAllText(fileName, dump);
}
@ -958,6 +1041,12 @@ public void DumpSpecific()
{
var files = new[]
{
"world/data/ui/item_machine/item_table/item_table_array.bfbs",
"world/data/ui/item_machine/lottery_rate/lottery_rate_array.bfbs",
"world/data/ui/item_machine/special_item_table/special_item_table_array.bfbs",
"world/data/ui/item_machine/effect_table/effect_table_array.bfbs",
"world/data/ui/item_machine/base_param/base_param_array.bfbs",
"world/data/encount/delivery_outbreak/delivery_outbreak_pokedata/delivery_outbreak_pokedata_array.bfbs",
"world/data/encount/delivery_outbreak/delivery_outbreak_zone_main/delivery_outbreak_zone_main_array.bfbs",
"world/data/encount/delivery_outbreak/delivery_outbreak_zone_su1/delivery_outbreak_zone_su1_array.bfbs",
@ -1009,16 +1098,21 @@ public void DumpSpecific()
"world/data/encount/point_data/point_data/encount_data_atlantis.bfbs",
"world/data/encount/point_data/point_data/encount_data_100000.bfbs",
"world/data/encount/point_data/point_data/encount_data_su1.bfbs",
"world/data/encount/point_data/point_data/encount_data_su2.bfbs",
"world/data/encount/point_data/outbreak_point_data/outbreak_point_main.bfbs",
"world/data/encount/point_data/outbreak_point_data/outbreak_point_su1.bfbs",
"world/data/encount/point_data/outbreak_point_data/outbreak_point_su2.bfbs",
"world/data/encount/pokedata/pokedata/pokedata_array.bfbs",
"world/data/encount/pokedata/pokedata_su1/pokedata_su1_array.bfbs",
"world/data/encount/pokedata/pokedata_su2/pokedata_su2_array.bfbs",
"world/data/encount/setting/setting/data.bfbs",
"world/data/encount/setting/raid_difficulty_lottery/raid_difficulty_lottery_array.bfbs",
"world/data/encount/setting/raid_gem_setting/raid_gem_setting.bfbs",
"world/data/encount/setting/raid_gem_setting/su1_raid_gem_setting.bfbs",
"world/data/encount/setting/raid_gem_setting/su2_raid_gem_setting.bfbs",
"world/data/encount/setting/outbreak_setting/data.bfbs",
"world/data/event/treeshake/treeshake_pokemon/treeshake_pokemon_array.bfbs",
"world/data/event/npc_management/npc_management_s1_sub_003_always/npc_management_s1_sub_003_always_array.bfbs",
// Field
"world/data/field/area/field_dungeon_area/field_dungeon_area_array.bfbs",
"world/data/field/area/field_inside_area/field_inside_area_array.bfbs",
@ -1030,6 +1124,11 @@ public void DumpSpecific()
"world/data/field/area_su1/field_location_su1/field_location_su1_array.bfbs",
"world/data/field/area_su1/field_main_area_su1/field_main_area_su1_array.bfbs",
"world/data/field/area_su1/field_sub_area_su1/field_sub_area_su1_array.bfbs",
"world/data/field/area_su2/field_dungeon_area_su2/field_dungeon_area_su2_array.bfbs",
"world/data/field/area_su2/field_inside_area_su2/field_inside_area_su2_array.bfbs",
//"world/data/field/area_su2/field_location_su2/field_location_su2_array.bfbs", DOES NOT EXIST.
"world/data/field/area_su2/field_main_area_su2/field_main_area_su2_array.bfbs",
"world/data/field/area_su2/field_sub_area_su2/field_sub_area_su2_array.bfbs",
"world/data/field/fixed_symbol/fixed_symbol_table/fixed_symbol_table_array.bfbs",
// Event Trade
"world/data/event/eventTradeList/eventTradeList_array.bfbs",
@ -1169,11 +1268,71 @@ public void DumpSpecific()
"world/data/ui/tips/tips_data/tips_data_array.bfbs",
"world/data/ui/ymap/yamp_npc_navigation_data/yamp_npc_navigation_data_array.bfbs",
"world/data/ui/ymap/ymap_destination_data/ymap_destination_data_array.bfbs",
"world/data/ui/ymap/ymap_destination_dlc1_data/ymap_destination_dlc1_data_array.bfbs",
"world/data/ui/ymap/ymap_destination_dlc2_data/ymap_destination_dlc2_data_array.bfbs",
"world/data/ui/ymap/ymap_place_name_data/ymap_place_name_data_array.bfbs",
"world/data/ui/schoolmap/schoolmap_data/schoolmap_data_array.bfbs",
"world/data/ui/shop/friendlyshop/friendlyshop_data/friendlyshop_data_array.bfbs",
"world/data/ui/shop/friendlyshop/friendlyshop_lineup_data/friendlyshop_lineup_data_array.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_013_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_014_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_015_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_016_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_017_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_018_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_019_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_020_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_021_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_022_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_023_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_024_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_025_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_026_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_027_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_028_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_029_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_030_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_031_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_032_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_033_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_034_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_035_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_036_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/legend_poke/s2_sub_037_legend_poke.bfbs",
"world/data/event/s2_sub_012_legend_poke/release_poke/release_poke_array.bfbs",
"world/data/event/sub_012/sub_012_reward/sub_012_reward_array.bfbs",
"world/data/event/s2_sub_012_legend_poke/release_config/default.bfbs",
"world/data/event/s1_sub_013/s1_sub_013_chair_reward/s1_sub_013_chair_reward_array.bfbs",
"world/data/event/s1_sub_013/s1_sub_013_complete_reward/s1_sub_013_complete_reward_array.bfbs",
"world/data/event/s1_sub_013/s1_sub_013_food_reward/s1_sub_013_food_reward_array.bfbs",
"world/data/bb_challenge/fairy_challenge_questionInfos/fairy_challenge_questionInfos_array.bfbs",
"world/data/bb_challenge/fairy_challenge_targetInfos/fairy_challenge_targetInfos_array.bfbs",
"world/data/bb_challenge/hagane_challenge_course/hagane_challenge_course_array.bfbs",
"world/data/bb_challenge/honoo_challenge_npc/honoo_challenge_npc_array.bfbs",
"world/data/ui/schoolmap/bb_schoolmap_data/bb_schoolmap_data_array.bfbs",
"world/data/club/ClubNpcRandomRewardList/ClubNpcRandomRewardList_array.bfbs",
"world/data/club/ClubNpcRewardList/ClubNpcRewardList_array.bfbs",
"world/data/club/ClubNpcTradeList/ClubNpcTradeList_array.bfbs",
"world/data/club/ClubPairNpcFaceInfo/ClubPairNpcFaceInfo_array.bfbs",
"world/data/club/ClubRoomNpcPairTable/ClubRoomNpcPairTable_array.bfbs",
"world/data/club/MetamonBlockInfo/metamonBlockInfoData.bfbs",
"world/data/club/MissionInfo/MissionInfo_array.bfbs",
"world/data/club/Quiz/quiz_poke_data_easy/quiz_poke_data_easy_array.bfbs",
"world/data/club/Quiz/quiz_poke_data_normal/quiz_poke_data_normal_array.bfbs",
"world/data/club/Quiz/quiz_poke_data_hard/quiz_poke_data_hard_array.bfbs",
"world/data/ui/clubroom_bgm_select/clubroom_bgm_select_data/clubroom_bgm_select_data_array.bfbs",
"world/data/club/ClubRoomBoardInfo/ClubRoomBoardInfo_array.bfbs",
"world/data/club/MissionSettings/MissionSettings_array.bfbs",
"world/data/field/synchro/synchro_data/synchro_data_array.bfbs",
"world/data/event/field_npc/event_field_npc_message/event_field_npc_message_condition_flagwork/event_field_npc_message_condition_flagwork_array.bfbs",
};
foreach (var f in files)
{

View File

@ -39,8 +39,10 @@ public class EncounterDumperSV
var mlEncPoints = FlatBufferConverter.DeserializeFrom<PointDataArray>(ROM.GetPackedFile("world/data/encount/point_data/point_data/encount_data_100000.bin"));
var alEncPoints = FlatBufferConverter.DeserializeFrom<PointDataArray>(ROM.GetPackedFile("world/data/encount/point_data/point_data/encount_data_atlantis.bin"));
var su1EncPoints = FlatBufferConverter.DeserializeFrom<PointDataArray>(ROM.GetPackedFile("world/data/encount/point_data/point_data/encount_data_su1.bin"));
var su2EncPoints = FlatBufferConverter.DeserializeFrom<PointDataArray>(ROM.GetPackedFile("world/data/encount/point_data/point_data/encount_data_su2.bin"));
var pokeDataMain = FlatBufferConverter.DeserializeFrom<EncountPokeDataArray>(ROM.GetPackedFile("world/data/encount/pokedata/pokedata/pokedata_array.bin"));
var pokeDataSu1 = FlatBufferConverter.DeserializeFrom<EncountPokeDataArray>(ROM.GetPackedFile("world/data/encount/pokedata/pokedata_su1/pokedata_su1_array.bin"));
var pokeDataSu2 = FlatBufferConverter.DeserializeFrom<EncountPokeDataArray>(ROM.GetPackedFile("world/data/encount/pokedata/pokedata_su2/pokedata_su2_array.bin"));
var db = new LocationDatabase();
@ -48,10 +50,12 @@ public class EncounterDumperSV
var pointMain = ReformatPoints(mlEncPoints);
var pointAtlantis = ReformatPoints(alEncPoints);
var pointSu1 = ReformatPoints(su1EncPoints);
var pointSu2 = ReformatPoints(su2EncPoints);
// Process all field indices
ProcessAreas(PaldeaFieldIndex.Paldea);
ProcessAreas(PaldeaFieldIndex.Kitakami);
ProcessAreas(PaldeaFieldIndex.Terarium);
// Each area and their local / crossover points have been aggregated.
// Integrate the points' slots into a single list, and consolidate entries with same level ranges to as few objects as possible.
@ -89,14 +93,14 @@ public class EncounterDumperSV
foreach (var (game, gamePoints) in new[] { ("sl", fsym.scarletPoints), ("vl", fsym.violetPoints) })
{
using var gw = File.CreateText(Path.Combine(path, $"titan_fixed_{game}.txt"));
foreach (var fieldIndex in new[] { PaldeaFieldIndex.Paldea, PaldeaFieldIndex.Kitakami })
foreach (var fieldIndex in new[] { PaldeaFieldIndex.Paldea, PaldeaFieldIndex.Kitakami, PaldeaFieldIndex.Terarium })
{
var areaNames = scene.AreaNames[(int)fieldIndex];
var areas = scene.AreaInfos[(int)fieldIndex];
var atlantis = scene.IsAtlantis[(int)fieldIndex];
var allPoints = gamePoints[(int)fieldIndex];
if (fieldIndex == PaldeaFieldIndex.Kitakami)
if (fieldIndex == PaldeaFieldIndex.Kitakami || fieldIndex == PaldeaFieldIndex.Terarium)
{
areas = areas.Where(z => z.Value.AdjustEncLv != 0)
.ToDictionary(z => z.Key, z => z.Value);
@ -346,6 +350,7 @@ bool FindArea(AreaType type)
{
PaldeaFieldIndex.Paldea => isAtlantis ? pointAtlantis : pointMain,
PaldeaFieldIndex.Kitakami => pointSu1,
PaldeaFieldIndex.Terarium => pointSu2,
_ => throw new ArgumentException($"Could not handle {fieldIndex}"),
};
@ -353,6 +358,7 @@ bool FindArea(AreaType type)
{
PaldeaFieldIndex.Paldea => pokeDataMain,
PaldeaFieldIndex.Kitakami => pokeDataSu1,
PaldeaFieldIndex.Terarium => pokeDataSu2,
_ => throw new ArgumentException($"Could not handle {fieldIndex}"),
};
@ -365,6 +371,11 @@ void ProcessAreas(PaldeaFieldIndex fieldIndex)
// 4 - Consolidate the encounters from both point lists.
// Just compute everything (big memory!) then crunch it all down.
if (fieldIndex == PaldeaFieldIndex.Terarium)
{
var z = -1;
}
// Fill the point lists for each area, then spawn everything into those points.
var areaNames = scene.AreaNames[(int)fieldIndex];
var areas = scene.AreaInfos[(int)fieldIndex];
@ -387,7 +398,7 @@ void ProcessAreas(PaldeaFieldIndex fieldIndex)
// Locations that do not spawn encounters can still have crossovers bleed into them.
// We'll have empty local encounter lists for them.
var storage = db.Get(placeNameMap[placeName].Index, fieldIndex, areaName, areaInfo);
var storage = db.Get(placeNameMap[placeName].Index, fieldIndex, areaName, areas[areaName]);
if (areaInfo.Tag is AreaTag.NG_Encount or AreaTag.NG_All)
continue;

View File

@ -7,7 +7,7 @@ namespace pkNX.Structures.FlatBuffers;
public class PaldeaFieldModel
{
private const int MapCount = 2;
private const int MapCount = 3;
public IList<FieldMainArea>[] MainAreas { get; } = new IList<FieldMainArea>[MapCount];
public IList<FieldSubArea>[] SubAreas { get; } = new IList<FieldSubArea>[MapCount];
public IList<FieldInsideArea>[] InsideAreas { get; } = new IList<FieldInsideArea>[MapCount];
@ -27,6 +27,12 @@ public PaldeaFieldModel(IFileInternal ROM)
InsideAreas[(int)PaldeaFieldIndex.Kitakami] = FlatBufferConverter.DeserializeFrom<FieldInsideAreaArray>(ROM.GetPackedFile("world/data/field/area_su1/field_inside_area_su1/field_inside_area_su1_array.bin")).Table;
DungeonAreas[(int)PaldeaFieldIndex.Kitakami] = FlatBufferConverter.DeserializeFrom<FieldDungeonAreaArray>(ROM.GetPackedFile("world/data/field/area_su1/field_dungeon_area_su1/field_dungeon_area_su1_array.bin")).Table;
FieldLocations[(int)PaldeaFieldIndex.Kitakami] = FlatBufferConverter.DeserializeFrom<FieldLocationArray>(ROM.GetPackedFile("world/data/field/area_su1/field_location_su1/field_location_su1_array.bin")).Table;
MainAreas[(int)PaldeaFieldIndex.Terarium] = FlatBufferConverter.DeserializeFrom<FieldMainAreaArray>(ROM.GetPackedFile("world/data/field/area_su2/field_main_area_su2/field_main_area_su2_array.bin")).Table;
SubAreas[(int)PaldeaFieldIndex.Terarium] = FlatBufferConverter.DeserializeFrom<FieldSubAreaArray>(ROM.GetPackedFile("world/data/field/area_su2/field_sub_area_su2/field_sub_area_su2_array.bin")).Table;
InsideAreas[(int)PaldeaFieldIndex.Terarium] = FlatBufferConverter.DeserializeFrom<FieldInsideAreaArray>(ROM.GetPackedFile("world/data/field/area_su2/field_inside_area_su2/field_inside_area_su2_array.bin")).Table;
DungeonAreas[(int)PaldeaFieldIndex.Terarium] = FlatBufferConverter.DeserializeFrom<FieldDungeonAreaArray>(ROM.GetPackedFile("world/data/field/area_su2/field_dungeon_area_su2/field_dungeon_area_su2_array.bin")).Table;
FieldLocations[(int)PaldeaFieldIndex.Terarium] = new List<FieldLocation>(); //FlatBufferConverter.DeserializeFrom<FieldLocationArray>(ROM.GetPackedFile("world/data/field/area_su2/field_location_su2/field_location_su2_array.bin")).Table;
}
public AreaInfo FindAreaInfo(PaldeaFieldIndex index, string name)
@ -64,5 +70,5 @@ public enum PaldeaFieldIndex
{
Paldea = 0,
Kitakami = 1,
Blueberry = 2,
Terarium = 2,
}

View File

@ -8,8 +8,8 @@ namespace pkNX.WinForms;
public class PaldeaFixedSymbolModel
{
public readonly List<PaldeaFixedSymbolPoint>[] scarletPoints = new List<PaldeaFixedSymbolPoint>[] { new(), new() };
public readonly List<PaldeaFixedSymbolPoint>[] violetPoints = new List<PaldeaFixedSymbolPoint>[] { new(), new() };
public readonly List<PaldeaFixedSymbolPoint>[] scarletPoints = new List<PaldeaFixedSymbolPoint>[] { new(), new(), new() };
public readonly List<PaldeaFixedSymbolPoint>[] violetPoints = new List<PaldeaFixedSymbolPoint>[] { new(), new(), new() };
public PaldeaFixedSymbolModel(IFileInternal ROM)
{
@ -32,6 +32,16 @@ public PaldeaFixedSymbolModel(IFileInternal ROM)
scarletPoints[(int)PaldeaFieldIndex.Kitakami].AddRange(GetObjectTemplateSymbolPoints(k0));
violetPoints[(int)PaldeaFieldIndex.Kitakami].AddRange(GetObjectTemplateSymbolPoints(k1));
// Terarium
var b0Data = ROM.GetPackedFile("world/scene/parts/field/streaming_event/su2_world_fixed_placement_symbol_/su2_world_fixed_placement_symbol_0.trscn");
var b1Data = ROM.GetPackedFile("world/scene/parts/field/streaming_event/su2_world_fixed_placement_symbol_/su2_world_fixed_placement_symbol_1.trscn");
var b0 = FlatBufferConverter.DeserializeFrom<TrinitySceneObjectTemplate>(b0Data);
var b1 = FlatBufferConverter.DeserializeFrom<TrinitySceneObjectTemplate>(b1Data);
scarletPoints[(int)PaldeaFieldIndex.Terarium].AddRange(GetObjectTemplateSymbolPoints(b0));
violetPoints[(int)PaldeaFieldIndex.Terarium].AddRange(GetObjectTemplateSymbolPoints(b1));
}
private IEnumerable<PaldeaFixedSymbolPoint> GetObjectTemplateSymbolPoints(TrinitySceneObjectTemplate template)

View File

@ -11,11 +11,11 @@ namespace pkNX.Structures.FlatBuffers;
public class PaldeaSceneModel
{
public List<string>[] AreaNames { get; } = { new(), new() };
public Dictionary<string, AreaInfo>[] AreaInfos { get; } = { new(), new() };
public Dictionary<string, HavokCollision.AABBTree>[] AreaCollisionTrees { get; } = { new(), new() };
public Dictionary<string, BoxCollision9>[] AreaCollisionBoxes { get; } = { new(), new() };
public Dictionary<string, bool>[] IsAtlantis { get; } = { new(), new() };
public List<string>[] AreaNames { get; } = { new(), new(), new() };
public Dictionary<string, AreaInfo>[] AreaInfos { get; } = { new(), new(), new() };
public Dictionary<string, HavokCollision.AABBTree>[] AreaCollisionTrees { get; } = { new(), new(), new() };
public Dictionary<string, BoxCollision9>[] AreaCollisionBoxes { get; } = { new(), new(), new() };
public Dictionary<string, bool>[] IsAtlantis { get; } = { new(), new(), new() };
public PaldeaSceneModel(IFileInternal ROM, PaldeaFieldModel field)
{
@ -30,12 +30,19 @@ public PaldeaSceneModel(IFileInternal ROM, PaldeaFieldModel field)
foreach (var obj in area_collision.Objects.Concat(a_w23_field_area_col.Objects))
AddIfAppropriate(ROM, field, PaldeaFieldIndex.Paldea, a_w23_field_area_col.Objects, obj);
// TODO: is this _0 or _1? Identical? Name?
var area_collision_su1 = FlatBufferConverter.DeserializeFrom<TrinitySceneObjectTemplate>(ROM.GetPackedFile(0x441FE0A17C85BEAA));
// NOTE: Safe to only use _0 because _1 is identical.
var area_collision_su1 = FlatBufferConverter.DeserializeFrom<TrinitySceneObjectTemplate>(ROM.GetPackedFile("world/scene/parts/field/main/field_1/field_main/resident_event/resident_area_collision_/resident_area_collision_0.trscn"));
Debug.Assert(area_collision_su1.ObjectTemplateName == "resident_area_collision");
foreach (var obj in area_collision_su1.Objects)
AddIfAppropriate(ROM, field, PaldeaFieldIndex.Kitakami, new List<TrinitySceneObjectTemplateEntry>(), obj);
// NOTE: Safe to only use _0 because _1 is identical.
var area_collision_su2 = FlatBufferConverter.DeserializeFrom<TrinitySceneObjectTemplate>(ROM.GetPackedFile("world/scene/parts/field/main/field_2/field_main/resident_event/resident_area_collision_/resident_area_collision_0.trscn"));
Debug.Assert(area_collision_su2.ObjectTemplateName == "resident_area_collision");
foreach (var obj in area_collision_su2.Objects)
AddIfAppropriate(ROM, field, PaldeaFieldIndex.Terarium, new List<TrinitySceneObjectTemplateEntry>(), obj);
}
private void AddIfAppropriate(IFileInternal ROM, PaldeaFieldModel field, PaldeaFieldIndex index, IList<TrinitySceneObjectTemplateEntry> atlantis, TrinitySceneObjectTemplateEntry obj)

View File

@ -20,7 +20,7 @@ public MapViewer9(GameManagerSV rom)
InitializeComponent();
Loading = true;
CB_Field.Items.AddRange(new[] { "Paldea", "Kitakami" });
CB_Field.Items.AddRange(new[] { "Paldea", "Kitakami", "Terarium" });
Loading = false;
CB_Field.SelectedIndex = 0;
}
@ -29,6 +29,7 @@ public MapViewer9(GameManagerSV rom)
{
0 => 5000,
1 => 2000,
2 => 2000,
_ => throw new ArgumentOutOfRangeException(nameof(FieldIndex)),
};
@ -36,6 +37,7 @@ public MapViewer9(GameManagerSV rom)
{
0 => 5000,
1 => 2000,
2 => 2000,
_ => throw new ArgumentOutOfRangeException(nameof(FieldIndex)),
};
@ -43,6 +45,7 @@ public MapViewer9(GameManagerSV rom)
{
0 => 5500,
1 => 2000,
2 => 2000,
_ => throw new ArgumentOutOfRangeException(nameof(FieldIndex)),
};
@ -71,6 +74,7 @@ private void CB_Map_SelectedIndexChanged(object sender, EventArgs e)
{
0 => @"map_sv\paldea.png",
1 => @"map_sv\kitakami.png",
2 => @"map_sv\terarium.png",
_ => throw new ArgumentException($"Unknown field {field}"),
};

View File

@ -10,16 +10,16 @@ namespace pkNX.WinForms.Subforms
{
public class PaldeaMap
{
public readonly List<string>[] AreaNames = { new(), new() };
private readonly Dictionary<string, AreaDef9>[] Areas = { new(), new() };
public readonly Dictionary<string, HavokCollision.AABBTree>[] AreaCollisionTrees = { new(), new() };
public readonly Dictionary<string, BoxCollision9>[] AreaCollisionBoxes = { new(), new() };
public readonly List<string>[] AreaNames = { new(), new(), new() };
private readonly Dictionary<string, AreaDef9>[] Areas = { new(), new(), new() };
public readonly Dictionary<string, HavokCollision.AABBTree>[] AreaCollisionTrees = { new(), new(), new() };
public readonly Dictionary<string, BoxCollision9>[] AreaCollisionBoxes = { new(), new(), new() };
private readonly IList<FieldMainArea>[] MainAreas = new IList<FieldMainArea>[2];
private readonly IList<FieldSubArea>[] SubAreas = new IList<FieldSubArea>[2];
private readonly IList<FieldInsideArea>[] InsideAreas = new IList<FieldInsideArea>[2];
private readonly IList<FieldDungeonArea>[] DungeonAreas = new IList<FieldDungeonArea>[2];
private readonly IList<FieldLocation>[] FieldLocations = new IList<FieldLocation>[2];
private readonly IList<FieldMainArea>[] MainAreas = new IList<FieldMainArea>[3];
private readonly IList<FieldSubArea>[] SubAreas = new IList<FieldSubArea>[3];
private readonly IList<FieldInsideArea>[] InsideAreas = new IList<FieldInsideArea>[3];
private readonly IList<FieldDungeonArea>[] DungeonAreas = new IList<FieldDungeonArea>[3];
private readonly IList<FieldLocation>[] FieldLocations = new IList<FieldLocation>[3];
public PaldeaMap(GameManagerSV ROM)
{
@ -35,6 +35,12 @@ public PaldeaMap(GameManagerSV ROM)
DungeonAreas[1] = FlatBufferConverter.DeserializeFrom<FieldDungeonAreaArray>(ROM.GetPackedFile("world/data/field/area_su1/field_dungeon_area_su1/field_dungeon_area_su1_array.bin")).Table;
FieldLocations[1] = FlatBufferConverter.DeserializeFrom<FieldLocationArray>(ROM.GetPackedFile("world/data/field/area_su1/field_location_su1/field_location_su1_array.bin")).Table;
MainAreas[2] = FlatBufferConverter.DeserializeFrom<FieldMainAreaArray>(ROM.GetPackedFile("world/data/field/area_su2/field_main_area_su2/field_main_area_su2_array.bin")).Table;
SubAreas[2] = FlatBufferConverter.DeserializeFrom<FieldSubAreaArray>(ROM.GetPackedFile("world/data/field/area_su2/field_sub_area_su2/field_sub_area_su2_array.bin")).Table;
InsideAreas[2] = FlatBufferConverter.DeserializeFrom<FieldInsideAreaArray>(ROM.GetPackedFile("world/data/field/area_su2/field_inside_area_su2/field_inside_area_su2_array.bin")).Table;
DungeonAreas[2] = FlatBufferConverter.DeserializeFrom<FieldDungeonAreaArray>(ROM.GetPackedFile("world/data/field/area_su2/field_dungeon_area_su2/field_dungeon_area_su2_array.bin")).Table;
FieldLocations[2] = new List<FieldLocation>(); // FlatBufferConverter.DeserializeFrom<FieldLocationArray>(ROM.GetPackedFile("world/data/field/area_su2/field_location_su2/field_location_su2_array.bin")).Table;
LoadScenes(ROM);
}
@ -44,7 +50,10 @@ private void LoadScenes(GameManagerSV ROM)
LoadScene(ROM, ROM.GetPackedFile("world/scene/parts/field/resident_event/resident_area_collision_/resident_area_collision_0.trscn"), 0);
// Load default scenes
LoadScene(ROM, ROM.GetPackedFile(0x441FE0A17C85BEAA), 1);
LoadScene(ROM, ROM.GetPackedFile("world/scene/parts/field/main/field_1/field_main/resident_event/resident_area_collision_/resident_area_collision_0.trscn"), 1);
// Load default scenes
LoadScene(ROM, ROM.GetPackedFile("world/scene/parts/field/main/field_2/field_main/resident_event/resident_area_collision_/resident_area_collision_0.trscn"), 2);
}
private void LoadScene(GameManagerSV ROM, byte[] collisionFile, int index)

View File

@ -20,8 +20,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "pkNX.WinForms", "pkNX.WinFo
{77E3FEBB-9C86-4F8D-B4E0-66B7504080D5} = {77E3FEBB-9C86-4F8D-B4E0-66B7504080D5}
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "pkNX.Tests", "pkNX.Tests\pkNX.Tests.csproj", "{6CF919B7-BA0F-4A04-899B-6C8CAB343B86}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "pkNX.Game", "pkNX.Game\pkNX.Game.csproj", "{3C4AF1ED-7C81-4AF8-A6DB-1D397650DA0A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{BC933AB9-8BF5-4E94-BC26-7EDE48BFD300}"
@ -77,6 +75,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "pkNX.Structures.FlatBuffers
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "pkNX.Structures.FlatBuffers.SV.Audio", "pkNX.Structures.FlatBuffers.SV\pkNX.Structures.FlatBuffers.SV.Audio\pkNX.Structures.FlatBuffers.SV.Audio.csproj", "{97BC69AF-3CE9-48BC-A2AC-197D43184821}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "pkNX.Tests.Trinity", "..\idNX\pkNX.Tests\pkNX.Tests.Trinity\pkNX.Tests.Trinity.csproj", "{99593CBB-F0E6-4D27-ACB0-E89B383D0F9E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D571A50B-59B6-4DA6-9184-0C1A546D7137}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "pkNX.Tests.FileSystem", "..\idNX\pkNX.Tests\pkNX.Tests.FileSystem\pkNX.Tests.FileSystem.csproj", "{B186AD07-C9BB-4609-B7DD-42D8DF9FE92A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -99,10 +103,6 @@ Global
{3CF3FA3E-B38E-4774-BA77-924A391DDC9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3CF3FA3E-B38E-4774-BA77-924A391DDC9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3CF3FA3E-B38E-4774-BA77-924A391DDC9D}.Release|Any CPU.Build.0 = Release|Any CPU
{6CF919B7-BA0F-4A04-899B-6C8CAB343B86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6CF919B7-BA0F-4A04-899B-6C8CAB343B86}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6CF919B7-BA0F-4A04-899B-6C8CAB343B86}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6CF919B7-BA0F-4A04-899B-6C8CAB343B86}.Release|Any CPU.Build.0 = Release|Any CPU
{3C4AF1ED-7C81-4AF8-A6DB-1D397650DA0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3C4AF1ED-7C81-4AF8-A6DB-1D397650DA0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3C4AF1ED-7C81-4AF8-A6DB-1D397650DA0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -199,6 +199,14 @@ Global
{97BC69AF-3CE9-48BC-A2AC-197D43184821}.Debug|Any CPU.Build.0 = Debug|Any CPU
{97BC69AF-3CE9-48BC-A2AC-197D43184821}.Release|Any CPU.ActiveCfg = Release|Any CPU
{97BC69AF-3CE9-48BC-A2AC-197D43184821}.Release|Any CPU.Build.0 = Release|Any CPU
{99593CBB-F0E6-4D27-ACB0-E89B383D0F9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{99593CBB-F0E6-4D27-ACB0-E89B383D0F9E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{99593CBB-F0E6-4D27-ACB0-E89B383D0F9E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{99593CBB-F0E6-4D27-ACB0-E89B383D0F9E}.Release|Any CPU.Build.0 = Release|Any CPU
{B186AD07-C9BB-4609-B7DD-42D8DF9FE92A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B186AD07-C9BB-4609-B7DD-42D8DF9FE92A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B186AD07-C9BB-4609-B7DD-42D8DF9FE92A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B186AD07-C9BB-4609-B7DD-42D8DF9FE92A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -222,6 +230,8 @@ Global
{BB73E54A-20F9-44BA-B6E2-7C7E2C22CA77} = {37650547-FB5B-4CB4-A815-8785DB64BA90}
{1B561015-5A83-422D-A75F-A1A2FC756C8D} = {37650547-FB5B-4CB4-A815-8785DB64BA90}
{97BC69AF-3CE9-48BC-A2AC-197D43184821} = {37650547-FB5B-4CB4-A815-8785DB64BA90}
{99593CBB-F0E6-4D27-ACB0-E89B383D0F9E} = {D571A50B-59B6-4DA6-9184-0C1A546D7137}
{B186AD07-C9BB-4609-B7DD-42D8DF9FE92A} = {D571A50B-59B6-4DA6-9184-0C1A546D7137}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3EB083E9-2376-4061-91EB-BA8DC7F2712F}