From 005daf93f8b609ce17bb1b026c6b0b9e32c51606 Mon Sep 17 00:00:00 2001 From: Thomas Couchoud <1688389+Rakambda@users.noreply.github.com> Date: Sun, 9 Feb 2025 18:24:16 +0100 Subject: [PATCH] Fix previous release # Conflicts: # fabric/src/main/java/fr/rakambda/fallingtree/fabric/mixin/AbstractBlockMixin.java --- .../common/tree/BreakTreeResult.java | 24 --- .../common/tree/IBreakAttemptResult.java | 2 +- .../common/tree/SuccessResult.java | 16 ++ .../fallingtree/common/tree/Tree.java | 35 +++- .../fallingtree/common/tree/TreeHandler.java | 19 +-- .../fallingtree/common/tree/TreePart.java | 7 +- .../fallingtree/common/tree/TreePartType.java | 14 +- .../FallingAnimationTreeBreakingHandler.java | 14 +- .../tree/breaking/ITreeBreakingHandler.java | 4 +- .../InstantaneousTreeBreakingHandler.java | 14 +- .../ShiftDownTreeBreakingHandler.java | 70 +++++--- .../tree/breaking/ToolDamageHandler.java | 2 +- .../common/tree/builder/ToAnalyzePos.java | 7 +- .../common/tree/builder/TreeBuilder.java | 20 +-- .../position/AbovePositionFetcher.java | 21 +-- .../tree/builder/position/AboveYFetcher.java | 17 +- .../position/BasicPositionFetcher.java | 17 +- .../fallingtree/common/wrapper/ILevel.java | 2 + .../fabric/common/FallingTreeCommonsImpl.java | 1 + .../fabric/common/wrapper/LevelWrapper.java | 153 +++++++++--------- .../fabric/event/BlockBreakListener.java | 7 +- .../fabric/mixin/AbstractBlockMixin.java | 4 +- .../forge/common/wrapper/LevelWrapper.java | 5 + .../forge/event/BlockBreakListener.java | 17 +- .../neoforge/common/wrapper/LevelWrapper.java | 151 ++++++++--------- .../neoforge/event/BlockBreakListener.java | 15 +- 26 files changed, 383 insertions(+), 275 deletions(-) delete mode 100644 common/src/main/java/fr/rakambda/fallingtree/common/tree/BreakTreeResult.java create mode 100644 common/src/main/java/fr/rakambda/fallingtree/common/tree/SuccessResult.java diff --git a/common/src/main/java/fr/rakambda/fallingtree/common/tree/BreakTreeResult.java b/common/src/main/java/fr/rakambda/fallingtree/common/tree/BreakTreeResult.java deleted file mode 100644 index 687a1c2c..00000000 --- a/common/src/main/java/fr/rakambda/fallingtree/common/tree/BreakTreeResult.java +++ /dev/null @@ -1,24 +0,0 @@ -package fr.rakambda.fallingtree.common.tree; - -import fr.rakambda.fallingtree.common.config.enums.BreakMode; -import org.jetbrains.annotations.NotNull; - -/** - * Record that denotes that an attempt to break a tree with the given mode has - * succeeded. Failures are instead denoted as {@link AbortedResult}. - * - * @param shouldCancel Whether the event which triggered the query should be cancelled as a result of this result. - * @param breakMode The mode with which the block was broken. - */ -public record BreakTreeResult( - boolean shouldCancel, - @NotNull BreakMode breakMode -) implements IBreakAttemptResult{ - @Override - public boolean shouldCancel(){ - return switch(breakMode()){ - case INSTANTANEOUS, FALL_ITEM, FALL_BLOCK, FALL_ALL_BLOCK -> shouldCancel; - case SHIFT_DOWN -> true; - }; - } -} diff --git a/common/src/main/java/fr/rakambda/fallingtree/common/tree/IBreakAttemptResult.java b/common/src/main/java/fr/rakambda/fallingtree/common/tree/IBreakAttemptResult.java index 037b54db..e9d0edd5 100644 --- a/common/src/main/java/fr/rakambda/fallingtree/common/tree/IBreakAttemptResult.java +++ b/common/src/main/java/fr/rakambda/fallingtree/common/tree/IBreakAttemptResult.java @@ -9,6 +9,6 @@ * Failures are generally instances of {@link AbortedResult}, where are succeeded attempts are instances of * {@link BreakTreeResult}. */ -public sealed interface IBreakAttemptResult permits BreakTreeResult, AbortedResult{ +public sealed interface IBreakAttemptResult permits SuccessResult, AbortedResult{ boolean shouldCancel(); } diff --git a/common/src/main/java/fr/rakambda/fallingtree/common/tree/SuccessResult.java b/common/src/main/java/fr/rakambda/fallingtree/common/tree/SuccessResult.java new file mode 100644 index 00000000..58853092 --- /dev/null +++ b/common/src/main/java/fr/rakambda/fallingtree/common/tree/SuccessResult.java @@ -0,0 +1,16 @@ +package fr.rakambda.fallingtree.common.tree; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public enum SuccessResult implements IBreakAttemptResult { + CANCEL(true), + DO_NOT_CANCEL(false); + + private final boolean cancel; + + @Override + public boolean shouldCancel() { + return cancel; + } +} diff --git a/common/src/main/java/fr/rakambda/fallingtree/common/tree/Tree.java b/common/src/main/java/fr/rakambda/fallingtree/common/tree/Tree.java index cb120996..1a9cca11 100644 --- a/common/src/main/java/fr/rakambda/fallingtree/common/tree/Tree.java +++ b/common/src/main/java/fr/rakambda/fallingtree/common/tree/Tree.java @@ -1,14 +1,20 @@ package fr.rakambda.fallingtree.common.tree; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import static java.util.Comparator.comparingInt; +import static java.util.Objects.isNull; +import static java.util.stream.Collectors.toSet; import fr.rakambda.fallingtree.common.wrapper.IBlockPos; import fr.rakambda.fallingtree.common.wrapper.ILevel; import lombok.Getter; import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; -import java.util.*; -import static java.util.Comparator.comparingInt; -import static java.util.Objects.isNull; -import static java.util.stream.Collectors.toSet; @RequiredArgsConstructor public class Tree{ @@ -68,9 +74,17 @@ public Optional getLastSequencePart(){ } @NotNull - public Collection getLogs(){ + public Optional getLastSequenceLogPart(){ + return getParts().stream() + .filter(part -> part.treePartType().isLog()) + .max(comparingInt(TreePart::sequence)); + } + + @NotNull + public Collection getBreakableLogs(){ return getParts().stream() - .filter(part -> part.treePartType() == TreePartType.LOG) + .filter(part -> part.treePartType().isLog()) + .filter(part -> part.treePartType().isBreakable()) .collect(toSet()); } @@ -87,7 +101,7 @@ public int getLogCount(){ @NotNull public Optional getTopMostLog(){ - return getLogs().stream() + return getBreakableLogs().stream() .map(TreePart::blockPos) .max(comparingInt(IBlockPos::getY)); } @@ -105,4 +119,11 @@ public Collection getWarts(){ .filter(part -> part.treePartType() == TreePartType.NETHER_WART) .collect(toSet()); } + + @NotNull + public Optional getStart(){ + return getParts().stream() + .filter(part -> part.treePartType() == TreePartType.LOG_START) + .findFirst(); + } } diff --git a/common/src/main/java/fr/rakambda/fallingtree/common/tree/TreeHandler.java b/common/src/main/java/fr/rakambda/fallingtree/common/tree/TreeHandler.java index 52e90eb7..1602ad75 100644 --- a/common/src/main/java/fr/rakambda/fallingtree/common/tree/TreeHandler.java +++ b/common/src/main/java/fr/rakambda/fallingtree/common/tree/TreeHandler.java @@ -14,7 +14,9 @@ import fr.rakambda.fallingtree.common.tree.breaking.ShiftDownTreeBreakingHandler; import fr.rakambda.fallingtree.common.tree.builder.TreeTooBigException; import fr.rakambda.fallingtree.common.utils.CacheSpeed; +import fr.rakambda.fallingtree.common.wrapper.IBlockEntity; import fr.rakambda.fallingtree.common.wrapper.IBlockPos; +import fr.rakambda.fallingtree.common.wrapper.IBlockState; import fr.rakambda.fallingtree.common.wrapper.IItemStack; import fr.rakambda.fallingtree.common.wrapper.ILevel; import fr.rakambda.fallingtree.common.wrapper.IPlayer; @@ -40,7 +42,7 @@ private boolean shouldPreserveTool(@NotNull IPlayer player){ } @NotNull - public IBreakAttemptResult breakTree(@NotNull ILevel level, @NotNull IPlayer player, @NotNull IBlockPos blockPos){ + public IBreakAttemptResult breakTree(boolean isCancellable, @NotNull ILevel level, @NotNull IPlayer player, @NotNull IBlockPos originPos, @NotNull IBlockState originState, @Nullable IBlockEntity originEntity){ if(!level.isServer()){ return AbortedResult.NOT_SERVER; } @@ -48,7 +50,7 @@ public IBreakAttemptResult breakTree(@NotNull ILevel level, @NotNull IPlayer pla return AbortedResult.NOT_ENABLED; } - if(!mod.checkForceToolUsage(player, level, blockPos)){ + if(!mod.checkForceToolUsage(player, level, originPos)){ mod.notifyPlayer(player, mod.translate("chat.fallingtree.force_tool_usage", mod.getConfiguration().getTrees().getMaxScanSize())); return AbortedResult.REQUIRED_TOOL_ABSENT; } @@ -58,15 +60,14 @@ public IBreakAttemptResult breakTree(@NotNull ILevel level, @NotNull IPlayer pla } try{ - var treeOptional = mod.getTreeBuilder().getTree(player, level, blockPos); + var treeOptional = mod.getTreeBuilder().getTree(player, level, originPos, originState, originEntity); if(treeOptional.isEmpty()){ return AbortedResult.NO_SUCH_TREE; } var tree = treeOptional.get(); var breakMode = getBreakMode(player.getMainHandItem()); - var result = getBreakingHandler(breakMode).breakTree(player, tree); - return new BreakTreeResult(!result, breakMode); + return getBreakingHandler(breakMode).breakTree(isCancellable, player, tree); } catch(TreeTooBigException e){ mod.notifyPlayer(player, mod.translate("chat.fallingtree.tree_too_big", mod.getConfiguration().getTrees().getMaxScanSize())); @@ -96,7 +97,7 @@ private ITreeBreakingHandler getBreakingHandler(@NotNull BreakMode breakMode){ } @NotNull - public Optional getBreakSpeed(@NotNull IPlayer player, @NotNull IBlockPos blockPos, float originalSpeed){ + public Optional getBreakSpeed(@NotNull IPlayer player, @NotNull IBlockPos blockPos, @NotNull IBlockState blockState, float originalSpeed){ if(!mod.getConfiguration().getTrees().isTreeBreaking()){ return Optional.empty(); } @@ -109,7 +110,7 @@ public Optional getBreakSpeed(@NotNull IPlayer player, @NotNull IBlockPos var cacheSpeed = speedCache.compute(player.getUUID(), (uuid, speed) -> { if(isNull(speed) || !speed.isValid(blockPos)){ - speed = getSpeed(player, blockPos, originalSpeed); + speed = getSpeed(player, blockPos, blockState, originalSpeed); } return speed; }); @@ -117,11 +118,11 @@ public Optional getBreakSpeed(@NotNull IPlayer player, @NotNull IBlockPos } @Nullable - private CacheSpeed getSpeed(@NotNull IPlayer player, @NotNull IBlockPos pos, float originalSpeed){ + private CacheSpeed getSpeed(@NotNull IPlayer player, @NotNull IBlockPos pos, @NotNull IBlockState blockState, float originalSpeed){ var speedMultiplicand = mod.getConfiguration().getTools().getSpeedMultiplicand(); try{ return speedMultiplicand <= 0 ? null : - mod.getTreeBuilder().getTree(player, player.getLevel(), pos) + mod.getTreeBuilder().getTree(player, player.getLevel(), pos, blockState, null) .map(tree -> new CacheSpeed(pos, originalSpeed / ((float) speedMultiplicand * tree.getLogCount()))) .orElse(null); } diff --git a/common/src/main/java/fr/rakambda/fallingtree/common/tree/TreePart.java b/common/src/main/java/fr/rakambda/fallingtree/common/tree/TreePart.java index 43f18d32..3a31d3f7 100644 --- a/common/src/main/java/fr/rakambda/fallingtree/common/tree/TreePart.java +++ b/common/src/main/java/fr/rakambda/fallingtree/common/tree/TreePart.java @@ -1,11 +1,16 @@ package fr.rakambda.fallingtree.common.tree; +import fr.rakambda.fallingtree.common.wrapper.IBlockEntity; import fr.rakambda.fallingtree.common.wrapper.IBlockPos; +import fr.rakambda.fallingtree.common.wrapper.IBlockState; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public record TreePart( @NotNull IBlockPos blockPos, @NotNull TreePartType treePartType, - int sequence + int sequence, + @NotNull IBlockState blockState, + @Nullable IBlockEntity blockEntity ){ } diff --git a/common/src/main/java/fr/rakambda/fallingtree/common/tree/TreePartType.java b/common/src/main/java/fr/rakambda/fallingtree/common/tree/TreePartType.java index e2ebd6c1..da69230d 100644 --- a/common/src/main/java/fr/rakambda/fallingtree/common/tree/TreePartType.java +++ b/common/src/main/java/fr/rakambda/fallingtree/common/tree/TreePartType.java @@ -6,12 +6,13 @@ @Getter @RequiredArgsConstructor public enum TreePartType{ - LEAF(false, true, false), - LEAF_NEED_BREAK(true, true, true), - LOG(true, false, true), - NETHER_WART(true, false, true), - MANGROVE_ROOTS(true, false, true), - OTHER(false, false, false); + LEAF(false, true, false, false), + LEAF_NEED_BREAK(true, true, true, false), + LOG(true, false, true, true), + LOG_START(false, false, true, true), + MANGROVE_ROOTS(true, false, true, false), + NETHER_WART(true, false, true, false), + OTHER(false, false, false, false); @Getter private static final TreePartType[] values = values(); @@ -19,4 +20,5 @@ public enum TreePartType{ private final boolean breakable; private final boolean edge; private final boolean includeInTree; + private final boolean log; } diff --git a/common/src/main/java/fr/rakambda/fallingtree/common/tree/breaking/FallingAnimationTreeBreakingHandler.java b/common/src/main/java/fr/rakambda/fallingtree/common/tree/breaking/FallingAnimationTreeBreakingHandler.java index cfcbeb3e..ae6d1d99 100644 --- a/common/src/main/java/fr/rakambda/fallingtree/common/tree/breaking/FallingAnimationTreeBreakingHandler.java +++ b/common/src/main/java/fr/rakambda/fallingtree/common/tree/breaking/FallingAnimationTreeBreakingHandler.java @@ -1,6 +1,8 @@ package fr.rakambda.fallingtree.common.tree.breaking; import fr.rakambda.fallingtree.common.FallingTreeCommon; +import fr.rakambda.fallingtree.common.tree.IBreakAttemptResult; +import fr.rakambda.fallingtree.common.tree.SuccessResult; import fr.rakambda.fallingtree.common.tree.Tree; import fr.rakambda.fallingtree.common.wrapper.IBlockPos; import fr.rakambda.fallingtree.common.wrapper.ILevel; @@ -24,7 +26,8 @@ public class FallingAnimationTreeBreakingHandler implements ITreeBreakingHandler private final LeafForceBreaker leafForceBreaker; @Override - public boolean breakTree(@NotNull IPlayer player, @NotNull Tree tree) throws BreakTreeTooBigException{ + @NotNull + public IBreakAttemptResult breakTree(boolean isCancellable, @NotNull IPlayer player, @NotNull Tree tree) throws BreakTreeTooBigException{ var tool = player.getMainHandItem(); var level = tree.getLevel(); var toolHandler = new ToolDamageHandler(tool, @@ -36,9 +39,9 @@ public boolean breakTree(@NotNull IPlayer player, @NotNull Tree tree) throws Bre mod.getConfiguration().getTools().getDamageRounding()); if(toolHandler.isPreserveTool()){ - log.debug("Didn't break tree at {} as {}'s tool was about to break", tree.getHitPos(), player); + log.info("Didn't break tree at {} as {}'s tool was about to break", tree.getHitPos(), player); mod.notifyPlayer(player, mod.translate("chat.fallingtree.prevented_break_tool")); - return false; + return SuccessResult.DO_NOT_CANCEL; } var scannedLeaves = new LinkedList(); @@ -84,7 +87,10 @@ public boolean breakTree(@NotNull IPlayer player, @NotNull Tree tree) throws Bre if(brokenCount >= wantToBreakCount){ leafForceBreaker.forceBreakDecayLeaves(player, tree, level); } - return true; + if(player.isCreative() && mod.getConfiguration().isLootInCreative()){ + tree.getStart().ifPresent(part -> part.blockState().getBlock().playerDestroy(level, player, tree.getHitPos(), part.blockState(), part.blockEntity(), tool)); + } + return SuccessResult.DO_NOT_CANCEL; } private void fallLeaf(LinkedList scannedLeaves, @NotNull IPlayer player, @NotNull ILevel level, int distance, @NotNull IBlockPos blockPos){ diff --git a/common/src/main/java/fr/rakambda/fallingtree/common/tree/breaking/ITreeBreakingHandler.java b/common/src/main/java/fr/rakambda/fallingtree/common/tree/breaking/ITreeBreakingHandler.java index a4154183..8df0816a 100644 --- a/common/src/main/java/fr/rakambda/fallingtree/common/tree/breaking/ITreeBreakingHandler.java +++ b/common/src/main/java/fr/rakambda/fallingtree/common/tree/breaking/ITreeBreakingHandler.java @@ -1,9 +1,11 @@ package fr.rakambda.fallingtree.common.tree.breaking; +import fr.rakambda.fallingtree.common.tree.IBreakAttemptResult; import fr.rakambda.fallingtree.common.tree.Tree; import fr.rakambda.fallingtree.common.wrapper.IPlayer; import org.jetbrains.annotations.NotNull; public interface ITreeBreakingHandler{ - boolean breakTree(@NotNull IPlayer player, @NotNull Tree tree) throws BreakTreeTooBigException; + @NotNull + IBreakAttemptResult breakTree(boolean isCancellable, @NotNull IPlayer player, @NotNull Tree tree) throws BreakTreeTooBigException; } diff --git a/common/src/main/java/fr/rakambda/fallingtree/common/tree/breaking/InstantaneousTreeBreakingHandler.java b/common/src/main/java/fr/rakambda/fallingtree/common/tree/breaking/InstantaneousTreeBreakingHandler.java index 079ee3d7..edfe2540 100644 --- a/common/src/main/java/fr/rakambda/fallingtree/common/tree/breaking/InstantaneousTreeBreakingHandler.java +++ b/common/src/main/java/fr/rakambda/fallingtree/common/tree/breaking/InstantaneousTreeBreakingHandler.java @@ -1,6 +1,8 @@ package fr.rakambda.fallingtree.common.tree.breaking; import fr.rakambda.fallingtree.common.FallingTreeCommon; +import fr.rakambda.fallingtree.common.tree.IBreakAttemptResult; +import fr.rakambda.fallingtree.common.tree.SuccessResult; import fr.rakambda.fallingtree.common.tree.Tree; import fr.rakambda.fallingtree.common.tree.TreePart; import fr.rakambda.fallingtree.common.wrapper.IPlayer; @@ -18,7 +20,8 @@ public class InstantaneousTreeBreakingHandler implements ITreeBreakingHandler{ private final LeafForceBreaker leafForceBreaker; @Override - public boolean breakTree(@NotNull IPlayer player, @NotNull Tree tree) throws BreakTreeTooBigException{ + @NotNull + public IBreakAttemptResult breakTree(boolean isCancellable, @NotNull IPlayer player, @NotNull Tree tree) throws BreakTreeTooBigException{ var tool = player.getMainHandItem(); var level = tree.getLevel(); var toolHandler = new ToolDamageHandler(tool, @@ -30,9 +33,9 @@ public boolean breakTree(@NotNull IPlayer player, @NotNull Tree tree) throws Bre mod.getConfiguration().getTools().getDamageRounding()); if(toolHandler.isPreserveTool()){ - log.debug("Didn't break tree at {} as {}'s tool was about to break", tree.getHitPos(), player); + log.info("Didn't break tree at {} as {}'s tool was about to break", tree.getHitPos(), player); mod.notifyPlayer(player, mod.translate("chat.fallingtree.prevented_break_tool")); - return false; + return SuccessResult.DO_NOT_CANCEL; } var wantToBreakCount = Math.min(tree.getBreakableCount(), toolHandler.getMaxBreakCount()); @@ -71,7 +74,10 @@ public boolean breakTree(@NotNull IPlayer player, @NotNull Tree tree) throws Bre if(brokenCount >= wantToBreakCount){ leafForceBreaker.forceBreakDecayLeaves(player, tree, level); } - return true; + if(player.isCreative() && mod.getConfiguration().isLootInCreative()){ + tree.getStart().ifPresent(part -> part.blockState().getBlock().playerDestroy(level, player, tree.getHitPos(), part.blockState(), part.blockEntity(), tool)); + } + return SuccessResult.DO_NOT_CANCEL; } @NotNull diff --git a/common/src/main/java/fr/rakambda/fallingtree/common/tree/breaking/ShiftDownTreeBreakingHandler.java b/common/src/main/java/fr/rakambda/fallingtree/common/tree/breaking/ShiftDownTreeBreakingHandler.java index 327bc016..d62b2051 100644 --- a/common/src/main/java/fr/rakambda/fallingtree/common/tree/breaking/ShiftDownTreeBreakingHandler.java +++ b/common/src/main/java/fr/rakambda/fallingtree/common/tree/breaking/ShiftDownTreeBreakingHandler.java @@ -1,8 +1,15 @@ package fr.rakambda.fallingtree.common.tree.breaking; +import java.util.Collection; +import java.util.List; +import static fr.rakambda.fallingtree.common.tree.TreePartType.NETHER_WART; +import static java.util.Objects.isNull; import fr.rakambda.fallingtree.common.FallingTreeCommon; +import fr.rakambda.fallingtree.common.tree.IBreakAttemptResult; +import fr.rakambda.fallingtree.common.tree.SuccessResult; import fr.rakambda.fallingtree.common.tree.Tree; import fr.rakambda.fallingtree.common.tree.TreePart; +import fr.rakambda.fallingtree.common.tree.TreePartType; import fr.rakambda.fallingtree.common.wrapper.IItemStack; import fr.rakambda.fallingtree.common.wrapper.ILevel; import fr.rakambda.fallingtree.common.wrapper.IPlayer; @@ -11,12 +18,6 @@ import lombok.extern.log4j.Log4j2; import org.jetbrains.annotations.NotNull; -import java.util.Collection; -import java.util.List; - -import static fr.rakambda.fallingtree.common.tree.TreePartType.NETHER_WART; -import static java.util.Objects.isNull; - @Log4j2 @RequiredArgsConstructor public class ShiftDownTreeBreakingHandler implements ITreeBreakingHandler{ @@ -25,25 +26,29 @@ public class ShiftDownTreeBreakingHandler implements ITreeBreakingHandler{ private final FallingTreeCommon mod; @Override - public boolean breakTree(@NotNull IPlayer player, @NotNull Tree tree) throws BreakTreeTooBigException{ + @NotNull + public IBreakAttemptResult breakTree(boolean isCancellable, @NotNull IPlayer player, @NotNull Tree tree) throws BreakTreeTooBigException{ var tool = player.getMainHandItem(); var treePartOptional = tree.getLastSequencePart(); - if(treePartOptional.isEmpty()){ - return false; + var treePartLogOptional = tree.getLastSequenceLogPart(); + if(treePartOptional.isEmpty() || treePartLogOptional.isEmpty()){ + return SuccessResult.DO_NOT_CANCEL; } var treePart = treePartOptional.get(); + var treePartLog = treePartLogOptional.get(); var level = tree.getLevel(); if(treePart.treePartType() == NETHER_WART && mod.getConfiguration().getTrees().isBreakNetherTreeWarts()){ - return breakElements(tree, level, player, tool, tree.getWarts()); + return breakElements(isCancellable, tree, level, player, tool, treePartLog, tree.getWarts()); } else{ - return breakElements(tree, level, player, tool, List.of(treePart)); + return breakElements(isCancellable, tree, level, player, tool, treePartLog, List.of()); } } - private boolean breakElements(@NotNull Tree tree, @NotNull ILevel level, @NotNull IPlayer player, @NotNull IItemStack tool, @NotNull Collection parts) throws BreakTreeTooBigException{ - var count = parts.size(); + @NotNull + private IBreakAttemptResult breakElements(boolean isCancellable, @NotNull Tree tree, @NotNull ILevel level, @NotNull IPlayer player, @NotNull IItemStack tool, @NotNull TreePart logPart, @NotNull Collection leaves) throws BreakTreeTooBigException{ + var count = leaves.size(); var damageMultiplicand = mod.getConfiguration().getTools().getDamageMultiplicand(); var toolHandler = new ToolDamageHandler(tool, damageMultiplicand, @@ -54,32 +59,47 @@ private boolean breakElements(@NotNull Tree tree, @NotNull ILevel level, @NotNul mod.getConfiguration().getTools().getDamageRounding()); if(toolHandler.isPreserveTool()){ - log.debug("Didn't break tree at {} as {}'s tool was about to break", tree.getHitPos(), player); + log.info("Didn't break tree at {} as {}'s tool was about to break", tree.getHitPos(), player); mod.notifyPlayer(player, mod.translate("chat.fallingtree.prevented_break_tool")); - return false; + return SuccessResult.DO_NOT_CANCEL; } - var breakCount = parts.stream() + var breakCount = leaves.stream() .limit(toolHandler.getMaxBreakCount()) - .mapToInt(wart -> breakPart(tree, wart, level, player, tool)) - .sum(); + .mapToInt(part -> breakPart(tree, part, level, player, tool)) + .sum() + + + breakPart(tree, logPart, level, player, tool); - var damage = toolHandler.getActualDamage(breakCount); + var damage = toolHandler.getActualDamage(breakCount - 1); if(damage > 0){ tool.damage(damage, player); } - - if (level instanceof IServerLevel serverLevel) { - serverLevel.spawnParticle(tree.getHitPos(), level.getBlockState(tree.getHitPos()), 10, 1, 1, 1, 5); - } - - return true; + + if(breakCount >= 1){ + if(level instanceof IServerLevel serverLevel){ + serverLevel.spawnParticle(tree.getHitPos(), level.getBlockState(tree.getHitPos()), 10, 1, 1, 1, 5); + } + if(isCancellable){ + return SuccessResult.CANCEL; + } + tree.getStart().ifPresent(part -> level.setBlock(part.blockPos(), part.blockState())); + return SuccessResult.DO_NOT_CANCEL; + } + + if(player.isCreative() && mod.getConfiguration().isLootInCreative()){ + tree.getStart().ifPresent(part -> part.blockState().getBlock().playerDestroy(level, player, tree.getHitPos(), part.blockState(), part.blockEntity(), tool)); + } + return SuccessResult.DO_NOT_CANCEL; } private int breakPart(@NotNull Tree tree, @NotNull TreePart treePart, @NotNull ILevel level, @NotNull IPlayer player, @NotNull IItemStack tool){ var blockPos = treePart.blockPos(); var logState = level.getBlockState(blockPos); + if(treePart.treePartType() == TreePartType.LOG_START){ + return 0; + } if(!mod.checkCanBreakBlock(level, blockPos, logState, player)){ return 0; } diff --git a/common/src/main/java/fr/rakambda/fallingtree/common/tree/breaking/ToolDamageHandler.java b/common/src/main/java/fr/rakambda/fallingtree/common/tree/breaking/ToolDamageHandler.java index 26622a7a..cba76287 100644 --- a/common/src/main/java/fr/rakambda/fallingtree/common/tree/breaking/ToolDamageHandler.java +++ b/common/src/main/java/fr/rakambda/fallingtree/common/tree/breaking/ToolDamageHandler.java @@ -25,7 +25,7 @@ public ToolDamageHandler(@NotNull IItemStack tool, double damageMultiplicand, @N this.damageRounding = damageRounding; if(breakableCount > maxSize && maxSizeAction == MaxSizeAction.ABORT){ - log.debug("Tree reached max size of {}", maxSize); + log.info("Tree reached max size of {}", maxSize); throw new BreakTreeTooBigException(); } diff --git a/common/src/main/java/fr/rakambda/fallingtree/common/tree/builder/ToAnalyzePos.java b/common/src/main/java/fr/rakambda/fallingtree/common/tree/builder/ToAnalyzePos.java index 9fb4129a..f21e0de9 100644 --- a/common/src/main/java/fr/rakambda/fallingtree/common/tree/builder/ToAnalyzePos.java +++ b/common/src/main/java/fr/rakambda/fallingtree/common/tree/builder/ToAnalyzePos.java @@ -4,8 +4,11 @@ import fr.rakambda.fallingtree.common.tree.TreePartType; import fr.rakambda.fallingtree.common.tree.builder.position.IPositionFetcher; import fr.rakambda.fallingtree.common.wrapper.IBlock; +import fr.rakambda.fallingtree.common.wrapper.IBlockEntity; import fr.rakambda.fallingtree.common.wrapper.IBlockPos; +import fr.rakambda.fallingtree.common.wrapper.IBlockState; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Objects; public record ToAnalyzePos(@NotNull IPositionFetcher positionFetcher, @@ -13,6 +16,8 @@ public record ToAnalyzePos(@NotNull IPositionFetcher positionFetcher, @NotNull IBlock parentBlock, @NotNull IBlockPos checkPos, @NotNull IBlock checkBlock, + @NotNull IBlockState checkState, + @Nullable IBlockEntity checkEntity, @NotNull TreePartType treePartType, int sequence, int sequenceSinceLastLog) @@ -24,7 +29,7 @@ public int compareTo(@NotNull ToAnalyzePos o){ } public TreePart toTreePart(){ - return new TreePart(checkPos(), treePartType(), sequence()); + return new TreePart(checkPos(), treePartType(), sequence(), checkState(), checkEntity()); } @Override diff --git a/common/src/main/java/fr/rakambda/fallingtree/common/tree/builder/TreeBuilder.java b/common/src/main/java/fr/rakambda/fallingtree/common/tree/builder/TreeBuilder.java index c1e0ff26..91b5fffa 100644 --- a/common/src/main/java/fr/rakambda/fallingtree/common/tree/builder/TreeBuilder.java +++ b/common/src/main/java/fr/rakambda/fallingtree/common/tree/builder/TreeBuilder.java @@ -9,6 +9,7 @@ import fr.rakambda.fallingtree.common.FallingTreeCommon; import fr.rakambda.fallingtree.common.wrapper.DirectionCompat; import fr.rakambda.fallingtree.common.wrapper.IBlock; +import fr.rakambda.fallingtree.common.wrapper.IBlockEntity; import fr.rakambda.fallingtree.common.wrapper.IBlockPos; import fr.rakambda.fallingtree.common.wrapper.IBlockState; import fr.rakambda.fallingtree.common.wrapper.ILevel; @@ -16,6 +17,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Collection; import java.util.EnumSet; import java.util.HashSet; @@ -33,8 +35,8 @@ public class TreeBuilder{ private final FallingTreeCommon mod; @NotNull - public Optional getTree(@NotNull IPlayer player, @NotNull ILevel level, @NotNull IBlockPos originPos) throws TreeTooBigException{ - var originBlock = level.getBlockState(originPos).getBlock(); + public Optional getTree(@NotNull IPlayer player, @NotNull ILevel level, @NotNull IBlockPos originPos, @NotNull IBlockState originState, @Nullable IBlockEntity originEntity) throws TreeTooBigException{ + var originBlock = originState.getBlock(); if(!mod.isLogBlock(originBlock)){ return empty(); } @@ -43,7 +45,7 @@ public Optional getTree(@NotNull IPlayer player, @NotNull ILevel level, @N var toAnalyzePos = new PriorityQueue(); var analyzedPos = new HashSet(); var tree = new Tree(level, originPos); - toAnalyzePos.add(new ToAnalyzePos(getFirstPositionFetcher(), originPos, originBlock, originPos, originBlock, TreePartType.LOG, 0, 0)); + toAnalyzePos.add(new ToAnalyzePos(getFirstPositionFetcher(), originPos, originBlock, originPos, originBlock, originState, originEntity, TreePartType.LOG_START, 0, 0)); var boundingBoxSearch = getBoundingBoxSearch(originPos); var adjacentPredicate = getAdjacentPredicate(); @@ -59,7 +61,7 @@ public Optional getTree(@NotNull IPlayer player, @NotNull ILevel level, @N analyzedPos.add(analyzingPos); if(tree.getSize() > maxScanSize){ - log.debug("Tree at {} reached max scan size of {}", tree.getHitPos(), maxScanSize); + log.info("Tree at {} reached max scan size of {}", tree.getHitPos(), maxScanSize); throw new TreeTooBigException(); } if(analyzingPos.treePartType().isEdge() && analyzingPos.sequenceSinceLastLog() >= mod.getConfiguration().getTrees().getMaxLeafDistanceFromLog()){ @@ -77,7 +79,7 @@ public Optional getTree(@NotNull IPlayer player, @NotNull ILevel level, @N postProcess(tree); } catch(AbortSearchException e){ - log.debug("Didn't cut tree at {}, reason: {}", originPos, e.getMessage()); + log.info("Didn't cut tree at {}, reason: {}", originPos, e.getMessage()); mod.notifyPlayer(player, mod.translate("chat.fallingtree.search_aborted").append(e.getComponent())); return empty(); } @@ -87,7 +89,7 @@ public Optional getTree(@NotNull IPlayer player, @NotNull ILevel level, @N if(tree.getTopMostLog() .map(topLog -> getLeavesAround(level, topLog) < aroundRequired) .orElse(true)){ - log.debug("Tree at {} doesn't have enough leaves around top most log", originPos); + log.info("Tree at {} doesn't have enough leaves around top most log", originPos); return empty(); } } @@ -118,7 +120,7 @@ private Predicate getAdjacentPredicate(){ case STOP_BRANCH -> block -> { var isAllowed = allowedList.contains(block) || base.contains(block); if(!isAllowed){ - log.debug("Found block {} that isn't allowed in the adjacent blocks, branch will be ignored further", block); + log.info("Found block {} that isn't allowed in the adjacent blocks, branch will be ignored further", block); return false; } return true; @@ -202,7 +204,7 @@ private boolean shouldIncludeInChain(@NotNull Predicate boundingBoxSe if(parent.treePartType().isEdge() && !check.treePartType().isEdge()){ return false; } - if(parent.treePartType() == TreePartType.LOG && isSameTree(originBlock, check) && boundingBoxSearch.test(check.checkPos())){ + if(parent.treePartType().isLog() && isSameTree(originBlock, check) && boundingBoxSearch.test(check.checkPos())){ return true; } if(mod.getConfiguration().getTrees().isBreakNetherTreeWarts()){ @@ -223,7 +225,7 @@ private boolean shouldIncludeInChain(@NotNull Predicate boundingBoxSe private boolean isSameTree(@NotNull IBlock parentLogBlock, @NotNull ToAnalyzePos check){ if(mod.getConfiguration().getTrees().isAllowMixedLogs()){ - return check.treePartType() == TreePartType.LOG; + return check.treePartType().isLog(); } else{ return check.checkBlock().equals(parentLogBlock); diff --git a/common/src/main/java/fr/rakambda/fallingtree/common/tree/builder/position/AbovePositionFetcher.java b/common/src/main/java/fr/rakambda/fallingtree/common/tree/builder/position/AbovePositionFetcher.java index 01817172..893ab021 100644 --- a/common/src/main/java/fr/rakambda/fallingtree/common/tree/builder/position/AbovePositionFetcher.java +++ b/common/src/main/java/fr/rakambda/fallingtree/common/tree/builder/position/AbovePositionFetcher.java @@ -1,18 +1,17 @@ package fr.rakambda.fallingtree.common.tree.builder.position; -import fr.rakambda.fallingtree.common.tree.TreePartType; -import fr.rakambda.fallingtree.common.tree.builder.ToAnalyzePos; +import java.util.Collection; +import java.util.function.Function; +import java.util.function.Supplier; +import static java.util.Objects.isNull; +import static java.util.stream.Collectors.toList; import fr.rakambda.fallingtree.common.FallingTreeCommon; +import fr.rakambda.fallingtree.common.tree.builder.ToAnalyzePos; import fr.rakambda.fallingtree.common.wrapper.IBlockPos; import fr.rakambda.fallingtree.common.wrapper.ILevel; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; -import java.util.Collection; -import java.util.function.Function; -import java.util.function.Supplier; -import static java.util.Objects.isNull; -import static java.util.stream.Collectors.toList; @RequiredArgsConstructor(access = AccessLevel.PRIVATE) public class AbovePositionFetcher implements IPositionFetcher{ @@ -33,10 +32,12 @@ public Collection getPositions(@NotNull ILevel level, @NotNull IBl var parentBlock = level.getBlockState(parentPos).getBlock(); return parentPos.betweenClosedStream(parentPos.above().north().east(), lowerPosProvider.apply(parentPos).south().west()) .map(checkPos -> { - var checkBlock = level.getBlockState(checkPos).getBlock(); + var checkedState = level.getBlockState(checkPos); + var checkedEntity = level.getBlockEntity(checkPos); + var checkBlock = checkedState.getBlock(); var treePart = mod.getTreePart(checkBlock); - var logSequence = treePart == TreePartType.LOG ? 0 : (parent.sequenceSinceLastLog() + 1); - return new ToAnalyzePos(this, parentPos, parentBlock, checkPos.immutable(), checkBlock, treePart, parent.sequence() + 1, logSequence); + var logSequence = treePart.isLog() ? 0 : (parent.sequenceSinceLastLog() + 1); + return new ToAnalyzePos(this, parentPos, parentBlock, checkPos.immutable(), checkBlock, checkedState, checkedEntity, treePart, parent.sequence() + 1, logSequence); }) .collect(toList()); } diff --git a/common/src/main/java/fr/rakambda/fallingtree/common/tree/builder/position/AboveYFetcher.java b/common/src/main/java/fr/rakambda/fallingtree/common/tree/builder/position/AboveYFetcher.java index 8819804d..b52d9273 100644 --- a/common/src/main/java/fr/rakambda/fallingtree/common/tree/builder/position/AboveYFetcher.java +++ b/common/src/main/java/fr/rakambda/fallingtree/common/tree/builder/position/AboveYFetcher.java @@ -1,16 +1,15 @@ package fr.rakambda.fallingtree.common.tree.builder.position; -import fr.rakambda.fallingtree.common.tree.TreePartType; -import fr.rakambda.fallingtree.common.tree.builder.ToAnalyzePos; +import java.util.Collection; +import static java.util.Objects.isNull; +import static java.util.stream.Collectors.toList; import fr.rakambda.fallingtree.common.FallingTreeCommon; +import fr.rakambda.fallingtree.common.tree.builder.ToAnalyzePos; import fr.rakambda.fallingtree.common.wrapper.IBlockPos; import fr.rakambda.fallingtree.common.wrapper.ILevel; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; -import java.util.Collection; -import static java.util.Objects.isNull; -import static java.util.stream.Collectors.toList; @RequiredArgsConstructor(access = AccessLevel.PRIVATE) public class AboveYFetcher implements IPositionFetcher{ @@ -27,10 +26,12 @@ public Collection getPositions(@NotNull ILevel level, @NotNull IBl return parentPos.betweenClosedStream(parentPos.above().north().east(), parentPos.below().south().west()) .filter(pos -> pos.getY() > originPos.getY()) .map(checkPos -> { - var checkBlock = level.getBlockState(checkPos).getBlock(); + var checkState = level.getBlockState(checkPos); + var checkedEntity = level.getBlockEntity(checkPos); + var checkBlock = checkState.getBlock(); var treePart = mod.getTreePart(checkBlock); - var logSequence = treePart == TreePartType.LOG ? 0 : (parent.sequenceSinceLastLog() + 1); - return new ToAnalyzePos(this, parentPos, parentBlock, checkPos.immutable(), checkBlock, treePart, parent.sequence() + 1, logSequence); + var logSequence = treePart.isLog() ? 0 : (parent.sequenceSinceLastLog() + 1); + return new ToAnalyzePos(this, parentPos, parentBlock, checkPos.immutable(), checkBlock, checkState, checkedEntity, treePart, parent.sequence() + 1, logSequence); }) .collect(toList()); } diff --git a/common/src/main/java/fr/rakambda/fallingtree/common/tree/builder/position/BasicPositionFetcher.java b/common/src/main/java/fr/rakambda/fallingtree/common/tree/builder/position/BasicPositionFetcher.java index cc40fabb..ac6f50e4 100644 --- a/common/src/main/java/fr/rakambda/fallingtree/common/tree/builder/position/BasicPositionFetcher.java +++ b/common/src/main/java/fr/rakambda/fallingtree/common/tree/builder/position/BasicPositionFetcher.java @@ -1,16 +1,15 @@ package fr.rakambda.fallingtree.common.tree.builder.position; -import fr.rakambda.fallingtree.common.tree.TreePartType; -import fr.rakambda.fallingtree.common.tree.builder.ToAnalyzePos; +import java.util.Collection; +import static java.util.Objects.isNull; +import static java.util.stream.Collectors.toList; import fr.rakambda.fallingtree.common.FallingTreeCommon; +import fr.rakambda.fallingtree.common.tree.builder.ToAnalyzePos; import fr.rakambda.fallingtree.common.wrapper.IBlockPos; import fr.rakambda.fallingtree.common.wrapper.ILevel; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.NotNull; -import java.util.Collection; -import static java.util.Objects.isNull; -import static java.util.stream.Collectors.toList; @RequiredArgsConstructor(access = AccessLevel.PRIVATE) public class BasicPositionFetcher implements IPositionFetcher{ @@ -26,10 +25,12 @@ public Collection getPositions(@NotNull ILevel level, @NotNull IBl var parentBlock = level.getBlockState(parentPos).getBlock(); return parentPos.betweenClosedStream(parentPos.above().north().east(), parentPos.below().south().west()) .map(checkPos -> { - var checkBlock = level.getBlockState(checkPos).getBlock(); + var checkState = level.getBlockState(checkPos); + var checkedEntity = level.getBlockEntity(checkPos); + var checkBlock = checkState.getBlock(); var treePart = mod.getTreePart(checkBlock); - var logSequence = treePart == TreePartType.LOG ? 0 : (parent.sequenceSinceLastLog() + 1); - return new ToAnalyzePos(this, parentPos, parentBlock, checkPos.immutable(), checkBlock, treePart, parent.sequence() + 1, logSequence); + var logSequence = treePart.isLog() ? 0 : (parent.sequenceSinceLastLog() + 1); + return new ToAnalyzePos(this, parentPos, parentBlock, checkPos.immutable(), checkBlock, checkState, checkedEntity, treePart, parent.sequence() + 1, logSequence); }) .collect(toList()); } diff --git a/common/src/main/java/fr/rakambda/fallingtree/common/wrapper/ILevel.java b/common/src/main/java/fr/rakambda/fallingtree/common/wrapper/ILevel.java index 271230d0..7c043d15 100644 --- a/common/src/main/java/fr/rakambda/fallingtree/common/wrapper/ILevel.java +++ b/common/src/main/java/fr/rakambda/fallingtree/common/wrapper/ILevel.java @@ -21,6 +21,8 @@ public interface ILevel extends IWrapper{ IBlockEntity getBlockEntity(@NotNull IBlockPos blockPos); boolean removeBlock(@NotNull IBlockPos blockPos, boolean b); + + void setBlock(@NotNull IBlockPos blockPos, @NotNull IBlockState blockState); void fallBlock(@NotNull IBlockPos blockPos, boolean drop, double dx, double dy, double dz, double vx, double vy, double vz); } diff --git a/fabric/src/main/java/fr/rakambda/fallingtree/fabric/common/FallingTreeCommonsImpl.java b/fabric/src/main/java/fr/rakambda/fallingtree/fabric/common/FallingTreeCommonsImpl.java index 84de95e9..089afbea 100644 --- a/fabric/src/main/java/fr/rakambda/fallingtree/fabric/common/FallingTreeCommonsImpl.java +++ b/fabric/src/main/java/fr/rakambda/fallingtree/fabric/common/FallingTreeCommonsImpl.java @@ -228,6 +228,7 @@ public void register(){ ServerTickEvents.END_SERVER_TICK.register(new LeafBreakingListener(this)); PlayerBlockBreakEvents.BEFORE.register(new BlockBreakListener(this)); + PlayerBlockBreakEvents.AFTER.register(new BlockBreakListener(this)); CommandRegistrationCallback.EVENT.register(new ServerCommandRegistrationListener(this)); } diff --git a/fabric/src/main/java/fr/rakambda/fallingtree/fabric/common/wrapper/LevelWrapper.java b/fabric/src/main/java/fr/rakambda/fallingtree/fabric/common/wrapper/LevelWrapper.java index 5832aeec..fd7f0384 100644 --- a/fabric/src/main/java/fr/rakambda/fallingtree/fabric/common/wrapper/LevelWrapper.java +++ b/fabric/src/main/java/fr/rakambda/fallingtree/fabric/common/wrapper/LevelWrapper.java @@ -22,79 +22,84 @@ @RequiredArgsConstructor @ToString @Log4j2 -public class LevelWrapper implements ILevel { - @NotNull - @Getter - private final Level raw; - - @Override - public boolean isServer() { - return !raw.isClientSide(); - } - - @Override - @NotNull - public IChunk getChunk(@NotNull IBlockPos blockPos) { - var pos = (BlockPos) blockPos.getRaw(); - return new ChunkAccessWrapper(raw.getChunk(pos)); - } - - @Override - public boolean hasChunk(int x, int z) { - return raw.hasChunk(x, z); - } - - @Override - @NotNull - public IBlockState getBlockState(@NotNull IBlockPos blockPos) { - var pos = (BlockPos) blockPos.getRaw(); - return new BlockStateWrapper(raw.getBlockState(pos)); - } - - @Override - @Nullable - public IBlockEntity getBlockEntity(@NotNull IBlockPos blockPos) { - var entity = raw.getBlockEntity((BlockPos) blockPos.getRaw()); - return entity == null ? null : new BlockEntityWrapper(entity); - } - - @Override - public boolean removeBlock(@NotNull IBlockPos blockPos, boolean b) { - return raw.removeBlock((BlockPos) blockPos.getRaw(), b); - } - - @Override - public void fallBlock(@NotNull IBlockPos logBlockPos, boolean drop, double dx, double dy, double dz, double vx, double vy, double vz) { - var entity = createFallingEntity(logBlockPos, dx, dy, dz); - if (!drop) { - entity.disableDrop(); - } - entity.setDeltaMovement(vx, vy, vz); - raw.addFreshEntity(entity); - } - - @NotNull - private FallingBlockEntity createFallingEntity(@NotNull IBlockPos logBlockPos, double dx, double dy, double dz) { - var x = (double) logBlockPos.getX() + dx; - var y = (double) logBlockPos.getY() + dy; - var z = (double) logBlockPos.getZ() + dz; - var blockState = (BlockState) getBlockState(logBlockPos).getRaw(); - var newBlockState = blockState.hasProperty(BlockStateProperties.WATERLOGGED) ? blockState.setValue(BlockStateProperties.WATERLOGGED, false) : blockState; - - var entity = new FallingBlockEntity(EntityType.FALLING_BLOCK, raw); - entity.blocksBuilding = true; - entity.setPos(x, y, z); - entity.xo = x; - entity.yo = y; - entity.zo = z; - entity.setStartPos((BlockPos) logBlockPos.getRaw()); +public class LevelWrapper implements ILevel{ + @NotNull + @Getter + private final Level raw; + + @Override + public boolean isServer(){ + return !raw.isClientSide(); + } + + @Override + @NotNull + public IChunk getChunk(@NotNull IBlockPos blockPos){ + var pos = (BlockPos) blockPos.getRaw(); + return new ChunkAccessWrapper(raw.getChunk(pos)); + } + + @Override + public boolean hasChunk(int x, int z){ + return raw.hasChunk(x, z); + } + + @Override + @NotNull + public IBlockState getBlockState(@NotNull IBlockPos blockPos){ + var pos = (BlockPos) blockPos.getRaw(); + return new BlockStateWrapper(raw.getBlockState(pos)); + } + + @Override + @Nullable + public IBlockEntity getBlockEntity(@NotNull IBlockPos blockPos){ + var entity = raw.getBlockEntity((BlockPos) blockPos.getRaw()); + return entity == null ? null : new BlockEntityWrapper(entity); + } + + @Override + public boolean removeBlock(@NotNull IBlockPos blockPos, boolean b){ + return raw.removeBlock((BlockPos) blockPos.getRaw(), b); + } + + @Override + public void setBlock(@NotNull IBlockPos blockPos, @NotNull IBlockState blockState){ + raw.setBlock((BlockPos) blockPos.getRaw(), (BlockState) blockState.getRaw(), 3); + } + + @Override + public void fallBlock(@NotNull IBlockPos logBlockPos, boolean drop, double dx, double dy, double dz, double vx, double vy, double vz){ + var entity = createFallingEntity(logBlockPos, dx, dy, dz); + if(!drop){ + entity.disableDrop(); + } + entity.setDeltaMovement(vx, vy, vz); + raw.addFreshEntity(entity); + } + + @NotNull + private FallingBlockEntity createFallingEntity(@NotNull IBlockPos logBlockPos, double dx, double dy, double dz){ + var x = (double) logBlockPos.getX() + dx; + var y = (double) logBlockPos.getY() + dy; + var z = (double) logBlockPos.getZ() + dz; + var blockState = (BlockState) getBlockState(logBlockPos).getRaw(); + var newBlockState = blockState.hasProperty(BlockStateProperties.WATERLOGGED) ? blockState.setValue(BlockStateProperties.WATERLOGGED, false) : blockState; + + var entity = new FallingBlockEntity(EntityType.FALLING_BLOCK, raw); + entity.blocksBuilding = true; + entity.setPos(x, y, z); + entity.xo = x; + entity.yo = y; + entity.zo = z; + entity.setStartPos((BlockPos) logBlockPos.getRaw()); entity.blockState = newBlockState; - return entity; - } - - @Override - @NotNull - public IRandomSource getRandom() { - return new RandomSourceWrapper(raw.getRandom()); - } + return entity; + } + + @Override + @NotNull + public IRandomSource getRandom(){ + return new RandomSourceWrapper(raw.getRandom()); + } } diff --git a/fabric/src/main/java/fr/rakambda/fallingtree/fabric/event/BlockBreakListener.java b/fabric/src/main/java/fr/rakambda/fallingtree/fabric/event/BlockBreakListener.java index f6e8e113..f89bb5c4 100644 --- a/fabric/src/main/java/fr/rakambda/fallingtree/fabric/event/BlockBreakListener.java +++ b/fabric/src/main/java/fr/rakambda/fallingtree/fabric/event/BlockBreakListener.java @@ -1,7 +1,10 @@ package fr.rakambda.fallingtree.fabric.event; +import java.util.Optional; import fr.rakambda.fallingtree.common.FallingTreeCommon; +import fr.rakambda.fallingtree.fabric.common.wrapper.BlockEntityWrapper; import fr.rakambda.fallingtree.fabric.common.wrapper.BlockPosWrapper; +import fr.rakambda.fallingtree.fabric.common.wrapper.BlockStateWrapper; import fr.rakambda.fallingtree.fabric.common.wrapper.LevelWrapper; import fr.rakambda.fallingtree.fabric.common.wrapper.PlayerWrapper; import fr.rakambda.fallingtree.fabric.common.wrapper.ServerLevelWrapper; @@ -35,7 +38,9 @@ public void afterBlockBreak(Level level, Player player, BlockPos blockPos, Block var wrappedPlayer = new PlayerWrapper(player); var wrappedLevel = level instanceof ServerLevel serverLevel ? new ServerLevelWrapper(serverLevel) : new LevelWrapper(level); var wrappedPos = new BlockPosWrapper(blockPos); + var wrappedState = new BlockStateWrapper(blockState); + var wrappedEntity = Optional.ofNullable(blockEntity).map(BlockEntityWrapper::new).orElse(null); - mod.getTreeHandler().breakTree(wrappedLevel, wrappedPlayer, wrappedPos); + mod.getTreeHandler().breakTree(false, wrappedLevel, wrappedPlayer, wrappedPos, wrappedState, wrappedEntity); } } diff --git a/fabric/src/main/java/fr/rakambda/fallingtree/fabric/mixin/AbstractBlockMixin.java b/fabric/src/main/java/fr/rakambda/fallingtree/fabric/mixin/AbstractBlockMixin.java index dac8411f..351557d9 100644 --- a/fabric/src/main/java/fr/rakambda/fallingtree/fabric/mixin/AbstractBlockMixin.java +++ b/fabric/src/main/java/fr/rakambda/fallingtree/fabric/mixin/AbstractBlockMixin.java @@ -2,6 +2,7 @@ import fr.rakambda.fallingtree.fabric.FallingTree; import fr.rakambda.fallingtree.fabric.common.wrapper.BlockPosWrapper; +import fr.rakambda.fallingtree.fabric.common.wrapper.BlockStateWrapper; import fr.rakambda.fallingtree.fabric.common.wrapper.PlayerWrapper; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.player.Player; @@ -19,8 +20,9 @@ public abstract class AbstractBlockMixin{ public void calcBlockBreakingDelta(BlockState blockState, Player player, BlockGetter blockGetter, BlockPos blockPos, CallbackInfoReturnable callbackInfoReturnable){ var wrappedPlayer = new PlayerWrapper(player); var wrappedPos = new BlockPosWrapper(blockPos); + var wrappedState = new BlockStateWrapper(blockState); - var result = FallingTree.getMod().getTreeHandler().getBreakSpeed(wrappedPlayer, wrappedPos, callbackInfoReturnable.getReturnValue()); + var result = FallingTree.getMod().getTreeHandler().getBreakSpeed(wrappedPlayer, wrappedPos, wrappedState, callbackInfoReturnable.getReturnValue()); if(result.isEmpty()){ return; } diff --git a/forge/src/main/java/fr/rakambda/fallingtree/forge/common/wrapper/LevelWrapper.java b/forge/src/main/java/fr/rakambda/fallingtree/forge/common/wrapper/LevelWrapper.java index 89f72bf3..55ce6a99 100644 --- a/forge/src/main/java/fr/rakambda/fallingtree/forge/common/wrapper/LevelWrapper.java +++ b/forge/src/main/java/fr/rakambda/fallingtree/forge/common/wrapper/LevelWrapper.java @@ -69,6 +69,11 @@ public IRandomSource getRandom() { public boolean removeBlock(@NotNull IBlockPos blockPos, boolean b) { return raw.removeBlock((BlockPos) blockPos.getRaw(), b); } + + @Override + public void setBlock(@NotNull IBlockPos blockPos, @NotNull IBlockState blockState) { + raw.setBlock((BlockPos) blockPos.getRaw(), (BlockState) blockState.getRaw(),1 ); + } @Override public void fallBlock(@NotNull IBlockPos logBlockPos, boolean drop, double dx, double dy, double dz, double vx, double vy, double vz) { diff --git a/forge/src/main/java/fr/rakambda/fallingtree/forge/event/BlockBreakListener.java b/forge/src/main/java/fr/rakambda/fallingtree/forge/event/BlockBreakListener.java index 9f34b570..f63bd412 100644 --- a/forge/src/main/java/fr/rakambda/fallingtree/forge/event/BlockBreakListener.java +++ b/forge/src/main/java/fr/rakambda/fallingtree/forge/event/BlockBreakListener.java @@ -1,7 +1,9 @@ package fr.rakambda.fallingtree.forge.event; +import javax.annotation.Nonnull; import fr.rakambda.fallingtree.common.FallingTreeCommon; import fr.rakambda.fallingtree.forge.common.wrapper.BlockPosWrapper; +import fr.rakambda.fallingtree.forge.common.wrapper.BlockStateWrapper; import fr.rakambda.fallingtree.forge.common.wrapper.LevelWrapper; import fr.rakambda.fallingtree.forge.common.wrapper.PlayerWrapper; import fr.rakambda.fallingtree.forge.common.wrapper.ServerLevelWrapper; @@ -11,7 +13,6 @@ import net.minecraftforge.event.level.BlockEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; import org.jetbrains.annotations.NotNull; -import javax.annotation.Nonnull; @RequiredArgsConstructor public class BlockBreakListener{ @@ -31,8 +32,9 @@ public void onBreakSpeed(@Nonnull PlayerEvent.BreakSpeed event){ var wrappedPlayer = new PlayerWrapper(event.getEntity()); var wrappedPos = new BlockPosWrapper(optionalPos.get()); + var wrappedState = new BlockStateWrapper(event.getState()); - var result = mod.getTreeHandler().getBreakSpeed(wrappedPlayer, wrappedPos, event.getNewSpeed()); + var result = mod.getTreeHandler().getBreakSpeed(wrappedPlayer, wrappedPos, wrappedState, event.getNewSpeed()); if(result.isEmpty()){ return; } @@ -52,9 +54,16 @@ public void onBlockBreakEvent(@Nonnull BlockEvent.BreakEvent event){ var wrappedPlayer = new PlayerWrapper(event.getPlayer()); var wrappedLevel = event.getLevel() instanceof ServerLevel serverLevel ? new ServerLevelWrapper(serverLevel) : new LevelWrapper(event.getLevel()); var wrappedPos = new BlockPosWrapper(event.getPos()); + var wrappedState = new BlockStateWrapper(event.getState()); + var wrappedEntity = wrappedLevel.getBlockEntity(wrappedPos); + + if(mod.getTreeHandler().shouldCancelEvent(wrappedPlayer)){ + event.setCanceled(true); + return; + } - var result = mod.getTreeHandler().breakTree(wrappedLevel, wrappedPlayer, wrappedPos); - if(result.shouldCancel() && event.isCancelable()){ + var result = mod.getTreeHandler().breakTree(event.isCancelable(), wrappedLevel, wrappedPlayer, wrappedPos, wrappedState, wrappedEntity); + if(result.shouldCancel()){ event.setCanceled(true); } } diff --git a/neoforge/src/main/java/fr/rakambda/fallingtree/neoforge/common/wrapper/LevelWrapper.java b/neoforge/src/main/java/fr/rakambda/fallingtree/neoforge/common/wrapper/LevelWrapper.java index de472925..ec8ed127 100644 --- a/neoforge/src/main/java/fr/rakambda/fallingtree/neoforge/common/wrapper/LevelWrapper.java +++ b/neoforge/src/main/java/fr/rakambda/fallingtree/neoforge/common/wrapper/LevelWrapper.java @@ -23,78 +23,83 @@ @RequiredArgsConstructor @ToString @Log4j2 -public class LevelWrapper implements ILevel { - @NotNull - @Getter - private final LevelAccessor raw; - - @Override - public boolean isServer() { - return !raw.isClientSide(); - } - - @Override - @NotNull - public IChunk getChunk(@NotNull IBlockPos blockPos) { - var pos = (BlockPos) blockPos.getRaw(); - return new ChunkAccessWrapper(raw.getChunk(pos)); - } - - @Override - public boolean hasChunk(int x, int z) { - return raw.hasChunk(x, z); - } - - @Override - @NotNull - public IBlockState getBlockState(@NotNull IBlockPos blockPos) { - var pos = (BlockPos) blockPos.getRaw(); - return new BlockStateWrapper(raw.getBlockState(pos)); - } - - @Override - @Nullable - public IBlockEntity getBlockEntity(@NotNull IBlockPos blockPos) { - var entity = raw.getBlockEntity((BlockPos) blockPos.getRaw()); - return entity == null ? null : new BlockEntityWrapper(entity); - } - - @Override - @NotNull - public IRandomSource getRandom() { - return new RandomSourceWrapper(raw.getRandom()); - } - - @Override - public boolean removeBlock(@NotNull IBlockPos blockPos, boolean b) { - return raw.removeBlock((BlockPos) blockPos.getRaw(), b); - } - - @Override - public void fallBlock(@NotNull IBlockPos logBlockPos, boolean drop, double dx, double dy, double dz, double vx, double vy, double vz) { - var entity = createFallingEntity(logBlockPos, dx, dy, dz); - if (!drop) { - entity.disableDrop(); - } - entity.setDeltaMovement(vx, vy, vz); - raw.addFreshEntity(entity); - } - - @NotNull - private FallingBlockEntity createFallingEntity(@NotNull IBlockPos logBlockPos, double dx, double dy, double dz) { - var x = (double) logBlockPos.getX() + dx; - var y = (double) logBlockPos.getY() + dy; - var z = (double) logBlockPos.getZ() + dz; +public class LevelWrapper implements ILevel{ + @NotNull + @Getter + private final LevelAccessor raw; + + @Override + public boolean isServer(){ + return !raw.isClientSide(); + } + + @Override + @NotNull + public IChunk getChunk(@NotNull IBlockPos blockPos){ + var pos = (BlockPos) blockPos.getRaw(); + return new ChunkAccessWrapper(raw.getChunk(pos)); + } + + @Override + public boolean hasChunk(int x, int z){ + return raw.hasChunk(x, z); + } + + @Override + @NotNull + public IBlockState getBlockState(@NotNull IBlockPos blockPos){ + var pos = (BlockPos) blockPos.getRaw(); + return new BlockStateWrapper(raw.getBlockState(pos)); + } + + @Override + @Nullable + public IBlockEntity getBlockEntity(@NotNull IBlockPos blockPos){ + var entity = raw.getBlockEntity((BlockPos) blockPos.getRaw()); + return entity == null ? null : new BlockEntityWrapper(entity); + } + + @Override + @NotNull + public IRandomSource getRandom(){ + return new RandomSourceWrapper(raw.getRandom()); + } + + @Override + public boolean removeBlock(@NotNull IBlockPos blockPos, boolean b){ + return raw.removeBlock((BlockPos) blockPos.getRaw(), b); + } + + @Override + public void setBlock(@NotNull IBlockPos blockPos, @NotNull IBlockState blockState){ + raw.setBlock((BlockPos) blockPos.getRaw(), (BlockState) blockState.getRaw(), 1); + } + + @Override + public void fallBlock(@NotNull IBlockPos logBlockPos, boolean drop, double dx, double dy, double dz, double vx, double vy, double vz){ + var entity = createFallingEntity(logBlockPos, dx, dy, dz); + if(!drop){ + entity.disableDrop(); + } + entity.setDeltaMovement(vx, vy, vz); + raw.addFreshEntity(entity); + } + + @NotNull + private FallingBlockEntity createFallingEntity(@NotNull IBlockPos logBlockPos, double dx, double dy, double dz){ + var x = (double) logBlockPos.getX() + dx; + var y = (double) logBlockPos.getY() + dy; + var z = (double) logBlockPos.getZ() + dz; var blockState = (BlockState) getBlockState(logBlockPos).getRaw(); - var newBlockState = blockState.hasProperty(BlockStateProperties.WATERLOGGED) ? blockState.setValue(BlockStateProperties.WATERLOGGED, false) : blockState; - - var entity = new FallingBlockEntity(EntityType.FALLING_BLOCK, (Level) raw); - entity.blocksBuilding = true; - entity.setPos(x, y, z); - entity.xo = x; - entity.yo = y; - entity.zo = z; - entity.blockState = newBlockState; - return entity; - } + var newBlockState = blockState.hasProperty(BlockStateProperties.WATERLOGGED) ? blockState.setValue(BlockStateProperties.WATERLOGGED, false) : blockState; + + var entity = new FallingBlockEntity(EntityType.FALLING_BLOCK, (Level) raw); + entity.blocksBuilding = true; + entity.setPos(x, y, z); + entity.xo = x; + entity.yo = y; + entity.zo = z; + entity.blockState = newBlockState; + return entity; + } } diff --git a/neoforge/src/main/java/fr/rakambda/fallingtree/neoforge/event/BlockBreakListener.java b/neoforge/src/main/java/fr/rakambda/fallingtree/neoforge/event/BlockBreakListener.java index f316d88c..f6cfd3dd 100644 --- a/neoforge/src/main/java/fr/rakambda/fallingtree/neoforge/event/BlockBreakListener.java +++ b/neoforge/src/main/java/fr/rakambda/fallingtree/neoforge/event/BlockBreakListener.java @@ -1,7 +1,9 @@ package fr.rakambda.fallingtree.neoforge.event; +import javax.annotation.Nonnull; import fr.rakambda.fallingtree.common.FallingTreeCommon; import fr.rakambda.fallingtree.neoforge.common.wrapper.BlockPosWrapper; +import fr.rakambda.fallingtree.neoforge.common.wrapper.BlockStateWrapper; import fr.rakambda.fallingtree.neoforge.common.wrapper.LevelWrapper; import fr.rakambda.fallingtree.neoforge.common.wrapper.PlayerWrapper; import fr.rakambda.fallingtree.neoforge.common.wrapper.ServerLevelWrapper; @@ -11,7 +13,6 @@ import net.neoforged.neoforge.event.entity.player.PlayerEvent; import net.neoforged.neoforge.event.level.BlockEvent; import org.jetbrains.annotations.NotNull; -import javax.annotation.Nonnull; @RequiredArgsConstructor public class BlockBreakListener{ @@ -31,8 +32,9 @@ public void onBreakSpeed(@Nonnull PlayerEvent.BreakSpeed event){ var wrappedPlayer = new PlayerWrapper(event.getEntity()); var wrappedPos = new BlockPosWrapper(optionalPos.get()); + var wrappedState = new BlockStateWrapper(event.getState()); - var result = mod.getTreeHandler().getBreakSpeed(wrappedPlayer, wrappedPos, event.getNewSpeed()); + var result = mod.getTreeHandler().getBreakSpeed(wrappedPlayer, wrappedPos, wrappedState, event.getNewSpeed()); if(result.isEmpty()){ return; } @@ -52,8 +54,15 @@ public void onBlockBreakEvent(@Nonnull BlockEvent.BreakEvent event){ var wrappedPlayer = new PlayerWrapper(event.getPlayer()); var wrappedLevel = event.getLevel() instanceof ServerLevel serverLevel ? new ServerLevelWrapper(serverLevel) : new LevelWrapper(event.getLevel()); var wrappedPos = new BlockPosWrapper(event.getPos()); + var wrappedState = new BlockStateWrapper(event.getState()); + var wrappedEntity = wrappedLevel.getBlockEntity(wrappedPos); + + if(mod.getTreeHandler().shouldCancelEvent(wrappedPlayer)){ + event.setCanceled(true); + return; + } - var result = mod.getTreeHandler().breakTree(wrappedLevel, wrappedPlayer, wrappedPos); + var result = mod.getTreeHandler().breakTree(true, wrappedLevel, wrappedPlayer, wrappedPos, wrappedState, wrappedEntity); if(result.shouldCancel()){ event.setCanceled(true); }