@Override
 public boolean isItemValidForSlot(int slot, ItemStack is) {
   if (slot > 3 && slot < 9) return false;
   if (slot == 0)
     return ReikaBlockHelper.isOre(is)
         || CustomExtractLoader.instance.getEntryFromOreBlock(is) != null;
   if (ItemRegistry.EXTRACTS.matchItem(is)) {
     return slot == 1 + is.getItemDamage() / 8;
   } else if (ItemRegistry.MODEXTRACTS.matchItem(is)) {
     return slot == 1 + is.getItemDamage() % 4;
   } else if (ItemRegistry.CUSTOMEXTRACT.matchItem(is)) {
     return slot == 1 + is.getItemDamage() % 4;
   }
   if (slot == 9)
     return !bedrock
         && ConfigRegistry.EXTRACTORMAINTAIN.getState()
         && ReikaItemHelper.matchStacks(is, ItemStacks.drill);
   return false;
 }
 private void removeFound(World world, int x, int y, int z, Block b, int meta) {
   if (Item.getItemFromBlock(b) == null) return;
   ItemStack is = new ItemStack(b, 1, meta);
   if (b instanceof SpecialOreBlock) {
     is = ((SpecialOreBlock) b).getDisplayItem(world, x, y, z);
   } else if (ReikaBlockHelper.isOre(b, meta)) {
     ReikaOreHelper ore = ReikaOreHelper.getEntryByOreDict(is);
     ModOreList mod = ModOreList.getModOreFromOre(is);
     if (ore != null) {
       is = ore.getOreBlock();
     } else if (mod != null && mod != ModOreList.CERTUSQUARTZ) {
       is = mod.getFirstOreBlock();
     }
   }
   Integer i = found.get(is);
   if (i == null) i = 0;
   if (i > 1) found.put(is, i - 1);
   else found.remove(is);
   // ReikaJavaLibrary.pConsole("Removed "+b+":"+meta+" from cache, now have "+found.get(is));
 }
 private void addFound(World world, int x, int y, int z, Block b, int meta) {
   if (b != null && Item.getItemFromBlock(b) == null) {
     ChromatiCraft.logger.logError("Block " + b + " has no item to drop when mined???");
     return;
   }
   ItemStack is = new ItemStack(b, 1, meta);
   if (b instanceof SpecialOreBlock) {
     is = ((SpecialOreBlock) b).getDisplayItem(world, x, y, z);
   } else if (ReikaBlockHelper.isOre(b, meta)) {
     ReikaOreHelper ore = ReikaOreHelper.getEntryByOreDict(is);
     ModOreList mod = ModOreList.getModOreFromOre(is);
     if (ore != null) {
       is = ore.getOreBlock();
     } else if (mod != null && mod != ModOreList.CERTUSQUARTZ) {
       is = mod.getFirstOreBlock();
     }
   }
   Integer i = found.get(is);
   if (i == null) i = 0;
   found.put(is, i + 1);
   // ReikaJavaLibrary.pConsole("Found "+b+":"+meta+" @ "+x+","+y+","+z+"; have "+(i+1));
 }
 @Override
 public void updateEntity(World world, int x, int y, int z, int meta) {
   if (!world.isRemote) {
     if (dropFlag) {
       if (this.getTicksExisted() % 20 == 0) {
         this.doDropWarning(world, x, y, z);
       }
     } else {
       int n = this.hasSpeed() ? 4 : 1;
       for (int k = 0; k < n; k++) {
         if (digging && !coords.isEmpty()) {
           // this.prepareChunkloading();
           if (this.hasEnergy(required)) {
             Coordinate c = coords.get(index);
             int dx = c.xCoord;
             int dy = c.yCoord;
             int dz = c.zCoord;
             Block id = this.parseBlock(world.getBlock(dx, dy, dz));
             int meta2 = world.getBlockMetadata(dx, dy, dz);
             // ReikaJavaLibrary.pConsole(readX+":"+dx+", "+dy+", "+readZ+":"+dz+" >
             // "+ores.getSize(), Side.SERVER);
             this.removeFound(world, dx, dy, dz, id, meta2);
             if (id instanceof SpecialOreBlock) {
               this.dropSpecialOreBlock(world, x, y, z, dx, dy, dz, (SpecialOreBlock) id, meta2);
             } else if (ReikaBlockHelper.isOre(id, meta2)) {
               // ores.addBlockCoordinate(dx, dy, dz);
               this.dropBlock(world, x, y, z, dx, dy, dz, id, meta2);
             } else if (this.shouldMine(id, meta2)) {
               this.dropBlock(world, x, y, z, dx, dy, dz, id, meta2);
             } else if (this.isTieredResource(world, dx, dy, dz, id, meta2)) {
               this.dropTieredResource(world, x, y, z, dx, dy, dz, id, meta2);
             } else if (id instanceof MinerBlock) {
               this.dropMineableBlock(world, x, y, z, dx, dy, dz, id, meta2);
             }
             this.useEnergy(required.copy().scale(this.hasEfficiency() ? 0.25F : 1));
             // ReikaJavaLibrary.pConsole("Mining "+id+":"+meta2+" @ "+dx+","+dy+","+dz+";
             // index="+index);
             index++;
             if (index >= coords.size()) {
               this.finishDigging();
               k = n;
             }
           }
         } else if (!digReady && !finishedDigging) {
           this.prepareChunkloading();
           for (int i = 0; i < TICKSTEP; i++) {
             int dx = x + readX;
             int dy = readY;
             int dz = z + readZ;
             ReikaWorldHelper.forceGenAndPopulate(world, dx, dz);
             Block id = this.parseBlock(world.getBlock(dx, dy, dz));
             int meta2 = world.getBlockMetadata(dx, dy, dz);
             // ReikaJavaLibrary.pConsole(readX+":"+dx+", "+dy+", "+readZ+":"+dz+" >
             // "+ores.getSize(), Side.SERVER);
             boolean add = false;
             if (ReikaBlockHelper.isOre(id, meta2)) {
               // ores.addBlockCoordinate(dx, dy, dz);
               add = coords.add(new Coordinate(dx, dy, dz));
             } else if (this.isTieredResource(world, dx, dy, dz, id, meta2)) {
               add = coords.add(new Coordinate(dx, dy, dz));
             } else if (id instanceof MinerBlock && ((MinerBlock) id).isMineable(meta2)) {
               add = coords.add(new Coordinate(dx, dy, dz));
             } else if (this.shouldMine(id, meta2)) {
               add = coords.add(new Coordinate(dx, dy, dz));
             }
             if (add) {
               this.addFound(world, dx, dy, dz, id, meta2);
             }
             this.updateReadPosition();
             if (readY >= worldObj.getActualHeight()) {
               this.prepareDigging();
             }
           }
         }
       }
       progress = readY;
     }
   }
   if (world.isRemote) this.spawnParticles(world, x, y, z);
 }