Flatsharp codegen (#326)

* Manually translated/attributed fbs files.

* Include fields in obj-as-table dump

* Emit fields for json too. FlatSharp generates structs with fields rather than properties at fixed offsets (maybe I'm missing a setting)

* Update .editorconfig to ignore generated code files (unsure if this actually works).
This commit is contained in:
Kurt
2023-04-06 18:00:19 -07:00
committed by GitHub
parent 823a204bfa
commit 8e83b63d95
955 changed files with 17362 additions and 19328 deletions

View File

@@ -43,3 +43,9 @@ dotnet_style_parentheses_in_other_operators = always_for_clarity:suggest
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.capitalization = pascal_case
# Generated Code
[**/obj/**.cs]
generated_code = true
dotnet_diagnostic.CS8019.severity = none
dotnet_analyzer_diagnostic.severity = none

View File

@@ -72,7 +72,7 @@ public Stream OpenFile(FileSystemPath path, FileAccess access)
{
IFileSystem? fs = GetFirst(path);
if (fs == null)
throw new FileNotFoundException();
throw new FileNotFoundException($"Unable to find {path.Path}");
return fs.OpenFile(path, access);
}

View File

@@ -1,4 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using FlatSharp;
using pkNX.Containers;
using pkNX.Structures.FlatBuffers;
@@ -10,13 +13,13 @@ public class DataCache<T> : IDataEditor where T : class
public Func<byte[], T> Create { private get; set; } = null!;
public Func<T, byte[]> Write { protected get; set; } = null!;
public DataCache(T?[] cache) => Cache = cache;
public DataCache(IList<T?> cache) => Cache = cache;
public DataCache(IFileContainer f) : this(new T[f.Count]) => Data = f;
protected readonly T?[] Cache;
protected readonly IList<T?> Cache;
private bool Cached;
public int Length => Cache.Length;
public int Length => Cache.Count;
public T this[int index]
{
@@ -26,7 +29,7 @@ public class DataCache<T> : IDataEditor where T : class
public void CancelEdits()
{
for (int i = 0; i < Cache.Length; i++)
for (int i = 0; i < Cache.Count; i++)
Cache[i] = default;
}
@@ -35,7 +38,7 @@ public void CancelEdits()
public T[] LoadAll()
{
if (Cached)
return Cache!;
return Cache.ToArray()!;
for (int i = 0; i < Length; i++)
{
// ReSharper disable once AssignmentIsFullyDiscarded
@@ -43,13 +46,13 @@ public T[] LoadAll()
}
Cached = true;
return Cache!;
return Cache.ToArray()!;
}
public void ClearAll()
{
Cached = false;
for (int i = 0; i < Cache.Length; i++)
for (int i = 0; i < Cache.Count; i++)
Cache[i] = null;
}
@@ -58,7 +61,7 @@ public void ClearAll()
/// </summary>
public virtual void Save()
{
for (int i = 0; i < Cache.Length; i++)
for (int i = 0; i < Cache.Count; i++)
{
var val = Cache[i];
if (val == null)
@@ -74,7 +77,7 @@ public virtual void Save()
/// <typeparam name="T"></typeparam>
public class DirectCache<T> : DataCache<T> where T : class
{
public DirectCache(T[] cache) : base(cache) { }
public DirectCache(IList<T?> cache) : base(cache) { }
public override void Save() { }
}
@@ -84,24 +87,25 @@ public class DirectCache<T> : DataCache<T> where T : class
/// <typeparam name="TTable">The type of table</typeparam>
/// <typeparam name="TData">The type of data inside the table</typeparam>
public class TableCache<TTable, TData>
where TTable : class, IFlatBufferArchive<TData>
where TTable : class, IFlatBufferSerializable<TTable>
where TData : class
{
public IFileContainer File { get; private set; }
public TTable Root { get; private set; }
public TData[] Table => Root.Table;
public IList<TData> Table { get; private set; }
public DataCache<TData> Cache { get; private set; }
public TableCache(IFileContainer f)
public TableCache(IFileContainer f, Func<TTable, IList<TData>> sel)
{
File = f;
Root = FlatBufferConverter.DeserializeFrom<TTable>(f[0]);
Cache = new DirectCache<TData>(Root.Table);
Table = sel(Root);
Cache = new DirectCache<TData>(Table!);
}
public void Save()
{
File[0] = FlatBufferConverter.SerializeFrom(Root);
File[0] = Root.SerializeFrom();
}
public TData this[int index]

View File

@@ -1,22 +1,24 @@
using pkNX.Structures;
using pkNX.Structures.FlatBuffers;
using pkNX.Structures.FlatBuffers.Arceus;
using Learnset = pkNX.Structures.FlatBuffers.Arceus.Learnset;
using EvolutionSet = pkNX.Structures.FlatBuffers.Arceus.EvolutionSet;
namespace pkNX.Game;
public class PokeEditor8a : IDataEditor
{
public IPersonalTable Personal { get; init; } = null!;
public TableCache<PokeMiscTable8a, PokeMisc8a> PokeMisc { get; init; } = null!;
public TableCache<PokeAIArchive8a, PokeAI8a> SymbolBehave { get; init; } = null!;
public TableCache<EvolutionTable8, EvolutionSet8a> Evolve { get; init; } = null!;
public TableCache<Learnset8a, Learnset8aMeta> Learn { get; init; } = null!;
public TableCache<PokeDropItemArchive8a, PokeDropItem8a> FieldDropTables { get; init; } = null!;
public TableCache<PokeDropItemBattleArchive8a, PokeDropItemBattle8a> BattleDropTabels { get; init; } = null!;
public TableCache<PokeMiscTable, PokeMisc> PokeMisc { get; init; } = null!;
public TableCache<PokeAIArchive, PokeAI> SymbolBehave { get; init; } = null!;
public TableCache<EvolutionTable, EvolutionSet> Evolve { get; init; } = null!;
public TableCache<Learnset, LearnsetMeta> Learn { get; init; } = null!;
public TableCache<PokeDropItemArchive, PokeDropItem> FieldDropTables { get; init; } = null!;
public TableCache<PokeDropItemBattleArchive, PokeDropItemBattle> BattleDropTabels { get; init; } = null!;
public TableCache<PokedexResearchTable, PokedexResearchTask> DexResearch { get; init; } = null!;
public TableCache<PokeInfoList8a, PokeInfo8a> PokeResourceList { get; init; } = null!;
public TableCache<PokeResourceTable8a, PokeModelConfig8a> PokeResourceTable { get; init; } = null!;
public TableCache<EncounterMultiplierArchive8a, EncounterMultiplier8a> EncounterRateTable { get; init; } = null!;
public TableCache<PokeCaptureCollisionArchive8a, PokeCaptureCollision8a> CaptureCollisionTable { get; init; } = null!;
public TableCache<PokeInfoList, PokeInfo> PokeResourceList { get; init; } = null!;
public TableCache<PokeResourceTable, PokeModelConfig> PokeResourceTable { get; init; } = null!;
public TableCache<EncounterMultiplierArchive, EncounterMultiplier> EncounterRateTable { get; init; } = null!;
public TableCache<PokeCaptureCollisionArchive, PokeCaptureCollision> CaptureCollisionTable { get; init; } = null!;
public void CancelEdits() { }

View File

@@ -1,16 +1,16 @@
using pkNX.Structures;
using pkNX.Structures.FlatBuffers;
using pkNX.Structures.FlatBuffers.Arceus;
namespace pkNX.Game;
public class GameData8a
{
public IPersonalTable PersonalData { get; init; } = null!;
public DataCache<Waza8a> MoveData { get; init; } = null!;
public TableCache<EvolutionTable8, EvolutionSet8a> EvolutionData { get; init; } = null!;
public TableCache<Learnset8a, Learnset8aMeta> LevelUpData { get; init; } = null!;
public DataCache<Waza> MoveData { get; init; } = null!;
public TableCache<EvolutionTable, pkNX.Structures.FlatBuffers.Arceus.EvolutionSet> EvolutionData { get; init; } = null!;
public TableCache<pkNX.Structures.FlatBuffers.Arceus.Learnset, LearnsetMeta> LevelUpData { get; init; } = null!;
public TableCache<PokeDropItemArchive8a, PokeDropItem8a> FieldDrops { get; init; } = null!;
public TableCache<PokeDropItemBattleArchive8a, PokeDropItemBattle8a> BattleDrops { get; init; } = null!;
public TableCache<PokeDropItemArchive, PokeDropItem> FieldDrops { get; init; } = null!;
public TableCache<PokeDropItemBattleArchive, PokeDropItemBattle> BattleDrops { get; init; } = null!;
public TableCache<PokedexResearchTable, PokedexResearchTask> DexResearch { get; init; } = null!;
}

View File

@@ -6,6 +6,7 @@
using pkNX.Containers.VFS;
using pkNX.Structures;
using pkNX.Structures.FlatBuffers;
using pkNX.Structures.FlatBuffers.Arceus;
namespace pkNX.Game;
@@ -192,23 +193,23 @@ private void ResetData()
// Single Files
PersonalData = new PersonalTable8LA(GetFile(GameFile.PersonalStats)),
LevelUpData = new(GetFile(GameFile.Learnsets)),
EvolutionData = new(GetFile(GameFile.Evolutions)),
LevelUpData = new(GetFile(GameFile.Learnsets), z => z.Table),
EvolutionData = new(GetFile(GameFile.Evolutions), z => z.Table),
FieldDrops = new(GetFile(GameFile.FieldDrops)),
BattleDrops = new(GetFile(GameFile.BattleDrops)),
DexResearch = new(GetFile(GameFile.DexResearch)),
FieldDrops = new(GetFile(GameFile.FieldDrops), z => z.Table),
BattleDrops = new(GetFile(GameFile.BattleDrops), z => z.Table),
DexResearch = new(GetFile(GameFile.DexResearch), z => z.Table),
};
DropTableConverter.DropTableHashes = Data.FieldDrops.Table.Select(x => x.Hash).ToArray();
}
private DataCache<Waza8a> GetMoves()
private DataCache<Waza> GetMoves()
{
var move = GetFilteredFolder(GameFile.MoveStats);
return new DataCache<Waza8a>(move)
return new DataCache<Waza>(move)
{
Create = FlatBufferConverter.DeserializeFrom<Waza8a>,
Create = FlatBufferConverter.DeserializeFrom<Waza>,
Write = FlatBufferConverter.SerializeFrom,
};
}

View File

@@ -1,7 +1,7 @@
using System;
using System.IO;
using pkNX.Containers;
using pkNX.Structures.FlatBuffers;
using pkNX.Structures.FlatBuffers.SV.Trinity;
namespace pkNX.Game;

View File

@@ -4,6 +4,7 @@
using pkNX.Containers;
using pkNX.Structures;
using pkNX.Structures.FlatBuffers;
using pkNX.Structures.FlatBuffers.SWSH;
namespace pkNX.Game;
@@ -49,8 +50,8 @@ public override void Initialize()
{
MoveData = new DataCache<IMove>(move)
{
Create = FlatBufferConverter.DeserializeFrom<Waza8>,
Write = z => FlatBufferConverter.SerializeFrom((Waza8)z),
Create = bytes => (IMove)FlatBufferConverter.DeserializeFrom<Waza>(bytes),
Write = z => ((Waza)z).SerializeFrom(),
},
LevelUpData = new DataCache<Learnset>(Learn)
{

View File

@@ -8,6 +8,10 @@
<ItemGroup>
<ProjectReference Include="..\pkNX.Containers\pkNX.Containers.csproj" />
<ProjectReference Include="..\pkNX.Randomization\pkNX.Randomization.csproj" />
<ProjectReference Include="..\pkNX.Structures.FlatBuffers.Arceus\pkNX.Structures.FlatBuffers.Arceus.csproj" />
<ProjectReference Include="..\pkNX.Structures.FlatBuffers.LGPE\pkNX.Structures.FlatBuffers.LGPE.csproj" />
<ProjectReference Include="..\pkNX.Structures.FlatBuffers.SV\pkNX.Structures.FlatBuffers.SV.csproj" />
<ProjectReference Include="..\pkNX.Structures.FlatBuffers.SWSH\pkNX.Structures.FlatBuffers.SWSH.csproj" />
<ProjectReference Include="..\pkNX.Structures.FlatBuffers\pkNX.Structures.FlatBuffers.csproj" />
<ProjectReference Include="..\pkNX.Structures\pkNX.Structures.csproj" />
</ItemGroup>

View File

@@ -1,19 +1,17 @@
using System;
using System.Linq;
namespace pkNX.Structures.FlatBuffers;
namespace pkNX.Structures.FlatBuffers.Arceus;
public static class Condition8aUtil
public static class ConditionUtil
{
public static string GetConditionTypeSummary(this IHasCondition8a cond)
public static string GetConditionTypeSummary(this IHasCondition cond)
{
if (!Enum.IsDefined(typeof(ConditionType8a), cond.ConditionTypeID))
return $"0x{(ulong)cond.ConditionTypeID:X16}";
//throw new ArgumentOutOfRangeException(nameof(cond.ConditionTypeID), cond.ConditionTypeID, "Unknown.");
// todo lookup
return $"{cond.ConditionTypeID}";
}
public static string GetConditionArgsSummary(this IHasCondition8a cond)
public static string GetConditionArgsSummary(this IHasCondition cond)
{
var args = new[] { cond.ConditionArg1, cond.ConditionArg2, cond.ConditionArg3, cond.ConditionArg4, cond.ConditionArg5 };
@@ -28,10 +26,9 @@ public static string GetConditionArgsSummary(this IHasCondition8a cond)
return string.Join(", ", args.Select(s => $"\"{s}\"").Take(firstEmpty >= 0 ? firstEmpty : args.Length));
}
public static string GetConditionSummary(this IHasCondition8a cond)
public static string GetConditionSummary(this IHasCondition cond)
{
if (!Enum.IsDefined(typeof(Condition8a), cond.ConditionID))
throw new ArgumentOutOfRangeException(nameof(cond.ConditionID), cond.ConditionID, "Unknown.");
// todo lookup
return $"{cond.ConditionID}({GetConditionArgsSummary(cond)})";
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class AppConfigEntry { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class AppConfigList { }

View File

@@ -0,0 +1,24 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class ConfigArchive { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class ConfigEntry
{
public string ConfiguredValue
{
get => Parameters[0];
set => Parameters[0] = value;
}
}

View File

@@ -0,0 +1,16 @@
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class DressUpTable { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class DressUpEntry { }

View File

@@ -0,0 +1,30 @@
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class TriggerTable { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class Trigger { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class TriggerMeta { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class TriggerCondition : IHasCondition
{
// For interface compat
public string ConditionArg4 { get; set; } = string.Empty;
public string ConditionArg5 { get; set; } = string.Empty;
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class TriggerCommand { }

View File

@@ -1,4 +1,4 @@
namespace pkNX.Structures.FlatBuffers;
namespace pkNX.Structures.FlatBuffers.Arceus;
public interface ISlotTableConsumer
{

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using FlatSharp.Attributes;
using pkNX.Containers;
// ReSharper disable UnusedAutoPropertyAccessor.Global
@@ -11,30 +10,14 @@
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers;
namespace pkNX.Structures.FlatBuffers.Arceus;
[FlatBufferTable, TypeConverter(typeof(ExpandableObjectConverter))]
public class LandmarkItemSpawnTable8a : IFlatBufferArchive<LandmarkItemSpawn8a>
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class LandmarkItemSpawnTable { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class LandmarkItemSpawn
{
public byte[] Write() => FlatBufferConverter.SerializeFrom(this);
[FlatBufferItem(0)] public LandmarkItemSpawn8a[] Table { get; set; } = Array.Empty<LandmarkItemSpawn8a>();
}
[FlatBufferTable, TypeConverter(typeof(ExpandableObjectConverter))]
public class LandmarkItemSpawn8a
{
[FlatBufferItem(00)] public ulong LandmarkItemSpawnTableID { get; set; }
[FlatBufferItem(01)] public int ItemRewardMin { get; set; } // counts apply only for inactivated landmarks
[FlatBufferItem(02)] public int ItemRewardMax { get; set; }
[FlatBufferItem(03)] public LandmarkItemSpawn8a_F03[] Field_03 { get; set; } = Array.Empty<LandmarkItemSpawn8a_F03>();
[FlatBufferItem(04)] public int ActivationRate { get; set; }
[FlatBufferItem(05)] public byte Field_05 { get; set; } // unknown
[FlatBufferItem(06)] public byte Field_06 { get; set; } // unknown
[FlatBufferItem(07)] public ulong EncounterTableID { get; set; }
[FlatBufferItem(08)] public int LevelBoost { get; set; }
[FlatBufferItem(09)] public int RareRate { get; set; }
public bool UsesTable(ulong table) => EncounterTableID == table;
public string NameSummary
@@ -108,10 +91,5 @@ public string NameSummary
}
}
[FlatBufferTable, TypeConverter(typeof(ExpandableObjectConverter))]
public class LandmarkItemSpawn8a_F03
{
[FlatBufferItem(00)] public int ItemId { get; set; }
[FlatBufferItem(01)] public int Probability { get; set; }
[FlatBufferItem(02)] public bool IsRare { get; set; }
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class LandmarkItemSpawn_F03 { }

View File

@@ -1,9 +1,4 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using FlatSharp.Attributes;
using pkNX.Containers;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
@@ -12,46 +7,31 @@
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers;
namespace pkNX.Structures.FlatBuffers.Arceus;
[FlatBufferTable, TypeConverter(typeof(ExpandableObjectConverter))]
public class LandmarkItemTable8a : IFlatBufferArchive<LandmarkItem8a>
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class LandmarkItemTable { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class LandmarkItem : ISlotTableConsumer
{
public byte[] Write() => FlatBufferConverter.SerializeFrom(this);
[FlatBufferItem(0)] public LandmarkItem8a[] Table { get; set; } = Array.Empty<LandmarkItem8a>();
}
[FlatBufferTable, TypeConverter(typeof(ExpandableObjectConverter))]
public class LandmarkItem8a : ISlotTableConsumer
{
[FlatBufferItem(00)] public string Field_00 { get; set; } = string.Empty;
[FlatBufferItem(01)] public ulong Field_01 { get; set; }
[FlatBufferItem(02)] public ulong LandmarkItemNameID { get; set; }
[FlatBufferItem(03)] public PlacementParameters8a[] Field_03 { get; set; } = Array.Empty<PlacementParameters8a>();
[FlatBufferItem(04)] public float Scalar { get; set; }
[FlatBufferItem(05)] public FlatDummyObject Field_05 { get; set; } = new();
[FlatBufferItem(06)] public FlatDummyObject Field_06 { get; set; } = new();
[FlatBufferItem(07)] public FlatDummyObject Field_07 { get; set; } = new();
[FlatBufferItem(08)] public ulong LandmarkItemSpawnTableID { get; set; }
public PlacementParameters8a Parameters
public PlacementParameters Parameters
{
get { if (Field_03.Length != 1) throw new ArgumentException($"Invalid {nameof(Field_03)}"); return Field_03[0]; }
set { if (Field_03.Length != 1) throw new ArgumentException($"Invalid {nameof(Field_03)}"); Field_03[0] = value; }
get { if (Field03.Count != 1) throw new ArgumentException($"Invalid {nameof(Field03)}"); return Field03[0]; }
set { if (Field03.Count != 1) throw new ArgumentException($"Invalid {nameof(Field03)}"); Field03[0] = value; }
}
public bool UsesTable(ulong table) => LandmarkItemSpawnTableID == table;
public IEnumerable<PlacementLocation8a> GetIntersectingLocations(IReadOnlyList<PlacementLocation8a> locations, float bias)
public IEnumerable<PlacementLocation> GetIntersectingLocations(IList<PlacementLocation> locations, float bias)
{
var c = Parameters.Coordinates;
return GetIntersectingLocations(locations, bias, c, Scalar);
}
private static IEnumerable<PlacementLocation8a> GetIntersectingLocations(IReadOnlyList<PlacementLocation8a> locations, float bias, Vec3f c, float scalar)
private static IEnumerable<PlacementLocation> GetIntersectingLocations(IList<PlacementLocation> locations, float bias, Vec3f c, float scalar)
{
var result = new List<PlacementLocation8a>();
var result = new List<PlacementLocation>();
foreach (var loc in locations)
{
if (!loc.IsNamedPlace)
@@ -65,9 +45,9 @@ private static IEnumerable<PlacementLocation8a> GetIntersectingLocations(IReadOn
return result;
}
public IEnumerable<PlacementLocation8a> GetContainingLocations(IReadOnlyList<PlacementLocation8a> locations)
public IEnumerable<PlacementLocation> GetContainingLocations(IList<PlacementLocation> locations)
{
var result = new List<PlacementLocation8a>();
var result = new List<PlacementLocation>();
foreach (var loc in locations)
{
if (!loc.IsNamedPlace)
@@ -86,7 +66,7 @@ public string NameSummary
{
var map = GetNameMap();
if (map.TryGetValue(LandmarkItemNameID, out var name))
return $"\"{name}\" ({Field_00})";
return $"\"{name}\" ({Field00})";
return $"0x{LandmarkItemNameID:X16}";
}

View File

@@ -0,0 +1,22 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class MassOutbreakTable { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class MassOutbreak { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class MassOutbreakCondition : IHasCondition
{
}

View File

@@ -0,0 +1,33 @@
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class NewHugeOutbreakGroupArchive { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class NewHugeOutbreakGroup
{
public int SumTable => Table.Sum(z => z.Rate);
public bool UsesTable(ulong tableID)
{
if (EncounterTableID == tableID)
return true;
var matches = Table.FirstOrDefault(z => z.EncounterTableID == tableID);
return matches is not null;
}
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class NewHugeOutbreakDetail : IHasCondition
{
public override string ToString() => $"PlacementParameters(/* ConditionTypeID = */ {this.GetConditionTypeSummary()}, /* Condition = */ {this.GetConditionSummary()}, {EncounterTableID:X16}, {Rate})";
}

View File

@@ -0,0 +1,68 @@
using System;
using System.ComponentModel;
using System.Linq;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class NewHugeOutbreakGroupLotteryArchive
{
public bool IsAreaGroup(PlacementSpawner spawner, NewHugeOutbreakGroupArchive groups, ulong tableID)
{
var hash = spawner.Field20Value.EncounterTableID;
var group = Table.FirstOrDefault(z => z.LotteryGroup == hash);
if (group == null)
return false;
return group.IsUseTable(groups, tableID);
}
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class NewHugeOutbreakGroupLottery
{
public int SumTableCommon => TableCommon.Sum(z => z.Rate);
public int SumTableRare1 => TableRare1.Sum(z => z.Rate);
public int SumTableRare2 => TableRare2.Sum(z => z.Rate);
public bool IsUseTable(NewHugeOutbreakGroupArchive groups, ulong tableID)
{
foreach (var lotteryChoice in TableCommon)
{
if (lotteryChoice.UsesTable(groups, tableID))
return true;
}
foreach (var lotteryChoice in TableRare1)
{
if (lotteryChoice.UsesTable(groups, tableID))
return true;
}
foreach (var lotteryChoice in TableRare2)
{
if (lotteryChoice.UsesTable(groups, tableID))
return true;
}
return false;
}
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class NewHugeOutbreakGroupLotteryDetail
{
public override string ToString() => $"{Group:X16}|{Rate}";
public bool UsesTable(NewHugeOutbreakGroupArchive groups, ulong tableID)
{
var lottery = groups.Table.FirstOrDefault(z => z.Group == Group);
if (lottery is null)
return false;
return lottery.UsesTable(tableID);
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class NewHugeOutbreakLotteryArchive { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class NewHugeOutbreakLottery { }

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class NewHugeOutbreakTimeLimitArchive { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class NewHugeOutbreakTimeLimit { }

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class OybnSettingTable { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class OybnSetting { }

View File

@@ -0,0 +1,23 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PlacementItemArchive { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PlacementItem { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PlacementItem_F03 { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PlacementItem_F08 { }

View File

@@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Numerics;
using FlatSharp.Attributes;
using pkNX.Containers;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
@@ -12,48 +8,19 @@
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers;
namespace pkNX.Structures.FlatBuffers.Arceus;
[FlatBufferTable, TypeConverter(typeof(ExpandableObjectConverter))]
public class PlacementLocation8a
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PlacementLocation
{
public const ulong ShapeIdSphere = 0x645FB59E96A6F998;
public const ulong ShapeIdBox = 0xE6B50E272D8CD992;
public const ulong ShapeNone = 0xCBF29CE484222645;
[FlatBufferEnum(typeof(ulong))]
public enum LocationType8a : ulong
public PlacementParameters Parameters
{
Bgm = 0xD090DB268FBCE531, // "Bgm"
BuddyInfeasibleOcclusion = 0x1713B588A00FF9F2, // "BuddyInfeasibleOcclusion"
Evolution = 0x51550D70709EA65E, // "Evolution"
LightOcclusion = 0x94FEC9F97E988350, // "LightOcclusion"
NoRespawnOcclusion = 0xD91EE555A7E6DC07, // "NoRespawnOcclusion"
OcclusionSpace = 0x613F7FD830366C6C, // "OcclusionSpace"
PlaceName = 0x0351C91B3FD84C97, // "PlaceName
RideInfeasibleOcclusion = 0x677D529DBB999AD6, // "RideInfeasibleOcclusion"
SafetyArea = 0x4C62CAA0FF9B445A, // "SafetyArea"
SaveGameOver = 0x77EEDD438D48D1B8, // "SaveGameOver"
TakeOffShoesOcclusion = 0x09FBFD6B423FAEA6, // "TakeOffShoesOcclusion"
TreeCullingFrustumFar = 0xD55673931A300690, // "TreeCullingFrustumFar"
WeatherOcclusion = 0x2B3435F7DF6CF454, // "WeatherOcclusion"
}
[FlatBufferItem(0)] public string Field_00 { get; set; } = string.Empty;
[FlatBufferItem(1)] public ulong Field_01 { get; set; }
[FlatBufferItem(2)] public PlacementParameters8a[] ParameterSet { get; set; } = { new() };
[FlatBufferItem(3)] public ulong ShapeID { get; set; }
[FlatBufferItem(4)] public float SizeX { get; set; }
[FlatBufferItem(5)] public float SizeY { get; set; }
[FlatBufferItem(6)] public float SizeZ { get; set; }
[FlatBufferItem(7)] public ulong LocationTypeID { get; set; }
[FlatBufferItem(8)] public string LocationTypeArg1 { get; set; } = string.Empty;
[FlatBufferItem(9)] public ulong LocationTypeArg2 { get; set; }
public PlacementParameters8a Parameters
{
get { if (ParameterSet.Length != 1) throw new ArgumentException($"Invalid {nameof(ParameterSet)}"); return ParameterSet[0]; }
set { if (ParameterSet.Length != 1) throw new ArgumentException($"Invalid {nameof(ParameterSet)}"); ParameterSet[0] = value; }
get { if (ParameterSet.Count != 1) throw new ArgumentException($"Invalid {nameof(ParameterSet)}"); return ParameterSet[0]; }
set { if (ParameterSet.Count != 1) throw new ArgumentException($"Invalid {nameof(ParameterSet)}"); ParameterSet[0] = value; }
}
public bool IsNamedPlace => LocationTypeID == 0x0351C91B3FD84C97;
@@ -196,9 +163,8 @@ public string LocationTypeIdSummary
{
get
{
if (!Enum.IsDefined(typeof(LocationType8a), LocationTypeID))
throw new ArgumentOutOfRangeException(nameof(LocationTypeID), LocationTypeID, $"Unknown 0x{LocationTypeID:X16}.");
return ((LocationType8a)LocationTypeID).ToString();
// todo lookup
return (LocationTypeID).ToString();
}
}
@@ -218,5 +184,5 @@ public string LocationTypeIdSummary
public string LocationArg2Summary => GetLocationArgMap().TryGetValue(LocationTypeArg2, out var arg) ? $"\"{arg}\"" : $"0x{LocationTypeArg2:X16}";
public override string ToString() => $"Location(\"{Field_00}\", 0x{Field_01:X16}, {Parameters}, {ShapeSummary}, {SizeX}, {SizeY}, {SizeZ}, {LocationTypeSummary})";
public override string ToString() => $"Location(\"{Field00}\", 0x{Field01:X16}, {Parameters}, {ShapeSummary}, {SizeX}, {SizeY}, {SizeZ}, {LocationTypeSummary})";
}

View File

@@ -0,0 +1,14 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PlacementLocationArchive { }

View File

@@ -0,0 +1,40 @@
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PlacementMkrgTable { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PlacementMkrgEntry
{
public PlacementParameters Parameters
{
get { if (Field02.Count != 1) throw new ArgumentException($"Invalid {nameof(Field02)}"); return Field02[0]; }
set { if (Field02.Count != 1) throw new ArgumentException($"Invalid {nameof(Field02)}"); Field02[0] = value; }
}
public override string ToString() => $"Mikaruge(\"{Identifier}\", 0x{Hash01:X16}, {Parameters}, {Field03}, {Field04})";
public IEnumerable<PlacementLocation> GetContainingLocations(IList<PlacementLocation> locations)
{
var result = new List<PlacementLocation>();
foreach (var loc in locations)
{
if (!loc.IsNamedPlace)
continue;
if (loc.Contains(Parameters.Coordinates))
result.Add(loc);
}
if (result.Count == 0)
result.Add(locations.First(l => l.IsNamedPlace)); // base area name
return result;
}
}

View File

@@ -0,0 +1,16 @@
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PlacementParameters : IHasCondition
{
public override string ToString() => $"PlacementParameters(/* ConditionTypeID = */ {this.GetConditionTypeSummary()}, /* Condition = */ {this.GetConditionSummary()}, {Coordinates}, {Rotation}, {Scale})";
}

View File

@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PlacementSearchItemTable { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PlacementSearchItem
{
public PlacementParameters Parameters
{
get { if (Field02.Count != 1) throw new ArgumentException($"Invalid {nameof(Field02)}"); return Field02[0]; }
set { if (Field02.Count != 1) throw new ArgumentException($"Invalid {nameof(Field02)}"); Field02[0] = value; }
}
public override string ToString() => $"SearchItem(\"{Identifier}\", 0x{Hash01:X16}, {Parameters}, {Rate}, {Field03}, {Field04})";
public IEnumerable<PlacementLocation> GetContainingLocations(IList<PlacementLocation> locations)
{
var result = new List<PlacementLocation>();
foreach (var loc in locations)
{
if (!loc.IsNamedPlace)
continue;
if (loc.Contains(Parameters.Coordinates))
result.Add(loc);
}
if (result.Count == 0)
result.Add(locations.First(l => l.IsNamedPlace)); // base area name
return result;
}
}

View File

@@ -0,0 +1,193 @@
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PlacementSpawner : ISlotTableConsumer
{
public PlacementParameters Parameters
{
get { if (Field02.Count != 1) throw new ArgumentException($"Invalid {nameof(Field02)}"); return Field02[0]; }
set { if (Field02.Count != 1) throw new ArgumentException($"Invalid {nameof(Field02)}"); Field02[0] = value; }
}
public PlacementSpawnerF20 Field20Value
{
get { if (Field20.Count != 1) throw new ArgumentException($"Invalid {nameof(Field20)}"); return Field20[0]; }
set { if (Field20.Count != 1) throw new ArgumentException($"Invalid {nameof(Field20)}"); Field20[0] = value; }
}
public PlacementSpawnerF21 Field21Value
{
get { if (Field21.Count != 1) throw new ArgumentException($"Invalid {nameof(Field21)}"); return Field21[0]; }
set { if (Field21.Count != 1) throw new ArgumentException($"Invalid {nameof(Field21)}"); Field21[0] = value; }
}
public string PathToFollowID
{
get { if (PathToFollowIDs.Count != 1) throw new ArgumentException($"Invalid {nameof(PathToFollowIDs)}"); return PathToFollowIDs[0]; }
set { if (PathToFollowIDs.Count != 1) throw new ArgumentException($"Invalid {nameof(PathToFollowIDs)}"); PathToFollowIDs[0] = value; }
}
public IEnumerable<PlacementLocation> GetIntersectingLocations(IList<PlacementLocation> locations, float bias)
{
var c = Parameters.Coordinates;
return GetIntersectingLocations(locations, bias, c, Scalar);
}
private static IEnumerable<PlacementLocation> GetIntersectingLocations(IList<PlacementLocation> locations, float bias, Vec3f c, float scalar)
{
var result = new List<PlacementLocation>();
foreach (var loc in locations)
{
if (!loc.IsNamedPlace)
continue;
if (loc.IntersectsSphere(c.X, c.Y, c.Z, scalar + bias))
result.Add(loc);
}
if (result.Count == 0)
result.Add(locations.First(l => l.IsNamedPlace)); // base area name
return result;
}
public IEnumerable<PlacementLocation> GetContainingLocations(IList<PlacementLocation> locations)
{
var result = new List<PlacementLocation>();
foreach (var loc in locations)
{
if (!loc.IsNamedPlace)
continue;
if (loc.Contains(Parameters.Coordinates))
result.Add(loc);
}
if (result.Count == 0)
result.Add(locations.First(l => l.IsNamedPlace)); // base area name
return result;
}
private static IReadOnlyDictionary<ulong, string>? spawnerNameMap;
private static IReadOnlyDictionary<ulong, string> GetSpawnerNameMap() => spawnerNameMap ??= GenerateSpawnerNameMap();
private static IReadOnlyDictionary<ulong, string> GenerateSpawnerNameMap()
{
var result = new Dictionary<ulong, string>();
for (var i = 0; i < 10000; i++)
{
result[FnvHash.HashFnv1a_64($"{i:0000}")] = $"{i:0000}";
result[FnvHash.HashFnv1a_64($"1{i:0000}")] = $"1{i:0000}";
result[FnvHash.HashFnv1a_64($"02{i:0000}")] = $"02{i:0000}";
result[FnvHash.HashFnv1a_64($"03{i:0000}")] = $"03{i:0000}";
result[FnvHash.HashFnv1a_64($"4{i:0000}")] = $"4{i:0000}";
result[FnvHash.HashFnv1a_64($"5{i:0000}")] = $"5{i:0000}";
result[FnvHash.HashFnv1a_64($"ev{i:0000}")] = $"ev{i:0000}";
result[FnvHash.HashFnv1a_64($"ex{i:0000}")] = $"ex{i:0000}";
result[FnvHash.HashFnv1a_64($"eveex{i:0000}")] = $"eveex{i:0000}";
result[FnvHash.HashFnv1a_64($"huge{i:0000}")] = $"huge{i:0000}";
for (var j = 0; j < 20; j++)
{
result[FnvHash.HashFnv1a_64($"{i:0000}{j:00}")] = $"{i:0000}{j:00}";
}
}
for (var i = 0; i < 100; i++)
{
result[FnvHash.HashFnv1a_64($"area00{i:00}")] = $"area00{i:00}";
result[FnvHash.HashFnv1a_64($"poke{i:00}")] = $"poke{i:00}";
result[FnvHash.HashFnv1a_64($"sky{i:00}")] = $"sky{i:00}";
result[FnvHash.HashFnv1a_64($"lndno{i:00}")] = $"lndno{i:00}";
result[FnvHash.HashFnv1a_64($"sky{i:00}")] = $"sky{i:00}";
result[FnvHash.HashFnv1a_64($"exmkrg{i:00}")] = $"exmkrg{i:00}";
result[FnvHash.HashFnv1a_64($"exunnn{i:00}")] = $"exunnn{i:00}";
result[FnvHash.HashFnv1a_64($"extrs{i:00}")] = $"extrs{i:00}";
}
result[FnvHash.HashFnv1a_64("haarea01s01ev001")] = "haarea01s01ev001";
result[FnvHash.HashFnv1a_64("haarea02s02ev001")] = "haarea02s02ev001";
result[FnvHash.HashFnv1a_64("haarea02s02ev002")] = "haarea02s02ev002";
result[FnvHash.HashFnv1a_64("haarea03s03ev001")] = "haarea03s03ev001";
result[FnvHash.HashFnv1a_64("haarea04ev001")] = "haarea04ev001";
result[FnvHash.HashFnv1a_64("haarea05s03ev001")] = "haarea05s03ev001";
result[FnvHash.HashFnv1a_64("area03s04ev001")] = "area03s04ev001";
result[FnvHash.HashFnv1a_64("area03s04ev002")] = "area03s04ev002";
result[FnvHash.HashFnv1a_64("area03s04ev003")] = "area03s04ev003";
result[FnvHash.HashFnv1a_64("area03s04ev004")] = "area03s04ev004";
result[FnvHash.HashFnv1a_64("area03s04ev005")] = "area03s04ev005";
// 1.0.2
result[FnvHash.HashFnv1a_64("haarea01s011000")] = "haarea01s011000";
result[FnvHash.HashFnv1a_64("haarea02s021000")] = "haarea02s021000";
result[FnvHash.HashFnv1a_64("haarea05s031000")] = "haarea05s031000";
for (var wh = 1; wh < 8; wh++)
{
for (var sub = 1; sub < 4; sub++)
{
for (var n = 1; n < 7; n++)
{
result[FnvHash.HashFnv1a_64($"mainwhSpawner{wh:00}{sub:00}{n:00}")] = $"mainwhSpawner{wh:00}{sub:00}{n:00}";
result[FnvHash.HashFnv1a_64($"subwhSpawner{wh:00}{sub:00}{n:00}")] = $"subwhSpawner{wh:00}{sub:00}{n:00}";
}
}
}
return result;
}
public string NameSummary
{
get
{
var map = GetSpawnerNameMap();
if (map.TryGetValue(SpawnerID, out var name))
return $"\"{name}\"";
return $"0x{SpawnerID:X16}";
}
}
// lazy init
private static IReadOnlyDictionary<ulong, string>? groupNameMap;
private static IReadOnlyDictionary<ulong, string> GetGroupNameMap() => groupNameMap ??= GenerateGroupNameMap();
private static IReadOnlyDictionary<ulong, string> GenerateGroupNameMap()
{
var result = new Dictionary<ulong, string>();
for (var i = 0; i < 100; i++)
{
var reg = $"grp{i:00}";
var und = $"grp{i:00}";
result[FnvHash.HashFnv1a_64(und)] = und;
result[FnvHash.HashFnv1a_64(reg)] = reg;
}
result[0xCBF29CE484222645] = "";
return result;
}
public string GroupSummary
{
get
{
var map = GetGroupNameMap();
if (map.TryGetValue(GroupID, out var name))
return $"\"{name}\"";
return $"0x{GroupID:X16}";
}
}
public override string ToString() => $"Spawner({NameSummary}, 0x{Field01:X16}, {Parameters}, \"{Shape}\", {Scalar}, {Field05}, {Field06}, {MinSpawnCount}, {MaxSpawnCount}, {Field09}, {IsMassOutbreak}, {IsWater}, {IsSky}, /* Group = */ {GroupSummary}, {Field14}, {Field15}, {ParentLink}, {Field17}, {Field18}, {Field19}, {Field20Value}, {Field21Value}, {PathToFollowID})";
public bool UsesTable(ulong table) => Field20Value.EncounterTableID == table;
}

View File

@@ -0,0 +1,14 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PlacementSpawnerArchive { }

View File

@@ -0,0 +1,16 @@
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PlacementSpawnerF20 : IHasCondition
{
public override string ToString() => $"Spawn_20(/* EncounterTableId = */ {EncounterTable.GetTableName(EncounterTableID)}, /* ConditionTypeID = */ {this.GetConditionTypeSummary()}, /* Condition = */ {this.GetConditionSummary()}, {BonusLevelMin}, {BonusLevelMax})";
}

View File

@@ -1,7 +1,6 @@
using System;
using System.ComponentModel;
using System.Linq;
using FlatSharp.Attributes;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
@@ -10,24 +9,11 @@
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers;
namespace pkNX.Structures.FlatBuffers.Arceus;
[FlatBufferTable, TypeConverter(typeof(ExpandableObjectConverter))]
public class PlacementSpawnerF218a
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PlacementSpawnerF21
{
[FlatBufferItem(0)] public ulong VarHash0 { get; set; }
[FlatBufferItem(1)] public ulong VarHash1 { get; set; } // Sometimes contains Slot ID from specific encounter table specified by the F20 in the same Spawner?
[FlatBufferItem(2)] public ulong VarHash2 { get; set; } // Sometimes contains Slot ID from specific encounter table specified by the F20 in the same Spawner?
[FlatBufferItem(3)] public ulong VarHash3 { get; set; } // ??? Is this as 01/02?
[FlatBufferItem(4)] public ulong VarHash4 { get; set; } // ??? Is this as 01/02?
[FlatBufferItem(5)] public ulong VarHash5 { get; set; } // ??? Is this as 01/02?
[FlatBufferItem(6)] public Vec3f Field_06 { get; set; } = new();
[FlatBufferItem(7)] public string Field_07 { get; set; } = string.Empty;
[FlatBufferItem(8)] public float Scalar { get; set; }
[FlatBufferItem(9)] public Vec3f Field_09 { get; set; } = new();
[FlatBufferItem(10)] public Vec3f Field_10 { get; set; } = new();
[FlatBufferItem(11)] public int NumVarHashes { get; set; }
public string SlotSummary
{
get
@@ -50,11 +36,11 @@ public string SlotSummary
if (NumVarHashes == 1)
throw new ArgumentException("Invalid NumVarHashes!");
var slots = rawSlots.Skip(1).Take(NumVarHashes - 1).Select(EncounterSlot8a.GetSlotName);
var slots = rawSlots.Skip(1).Take(NumVarHashes - 1).Select(EncounterSlot.GetSlotName);
return $"/* Slots = */ 0x{VarHash0:X16}({string.Join(", ", slots)})";
}
}
public override string ToString() => $"Spawn_21({SlotSummary}, {Field_06}, \"{Field_07}\", {Scalar}, {Field_09}, {Field_10})";
public override string ToString() => $"Spawn_21({SlotSummary}, {Field06}, \"{Field07}\", {Scalar}, {Field09}, {Field10})";
}

View File

@@ -0,0 +1,60 @@
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PlacementUnnnTable { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PlacementUnnnEntry
{
public PlacementParameters Parameters
{
get { if (Field03.Count != 1) throw new ArgumentException($"Invalid {nameof(Field03)}"); return Field03[0]; }
set { if (Field03.Count != 1) throw new ArgumentException($"Invalid {nameof(Field03)}"); Field03[0] = value; }
}
public IEnumerable<PlacementLocation> GetIntersectingLocations(IList<PlacementLocation> locations, float bias)
{
var c = Parameters.Coordinates;
return GetIntersectingLocations(locations, bias, c, 0);
}
private static IEnumerable<PlacementLocation> GetIntersectingLocations(IList<PlacementLocation> locations, float bias, Vec3f c, float scalar)
{
var result = new List<PlacementLocation>();
foreach (var loc in locations)
{
if (!loc.IsNamedPlace)
continue;
if (loc.IntersectsSphere(c.X, c.Y, c.Z, scalar + bias))
result.Add(loc);
}
if (result.Count == 0)
result.Add(locations.First(l => l.IsNamedPlace)); // base area name
return result;
}
public IEnumerable<PlacementLocation> GetContainingLocations(IList<PlacementLocation> locations)
{
var result = new List<PlacementLocation>();
foreach (var loc in locations)
{
if (!loc.IsNamedPlace)
continue;
if (loc.Contains(Parameters.Coordinates))
result.Add(loc);
}
if (result.Count == 0)
result.Add(locations.First(l => l.IsNamedPlace)); // base area name
return result;
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class AreaBGMTable { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class AreaBGM { }

View File

@@ -0,0 +1,48 @@
using pkNX.Containers;
namespace pkNX.Structures.FlatBuffers.Arceus;
// Not a FlatBuffer; wraps the fields into a single object.
public sealed class AreaInstance
{
// Area Info
private readonly ResidentArea Area;
public readonly AreaInstance? ParentArea;
private readonly List<AreaInstance> Children = new();
public bool IsSubArea => ParentArea != null;
public IReadOnlyList<AreaInstance> SubAreas => Children;
public string AreaName => Area.AreaName;
public string FriendlyAreaName => Area.FriendlyAreaName;
// Encount
public IList<EncounterTable> Encounters => Area.Encounters.Table;
public IList<PlacementLocation> Locations => Area.Locations.Table;
public IList<PlacementSpawner> Spawners => Area.Spawners.Table;
public IList<PlacementSpawner> Wormholes => Area.Wormholes.Table;
public IList<LandmarkItemSpawn> LandItems => Area.LandItems.Table;
public IList<LandmarkItem> LandMarks => Area.LandMarks.Table;
public IList<PlacementUnnnEntry> Unown => Area.Unown.Table;
public IList<PlacementMkrgEntry> Mikaruge => Area.Mikaruge.Table;
public IList<PlacementSearchItem> SearchItem => Area.SearchItem.Table;
private AreaInstance(GFPack resident, AreaSettings settings, AreaInstance? parentArea = null)
{
// General area properties
Area = new ResidentArea(resident, settings);
ParentArea = parentArea;
Area.LoadInfo();
}
public static AreaInstance Create(GFPack resident, ResidentAreaSet areaNameList, AreaSettingsTable settingsTable)
{
var parentSettings = settingsTable.Find(areaNameList.ParentName);
var parent = new AreaInstance(resident, parentSettings);
foreach (var child in areaNameList.SubAreas)
{
var childSettings = settingsTable.Find(child);
parent.Children.Add(new AreaInstance(resident, childSettings, parent));
}
return parent;
}
}

View File

@@ -0,0 +1,44 @@
using System;
using System.ComponentModel;
using System.Linq;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class AreaSettingsTable
{
public AreaSettings Find(string name) => Table.First(z => z.Name == name);
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class AreaSettings
{
// Get the in game name of the area
public string FriendlyAreaName
{
get
{
return Name switch
{
"ha_area00" => "Jubilife Village",
"ha_area01" => "Obsidian Fieldlands",
"ha_area02" => "Crimson Mirelands",
"ha_area03" => "Cobalt Coastlands",
"ha_area04" => "Coronet Highlands",
"ha_area05" => "Alabaster Icelands",
"ha_area06" => "Ancient Retreat",
_ => $"Unknown Area ({Name})",
};
}
}
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class AreaSettings_F50 { }

View File

@@ -0,0 +1,20 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class AreaWeatherTable { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class AreaWeather
{
public int WeightTotal => WeightSunny + WeightCloudy + WeightRain + WeightSnow + WeightDrought + WeightFog + WeightRainstorm + WeightSnowstorm;
}

View File

@@ -0,0 +1,92 @@
using System.Buffers;
using FlatSharp;
using pkNX.Containers;
namespace pkNX.Structures.FlatBuffers.Arceus;
// Not a FlatBuffer; wraps the fields into a single object.
public sealed class ResidentArea
{
public readonly AreaSettings Settings;
private readonly GFPack Resident;
public ResidentArea(GFPack resident, AreaSettings settings)
{
Resident = resident;
Settings = settings;
}
public string AreaName => Settings.Name;
public string FriendlyAreaName => Settings.FriendlyAreaName;
// Encount
public EncounterDataArchive Encounters { get; private set; } = null!;
// Placement
public PlacementLocationArchive Locations { get; private set; } = null!;
public PlacementSpawnerArchive Spawners { get; private set; } = null!;
public PlacementSpawnerArchive Wormholes { get; private set; } = null!;
public LandmarkItemSpawnTable LandItems { get; private set; } = null!;
public LandmarkItemTable LandMarks { get; private set; } = null!;
public PlacementUnnnTable Unown { get; private set; } = null!;
public PlacementMkrgTable Mikaruge { get; private set; } = null!;
public PlacementSearchItemTable SearchItem { get; private set; } = null!;
private T TryRead<T>(string path) where T : class, IFlatBufferSerializable<T>
{
var index = Resident.GetIndexFull(path);
if (index == -1)
throw new ArgumentOutOfRangeException(nameof(path));
var data = Resident[index];
return T.GreedyMutableSerializer.Parse(data);
}
private static byte[] Write<T>(T obj) where T : class, IFlatBufferSerializable<T>
{
var pool = ArrayPool<byte>.Shared;
var serializer = obj.Serializer;
var data = pool.Rent(serializer.GetMaxSize(obj));
var len = serializer.Write(data, obj);
var result = data.AsSpan(0, len).ToArray();
pool.Return(data);
return result;
}
private void TryWrite<T>(string path, T obj) where T : class, IFlatBufferSerializable<T>
{
var index = Resident.GetIndexFull(path);
if (index == -1)
return;
byte[] result = Write(obj);
Resident[index] = result;
}
public void LoadInfo()
{
// Load encount
Encounters = TryRead<EncounterDataArchive >(Settings.Encounters);
Locations = TryRead<PlacementLocationArchive >(Settings.Locations);
Spawners = TryRead<PlacementSpawnerArchive >(Settings.Spawners);
Wormholes = TryRead<PlacementSpawnerArchive >(Settings.WormholeSpawners);
LandItems = TryRead<LandmarkItemSpawnTable >(Settings.LandmarkItemSpawns);
LandMarks = TryRead<LandmarkItemTable >(Settings.LandmarkItems);
Unown = TryRead<PlacementUnnnTable >(Settings.UnownSpawners);
Mikaruge = TryRead<PlacementMkrgTable >(Settings.Mkrg);
SearchItem = TryRead<PlacementSearchItemTable >(Settings.SearchItem);
}
public void SaveInfo()
{
TryWrite(Settings.Encounters, Encounters);
TryWrite(Settings.Locations, Locations);
TryWrite(Settings.Spawners, Spawners);
TryWrite(Settings.WormholeSpawners, Wormholes);
TryWrite(Settings.LandmarkItemSpawns, LandItems);
TryWrite(Settings.LandmarkItems, LandMarks);
TryWrite(Settings.UnownSpawners, Unown);
TryWrite(Settings.Mkrg, Mikaruge);
TryWrite(Settings.SearchItem, SearchItem);
}
}

View File

@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
namespace pkNX.Structures.FlatBuffers;
namespace pkNX.Structures.FlatBuffers.Arceus;
/// <summary>
/// Manually entered metadata about the interesting areas.

View File

@@ -0,0 +1,179 @@
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class EncounterDataArchive { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class EncounterEligiblityTraits : IHasCondition, ISlotModifierTime, ISlotModifierWeather
{
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class EncounterOybnTraits
{
public bool IsOybnAny => Oybn1 || Oybn2 || Field02 || Field03;
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class EncounterTable
{
// lazy init
private static Dictionary<ulong, string>? _tableNameMap;
private static IReadOnlyDictionary<ulong, string> GetTableNameMap() => _tableNameMap ??= GenerateTableMap();
private static Dictionary<ulong, string> GenerateTableMap()
{
var result = new Dictionary<ulong, string>
{
[0xCBF29CE484222645] = "",
};
var prefixes = new[] { "eve", "fly", "gmk", "lnd", "mas", "oyb", "swm", "whl" };
var kinds = new[] { "ex", "no", "ra" };
foreach (var prefix in prefixes)
{
foreach (var kind in kinds)
{
for (var i = 0; i < 150; i++)
{
var name = $"{prefix}_{kind}_{i:00}";
var hash = FnvHash.HashFnv1a_64(name);
result[hash] = name;
}
}
}
for (var area = 0; area < 6; area++)
{
for (var i = 0; i < 10; i++)
{
result[FnvHash.HashFnv1a_64($"sky_area{area}_{i:00}")] = $"sky_area{area}_{i:00}";
}
}
result[FnvHash.HashFnv1a_64("eve_ex_16_b")] = "eve_ex_16_b";
result[FnvHash.HashFnv1a_64("eve_ex_17_b")] = "eve_ex_17_b";
result[FnvHash.HashFnv1a_64("eve_ex_18_b")] = "eve_ex_18_b";
var gimmicks = new[] { "no", "tree", "rock", "crystal", "snow", "box" };
foreach (var gimmick in gimmicks)
{
for (var i = 0; i < 100; i++)
{
result[FnvHash.HashFnv1a_64($"gmk_{gimmick}_{i:00}")] = $"gmk_{gimmick}_{i:00}";
for (var j = 0; j < 3; j++)
{
result[FnvHash.HashFnv1a_64($"gmk_{gimmick}_{i:00}_{j:00}")] = $"gmk_{gimmick}_{i:00}_{j:00}";
for (var k = 0; k < 3; k++)
{
result[FnvHash.HashFnv1a_64($"gmk_{gimmick}_{i:00}{j:00}_{k:00}")] = $"gmk_{gimmick}_{i:00}{j:00}_{k:00}";
}
}
}
}
return result;
}
public static string GetTableName(ulong tableId)
{
var map = GetTableNameMap();
if (map.TryGetValue(tableId, out var name))
return $"\"{name}\"";
return $"0x{tableId:X16}";
}
public string TableName => GetTableName(TableID);
public override string ToString() => $"{TableName} (Lv. {MinLevel}-{MaxLevel})";
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class EncounterSlot
{
public override string ToString() => $"{(Species)Species}{(Form == 0 ? "" : $"-{Form}")}{(Oybn.IsOybnAny ? "*" : "")} - {BaseProbability}={ShinyLock}";
public (bool forced, int min, int max) GetLevels(int min, int max)
{
bool force = false;
if (OverrideMinLevel is > 0 and <= 100)
{
force = true;
min = OverrideMinLevel;
}
if (OverrideMaxLevel is > 0 and <= 100)
{
force = true;
max = OverrideMaxLevel;
}
return (force, min, max);
}
public float GetTimeModifier(int time, EncounterMultiplier default_mults)
{
// If the slot has defined an override factor, use it; otherwise, fall back on the default multiplier for (species, form).
if (Eligibility.HasTimeModifier(time))
return Eligibility.GetTimeMultiplier(time);
if (default_mults.HasTimeModifier(time))
return default_mults.GetTimeMultiplier(time);
return 1.0f;
}
public float GetWeatherModifier(int weather, EncounterMultiplier default_mults)
{
// If the slot has defined an override factor, use it; otherwise, fall back on the default multiplier for (species, form).
if (Eligibility.HasWeatherModifier(weather))
return Eligibility.GetWeatherMultiplier(weather);
if (default_mults.HasWeatherModifier(weather))
return default_mults.GetWeatherMultiplier(weather);
return 1.0f;
}
// lazy init
private static Dictionary<ulong, string>? _slotNameMap;
private static IReadOnlyDictionary<ulong, string> GetSlotNameMap() => _slotNameMap ??= GenerateTableMap();
private static Dictionary<ulong, string> GenerateTableMap()
{
var result = new Dictionary<ulong, string>();
for (var i = 0; i < 1000; i++)
{
var life = $"life{i:000}";
var pm = $"pm{i:0000}";
result[FnvHash.HashFnv1a_64(life)] = life;
result[FnvHash.HashFnv1a_64(pm)] = pm;
}
for (var i = 0; i < 100; i++)
{
var poke = $"poke{i:00}";
result[FnvHash.HashFnv1a_64(poke)] = poke;
}
return result;
}
public static string GetSlotName(ulong slotId)
{
var map = GetSlotNameMap();
if (map.TryGetValue(slotId, out var name))
return $"\"{name}\"";
return $"0x{slotId:X16}";
}
public string SlotName => GetSlotName(SlotID);
public void ClearMoves()
{
Move1 = Move2 = Move3 = Move4 = 0;
Move1Mastered = Move2Mastered = Move3Mastered = Move4Mastered = false;
}
}

View File

@@ -0,0 +1,76 @@
using System.ComponentModel;
using System.Diagnostics;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class EncounterMultiplier : ISlotModifierTime, ISlotModifierWeather
{
public float GetTimeMultiplier(int index) => index switch
{
0 => TimeOfDayMultiplier0,
1 => TimeOfDayMultiplier1,
2 => TimeOfDayMultiplier2,
3 => TimeOfDayMultiplier3,
_ => throw new ArgumentOutOfRangeException(nameof(index)),
};
public float GetWeatherMultiplier(int index) => index switch
{
0 => 1.0f, // "No Weather" results in no modification of rate for all species/forms
1 => WeatherMultiplier1,
2 => WeatherMultiplier2,
3 => WeatherMultiplier3,
4 => WeatherMultiplier4,
5 => WeatherMultiplier5,
6 => WeatherMultiplier6,
7 => WeatherMultiplier7,
8 => WeatherMultiplier8,
_ => throw new ArgumentOutOfRangeException(nameof(index)),
};
public bool HasTimeModifier(int index) => GetTimeMultiplier(index) != -1.0f;
public bool HasWeatherModifier(int index) => index != 0 && GetWeatherMultiplier(index) != -1.0f;
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class EncounterMultiplierArchive
{
public EncounterMultiplier GetEncounterMultiplier(EncounterSlot slot)
{
var result = GetEntry((ushort)slot.Species, (ushort)slot.Form);
if (result == null)
throw new ArgumentException($"Invalid Encounter Slot {slot.Species} - {slot.Form}");
return result;
}
public EncounterMultiplier GetEntry(ushort species, ushort form)
{
return Table.FirstOrDefault(x => x.Species == species && x.Form == form) ??
new EncounterMultiplier();
}
public bool HasEntry(ushort species, ushort form)
{
return Table.Any(x => x.Species == species && x.Form == form);
}
public EncounterMultiplier AddEntry(ushort species, ushort form)
{
Debug.Assert(!HasEntry(species, form), "The encounter rate table already contains an entry for the same species and form!");
var entry = new EncounterMultiplier { Species = species, Form = form };
Table = Table.Append(entry)
.OrderBy(x => x.Species)
.ThenBy(x => x.Form)
.ToArray();
return entry;
}
}

View File

@@ -1,23 +1,23 @@
using System;
namespace pkNX.Structures.FlatBuffers;
namespace pkNX.Structures.FlatBuffers.Arceus;
public interface ISlotModifierTime
{
float TimeOfDayMultiplier_0 { get; set; }
float TimeOfDayMultiplier_1 { get; set; }
float TimeOfDayMultiplier_2 { get; set; }
float TimeOfDayMultiplier_3 { get; set; }
float TimeOfDayMultiplier0 {get;set;}
float TimeOfDayMultiplier1 {get;set;}
float TimeOfDayMultiplier2 {get;set;}
float TimeOfDayMultiplier3 {get;set;}
}
public static class SlotModifierTimeExtensions
{
public static float GetTimeMultiplier(this ISlotModifierTime x, int index) => index switch
{
0 => x.TimeOfDayMultiplier_0,
1 => x.TimeOfDayMultiplier_1,
2 => x.TimeOfDayMultiplier_2,
3 => x.TimeOfDayMultiplier_3,
0 => x.TimeOfDayMultiplier0,
1 => x.TimeOfDayMultiplier1,
2 => x.TimeOfDayMultiplier2,
3 => x.TimeOfDayMultiplier3,
_ => throw new ArgumentOutOfRangeException(nameof(index)),
};

View File

@@ -0,0 +1,34 @@
using System;
namespace pkNX.Structures.FlatBuffers.Arceus;
public interface ISlotModifierWeather
{
float WeatherMultiplier1 {get; set;}
float WeatherMultiplier2 {get; set;}
float WeatherMultiplier3 {get; set;}
float WeatherMultiplier4 {get; set;}
float WeatherMultiplier5 {get; set;}
float WeatherMultiplier6 {get; set;}
float WeatherMultiplier7 {get; set;}
float WeatherMultiplier8 {get; set;}
}
public static class SlotModifierWeatherExtensions
{
public static float GetWeatherMultiplier(this ISlotModifierWeather x, int index) => index switch
{
0 => 1.0f, // "No Weather" results in no modification of rate for all species/forms
1 => x.WeatherMultiplier1,
2 => x.WeatherMultiplier2,
3 => x.WeatherMultiplier3,
4 => x.WeatherMultiplier4,
5 => x.WeatherMultiplier5,
6 => x.WeatherMultiplier6,
7 => x.WeatherMultiplier7,
8 => x.WeatherMultiplier8,
_ => throw new ArgumentOutOfRangeException(nameof(index)),
};
public static bool HasWeatherModifier(this ISlotModifierWeather w, int index) => index != 0 && w.GetWeatherMultiplier(index) != -1.0f;
}

View File

@@ -0,0 +1,41 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class EventEncount { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class EventEncountArchive { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class EventEncountPoke
{
public bool HasMoveset => Move1 != 0;
public bool HasGVs => GVHP != 0 || GVATK != 0 || GVDEF != 0 || GVSPA != 0 || GVSPD != 0 || GVSPE != 0;
public string Dump(string[] speciesNames, string argEncounterName)
{
var natureStr = Nature == NatureType.Random ? "" : $", Nature = (int){(NatureType)Nature}";
var shinyStr = $", Shiny = {ShinyLock}";
var gvStr = "";
if (HasGVs)
gvStr = $", GVs = new[]{{{GVHP},{GVATK},{GVDEF},{GVSPE},{GVSPA},{GVSPD}}}";
var moves = !HasMoveset ? "" : $", Moves = new[] {{{Move1:000},{Move2:000},{Move3:000},{Move4:000}}}";
var mastery = !HasMoveset ? "" : $", Mastery = new[] {{{Mastered1.ToString().ToLower()},{Mastered2.ToString().ToLower()},{Mastered3.ToString().ToLower()},{Mastered4.ToString().ToLower()}}}";
var alpha = !IsOybn ? "" : ", IsAlpha = true";
var genderStr = Gender == -1 ? "" : $", Gender = {Gender}";
var iv = NumPerfectIvs == 0 ? "" : $", FlawlessIVCount = {NumPerfectIvs}";
string comment = $"// {argEncounterName}: {speciesNames[Species]}{(Form == 0 ? "" : $"-{Form}")}";
return $"new({Species:000},{Form:000},{Level:00},{Height},{Weight}) {{ Location = -01{shinyStr}{alpha}{genderStr}{natureStr}{iv}{gvStr}{moves}{mastery} }}, {comment}";
}
}

View File

@@ -0,0 +1,72 @@
using System.ComponentModel;
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class Vec3f : IEquatable<Vec3f>
{
public static readonly Vec3f Zero = new();
public static readonly Vec3f One = new(1, 1, 1);
public Vec3f(float x = 0, float y = 0, float z = 0)
{
X = x;
Y = y;
Z = z;
}
public bool IsOne => X is 1 && Y is 1 && Z is 1;
public bool IsZero => X is 0 && Y is 0 && Z is 0;
public float Magnitude => MathF.Sqrt(MagnitudeSqr);
public float MagnitudeSqr => Dot(this);
public Vec3f Normalized() => this * (1 / Magnitude);
public float Dot(Vec3f other) => X * other.X + Y * other.Y + Z * other.Z;
public Vec3f Cross(Vec3f other) => new(Y * other.Z - Z * other.Y, Z * other.X - X * other.Z, X * other.Y - Y * other.X);
public float DistanceTo(Vec3f other) => (this - other).Magnitude;
public float DistanceToSqr(Vec3f other) => (this - other).MagnitudeSqr;
public Vec3f Lerp(Vec3f other, float t) => this + (other - this) * t;
public Vec3f Clone() => new()
{
X = X,
Y = Y,
Z = Z,
};
public override string ToString() => $"V3f({X}, {Y}, {Z})";
public string ToTriple() => $"({X}, {Y}, {Z})";
public bool Equals(Vec3f? other)
{
if (other is null) return false;
if (ReferenceEquals(this, other)) return true;
return X.Equals(other.X) && Y.Equals(other.Y) && Z.Equals(other.Z);
}
public override bool Equals(object? obj)
{
if (obj is null) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((Vec3f)obj);
}
public override int GetHashCode() => HashCode.Combine(X, Y, Z);
public static Vec3f operator -(Vec3f v) => new(-v.X, -v.Y, -v.Z);
public static Vec3f operator +(Vec3f l, Vec3f r) => new(l.X + r.X, l.Y + r.Y, l.Z + r.Z);
public static Vec3f operator -(Vec3f l, Vec3f r) => new(l.X - r.X, l.Y - r.Y, l.Z - r.Z);
public static Vec3f operator *(Vec3f l, Vec3f r) => new(l.X * r.X, l.Y * r.Y, l.Z * r.Z);
public static Vec3f operator /(Vec3f l, Vec3f r) => new(l.X / r.X, l.Y / r.Y, l.Z / r.Z);
public static Vec3f operator +(Vec3f l, float r) => new(l.X + r, l.Y + r, l.Z + r);
public static Vec3f operator -(Vec3f l, float r) => new(l.X - r, l.Y - r, l.Z - r);
public static Vec3f operator *(Vec3f l, float r) => new(l.X * r, l.Y * r, l.Z * r);
public static Vec3f operator /(Vec3f l, float r) => new(l.X / r, l.Y / r, l.Z / r);
public static bool operator ==(Vec3f? left, Vec3f? right) => Equals(left, right);
public static bool operator !=(Vec3f? left, Vec3f? right) => !Equals(left, right);
}

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class KeyAssignmentTable { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class KeyAssignment { }

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class LbPointsTable { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class LbPointsInfo { }

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class MoveShopTable { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class MoveShopIndex { }

View File

@@ -0,0 +1,22 @@
using System;
using System.ComponentModel;
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class NPCModelSet { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class NPCModelSetEntry { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class NPCModelAnimations { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class NPCModelMeshes { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class NPCModelRigs { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class NPCModelColorConfig { }

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PlayReportTable { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PlayReportItem { }

View File

@@ -1,7 +1,4 @@
using System;
using System.ComponentModel;
using System.IO;
using FlatSharp.Attributes;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
@@ -10,26 +7,20 @@
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers;
namespace pkNX.Structures.FlatBuffers.Arceus;
[FlatBufferTable, TypeConverter(typeof(ExpandableObjectConverter))]
public class EvolutionTable8 : IFlatBufferArchive<EvolutionSet8a>
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class EvolutionTable { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class EvolutionEntry { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class EvolutionSet
{
public byte[] Write() => FlatBufferConverter.SerializeFrom(this);
[FlatBufferItem(0)] public EvolutionSet8a[] Table { get; set; } = Array.Empty<EvolutionSet8a>();
}
[FlatBufferTable, TypeConverter(typeof(ExpandableObjectConverter))]
public class EvolutionSet8a
{
[FlatBufferItem(0)] public ushort Species { get; set; }
[FlatBufferItem(1)] public ushort Form { get; set; }
[FlatBufferItem(2)] public EvolutionEntry8a[] Table { get; set; } = Array.Empty<EvolutionEntry8a>();
public byte[] Write()
{
if (Table.Length == 0)
if (Table is null || Table.Count == 0)
return Array.Empty<byte>();
using var ms = new MemoryStream();
@@ -58,13 +49,3 @@ public byte[] Write()
};
}
}
[FlatBufferTable, TypeConverter(typeof(ExpandableObjectConverter))]
public class EvolutionEntry8a
{
[FlatBufferItem(0)] public ushort Method { get; set; }
[FlatBufferItem(1)] public ushort Argument { get; set; }
[FlatBufferItem(2)] public ushort Species { get; set; }
[FlatBufferItem(3)] public ushort Form { get; set; }
[FlatBufferItem(4)] public ushort Level { get; set; }
}

View File

@@ -0,0 +1,48 @@
using System;
using System.ComponentModel;
using System.IO;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class Learnset { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class LearnsetEntry { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class LearnsetMeta
{
public byte[] WriteLearnsetAsLearn6()
{
using var ms = new MemoryStream();
using var br = new BinaryWriter(ms);
foreach (var entry in Arceus)
{
br.Write(entry.Move);
br.Write(entry.Level);
}
br.Write(-1);
return ms.ToArray();
}
public byte[] WriteMasteryAsLearn6()
{
using var ms = new MemoryStream();
using var br = new BinaryWriter(ms);
foreach (var entry in Arceus)
{
br.Write(entry.Move);
br.Write(entry.LevelMaster);
}
br.Write(-1);
return ms.ToArray();
}
}

View File

@@ -0,0 +1,44 @@
using System.ComponentModel;
using System.Diagnostics;
namespace pkNX.Structures.FlatBuffers.Arceus;
// resident_release.bin -> bin/field/param/placement/common/pokemon_model_set.bin
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeModelSet
{
public PokeModelSetEntry GetEntry(ushort species)
{
return Table.FirstOrDefault(z => z.Species == species) ?? new ()
{
VariantDesc = string.Empty,
};
}
public bool HasEntry(ushort species)
{
return Table.Any(x => x.Species == species);
}
public PokeModelSetEntry AddEntry(ushort species, ushort form)
{
Debug.Assert(!HasEntry(species), "The resource info table already contains an entry for the same species!");
var entry = new PokeModelSetEntry
{
Species = species,
Form = form,
VariantDesc = string.Empty,
PokeModelHash = FnvHash.HashFnv1a_64(""),
};
Table = Table.Append(entry)
.OrderBy(x => x.Species)
.ThenBy(x => x.Form)
.ToArray();
return entry;
}
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeModelSetEntry { }

View File

@@ -0,0 +1,23 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
/// <summary>
/// Personal Info class with values from the <see cref="GameVersion.PLA"/> games.
/// </summary>
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PersonalTable { }
/// <summary>
/// Personal Info class with values from the <see cref="GameVersion.PLA"/> games.
/// </summary>
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PersonalInfo { }

View File

@@ -0,0 +1,139 @@
using System.ComponentModel;
using System.Diagnostics;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeAIArchive
{
public PokeAI GetEntry(ushort species, ushort form)
{
return Table.FirstOrDefault(z => z.Species == species && z.Form == form) ?? PokeAI.GetNew();
}
public bool HasEntry(ushort species, ushort form, bool isAlpha)
{
return Table.Any(x => x.Species == species && x.Form == form && x.IsAlpha == isAlpha);
}
public PokeAI AddEntry(ushort species, ushort form, bool isAlpha)
{
Debug.Assert(!HasEntry(species, form, isAlpha), "The symbol behave table already contains an entry for the same species + form!");
var entry = PokeAI.GetNew(species, form, isAlpha);
Table = Table.Append(entry)
.OrderBy(x => x.Species)
.ThenBy(x => x.Form)
.ThenBy(x => x.IsAlpha)
.ToArray();
return entry;
}
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeAI
{
public static PokeAI GetNew(ushort species = 0, ushort form = 0, bool isAlpha = false) => new()
{
Species = species,
Form = form,
IsAlpha = isAlpha,
Behavior1 = string.Empty,
Behavior2 = string.Empty,
Behavior3 = string.Empty,
Field09 = PokeAI_F09.DefaultBehaviour_F09,
Field17 = PokeAI_F09.DefaultBehaviour_F09,
Field18 = new(),
Field19 = new(),
Field20 = new(),
Field21 = new(),
MoveEffect1 = string.Empty,
MoveEffect2 = string.Empty,
Field24 = new(),
Field27 = new(),
Field28 = new(),
Field29 = new(),
Field30 = new(),
};
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeAI_F24 { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeAI_F18 { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeAI_F09
{
public static readonly PokeAI_F09 DefaultBehaviour02 = new()
{
Field00 = new() { BehaviourHash = 9252365659083253459, Parameters = new[] { "0.5", "35" } },
Field01 = new() { BehaviourHash = 9252365659083253459, Parameters = new[] { "0.5", "35" } },
Field02 = new() { BehaviourHash = 9252365659083253459, Parameters = new[] { "0.5", "35" } },
Field03 = new() { BehaviourHash = 9252365659083253459, Parameters = new[] { "0.5", "35" } },
Field04 = new() { BehaviourHash = 9252365659083253459, Parameters = new[] { "0.5", "35" } },
Field05 = new() { BehaviourHash = 9252365659083253459, Parameters = new[] { "0.5", "35" } },
Field06 = new() { BehaviourHash = 9252365659083253459, Parameters = new[] { "0.5", "35" } },
Field07 = new() { BehaviourHash = 9252365659083253459, Parameters = new[] { "0.5", "35" } },
Field08 = new() { BehaviourHash = 9252365659083253459, Parameters = new[] { "0.5", "35" } },
};
public static readonly PokeAI_F09 DefaultBehaviour_F09 = new()
{
Field00 = PokeAIBehaviour.DefaultBehaviour02,
Field01 = PokeAIBehaviour.Behaviour_X_Params,
Field02 = PokeAIBehaviour.DefaultBehaviour02,
Field03 = PokeAIBehaviour.DefaultBehaviour02,
Field04 = PokeAIBehaviour.Behaviour_04_Params,
Field05 = PokeAIBehaviour.DefaultBehaviour02,
Field06 = PokeAIBehaviour.DefaultBehaviour02,
Field07 = PokeAIBehaviour.DefaultBehaviour02,
Field08 = PokeAIBehaviour.Behaviour_X2_Params,
};
public static readonly PokeAI_F09 DefaultBehaviour_F11 = new()
{
Field00 = PokeAIBehaviour.DefaultBehaviour02_20,
Field01 = PokeAIBehaviour.Behaviour_04_Params,
Field02 = PokeAIBehaviour.DefaultBehaviour02,
Field03 = PokeAIBehaviour.DefaultBehaviour02,
Field04 = PokeAIBehaviour.Behaviour_04_Params,
Field05 = PokeAIBehaviour.DefaultBehaviour02,
Field06 = PokeAIBehaviour.DefaultBehaviour02,
Field07 = PokeAIBehaviour.DefaultBehaviour02,
Field08 = PokeAIBehaviour.DefaultBehaviour02,
};
public static readonly PokeAI_F09 DefaultBehaviour05 = new()
{
Field00 = PokeAIBehaviour.DefaultBehaviour05,
Field01 = PokeAIBehaviour.DefaultBehaviour05,
Field02 = PokeAIBehaviour.DefaultBehaviour05,
Field03 = PokeAIBehaviour.DefaultBehaviour05,
Field04 = PokeAIBehaviour.Behaviour_04_Params,
Field05 = PokeAIBehaviour.DefaultBehaviour05,
Field06 = PokeAIBehaviour.DefaultBehaviour05,
Field07 = PokeAIBehaviour.DefaultBehaviour05,
Field08 = PokeAIBehaviour.DefaultBehaviour05,
};
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeAIBehaviour
{
public static readonly PokeAIBehaviour DefaultBehaviour02 = new() { BehaviourHash = 9252365659083253459, Parameters = new [] { "0.2", "35" } };
public static readonly PokeAIBehaviour DefaultBehaviour02_20 = new() { BehaviourHash = 9252365659083253459, Parameters = new [] { "0.2", "20" } };
public static readonly PokeAIBehaviour DefaultBehaviour05 = new() { BehaviourHash = 9252365659083253459, Parameters = new [] { "0.5", "35" } };
public static readonly PokeAIBehaviour Behaviour_X_Params = new() { BehaviourHash = 17205188591700921149, Parameters = new [] { "10", "3", "run", "Normal" } };
public static readonly PokeAIBehaviour Behaviour_X2_Params = new() { BehaviourHash = 17205188591700921149, Parameters = new [] { "10", "0.5", "run", "Normal" } };
public static readonly PokeAIBehaviour Behaviour_04_Params = new() { BehaviourHash = 1234775724179408742, Parameters = new [] { "3", "5", "60", "90", "4", "run", "Normal" } };
}

View File

@@ -0,0 +1,43 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeAddArchive { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeAdd
{
public string Dump(string[] speciesNames)
{
var natureStr = Nature == NatureType.Random ? "" : $", Nature = {Nature}";
var shinyStr = $", Shiny = {ShinyLock}";
var gvStr = "";
if (GVHP != 0)
gvStr += $", GV_HP = {GVHP}";
if (GVATK != 0)
gvStr += $", GV_ATK = {GVATK}";
if (GVDEF != 0)
gvStr += $", GV_DEF = {GVDEF}";
if (GVSPA != 0)
gvStr += $", GV_SPA = {GVSPA}";
if (GVSPD != 0)
gvStr += $", GV_SPD = {GVSPD}";
if (GVSPE != 0)
gvStr += $", GV_SPE = {GVSPE}";
var hw = $"HeightScalar = {Height:000}, WeightScalar = {Weight:000}";
var genderStr = Gender == -1 ? "" : $", Gender = {Gender}";
var iv = NumPerfectIvs == 0 ? "" : $", FlawlessIVCount = {NumPerfectIvs}";
string comment = $"// {speciesNames[Species]}{(Form == 0 ? "" : $"-{Form}")}";
return $"new({Species:000},{Form:000},{Level:00}) {{ Gift = true, {hw}{shinyStr}{genderStr}{natureStr}{iv}{gvStr} }}, {comment}";
}
}

View File

@@ -0,0 +1,20 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
/// <summary>
/// Seems to be a file left over from development. Only has test entries
/// </summary>
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeBattleSpawnArchive { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeBattleSpawn { }

View File

@@ -0,0 +1,20 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeBodyParticleArchive { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeBodyParticle { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeBodyParticle_F03 { }

View File

@@ -0,0 +1,75 @@
using System.ComponentModel;
using System.Diagnostics;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeCaptureCollision { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeCaptureCollider { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeCaptureCollisionArchive
{
public PokeCaptureCollision GetEntry(ushort species, ushort form)
{
return Table.FirstOrDefault(x => x.Species == species && x.Form == form) ?? new()
{
Colliders = new List<PokeCaptureCollider>(),
};
}
public bool HasEntry(ushort species, ushort form)
{
return Table.Any(x => x.Species == species && x.Form == form);
}
public PokeCaptureCollision AddEntry(ushort species, ushort form)
{
Debug.Assert(!HasEntry(species, form), "The encounter rate table already contains an entry for the same species and form!");
var entry = new PokeCaptureCollision
{
Species = species,
Form = form,
Colliders = new PokeCaptureCollider[]
{
new() {
Shape = "Capsule",
ShapeParameters = new[]{ 0.5f, 0.2f, 0, 0, 0, 0, 0, 0 },
SocketName = "waist",
Type = "Normal",
Field07 = string.Empty,
},
new() {
Shape = "Capsule",
ShapeParameters = new[]{ 0.5f, 0.2f, 0, 0, 0, 0, 0, 0 },
SocketName = string.Empty,
Type = "Pysics",
Field07 = string.Empty,
},
new() {
Shape = "Capsule",
ShapeParameters = new[]{ 0.5f, 0.2f, 0, 0, 0, 0, 0, 0 },
SocketName = "origin",
Type = "Barrier",
Field07 = string.Empty,
},
}
};
Table = Table.Append(entry)
.OrderBy(x => x.Species)
.ThenBy(x => x.Form)
.ToArray();
return entry;
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeDefaultLocatorArchive { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeDefaultLocator { }

View File

@@ -0,0 +1,20 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeDropItemArchive { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeDropItem
{
public string Dump(string[] itemNames) => $"{Hash:X16}\t{itemNames[RegularItem]}\t{RegularItemProbability}\t{itemNames[RareItem]}\t{RareItemProbability}";
}

View File

@@ -0,0 +1,20 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeDropItemBattleArchive { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeDropItemBattle
{
public string Dump(string[] n) => $"{RateItem1}\t{n[IndexItem1]}\t{RateItem2}\t{n[IndexItem2]}\t{RateItem3}\t{n[IndexItem3]}\t{RateItem4}\t{n[IndexItem4]}\t{RateItem5}\t{n[IndexItem5]}";
}

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeEatingHabitsArchive { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeEatingHabits { }

View File

@@ -0,0 +1,14 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeFieldObstructionWaza { }

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeFieldObstructionWazaNsLegendArchive { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeFieldObstructionWazaNsLegend { }

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeFieldObstructionWazaNsLegendEffectArchive { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeFieldObstructionWazaNsLegendEffect { }

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeFieldObstructionWazaSeArchive { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeFieldObstructionWazaSe { }

View File

@@ -0,0 +1,14 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeFieldObstructionWazaWildArchive { }

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeFieldObstructionWazaWildEffectArchive { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeFieldObstructionWazaWildEffect { }

View File

@@ -0,0 +1,14 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeFieldObstructionWazaWildWaterArchive { }

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeFieldObstructionWazaWildWaterEffectArchive { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeFieldObstructionWazaWildWaterEffect { }

View File

@@ -0,0 +1,50 @@
using System.ComponentModel;
using System.Diagnostics;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeMisc { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeMiscTable
{
public PokeMisc GetEntry(ushort species, ushort form)
{
return Table.FirstOrDefault(z => z.Species == species && z.Form == form) ?? new()
{
Value = $"{species}-{form} is not in {nameof(PokeMiscTable)}.",
Field10 = Array.Empty<uint>(),
};
}
public bool HasEntry(ushort species, ushort form)
{
return Table.Any(x => x.Species == species && x.Form == form);
}
public PokeMisc AddEntry(ushort species, ushort form)
{
Debug.Assert(!HasEntry(species, form), "The misc table already contains an entry for the same species + form!");
var entry = new PokeMisc
{
Value = $"{species}-{form} is not in {nameof(PokeMiscTable)}.",
Species = species,
Form = form,
Field10 = Array.Empty<uint>(),
};
Table = Table.Append(entry)
.OrderBy(x => x.Species)
.ThenBy(x => x.Form)
.ToArray();
return entry;
}
}

View File

@@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using FlatSharp.Attributes;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
@@ -12,55 +8,54 @@
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers;
namespace pkNX.Structures.FlatBuffers.Arceus;
// bin/appli/res_pokemon/list/pokemon_info_list.bin
[FlatBufferTable, TypeConverter(typeof(ExpandableObjectConverter))]
public class PokeInfoList8a : IFlatBufferArchive<PokeInfo8a>
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeInfoList
{
public byte[] Write() => FlatBufferConverter.SerializeFrom(this);
[FlatBufferItem(0)] public string DefaultIcon { get; set; } = string.Empty;
[FlatBufferItem(1)] public PokeInfo8a[] Table { get; set; } = Array.Empty<PokeInfo8a>();
public PokeInfo8a GetEntry(ushort species)
public PokeInfo GetEntry(ushort species)
{
return Array.Find(Table, z => z.Species == species) ??
new PokeInfo8a();
return Table.FirstOrDefault(z => z.Species == species) ?? new()
{
Species = species,
Children = Array.Empty<PokeInfoDetail>(),
};
}
public bool HasEntry(ushort species)
{
return Array.Exists(Table, x => x.Species == species);
return Table.Any(x => x.Species == species);
}
public PokeInfo8a AddEntry(ushort species, byte formCount)
public PokeInfo AddEntry(ushort species, byte formCount)
{
Debug.Assert(!HasEntry(species), "The resource info table already contains an entry for the same species!");
var entry = new PokeInfo8a
var entry = new PokeInfo
{
Species = species,
Children = new PokeInfoDetail8a[formCount]
Children = new PokeInfoDetail[formCount],
};
int genderId = 0;
for (int form = 0; form < formCount; form++)
{
entry.Children[form] = new PokeInfoDetail8a
entry.Children[form] = new PokeInfoDetail
{
Form = form,
Detail = new PokeInfoDetail8a_2[]
Detail = new PokeInfoDetail_2[]
{
new() {
IsRare = false,
Detail = new PokeInfoDetail8a_3[] {
Detail = new PokeInfoDetail_3[] {
new() {
Detail = new PokeInfoDetail8a_5[] {
Detail = new PokeInfoDetail_5[] {
new() {
AssetName = $"{species:0000}_{genderId:000}_{form:000}_n_00000000_fn_n",
Gender = new PokeInfoGender(),
}
}
}
@@ -68,11 +63,12 @@ public PokeInfo8a AddEntry(ushort species, byte formCount)
},
new() {
IsRare = true, // Shiny form
Detail = new PokeInfoDetail8a_3[] {
Detail = new PokeInfoDetail_3[] {
new() {
Detail = new PokeInfoDetail8a_5[] {
Detail = new PokeInfoDetail_5[] {
new() {
AssetName = $"{species:0000}_{genderId:000}_{form:000}_n_00000000_fn_r",
Gender = new PokeInfoGender(),
}
}
}
@@ -136,54 +132,20 @@ public IEnumerable<int> GetDexFormEntries()
}
}
[FlatBufferTable, TypeConverter(typeof(ExpandableObjectConverter))]
public class PokeInfo8a
{
[FlatBufferItem(00)] public int Species { get; set; }
[FlatBufferItem(01)] public PokeInfoDetail8a[] Children { get; set; } = Array.Empty<PokeInfoDetail8a>();
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeInfo { }
[FlatBufferTable, TypeConverter(typeof(ExpandableObjectConverter))]
public class PokeInfoDetail8a
{
[FlatBufferItem(00)] public int Form { get; set; }
[FlatBufferItem(01)] public PokeInfoDetail8a_2[] Detail { get; set; } = Array.Empty<PokeInfoDetail8a_2>();
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeInfoDetail { }
[FlatBufferTable, TypeConverter(typeof(ExpandableObjectConverter))]
public class PokeInfoDetail8a_2
{
[FlatBufferItem(00)] public bool IsRare { get; set; }
[FlatBufferItem(01)] public PokeInfoDetail8a_3[] Detail { get; set; } = Array.Empty<PokeInfoDetail8a_3>();
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeInfoDetail_2 { }
[FlatBufferTable, TypeConverter(typeof(ExpandableObjectConverter))]
public class PokeInfoDetail8a_3
{
[FlatBufferItem(00)] public bool Unknown { get; set; }
[FlatBufferItem(01)] public PokeInfoDetail8a_5[] Detail { get; set; } = Array.Empty<PokeInfoDetail8a_5>();
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeInfoDetail_3 { }
[FlatBufferTable, TypeConverter(typeof(ExpandableObjectConverter))]
public class PokeInfoDetail8a_5
{
[FlatBufferItem(00)] public PokeInfoGender8a Gender { get; set; } = new();
[FlatBufferItem(01)] public string AssetName { get; set; } = string.Empty;
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeInfoDetail_5 { }
[FlatBufferTable, TypeConverter(typeof(ExpandableObjectConverter))]
public class PokeInfoGender8a
{
[FlatBufferItem(00)] public PokeInfoGender GenderValue { get; set; } = PokeInfoGender.DualGenderNoDifference;
}
[FlatBufferEnum(typeof(byte))]
public enum PokeInfoGender : byte
{
GenderDiffMale,
GenderDiffFemale,
Genderless,
DualGenderNoDifference,
MaleOnly,
FemaleOnly,
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeInfoGender { }

View File

@@ -0,0 +1,92 @@
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
// poke_resource_table.trpmcatalog
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeResourceMeta { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeModelConfig { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeModelMeta { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class AnimationConfigStringTuple { }
/// <summary> <see cref="PokeResourceTable"/> for Legends: Arceus, adding <see cref="PokeModelConfig.ArceusType"/></summary>
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokeResourceTable
{
public PokeModelConfig GetEntry(ushort species, ushort form, byte gender)
{
return Table.FirstOrDefault(x => x.Meta.Species == species && x.Meta.Form == form && x.Meta.Gender == gender) ?? new()
{
Animations = Array.Empty<AnimationConfigStringTuple>(),
Meta = new PokeModelMeta(),
PathModel = string.Empty,
PathMeshMaterial = string.Empty,
PathConfig = string.Empty,
Effects = Array.Empty<AnimationConfigStringTuple>(),
};
}
public bool HasEntry(ushort species, ushort form, byte gender)
{
return Table.Any(x => x.Meta.Species == species && x.Meta.Form == form && x.Meta.Gender == gender);
}
public PokeModelConfig AddEntry(ushort species, ushort form, byte gender)
{
Debug.Assert(!HasEntry(species, form, gender), "The resource info table already contains an entry for the same species!");
string pmStr = $"pm{species:0000}_{gender:00}_{form:00}";
string basePath = $"bin/pokemon/pm{species:0000}/{pmStr}";
var entry = new PokeModelConfig
{
Meta = new()
{
Species = species,
Form = form,
Gender = gender,
},
PathModel = $"{basePath}/mdl/{pmStr}.trmdl",
PathMeshMaterial = $"{basePath}/mdl/{pmStr}.trmmt",
PathConfig = $"{basePath}/{pmStr}.trpokecfg",
Animations = new AnimationConfigStringTuple[] {
new(){
Name = "base",
Path = $"{basePath}/anm/{pmStr}_base.tracn",
}
},
Effects = new AnimationConfigStringTuple[] {
new() {
Name = "eff",
Path = $"{basePath}/locators/{pmStr}_eff.trskl",
}
},
};
Table = Table.Append(entry)
.OrderBy(x => x.Meta.Species)
.ThenBy(x => x.Meta.Form)
.ThenBy(x => x.Meta.Gender)
.ToArray();
return entry;
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokedexDistributionTable { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokedexDistributionEntry { }

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokedexRankTable { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokedexRankLevel { }

View File

@@ -0,0 +1,35 @@
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokedexResearchTable
{
public PokedexResearchTask[] GetEntries(int species)
{
return Table.Where(z => z.Species == species).ToArray();
}
public PokedexResearchTask AddTask(int Species)
{
var task = new PokedexResearchTask { Species = Species };
AddTask(task);
return task;
}
public void AddTask(PokedexResearchTask task) => Table = Table.Append(task).ToArray();
public bool RemoveTask(PokedexResearchTask taskToRemove)
{
return Table.Remove(taskToRemove);
}
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class PokedexResearchTask { }

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class ScriptIDRecordRelease { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class ScriptIDRecord { }

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class HaShopTable { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class HaShopItem { }

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class CommonCaptureConfigTable { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class CommonCaptureConfig { }

View File

@@ -0,0 +1,20 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class ThrowParamTable { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class ThrowParam
{
public string Dump() => $"{ThrowParamType:X16}\t{Velocity}\t{Arc}\t{GravityDirection}\t{ThrowAngle}";
}

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class ThrowPermissionSetDictionary { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class ThrowPermissionSetEntry { }

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class ThrowableBaitParamDictionary { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class ThrowableBaitParamEntry { }

View File

@@ -0,0 +1,26 @@
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class ThrowableParamTable
{
public void AddEntry(int i)
{
Table = Table.Append(new ThrowableParam
{
Label01 = string.Empty,
Label02 = string.Empty,
}).ToList();
}
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class ThrowableParam { }

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class ThrowableResourceDictionary { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class ThrowableResourceEntry { }

View File

@@ -0,0 +1,17 @@
using System;
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class ThrowableResourceSetDictionary { }
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class ThrowableResourceSetEntry { }

View File

@@ -0,0 +1,37 @@
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class TrainerData
{
public string TeamSummary => Environment.NewLine + string.Join(Environment.NewLine, Team.Select(z => "\t" + z));
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class TrainerPoke
{
public override string ToString()
{
return $"{((Species)Species) + (Form == 0 ? "" : $"-{Form}"),-15}|({Move01,4},{Move02,4},{Move03,4},{Move04,4})|{Level,2}|{Nature,8}|{Gender}|({GVHP}/{GVATK}/{GVDEF}/{GVSPA}/{GVSPD}/{GVSPE})";
}
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class WazaSet
{
public override string ToString() => $"{Move}{(Mastered ? "*":"")}";
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class TrFloatQuad
{
public override string ToString() => $"({Float00},{Float01},{Float02},{Float03})";
}

View File

@@ -0,0 +1,40 @@
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class ArchiveContents
{
public ArchiveContent AddEntry()
{
var entry = new ArchiveContent
{
ArchiveContentPathHashes = new List<ulong>(),
};
Table = Table.Append(entry).ToList();
return entry;
}
public ArchiveContent AddEntry(string archiveFile, string[] internalArchiveFiles)
{
var entry = new ArchiveContent
{
ArchivePathHash = FnvHash.HashFnv1a_64(archiveFile),
ArchiveContentPathHashes = internalArchiveFiles.Select(p => FnvHash.HashFnv1a_64(p)).ToArray(),
};
Table = Table.Append(entry).ToList();
return entry;
}
}
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class ArchiveContent { }

View File

@@ -1,25 +1,25 @@
using System.Collections.Generic;
using System.Linq;
namespace pkNX.Structures.FlatBuffers;
namespace pkNX.Structures.FlatBuffers.Arceus;
public record struct EncounterDetail8a(double Rate, double MultT, double MultW, int Unk, EncounterSlot8a Slot)
public record struct EncounterDetail(double Rate, double MultT, double MultW, int Unk, EncounterSlot Slot)
{
private const int WeatherCount = (int)Weather8a.Count;
private const int TimeCount = (int)Time8a.Count;
private const int WeatherCount = (int)Weather.Count;
private const int TimeCount = (int)Time.Count;
public static List<EncounterDetail8a>[,] GetEmpty()
public static List<EncounterDetail>[,] GetEmpty()
{
var result = new List<EncounterDetail8a>[TimeCount, WeatherCount];
var result = new List<EncounterDetail>[TimeCount, WeatherCount];
for (var t = 0; t < TimeCount; t++)
{
for (var w = 0; w < WeatherCount; w++)
result[t, w] = new List<EncounterDetail8a>();
result[t, w] = new List<EncounterDetail>();
}
return result;
}
public static void Divide(List<EncounterDetail8a>[,] table)
public static void Divide(List<EncounterDetail>[,] table)
{
for (var time = 0; time < TimeCount; time++)
{
@@ -40,14 +40,14 @@ public static void Divide(List<EncounterDetail8a>[,] table)
}
}
}
public static TableSymmetryResult AnalyzeSymmetry(List<EncounterDetail8a>[,] table)
public static TableSymmetryResult AnalyzeSymmetry(List<EncounterDetail>[,] table)
{
var isWeatherSymmetric = true;
var isTimeSymmetric = true;
var weatherSymmetricPerTime = new[] { true, true, true, true };
for (var time = 0; time < 4; time++)
{
for (var weather = 0; weather < (int)Weather8a.Count; weather++)
for (var weather = 0; weather < (int)Weather.Count; weather++)
{
var ts = IsSameEffectiveTable(table[time, weather], table[0, weather]);
var ws = IsSameEffectiveTable(table[time, weather], table[time, 0]);
@@ -60,7 +60,7 @@ public static TableSymmetryResult AnalyzeSymmetry(List<EncounterDetail8a>[,] tab
return new TableSymmetryResult(isWeatherSymmetric, isTimeSymmetric, weatherSymmetricPerTime);
}
private static bool IsSameEffectiveTable(IReadOnlyList<EncounterDetail8a> lhs, IReadOnlyList<EncounterDetail8a> rhs)
private static bool IsSameEffectiveTable(IReadOnlyList<EncounterDetail> lhs, IReadOnlyList<EncounterDetail> rhs)
{
if (lhs.Count != rhs.Count) return false;

View File

@@ -3,25 +3,25 @@
using System.IO;
using System.Linq;
namespace pkNX.Structures.FlatBuffers;
namespace pkNX.Structures.FlatBuffers.Arceus;
public static class EncounterTable8aUtil
public static class EncounterTableUtil
{
private const float SpawnerBias = 73; // lured unown and jet + run
private const float WormholeBias = 15;
private const float LandmarkBias = 15;
public static IEnumerable<byte[]> GetEncounterDump(AreaInstance8a area,
IReadOnlyDictionary<string, (string Name, int Index)> map, PokeMiscTable8a misc,
NewHugeOutbreakGroupArchive8a nhoGroup,
NewHugeOutbreakGroupLotteryArchive8a nhoLottery)
public static IEnumerable<byte[]> GetEncounterDump(AreaInstance area,
IReadOnlyDictionary<string, (string Name, int Index)> map, PokeMiscTable misc,
NewHugeOutbreakGroupArchive nhoGroup,
NewHugeOutbreakGroupLotteryArchive nhoLottery)
{
if (area.Locations.Length == 0)
if (area.Locations.Count == 0)
yield break;
foreach (var table in area.Encounters)
{
var slots = table.Table.Where(z => z.ShinyLock is ShinyType8a.Random).ToList();
var slots = table.Table.Where(z => z.ShinyLock is ShinyType.Random).ToList();
if (slots.Count == 0)
continue;
@@ -35,12 +35,12 @@ public static class EncounterTable8aUtil
}
}
private static IEnumerable<byte[]> GetAreas(AreaInstance8a area, IReadOnlyCollection<EncounterSlot8a> slots, EncounterTable8a table,
IReadOnlyDictionary<string, (string Name, int Index)> map, PokeMiscTable8a misc,
NewHugeOutbreakGroupArchive8a nhoGroup,
NewHugeOutbreakGroupLotteryArchive8a nhoLottery)
private static IEnumerable<byte[]> GetAreas(AreaInstance area, IReadOnlyCollection<EncounterSlot> slots, EncounterTable table,
IReadOnlyDictionary<string, (string Name, int Index)> map, PokeMiscTable misc,
NewHugeOutbreakGroupArchive nhoGroup,
NewHugeOutbreakGroupLotteryArchive nhoLottery)
{
if (area.Locations.Length == 0)
if (area.Locations.Count == 0)
yield break;
int baseArea = map[area.Locations.First(z => z.IsNamedPlace).PlaceName].Index;
@@ -80,8 +80,8 @@ public static class EncounterTable8aUtil
// Since Wormholes can have different bonus level ranges, we defer uniqueness testing to the outer method. Just yield all spawners.
foreach (var w in spawners)
{
var bmin = w.Field_20_Value.BonusLevelMin;
var bmax = w.Field_20_Value.BonusLevelMax;
var bmin = w.Field20Value.BonusLevelMin;
var bmax = w.Field20Value.BonusLevelMax;
var sl = w.GetIntersectingLocations(area.Locations, WormholeBias);
foreach (var a in GetAll(sl, SpawnerType.Wormhole, bmin, bmax))
@@ -101,7 +101,7 @@ public static class EncounterTable8aUtil
yield return a;
}
IEnumerable<byte[]> GetAll(IEnumerable<PlacementLocation8a> places, SpawnerType type, int bmin = 0, int bmax = 0)
IEnumerable<byte[]> GetAll(IEnumerable<PlacementLocation> places, SpawnerType type, int bmin = 0, int bmax = 0)
{
var temp = places.Select(z => z.PlaceName);
var areas = temp.Select(z => map[z].Index).Distinct().ToList();
@@ -117,10 +117,10 @@ IEnumerable<byte[]> GetAll(IEnumerable<PlacementLocation8a> places, SpawnerType
}
}
private static SpawnerType GetSpawnerType(PlacementSpawner8a spawner)
private static SpawnerType GetSpawnerType(PlacementSpawner spawner)
{
var criteria = spawner.Parameters;
if (criteria.ConditionID == Condition8a.Equal)
if (criteria.ConditionID == Condition.Equal)
{
var arg = criteria.ConditionArg1;
if (arg.StartsWith("FSYS_NEW_OUTBREAK"))
@@ -138,9 +138,9 @@ private static SpawnerType GetSpawnerType(PlacementSpawner8a spawner)
private static readonly int[] OybnSettings = { 15, 15, 15, 20, 20 };
private static byte[] GetArea(IReadOnlyList<int> locations, IReadOnlyCollection<EncounterSlot8a> slots,
private static byte[] GetArea(IReadOnlyList<int> locations, IReadOnlyCollection<EncounterSlot> slots,
int tableMinLevel, int tableMaxLevel, SpawnerType type,
PokeMiscTable8a misc,
PokeMiscTable misc,
int bonusMin = 0,
int bonusMax = 0)
{
@@ -188,7 +188,7 @@ private static SpawnerType GetSpawnerType(PlacementSpawner8a spawner)
return ms.ToArray();
}
public static IEnumerable<string> GetUnownLines(AreaInstance8a area, IReadOnlyDictionary<string, (string Name, int Index)> map)
public static IEnumerable<string> GetUnownLines(AreaInstance area, IReadOnlyDictionary<string, (string Name, int Index)> map)
{
yield return $"Area: {area.AreaName}";
foreach (var u in area.Unown.Concat(area.SubAreas.SelectMany(x => x.Unown)))
@@ -196,11 +196,11 @@ public static IEnumerable<string> GetUnownLines(AreaInstance8a area, IReadOnlyDi
var contained = u.GetContainingLocations(area.Locations).First().PlaceName;
var name = map[contained].Name;
var p = u.Parameters;
yield return $"Unown {u.Identifier} @ {u.Hash_01:X16}_{u.Hash_03:X16} {u.Flag} ({p.GetConditionSummary()}) @ {p.Coordinates.ToTriple()}, {area.AreaName} = {name}";
yield return $"Unown {u.Identifier} @ {u.Hash01:X16}_{u.Hash03:X16} {u.Flag} ({p.GetConditionSummary()}) @ {p.Coordinates.ToTriple()}, {area.AreaName} = {name}";
}
}
public static IEnumerable<string> GetUnownLinesBias(AreaInstance8a area, IReadOnlyDictionary<string, (string Name, int Index)> map, float bias)
public static IEnumerable<string> GetUnownLinesBias(AreaInstance area, IReadOnlyDictionary<string, (string Name, int Index)> map, float bias)
{
yield return $"Area: {area.AreaName}";
foreach (var u in area.Unown.Concat(area.SubAreas.SelectMany(x => x.Unown)))
@@ -210,16 +210,16 @@ public static IEnumerable<string> GetUnownLinesBias(AreaInstance8a area, IReadOn
{
var name = map[c.PlaceName].Name;
var p = u.Parameters;
yield return $"Unown {u.Identifier} @ {u.Hash_01:X16}_{u.Hash_03:X16} {u.Flag} ({p.GetConditionSummary()}) @ {p.Coordinates.ToTriple()}, {area.AreaName} = {name}";
yield return $"Unown {u.Identifier} @ {u.Hash01:X16}_{u.Hash03:X16} {u.Flag} ({p.GetConditionSummary()}) @ {p.Coordinates.ToTriple()}, {area.AreaName} = {name}";
}
}
}
public static IEnumerable<string> GetLines(EncounterMultiplierArchive8a multiplier_archive,
PokeMiscTable8a misc, string[] speciesNames,
AreaInstance8a area,
NewHugeOutbreakGroupArchive8a nhoGroup,
NewHugeOutbreakGroupLotteryArchive8a nhoLottery,
public static IEnumerable<string> GetLines(EncounterMultiplierArchive multiplier_archive,
PokeMiscTable misc, string[] speciesNames,
AreaInstance area,
NewHugeOutbreakGroupArchive nhoGroup,
NewHugeOutbreakGroupLotteryArchive nhoLottery,
IReadOnlyDictionary<string, (string Name, int Index)> map)
{
yield return $"Area: {area.AreaName}";
@@ -233,38 +233,38 @@ public static IEnumerable<string> GetUnownLinesBias(AreaInstance8a area, IReadOn
}
}
private static IEnumerable<string> GetUsedSpawnerSummary(EncounterTable8a t, AreaInstance8a area,
private static IEnumerable<string> GetUsedSpawnerSummary(EncounterTable t, AreaInstance area,
IReadOnlyDictionary<string, (string Name, int Index)> valueTuples,
NewHugeOutbreakGroupArchive8a nhoGroup,
NewHugeOutbreakGroupLotteryArchive8a nhoLottery)
NewHugeOutbreakGroupArchive nhoGroup,
NewHugeOutbreakGroupLotteryArchive nhoLottery)
{
var usedBySpawners = Array.FindAll(area.Spawners, z => z.UsesTable(t.TableID));
var usedByWormholes = Array.FindAll(area.Wormholes, z => z.UsesTable(t.TableID));
var usedByLandmarkSpawns = Array.FindAll(area.LandItems, z => z.UsesTable(t.TableID));
var usedByLandmarks = Array.FindAll(area.LandMarks, z => usedByLandmarkSpawns.Any(sz => z.UsesTable(sz.LandmarkItemSpawnTableID)));
var usedByNHO = Array.FindAll(area.Spawners, z => nhoLottery.IsAreaGroup(z, nhoGroup, t.TableID));
var usedBySpawners = area.Spawners.Where(z => z.UsesTable(t.TableID));
var usedByWormholes = area.Wormholes.Where(z => z.UsesTable(t.TableID));
var usedByLandmarkSpawns = area.LandItems.Where(z => z.UsesTable(t.TableID)).ToArray();
var usedByLandmarks = area.LandMarks.Where(z => usedByLandmarkSpawns.Any(sz => z.UsesTable(sz.LandmarkItemSpawnTableID)));
var usedByNHO = area.Spawners.Where(z => nhoLottery.IsAreaGroup(z, nhoGroup, t.TableID));
foreach (var s in usedBySpawners)
{
var contained = s.GetContainingLocations(area.Locations).First().PlaceName;
var name = valueTuples[contained].Name;
var p = s.Parameters;
yield return $"Spawner @ {s.NameSummary}_{s.Field_01:X16} ({p.GetConditionSummary()}) @ {p.Coordinates.ToTriple()} ({s.MinSpawnCount}-{s.MaxSpawnCount}), {area.AreaName} = {name}";
yield return $"Spawner @ {s.NameSummary}_{s.Field01:X16} ({p.GetConditionSummary()}) @ {p.Coordinates.ToTriple()} ({s.MinSpawnCount}-{s.MaxSpawnCount}), {area.AreaName} = {name}";
}
foreach (var s in usedByNHO)
{
var contained = s.GetContainingLocations(area.Locations).First().PlaceName;
var name = valueTuples[contained].Name;
var p = s.Parameters;
yield return $"SpawnerNHO @ {s.NameSummary}_{s.Field_01:X16} ({p.GetConditionSummary()}) @ {p.Coordinates.ToTriple()} ({s.MinSpawnCount}-{s.MaxSpawnCount}), {area.AreaName} = {name}";
yield return $"SpawnerNHO @ {s.NameSummary}_{s.Field01:X16} ({p.GetConditionSummary()}) @ {p.Coordinates.ToTriple()} ({s.MinSpawnCount}-{s.MaxSpawnCount}), {area.AreaName} = {name}";
}
foreach (var s in usedByWormholes)
{
var contained = s.GetContainingLocations(area.Locations).First().PlaceName;
var name = valueTuples[contained].Name;
var p = s.Parameters;
var c = s.Field_20_Value;
yield return $"Wormhole: {s.NameSummary}_{s.Field_01:X16} ({p.GetConditionSummary()}) [{c.BonusLevelMin}-{c.BonusLevelMax}] @ {p.Coordinates.ToTriple()} ({s.MinSpawnCount}-{s.MaxSpawnCount}), {area.AreaName} = {name}";
var c = s.Field20Value;
yield return $"Wormhole: {s.NameSummary}_{s.Field01:X16} ({p.GetConditionSummary()}) [{c.BonusLevelMin}-{c.BonusLevelMax}] @ {p.Coordinates.ToTriple()} ({s.MinSpawnCount}-{s.MaxSpawnCount}), {area.AreaName} = {name}";
}
foreach (var s in usedByLandmarks)
{
@@ -272,16 +272,16 @@ public static IEnumerable<string> GetUnownLinesBias(AreaInstance8a area, IReadOn
var name = valueTuples[contained].Name;
var spawn = usedByLandmarkSpawns.First(sz => s.UsesTable(sz.LandmarkItemSpawnTableID));
var p = s.Parameters;
yield return $"Landmark: {s.NameSummary}_{s.Field_01:X16}_{spawn.NameSummary} ({p.GetConditionSummary()}) @ {p.Coordinates.ToTriple()}, {area.AreaName} = {name}";
yield return $"Landmark: {s.NameSummary}_{s.Field01:X16}_{spawn.NameSummary} ({p.GetConditionSummary()}) @ {p.Coordinates.ToTriple()}, {area.AreaName} = {name}";
}
}
private static IEnumerable<string> GetTableSummary(EncounterTable8a t,
EncounterMultiplierArchive8a multiplier_archive, string[] speciesNames,
PokeMiscTable8a misc,
AreaInstance8a area,
NewHugeOutbreakGroupArchive8a nhoGroup,
NewHugeOutbreakGroupLotteryArchive8a nhoLottery,
private static IEnumerable<string> GetTableSummary(EncounterTable t,
EncounterMultiplierArchive multiplier_archive, string[] speciesNames,
PokeMiscTable misc,
AreaInstance area,
NewHugeOutbreakGroupArchive nhoGroup,
NewHugeOutbreakGroupLotteryArchive nhoLottery,
IReadOnlyDictionary<string, (string Name, int Index)> valueTuples)
{
yield return $"{t}:";
@@ -311,15 +311,15 @@ public static IEnumerable<string> GetUnownLinesBias(AreaInstance8a area, IReadOn
yield return $"\t{line}";
}
private static IEnumerable<string> GetLines(IReadOnlyList<EncounterSlot8a> arr,
EncounterMultiplierArchive8a multiplier_archive, IReadOnlyList<string> speciesNames, int lvMin, int lvMax,
PokeMiscTable8a misc)
private static IEnumerable<string> GetLines(IList<EncounterSlot> arr,
EncounterMultiplierArchive multiplier_archive, IReadOnlyList<string> speciesNames, int lvMin, int lvMax,
PokeMiscTable misc)
{
var dividedTables = EncounterDetail8a.GetEmpty();
var dividedTables = EncounterDetail.GetEmpty();
FillSlots(arr, multiplier_archive, dividedTables);
EncounterDetail8a.Divide(dividedTables);
EncounterDetail.Divide(dividedTables);
var sym = EncounterDetail8a.AnalyzeSymmetry(dividedTables);
var sym = EncounterDetail.AnalyzeSymmetry(dividedTables);
if (sym.Time && sym.Weather)
{
yield return "Any Time/All Weather:";
@@ -330,7 +330,7 @@ public static IEnumerable<string> GetUnownLinesBias(AreaInstance8a area, IReadOn
{
for (var time = 0; time < dividedTables.GetLength(0); time++)
{
yield return $"{(Time8a)time}/All Weather:";
yield return $"{(Time)time}/All Weather:";
foreach (var line in GetEffectiveTableSummary(dividedTables[time, 0], speciesNames, lvMin, lvMax, misc))
yield return $"\t{line}";
}
@@ -339,7 +339,7 @@ public static IEnumerable<string> GetUnownLinesBias(AreaInstance8a area, IReadOn
{
for (var weather = 0; weather < dividedTables.GetLength(1); weather++)
{
yield return $"Any Time/{(Weather8a)weather}:";
yield return $"Any Time/{(Weather)weather}:";
foreach (var line in GetEffectiveTableSummary(dividedTables[0, weather], speciesNames, lvMin, lvMax, misc))
yield return $"\t{line}";
}
@@ -350,7 +350,7 @@ public static IEnumerable<string> GetUnownLinesBias(AreaInstance8a area, IReadOn
{
if (sym.Complexed[time])
{
yield return $"{(Time8a)time}/All Weather:";
yield return $"{(Time)time}/All Weather:";
foreach (var line in GetEffectiveTableSummary(dividedTables[time, 0], speciesNames, lvMin, lvMax, misc))
yield return $"\t{line}";
}
@@ -358,7 +358,7 @@ public static IEnumerable<string> GetUnownLinesBias(AreaInstance8a area, IReadOn
{
for (var weather = 0; weather < dividedTables.GetLength(1); weather++)
{
yield return $"{(Time8a)time}/{(Weather8a)weather}:";
yield return $"{(Time)time}/{(Weather)weather}:";
foreach (var line in GetEffectiveTableSummary(dividedTables[time, weather], speciesNames, lvMin, lvMax, misc))
yield return $"\t{line}";
}
@@ -367,7 +367,7 @@ public static IEnumerable<string> GetUnownLinesBias(AreaInstance8a area, IReadOn
}
}
private static void FillSlots(IEnumerable<EncounterSlot8a> arr, EncounterMultiplierArchive8a multArchive, List<EncounterDetail8a>[,] dividedTables)
private static void FillSlots(IEnumerable<EncounterSlot> arr, EncounterMultiplierArchive multArchive, List<EncounterDetail>[,] dividedTables)
{
var ctr = 0;
foreach (var slot in arr.OrderByDescending(sl => sl.BaseProbability))
@@ -383,7 +383,7 @@ private static void FillSlots(IEnumerable<EncounterSlot8a> arr, EncounterMultipl
if (rate == 0)
continue;
var detail = new EncounterDetail8a(slot.BaseProbability * MultT * MultW, MultT, MultW, ctr, slot);
var detail = new EncounterDetail(slot.BaseProbability * MultT * MultW, MultT, MultW, ctr, slot);
dividedTables[time, weather].Add(detail);
}
}
@@ -392,7 +392,7 @@ private static void FillSlots(IEnumerable<EncounterSlot8a> arr, EncounterMultipl
}
}
private static IEnumerable<string> GetEffectiveTableSummary(IReadOnlyList<EncounterDetail8a> table, IReadOnlyList<string> speciesNames, int lvMin, int lvMax, PokeMiscTable8a misc)
private static IEnumerable<string> GetEffectiveTableSummary(IReadOnlyList<EncounterDetail> table, IReadOnlyList<string> speciesNames, int lvMin, int lvMax, PokeMiscTable misc)
{
if (table.Count == 0)
{
@@ -400,7 +400,7 @@ private static IEnumerable<string> GetEffectiveTableSummary(IReadOnlyList<Encoun
yield break;
}
foreach ((double rate, _, _, _, EncounterSlot8a? slot) in table)
foreach ((double rate, _, _, _, EncounterSlot? slot) in table)
{
string form = slot.Form == 0 ? string.Empty : $"-{slot.Form}";
var spec_form = $"{speciesNames[slot.Species]}{form}";
@@ -425,39 +425,39 @@ private static IEnumerable<string> GetEffectiveTableSummary(IReadOnlyList<Encoun
if (slot.Gender != -1)
summary += $"\tGender={slot.Gender}";
if (slot.ShinyLock is not ShinyType8a.Random)
if (slot.ShinyLock is not ShinyType.Random)
summary += $"\tShinyLock={slot.ShinyLock}";
if (slot.AbilityRandType is not AbilityType8a.Any12)
if (slot.AbilityRandType is not AbilityType.Any12)
summary += $"\tAbility={slot.AbilityRandType}";
if (slot.Nature is not NatureType8a.Random)
if (slot.Nature is not NatureType.Random)
summary += $"\tNature={slot.Nature}";
var gvs = new[] { slot.GV_HP, slot.GV_ATK, slot.GV_DEF, slot.GV_SPA, slot.GV_SPD, slot.GV_SPE };
var gvs = new[] { slot.GVHP, slot.GVATK, slot.GVDEF, slot.GVSPA, slot.GVSPD, slot.GVSPE };
if (gvs.Any(x => x != -1))
summary += $"\tGVS={string.Join("/", gvs.Select(v => v != -1 ? v.ToString() : "*").ToArray())}";
if (slot.NumPerfectIvs != 0)
summary += $"\tPerfectIvs={slot.NumPerfectIvs}";
var ivs = new[] { slot.IV_HP, slot.IV_ATK, slot.IV_DEF, slot.IV_SPA, slot.IV_SPD, slot.IV_SPE };
var ivs = new[] { slot.IVHP, slot.IVATK, slot.IVDEF, slot.IVSPA, slot.IVSPD, slot.IVSPE };
if (ivs.Any(x => x != -1))
summary += $"\tIVS={string.Join("/", ivs.Select(v => v != -1 ? v.ToString() : "*").ToArray())}";
var oybn = slot.Oybn;
if (oybn.IsOybnAny)
{
if (oybn.Oybn1 && !oybn.Oybn2 && oybn.Field_02 && oybn.Field_03)
if (oybn is { Oybn1: true, Oybn2: false, Field02: true, Field03: true })
summary += "\tOybn=Type1";
else if (oybn.Oybn1 && oybn.Oybn2 && oybn.Field_02 && oybn.Field_03)
else if (oybn is { Oybn1: true, Oybn2: true, Field02: true, Field03: true })
summary += "\tOybn=Type2";
else
summary += $"\tOybn={{{(oybn.Oybn1 ? 1 : 0)},{(oybn.Oybn2 ? 1 : 0)},{(oybn.Field_02 ? 1 : 0)},{(oybn.Field_03 ? 1 : 0)}}}";
summary += $"\tOybn={{{(oybn.Oybn1 ? 1 : 0)},{(oybn.Oybn2 ? 1 : 0)},{(oybn.Field02 ? 1 : 0)},{(oybn.Field03 ? 1 : 0)}}}";
}
var elg = slot.Eligibility;
if (slot.Eligibility.ConditionTypeID != ConditionType8a.None)
if (slot.Eligibility.ConditionTypeID != ConditionType.None)
{
summary += $"\tConditionType={elg.GetConditionTypeSummary()}";
summary += $"\tCondition={elg.GetConditionSummary()}";
@@ -476,3 +476,63 @@ private static IEnumerable<string> GetEffectiveTableSummary(IReadOnlyList<Encoun
}
}
}
public static class Condition
{
public const ulong Empty = 0;
public const ulong GreaterThanEqual = 0x34F605C97C571896;
public const ulong LessThanEqual = 0x488B1F9FBC949365;
public const ulong NotEqual = 0x88C99E99F1FC6C55;
public const ulong Equal = 0xB763CBE88B6F844F;
public const ulong None = 0xCBF29CE484222645;
public const ulong Between = 0xE5E34D77DC75E2EF;
}
public static class ConditionType
{
public const ulong Empty = 0;
public const ulong None = 0xCBF29CE484222645; // ""
public const ulong BattleWin = 0xB2EE750DBCD8FFD6; // "battle_win" // UNUSED
public const ulong EventEndFlagComparison = 0xB1D54CA3ACFD951C; // "event_end_flag_comparison"
public const ulong FlagComparison = 0x3DDD5FEB4A6149; // "flag_comparison"
public const ulong FlagComparisonMultiAnd = 0x1474C7C46A813955; // "flag_comparison_multi_and"
public const ulong FlagComparisonMultiOr = 0x99A60B9D95356789; // "flag_comparison_multi_or"
public const ulong Force = 0x344570C1301A7584; // "force"
public const ulong IsRide = 0xE1DBDA285AC7E0C4; // "is_ride"
public const ulong ItemNum = 0x4218EEEA9BFE8019; // "item_num"
public const ulong MkrgCondition = 0xFDF49E06E61C30; // "mkrg_condition
public const ulong MoonType = 0x9C765A1AAAC34605; // "moon_type"
public const ulong MydressupParts = 0x6E4AB6860240F386; // "mydressup_parts"
public const ulong NpcPassPokeForm = 0xDD65C7864951449B; // "npc_pass_poke_form"
public const ulong NpcPassPokeIndividualNum = 0xCE6FB5F32B6297C5; // "npc_pass_poke_individual_num"
public const ulong NpcPassPokeMonsNum = 0x26D399D556EE1C2D; // "npc_pass_poke_mons_num"
public const ulong NpcPassPokeOybn = 0x769FC8C156B7CDBD; // "npc_pass_poke_oybn"
public const ulong NpcPassPokeSeikaku = 0xF27E3B012D8F762C; // "npc_pass_poke_seikaku" // UNUSED
public const ulong NpcPassPokeSex = 0xABE95BDC028692F3; // "npc_pass_poke_sex"
public const ulong NpcPassPokeSizeAbsolute = 0xA6F824297967B404; // "npc_pass_poke_size_absolute" // UNUSED
public const ulong NpcPassPokeSizeIndividual = 0x4CED96920003025E; // "npc_pass_poke_size_individual" // UNUSED
public const ulong NpcPassPokeType = 0xC4BB08F0E0BB1979; // "npc_pass_poke_type"
public const ulong NpcPassPokeWaza = 0xF26110F743861738; // "npc_pass_poke_waza"
public const ulong PartyMonsNoNum = 0x0B830B240F28E61C; // "party_mons_no_num"
public const ulong PartyPokeNum = 0x313CB8E1DEBB01DE; // "party_poke_num"
public const ulong PhaseCondition = 0x8E77D62D1E38721E; // "phase_condition"
public const ulong PlayerSex = 0xFA75906B85AE950F; // "player_sex"
public const ulong PokeGetNum = 0x56E50D419BFB3A2C; // "poke_get_num"
public const ulong PokeGetSelf = 0x7AAB4D6FEBAC4C0E; // "poke_get_self"
public const ulong PokeResearchComplete = 0x5B017A2B0C07CD1A; // "poke_research_complete" // UNUSED
public const ulong PokeTotalNum = 0x892E20D02629F1FA; // "poke_total_num"
public const ulong Probability = 0x5E53C6367A2D36BC; // "probability"
public const ulong ProgressWorkCondition = 0x43C4820F12B5385C; // "progress_work_condition"
public const ulong ProgressWorkConditionHash = 0x409A7F367B037545; // "progress_work_condition_hash"
public const ulong ProgressResidentWorkCondition = 0xD0D514A85FC0B50F; // "progress_resident_work_condition" // UNUSED
public const ulong ProgressResidentWorkConditionHash = 0x1C5747049C3B1920; // "progress_resident_work_condition_hash"
public const ulong QuestProgressCondition = 0x2041C674206FE0A7; // "quest_progress_condition"
public const ulong QuestTaskClearCheck = 0x4BBF494C6CE53FEA; // "quest_task_clear_check" // UNUSED
public const ulong ThrowItemCondition = 0x15C4DB49A2D05975; // "throw_item_condition" // UNUSED
public const ulong TimeZone = 0x46EBE59F660B132B; // "time_zone"
public const ulong TimeZoneAfternoon = 0x8E0F436D4E20E310; // "time_zone_afternoon"
public const ulong TimeZoneNight = 0xD95B681BFE1BB762; // "time_zone_night"
public const ulong WorkCondition = 0x2557279B949C81D6; // "work_condition"
public const ulong ZukanResearchCondition = 0x854B2B1FDB9AC9B4; // "zukan_research_condition"
public const ulong ZukanStageCondition = 0x9A193E701C7F9A61; // "zukan_stage_condition"
}

View File

@@ -1,11 +1,11 @@
// ReSharper disable UnusedMember.Global
namespace pkNX.Structures.FlatBuffers;
namespace pkNX.Structures.FlatBuffers.Arceus;
public interface IHasCondition8a
public interface IHasCondition
{
ConditionType8a ConditionTypeID { get; set; }
Condition8a ConditionID { get; set; }
ulong ConditionTypeID { get; set; }
ulong ConditionID { get; set; }
string ConditionArg1 { get; set; }
string ConditionArg2 { get; set; }
string ConditionArg3 { get; set; }

View File

@@ -1,4 +1,4 @@
namespace pkNX.Structures.FlatBuffers;
namespace pkNX.Structures.FlatBuffers.Arceus;
public enum SpawnerType
{

View File

@@ -1,8 +1,8 @@
// ReSharper disable UnusedMember.Global
namespace pkNX.Structures.FlatBuffers;
namespace pkNX.Structures.FlatBuffers.Arceus;
public enum Time8a
public enum Time
{
Dawn = 0,
Day = 1,

View File

@@ -1,12 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace pkNX.Structures.FlatBuffers.Arceus;
namespace pkNX.Structures.FlatBuffers;
public static class Trigger8aUtil
public static class TriggerUtil
{
public static IEnumerable<string> GetTriggerTableSummary(TriggerTable8a tab)
public static IEnumerable<string> GetTriggerTableSummary(TriggerTable tab)
{
foreach (var trg in tab.Table)
{
@@ -16,7 +12,7 @@ public static IEnumerable<string> GetTriggerTableSummary(TriggerTable8a tab)
}
}
public static IEnumerable<string> GetTriggerSummary(Trigger8a trg)
public static IEnumerable<string> GetTriggerSummary(Trigger trg)
{
yield return "Meta:";
yield return $"\t{GetTriggerMetaSummary(trg.Meta)}";
@@ -28,43 +24,39 @@ public static IEnumerable<string> GetTriggerSummary(Trigger8a trg)
yield return $"\t{line}";
}
public static string GetTriggerMetaSummary(TriggerMeta8a meta)
public static string GetTriggerMetaSummary(TriggerMeta meta)
{
if (meta.Unused_01 != 0)
if (meta.Unused01 != 0)
throw new ArgumentException("TriggerMeta has unused field set?");
var argsSummary = GetTriggerArgsSummary(meta.TriggerMetaArg1, meta.TriggerMetaArg2, meta.TriggerMetaArg3);
var argsSummary = GetTriggerArgsSummary(new string[] {meta.TriggerMetaArg1, meta.TriggerMetaArg2, meta.TriggerMetaArg3});
if (Enum.IsDefined(typeof(TriggerType8a), meta.TriggerTypeID))
return $"{meta.TriggerTypeID}({argsSummary})";
return $"0x{(ulong)meta.TriggerTypeID:X16}({argsSummary})";
}
public static IEnumerable<string> GetTriggerConditionsSummary(IEnumerable<TriggerCondition8a> conds)
public static IEnumerable<string> GetTriggerConditionsSummary(IEnumerable<TriggerCondition> conds)
{
foreach (var cond in conds)
yield return $"{cond.GetConditionTypeSummary()}: {cond.GetConditionSummary()}";
}
public static IEnumerable<string> GetTriggerCommandsSummary(IEnumerable<TriggerCommand8a> cmds)
public static IEnumerable<string> GetTriggerCommandsSummary(IEnumerable<TriggerCommand> cmds)
{
foreach (var cmd in cmds)
yield return GetTriggerCommandSummary(cmd);
}
public static string GetTriggerCommandSummary(TriggerCommand8a cmd)
public static string GetTriggerCommandSummary(TriggerCommand cmd)
{
var argsSummary = GetTriggerArgsSummary(cmd.Arguments);
if (Enum.IsDefined(typeof(TriggerCommandType8a), cmd.CommandTypeID))
return $"{cmd.CommandTypeID}({argsSummary})";
return $"0x{(ulong)cmd.CommandTypeID:X16}({argsSummary})";
}
public static string GetTriggerArgsSummary(params string[] args)
public static string GetTriggerArgsSummary(IList<string> args)
{
var firstEmpty = -1;
for (var i = 0; i < args.Length; i++)
for (var i = 0; i < args.Count; i++)
{
if (firstEmpty >= 0 && !string.IsNullOrEmpty(args[i]))
throw new ArgumentException($"Invalid TriggerArg at index {i}!");
@@ -72,6 +64,6 @@ public static string GetTriggerArgsSummary(params string[] args)
firstEmpty = i;
}
return string.Join(", ", args.Select(s => $"\"{s}\"").Take(firstEmpty >= 0 ? firstEmpty : args.Length));
return string.Join(", ", args.Select(s => $"\"{s}\"").Take(firstEmpty >= 0 ? firstEmpty : args.Count));
}
}

View File

@@ -1,8 +1,8 @@
namespace pkNX.Structures.FlatBuffers;
namespace pkNX.Structures.FlatBuffers.Arceus;
// ReSharper disable UnusedMember.Global
public enum Weather8a
public enum Weather
{
None = 0,
Sunny = 1,

View File

@@ -0,0 +1,13 @@
using System.ComponentModel;
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedType.Global
// ReSharper disable UnusedMember.Global
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
namespace pkNX.Structures.FlatBuffers.Arceus;
[TypeConverter(typeof(ExpandableObjectConverter))]
public partial class Waza { }

View File

@@ -1,10 +1,8 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
#nullable disable // meh
namespace pkNX.Structures.FlatBuffers;
namespace pkNX.Structures.FlatBuffers.Arceus;
public class PersonalDumperPLA
{
@@ -44,8 +42,8 @@ private void AddTRs(List<string> lines, IMovesInfo_1 pi, string specCode)
public IReadOnlyList<string> ZukanA { private get; set; }
public IReadOnlyList<string> ZukanB { private get; set; }
public Learnset8aMeta[] EntryLearnsets { private get; set; }
public EvolutionSet8a[] Evos { private get; set; }
public IList<LearnsetMeta> EntryLearnsets { private get; set; }
public IList<EvolutionSet> Evos { private get; set; }
public IReadOnlyList<ushort> TMIndexes { protected get; set; }
private static readonly string[] AbilitySuffix = { " (1)", " (2)", " (H)" };
@@ -151,7 +149,7 @@ protected virtual void AddArmorTutors(List<string> lines, IMovesInfo_2 pi, strin
private void AddLearnsetsLegacy(List<string> lines, string specCode, int species, int form)
{
var learn = Array.Find(EntryLearnsets, z => z.Species == species && z.Form == form);
var learn = EntryLearnsets.FirstOrDefault(z => z.Species == species && z.Form == form);
if (learn is null)
return;
@@ -167,7 +165,7 @@ private void AddLearnsetsLegacy(List<string> lines, string specCode, int species
private void AddLearnsets(List<string> lines, string specCode, int species, int form)
{
var learn = Array.Find(EntryLearnsets, z => z.Species == species && z.Form == form);
var learn = EntryLearnsets.FirstOrDefault(z => z.Species == species && z.Form == form);
if (learn is null)
return;
@@ -184,7 +182,7 @@ private void AddLearnsets(List<string> lines, string specCode, int species, int
private void AddEvolutions(List<string> lines, int species, int form)
{
var evo = Array.Find(Evos, z => z.Species == species && z.Form == form);
var evo = Evos.FirstOrDefault(z => z.Species == species && z.Form == form);
if (evo?.Table is null)
return;
var evo2 = evo.Table.Where(z => z.Species != 0).ToArray();

View File

@@ -1,14 +1,13 @@
using System;
using System.Collections;
namespace pkNX.Structures.FlatBuffers;
namespace pkNX.Structures.FlatBuffers.Arceus;
/// <summary>
/// Personal Info class with values from the <see cref="GameVersion.PLA"/> games.
/// </summary>
public sealed class PersonalInfo8LA : IPersonalInfoPLA
{
public PersonalInfoLAfb FB { get; }
public PersonalInfo FB { get; }
private bool[][] _SpecialTutors = Array.Empty<bool[]>();
public bool[][] SpecialTutors
@@ -25,7 +24,7 @@ public bool[][] SpecialTutors
}
}
public PersonalInfo8LA(PersonalInfoLAfb fb)
public PersonalInfo8LA(PersonalInfo fb)
{
FB = fb;
@@ -36,24 +35,24 @@ public PersonalInfo8LA(PersonalInfoLAfb fb)
SpecialTutors = new[] { flags };
}
public int HP { get => FB.Stat_HP; set => FB.Stat_HP = (byte)value; }
public int ATK { get => FB.Stat_ATK; set => FB.Stat_ATK = (byte)value; }
public int DEF { get => FB.Stat_DEF; set => FB.Stat_DEF = (byte)value; }
public int SPE { get => FB.Stat_SPE; set => FB.Stat_SPE = (byte)value; }
public int SPA { get => FB.Stat_SPA; set => FB.Stat_SPA = (byte)value; }
public int SPD { get => FB.Stat_SPD; set => FB.Stat_SPD = (byte)value; }
public int HP { get => FB.StatHP; set => FB.StatHP = (byte)value; }
public int ATK { get => FB.StatATK; set => FB.StatATK = (byte)value; }
public int DEF { get => FB.StatDEF; set => FB.StatDEF = (byte)value; }
public int SPE { get => FB.StatSPE; set => FB.StatSPE = (byte)value; }
public int SPA { get => FB.StatSPA; set => FB.StatSPA = (byte)value; }
public int SPD { get => FB.StatSPD; set => FB.StatSPD = (byte)value; }
public Types Type1 { get => (Types)FB.Type1; set => FB.Type1 = (byte)value; }
public Types Type2 { get => (Types)FB.Type2; set => FB.Type2 = (byte)value; }
public int CatchRate { get => FB.CatchRate; set => FB.CatchRate = (byte)value; }
public int EvoStage { get => FB.EvoStage; set => FB.EvoStage = (byte)value; }
public byte Field_18 { get => FB.Field_18; set => FB.Field_18 = value; }
public byte Field_18 { get => FB.Field18; set => FB.Field18 = value; }
public int EV_HP { get => FB.EV_HP; set => FB.EV_HP = (byte)value; }
public int EV_ATK { get => FB.EV_ATK; set => FB.EV_ATK = (byte)value; }
public int EV_DEF { get => FB.EV_DEF; set => FB.EV_DEF = (byte)value; }
public int EV_SPE { get => FB.EV_SPE; set => FB.EV_SPE = (byte)value; }
public int EV_SPA { get => FB.EV_SPA; set => FB.EV_SPA = (byte)value; }
public int EV_SPD { get => FB.EV_SPD; set => FB.EV_SPD = (byte)value; }
public int EV_HP { get => FB.EVHP; set => FB.EVHP = (byte)value; }
public int EV_ATK { get => FB.EVATK; set => FB.EVATK = (byte)value; }
public int EV_DEF { get => FB.EVDEF; set => FB.EVDEF = (byte)value; }
public int EV_SPE { get => FB.EVSPE; set => FB.EVSPE = (byte)value; }
public int EV_SPA { get => FB.EVSPA; set => FB.EVSPA = (byte)value; }
public int EV_SPD { get => FB.EVSPD; set => FB.EVSPD = (byte)value; }
public int Item1 { get => FB.Item1; set => FB.Item1 = (ushort)value; }
public int Item2 { get => FB.Item2; set => FB.Item2 = (ushort)value; }
public int Item3 { get => FB.Item3; set => FB.Item3 = (ushort)value; }
@@ -71,21 +70,21 @@ public PersonalInfo8LA(PersonalInfoLAfb fb)
public int Height { get => FB.Height; set => FB.Height = (ushort)value; }
public int Weight { get => FB.Weight; set => FB.Weight = (ushort)value; }
public uint TM_A { get => FB.TM_A; set => FB.TM_A = value; }
public uint TM_B { get => FB.TM_B; set => FB.TM_B = value; }
public uint TM_C { get => FB.TM_C; set => FB.TM_C = value; }
public uint TM_D { get => FB.TM_D; set => FB.TM_D = value; }
public uint TR_A { get => FB.TR_A; set => FB.TR_A = value; }
public uint TR_B { get => FB.TR_B; set => FB.TR_B = value; }
public uint TR_C { get => FB.TR_C; set => FB.TR_C = value; }
public uint TR_D { get => FB.TR_D; set => FB.TR_D = value; }
public uint TM_A { get => FB.TMA; set => FB.TMA = value; }
public uint TM_B { get => FB.TMB; set => FB.TMB = value; }
public uint TM_C { get => FB.TMC; set => FB.TMC = value; }
public uint TM_D { get => FB.TMD; set => FB.TMD = value; }
public uint TR_A { get => FB.TRA; set => FB.TRA = value; }
public uint TR_B { get => FB.TRB; set => FB.TRB = value; }
public uint TR_C { get => FB.TRC; set => FB.TRC = value; }
public uint TR_D { get => FB.TRD; set => FB.TRD = value; }
public uint TypeTutor { get => FB.TypeTutor; set => FB.TypeTutor = value; }
public ushort HatchedSpecies { get => FB.HatchedSpecies; set => FB.HatchedSpecies = value; }
public ushort LocalFormIndex { get => FB.LocalFormIndex; set => FB.LocalFormIndex = value; }
public bool Field_45 { get => FB.Field_45; set => FB.Field_45 = value; }
public ushort Field_46 { get => FB.Field_46; set => FB.Field_46 = value; }
public byte Field_47 { get => FB.Field_47; set => FB.Field_47 = value; }
public bool Field_45 { get => FB.Field45; set => FB.Field45 = value; }
public ushort Field_46 { get => FB.Field46; set => FB.Field46 = value; }
public byte Field_47 { get => FB.Field47; set => FB.Field47 = value; }
public ushort ModelID { get => FB.ModelID; set => FB.ModelID = value; }
public ushort Form { get => FB.Form; set => FB.Form = value; }

View File

@@ -1,11 +1,10 @@
using System.Collections;
using pkNX.Containers;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Collections.Immutable;
using FlatSharp;
namespace pkNX.Structures.FlatBuffers;
namespace pkNX.Structures.FlatBuffers.Arceus;
/// <summary>
/// Personal Table storing <see cref="PersonalInfo8LA"/> used in <see cref="GameVersion.PLA"/>.
@@ -17,12 +16,12 @@ public sealed class PersonalTable8LA : IPersonalTable, IPersonalTable<PersonalIn
public int MaxSpeciesID => MaxSpecies;
private readonly IFileContainer File;
public PersonalTableLAfb Root { get; }
public PersonalTable Root { get; }
public PersonalTable8LA(IFileContainer file)
{
File = file;
Root = FlatBufferConverter.DeserializeFrom<PersonalTableLAfb>(file[0]);
Root = PersonalTable.Serializer.Parse(file[0], FlatBufferDeserializationOption.GreedyMutable);
var baseForms = new PersonalInfo8LA[MaxSpecies + 1];
var formTable = new List<PersonalInfo8LA>();
@@ -31,11 +30,12 @@ public PersonalTable8LA(IFileContainer file)
.OrderBy(z => z.DexIndexNational)
.ThenBy(z => z.Form)
.GroupBy(x => x.DexIndexNational)
.Select(group => group.ToImmutableArray());
.Select(group => group.ToImmutableArray())
.ToArray();
for (int i = 0; i <= MaxSpecies; i++)
{
var forms = formGrouped.ElementAt(i);
var forms = formGrouped[i];
baseForms[i] = GetObj(forms[0], forms, MaxSpecies, formTable);
for (int f = 1; f < forms.Length; f++)
@@ -45,7 +45,7 @@ public PersonalTable8LA(IFileContainer file)
Table = baseForms.Concat(formTable).ToArray();
}
private static PersonalInfo8LA GetObj(PersonalInfoLAfb e, ICollection forms, ushort max, ICollection formTable, int f = 0)
private static PersonalInfo8LA GetObj(PersonalInfo e, ICollection forms, ushort max, ICollection formTable, int f = 0)
{
return new PersonalInfo8LA(e)
{
@@ -56,7 +56,14 @@ private static PersonalInfo8LA GetObj(PersonalInfoLAfb e, ICollection forms, ush
public void Save()
{
File[0] = FlatBufferConverter.SerializeFrom(Root);
var pool = System.Buffers.ArrayPool<byte>.Shared;
var serializer = PersonalTable.Serializer;
var size = serializer.GetMaxSize(Root);
var arr = pool.Rent(size);
var len = serializer.Write(arr, Root);
var data = arr.AsSpan(0, len).ToArray();
pool.Return(arr);
File[0] = data;
}
public PersonalInfo8LA this[int index] => Table[(uint)index < Table.Length ? index : 0];

Some files were not shown because too many files have changed in this diff Show More