diff --git a/UltimateTimber-Adapter/Current/src/main/java/com.songoda.ultimatetimber.adapter.current/CurrentAdapter.java b/UltimateTimber-Adapter/Current/src/main/java/com.songoda.ultimatetimber.adapter.current/CurrentAdapter.java index 1f5d615..a2db9fd 100644 --- a/UltimateTimber-Adapter/Current/src/main/java/com.songoda.ultimatetimber.adapter.current/CurrentAdapter.java +++ b/UltimateTimber-Adapter/Current/src/main/java/com.songoda.ultimatetimber.adapter.current/CurrentAdapter.java @@ -3,7 +3,9 @@ package com.songoda.ultimatetimber.adapter.current; import com.songoda.ultimatetimber.adapter.IBlockData; import com.songoda.ultimatetimber.adapter.VersionAdapter; import com.songoda.ultimatetimber.adapter.VersionAdapterType; -import com.songoda.ultimatetimber.tree.*; +import com.songoda.ultimatetimber.tree.ITreeBlock; +import com.songoda.ultimatetimber.tree.TreeBlockType; +import com.songoda.ultimatetimber.tree.TreeDefinition; import com.songoda.ultimatetimber.utils.Methods; import org.bukkit.Location; import org.bukkit.Material; @@ -44,6 +46,8 @@ public class CurrentAdapter implements VersionAdapter { Set drops = new HashSet<>(); if (treeBlock.getBlock() instanceof Block) { Block block = (Block)treeBlock.getBlock(); + if (block.getType().equals(Material.AIR)) + return drops; drops.add(new ItemStack(block.getType())); } else if (treeBlock.getBlock() instanceof FallingBlock) { FallingBlock fallingBlock = (FallingBlock)treeBlock.getBlock(); diff --git a/UltimateTimber-Adapter/Legacy/src/main/java/com.songoda.ultimatetimber.adapter.legacy/LegacyAdapter.java b/UltimateTimber-Adapter/Legacy/src/main/java/com.songoda.ultimatetimber.adapter.legacy/LegacyAdapter.java index 259d950..363fb54 100644 --- a/UltimateTimber-Adapter/Legacy/src/main/java/com.songoda.ultimatetimber.adapter.legacy/LegacyAdapter.java +++ b/UltimateTimber-Adapter/Legacy/src/main/java/com.songoda.ultimatetimber.adapter.legacy/LegacyAdapter.java @@ -3,18 +3,27 @@ package com.songoda.ultimatetimber.adapter.legacy; import com.songoda.ultimatetimber.adapter.IBlockData; import com.songoda.ultimatetimber.adapter.VersionAdapter; import com.songoda.ultimatetimber.adapter.VersionAdapterType; -import com.songoda.ultimatetimber.tree.*; +import com.songoda.ultimatetimber.tree.ITreeBlock; +import com.songoda.ultimatetimber.tree.TreeBlockType; +import com.songoda.ultimatetimber.tree.TreeDefinition; import com.songoda.ultimatetimber.utils.Methods; import com.songoda.ultimatetimber.utils.NMSUtil; -import org.bukkit.*; +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.Particle; +import org.bukkit.Sound; import org.bukkit.block.Block; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.FallingBlock; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import org.bukkit.material.MaterialData; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; @SuppressWarnings("deprecation") public class LegacyAdapter implements VersionAdapter { @@ -57,6 +66,8 @@ public class LegacyAdapter implements VersionAdapter { IBlockData treeBlockData; if (treeBlock.getBlock() instanceof Block) { Block block = (Block)treeBlock.getBlock(); + if (block.getType().equals(Material.AIR)) + return drops; List data = new ArrayList<>(); data.add(block.getData()); treeBlockData = new LegacyBlockData(block.getType(), data); diff --git a/UltimateTimber-Adapter/Legacy/src/main/java/com.songoda.ultimatetimber.adapter.legacy/LegacyBlockData.java b/UltimateTimber-Adapter/Legacy/src/main/java/com.songoda.ultimatetimber.adapter.legacy/LegacyBlockData.java index 254c5eb..f6be43a 100644 --- a/UltimateTimber-Adapter/Legacy/src/main/java/com.songoda.ultimatetimber.adapter.legacy/LegacyBlockData.java +++ b/UltimateTimber-Adapter/Legacy/src/main/java/com.songoda.ultimatetimber.adapter.legacy/LegacyBlockData.java @@ -4,7 +4,6 @@ import com.songoda.ultimatetimber.adapter.IBlockData; import org.bukkit.Material; import org.bukkit.block.Block; -import java.util.Arrays; import java.util.List; @SuppressWarnings("deprecation") diff --git a/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/adapter/VersionAdapter.java b/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/adapter/VersionAdapter.java index f272459..265865c 100644 --- a/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/adapter/VersionAdapter.java +++ b/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/adapter/VersionAdapter.java @@ -1,10 +1,7 @@ package com.songoda.ultimatetimber.adapter; -import com.songoda.ultimatetimber.tree.FallingTreeBlock; import com.songoda.ultimatetimber.tree.ITreeBlock; -import com.songoda.ultimatetimber.tree.TreeBlockSet; import com.songoda.ultimatetimber.tree.TreeDefinition; -import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; diff --git a/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/tree/FallingTreeBlock.java b/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/tree/FallingTreeBlock.java index 3b07962..843565b 100644 --- a/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/tree/FallingTreeBlock.java +++ b/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/tree/FallingTreeBlock.java @@ -2,9 +2,6 @@ package com.songoda.ultimatetimber.tree; import org.bukkit.Location; import org.bukkit.entity.FallingBlock; -import org.bukkit.inventory.ItemStack; - -import java.util.Collection; public class FallingTreeBlock implements ITreeBlock { diff --git a/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/tree/ITreeBlock.java b/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/tree/ITreeBlock.java index 077d5ab..1d2cb1d 100644 --- a/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/tree/ITreeBlock.java +++ b/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/tree/ITreeBlock.java @@ -1,9 +1,6 @@ package com.songoda.ultimatetimber.tree; import org.bukkit.Location; -import org.bukkit.inventory.ItemStack; - -import java.util.Collection; public interface ITreeBlock { diff --git a/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/tree/TreeBlock.java b/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/tree/TreeBlock.java index dc59c2e..2f6f45c 100644 --- a/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/tree/TreeBlock.java +++ b/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/tree/TreeBlock.java @@ -2,9 +2,7 @@ package com.songoda.ultimatetimber.tree; import org.bukkit.Location; import org.bukkit.block.Block; -import org.bukkit.inventory.ItemStack; -import java.util.Collection; import java.util.Objects; public class TreeBlock implements ITreeBlock { diff --git a/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/tree/TreeBlockSet.java b/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/tree/TreeBlockSet.java index c9a3720..cf39bda 100644 --- a/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/tree/TreeBlockSet.java +++ b/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/tree/TreeBlockSet.java @@ -1,6 +1,10 @@ package com.songoda.ultimatetimber.tree; -import java.util.*; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; public class TreeBlockSet implements Collection { diff --git a/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/utils/Metrics.java b/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/utils/Metrics.java index 6ddcae1..4ac9b6a 100644 --- a/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/utils/Metrics.java +++ b/UltimateTimber/Core/src/main/java/com/songoda/ultimatetimber/utils/Metrics.java @@ -10,12 +10,24 @@ import org.json.simple.JSONArray; import org.json.simple.JSONObject; import javax.net.ssl.HttpsURLConnection; -import java.io.*; +import java.io.BufferedReader; +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; import java.nio.charset.StandardCharsets; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Timer; +import java.util.TimerTask; +import java.util.UUID; import java.util.concurrent.Callable; import java.util.logging.Level; import java.util.zip.GZIPOutputStream; diff --git a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/UltimateTimber.java b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/UltimateTimber.java index 2f91346..0d17c92 100644 --- a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/UltimateTimber.java +++ b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/UltimateTimber.java @@ -3,7 +3,16 @@ package com.songoda.ultimatetimber; import com.songoda.ultimatetimber.adapter.VersionAdapter; import com.songoda.ultimatetimber.adapter.current.CurrentAdapter; import com.songoda.ultimatetimber.adapter.legacy.LegacyAdapter; -import com.songoda.ultimatetimber.manager.*; +import com.songoda.ultimatetimber.manager.ChoppingManager; +import com.songoda.ultimatetimber.manager.CommandManager; +import com.songoda.ultimatetimber.manager.ConfigurationManager; +import com.songoda.ultimatetimber.manager.HookManager; +import com.songoda.ultimatetimber.manager.Manager; +import com.songoda.ultimatetimber.manager.SaplingManager; +import com.songoda.ultimatetimber.manager.TreeAnimationManager; +import com.songoda.ultimatetimber.manager.TreeDefinitionManager; +import com.songoda.ultimatetimber.manager.TreeDetectionManager; +import com.songoda.ultimatetimber.manager.TreeFallManager; import com.songoda.ultimatetimber.utils.Methods; import com.songoda.ultimatetimber.utils.Metrics; import com.songoda.ultimatetimber.utils.NMSUtil; diff --git a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/animation/TreeAnimation.java b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/animation/TreeAnimation.java index b58d64e..48c462c 100644 --- a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/animation/TreeAnimation.java +++ b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/animation/TreeAnimation.java @@ -1,15 +1,17 @@ package com.songoda.ultimatetimber.animation; import com.songoda.ultimatetimber.UltimateTimber; -import com.songoda.ultimatetimber.manager.ConfigurationManager; -import com.songoda.ultimatetimber.manager.SaplingManager; import com.songoda.ultimatetimber.tree.DetectedTree; +import com.songoda.ultimatetimber.tree.FallingTreeBlock; +import com.songoda.ultimatetimber.tree.ITreeBlock; +import com.songoda.ultimatetimber.tree.TreeBlock; import com.songoda.ultimatetimber.tree.TreeBlockSet; -import com.songoda.ultimatetimber.tree.TreeDefinition; -import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.FallingBlock; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -19,6 +21,7 @@ public abstract class TreeAnimation { protected final DetectedTree detectedTree; protected final Player player; protected final boolean hasSilkTouch; + protected TreeBlockSet fallingTreeBlocks; TreeAnimation(TreeAnimationType treeAnimationType, DetectedTree detectedTree, Player player) { this.treeAnimationType = treeAnimationType; @@ -27,6 +30,8 @@ public abstract class TreeAnimation { ItemStack itemInHand = UltimateTimber.getInstance().getVersionAdapter().getItemInHand(player); this.hasSilkTouch = itemInHand != null && itemInHand.hasItemMeta() && itemInHand.getItemMeta().hasEnchant(Enchantment.SILK_TOUCH); + + this.fallingTreeBlocks = null; } /** @@ -36,14 +41,99 @@ public abstract class TreeAnimation { */ public abstract void playAnimation(Runnable whenFinished); + /** + * Gets the type of tree animation that this is + * + * @return The TreeAnimationType + */ + public TreeAnimationType getTreeAnimationType() { + return this.treeAnimationType; + } + + /** + * Gets the detected tree + * + * @return The detected tree + */ + public DetectedTree getDetectedTree() { + return this.detectedTree; + } + + /** + * Gets the player who started this tree animation + * + * @return The player who started this tree animation + */ + public Player getPlayer() { + return this.player; + } + + /** + * Checks if this tree animation has silk touch + * + * @return True if this animation has silk touch, otherwise false + */ + public boolean hasSilkTouch() { + return this.hasSilkTouch; + } + + /** + * Gets a TreeBlockSet of the active falling tree blocks + * May return null if the animation type does not use falling blocks + * + * @return A tree block set + */ + public TreeBlockSet getFallingTreeBlocks() { + return this.fallingTreeBlocks; + } + + /** + * Converts a TreeBlock into a FallingTreeBlock + * + * @param treeBlock The TreeBlock to convert + * @return A FallingTreeBlock that has been converted from a TreeBlock + */ + protected FallingTreeBlock convertToFallingBlock(TreeBlock treeBlock) { + Location location = treeBlock.getLocation().clone().add(0.5, 0, 0.5); + World world = location.getWorld(); + Block block = treeBlock.getBlock(); + + if (block.getType().equals(Material.AIR)) + return null; + + FallingBlock fallingBlock = world.spawnFallingBlock(location, block.getBlockData()); + + fallingBlock.setGravity(false); + fallingBlock.setDropItem(false); + fallingBlock.setHurtEntities(false); + + FallingTreeBlock fallingTreeBlock = new FallingTreeBlock(fallingBlock, treeBlock.getTreeBlockType()); + this.replaceBlock(treeBlock); + return fallingTreeBlock; + } + /** * Replaces a given block with a new one * - * @param block The block to replace + * @param treeBlock The tree block to replace */ - protected void replaceBlock(Block block) { - block.setType(Material.AIR); - UltimateTimber.getInstance().getSaplingManager().replantSapling(this.detectedTree.getTreeDefinition(), block.getLocation()); + public void replaceBlock(TreeBlock treeBlock) { + treeBlock.getBlock().setType(Material.AIR); + UltimateTimber.getInstance().getSaplingManager().replantSapling(this.detectedTree.getTreeDefinition(), treeBlock); + } + + /** + * Removes a falling block from the animation + * + * @param fallingBlock The FallingBlock to remove + */ + public void removeFallingBlock(FallingBlock fallingBlock) { + for (ITreeBlock fallingTreeBlock : this.fallingTreeBlocks.getAllTreeBlocks()) { + if (fallingTreeBlock.equals(fallingBlock)) { + this.fallingTreeBlocks.remove(fallingTreeBlock); + return; + } + } } } diff --git a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/animation/TreeAnimationChaos.java b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/animation/TreeAnimationChaos.java index 91e5fb2..d3f6314 100644 --- a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/animation/TreeAnimationChaos.java +++ b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/animation/TreeAnimationChaos.java @@ -1,9 +1,6 @@ package com.songoda.ultimatetimber.animation; import com.songoda.ultimatetimber.tree.DetectedTree; -import com.songoda.ultimatetimber.tree.TreeBlockSet; -import com.songoda.ultimatetimber.tree.TreeDefinition; -import org.bukkit.block.Block; import org.bukkit.entity.Player; public class TreeAnimationChaos extends TreeAnimation { diff --git a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/animation/TreeAnimationDisintegrate.java b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/animation/TreeAnimationDisintegrate.java index 24e1726..ff2fe9a 100644 --- a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/animation/TreeAnimationDisintegrate.java +++ b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/animation/TreeAnimationDisintegrate.java @@ -4,13 +4,18 @@ import com.songoda.ultimatetimber.UltimateTimber; import com.songoda.ultimatetimber.adapter.VersionAdapter; import com.songoda.ultimatetimber.manager.ConfigurationManager; import com.songoda.ultimatetimber.manager.TreeDefinitionManager; -import com.songoda.ultimatetimber.tree.*; -import org.bukkit.Bukkit; +import com.songoda.ultimatetimber.tree.DetectedTree; +import com.songoda.ultimatetimber.tree.ITreeBlock; +import com.songoda.ultimatetimber.tree.TreeBlock; +import com.songoda.ultimatetimber.tree.TreeDefinition; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; public class TreeAnimationDisintegrate extends TreeAnimation { @@ -67,10 +72,11 @@ public class TreeAnimationDisintegrate extends TreeAnimation { if (useCustomParticles) versionAdapter.playFallingParticles(td, treeBlock); treeDefinitionManager.dropTreeLoot(td, treeBlock, p, hst); - TreeAnimationDisintegrate.this.replaceBlock(treeBlock.getBlock()); + TreeAnimationDisintegrate.this.replaceBlock((TreeBlock)treeBlock); } } else { this.cancel(); + whenFinished.run(); } } }.runTaskTimer(ultimateTimber, 0, 1); diff --git a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/animation/TreeAnimationFancy.java b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/animation/TreeAnimationFancy.java index 45a2015..3964e4b 100644 --- a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/animation/TreeAnimationFancy.java +++ b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/animation/TreeAnimationFancy.java @@ -1,10 +1,19 @@ package com.songoda.ultimatetimber.animation; +import com.songoda.ultimatetimber.UltimateTimber; +import com.songoda.ultimatetimber.adapter.VersionAdapter; +import com.songoda.ultimatetimber.manager.ConfigurationManager; +import com.songoda.ultimatetimber.manager.TreeAnimationManager; import com.songoda.ultimatetimber.tree.DetectedTree; +import com.songoda.ultimatetimber.tree.FallingTreeBlock; +import com.songoda.ultimatetimber.tree.ITreeBlock; +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.entity.FallingBlock; import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; public class TreeAnimationFancy extends TreeAnimation { @@ -14,7 +23,74 @@ public class TreeAnimationFancy extends TreeAnimation { @Override public void playAnimation(Runnable whenFinished) { + UltimateTimber ultimateTimber = UltimateTimber.getInstance(); + VersionAdapter versionAdapter = ultimateTimber.getVersionAdapter(); + boolean useCustomSound = ConfigurationManager.Setting.USE_CUSTOM_SOUNDS.getBoolean(); + boolean useCustomParticles = ConfigurationManager.Setting.USE_CUSTOM_PARTICLES.getBoolean(); + + ITreeBlock initialTreeBlock = this.detectedTree.getDetectedTreeBlocks().getInitialLogBlock(); + FallingTreeBlock initialFallingBlock = this.convertToFallingBlock((TreeBlock)this.detectedTree.getDetectedTreeBlocks().getInitialLogBlock()); + + if (useCustomSound) + versionAdapter.playFallingSound(initialTreeBlock); + + Vector velocityVector = initialTreeBlock.getLocation().clone().subtract(this.player.getLocation().clone()).toVector().normalize().setY(0); + + this.fallingTreeBlocks = new TreeBlockSet<>(initialFallingBlock); + for (ITreeBlock treeBlock : this.detectedTree.getDetectedTreeBlocks().getAllTreeBlocks()) { + FallingTreeBlock fallingTreeBlock = this.convertToFallingBlock((TreeBlock)treeBlock); + if (fallingTreeBlock == null) + continue; + + FallingBlock fallingBlock = fallingTreeBlock.getBlock(); + this.fallingTreeBlocks.add(fallingTreeBlock); + + if (useCustomParticles) + versionAdapter.playFallingParticles(this.detectedTree.getTreeDefinition(), treeBlock); + + double multiplier = (treeBlock.getLocation().getY() - this.player.getLocation().getY()) * 0.05; + fallingBlock.setVelocity(velocityVector.clone().multiply(multiplier)); + fallingBlock.setVelocity(fallingBlock.getVelocity().multiply(0.3)); + } + + new BukkitRunnable() { + int timer = 0; + + @Override + public void run() { + if (this.timer == 0) { + for (ITreeBlock fallingTreeBlock : TreeAnimationFancy.this.fallingTreeBlocks.getAllTreeBlocks()) { + FallingBlock fallingBlock = fallingTreeBlock.getBlock(); + fallingBlock.setGravity(true); + fallingBlock.setVelocity(fallingBlock.getVelocity().multiply(1.5)); + } + } + + if (TreeAnimationFancy.this.fallingTreeBlocks.getAllTreeBlocks().isEmpty()) { + whenFinished.run(); + this.cancel(); + return; + } + + for (ITreeBlock fallingTreeBlock : TreeAnimationFancy.this.fallingTreeBlocks.getAllTreeBlocks()) { + FallingBlock fallingBlock = fallingTreeBlock.getBlock(); + fallingBlock.setVelocity(fallingBlock.getVelocity().clone().subtract(new Vector(0, 0.01, 0))); + } + + this.timer++; + + if (this.timer > 4 * 20) { + TreeAnimationManager treeAnimationManager = ultimateTimber.getTreeAnimationManager(); + for (ITreeBlock fallingTreeBlock : TreeAnimationFancy.this.fallingTreeBlocks.getAllTreeBlocks()) + treeAnimationManager.runFallingBlockImpact(TreeAnimationFancy.this, fallingTreeBlock); + whenFinished.run(); + this.cancel(); + } + } + }.runTaskTimer(ultimateTimber, 20L, 1L); + + whenFinished.run(); } } diff --git a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/animation/TreeAnimationNone.java b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/animation/TreeAnimationNone.java index 03cbb3d..4dad59d 100644 --- a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/animation/TreeAnimationNone.java +++ b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/animation/TreeAnimationNone.java @@ -6,8 +6,7 @@ import com.songoda.ultimatetimber.manager.ConfigurationManager; import com.songoda.ultimatetimber.manager.TreeDefinitionManager; import com.songoda.ultimatetimber.tree.DetectedTree; import com.songoda.ultimatetimber.tree.ITreeBlock; -import com.songoda.ultimatetimber.tree.TreeBlockSet; -import com.songoda.ultimatetimber.tree.TreeDefinition; +import com.songoda.ultimatetimber.tree.TreeBlock; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -31,8 +30,10 @@ public class TreeAnimationNone extends TreeAnimation { for (ITreeBlock treeBlock : this.detectedTree.getDetectedTreeBlocks().getAllTreeBlocks()) { treeDefinitionManager.dropTreeLoot(this.detectedTree.getTreeDefinition(), treeBlock, this.player, this.hasSilkTouch); - this.replaceBlock(treeBlock.getBlock()); + this.replaceBlock((TreeBlock)treeBlock); } + + whenFinished.run(); } } diff --git a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/CommandManager.java b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/CommandManager.java index 560d2da..fb26943 100644 --- a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/CommandManager.java +++ b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/CommandManager.java @@ -2,7 +2,11 @@ package com.songoda.ultimatetimber.manager; import com.songoda.ultimatetimber.UltimateTimber; import com.songoda.ultimatetimber.utils.Methods; -import org.bukkit.command.*; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.PluginCommand; +import org.bukkit.command.TabCompleter; import org.bukkit.entity.Player; import org.bukkit.util.StringUtil; diff --git a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/SaplingManager.java b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/SaplingManager.java index 48d80b6..63f2d03 100644 --- a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/SaplingManager.java +++ b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/SaplingManager.java @@ -2,6 +2,8 @@ package com.songoda.ultimatetimber.manager; import com.songoda.ultimatetimber.UltimateTimber; import com.songoda.ultimatetimber.adapter.IBlockData; +import com.songoda.ultimatetimber.tree.ITreeBlock; +import com.songoda.ultimatetimber.tree.TreeBlockType; import com.songoda.ultimatetimber.tree.TreeDefinition; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -39,13 +41,13 @@ public class SaplingManager extends Manager { * Takes into account config settings * * @param treeDefinition The TreeDefinition of the sapling - * @param location The Location to plant the sapling + * @param treeBlock The ITreeBlock to replant for */ - public void replantSapling(TreeDefinition treeDefinition, Location location) { + public void replantSapling(TreeDefinition treeDefinition, ITreeBlock treeBlock) { if (!ConfigurationManager.Setting.REPLANT_SAPLINGS.getBoolean()) return; - Bukkit.getScheduler().scheduleSyncDelayedTask(this.ultimateTimber, () -> this.internalReplant(treeDefinition, location), 1L); + Bukkit.getScheduler().scheduleSyncDelayedTask(this.ultimateTimber, () -> this.internalReplant(treeDefinition, treeBlock), 1L); } /** @@ -53,9 +55,9 @@ public class SaplingManager extends Manager { * Takes into account config settings * * @param treeDefinition The TreeDefinition of the sapling - * @param location The Location to plant the sapling + * @param treeBlock The ITreeBlock to replant for */ - public void replantSaplingWithChance(TreeDefinition treeDefinition, Location location) { + public void replantSaplingWithChance(TreeDefinition treeDefinition, ITreeBlock treeBlock) { if (!ConfigurationManager.Setting.FALLING_BLOCKS_REPLANT_SAPLINGS.getBoolean()) return; @@ -63,20 +65,20 @@ public class SaplingManager extends Manager { if (this.random.nextDouble() > chance / 100) return; - Bukkit.getScheduler().scheduleSyncDelayedTask(this.ultimateTimber, () -> this.internalReplant(treeDefinition, location), 1L); + Bukkit.getScheduler().scheduleSyncDelayedTask(this.ultimateTimber, () -> this.internalReplant(treeDefinition, treeBlock), 1L); } /** * Replants a sapling given a TreeDefinition and Location * * @param treeDefinition The TreeDefinition of the sapling - * @param location The Location to plant the sapling + * @param treeBlock The ITreeBlock to replant for */ - private void internalReplant(TreeDefinition treeDefinition, Location location) { + private void internalReplant(TreeDefinition treeDefinition, ITreeBlock treeBlock) { TreeDefinitionManager treeDefinitionManager = this.ultimateTimber.getTreeDefinitionManager(); - Block block = location.getBlock(); - if (!block.getType().equals(Material.AIR)) + Block block = treeBlock.getLocation().getBlock(); + if (!block.getType().equals(Material.AIR) || !treeBlock.getTreeBlockType().equals(TreeBlockType.LOG)) return; Block blockBelow = block.getRelative(BlockFace.DOWN); @@ -92,12 +94,12 @@ public class SaplingManager extends Manager { return; IBlockData saplingBlockData = treeDefinition.getSaplingBlockData(); - saplingBlockData.setBlock(location.getBlock()); + saplingBlockData.setBlock(block); int cooldown = ConfigurationManager.Setting.REPLANT_SAPLINGS_COOLDOWN.getInt(); if (cooldown != 0) { - this.protectedSaplings.add(location); - Bukkit.getScheduler().scheduleSyncDelayedTask(this.ultimateTimber, () -> this.protectedSaplings.remove(location), cooldown * 20L); + this.protectedSaplings.add(block.getLocation()); + Bukkit.getScheduler().scheduleSyncDelayedTask(this.ultimateTimber, () -> this.protectedSaplings.remove(block.getLocation()), cooldown * 20L); } } diff --git a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeAnimationManager.java b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeAnimationManager.java index 92c2803..3c6adc4 100644 --- a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeAnimationManager.java +++ b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeAnimationManager.java @@ -1,10 +1,21 @@ package com.songoda.ultimatetimber.manager; import com.songoda.ultimatetimber.UltimateTimber; -import com.songoda.ultimatetimber.animation.*; +import com.songoda.ultimatetimber.adapter.VersionAdapter; +import com.songoda.ultimatetimber.animation.TreeAnimation; +import com.songoda.ultimatetimber.animation.TreeAnimationChaos; +import com.songoda.ultimatetimber.animation.TreeAnimationDisintegrate; +import com.songoda.ultimatetimber.animation.TreeAnimationFancy; +import com.songoda.ultimatetimber.animation.TreeAnimationNone; import com.songoda.ultimatetimber.tree.DetectedTree; +import com.songoda.ultimatetimber.tree.ITreeBlock; import com.songoda.ultimatetimber.tree.TreeDefinition; import org.bukkit.Bukkit; +import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.FallingBlock; +import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -14,14 +25,17 @@ import org.bukkit.event.entity.EntityChangeBlockEvent; import java.util.HashSet; import java.util.Set; -public class TreeAnimationManager extends Manager implements Listener { +public class TreeAnimationManager extends Manager implements Listener, Runnable { - private Set activeAnimations; + private final Set activeAnimations; + private int taskId; public TreeAnimationManager(UltimateTimber ultimateTimber) { super(ultimateTimber); this.activeAnimations = new HashSet<>(); + this.taskId = -1; Bukkit.getPluginManager().registerEvents(this, ultimateTimber); + Bukkit.getScheduler().runTaskTimer(this.ultimateTimber, this, 0, 1L); } @Override @@ -32,6 +46,24 @@ public class TreeAnimationManager extends Manager implements Listener { @Override public void disable() { this.activeAnimations.clear(); + Bukkit.getScheduler().cancelTask(this.taskId); + } + + @Override + public void run() { + for (TreeAnimation treeAnimation : this.activeAnimations) { + Set> groundedBlocks = new HashSet<>(); + for (ITreeBlock fallingTreeBlock : treeAnimation.getFallingTreeBlocks().getAllTreeBlocks()) { + FallingBlock fallingBlock = fallingTreeBlock.getBlock(); + if (fallingBlock.isDead()) + groundedBlocks.add(fallingTreeBlock); + } + + for (ITreeBlock fallingBlock : groundedBlocks) { + this.runFallingBlockImpact(treeAnimation, fallingBlock); + treeAnimation.getFallingTreeBlocks().remove(fallingBlock); + } + } } /** @@ -57,6 +89,45 @@ public class TreeAnimationManager extends Manager implements Listener { } } + /** + * Checks if the given block is in an animation + * + * @param block The block to check + */ + public boolean isBlockInAnimation(Block block) { + for (TreeAnimation treeAnimation : this.activeAnimations) + for (ITreeBlock treeBlock : treeAnimation.getDetectedTree().getDetectedTreeBlocks().getAllTreeBlocks()) + if (treeBlock.getBlock().getLocation().equals(block.getLocation())) + return true; + return false; + } + + /** + * Checks if the given falling block is in an animation + * + * @param fallingBlock The falling block to check + */ + public boolean isBlockInAnimation(FallingBlock fallingBlock) { + for (TreeAnimation treeAnimation : this.activeAnimations) + for (ITreeBlock treeBlock : treeAnimation.getFallingTreeBlocks().getAllTreeBlocks()) + if (treeBlock.getBlock().equals(fallingBlock)) + return true; + return false; + } + + /** + * Gets a TreeAnimation that a given falling block is in + * + * @return A TreeAnimation + */ + private TreeAnimation getAnimationForBlock(FallingBlock fallingBlock) { + for (TreeAnimation treeAnimation : this.activeAnimations) + for (ITreeBlock treeBlock : treeAnimation.getFallingTreeBlocks().getAllTreeBlocks()) + if (treeBlock.getBlock().equals(fallingBlock)) + return treeAnimation; + return null; + } + /** * Registers and runs a tree animation */ @@ -65,9 +136,55 @@ public class TreeAnimationManager extends Manager implements Listener { treeAnimation.playAnimation(() -> this.activeAnimations.remove(treeAnimation)); } + /** + * Reacts to a falling block hitting the ground + * + * @param treeAnimation The tree animation for the falling block + * @param treeBlock The tree block to impact + */ + public void runFallingBlockImpact(TreeAnimation treeAnimation, ITreeBlock treeBlock) { + TreeDefinitionManager treeDefinitionManager = this.ultimateTimber.getTreeDefinitionManager(); + VersionAdapter versionAdapter = this.ultimateTimber.getVersionAdapter(); + boolean useCustomSound = ConfigurationManager.Setting.USE_CUSTOM_SOUNDS.getBoolean(); + boolean useCustomParticles = ConfigurationManager.Setting.USE_CUSTOM_PARTICLES.getBoolean(); + TreeDefinition treeDefinition = treeAnimation.getDetectedTree().getTreeDefinition(); + + if (useCustomParticles) + versionAdapter.playLandingParticles(treeDefinition, treeBlock); + if (useCustomSound) + versionAdapter.playLandingSound(treeBlock); + + treeDefinitionManager.dropTreeLoot(treeDefinition, treeBlock, treeAnimation.getPlayer(), treeAnimation.hasSilkTouch()); + this.ultimateTimber.getSaplingManager().replantSaplingWithChance(treeDefinition, treeBlock); + treeAnimation.getFallingTreeBlocks().remove(treeBlock); + } + @EventHandler(priority = EventPriority.HIGH) public void onFallingBlockLand(EntityChangeBlockEvent event) { + if (!event.getEntityType().equals(EntityType.FALLING_BLOCK)) + return; + FallingBlock fallingBlock = (FallingBlock)event.getEntity(); + if (!this.isBlockInAnimation(fallingBlock)) + return; + + if (ConfigurationManager.Setting.FALLING_BLOCKS_DEAL_DAMAGE.getBoolean()) { + int damage = ConfigurationManager.Setting.FALLING_BLOCK_DAMAGE.getInt(); + for (Entity entity : fallingBlock.getNearbyEntities(0.5, 0.5, 0.5)) { + if (!(entity instanceof LivingEntity)) continue; + ((LivingEntity)entity).damage(damage); + } + } + + if (ConfigurationManager.Setting.SCATTER_TREE_BLOCKS_ON_GROUND.getBoolean()) { + TreeAnimation treeAnimation = this.getAnimationForBlock(fallingBlock); + if (treeAnimation != null) { + treeAnimation.removeFallingBlock(fallingBlock); + return; + } + } + + event.setCancelled(true); } } diff --git a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeDefinitionManager.java b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeDefinitionManager.java index 343caaa..8553ce3 100644 --- a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeDefinitionManager.java +++ b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeDefinitionManager.java @@ -12,7 +12,6 @@ import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; diff --git a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeDetectionManager.java b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeDetectionManager.java index 52e078b..cca8c0a 100644 --- a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeDetectionManager.java +++ b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeDetectionManager.java @@ -2,7 +2,12 @@ package com.songoda.ultimatetimber.manager; import com.songoda.ultimatetimber.UltimateTimber; import com.songoda.ultimatetimber.adapter.IBlockData; -import com.songoda.ultimatetimber.tree.*; +import com.songoda.ultimatetimber.tree.DetectedTree; +import com.songoda.ultimatetimber.tree.ITreeBlock; +import com.songoda.ultimatetimber.tree.TreeBlock; +import com.songoda.ultimatetimber.tree.TreeBlockSet; +import com.songoda.ultimatetimber.tree.TreeBlockType; +import com.songoda.ultimatetimber.tree.TreeDefinition; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.util.Vector; diff --git a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeFallManager.java b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeFallManager.java index b6118de..216191d 100644 --- a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeFallManager.java +++ b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/manager/TreeFallManager.java @@ -68,6 +68,9 @@ public class TreeFallManager extends Manager implements Listener { if (!choppingManager.isChopping(player)) return; + if (treeAnimationManager.isBlockInAnimation(block)) + return; + if (!treeDefinitionManager.isToolValidForAnyTreeDefinition(tool)) return; diff --git a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/old_code/NoAnimationTreeDestroyer.java b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/old_code/NoAnimationTreeDestroyer.java deleted file mode 100644 index ac000ef..0000000 --- a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/old_code/NoAnimationTreeDestroyer.java +++ /dev/null @@ -1,20 +0,0 @@ -//package com.songoda.ultimatetimber.old_code; -// -//import org.bukkit.block.Block; -// -//import java.util.HashSet; -// -//class NoAnimationTreeDestroyer { -// -// /* -// Only ever triggers when people have tree falling animations off in the config -// */ -// static void destroyTree(HashSet blocks, boolean hasBonusLoot, boolean hasSilkTouch) { -// // Drop loot and plant a new sapling -// for (Block block : blocks) { -// TreeLoot.dropTreeLoot(block.getBlockData(), block.getLocation().clone().add(0.5, 0.5, 0.5), hasBonusLoot, hasSilkTouch); -// TreeReplant.replaceOriginalBlock(block); -// } -// } -// -//} diff --git a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/old_code/TreeEntityDamage.java b/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/old_code/TreeEntityDamage.java deleted file mode 100644 index 411af37..0000000 --- a/UltimateTimber/Plugin/src/main/java/com/songoda/ultimatetimber/old_code/TreeEntityDamage.java +++ /dev/null @@ -1,21 +0,0 @@ -//package com.songoda.ultimatetimber.old_code; -// -//import org.bukkit.entity.Entity; -//import org.bukkit.entity.FallingBlock; -//import org.bukkit.entity.LivingEntity; -// -//class TreeEntityDamage { -// -// static void runDamage(FallingBlock fallingBlock) { -// -// for (Entity entity : fallingBlock.getNearbyEntities(0.5, 0.5, 0.5)) { -// -// if (!(entity instanceof LivingEntity)) continue; -// -// ((LivingEntity) entity).damage(1); -// -// } -// -// } -// -//}