@Override
  public void fire(World world, double[] xyz) {
    ReikaSoundHelper.playSoundAtBlock(world, xCoord, yCoord, zCoord, "random.explode", 1F, 1.3F);
    ReikaSoundHelper.playSoundAtBlock(world, xCoord, yCoord, zCoord, "random.explode", 1F, 0.5F);

    if (rand.nextBoolean()) {
      int slot = ReikaInventoryHelper.locateInInventory(ItemStacks.scrap, inv, false);
      ReikaInventoryHelper.decrStack(slot, inv);
    }

    double speed = 2;
    double[] v = new double[3];
    v[0] = xyz[0] - xCoord;
    v[1] = xyz[1] - yCoord;
    v[2] = xyz[2] - zCoord;
    double dd = ReikaMathLibrary.py3d(v[0], v[1], v[2]);
    for (int i = 0; i < 3; i++) v[i] /= dd;
    for (int i = 0; i < 3; i++) v[i] *= speed;
    dd = ReikaMathLibrary.py3d(v[0], v[1], v[2]);
    double dx = v[0] / dd;
    double dy = v[1] / dd;
    double dz = v[2] / dd;

    // ReikaJavaLibrary.pConsole(dx+"  "+dy+"  "+dz);
    if (!world.isRemote) {
      double y = this.getFiringPositionY(dy);
      EntityFlakShot flak =
          new EntityFlakShot(
              world, xCoord + 0.5 + dx, y, zCoord + 0.5 + dz, 3 * v[0], 3 * v[1], 3 * v[2], this);
      world.spawnEntityInWorld(flak);
    }
  }
  private void dropBlocks(World world, int x, int y, int z) {
    Block drop = world.getBlock(x, y, z);
    if (drop == Blocks.air) return;
    int dropmeta = world.getBlockMetadata(x, y, z);
    ItemStack sapling = tree.getSapling();
    Block logID = tree.getTreeType().getLogID();

    Collection<ItemStack> drops = this.getDrops(world, x, y, z, drop, dropmeta);
    if (drop == logID && logID != null) {
      if (rand.nextInt(3) == 0) {
        drops.add(
            ReikaItemHelper.getSizedItemStack(ItemStacks.sawdust.copy(), 1 + rand.nextInt(4)));
      }
    }

    for (ItemStack todrop : drops) {
      if (ReikaItemHelper.matchStacks(todrop, sapling)) {
        if (inv[0] != null && inv[0].stackSize >= inv[0].getMaxStackSize()) {
          if (!this.chestCheck(todrop))
            ReikaItemHelper.dropItem(world, dropx, yCoord - 0.25, dropz, todrop);
        } else ReikaInventoryHelper.addOrSetStack(todrop, inv, 0);
      } else {
        if (!this.chestCheck(todrop))
          ReikaItemHelper.dropItem(world, dropx, yCoord - 0.25, dropz, todrop);
      }
    }
  }
  @Override
  public void updateEntity(World world, int x, int y, int z, int meta) {
    super.updateTileEntity();
    this.getPowerBelow();
    if (DragonAPICore.debugtest) tank.addLiquid(1000, FluidRegistry.WATER);
    this.testIdle();
    this.throughPut();
    if (world.isRemote) return;
    if (!bedrock) {
      if (ConfigRegistry.EXTRACTORMAINTAIN.getState()) {
        if (drillTime <= 0
            && inv[9] != null
            && ReikaItemHelper.matchStacks(inv[9], ItemStacks.drill)) {
          ReikaInventoryHelper.decrStack(9, inv);
          drillTime = DRILL_LIFE;
        }
      } else {
        drillTime = DRILL_LIFE;
        inv[9] = null;
      }
    }
    boolean[] tickPer = new boolean[4];
    for (int i = 0; i < 4; i++) {
      boolean flag1 = false;

      int n = this.getNumberConsecutiveOperations(i);
      for (int k = 0; k < n; k++) flag1 |= this.doOperation(n > 1, i, tickPer);

      if (flag1) this.markDirty();
    }
    if (ReikaArrayHelper.isAllTrue(tickPer))
      RotaryAchievements.INSANITY.triggerAchievement(this.getPlacer());
  }
 private boolean chestCheck(ItemStack is) {
   TileEntity te = worldObj.getTileEntity(xCoord, yCoord - 1, zCoord);
   if (te instanceof IInventory) {
     IInventory ii = (IInventory) te;
     if (ReikaInventoryHelper.addToIInv(is, ii)) return true;
   }
   return false;
 }
 public void dropItemFromInventory() {
   if (inv[0] == null) return;
   this.dropItem(
       worldObj,
       xCoord,
       yCoord,
       zCoord,
       this.getBlockMetadata(),
       ReikaItemHelper.getSizedItemStack(inv[0], 1));
   ReikaInventoryHelper.decrStack(0, inv);
 }
 private void craft(World world, int x, int y, int z) {
   if (recipe instanceof FluidRecipe) {
     TileEntity te = this.getAdjacentTileEntity(ForgeDirection.DOWN);
     ((IFluidHandler) te)
         .fill(ForgeDirection.UP, new FluidStack(((FluidRecipe) recipe).fluid, 1000), true);
   } else {
     ReikaInventoryHelper.addOrSetStack(recipe.output.copy(), inv, 1);
   }
   energy.subtract(recipe.energy);
   progress = 0;
   this.markDirty();
 }
 public void throughPut() {
   for (int i = 1; i < 4; i++) {
     if (inv[i + 3] != null) {
       if (inv[i] == null) {
         inv[i] = inv[i + 3];
         inv[i + 3] = null;
       } else if (inv[i].stackSize < inv[i].getMaxStackSize()) {
         if (ReikaItemHelper.matchStacks(inv[i], inv[i + 3])) {
           inv[i].stackSize++;
           ReikaInventoryHelper.decrStack(i + 3, inv);
         }
       }
     }
   }
 }
 private void dropItems(World world, int x, int y, int z, Collection<ItemStack> li) {
   for (ItemStack is : li) {
     boolean flag = true;
     for (int i = 0; i < 6 && flag; i++) {
       TileEntity te = this.getAdjacentTileEntity(dirs[i]);
       if (te instanceof IInventory) {
         if (ReikaInventoryHelper.addToIInv(is, (IInventory) te)) flag = false;
       }
     }
     if (flag) {
       ReikaItemHelper.dropItem(world, x + 0.5, y + 1.5, z + 0.5, is);
       dropFlag = true;
       this.doDropWarning(world, x, y, z);
     }
   }
 }
  @Override
  public void updateEntity(World world, int x, int y, int z, int meta) {
    super.updateTileEntity();
    this.getPowerBelow();

    timer.update();
    if (timer.checkCap()) this.updateTemperature(world, x, y, z, meta);
    if (temperature > this.getMeltingTemperature()) energy += power;
    else energy *= 0.85;

    // ReikaJavaLibrary.pConsole(this.getMeltingTemperature()+":"+energy/20F/MELT_ENERGY,
    // Side.SERVER);

    tickcount++;
    if (omega > 0 && power > 0) {
      if (tickcount > 98) {
        SoundRegistry.FRICTION.playSoundAtBlock(
            world, x, y, z, RotaryAux.isMuffled(this) ? 0.1F : 0.5F, 0.5F);
        tickcount = 0;
      }
      world.spawnParticle(
          "crit",
          x + rand.nextDouble(),
          y,
          z + rand.nextDouble(),
          -0.2 + 0.4 * rand.nextDouble(),
          0.4 * rand.nextDouble(),
          -0.2 + 0.4 * rand.nextDouble());
    }

    for (int i = 0; i < inv.length; i++) {
      ItemStack is = inv[i];
      if (is != null) {
        FluidStack fs = RecipesLavaMaker.getRecipes().getMelting(is);
        long melt_energy = RecipesLavaMaker.getRecipes().getMeltingEnergy(is);
        // ReikaJavaLibrary.pConsole(energy/20L+":"+melt_energy, Side.SERVER);
        if (fs != null) {
          if (this.canMake(fs) && energy >= melt_energy * 20) {
            tank.addLiquid(fs.amount, fs.getFluid());
            ReikaInventoryHelper.decrStack(i, inv);
            energy -= melt_energy * 20;
            return;
          }
        }
      }
    }
  }
  @Override
  public void updateTemperature(World world, int x, int y, int z, int meta) {
    int Tamb = ReikaWorldHelper.getAmbientTemperatureAt(world, x, y, z);
    if (ReikaWorldHelper.checkForAdjBlock(world, x, y, z, Blocks.snow) != null) Tamb -= 5;
    if (RotaryAux.isNextToWater(world, x, y, z)) Tamb -= 15;
    if (RotaryAux.isNextToIce(world, x, y, z)) Tamb -= 30;

    ItemStack cryo =
        GameRegistry.findItemStack(ModList.THERMALFOUNDATION.modLabel, "dustCryotheum", 1);
    if (ReikaItemHelper.matchStacks(ItemStacks.dryice, inv[1])
        || (cryo != null && ReikaItemHelper.matchStacks(cryo, inv[1]))) {
      Tamb -= 40;
      if (temperature > Tamb + 4 || rand.nextInt(20) == 0) ReikaInventoryHelper.decrStack(1, inv);
    }

    int dT = Tamb - temperature;
    temperature += dT / 4;
  }
 private boolean chestCheck(World world, int x, int y, int z, ItemStack is) {
   if (is == null) return false;
   if (world.isRemote) return false;
   for (int i = 0; i < 6; i++) {
     ForgeDirection dir = dirs[i];
     TileEntity te = this.getAdjacentTileEntity(dir);
     if (te instanceof IInventory) {
       boolean flag = true;
       if (te instanceof PartialInventory) {
         if (!((PartialInventory) te).hasInventory()) flag = false;
       }
       if (flag) {
         if (ReikaInventoryHelper.addToIInv(is, (IInventory) te)) return true;
       }
     }
   }
   return false;
 }
 private void processItem(World world, int x, int y, int z) {
   if (ReikaItemHelper.isBlock(inv[0])) {
     Block b = Block.getBlockFromItem(inv[0].getItem());
     ArrayList<ItemStack> li =
         b.getDrops(
             world, x, y, z, inv[0].getItemDamage(), this.getEnchantment(Enchantment.fortune));
     li = ReikaItemHelper.collateItemList(li);
     if (!li.isEmpty()) {
       inv[1] = li.remove(0);
       overflow.addAll(li);
     }
   } else if (ModList.IC2.isLoaded() && IC2Handler.IC2Stacks.SCRAPBOX.match(inv[0])) {
     inv[1] = Recipes.scrapboxDrops.getDrop(inv[0], false);
   } else if (ModList.MYSTCRAFT.isLoaded()
       && inv[0].getItem() == MystCraftHandler.getInstance().folderID) {
     List<ItemStack> li = ReikaMystcraftHelper.getPagesInFolder(this.getPlacer(), inv[0], true);
     if (!li.isEmpty()) {
       inv[1] = li.remove(0);
       overflow.addAll(li);
     }
   } else if (inv[0].getItem().getClass() == lootBagClass) {
     ArrayList<ItemStack> li = new ArrayList();
     int n = 8 + rand.nextInt(5);
     for (int i = 0; i < n; i++) {
       try {
         ItemStack is = (ItemStack) generateBagLoot.invoke(null, inv[0].getItemDamage(), rand);
         if (is != null) {
           li.add(is);
         }
       } catch (Exception e) {
         e.printStackTrace();
         this.writeError(e);
       }
     }
     li = ReikaItemHelper.collateItemList(li);
     if (!li.isEmpty()) {
       inv[1] = li.remove(0);
       overflow.addAll(li);
     }
   }
   ReikaInventoryHelper.decrStack(0, inv);
 }
 public void grind(World world, int x, int y, int z, int meta) {
   if (y <= 0) return;
   if (!world.isRemote) {
     if (world.getBlockId(harvestx, harvesty, harvestz) == 7) {
       world.playSoundEffect(
           x + 0.5D, y + 0.5D, z + 0.5D, "dig.stone", 0.5F, par5Random.nextFloat() * 0.4F + 0.8F);
       ReikaWorldHelper.legacySetBlockAndMetadataWithNotify(
           world, harvestx, harvesty, harvestz, RotaryCraft.bedrockslice.blockID, 0);
     } else {
       int rockmetadata = world.getBlockMetadata(harvestx, harvesty, harvestz);
       if (rockmetadata < 15) {
         world.playSoundEffect(
             x + 0.5D,
             y + 0.5D,
             z + 0.5D,
             "dig.stone",
             0.5F,
             par5Random.nextFloat() * 0.4F + 0.8F);
         ReikaWorldHelper.legacySetBlockAndMetadataWithNotify(
             world,
             harvestx,
             harvesty,
             harvestz,
             RotaryCraft.bedrockslice.blockID,
             rockmetadata + 1);
       } else {
         world.playSoundEffect(
             x + 0.5D,
             y + 0.5D,
             z + 0.5D,
             "mob.blaze.hit",
             0.5F,
             par5Random.nextFloat() * 0.4F + 0.8F);
         ReikaWorldHelper.legacySetBlockWithNotify(world, harvestx, harvesty, harvestz, 0);
         if (this.isInventoryFull())
           this.dropItem(world, x, y, z, meta, ItemStacks.bedrockdust.copy());
         else ReikaInventoryHelper.addOrSetStack(ItemStacks.bedrockdust, inv, 0);
         RotaryAchievements.BEDROCKBREAKER.triggerAchievement(this.getPlacer());
       }
     }
   }
 }
 public void grind(World world, int mx, int my, int mz, int x, int y, int z, int meta) {
   if (this.processBlock(world, x, y, z)) {
     if (this.isBedrock(world, x, y, z)) {
       world.playSoundEffect(
           x + 0.5D, y + 0.5D, z + 0.5D, "dig.stone", 0.5F, rand.nextFloat() * 0.4F + 0.8F);
       world.setBlock(x, y, z, BlockRegistry.BEDROCKSLICE.getBlockInstance(), 0, 3);
     } else {
       int rockmetadata = world.getBlockMetadata(x, y, z);
       if (rockmetadata < 15) {
         world.playSoundEffect(
             x + 0.5D, y + 0.5D, z + 0.5D, "dig.stone", 0.5F, rand.nextFloat() * 0.4F + 0.8F);
         world.setBlockMetadataWithNotify(x, y, z, rockmetadata + 1, 3);
       } else {
         world.playSoundEffect(
             x + 0.5D, y + 0.5D, z + 0.5D, "mob.blaze.hit", 0.5F, rand.nextFloat() * 0.4F + 0.8F);
         ItemStack is = this.getDrops(world, x, y, z);
         world.setBlockToAir(x, y, z);
         if (!this.chestCheck(world, x, y, z, is)) {
           if (this.isInventoryFull()) ReikaItemHelper.dropItem(world, dropx, dropy, dropz, is);
           else ReikaInventoryHelper.addOrSetStack(is, inv, 0);
         }
         RotaryAchievements.BEDROCKBREAKER.triggerAchievement(this.getPlacer());
         MinecraftForge.EVENT_BUS.post(new BedrockDigEvent(this, x, y, z));
         if (!world.isRemote) this.incrementStep(world, mx, my, mz);
       }
     }
   } else {
     Block b = world.getBlock(x, y, z);
     if (b != Blocks.air && b.getBlockHardness(world, x, y, z) >= 0) {
       ReikaSoundHelper.playBreakSound(world, x, y, z, b);
       if (FMLCommonHandler.instance().getEffectiveSide() == Side.CLIENT)
         ReikaRenderHelper.spawnDropParticles(world, x, y, z, b, world.getBlockMetadata(x, y, z));
       world.setBlockToAir(x, y, z);
     }
     if (!world.isRemote) this.incrementStep(world, mx, my, mz);
   }
 }
 @Override
 protected void onDecayWaste(int i) {
   super.onDecayWaste(i);
   if (ReikaInventoryHelper.isEmpty(this))
     ReactorAchievements.DECAY.triggerAchievement(this.getPlacer());
 }
 @Override
 public boolean areConditionsMet() {
   return !tank.isEmpty() && !ReikaInventoryHelper.isEmpty(inv, 0, 4);
 }
 /*
 private ReikaOreHelper getVanillaOreByItem(ItemStack is) {
 	return ReikaOreHelper.oreList[is.getItemDamage()%ReikaOreHelper.oreList.length];
 }
  */
 private void bonusItems(ItemStack is) {
   ExtractorBonus e = ExtractorBonus.getBonusForIngredient(is);
   if (e != null && e.doBonus()) {
     ReikaInventoryHelper.addOrSetStack(ExtractorBonus.getBonusItemForIngredient(is), inv, 8);
   }
 }
  @Override
  public ItemStack onItemRightClick(ItemStack is, World world, EntityPlayer ep) {
    if (is.getItemDamage() <= 0) {
      this.noCharge();
      return is;
    }
    this.warnCharge(is);
    if (!ReikaPlayerAPI.playerHasOrIsCreative(ep, Block.gravel.blockID, -1)) {
      if (!world.isRemote) world.playAuxSFX(1001, (int) ep.posX, (int) ep.posY, (int) ep.posZ, 1);
      return is;
    }
    for (float i = 1; i <= 128; i += 0.5) {
      Vec3 look = ep.getLookVec();
      double[] looks = ReikaVectorHelper.getPlayerLookCoords(ep, i);
      AxisAlignedBB fov =
          AxisAlignedBB.getBoundingBox(
              looks[0] - 0.5,
              looks[1] - 0.5,
              looks[2] - 0.5,
              looks[0] + 0.5,
              looks[1] + 0.5,
              looks[2] + 0.5);
      List infov = world.getEntitiesWithinAABB(EntityLivingBase.class, fov);
      for (int k = 0; k < infov.size(); k++) {
        EntityLivingBase ent = (EntityLivingBase) infov.get(k);
        if (!ep.equals(ent)
            && this.isEntityAttackable(ent)
            && ReikaWorldHelper.lineOfSight(world, ep, ent)) {
          double dist =
              ReikaMathLibrary.py3d(ep.posX - ent.posX, ep.posY - ent.posY, ep.posZ - ent.posZ);
          double x = ep.posX + look.xCoord;
          double y = ep.posY + ep.getEyeHeight() + look.yCoord;
          double z = ep.posZ + look.zCoord;
          double dx = ent.posX - ep.posX;
          double dy = ent.posY - ep.posY;
          double dz = ent.posZ - ep.posZ;
          if (!world.isRemote) {
            ItemStack fl = new ItemStack(Item.flint);
            EntityItem ei =
                new EntityItem(
                    world,
                    look.xCoord / look.lengthVector() + ep.posX,
                    look.yCoord / look.lengthVector() + ep.posY,
                    look.zCoord / look.lengthVector() + ep.posZ,
                    fl);
            ei.delayBeforeCanPickup = 100;
            ei.motionX = dx;
            ei.motionY = dy + 1;
            ei.motionZ = dz;
            // ReikaChatHelper.writeCoords(world, ei.posX, ei.posY, ei.posZ);
            ei.velocityChanged = true;
            world.playSoundAtEntity(ep, "dig.gravel", 1.5F, 2F);
            ei.lifespan = 5;
            world.spawnEntityInWorld(ei);

            if (is.getItemDamage() > 4096) { // approx the 1-hit kill of a 10-heart mob
              // ReikaPacketHelper.sendUpdatePacket(RotaryCraft.packetChannel,
              // PacketRegistry.GRAVELGUN.getMinValue(), world, (int)ent.posX, (int)ent.posY,
              // (int)ent.posZ);
              // world.playSoundAtEntity(ep, "random.explode", 0.25F, 1F);
            }
            if (ent instanceof EntityDragon) {
              EntityDragon ed = (EntityDragon) ent;
              ed.attackEntityFromPart(
                  ed.dragonPartBody, DamageSource.causePlayerDamage(ep), this.getAttackDamage(is));
            } else {
              int dmg = this.getAttackDamage(is);
              if (ent instanceof EntityPlayer) {
                for (int n = 1; n < 5; n++) {
                  ItemRegistry ir = ItemRegistry.getEntry(ent.getCurrentItemOrArmor(n));
                  if (ir != null) {
                    if (ir.isBedrockArmor()) dmg *= 0.75;
                  }
                }
              }
              ent.attackEntityFrom(DamageSource.causePlayerDamage(ep), dmg);
              if (dmg >= 500) RotaryAchievements.MASSIVEHIT.triggerAchievement(ep);
            }
            if (ent instanceof EntityMob
                && (ent.isDead || ent.getHealth() <= 0)
                && ReikaMathLibrary.py3d(ep.posX - ent.posX, ep.posY - ent.posY, ep.posZ - ent.posZ)
                    >= 80) RotaryAchievements.GRAVELGUN.triggerAchievement(ep);
          }
          // ReikaWorldHelper.spawnParticleLine(world, x, y, z, ent.posX, ent.posY+ent.height/2,
          // ent.posZ, "crit", 0, 0, 0, 60);
          for (float t = 0; t < 2; t += 0.05F)
            world.spawnParticle("crit", x, y, z, dx / dist * t, dy / dist * t, dz / dist * t);
        }
      }
      if (infov.size() > 0 && !(infov.size() == 1 && infov.get(0) instanceof EntityPlayer)) {
        if (!ep.capabilities.isCreativeMode)
          ReikaInventoryHelper.findAndDecrStack(
              Block.gravel.blockID, -1, ep.inventory.mainInventory);
        return new ItemStack(is.itemID, is.stackSize, is.getItemDamage() - 1);
      }
    }
    return is;
  }
 @Override
 public boolean hasAmmo() {
   return ReikaInventoryHelper.checkForItemStack(ItemStacks.scrap, inv, false);
 }
 private void make(ItemStack toMake) {
   ReikaInventoryHelper.addOrSetStack(toMake, inv, 0);
   int amt = RecipesCrystallizer.getRecipes().getRecipeConsumption(toMake);
   tank.removeLiquid(amt);
 }
 @Override
 public void decrementSlot(ItemStack is, int slot) {
   ItemStack[] inv = this.getInventory(is);
   ReikaInventoryHelper.decrStack(slot, inv);
   this.setItems(is, inv);
 }
  @Override
  public void updateEntity(World world, int x, int y, int z, int meta) {
    super.updateTileEntity();
    tickcount++;

    tree.setWorld(world);
    treeCopy.setWorld(world);

    this.getIOSides(world, x, y, z, meta);
    this.getPower(false);

    if (power < MINPOWER || torque < MINTORQUE) {
      return;
    }

    if (this.isJammed()) return;

    if (world.isRemote) return;

    if (tree.isEmpty() && this.hasWood()) {
      tree.reset();
      ModWoodList wood =
          ModWoodList.getModWood(
              world.getBlock(editx, edity, editz), world.getBlockMetadata(editx, edity, editz));
      ReikaTreeHelper vanilla =
          ReikaTreeHelper.getTree(
              world.getBlock(editx, edity, editz), world.getBlockMetadata(editx, edity, editz));

      for (int i = -1; i <= 1; i++) {
        for (int j = -1; j <= 1; j++) {
          tree.checkAndAddDyeTree(world, editx + i, edity, editz + j);
          if (tree.isEmpty() || !tree.isValidTree()) tree.clear();
        }
      }
      if (tree.isEmpty()) {
        for (int i = -1; i <= 1; i++) {
          for (int j = -1; j <= 1; j++) {
            tree.checkAndAddRainbowTree(world, editx + i, edity, editz + j);
            if (tree.isEmpty() || !tree.isValidTree()) tree.clear();
          }
        }
      }

      if (tree.isEmpty()) {

        if (wood == ModWoodList.SEQUOIA) {
          for (int i = -32; i < 255; i += 16)
            tree.addSequoia(world, editx, edity + i, editz, RotaryCraft.logger.shouldDebug());
        } else if (wood == ModWoodList.DARKWOOD) {
          tree.addDarkForest(
              world,
              editx,
              edity,
              editz,
              editx - 8,
              editx + 8,
              editz - 8,
              editz + 8,
              RotaryCraft.logger.shouldDebug());
        } else if (wood == ModWoodList.IRONWOOD) {
          for (int i = -2; i < 128; i += 16)
            tree.addIronwood(world, editx, edity + i, editz, RotaryCraft.logger.shouldDebug());
        } else if (wood != null) {
          for (int i = -1; i <= 1; i++) {
            for (int j = -1; j <= 1; j++) {
              // tree.addGenerousTree(world, editx+i, edity, editz+j, 16);
              tree.setTree(wood);
              tree.addModTree(world, editx + i, edity, editz + j);
            }
            // ReikaJavaLibrary.pConsole(tree, Side.SERVER);
          }
        } else if (vanilla != null) {
          for (int i = -1; i <= 1; i++) {
            for (int j = -1; j <= 1; j++) {
              // tree.addGenerousTree(world, editx+i, edity, editz+j, 16);
              tree.setTree(vanilla);
              tree.addTree(world, editx + i, edity, editz + j);
            }
          }
        }
      }

      this.checkAndMatchInventory();

      tree.sortBlocksByHeight();
      tree.reverseBlockOrder();
      tree.sort(inwardsComparator);
      tree.sort(leafPriority);
      treeCopy = (TreeReader) tree.copy();
    }

    Block b = world.getBlock(x, y + 1, z);
    if (b != Blocks.air) {
      if (b.getMaterial() == Material.wood || b.getMaterial() == Material.leaves) {
        ReikaItemHelper.dropItems(
            world,
            dropx,
            y - 0.25,
            dropz,
            this.getDrops(world, x, y + 1, z, b, world.getBlockMetadata(x, y, z)));
        world.setBlockToAir(x, y + 1, z);
      }
    }

    // RotaryCraft.logger.debug(tree);

    if (tree.isEmpty()) return;

    if (tickcount < this.getOperationTime()) return;
    tickcount = 0;

    if (!tree.isValidTree()) {
      tree.reset();
      tree.clear();
      return;
    }

    for (int i = 0; i < this.getNumberConsecutiveOperations(); i++) {
      Coordinate c = tree.getNextAndMoveOn();
      Block drop = c.getBlock(world);
      int dropmeta = c.getBlockMetadata(world);

      if (drop != Blocks.air) {
        Material mat = ReikaWorldHelper.getMaterial(world, c.xCoord, c.yCoord, c.zCoord);
        if (ConfigRegistry.INSTACUT.getState()) {
          // ReikaItemHelper.dropItems(world, dropx, y-0.25, dropz, dropBlocks.getDrops(world,
          // c.xCoord, c.yCoord, c.zCoord, dropmeta, 0));
          this.cutBlock(world, x, y, z, c, mat);

          if (c.yCoord == edity) {
            Block idbelow = world.getBlock(c.xCoord, c.yCoord - 1, c.zCoord);
            Block root = TwilightForestHandler.BlockEntry.ROOT.getBlock();
            if (ReikaPlantHelper.SAPLING.canPlantAt(world, c.xCoord, c.yCoord, c.zCoord)) {
              ItemStack plant = this.getPlantedSapling();
              if (plant != null) {
                if (inv[0] != null && !this.hasEnchantment(Enchantment.infinity))
                  ReikaInventoryHelper.decrStack(0, inv);
                ReikaWorldHelper.setBlock(world, c.xCoord, c.yCoord, c.zCoord, plant);
              }
            } else if (tree.getTreeType() == ModWoodList.TIMEWOOD
                && (idbelow == root || idbelow == Blocks.air)) {
              ItemStack plant = this.getPlantedSapling();
              if (plant != null) {
                if (inv[0] != null && !this.hasEnchantment(Enchantment.infinity))
                  ReikaInventoryHelper.decrStack(0, inv);
                world.setBlock(c.xCoord, c.yCoord - 1, c.zCoord, Blocks.dirt);
                ReikaWorldHelper.setBlock(world, c.xCoord, c.yCoord, c.zCoord, plant);
              }
            }
          }
        } else {
          boolean fall = BlockSand.func_149831_e(world, c.xCoord, c.yCoord - 1, c.zCoord);
          if (fall) {
            EntityFallingBlock e =
                new EntityFallingBlock(
                    world, c.xCoord + 0.5, c.yCoord + 0.65, c.zCoord + 0.5, drop, dropmeta);
            e.field_145812_b = -5000;
            if (!world.isRemote) {
              world.spawnEntityInWorld(e);
            }
            c.setBlock(world, Blocks.air);
          } else {
            this.cutBlock(world, x, y, z, c, mat);
            if (c.yCoord == edity) {
              Block idbelow = world.getBlock(c.xCoord, c.yCoord - 1, c.zCoord);
              Block root = TwilightForestHandler.BlockEntry.ROOT.getBlock();
              if (ReikaPlantHelper.SAPLING.canPlantAt(world, c.xCoord, c.yCoord, c.zCoord)) {
                ItemStack plant = this.getPlantedSapling();
                if (plant != null) {
                  if (inv[0] != null && !this.hasEnchantment(Enchantment.infinity))
                    ReikaInventoryHelper.decrStack(0, inv);
                  ReikaWorldHelper.setBlock(world, c.xCoord, c.yCoord, c.zCoord, plant);
                }
              } else if (tree.getTreeType() == ModWoodList.TIMEWOOD
                  && (idbelow == root || idbelow == Blocks.air)) {
                ItemStack plant = this.getPlantedSapling();
                if (plant != null) {
                  if (inv[0] != null && !this.hasEnchantment(Enchantment.infinity))
                    ReikaInventoryHelper.decrStack(0, inv);
                  world.setBlock(c.xCoord, c.yCoord - 1, c.zCoord, Blocks.dirt);
                  ReikaWorldHelper.setBlock(world, c.xCoord, c.yCoord, c.zCoord, plant);
                }
              }
            }
          }
        }
      }
      if (tree.isEmpty()) break;
    }
  }
 @Override
 public boolean areConditionsMet() {
   return !ReikaInventoryHelper.isEmpty(inv);
 }
 public boolean hasStone() {
   return !ReikaInventoryHelper.isEmpty(inv);
 }
 @Override
 public void onNewPlayer(EntityPlayer ep) {
   if (ReikaInventoryHelper.checkForItemStack(this.getItem(), ep.inventory, false)) return;
   if (!ep.inventory.addItemStackToInventory(this.getItem()))
     ep.dropPlayerItemWithRandomChoice(this.getItem(), true);
 }