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); }