2222import org .jspecify .annotations .NonNull ;
2323import org .jspecify .annotations .Nullable ;
2424import java .util .Map ;
25+ import java .util .Objects ;
2526import java .util .Optional ;
2627import java .util .UUID ;
27- import java .util .concurrent .ConcurrentHashMap ;
2828import static java .util .Objects .isNull ;
2929
3030@ Log4j2
3131@ RequiredArgsConstructor
3232public class TreeHandler {
3333 @ NonNull
3434 private final FallingTreeCommon <?> mod ;
35- private final Map <UUID , CacheSpeed > speedCache = new ConcurrentHashMap <>();
35+ @ NonNull
36+ private final Map <UUID , CacheSpeed > speedCache ;
37+
38+ @ NonNull
39+ private final IPlayer player ;
40+ @ NonNull
41+ private final ILevel level ;
42+ @ NonNull
43+ private final IBlockPos originPos ;
44+ @ NonNull
45+ private final IBlockState originState ;
46+ @ Nullable
47+ private final IBlockEntity originEntity ;
3648
37- public boolean shouldCancelEvent (@ NonNull ILevel level , @ NonNull IPlayer player , @ NonNull IBlockPos originPos , @ NonNull IBlockState originState , @ Nullable IBlockEntity originEntity ){
49+ @ Nullable
50+ private Tree cachedTree = null ;
51+
52+ @ Nullable
53+ public Tree getTree () throws TreeTooBigException {
54+ if (Objects .isNull (cachedTree )){
55+ cachedTree = mod .getTreeBuilder ().getTree (player , level , originPos , originState , originEntity ).orElse (null );
56+ }
57+ return cachedTree ;
58+ }
59+
60+ public boolean shouldCancelEvent (){
3861 if (!mod .isPlayerInRightState (player )){
3962 return false ;
4063 }
4164 if (shouldPreserveTool (player )){
4265 return true ;
4366 }
4467 try {
45- mod . getTreeBuilder (). getTree ( player , level , originPos , originState , originEntity ). isEmpty ();
68+ getTree ();
4669 }
4770 catch (TreeTooBigException e ){
4871 return false ;
4972 }
5073 return false ;
5174 }
5275
53- private boolean shouldPreserveTool (@ NonNull IPlayer player ){
54- var handItem = player .getMainHandItem ();
55- return mod .getConfiguration ().getTools ().getDurabilityMode ().shouldPreserve (handItem .getDurability ());
56- }
57-
5876 @ NonNull
59- public IBreakAttemptResult breakTree (boolean isCancellable , @ NonNull ILevel level , @ NonNull IPlayer player , @ NonNull IBlockPos originPos , @ NonNull IBlockState originState , @ Nullable IBlockEntity originEntity ){
77+ public IBreakAttemptResult breakTree (boolean isCancellable ){
6078 if (!level .isServer ()){
6179 return AbortedResult .NOT_SERVER ;
6280 }
@@ -74,12 +92,11 @@ public IBreakAttemptResult breakTree(boolean isCancellable, @NonNull ILevel leve
7492 }
7593
7694 try {
77- var treeOptional = mod . getTreeBuilder (). getTree (player , level , originPos , originState , originEntity );
78- if (treeOptional . isEmpty () ){
95+ var tree = getTree ();
96+ if (tree == null ){
7997 return AbortedResult .NO_SUCH_TREE ;
8098 }
8199
82- var tree = treeOptional .get ();
83100 var breakMode = getBreakMode (player .getMainHandItem ());
84101 return getBreakingHandler (breakMode ).breakTree (isCancellable , player , tree );
85102 }
@@ -98,25 +115,7 @@ public IBreakAttemptResult breakTree(boolean isCancellable, @NonNull ILevel leve
98115 }
99116
100117 @ NonNull
101- private BreakMode getBreakMode (@ NonNull IItemStack itemStack ){
102- return itemStack .getBreakModeFromEnchant ()
103- .orElseGet (() -> mod .getConfiguration ().getTrees ().getBreakMode ());
104- }
105-
106- @ NonNull
107- private ITreeBreakingHandler getBreakingHandler (@ NonNull BreakMode breakMode ){
108- return switch (breakMode ){
109- case INSTANTANEOUS -> InstantaneousTreeBreakingHandler .getInstance (mod );
110- case FALL_ITEM -> FallingAnimationTreeBreakingHandler .getInstance (mod , FallingAnimationTreeBreakingConfig .withRandomSpread (true , true ));
111- case FALL_ITEM_STRAIGHT -> FallingAnimationTreeBreakingHandler .getInstance (mod , FallingAnimationTreeBreakingConfig .straightDown (true , true ));
112- case FALL_BLOCK -> FallingAnimationTreeBreakingHandler .getInstance (mod , FallingAnimationTreeBreakingConfig .withRandomSpread (false , true ));
113- case FALL_ALL_BLOCK -> FallingAnimationTreeBreakingHandler .getInstance (mod , FallingAnimationTreeBreakingConfig .withRandomSpread (false , false ));
114- case SHIFT_DOWN -> ShiftDownTreeBreakingHandler .getInstance (mod );
115- };
116- }
117-
118- @ NonNull
119- public Optional <Float > getBreakSpeed (@ NonNull IPlayer player , @ NonNull IBlockPos blockPos , @ NonNull IBlockState blockState , float originalSpeed ){
118+ public Optional <Float > getBreakSpeed (float originalSpeed ){
120119 if (!mod .getConfiguration ().getTrees ().isTreeBreaking ()){
121120 return Optional .empty ();
122121 }
@@ -128,25 +127,48 @@ public Optional<Float> getBreakSpeed(@NonNull IPlayer player, @NonNull IBlockPos
128127 }
129128
130129 var cacheSpeed = speedCache .compute (player .getUUID (), (uuid , speed ) -> {
131- if (isNull (speed ) || !speed .isValid (blockPos )){
132- speed = getSpeed (player , blockPos , blockState , originalSpeed );
130+ if (isNull (speed ) || !speed .isValid (originPos )){
131+ speed = getSpeed (originalSpeed );
133132 }
134133 return speed ;
135134 });
136135 return Optional .ofNullable (cacheSpeed ).map (CacheSpeed ::getSpeed );
137136 }
138137
139138 @ Nullable
140- private CacheSpeed getSpeed (@ NonNull IPlayer player , @ NonNull IBlockPos pos , @ NonNull IBlockState blockState , float originalSpeed ){
139+ private CacheSpeed getSpeed (float originalSpeed ){
141140 var speedMultiplicand = mod .getConfiguration ().getTools ().getSpeedMultiplicand ();
142141 try {
143- return speedMultiplicand <= 0 ? null :
144- mod .getTreeBuilder ().getTree (player , player .getLevel (), pos , blockState , null )
145- .map (tree -> new CacheSpeed (pos , originalSpeed / ((float ) speedMultiplicand * tree .getLogCount ())))
142+ return speedMultiplicand <= 0
143+ ? null
144+ : Optional .ofNullable (getTree ())
145+ .map (tree -> new CacheSpeed (originPos , originalSpeed / ((float ) speedMultiplicand * tree .getLogCount ())))
146146 .orElse (null );
147147 }
148148 catch (TreeTooBigException e ){
149149 return null ;
150150 }
151151 }
152+
153+ private boolean shouldPreserveTool (@ NonNull IPlayer player ){
154+ var handItem = player .getMainHandItem ();
155+ return mod .getConfiguration ().getTools ().getDurabilityMode ().shouldPreserve (handItem .getDurability ());
156+ }
157+
158+ @ NonNull
159+ private BreakMode getBreakMode (@ NonNull IItemStack itemStack ){
160+ return itemStack .getBreakModeFromEnchant ().orElseGet (() -> mod .getConfiguration ().getTrees ().getBreakMode ());
161+ }
162+
163+ @ NonNull
164+ private ITreeBreakingHandler getBreakingHandler (@ NonNull BreakMode breakMode ){
165+ return switch (breakMode ){
166+ case INSTANTANEOUS -> InstantaneousTreeBreakingHandler .getInstance (mod );
167+ case FALL_ITEM -> FallingAnimationTreeBreakingHandler .getInstance (mod , FallingAnimationTreeBreakingConfig .withRandomSpread (true , true ));
168+ case FALL_ITEM_STRAIGHT -> FallingAnimationTreeBreakingHandler .getInstance (mod , FallingAnimationTreeBreakingConfig .straightDown (true , true ));
169+ case FALL_BLOCK -> FallingAnimationTreeBreakingHandler .getInstance (mod , FallingAnimationTreeBreakingConfig .withRandomSpread (false , true ));
170+ case FALL_ALL_BLOCK -> FallingAnimationTreeBreakingHandler .getInstance (mod , FallingAnimationTreeBreakingConfig .withRandomSpread (false , false ));
171+ case SHIFT_DOWN -> ShiftDownTreeBreakingHandler .getInstance (mod );
172+ };
173+ }
152174}
0 commit comments