Version 0.0.6

- Added custom loot
- Enhanced the tree search algorithm so it can do branches (fixes the format of a number of trees) among other tweaks
- Fixed a number of loot issues
- Fixed the tree leaf fall replant % being too high
- Added a no animation version of the tree drop
- Added a LeafToSapling converter util
- Fixed durability issue where the plugin was taking too much durability from axes
- Added dirt/grass/coarse dirt ledge compatibility, allows for more flexibility in the tree identification process
This commit is contained in:
MagmaGuy 2018-11-07 04:41:40 +00:00
parent 8aa7c177c1
commit 54ab6c9690
12 changed files with 346 additions and 77 deletions

View File

@ -2,6 +2,7 @@ package com.songoda.ultimatetimber;
import com.songoda.ultimatetimber.commands.CommandHandler; import com.songoda.ultimatetimber.commands.CommandHandler;
import com.songoda.ultimatetimber.configurations.DefaultConfig; import com.songoda.ultimatetimber.configurations.DefaultConfig;
import com.songoda.ultimatetimber.treefall.CustomLoot;
import com.songoda.ultimatetimber.treefall.TreeFallAnimation; import com.songoda.ultimatetimber.treefall.TreeFallAnimation;
import com.songoda.ultimatetimber.treefall.TreeFallEvent; import com.songoda.ultimatetimber.treefall.TreeFallEvent;
import com.songoda.ultimatetimber.utils.Methods; import com.songoda.ultimatetimber.utils.Methods;
@ -45,10 +46,15 @@ public class UltimateTimber extends JavaPlugin {
Bukkit.getServer().getPluginManager().registerEvents(new TreeFallAnimation(), this); Bukkit.getServer().getPluginManager().registerEvents(new TreeFallAnimation(), this);
/* /*
Initialize and cache config Initialize config
*/ */
DefaultConfig.initialize(); DefaultConfig.initialize();
/*
Initialize custom loot
*/
CustomLoot.initializeCustomItems();
/* /*
Cache valid worlds for later use Cache valid worlds for later use
*/ */

View File

@ -5,6 +5,9 @@ import org.bukkit.Bukkit;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.configuration.Configuration; import org.bukkit.configuration.Configuration;
import java.util.Arrays;
import java.util.Collections;
public class DefaultConfig { public class DefaultConfig {
/* /*
@ -26,6 +29,9 @@ public class DefaultConfig {
public static final String REPLANT_SAPLING = "Replant sapling when tree is cut down"; public static final String REPLANT_SAPLING = "Replant sapling when tree is cut down";
public static final String REPLANT_FROM_LEAVES = "Fallen leaves have a chance to plant saplings"; public static final String REPLANT_FROM_LEAVES = "Fallen leaves have a chance to plant saplings";
public static final String CUSTOM_AUDIO = "Use custom sounds for trees falling"; public static final String CUSTOM_AUDIO = "Use custom sounds for trees falling";
public static final String SHOW_ANIMATION = "Show tree fall animation";
public static final String CUSTOM_LOOT_LIST = "Custom loot";
private static final String CUSTOM_LOOT_ITEM = "Material:GOLDEN_APPLE,Chance:1";
public static void initialize() { public static void initialize() {
UltimateTimber plugin = UltimateTimber.getInstance(); UltimateTimber plugin = UltimateTimber.getInstance();
@ -40,6 +46,7 @@ public class DefaultConfig {
configuration.addDefault(REPLANT_SAPLING, true); configuration.addDefault(REPLANT_SAPLING, true);
configuration.addDefault(REPLANT_FROM_LEAVES, true); configuration.addDefault(REPLANT_FROM_LEAVES, true);
configuration.addDefault(CUSTOM_AUDIO, true); configuration.addDefault(CUSTOM_AUDIO, true);
configuration.addDefault(SHOW_ANIMATION, true);
/* /*
Add all worlds that exist in the world at startup Add all worlds that exist in the world at startup
@ -47,6 +54,8 @@ public class DefaultConfig {
for (World world : Bukkit.getServer().getWorlds()) for (World world : Bukkit.getServer().getWorlds())
configuration.addDefault(VALID_WORLDS + world.getName(), true); configuration.addDefault(VALID_WORLDS + world.getName(), true);
configuration.addDefault(CUSTOM_LOOT_LIST, Collections.singletonList(CUSTOM_LOOT_ITEM));
configuration.options().copyDefaults(true); configuration.options().copyDefaults(true);
plugin.saveConfig(); plugin.saveConfig();

View File

@ -1,5 +1,6 @@
package com.songoda.ultimatetimber.treefall; package com.songoda.ultimatetimber.treefall;
import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -8,10 +9,11 @@ import org.bukkit.inventory.meta.Damageable;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashSet;
public class AxeDurability { public class AxeDurability {
public static void adjustAxeDamage(ArrayList<Block> blocks, Player player) { public static void adjustAxeDamage(LinkedHashSet<Block> blocks, Player player) {
if (!(player.getInventory().getItemInMainHand().getType().equals(Material.DIAMOND_AXE) || if (!(player.getInventory().getItemInMainHand().getType().equals(Material.DIAMOND_AXE) ||
player.getInventory().getItemInMainHand().getType().equals(Material.GOLDEN_AXE) || player.getInventory().getItemInMainHand().getType().equals(Material.GOLDEN_AXE) ||
@ -22,7 +24,21 @@ public class AxeDurability {
ItemStack itemStack = player.getInventory().getItemInMainHand(); ItemStack itemStack = player.getInventory().getItemInMainHand();
ItemMeta itemMeta = itemStack.getItemMeta(); ItemMeta itemMeta = itemStack.getItemMeta();
Damageable damageableMeta = (Damageable) itemMeta; Damageable damageableMeta = (Damageable) itemMeta;
damageableMeta.setDamage(damageableMeta.getDamage() + blocks.size()); for (Block block : blocks)
if (block.getType().equals(Material.ACACIA_LOG) ||
block.getType().equals(Material.BIRCH_LOG) ||
block.getType().equals(Material.DARK_OAK_LOG) ||
block.getType().equals(Material.JUNGLE_LOG) ||
block.getType().equals(Material.OAK_LOG) ||
block.getType().equals(Material.SPRUCE_LOG) ||
block.getType().equals(Material.STRIPPED_ACACIA_LOG) ||
block.getType().equals(Material.STRIPPED_BIRCH_LOG) ||
block.getType().equals(Material.STRIPPED_DARK_OAK_LOG) ||
block.getType().equals(Material.STRIPPED_JUNGLE_LOG) ||
block.getType().equals(Material.STRIPPED_OAK_LOG) ||
block.getType().equals(Material.STRIPPED_SPRUCE_LOG))
damageableMeta.setDamage(damageableMeta.getDamage() + 1);
itemStack.setItemMeta((ItemMeta) damageableMeta); itemStack.setItemMeta((ItemMeta) damageableMeta);
} }

View File

@ -0,0 +1,60 @@
package com.songoda.ultimatetimber.treefall;
import com.songoda.ultimatetimber.UltimateTimber;
import com.songoda.ultimatetimber.configurations.DefaultConfig;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.inventory.ItemStack;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
public class CustomLoot {
private static HashMap<ItemStack, Double> itemMap = new HashMap<>();
public static void doCustomItemDrop(Location location) {
for (ItemStack itemStack : itemMap.keySet())
if ((ThreadLocalRandom.current().nextDouble()) < itemMap.get(itemStack) / 100)
location.getWorld().dropItem(location, itemStack);
}
public static void initializeCustomItems() {
FileConfiguration fileConfiguration = UltimateTimber.getInstance().getConfig();
List<String> arrayList = (List<String>) fileConfiguration.getList(DefaultConfig.CUSTOM_LOOT_LIST);
for (String string : arrayList) {
Material material = null;
double chance = 0;
String materialString = string.split(",")[0].replace("Material:", "");
try {
material = Material.valueOf(materialString);
} catch (Exception ex) {
Bukkit.getLogger().warning("[UltimateTimber] Warning: " + materialString + " is not a valid material name.");
}
String chanceString = string.split(",")[1].replace("Chance:", "");
try {
chance = Double.parseDouble(chanceString);
} catch (Exception ex) {
Bukkit.getLogger().warning("[UltimateTimber] Warning: " + chanceString + " is not a valid chance.");
}
if (material == null || chance == 0) continue;
ItemStack itemStack = new ItemStack(material);
itemMap.put(itemStack, chance);
}
}
}

View File

@ -0,0 +1,67 @@
package com.songoda.ultimatetimber.treefall;
import com.songoda.ultimatetimber.utils.LeafToSaplingConverter;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.inventory.ItemStack;
import java.util.LinkedHashSet;
import java.util.concurrent.ThreadLocalRandom;
public class NoAnimationTreeDestroyer {
/*
Only ever triggers when people have tree falling animations off in the config
*/
public static void destroyTree(LinkedHashSet<Block> blocks, boolean hasBonusLoot, boolean hasSilkTouch) {
for (Block block : blocks) {
Material material = LeafToSaplingConverter.convertLeaves(block.getType());
if (material.equals(Material.AIR)) continue;
if (material.equals(Material.VINE)) continue;
if (hasSilkTouch) {
if (hasBonusLoot)
block.getWorld().dropItem(block.getLocation(), new ItemStack(block.getType(), 1));
block.getWorld().dropItem(block.getLocation(), new ItemStack(block.getType(), 1));
CustomLoot.doCustomItemDrop(block.getLocation());
block.setType(Material.AIR);
continue;
}
if (material.equals(Material.ACACIA_SAPLING) ||
material.equals(Material.BIRCH_SAPLING) ||
material.equals(Material.DARK_OAK_SAPLING) ||
material.equals(Material.JUNGLE_SAPLING) ||
material.equals(Material.OAK_SAPLING) ||
material.equals(Material.SPRUCE_SAPLING)) {
if (ThreadLocalRandom.current().nextDouble() < 0.05) {
if (hasBonusLoot) {
block.getWorld().dropItem(block.getLocation(), new ItemStack(material, 1));
}
block.getWorld().dropItem(block.getLocation(), new ItemStack(material, 1));
block.setType(Material.AIR);
CustomLoot.doCustomItemDrop(block.getLocation());
continue;
} else {
block.setType(Material.AIR);
CustomLoot.doCustomItemDrop(block.getLocation());
continue;
}
}
if (hasBonusLoot)
block.getWorld().dropItem(block.getLocation(), new ItemStack(material, 1));
block.getWorld().dropItem(block.getLocation(), new ItemStack(material, 1));
block.setType(Material.AIR);
CustomLoot.doCustomItemDrop(block.getLocation());
}
}
}

View File

@ -1,11 +1,13 @@
package com.songoda.ultimatetimber.treefall; package com.songoda.ultimatetimber.treefall;
import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
public class TreeChecker { public class TreeChecker {
@ -32,7 +34,7 @@ public class TreeChecker {
/* /*
Used to limit the blocks that constitute a tree Used to limit the blocks that constitute a tree
*/ */
private static List<Material> validSurroundingMaterials = new ArrayList<>(Arrays.asList( public static List<Material> validTreeMaterials = new ArrayList<>(Arrays.asList(
Material.ACACIA_LEAVES, Material.ACACIA_LEAVES,
Material.BIRCH_LEAVES, Material.BIRCH_LEAVES,
Material.DARK_OAK_LEAVES, Material.DARK_OAK_LEAVES,
@ -44,16 +46,13 @@ public class TreeChecker {
Material.RED_MUSHROOM_BLOCK Material.RED_MUSHROOM_BLOCK
)); ));
public static ArrayList<Block> parseTree(Block block) { public static LinkedHashSet<Block> parseTree(Block block, boolean isSourceBlock) {
/* /*
Check if material is valid Check if material is valid
*/ */
if (!validMaterials.contains(block.getType())) return null; if (!validMaterials.contains(block.getType())) return null;
ArrayList<Block> blocks = new ArrayList<>();
boolean containsSecondaryBlock = false;
/* /*
Check if block is surrounded by air (bottom blocks are) Check if block is surrounded by air (bottom blocks are)
Every third block expand one block laterally until the main block line reaches air or the max height is reached Every third block expand one block laterally until the main block line reaches air or the max height is reached
@ -61,6 +60,12 @@ public class TreeChecker {
int offset = 1; int offset = 1;
int maxHeight = 31; int maxHeight = 31;
/*
This is used to crawl the location up the tree
*/
Location blockLocation = block.getLocation().clone();
Material originalMaterial = block.getType();
for (int i = 0; i < maxHeight; i++) { for (int i = 0; i < maxHeight; i++) {
if ((i + 1) % 2 == 0 && offset < 6) if ((i + 1) % 2 == 0 && offset < 6)
@ -70,21 +75,31 @@ public class TreeChecker {
This expands the inverted search pyramid vertically This expands the inverted search pyramid vertically
*/ */
int xOffset = -offset; int xOffset = -offset;
for (int j = xOffset - 1; j < offset; j++) { for (int j = xOffset; j < offset + 1; j++) {
int zOffset = -offset; int zOffset = -offset;
for (int k = zOffset - 1; k < offset; k++) { for (int k = zOffset; k < offset + 1; k++) {
Block thisBlock = block.getLocation().clone().add(new Vector(xOffset, i, zOffset)).getBlock(); Block thisBlock = blockLocation.clone().add(new Vector(xOffset, 0, zOffset)).getBlock();
if (allBlocks.contains(thisBlock)) continue;
/* /*
This exclusion list should include everything you may find near trees as to not invalidate trees This exclusion list should include everything you may find near trees as to not invalidate trees
in natural forests and such in natural forests and such
Construction blocks aren't included because that would bust buildings. Construction blocks aren't included because that would bust buildings.
*/ */
if (!thisBlock.getType().equals(block.getType()) &&
!validSurroundingMaterials.contains(thisBlock.getType()) && if ((thisBlock.getType().equals(Material.DIRT) ||
thisBlock.getType().equals(Material.COARSE_DIRT) ||
thisBlock.getType().equals(Material.GRASS_BLOCK)) &&
(i > 1) && isSourceBlock) {
return null;
}
if (!thisBlock.getType().equals(originalMaterial) &&
!validTreeMaterials.contains(thisBlock.getType()) &&
!thisBlock.getType().equals(Material.AIR) && !thisBlock.getType().equals(Material.AIR) &&
!thisBlock.getType().equals(Material.VINE) && !thisBlock.getType().equals(Material.VINE) &&
!thisBlock.getType().equals(Material.ROSE_BUSH) && !thisBlock.getType().equals(Material.ROSE_BUSH) &&
@ -116,20 +131,21 @@ public class TreeChecker {
!thisBlock.getType().equals(Material.DARK_OAK_SAPLING) && !thisBlock.getType().equals(Material.DARK_OAK_SAPLING) &&
!thisBlock.getType().equals(Material.VOID_AIR) && !thisBlock.getType().equals(Material.VOID_AIR) &&
!thisBlock.getType().equals(Material.CAVE_AIR) && !thisBlock.getType().equals(Material.CAVE_AIR) &&
(!thisBlock.getType().equals(Material.DIRT) &&
!thisBlock.getType().equals(Material.COARSE_DIRT) &&
!thisBlock.getType().equals(Material.GRASS_BLOCK) &&
(i == 0 || i == 1)))
return null;
if (validSurroundingMaterials.contains(thisBlock.getType()))
containsSecondaryBlock = true;
if (!thisBlock.getType().equals(Material.AIR) &&
!thisBlock.getType().equals(Material.DIRT) && !thisBlock.getType().equals(Material.DIRT) &&
!thisBlock.getType().equals(Material.COARSE_DIRT) && !thisBlock.getType().equals(Material.COARSE_DIRT) &&
!thisBlock.getType().equals(Material.GRASS_BLOCK)) !thisBlock.getType().equals(Material.GRASS_BLOCK)) {
blocks.add(thisBlock);
return null;
}
if (!thisBlock.getType().equals(Material.AIR) &&
!thisBlock.getType().equals(Material.CAVE_AIR) &&
!thisBlock.getType().equals(Material.VOID_AIR) &&
!thisBlock.getType().equals(Material.DIRT) &&
!thisBlock.getType().equals(Material.COARSE_DIRT) &&
!thisBlock.getType().equals(Material.GRASS_BLOCK)) {
allBlocks.add(thisBlock);
}
zOffset++; zOffset++;
@ -139,20 +155,63 @@ public class TreeChecker {
} }
if (block.getLocation().clone().add(new Vector(0, i, 0)).getBlock().getType().equals(Material.AIR)) /*
if (i > 1) Increment the height of the block location
break; */
else blockLocation.add(new Vector(0, 1, 0));
return null;
}
/* /*
If there are no leaves, don't see it as a tree Detect if it's the end of the tree
If a block above it continues the same material type as the original block, continue with that block as the
new source block
If it doesn't break the loop and return the blocks list
*/ */
if (!containsSecondaryBlock) return null; if (blockLocation.getBlock().getType().equals(Material.AIR) || validTreeMaterials.contains(blockLocation.getBlock().getType())) {
return blocks; if (isSourceBlock && blockLocation.clone().subtract(block.getLocation().clone()).getY() < 2)
return null;
ArrayList<Block> newBlocks = scanNearbyBranching(originalMaterial, blockLocation);
if (newBlocks != null)
for (Block newBlock : newBlocks) {
LinkedHashSet<Block> newBlockList = parseTree(newBlock, false);
if (newBlockList == null) {
return null;
} else {
allBlocks.addAll(newBlocks);
}
}
else if (blockLocation.getBlock().getType().equals(Material.AIR))
break;
}
}
return allBlocks;
}
private static LinkedHashSet<Block> allBlocks = new LinkedHashSet<>();
/*
Some trees veer to a side as they reach the top, this scans for blocks adjacent to the air block above the trunk
*/
private static ArrayList<Block> scanNearbyBranching(Material originalMaterial, Location location) {
ArrayList<Block> newBlocks = new ArrayList<>();
for (int i = -1; i < 2; i++)
for (int j = -1; j < 2; j++) {
Block nearbyBlock = location.clone().add(new Vector(i, 0, j)).getBlock();
if (!nearbyBlock.getType().equals(originalMaterial)) continue;
if (allBlocks.contains(nearbyBlock)) continue;
if (nearbyBlock.getLocation().equals(location)) continue;
newBlocks.add(nearbyBlock);
}
if (newBlocks.isEmpty()) return null;
return newBlocks;
} }

View File

@ -16,6 +16,7 @@ import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashSet;
public class TreeFallAnimation implements Listener { public class TreeFallAnimation implements Listener {
@ -100,7 +101,7 @@ public class TreeFallAnimation implements Listener {
Initially, the tree will start slowly toppling over. Initially, the tree will start slowly toppling over.
After a short while, it goes over the tipping point and the fall accelerates. After a short while, it goes over the tipping point and the fall accelerates.
*/ */
public void startAnimation(Block originalBlock, ArrayList<Block> blocks, Player player) { public void startAnimation(Block originalBlock, LinkedHashSet<Block> blocks, Player player) {
/* /*
This vector makes sure that the entire tree falls in the same direction from the same reference point This vector makes sure that the entire tree falls in the same direction from the same reference point
*/ */

View File

@ -4,12 +4,13 @@ import com.songoda.ultimatetimber.UltimateTimber;
import com.songoda.ultimatetimber.configurations.DefaultConfig; import com.songoda.ultimatetimber.configurations.DefaultConfig;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import java.util.ArrayList; import java.util.LinkedHashSet;
public class TreeFallEvent implements Listener { public class TreeFallEvent implements Listener {
@ -21,17 +22,41 @@ public class TreeFallEvent implements Listener {
public void onTreeBreak(BlockBreakEvent event) { public void onTreeBreak(BlockBreakEvent event) {
if (!EventFilter.eventIsValid(event)) return; if (!EventFilter.eventIsValid(event)) return;
ArrayList<Block> blocks = TreeChecker.parseTree(event.getBlock()); LinkedHashSet<Block> blocks = TreeChecker.parseTree(event.getBlock(), true);
if (blocks == null) return;
/*
Check if the list of blocks carried over from the tree parser contains everything you'd expect from a tree
*/
if (blocks == null)
return;
boolean containsLeaves = false;
for (Block block : blocks)
if (TreeChecker.validTreeMaterials.contains(block.getType())) {
containsLeaves = true;
break;
}
if (!containsLeaves)
return;
FileConfiguration fileConfiguration = UltimateTimber.getInstance().getConfig(); FileConfiguration fileConfiguration = UltimateTimber.getInstance().getConfig();
if (fileConfiguration.getBoolean(DefaultConfig.ACCURATE_AXE_DURABILITY)) if (fileConfiguration.getBoolean(DefaultConfig.ACCURATE_AXE_DURABILITY))
AxeDurability.adjustAxeDamage(blocks, event.getPlayer()); AxeDurability.adjustAxeDamage(blocks, event.getPlayer());
if (fileConfiguration.getBoolean(DefaultConfig.CUSTOM_AUDIO)) if (fileConfiguration.getBoolean(DefaultConfig.CUSTOM_AUDIO))
TreeSounds.tipOverNoise(event.getBlock().getLocation()); TreeSounds.tipOverNoise(event.getBlock().getLocation());
if (fileConfiguration.getBoolean(DefaultConfig.SHOW_ANIMATION)) {
TreeFallAnimation treeFallAnimation = new TreeFallAnimation(); TreeFallAnimation treeFallAnimation = new TreeFallAnimation();
treeFallAnimation.startAnimation(event.getBlock(), blocks, event.getPlayer()); treeFallAnimation.startAnimation(event.getBlock(), blocks, event.getPlayer());
} else {
NoAnimationTreeDestroyer.destroyTree(blocks, event.getPlayer().hasPermission("ultimatetimber.bonusloot"),
event.getPlayer().getInventory().getItemInMainHand().containsEnchantment(Enchantment.SILK_TOUCH));
}
} }

View File

@ -1,5 +1,6 @@
package com.songoda.ultimatetimber.treefall; package com.songoda.ultimatetimber.treefall;
import com.songoda.ultimatetimber.utils.LeafToSaplingConverter;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.FallingBlock; import org.bukkit.entity.FallingBlock;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -10,40 +11,16 @@ public class TreeLoot {
public static void convertFallingBlock(FallingBlock fallingBlock, boolean hasBonusLoot, boolean hasSilkTouch) { public static void convertFallingBlock(FallingBlock fallingBlock, boolean hasBonusLoot, boolean hasSilkTouch) {
Material material; Material material = LeafToSaplingConverter.convertLeaves(fallingBlock.getBlockData().getMaterial());
switch (fallingBlock.getBlockData().getMaterial()) {
case ACACIA_LEAVES:
material = Material.ACACIA_SAPLING;
break;
case BIRCH_LEAVES:
material = Material.BIRCH_SAPLING;
break;
case DARK_OAK_LEAVES:
material = Material.DARK_OAK_SAPLING;
break;
case JUNGLE_LEAVES:
material = Material.JUNGLE_SAPLING;
break;
case OAK_LEAVES:
material = Material.OAK_SAPLING;
break;
case SPRUCE_LEAVES:
material = Material.SPRUCE_SAPLING;
break;
default:
material = fallingBlock.getBlockData().getMaterial();
}
if (material.equals(Material.VINE)) if (material.equals(Material.VINE))
return; return;
if (hasSilkTouch) { if (hasSilkTouch) {
if (hasBonusLoot) if (hasBonusLoot)
fallingBlock.getWorld().dropItem(fallingBlock.getLocation(), new ItemStack(material, 1));
fallingBlock.getWorld().dropItem(fallingBlock.getLocation(), new ItemStack(fallingBlock.getBlockData().getMaterial(), 1)); fallingBlock.getWorld().dropItem(fallingBlock.getLocation(), new ItemStack(fallingBlock.getBlockData().getMaterial(), 1));
fallingBlock.getWorld().dropItem(fallingBlock.getLocation(), new ItemStack(fallingBlock.getBlockData().getMaterial(), 1));
CustomLoot.doCustomItemDrop(fallingBlock.getLocation());
return; return;
} }
@ -53,14 +30,20 @@ public class TreeLoot {
material.equals(Material.JUNGLE_SAPLING) || material.equals(Material.JUNGLE_SAPLING) ||
material.equals(Material.OAK_SAPLING) || material.equals(Material.OAK_SAPLING) ||
material.equals(Material.SPRUCE_SAPLING)) { material.equals(Material.SPRUCE_SAPLING)) {
if (ThreadLocalRandom.current().nextDouble() < 0.05) { if (ThreadLocalRandom.current().nextDouble() < 0.05) {
if (hasBonusLoot) if (hasBonusLoot) {
fallingBlock.getWorld().dropItem(fallingBlock.getLocation(), new ItemStack(material, 1)); fallingBlock.getWorld().dropItem(fallingBlock.getLocation(), new ItemStack(material, 1));
}
fallingBlock.getWorld().dropItem(fallingBlock.getLocation(), new ItemStack(material, 1)); fallingBlock.getWorld().dropItem(fallingBlock.getLocation(), new ItemStack(material, 1));
CustomLoot.doCustomItemDrop(fallingBlock.getLocation());
return;
} else {
CustomLoot.doCustomItemDrop(fallingBlock.getLocation());
return; return;
} else return;
} }
}
if (hasBonusLoot) if (hasBonusLoot)
fallingBlock.getWorld().dropItem(fallingBlock.getLocation(), new ItemStack(material, 1)); fallingBlock.getWorld().dropItem(fallingBlock.getLocation(), new ItemStack(material, 1));
@ -68,4 +51,6 @@ public class TreeLoot {
} }
} }

View File

@ -94,7 +94,7 @@ public class TreeReplant {
if (material == null) return; if (material == null) return;
if (ThreadLocalRandom.current().nextDouble() > 0.05) return; if (ThreadLocalRandom.current().nextDouble() > 0.01) return;
Block block = fallingBlock.getLocation().clone().subtract(new Vector(0, 1, 0)).getBlock(); Block block = fallingBlock.getLocation().clone().subtract(new Vector(0, 1, 0)).getBlock();

View File

@ -0,0 +1,41 @@
package com.songoda.ultimatetimber.utils;
import org.bukkit.Material;
public class LeafToSaplingConverter {
/*
Defaults to returning the same material type that is fed into it
*/
public static Material convertLeaves(Material material){
switch (material) {
case ACACIA_LEAVES:
material = org.bukkit.Material.ACACIA_SAPLING;
break;
case BIRCH_LEAVES:
material = org.bukkit.Material.BIRCH_SAPLING;
break;
case DARK_OAK_LEAVES:
material = org.bukkit.Material.DARK_OAK_SAPLING;
break;
case JUNGLE_LEAVES:
material = org.bukkit.Material.JUNGLE_SAPLING;
break;
case OAK_LEAVES:
material = org.bukkit.Material.OAK_SAPLING;
break;
case SPRUCE_LEAVES:
material = org.bukkit.Material.SPRUCE_SAPLING;
break;
default:
material = material;
}
return material;
}
}

View File

@ -1,5 +1,5 @@
name: UltimateTimber name: UltimateTimber
version: 0.0.4 version: 0.0.5
author: Songoda author: Songoda
main: com.songoda.ultimatetimber.UltimateTimber main: com.songoda.ultimatetimber.UltimateTimber
api-version: 1.13 api-version: 1.13