@Override
  public boolean onEntityItemUpdate(EntityItem entityItem) {
    if (type != EnumFlutterType.BUTTERFLY) return false;
    if (!Proxies.common.isSimulating(entityItem.worldObj) || entityItem.ticksExisted < 80)
      return false;
    if (entityItem.worldObj.getTotalWorldTime() % 24 != 0) return false;

    IButterfly butterfly =
        PluginLepidopterology.butterflyInterface.getMember(entityItem.getEntityItem());
    if (butterfly == null) return false;

    if (!butterfly.canTakeFlight(
        entityItem.worldObj, entityItem.posX, entityItem.posY, entityItem.posZ)) return false;

    if (entityItem.worldObj.countEntities(EntityButterfly.class)
        > PluginLepidopterology.entityConstraint) return false;

    if (Utils.spawnEntity(
            entityItem.worldObj,
            new EntityButterfly(entityItem.worldObj, butterfly),
            entityItem.posX,
            entityItem.posY,
            entityItem.posZ)
        != null) {
      if (entityItem.getEntityItem().stackSize > 1) entityItem.getEntityItem().stackSize--;
      else entityItem.setDead();
      return true;
    }

    return false;
  }
 private void attemptButterflySpawn(
     World world, IButterfly butterfly, double x, double y, double z) {
   if (PluginLepidopterology.butterflyInterface.spawnButterflyInWorld(
           world, butterfly.copy(), x, y + 0.1f, z)
       != null) {
     Proxies.log.finest(
         "Spawned a butterfly '%s' at %s/%s/%s.", butterfly.getDisplayName(), x, y, z);
   }
 }
  @Override
  public String getItemStackDisplayName(ItemStack itemstack) {

    if (itemstack.getTagCompound() == null) return "???";

    IButterfly butterfly = PluginLepidopterology.butterflyInterface.getMember(itemstack);
    if (butterfly == null) return "???";

    return butterfly.getDisplayName();
  }
  @Override
  public boolean onRandomLeafTick(
      ITree tree, World world, int biomeId, int x, int y, int z, boolean isDestroyed) {

    if (world.rand.nextFloat() >= tree.getGenome().getSappiness() * tree.getGenome().getYield()) {
      return false;
    }

    IButterfly spawn =
        PluginLepidopterology.butterflyInterface
            .getIndividualTemplates()
            .get(
                world.rand.nextInt(
                    PluginLepidopterology.butterflyInterface.getIndividualTemplates().size()));
    if (world.rand.nextFloat() >= spawn.getGenome().getPrimary().getRarity() * 0.5f) {
      return false;
    }

    if (world.countEntities(EntityButterfly.class) > PluginLepidopterology.spawnConstraint) {
      return false;
    }

    if (!spawn.canSpawn(world, x, y, z)) {
      return false;
    }

    if (world.isAirBlock(x - 1, y, z)) {
      attemptButterflySpawn(world, spawn, x - 1, y, z);
    } else if (world.isAirBlock(x + 1, y, z)) {
      attemptButterflySpawn(world, spawn, x + 1, y, z);
    } else if (world.isAirBlock(x, y, z - 1)) {
      attemptButterflySpawn(world, spawn, x, y, z - 1);
    } else if (world.isAirBlock(x, y, z + 1)) {
      attemptButterflySpawn(world, spawn, x, y, z + 1);
    }

    return false;
  }