Пример #1
0
        public static ParseResult FillBinaryRecordTypes(
            IGlobalInternal item,
            MutagenFrame frame,
            Dictionary <RecordType, int>?recordParseCount,
            RecordType nextRecordType,
            int contentLength,
            RecordTypeConverter?recordTypeConverter = null)
        {
            nextRecordType = recordTypeConverter.ConvertToStandard(nextRecordType);
            switch (nextRecordType.TypeInt)
            {
            case RecordTypeInts.FNAM:
            {
                GlobalBinaryCreateTranslation.FillBinaryTypeCharCustom(
                    frame: frame.SpawnWithLength(frame.MetaData.Constants.SubConstants.HeaderLength + contentLength),
                    item: item);
                return(null);
            }

            default:
                return(OblivionMajorRecordBinaryCreateTranslation.FillBinaryRecordTypes(
                           item: item,
                           frame: frame,
                           recordParseCount: recordParseCount,
                           nextRecordType: nextRecordType,
                           contentLength: contentLength));
            }
        }
Пример #2
0
 public static partial ParseResult FillBinaryDataLogicCustom(MutagenFrame frame, IANavigationMeshInternal item)
 {
     HeaderTranslation.ReadNextSubrecordType(frame, out var len);
     frame = frame.SpawnWithLength(len);
     GetSetData(frame, item);
     return(null);
 }
Пример #3
0
 static partial void CustomBinaryEndImport(MutagenFrame frame, IDialogTopicInternal obj)
 {
     if (frame.Reader.Complete)
     {
         return;
     }
     if (!frame.TryGetGroup(out var groupMeta))
     {
         return;
     }
     if (groupMeta.GroupType == (int)GroupTypeEnum.TopicChildren)
     {
         obj.Timestamp = BinaryPrimitives.ReadInt32LittleEndian(groupMeta.LastModifiedData);
         if (FormKey.Factory(frame.MetaData.MasterReferences !, BinaryPrimitives.ReadUInt32LittleEndian(groupMeta.ContainedRecordTypeData)) != obj.FormKey)
         {
             throw new ArgumentException("Dialog children group did not match the FormID of the parent.");
         }
     }
     else
     {
         return;
     }
     frame.Reader.Position += groupMeta.HeaderLength;
     obj.Items.SetTo(Mutagen.Bethesda.Binary.ListBinaryTranslation <DialogItem> .Instance.Parse(
                         frame: frame.SpawnWithLength(groupMeta.ContentLength),
                         transl: (MutagenFrame r, RecordType header, out DialogItem listItem) =>
     {
         return(LoquiBinaryTranslation <DialogItem> .Instance.Parse(
                    frame: r,
                    item: out listItem));
     }));
 }
Пример #4
0
        public ExtendedList <T> Parse(
            MutagenFrame reader,
            RecordType triggeringRecord,
            BinaryMasterParseDelegate <T> transl,
            TypedParseParams?translationParams = null,
            bool skipHeader = false)
        {
            var ret = new ExtendedList <T>();

            triggeringRecord = translationParams.ConvertToCustom(triggeringRecord);
            while (!reader.Complete && !reader.Reader.Complete)
            {
                if (!reader.Reader.TryGetSubrecord(triggeringRecord, out var header))
                {
                    break;
                }
                if (!IsLoqui || skipHeader)
                {
                    reader.Position += header.HeaderLength;
                }
                var startingPos = reader.Position;
                if (transl(skipHeader ? reader.SpawnWithLength(header.ContentLength) : reader, out var subItem, translationParams))
                {
                    ret.Add(subItem);
                }

                if (reader.Position == startingPos)
                {
                    reader.Position += reader.MetaData.Constants.SubConstants.HeaderLength;
                    throw new ArgumentException($"Parsed item on the list consumed no data: {subItem}");
                }
            }
            return(ret);
        }
Пример #5
0
            static partial void FillBinaryLengthLogicCustom(MutagenFrame frame, IANavigationMeshInternal item)
            {
                frame.Position += frame.MetaData.Constants.SubConstants.HeaderLength;
                var xxxxSize = frame.ReadInt32();

                HeaderTranslation.ReadNextSubrecordType(frame, out var len);
                frame = frame.SpawnWithLength(xxxxSize, checkFraming: false);
                GetSetData(frame, item);
            }
Пример #6
0
        public static Condition CreateFromBinary(
            MutagenFrame frame,
            RecordTypeConverter?recordTypeConverter)
        {
            if (!frame.Reader.TryGetSubrecord(Mutagen.Bethesda.Fallout4.Internals.RecordTypes.CTDA, out var subRecMeta))
            {
                throw new ArgumentException();
            }
            var flagByte = frame.GetUInt8(subRecMeta.HeaderLength);

            Condition.Flag flag = ConditionBinaryCreateTranslation.GetFlag(flagByte);
            if (flag.HasFlag(Condition.Flag.UseGlobal))
            {
                return(ConditionGlobal.CreateFromBinary(frame.SpawnWithLength(subRecMeta.ContentLength, checkFraming: false)));
            }
            else
            {
                return(ConditionFloat.CreateFromBinary(frame.SpawnWithLength(subRecMeta.ContentLength, checkFraming: false)));
            }
        }
Пример #7
0
            static bool ParseTemporaryOutliers(MutagenFrame frame, ICellInternal obj)
            {
                var majorMeta  = frame.GetMajorRecord();
                var nextHeader = majorMeta.RecordType;

                if (nextHeader.Equals(RecordTypes.PGRD))
                {
                    obj.PathGrid = PathGrid.CreateFromBinary(
                        frame.SpawnWithLength(majorMeta.TotalLength),
                        translationParams: null);
                    return(true);
                }
                else if (nextHeader.Equals(RecordTypes.LAND))
                {
                    obj.Landscape = Landscape.CreateFromBinary(
                        frame.SpawnWithLength(majorMeta.TotalLength),
                        translationParams: null);
                    return(true);
                }
                return(false);
            }
Пример #8
0
        static void ParseRegionData(MutagenFrame frame, IRegionInternal item)
        {
            var rdatFrame = frame.GetSubrecordFrame();

            RegionData.RegionDataType dataType = (RegionData.RegionDataType)BinaryPrimitives.ReadUInt32LittleEndian(rdatFrame.Content);
            var subMeta = frame.GetSubrecord(offset: rdatFrame.TotalLength);
            int len     = rdatFrame.TotalLength;

            if (IsExpected(dataType, subMeta.RecordType))
            {
                len += subMeta.TotalLength;
            }
            switch (dataType)
            {
            case RegionData.RegionDataType.Object:
                item.Objects = RegionObjects.CreateFromBinary(frame.SpawnWithLength(len, checkFraming: false));
                break;

            case RegionData.RegionDataType.Map:
                item.MapName = RegionMap.CreateFromBinary(frame.SpawnWithLength(len, checkFraming: false));
                break;

            case RegionData.RegionDataType.Grass:
                item.Grasses = RegionGrasses.CreateFromBinary(frame.SpawnWithLength(len, checkFraming: false));
                break;

            case RegionData.RegionDataType.Sound:
                if (frame.Reader.TryGetSubrecord(out var nextRec, offset: len) &&
                    (nextRec.RecordType.Equals(RDSD) || nextRec.RecordType.Equals(RDMD)))
                {
                    len += nextRec.TotalLength;
                }
                item.Sounds = RegionSounds.CreateFromBinary(frame.SpawnWithLength(len, checkFraming: false));
                break;

            case RegionData.RegionDataType.Weather:
                item.Weather = RegionWeather.CreateFromBinary(frame.SpawnWithLength(len, checkFraming: false));
                break;

            case RegionData.RegionDataType.Icon:
                frame.Position += frame.MetaData.Constants.SubConstants.HeaderLength + rdatFrame.TotalLength;
                len             = len - frame.MetaData.Constants.SubConstants.HeaderLength - rdatFrame.TotalLength;
                if (StringBinaryTranslation.Instance.Parse(
                        frame.SpawnWithLength(len, checkFraming: false),
                        out var iconVal))
                {
                    item.Icon = iconVal;
                }
                else
                {
                    item.Icon = null;
                }
                break;

            default:
                throw new NotImplementedException();
            }
        }
Пример #9
0
            static void ParseRegionData(MutagenFrame frame, IRegionInternal item)
            {
                var rdatFrame = frame.Reader.GetSubrecordFrame();
                int len       = rdatFrame.TotalLength;

                RegionData.RegionDataType dataType = (RegionData.RegionDataType)BinaryPrimitives.ReadUInt32LittleEndian(rdatFrame.Content);

                if (frame.Reader.TryGetSubrecord(out var subMeta, offset: len))
                {
                    var recType = subMeta.RecordType;
                    if (recType == RecordTypes.ICON)
                    {
                        len += subMeta.TotalLength;
                        // Skip icon subrecord for now
                        subMeta = frame.Reader.GetSubrecord(offset: rdatFrame.TotalLength + subMeta.TotalLength);
                    }
                    if (IsExpected(dataType, recType))
                    {
                        len += subMeta.TotalLength;
                    }
                }

                switch (dataType)
                {
                case RegionData.RegionDataType.Object:
                    item.Objects = RegionObjects.CreateFromBinary(frame.SpawnWithLength(len, checkFraming: false));
                    break;

                case RegionData.RegionDataType.Map:
                    item.Map = RegionMap.CreateFromBinary(frame.SpawnWithLength(len, checkFraming: false));
                    break;

                case RegionData.RegionDataType.Grass:
                    item.Grasses = RegionGrasses.CreateFromBinary(frame.SpawnWithLength(len, checkFraming: false));
                    break;

                case RegionData.RegionDataType.Sound:
                    if (frame.Reader.TryGetSubrecord(out var nextRec, offset: len) &&
                        (nextRec.RecordType.Equals(RDSA) || nextRec.RecordType.Equals(RDMO)))
                    {
                        len += nextRec.TotalLength;
                    }
                    item.Sounds = RegionSounds.CreateFromBinary(frame.SpawnWithLength(len, checkFraming: false));
                    break;

                case RegionData.RegionDataType.Weather:
                    item.Weather = RegionWeather.CreateFromBinary(frame.SpawnWithLength(len, checkFraming: false));
                    break;

                case RegionData.RegionDataType.Land:
                    item.Land = RegionLand.CreateFromBinary(frame.SpawnWithLength(len, checkFraming: false));
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
Пример #10
0
            static bool ParseTemporaryOutliers(MutagenFrame frame, ICellInternal obj)
            {
                var majorMeta  = frame.GetMajorRecord();
                var nextHeader = majorMeta.RecordType;

                if (nextHeader.Equals(RecordTypes.NAVM))
                {
                    if (frame.MetaData.InWorldspace)
                    {
                        obj.NavigationMeshes.Add(
                            WorldspaceNavigationMesh.CreateFromBinary(
                                frame.SpawnWithLength(majorMeta.TotalLength),
                                recordTypeConverter: null));
                    }
                    else
                    {
                        obj.NavigationMeshes.Add(
                            CellNavigationMesh.CreateFromBinary(
                                frame.SpawnWithLength(majorMeta.TotalLength),
                                recordTypeConverter: null));
                    }
                    return(true);
                }
                else if (nextHeader.Equals(RecordTypes.LAND))
                {
                    if (obj.Landscape != null)
                    {
                        throw new ArgumentException("Had more than one landscape");
                    }
                    obj.Landscape = Landscape.CreateFromBinary(
                        frame.SpawnWithLength(majorMeta.TotalLength),
                        recordTypeConverter: null);
                    return(true);
                }
                return(false);
            }
Пример #11
0
            public static void FillBinaryCloudColors(MutagenFrame frame, CloudLayer[] clouds)
            {
                var rec = frame.ReadSubrecord();

                frame = frame.SpawnWithLength(rec.ContentLength);
                for (int i = 0; i < NumLayers; i++)
                {
                    if (frame.Complete)
                    {
                        return;
                    }
                    clouds[i].Colors = new WeatherColor()
                    {
                        Sunrise = frame.ReadColor(ColorBinaryType.Alpha),
                        Day     = frame.ReadColor(ColorBinaryType.Alpha),
                        Sunset  = frame.ReadColor(ColorBinaryType.Alpha),
                        Night   = frame.ReadColor(ColorBinaryType.Alpha),
                    };
                }
            }
Пример #12
0
            public static WeatherAmbientColorSet GetBinaryDirectionalAmbientLightingColors(MutagenFrame frame)
            {
                AmbientColors Parse()
                {
                    var subMeta = frame.ReadSubrecord();

                    if (subMeta.RecordType != RecordTypes.DALC)
                    {
                        throw new ArgumentException();
                    }
                    return(AmbientColors.CreateFromBinary(frame.SpawnWithLength(subMeta.ContentLength, checkFraming: false)));
                }

                return(new WeatherAmbientColorSet()
                {
                    Sunrise = Parse(),
                    Day = Parse(),
                    Sunset = Parse(),
                    Night = Parse(),
                });
            }
Пример #13
0
            private static void CustomBinaryEnd(MutagenFrame frame, ICellInternal obj)
            {
                if (frame.Reader.Complete)
                {
                    return;
                }
                if (!frame.TryGetGroup(out var groupMeta))
                {
                    return;
                }
                var formKey = FormKey.Factory(frame.MetaData.MasterReferences !, BinaryPrimitives.ReadUInt32LittleEndian(groupMeta.ContainedRecordTypeData));

                if (groupMeta.GroupType == (int)GroupTypeEnum.CellChildren)
                {
                    obj.Timestamp   = BinaryPrimitives.ReadInt32LittleEndian(groupMeta.LastModifiedData);
                    frame.Position += groupMeta.HeaderLength;
                    if (formKey != obj.FormKey)
                    {
                        throw new ArgumentException("Cell children group did not match the FormID of the parent cell.");
                    }
                }
                else
                {
                    return;
                }
                var subFrame = frame.SpawnWithLength(groupMeta.ContentLength);

                while (!subFrame.Complete)
                {
                    var persistGroupMeta = frame.GetGroup();
                    if (!persistGroupMeta.IsGroup)
                    {
                        throw new ArgumentException();
                    }
                    GroupTypeEnum type      = (GroupTypeEnum)persistGroupMeta.GroupType;
                    var           itemFrame = frame.SpawnWithLength(persistGroupMeta.TotalLength);
                    switch (type)
                    {
                    case GroupTypeEnum.CellPersistentChildren:
                        ParseTypical(
                            frame: itemFrame,
                            obj: obj,
                            coll: obj.Persistent,
                            persistentParse: true);
                        break;

                    case GroupTypeEnum.CellTemporaryChildren:
                        ParseTemporary(
                            itemFrame,
                            obj);
                        break;

                    case GroupTypeEnum.CellVisibleDistantChildren:
                        ParseTypical(
                            frame: itemFrame,
                            obj: obj,
                            coll: obj.VisibleWhenDistant,
                            persistentParse: false);
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                }
            }
Пример #14
0
        public static void FillBinaryPointToPointConnections(MutagenFrame frame, IPathGridInternal item)
        {
            if (!frame.TryReadSubrecord(RecordTypes.DATA, out var subMeta))
            {
                return;
            }

            uint ptCount = frame.Reader.ReadUInt16();

            if (!frame.Reader.TryReadSubrecord(PGRP, out subMeta))
            {
                return;
            }
            var pointDataSpan = frame.Reader.ReadSpan(subMeta.ContentLength);
            var bytePointsNum = pointDataSpan.Length / POINT_LEN;

            if (bytePointsNum != ptCount)
            {
                throw new ArgumentException($"Unexpected point byte length, when compared to expected point count. {pointDataSpan.Length} bytes: {bytePointsNum} != {ptCount} points.");
            }

            bool readPGRR = false;

            for (int recAttempt = 0; recAttempt < 2; recAttempt++)
            {
                if (frame.Reader.Complete)
                {
                    break;
                }
                subMeta = frame.GetSubrecord();
                switch (subMeta.RecordType.TypeInt)
                {
                case 0x47414750:     //"PGAG":
                    frame.Reader.Position += subMeta.HeaderLength;
                    if (ByteArrayBinaryTranslation <MutagenFrame, MutagenWriter> .Instance.Parse(
                            frame.SpawnWithLength(subMeta.ContentLength, checkFraming: false),
                            item: out var unknownBytes))
                    {
                        item.PGAG = unknownBytes;
                    }
                    else
                    {
                        item.PGAG = default;
                    }
                    break;

                case 0x52524750:     // "PGRR":
                    frame.Reader.Position += subMeta.HeaderLength;
                    var             connectionInts = frame.Reader.ReadSpan(subMeta.ContentLength).AsInt16Span();
                    int             numPts         = pointDataSpan.Length / POINT_LEN;
                    PathGridPoint[] pathGridPoints = new PathGridPoint[numPts];
                    for (int i = 0; i < numPts; i++)
                    {
                        var pt = ReadPathGridPoint(pointDataSpan, out var numConn);
                        pt.Connections.AddRange(connectionInts.Slice(0, numConn).ToArray());
                        pathGridPoints[i] = pt;
                        pointDataSpan     = pointDataSpan.Slice(16);
                        connectionInts    = connectionInts.Slice(numConn);
                    }
                    item.PointToPointConnections = pathGridPoints.ToExtendedList();
                    readPGRR = true;
                    break;

                default:
                    break;
                }
            }

            if (!readPGRR)
            {
                ExtendedList <PathGridPoint> list = new ExtendedList <PathGridPoint>();
                while (pointDataSpan.Length > 0)
                {
                    list.Add(
                        ReadPathGridPoint(pointDataSpan, out var numConn));
                    pointDataSpan = pointDataSpan.Slice(16);
                }
                item.PointToPointConnections = list;
            }
        }