mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2024-12-26 02:28:03 +01:00
Create a WoodcuttingManager
This commit is contained in:
parent
c1161da6de
commit
44ede5c3f8
@ -34,6 +34,7 @@ import com.gmail.nossr50.skills.smelting.SmeltingManager;
|
||||
import com.gmail.nossr50.skills.swords.SwordsManager;
|
||||
import com.gmail.nossr50.skills.taming.TamingManager;
|
||||
import com.gmail.nossr50.skills.unarmed.UnarmedManager;
|
||||
import com.gmail.nossr50.skills.woodcutting.WoodcuttingManager;
|
||||
import com.gmail.nossr50.util.Misc;
|
||||
import com.gmail.nossr50.util.ModUtils;
|
||||
import com.gmail.nossr50.util.Permissions;
|
||||
@ -94,12 +95,7 @@ public class McMMOPlayer {
|
||||
*/
|
||||
try {
|
||||
for (SkillType skillType : SkillType.values()) {
|
||||
Class<? extends SkillManager> skillManagerClass = skillType.getManagerClass();
|
||||
|
||||
// TODO: The null check is needed only because currently some SkillType doesn't have a valid skillManagerClass
|
||||
if (skillManagerClass != null) {
|
||||
skillManagers.put(skillType, skillManagerClass.getConstructor(McMMOPlayer.class).newInstance(this));
|
||||
}
|
||||
skillManagers.put(skillType, skillType.getManagerClass().getConstructor(McMMOPlayer.class).newInstance(this));
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
@ -166,6 +162,10 @@ public class McMMOPlayer {
|
||||
return (UnarmedManager) skillManagers.get(SkillType.UNARMED);
|
||||
}
|
||||
|
||||
public WoodcuttingManager getWoodcuttingManager() {
|
||||
return (WoodcuttingManager) skillManagers.get(SkillType.WOODCUTTING);
|
||||
}
|
||||
|
||||
/*
|
||||
* Abilities
|
||||
*/
|
||||
|
@ -16,6 +16,7 @@ import com.gmail.nossr50.skills.smelting.SmeltingManager;
|
||||
import com.gmail.nossr50.skills.swords.SwordsManager;
|
||||
import com.gmail.nossr50.skills.taming.TamingManager;
|
||||
import com.gmail.nossr50.skills.unarmed.UnarmedManager;
|
||||
import com.gmail.nossr50.skills.woodcutting.WoodcuttingManager;
|
||||
import com.gmail.nossr50.util.StringUtils;
|
||||
|
||||
public enum SkillType {
|
||||
@ -31,7 +32,7 @@ public enum SkillType {
|
||||
SWORDS(SwordsManager.class, AbilityType.SERRATED_STRIKES, ToolType.SWORD),
|
||||
TAMING(TamingManager.class),
|
||||
UNARMED(UnarmedManager.class, AbilityType.BERSERK, ToolType.FISTS),
|
||||
WOODCUTTING(null, AbilityType.TREE_FELLER, ToolType.AXE); // TODO: Create a proper WoodcuttingManager class
|
||||
WOODCUTTING(WoodcuttingManager.class, AbilityType.TREE_FELLER, ToolType.AXE);
|
||||
|
||||
private Class<? extends SkillManager> managerClass;
|
||||
private AbilityType ability;
|
||||
|
@ -20,8 +20,6 @@ import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.config.AdvancedConfig;
|
||||
import com.gmail.nossr50.config.Config;
|
||||
import com.gmail.nossr50.config.HiddenConfig;
|
||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
import com.gmail.nossr50.datatypes.skills.AbilityType;
|
||||
@ -37,7 +35,7 @@ import com.gmail.nossr50.skills.mining.MiningManager;
|
||||
import com.gmail.nossr50.skills.repair.Repair;
|
||||
import com.gmail.nossr50.skills.smelting.SmeltingManager;
|
||||
import com.gmail.nossr50.skills.unarmed.Unarmed;
|
||||
import com.gmail.nossr50.skills.woodcutting.Woodcutting;
|
||||
import com.gmail.nossr50.skills.woodcutting.WoodcuttingManager;
|
||||
import com.gmail.nossr50.util.BlockUtils;
|
||||
import com.gmail.nossr50.util.ItemUtils;
|
||||
import com.gmail.nossr50.util.Misc;
|
||||
@ -179,18 +177,13 @@ public class BlockListener implements Listener {
|
||||
|
||||
/* WOOD CUTTING */
|
||||
else if (BlockUtils.isLog(blockState) && Permissions.skillEnabled(player, SkillType.WOODCUTTING) && !mcMMO.placeStore.isTrue(blockState)) {
|
||||
if (mcMMOPlayer.getAbilityMode(AbilityType.TREE_FELLER) && Permissions.treeFeller(player) && ItemUtils.isAxe(heldItem)) {
|
||||
Woodcutting.beginTreeFeller(blockState, player);
|
||||
WoodcuttingManager woodcuttingManager = mcMMOPlayer.getWoodcuttingManager();
|
||||
|
||||
if (woodcuttingManager.canUseTreeFeller(heldItem)) {
|
||||
woodcuttingManager.processTreeFeller(blockState);
|
||||
}
|
||||
else {
|
||||
if (Config.getInstance().getWoodcuttingRequiresTool()) {
|
||||
if (ItemUtils.isAxe(heldItem)) {
|
||||
Woodcutting.beginWoodcutting(player, blockState);
|
||||
}
|
||||
}
|
||||
else {
|
||||
Woodcutting.beginWoodcutting(player, blockState);
|
||||
}
|
||||
woodcuttingManager.woodcuttingBlockCheck(blockState);
|
||||
}
|
||||
}
|
||||
|
||||
@ -367,18 +360,10 @@ public class BlockListener implements Listener {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((mcMMOPlayer.getProfile().getSkillLevel(SkillType.WOODCUTTING) >= AdvancedConfig.getInstance().getLeafBlowUnlockLevel()) && BlockUtils.isLeaves(blockState)) {
|
||||
if (SkillUtils.triggerCheck(player, block, AbilityType.LEAF_BLOWER)) {
|
||||
if (Config.getInstance().getWoodcuttingRequiresTool()) {
|
||||
if (ItemUtils.isAxe(heldItem)) {
|
||||
event.setInstaBreak(true);
|
||||
Woodcutting.beginLeafBlower(player, blockState);
|
||||
}
|
||||
}
|
||||
else if (!(heldItem.getType() == Material.SHEARS)) {
|
||||
event.setInstaBreak(true);
|
||||
Woodcutting.beginLeafBlower(player, blockState);
|
||||
}
|
||||
else if (BlockUtils.isLeaves(blockState)) {
|
||||
if (UserManager.getPlayer(player).getWoodcuttingManager().canUseLeafBlower(heldItem) && SkillUtils.blockBreakSimulate(block, player, true)) {
|
||||
event.setInstaBreak(true);
|
||||
player.playSound(blockState.getLocation(), Sound.ITEM_PICKUP, Misc.POP_VOLUME, Misc.POP_PITCH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,276 +0,0 @@
|
||||
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.BlockState;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.Tree;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.config.Config;
|
||||
import com.gmail.nossr50.datatypes.mods.CustomBlock;
|
||||
import com.gmail.nossr50.datatypes.skills.SkillType;
|
||||
import com.gmail.nossr50.locale.LocaleLoader;
|
||||
import com.gmail.nossr50.skills.woodcutting.Woodcutting.ExperienceGainMethod;
|
||||
import com.gmail.nossr50.util.BlockUtils;
|
||||
import com.gmail.nossr50.util.Misc;
|
||||
import com.gmail.nossr50.util.ModUtils;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import com.gmail.nossr50.util.skills.CombatUtils;
|
||||
import com.gmail.nossr50.util.skills.SkillUtils;
|
||||
|
||||
public final class TreeFeller {
|
||||
private static boolean treeFellerReachedThreshold = false;
|
||||
|
||||
private TreeFeller() {}
|
||||
|
||||
/**
|
||||
* Begins Tree Feller
|
||||
*
|
||||
* @param mcMMOPlayer Player using Tree Feller
|
||||
* @param blockState Block being broken
|
||||
*/
|
||||
protected static void processTreeFeller(BlockState blockState, Player player) {
|
||||
List<BlockState> treeFellerBlocks = new ArrayList<BlockState>();
|
||||
|
||||
if (blockState.getTypeId() == 17 || blockState.getTypeId() == 99) {
|
||||
processRegularTrees(blockState, treeFellerBlocks);
|
||||
}
|
||||
else {
|
||||
processRedMushroomTrees(blockState, treeFellerBlocks);
|
||||
}
|
||||
|
||||
// If the player is trying to break too many blocks
|
||||
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.getItemInHand())) {
|
||||
player.sendMessage(LocaleLoader.getString("Woodcutting.Skills.TreeFeller.Splinter"));
|
||||
|
||||
int health = player.getHealth();
|
||||
|
||||
if (health > 1) {
|
||||
CombatUtils.dealDamage(player, Misc.getRandom().nextInt(health - 1));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
dropBlocks(treeFellerBlocks, player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes Tree Feller for generic Trees
|
||||
*
|
||||
* @param blockState Block being checked
|
||||
* @param treeFellerBlocks List of blocks to be removed
|
||||
*/
|
||||
private static void processRegularTrees(BlockState blockState, List<BlockState> treeFellerBlocks) {
|
||||
if (!BlockUtils.isLog(blockState)) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<BlockState> futureCenterBlocks = new ArrayList<BlockState>();
|
||||
World world = blockState.getWorld();
|
||||
|
||||
// Handle the blocks around 'block'
|
||||
for (int y = 0; y <= 1; y++) {
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
for (int z = -1; z <= 1; z++) {
|
||||
BlockState nextBlock = world.getBlockAt(blockState.getLocation().add(x, y, z)).getState();
|
||||
|
||||
handleBlock(nextBlock, futureCenterBlocks, treeFellerBlocks);
|
||||
|
||||
if (treeFellerReachedThreshold) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Recursive call for each log found
|
||||
for (BlockState futureCenterBlock : futureCenterBlocks) {
|
||||
if (treeFellerReachedThreshold) {
|
||||
return;
|
||||
}
|
||||
|
||||
processRegularTrees(futureCenterBlock, treeFellerBlocks);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes Tree Feller for Red Mushrooms (Dome Shaped)
|
||||
*
|
||||
* @param blockState Block being checked
|
||||
* @param treeFellerBlocks List of blocks to be removed
|
||||
*/
|
||||
private static void processRedMushroomTrees(BlockState blockState, List<BlockState> treeFellerBlocks) {
|
||||
if (!BlockUtils.isLog(blockState)) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<BlockState> futureCenterBlocks = new ArrayList<BlockState>();
|
||||
World world = blockState.getWorld();
|
||||
|
||||
// Handle the blocks around 'block'
|
||||
for (int y = 0; y <= 1; y++) {
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
for (int z = -1; z <= 1; z++) {
|
||||
BlockState nextBlock = world.getBlockAt(blockState.getLocation().add(x, y, z)).getState();
|
||||
BlockState otherNextBlock = world.getBlockAt(blockState.getLocation().add(x, y - (y * 2), z)).getState();
|
||||
|
||||
handleBlock(nextBlock, futureCenterBlocks, treeFellerBlocks);
|
||||
handleBlock(otherNextBlock, futureCenterBlocks, treeFellerBlocks);
|
||||
|
||||
if (treeFellerReachedThreshold) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Recursive call for each log found
|
||||
for (BlockState futureCenterBlock : futureCenterBlocks) {
|
||||
if (treeFellerReachedThreshold) {
|
||||
return;
|
||||
}
|
||||
|
||||
processRedMushroomTrees(futureCenterBlock, treeFellerBlocks);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a block addition to the list of blocks to be removed and to the list of blocks used for future recursive calls of 'processRecursively()'
|
||||
*
|
||||
* @param blockState Block to be added
|
||||
* @param futureCenterBlocks List of blocks that will be used to call 'processRecursively()'
|
||||
* @param treeFellerBlocks List of blocks to be removed
|
||||
*/
|
||||
private static void handleBlock(BlockState blockState, List<BlockState> futureCenterBlocks, List<BlockState> treeFellerBlocks) {
|
||||
if (!BlockUtils.affectedByTreeFeller(blockState) || mcMMO.placeStore.isTrue(blockState) || treeFellerBlocks.contains(blockState)) {
|
||||
return;
|
||||
}
|
||||
|
||||
treeFellerBlocks.add(blockState);
|
||||
|
||||
if (treeFellerBlocks.size() > Config.getInstance().getTreeFellerThreshold()) {
|
||||
treeFellerReachedThreshold = true;
|
||||
return;
|
||||
}
|
||||
|
||||
futureCenterBlocks.add(blockState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the durability loss
|
||||
*
|
||||
* @param treeFellerBlocks List of blocks to be removed
|
||||
* @param inHand tool being used
|
||||
* @return True if the tool can sustain the durability loss
|
||||
*/
|
||||
private static boolean handleDurabilityLoss(List<BlockState> treeFellerBlocks, ItemStack inHand) {
|
||||
Material inHandMaterial = inHand.getType();
|
||||
|
||||
if (inHandMaterial != Material.AIR) {
|
||||
short durabilityLoss = 0;
|
||||
int unbreakingLevel = inHand.getEnchantmentLevel(Enchantment.DURABILITY);
|
||||
|
||||
for (BlockState blockState : treeFellerBlocks) {
|
||||
if (BlockUtils.isLog(blockState) && Misc.getRandom().nextInt(unbreakingLevel + 1) == 0) {
|
||||
durabilityLoss += Config.getInstance().getAbilityToolDamage();
|
||||
}
|
||||
}
|
||||
|
||||
short finalDurability = (short) (inHand.getDurability() + durabilityLoss);
|
||||
short maxDurability = ModUtils.isCustomTool(inHand) ? ModUtils.getToolFromItemStack(inHand).getDurability() : inHandMaterial.getMaxDurability();
|
||||
|
||||
if (finalDurability >= maxDurability) {
|
||||
inHand.setDurability(maxDurability);
|
||||
return false;
|
||||
}
|
||||
|
||||
inHand.setDurability(finalDurability);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the dropping of blocks
|
||||
*
|
||||
* @param treeFellerBlocks List of blocks to be dropped
|
||||
* @param player Player using the ability
|
||||
*/
|
||||
private static void dropBlocks(List<BlockState> treeFellerBlocks, Player player) {
|
||||
int xp = 0;
|
||||
|
||||
for (BlockState blockState : treeFellerBlocks) {
|
||||
if (!SkillUtils.blockBreakSimulate(blockState.getBlock(), player, true)) {
|
||||
break; // TODO: Shouldn't we use continue instead?
|
||||
}
|
||||
|
||||
Material material = blockState.getType();
|
||||
|
||||
if (material == Material.HUGE_MUSHROOM_1 || material == Material.HUGE_MUSHROOM_2) {
|
||||
xp += Woodcutting.getExperienceFromLog(blockState, ExperienceGainMethod.TREE_FELLER);
|
||||
|
||||
for (ItemStack drop : blockState.getBlock().getDrops()) {
|
||||
Misc.dropItem(blockState.getLocation(), drop);
|
||||
}
|
||||
}
|
||||
else if (ModUtils.isCustomLogBlock(blockState)) {
|
||||
Woodcutting.checkForDoubleDrop(player, blockState);
|
||||
|
||||
CustomBlock customBlock = ModUtils.getCustomBlock(blockState);
|
||||
xp = customBlock.getXpGain();
|
||||
int minimumDropAmount = customBlock.getMinimumDropAmount();
|
||||
int maximumDropAmount = customBlock.getMaximumDropAmount();
|
||||
Location location = blockState.getLocation();
|
||||
ItemStack item = customBlock.getItemDrop();;
|
||||
|
||||
Misc.dropItems(location, item, minimumDropAmount);
|
||||
|
||||
if (minimumDropAmount < maximumDropAmount) {
|
||||
Misc.randomDropItems(location, item, maximumDropAmount - minimumDropAmount);
|
||||
}
|
||||
}
|
||||
else if (ModUtils.isCustomLeafBlock(blockState)) {
|
||||
Misc.randomDropItem(blockState.getLocation(), ModUtils.getCustomBlock(blockState).getItemDrop(), 10);
|
||||
}
|
||||
else {
|
||||
Tree tree = (Tree) blockState.getData();
|
||||
switch (material) {
|
||||
case LOG:
|
||||
Woodcutting.checkForDoubleDrop(player, blockState);
|
||||
xp += Woodcutting.getExperienceFromLog(blockState, ExperienceGainMethod.TREE_FELLER);
|
||||
Misc.dropItem(blockState.getLocation(), new ItemStack(Material.LOG, 1, tree.getSpecies().getData()));
|
||||
break;
|
||||
|
||||
case LEAVES:
|
||||
Misc.randomDropItem(blockState.getLocation(), new ItemStack(Material.SAPLING, 1, tree.getSpecies().getData()), 10);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
blockState.setRawData((byte) 0x0);
|
||||
blockState.setType(Material.AIR);
|
||||
blockState.update(true);
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(SkillType.WOODCUTTING, xp);
|
||||
}
|
||||
}
|
@ -1,10 +1,12 @@
|
||||
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.Sound;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.Tree;
|
||||
|
||||
@ -12,18 +14,17 @@ import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.config.AdvancedConfig;
|
||||
import com.gmail.nossr50.config.Config;
|
||||
import com.gmail.nossr50.datatypes.mods.CustomBlock;
|
||||
import com.gmail.nossr50.datatypes.skills.SkillType;
|
||||
import com.gmail.nossr50.events.fake.FakePlayerAnimationEvent;
|
||||
import com.gmail.nossr50.util.BlockUtils;
|
||||
import com.gmail.nossr50.util.Misc;
|
||||
import com.gmail.nossr50.util.ModUtils;
|
||||
import com.gmail.nossr50.util.Permissions;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import com.gmail.nossr50.util.skills.SkillUtils;
|
||||
|
||||
public final class Woodcutting {
|
||||
public static int doubleDropsMaxLevel = AdvancedConfig.getInstance().getWoodcuttingDoubleDropMaxLevel();
|
||||
public static double doubleDropsMaxChance = AdvancedConfig.getInstance().getWoodcuttingDoubleDropChance();
|
||||
|
||||
public static int leafBlowerUnlockLevel = AdvancedConfig.getInstance().getLeafBlowUnlockLevel();
|
||||
public static int treeFellerThreshold = Config.getInstance().getTreeFellerThreshold();
|
||||
|
||||
protected enum ExperienceGainMethod {
|
||||
DEFAULT,
|
||||
TREE_FELLER,
|
||||
@ -31,47 +32,6 @@ public final class Woodcutting {
|
||||
|
||||
private Woodcutting() {}
|
||||
|
||||
/**
|
||||
* Begins the Tree Feller ability
|
||||
*
|
||||
* @param mcMMOPlayer Player using the ability
|
||||
* @param block Block being broken
|
||||
*/
|
||||
public static void beginTreeFeller(BlockState blockState, Player player) {
|
||||
TreeFeller.processTreeFeller(blockState, player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins the Leaf Blower ability
|
||||
*
|
||||
* @param player Player using the ability
|
||||
* @param block Block being broken
|
||||
*/
|
||||
public static void beginLeafBlower(Player player, BlockState blockState) {
|
||||
mcMMO.p.getServer().getPluginManager().callEvent(new FakePlayerAnimationEvent(player));
|
||||
player.playSound(blockState.getLocation(), Sound.ITEM_PICKUP, Misc.POP_VOLUME, Misc.POP_PITCH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins Woodcutting
|
||||
*
|
||||
* @param mcMMOPlayer Player breaking the block
|
||||
* @param block Block being broken
|
||||
*/
|
||||
public static void beginWoodcutting(Player player, BlockState blockState) {
|
||||
int xp = getExperienceFromLog(blockState, ExperienceGainMethod.DEFAULT);
|
||||
|
||||
if (Permissions.doubleDrops(player, SkillType.WOODCUTTING)) {
|
||||
Material blockType = blockState.getType();
|
||||
|
||||
if (blockType != Material.HUGE_MUSHROOM_1 && blockType != Material.HUGE_MUSHROOM_2) {
|
||||
checkForDoubleDrop(player, blockState);
|
||||
}
|
||||
}
|
||||
|
||||
UserManager.getPlayer(player).beginXpGain(SkillType.WOODCUTTING, xp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the experience reward from a log
|
||||
*
|
||||
@ -126,11 +86,7 @@ public final class Woodcutting {
|
||||
* @param mcMMOPlayer Player breaking the block
|
||||
* @param blockState Block being broken
|
||||
*/
|
||||
protected static void checkForDoubleDrop(Player player, BlockState blockState) {
|
||||
if (!SkillUtils.activationSuccessful(player, SkillType.WOODCUTTING, doubleDropsMaxChance, doubleDropsMaxLevel)) {
|
||||
return;
|
||||
}
|
||||
|
||||
protected static void checkForDoubleDrop(BlockState blockState) {
|
||||
if (ModUtils.isCustomLogBlock(blockState)) {
|
||||
CustomBlock customBlock = ModUtils.getCustomBlock(blockState);
|
||||
int minimumDropAmount = customBlock.getMinimumDropAmount();
|
||||
@ -179,4 +135,129 @@ public final class Woodcutting {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes Tree Feller for generic Trees
|
||||
*
|
||||
* @param blockState Block being checked
|
||||
* @param treeFellerBlocks List of blocks to be removed
|
||||
*/
|
||||
protected static void processRegularTrees(BlockState blockState, List<BlockState> treeFellerBlocks) {
|
||||
List<BlockState> futureCenterBlocks = new ArrayList<BlockState>();
|
||||
|
||||
// Handle the blocks around 'block'
|
||||
for (int y = 0; y <= 1; y++) {
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
for (int z = -1; z <= 1; z++) {
|
||||
BlockState nextBlock = blockState.getBlock().getRelative(x, y, z).getState();
|
||||
handleBlock(nextBlock, futureCenterBlocks, treeFellerBlocks);
|
||||
|
||||
if (WoodcuttingManager.treeFellerReachedThreshold) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Recursive call for each log found
|
||||
for (BlockState futureCenterBlock : futureCenterBlocks) {
|
||||
if (WoodcuttingManager.treeFellerReachedThreshold) {
|
||||
return;
|
||||
}
|
||||
|
||||
processRegularTrees(futureCenterBlock, treeFellerBlocks);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes Tree Feller for Red Mushrooms (Dome Shaped)
|
||||
*
|
||||
* @param blockState Block being checked
|
||||
* @param treeFellerBlocks List of blocks to be removed
|
||||
*/
|
||||
protected static void processRedMushroomTrees(BlockState blockState, List<BlockState> treeFellerBlocks) {
|
||||
List<BlockState> futureCenterBlocks = new ArrayList<BlockState>();
|
||||
|
||||
// Handle the blocks around 'block'
|
||||
for (int y = 0; y <= 1; y++) {
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
for (int z = -1; z <= 1; z++) {
|
||||
BlockState nextBlock = blockState.getBlock().getRelative(x, y, z).getState();
|
||||
BlockState otherNextBlock = blockState.getBlock().getRelative(x, y - (y * 2), z).getState();
|
||||
|
||||
handleBlock(nextBlock, futureCenterBlocks, treeFellerBlocks);
|
||||
handleBlock(otherNextBlock, futureCenterBlocks, treeFellerBlocks);
|
||||
|
||||
if (WoodcuttingManager.treeFellerReachedThreshold) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Recursive call for each log found
|
||||
for (BlockState futureCenterBlock : futureCenterBlocks) {
|
||||
if (WoodcuttingManager.treeFellerReachedThreshold) {
|
||||
return;
|
||||
}
|
||||
|
||||
processRedMushroomTrees(futureCenterBlock, treeFellerBlocks);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the durability loss
|
||||
*
|
||||
* @param treeFellerBlocks List of blocks to be removed
|
||||
* @param inHand tool being used
|
||||
* @return True if the tool can sustain the durability loss
|
||||
*/
|
||||
protected static boolean handleDurabilityLoss(List<BlockState> treeFellerBlocks, ItemStack inHand) {
|
||||
Material inHandMaterial = inHand.getType();
|
||||
|
||||
if (inHandMaterial == Material.AIR) {
|
||||
return false;
|
||||
}
|
||||
|
||||
short durabilityLoss = 0;
|
||||
int unbreakingLevel = inHand.getEnchantmentLevel(Enchantment.DURABILITY);
|
||||
|
||||
for (BlockState blockState : treeFellerBlocks) {
|
||||
if (BlockUtils.isLog(blockState) && Misc.getRandom().nextInt(unbreakingLevel + 1) == 0) {
|
||||
durabilityLoss += Config.getInstance().getAbilityToolDamage();
|
||||
}
|
||||
}
|
||||
|
||||
short finalDurability = (short) (inHand.getDurability() + durabilityLoss);
|
||||
short maxDurability = ModUtils.isCustomTool(inHand) ? ModUtils.getToolFromItemStack(inHand).getDurability() : inHandMaterial.getMaxDurability();
|
||||
|
||||
if (finalDurability >= maxDurability) {
|
||||
return false;
|
||||
}
|
||||
|
||||
inHand.setDurability(finalDurability);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a block addition to the list of blocks to be removed and to the list of blocks used for future recursive calls of 'processRecursively()'
|
||||
*
|
||||
* @param blockState Block to be added
|
||||
* @param futureCenterBlocks List of blocks that will be used to call 'processRecursively()'
|
||||
* @param treeFellerBlocks List of blocks to be removed
|
||||
*/
|
||||
private static void handleBlock(BlockState blockState, List<BlockState> futureCenterBlocks, List<BlockState> treeFellerBlocks) {
|
||||
if (!BlockUtils.affectedByTreeFeller(blockState) || mcMMO.placeStore.isTrue(blockState) || treeFellerBlocks.contains(blockState)) {
|
||||
return;
|
||||
}
|
||||
|
||||
treeFellerBlocks.add(blockState);
|
||||
|
||||
if (treeFellerBlocks.size() > treeFellerThreshold) {
|
||||
WoodcuttingManager.treeFellerReachedThreshold = true;
|
||||
return;
|
||||
}
|
||||
|
||||
futureCenterBlocks.add(blockState);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,192 @@
|
||||
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.block.BlockState;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.Tree;
|
||||
|
||||
import com.gmail.nossr50.datatypes.mods.CustomBlock;
|
||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
import com.gmail.nossr50.datatypes.skills.AbilityType;
|
||||
import com.gmail.nossr50.datatypes.skills.SkillType;
|
||||
import com.gmail.nossr50.locale.LocaleLoader;
|
||||
import com.gmail.nossr50.skills.SkillManager;
|
||||
import com.gmail.nossr50.skills.woodcutting.Woodcutting.ExperienceGainMethod;
|
||||
import com.gmail.nossr50.util.ItemUtils;
|
||||
import com.gmail.nossr50.util.Misc;
|
||||
import com.gmail.nossr50.util.ModUtils;
|
||||
import com.gmail.nossr50.util.Permissions;
|
||||
import com.gmail.nossr50.util.skills.CombatUtils;
|
||||
import com.gmail.nossr50.util.skills.SkillUtils;
|
||||
|
||||
public class WoodcuttingManager extends SkillManager {
|
||||
protected static boolean treeFellerReachedThreshold = false;
|
||||
|
||||
public WoodcuttingManager(McMMOPlayer mcMMOPlayer) {
|
||||
super(mcMMOPlayer, SkillType.WOODCUTTING);
|
||||
}
|
||||
|
||||
public boolean canUseLeafBlower(ItemStack heldItem) {
|
||||
return getSkillLevel() >= Woodcutting.leafBlowerUnlockLevel && ItemUtils.isAxe(heldItem);
|
||||
}
|
||||
|
||||
public boolean canUseTreeFeller(ItemStack heldItem) {
|
||||
return mcMMOPlayer.getAbilityMode(AbilityType.TREE_FELLER) && Permissions.treeFeller(getPlayer()) && ItemUtils.isAxe(heldItem);
|
||||
}
|
||||
|
||||
protected boolean canGetDoubleDrops() {
|
||||
return Permissions.doubleDrops(getPlayer(), skill) && SkillUtils.activationSuccessful(getSkillLevel(), getActivationChance(), Woodcutting.doubleDropsMaxChance, Woodcutting.doubleDropsMaxLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins Woodcutting
|
||||
*
|
||||
* @param blockState Block being broken
|
||||
*/
|
||||
public void woodcuttingBlockCheck(BlockState blockState) {
|
||||
int xp = Woodcutting.getExperienceFromLog(blockState, ExperienceGainMethod.DEFAULT);
|
||||
|
||||
switch (blockState.getType()) {
|
||||
case HUGE_MUSHROOM_1:
|
||||
case HUGE_MUSHROOM_2:
|
||||
break;
|
||||
|
||||
default:
|
||||
if (canGetDoubleDrops()) {
|
||||
Woodcutting.checkForDoubleDrop(blockState);
|
||||
}
|
||||
}
|
||||
|
||||
applyXpGain(xp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins Tree Feller
|
||||
*
|
||||
* @param blockState Block being broken
|
||||
*/
|
||||
public void processTreeFeller(BlockState blockState) {
|
||||
Player player = getPlayer();
|
||||
List<BlockState> treeFellerBlocks = new ArrayList<BlockState>();
|
||||
|
||||
switch (blockState.getType()) {
|
||||
case LOG:
|
||||
case HUGE_MUSHROOM_1:
|
||||
Woodcutting.processRegularTrees(blockState, treeFellerBlocks);
|
||||
break;
|
||||
|
||||
case HUGE_MUSHROOM_2:
|
||||
Woodcutting.processRedMushroomTrees(blockState, treeFellerBlocks);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (ModUtils.isCustomLogBlock(blockState)) {
|
||||
Woodcutting.processRegularTrees(blockState, treeFellerBlocks);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// If the player is trying to break too many blocks
|
||||
if (treeFellerReachedThreshold) {
|
||||
treeFellerReachedThreshold = false;
|
||||
|
||||
player.sendMessage(LocaleLoader.getString("Woodcutting.Skills.TreeFellerThreshold"));
|
||||
return;
|
||||
}
|
||||
|
||||
// If the tool can't sustain the durability loss
|
||||
if (!Woodcutting.handleDurabilityLoss(treeFellerBlocks, player.getItemInHand())) {
|
||||
player.sendMessage(LocaleLoader.getString("Woodcutting.Skills.TreeFeller.Splinter"));
|
||||
|
||||
int health = player.getHealth();
|
||||
|
||||
if (health > 1) {
|
||||
CombatUtils.dealDamage(player, Misc.getRandom().nextInt(health - 1));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
dropBlocks(treeFellerBlocks);
|
||||
treeFellerReachedThreshold = false; // Reset the value after we're done with Tree Feller each time.
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the dropping of blocks
|
||||
*
|
||||
* @param treeFellerBlocks List of blocks to be dropped
|
||||
* @param player Player using the ability
|
||||
*/
|
||||
private void dropBlocks(List<BlockState> treeFellerBlocks) {
|
||||
Player player = getPlayer();
|
||||
int xp = 0;
|
||||
|
||||
for (BlockState blockState : treeFellerBlocks) {
|
||||
if (!SkillUtils.blockBreakSimulate(blockState.getBlock(), player, true)) {
|
||||
break; // TODO: Shouldn't we use continue instead?
|
||||
}
|
||||
|
||||
Material material = blockState.getType();
|
||||
|
||||
if (material == Material.HUGE_MUSHROOM_1 || material == Material.HUGE_MUSHROOM_2) {
|
||||
xp += Woodcutting.getExperienceFromLog(blockState, ExperienceGainMethod.TREE_FELLER);
|
||||
|
||||
for (ItemStack drop : blockState.getBlock().getDrops()) {
|
||||
Misc.dropItem(blockState.getLocation(), drop);
|
||||
}
|
||||
}
|
||||
else if (ModUtils.isCustomLogBlock(blockState)) {
|
||||
if (canGetDoubleDrops()) {
|
||||
Woodcutting.checkForDoubleDrop(blockState);
|
||||
}
|
||||
|
||||
CustomBlock customBlock = ModUtils.getCustomBlock(blockState);
|
||||
xp = customBlock.getXpGain();
|
||||
int minimumDropAmount = customBlock.getMinimumDropAmount();
|
||||
int maximumDropAmount = customBlock.getMaximumDropAmount();
|
||||
Location location = blockState.getLocation();
|
||||
ItemStack item = customBlock.getItemDrop();;
|
||||
|
||||
Misc.dropItems(location, item, minimumDropAmount);
|
||||
|
||||
if (minimumDropAmount < maximumDropAmount) {
|
||||
Misc.randomDropItems(location, item, maximumDropAmount - minimumDropAmount);
|
||||
}
|
||||
}
|
||||
else if (ModUtils.isCustomLeafBlock(blockState)) {
|
||||
Misc.randomDropItem(blockState.getLocation(), ModUtils.getCustomBlock(blockState).getItemDrop(), 10);
|
||||
}
|
||||
else {
|
||||
Tree tree = (Tree) blockState.getData();
|
||||
switch (material) {
|
||||
case LOG:
|
||||
if (canGetDoubleDrops()) {
|
||||
Woodcutting.checkForDoubleDrop(blockState);
|
||||
}
|
||||
xp += Woodcutting.getExperienceFromLog(blockState, ExperienceGainMethod.TREE_FELLER);
|
||||
Misc.dropItem(blockState.getLocation(), new ItemStack(Material.LOG, 1, tree.getSpecies().getData()));
|
||||
break;
|
||||
|
||||
case LEAVES:
|
||||
Misc.randomDropItem(blockState.getLocation(), new ItemStack(Material.SAPLING, 1, tree.getSpecies().getData()), 10);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
blockState.setRawData((byte) 0x0);
|
||||
blockState.setType(Material.AIR);
|
||||
blockState.update(true);
|
||||
}
|
||||
|
||||
applyXpGain(xp);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user