diff --git a/src/main/java/com/gmail/nossr50/listeners/mcBlockListener.java b/src/main/java/com/gmail/nossr50/listeners/mcBlockListener.java index 2ea367e99..c52a965a2 100644 --- a/src/main/java/com/gmail/nossr50/listeners/mcBlockListener.java +++ b/src/main/java/com/gmail/nossr50/listeners/mcBlockListener.java @@ -176,7 +176,7 @@ public class mcBlockListener implements Listener { * EXCAVATION */ - if (Excavation.canBeGigaDrillBroken(mat) && mcPermissions.getInstance().excavation(player) && !block.hasMetadata("mcmmoPlacedBlock")) { + if (Excavation.canBeGigaDrillBroken(mat) && mcPermissions.getInstance().excavation(player) && block.hasMetadata("mcmmoPlacedBlock")) { if (LoadProperties.excavationRequiresShovel && ItemChecks.isShovel(inhand)) { Excavation.excavationProcCheck(block, player); } @@ -198,6 +198,8 @@ public class mcBlockListener implements Listener { */ @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onBlockDamage(BlockDamageEvent event) { + final int LEAF_BLOWER_LEVEL = 100; + Player player = event.getPlayer(); PlayerProfile PP = Users.getProfile(player); ItemStack inhand = player.getItemInHand(); @@ -268,15 +270,15 @@ public class mcBlockListener implements Listener { Mining.SuperBreakerBlockCheck(player, block); } } - else if (PP.getSkillLevel(SkillType.WOODCUTTING) >= 100 && mat.equals(Material.LEAVES)) { + else if (PP.getSkillLevel(SkillType.WOODCUTTING) >= LEAF_BLOWER_LEVEL && mat.equals(Material.LEAVES)) { if (LoadProperties.woodcuttingrequiresaxe && ItemChecks.isAxe(inhand)) { - if(Skills.triggerCheck(player, block, AbilityType.LEAF_BLOWER)) { + if (Skills.triggerCheck(player, block, AbilityType.LEAF_BLOWER)) { event.setInstaBreak(true); WoodCutting.leafBlower(player, block); } } else if (!LoadProperties.woodcuttingrequiresaxe && !inhand.getType().equals(Material.SHEARS)) { - if(Skills.triggerCheck(player, block, AbilityType.LEAF_BLOWER)) { + if (Skills.triggerCheck(player, block, AbilityType.LEAF_BLOWER)) { event.setInstaBreak(true); WoodCutting.leafBlower(player, block); } diff --git a/src/main/java/com/gmail/nossr50/skills/Mining.java b/src/main/java/com/gmail/nossr50/skills/Mining.java index 2c38afeb8..c96b66e73 100644 --- a/src/main/java/com/gmail/nossr50/skills/Mining.java +++ b/src/main/java/com/gmail/nossr50/skills/Mining.java @@ -35,7 +35,7 @@ public class Mining switch (type) { case COAL_ORE: - item = new ItemStack(Material.COAL, 1, (byte) 0x0, CoalType.COAL.getData()); + item = new ItemStack(Material.COAL, 1, (short) 0, CoalType.COAL.getData()); m.mcDropItem(loc, item); break; @@ -58,7 +58,7 @@ public class Mining break; case LAPIS_ORE: - item = new ItemStack(Material.INK_SACK, 1, (byte) 0x0, DyeColor.BLUE.getData()); + item = new ItemStack(Material.INK_SACK, 1, (short) 0, DyeColor.BLUE.getData()); m.mcDropItems(loc, item, 4); m.mcRandomDropItems(loc, item, 50, 4); break; diff --git a/src/main/java/com/gmail/nossr50/skills/WoodCutting.java b/src/main/java/com/gmail/nossr50/skills/WoodCutting.java index 86d228822..b44ca90a1 100644 --- a/src/main/java/com/gmail/nossr50/skills/WoodCutting.java +++ b/src/main/java/com/gmail/nossr50/skills/WoodCutting.java @@ -3,6 +3,7 @@ package com.gmail.nossr50.skills; import java.util.ArrayList; import org.bukkit.Material; +import org.bukkit.TreeSpecies; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -29,225 +30,287 @@ public class WoodCutting { * @param event Event to modify */ public static void treeFeller(BlockBreakEvent event) { - //Setup vars Player player = event.getPlayer(); Block firstBlock = event.getBlock(); PlayerProfile PP = Users.getProfile(player); - - //Prepare array ArrayList toBeFelled = new ArrayList(); - - //NOTE: Tree Feller will cut upwards like how you actually fell trees + + /* NOTE: Tree Feller will cut upwards like how you actually fell trees */ processTreeFelling(firstBlock, toBeFelled); removeBlocks(toBeFelled, player, PP); } - - private static void removeBlocks(ArrayList toBeFelled, Player player, PlayerProfile PP) - { - if(toBeFelled.size() > LoadProperties.treeFellerThreshold) - { + + /** + * Handles removing & dropping the blocks from Tree Feller. + * + * @param toBeFelled List of Blocks to be removed from the tree + * @param player The player using the ability + * @param PP The PlayerProfile of the player + */ + private static void removeBlocks(ArrayList toBeFelled, Player player, PlayerProfile PP) { + if(toBeFelled.size() > LoadProperties.treeFellerThreshold) { player.sendMessage(mcLocale.getString("Skills.Woodcutting.TreeFellerThreshold")); return; } - int durabilityLoss = toBeFelled.size(), xp = 0; - - //Damage the tool - player.getItemInHand().setDurability((short) (player.getItemInHand().getDurability()+durabilityLoss)); - - //This is to prevent using wood axes everytime you tree fell - if((player.getItemInHand().getDurability() + durabilityLoss >= player.getItemInHand().getType().getMaxDurability()) - || player.getItemInHand().getType() == Material.AIR || player.getItemInHand() == null) - { + + int durabilityLoss = toBeFelled.size(); + int xp = 0; + ItemStack inHand = player.getItemInHand(); + + /* Damage the tool */ + inHand.setDurability((short) (inHand.getDurability() + durabilityLoss)); + + /* This is to prevent using wood axes everytime you tree fell */ + if ((inHand.getDurability() + durabilityLoss >= inHand.getType().getMaxDurability()) || inHand.getType().equals(Material.AIR)) { player.sendMessage(mcLocale.getString("TreeFeller.AxeSplinters")); - - if(player.getHealth() >= 2) - Combat.dealDamage(player, (int)(Math.random() * (player.getHealth()-1))); + + int health = player.getHealth(); + + if (health >= 2) { + Combat.dealDamage(player, (int)(Math.random() * (health - 1))); + } return; } - + //Prepare ItemStacks - ItemStack item; - ItemStack oak = new ItemStack(Material.LOG, 1, (byte)0, (byte)0); - ItemStack spruce = new ItemStack(Material.LOG, 1, (byte)0, (byte)1); - ItemStack birch = new ItemStack(Material.LOG, 1, (byte)0, (byte)2); - ItemStack jungle = new ItemStack(Material.LOG, 1, (byte)0, (byte)3); + ItemStack item = null; + ItemStack oak = new ItemStack(Material.LOG, 1, (byte) 0x0, TreeSpecies.GENERIC.getData()); + ItemStack spruce = new ItemStack(Material.LOG, 1, (byte) 0x0, TreeSpecies.REDWOOD.getData()); + ItemStack birch = new ItemStack(Material.LOG, 1, (byte) 0x0, TreeSpecies.BIRCH.getData()); + ItemStack jungle = new ItemStack(Material.LOG, 1, (byte)0, TreeSpecies.JUNGLE.getData()); - for(Block x : toBeFelled) - { - if(m.blockBreakSimulate(x, player, true)) - { - if(x.getType() == Material.LOG) - { - switch(x.getData()) - { - case 0: + for (Block x : toBeFelled) { + if (m.blockBreakSimulate(x, player, true)) { + if (x.getType() == Material.LOG) { + TreeSpecies species = TreeSpecies.getByData(x.getData()); + + switch (species) { + case GENERIC: item = oak; break; - case 1: + + case REDWOOD: item = spruce; break; - case 2: + + case BIRCH: item = birch; break; - case 3: + + case JUNGLE: item = jungle; break; + default: - item = oak; break; } - - if(!x.hasMetadata("mcmmoPlacedBlock")) - { + + if (!x.hasMetadata("mcmmoPlacedBlock")) { WoodCutting.woodCuttingProcCheck(player, x); - - switch(x.getData()) - { - case 0: + + switch (species) { + case GENERIC: xp += LoadProperties.moak; break; - case 1: + + case REDWOOD: xp += LoadProperties.mspruce; break; - case 2: + + case BIRCH: xp += LoadProperties.mbirch; break; - case 3: - xp += LoadProperties.mjungle/4; + + case JUNGLE: + xp += LoadProperties.mjungle / 4; //Nerf XP from Jungle Trees when using Tree Feller + break; + + default: break; } } - - //Remove the block - x.setData((byte) 0); + + /* Remove the block */ + x.setData((byte) 0x0); x.setType(Material.AIR); - - //Drop the block - m.mcDropItem(x.getLocation(), item); - } else if(x.getType() == Material.LEAVES) - { - Material mat = Material.SAPLING; - item = new ItemStack(mat, 1, (short)0, (byte)(x.getData()-8)); - - //90% chance to drop sapling - if(Math.random() * 10 > 9) - m.mcRandomDropItem(x.getLocation(), item, 90); - + + /* Drop the block */ + m.mcDropItem(x.getLocation(), item); + } + else if (x.getType() == Material.LEAVES) { + final int SAPLING_DROP_CHANCE = 90; + + item = new ItemStack(Material.SAPLING, 1, (short) 0, (byte) (x.getData() - 8)); //Drop the right type of sapling + + if(Math.random() * 100 <= 90) + m.mcRandomDropItem(x.getLocation(), item, SAPLING_DROP_CHANCE); + //Remove the block x.setData((byte) 0); x.setType(Material.AIR); } } } - + PP.addXP(SkillType.WOODCUTTING, xp, player); //Tree Feller gives nerf'd XP Skills.XpCheckSkill(SkillType.WOODCUTTING, player); } - - private static boolean treeFellerCompatible(Block block) - { - return block.getType() == Material.LOG || block.getType() == Material.LEAVES || block.getType() == Material.AIR; + + /** + * Checks if the block is affected by Tree Feller. + * + * @param block Block to check + * @return true if the block is affected by Tree Feller, false otherwise + */ + private static boolean treeFellerCompatible(Block block) { + switch (block.getType()) { + case LOG: + case LEAVES: + case AIR: + return true; + + default: + return false; + } } - - private static void processTreeFelling(Block currentBlock, ArrayList toBeFelled) - { - - if(currentBlock.getType() == Material.LOG || currentBlock.getType() == Material.LEAVES) + + /** + * Handle the calculations from Tree Feller. + * + * @param currentBlock The current block to be removed + * @param toBeFelled The list of blocks left to be removed + */ + private static void processTreeFelling(Block currentBlock, ArrayList toBeFelled) { + Material type = currentBlock.getType(); + + if (type.equals(Material.LOG) || type.equals(Material.LEAVES)) { toBeFelled.add(currentBlock); - - //These 2 are to make sure that Tree Feller isn't so aggressive - boolean isAirOrLeaves = currentBlock.getType() == Material.LEAVES || currentBlock.getType() == Material.AIR; - + } + Block xPositive = currentBlock.getRelative(1, 0, 0); Block xNegative = currentBlock.getRelative(-1, 0, 0); Block zPositive = currentBlock.getRelative(0, 0, 1); Block zNegative = currentBlock.getRelative(0, 0, -1); - - if(!currentBlock.hasMetadata("mcmmoPlacedBlock") && - !isTooAgressive(isAirOrLeaves, xPositive) && treeFellerCompatible(xPositive) && !toBeFelled.contains(xPositive)) - processTreeFelling(xPositive, toBeFelled); - if(!currentBlock.hasMetadata("mcmmoPlacedBlock") && - !isTooAgressive(isAirOrLeaves, xNegative) && treeFellerCompatible(xNegative) && !toBeFelled.contains(xNegative)) - processTreeFelling(xNegative, toBeFelled); - if(!currentBlock.hasMetadata("mcmmoPlacedBlock") && - !isTooAgressive(isAirOrLeaves, zPositive) && treeFellerCompatible(zPositive) && !toBeFelled.contains(zPositive)) - processTreeFelling(zPositive, toBeFelled); - if(!currentBlock.hasMetadata("mcmmoPlacedBlock") && - !isTooAgressive(isAirOrLeaves, zNegative) && treeFellerCompatible(zNegative) && !toBeFelled.contains(zNegative)) - processTreeFelling(zNegative, toBeFelled); - - //Finally go Y+ Block yPositive = currentBlock.getRelative(0, 1, 0); - - if(treeFellerCompatible(yPositive)) - { - if(!currentBlock.hasMetadata("mcmmoPlacedBlock") && !toBeFelled.contains(yPositive)) - { + + if (!currentBlock.hasMetadata("mcmmoPlacedBlock")) { + if (!isTooAggressive(currentBlock, xPositive) && treeFellerCompatible(xPositive) && !toBeFelled.contains(xPositive)) { + processTreeFelling(xPositive, toBeFelled); + } + + if (!isTooAggressive(currentBlock, xNegative) && treeFellerCompatible(xNegative) && !toBeFelled.contains(xNegative)) { + processTreeFelling(xNegative, toBeFelled); + } + + if (!isTooAggressive(currentBlock, zPositive) && treeFellerCompatible(zPositive) && !toBeFelled.contains(zPositive)) { + processTreeFelling(zPositive, toBeFelled); + } + + if (!isTooAggressive(currentBlock, zNegative) && treeFellerCompatible(zNegative) && !toBeFelled.contains(zNegative)) { + processTreeFelling(zNegative, toBeFelled); + } + + if (treeFellerCompatible(yPositive) && !toBeFelled.contains(yPositive)) { processTreeFelling(yPositive, toBeFelled); } } } - - private static boolean isTooAgressive(boolean bool, Block block) - { - return bool && (block.getType() == Material.AIR || block.getType() == Material.LEAVES); + + /** + * Check if Tree Feller is being too aggressive. + * + * @param currentBlock The current block being felled + * @param newBlock The next block to be felled + * @return true if Tree Feller is too aggressive, false otherwise + */ + private static boolean isTooAggressive(Block currentBlock, Block newBlock) { + Material currentType = currentBlock.getType(); + Material newType = currentBlock.getType(); + + if ((currentType.equals(Material.LEAVES) || currentType.equals(Material.AIR)) && (newType.equals(Material.LEAVES) || newType.equals(Material.AIR))) { + return true; + } + else { + return false; + } } - - public static void woodCuttingProcCheck(Player player, Block block) - { - PlayerProfile PP = Users.getProfile(player); - byte type = block.getData(); - Material mat = Material.getMaterial(block.getTypeId()); - if(player != null) - { - if(PP.getSkillLevel(SkillType.WOODCUTTING) > 1000 || (Math.random() * 1000 <= PP.getSkillLevel(SkillType.WOODCUTTING))) - { - ItemStack item = new ItemStack(mat, 1, (short) 0, type); - m.mcDropItem(block.getLocation(), item); - } - } + + /** + * Check for double drops. + * + * @param player Player breaking the block + * @param block The block being broken + */ + private static void woodCuttingProcCheck(Player player, Block block) { + final int MAX_SKILL_LEVEL = 1000; + + int skillLevel = Users.getProfile(player).getSkillLevel(SkillType.WOODCUTTING); + byte type = block.getData(); + Material mat = Material.getMaterial(block.getTypeId()); + + if (skillLevel > MAX_SKILL_LEVEL || Math.random() * 1000 <= skillLevel) { + ItemStack item = new ItemStack(mat, 1, (short) 0, type); + m.mcDropItem(block.getLocation(), item); + } } - - public static void woodcuttingBlockCheck(Player player, Block block) - { - PlayerProfile PP = Users.getProfile(player); - int xp = 0; - byte data = block.getData(); - - if(block.hasMetadata("placedBlock")) - return; - - switch(data) - { - case 0: - xp += LoadProperties.moak; - break; - case 1: - xp += LoadProperties.mspruce; - break; - case 2: - xp += LoadProperties.mbirch; - break; - case 3: - xp += LoadProperties.mjungle; - break; - } - - if(block.getTypeId() == 17) - { - WoodCutting.woodCuttingProcCheck(player, block); - PP.addXP(SkillType.WOODCUTTING, xp, player); - Skills.XpCheckSkill(SkillType.WOODCUTTING, player); - } + + /** + * Check XP gain for woodcutting. + * + * @param player The player breaking the block + * @param block The block being broken + */ + public static void woodcuttingBlockCheck(Player player, Block block) { + PlayerProfile PP = Users.getProfile(player); + int xp = 0; + TreeSpecies species = TreeSpecies.getByData(block.getData()); + + if (block.hasMetadata("placedBlock")) { + return; + } + + switch (species) { + case GENERIC: + xp += LoadProperties.moak; + break; + + case REDWOOD: + xp += LoadProperties.mspruce; + break; + + case BIRCH: + xp += LoadProperties.mbirch; + break; + + case JUNGLE: + xp += LoadProperties.mjungle; + break; + + default: + break; + } + + WoodCutting.woodCuttingProcCheck(player, block); + PP.addXP(SkillType.WOODCUTTING, xp, player); + Skills.XpCheckSkill(SkillType.WOODCUTTING, player); } - - public static void leafBlower(Player player, Block block){ - - PlayerAnimationEvent armswing = new PlayerAnimationEvent(player); - Bukkit.getPluginManager().callEvent(armswing); - if(LoadProperties.woodcuttingrequiresaxe) - Skills.abilityDurabilityLoss(player.getItemInHand(), LoadProperties.abilityDurabilityLoss); - if(LoadProperties.spoutEnabled) - SpoutStuff.playSoundForPlayer(SoundEffect.POP, player, block.getLocation()); + + /** + * Handle the Leaf Blower ability. + * + * @param player Player using the ability + * @param block Block being broken + */ + public static void leafBlower(Player player, Block block) { + PlayerAnimationEvent armswing = new PlayerAnimationEvent(player); + Bukkit.getPluginManager().callEvent(armswing); + + if (LoadProperties.woodcuttingrequiresaxe) { + Skills.abilityDurabilityLoss(player.getItemInHand(), LoadProperties.abilityDurabilityLoss); + } + + if (LoadProperties.spoutEnabled) { + SpoutStuff.playSoundForPlayer(SoundEffect.POP, player, block.getLocation()); + } } }