diff --git a/SoulsFormats/Formats/NVA.cs b/SoulsFormats/Formats/NVA.cs
index 9b656373..1e8e15e8 100644
--- a/SoulsFormats/Formats/NVA.cs
+++ b/SoulsFormats/Formats/NVA.cs
@@ -7,7 +7,7 @@
namespace SoulsFormats
{
///
- /// A file that defines the placement and properties of navmeshes in BB, DS3, and Sekiro. Extension: .nva
+ /// A file that defines the placement and properties of navmeshes in BB, DS3, Sekiro, and ER. Extension: .nva
///
public class NVA : SoulsFile
{
@@ -30,6 +30,11 @@ public enum NVAVersion : uint
/// Sekiro
///
Sekiro = 5,
+
+ ///
+ /// Elden Ring
+ ///
+ EldenRing = 8,
}
///
@@ -42,38 +47,73 @@ public enum NVAVersion : uint
///
public NavmeshSection Navmeshes { get; set; }
- ///
- /// Unknown.
- ///
- public Section1 Entries1 { get; set; }
+ public FaceDataSection FaceDatas { get; set; }
- ///
- /// Unknown.
- ///
- public Section2 Entries2 { get; set; }
+ public NodeBankSection NodeBanks { get; set; }
+
+ public Section3 Entries3 { get; set; }
///
/// Connections between different navmeshes.
///
public ConnectorSection Connectors { get; set; }
+ public LevelConnectorSection LevelConnectors { get; set; }
+
+ public Section9 Entries9 { get; set; }
+ public Section10 Entries10 { get; set; }
+ public Section11 Entries11 { get; set; }
+ public Section13 Entries13 { get; set; }
+
///
- /// Unknown.
+ /// Keeps track of whether the empty Section 12 was present in the file.
///
- public Section7 Entries7 { get; set; }
+ public bool HasSection12 { get; set; } = false;
+
+ ///
+ /// Keeps track of the version used by the empty Section 12 for reserialization.
+ ///
+ public int Section12Version { get; set; } = 1;
///
- /// Creates an empty NVA formatted for DS3.
+ /// Creates an empty NVA formatted for Elden Ring.
///
- public NVA()
+ public NVA() // : this(NVAVersion.EldenRing) // for future compatability
{
- Version = NVAVersion.DarkSouls3;
- Navmeshes = new NavmeshSection(2);
- Entries1 = new Section1();
- Entries2 = new Section2();
+ Version = NVAVersion.EldenRing;
+ Entries11 = new Section11();
+ Navmeshes = new NavmeshSection(4);
+ FaceDatas = new FaceDataSection();
+ NodeBanks = new NodeBankSection();
+ Entries3 = new Section3();
Connectors = new ConnectorSection();
- Entries7 = new Section7();
+ LevelConnectors = new LevelConnectorSection();
+ Entries9 = new Section9();
+ Entries10 = new Section10();
+ HasSection12 = true;
+ Entries13 = new Section13();
}
+
+ // ///
+ // /// Creates an empty NVA formatted for specified version.
+ // ///
+ // public NVA(NVAVersion version)
+ // {
+ // // Need to go through this and only intialize the sections needed for that version.
+ // // Probably need a switch statement with fallthrough
+ // Version = version;
+ // Entries11 = new Section11();
+ // Navmeshes = new NavmeshSection(2);
+ // FaceDatas = new FaceDataSection();
+ // NodeBanks = new NodeBankSection();
+ // Entries3 = new Section3();
+ // Connectors = new ConnectorSection();
+ // LevelConnectors = new LevelConnectorSection();
+ // Entries9 = new Section9();
+ // Entries10 = new Section10();
+ // HasSection12 = true;
+ // Entries13 = new Section13();
+ // }
///
/// Checks whether the data appears to be a file of this format.
@@ -96,27 +136,57 @@ protected override void Read(BinaryReaderEx br)
br.AssertASCII("NVMA");
Version = br.ReadEnum32();
br.ReadUInt32(); // File size
- br.AssertInt32(Version == NVAVersion.OldBloodborne ? 8 : 9); // Section count
-
- Navmeshes = new NavmeshSection(br);
- Entries1 = new Section1(br);
- Entries2 = new Section2(br);
- new Section3(br);
- Connectors = new ConnectorSection(br);
- var connectorPoints = new ConnectorPointSection(br);
- var connectorConditions = new ConnectorConditionSection(br);
- Entries7 = new Section7(br);
- MapNodeSection mapNodes;
- if (Version == NVAVersion.OldBloodborne)
- mapNodes = new MapNodeSection(1);
- else
- mapNodes = new MapNodeSection(br);
-
- foreach (Navmesh navmesh in Navmeshes)
- navmesh.TakeMapNodes(mapNodes);
-
- foreach (Connector connector in Connectors)
- connector.TakePointsAndConds(connectorPoints, connectorConditions);
+ int sectionCount = br.ReadInt32();
+
+ NavMeshConnectionSection navMeshConns = null;
+ GraphConnectionSection graphConns = null;
+ GateNodeSection gateNodes = null;
+
+ for (int i = 0; i < sectionCount; i++)
+ {
+ // Peek at the index of the next section
+ int index = br.GetInt32(br.Position);
+
+ switch (index)
+ {
+ case 0: Navmeshes = new NavmeshSection(br); break;
+ case 1: FaceDatas = new FaceDataSection(br); break;
+ case 2: NodeBanks = new NodeBankSection(br); break;
+ case 3: Entries3 = new Section3(br); break;
+ case 4: Connectors = new ConnectorSection(br); break;
+ case 5: navMeshConns = new NavMeshConnectionSection(br); break;
+ case 6: graphConns = new GraphConnectionSection(br); break;
+ case 7: LevelConnectors = new LevelConnectorSection(br); break;
+ case 8: gateNodes = new GateNodeSection(br); break;
+ case 9: Entries9 = new Section9(br); break;
+ case 10: Entries10 = new Section10(br); break;
+ case 11: Entries11 = new Section11(br); break;
+ case 12:
+ br.AssertInt32(12);
+ Section12Version = br.ReadInt32();
+ int length = br.ReadInt32();
+ br.ReadInt32(); // entryCount
+ br.Skip(length);
+ HasSection12 = true;
+ break;
+ case 13: Entries13 = new Section13(br); break;
+ default:
+ throw new NotImplementedException($"Unrecognized section index: {index}");
+ }
+ }
+
+ // Link sub-sections back to their parent classes
+ if (Navmeshes != null && gateNodes != null)
+ {
+ foreach (Navmesh navmesh in Navmeshes)
+ navmesh.TakeGateNodes(gateNodes);
+ }
+
+ if (Connectors != null && navMeshConns != null && graphConns != null)
+ {
+ foreach (Connector connector in Connectors)
+ connector.TakeConnections(navMeshConns, graphConns);
+ }
}
///
@@ -124,37 +194,84 @@ protected override void Read(BinaryReaderEx br)
///
protected override void Write(BinaryWriterEx bw)
{
- var connectorPoints = new ConnectorPointSection();
- var connectorConditions = new ConnectorConditionSection();
- foreach (Connector connector in Connectors)
- connector.GivePointsAndConds(connectorPoints, connectorConditions);
+ var navMeshConns = new NavMeshConnectionSection();
+ var graphConns = new GraphConnectionSection();
+ if (Connectors != null)
+ {
+ foreach (Connector connector in Connectors)
+ connector.GiveConnections(navMeshConns, graphConns);
+ }
- var mapNodes = new MapNodeSection(Version == NVAVersion.Sekiro ? 2 : 1);
- foreach (Navmesh navmesh in Navmeshes)
- navmesh.GiveMapNodes(mapNodes);
+ var gateNodes = new GateNodeSection(Version == NVAVersion.Sekiro ? 2 : 1);
+ if (Navmeshes != null)
+ {
+ foreach (Navmesh navmesh in Navmeshes)
+ navmesh.GiveGateNodes(gateNodes);
+ }
+
+ // Dynamically determine the section count based on present data
+ int sectionCount = 0;
+ if (Navmeshes != null) sectionCount++;
+ if (FaceDatas != null) sectionCount++;
+ if (NodeBanks != null) sectionCount++;
+ if (Entries3 != null) sectionCount++;
+ if (Connectors != null) sectionCount += 3; // Connectors (4), NavMeshConns (5), GraphConns (6)
+ if (LevelConnectors != null) sectionCount++;
+
+ // GateNodes (8) - Explicitly exclude for OldBloodborne
+ if (Navmeshes != null && Version != NVAVersion.OldBloodborne) sectionCount++;
+
+ if (Entries9 != null) sectionCount++;
+ if (Entries10 != null) sectionCount++;
+ if (Entries11 != null) sectionCount++;
+ if (HasSection12) sectionCount++;
+ if (Entries13 != null) sectionCount++;
bw.BigEndian = false;
bw.WriteASCII("NVMA");
bw.WriteUInt32((uint)Version);
bw.ReserveUInt32("FileSize");
- bw.WriteInt32(Version == NVAVersion.OldBloodborne ? 8 : 9);
-
- Navmeshes.Write(bw, 0);
- Entries1.Write(bw, 1);
- Entries2.Write(bw, 2);
- new Section3().Write(bw, 3);
- Connectors.Write(bw, 4);
- connectorPoints.Write(bw, 5);
- connectorConditions.Write(bw, 6);
- Entries7.Write(bw, 7);
- if (Version != NVAVersion.OldBloodborne)
- mapNodes.Write(bw, 8);
+ bw.WriteInt32(sectionCount);
+
+ // Write sections only if they exist
+ if (Entries11 != null) Entries11.Write(bw, 11);
+ if (Navmeshes != null) Navmeshes.Write(bw, 0);
+ if (FaceDatas != null) FaceDatas.Write(bw, 1);
+ if (NodeBanks != null) NodeBanks.Write(bw, 2);
+ if (Entries3 != null) Entries3.Write(bw, 3);
+
+ if (Connectors != null)
+ {
+ Connectors.Write(bw, 4);
+ navMeshConns.Write(bw, 5);
+ graphConns.Write(bw, 6);
+ }
+
+ if (LevelConnectors != null) LevelConnectors.Write(bw, 7);
+ if (Navmeshes != null) gateNodes.Write(bw, 8);
+ if (Entries9 != null) Entries9.Write(bw, 9);
+ if (Entries10 != null) Entries10.Write(bw, 10);
+
+ if (HasSection12)
+ {
+ bw.WriteInt32(12);
+ bw.WriteInt32(Section12Version);
+ bw.ReserveInt32("Section12Length");
+ bw.WriteInt32(0); // count
+
+ long start = bw.Position;
+ if (bw.Position % 0x10 != 0)
+ bw.WritePattern(0x10 - (int)bw.Position % 0x10, 0xFF);
+ bw.FillInt32("Section12Length", (int)(bw.Position - start));
+ }
+
+ if (Entries13 != null) Entries13.Write(bw, 13);
bw.FillUInt32("FileSize", (uint)bw.Position);
}
///
- /// NVA is split up into 8 lists of different types.
+ /// NVA is split up into lists of different types.
///
public abstract class Section : List
{
@@ -236,17 +353,17 @@ public class Navmesh
///
/// Position of the mesh.
///
- public Vector3 Position { get; set; }
+ public Vector4 Position { get; set; }
///
/// Rotation of the mesh, in radians.
///
- public Vector3 Rotation { get; set; }
+ public Vector4 Rotation { get; set; }
///
/// Scale of the mesh.
///
- public Vector3 Scale { get; set; }
+ public Vector4 Scale { get; set; }
///
/// Unknown.
@@ -257,355 +374,335 @@ public class Navmesh
/// Unknown.
///
public int ModelID { get; set; }
-
- ///
- /// Unknown.
- ///
- public int Unk38 { get; set; }
-
+ public int FaceDataIndex { get; set; }
+ public int Unk3C { get; set; }
///
/// Should equal number of vertices in the model file.
///
- public int VertexCount { get; set; }
-
- ///
- /// Unknown.
- ///
- public List NameReferenceIDs { get; set; }
+ public int FaceCount { get; set; }
+ public int Unk4C { get; set; }
+ public bool IsConnectedNavmeshesInline { get; set; }
+ public List ConnectedNavmeshes { get; set; }
///
/// Adjacent nodes in an inter-navmesh graph.
///
- public List MapNodes { get; set; }
-
- ///
- /// Unknown
- ///
- public bool Unk4C { get; set; }
+ public List GateNodes { get; set; }
- private short MapNodesIndex;
- private short MapNodeCount;
+ private short GateNodeIndex;
+ private short GateNodeCount;
+ private int ConnectedNavmeshesCount;
///
/// Creates a Navmesh with default values.
///
public Navmesh()
{
- Scale = Vector3.One;
- NameReferenceIDs = new List();
- MapNodes = new List();
+ Scale = Vector4.One;
+ ConnectedNavmeshes = new List();
+ GateNodes = new List();
+ // No clue. Maybe a sentinel value for when
+ // ConnectedNavmeshes is inline (even though unkOffset seems to also do that?)
+ ConnectedNavmeshesCount = 1075419545;
}
internal Navmesh(BinaryReaderEx br, int version)
{
- Position = br.ReadVector3();
- br.AssertSingle(1);
- Rotation = br.ReadVector3();
- br.AssertInt32(0);
- Scale = br.ReadVector3();
- br.AssertInt32(0);
+ Position = br.ReadVector4();
+ Rotation = br.ReadVector4();
+ Scale = br.ReadVector4();
NameID = br.ReadInt32();
ModelID = br.ReadInt32();
- Unk38 = br.ReadInt32();
- br.AssertInt32(0);
- VertexCount = br.ReadInt32();
- int nameRefCount = br.ReadInt32();
- MapNodesIndex = br.ReadInt16();
- MapNodeCount = br.ReadInt16();
- Unk4C = br.AssertInt32(0, 1) == 1;
+ FaceDataIndex = br.ReadInt32();
+ Unk3C = br.ReadInt32();
+ FaceCount = br.ReadInt32();
+ ConnectedNavmeshesCount = br.ReadInt32();
+ GateNodeIndex = br.ReadInt16();
+ GateNodeCount = br.ReadInt16();
+ Unk4C = br.ReadInt32();
if (version < 4)
{
- if (nameRefCount > 16)
- throw new InvalidDataException("Name reference count should not exceed 16 in DS3/BB.");
- NameReferenceIDs = new List(br.ReadInt32s(nameRefCount));
- for (int i = 0; i < 16 - nameRefCount; i++)
+ if (ConnectedNavmeshesCount > 16)
+ throw new InvalidDataException("Connected navmeshes count should not exceed 16 in DS3/BB.");
+ ConnectedNavmeshes = new List(br.ReadInt32s(ConnectedNavmeshesCount));
+ for (int i = 0; i < 16 - ConnectedNavmeshesCount; i++)
br.AssertInt32(-1);
}
else
{
- int nameRefOffset = br.ReadInt32();
+ int unkOffset = br.ReadInt32();
br.AssertInt32(0);
br.AssertInt32(0);
br.AssertInt32(0);
- NameReferenceIDs = new List(br.GetInt32s(nameRefOffset, nameRefCount));
+
+ if (unkOffset == 0xFF01)
+ {
+ IsConnectedNavmeshesInline = true;
+ ConnectedNavmeshes = new List(br.ReadInt32s(12));
+ }
+ else if (ConnectedNavmeshesCount > 0)
+ {
+ ConnectedNavmeshes = new List(br.GetInt32s(unkOffset, ConnectedNavmeshesCount));
+ }
+ else
+ {
+ ConnectedNavmeshes = new List();
+ }
}
}
- internal void TakeMapNodes(MapNodeSection entries8)
+ internal void TakeGateNodes(GateNodeSection gateNodes)
{
- MapNodes = new List(MapNodeCount);
- for (int i = 0; i < MapNodeCount; i++)
- MapNodes.Add(entries8[MapNodesIndex + i]);
- MapNodeCount = -1;
+ GateNodes = new List(GateNodeCount);
+ for (int i = 0; i < GateNodeCount; i++)
+ GateNodes.Add(gateNodes[GateNodeIndex + i]);
+ GateNodeCount = -1;
+ }
- foreach (MapNode mapNode in MapNodes)
- {
- if (mapNode.SiblingDistances.Count > MapNodes.Count)
- mapNode.SiblingDistances.RemoveRange(MapNodes.Count, mapNode.SiblingDistances.Count - MapNodes.Count);
- }
+ internal void GiveGateNodes(GateNodeSection gateNodesList)
+ {
+ // Sometimes when the gate node count is 0 the index is also 0,
+ // but usually this is accurate.
+ GateNodeIndex = (short)gateNodesList.Count;
+ gateNodesList.AddRange(GateNodes);
}
internal void Write(BinaryWriterEx bw, int version, int index)
{
- bw.WriteVector3(Position);
- bw.WriteSingle(1);
- bw.WriteVector3(Rotation);
- bw.WriteInt32(0);
- bw.WriteVector3(Scale);
- bw.WriteInt32(0);
+ bw.WriteVector4(Position);
+ bw.WriteVector4(Rotation);
+ bw.WriteVector4(Scale);
bw.WriteInt32(NameID);
bw.WriteInt32(ModelID);
- bw.WriteInt32(Unk38);
- bw.WriteInt32(0);
- bw.WriteInt32(VertexCount);
- bw.WriteInt32(NameReferenceIDs.Count);
- bw.WriteInt16(MapNodesIndex);
- bw.WriteInt16((short)MapNodes.Count);
- bw.WriteInt32(Unk4C ? 1 : 0);
+ bw.WriteInt32(FaceDataIndex);
+ bw.WriteInt32(Unk3C);
+ bw.WriteInt32(FaceCount);
+ bw.WriteInt32(IsConnectedNavmeshesInline ? ConnectedNavmeshesCount : ConnectedNavmeshes.Count);
+ bw.WriteInt16(GateNodeIndex);
+ bw.WriteInt16((short)GateNodes.Count);
+ bw.WriteInt32(Unk4C);
if (version < 4)
{
- if (NameReferenceIDs.Count > 16)
- throw new InvalidDataException("Name reference count should not exceed 16 in DS3/BB.");
- bw.WriteInt32s(NameReferenceIDs);
- for (int i = 0; i < 16 - NameReferenceIDs.Count; i++)
+ if (ConnectedNavmeshes.Count > 16)
+ throw new InvalidDataException("Connected navmeshes count should not exceed 16 in DS3/BB.");
+ bw.WriteInt32s(ConnectedNavmeshes);
+ for (int i = 0; i < 16 - ConnectedNavmeshes.Count; i++)
bw.WriteInt32(-1);
}
else
{
- bw.ReserveInt32($"NameRefOffset{index}");
- bw.WriteInt32(0);
- bw.WriteInt32(0);
- bw.WriteInt32(0);
+ if (IsConnectedNavmeshesInline)
+ {
+ bw.WriteInt32(0xFF01);
+ bw.WriteInt32(0);
+ bw.WriteInt32(0);
+ bw.WriteInt32(0);
+ for (int i = 0; i < 12; i++)
+ {
+ bw.WriteInt32(i < ConnectedNavmeshes.Count ? ConnectedNavmeshes[i] : 0);
+ }
+ }
+ else
+ {
+ bw.ReserveInt32($"UnkOffset{index}");
+ bw.WriteInt32(0);
+ bw.WriteInt32(0);
+ bw.WriteInt32(0);
+ }
}
}
internal void WriteNameRefs(BinaryWriterEx bw, int version, int index)
{
- if (version >= 4)
+ if (version >= 4 && !IsConnectedNavmeshesInline)
{
- bw.FillInt32($"NameRefOffset{index}", (int)bw.Position);
- bw.WriteInt32s(NameReferenceIDs);
+ if (ConnectedNavmeshes.Count > 0)
+ {
+ bw.FillInt32($"UnkOffset{index}", (int)bw.Position);
+ bw.WriteInt32s(ConnectedNavmeshes);
+ }
+ else
+ {
+ bw.FillInt32($"UnkOffset{index}", 0);
+ }
}
}
-
- internal void GiveMapNodes(MapNodeSection mapNodes)
- {
- // Sometimes when the map node count is 0 the index is also 0,
- // but usually this is accurate.
- MapNodesIndex = (short)mapNodes.Count;
- mapNodes.AddRange(MapNodes);
- }
-
- ///
- /// Returns a string representation of the navmesh.
- ///
- public override string ToString()
- {
- return $"{NameID} {Position} {Rotation} [{NameReferenceIDs.Count} References] [{MapNodes.Count} MapNodes]";
- }
}
///
- /// Unknown.
+ /// Face Data Section.
///
- public class Section1 : Section
+ public class FaceDataSection : Section
{
- ///
- /// Creates an empty Section1.
- ///
- public Section1() : base(1) { }
+ public FaceDataSection() : base(1) { }
- internal Section1(BinaryReaderEx br) : base(br, 1, 1) { }
+ internal FaceDataSection(BinaryReaderEx br) : base(br, 1, 1) { }
internal override void ReadEntries(BinaryReaderEx br, int count)
{
- for (int i = 0; i < count; i++)
- Add(new Entry1(br));
+ for (int i = 0; i < count; i++)
+ Add(new FaceData(br));
}
internal override void WriteEntries(BinaryWriterEx bw)
{
- foreach (Entry1 entry in this)
+ foreach (FaceData entry in this)
entry.Write(bw);
}
}
///
- /// Unknown.
+ /// Face Data.
///
- public class Entry1
+ public class FaceData
{
- ///
- /// Unknown; always 0 in DS3 and SDT, sometimes 1 in BB.
- ///
public int Unk00 { get; set; }
+ public int Unk04 { get; set; }
- ///
- /// Creates an Entry1 with default values.
- ///
- public Entry1() { }
+ public FaceData() { }
- internal Entry1(BinaryReaderEx br)
+ internal FaceData(BinaryReaderEx br)
{
Unk00 = br.ReadInt32();
- br.AssertInt32(0);
+ Unk04 = br.ReadInt32();
}
internal void Write(BinaryWriterEx bw)
{
bw.WriteInt32(Unk00);
- bw.WriteInt32(0);
+ bw.WriteInt32(Unk04);
}
-
+
///
/// Returns a string representation of the entry.
///
public override string ToString()
{
- return $"{Unk00}";
+ return $"Unk00: {Unk00} Unk04: {Unk04}";
}
}
///
- /// Unknown.
+ /// Node Bank Section.
///
- public class Section2 : Section
+ public class NodeBankSection : Section
{
- ///
- /// Creates an empty Section2.
- ///
- public Section2() : base(1) { }
+ public NodeBankSection() : base(1) { }
- internal Section2(BinaryReaderEx br) : base(br, 2, 1) { }
+ internal NodeBankSection(BinaryReaderEx br) : base(br, 2, 1) { }
internal override void ReadEntries(BinaryReaderEx br, int count)
{
- for (int i = 0; i < count; i++)
- Add(new Entry2(br));
+ for (int i = 0; i < count; i++)
+ Add(new NodeBank(br));
}
internal override void WriteEntries(BinaryWriterEx bw)
{
- foreach (Entry2 entry in this)
+ foreach (NodeBank entry in this)
entry.Write(bw);
}
}
///
- /// Unknown.
+ /// Node Bank.
///
- public class Entry2
+ public class NodeBank
{
///
- /// Unknown; seems to just be the index of this entry.
- ///
- public int Unk00 { get; set; }
-
- ///
- /// References in this entry; maximum of 64.
+ /// Bank ID.
///
- public List References { get; set; }
+ public int BankID { get; set; }
///
- /// Unknown.
+ /// Face references in this entry; maximum of 64.
///
- public int Unk08 { get; set; }
+ public List Faces { get; set; }
+
+ public int EntityID { get; set; }
+ public int Unk0C { get; set; }
- ///
- /// Creates an Entry2 with default values.
- ///
- public Entry2()
+ public NodeBank()
{
- References = new List();
- Unk08 = -1;
+ Faces = new List();
}
- internal Entry2(BinaryReaderEx br)
+ internal NodeBank(BinaryReaderEx br)
{
- Unk00 = br.ReadInt32();
- int referenceCount = br.ReadInt32();
- Unk08 = br.ReadInt32();
- br.AssertInt32(0);
- if (referenceCount > 64)
- throw new InvalidDataException("Entry2 reference count should not exceed 64.");
+ BankID = br.ReadInt32();
+ int faceNum = br.ReadInt32();
+ EntityID = br.ReadInt32();
+ Unk0C = br.ReadInt32();
+
+ if (faceNum > 64)
+ throw new InvalidDataException("NodeBank face count should not exceed 64.");
- References = new List(referenceCount);
- for (int i = 0; i < referenceCount; i++)
- References.Add(new Reference(br));
+ Faces = new List(faceNum);
+ for (int i = 0; i < faceNum; i++)
+ Faces.Add(new NodeBankFace(br));
- for (int i = 0; i < 64 - referenceCount; i++)
+ for (int i = 0; i < 64 - faceNum; i++)
br.AssertInt64(0);
}
internal void Write(BinaryWriterEx bw)
{
- bw.WriteInt32(Unk00);
- bw.WriteInt32(References.Count);
- bw.WriteInt32(Unk08);
- bw.WriteInt32(0);
- if (References.Count > 64)
- throw new InvalidDataException("Entry2 reference count should not exceed 64.");
+ bw.WriteInt32(BankID);
+ bw.WriteInt32(Faces.Count);
+ bw.WriteInt32(EntityID);
+ bw.WriteInt32(Unk0C);
- foreach (Reference reference in References)
- reference.Write(bw);
+ if (Faces.Count > 64)
+ throw new InvalidDataException("NodeBank face count should not exceed 64.");
- for (int i = 0; i < 64 - References.Count; i++)
+ foreach (NodeBankFace face in Faces)
+ face.Write(bw);
+
+ for (int i = 0; i < 64 - Faces.Count; i++)
bw.WriteInt64(0);
}
-
+
///
/// Returns a string representation of the entry.
///
public override string ToString()
{
- return $"{Unk00} {Unk08} [{References.Count} References]";
+ return $"{BankID} {EntityID} [{Faces.Count} Faces]";
}
- ///
- /// Unknown.
- ///
- public class Reference
- {
- ///
- /// Unknown.
- ///
- public int UnkIndex { get; set; }
-
- ///
- /// Unknown.
- ///
- public int NameID { get; set; }
+ }
- ///
- /// Creates a Reference with defalt values.
- ///
- public Reference() { }
+ public class NodeBankFace
+ {
+ public int FaceIndex { get; set; }
+ public int CollisionID { get; set; }
- internal Reference(BinaryReaderEx br)
- {
- UnkIndex = br.ReadInt32();
- NameID = br.ReadInt32();
- }
+ public NodeBankFace() { }
- internal void Write(BinaryWriterEx bw)
- {
- bw.WriteInt32(UnkIndex);
- bw.WriteInt32(NameID);
- }
+ internal NodeBankFace(BinaryReaderEx br)
+ {
+ FaceIndex = br.ReadInt32();
+ CollisionID = br.ReadInt32();
+ }
- ///
- /// Returns a string representation of the reference.
- ///
- public override string ToString()
- {
- return $"{UnkIndex} {NameID}";
- }
+ internal void Write(BinaryWriterEx bw)
+ {
+ bw.WriteInt32(FaceIndex);
+ bw.WriteInt32(CollisionID);
+ }
+
+ ///
+ /// Returns a string representation of the reference.
+ ///
+ public override string ToString()
+ {
+ return $"{FaceIndex} {CollisionID}";
}
}
- private class Section3 : Section
+ public class Section3 : Section
{
public Section3() : base(1) { }
@@ -613,27 +710,44 @@ internal Section3(BinaryReaderEx br) : base(br, 3, 1) { }
internal override void ReadEntries(BinaryReaderEx br, int count)
{
- for (int i = 0; i < count; i++)
+ for (int i = 0; i < count; i++)
Add(new Entry3(br));
}
internal override void WriteEntries(BinaryWriterEx bw)
{
- foreach (Entry3 entry in this)
+ foreach (Entry3 entry in this)
entry.Write(bw);
}
}
- private class Entry3
+ public class Entry3
{
+ public Vector4[] Vectors { get; set; }
+
+ const int _numElements = 8;
+
+ public Entry3()
+ {
+ Vectors = new Vector4[_numElements];
+ }
+
internal Entry3(BinaryReaderEx br)
{
- throw new NotImplementedException("Section3 is empty in all known NVAs.");
+ // Reminder that this should be empty prior to Elden Ring
+ // throw new NotImplementedException("Section3 is empty in all known NVAs.");
+ Vectors = new Vector4[_numElements];
+ for (int i = 0; i < _numElements; i++)
+ Vectors[i] = br.ReadVector4();
}
internal void Write(BinaryWriterEx bw)
{
- throw new NotImplementedException("Section3 is empty in all known NVAs.");
+ // Reminder that this should be empty prior to Elden Ring
+ // throw new NotImplementedException("Section3 is empty in all known NVAs.");
+
+ for (int i = 0; i < _numElements; i++)
+ bw.WriteVector4(Vectors[i]);
}
}
@@ -676,107 +790,109 @@ public class Connector
/// The navmesh to be attached.
///
public int TargetNameID { get; set; }
+ public int Unk14 { get; set; }
+ public int Unk1C { get; set; }
///
- /// Points used by this connection.
- ///
- public List Points { get; set; }
-
- ///
- /// Conditions used by this connection.
+ /// NavMeshs used by this connection.
///
- public List Conditions { get; set; }
+ public List NavMeshConnections { get; set; }
+ public List GraphConnections { get; set; }
- private int PointCount;
- private int ConditionCount;
- private int PointsIndex;
- private int ConditionsIndex;
+ private int NavMeshConnectionCount;
+ private int GraphConnectionCount;
+ private int NavMeshConnectionIndex;
+ private int GraphConnectionIndex;
///
/// Creates a Connector with default values.
///
public Connector()
{
- Points = new List();
- Conditions = new List();
+ NavMeshConnections = new List();
+ GraphConnections = new List();
}
internal Connector(BinaryReaderEx br)
{
MainNameID = br.ReadInt32();
TargetNameID = br.ReadInt32();
- PointCount = br.ReadInt32();
- ConditionCount = br.ReadInt32();
- PointsIndex = br.ReadInt32();
- br.AssertInt32(0);
- ConditionsIndex = br.ReadInt32();
- br.AssertInt32(0);
+ NavMeshConnectionCount = br.ReadInt32();
+ GraphConnectionCount = br.ReadInt32();
+ NavMeshConnectionIndex = br.ReadInt32();
+ Unk14 = br.ReadInt32();
+ GraphConnectionIndex = br.ReadInt32();
+ Unk1C = br.ReadInt32();
}
- internal void TakePointsAndConds(ConnectorPointSection points, ConnectorConditionSection conds)
+ internal void TakeConnections(NavMeshConnectionSection navMeshConns, GraphConnectionSection graphConns)
{
- Points = new List(PointCount);
- for (int i = 0; i < PointCount; i++)
- Points.Add(points[PointsIndex + i]);
- PointCount = -1;
-
- Conditions = new List(ConditionCount);
- for (int i = 0; i < ConditionCount; i++)
- Conditions.Add(conds[ConditionsIndex + i]);
- ConditionCount = -1;
+ NavMeshConnections = new List(NavMeshConnectionCount);
+ for (int i = 0; i < NavMeshConnectionCount; i++)
+ NavMeshConnections.Add(navMeshConns[NavMeshConnectionIndex + i]);
+ NavMeshConnectionCount = -1;
+
+ GraphConnections = new List(GraphConnectionCount);
+ for (int i = 0; i < GraphConnectionCount; i++)
+ GraphConnections.Add(graphConns[GraphConnectionIndex + i]);
+ GraphConnectionCount = -1;
}
- internal void GivePointsAndConds(ConnectorPointSection points, ConnectorConditionSection conds)
+ internal void GiveConnections(NavMeshConnectionSection navMeshConns, GraphConnectionSection graphConns)
{
- PointsIndex = points.Count;
- points.AddRange(Points);
+ NavMeshConnectionIndex = navMeshConns.Count;
+ navMeshConns.AddRange(NavMeshConnections);
- ConditionsIndex = conds.Count;
- conds.AddRange(Conditions);
+ GraphConnectionIndex = graphConns.Count;
+ graphConns.AddRange(GraphConnections);
}
internal void Write(BinaryWriterEx bw)
{
bw.WriteInt32(MainNameID);
bw.WriteInt32(TargetNameID);
- bw.WriteInt32(Points.Count);
- bw.WriteInt32(Conditions.Count);
- bw.WriteInt32(PointsIndex);
- bw.WriteInt32(0);
- bw.WriteInt32(ConditionsIndex);
- bw.WriteInt32(0);
+ bw.WriteInt32(NavMeshConnections.Count);
+ bw.WriteInt32(GraphConnections.Count);
+ bw.WriteInt32(NavMeshConnectionIndex);
+ bw.WriteInt32(Unk14);
+ bw.WriteInt32(GraphConnectionIndex);
+ bw.WriteInt32(Unk1C);
}
-
+
///
/// Returns a string representation of the connector.
///
public override string ToString()
{
- return $"{MainNameID} -> {TargetNameID} [{Points.Count} Points][{Conditions.Count} Conditions]";
+ return $"{MainNameID} -> {TargetNameID} [{NavMeshConnections.Count} Points][{GraphConnections.Count} Conditions]";
}
+
}
///
- /// A list of points used to connect navmeshes.
+ /// A list of NavMeshes used to connect navmeshes.
///
- internal class ConnectorPointSection : Section
+ internal class NavMeshConnectionSection : Section
{
///
/// Creates an empty ConnectorPointSection.
///
- public ConnectorPointSection() : base(1) { }
+ public NavMeshConnectionSection() : base(1) { }
- internal ConnectorPointSection(BinaryReaderEx br) : base(br, 5, 1) { }
+ ///
+ /// Creates an empty NavMeshConnectionSection
+ ///
+ internal NavMeshConnectionSection(BinaryReaderEx br) : base(br, 5, 1) { }
internal override void ReadEntries(BinaryReaderEx br, int count)
{
for (int i = 0; i < count; i++)
- Add(new ConnectorPoint(br));
+ Add(new NavMeshConnection(br));
}
internal override void WriteEntries(BinaryWriterEx bw)
{
- foreach (ConnectorPoint entry in this)
+ foreach (NavMeshConnection entry in this)
entry.Write(bw);
}
}
@@ -784,79 +900,50 @@ internal override void WriteEntries(BinaryWriterEx bw)
///
/// A point used to connect two navmeshes.
///
- public class ConnectorPoint
+ public class NavMeshConnection
{
- ///
- /// Unknown.
- ///
- public int Unk00 { get; set; }
-
- ///
- /// Unknown.
- ///
- public int Unk04 { get; set; }
-
- ///
- /// Unknown.
- ///
- public int Unk08 { get; set; }
-
- ///
- /// Unknown.
- ///
- public int Unk0C { get; set; }
+ public int FaceIndex { get; set; }
+ public int EdgeIndex { get; set; }
+ public int OppositeFaceIndex { get; set; }
+ public int OppositeEdgeIndex { get; set; }
- ///
- /// Creates a ConnectorPoint with default values.
- ///
- public ConnectorPoint() { }
+ public NavMeshConnection() { }
- internal ConnectorPoint(BinaryReaderEx br)
+ internal NavMeshConnection(BinaryReaderEx br)
{
- Unk00 = br.ReadInt32();
- Unk04 = br.ReadInt32();
- Unk08 = br.ReadInt32();
- Unk0C = br.ReadInt32();
+ FaceIndex = br.ReadInt32();
+ EdgeIndex = br.ReadInt32();
+ OppositeFaceIndex = br.ReadInt32();
+ OppositeEdgeIndex = br.ReadInt32();
}
internal void Write(BinaryWriterEx bw)
{
- bw.WriteInt32(Unk00);
- bw.WriteInt32(Unk04);
- bw.WriteInt32(Unk08);
- bw.WriteInt32(Unk0C);
- }
-
- ///
- /// Returns a string representation of the point.
- ///
- public override string ToString()
- {
- return $"{Unk00} {Unk04} {Unk08} {Unk0C}";
+ bw.WriteInt32(FaceIndex);
+ bw.WriteInt32(EdgeIndex);
+ bw.WriteInt32(OppositeFaceIndex);
+ bw.WriteInt32(OppositeEdgeIndex);
}
}
///
/// A list of unknown conditions used by connectors.
///
- internal class ConnectorConditionSection : Section
+ internal class GraphConnectionSection : Section
{
- ///
- /// Creates an empty ConnectorConditionSection.
- ///
- public ConnectorConditionSection() : base(1) { }
+ public GraphConnectionSection() : base(1) { }
- internal ConnectorConditionSection(BinaryReaderEx br) : base(br, 6, 1) { }
+ internal GraphConnectionSection(BinaryReaderEx br) : base(br, 6, 1) { }
internal override void ReadEntries(BinaryReaderEx br, int count)
{
for (int i = 0; i < count; i++)
- Add(new ConnectorCondition(br));
+ Add(new GraphConnection(br));
}
internal override void WriteEntries(BinaryWriterEx bw)
{
- foreach (ConnectorCondition entry in this)
+ foreach (GraphConnection entry in this)
entry.Write(bw);
}
}
@@ -864,65 +951,53 @@ internal override void WriteEntries(BinaryWriterEx bw)
///
/// An unknown condition used by a connector.
///
- public class ConnectorCondition
+ public class GraphConnection
{
- ///
- /// Unknown.
- ///
- public int Condition1 { get; set; }
+ public int NodeIndex { get; set; }
+ public int OppositeNodeIndex { get; set; }
- ///
- /// Unknown.
- ///
- public int Condition2 { get; set; }
-
- ///
- /// Creates a ConnectorCondition with default values.
- ///
- public ConnectorCondition() { }
+ public GraphConnection() { }
- internal ConnectorCondition(BinaryReaderEx br)
+ internal GraphConnection(BinaryReaderEx br)
{
- Condition1 = br.ReadInt32();
- Condition2 = br.ReadInt32();
+ NodeIndex = br.ReadInt32();
+ OppositeNodeIndex = br.ReadInt32();
}
internal void Write(BinaryWriterEx bw)
{
- bw.WriteInt32(Condition1);
- bw.WriteInt32(Condition2);
+ bw.WriteInt32(NodeIndex);
+ bw.WriteInt32(OppositeNodeIndex);
}
-
+
///
/// Returns a string representation of the condition.
///
public override string ToString()
{
- return $"{Condition1} {Condition2}";
+ return $"{NodeIndex} {OppositeNodeIndex}";
}
}
+
///
- /// Unknown.
+ /// Returns a string representation of the condition.
///
- public class Section7 : Section
+ public class LevelConnectorSection : Section
{
- ///
- /// Creates an empty Section7.
- ///
- public Section7() : base(1) { }
+ public LevelConnectorSection() : base(1) { }
- internal Section7(BinaryReaderEx br) : base(br, 7, 1) { }
+ internal LevelConnectorSection(BinaryReaderEx br) : base(br, 7, 1) { }
internal override void ReadEntries(BinaryReaderEx br, int count)
{
for (int i = 0; i < count; i++)
- Add(new Entry7(br));
+ Add(new LevelConnector(br));
}
internal override void WriteEntries(BinaryWriterEx bw)
{
- foreach (Entry7 entry in this)
+ foreach (LevelConnector entry in this)
entry.Write(bw);
}
}
@@ -930,46 +1005,35 @@ internal override void WriteEntries(BinaryWriterEx bw)
///
/// Unknown; believed to have something to do with connecting maps.
///
- public class Entry7
+ public class LevelConnector
{
- ///
- /// Unknown.
- ///
- public Vector3 Position { get; set; }
-
- ///
- /// Unknown.
- ///
- public int NameID { get; set; }
-
- ///
- /// Unknown.
- ///
+ public Vector4 Position { get; set; }
+ public int NavmeshID { get; set; }
+ public int Unk14 { get; set; }
public int Unk18 { get; set; }
+ public int Unk1C { get; set; }
///
- /// Creates an Entry7 with default values.
+ /// Creates a LevelConnector with default values.
///
- public Entry7() { }
+ public LevelConnector() { }
- internal Entry7(BinaryReaderEx br)
+ internal LevelConnector(BinaryReaderEx br)
{
- Position = br.ReadVector3();
- br.AssertSingle(1);
- NameID = br.ReadInt32();
- br.AssertInt32(0);
+ Position = br.ReadVector4();
+ NavmeshID = br.ReadInt32();
+ Unk14 = br.ReadInt32();
Unk18 = br.ReadInt32();
- br.AssertInt32(0);
+ Unk1C = br.ReadInt32();
}
internal void Write(BinaryWriterEx bw)
{
- bw.WriteVector3(Position);
- bw.WriteSingle(1);
- bw.WriteInt32(NameID);
- bw.WriteInt32(0);
+ bw.WriteVector4(Position);
+ bw.WriteInt32(NavmeshID);
+ bw.WriteInt32(Unk14);
bw.WriteInt32(Unk18);
- bw.WriteInt32(0);
+ bw.WriteInt32(Unk1C);
}
///
@@ -977,26 +1041,23 @@ internal void Write(BinaryWriterEx bw)
///
public override string ToString()
{
- return $"{Position} {NameID} {Unk18}";
+ return $"Position: {Position} NavmeshID: {NavmeshID} Unk14: {Unk14} Unk18: {Unk18} Unk1C: {Unk1C}";
}
}
///
/// Unknown. Version: 1 for BB and DS3, 2 for Sekiro.
///
- internal class MapNodeSection : Section
+ internal class GateNodeSection : Section
{
- ///
- /// Creates an empty Section8 with the given version.
- ///
- public MapNodeSection(int version) : base(version) { }
+ public GateNodeSection(int version) : base(version) { }
- internal MapNodeSection(BinaryReaderEx br) : base(br, 8, 1, 2) { }
+ internal GateNodeSection(BinaryReaderEx br) : base(br, 8, 1, 2) { }
internal override void ReadEntries(BinaryReaderEx br, int count)
{
for (int i = 0; i < count; i++)
- Add(new MapNode(br, Version));
+ Add(new GateNode(br, Version));
}
internal override void WriteEntries(BinaryWriterEx bw)
@@ -1005,113 +1066,316 @@ internal override void WriteEntries(BinaryWriterEx bw)
this[i].Write(bw, Version, i);
for (int i = 0; i < Count; i++)
- this[i].WriteSubIDs(bw, Version, i);
+ this[i].WriteCosts(bw, Version, i);
}
}
///
/// Unknown.
///
- public class MapNode
+ public class GateNode
{
///
/// Unknown.
///
public Vector3 Position { get; set; }
-
///
/// Index to a navmesh.
///
- public short Section0Index { get; set; }
-
+ public short ConnectedNavmeshIndex { get; set; }
///
/// Unknown.
///
- public short MainID { get; set; }
-
+ public short NodeSubID { get; set; }
///
/// Unknown.
///
- public List SiblingDistances { get; set; }
-
+ public List NeighbourGateNodeCosts { get; set; }
+
///
/// Unknown; only present in Sekiro.
///
public int Unk14 { get; set; }
///
- /// Creates an Entry8 with default values.
+ /// Creates a GateNode with default values.
///
- public MapNode()
+ public GateNode()
{
- SiblingDistances = new List();
+ NeighbourGateNodeCosts = new List();
}
- internal MapNode(BinaryReaderEx br, int version)
+ internal GateNode(BinaryReaderEx br, int version)
{
Position = br.ReadVector3();
- Section0Index = br.ReadInt16();
- MainID = br.ReadInt16();
+ ConnectedNavmeshIndex = br.ReadInt16();
+ NodeSubID = br.ReadInt16();
if (version < 2)
{
- SiblingDistances = new List(
- br.ReadUInt16s(16).Select(s => s == 0xFFFF ? -1 : s * 0.01f));
+ NeighbourGateNodeCosts = new List(br.ReadInt16s(16));
}
else
{
- int subIDCount = br.ReadInt32();
+ int costsCount = br.ReadInt32();
Unk14 = br.ReadInt32();
- int subIDsOffset = br.ReadInt32();
+ int costsOffset = br.ReadInt32();
br.AssertInt32(0);
- SiblingDistances = new List(
- br.GetUInt16s(subIDsOffset, subIDCount).Select(s => s == 0xFFFF ? -1 : s * 0.01f));
+
+ if (costsCount > 0)
+ NeighbourGateNodeCosts = new List(br.GetInt16s(costsOffset, costsCount));
+ else
+ NeighbourGateNodeCosts = new List();
}
}
internal void Write(BinaryWriterEx bw, int version, int index)
{
bw.WriteVector3(Position);
- bw.WriteInt16(Section0Index);
- bw.WriteInt16(MainID);
+ bw.WriteInt16(ConnectedNavmeshIndex);
+ bw.WriteInt16(NodeSubID);
if (version < 2)
{
- if (SiblingDistances.Count > 16)
- throw new InvalidDataException("MapNode distance count must not exceed 16 in DS3/BB.");
+ if (NeighbourGateNodeCosts.Count > 16)
+ throw new InvalidDataException("GateNode costs count must not exceed 16 in BB/DS3.");
- foreach (float distance in SiblingDistances)
- bw.WriteUInt16((ushort)(distance == -1 ? 0xFFFF : Math.Round(distance * 100)));
+ // Stored as floats in previous nva implementation. Converted with:
+ // (ushort)(distance == -1 ? 0xFFFF : Math.Round(distance * 100)
+ foreach (short cost in NeighbourGateNodeCosts)
+ bw.WriteInt16(cost);
- for (int i = 0; i < 16 - SiblingDistances.Count; i++)
- bw.WriteUInt16(0xFFFF);
+ for (int i = 0; i < 16 - NeighbourGateNodeCosts.Count; i++)
+ bw.WriteInt16(-1);
}
else
{
- bw.WriteInt32(SiblingDistances.Count);
+ bw.WriteInt32(NeighbourGateNodeCosts.Count);
bw.WriteInt32(Unk14);
- bw.ReserveInt32($"SubIDsOffset{index}");
+ bw.ReserveInt32($"CostsOffset{index}");
bw.WriteInt32(0);
}
}
- internal void WriteSubIDs(BinaryWriterEx bw, int version, int index)
+ internal void WriteCosts(BinaryWriterEx bw, int version, int index)
{
if (version >= 2)
{
- bw.FillInt32($"SubIDsOffset{index}", (int)bw.Position);
- foreach (float distance in SiblingDistances)
- bw.WriteUInt16((ushort)(distance == -1 ? 0xFFFF : Math.Round(distance * 100)));
+ // This check not in original. Is this needed?
+ if (NeighbourGateNodeCosts.Count > 0)
+ {
+ bw.FillInt32($"CostsOffset{index}", (int)bw.Position);
+ foreach (short cost in NeighbourGateNodeCosts)
+ bw.WriteInt16(cost);
+ }
+ else
+ {
+ bw.FillInt32($"CostsOffset{index}", 0);
+ }
}
}
-
+
///
/// Returns a string representation of the entry.
///
public override string ToString()
{
- return $"{Position} {Section0Index} {MainID} [{SiblingDistances.Count} SubIDs]";
+ return $"[Position: {Position} ConnectedNavmeshIndex: {ConnectedNavmeshIndex} NeighbourGateNodeCosts.Count: {NeighbourGateNodeCosts.Count} SubIDs Unk14: {Unk14}]";
+ }
+ }
+
+ public class Section9 : Section
+ {
+ public Section9() : base(1) { }
+
+ internal Section9(BinaryReaderEx br) : base(br, 9, 1) { }
+
+ internal override void ReadEntries(BinaryReaderEx br, int count)
+ {
+ for (int i = 0; i < count; i++) Add(new Entry9(br));
+ }
+
+ internal override void WriteEntries(BinaryWriterEx bw)
+ {
+ foreach (Entry9 entry in this) entry.Write(bw);
+ }
+ }
+
+ public class Entry9
+ {
+ public int Unk00 { get; set; }
+ public int Unk04 { get; set; }
+ public int Unk08 { get; set; }
+ public int Unk0C { get; set; }
+
+ public Entry9()
+ {
+ }
+
+ internal Entry9(BinaryReaderEx br)
+ {
+ Unk00 = br.ReadInt32();
+ Unk04 = br.ReadInt32();
+ Unk08 = br.ReadInt32();
+ Unk0C = br.ReadInt32();
+ }
+
+ internal void Write(BinaryWriterEx bw)
+ {
+ bw.WriteInt32(Unk00);
+ bw.WriteInt32(Unk04);
+ bw.WriteInt32(Unk08);
+ bw.WriteInt32(Unk0C);
+ }
+ }
+
+ public class Section10 : Section
+ {
+ public Section10() : base(1)
+ {
+ }
+
+ internal Section10(BinaryReaderEx br) : base(br, 10, 1)
+ {
+ }
+
+ internal override void ReadEntries(BinaryReaderEx br, int count)
+ {
+ for (int i = 0; i < count; i++) Add(new Entry10(br));
+ }
+
+ internal override void WriteEntries(BinaryWriterEx bw)
+ {
+ foreach (Entry10 entry in this) entry.Write(bw);
+ }
+ }
+
+ public class Entry10
+ {
+ public Vector4 Unk00 { get; set; }
+ public int Unk10 { get; set; }
+ public int Unk14 { get; set; }
+ public int Unk18 { get; set; }
+ public int Unk1C { get; set; }
+
+ public Entry10()
+ {
+ }
+
+ internal Entry10(BinaryReaderEx br)
+ {
+ Unk00 = br.ReadVector4();
+ Unk10 = br.ReadInt32();
+ Unk14 = br.ReadInt32();
+ Unk18 = br.ReadInt32();
+ Unk1C = br.ReadInt32();
+ }
+
+ internal void Write(BinaryWriterEx bw)
+ {
+ bw.WriteVector4(Unk00);
+ bw.WriteInt32(Unk10);
+ bw.WriteInt32(Unk14);
+ bw.WriteInt32(Unk18);
+ bw.WriteInt32(Unk1C);
+ }
+ }
+
+ public class Section11 : Section
+ {
+ public Section11() : base(1)
+ {
+ }
+
+ internal Section11(BinaryReaderEx br) : base(br, 11, 1)
+ {
+ }
+
+ internal override void ReadEntries(BinaryReaderEx br, int count)
+ {
+ for (int i = 0; i < count; i++) Add(new Entry11(br));
+ }
+
+ internal override void WriteEntries(BinaryWriterEx bw)
+ {
+ foreach (Entry11 entry in this) entry.Write(bw);
+ }
+ }
+
+ public class Entry11
+ {
+ public int Unk00 { get; set; }
+ public int Unk04 { get; set; }
+ public int Unk08 { get; set; }
+ public int Unk0C { get; set; }
+
+ public Entry11()
+ {
+ }
+
+ internal Entry11(BinaryReaderEx br)
+ {
+ Unk00 = br.ReadInt32();
+ Unk04 = br.ReadInt32();
+ Unk08 = br.ReadInt32();
+ Unk0C = br.ReadInt32();
+ }
+
+ internal void Write(BinaryWriterEx bw)
+ {
+ bw.WriteInt32(Unk00);
+ bw.WriteInt32(Unk04);
+ bw.WriteInt32(Unk08);
+ bw.WriteInt32(Unk0C);
+ }
+ }
+
+ public class Section13 : Section
+ {
+ public Section13() : base(1)
+ {
+ }
+
+ internal Section13(BinaryReaderEx br) : base(br, 13, 1)
+ {
+ }
+
+ internal override void ReadEntries(BinaryReaderEx br, int count)
+ {
+ for (int i = 0; i < count; i++) Add(new Entry13(br));
+ }
+
+ internal override void WriteEntries(BinaryWriterEx bw)
+ {
+ foreach (Entry13 entry in this) entry.Write(bw);
+ }
+ }
+
+ public class Entry13
+ {
+ public Vector4[] Vectors { get; set; }
+ public int[] Ints { get; set; }
+
+ public Entry13()
+ {
+ Vectors = new Vector4[6];
+ Ints = new int[8];
+ }
+
+ internal Entry13(BinaryReaderEx br)
+ {
+ Vectors = new Vector4[6];
+ for (int i = 0; i < 6; i++) Vectors[i] = br.ReadVector4();
+
+ Ints = new int[8];
+ for (int i = 0; i < 8; i++) Ints[i] = br.ReadInt32();
+ }
+
+ internal void Write(BinaryWriterEx bw)
+ {
+ for (int i = 0; i < 6; i++) bw.WriteVector4(Vectors[i]);
+ for (int i = 0; i < 8; i++) bw.WriteInt32(Ints[i]);
}
}
}
-}
+}
\ No newline at end of file