Exemplo n.º 1
0
            public static partial void CustomBinaryEndExport(MutagenWriter writer, IWorldspaceGetter obj)
            {
                try
                {
                    var topCell  = obj.TopCell;
                    var subCells = obj.SubCells;
                    if (subCells?.Count == 0 &&
                        topCell == null)
                    {
                        return;
                    }
                    using (HeaderExport.Header(writer, RecordTypes.GRUP, ObjectType.Group))
                    {
                        FormKeyBinaryTranslation.Instance.Write(
                            writer,
                            obj.FormKey);
                        writer.Write((int)GroupTypeEnum.WorldChildren);
                        writer.Write(obj.SubCellsTimestamp);
                        writer.Write(obj.SubCellsUnknown);

                        topCell?.WriteToBinary(writer);
                        ListBinaryTranslation <IWorldspaceBlockGetter> .Instance.Write(
                            writer : writer,
                            items : subCells,
                            transl : (MutagenWriter subWriter, IWorldspaceBlockGetter subItem) =>
                        {
                            subItem.WriteToBinary(subWriter);
                        });
                    }
                }
                catch (Exception ex)
                {
                    throw RecordException.Enrich(ex, obj);
                }
            }
Exemplo n.º 2
0
            static partial void CustomBinaryEndExport(MutagenWriter writer, IWorldspaceGetter obj)
            {
                var road     = obj.Road;
                var topCell  = obj.TopCell;
                var subCells = obj.SubCells;

                if (subCells?.Count == 0 &&
                    road == null &&
                    topCell == null)
                {
                    return;
                }
                using (HeaderExport.Header(writer, RecordTypes.GRUP, ObjectType.Group))
                {
                    FormKeyBinaryTranslation.Instance.Write(
                        writer,
                        obj.FormKey);
                    writer.Write((int)GroupTypeEnum.WorldChildren);
                    writer.Write(obj.SubCellsTimestamp);

                    road?.WriteToBinary(writer);
                    topCell?.WriteToBinary(writer);
                    Mutagen.Bethesda.Binary.ListBinaryTranslation <IWorldspaceBlockGetter> .Instance.Write(
                        writer : writer,
                        items : subCells,
                        transl : (MutagenWriter subWriter, IWorldspaceBlockGetter subItem) =>
                    {
                        subItem.WriteToBinary(subWriter);
                    });
                }
            }
Exemplo n.º 3
0
        internal static IEnumerable <IModContext <IOblivionMod, IOblivionModGetter, IMajorRecordCommon, IMajorRecordCommonGetter> > EnumerateMajorRecordContexts(
            this IReadOnlyList <IWorldspaceBlockGetter> worldspaceBlocks,
            IWorldspaceGetter worldspace,
            ILinkCache linkCache,
            Type type,
            ModKey modKey,
            IModContext?parent,
            bool throwIfUnknown,
            Func <IOblivionMod, IWorldspaceGetter, IWorldspace> getOrAddAsOverride)
        {
            foreach (var readOnlyBlock in worldspaceBlocks)
            {
                var blockNumX     = readOnlyBlock.BlockNumberX;
                var blockNumY     = readOnlyBlock.BlockNumberY;
                var blockModified = readOnlyBlock.LastModified;
                var blockContext  = new ModContext <IWorldspaceBlockGetter>(
                    modKey: modKey,
                    parent: parent,
                    record: readOnlyBlock);
                foreach (var readOnlySubBlock in readOnlyBlock.Items)
                {
                    var subBlockNumY     = readOnlySubBlock.BlockNumberY;
                    var subBlockNumX     = readOnlySubBlock.BlockNumberX;
                    var subBlockModified = readOnlySubBlock.LastModified;
                    var subBlockContext  = new ModContext <IWorldspaceSubBlockGetter>(
                        modKey: modKey,
                        parent: blockContext,
                        record: readOnlySubBlock);
                    foreach (var readOnlyCell in readOnlySubBlock.Items)
                    {
                        Func <IOblivionMod, ICellGetter, bool, string?, ICell> cellGetter = (mod, copyCell, dup, edid) =>
                        {
                            var worldspaceCopy = getOrAddAsOverride(mod, worldspace);
                            var formKey        = copyCell.FormKey;
                            var retrievedBlock = worldspaceCopy.SubCells.FirstOrDefault(x => x.BlockNumberX == blockNumX && x.BlockNumberY == blockNumY);
                            if (retrievedBlock == null)
                            {
                                retrievedBlock = new WorldspaceBlock()
                                {
                                    BlockNumberX = blockNumX,
                                    BlockNumberY = blockNumY,
                                    GroupType    = GroupTypeEnum.ExteriorCellBlock,
                                    LastModified = blockModified,
                                };
                                worldspaceCopy.SubCells.Add(retrievedBlock);
                            }
                            var subBlock = retrievedBlock.Items.FirstOrDefault(x => x.BlockNumberX == subBlockNumX && x.BlockNumberY == subBlockNumY);
                            if (subBlock == null)
                            {
                                subBlock = new WorldspaceSubBlock()
                                {
                                    BlockNumberX = subBlockNumX,
                                    BlockNumberY = subBlockNumY,
                                    GroupType    = GroupTypeEnum.ExteriorCellSubBlock,
                                    LastModified = readOnlySubBlock.LastModified,
                                };
                                retrievedBlock.Items.Add(subBlock);
                            }
                            var cell = subBlock.Items.FirstOrDefault(cell => cell.FormKey == formKey);
                            if (cell == null)
                            {
                                if (dup)
                                {
                                    cell = copyCell.Duplicate(mod.GetNextFormKey(edid), CellCopyMask);
                                }
                                else
                                {
                                    cell = copyCell.DeepCopy(CellCopyMask);
                                }
                                subBlock.Items.Add(cell);
                            }
                            return(cell);
                        };

                        if (LoquiRegistration.TryGetRegister(type, out var regis) &&
                            regis.ClassType == typeof(Cell))
                        {
                            yield return(new ModContext <IOblivionMod, IOblivionModGetter, IMajorRecordCommon, IMajorRecordCommonGetter>(
                                             modKey: modKey,
                                             record: readOnlyCell,
                                             getOrAddAsOverride: (m, r) => cellGetter(m, (ICellGetter)r, false, default(string?)),
                                             duplicateInto: (m, r, e) => cellGetter(m, (ICellGetter)r, true, e),
                                             parent: subBlockContext));
                        }
                        else
                        {
                            foreach (var con in CellCommon.Instance.EnumerateMajorRecordContexts(
                                         readOnlyCell,
                                         linkCache,
                                         type,
                                         modKey,
                                         subBlockContext,
                                         throwIfUnknown,
                                         (m, c) => cellGetter(m, c, false, default(string?)),
                                         (m, c, e) => cellGetter(m, c, true, e)))
                            {
                                yield return(con);
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 4
0
        void CreateFromWorld(IWorldspaceGetter wrld)
        {
            const int cellsize           = 33;   // Each cell has 33 x 33 datapoints. Some of those are double, which we don't care about, it will just look more gridlike.
            const int maxheight          = 9771; // -4842 is the lowest point of the map. 9771 is the total max
            const int minheight          = 4842; // These are just used to calculate the color of each pixel later.
            const int worldwidthincells  = 118;  // How many cells the world is in X and Y
            const int worldheightincells = 95;

            Bitmap    bitmap    = new Bitmap(cellsize * worldwidthincells, cellsize * worldheightincells, System.Drawing.Imaging.PixelFormat.Format48bppRgb);
            const int pixelsize = 6; // Each pixel is 6 bytes long

            byte[] outBuffer = new byte[bitmap.Width * bitmap.Height * pixelsize];

            foreach (var block in wrld.SubCells)
            {
                foreach (var subblock in block.Items)
                {
                    bool black = false;
                    foreach (var cell in subblock.Items)
                    {
                        //if (cell.Grid == null) continue;
                        int cell_x_normalized = cell.Grid.Point.X + 57; // -57 and -43 are the lowest numbers respectively
                        int cell_y_normalized = cell.Grid.Point.Y + 43;

                        if (!cell.Landscape.TryGet(out var land) ||
                            land.VertexHeightMap == null)
                        {
                            continue;
                        }
                        float[,] heightmap = ParseHeights(land.VertexHeightMap.Value);

                        for (int y = 0; y < cellsize; y++)
                        {
                            int rowoffsetbytes = (
                                (cell_y_normalized * bitmap.Width * cellsize)
                                + (y * bitmap.Width)
                                + (cell_y_normalized != 0 ? -bitmap.Width : 0)
                                ) * pixelsize;                  // this is the offset, in bytes, to find the correct row in the buffer


                            for (int x = 0; x < cellsize; x++)
                            {
                                // Decide the color of the pixel
                                float  percent = (heightmap[y, x] + minheight) / maxheight;
                                ushort color   = (ushort)(ushort.MaxValue * percent);
                                //ushort color = ushort.MaxValue / 2; //
                                byte[] snippet = BitConverter.GetBytes(color).Concat(BitConverter.GetBytes(color)).Concat(BitConverter.GetBytes(color)).ToArray(); // converted to byte array

                                // Figure out what position to put it in

                                int column = (
                                    (cell_x_normalized * cellsize)
                                    + x
                                    + (cell_x_normalized != 0 ? -1 : 0)
                                    ) * pixelsize;         // offset, in positions, in the row
                                int position = rowoffsetbytes + column;
                                //                               if(position < outBuffer.Length)
                                //                               {

                                snippet.CopyTo(outBuffer, position);
//                                }
                            }
                        }
                        black = !black;
                    }
                }
            }

            // Lock the unmanaged bits for efficient writing.
            var data = bitmap.LockBits(
                new Rectangle(0, 0, bitmap.Width, bitmap.Height),
                ImageLockMode.ReadWrite,
                bitmap.PixelFormat);

            // Bulk copy pixel data from a byte array:
            Marshal.Copy(outBuffer, 0, data.Scan0, outBuffer.Length);

            // When finished, unlock the unmanaged bits
            bitmap.UnlockBits(data);
            picture.Width  = bitmap.Width;
            picture.Height = bitmap.Height;
            picture.Image  = bitmap;
            bitmap.Save(@"C:\debug\tamriel.bmp");
        }
Exemplo n.º 5
0
        public (float, float) FindMinMax(IWorldspaceGetter worldspace)
        {
            float minheight = float.MaxValue;
            float maxheight = float.MaxValue;
            int   mincellx  = int.MaxValue;
            int   maxcellx  = int.MaxValue;
            int   mincelly  = int.MaxValue;
            int   maxcelly  = int.MaxValue;

            /*
             * foreach (var block in worldspace.SubCells)
             * {
             *  foreach (var subblock in block.Items)
             *  {
             *      foreach (var subcell in subblock.Items)
             *      {
             *          var land = subcell.Landscape;
             *          float[,] heightmap = ParseHeights((Noggog.ReadOnlyMemorySlice<byte>)land.VertexHeightMap);
             *          foreach (var pos in heightmap)
             *          {
             *              if (minheight == float.MaxValue || minheight > pos)
             *              {
             *                  minheight = pos;
             *              }
             *              if (maxheight == float.MaxValue || maxheight < pos)
             *              {
             *                  maxheight = pos;
             *              }
             *
             *              if (maxcellx == int.MaxValue || maxcellx < subcell.Grid.Point.X)
             *              {
             *                  maxcellx = subcell.Grid.Point.X;
             *              }
             *
             *              if (mincellx == int.MaxValue || mincellx > subcell.Grid.Point.X)
             *              {
             *                  mincellx = subcell.Grid.Point.X;
             *              }
             *
             *              if (maxcelly == int.MaxValue || maxcelly < subcell.Grid.Point.Y)
             *              {
             *                  maxcelly = subcell.Grid.Point.Y;
             *              }
             *
             *              if (mincelly == int.MaxValue || mincelly > subcell.Grid.Point.Y)
             *              {
             *                  mincelly = subcell.Grid.Point.Y;
             *              }
             *          }
             *
             *          //txtDebug.Text += subcell.EditorID;
             *
             *          if (subcell.EditorID == "Whiterun")
             *          {
             *              txtDebug.Text += "Woop, whiterun";
             *              CreateFromCell(heightmap);
             *          }
             *      }
             *  }
             *  //CreateFromBlock(block);
             * }*/
            //txtDebug.Text += "Min cell X: " + mincellx + " Max cell X: " + maxcellx + " Min cell y: " + mincelly + " Max cell y: " + maxcelly;
            //            txtDebug.Text += "Minheight: " + minheight + " Maxheight: " + maxheight + "\r\n";
            CreateFromWorld(worldspace);
            return(minheight, maxheight);
        }
Exemplo n.º 6
0
        internal static IEnumerable <IModContext <ISkyrimMod, IMajorRecordCommon, IMajorRecordCommonGetter> > EnumerateMajorRecordContexts(
            this IReadOnlyList <IWorldspaceBlockGetter> worldspaceBlocks,
            IWorldspaceGetter worldspace,
            ILinkCache linkCache,
            Type type,
            ModKey modKey,
            IModContext?parent,
            bool throwIfUnknown,
            Func <ISkyrimMod, IWorldspaceGetter, IWorldspace> getter)
        {
            foreach (var readOnlyBlock in worldspaceBlocks)
            {
                var blockNumX    = readOnlyBlock.BlockNumberX;
                var blockNumY    = readOnlyBlock.BlockNumberY;
                var blockContext = new ModContext <IWorldspaceBlockGetter>(
                    modKey: modKey,
                    parent: parent,
                    record: readOnlyBlock);
                foreach (var readOnlySubBlock in readOnlyBlock.Items)
                {
                    var subBlockNumY    = readOnlySubBlock.BlockNumberY;
                    var subBlockNumX    = readOnlySubBlock.BlockNumberX;
                    var subBlockContext = new ModContext <IWorldspaceSubBlockGetter>(
                        modKey: modKey,
                        parent: blockContext,
                        record: readOnlySubBlock);
                    foreach (var readOnlyCell in readOnlySubBlock.Items)
                    {
                        Func <ISkyrimMod, ICellGetter, ICell> cellGetter = (mod, copyCell) =>
                        {
                            var worldspaceCopy = getter(mod, worldspace);
                            var formKey        = copyCell.FormKey;
                            var retrievedBlock = worldspaceCopy.SubCells.FirstOrDefault(x => x.BlockNumberX == blockNumX && x.BlockNumberY == blockNumY);
                            if (retrievedBlock == null)
                            {
                                retrievedBlock = new WorldspaceBlock()
                                {
                                    BlockNumberX = blockNumX,
                                    BlockNumberY = blockNumY,
                                    GroupType    = GroupTypeEnum.ExteriorCellBlock,
                                };
                                worldspaceCopy.SubCells.Add(retrievedBlock);
                            }
                            var subBlock = retrievedBlock.Items.FirstOrDefault(x => x.BlockNumberX == subBlockNumX && x.BlockNumberY == subBlockNumY);
                            if (subBlock == null)
                            {
                                subBlock = new WorldspaceSubBlock()
                                {
                                    BlockNumberX = subBlockNumX,
                                    BlockNumberY = subBlockNumY,
                                    GroupType    = GroupTypeEnum.ExteriorCellSubBlock,
                                };
                                retrievedBlock.Items.Add(subBlock);
                            }
                            var cell = subBlock.Items.FirstOrDefault(cell => cell.FormKey == formKey);
                            if (cell == null)
                            {
                                cell = copyCell.DeepCopy(CellCopyMask);
                                subBlock.Items.Add(cell);
                            }
                            return(cell);
                        };

                        if (LoquiRegistration.TryGetRegister(type, out var regis) &&
                            regis.ClassType == typeof(Cell))
                        {
                            yield return(new ModContext <ISkyrimMod, IMajorRecordCommon, IMajorRecordCommonGetter>(
                                             modKey: modKey,
                                             record: readOnlyCell,
                                             getter: (m, r) => cellGetter(m, (ICellGetter)r),
                                             parent: subBlockContext));
                        }
                        else
                        {
                            foreach (var con in CellCommon.Instance.EnumerateMajorRecordContexts(readOnlyCell, linkCache, type, modKey, subBlockContext, throwIfUnknown, cellGetter))
                            {
                                yield return(con);
                            }
                        }
                    }
                }
            }
        }