public static float GetMiningSpeed(IItemStack itemstack, Block block, IPlayer forPlayer, IWorldAccessor world)
        {
            ItemStack partstack = ModularItemHelper.GetToolheadStack(itemstack);
            IToolPart part      = null;

            if (partstack != null)
            {
                partstack.ResolveBlockOrItem(world);
                part = (IToolPart)partstack.Item;
            }

            if (part != null)
            {
                return(part.GetMiningSpeed(itemstack, block, forPlayer));
            }

            return(itemstack.Item.GetMiningSpeed(itemstack, block, forPlayer));
        }
        public static Dictionary <EnumBlockMaterial, float> GetMiningSpeedDict(ItemSlot slot)
        {
            ItemStack itemstack = slot.Itemstack;
            ItemStack partstack = ModularItemHelper.GetToolheadStack(itemstack);
            IToolPart part      = null;

            if (partstack != null)
            {
                partstack.ResolveBlockOrItem(ModCore.api.World);
                part = (IToolPart)partstack.Item;
            }

            if (part != null)
            {
                return(part.TinkerProps.MiningSpeed);
            }

            return(itemstack.Item.MiningSpeed);
        }
        public static float OnBlockBreaking(IPlayer player, BlockSelection blockSel, ItemSlot itemslot, float remainingResistance, float dt, int counter, ICoreAPI api)
        {
            Block block = player.Entity.World.BlockAccessor.GetBlock(blockSel.Position);

            Vec3f  faceVec = blockSel.Face.Normalf;
            Random rnd     = player.Entity.World.Rand;

            ItemStack stack = itemslot.Itemstack;

            Dictionary <EnumBlockMaterial, float> speeds = null;
            ItemStack partstack = ModularItemHelper.GetToolheadStack(stack);
            IToolPart part      = null;

            if (partstack != null)
            {
                partstack.ResolveBlockOrItem(api.World);
                part = (IToolPart)partstack.Item;
            }

            if (part != null)
            {
                speeds = part.TinkerProps.MiningSpeed;
            }

            bool cantMine = true;

            cantMine &= block.RequiredMiningTier > 0;
            cantMine &= (part != null && (part.TinkerProps.ToolTier < block.RequiredMiningTier || speeds == null || !speeds.ContainsKey(block.BlockMaterial)) || stack.Attributes.GetInt("durability", GetDurability(stack)) < 1);

            double chance = block.BlockMaterial == EnumBlockMaterial.Ore ? 0.72 : 0.12;

            if ((counter % 5 == 0) && (rnd.NextDouble() < chance || cantMine) && (block.BlockMaterial == EnumBlockMaterial.Stone || block.BlockMaterial == EnumBlockMaterial.Ore) && (stack.Item.Tool == EnumTool.Pickaxe || stack.Item.Tool == EnumTool.Hammer))
            {
                double posx = blockSel.Position.X + blockSel.HitPosition.X;
                double posy = blockSel.Position.Y + blockSel.HitPosition.Y;
                double posz = blockSel.Position.Z + blockSel.HitPosition.Z;

                player.Entity.World.SpawnParticles(new SimpleParticleProperties()
                {
                    MinQuantity = 0,
                    AddQuantity = 8,
                    Color       = ColorUtil.ToRgba(255, 255, 255, 128),
                    MinPos      = new Vec3d(posx + faceVec.X * 0.01f, posy + faceVec.Y * 0.01f, posz + faceVec.Z * 0.01f),
                    AddPos      = new Vec3d(0, 0, 0),
                    MinVelocity = new Vec3f(
                        4 * faceVec.X,
                        4 * faceVec.Y,
                        4 * faceVec.Z
                        ),
                    AddVelocity = new Vec3f(
                        8 * ((float)rnd.NextDouble() - 0.5f),
                        8 * ((float)rnd.NextDouble() - 0.5f),
                        8 * ((float)rnd.NextDouble() - 0.5f)
                        ),
                    LifeLength    = 0.025f,
                    GravityEffect = 0f,
                    MinSize       = 0.03f,
                    MaxSize       = 0.4f,
                    ParticleModel = EnumParticleModel.Cube,
                    VertexFlags   = 200,
                    SizeEvolve    = new EvolvingNatFloat(EnumTransformFunction.LINEAR, -0.15f)
                }, player);
            }


            if (cantMine)
            {
                return(remainingResistance);
            }

            return(remainingResistance - GetMiningSpeed(itemslot.Itemstack, block, player, api.World) * dt);
        }