private MeshRef CreateModel(ItemStack forStack)
        {
            ITreeAttribute tree = forStack.Attributes;

            if (tree == null)
            {
                tree = new TreeAttribute();
            }
            int[]  materials = BlockEntityChisel.MaterialIdsFromAttributes(tree, capi.World);
            uint[] cuboids   = (tree["cuboids"] as IntArrayAttribute)?.AsUint;

            // When loaded from json
            if (cuboids == null)
            {
                cuboids = (tree["cuboids"] as LongArrayAttribute)?.AsUint;
            }

            List <uint> voxelCuboids = cuboids == null ? new List <uint>() : new List <uint>(cuboids);

            MeshData mesh = BlockEntityChisel.CreateMesh(capi, voxelCuboids, materials);

            //mesh.Rgba2 = null;

            return(capi.Render.UploadMesh(mesh));
        }
        public override string GetPlacedBlockName(IWorldAccessor world, BlockPos pos)
        {
            BlockEntityChisel be = world.BlockAccessor.GetBlockEntity(pos) as BlockEntityChisel;

            if (be != null)
            {
                return(be.BlockName);
            }

            return(base.GetPlacedBlockName(world, pos));
        }
        public override int GetColor(ICoreClientAPI capi, BlockPos pos)
        {
            BlockEntityChisel be = capi.World.BlockAccessor.GetBlockEntity(pos) as BlockEntityChisel;

            if (be?.Materials != null && be.Materials.Length > 0)
            {
                Block block = capi.World.GetBlock(be.Materials[0]);
                return(block.GetColor(capi, pos));
            }

            return(base.GetColor(capi, pos));
        }
        public override Cuboidf[] GetCollisionBoxes(IBlockAccessor blockAccessor, BlockPos pos)
        {
            BlockEntityChisel bec = blockAccessor.GetBlockEntity(pos) as BlockEntityChisel;

            if (bec != null)
            {
                Cuboidf[] selectionBoxes = bec.GetCollisionBoxes(blockAccessor, pos);

                return(selectionBoxes);
            }

            return(base.GetSelectionBoxes(blockAccessor, pos));
        }
        public override void GetDecal(IWorldAccessor world, BlockPos pos, ITexPositionSource decalTexSource, ref MeshData decalModelData, ref MeshData blockModelData)
        {
            BlockEntityChisel be = world.BlockAccessor.GetBlockEntity(pos) as BlockEntityChisel;

            if (be != null)
            {
                ICoreClientAPI capi = api as ICoreClientAPI;

                blockModelData = be.Mesh;
                decalModelData = be.CreateDecalMesh(decalTexSource);

                return;
            }

            base.GetDecal(world, pos, decalTexSource, ref decalModelData, ref blockModelData);
        }
        /*public override byte[] GetLightHsv(IBlockAccessor blockAccessor, BlockPos pos, ItemStack stack = null)
         * {
         *  BlockEntityChisel bec = blockAccessor.GetBlockEntity(pos) as BlockEntityChisel;
         *  if (bec?.Materials == null)
         *  {
         *      return base.GetLightHsv(blockAccessor, pos, stack);
         *  }
         *
         *  for (int i = 0; i < bec.Materials.Length; i++)
         *  {
         *      Block block = blockAccessor.GetBlock(bec.Materials[i]);
         *      if (block.LightHsv[2] > 0) return block.LightHsv;
         *  }
         *
         *  return base.GetLightHsv(blockAccessor, pos, stack);
         * }
         *
         * public override int GetLightAbsorption(IBlockAccessor blockAccessor, BlockPos pos)
         * {
         *  BlockEntityChisel bec = blockAccessor.GetBlockEntity(pos) as BlockEntityChisel;
         *  if (bec?.Materials == null)
         *  {
         *      return base.GetLightAbsorption(blockAccessor, pos);
         *  }
         *
         *  int absorb = 99;
         *
         *  for (int i = 0; i < bec.Materials.Length; i++)
         *  {
         *      Block block = blockAccessor.GetBlock(bec.Materials[i]);
         *      absorb = Math.Min(absorb, block.LightAbsorption);
         *  }
         *
         *  return base.GetLightAbsorption(blockAccessor, pos);
         * }*/


        public override ItemStack OnPickBlock(IWorldAccessor world, BlockPos pos)
        {
            BlockEntityChisel bec = world.BlockAccessor.GetBlockEntity(pos) as BlockEntityChisel;

            if (bec == null)
            {
                return(null);
            }

            TreeAttribute tree = new TreeAttribute();

            bec.ToTreeAttributes(tree);
            tree.RemoveAttribute("posx");
            tree.RemoveAttribute("posy");
            tree.RemoveAttribute("posz");

            return(new ItemStack(this.Id, EnumItemClass.Block, 1, tree, world));
        }
        public override void OnBlockPlaced(IWorldAccessor world, BlockPos blockPos, ItemStack byItemStack)
        {
            base.OnBlockPlaced(world, blockPos, byItemStack);

            BlockEntityChisel be = world.BlockAccessor.GetBlockEntity(blockPos) as BlockEntityChisel;

            if (be != null && byItemStack != null)
            {
                byItemStack.Attributes.SetInt("posx", blockPos.X);
                byItemStack.Attributes.SetInt("posy", blockPos.Y);
                byItemStack.Attributes.SetInt("posz", blockPos.Z);

                be.FromTreeAtributes(byItemStack.Attributes, world);
                be.MarkDirty(true);

                if (world.Side == EnumAppSide.Client)
                {
                    be.RegenMesh();
                }

                be.RegenSelectionBoxes(null);
            }
        }