diff --git a/Mutagen.Bethesda.Starfield/Records/Common Subrecords/NavmeshGeometry.xml b/Mutagen.Bethesda.Starfield/Records/Common Subrecords/NavmeshGeometry.xml
index f3fa40ddf4..536eb13d8d 100644
--- a/Mutagen.Bethesda.Starfield/Records/Common Subrecords/NavmeshGeometry.xml
+++ b/Mutagen.Bethesda.Starfield/Records/Common Subrecords/NavmeshGeometry.xml
@@ -16,7 +16,7 @@
-
+
diff --git a/Mutagen.Bethesda.Starfield/Records/Common Subrecords/NavmeshGeometry_Generated.cs b/Mutagen.Bethesda.Starfield/Records/Common Subrecords/NavmeshGeometry_Generated.cs
index 80d7d170f9..df75bb3dce 100644
--- a/Mutagen.Bethesda.Starfield/Records/Common Subrecords/NavmeshGeometry_Generated.cs
+++ b/Mutagen.Bethesda.Starfield/Records/Common Subrecords/NavmeshGeometry_Generated.cs
@@ -180,9 +180,18 @@ public ExtendedList Waypoints
public P3Float GridMax { get; set; } = default;
#endregion
#region GridArrays
- public NavmeshGridArray GridArrays { get; set; } = new NavmeshGridArray();
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
- INavmeshGridArrayGetter INavmeshGeometryGetter.GridArrays => GridArrays;
+ private ExtendedList _GridArrays = new ExtendedList();
+ public ExtendedList GridArrays
+ {
+ get => this._GridArrays;
+ init => this._GridArrays = value;
+ }
+ #region Interface Members
+ [DebuggerBrowsable(DebuggerBrowsableState.Never)]
+ IReadOnlyList INavmeshGeometryGetter.GridArrays => _GridArrays;
+ #endregion
+
#endregion
#region Unknown3
public Int32 Unknown3 { get; set; } = default;
@@ -241,7 +250,7 @@ public Mask(TItem initialValue)
this.GridMaxDistance = initialValue;
this.GridMin = initialValue;
this.GridMax = initialValue;
- this.GridArrays = new MaskItem?>(initialValue, new NavmeshGridArray.Mask(initialValue));
+ this.GridArrays = new MaskItem?>>?>(initialValue, Enumerable.Empty?>>());
this.Unknown3 = initialValue;
}
@@ -279,7 +288,7 @@ public Mask(
this.GridMaxDistance = GridMaxDistance;
this.GridMin = GridMin;
this.GridMax = GridMax;
- this.GridArrays = new MaskItem?>(GridArrays, new NavmeshGridArray.Mask(GridArrays));
+ this.GridArrays = new MaskItem?>>?>(GridArrays, Enumerable.Empty?>>());
this.Unknown3 = Unknown3;
}
@@ -307,7 +316,7 @@ protected Mask()
public TItem GridMaxDistance;
public TItem GridMin;
public TItem GridMax;
- public MaskItem?>? GridArrays { get; set; }
+ public MaskItem?>>?>? GridArrays;
public TItem Unknown3;
#endregion
@@ -464,10 +473,17 @@ public bool All(Func eval)
if (!eval(this.GridMaxDistance)) return false;
if (!eval(this.GridMin)) return false;
if (!eval(this.GridMax)) return false;
- if (GridArrays != null)
+ if (this.GridArrays != null)
{
if (!eval(this.GridArrays.Overall)) return false;
- if (this.GridArrays.Specific != null && !this.GridArrays.Specific.All(eval)) return false;
+ if (this.GridArrays.Specific != null)
+ {
+ foreach (var item in this.GridArrays.Specific)
+ {
+ if (!eval(item.Overall)) return false;
+ if (item.Specific != null && !item.Specific.All(eval)) return false;
+ }
+ }
}
if (!eval(this.Unknown3)) return false;
return true;
@@ -573,10 +589,17 @@ public bool Any(Func eval)
if (eval(this.GridMaxDistance)) return true;
if (eval(this.GridMin)) return true;
if (eval(this.GridMax)) return true;
- if (GridArrays != null)
+ if (this.GridArrays != null)
{
if (eval(this.GridArrays.Overall)) return true;
- if (this.GridArrays.Specific != null && this.GridArrays.Specific.Any(eval)) return true;
+ if (this.GridArrays.Specific != null)
+ {
+ foreach (var item in this.GridArrays.Specific)
+ {
+ if (!eval(item.Overall)) return false;
+ if (item.Specific != null && !item.Specific.All(eval)) return false;
+ }
+ }
}
if (eval(this.Unknown3)) return true;
return false;
@@ -706,7 +729,21 @@ protected void Translate_InternalFill(Mask obj, Func eval)
obj.GridMaxDistance = eval(this.GridMaxDistance);
obj.GridMin = eval(this.GridMin);
obj.GridMax = eval(this.GridMax);
- obj.GridArrays = this.GridArrays == null ? null : new MaskItem?>(eval(this.GridArrays.Overall), this.GridArrays.Specific?.Translate(eval));
+ if (GridArrays != null)
+ {
+ obj.GridArrays = new MaskItem?>>?>(eval(this.GridArrays.Overall), Enumerable.Empty?>>());
+ if (GridArrays.Specific != null)
+ {
+ var l = new List?>>();
+ obj.GridArrays.Specific = l;
+ foreach (var item in GridArrays.Specific)
+ {
+ MaskItemIndexed?>? mask = item == null ? null : new MaskItemIndexed?>(item.Index, eval(item.Overall), item.Specific?.Translate(eval));
+ if (mask == null) continue;
+ l.Add(mask);
+ }
+ }
+ }
obj.Unknown3 = eval(this.Unknown3);
}
#endregion
@@ -891,9 +928,24 @@ public void Print(StructuredStringBuilder sb, NavmeshGeometry.Mask? printM
{
sb.AppendItem(GridMax, "GridMax");
}
- if (printMask?.GridArrays?.Overall ?? true)
+ if ((printMask?.GridArrays?.Overall ?? true)
+ && GridArrays is {} GridArraysItem)
{
- GridArrays?.Print(sb);
+ sb.AppendLine("GridArrays =>");
+ using (sb.Brace())
+ {
+ sb.AppendItem(GridArraysItem.Overall);
+ if (GridArraysItem.Specific != null)
+ {
+ foreach (var subItem in GridArraysItem.Specific)
+ {
+ using (sb.Brace())
+ {
+ subItem?.Print(sb);
+ }
+ }
+ }
+ }
}
if (printMask?.Unknown3 ?? true)
{
@@ -938,7 +990,7 @@ public List Warnings
public Exception? GridMaxDistance;
public Exception? GridMin;
public Exception? GridMax;
- public MaskItem? GridArrays;
+ public MaskItem>?>? GridArrays;
public Exception? Unknown3;
#endregion
@@ -1038,7 +1090,7 @@ public void SetNthException(int index, Exception ex)
this.GridMax = ex;
break;
case NavmeshGeometry_FieldIndex.GridArrays:
- this.GridArrays = new MaskItem(ex, null);
+ this.GridArrays = new MaskItem>?>(ex, null);
break;
case NavmeshGeometry_FieldIndex.Unknown3:
this.Unknown3 = ex;
@@ -1099,7 +1151,7 @@ public void SetNthMask(int index, object obj)
this.GridMax = (Exception?)obj;
break;
case NavmeshGeometry_FieldIndex.GridArrays:
- this.GridArrays = (MaskItem?)obj;
+ this.GridArrays = (MaskItem>?>)obj;
break;
case NavmeshGeometry_FieldIndex.Unknown3:
this.Unknown3 = (Exception?)obj;
@@ -1302,7 +1354,24 @@ protected void PrintFillInternal(StructuredStringBuilder sb)
{
sb.AppendItem(GridMax, "GridMax");
}
- GridArrays?.Print(sb);
+ if (GridArrays is {} GridArraysItem)
+ {
+ sb.AppendLine("GridArrays =>");
+ using (sb.Brace())
+ {
+ sb.AppendItem(GridArraysItem.Overall);
+ if (GridArraysItem.Specific != null)
+ {
+ foreach (var subItem in GridArraysItem.Specific)
+ {
+ using (sb.Brace())
+ {
+ subItem?.Print(sb);
+ }
+ }
+ }
+ }
+ }
{
sb.AppendItem(Unknown3, "Unknown3");
}
@@ -1329,7 +1398,7 @@ public ErrorMask Combine(ErrorMask? rhs)
ret.GridMaxDistance = this.GridMaxDistance.Combine(rhs.GridMaxDistance);
ret.GridMin = this.GridMin.Combine(rhs.GridMin);
ret.GridMax = this.GridMax.Combine(rhs.GridMax);
- ret.GridArrays = this.GridArrays.Combine(rhs.GridArrays, (l, r) => l.Combine(r));
+ ret.GridArrays = new MaskItem>?>(Noggog.ExceptionExt.Combine(this.GridArrays?.Overall, rhs.GridArrays?.Overall), Noggog.ExceptionExt.Combine(this.GridArrays?.Specific, rhs.GridArrays?.Specific));
ret.Unknown3 = this.Unknown3.Combine(rhs.Unknown3);
return ret;
}
@@ -1418,7 +1487,7 @@ protected void GetCrystal(List<(bool On, TranslationCrystal? SubCrystal)> ret)
ret.Add((GridMaxDistance, null));
ret.Add((GridMin, null));
ret.Add((GridMax, null));
- ret.Add((GridArrays != null ? GridArrays.OnOverall : DefaultOn, GridArrays?.GetCrystal()));
+ ret.Add((GridArrays == null ? DefaultOn : !GridArrays.GetCrystal().CopyNothing, GridArrays?.GetCrystal()));
ret.Add((Unknown3, null));
}
@@ -1518,7 +1587,7 @@ public partial interface INavmeshGeometry :
new P2Float GridMaxDistance { get; set; }
new P3Float GridMin { get; set; }
new P3Float GridMax { get; set; }
- new NavmeshGridArray GridArrays { get; set; }
+ new ExtendedList GridArrays { get; }
new Int32 Unknown3 { get; set; }
}
@@ -1550,7 +1619,7 @@ public partial interface INavmeshGeometryGetter :
P2Float GridMaxDistance { get; }
P3Float GridMin { get; }
P3Float GridMax { get; }
- INavmeshGridArrayGetter GridArrays { get; }
+ IReadOnlyList GridArrays { get; }
Int32 Unknown3 { get; }
}
@@ -1932,7 +2001,10 @@ public void FillEqualsMask(
ret.GridMaxDistance = item.GridMaxDistance.Equals(rhs.GridMaxDistance);
ret.GridMin = item.GridMin.Equals(rhs.GridMin);
ret.GridMax = item.GridMax.Equals(rhs.GridMax);
- ret.GridArrays = MaskItemExt.Factory(item.GridArrays.GetEqualsMask(rhs.GridArrays, include), include);
+ ret.GridArrays = item.GridArrays.CollectionEqualsHelper(
+ rhs.GridArrays,
+ (loqLhs, loqRhs) => loqLhs.GetEqualsMask(loqRhs, include),
+ include);
ret.Unknown3 = item.Unknown3 == rhs.Unknown3;
}
@@ -2110,7 +2182,17 @@ protected static void ToStringFields(
}
if (printMask?.GridArrays?.Overall ?? true)
{
- item.GridArrays?.Print(sb, "GridArrays");
+ sb.AppendLine("GridArrays =>");
+ using (sb.Brace())
+ {
+ foreach (var subItem in item.GridArrays)
+ {
+ using (sb.Brace())
+ {
+ subItem?.Print(sb, "Item");
+ }
+ }
+ }
}
if (printMask?.Unknown3 ?? true)
{
@@ -2191,11 +2273,7 @@ public virtual bool Equals(
}
if ((equalsMask?.GetShouldTranslate((int)NavmeshGeometry_FieldIndex.GridArrays) ?? true))
{
- if (EqualsMaskHelper.RefEquality(lhs.GridArrays, rhs.GridArrays, out var lhsGridArrays, out var rhsGridArrays, out var isGridArraysEqual))
- {
- if (!((NavmeshGridArrayCommon)((INavmeshGridArrayGetter)lhsGridArrays).CommonInstance()!).Equals(lhsGridArrays, rhsGridArrays, equalsMask?.GetSubCrystal((int)NavmeshGeometry_FieldIndex.GridArrays))) return false;
- }
- else if (!isGridArraysEqual) return false;
+ if (!lhs.GridArrays.SequenceEqual(rhs.GridArrays, (l, r) => ((NavmeshGridArrayCommon)((INavmeshGridArrayGetter)l).CommonInstance()!).Equals(l, r, equalsMask?.GetSubCrystal((int)NavmeshGeometry_FieldIndex.GridArrays)))) return false;
}
if ((equalsMask?.GetShouldTranslate((int)NavmeshGeometry_FieldIndex.Unknown3) ?? true))
{
@@ -2494,12 +2572,14 @@ public void DeepCopyIn(
errorMask?.PushIndex((int)NavmeshGeometry_FieldIndex.GridArrays);
try
{
- if ((copyMask?.GetShouldTranslate((int)NavmeshGeometry_FieldIndex.GridArrays) ?? true))
- {
- item.GridArrays = rhs.GridArrays.DeepCopy(
- copyMask: copyMask?.GetSubCrystal((int)NavmeshGeometry_FieldIndex.GridArrays),
- errorMask: errorMask);
- }
+ item.GridArrays.SetTo(
+ rhs.GridArrays
+ .Select(r =>
+ {
+ return r.DeepCopy(
+ errorMask: errorMask,
+ default(TranslationCrystal));
+ }));
}
catch (Exception ex)
when (errorMask != null)
@@ -2711,10 +2791,17 @@ public static void WriteEmbedded(
P3FloatBinaryTranslation.Instance.Write(
writer: writer,
item: item.GridMax);
- var GridArraysItem = item.GridArrays;
- ((NavmeshGridArrayBinaryWriteTranslation)((IBinaryItem)GridArraysItem).BinaryWriteTranslator).Write(
- item: GridArraysItem,
- writer: writer);
+ Mutagen.Bethesda.Plugins.Binary.Translations.ListBinaryTranslation.Instance.Write(
+ writer: writer,
+ items: item.GridArrays,
+ transl: (MutagenWriter subWriter, INavmeshGridArrayGetter subItem, TypedWriteParams conv) =>
+ {
+ var Item = subItem;
+ ((NavmeshGridArrayBinaryWriteTranslation)((IBinaryItem)Item).BinaryWriteTranslator).Write(
+ item: Item,
+ writer: subWriter,
+ translationParams: conv);
+ });
if (!item.Versioning.HasFlag(NavmeshGeometry.VersioningBreaks.Break0))
{
writer.Write(item.Unknown3);
@@ -2816,7 +2903,10 @@ public static void FillBinaryStructs(
item.GridMaxDistance = P2FloatBinaryTranslation.Instance.Parse(reader: frame);
item.GridMin = P3FloatBinaryTranslation.Instance.Parse(reader: frame);
item.GridMax = P3FloatBinaryTranslation.Instance.Parse(reader: frame);
- item.GridArrays = Mutagen.Bethesda.Starfield.NavmeshGridArray.CreateFromBinary(frame: frame);
+ item.GridArrays.SetTo(
+ Mutagen.Bethesda.Plugins.Binary.Translations.ListBinaryTranslation.Instance.Parse(
+ reader: frame,
+ transl: NavmeshGridArray.TryCreateFromBinary));
if (frame.Complete)
{
item.Versioning |= NavmeshGeometry.VersioningBreaks.Break0;
@@ -2933,7 +3023,7 @@ void IBinaryItem.WriteToBinary(
public P3Float GridMin => P3FloatBinaryTranslation.Instance.Read(_structData.Slice(WaypointsEndingPos + 0xC, 0xC));
public P3Float GridMax => P3FloatBinaryTranslation.Instance.Read(_structData.Slice(WaypointsEndingPos + 0x18, 0xC));
#region GridArrays
- public INavmeshGridArrayGetter GridArrays => NavmeshGridArrayBinaryOverlay.NavmeshGridArrayFactory(_structData.Slice(WaypointsEndingPos + 0x24), _package, default(TypedParseParams));
+ public IReadOnlyList GridArrays => BinaryOverlayList.FactoryByLazyParse(_structData.Slice(WaypointsEndingPos + 0x24), _package, (s, p) => NavmeshGridArrayBinaryOverlay.NavmeshGridArrayFactory(s, p));
protected int GridArraysEndingPos;
#endregion
public Int32 Unknown3 => _structData.Length <= GridArraysEndingPos + 0x0 ? default : BinaryPrimitives.ReadInt32LittleEndian(_structData.Slice(GridArraysEndingPos + 0x0, 0x4));
@@ -2975,6 +3065,7 @@ public static INavmeshGeometryGetter NavmeshGeometryFactory(
ret.CoverEndingPos = ret.DoorTrianglesEndingPos + BinaryPrimitives.ReadInt32LittleEndian(ret._structData.Slice(ret.DoorTrianglesEndingPos)) * 12 + 4;
ret.CoverTriangleMappingsEndingPos = ret.CoverEndingPos + BinaryPrimitives.ReadInt32LittleEndian(ret._structData.Slice(ret.CoverEndingPos)) * 4 + 4;
ret.WaypointsEndingPos = ret.CoverTriangleMappingsEndingPos + BinaryPrimitives.ReadInt32LittleEndian(ret._structData.Slice(ret.CoverTriangleMappingsEndingPos)) * 18 + 4;
+ ret.GridArraysEndingPos = ret._structData.Length;
if (ret._structData.Length <= ret.GridArraysEndingPos)
{
ret.Versioning |= NavmeshGeometry.VersioningBreaks.Break0;
diff --git a/Mutagen.Bethesda.Starfield/Records/Common Subrecords/TraversalReference.cs b/Mutagen.Bethesda.Starfield/Records/Common Subrecords/TraversalReference.cs
index b8276ed6e1..350b952d24 100644
--- a/Mutagen.Bethesda.Starfield/Records/Common Subrecords/TraversalReference.cs
+++ b/Mutagen.Bethesda.Starfield/Records/Common Subrecords/TraversalReference.cs
@@ -1,6 +1,9 @@
-using Mutagen.Bethesda.Plugins;
+using System.Buffers.Binary;
+using Mutagen.Bethesda.Plugins;
+using Mutagen.Bethesda.Plugins.Binary.Overlay;
using Mutagen.Bethesda.Plugins.Binary.Streams;
using Mutagen.Bethesda.Plugins.Binary.Translations;
+using Mutagen.Bethesda.Starfield.Internals;
using Noggog;
namespace Mutagen.Bethesda.Starfield;
@@ -98,10 +101,72 @@ public static partial void WriteBinaryTraversalCustom(
partial class TraversalReferenceBinaryOverlay
{
+ private bool HasFormKey => !Enums.HasFlag(BinaryPrimitives.ReadInt32LittleEndian(_structData.Slice(0x28)), 4);
+
public partial IFormLinkNullableGetter GetTraversalCustom(int location)
{
- throw new NotImplementedException();
+ if (HasFormKey)
+ {
+ return new FormLinkNullable(
+ FormKey.Factory(_package.MetaData.MasterReferences!, BinaryPrimitives.ReadUInt32LittleEndian(
+ _structData.Slice(0x2C))));
+ }
+ else
+ {
+ return FormLinkNullable.Null;
+ }
+ }
+
+ public ReadOnlyMemorySlice Unknown => _structData.Slice(HasFormKey ? 0x30 : 0x2C, 8);
+
+ public static IReadOnlyList Factory(
+ OverlayStream stream, BinaryOverlayFactoryPackage package,
+ long finalPos, int offset, PreviousParse lastParsed)
+ {
+ stream.ReadSubrecordHeader(RecordTypes.XTV2);
+ return BinaryOverlayList.FactoryByArray(
+ mem: stream.RemainingMemory,
+ package: package,
+ getter: (s, p) =>
+ {
+ return TraversalReferenceFactory(s, p);
+ },
+ locs: GetLocs(stream, package, finalPos, offset, lastParsed));
+ }
+
+ public static IReadOnlyList GetLocs(
+ OverlayStream stream, BinaryOverlayFactoryPackage package,
+ long finalPos, int offset, PreviousParse lastParsed)
+ {
+ List locs = new();
+ var startingPos = stream.Position;
+ while (stream.Position < finalPos)
+ {
+ try
+ {
+ var itemPos = stream.Position;
+ var bytes = stream.ReadMemory(0x10);
+ if (bytes.All(b => b == 0)) break;
+ locs.Add(itemPos - startingPos);
+ stream.Position += 0x18;
+ var flags = stream.ReadInt32();
+ if (Enums.HasFlag(flags, 4))
+ {
+ stream.Position += 8;
+ }
+ else
+ {
+ stream.Position += 12;
+ }
+ }
+ catch (ArgumentOutOfRangeException)
+ {
+ // Expected to occur within Starfield.esm, due to fluff bytes of unknown length
+ stream.Position += checked((int)stream.Remaining);
+ break;
+ }
+ }
+
+ return locs;
}
-
- public ReadOnlyMemorySlice Unknown { get; }
}
\ No newline at end of file
diff --git a/Mutagen.Bethesda.Starfield/Records/Common Subrecords/VolumesComponentItem.cs b/Mutagen.Bethesda.Starfield/Records/Common Subrecords/VolumesComponentItem.cs
index cd05630507..7ab7b1d6cd 100644
--- a/Mutagen.Bethesda.Starfield/Records/Common Subrecords/VolumesComponentItem.cs
+++ b/Mutagen.Bethesda.Starfield/Records/Common Subrecords/VolumesComponentItem.cs
@@ -59,9 +59,23 @@ public static partial void FillBinaryEnderCustom(
partial class VolumesComponentItemBinaryOverlay
{
+ partial void CustomEnderEndPos()
+ {
+ var val = BinaryPrimitives.ReadInt32LittleEndian(_structData);
+ EnderEndingPos = 0x50;
+ EnderEndingPos += val switch
+ {
+ 1 => 4,
+ 3 => 8,
+ 5 => 12,
+ _ => throw new NotImplementedException()
+ };
+ }
+
public partial IAVolumesUnknownEnderGetter GetEnderCustom(int location)
{
- return BinaryPrimitives.ReadInt32LittleEndian(_structData) switch
+ var val = BinaryPrimitives.ReadInt32LittleEndian(_structData);
+ return val switch
{
1 => VolumesUnknownEnderSingleBinaryOverlay.VolumesUnknownEnderSingleFactory(_structData.Slice(location),
_package),
@@ -69,6 +83,7 @@ public partial IAVolumesUnknownEnderGetter GetEnderCustom(int location)
_package),
5 => VolumesUnknownEnderTrioBinaryOverlay.VolumesUnknownEnderTrioFactory(_structData.Slice(location),
_package),
+ _ => throw new NotImplementedException()
};
}
}
\ No newline at end of file
diff --git a/Mutagen.Bethesda.Starfield/Records/Major Records/Cell.cs b/Mutagen.Bethesda.Starfield/Records/Major Records/Cell.cs
index 316cbc64c1..aee306357d 100644
--- a/Mutagen.Bethesda.Starfield/Records/Major Records/Cell.cs
+++ b/Mutagen.Bethesda.Starfield/Records/Major Records/Cell.cs
@@ -359,7 +359,7 @@ partial class CellBinaryOverlay
private ReadOnlyMemorySlice? _grupData;
- public IReadOnlyList? Traversals => throw new NotImplementedException();
+ public IReadOnlyList? Traversals { get; private set; }
public IReadOnlyList NavigationMeshes { get; private set; } = Array.Empty();
public int UnknownGroupData => _grupData.HasValue ? BinaryPrimitives.ReadInt32LittleEndian(_grupData.Value.Slice(20)) : default;
@@ -572,4 +572,9 @@ IPlacedGetter TypicalGetter(
}
}
}
+
+ partial void TraversalsCustomParse(OverlayStream stream, long finalPos, int offset, RecordType type, PreviousParse lastParsed)
+ {
+ Traversals = TraversalReferenceBinaryOverlay.Factory(stream, _package, finalPos, offset, lastParsed);
+ }
}
diff --git a/Mutagen.Bethesda.Starfield/Records/Major Records/PlacedObject.cs b/Mutagen.Bethesda.Starfield/Records/Major Records/PlacedObject.cs
index 89ea65cc65..8e5a630623 100644
--- a/Mutagen.Bethesda.Starfield/Records/Major Records/PlacedObject.cs
+++ b/Mutagen.Bethesda.Starfield/Records/Major Records/PlacedObject.cs
@@ -1,4 +1,10 @@
-namespace Mutagen.Bethesda.Starfield;
+using Mutagen.Bethesda.Plugins;
+using Mutagen.Bethesda.Plugins.Binary.Overlay;
+using Mutagen.Bethesda.Plugins.Binary.Streams;
+using Mutagen.Bethesda.Plugins.Binary.Translations;
+using Mutagen.Bethesda.Starfield.Internals;
+
+namespace Mutagen.Bethesda.Starfield;
public partial class PlacedObject
{
@@ -155,4 +161,62 @@ public enum ItemMajorFlag : uint
NoRespawn = 0x4000_0000,
Multibound = 0x8000_0000,
}
+}
+
+partial class PlacedObjectBinaryWriteTranslation
+{
+ public static partial void WriteBinaryTraversalsCustom(
+ MutagenWriter writer,
+ IPlacedObjectGetter item)
+ {
+ Mutagen.Bethesda.Plugins.Binary.Translations.ListBinaryTranslation.Instance.Write(
+ writer: writer,
+ items: item.Traversals,
+ recordType: RecordTypes.XTV2,
+ overflowRecord: RecordTypes.XXXX,
+ transl: (MutagenWriter subWriter, ITraversalReferenceGetter subItem, TypedWriteParams conv) =>
+ {
+ var Item = subItem;
+ ((TraversalReferenceBinaryWriteTranslation)((IBinaryItem)Item).BinaryWriteTranslator).Write(
+ item: Item,
+ writer: subWriter,
+ translationParams: conv);
+ });
+ }
+}
+
+partial class PlacedObjectBinaryCreateTranslation
+{
+ public static partial void FillBinaryTraversalsCustom(
+ MutagenFrame frame,
+ IPlacedObjectInternal item,
+ PreviousParse lastParsed)
+ {
+ var sub = frame.ReadSubrecordHeader();
+ int len;
+ if (lastParsed.LengthOverride.HasValue)
+ {
+ len = lastParsed.LengthOverride.Value;
+ }
+ else
+ {
+ len = sub.ContentLength;
+ }
+ item.Traversals = TraversalReferenceBinaryCreateTranslation.Parse(frame.SpawnWithLength(len));
+ }
+}
+
+partial class PlacedObjectBinaryOverlay
+{
+ public IReadOnlyList? Traversals { get; private set; }
+
+ partial void TraversalsCustomParse(
+ OverlayStream stream,
+ long finalPos,
+ int offset,
+ RecordType type,
+ PreviousParse lastParsed)
+ {
+ Traversals = TraversalReferenceBinaryOverlay.Factory(stream, _package, finalPos, offset, lastParsed);
+ }
}
\ No newline at end of file
diff --git a/Mutagen.Bethesda.Starfield/Records/Major Records/PlacedObject.xml b/Mutagen.Bethesda.Starfield/Records/Major Records/PlacedObject.xml
index 6e2e19f815..2b1b7b87ea 100644
--- a/Mutagen.Bethesda.Starfield/Records/Major Records/PlacedObject.xml
+++ b/Mutagen.Bethesda.Starfield/Records/Major Records/PlacedObject.xml
@@ -82,7 +82,7 @@
-
+
diff --git a/Mutagen.Bethesda.Starfield/Records/Major Records/PlacedObject_Generated.cs b/Mutagen.Bethesda.Starfield/Records/Major Records/PlacedObject_Generated.cs
index cf8d2e3735..476f1c3195 100644
--- a/Mutagen.Bethesda.Starfield/Records/Major Records/PlacedObject_Generated.cs
+++ b/Mutagen.Bethesda.Starfield/Records/Major Records/PlacedObject_Generated.cs
@@ -8374,18 +8374,9 @@ public static void WriteRecordTypes(
writer: writer,
translationParams: translationParams);
}
- Mutagen.Bethesda.Plugins.Binary.Translations.ListBinaryTranslation.Instance.Write(
+ PlacedObjectBinaryWriteTranslation.WriteBinaryTraversals(
writer: writer,
- items: item.Traversals,
- recordType: translationParams.ConvertToCustom(RecordTypes.XTV2),
- transl: (MutagenWriter subWriter, ITraversalReferenceGetter subItem, TypedWriteParams conv) =>
- {
- var Item = subItem;
- ((TraversalReferenceBinaryWriteTranslation)((IBinaryItem)Item).BinaryWriteTranslator).Write(
- item: Item,
- writer: subWriter,
- translationParams: conv);
- });
+ item: item);
if (item.NavigationDoorLink is {} NavigationDoorLinkItem)
{
((NavigationDoorLinkBinaryWriteTranslation)((IBinaryItem)NavigationDoorLinkItem).BinaryWriteTranslator).Write(
@@ -8421,6 +8412,19 @@ public static void WriteRecordTypes(
binaryType: StringBinaryType.NullTerminate);
}
+ public static partial void WriteBinaryTraversalsCustom(
+ MutagenWriter writer,
+ IPlacedObjectGetter item);
+
+ public static void WriteBinaryTraversals(
+ MutagenWriter writer,
+ IPlacedObjectGetter item)
+ {
+ WriteBinaryTraversalsCustom(
+ writer: writer,
+ item: item);
+ }
+
public void Write(
MutagenWriter writer,
IPlacedObjectGetter item,
@@ -8939,12 +8943,10 @@ public static ParseResult FillBinaryRecordTypes(
}
case RecordTypeInts.XTV2:
{
- frame.Position += frame.MetaData.Constants.SubConstants.HeaderLength;
- item.Traversals =
- Mutagen.Bethesda.Plugins.Binary.Translations.ListBinaryTranslation.Instance.Parse(
- reader: frame.SpawnWithLength(contentLength),
- transl: TraversalReference.TryCreateFromBinary)
- .CastExtendedList();
+ PlacedObjectBinaryCreateTranslation.FillBinaryTraversalsCustom(
+ frame: frame.SpawnWithLength(frame.MetaData.Constants.SubConstants.HeaderLength + contentLength),
+ item: item,
+ lastParsed: lastParsed);
return (int)PlacedObject_FieldIndex.Traversals;
}
case RecordTypeInts.XNDP:
@@ -9003,6 +9005,11 @@ public static ParseResult FillBinaryRecordTypes(
}
}
+ public static partial void FillBinaryTraversalsCustom(
+ MutagenFrame frame,
+ IPlacedObjectInternal item,
+ PreviousParse lastParsed);
+
}
}
@@ -9272,7 +9279,14 @@ void IBinaryItem.WriteToBinary(
private RangeInt32? _EnableParentLocation;
public IEnableParentGetter? EnableParent => _EnableParentLocation.HasValue ? EnableParentBinaryOverlay.EnableParentFactory(_recordData.Slice(_EnableParentLocation!.Value.Min), _package) : default;
#endregion
- public IReadOnlyList? Traversals { get; private set; }
+ #region Traversals
+ partial void TraversalsCustomParse(
+ OverlayStream stream,
+ long finalPos,
+ int offset,
+ RecordType type,
+ PreviousParse lastParsed);
+ #endregion
#region NavigationDoorLink
private RangeInt32? _NavigationDoorLinkLocation;
public INavigationDoorLinkGetter? NavigationDoorLink => _NavigationDoorLinkLocation.HasValue ? NavigationDoorLinkBinaryOverlay.NavigationDoorLinkFactory(_recordData.Slice(_NavigationDoorLinkLocation!.Value.Min), _package) : default;
@@ -9802,13 +9816,12 @@ public override ParseResult FillRecordType(
}
case RecordTypeInts.XTV2:
{
- var subMeta = stream.ReadSubrecordHeader();
- var subLen = finalPos - stream.Position;
- this.Traversals = BinaryOverlayList.FactoryByLazyParse(
- mem: stream.RemainingMemory.Slice(0, subLen),
- package: _package,
- getter: (s, p) => TraversalReferenceBinaryOverlay.TraversalReferenceFactory(s, p));
- stream.Position += subLen;
+ TraversalsCustomParse(
+ stream: stream,
+ finalPos: finalPos,
+ offset: offset,
+ type: type,
+ lastParsed: lastParsed);
return (int)PlacedObject_FieldIndex.Traversals;
}
case RecordTypeInts.XNDP:
diff --git a/Mutagen.Bethesda.Tests/Passthrough Tests/PassthroughTest.cs b/Mutagen.Bethesda.Tests/Passthrough Tests/PassthroughTest.cs
index 55df3a7c5a..3905ac630f 100644
--- a/Mutagen.Bethesda.Tests/Passthrough Tests/PassthroughTest.cs
+++ b/Mutagen.Bethesda.Tests/Passthrough Tests/PassthroughTest.cs
@@ -399,10 +399,19 @@ public Test BinaryPassthroughTest()
o.OnNext(FilePath.ToString());
using (var wrapper = await ImportBinaryOverlay(trimmedPath, StringsParams))
{
- doStrings = wrapper.UsingLocalization;
- var writeParam = GetWriteParam(masterRefs, doStrings ? new StringsWriter(GameRelease, wrapper.ModKey, strsWriteDir, MutagenEncoding.Default) : null);
- wrapper.WriteToBinary(binaryOverlayPath, writeParam);
- writeParam.StringsWriter?.Dispose();
+ try
+ {
+
+ doStrings = wrapper.UsingLocalization;
+ var writeParam = GetWriteParam(masterRefs, doStrings ? new StringsWriter(GameRelease, wrapper.ModKey, strsWriteDir, MutagenEncoding.Default) : null);
+ wrapper.WriteToBinary(binaryOverlayPath, writeParam);
+ writeParam.StringsWriter?.Dispose();
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ throw;
+ }
}
using var stream = new MutagenBinaryReadStream(processedPath, GameRelease);
diff --git a/Mutagen.Bethesda.Tests/Processing/StarfieldProcessor.cs b/Mutagen.Bethesda.Tests/Processing/StarfieldProcessor.cs
index fe233ea165..91a0e87d0f 100644
--- a/Mutagen.Bethesda.Tests/Processing/StarfieldProcessor.cs
+++ b/Mutagen.Bethesda.Tests/Processing/StarfieldProcessor.cs
@@ -427,7 +427,6 @@ private void ProcessXTV2(MajorRecordFrame majorFrame, long fileOffset)
if (remainingLen < ushort.MaxValue && xtv2.LengthOverrideRecordLocation.HasValue)
{
RemoveOverflowRecord(majorFrame, xtv2, fileOffset, checked((uint)remainingLen));
- xtv2 = xtv2.WithoutOverflow();
cutLen += 10;
ProcessLengths(majorFrame, -cutLen, fileOffset);
}