mirror of
				https://github.com/mcMMO-Dev/mcMMO.git
				synced 2025-11-04 02:53:43 +01:00 
			
		
		
		
	More work on Woodcutting and Tree Feller
This commit is contained in:
		@@ -177,17 +177,18 @@ public class BlockListener implements Listener {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        /* WOOD CUTTING */
 | 
					        /* WOOD CUTTING */
 | 
				
			||||||
        else if (BlockChecks.isLog(block) && Permissions.woodcutting(player)) {
 | 
					        else if (BlockChecks.isLog(block) && Permissions.woodcutting(player)) {
 | 
				
			||||||
            if (configInstance.getWoodcuttingRequiresTool()) {
 | 
					            if (!mcMMO.placeStore.isTrue(block) && profile.getAbilityMode(AbilityType.TREE_FELLER) && Permissions.treeFeller(player) && ItemChecks.isAxe(inHand)) {
 | 
				
			||||||
                if (ItemChecks.isAxe(inHand)) {
 | 
					                Woodcutting.beginTreeFeller(event);
 | 
				
			||||||
                    Woodcutting.woodcuttingBlockCheck(player, block);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else {
 | 
					            else {
 | 
				
			||||||
                Woodcutting.woodcuttingBlockCheck(player, block);
 | 
					                if (configInstance.getWoodcuttingRequiresTool()) {
 | 
				
			||||||
            }
 | 
					                    if (ItemChecks.isAxe(inHand)) {
 | 
				
			||||||
 | 
					                        Woodcutting.beginWoodcutting(player, block);
 | 
				
			||||||
            if (!mcMMO.placeStore.isTrue(block) && profile.getAbilityMode(AbilityType.TREE_FELLER) && Permissions.treeFeller(player) && ItemChecks.isAxe(inHand)) {
 | 
					                    }
 | 
				
			||||||
                Woodcutting.treeFeller(event);
 | 
					                }
 | 
				
			||||||
 | 
					                else {
 | 
				
			||||||
 | 
					                    Woodcutting.beginWoodcutting(player, block);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -318,12 +319,12 @@ public class BlockListener implements Listener {
 | 
				
			|||||||
                if (configInstance.getWoodcuttingRequiresTool()) {
 | 
					                if (configInstance.getWoodcuttingRequiresTool()) {
 | 
				
			||||||
                    if (ItemChecks.isAxe(inHand)) {
 | 
					                    if (ItemChecks.isAxe(inHand)) {
 | 
				
			||||||
                        event.setInstaBreak(true);
 | 
					                        event.setInstaBreak(true);
 | 
				
			||||||
                        Woodcutting.leafBlower(player, block);
 | 
					                        Woodcutting.beginLeafBlower(player, block);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                else if (!inHand.getType().equals(Material.SHEARS)) {
 | 
					                else if (!inHand.getType().equals(Material.SHEARS)) {
 | 
				
			||||||
                    event.setInstaBreak(true);
 | 
					                    event.setInstaBreak(true);
 | 
				
			||||||
                    Woodcutting.leafBlower(player, block);
 | 
					                    Woodcutting.beginLeafBlower(player, block);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,235 @@
 | 
				
			|||||||
 | 
					package com.gmail.nossr50.skills.woodcutting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.bukkit.Location;
 | 
				
			||||||
 | 
					import org.bukkit.Material;
 | 
				
			||||||
 | 
					import org.bukkit.World;
 | 
				
			||||||
 | 
					import org.bukkit.block.Block;
 | 
				
			||||||
 | 
					import org.bukkit.block.BlockFace;
 | 
				
			||||||
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
 | 
					import org.bukkit.event.block.BlockBreakEvent;
 | 
				
			||||||
 | 
					import org.bukkit.inventory.ItemStack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.gmail.nossr50.mcMMO;
 | 
				
			||||||
 | 
					import com.gmail.nossr50.config.Config;
 | 
				
			||||||
 | 
					import com.gmail.nossr50.datatypes.mods.CustomBlock;
 | 
				
			||||||
 | 
					import com.gmail.nossr50.locale.LocaleLoader;
 | 
				
			||||||
 | 
					import com.gmail.nossr50.skills.Combat;
 | 
				
			||||||
 | 
					import com.gmail.nossr50.skills.SkillType;
 | 
				
			||||||
 | 
					import com.gmail.nossr50.skills.Skills;
 | 
				
			||||||
 | 
					import com.gmail.nossr50.util.BlockChecks;
 | 
				
			||||||
 | 
					import com.gmail.nossr50.util.Misc;
 | 
				
			||||||
 | 
					import com.gmail.nossr50.util.ModChecks;
 | 
				
			||||||
 | 
					import com.gmail.nossr50.util.Permissions;
 | 
				
			||||||
 | 
					import com.gmail.nossr50.util.Users;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public abstract class TreeFeller {
 | 
				
			||||||
 | 
					    private static boolean treeFellerReachedThreshold = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Handle the Tree Feller ability.
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param event Event to process
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public static void process(BlockBreakEvent event) {
 | 
				
			||||||
 | 
					        List<Block> treeFellerBlocks = new ArrayList<Block>();
 | 
				
			||||||
 | 
					        Player player = event.getPlayer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        processRecursively(event.getBlock(), treeFellerBlocks);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // If the player is trying to break to many block
 | 
				
			||||||
 | 
					        if (treeFellerReachedThreshold) {
 | 
				
			||||||
 | 
					            treeFellerReachedThreshold = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            player.sendMessage(LocaleLoader.getString("Woodcutting.Skills.TreeFellerThreshold"));
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // If the tool can't sustain the durability loss
 | 
				
			||||||
 | 
					        if (!handleDurabilityLoss(treeFellerBlocks, player)) {
 | 
				
			||||||
 | 
					            player.sendMessage(LocaleLoader.getString("Woodcutting.Skills.TreeFeller.Splinter"));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            int health = player.getHealth();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (health > 1) {
 | 
				
			||||||
 | 
					                Combat.dealDamage(player, Misc.getRandom().nextInt(health - 1));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        removeBlocks(treeFellerBlocks, player);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Process Tree Feller
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param block Point of origin of the layer
 | 
				
			||||||
 | 
					     * @param treeFellerBlocks List of blocks to be removed
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private static void processRecursively(Block block, List<Block> treeFellerBlocks) {
 | 
				
			||||||
 | 
					        List<Block> futureCenterBlocks = new ArrayList<Block>();
 | 
				
			||||||
 | 
					        boolean centerIsLog = (block.getType() == Material.LOG || (Config.getInstance().getBlockModsEnabled() && ModChecks.isCustomLogBlock(block)));
 | 
				
			||||||
 | 
					        Block nextBlock = block.getRelative(BlockFace.UP);;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Handle the block above 'block'
 | 
				
			||||||
 | 
					        if (addBlock(nextBlock, treeFellerBlocks)) {
 | 
				
			||||||
 | 
					            if (treeFellerReachedThreshold) {
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (centerIsLog) {
 | 
				
			||||||
 | 
					                futureCenterBlocks.add(nextBlock);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        World world = block.getWorld();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Handle the blocks around 'block'
 | 
				
			||||||
 | 
					        for (int x = -1 ; x <= 1 ; x++) {
 | 
				
			||||||
 | 
					            for (int z = -1 ; z <= 1 ; z++) {
 | 
				
			||||||
 | 
					                nextBlock = world.getBlockAt(block.getLocation().add(x, 0, z));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (addBlock(nextBlock, treeFellerBlocks)) {
 | 
				
			||||||
 | 
					                    if (treeFellerReachedThreshold) {
 | 
				
			||||||
 | 
					                        return;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (centerIsLog) {
 | 
				
			||||||
 | 
					                        futureCenterBlocks.add(nextBlock);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Recursive call for each log found
 | 
				
			||||||
 | 
					        for (Block futurCenterBlock : futureCenterBlocks) {
 | 
				
			||||||
 | 
					            if (treeFellerReachedThreshold) {
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            processRecursively(futurCenterBlock, treeFellerBlocks);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Add a block to the block list
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param block Block to be added
 | 
				
			||||||
 | 
					     * @param treeFellerBlocks List of blocks to be removed
 | 
				
			||||||
 | 
					     * @return True if block was added
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private static boolean addBlock(Block block, List<Block> treeFellerBlocks) {
 | 
				
			||||||
 | 
					        if (BlockChecks.treeFellerCompatible(block) && !treeFellerBlocks.contains(block) && !mcMMO.placeStore.isTrue(block)) {
 | 
				
			||||||
 | 
					            treeFellerBlocks.add(block);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (treeFellerBlocks.size() >= Config.getInstance().getTreeFellerThreshold()) {
 | 
				
			||||||
 | 
					                treeFellerReachedThreshold = true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Handle the durability loss
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param treeFellerBlocks List of blocks to be removed
 | 
				
			||||||
 | 
					     * @param Player Player using the ability
 | 
				
			||||||
 | 
					     * @return True if the tool can sustain the durability loss
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private static boolean handleDurabilityLoss(List<Block> treeFellerBlocks, Player player) {
 | 
				
			||||||
 | 
					        ItemStack inHand = player.getItemInHand();
 | 
				
			||||||
 | 
					        Material inHandMaterial = inHand.getType();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (inHandMaterial != Material.AIR) {
 | 
				
			||||||
 | 
					            boolean blockModsEnabled = Config.getInstance().getBlockModsEnabled();
 | 
				
			||||||
 | 
					            short durabilityLoss = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for (Block block : treeFellerBlocks) {
 | 
				
			||||||
 | 
					                if (block.getType() == Material.LOG || (blockModsEnabled && ModChecks.isCustomLogBlock(block))) {
 | 
				
			||||||
 | 
					                    durabilityLoss += Misc.toolDurabilityLoss;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            short finalDurability = (short) (inHand.getDurability() + durabilityLoss);
 | 
				
			||||||
 | 
					            short maxDurability = ModChecks.isCustomTool(inHand) ? ModChecks.getToolFromItemStack(inHand).getDurability() : inHandMaterial.getMaxDurability();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (finalDurability >= maxDurability) {
 | 
				
			||||||
 | 
					                inHand.setDurability(maxDurability);
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					            inHand.setDurability(finalDurability);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Handles removing & dropping the blocks
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param treeFellerBlocks List of blocks to be removed
 | 
				
			||||||
 | 
					     * @param player Player using the ability
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    private static void removeBlocks(List<Block> treeFellerBlocks, Player player) {
 | 
				
			||||||
 | 
					        int xp = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (Block block : treeFellerBlocks) {
 | 
				
			||||||
 | 
					            if (!Misc.blockBreakSimulate(block, player, true)) {
 | 
				
			||||||
 | 
					                break; // TODO: Shouldn't we use continue instead?
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            switch (block.getType()) {
 | 
				
			||||||
 | 
					            case LOG:
 | 
				
			||||||
 | 
					                Woodcutting.checkDoubleDrop(player, block);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                byte extraData = block.getData();
 | 
				
			||||||
 | 
					                xp += Woodcutting.getExperienceFromLog(block);
 | 
				
			||||||
 | 
					                // TODO: Nerf XP from jungle trees, as it was done previously
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Misc.dropItem(block.getLocation(), new ItemStack(Material.LOG, 1, extraData));
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case LEAVES:
 | 
				
			||||||
 | 
					                Misc.randomDropItem(block.getLocation(), new ItemStack(Material.LOG, 1, (short) (block.getData() & 3)), 10);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                if (ModChecks.isCustomLogBlock(block)) {
 | 
				
			||||||
 | 
					                    Woodcutting.checkDoubleDrop(player, block);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    CustomBlock customBlock = ModChecks.getCustomBlock(block);
 | 
				
			||||||
 | 
					                    xp = customBlock.getXpGain();
 | 
				
			||||||
 | 
					                    int minimumDropAmount = customBlock.getMinimumDropAmount();
 | 
				
			||||||
 | 
					                    int maximumDropAmount = customBlock.getMaximumDropAmount();
 | 
				
			||||||
 | 
					                    Location location = block.getLocation();
 | 
				
			||||||
 | 
					                    ItemStack item = customBlock.getItemDrop();;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    Misc.dropItems(location, item, minimumDropAmount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (minimumDropAmount < maximumDropAmount) {
 | 
				
			||||||
 | 
					                        Misc.randomDropItems(location, item, 50, maximumDropAmount - minimumDropAmount);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else if (ModChecks.isCustomLeafBlock(block)) {
 | 
				
			||||||
 | 
					                    CustomBlock customBlock = ModChecks.getCustomBlock(block);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    Misc.randomDropItem(block.getLocation(), customBlock.getItemDrop(), 10);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            block.setData((byte) 0);
 | 
				
			||||||
 | 
					            block.setType(Material.AIR);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Do we really have to check the permission here?
 | 
				
			||||||
 | 
					        if (Permissions.woodcutting(player)) {
 | 
				
			||||||
 | 
					            Skills.xpProcessing(player, Users.getProfile(player), SkillType.WOODCUTTING, xp);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,19 +1,12 @@
 | 
				
			|||||||
package com.gmail.nossr50.skills.woodcutting;
 | 
					package com.gmail.nossr50.skills.woodcutting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.ArrayList;
 | 
					 | 
				
			||||||
import java.util.List;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import org.bukkit.Location;
 | 
					import org.bukkit.Location;
 | 
				
			||||||
import org.bukkit.Material;
 | 
					import org.bukkit.Material;
 | 
				
			||||||
import org.bukkit.TreeSpecies;
 | 
					import org.bukkit.TreeSpecies;
 | 
				
			||||||
import org.bukkit.World;
 | 
					 | 
				
			||||||
import org.bukkit.block.Block;
 | 
					import org.bukkit.block.Block;
 | 
				
			||||||
import org.bukkit.block.BlockFace;
 | 
					 | 
				
			||||||
import org.bukkit.entity.Player;
 | 
					import org.bukkit.entity.Player;
 | 
				
			||||||
import org.bukkit.event.block.BlockBreakEvent;
 | 
					import org.bukkit.event.block.BlockBreakEvent;
 | 
				
			||||||
import org.bukkit.inventory.ItemStack;
 | 
					import org.bukkit.inventory.ItemStack;
 | 
				
			||||||
import org.bukkit.material.MaterialData;
 | 
					 | 
				
			||||||
import org.bukkit.material.Tree;
 | 
					 | 
				
			||||||
import org.getspout.spoutapi.sound.SoundEffect;
 | 
					import org.getspout.spoutapi.sound.SoundEffect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.gmail.nossr50.mcMMO;
 | 
					import com.gmail.nossr50.mcMMO;
 | 
				
			||||||
@@ -21,374 +14,36 @@ import com.gmail.nossr50.config.AdvancedConfig;
 | 
				
			|||||||
import com.gmail.nossr50.config.Config;
 | 
					import com.gmail.nossr50.config.Config;
 | 
				
			||||||
import com.gmail.nossr50.datatypes.mods.CustomBlock;
 | 
					import com.gmail.nossr50.datatypes.mods.CustomBlock;
 | 
				
			||||||
import com.gmail.nossr50.events.fake.FakePlayerAnimationEvent;
 | 
					import com.gmail.nossr50.events.fake.FakePlayerAnimationEvent;
 | 
				
			||||||
import com.gmail.nossr50.locale.LocaleLoader;
 | 
					 | 
				
			||||||
import com.gmail.nossr50.skills.Combat;
 | 
					 | 
				
			||||||
import com.gmail.nossr50.skills.SkillType;
 | 
					import com.gmail.nossr50.skills.SkillType;
 | 
				
			||||||
import com.gmail.nossr50.skills.Skills;
 | 
					import com.gmail.nossr50.skills.Skills;
 | 
				
			||||||
import com.gmail.nossr50.spout.SpoutSounds;
 | 
					import com.gmail.nossr50.spout.SpoutSounds;
 | 
				
			||||||
import com.gmail.nossr50.util.BlockChecks;
 | 
					 | 
				
			||||||
import com.gmail.nossr50.util.Misc;
 | 
					import com.gmail.nossr50.util.Misc;
 | 
				
			||||||
import com.gmail.nossr50.util.ModChecks;
 | 
					import com.gmail.nossr50.util.ModChecks;
 | 
				
			||||||
import com.gmail.nossr50.util.Permissions;
 | 
					import com.gmail.nossr50.util.Permissions;
 | 
				
			||||||
import com.gmail.nossr50.util.Users;
 | 
					import com.gmail.nossr50.util.Users;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class Woodcutting {
 | 
					public class Woodcutting {
 | 
				
			||||||
    private static final AdvancedConfig ADVANCED_CONFIG = AdvancedConfig.getInstance();
 | 
					    public static final int DOUBLE_DROP_MAX_LEVEL = AdvancedConfig.getInstance().getMiningDoubleDropMaxLevel();
 | 
				
			||||||
    private static boolean treeFellerReachedThreshold = false;
 | 
					    public static final double DOUBLE_DROP_CHANCE = AdvancedConfig.getInstance().getMiningDoubleDropChance();
 | 
				
			||||||
 | 
					    public static final int LEAF_BLOWER_UNLOCK_LEVEL = AdvancedConfig.getInstance().getLeafBlowUnlockLevel();
 | 
				
			||||||
    public static int doubleDropsMaxLevel = ADVANCED_CONFIG.getMiningDoubleDropMaxLevel();
 | 
					    public static final boolean DOUBLE_DROP_DISABLED = Config.getInstance().woodcuttingDoubleDropsDisabled();
 | 
				
			||||||
    public static double doubleDropsMaxChance = ADVANCED_CONFIG.getMiningDoubleDropChance();
 | 
					 | 
				
			||||||
    public static boolean doubleDropsDisabled = Config.getInstance().woodcuttingDoubleDropsDisabled();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public static int leafBlowerUnlockLevel = ADVANCED_CONFIG.getLeafBlowUnlockLevel();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Handle the Tree Feller ability.
 | 
					     * Begin Tree Feller ability
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param event Event to process
 | 
					     * @param event Event to process
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static void treeFeller(BlockBreakEvent event) {
 | 
					    public static void beginTreeFeller(BlockBreakEvent event) {
 | 
				
			||||||
        List<Block> toBeFelled = processTreeFeller(event);
 | 
					        TreeFeller.process(event);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (toBeFelled != null && !toBeFelled.isEmpty()) {
 | 
					 | 
				
			||||||
            removeBlocks(toBeFelled, event.getPlayer());
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Handles removing & dropping the blocks from Tree Feller.
 | 
					     * Begin Leaf Blower ability.
 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param toBeFelled List of blocks to be removed
 | 
					 | 
				
			||||||
     * @param player Player using the ability
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private static void removeBlocks(List<Block> toBeFelled, Player player) {
 | 
					 | 
				
			||||||
        ItemStack inHand = player.getItemInHand();
 | 
					 | 
				
			||||||
        Material inHandMaterial = inHand.getType();
 | 
					 | 
				
			||||||
        short finalDurability = (short) (inHand.getDurability() + calulateDurabilityLossFromTreeFeller(toBeFelled));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Prevent the tree to be cut down if the tool doesn't have enough durability
 | 
					 | 
				
			||||||
        if (inHandMaterial != Material.AIR) {
 | 
					 | 
				
			||||||
            short maxDurability = ModChecks.isCustomTool(inHand) ? ModChecks.getToolFromItemStack(inHand).getDurability() : inHandMaterial.getMaxDurability();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (finalDurability >= maxDurability) {
 | 
					 | 
				
			||||||
                player.sendMessage(LocaleLoader.getString("Woodcutting.Skills.TreeFeller.Splinter"));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                int health = player.getHealth();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (health >= 2) {
 | 
					 | 
				
			||||||
                    Combat.dealDamage(player, Misc.getRandom().nextInt(health - 1)); // Why not base the damage on the number of elements in toBeFelled?
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                inHand.setDurability(maxDurability);
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        inHand.setDurability(finalDurability);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        int xp = 0;
 | 
					 | 
				
			||||||
        ItemStack item = null;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for (Block block : toBeFelled) {
 | 
					 | 
				
			||||||
            if (!Misc.blockBreakSimulate(block, player, true)) {
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (block.getType() == Material.LOG) {
 | 
					 | 
				
			||||||
                Woodcutting.woodCuttingProcCheck(player, block);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                TreeSpecies species = ((Tree) block.getState().getData()).getSpecies();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                switch (species) {
 | 
					 | 
				
			||||||
                case GENERIC:
 | 
					 | 
				
			||||||
                    item = new MaterialData(Material.LOG, TreeSpecies.GENERIC.getData()).toItemStack(1);
 | 
					 | 
				
			||||||
                    xp += Config.getInstance().getWoodcuttingXPOak();
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                case REDWOOD:
 | 
					 | 
				
			||||||
                    item = new MaterialData(Material.LOG, TreeSpecies.REDWOOD.getData()).toItemStack(1);
 | 
					 | 
				
			||||||
                    xp += Config.getInstance().getWoodcuttingXPSpruce();
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                case BIRCH:
 | 
					 | 
				
			||||||
                    item = new MaterialData(Material.LOG, TreeSpecies.BIRCH.getData()).toItemStack(1);
 | 
					 | 
				
			||||||
                    xp += Config.getInstance().getWoodcuttingXPBirch();
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                case JUNGLE:
 | 
					 | 
				
			||||||
                    item = new MaterialData(Material.LOG, TreeSpecies.JUNGLE.getData()).toItemStack(1);
 | 
					 | 
				
			||||||
                    xp += Config.getInstance().getWoodcuttingXPJungle() / 2; // Nerf XP from Jungle Trees when using Tree Feller
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                default:
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                Misc.dropItem(block.getLocation(), item);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else if (block.getType() == Material.LEAVES) {
 | 
					 | 
				
			||||||
                item = new MaterialData(Material.SAPLING, (byte) (block.getData() & 3)).toItemStack(1); 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                Misc.randomDropItem(block.getLocation(), item, 10);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else if (Config.getInstance().getBlockModsEnabled()) {
 | 
					 | 
				
			||||||
                if (ModChecks.isCustomLogBlock(block)) {
 | 
					 | 
				
			||||||
                    CustomBlock customBlock = ModChecks.getCustomBlock(block);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    Woodcutting.woodCuttingProcCheck(player, block);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    xp = customBlock.getXpGain();
 | 
					 | 
				
			||||||
                    int minimumDropAmount = customBlock.getMinimumDropAmount();
 | 
					 | 
				
			||||||
                    int maximumDropAmount = customBlock.getMaximumDropAmount();
 | 
					 | 
				
			||||||
                    Location location = block.getLocation();
 | 
					 | 
				
			||||||
                    item = customBlock.getItemDrop();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    Misc.dropItems(location, item, minimumDropAmount);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if (minimumDropAmount < maximumDropAmount) {
 | 
					 | 
				
			||||||
                        Misc.randomDropItems(location, item, 50, maximumDropAmount - minimumDropAmount);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else if (ModChecks.isCustomLeafBlock(block)) {
 | 
					 | 
				
			||||||
                    CustomBlock customBlock = ModChecks.getCustomBlock(block);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    Misc.randomDropItem(block.getLocation(), customBlock.getItemDrop(), 10);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            block.setData((byte) 0);
 | 
					 | 
				
			||||||
            block.setType(Material.AIR);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (Permissions.woodcutting(player)) {
 | 
					 | 
				
			||||||
            Skills.xpProcessing(player, Users.getProfile(player), SkillType.WOODCUTTING, xp);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Process Tree Feller around a block.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param block Point of origin of the layer
 | 
					 | 
				
			||||||
     * @param toBeFelled List of blocks to be removed
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private static void processTreeFellerAroundBlock(Block block, List<Block> toBeFelled) {
 | 
					 | 
				
			||||||
        // TODO: too much duplicate code here
 | 
					 | 
				
			||||||
        List<Block> futureCenterBlocks = new ArrayList<Block>();
 | 
					 | 
				
			||||||
        boolean centerIsLog = (block.getType() == Material.LOG); //TODO: custom blocks?
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        // Handle the block above 'block'
 | 
					 | 
				
			||||||
        Block nextBlock = block.getRelative(BlockFace.UP);;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (BlockChecks.treeFellerCompatible(nextBlock) && !toBeFelled.contains(nextBlock) && !mcMMO.placeStore.isTrue(nextBlock)) {
 | 
					 | 
				
			||||||
            toBeFelled.add(nextBlock);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (centerIsLog) {
 | 
					 | 
				
			||||||
                futureCenterBlocks.add(nextBlock);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (toBeFelled.size() >= Config.getInstance().getTreeFellerThreshold()) {
 | 
					 | 
				
			||||||
                treeFellerReachedThreshold = true;
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        World world = block.getWorld();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Handle the blocks around 'block'
 | 
					 | 
				
			||||||
        for (int x = -1 ; x <= 1 ; x++) {
 | 
					 | 
				
			||||||
            for (int z = -1 ; z <= 1 ; z++) {
 | 
					 | 
				
			||||||
                nextBlock = world.getBlockAt(block.getLocation().add(x, 0, z));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (BlockChecks.treeFellerCompatible(nextBlock) && !toBeFelled.contains(nextBlock) && !mcMMO.placeStore.isTrue(nextBlock)) {
 | 
					 | 
				
			||||||
                    toBeFelled.add(nextBlock);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if (centerIsLog) {
 | 
					 | 
				
			||||||
                        futureCenterBlocks.add(nextBlock);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if (toBeFelled.size() >= Config.getInstance().getTreeFellerThreshold()) {
 | 
					 | 
				
			||||||
                        treeFellerReachedThreshold = true;
 | 
					 | 
				
			||||||
                        return;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Recursive call for each log found
 | 
					 | 
				
			||||||
        for (Block futurCenterBlock : futureCenterBlocks) {
 | 
					 | 
				
			||||||
            if (treeFellerReachedThreshold) {
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            processTreeFellerAroundBlock(futurCenterBlock, toBeFelled);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Process Tree Feller.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param event Event to process
 | 
					 | 
				
			||||||
     * @return List of blocks to be removed
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private static List<Block> processTreeFeller(BlockBreakEvent event) {
 | 
					 | 
				
			||||||
        List<Block> toBeFelled = new ArrayList<Block>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        processTreeFellerAroundBlock(event.getBlock(), toBeFelled);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (treeFellerReachedThreshold) {
 | 
					 | 
				
			||||||
            treeFellerReachedThreshold = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            event.getPlayer().sendMessage(LocaleLoader.getString("Woodcutting.Skills.TreeFellerThreshold"));
 | 
					 | 
				
			||||||
            return null;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return toBeFelled;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Check for double drops.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param player Player breaking the block
 | 
					 | 
				
			||||||
     * @param block Block being broken
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    private static void woodCuttingProcCheck(Player player, Block block) {
 | 
					 | 
				
			||||||
        final double MAX_CHANCE = ADVANCED_CONFIG.getWoodcuttingDoubleDropChance();
 | 
					 | 
				
			||||||
        final int MAX_BONUS_LEVEL = ADVANCED_CONFIG.getWoodcuttingDoubleDropMaxLevel();
 | 
					 | 
				
			||||||
        byte type = block.getData();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if ((type & 0x4) == 0x4)
 | 
					 | 
				
			||||||
            type ^= 0x4;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if ((type & 0x8) == 0x8)
 | 
					 | 
				
			||||||
            type ^= 0x8;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Material blockMaterial = block.getType();
 | 
					 | 
				
			||||||
        int chance = (int) ((MAX_CHANCE / MAX_BONUS_LEVEL) * Users.getProfile(player).getSkillLevel(SkillType.WOODCUTTING));
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        if (chance > MAX_CHANCE) {
 | 
					 | 
				
			||||||
            chance = (int) MAX_CHANCE;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        int activationChance = Misc.calculateActivationChance(Permissions.luckyWoodcutting(player));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (chance > Misc.getRandom().nextInt(activationChance) && Permissions.woodcuttingDoubleDrops(player)) {
 | 
					 | 
				
			||||||
            Config configInstance = Config.getInstance();
 | 
					 | 
				
			||||||
            ItemStack item = null;
 | 
					 | 
				
			||||||
            Location location = null;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (configInstance.getBlockModsEnabled() && ModChecks.isCustomLogBlock(block)) {
 | 
					 | 
				
			||||||
                CustomBlock customBlock = ModChecks.getCustomBlock(block);
 | 
					 | 
				
			||||||
                int minimumDropAmount = customBlock.getMinimumDropAmount();
 | 
					 | 
				
			||||||
                int maximumDropAmount = customBlock.getMaximumDropAmount();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                item = customBlock.getItemDrop();
 | 
					 | 
				
			||||||
                location = block.getLocation();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (minimumDropAmount != maximumDropAmount) {
 | 
					 | 
				
			||||||
                    Misc.dropItems(location, item, minimumDropAmount);
 | 
					 | 
				
			||||||
                    Misc.randomDropItems(location, item, 50, maximumDropAmount - minimumDropAmount);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                else {
 | 
					 | 
				
			||||||
                    Misc.dropItems(location, item, minimumDropAmount);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else {
 | 
					 | 
				
			||||||
                item = (new MaterialData(blockMaterial, type)).toItemStack(1);
 | 
					 | 
				
			||||||
                location = block.getLocation();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                switch (TreeSpecies.getByData(type)) {
 | 
					 | 
				
			||||||
                case GENERIC:
 | 
					 | 
				
			||||||
                    if (configInstance.getOakDoubleDropsEnabled()) {
 | 
					 | 
				
			||||||
                        Misc.dropItem(location, item);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                case REDWOOD:
 | 
					 | 
				
			||||||
                    if (configInstance.getSpruceDoubleDropsEnabled()) {
 | 
					 | 
				
			||||||
                        Misc.dropItem(location, item);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                case BIRCH:
 | 
					 | 
				
			||||||
                    if (configInstance.getBirchDoubleDropsEnabled()) {
 | 
					 | 
				
			||||||
                        Misc.dropItem(location, item);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                case JUNGLE:
 | 
					 | 
				
			||||||
                    if (configInstance.getJungleDoubleDropsEnabled()) {
 | 
					 | 
				
			||||||
                        Misc.dropItem(location, item);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                default:
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Check XP gain for woodcutting.
 | 
					 | 
				
			||||||
     *
 | 
					 | 
				
			||||||
     * @param player Player breaking the block
 | 
					 | 
				
			||||||
     * @param block Block being broken
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    public static void woodcuttingBlockCheck(Player player, Block block) {
 | 
					 | 
				
			||||||
        if (mcMMO.placeStore.isTrue(block)) {
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        int xp = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (Config.getInstance().getBlockModsEnabled() && ModChecks.isCustomLogBlock(block)) {
 | 
					 | 
				
			||||||
            xp = ModChecks.getCustomBlock(block).getXpGain();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else {
 | 
					 | 
				
			||||||
            byte type = block.getData();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if ((type & 0x4) == 0x4)
 | 
					 | 
				
			||||||
                type ^= 0x4;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if ((type & 0x8) == 0x8)
 | 
					 | 
				
			||||||
                type ^= 0x8;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            TreeSpecies species = TreeSpecies.getByData(type);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Apparently species can be null in certain cases (custom server mods?)
 | 
					 | 
				
			||||||
            // https://github.com/mcMMO-Dev/mcMMO/issues/229
 | 
					 | 
				
			||||||
            if (species == null)
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            switch (species) {
 | 
					 | 
				
			||||||
            case GENERIC:
 | 
					 | 
				
			||||||
                xp += Config.getInstance().getWoodcuttingXPOak();
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            case REDWOOD:
 | 
					 | 
				
			||||||
                xp += Config.getInstance().getWoodcuttingXPSpruce();
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            case BIRCH:
 | 
					 | 
				
			||||||
                xp += Config.getInstance().getWoodcuttingXPBirch();
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            case JUNGLE:
 | 
					 | 
				
			||||||
                xp += Config.getInstance().getWoodcuttingXPJungle();
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            default:
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Woodcutting.woodCuttingProcCheck(player, block);
 | 
					 | 
				
			||||||
        Skills.xpProcessing(player,  Users.getProfile(player), SkillType.WOODCUTTING, xp);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * Handle the Leaf Blower ability.
 | 
					 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param player Player using the ability
 | 
					     * @param player Player using the ability
 | 
				
			||||||
     * @param block Block being broken
 | 
					     * @param block Block being broken
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public static void leafBlower(Player player, Block block) {
 | 
					    public static void beginLeafBlower(Player player, Block block) {
 | 
				
			||||||
        mcMMO.p.getServer().getPluginManager().callEvent(new FakePlayerAnimationEvent(player));
 | 
					        mcMMO.p.getServer().getPluginManager().callEvent(new FakePlayerAnimationEvent(player));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (mcMMO.spoutEnabled) {
 | 
					        if (mcMMO.spoutEnabled) {
 | 
				
			||||||
@@ -397,21 +52,124 @@ public class Woodcutting {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Calculate the durability loss from Tree Feller
 | 
					     * Begin Woodcutting process
 | 
				
			||||||
     *
 | 
					     *
 | 
				
			||||||
     * @param List<Block> Blocks to be felled
 | 
					     * @param player Player breaking the block
 | 
				
			||||||
     * @return Durability loss
 | 
					     * @param block Block being broken
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    private static short calulateDurabilityLossFromTreeFeller(List<Block> toBeFelled) {
 | 
					    public static void beginWoodcutting(Player player, Block block) {
 | 
				
			||||||
        short durabilityLoss = 0;
 | 
					        int xp = 0;
 | 
				
			||||||
        boolean blockModsEnabled = Config.getInstance().getBlockModsEnabled();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for (Block block : toBeFelled) {
 | 
					        if (Config.getInstance().getBlockModsEnabled() && ModChecks.isCustomLogBlock(block)) {
 | 
				
			||||||
            if (block.getType() == Material.LOG || (blockModsEnabled && ModChecks.isCustomLogBlock(block))) {
 | 
					            xp = ModChecks.getCustomBlock(block).getXpGain();
 | 
				
			||||||
                durabilityLoss += Misc.toolDurabilityLoss;
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                xp = getExperienceFromLog(block);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            catch (IllegalArgumentException exception) {
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return durabilityLoss;
 | 
					        checkDoubleDrop(player, block);
 | 
				
			||||||
 | 
					        Skills.xpProcessing(player,  Users.getProfile(player), SkillType.WOODCUTTING, xp);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Retrieve the experience from a log
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param log Log being broken
 | 
				
			||||||
 | 
					     * @return Amount of experience
 | 
				
			||||||
 | 
					     * @throws IllegalArgumentException if 'log' is invalid
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected static int getExperienceFromLog(Block log) {
 | 
				
			||||||
 | 
					        TreeSpecies logType = TreeSpecies.getByData(log.getData());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Apparently species can be null in certain cases (custom server mods?)
 | 
				
			||||||
 | 
					        // https://github.com/mcMMO-Dev/mcMMO/issues/229
 | 
				
			||||||
 | 
					        if (logType == null) {
 | 
				
			||||||
 | 
					            throw new IllegalArgumentException();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch (logType) {
 | 
				
			||||||
 | 
					        case GENERIC:
 | 
				
			||||||
 | 
					            return Config.getInstance().getWoodcuttingXPOak();
 | 
				
			||||||
 | 
					        case REDWOOD:
 | 
				
			||||||
 | 
					            return Config.getInstance().getWoodcuttingXPSpruce();
 | 
				
			||||||
 | 
					        case BIRCH:
 | 
				
			||||||
 | 
					            return Config.getInstance().getWoodcuttingXPBirch();
 | 
				
			||||||
 | 
					        case JUNGLE:
 | 
				
			||||||
 | 
					            return Config.getInstance().getWoodcuttingXPJungle();
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            throw new IllegalArgumentException();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Check for double drops
 | 
				
			||||||
 | 
					     *
 | 
				
			||||||
 | 
					     * @param player Player breaking the block
 | 
				
			||||||
 | 
					     * @param block Block being broken
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    protected static void checkDoubleDrop(Player player, Block block) {
 | 
				
			||||||
 | 
					        if (!Permissions.woodcuttingDoubleDrops(player)) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int chance = (int) ((DOUBLE_DROP_CHANCE / DOUBLE_DROP_MAX_LEVEL) * Users.getProfile(player).getSkillLevel(SkillType.WOODCUTTING));
 | 
				
			||||||
 | 
					        int activationChance = Misc.calculateActivationChance(Permissions.luckyWoodcutting(player));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (chance > DOUBLE_DROP_CHANCE) {
 | 
				
			||||||
 | 
					            chance = (int) DOUBLE_DROP_CHANCE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (chance <= Misc.getRandom().nextInt(activationChance)) {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (Config.getInstance().getBlockModsEnabled() && ModChecks.isCustomLogBlock(block)) {
 | 
				
			||||||
 | 
					            CustomBlock customBlock = ModChecks.getCustomBlock(block);
 | 
				
			||||||
 | 
					            int minimumDropAmount = customBlock.getMinimumDropAmount();
 | 
				
			||||||
 | 
					            int maximumDropAmount = customBlock.getMaximumDropAmount();
 | 
				
			||||||
 | 
					            Location location = block.getLocation();
 | 
				
			||||||
 | 
					            ItemStack item = customBlock.getItemDrop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Misc.dropItems(location, item, minimumDropAmount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (minimumDropAmount != maximumDropAmount) {
 | 
				
			||||||
 | 
					                Misc.randomDropItems(location, item, 50, maximumDropAmount - minimumDropAmount);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            byte extraData = block.getData();
 | 
				
			||||||
 | 
					            Location location = block.getLocation();
 | 
				
			||||||
 | 
					            ItemStack item = new ItemStack(Material.LOG, 1, extraData);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            switch (TreeSpecies.getByData(extraData)) {
 | 
				
			||||||
 | 
					            case GENERIC:
 | 
				
			||||||
 | 
					                if (Config.getInstance().getOakDoubleDropsEnabled()) {
 | 
				
			||||||
 | 
					                    Misc.dropItem(location, item);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case REDWOOD:
 | 
				
			||||||
 | 
					                if (Config.getInstance().getSpruceDoubleDropsEnabled()) {
 | 
				
			||||||
 | 
					                    Misc.dropItem(location, item);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case BIRCH:
 | 
				
			||||||
 | 
					                if (Config.getInstance().getBirchDoubleDropsEnabled()) {
 | 
				
			||||||
 | 
					                    Misc.dropItem(location, item);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            case JUNGLE:
 | 
				
			||||||
 | 
					                if (Config.getInstance().getJungleDoubleDropsEnabled()) {
 | 
				
			||||||
 | 
					                    Misc.dropItem(location, item);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,11 @@
 | 
				
			|||||||
package com.gmail.nossr50.skills.woodcutting;
 | 
					package com.gmail.nossr50.skills.woodcutting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.gmail.nossr50.config.AdvancedConfig;
 | 
					 | 
				
			||||||
import com.gmail.nossr50.locale.LocaleLoader;
 | 
					import com.gmail.nossr50.locale.LocaleLoader;
 | 
				
			||||||
import com.gmail.nossr50.skills.SkillCommand;
 | 
					import com.gmail.nossr50.skills.SkillCommand;
 | 
				
			||||||
import com.gmail.nossr50.skills.SkillType;
 | 
					import com.gmail.nossr50.skills.SkillType;
 | 
				
			||||||
import com.gmail.nossr50.util.Permissions;
 | 
					import com.gmail.nossr50.util.Permissions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class WoodcuttingCommand extends SkillCommand {
 | 
					public class WoodcuttingCommand extends SkillCommand {
 | 
				
			||||||
    AdvancedConfig advancedConfig = AdvancedConfig.getInstance();
 | 
					 | 
				
			||||||
    private String treeFellerLength;
 | 
					    private String treeFellerLength;
 | 
				
			||||||
    private String treeFellerLengthEndurance;
 | 
					    private String treeFellerLengthEndurance;
 | 
				
			||||||
    private String doubleDropChance;
 | 
					    private String doubleDropChance;
 | 
				
			||||||
@@ -16,7 +14,6 @@ public class WoodcuttingCommand extends SkillCommand {
 | 
				
			|||||||
    private boolean canTreeFell;
 | 
					    private boolean canTreeFell;
 | 
				
			||||||
    private boolean canLeafBlow;
 | 
					    private boolean canLeafBlow;
 | 
				
			||||||
    private boolean canDoubleDrop;
 | 
					    private boolean canDoubleDrop;
 | 
				
			||||||
    private boolean doubleDropsDisabled;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public WoodcuttingCommand() {
 | 
					    public WoodcuttingCommand() {
 | 
				
			||||||
        super(SkillType.WOODCUTTING);
 | 
					        super(SkillType.WOODCUTTING);
 | 
				
			||||||
@@ -30,7 +27,7 @@ public class WoodcuttingCommand extends SkillCommand {
 | 
				
			|||||||
        treeFellerLengthEndurance = treeFellerStrings[1];
 | 
					        treeFellerLengthEndurance = treeFellerStrings[1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //DOUBLE DROPS
 | 
					        //DOUBLE DROPS
 | 
				
			||||||
        String[] doubleDropStrings = calculateAbilityDisplayValues(Woodcutting.doubleDropsMaxLevel, Woodcutting.doubleDropsMaxChance);
 | 
					        String[] doubleDropStrings = calculateAbilityDisplayValues(Woodcutting.DOUBLE_DROP_MAX_LEVEL, Woodcutting.DOUBLE_DROP_CHANCE);
 | 
				
			||||||
        doubleDropChance = doubleDropStrings[0];
 | 
					        doubleDropChance = doubleDropStrings[0];
 | 
				
			||||||
        doubleDropChanceLucky = doubleDropStrings[1];
 | 
					        doubleDropChanceLucky = doubleDropStrings[1];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -40,12 +37,11 @@ public class WoodcuttingCommand extends SkillCommand {
 | 
				
			|||||||
        canTreeFell = Permissions.treeFeller(player);
 | 
					        canTreeFell = Permissions.treeFeller(player);
 | 
				
			||||||
        canDoubleDrop = Permissions.woodcuttingDoubleDrops(player);
 | 
					        canDoubleDrop = Permissions.woodcuttingDoubleDrops(player);
 | 
				
			||||||
        canLeafBlow = Permissions.leafBlower(player);
 | 
					        canLeafBlow = Permissions.leafBlower(player);
 | 
				
			||||||
        doubleDropsDisabled = Woodcutting.doubleDropsDisabled;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    protected boolean effectsHeaderPermissions() {
 | 
					    protected boolean effectsHeaderPermissions() {
 | 
				
			||||||
        return (canDoubleDrop && !doubleDropsDisabled) || canLeafBlow || canTreeFell;
 | 
					        return (canDoubleDrop && !Woodcutting.DOUBLE_DROP_DISABLED) || canLeafBlow || canTreeFell;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
@@ -60,28 +56,28 @@ public class WoodcuttingCommand extends SkillCommand {
 | 
				
			|||||||
            player.sendMessage(LocaleLoader.getString("Effects.Template", new Object[] { LocaleLoader.getString("Woodcutting.Effect.2"), LocaleLoader.getString("Woodcutting.Effect.3") }));
 | 
					            player.sendMessage(LocaleLoader.getString("Effects.Template", new Object[] { LocaleLoader.getString("Woodcutting.Effect.2"), LocaleLoader.getString("Woodcutting.Effect.3") }));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (canDoubleDrop && !doubleDropsDisabled) {
 | 
					        if (canDoubleDrop && !Woodcutting.DOUBLE_DROP_DISABLED) {
 | 
				
			||||||
            player.sendMessage(LocaleLoader.getString("Effects.Template", new Object[] { LocaleLoader.getString("Woodcutting.Effect.4"), LocaleLoader.getString("Woodcutting.Effect.5") }));
 | 
					            player.sendMessage(LocaleLoader.getString("Effects.Template", new Object[] { LocaleLoader.getString("Woodcutting.Effect.4"), LocaleLoader.getString("Woodcutting.Effect.5") }));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    protected boolean statsHeaderPermissions() {
 | 
					    protected boolean statsHeaderPermissions() {
 | 
				
			||||||
        return (canDoubleDrop && !doubleDropsDisabled) || canLeafBlow || canTreeFell;
 | 
					        return (canDoubleDrop && !Woodcutting.DOUBLE_DROP_DISABLED) || canLeafBlow || canTreeFell;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    protected void statsDisplay() {
 | 
					    protected void statsDisplay() {
 | 
				
			||||||
        if (canLeafBlow) {
 | 
					        if (canLeafBlow) {
 | 
				
			||||||
            if (skillValue < Woodcutting.leafBlowerUnlockLevel) {
 | 
					            if (skillValue < Woodcutting.LEAF_BLOWER_UNLOCK_LEVEL) {
 | 
				
			||||||
                player.sendMessage(LocaleLoader.getString("Ability.Generic.Template.Lock", new Object[] { LocaleLoader.getString("Woodcutting.Ability.Locked.0", new Object[] { Woodcutting.leafBlowerUnlockLevel }) }));
 | 
					                player.sendMessage(LocaleLoader.getString("Ability.Generic.Template.Lock", new Object[] { LocaleLoader.getString("Woodcutting.Ability.Locked.0", new Object[] { Woodcutting.LEAF_BLOWER_UNLOCK_LEVEL }) }));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else {
 | 
					            else {
 | 
				
			||||||
                player.sendMessage(LocaleLoader.getString("Ability.Generic.Template", new Object[] { LocaleLoader.getString("Woodcutting.Ability.0"), LocaleLoader.getString("Woodcutting.Ability.1") }));
 | 
					                player.sendMessage(LocaleLoader.getString("Ability.Generic.Template", new Object[] { LocaleLoader.getString("Woodcutting.Ability.0"), LocaleLoader.getString("Woodcutting.Ability.1") }));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (canDoubleDrop && !doubleDropsDisabled) {
 | 
					        if (canDoubleDrop && !Woodcutting.DOUBLE_DROP_DISABLED) {
 | 
				
			||||||
            if (isLucky) {
 | 
					            if (isLucky) {
 | 
				
			||||||
                player.sendMessage(LocaleLoader.getString("Woodcutting.Ability.Chance.DDrop", new Object[] { doubleDropChance }) + LocaleLoader.getString("Perks.lucky.bonus", new Object[] { doubleDropChanceLucky }));
 | 
					                player.sendMessage(LocaleLoader.getString("Woodcutting.Ability.Chance.DDrop", new Object[] { doubleDropChance }) + LocaleLoader.getString("Perks.lucky.bonus", new Object[] { doubleDropChanceLucky }));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user