|
|
@ -50,9 +50,12 @@ import static java.util.Objects.requireNonNull;
|
|
|
|
public class HerbalismManager extends SkillManager {
|
|
|
|
public class HerbalismManager extends SkillManager {
|
|
|
|
private final static HashMap<String, Integer> plantBreakLimits;
|
|
|
|
private final static HashMap<String, Integer> plantBreakLimits;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static final String CACTUS_STR = "cactus";
|
|
|
|
|
|
|
|
private static final String CACTUS_FLOWER_STR = "cactus_flower";
|
|
|
|
|
|
|
|
|
|
|
|
static {
|
|
|
|
static {
|
|
|
|
plantBreakLimits = new HashMap<>();
|
|
|
|
plantBreakLimits = new HashMap<>();
|
|
|
|
plantBreakLimits.put("cactus", 3);
|
|
|
|
plantBreakLimits.put(CACTUS_STR, 3);
|
|
|
|
plantBreakLimits.put("bamboo", 20);
|
|
|
|
plantBreakLimits.put("bamboo", 20);
|
|
|
|
plantBreakLimits.put("sugar_cane", 3);
|
|
|
|
plantBreakLimits.put("sugar_cane", 3);
|
|
|
|
plantBreakLimits.put("kelp", 26);
|
|
|
|
plantBreakLimits.put("kelp", 26);
|
|
|
@ -68,10 +71,13 @@ public class HerbalismManager extends SkillManager {
|
|
|
|
if (!RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.HERBALISM_GREEN_THUMB))
|
|
|
|
if (!RankUtils.hasUnlockedSubskill(getPlayer(), SubSkillType.HERBALISM_GREEN_THUMB))
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
Player player = getPlayer();
|
|
|
|
final Player player = getPlayer();
|
|
|
|
ItemStack item = player.getInventory().getItemInMainHand();
|
|
|
|
final ItemStack item = player.getInventory().getItemInMainHand();
|
|
|
|
|
|
|
|
|
|
|
|
return item.getAmount() > 0 && item.getType() == Material.WHEAT_SEEDS && BlockUtils.canMakeMossy(blockState) && Permissions.greenThumbBlock(player, blockState.getType());
|
|
|
|
return item.getAmount() > 0
|
|
|
|
|
|
|
|
&& item.getType() == Material.WHEAT_SEEDS
|
|
|
|
|
|
|
|
&& BlockUtils.canMakeMossy(blockState.getBlock())
|
|
|
|
|
|
|
|
&& Permissions.greenThumbBlock(player, blockState.getType());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public boolean canUseShroomThumb(BlockState blockState) {
|
|
|
|
public boolean canUseShroomThumb(BlockState blockState) {
|
|
|
@ -163,10 +169,6 @@ public class HerbalismManager extends SkillManager {
|
|
|
|
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.HERBALISM_HYLIAN_LUCK);
|
|
|
|
return Permissions.isSubSkillEnabled(getPlayer(), SubSkillType.HERBALISM_HYLIAN_LUCK);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public boolean canGreenTerraBlock(BlockState blockState) {
|
|
|
|
|
|
|
|
return mmoPlayer.getAbilityMode(SuperAbilityType.GREEN_TERRA) && BlockUtils.canMakeMossy(blockState);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public boolean canActivateAbility() {
|
|
|
|
public boolean canActivateAbility() {
|
|
|
|
return mmoPlayer.getToolPreparationMode(ToolType.HOE) && Permissions.greenTerra(getPlayer());
|
|
|
|
return mmoPlayer.getToolPreparationMode(ToolType.HOE) && Permissions.greenTerra(getPlayer());
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -222,9 +224,9 @@ public class HerbalismManager extends SkillManager {
|
|
|
|
* @param blockBreakEvent The Block Break Event to process
|
|
|
|
* @param blockBreakEvent The Block Break Event to process
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public void processHerbalismBlockBreakEvent(BlockBreakEvent blockBreakEvent) {
|
|
|
|
public void processHerbalismBlockBreakEvent(BlockBreakEvent blockBreakEvent) {
|
|
|
|
Player player = getPlayer();
|
|
|
|
final Player player = getPlayer();
|
|
|
|
|
|
|
|
|
|
|
|
Block block = blockBreakEvent.getBlock();
|
|
|
|
final Block block = blockBreakEvent.getBlock();
|
|
|
|
|
|
|
|
|
|
|
|
if (mcMMO.p.getGeneralConfig().getHerbalismPreventAFK() && player.isInsideVehicle()) {
|
|
|
|
if (mcMMO.p.getGeneralConfig().getHerbalismPreventAFK() && player.isInsideVehicle()) {
|
|
|
|
if (block.hasMetadata(MetadataConstants.METADATA_KEY_REPLANT)) {
|
|
|
|
if (block.hasMetadata(MetadataConstants.METADATA_KEY_REPLANT)) {
|
|
|
@ -235,7 +237,7 @@ public class HerbalismManager extends SkillManager {
|
|
|
|
|
|
|
|
|
|
|
|
//Check if the plant was recently replanted
|
|
|
|
//Check if the plant was recently replanted
|
|
|
|
if (block.getBlockData() instanceof Ageable ageableCrop) {
|
|
|
|
if (block.getBlockData() instanceof Ageable ageableCrop) {
|
|
|
|
if (block.getMetadata(MetadataConstants.METADATA_KEY_REPLANT).size() >= 1) {
|
|
|
|
if (!block.getMetadata(MetadataConstants.METADATA_KEY_REPLANT).isEmpty()) {
|
|
|
|
if (block.getMetadata(MetadataConstants.METADATA_KEY_REPLANT).get(0).asBoolean()) {
|
|
|
|
if (block.getMetadata(MetadataConstants.METADATA_KEY_REPLANT).get(0).asBoolean()) {
|
|
|
|
if (isAgeableMature(ageableCrop)) {
|
|
|
|
if (isAgeableMature(ageableCrop)) {
|
|
|
|
block.removeMetadata(MetadataConstants.METADATA_KEY_REPLANT, mcMMO.p);
|
|
|
|
block.removeMetadata(MetadataConstants.METADATA_KEY_REPLANT, mcMMO.p);
|
|
|
@ -254,9 +256,9 @@ public class HerbalismManager extends SkillManager {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
//Grab all broken blocks
|
|
|
|
//Grab all broken blocks
|
|
|
|
HashSet<Block> brokenBlocks = getBrokenHerbalismBlocks(blockBreakEvent);
|
|
|
|
final HashSet<Block> brokenBlocks = getBrokenHerbalismBlocks(blockBreakEvent);
|
|
|
|
|
|
|
|
|
|
|
|
if (brokenBlocks.size() == 0)
|
|
|
|
if (brokenBlocks.isEmpty())
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
//Handle rewards, xp, ability interactions, etc
|
|
|
|
//Handle rewards, xp, ability interactions, etc
|
|
|
@ -272,7 +274,8 @@ public class HerbalismManager extends SkillManager {
|
|
|
|
if (blockBreakEvent.isCancelled())
|
|
|
|
if (blockBreakEvent.isCancelled())
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
BlockState originalBreak = blockBreakEvent.getBlock().getState();
|
|
|
|
final BlockState originalBreak = blockBreakEvent.getBlock().getState();
|
|
|
|
|
|
|
|
// TODO: Storing this boolean for no reason, refactor
|
|
|
|
boolean greenThumbActivated = false;
|
|
|
|
boolean greenThumbActivated = false;
|
|
|
|
|
|
|
|
|
|
|
|
//TODO: The design of Green Terra needs to change, this is a mess
|
|
|
|
//TODO: The design of Green Terra needs to change, this is a mess
|
|
|
@ -322,12 +325,12 @@ public class HerbalismManager extends SkillManager {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//Give out XP to the non-chorus blocks
|
|
|
|
//Give out XP to the non-chorus blocks
|
|
|
|
if (noDelayPlantBlocks.size() > 0) {
|
|
|
|
if (!noDelayPlantBlocks.isEmpty()) {
|
|
|
|
//Note: Will contain 1 chorus block if the original block was a chorus block, this is to prevent delays for the XP bar
|
|
|
|
//Note: Will contain 1 chorus block if the original block was a chorus block, this is to prevent delays for the XP bar
|
|
|
|
awardXPForPlantBlocks(noDelayPlantBlocks);
|
|
|
|
awardXPForPlantBlocks(noDelayPlantBlocks);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (delayedChorusBlocks.size() > 0) {
|
|
|
|
if (!delayedChorusBlocks.isEmpty()) {
|
|
|
|
//Check XP for chorus blocks
|
|
|
|
//Check XP for chorus blocks
|
|
|
|
DelayedHerbalismXPCheckTask delayedHerbalismXPCheckTask = new DelayedHerbalismXPCheckTask(mmoPlayer, delayedChorusBlocks);
|
|
|
|
DelayedHerbalismXPCheckTask delayedHerbalismXPCheckTask = new DelayedHerbalismXPCheckTask(mmoPlayer, delayedChorusBlocks);
|
|
|
|
|
|
|
|
|
|
|
@ -356,15 +359,9 @@ public class HerbalismManager extends SkillManager {
|
|
|
|
|
|
|
|
|
|
|
|
//Check for double drops
|
|
|
|
//Check for double drops
|
|
|
|
if (!mcMMO.getUserBlockTracker().isIneligible(brokenPlant)) {
|
|
|
|
if (!mcMMO.getUserBlockTracker().isIneligible(brokenPlant)) {
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
|
|
|
|
* Natural Blocks
|
|
|
|
* Natural Blocks
|
|
|
|
*
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
//Not all things that are natural should give double drops, make sure its fully mature as well
|
|
|
|
//Not all things that are natural should give double drops, make sure its fully mature as well
|
|
|
|
if (plantData instanceof Ageable ageable) {
|
|
|
|
if (plantData instanceof Ageable ageable) {
|
|
|
|
|
|
|
|
|
|
|
@ -378,13 +375,9 @@ public class HerbalismManager extends SkillManager {
|
|
|
|
markForBonusDrops(brokenPlant);
|
|
|
|
markForBonusDrops(brokenPlant);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
|
|
|
|
* Unnatural Blocks
|
|
|
|
* Unnatural Blocks
|
|
|
|
*
|
|
|
|
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
//If it's a crop, we need to reward XP when its fully grown
|
|
|
|
//If it's a crop, we need to reward XP when its fully grown
|
|
|
|
if (isAgeableAndFullyMature(plantData) && !isBizarreAgeable(plantData)) {
|
|
|
|
if (isAgeableAndFullyMature(plantData) && !isBizarreAgeable(plantData)) {
|
|
|
|
//Add metadata to mark this block for double or triple drops
|
|
|
|
//Add metadata to mark this block for double or triple drops
|
|
|
@ -401,7 +394,7 @@ public class HerbalismManager extends SkillManager {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public boolean isBizarreAgeable(BlockData blockData) {
|
|
|
|
public boolean isBizarreAgeable(BlockData blockData) {
|
|
|
|
if (blockData instanceof Ageable) {
|
|
|
|
if (blockData instanceof Ageable) {
|
|
|
|
//Catcus and Sugar Canes cannot be trusted
|
|
|
|
// Cactus and Sugar Canes cannot be trusted
|
|
|
|
return switch (blockData.getMaterial()) {
|
|
|
|
return switch (blockData.getMaterial()) {
|
|
|
|
case CACTUS, KELP, SUGAR_CANE, BAMBOO -> true;
|
|
|
|
case CACTUS, KELP, SUGAR_CANE, BAMBOO -> true;
|
|
|
|
default -> false;
|
|
|
|
default -> false;
|
|
|
@ -440,12 +433,8 @@ public class HerbalismManager extends SkillManager {
|
|
|
|
|
|
|
|
|
|
|
|
if (mcMMO.getUserBlockTracker().isIneligible(brokenBlockNewState)) {
|
|
|
|
if (mcMMO.getUserBlockTracker().isIneligible(brokenBlockNewState)) {
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
|
|
|
|
* Unnatural Blocks
|
|
|
|
* Unnatural Blocks
|
|
|
|
*
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
//If its a Crop we need to reward XP when its fully grown
|
|
|
|
//If its a Crop we need to reward XP when its fully grown
|
|
|
|
if (isAgeableAndFullyMature(plantData) && !isBizarreAgeable(plantData)) {
|
|
|
|
if (isAgeableAndFullyMature(plantData) && !isBizarreAgeable(plantData)) {
|
|
|
|
xpToReward += ExperienceConfig.getInstance().getXp(PrimarySkillType.HERBALISM, brokenBlockNewState.getType());
|
|
|
|
xpToReward += ExperienceConfig.getInstance().getXp(PrimarySkillType.HERBALISM, brokenBlockNewState.getType());
|
|
|
@ -457,13 +446,9 @@ public class HerbalismManager extends SkillManager {
|
|
|
|
mcMMO.getUserBlockTracker().setEligible(brokenBlockNewState);
|
|
|
|
mcMMO.getUserBlockTracker().setEligible(brokenBlockNewState);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
*
|
|
|
|
|
|
|
|
* Natural Blocks
|
|
|
|
* Natural Blocks
|
|
|
|
*
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Calculate XP
|
|
|
|
//Calculate XP
|
|
|
|
|
|
|
|
if (plantData instanceof Ageable plantAgeable) {
|
|
|
|
if (plantData instanceof Ageable plantAgeable) {
|
|
|
|
|
|
|
|
|
|
|
|
if (isAgeableMature(plantAgeable) || isBizarreAgeable(plantData)) {
|
|
|
|
if (isAgeableMature(plantAgeable) || isBizarreAgeable(plantData)) {
|
|
|
@ -481,7 +466,7 @@ public class HerbalismManager extends SkillManager {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (mmoPlayer.isDebugMode()) {
|
|
|
|
if (mmoPlayer.isDebugMode()) {
|
|
|
|
mmoPlayer.getPlayer().sendMessage("Plants processed: "+brokenPlants.size());
|
|
|
|
mmoPlayer.getPlayer().sendMessage("Plants processed: " + brokenPlants.size());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//Reward XP
|
|
|
|
//Reward XP
|
|
|
@ -489,7 +474,6 @@ public class HerbalismManager extends SkillManager {
|
|
|
|
// get first block from hash set using stream API
|
|
|
|
// get first block from hash set using stream API
|
|
|
|
final Block firstBlock = brokenPlants.stream().findFirst().orElse(null);
|
|
|
|
final Block firstBlock = brokenPlants.stream().findFirst().orElse(null);
|
|
|
|
if (firstBlock != null
|
|
|
|
if (firstBlock != null
|
|
|
|
&& firstXpReward != -1
|
|
|
|
|
|
|
|
&& ExperienceConfig.getInstance().limitXPOnTallPlants()
|
|
|
|
&& ExperienceConfig.getInstance().limitXPOnTallPlants()
|
|
|
|
&& plantBreakLimits.containsKey(firstBlock.getType().getKey().getKey())) {
|
|
|
|
&& plantBreakLimits.containsKey(firstBlock.getType().getKey().getKey())) {
|
|
|
|
int limit = plantBreakLimits.get(firstBlock.getType().getKey().getKey()) * firstXpReward;
|
|
|
|
int limit = plantBreakLimits.get(firstBlock.getType().getKey().getKey()) * firstXpReward;
|
|
|
@ -501,16 +485,6 @@ public class HerbalismManager extends SkillManager {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private int getNaturalGrowthLimit(Material brokenPlant) {
|
|
|
|
|
|
|
|
// This is an exploit counter-measure to prevent players from growing unnaturally tall plants and reaping XP
|
|
|
|
|
|
|
|
if (plantBreakLimits.containsKey(brokenPlant.getKey().getKey())) {
|
|
|
|
|
|
|
|
return plantBreakLimits.get(brokenPlant.getKey().getKey());
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public boolean isAgeableMature(Ageable ageable) {
|
|
|
|
public boolean isAgeableMature(Ageable ageable) {
|
|
|
|
return ageable.getAge() == ageable.getMaximumAge()
|
|
|
|
return ageable.getAge() == ageable.getMaximumAge()
|
|
|
|
&& ageable.getAge() != 0;
|
|
|
|
&& ageable.getAge() != 0;
|
|
|
@ -529,7 +503,7 @@ public class HerbalismManager extends SkillManager {
|
|
|
|
int blocksGivingXP = 0;
|
|
|
|
int blocksGivingXP = 0;
|
|
|
|
|
|
|
|
|
|
|
|
for(BlockSnapshot blockSnapshot : brokenPlants) {
|
|
|
|
for(BlockSnapshot blockSnapshot : brokenPlants) {
|
|
|
|
BlockState brokenBlockNewState = blockSnapshot.getBlockRef().getState();
|
|
|
|
final BlockState brokenBlockNewState = blockSnapshot.getBlockRef().getState();
|
|
|
|
|
|
|
|
|
|
|
|
//Remove metadata from the snapshot of blocks
|
|
|
|
//Remove metadata from the snapshot of blocks
|
|
|
|
if (brokenBlockNewState.hasMetadata(MetadataConstants.METADATA_KEY_BONUS_DROPS)) {
|
|
|
|
if (brokenBlockNewState.hasMetadata(MetadataConstants.METADATA_KEY_BONUS_DROPS)) {
|
|
|
@ -570,65 +544,66 @@ public class HerbalismManager extends SkillManager {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
private HashSet<Block> getBrokenHerbalismBlocks(@NotNull BlockBreakEvent blockBreakEvent) {
|
|
|
|
private HashSet<Block> getBrokenHerbalismBlocks(@NotNull BlockBreakEvent blockBreakEvent) {
|
|
|
|
//Get an updated capture of this block
|
|
|
|
//Get an updated capture of this block
|
|
|
|
BlockState originBlockState = blockBreakEvent.getBlock().getState();
|
|
|
|
final BlockState originBlockState = blockBreakEvent.getBlock().getState();
|
|
|
|
Material originBlockMaterial = originBlockState.getType();
|
|
|
|
final Material originBlockMaterial = originBlockState.getType();
|
|
|
|
HashSet<Block> blocksBroken = new HashSet<>(); //Blocks broken
|
|
|
|
final HashSet<Block> blocksBroken = new HashSet<>(); //Blocks broken
|
|
|
|
|
|
|
|
|
|
|
|
//Add the initial block
|
|
|
|
//Add the initial block
|
|
|
|
blocksBroken.add(originBlockState.getBlock());
|
|
|
|
blocksBroken.add(originBlockState.getBlock());
|
|
|
|
|
|
|
|
|
|
|
|
if (!isOneBlockPlant(originBlockMaterial)) {
|
|
|
|
if (!isOneBlockPlant(originBlockMaterial)) {
|
|
|
|
//If the block is a multi-block structure, capture a set of all blocks broken and return that
|
|
|
|
//If the block is a multi-block structure, capture a set of all blocks broken and return that
|
|
|
|
blocksBroken = getBrokenBlocksMultiBlockPlants(originBlockState);
|
|
|
|
addBrokenBlocksMultiBlockPlants(originBlockState, blocksBroken);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//Return all broken plant-blocks
|
|
|
|
//Return all broken plant-blocks
|
|
|
|
return blocksBroken;
|
|
|
|
return blocksBroken;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private HashSet<Block> getBrokenChorusBlocks(BlockState originalBreak) {
|
|
|
|
private void addChorusTreeBrokenBlocks(Block currentBlock, Set<Block> traversed) {
|
|
|
|
return grabChorusTreeBrokenBlocksRecursive(originalBreak.getBlock(), new HashSet<>());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private HashSet<Block> grabChorusTreeBrokenBlocksRecursive(Block currentBlock, HashSet<Block> traversed) {
|
|
|
|
|
|
|
|
if (!isChorusTree(currentBlock.getType()))
|
|
|
|
if (!isChorusTree(currentBlock.getType()))
|
|
|
|
return traversed;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
// Prevent any infinite loops, who needs more than 256 chorus anyways
|
|
|
|
// Prevent any infinite loops, who needs more than 256 chorus anyways
|
|
|
|
if (traversed.size() > 256)
|
|
|
|
if (traversed.size() > 256)
|
|
|
|
return traversed;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
if (!traversed.add(currentBlock))
|
|
|
|
if (!traversed.add(currentBlock))
|
|
|
|
return traversed;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
//Grab all Blocks in the Tree
|
|
|
|
//Grab all Blocks in the Tree
|
|
|
|
for (BlockFace blockFace : new BlockFace[] { BlockFace.UP, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST ,BlockFace.WEST})
|
|
|
|
for (BlockFace blockFace : new BlockFace[] { BlockFace.UP, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST ,BlockFace.WEST})
|
|
|
|
grabChorusTreeBrokenBlocksRecursive(currentBlock.getRelative(blockFace, 1), traversed);
|
|
|
|
addChorusTreeBrokenBlocks(currentBlock.getRelative(blockFace, 1), traversed);
|
|
|
|
|
|
|
|
|
|
|
|
traversed.add(currentBlock);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return traversed;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* Grab a set of all plant blocks that are broken as a result of this event
|
|
|
|
|
|
|
|
* The method to grab these blocks is a bit hacky and does not hook into the API
|
|
|
|
|
|
|
|
* Basically we expect the blocks to be broken if this event is not cancelled and we determine which block are broken on our end rather than any event state captures
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @return a set of plant-blocks broken from this event
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
protected HashSet<Block> getBrokenBlocksMultiBlockPlants(BlockState brokenBlock) {
|
|
|
|
|
|
|
|
//Track the broken blocks
|
|
|
|
|
|
|
|
HashSet<Block> brokenBlocks;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected void addBrokenBlocksMultiBlockPlants(BlockState brokenBlock, Set<Block> brokenBlocks) {
|
|
|
|
if (isChorusBranch(brokenBlock.getType())) {
|
|
|
|
if (isChorusBranch(brokenBlock.getType())) {
|
|
|
|
brokenBlocks = getBrokenChorusBlocks(brokenBlock);
|
|
|
|
addChorusTreeBrokenBlocks(brokenBlock.getBlock(), brokenBlocks);
|
|
|
|
|
|
|
|
} else if (isCactus(brokenBlock.getType())) {
|
|
|
|
|
|
|
|
addCactusBlocks(brokenBlock.getBlock(), brokenBlocks);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
brokenBlocks = getBlocksBrokenAboveOrBelow(
|
|
|
|
addBlocksBrokenAboveOrBelow(brokenBlock.getBlock(), brokenBlocks, mcMMO.getMaterialMapStore().isMultiBlockHangingPlant(brokenBlock.getType()));
|
|
|
|
brokenBlock, false, mcMMO.getMaterialMapStore().isMultiBlockHangingPlant(brokenBlock.getType()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return brokenBlocks;
|
|
|
|
private void addCactusBlocks(Block currentBlock, Set<Block> traversed) {
|
|
|
|
|
|
|
|
if (!isCactus(currentBlock.getType()))
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (traversed.size() > 4) // Max size 3 cactus + flower
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!traversed.add(currentBlock))
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
addCactusBlocks(currentBlock.getRelative(BlockFace.UP), traversed);
|
|
|
|
|
|
|
|
addCactusBlocks(currentBlock.getRelative(BlockFace.DOWN), traversed);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private boolean isCactus(Material material) {
|
|
|
|
|
|
|
|
return material.getKey().getKey().equalsIgnoreCase(CACTUS_STR)
|
|
|
|
|
|
|
|
|| material.getKey().getKey().equalsIgnoreCase(CACTUS_FLOWER_STR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private boolean isChorusBranch(Material blockType) {
|
|
|
|
private boolean isChorusBranch(Material blockType) {
|
|
|
@ -639,25 +614,7 @@ public class HerbalismManager extends SkillManager {
|
|
|
|
return blockType == Material.CHORUS_PLANT || blockType == Material.CHORUS_FLOWER;
|
|
|
|
return blockType == Material.CHORUS_PLANT || blockType == Material.CHORUS_FLOWER;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
private void addBlocksBrokenAboveOrBelow(Block originBlock, Set<Block> brokenBlocks, boolean below) {
|
|
|
|
* Grabs blocks upwards from a target block
|
|
|
|
|
|
|
|
* A lot of Plants/Crops in Herbalism only break vertically from a broken block
|
|
|
|
|
|
|
|
* The vertical search returns early if it runs into anything that is not a multi-block plant
|
|
|
|
|
|
|
|
* Multi-block plants are hard-coded and kept in {@link MaterialMapStore}
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param originBlock The point of the "break"
|
|
|
|
|
|
|
|
* @param inclusive Whether to include the origin block
|
|
|
|
|
|
|
|
* @param below Whether to search down instead of up.
|
|
|
|
|
|
|
|
* @return A set of blocks above the target block which can be assumed to be broken
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
private HashSet<Block> getBlocksBrokenAboveOrBelow(BlockState originBlock, boolean inclusive, boolean below) {
|
|
|
|
|
|
|
|
HashSet<Block> brokenBlocks = new HashSet<>();
|
|
|
|
|
|
|
|
Block block = originBlock.getBlock();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Add the initial block to the set
|
|
|
|
|
|
|
|
if (inclusive)
|
|
|
|
|
|
|
|
brokenBlocks.add(block);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Limit our search
|
|
|
|
//Limit our search
|
|
|
|
int maxHeight = 512;
|
|
|
|
int maxHeight = 512;
|
|
|
|
|
|
|
|
|
|
|
@ -665,8 +622,7 @@ public class HerbalismManager extends SkillManager {
|
|
|
|
|
|
|
|
|
|
|
|
// Search vertically for multi-block plants, exit early if any non-multi block plants
|
|
|
|
// Search vertically for multi-block plants, exit early if any non-multi block plants
|
|
|
|
for (int y = 0; y < maxHeight; y++) {
|
|
|
|
for (int y = 0; y < maxHeight; y++) {
|
|
|
|
//TODO: Should this grab state? It would be more expensive..
|
|
|
|
final Block relativeBlock = originBlock.getRelative(relativeFace, y);
|
|
|
|
Block relativeBlock = block.getRelative(relativeFace, y);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Abandon our search if the block isn't multi
|
|
|
|
//Abandon our search if the block isn't multi
|
|
|
|
if (isOneBlockPlant(relativeBlock.getType()))
|
|
|
|
if (isOneBlockPlant(relativeBlock.getType()))
|
|
|
@ -674,8 +630,6 @@ public class HerbalismManager extends SkillManager {
|
|
|
|
|
|
|
|
|
|
|
|
brokenBlocks.add(relativeBlock);
|
|
|
|
brokenBlocks.add(relativeBlock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return brokenBlocks;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|