Esempio n. 1
0
 /**
  * Checks if the object corresponds to provided parameters
  *
  * @param block Block to compare to
  * @return <b>true</b> if the conditions are met, <b>false</b> otherwise
  */
 public boolean equals(BlockState block) {
   if (ItemsWithMetadata.checkAgainst(block.getTypeId())) {
     return block.getType().equals(this.block.getType())
         && block.getData().getData() == this.block.getData().getData();
   } else {
     return block.getType().equals(this.block.getType());
   }
 }
Esempio n. 2
0
  public boolean canGreenThumbBlock(BlockState blockState) {
    Player player = getPlayer();

    return player.getItemInHand().getType() == Material.SEEDS
        && BlockUtils.canMakeMossy(blockState)
        && Permissions.greenThumbBlock(player, blockState.getType());
  }
Esempio n. 3
0
  /**
   * Check if a given block should allow for the activation of abilities
   *
   * @param blockState The {@link BlockState} of the block to check
   * @return true if the block should allow ability activation, false otherwise
   */
  public static boolean canActivateAbilities(BlockState blockState) {
    switch (blockState.getType()) {
      case BED_BLOCK:
      case BREWING_STAND:
      case BOOKSHELF:
      case BURNING_FURNACE:
      case CAKE_BLOCK:
      case CHEST:
      case DISPENSER:
      case ENCHANTMENT_TABLE:
      case ENDER_CHEST:
      case FENCE_GATE:
      case FURNACE:
      case IRON_DOOR_BLOCK:
      case JUKEBOX:
      case LEVER:
      case NOTE_BLOCK:
      case STONE_BUTTON:
      case WOOD_BUTTON:
      case TRAP_DOOR:
      case WALL_SIGN:
      case WOODEN_DOOR:
      case WORKBENCH:
      case BEACON:
      case ANVIL:
      case DROPPER:
      case HOPPER:
      case TRAPPED_CHEST:
        return false;

      default:
        return true;
    }
  }
Esempio n. 4
0
  /**
   * Check if a block is affected by this ability.
   *
   * @param blockState the block to check
   * @return true if the block is affected by this ability, false otherwise
   */
  public boolean blockCheck(BlockState blockState) {
    switch (this) {
      case BERSERK:
        return (BlockUtils.affectedByGigaDrillBreaker(blockState)
            || blockState.getType() == Material.SNOW);

      case BLOCK_CRACKER:
        return BlockUtils.affectedByBlockCracker(blockState);

      case GIGA_DRILL_BREAKER:
        return BlockUtils.affectedByGigaDrillBreaker(blockState);

      case GREEN_TERRA:
        return BlockUtils.canMakeMossy(blockState);

      case LEAF_BLOWER:
        return BlockUtils.isLeaves(blockState);

      case SUPER_BREAKER:
        return BlockUtils.affectedBySuperBreaker(blockState);

      case TREE_FELLER:
        return BlockUtils.isLog(blockState);

      default:
        return false;
    }
  }
Esempio n. 5
0
  public boolean loadSign(
      final World w, final int x1, final int x2, final int z1, final int z2, final int y1) {
    final boolean usingx = (x1 == x2) ? false : true;
    HungerGames.debug(w + " " + x1 + " " + x2 + " " + z1 + " " + z2 + " " + y1 + " " + usingx);
    final BlockFace facing =
        ((org.bukkit.material.Sign) new Location(w, x1, y1, z1).getBlock().getState()).getFacing();

    if (usingx) {
      for (int a = Math.max(x1, x2); a >= Math.min(x1, x2); a--) {
        final Location l = new Location(w, a, y1, z1);
        final BlockState b = l.getBlock().getState();
        if (b instanceof Sign) {
          signs.add((Sign) b);
          LobbyManager.lobbychunks.add(b.getChunk());
          HungerGames.debug("usingx - " + b.getLocation().toString());
        } else {
          HungerGames.debug("Not a sign" + b.getType().toString());
          return false;
        }
      }
    } else {
      for (int a = Math.min(z1, z2); a <= Math.max(z1, z2); a++) {
        HungerGames.debug(a);
        final Location l = new Location(w, x1, y1, a);
        final BlockState b = l.getBlock().getState();
        if (b instanceof Sign) {
          signs.add((Sign) b);
          LobbyManager.lobbychunks.add(b.getChunk());
          HungerGames.debug("notx - " + b.getLocation().toString());
        } else {
          HungerGames.debug("Not a sign" + b.getType().toString());
          return false;
        }
      }
    }
    // HungerGames.debug("dir: " + dir);
    if (facing == BlockFace.NORTH || facing == BlockFace.EAST) {
      Collections.reverse(signs);
    }
    addMsg("HungerGames");
    addMsg("Minealot");
    addMsg("minealot.com");
    addMsg("Game id: " + gameid);
    update();
    return true;
  }
  /** Detect when pistons affect water or sensor components. PISTONS MAH BOI! */
  @EventHandler
  public void onBlockPistonExtend(BlockPistonExtendEvent event) {
    if (event.isCancelled()) return;

    // Get the block just at the end of the piston chain (that will be replaced when the chain is
    // pushed)
    Block endblock = event.getBlock().getRelative(event.getDirection(), event.getLength() + 1);
    BlockState b = endblock.getState();
    plugin.debugprint("Block at end of piston chain " + b.getType());
    if (plugin.isBlockStateAnUpdater(b)) {
      plugin.executeSensorsAroundBlock(b, true, event);
    }
  }
Esempio n. 7
0
  /**
   * Process the Hylian Luck ability.
   *
   * @param blockState The {@link BlockState} to check ability activation for
   * @return true if the ability was successful, false otherwise
   */
  public boolean processHylianLuck(BlockState blockState) {
    if (!SkillUtils.activationSuccessful(
        SecondaryAbility.HYLIAN_LUCK, getPlayer(), getSkillLevel(), activationChance)) {
      return false;
    }

    List<HylianTreasure> treasures;

    switch (blockState.getType()) {
      case DEAD_BUSH:
      case LONG_GRASS:
      case SAPLING:
        treasures = TreasureConfig.getInstance().hylianFromBushes;
        break;

      case RED_ROSE:
      case YELLOW_FLOWER:
        if (mcMMO.getPlaceStore().isTrue(blockState)) {
          mcMMO.getPlaceStore().setFalse(blockState);
          return false;
        }

        treasures = TreasureConfig.getInstance().hylianFromFlowers;
        break;

      case FLOWER_POT:
        treasures = TreasureConfig.getInstance().hylianFromPots;
        break;

      default:
        return false;
    }

    Player player = getPlayer();

    if (treasures.isEmpty()
        || !EventUtils.simulateBlockBreak(blockState.getBlock(), player, false)) {
      return false;
    }

    blockState.setType(Material.AIR);

    Misc.dropItem(
        blockState.getLocation(),
        treasures.get(Misc.getRandom().nextInt(treasures.size())).getDrop());
    player.sendMessage(LocaleLoader.getString("Herbalism.HylianLuck"));
    return true;
  }
  private int HolderStateToInventory(PrisonPearl pp, Inventory inv[]) {
    if (pp == null || inv == null) {
      return HolderStateToInventory_BADPARAM;
    }
    BlockState inherentViolence = pp.getHolderBlockState();
    //		if (Bukkit.getPluginManager().isPluginEnabled("EnderExpansion")){
    //			if (pp.getLocation().getBlock().getType() == Material.ENDER_CHEST){
    //				inv[0] = Enderplugin.getchestInventory(pp.getLocation());
    //				return HolderStateToInventory_SUCCESS;
    //			}
    //		}
    if (inherentViolence == null) {
      return HolderStateToInventory_NULLSTATE;
    }
    Material mat = inherentViolence.getType();

    switch (mat) {
      case FURNACE:
        inv[0] = ((Furnace) inherentViolence).getInventory();
        break;
      case DISPENSER:
        inv[0] = ((Dispenser) inherentViolence).getInventory();
        break;
      case BREWING_STAND:
        inv[0] = ((BrewingStand) inherentViolence).getInventory();
        break;
      case CHEST:
      case TRAPPED_CHEST:
        Chest c = ((Chest) inherentViolence);
        DoubleChestInventory dblInv = null;
        try {
          dblInv = (DoubleChestInventory) c.getInventory();
          inv[0] = dblInv.getLeftSide();
          inv[1] = dblInv.getRightSide();
        } catch (Exception e) {
          inv[0] = c.getInventory();
        }
        break;
      default:
        return HolderStateToInventory_BADCONTAINER;
    }
    if (inv[0] == null && inv[1] == null) {
      return HolderStateToInventory_NULLINV;
    }
    return HolderStateToInventory_SUCCESS;
  }
Esempio n. 9
0
  /**
   * Process the Green Thumb ability for plants.
   *
   * @param blockState The {@link BlockState} to check ability activation for
   * @param greenTerra boolean to determine if greenTerra is active or not
   */
  private void processGreenThumbPlants(BlockState blockState, boolean greenTerra) {
    Player player = getPlayer();
    PlayerInventory playerInventory = player.getInventory();
    ItemStack seed = null;

    switch (blockState.getType()) {
      case CARROT:
        seed = new ItemStack(Material.CARROT_ITEM);
        break;

      case CROPS:
        seed = new ItemStack(Material.SEEDS);
        break;

      case NETHER_WARTS:
        seed = new ItemStack(Material.NETHER_STALK);
        break;

      case POTATO:
        seed = new ItemStack(Material.POTATO_ITEM);
        break;

      default:
        break;
    }

    if (!playerInventory.containsAtLeast(seed, 1)) {
      return;
    }

    if (!greenTerra
        && !SkillUtils.activationSuccessful(
            SecondaryAbility.GREEN_THUMB_PLANT, getPlayer(), getSkillLevel(), activationChance)) {
      return;
    }

    if (!handleBlockState(blockState, greenTerra)) {
      return;
    }

    playerInventory.removeItem(seed);
    player.updateInventory(); // Needed until replacement available
    new HerbalismBlockUpdaterTask(blockState).runTaskLater(mcMMO.p, 0);
  }
Esempio n. 10
0
  /**
   * Check if a given block cannot be replaced
   *
   * @param blockState The {@link BlockState} of the block to check
   * @return true if the block cannot be replaced, false otherwise
   */
  public static boolean cannotBeReplaced(BlockState blockState) {
    switch (blockState.getType()) {
      case STEP:
      case TORCH:
      case REDSTONE_WIRE:
      case RAILS:
      case ACTIVATOR_RAIL:
      case DETECTOR_RAIL:
      case STONE_PLATE:
      case WOOD_PLATE:
      case REDSTONE_TORCH_ON:
      case REDSTONE_TORCH_OFF:
      case CAKE_BLOCK:
        return true;

      default:
        return false;
    }
  }
Esempio n. 11
0
  /**
   * Process the Green Terra ability.
   *
   * @param blockState The {@link BlockState} to check ability activation for
   * @return true if the ability was successful, false otherwise
   */
  public boolean processGreenTerra(BlockState blockState) {
    Player player = getPlayer();

    if (!Permissions.greenThumbBlock(player, blockState.getType())) {
      return false;
    }

    PlayerInventory playerInventory = player.getInventory();
    ItemStack seed = new ItemStack(Material.SEEDS);

    if (!playerInventory.containsAtLeast(seed, 1)) {
      player.sendMessage(LocaleLoader.getString("Herbalism.Ability.GTe.NeedMore"));
      return false;
    }

    playerInventory.removeItem(seed);
    player.updateInventory(); // Needed until replacement available

    return Herbalism.convertGreenTerraBlocks(blockState);
  }
 private int HolderStateToInventory(PrisonPearl pp, Inventory inv[]) {
   if (pp == null || inv == null) {
     return HolderStateToInventory_BADPARAM;
   }
   BlockState inherentViolence = pp.getHolderBlockState();
   if (inherentViolence == null) {
     return HolderStateToInventory_NULLSTATE;
   }
   Material mat = inherentViolence.getType();
   switch (mat) {
     case FURNACE:
       inv[0] = ((Furnace) inherentViolence).getInventory();
       break;
     case DISPENSER:
       inv[0] = ((Dispenser) inherentViolence).getInventory();
       break;
     case BREWING_STAND:
       inv[0] = ((BrewingStand) inherentViolence).getInventory();
       break;
     case CHEST:
     case LOCKED_CHEST:
     case TRAPPED_CHEST:
       Chest c = ((Chest) inherentViolence);
       DoubleChestInventory dblInv = null;
       try {
         dblInv = (DoubleChestInventory) c.getInventory();
         inv[0] = dblInv.getLeftSide();
         inv[1] = dblInv.getRightSide();
       } catch (Exception e) {
         inv[0] = c.getInventory();
       }
       break;
     default:
       return HolderStateToInventory_BADCONTAINER;
   }
   if (inv[0] == null && inv[1] == null) {
     return HolderStateToInventory_NULLINV;
   }
   return HolderStateToInventory_SUCCESS;
 }
 @Override
 public void run() {
   if (active) {
     if (!fInit) {
       fInit = true;
     }
     int lRadius = fRadius;
     int lDy = 0;
     switch (mode) {
       case Down:
         lDy = -1;
         break;
       case Up:
         lDy = 1;
         break;
     }
     Logger.getLogger("LandSlip").info("strength " + new Integer(fStrength));
     for (int dx = -lRadius; dx <= lRadius; dx++) {
       for (int dz = -lRadius; dz <= lRadius; dz++) {
         Block lBlock = world.getHighestBlockAt(x + dx, z + dz);
         lBlock = lBlock.getLocation().add(0, -1, 0).getBlock();
         BlockState lState = lBlock.getState();
         Location lTo = lBlock.getLocation().add(0, lDy, 0);
         plugin.setTypeAndData(lTo, lState.getType(), lState.getRawData(), true);
         // if (mode == Mode.Down) {
         plugin.setTypeAndData(lBlock.getLocation(), Material.AIR, (byte) 0, false);
         // }
       }
     }
     fRadius++;
     if (fRadius > radius) {
       fRadius = 0;
       fStrength++;
       if (fStrength >= strength) {
         Logger.getLogger("LandSlip").info("stopped");
         plugin.getServer().getScheduler().cancelTask(taskId);
       }
     }
   }
 }
Esempio n. 14
0
 /**
  * Create a new CreeperBlock of the right class. Factory method that should be used as a
  * constructor.
  *
  * @param blockState The block to be represented.
  * @return A new CreeperBlock of the right subclass.
  */
 public static CreeperBlock newBlock(BlockState blockState) {
   if (blockState instanceof InventoryHolder) return new CreeperChest(blockState);
   if (hasPhysics(blockState.getTypeId())) return new CreeperPhysicsBlock(blockState);
   switch (blockState.getType()) {
     case BED_BLOCK:
       return new CreeperBed(blockState);
     case RAILS:
     case POWERED_RAIL:
     case DETECTOR_RAIL:
       return new CreeperRail(blockState);
     case SKULL:
       if (PluginHandler.isPlayerHeadsActivated()) return new CreeperSkull(blockState);
       return new CreeperHead(blockState);
     case PISTON_BASE:
     case PISTON_STICKY_BASE:
     case PISTON_EXTENSION:
       return new CreeperPiston(blockState);
     case WOODEN_DOOR:
     case IRON_DOOR_BLOCK:
       return new CreeperDoor(blockState);
     case NOTE_BLOCK:
       return new CreeperNoteBlock((NoteBlock) blockState);
     case SIGN:
     case SIGN_POST:
       return new CreeperSign((Sign) blockState);
     case MOB_SPAWNER:
       return new CreeperMonsterSpawner((CreatureSpawner) blockState);
     case WOOD_PLATE:
     case STONE_PLATE:
       return new CreeperPlate(blockState);
     case GRASS:
       return new CreeperGrass(blockState);
     case TNT:
     case FIRE:
     case AIR:
       return null;
     default:
       return new CreeperBlock(blockState);
   }
 }
Esempio n. 15
0
 /**
  * @param mat
  * @return count of how many tile entities of type mat are on the island at last count. Counts are
  *     done when a player places a tile entity.
  */
 public int getTileEntityCount(Material material) {
   int result = 0;
   for (int x = getMinProtectedX() / 16;
       x <= (getMinProtectedX() + getProtectionSize() - 1) / 16;
       x++) {
     for (int z = getMinProtectedZ() / 16;
         z <= (getMinProtectedZ() + getProtectionSize() - 1) / 16;
         z++) {
       for (BlockState holder : world.getChunkAt(x, z).getTileEntities()) {
         // plugin.getLogger().info("DEBUG: tile entity: " + holder.getType());
         if (holder.getType() == material) {
           result++;
         } else if (material.equals(Material.REDSTONE_COMPARATOR_OFF)) {
           if (holder.getType().equals(Material.REDSTONE_COMPARATOR_ON)) {
             result++;
           }
         } else if (material.equals(Material.FURNACE)) {
           if (holder.getType().equals(Material.BURNING_FURNACE)) {
             result++;
           }
         } else if (material.toString().endsWith("BANNER")) {
           if (holder.getType().toString().endsWith("BANNER")) {
             result++;
           }
         } else if (material.equals(Material.WALL_SIGN) || material.equals(Material.SIGN_POST)) {
           if (holder.getType().equals(Material.WALL_SIGN)
               || holder.getType().equals(Material.SIGN_POST)) {
             result++;
           }
         }
       }
       for (Entity holder : world.getChunkAt(x, z).getEntities()) {
         // plugin.getLogger().info("DEBUG: entity: " + holder.getType());
         if (holder.getType().toString().equals(material.toString())) {
           result++;
         }
       }
     }
   }
   // Version 1.7.x counts differently to 1.8 (ugh)
   // In 1.7, the entity is present before it is cancelled and so gets counted.
   // Remove 1 from count if it is 1.7.x
   if (!plugin.isOnePointEight()) {
     result--;
   }
   return result;
 }
Esempio n. 16
0
  /**
   * Check if a given block can be replaced
   *
   * @param blockState The {@link BlockState} of the block to check
   * @return true if the block can be replaced, false otherwise
   */
  public static boolean canBeReplaced(BlockState blockState) {
    switch (blockState.getType()) {
      case AIR:
      case SAPLING:
      case WATER:
      case STATIONARY_WATER:
      case LAVA:
      case STATIONARY_LAVA:
      case YELLOW_FLOWER:
      case RED_ROSE:
      case BROWN_MUSHROOM:
      case RED_MUSHROOM:
      case FIRE:
      case CROPS:
      case SNOW:
      case SUGAR_CANE:
      case GRAVEL:
      case SAND:
        return true;

      default:
        return false;
    }
  }
Esempio n. 17
0
  private boolean handleBlockState(BlockState blockState, boolean greenTerra) {
    byte greenThumbStage = getGreenThumbStage();

    switch (blockState.getType()) {
      case CROPS:
        Crops crops = (Crops) blockState.getData();

        if (greenTerra) {
          crops.setState(CropState.MEDIUM);
        } else {
          switch (greenThumbStage) {
            case 4:
              crops.setState(CropState.SMALL);
              break;
            case 3:
              crops.setState(CropState.VERY_SMALL);
              break;
            case 2:
              crops.setState(CropState.GERMINATED);
              break;
            default:
              crops.setState(CropState.SEEDED);
              break;
          }
        }

        return true;

      case CARROT:
      case POTATO:
        if (greenTerra) {
          blockState.setRawData(CropState.MEDIUM.getData());
        } else {
          blockState.setRawData(greenThumbStage);
        }

        return true;

      case NETHER_WARTS:
        NetherWarts warts = (NetherWarts) blockState.getData();

        if (greenTerra || greenThumbStage > 2) {
          warts.setState(NetherWartsState.STAGE_TWO);
        } else if (greenThumbStage == 2) {
          warts.setState(NetherWartsState.STAGE_ONE);
        } else {
          warts.setState(NetherWartsState.SEEDED);
        }

        return true;

      case COCOA:
        CocoaPlant plant = (CocoaPlant) blockState.getData();

        if (greenTerra || getGreenThumbStage() > 1) {
          plant.setSize(CocoaPlantSize.MEDIUM);
        } else {
          plant.setSize(CocoaPlantSize.SMALL);
        }

        return true;

      default:
        return false;
    }
  }
Esempio n. 18
0
  public boolean placeItem(
      EntityHuman entityhuman,
      World world,
      BlockPosition blockposition,
      EnumDirection enumdirection,
      float f,
      float f1,
      float f2) {
    // CraftBukkit start - handle all block place event logic here
    int data = this.getData();
    int count = this.count;

    if (!(this.getItem() instanceof ItemBucket)) { // if not bucket
      world.captureBlockStates = true;
      // special case bonemeal
      if (this.getItem() instanceof ItemDye && this.getData() == 15) {
        Block block = world.getType(blockposition).getBlock();
        if (block == Blocks.SAPLING || block instanceof BlockMushroom) {
          world.captureTreeGeneration = true;
        }
      }
    }
    boolean flag =
        this.getItem()
            .interactWith(this, entityhuman, world, blockposition, enumdirection, f, f1, f2);
    int newData = this.getData();
    int newCount = this.count;
    this.count = count;
    this.setData(data);
    world.captureBlockStates = false;
    if (flag && world.captureTreeGeneration && world.capturedBlockStates.size() > 0) {
      world.captureTreeGeneration = false;
      Location location =
          new Location(
              world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ());
      TreeType treeType = BlockSapling.treeType;
      BlockSapling.treeType = null;
      List<BlockState> blocks = (List<BlockState>) world.capturedBlockStates.clone();
      world.capturedBlockStates.clear();
      StructureGrowEvent event = null;
      if (treeType != null) {
        event =
            new StructureGrowEvent(
                location, treeType, false, (Player) entityhuman.getBukkitEntity(), blocks);
        org.bukkit.Bukkit.getPluginManager().callEvent(event);
      }
      if (event == null || !event.isCancelled()) {
        // Change the stack to its new contents if it hasn't been tampered with.
        if (this.count == count && this.getData() == data) {
          this.setData(newData);
          this.count = newCount;
        }
        for (BlockState blockstate : blocks) {
          blockstate.update(true);
        }
      }

      return flag;
    }
    world.captureTreeGeneration = false;

    if (flag) {
      org.bukkit.event.block.BlockPlaceEvent placeEvent = null;
      List<BlockState> blocks = (List<BlockState>) world.capturedBlockStates.clone();
      world.capturedBlockStates.clear();
      if (blocks.size() > 1) {
        placeEvent =
            org.bukkit.craftbukkit.event.CraftEventFactory.callBlockMultiPlaceEvent(
                world,
                entityhuman,
                blocks,
                blockposition.getX(),
                blockposition.getY(),
                blockposition.getZ());
      } else if (blocks.size() == 1) {
        placeEvent =
            org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(
                world,
                entityhuman,
                blocks.get(0),
                blockposition.getX(),
                blockposition.getY(),
                blockposition.getZ());
      }

      if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) {
        flag = false; // cancel placement
        // revert back all captured blocks
        for (BlockState blockstate : blocks) {
          blockstate.update(true, false);
        }
      } else {
        // Change the stack to its new contents if it hasn't been tampered with.
        if (this.count == count && this.getData() == data) {
          this.setData(newData);
          this.count = newCount;
        }
        for (BlockState blockstate : blocks) {
          int x = blockstate.getX();
          int y = blockstate.getY();
          int z = blockstate.getZ();
          int updateFlag = ((CraftBlockState) blockstate).getFlag();
          org.bukkit.Material mat = blockstate.getType();
          Block oldBlock = CraftMagicNumbers.getBlock(mat);
          BlockPosition newblockposition = new BlockPosition(x, y, z);
          IBlockData block = world.getType(newblockposition);

          if (!(block instanceof BlockContainer)) { // Containers get placed automatically
            block.getBlock().onPlace(world, newblockposition, block);
          }

          world.notifyAndUpdatePhysics(
              newblockposition,
              null,
              oldBlock,
              block.getBlock(),
              updateFlag); // send null chunk as chunk.k() returns false by this point
        }
        entityhuman.b(StatisticList.USE_ITEM_COUNT[Item.getId(this.item)]);
      }
    }
    world.capturedBlockStates.clear();
    // CraftBukkit end

    return flag;
  }
Esempio n. 19
0
  /** @param blockState The {@link BlockState} to check ability activation for */
  public void herbalismBlockCheck(BlockState blockState) {
    Player player = getPlayer();
    Material material = blockState.getType();
    boolean oneBlockPlant = !(material == Material.CACTUS || material == Material.SUGAR_CANE_BLOCK);

    if (oneBlockPlant && mcMMO.getPlaceStore().isTrue(blockState)) {
      return;
    }

    if (!canBlockCheck()) {
      return;
    }

    Collection<ItemStack> drops = null;
    int amount = 1;
    int xp;
    boolean greenTerra = mcMMOPlayer.getAbilityMode(skill.getAbility());

    if (mcMMO.getModManager().isCustomHerbalismBlock(blockState)) {
      CustomBlock customBlock = mcMMO.getModManager().getBlock(blockState);
      xp = customBlock.getXpGain();

      if (Permissions.secondaryAbilityEnabled(player, SecondaryAbility.HERBALISM_DOUBLE_DROPS)
          && customBlock.isDoubleDropEnabled()) {
        drops = blockState.getBlock().getDrops();
      }
    } else {
      if (Permissions.greenThumbPlant(player, material)) {
        processGreenThumbPlants(blockState, greenTerra);
      }

      xp = ExperienceConfig.getInstance().getXp(skill, material);

      if (Config.getInstance().getDoubleDropsEnabled(skill, material)
          && Permissions.secondaryAbilityEnabled(player, SecondaryAbility.HERBALISM_DOUBLE_DROPS)) {
        drops = blockState.getBlock().getDrops();
      }

      if (!oneBlockPlant) {
        amount = Herbalism.calculateCatciAndSugarDrops(blockState);
        xp *= amount;
      }
    }

    applyXpGain(xp);

    if (drops == null) {
      return;
    }

    for (int i = greenTerra ? 2 : 1; i != 0; i--) {
      if (SkillUtils.activationSuccessful(
          SecondaryAbility.HERBALISM_DOUBLE_DROPS,
          getPlayer(),
          getSkillLevel(),
          activationChance)) {
        for (ItemStack item : drops) {
          Misc.dropItems(blockState.getLocation(), item, amount);
        }
      }
    }
  }