Example #1
0
        private static Schematic LoadSchematic(NbtFile nbtFile)
        {
            RawSchematic    raw       = LoadRaw(nbtFile);
            HashSet <Block> blocks    = GetBlocks(raw);
            string          name      = Path.GetFileNameWithoutExtension(nbtFile.FileName);
            Schematic       schematic = new Schematic(name, raw.Width, raw.Heigth, raw.Length, blocks);

            schematic.Width  *= (short)_scale;
            schematic.Heigth *= (short)_scale;
            schematic.Length *= (short)_scale;
            return(schematic);
        }
Example #2
0
        private static 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}");
            Console.WriteLine($"[INFO] Memory: {rawSchematic.Data.Length * Marshal.SizeOf(typeof(Block))} bytes");

            WidthSchematic  = (short)(rawSchematic.Width * _scale);
            LengthSchematic = (short)(rawSchematic.Length * _scale);
            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 = Math.Min(_ignoreMaxY, 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,
                                                    Extensions.Extensions.GetBlockColor(rawSchematic.Blocks[index],
                                                                                        rawSchematic.Data[index]).ColorToUInt());
                            if ((_excavate && IsBlockConnectedToAir(rawSchematic, block, minY, maxY) || !_excavate))
                            {
                                blocks.Add(block);
                            }
                        }
                    }
                }
            });
            return(blocks.ToHashSet());
        }
Example #3
0
        private static 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;
                    WidthSchematic = raw.Width;
                    break;

                case "Height":     //Short
                    raw.Heigth      = tag.ShortValue;
                    HeightSchematic = 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);
        }
Example #4
0
        private static 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);
        }