Tree detection

This commit is contained in:
Esophose 2019-03-28 11:38:37 -06:00
parent 671236f57d
commit 9329cc1fb6
15 changed files with 355 additions and 66 deletions

View File

@ -29,7 +29,6 @@ public class UltimateTimber extends JavaPlugin {
private CommandManager commandManager;
private ConfigurationManager configurationManager;
private HookManager hookManager;
private MessageManager messageManager;
private TreeAnimationManager treeAnimationManager;
private TreeDefinitionManager treeDefinitionManager;
private TreeDetectionManager treeDetectionManager;
@ -50,15 +49,15 @@ public class UltimateTimber extends JavaPlugin {
this.managers = new HashSet<>();
this.choppingManager = this.registerManager(ChoppingManager.class);
this.commandManager = this.registerManager(CommandManager.class);
this.configurationManager = this.registerManager(ConfigurationManager.class);
this.configurationManager = new ConfigurationManager(this);
this.hookManager = this.registerManager(HookManager.class);
this.messageManager = this.registerManager(MessageManager.class);
this.treeAnimationManager = this.registerManager(TreeAnimationManager.class);
this.treeDefinitionManager = this.registerManager(TreeDefinitionManager.class);
this.treeDetectionManager = this.registerManager(TreeDetectionManager.class);
this.treeFallManager = this.registerManager(TreeFallManager.class);
this.setupVersionAdapter();
this.reload();
new Metrics(this);
@ -80,6 +79,7 @@ public class UltimateTimber extends JavaPlugin {
* Reloads the plugin's settings
*/
public void reload() {
this.configurationManager.reload();
this.managers.forEach(Manager::reload);
}
@ -87,6 +87,7 @@ public class UltimateTimber extends JavaPlugin {
* Disables most of the plugin
*/
public void disable() {
this.configurationManager.disable();
this.managers.forEach(Manager::disable);
}
@ -112,9 +113,9 @@ public class UltimateTimber extends JavaPlugin {
try {
T newManager = managerClass.getConstructor(UltimateTimber.class).newInstance(this);
this.managers.add(newManager);
newManager.reload();
return newManager;
} catch (Exception ignored) {
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
@ -164,15 +165,6 @@ public class UltimateTimber extends JavaPlugin {
return hookManager;
}
/**
* Gets the configuration manager
*
* @return The ConfigurationManager instance
*/
public MessageManager getMessageManager() {
return messageManager;
}
/**
* Gets the tree animation manager
*

View File

@ -9,10 +9,16 @@ import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.Collection;
import java.util.Set;
public interface VersionAdapter {
/**
* Gets the version adapter type
*
* @return The VersionAdapterType
*/
VersionAdapterType getVersionAdapterType();
/**
@ -34,11 +40,19 @@ public interface VersionAdapter {
/**
* Get the items that a tree block should drop when it breaks
*
* @param treeBlock The tree block broken
* @param treeDefinition The tree definition to get the drops for
* @param treeBlock The tree block
* @return A Set of ItemStacks that should be dropped
*/
Set<ItemStack> getTreeBlockDrops(TreeBlock treeBlock, TreeDefinition treeDefinition);
Collection<ItemStack> getBlockDrops(TreeBlock treeBlock);
/**
* Checks if two block states are similar
*
* @param blockState1 The first BlockState
* @param blockState2 The second BlockState
* @return True if the BlockStates are similar, otherwise false
*/
boolean areBlockStatesSimilar(BlockState blockState1, BlockState blockState2);
/**
* Applies damage to a tool

View File

@ -5,13 +5,12 @@ import com.songoda.ultimatetimber.adapter.VersionAdapterType;
import com.songoda.ultimatetimber.tree.FallingTreeBlock;
import com.songoda.ultimatetimber.tree.TreeBlock;
import com.songoda.ultimatetimber.tree.TreeBlockSet;
import com.songoda.ultimatetimber.tree.TreeDefinition;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.Set;
import java.util.Collection;
public class CurrentAdapter implements VersionAdapter {
@ -31,10 +30,15 @@ public class CurrentAdapter implements VersionAdapter {
}
@Override
public Set<ItemStack> getTreeBlockDrops(TreeBlock treeBlock, TreeDefinition treeDefinition) {
public Collection<ItemStack> getBlockDrops(TreeBlock treeBlock) {
return null;
}
@Override
public boolean areBlockStatesSimilar(BlockState blockState1, BlockState blockState2) {
return false;
}
@Override
public void applyToolDurability(TreeBlockSet<Block> treeBlocks, ItemStack tool) {

View File

@ -5,13 +5,12 @@ import com.songoda.ultimatetimber.adapter.VersionAdapterType;
import com.songoda.ultimatetimber.tree.FallingTreeBlock;
import com.songoda.ultimatetimber.tree.TreeBlock;
import com.songoda.ultimatetimber.tree.TreeBlockSet;
import com.songoda.ultimatetimber.tree.TreeDefinition;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.Set;
import java.util.Collection;
public class LegacyAdapter implements VersionAdapter {
@ -31,10 +30,15 @@ public class LegacyAdapter implements VersionAdapter {
}
@Override
public Set<ItemStack> getTreeBlockDrops(TreeBlock treeBlock, TreeDefinition treeDefinition) {
public Collection<ItemStack> getBlockDrops(TreeBlock treeBlock) {
return null;
}
@Override
public boolean areBlockStatesSimilar(BlockState blockState1, BlockState blockState2) {
return false;
}
@Override
public void applyToolDurability(TreeBlockSet<Block> treeBlocks, ItemStack tool) {

View File

@ -20,7 +20,7 @@ public abstract class TreeEvent extends PlayerEvent {
/**
* Get the tree blocks
*
* @return tree checker for the tree
* @return The blocks that are part of the tree
*/
public TreeBlockSet<Block> getTreeBlocks() {
return this.treeBlocks;

View File

@ -6,6 +6,7 @@ import com.songoda.ultimatetimber.hooks.McMMOHook;
import com.songoda.ultimatetimber.hooks.TimberHook;
import com.songoda.ultimatetimber.tree.TreeBlockSet;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import java.util.HashSet;
@ -56,7 +57,7 @@ public class HookManager extends Manager {
* @param player The player to apply the hook for
* @param treeBlocks The blocks of the tree that were broken
*/
public void applyHooks(Player player, TreeBlockSet treeBlocks) {
public void applyHooks(Player player, TreeBlockSet<Block> treeBlocks) {
Set<TimberHook> invalidHooks = new HashSet<>();
for (TimberHook hook : this.hooks) {
try {

View File

@ -1,33 +0,0 @@
package com.songoda.ultimatetimber.manager;
import com.songoda.ultimatetimber.UltimateTimber;
public class MessageManager extends Manager {
public enum MessageType {
TOGGLE_ON,
TOGGLE_OFF,
RELOAD
}
private final String prefix = "&8[&6UltimateTimber&8]";
public MessageManager(UltimateTimber ultimateTimber) {
super(ultimateTimber);
}
@Override
public void reload() {
}
@Override
public void disable() {
}
public String getPrefix() {
return this.prefix;
}
}

View File

@ -8,7 +8,6 @@ import com.songoda.ultimatetimber.tree.TreeDefinition;
import com.songoda.ultimatetimber.tree.TreeLoot;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
@ -56,6 +55,7 @@ public class TreeDefinitionManager extends Manager {
Set<BlockState> leafBlockStates = new HashSet<>();
BlockState saplingBlockState;
int maxLeafDistanceFromLog;
boolean detectLeavesDiagonally;
boolean dropOriginalLog;
boolean dropOriginalLeaf;
Set<TreeLoot> logLoot = new HashSet<>();
@ -70,6 +70,7 @@ public class TreeDefinitionManager extends Manager {
saplingBlockState = versionAdapter.parseBlockStateFromString(tree.getString("sapling"));
maxLeafDistanceFromLog = tree.getInt("max-leaf-distance-from-log");
detectLeavesDiagonally = tree.getBoolean("search-for-leaves-diagonally");
dropOriginalLog = tree.getBoolean("drop-original-log");
dropOriginalLeaf = tree.getBoolean("drop-original-leaf");
@ -84,7 +85,7 @@ public class TreeDefinitionManager extends Manager {
for (String itemStackString : tree.getStringList("required-tools"))
requiredTools.add(versionAdapter.parseItemStackFromString(itemStackString));
this.treeDefinitions.add(new TreeDefinition(key, logBlockStates, leafBlockStates, saplingBlockState, maxLeafDistanceFromLog, dropOriginalLog, dropOriginalLeaf, logLoot, leafLoot, requiredTools));
this.treeDefinitions.add(new TreeDefinition(key, logBlockStates, leafBlockStates, saplingBlockState, maxLeafDistanceFromLog, detectLeavesDiagonally, dropOriginalLog, dropOriginalLeaf, logLoot, leafLoot, requiredTools));
}
// Load global log drops
@ -107,6 +108,54 @@ public class TreeDefinitionManager extends Manager {
this.treeDefinitions.clear();
}
/**
* Gets a Set of possible TreeDefinitions that match the given BlockState
*
* @param blockState The BlockState to check
* @return A Set of TreeDefinitions for the given BlockState
*/
public Set<TreeDefinition> getTreeDefinitionsForLog(BlockState blockState) {
return this.narrowTreeDefinition(this.treeDefinitions, blockState, TreeBlockType.LOG);
}
/**
* Narrows a Set of TreeDefinitions down to ones matching the given BlockState and TreeBlockType
*
* @param possibleTreeDefinitions The possible TreeDefinitions
* @param blockState The BlockState to narrow to
* @param treeBlockType The TreeBlockType of the given BlockState
* @return A Set of TreeDefinitions narrowed down
*/
public Set<TreeDefinition> narrowTreeDefinition(Set<TreeDefinition> possibleTreeDefinitions, BlockState blockState, TreeBlockType treeBlockType) {
VersionAdapter versionAdapter = this.ultimateTimber.getVersionAdapter();
Set<TreeDefinition> matchingTreeDefinitions = new HashSet<>();
switch (treeBlockType) {
case LOG:
for (TreeDefinition treeDefinition : this.treeDefinitions) {
for (BlockState logBlockState : treeDefinition.getLogBlockStates()) {
if (versionAdapter.areBlockStatesSimilar(logBlockState, blockState)) {
matchingTreeDefinitions.add(treeDefinition);
break;
}
}
}
break;
case LEAF:
for (TreeDefinition treeDefinition : this.treeDefinitions) {
for (BlockState leafBlockState : treeDefinition.getLeafBlockStates()) {
if (versionAdapter.areBlockStatesSimilar(leafBlockState, blockState)) {
matchingTreeDefinitions.add(treeDefinition);
break;
}
}
}
break;
}
return matchingTreeDefinitions;
}
/**
* Checks if a given tool is valid for a given tree definition, also takes into account global tools
*

View File

@ -1,18 +1,65 @@
package com.songoda.ultimatetimber.manager;
import com.songoda.ultimatetimber.UltimateTimber;
import com.songoda.ultimatetimber.adapter.VersionAdapter;
import com.songoda.ultimatetimber.tree.*;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.util.Vector;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
public class TreeDetectionManager extends Manager {
private UltimateTimber ultimateTimber;
private final Set<Vector> VALID_TRUNK_OFFSETS, VALID_BRANCH_OFFSETS, VALID_LEAF_OFFSETS;
private TreeDefinitionManager treeDefinitionManager;
private int maxBranchBlocksAllowed;
private int numLeavesRequiredForTree;
private boolean allowMixedTreeTypes;
private boolean onlyBreakLogsUpwards;
private boolean destroyBaseLog;
private boolean entireTreeBase;
public TreeDetectionManager(UltimateTimber ultimateTimber) {
super(ultimateTimber);
VALID_BRANCH_OFFSETS = new HashSet<>();
VALID_TRUNK_OFFSETS = new HashSet<>();
VALID_LEAF_OFFSETS = new HashSet<>();
// 3x2x3 centered around log, excluding -y axis
for (int x = -1; x <= 1; x++)
for (int y = 0; y <= 1; y++)
for (int z = -1; z <= 1; z++)
VALID_BRANCH_OFFSETS.add(new Vector(x, y, z));
// 3x3x3 centered around log
for (int x = -1; x <= 1; x++)
for (int y = -1; y <= 1; y++)
for (int z = -1; z <= 1; z++)
VALID_TRUNK_OFFSETS.add(new Vector(x, y, z));
// Adjacent blocks to log
for (int i = -1; i <= 1; i += 2) {
VALID_LEAF_OFFSETS.add(new Vector(i, 0, 0));
VALID_LEAF_OFFSETS.add(new Vector(0, i, 0));
VALID_LEAF_OFFSETS.add(new Vector(0, 0, i));
}
}
@Override
public void reload() {
this.treeDefinitionManager = this.ultimateTimber.getTreeDefinitionManager();
this.maxBranchBlocksAllowed = ConfigurationManager.Setting.MAX_LOGS_PER_CHOP.getInt();
this.numLeavesRequiredForTree = ConfigurationManager.Setting.LEAVES_REQUIRED_FOR_TREE.getInt();
this.allowMixedTreeTypes = ConfigurationManager.Setting.MIX_ALL_TREE_TYPES.getBoolean();
this.onlyBreakLogsUpwards = ConfigurationManager.Setting.ONLY_DETECT_LOGS_UPWARDS.getBoolean();
this.destroyBaseLog = ConfigurationManager.Setting.DESTROY_INITIATED_BLOCK.getBoolean();
this.entireTreeBase = ConfigurationManager.Setting.BREAK_ENTIRE_TREE_BASE.getBoolean();
}
@Override
@ -20,4 +67,154 @@ public class TreeDetectionManager extends Manager {
}
/**
* Detects a tree given an initial starting block
*
* @param initialBlock The starting Block of the detection
* @return A DetectedTree if one was found, otherwise null
*/
public DetectedTree detectTree(Block initialBlock) {
TreeBlock initialTreeBlock = new TreeBlock(initialBlock, TreeBlockType.LOG);
TreeBlockSet<Block> detectedTreeBlocks = new TreeBlockSet<>(initialTreeBlock);
Set<TreeDefinition> possibleTreeDefinitions = treeDefinitionManager.getTreeDefinitionsForLog(initialBlock.getState());
// Detect tree trunk
Set<Block> trunkBlocks = new HashSet<>();
trunkBlocks.add(initialBlock);
Block targetBlock = initialBlock;
while (this.isValidLogType(possibleTreeDefinitions, (targetBlock = targetBlock.getRelative(BlockFace.UP)))) {
TreeBlock treeBlock = new TreeBlock(targetBlock, TreeBlockType.LOG);
detectedTreeBlocks.add(treeBlock);
trunkBlocks.add(initialBlock);
possibleTreeDefinitions.retainAll(this.treeDefinitionManager.narrowTreeDefinition(possibleTreeDefinitions, targetBlock.getState(), TreeBlockType.LOG));
}
// Tree must be at least 2 blocks tall
if (detectedTreeBlocks.size() < 2)
return null;
// Detect branches off the main trunk
for (Block trunkBlock : trunkBlocks)
this.recursiveBranchSearch(possibleTreeDefinitions, detectedTreeBlocks, trunkBlock, initialBlock.getY());
// Detect leaves off the trunk/branches
Set<ITreeBlock<Block>> branchBlocks = new HashSet<>(detectedTreeBlocks.getLogBlocks());
for (ITreeBlock<Block> branchBlock : branchBlocks)
this.recursiveLeafSearch(possibleTreeDefinitions, detectedTreeBlocks, branchBlock.getBlock(), 1);
// Trees need at least a certain number of leaves
if (detectedTreeBlocks.getLeafBlocks().size() < this.numLeavesRequiredForTree)
return null;
// TODO: Soil detection
// Delete the starting block if applicable
if (this.destroyBaseLog)
detectedTreeBlocks.remove(initialTreeBlock);
// Use the first tree definition in the set
return new DetectedTree(possibleTreeDefinitions.iterator().next(), detectedTreeBlocks);
}
/**
* Recursively searches for branches off a given block
*
* @param treeDefinitions The possible tree definitions
* @param treeBlocks The detected tree blocks
* @param block The next block to check for a branch
* @param startingBlockY The Y coordinate of the initial block
*/
private void recursiveBranchSearch(Set<TreeDefinition> treeDefinitions, TreeBlockSet<Block> treeBlocks, Block block, int startingBlockY) {
if (treeBlocks.size() > this.maxBranchBlocksAllowed)
return;
for (Vector offset : this.onlyBreakLogsUpwards ? VALID_BRANCH_OFFSETS : VALID_TRUNK_OFFSETS) {
Block targetBlock = block.getRelative(offset.getBlockX(), offset.getBlockY(), offset.getBlockZ());
TreeBlock treeBlock = new TreeBlock(targetBlock, TreeBlockType.LOG);
if (this.isValidLogType(treeDefinitions, targetBlock) && !treeBlocks.contains(treeBlock)) {
treeBlocks.add(treeBlock);
treeDefinitions.retainAll(this.treeDefinitionManager.narrowTreeDefinition(treeDefinitions, block.getState(), TreeBlockType.LOG));
if (!this.onlyBreakLogsUpwards || targetBlock.getLocation().getBlockY() > startingBlockY)
this.recursiveBranchSearch(treeDefinitions, treeBlocks, targetBlock, startingBlockY);
}
}
}
/**
* Recursively searches for leaves that are next to this tree
*
* @param treeDefinitions The possible tree definitions
* @param treeBlocks The detected tree blocks
* @param block The next block to check for a leaf
* @param distanceFromLog The distance this leaf is from a log
*/
private void recursiveLeafSearch(Set<TreeDefinition> treeDefinitions, TreeBlockSet<Block> treeBlocks, Block block, int distanceFromLog) {
int maxDistanceFromLog = treeDefinitions.stream().max(Comparator.comparingInt(TreeDefinition::getMaxLeafDistanceFromLog)).get().getMaxLeafDistanceFromLog();
boolean detectLeavesDiagonally = treeDefinitions.stream().anyMatch(TreeDefinition::shouldDetectLeavesDiagonally);
if (distanceFromLog > maxDistanceFromLog)
return;
for (Vector offset : !detectLeavesDiagonally ? VALID_LEAF_OFFSETS : VALID_TRUNK_OFFSETS) {
Block targetBlock = block.getRelative(offset.getBlockX(), offset.getBlockY(), offset.getBlockZ());
TreeBlock treeBlock = new TreeBlock(targetBlock, TreeBlockType.LEAF);
if (this.isValidLeafType(treeDefinitions, targetBlock)) {
if (!treeBlocks.contains(treeBlock) && !this.doesLeafBorderInvalidLog(treeDefinitions, treeBlocks, targetBlock)) {
treeBlocks.add(treeBlock);
treeDefinitions.retainAll(this.treeDefinitionManager.narrowTreeDefinition(treeDefinitions, block.getState(), TreeBlockType.LEAF));
}
this.recursiveLeafSearch(treeDefinitions, treeBlocks, targetBlock, distanceFromLog + 1);
}
}
}
/**
* Checks if a leaf is bordering a log that isn't part of this tree
*
* @param treeDefinitions The possible tree definitions
* @param treeBlocks The detected tree blocks
* @param block The block to check
* @return True if the leaf borders an invalid log, otherwise false
*/
private boolean doesLeafBorderInvalidLog(Set<TreeDefinition> treeDefinitions, TreeBlockSet<Block> treeBlocks, Block block) {
for (Vector offset : VALID_TRUNK_OFFSETS) {
Block targetBlock = block.getRelative(offset.getBlockX(), offset.getBlockY(), offset.getBlockZ());
if (this.isValidLogType(treeDefinitions, targetBlock) && !treeBlocks.contains(new TreeBlock(targetBlock, TreeBlockType.LOG)))
return true;
}
return false;
}
/**
* Checks if a given block is valid for the given TreeDefinitions
*
* @param treeDefinitions The Set of TreeDefinitions to compare against
* @param block The Block to check
* @return True if the block is a valid log type, otherwise false
*/
private boolean isValidLogType(Set<TreeDefinition> treeDefinitions, Block block) {
VersionAdapter versionAdapter = this.ultimateTimber.getVersionAdapter();
for (TreeDefinition treeDefinition : treeDefinitions)
for (BlockState logBlockState : treeDefinition.getLogBlockStates())
if (versionAdapter.areBlockStatesSimilar(logBlockState, block.getState()))
return true;
return false;
}
/**
* Checks if a given block is valid for the given TreeDefinitions
*
* @param treeDefinitions The Set of TreeDefinitions to compare against
* @param block The Block to check
* @return True if the block is a valid log type, otherwise false
*/
private boolean isValidLeafType(Set<TreeDefinition> treeDefinitions, Block block) {
VersionAdapter versionAdapter = this.ultimateTimber.getVersionAdapter();
for (TreeDefinition treeDefinition : treeDefinitions)
for (BlockState leafBlockState : treeDefinition.getLeafBlockStates())
if (versionAdapter.areBlockStatesSimilar(leafBlockState, block.getState()))
return true;
return false;
}
}

View File

@ -0,0 +1,33 @@
package com.songoda.ultimatetimber.tree;
import org.bukkit.block.Block;
public class DetectedTree {
private TreeDefinition treeDefinition;
private TreeBlockSet<Block> detectedTreeBlocks;
public DetectedTree(TreeDefinition treeDefinition, TreeBlockSet<Block> detectedTreeBlocks) {
this.treeDefinition = treeDefinition;
this.detectedTreeBlocks = detectedTreeBlocks;
}
/**
* Gets the TreeDefinition of this detected tree
*
* @return The TreeDefinition of this detected tree
*/
public TreeDefinition getTreeDefinition() {
return this.treeDefinition;
}
/**
* Gets the blocks that were detected as part of this tree
*
* @return A TreeBlockSet of detected Blocks
*/
public TreeBlockSet<Block> getDetectedTreeBlocks() {
return this.detectedTreeBlocks;
}
}

View File

@ -1,5 +1,6 @@
package com.songoda.ultimatetimber.tree;
import com.songoda.ultimatetimber.UltimateTimber;
import org.bukkit.Location;
import org.bukkit.entity.FallingBlock;
import org.bukkit.inventory.ItemStack;
@ -15,7 +16,7 @@ public class FallingTreeBlock implements ITreeBlock<FallingBlock> {
public FallingTreeBlock(TreeBlock originalTreeBlock, FallingBlock fallingBlock, TreeBlockType treeBlockType) {
this.fallingBlock = fallingBlock;
this.treeBlockType = treeBlockType;
this.drops = originalTreeBlock.getDrops();
this.drops = UltimateTimber.getInstance().getVersionAdapter().getBlockDrops(originalTreeBlock);
}
@Override

View File

@ -1,11 +1,11 @@
package com.songoda.ultimatetimber.tree;
import com.songoda.ultimatetimber.UltimateTimber;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.inventory.ItemStack;
import java.util.Collection;
import java.util.Set;
public class TreeBlock implements ITreeBlock<Block> {
@ -29,7 +29,7 @@ public class TreeBlock implements ITreeBlock<Block> {
@Override
public Collection<ItemStack> getDrops() {
return this.block.getDrops();
return UltimateTimber.getInstance().getVersionAdapter().getBlockDrops(this);
}
@Override

View File

@ -12,18 +12,20 @@ public class TreeDefinition {
private final Set<BlockState> logBlockStates, leafBlockStates;
private final BlockState saplingBlockState;
private final int maxLeafDistanceFromLog;
private final boolean detectLeavesDiagonally;
private final boolean dropOriginalLog, dropOriginalLeaf;
private final Set<TreeLoot> logLoot, leafLoot;
private final Set<ItemStack> requiredTools;
public TreeDefinition(String key, Set<BlockState> logBlocks, Set<BlockState> leafBlocks, BlockState saplingBlockState,
int maxLeafDistanceFromLog, boolean dropOriginalLog, boolean dropOriginalLeaf,
int maxLeafDistanceFromLog, boolean detectLeavesDiagonally, boolean dropOriginalLog, boolean dropOriginalLeaf,
Set<TreeLoot> logLoot, Set<TreeLoot> leafLoot, Set<ItemStack> requiredTools) {
this.key = key;
this.logBlockStates = logBlocks;
this.leafBlockStates = leafBlocks;
this.saplingBlockState = saplingBlockState;
this.maxLeafDistanceFromLog = maxLeafDistanceFromLog;
this.detectLeavesDiagonally = detectLeavesDiagonally;
this.dropOriginalLog = dropOriginalLog;
this.dropOriginalLeaf = dropOriginalLeaf;
this.logLoot = logLoot;
@ -76,6 +78,15 @@ public class TreeDefinition {
return this.maxLeafDistanceFromLog;
}
/**
* Gets if tree detection should check for leaves diagonally
*
* @return True if leaves should be searched for diagonally, otherwise false
*/
public boolean shouldDetectLeavesDiagonally() {
return this.detectLeavesDiagonally;
}
/**
* Gets if the logs of this tree should drop their original block
*

View File

@ -125,6 +125,7 @@ trees:
- OAK_LEAVES
sapling: OAK_SAPLING
max-leaf-distance-from-log: 6
search-for-leaves-diagonally: false
drop-original-log: true
drop-original-leaf: false
log-loot: []
@ -146,6 +147,7 @@ trees:
- SPRUCE_LEAVES
sapling: SPRUCE_SAPLING
max-leaf-distance-from-log: 6
search-for-leaves-diagonally: false
drop-original-log: true
drop-original-leaf: false
log-loot: []
@ -164,6 +166,7 @@ trees:
- SPRUCE_BIRCH
sapling: BIRCH_SAPLING
max-leaf-distance-from-log: 4
search-for-leaves-diagonally: false
drop-original-log: true
drop-original-leaf: false
log-loot: []
@ -182,6 +185,7 @@ trees:
- SPRUCE_LEAVES
sapling: SPRUCE_SAPLING
max-leaf-distance-from-log: 5
search-for-leaves-diagonally: false
drop-original-log: true
drop-original-leaf: false
log-loot: []
@ -200,6 +204,7 @@ trees:
- ACACIA_LEAVES
sapling: ACACIA_SAPLING
max-leaf-distance-from-log: 5
search-for-leaves-diagonally: false
drop-original-log: true
drop-original-leaf: false
log-loot: []
@ -218,6 +223,7 @@ trees:
- DARK_OAK_LEAVES
sapling: DARK_OAK_SAPLING
max-leaf-distance-from-log: 5
search-for-leaves-diagonally: false
drop-original-log: true
drop-original-leaf: false
log-loot: []
@ -236,6 +242,7 @@ trees:
- BROWN_MUSHROOM_BLOCK
sapling: BROWN_MUSHROOM
max-leaf-distance-from-log: 4
search-for-leaves-diagonally: false
drop-original-log: false
drop-original-leaf: false
log-loot: []
@ -251,6 +258,7 @@ trees:
- RED_MUSHROOM_BLOCK
sapling: RED_MUSHROOM
max-leaf-distance-from-log: 4
search-for-leaves-diagonally: true
drop-original-log: false
drop-original-leaf: false
log-loot: []

View File

@ -128,6 +128,7 @@ trees:
- LEAVES:12
sapling: SAPLING:0
max-leaf-distance-from-log: 6
search-for-leaves-diagonally: false
drop-original-log: true
drop-original-leaf: false
log-loot: []
@ -152,6 +153,7 @@ trees:
- LEAVES:13
sapling: SAPLING:1
max-leaf-distance-from-log: 6
search-for-leaves-diagonally: false
drop-original-log: true
drop-original-leaf: false
log-loot: []
@ -173,6 +175,7 @@ trees:
- LEAVES:14
sapling: SAPLING:2
max-leaf-distance-from-log: 4
search-for-leaves-diagonally: false
drop-original-log: true
drop-original-leaf: false
log-loot: []
@ -194,6 +197,7 @@ trees:
- LEAVES:15
sapling: SAPLING:3
max-leaf-distance-from-log: 5
search-for-leaves-diagonally: false
drop-original-log: true
drop-original-leaf: false
log-loot: []
@ -215,6 +219,7 @@ trees:
- LEAVES_2:12
sapling: SAPLING:4
max-leaf-distance-from-log: 5
search-for-leaves-diagonally: false
drop-original-log: true
drop-original-leaf: false
log-loot: []
@ -236,6 +241,7 @@ trees:
- LEAVES:13
sapling: SAPLING:5
max-leaf-distance-from-log: 5
search-for-leaves-diagonally: false
drop-original-log: true
drop-original-leaf: false
log-loot: []
@ -265,6 +271,7 @@ trees:
- HUGE_MUSHROOM_1:14
sapling: BROWN_MUSHROOM
max-leaf-distance-from-log: 4
search-for-leaves-diagonally: false
drop-original-log: false
drop-original-leaf: false
log-loot: []
@ -291,6 +298,7 @@ trees:
- HUGE_MUSHROOM_2:14
sapling: RED_MUSHROOM
max-leaf-distance-from-log: 4
search-for-leaves-diagonally: true
drop-original-log: false
drop-original-leaf: false
log-loot: []