Misc tweaks

Add lc (empty testing set)
Add underdepths fixed spawns
This commit is contained in:
Kurt
2023-12-20 23:41:57 -08:00
parent f2faa6aab4
commit 26e7a0d937
10 changed files with 158 additions and 97 deletions

View File

@@ -4,10 +4,6 @@ include "Shared/ItemID.fbs";
namespace pkNX.Structures.FlatBuffers.SV;
attribute "fs_serializer";
table ReleasePokeTableArray (fs_serializer) {
Table:[ReleasePokeTable];
}
table ReleasePokeTable {
EventId:int;
StateWorkName:string;
@@ -19,4 +15,8 @@ table ReleasePokeTable {
TeamMissionB:bool;
}
table ReleasePokeTableArray (fs_serializer) {
Table:[ReleasePokeTable] (required);
}
root_type ReleasePokeTableArray;

View File

@@ -3,14 +3,14 @@ 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;
}
table MissionSettingsArray (fs_serializer) {
Table:[MissionSettings] (required);
}
root_type MissionSettingsArray;

View File

@@ -10,8 +10,8 @@
<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">
<PackageReference Include="xunit" Version="2.6.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -10,8 +10,8 @@
<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">
<PackageReference Include="xunit" Version="2.6.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.5">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@@ -546,12 +546,14 @@ private void DumpEncount()
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<PointDataArray, PointData>("world/data/encount/point_data/point_data/encount_data_lc.bfbs", z => z.Table); -- no points (null array)
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);
Dump<EncountPokeDataArray, EncountPokeData>("world/data/encount/pokedata/pokedata_lc/pokedata_lc_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");
@@ -748,11 +750,13 @@ private void DumpItems()
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<HiddenItemBiomeTableArray, HiddenItemBiomeTable>("world/data/item/hiddenItemBiomeTable_lc/hiddenItemBiomeTable_lc_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<HiddenItemDataTableArray, HiddenItemDataTable>("world/data/item/hiddenItemDataTable_lc/hiddenItemDataTable_lc_array.bfbs", z => z.Table);
Dump<MonohiroiItemArray, MonohiroiItem>("world/data/item/monohiroiItemData/monohiroiItemData_array.bfbs", z => z.Table);
}
@@ -1106,12 +1110,14 @@ public void DumpSpecific()
"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/point_data/encount_data_lc.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/pokedata/pokedata_lc/pokedata_lc_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",

View File

@@ -188,7 +188,7 @@ private static void ScanAssertions(params DeliveryOutbreakPokeDataArray[] obs)
var areas = scene.AreaInfos[(int)fieldIndex];
var areaNames = scene.AreaNames[(int)fieldIndex];
var atlantis = scene.IsAtlantis[(int)fieldIndex];
var atlantis = scene.PaldeaType[(int)fieldIndex];
if (fieldIndex == PaldeaFieldIndex.Kitakami)
{
areas = areas.Where(z => z.Value.AdjustEncLv != 0)
@@ -311,7 +311,7 @@ private static void AddToJar(IEnumerable<CachedOutbreak> encs)
}
private static (UInt128 Met, int Boost) GetMetFlags(PaldeaSceneModel scene, Dictionary<string, (string Name, int Index)> placeNameMap, PaldeaFieldIndex fieldIndex,
byte baseMet, List<string> areaNames, Dictionary<string, AreaInfo> areas, OutbreakPointData point, Dictionary<string, bool> atlantis)
byte baseMet, List<string> areaNames, Dictionary<string, AreaInfo> areas, OutbreakPointData point, Dictionary<string, PaldeaPointPivot> atlantis)
{
UInt128 result = 0;
int boost = 0;
@@ -319,7 +319,7 @@ private static void AddToJar(IEnumerable<CachedOutbreak> encs)
{
var areaName = areaNames[i];
var areaInfo = areas[areaName];
if (atlantis[areaName])
if (atlantis[areaName] != PaldeaPointPivot.Overworld)
continue;
if (areaInfo.Tag is AreaTag.NG_Encount)

View File

@@ -20,10 +20,14 @@ public class EncounterDumperSV
public EncounterDumperSV(IFileInternal rom) => ROM = rom;
private static readonly string[] BannedFixedSpawnNames =
{
"ai_area01_30", // Lighthouse Wingull
};
private static readonly string[] BannedFixedSpawnNames = ["ai_area01_30"]; // Lighthouse Wingull
private static ReadOnlySpan<PaldeaFieldIndex> AllMaps =>
[
PaldeaFieldIndex.Paldea,
PaldeaFieldIndex.Kitakami,
PaldeaFieldIndex.Terarium,
];
public void DumpTo(string path, IReadOnlyList<string> specNamesInternal, IReadOnlyList<string> moveNames,
Dictionary<string, (string Name, int Index)> placeNameMap,
@@ -40,9 +44,11 @@ public class EncounterDumperSV
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 lcEncPoints = FlatBufferConverter.DeserializeFrom<PointDataArray>(ROM.GetPackedFile("world/data/encount/point_data/point_data/encount_data_lc.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 pokeDataLc = FlatBufferConverter.DeserializeFrom<EncountPokeDataArray>(ROM.GetPackedFile("world/data/encount/pokedata/pokedata_lc/pokedata_lc_array.bfbs"));
var db = new LocationDatabase();
@@ -51,6 +57,7 @@ public class EncounterDumperSV
var pointAtlantis = ReformatPoints(alEncPoints);
var pointSu1 = ReformatPoints(su1EncPoints);
var pointSu2 = ReformatPoints(su2EncPoints);
//var lc = ReformatPoints(lcEncPoints);
// Process all field indices
ProcessAreas(PaldeaFieldIndex.Paldea);
@@ -93,11 +100,11 @@ 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, PaldeaFieldIndex.Terarium })
foreach (var fieldIndex in AllMaps)
{
var areaNames = scene.AreaNames[(int)fieldIndex];
var areas = scene.AreaInfos[(int)fieldIndex];
var atlantis = scene.IsAtlantis[(int)fieldIndex];
var atlantis = scene.PaldeaType[(int)fieldIndex];
var allPoints = gamePoints[(int)fieldIndex];
if (fieldIndex is PaldeaFieldIndex.Kitakami)
@@ -111,6 +118,8 @@ public class EncounterDumperSV
{
var entry = fsymData.Table[i];
var tableKey = entry.TableKey;
if (tableKey.StartsWith("su2_w23d10_"))
continue; // handle later, manually
var points = allPoints.FindAll(p => p.TableKey == tableKey);
if (points.Count == 0)
continue;
@@ -125,7 +134,7 @@ bool FindArea(AreaType type)
for (var x = areaNames.Count - 1; x >= 0; x--)
{
var areaName = areaNames[x];
if (atlantis[areaName])
if (atlantis[areaName] != PaldeaPointPivot.Overworld)
continue;
var areaInfo = areas[areaName];
@@ -156,61 +165,10 @@ bool FindArea(AreaType type)
return false;
}
var locs = appearAreas.Select(a => placeNameMap[a.PlaceName].Index).Distinct().ToList();
gw.WriteLine("===");
gw.WriteLine($"{tableKey} - {i}");
gw.WriteLine("===");
gw.WriteLine(" PokeData:");
var pd = entry.Symbol;
gw.WriteLine($" Species: {specNamesInternal[(int)pd.DevId]}");
gw.WriteLine($" Form: {pd.FormId}");
gw.Write($" Level: {pd.Level}");
foreach (var adj in appearAreas.Select(a => a.Adjust).Where(lv => lv != 0).Distinct().Order())
{
gw.Write($", {pd.Level + adj}");
}
gw.WriteLine();
gw.WriteLine($" Sex: {Humanize(pd.Sex)}");
gw.WriteLine($" Shiny: {Humanize(pd.RareType)}");
var talentStr = pd.TalentType switch
{
TalentType.RANDOM => "Random",
TalentType.V_NUM => $"{pd.TalentVNum} Perfect",
TalentType.VALUE => $"{pd.TalentValue.HP}/{pd.TalentValue.ATK}/{pd.TalentValue.DEF}/{pd.TalentValue.SPA}/{pd.TalentValue.SPD}/{pd.TalentValue.SPE}",
_ => "Invalid",
};
gw.WriteLine($" IVs: {talentStr}");
gw.WriteLine($" Ability: {Humanize(pd.TokuseiIndex)}");
switch (pd.WazaType)
{
case WazaType.DEFAULT:
gw.WriteLine(" Moves: Random");
break;
case WazaType.MANUAL:
gw.WriteLine($" Moves: {moveNames[(int)pd.Waza1.WazaId]}/{moveNames[(int)pd.Waza2.WazaId]}/{moveNames[(int)pd.Waza3.WazaId]}/{moveNames[(int)pd.Waza4.WazaId]}");
break;
}
gw.WriteLine($" Scale: {Humanize(pd.ScaleType, pd.ScaleValue)}");
gw.WriteLine($" GemType: {(int)pd.GemType}");
gw.WriteLine(" Points:");
foreach (var point in points)
{
gw.WriteLine($" - ({point.Position.X}, {point.Position.Y}, {point.Position.Z})");
}
gw.WriteLine(" Areas:");
foreach (var area in appearAreas)
{
var loc = area.PlaceName;
(string name, int index) = placeNameMap[loc];
gw.WriteLine($" - {area.PlaceName} - {loc} - {name} ({index})");
}
WriteFixedSpawn(specNamesInternal, moveNames, placeNameMap, gw, tableKey, i, entry, appearAreas, points);
// Serialize
var locs = appearAreas.Select(a => placeNameMap[a.PlaceName].Index).Distinct().ToList();
if (locs.Count == 0)
continue;
if (BannedFixedSpawnNames.Contains(entry.TableKey))
@@ -226,7 +184,7 @@ bool FindArea(AreaType type)
for (var a = 0; a < allNames.Count; a++)
{
var areaName = allNames[a];
if (atlantis[areaName])
if (atlantis[areaName] != PaldeaPointPivot.Overworld)
continue;
var areaInfo = allInfos[areaName];
@@ -255,10 +213,21 @@ bool FindArea(AreaType type)
locationIDs.Sort();
WriteFixedSymbol(serialized, entry, locationIDs);
WriteFixedSymbol(serialized, entry, locationIDs, adjust);
if (adjust != 0)
WriteFixedSymbol(serialized, entry, locationIDs, adjust);
}
}
}
var underDepths = Array.FindIndex(fsymData.Table.ToArray(), x => x.TableKey == "su2_w23d10_01");
for (int i = underDepths; i < underDepths + 23; i++)
{
var entry = fsymData.Table[i];
var tableKey = entry.TableKey;
var appearAreas = new List<AppearTuple> { new("PLACENAME_a_w23_d10_01", "a_w23_d10_subarea", 0, new()) };
WriteFixedSpawn(specNamesInternal, moveNames, placeNameMap, gw, tableKey, i, entry, appearAreas, []);
WriteFixedSymbol(serialized, entry, new[] { 196 });
}
}
// Gimmighoul only in Paldea
@@ -268,7 +237,7 @@ bool FindArea(AreaType type)
var areas = new List<string>();
foreach (var areaName in scene.AreaNames[(int)PaldeaFieldIndex.Paldea])
{
if (scene.IsAtlantis[(int)PaldeaFieldIndex.Paldea][areaName])
if (scene.PaldeaType[(int)PaldeaFieldIndex.Paldea][areaName] != PaldeaPointPivot.Overworld)
continue;
var areaInfo = scene.AreaInfos[(int)PaldeaFieldIndex.Paldea][areaName];
@@ -346,9 +315,14 @@ bool FindArea(AreaType type)
return;
// HELPERS
LocationPointDetail[] GetPoints(PaldeaFieldIndex fieldIndex, bool isAtlantis) => fieldIndex switch
LocationPointDetail[] GetPoints(PaldeaFieldIndex fieldIndex, PaldeaPointPivot type) => fieldIndex switch
{
PaldeaFieldIndex.Paldea => isAtlantis ? pointAtlantis : pointMain,
PaldeaFieldIndex.Paldea => type switch
{
PaldeaPointPivot.Overworld => pointMain,
PaldeaPointPivot.AreaZero => pointAtlantis,
_ => throw new ArgumentException($"Could not handle {type}"),
},
PaldeaFieldIndex.Kitakami => pointSu1,
PaldeaFieldIndex.Terarium => pointSu2,
_ => throw new ArgumentException($"Could not handle {fieldIndex}"),
@@ -374,11 +348,10 @@ void ProcessAreas(PaldeaFieldIndex fieldIndex)
// 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];
var atlantis = scene.IsAtlantis[(int)fieldIndex];
var types = scene.PaldeaType[(int)fieldIndex];
for (var i = areaNames.Count - 1; i >= 0; i--)
{
var areaName = areaNames[i];
var areaInfo = areas[areaName];
// Determine potential spawners
if (!scene.TryGetContainsCheck(fieldIndex, areaName, out var collider))
@@ -387,6 +360,7 @@ void ProcessAreas(PaldeaFieldIndex fieldIndex)
continue;
}
var areaInfo = areas[areaName];
// Areas without a location name can't be reversed into location ID.
if (!TryGetPlaceName(ref areaName, areaInfo, collider, placeNameMap, areas, scene, fieldIndex, out var placeName))
continue;
@@ -397,7 +371,8 @@ void ProcessAreas(PaldeaFieldIndex fieldIndex)
if (areaInfo.Tag is AreaTag.NG_Encount or AreaTag.NG_All)
continue;
var points = GetPoints(fieldIndex, atlantis[areaName]);
var type = types[areaName];
var points = GetPoints(fieldIndex, type);
storage.LoadPoints(points, collider, areaInfo.ActualMinLevel, areaInfo.ActualMaxLevel, areaInfo.AdjustEncLv);
storage.GetEncounters(GetPokeData(fieldIndex), scene);
}
@@ -458,6 +433,62 @@ void ProcessAreas(PaldeaFieldIndex fieldIndex)
}
}
private static void WriteFixedSpawn(IReadOnlyList<string> specNamesInternal, IReadOnlyList<string> moveNames, Dictionary<string, (string Name, int Index)> placeNameMap,
StreamWriter gw, string tableKey, int i, FixedSymbolTable entry, List<AppearTuple> appearAreas, List<PaldeaFixedSymbolPoint> points)
{
gw.WriteLine("===");
gw.WriteLine($"{tableKey} - {i}");
gw.WriteLine("===");
gw.WriteLine(" PokeData:");
var pd = entry.Symbol;
gw.WriteLine($" Species: {specNamesInternal[(int)pd.DevId]}");
gw.WriteLine($" Form: {pd.FormId}");
gw.Write($" Level: {pd.Level}");
foreach (var adj in appearAreas.Select(a => a.Adjust).Where(lv => lv != 0).Distinct().Order())
{
gw.Write($", {pd.Level + adj}");
}
gw.WriteLine();
gw.WriteLine($" Sex: {Humanize(pd.Sex)}");
gw.WriteLine($" Shiny: {Humanize(pd.RareType)}");
var talentStr = pd.TalentType switch
{
TalentType.RANDOM => "Random",
TalentType.V_NUM => $"{pd.TalentVNum} Perfect",
TalentType.VALUE => $"{pd.TalentValue.HP}/{pd.TalentValue.ATK}/{pd.TalentValue.DEF}/{pd.TalentValue.SPA}/{pd.TalentValue.SPD}/{pd.TalentValue.SPE}",
_ => "Invalid",
};
gw.WriteLine($" IVs: {talentStr}");
gw.WriteLine($" Ability: {Humanize(pd.TokuseiIndex)}");
switch (pd.WazaType)
{
case WazaType.DEFAULT:
gw.WriteLine(" Moves: Random");
break;
case WazaType.MANUAL:
gw.WriteLine($" Moves: {moveNames[(int)pd.Waza1.WazaId]}/{moveNames[(int)pd.Waza2.WazaId]}/{moveNames[(int)pd.Waza3.WazaId]}/{moveNames[(int)pd.Waza4.WazaId]}");
break;
}
gw.WriteLine($" Scale: {Humanize(pd.ScaleType, pd.ScaleValue)}");
gw.WriteLine($" GemType: {(int)pd.GemType}");
gw.WriteLine(" Points:");
foreach (var point in points)
{
gw.WriteLine($" - ({point.Position.X}, {point.Position.Y}, {point.Position.Z})");
}
gw.WriteLine(" Areas:");
foreach (var area in appearAreas)
{
var loc = area.PlaceName;
(string name, int index) = placeNameMap[loc];
gw.WriteLine($" - {area.PlaceName} - {loc} - {name} ({index})");
}
}
private static bool TryGetBleedArea(IContainsV3f collider, List<AppearTuple> appearAreas, PaldeaSceneModel scene, PaldeaFieldIndex fieldIndex, out AppearTuple bledFrom)
{
foreach (var a in appearAreas)
@@ -644,7 +675,7 @@ private static void WriteFixedSymbol(ICollection<byte[]> exist, FixedSymbolTable
bw.Write(form);
bw.Write((byte)(enc.Level + adjustLevel));
bw.Write((byte)enc.TalentVNum);
bw.Write(enc.TalentType == TalentType.RANDOM ? (byte)0 : (byte)enc.TalentVNum);
bw.Write((byte)enc.GemType);
bw.Write((byte)(enc.Sex - 1));
bw.Write((byte)0); // reserved

View File

@@ -50,6 +50,15 @@ public PaldeaFixedSymbolModel(IFileInternal ROM)
scarletPoints[(int)PaldeaFieldIndex.Terarium].AddRange(GetObjectTemplateSymbolPoints(b0));
violetPoints[(int)PaldeaFieldIndex.Terarium].AddRange(GetObjectTemplateSymbolPoints(b1));
// Underdepths
//var u0Data = ROM.GetPackedFile("world/scene/parts/field/room/a_w23_d10/a_w23_d10_event/a_w23_d10_fixed_placement_symbol_/a_w23_d10_fixed_placement_symbol_0.trscn");
//var u1Data = ROM.GetPackedFile("world/scene/parts/field/room/a_w23_d10/a_w23_d10_event/a_w23_d10_fixed_placement_symbol_/a_w23_d10_fixed_placement_symbol_1.trscn");
//var u0 = FlatBufferConverter.DeserializeFrom<TrinitySceneObjectTemplate>(u0Data);
//var u1 = FlatBufferConverter.DeserializeFrom<TrinitySceneObjectTemplate>(u1Data);
//
//scarletPoints[(int)PaldeaFieldIndex.Paldea].AddRange(GetObjectTemplateSymbolPoints(u0));
//violetPoints[(int)PaldeaFieldIndex.Paldea].AddRange(GetObjectTemplateSymbolPoints(u1));
}
private static string[] GetTableGetKeys(GemSymbolLotteryTable entry)

View File

@@ -9,13 +9,19 @@
namespace pkNX.Structures.FlatBuffers;
public enum PaldeaPointPivot
{
Overworld,
AreaZero,
}
public class PaldeaSceneModel
{
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 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, PaldeaPointPivot>[] PaldeaType { get; } = [new(), new(), new()];
public PaldeaSceneModel(IFileInternal ROM, PaldeaFieldModel field)
{
@@ -24,7 +30,8 @@ public PaldeaSceneModel(IFileInternal ROM, PaldeaFieldModel field)
Debug.Assert(area_collision.ObjectTemplateName == "resident_area_collision");
// NOTE: Safe to only use _0 because _1 is identical.
var a_w23_field_area_col = FlatBufferConverter.DeserializeFrom<TrinitySceneObjectTemplate>(ROM.GetPackedFile("world/scene/parts/field/room/a_w23_field/a_w23_field_area_col_/a_w23_field_area_col_0.trscn"));
var a0 = ROM.GetPackedFile("world/scene/parts/field/room/a_w23_field/a_w23_field_area_col_/a_w23_field_area_col_0.trscn");
var a_w23_field_area_col = FlatBufferConverter.DeserializeFrom<TrinitySceneObjectTemplate>(a0);
Debug.Assert(a_w23_field_area_col.ObjectTemplateName == "a_w23_field_area_col");
foreach (var obj in area_collision.Objects.Concat(a_w23_field_area_col.Objects))
@@ -35,17 +42,18 @@ public PaldeaSceneModel(IFileInternal ROM, PaldeaFieldModel field)
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);
AddIfAppropriate(ROM, field, PaldeaFieldIndex.Kitakami, [], 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);
AddIfAppropriate(ROM, field, PaldeaFieldIndex.Terarium, [], obj);
}
private void AddIfAppropriate(IFileInternal ROM, PaldeaFieldModel field, PaldeaFieldIndex index, IList<TrinitySceneObjectTemplateEntry> atlantis, TrinitySceneObjectTemplateEntry obj)
private void AddIfAppropriate(IFileInternal ROM, PaldeaFieldModel field, PaldeaFieldIndex index,
IList<TrinitySceneObjectTemplateEntry> a0, TrinitySceneObjectTemplateEntry obj)
{
if (!(obj.SubObjects.Count > 0 && obj.SubObjects[0].Type == "trinity_CollisionComponent"))
return;
@@ -54,7 +62,7 @@ private void AddIfAppropriate(IFileInternal ROM, PaldeaFieldModel field, PaldeaF
var tcom = FlatBufferConverter.DeserializeFrom<TrinityComponent>(inner);
var collision = tcom.Component.CollisionComponent.Shape;
var isAtlantisObj = atlantis.Contains(obj);
var isAtlantisObj = GetPaldeaType(a0, obj);
switch (obj.Type)
{
case "trinity_ObjectTemplate":
@@ -66,14 +74,14 @@ private void AddIfAppropriate(IFileInternal ROM, PaldeaFieldModel field, PaldeaF
Debug.Assert(sceneObject.ObjectName == sObj.ObjectTemplateExtra);
AddSceneObject(index, sObj.ObjectTemplateName, sceneObject, collision, field, ROM);
IsAtlantis[(int)index][sObj.ObjectTemplateName] = isAtlantisObj;
PaldeaType[(int)index][sObj.ObjectTemplateName] = isAtlantisObj;
break;
}
case "trinity_SceneObject":
{
var sceneObject = FlatBufferConverter.DeserializeFrom<TrinitySceneObject>(obj.Data);
AddSceneObject(index, sceneObject.ObjectName, sceneObject, collision, field, ROM);
IsAtlantis[(int)index][sceneObject.ObjectName] = isAtlantisObj;
PaldeaType[(int)index][sceneObject.ObjectName] = isAtlantisObj;
break;
}
// ReSharper disable once RedundantEmptySwitchSection
@@ -85,6 +93,13 @@ private void AddIfAppropriate(IFileInternal ROM, PaldeaFieldModel field, PaldeaF
}
}
private PaldeaPointPivot GetPaldeaType(IList<TrinitySceneObjectTemplateEntry> a0, TrinitySceneObjectTemplateEntry obj)
{
if (a0.Contains(obj))
return PaldeaPointPivot.AreaZero;
return PaldeaPointPivot.Overworld;
}
private void AddSceneObject(PaldeaFieldIndex index, string name, TrinitySceneObject sceneObject, CollisionUnion shape, PaldeaFieldModel field, IFileInternal ROM)
{
AreaNames[(int)index].Add(name);

View File

@@ -46,7 +46,7 @@
<ItemGroup>
<PackageReference Include="FontAwesome.Sharp" Version="6.3.0" />
<PackageReference Include="PKHeX.Core" Version="23.10.12" />
<PackageReference Include="PKHeX.Core" Version="23.12.19" />
</ItemGroup>
<ItemGroup>