Beispiel #1
0
        private HashSet <Block> GetBlocks(RawSchematic rawSchematic)
        {
            if (rawSchematic.Heigth > 2016 || rawSchematic.Length > 2016 || rawSchematic.Width > 2016)
            {
                throw new Exception("Schematic is too big");
            }

            Console.WriteLine($"[LOG] Started to read all blocks of the schematic...");
            Console.WriteLine($"[INFO] Raw schematic Width: {rawSchematic.Width}");
            Console.WriteLine($"[INFO] Raw schematic Length: {rawSchematic.Length}");
            Console.WriteLine($"[INFO] Raw schematic Height: {rawSchematic.Heigth}");
            Console.WriteLine($"[INFO] Raw schematic total blocks: {rawSchematic.Data.Length}");

            LoadedSchematic.WidthSchematic  = (short)(rawSchematic.Width * _scale);
            LoadedSchematic.LengthSchematic = (short)(rawSchematic.Length * _scale);
            LoadedSchematic.HeightSchematic = (short)(rawSchematic.Heigth * _scale);

            //Sorted by height (bottom to top) then length then width -- the index of the block at X,Y,Z is (Y×length + Z)×width + X.
            ConcurrentBag <Block> blocks = new ConcurrentBag <Block>();

            int minY = Math.Max(_ignoreMinY, 0);
            int maxY = 0;

            if (rawSchematic.Heigth <= _ignoreMaxY)
            {
                maxY = Math.Min(_ignoreMaxY, rawSchematic.Heigth);
            }
            else
            {
                maxY = rawSchematic.Heigth;
            }

            Parallel.For(minY, (maxY * _scale), y =>
            {
                for (int z = 0; z < (rawSchematic.Length * _scale); z++)
                {
                    for (int x = 0; x < (rawSchematic.Width * _scale); x++)
                    {
                        int yProgress = (y / _scale);
                        int zProgress = (z / _scale);
                        int xProgress = (x / _scale);
                        int index     = (yProgress * rawSchematic.Length + zProgress) * rawSchematic.Width + xProgress;
                        int blockId   = rawSchematic.Blocks[index];
                        if (blockId != 0)
                        {
                            Block block = new Block((short)x, (short)y, (short)z,
                                                    GetBlockColor(rawSchematic.Blocks[index],
                                                                  rawSchematic.Data[index]).ColorToUInt());
                            if ((_excavate && IsBlockConnectedToAir(rawSchematic, block, minY, maxY) || !_excavate))
                            {
                                blocks.Add(block);
                            }
                        }
                    }
                }
            });
            Console.WriteLine($"[LOG] Done.");
            return(blocks.ToHashSet());
        }
Beispiel #2
0
        private Schematic LoadSchematic(NbtFile nbtFile)
        {
            RawSchematic    raw       = LoadRaw(nbtFile);
            HashSet <Voxel> blocks    = GetBlocks(raw);
            Schematic       schematic = new Schematic(blocks);

            return(schematic);
        }
        private Schematic LoadSchematic(NbtFile nbtFile)
        {
            RawSchematic    raw       = LoadRaw(nbtFile);
            HashSet <Block> blocks    = GetBlocks(raw);
            string          name      = Path.GetFileNameWithoutExtension(nbtFile.FileName);
            Schematic       schematic = new Schematic((ushort)raw.Width, (ushort)raw.Heigth, (ushort)raw.Length, blocks);

            schematic.Width  *= (ushort)_scale;
            schematic.Height *= (ushort)_scale;
            schematic.Length *= (ushort)_scale;
            return(schematic);
        }
Beispiel #4
0
        private HashSet <Voxel> GetBlocks(RawSchematic rawSchematic)
        {
            if (rawSchematic.Heigth > Schematic.MAX_WORLD_HEIGHT || rawSchematic.Length > Schematic.MAX_WORLD_LENGTH || rawSchematic.Width > Schematic.MAX_WORLD_WIDTH)
            {
                throw new Exception("Schematic is too big");
            }

            Console.WriteLine($"[LOG] Started to read all blocks of the schematic...");

            //Sorted by height (bottom to top) then length then width -- the index of the block at X,Y,Z is (Y×length + Z)×width + X.
            HashSet <Voxel> blocks = new HashSet <Voxel>();

            int minY = Math.Max(mIgnoreMinY, 0);
            int maxY = rawSchematic.Heigth <= mIgnoreMaxY?Math.Min(mIgnoreMaxY, rawSchematic.Heigth) : rawSchematic.Heigth;

            int total         = (maxY * mScale) * (rawSchematic.Length * mScale) * (rawSchematic.Width * mScale);
            int indexProgress = 0;

            using (ProgressBar progressbar = new ProgressBar())
            {
                for (int y = minY; y < (maxY * mScale); y++)
                {
                    for (int z = 0; z < (rawSchematic.Length * mScale); z++)
                    {
                        for (int x = 0; x < (rawSchematic.Width * mScale); x++)
                        {
                            int yProgress = (y / mScale);
                            int zProgress = (z / mScale);
                            int xProgress = (x / mScale);
                            int index     = (yProgress * rawSchematic.Length + zProgress) * rawSchematic.Width + xProgress;
                            int blockId   = rawSchematic.Blocks[index];
                            if (blockId != 0)
                            {
                                Voxel voxel = new Voxel((ushort)x, (ushort)y, (ushort)z, GetBlockColor(rawSchematic.Blocks[index], rawSchematic.Data[index]).ColorToUInt());
                                if ((mExcavate && IsBlockConnectedToAir(rawSchematic, voxel, minY, maxY) || !mExcavate))
                                {
                                    if (!blocks.Contains(voxel))
                                    {
                                        blocks.Add(voxel);
                                    }
                                }
                            }

                            progressbar.Report(indexProgress++ / (float)total);
                        }
                    }
                }
            }

            Console.WriteLine($"[LOG] Done.");
            return(blocks);
        }
        private RawSchematic LoadRaw(NbtFile nbtFile)
        {
            RawSchematic raw     = new RawSchematic();
            var          rootTag = nbtFile.RootTag;

            foreach (NbtTag tag in rootTag.Tags)
            {
                switch (tag.Name)
                {
                case "Width":     //Short
                    raw.Width = tag.ShortValue;
                    LoadedSchematic.WidthSchematic = (ushort)raw.Width;
                    break;

                case "Height":     //Short
                    raw.Heigth = tag.ShortValue;
                    LoadedSchematic.HeightSchematic = (ushort)raw.Heigth;
                    break;

                case "Length":     //Short
                    raw.Length = tag.ShortValue;
                    break;

                case "Blocks":     //ByteArray
                    raw.Blocks = tag.ByteArrayValue;
                    break;

                case "Data":     //ByteArray
                    raw.Data = tag.ByteArrayValue;
                    break;

                case "Entities":     //List
                    break;           //Ignore

                case "TileEntities": //List
                    break;

                case "Icon":              //Compound
                    break;                //Ignore

                case "SchematicaMapping": //Compound
                    tag.ToString();
                    break;                //Ignore

                default:
                    break;
                }
            }
            return(raw);
        }
        private Schematic CreateSchematic(RawSchematic rawSchematic)
        {
            if (rawSchematic.Heigth > Schematic.MAX_WORLD_HEIGHT || rawSchematic.Length > Schematic.MAX_WORLD_LENGTH || rawSchematic.Width > Schematic.MAX_WORLD_WIDTH)
            {
                throw new Exception("Schematic is too big");
            }

            Console.WriteLine($"[INFO] Started to read all blocks of the schematic...");

            //Sorted by height (bottom to top) then length then width -- the index of the block at X,Y,Z is (Y×length + Z)×width + X.
            Schematic schematic = new Schematic();

            int total         = (rawSchematic.Heigth) * (rawSchematic.Length) * (rawSchematic.Width);
            int indexProgress = 0;

            using (ProgressBar progressbar = new ProgressBar())
            {
                for (int y = 0; y < (rawSchematic.Heigth); y++)
                {
                    for (int z = 0; z < (rawSchematic.Length); z++)
                    {
                        for (int x = 0; x < (rawSchematic.Width); x++)
                        {
                            int index   = (y * rawSchematic.Length + z) * rawSchematic.Width + x;
                            int blockId = rawSchematic.Blocks[index];
                            if (blockId != 0)
                            {
                                Voxel voxel = new Voxel((ushort)x, (ushort)y, (ushort)z, GetBlockColor(rawSchematic.Blocks[index], rawSchematic.Data[index]).ColorToUInt());
                                if ((mExcavate && IsBlockConnectedToAir(rawSchematic, voxel, 0, rawSchematic.Heigth) || !mExcavate))
                                {
                                    if (!schematic.ContainsVoxel(x, y, z))
                                    {
                                        schematic.AddVoxel(x, y, z, voxel.Color);
                                    }
                                }
                            }

                            progressbar.Report(indexProgress++ / (float)total);
                        }
                    }
                }
            }

            Console.WriteLine($"[INFO] Done.");
            return(schematic);
        }
        private bool IsBlockConnectedToAir(RawSchematic rawSchematic, Block block, int minY, int maxY)
        {
            if (block.X - 1 >= 0 && block.X + 1 < rawSchematic.Width && block.Y - 1 >= minY && block.Y + 1 < maxY && block.Z - 1 >= 0 && block.Z < rawSchematic.Length)
            {
                int indexLeftX  = (block.Y * rawSchematic.Length + block.Z) * rawSchematic.Width + (block.X - 1);
                int indexRightX = (block.Y * rawSchematic.Length + block.Z) * rawSchematic.Width + (block.X + 1);

                int indexTop    = ((block.Y + 1) * rawSchematic.Length + block.Z) * rawSchematic.Width + block.X;
                int indexBottom = ((block.Y - 1) * rawSchematic.Length + block.Z) * rawSchematic.Width + block.X;

                int indexAhead  = (block.Y * rawSchematic.Length + block.Z + 1) * rawSchematic.Width + block.X;
                int indexBehind = (block.Y * rawSchematic.Length + block.Z - 1) * rawSchematic.Width + block.X;
                return(rawSchematic.Blocks[indexLeftX] == 0 || rawSchematic.Blocks[indexRightX] == 0 ||
                       rawSchematic.Blocks[indexTop] == 0 || rawSchematic.Blocks[indexBottom] == 0 ||
                       rawSchematic.Blocks[indexAhead] == 0 || rawSchematic.Blocks[indexBehind] == 0);
            }
            return(false);
        }
        private Schematic LoadSchematic(NbtFile nbtFile)
        {
            RawSchematic raw = LoadRaw(nbtFile);

            return(CreateSchematic(raw));
        }