@@ -29,6 +29,13 @@ import com.lambda.interaction.construction.result.BreakResult
2929import com.lambda.interaction.construction.result.BuildResult
3030import com.lambda.interaction.construction.result.PlaceResult
3131import com.lambda.interaction.construction.verify.TargetState
32+ import com.lambda.interaction.material.ContainerSelection.Companion.selectContainer
33+ import com.lambda.interaction.material.StackSelection.Companion.select
34+ import com.lambda.interaction.material.StackSelection.Companion.selectStack
35+ import com.lambda.interaction.material.container.ContainerManager
36+ import com.lambda.interaction.material.container.ContainerManager.containerWithMaterial
37+ import com.lambda.interaction.material.container.ContainerManager.findContainerWithMaterial
38+ import com.lambda.interaction.material.container.MaterialContainer
3239import com.lambda.interaction.request.rotation.Rotation.Companion.rotation
3340import com.lambda.interaction.request.rotation.Rotation.Companion.rotationTo
3441import com.lambda.interaction.request.rotation.RotationConfig
@@ -47,12 +54,13 @@ import com.lambda.util.BlockUtils.instantBreakable
4754import com.lambda.util.BlockUtils.vecOf
4855import com.lambda.util.Communication.warn
4956import com.lambda.util.item.ItemStackUtils.equal
50- import com.lambda.util.item.ItemUtils.findBestAvailableTool
57+ import com.lambda.util.item.ItemUtils.findBestToolsForBreaking
5158import com.lambda.util.math.distSq
5259import com.lambda.util.player.copyPlayer
5360import com.lambda.util.world.raycast.RayCastUtils.blockResult
5461import net.minecraft.block.OperatorBlock
5562import net.minecraft.block.pattern.CachedBlockPosition
63+ import net.minecraft.enchantment.Enchantments
5664import net.minecraft.item.BlockItem
5765import net.minecraft.item.ItemPlacementContext
5866import net.minecraft.item.ItemUsageContext
@@ -280,7 +288,7 @@ object BuildSimulator {
280288
281289 val blockHit = checkedResult.blockResult ? : return @forEach
282290 val hitBlock = blockState(blockHit.blockPos).block
283- val shouldSneak = hitBlock::class in BlockUtils .interactionClasses
291+ val shouldSneak = hitBlock::class in BlockUtils .interactionBlocks
284292
285293 val primeDirection =
286294 (target as ? TargetState .State )?.blockState?.getOrEmpty(Properties .HORIZONTAL_FACING )?.getOrNull()
@@ -373,15 +381,6 @@ object BuildSimulator {
373381 return acc
374382 }
375383
376- /* The current selected item cant mine the block */
377- Hand .entries.forEach {
378- val stack = player.getStackInHand(it)
379- if (stack.isEmpty) return @forEach
380- if (stack.item.canMine(state, world, pos, player)) return @forEach
381- acc.add(BreakResult .ItemCantMine (pos, state, stack.item, inventory))
382- return acc
383- }
384-
385384 val currentRotation = RotationManager .currentRotation
386385 val currentCast = currentRotation.rayCast(interact.interactReach, eye)
387386
@@ -412,7 +411,7 @@ object BuildSimulator {
412411 rotationRequest,
413412 state,
414413 targetState,
415- player.inventory.selectedSlot,
414+ player.inventory.selectedSlot + 1 ,
416415 instantBreakable(state, pos),
417416 build
418417 )
@@ -426,6 +425,7 @@ object BuildSimulator {
426425 val reachSq = interact.interactReach.pow(2 )
427426
428427 boxes.forEach { box ->
428+ // ToDo: Rewrite Rotation request system to allow support for all sim features and use the rotation finder
429429 scanSurfaces(box, Direction .entries.toSet(), interact.resolution) { side, vec ->
430430 if (eye distSq vec > reachSq) {
431431 misses.add(vec)
@@ -454,41 +454,62 @@ object BuildSimulator {
454454 return acc
455455 }
456456
457- interact.pointSelection.select(validHits)?.let { checkedHit ->
458- val blockHit = checkedHit.hit.blockResult ? : return @let
459-
460- val breakContext = BreakContext (
461- eye,
462- blockHit,
463- RotationRequest (lookAt(checkedHit.targetRotation, 0.001 ), rotation),
464- state,
465- targetState,
466- player.inventory.selectedSlot,
467- instantBreakable(state, pos),
468- build
469- )
470-
471- /* player has a better tool for the job available */
472- if (! player.isCreative) findBestAvailableTool(state).let { bestTools ->
473- Hand .entries.map {
474- player.getStackInHand(it)
475- }.filter { stack ->
476- bestTools.any { tool -> tool == stack.item }
477- }.sortedByDescending {
478- state.calcItemBlockBreakingDelta(player, world, pos, it)
479- }.let { stackList ->
480- if (stackList.isEmpty()) {
481- acc.add(BuildResult .WrongItem (pos, breakContext, bestTools.first(), player.activeItem, inventory))
482- return acc
483- }
484- breakContext.slotIndex = player.inventory.getSlotWithStack(stackList.first())
485- acc.add(BreakResult .Break (pos, breakContext))
486- return acc
487- }
488- }
457+ val bestHit = interact.pointSelection.select(validHits) ? : return acc
458+ val blockHit = bestHit.hit.blockResult ? : return acc
459+ val target = lookAt(bestHit.targetRotation, 0.001 )
460+ val request = RotationRequest (target, rotation)
461+ val instant = instantBreakable(state, pos)
462+ val useSlotIndex = player.inventory.selectedSlot + 1
463+
464+ val breakContext = BreakContext (
465+ eye, blockHit, request, state, targetState, useSlotIndex, instant, build
466+ )
489467
468+ if (player.isCreative) {
490469 acc.add(BreakResult .Break (pos, breakContext))
470+ return acc
491471 }
472+
473+ val bestTools = findBestToolsForBreaking(state)
474+
475+ /* there is no good tool for the job */
476+ if (bestTools.isEmpty()) {
477+ /* The current selected item cant mine the block */
478+ Hand .entries.forEach {
479+ val stack = player.getStackInHand(it)
480+ if (stack.isEmpty) return @forEach
481+ if (stack.item.canMine(state, world, pos, player)) return @forEach
482+ acc.add(BreakResult .ItemCantMine (pos, state, stack.item, inventory))
483+ return acc
484+ }
485+ // ToDo: Switch to non destroyable item
486+ acc.add(BreakResult .Break (pos, breakContext))
487+ return acc
488+ }
489+
490+ val bestTool = bestTools.firstOrNull() ? : return acc
491+ val toolSelection = if (build.forceSilkTouch) {
492+ selectStack { isItem(bestTool) and hasEnchantment(Enchantments .SILK_TOUCH ) }
493+ } else {
494+ bestTool.select()
495+ }
496+ val containerSelection = selectContainer {
497+ matches(toolSelection) and ofAnyType(MaterialContainer .Rank .OFF_HAND , MaterialContainer .Rank .HOTBAR )
498+ }
499+ val allContainersWithTools = toolSelection.containerWithMaterial(inventory, containerSelection)
500+ val matchingStacks = allContainersWithTools.associateWith { it.matchingStacks(toolSelection) }
501+ val bestDeltaTool = matchingStacks.mapValues { (_, stacks) ->
502+ stacks.associateWith { state.calcItemBlockBreakingDelta(player, world, pos, it) }
503+ .maxByOrNull { it.value }
504+ ?.toPair()
505+ }.entries.maxByOrNull { it.value?.second ? : 0f }?.toPair() ? : return acc
506+
507+ if (bestDeltaTool.second == null ) {
508+ acc.add(BuildResult .WrongItem (pos, breakContext, bestTools.first(), player.activeItem, inventory))
509+ return acc
510+ }
511+
512+ acc.add(BreakResult .Break (pos, breakContext))
492513 return acc
493514 }
494515}
0 commit comments