diff --git a/build.gradle b/build.gradle index f31151d..8c58a5a 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ plugins { } group = 'com.maximde' -version = '2.9.1' +version = '2.9.2' repositories { mavenCentral() diff --git a/src/main/java/com/maximde/fancyphysics/listeners/player/BlockBreakListener.java b/src/main/java/com/maximde/fancyphysics/listeners/player/BlockBreakListener.java index b732238..9b38743 100644 --- a/src/main/java/com/maximde/fancyphysics/listeners/player/BlockBreakListener.java +++ b/src/main/java/com/maximde/fancyphysics/listeners/player/BlockBreakListener.java @@ -7,9 +7,13 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.BlockFace; +import org.bukkit.entity.BlockDisplay; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.util.Transformation; +import org.joml.Quaternionf; +import org.joml.Vector3f; import java.util.HashMap; @@ -23,7 +27,8 @@ public BlockBreakListener(FancyPhysics fancyPhysics) { public void onBlockBreak(BlockBreakEvent event) { if(event.isCancelled()) return; if(this.fancyPhysics.getPluginConfig().getDisabledWorldsList().contains(event.getPlayer().getLocation().getWorld().getName())) return; - manageTreePhysics(event); + boolean playParticles = manageTreePhysics(event); + if(!playParticles) return; if(fancyPhysics.getPluginConfig().isFlyUpParticles()) { this.fancyPhysics.getParticleGenerator().simulateBigBlockParticle(event.getBlock().getLocation(), event.getBlock().getType()); } else { @@ -34,16 +39,53 @@ public void onBlockBreak(BlockBreakEvent event) { /** * Creates a new Tree object and plays a break animation */ - private void manageTreePhysics(BlockBreakEvent event) { + private boolean manageTreePhysics(BlockBreakEvent event) { if (isWood(event.getBlock().getType()) && this.fancyPhysics.getPluginConfig().isRealisticTrees() && event.getBlock().getRelative(BlockFace.DOWN).getType() != Material.AIR && isWood(event.getBlock().getRelative(BlockFace.UP).getType())) { Tree tree = new Tree(event.getBlock(), this.fancyPhysics); + + if(fancyPhysics.getPluginConfig().isTreeChopDelay() && tree.isNatural() && tree.getStem().size() > 4 && !event.getBlock().getType().name().contains("STRIPPED") && !event.getBlock().getType().name().contains("FENCE")) { + event.getBlock().setType(getStripedLog(event.getBlock().getType())); + event.setCancelled(true); + return false; + } + + if(fancyPhysics.getPluginConfig().isTreeChopDelay() && tree.isNatural() && tree.getStem().size() > 8 && event.getBlock().getType().name().contains("STRIPPED")) { + event.getBlock().setType(getFenceFromStrippedLog(event.getBlock().getType())); + event.getBlock().getLocation().getWorld().spawn(event.getBlock().getLocation(), BlockDisplay.class, blockDisplay -> { + blockDisplay.setBlock(event.getBlock().getType().createBlockData()); + blockDisplay.setInterpolationDuration(0); + blockDisplay.setInterpolationDelay(-1); + blockDisplay.setTransformation(new Transformation( + new Vector3f(-1F,0,-1F), + new Quaternionf(0,0,0,1), + new Vector3f(3F, 1F, 3F), + new Quaternionf(0,0,0,1) + )); + Bukkit.getScheduler().scheduleSyncDelayedTask(this.fancyPhysics, () -> { + int animLenght = 3; + blockDisplay.setInterpolationDuration(animLenght); + blockDisplay.setInterpolationDelay(-1); + blockDisplay.setTransformation(new Transformation( + new Vector3f(0.1F,0,0.1F), + new Quaternionf(0,0,0,1), + new Vector3f(0.9F, 0.9F, 0.9F), + new Quaternionf(0,0,0,1) + )); + Bukkit.getScheduler().scheduleSyncDelayedTask(this.fancyPhysics, blockDisplay::remove, animLenght); + }, 2L); + }); + event.setCancelled(true); + return true; + } + TreeBreakEvent treeBreakEvent = new TreeBreakEvent(tree); Bukkit.getServer().getPluginManager().callEvent(treeBreakEvent); - if (treeBreakEvent.isCancelled()) return; + if (treeBreakEvent.isCancelled()) return true; tree.breakWithFallAnimation(); if(fancyPhysics.getPluginConfig().isTreeRegeneration()) regenerate(tree, 10); } + return true; } private void regenerate(Tree tree, int seconds) { @@ -56,12 +98,39 @@ private void regenerate(Tree tree, int seconds) { }, 20L * seconds); } - private boolean isWood(Material pMaterial) { - return switch (pMaterial.name()) { - case "BIRCH_LOG", "OAK_LOG", "SPRUCE_LOG", "DARK_OAK_LOG", "ACACIA_LOG", "JUNGLE_LOG", "CRIMSON_STEM", "WARPED_STEM", "MANGROVE_LOG", "CHERRY_LOG" -> - true; - default -> false; + private Material getStripedLog(Material logType) { + return switch (logType) { + case BIRCH_LOG -> Material.STRIPPED_BIRCH_LOG; + case SPRUCE_LOG -> Material.STRIPPED_SPRUCE_LOG; + case DARK_OAK_LOG -> Material.STRIPPED_DARK_OAK_LOG; + case ACACIA_LOG -> Material.STRIPPED_ACACIA_LOG; + case JUNGLE_LOG -> Material.STRIPPED_JUNGLE_LOG; + case CRIMSON_STEM -> Material.STRIPPED_CRIMSON_STEM; + case WARPED_STEM -> Material.STRIPPED_WARPED_STEM; + case MANGROVE_LOG -> Material.STRIPPED_MANGROVE_LOG; + case CHERRY_LOG -> Material.STRIPPED_CHERRY_LOG; + default -> Material.STRIPPED_OAK_LOG; }; } + private Material getFenceFromStrippedLog(Material strippedLog) { + return switch (strippedLog) { + case STRIPPED_BIRCH_LOG -> Material.BIRCH_FENCE; + case STRIPPED_SPRUCE_LOG -> Material.SPRUCE_FENCE; + case STRIPPED_DARK_OAK_LOG -> Material.DARK_OAK_FENCE; + case STRIPPED_ACACIA_LOG -> Material.ACACIA_FENCE; + case STRIPPED_JUNGLE_LOG -> Material.JUNGLE_FENCE; + case STRIPPED_CRIMSON_STEM -> Material.CRIMSON_FENCE; + case STRIPPED_WARPED_STEM -> Material.WARPED_FENCE; + case STRIPPED_MANGROVE_LOG -> Material.MANGROVE_FENCE; + case STRIPPED_CHERRY_LOG -> Material.CHERRY_FENCE; + default -> Material.OAK_FENCE; + }; + } + + + private boolean isWood(Material pMaterial) { + return pMaterial.name().endsWith("LOG") || pMaterial.name().endsWith("STEM") ||pMaterial.name().endsWith("FENCE"); + } + } diff --git a/src/main/java/com/maximde/fancyphysics/utils/Config.java b/src/main/java/com/maximde/fancyphysics/utils/Config.java index 66b5a15..fca3bc2 100644 --- a/src/main/java/com/maximde/fancyphysics/utils/Config.java +++ b/src/main/java/com/maximde/fancyphysics/utils/Config.java @@ -39,6 +39,7 @@ public class Config { private List blockParticleBlackList; private List disabledWorldsList; private boolean sounds; + private boolean treeChopDelay; public Config() { String[] settingsPhysicsEnabled = { @@ -54,7 +55,8 @@ public Config() { "VisualCrafting", "FallingBlockPhysics", "NaturalDropsOnExplode", - "BlockCrackOnFall"}; + "BlockCrackOnFall", + "TreeChopDelay"}; String[] settingsPhysicsDisabled = { "TrapdoorPhysics", @@ -134,6 +136,7 @@ private void initValues() { treeMaxInvalidScans = cfg.getInt("Physics.TreeMaxInvalidScans"); treeMaxInvalidBlockDistance = cfg.getInt("Physics.TreeMaxInvalidBlockDistance"); sounds = cfg.getBoolean("Physics.Sounds"); + treeChopDelay = cfg.getBoolean("Physics.TreeChopDelay"); } public void reload() { diff --git a/src/main/java/com/maximde/fancyphysics/utils/Tree.java b/src/main/java/com/maximde/fancyphysics/utils/Tree.java index fa2b472..dac4c25 100644 --- a/src/main/java/com/maximde/fancyphysics/utils/Tree.java +++ b/src/main/java/com/maximde/fancyphysics/utils/Tree.java @@ -20,6 +20,7 @@ public class Tree { /** * Returns true if the tree's properties are characteristic of a naturally generated tree. */ + @Getter private boolean isNatural; /** * The block that was broken by the player @@ -47,10 +48,12 @@ public class Tree { public Tree(Block origin, FancyPhysics fancyPhysics) { this.fancyPhysics = fancyPhysics; this.origin = origin; - this.wood_material = origin.getType(); + Block aboveOrigin = origin.getLocation().clone().add(0, 1, 0).getBlock(); + this.wood_material = aboveOrigin.getType(); this.leave_material = Material.valueOf(getLeaveType(this.wood_material)); - scanTree(origin); - this.isNatural = (this.stem.size() > 3 && this.leaves.size() > 8); + scanTree(aboveOrigin); + stem.add(origin); + this.isNatural = (this.stem.size() > 3 && this.leaves.size() > 5); } /** @@ -171,25 +174,26 @@ public void breakInstantWithParticles() { /** * Determines the material of the leaves based on the wood material of the tree. * - * @param wood The wood material of the tree. + * @param material The wood material of the tree. * @return The material of the leaves. */ - private String getLeaveType(Material wood) { - return switch (wood.name()) { - case "OAK_LOG" -> "OAK_LEAVES"; - case "DARK_OAK_LOG" -> "DARK_OAK_LEAVES"; - case "JUNGLE_LOG" -> "JUNGLE_LEAVES"; - case "ACACIA_LOG" -> "ACACIA_LEAVES"; - case "BIRCH_LOG" -> "BIRCH_LEAVES"; - case "SPRUCE_LOG" -> "SPRUCE_LEAVES"; - case "CHERRY_LOG" -> "CHERRY_LEAVES"; - case "MANGROVE_LOG" -> "MANGROVE_LEAVES"; - case "WARPED_STEM" -> "WARPED_WART_BLOCK"; + private String getLeaveType(Material material) { + return switch (material.name()) { + case "OAK_LOG", "STRIPPED_OAK_LOG", "OAK_FENCE" -> "OAK_LEAVES"; + case "DARK_OAK_LOG", "STRIPPED_DARK_OAK_LOG", "DARK_OAK_FENCE" -> "DARK_OAK_LEAVES"; + case "JUNGLE_LOG", "STRIPPED_JUNGLE_LOG", "JUNGLE_FENCE" -> "JUNGLE_LEAVES"; + case "ACACIA_LOG", "STRIPPED_ACACIA_LOG", "ACACIA_FENCE" -> "ACACIA_LEAVES"; + case "BIRCH_LOG", "STRIPPED_BIRCH_LOG", "BIRCH_FENCE" -> "BIRCH_LEAVES"; + case "SPRUCE_LOG", "STRIPPED_SPRUCE_LOG", "SPRUCE_FENCE" -> "SPRUCE_LEAVES"; + case "CHERRY_LOG", "STRIPPED_CHERRY_LOG", "CHERRY_FENCE" -> "CHERRY_LEAVES"; + case "MANGROVE_LOG", "STRIPPED_MANGROVE_LOG", "MANGROVE_FENCE" -> "MANGROVE_LEAVES"; + case "WARPED_STEM", "NETHER_WART_BLOCK" -> "WARPED_WART_BLOCK"; case "CRIMSON_STEM" -> "NETHER_WART_BLOCK"; default -> "AIR"; }; } + private int distanceToLastValid = 0; private int amount = 0; @@ -236,7 +240,7 @@ private void scanTree(Block block) { final var currentBlock = block.getRelative(blockFace); boolean scan = (currentBlock.getType() == this.wood_material || currentBlock.getType() == this.leave_material); - if(blockFace == BlockFace.DOWN && currentBlock.getY() <= this.origin.getY()) { + if(blockFace == BlockFace.DOWN && currentBlock.getY() <= this.origin.getY() + 12) { scan = false; } if (scan) {