From 17161013ab8a02d2cb28407bac8e13ffee715d41 Mon Sep 17 00:00:00 2001 From: Thomas Couchoud Date: Tue, 29 Sep 2020 21:36:39 +0200 Subject: [PATCH] Shift down nether trees --- .../fallingtree/config/TreeConfiguration.java | 2 +- .../fr/raksrinana/fallingtree/tree/Tree.java | 70 +++++++------------ .../fallingtree/tree/TreeHandler.java | 61 +++++++++------- .../raksrinana/fallingtree/tree/TreePart.java | 28 ++++++++ .../fallingtree/utils/ToAnalyzePos.java | 21 ++++-- .../{TreePart.java => TreePartType.java} | 2 +- 6 files changed, 106 insertions(+), 78 deletions(-) create mode 100644 src/main/java/fr/raksrinana/fallingtree/tree/TreePart.java rename src/main/java/fr/raksrinana/fallingtree/utils/{TreePart.java => TreePartType.java} (70%) diff --git a/src/main/java/fr/raksrinana/fallingtree/config/TreeConfiguration.java b/src/main/java/fr/raksrinana/fallingtree/config/TreeConfiguration.java index ea223326..7886cb67 100644 --- a/src/main/java/fr/raksrinana/fallingtree/config/TreeConfiguration.java +++ b/src/main/java/fr/raksrinana/fallingtree/config/TreeConfiguration.java @@ -37,7 +37,7 @@ public class TreeConfiguration{ "INFO: Only in INSTANTANEOUS mode.") @Min(0) @Max(5) - public int minimumLeavesAroundRequired = 3; + public int minimumLeavesAroundRequired = 1; @Comment("When set to true, leaves that should naturally break will be broken instantly.") public boolean leavesBreaking = true; @Comment("Radius to force break leaves. If another tree is still holding the leaves they'll still be broken. If the leaves are persistent (placed by player) they'll also be destroyed. " + diff --git a/src/main/java/fr/raksrinana/fallingtree/tree/Tree.java b/src/main/java/fr/raksrinana/fallingtree/tree/Tree.java index 58896488..8238cc7f 100644 --- a/src/main/java/fr/raksrinana/fallingtree/tree/Tree.java +++ b/src/main/java/fr/raksrinana/fallingtree/tree/Tree.java @@ -1,75 +1,57 @@ package fr.raksrinana.fallingtree.tree; -import fr.raksrinana.fallingtree.utils.TreePart; +import fr.raksrinana.fallingtree.utils.TreePartType; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import java.util.*; -import java.util.stream.Stream; +import java.util.stream.Collectors; public class Tree{ private final World world; - private final Set logs; - private final Set warts; + private final Set parts; private final BlockPos hitPos; public Tree(World world, BlockPos blockPos){ this.world = world; this.hitPos = blockPos; - this.logs = new LinkedHashSet<>(); - this.warts = new LinkedHashSet<>(); + this.parts = new LinkedHashSet<>(); } - public void addLog(BlockPos blockPos){ - if(Objects.nonNull(blockPos)){ - this.logs.add(blockPos); - } + public void addPart(TreePart treePart){ + this.parts.add(treePart); } - public void addWart(BlockPos blockPos){ - if(Objects.nonNull(blockPos)){ - this.warts.add(blockPos); - } + public Optional getLastSequencePart(){ + return getParts().stream() + .max(Comparator.comparingInt(TreePart::getSequence)); } - public void addPart(TreePart treePart, BlockPos blockPos){ - switch(treePart){ - case LOG: - addLog(blockPos); - break; - case WART: - addWart(blockPos); - break; - } + public Collection getWarts(){ + return getParts().stream() + .filter(part -> part.getTreePartType() == TreePartType.WART) + .collect(Collectors.toSet()); } - public Collection getWarts(){ - return this.warts; - } - - public Optional getTopMostFurthestPart(){ - return getTopMostPart().flatMap(topMost -> logs.stream() - .filter(log -> Objects.equals(log.getY(), topMost.getY())) - .max(Comparator.comparingInt(this::getDistanceFromHit))); + public Collection getLogs(){ + return getParts().stream() + .filter(part -> part.getTreePartType() == TreePartType.LOG) + .collect(Collectors.toSet()); } private Optional getTopMostPart(){ - return getAllPartsStream().max(Comparator.comparingInt(BlockPos::getY)); + return getParts().stream() + .map(TreePart::getBlockPos) + .max(Comparator.comparingInt(BlockPos::getY)); } public Optional getTopMostLog(){ - return getLogs().stream().max(Comparator.comparingInt(BlockPos::getY)); - } - - private Stream getAllPartsStream(){ - return Stream.concat(getLogs().stream(), getWarts().stream()); - } - - public int getDistanceFromHit(BlockPos pos){ - return Math.abs(hitPos.getX() - pos.getX()) + Math.abs(hitPos.getY() - pos.getY()) + Math.abs(hitPos.getZ() - pos.getZ()); + return getLogs().stream() + .map(TreePart::getBlockPos) + .max(Comparator.comparingInt(BlockPos::getY)); } public int getLogCount(){ - return this.logs.size(); + return this.getLogs().size(); } public BlockPos getHitPos(){ @@ -80,7 +62,7 @@ public World getWorld(){ return this.world; } - public Collection getLogs(){ - return this.logs; + public Collection getParts(){ + return this.parts; } } diff --git a/src/main/java/fr/raksrinana/fallingtree/tree/TreeHandler.java b/src/main/java/fr/raksrinana/fallingtree/tree/TreeHandler.java index e5a13055..bd678ff2 100644 --- a/src/main/java/fr/raksrinana/fallingtree/tree/TreeHandler.java +++ b/src/main/java/fr/raksrinana/fallingtree/tree/TreeHandler.java @@ -2,7 +2,7 @@ import fr.raksrinana.fallingtree.FallingTree; import fr.raksrinana.fallingtree.utils.ToAnalyzePos; -import fr.raksrinana.fallingtree.utils.TreePart; +import fr.raksrinana.fallingtree.utils.TreePartType; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; @@ -25,10 +25,10 @@ public static Optional getTree(World world, BlockPos originPos){ Queue toAnalyzePos = new PriorityQueue<>(); Set analyzedPos = new HashSet<>(); Tree tree = new Tree(world, originPos); - toAnalyzePos.add(new ToAnalyzePos(originPos, originBlock, originPos, originBlock, TreePart.LOG)); + toAnalyzePos.add(new ToAnalyzePos(originPos, originBlock, originPos, originBlock, TreePartType.LOG, 0)); while(!toAnalyzePos.isEmpty()){ ToAnalyzePos analyzingPos = toAnalyzePos.remove(); - tree.addPart(analyzingPos.getTreePart(), analyzingPos.getCheckPos()); + tree.addPart(analyzingPos.toTreePart()); analyzedPos.add(analyzingPos); Collection nearbyPos = neighborLogs(world, originPos, originBlock, analyzingPos, analyzedPos); nearbyPos.removeAll(analyzedPos); @@ -56,7 +56,7 @@ private static Collection neighborLogs(World world, BlockPos origi for(int y = -1; y <= 1; y++){ checkPos.set(blockPos.getX() + x, blockPos.getY() + y, blockPos.getZ() + z); Block checkBlock = world.getBlockState(checkPos).getBlock(); - ToAnalyzePos analyzed = new ToAnalyzePos(blockPos, parent.getCheckBlock(), checkPos.toImmutable(), checkBlock, getTreePart(checkBlock)); + ToAnalyzePos analyzed = new ToAnalyzePos(blockPos, parent.getCheckBlock(), checkPos.toImmutable(), checkBlock, getTreePart(checkBlock), parent.getSequence() + 1); if(!analyzedPos.contains(analyzed) && shouldIncludeInChain(originPos, originBlock, parent, analyzed)){ neighborLogs.add(analyzed); } @@ -67,14 +67,14 @@ private static Collection neighborLogs(World world, BlockPos origi return neighborLogs; } - private static TreePart getTreePart(Block checkBlock){ + private static TreePartType getTreePart(Block checkBlock){ if(isLogBlock(checkBlock)){ - return TreePart.LOG; + return TreePartType.LOG; } if(isNetherWartOrShroomlight(checkBlock)){ - return TreePart.WART; + return TreePartType.WART; } - return TreePart.OTHER; + return TreePartType.OTHER; } private static long getLeavesAround(World world, BlockPos blockPos){ @@ -88,11 +88,11 @@ private static long getLeavesAround(World world, BlockPos blockPos){ } private static boolean shouldIncludeInChain(BlockPos originPos, Block originBlock, ToAnalyzePos parent, ToAnalyzePos check){ - if(parent.getTreePart() == TreePart.LOG && isSameTree(originBlock, check)){ + if(parent.getTreePartType() == TreePartType.LOG && isSameTree(originBlock, check)){ return true; } if(FallingTree.config.trees.isBreakNetherTreeWarts()){ - if(check.getTreePart() == TreePart.WART){ + if(check.getTreePartType() == TreePartType.WART){ BlockPos checkBlockPos = check.getCheckPos(); int dx = Math.abs(originPos.getX() - checkBlockPos.getX()); int dz = Math.abs(originPos.getZ() - checkBlockPos.getZ()); @@ -104,7 +104,7 @@ private static boolean shouldIncludeInChain(BlockPos originPos, Block originBloc private static boolean isSameTree(Block parentLogBlock, ToAnalyzePos check){ if(FallingTree.config.getTreesConfiguration().isAllowMixedLogs()){ - return check.getTreePart() == TreePart.LOG; + return check.getTreePartType() == TreePartType.LOG; } else{ return check.getCheckBlock().equals(parentLogBlock); @@ -126,24 +126,29 @@ public static boolean destroyInstant(Tree tree, PlayerEntity player, ItemStack t } } final boolean isTreeFullyBroken = damageMultiplicand == 0 || rawWeightedUsesLeft >= tree.getLogCount(); - tree.getLogs().stream().limit((int) rawWeightedUsesLeft).forEachOrdered(logBlock -> { - final BlockState logState = world.getBlockState(logBlock); - logState.getBlock().afterBreak(world, player, logBlock, logState, world.getBlockEntity(logBlock), tool); - world.removeBlock(logBlock, false); - }); + tree.getLogs().stream() + .limit((int) rawWeightedUsesLeft) + .map(TreePart::getBlockPos) + .forEachOrdered(logBlockPos -> { + final BlockState logState = world.getBlockState(logBlockPos); + logState.getBlock().afterBreak(world, player, logBlockPos, logState, world.getBlockEntity(logBlockPos), tool); + world.removeBlock(logBlockPos, false); + }); int toolDamage = (damageMultiplicand * (int) Math.min(tree.getLogCount(), rawWeightedUsesLeft)) - 1; if(toolDamage > 0){ tool.damage(toolDamage, player, (entity) -> {}); } if(isTreeFullyBroken){ - tree.getWarts().forEach(wartPos -> { - final BlockState wartState = world.getBlockState(wartPos); - wartState.getBlock().afterBreak(world, player, wartPos, wartState, world.getBlockEntity(wartPos), tool); - world.removeBlock(wartPos, false); - }); + tree.getWarts().stream() + .map(TreePart::getBlockPos) + .forEach(wartPos -> { + final BlockState wartState = world.getBlockState(wartPos); + wartState.getBlock().afterBreak(world, player, wartPos, wartState, world.getBlockEntity(wartPos), tool); + world.removeBlock(wartPos, false); + }); final int radius = FallingTree.config.getTreesConfiguration().getLeavesBreakingForceRadius(); if(radius > 0){ - tree.getLogs().stream().max(Comparator.comparingInt(BlockPos::getY)).ifPresent(topLog -> { + tree.getTopMostLog().ifPresent(topLog -> { BlockPos.Mutable checkPos = new BlockPos.Mutable(); for(int dx = -radius; dx < radius; dx++){ for(int dy = -radius; dy < radius; dy++){ @@ -175,11 +180,13 @@ public static boolean destroyShift(Tree tree, PlayerEntity player, ItemStack too return false; } } - tree.getTopMostFurthestPart().ifPresent(logBlock -> { - final BlockState logState = world.getBlockState(logBlock); - logState.getBlock().afterBreak(world, player, tree.getHitPos(), logState, world.getBlockEntity(logBlock), tool); - world.removeBlock(logBlock, false); - }); + tree.getLastSequencePart() + .map(TreePart::getBlockPos) + .ifPresent(logBlock -> { + final BlockState logState = world.getBlockState(logBlock); + logState.getBlock().afterBreak(world, player, tree.getHitPos(), logState, world.getBlockEntity(logBlock), tool); + world.removeBlock(logBlock, false); + }); int toolDamage = damageMultiplicand; if(toolDamage > 0){ tool.damage(toolDamage, player, (entity) -> {}); diff --git a/src/main/java/fr/raksrinana/fallingtree/tree/TreePart.java b/src/main/java/fr/raksrinana/fallingtree/tree/TreePart.java new file mode 100644 index 00000000..a7663b6c --- /dev/null +++ b/src/main/java/fr/raksrinana/fallingtree/tree/TreePart.java @@ -0,0 +1,28 @@ +package fr.raksrinana.fallingtree.tree; + +import fr.raksrinana.fallingtree.utils.TreePartType; +import net.minecraft.util.math.BlockPos; + +public class TreePart{ + private final BlockPos blockPos; + private final TreePartType treePartType; + private final int sequence; + + public TreePart(BlockPos blockPos, TreePartType treePartType, int sequence){ + this.blockPos = blockPos; + this.treePartType = treePartType; + this.sequence = sequence; + } + + public BlockPos getBlockPos(){ + return blockPos; + } + + public int getSequence(){ + return sequence; + } + + public TreePartType getTreePartType(){ + return treePartType; + } +} diff --git a/src/main/java/fr/raksrinana/fallingtree/utils/ToAnalyzePos.java b/src/main/java/fr/raksrinana/fallingtree/utils/ToAnalyzePos.java index 77a6867a..2fb1a193 100644 --- a/src/main/java/fr/raksrinana/fallingtree/utils/ToAnalyzePos.java +++ b/src/main/java/fr/raksrinana/fallingtree/utils/ToAnalyzePos.java @@ -1,5 +1,6 @@ package fr.raksrinana.fallingtree.utils; +import fr.raksrinana.fallingtree.tree.TreePart; import net.minecraft.block.Block; import net.minecraft.util.math.BlockPos; import java.util.Objects; @@ -9,14 +10,16 @@ public class ToAnalyzePos implements Comparable{ private final Block parentBlock; private final BlockPos checkPos; private final Block checkBlock; - private final TreePart treePart; + private final TreePartType treePartType; + private final int sequence; - public ToAnalyzePos(BlockPos parentPos, Block parentBlock, BlockPos checkPos, Block checkBlock, TreePart treePart){ + public ToAnalyzePos(BlockPos parentPos, Block parentBlock, BlockPos checkPos, Block checkBlock, TreePartType treePartType, int sequence){ this.parentPos = parentPos; this.parentBlock = parentBlock; this.checkPos = checkPos; this.checkBlock = checkBlock; - this.treePart = treePart; + this.treePartType = treePartType; + this.sequence = sequence; } @Override @@ -24,6 +27,10 @@ public int compareTo(ToAnalyzePos o){ return 0; } + public TreePart toTreePart(){ + return new TreePart(getCheckPos(), getTreePartType(), sequence); + } + public Block getCheckBlock(){ return checkBlock; } @@ -40,8 +47,12 @@ public BlockPos getCheckPos(){ return checkPos; } - public TreePart getTreePart(){ - return treePart; + public TreePartType getTreePartType(){ + return treePartType; + } + + public int getSequence(){ + return sequence; } @Override diff --git a/src/main/java/fr/raksrinana/fallingtree/utils/TreePart.java b/src/main/java/fr/raksrinana/fallingtree/utils/TreePartType.java similarity index 70% rename from src/main/java/fr/raksrinana/fallingtree/utils/TreePart.java rename to src/main/java/fr/raksrinana/fallingtree/utils/TreePartType.java index 73c823da..de6a5e88 100644 --- a/src/main/java/fr/raksrinana/fallingtree/utils/TreePart.java +++ b/src/main/java/fr/raksrinana/fallingtree/utils/TreePartType.java @@ -1,5 +1,5 @@ package fr.raksrinana.fallingtree.utils; -public enum TreePart{ +public enum TreePartType{ LOG, WART, OTHER }