mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2025-04-01 17:26:25 +02:00

Tree Feller has been shown, both anecdotally and with timings, to put a strain on the server, and therefore is worthy of the effort of optimization. Prior to this change, on jungle trees, Tree Feller would take around 20-40 milliseconds to process a Jungle Tree after the JIT kicked in, and around 15-25 milliseconds for a normal tree. Additionally, logs would be left up in the air for jungle trees. After this change, Tree Feller takes 2-5 milliseconds on normal trees, and 10-15 milliseconds on jungle trees, and no logs are left up in the air.
171 lines
5.9 KiB
Java
171 lines
5.9 KiB
Java
package com.gmail.nossr50.skills.woodcutting;
|
|
|
|
import java.util.LinkedHashSet;
|
|
import java.util.Set;
|
|
|
|
import org.bukkit.Material;
|
|
import org.bukkit.block.Block;
|
|
import org.bukkit.block.BlockFace;
|
|
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.EventUtils;
|
|
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 {
|
|
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();
|
|
LinkedHashSet<BlockState> treeFellerBlocks = new LinkedHashSet<BlockState>();
|
|
|
|
Woodcutting.treeFellerReachedThreshold = false;
|
|
|
|
Woodcutting.processTree(blockState, treeFellerBlocks);
|
|
|
|
// If the player is trying to break too many blocks
|
|
if (Woodcutting.treeFellerReachedThreshold) {
|
|
Woodcutting.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"));
|
|
|
|
double health = player.getHealth();
|
|
|
|
if (health > 1) {
|
|
CombatUtils.dealDamage(player, Misc.getRandom().nextInt((int) (health - 1)));
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
dropBlocks(treeFellerBlocks);
|
|
Woodcutting.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
|
|
*/
|
|
private void dropBlocks(Set<BlockState> treeFellerBlocks) {
|
|
Player player = getPlayer();
|
|
int xp = 0;
|
|
|
|
for (BlockState blockState : treeFellerBlocks) {
|
|
Block block = blockState.getBlock();
|
|
|
|
if (!EventUtils.simulateBlockBreak(block, 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);
|
|
Misc.dropItems(blockState.getLocation(), block.getDrops());
|
|
}
|
|
else if (ModUtils.isCustomLogBlock(blockState)) {
|
|
if (canGetDoubleDrops()) {
|
|
Woodcutting.checkForDoubleDrop(blockState);
|
|
}
|
|
|
|
CustomBlock customBlock = ModUtils.getCustomBlock(blockState);
|
|
xp = customBlock.getXpGain();
|
|
|
|
Misc.dropItems(blockState.getLocation(), block.getDrops());
|
|
}
|
|
else if (ModUtils.isCustomLeafBlock(blockState)) {
|
|
Misc.randomDropItems(blockState.getLocation(), block.getDrops(), 10.0);
|
|
}
|
|
else {
|
|
Tree tree = (Tree) blockState.getData();
|
|
tree.setDirection(BlockFace.UP);
|
|
|
|
switch (material) {
|
|
case LOG:
|
|
if (canGetDoubleDrops()) {
|
|
Woodcutting.checkForDoubleDrop(blockState);
|
|
}
|
|
xp += Woodcutting.getExperienceFromLog(blockState, ExperienceGainMethod.TREE_FELLER);
|
|
Misc.dropItems(blockState.getLocation(), block.getDrops());
|
|
break;
|
|
|
|
case LEAVES:
|
|
Misc.randomDropItems(blockState.getLocation(), block.getDrops(), 10.0);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
blockState.setType(Material.AIR);
|
|
blockState.update(true);
|
|
}
|
|
|
|
applyXpGain(xp);
|
|
}
|
|
|
|
}
|