@Override
 public void onUsingTick(ItemStack stack, EntityPlayer player, int count) {
   if (toolMaterial == ToolMaterial.EMERALD) {
     if (player.getHeldItem() != null && ZSSPlayerInfo.get(player).canBlock()) {
       Vec3 vec3 = player.getLookVec();
       double dx = player.posX + vec3.xCoord * 2.0D;
       double dy = player.posY + player.getEyeHeight() + vec3.yCoord * 2.0D;
       double dz = player.posZ + vec3.zCoord * 2.0D;
       List<EntityFireball> list =
           player.worldObj.getEntitiesWithinAABB(
               EntityFireball.class,
               AxisAlignedBB.getBoundingBox(dx - 1, dy - 1, dz - 1, dx + 1, dy + 1, dz + 1));
       for (EntityFireball fireball : list) {
         DamageSource source = DamageSource.causeFireballDamage(fireball, fireball.shootingEntity);
         if (canBlockDamage(stack, source)
             && fireball.attackEntityFrom(DamageSource.causePlayerDamage(player), 1.0F)) {
           fireball.getEntityData().setBoolean("isReflected", true);
           ZSSPlayerInfo.get(player).onAttackBlocked(stack, 1.0F);
           WorldUtils.playSoundAtEntity(player, Sounds.HAMMER, 0.4F, 0.5F);
           break;
         }
       }
     }
   }
 }
 @Override
 public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player) {
   if (ZSSPlayerInfo.get(player).canBlock()) {
     player.setItemInUse(stack, getMaxItemUseDuration(stack));
   }
   return stack;
 }
 /**
  * Called when the shield blocks an attack when held in the normal fashion (i.e. non-BG2) used by
  * Deku Shield to damage / destroy the stack and by Mirror Shield to reflect projectiles
  *
  * @return Return the amount of damage remaining, if any; 0 cancels the hurt event
  */
 public float onBlock(EntityPlayer player, ItemStack shield, DamageSource source, float damage) {
   ZSSPlayerInfo.get(player).onAttackBlocked(shield, damage);
   WorldUtils.playSoundAtEntity(player, Sounds.HAMMER, 0.4F, 0.5F);
   float damageBlocked = damage;
   if (toolMaterial == ToolMaterial.WOOD) {
     if (source.isProjectile()
         && !source.isExplosion()
         && source.getSourceOfDamage() instanceof IProjectile) {
       if (ZSSMain.isBG2Enabled
           && player.getHeldItem() == shield
           && shield.getItem() instanceof IArrowCatcher) {
         if (((IArrowCatcher) shield.getItem())
             .catchArrow(shield, player, (IProjectile) source.getSourceOfDamage())) {
           ((InventoryPlayerBattle) player.inventory).hasChanged = true;
         }
       }
     } else if (source instanceof IDamageAoE && ((IDamageAoE) source).isAoEDamage()) {
       damageBlocked *= magicReduction;
     }
     int dmg = Math.round(source.isFireDamage() ? damage + 10.0F : damage - 2.0F);
     if (dmg > 0) {
       shield.damageItem(dmg, player);
       if (shield.stackSize <= 0) {
         ForgeEventFactory.onPlayerDestroyItem(player, shield);
         if (ZSSMain.isBG2Enabled && BattlegearUtils.isPlayerInBattlemode(player)) {
           BattlegearUtils.setPlayerOffhandItem(player, null);
         } else {
           player.destroyCurrentEquippedItem();
         }
       }
     }
   } else if (toolMaterial == ToolMaterial.EMERALD) {
     if (source.isProjectile() && !source.isExplosion() && source.getSourceOfDamage() != null) {
       float chance = (source.isMagicDamage() ? (1F / 3F) : 1.0F);
       if (source.getSourceOfDamage() instanceof IReflectable) {
         ((IReflectable) source.getSourceOfDamage())
             .getReflectChance(shield, player, source.getEntity());
       }
       if (player.worldObj.rand.nextFloat() < chance) {
         Entity projectile = null;
         try {
           projectile =
               source
                   .getSourceOfDamage()
                   .getClass()
                   .getConstructor(World.class)
                   .newInstance(player.worldObj);
         } catch (Exception e) {;
         }
         if (projectile != null) {
           NBTTagCompound data = new NBTTagCompound();
           source.getSourceOfDamage().writeToNBT(data);
           projectile.readFromNBT(data);
           projectile.getEntityData().setBoolean("isReflected", true);
           projectile.posX -= projectile.motionX;
           projectile.posY -= projectile.motionY;
           projectile.posZ -= projectile.motionZ;
           double motionX =
               (double)
                   (-MathHelper.sin(player.rotationYaw / 180.0F * (float) Math.PI)
                       * MathHelper.cos(player.rotationPitch / 180.0F * (float) Math.PI));
           double motionZ =
               (double)
                   (MathHelper.cos(player.rotationYaw / 180.0F * (float) Math.PI)
                       * MathHelper.cos(player.rotationPitch / 180.0F * (float) Math.PI));
           double motionY =
               (double) (-MathHelper.sin(player.rotationPitch / 180.0F * (float) Math.PI));
           TargetUtils.setEntityHeading(
               projectile,
               motionX,
               motionY,
               motionZ,
               1.0F,
               2.0F + (20.0F * player.worldObj.rand.nextFloat()),
               false);
           if (projectile instanceof IReflectable) {
             ((IReflectable) projectile)
                 .onReflected(shield, player, source.getEntity(), source.getSourceOfDamage());
           }
           player.worldObj.spawnEntityInWorld(projectile);
         }
       } else if (source.isUnblockable()
           || (source instanceof IDamageAoE
               && ((IDamageAoE) source).isAoEDamage())) { // failed to reflect projectile
         damageBlocked *= magicReduction;
       }
     }
   } else if (source.isUnblockable()
       || (source instanceof IDamageAoE && ((IDamageAoE) source).isAoEDamage())) {
     damageBlocked *=
         magicReduction; // default shield behavior blocks half damage from AoE magic attacks
   }
   return (damage - damageBlocked);
 }
 @Override
 public boolean isUseableByPlayer(EntityPlayer player) {
   return ZSSPlayerInfo.get(player).getBorrowedMask() == null;
 }