Clean up imports, start work on fancy tree animation

This commit is contained in:
Esophose 2019-04-01 04:22:08 -06:00
parent 26c567bb56
commit 7b2ddb1562
23 changed files with 387 additions and 100 deletions

View File

@ -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<ItemStack> 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();

View File

@ -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<Byte> data = new ArrayList<>();
data.add(block.getData());
treeBlockData = new LegacyBlockData(block.getType(), data);

View File

@ -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")

View File

@ -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;

View File

@ -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<FallingBlock> {

View File

@ -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<BlockType> {

View File

@ -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<Block> {

View File

@ -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<BlockType> implements Collection {

View File

@ -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;

View File

@ -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;

View File

@ -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<FallingBlock> 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<FallingBlock> 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<FallingBlock> fallingTreeBlock : this.fallingTreeBlocks.getAllTreeBlocks()) {
if (fallingTreeBlock.equals(fallingBlock)) {
this.fallingTreeBlocks.remove(fallingTreeBlock);
return;
}
}
}
}

View File

@ -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 {

View File

@ -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);

View File

@ -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<Block> 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<Block> 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<FallingBlock> 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<FallingBlock> 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<FallingBlock> fallingTreeBlock : TreeAnimationFancy.this.fallingTreeBlocks.getAllTreeBlocks())
treeAnimationManager.runFallingBlockImpact(TreeAnimationFancy.this, fallingTreeBlock);
whenFinished.run();
this.cancel();
}
}
}.runTaskTimer(ultimateTimber, 20L, 1L);
whenFinished.run();
}
}

View File

@ -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<Block> 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();
}
}

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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<TreeAnimation> activeAnimations;
private final Set<TreeAnimation> 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<ITreeBlock<FallingBlock>> groundedBlocks = new HashSet<>();
for (ITreeBlock<FallingBlock> fallingTreeBlock : treeAnimation.getFallingTreeBlocks().getAllTreeBlocks()) {
FallingBlock fallingBlock = fallingTreeBlock.getBlock();
if (fallingBlock.isDead())
groundedBlocks.add(fallingTreeBlock);
}
for (ITreeBlock<FallingBlock> 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<Block> 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<FallingBlock> 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<FallingBlock> 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<FallingBlock> 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);
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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<Block> 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);
// }
// }
//
//}

View File

@ -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);
//
// }
//
// }
//
//}