|
@@ -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<Block> toBeFelled = new ArrayList<Block>();
|
|
|
-
|
|
|
- //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<Block> 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<Block> 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<Block> 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<Block> 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());
|
|
|
+ }
|
|
|
}
|
|
|
}
|