1818package com.lambda.interaction.construction.simulation.checks
1919
2020import com.lambda.context.AutomatedSafeContext
21- import com.lambda.context.SafeContext
2221import com.lambda.interaction.construction.context.BreakContext
2322import com.lambda.interaction.construction.result.BuildResult
2423import com.lambda.interaction.construction.result.Dependable
@@ -38,12 +37,8 @@ import com.lambda.interaction.material.StackSelection.Companion.select
3837import com.lambda.interaction.material.StackSelection.Companion.selectStack
3938import com.lambda.interaction.material.container.ContainerManager.containerWithMaterial
4039import com.lambda.interaction.material.container.MaterialContainer
41- import com.lambda.interaction.request.rotating.Rotation.Companion.rotationTo
4240import com.lambda.interaction.request.rotating.RotationManager
4341import com.lambda.interaction.request.rotating.RotationRequest
44- import com.lambda.interaction.request.rotating.visibilty.VisibilityChecker.CheckedHit
45- import com.lambda.interaction.request.rotating.visibilty.VisibilityChecker.getVisibleSurfaces
46- import com.lambda.interaction.request.rotating.visibilty.VisibilityChecker.scanSurfaces
4742import com.lambda.interaction.request.rotating.visibilty.lookAt
4843import com.lambda.interaction.request.rotating.visibilty.lookAtBlock
4944import com.lambda.threading.runSafe
@@ -52,14 +47,7 @@ import com.lambda.util.BlockUtils.calcItemBlockBreakingDelta
5247import com.lambda.util.BlockUtils.instantBreakable
5348import com.lambda.util.BlockUtils.isEmpty
5449import com.lambda.util.item.ItemStackUtils.inventoryIndexOrSelected
55- import com.lambda.util.math.distSq
56- import com.lambda.util.math.vec3d
5750import com.lambda.util.world.raycast.RayCastUtils.blockResult
58- import io.ktor.util.collections.*
59- import kotlinx.coroutines.Dispatchers
60- import kotlinx.coroutines.joinAll
61- import kotlinx.coroutines.launch
62- import kotlinx.coroutines.withContext
6351import net.minecraft.block.BlockState
6452import net.minecraft.block.FallingBlock
6553import net.minecraft.block.Waterloggable
@@ -75,12 +63,9 @@ import net.minecraft.registry.tag.ItemTags.IRON_TOOL_MATERIALS
7563import net.minecraft.registry.tag.ItemTags.NETHERITE_TOOL_MATERIALS
7664import net.minecraft.registry.tag.ItemTags.STONE_TOOL_MATERIALS
7765import net.minecraft.registry.tag.ItemTags.WOODEN_TOOL_MATERIALS
78- import net.minecraft.util.hit.BlockHitResult
7966import net.minecraft.util.math.BlockPos
8067import net.minecraft.util.math.Direction
81- import net.minecraft.util.math.Vec3d
8268import kotlin.jvm.optionals.getOrNull
83- import kotlin.math.pow
8469
8570class BreakChecker @SimCheckerDsl private constructor(simInfo : SimInfo )
8671 : SimChecker <BreakResult >(), Dependable ,
@@ -134,14 +119,12 @@ class BreakChecker @SimCheckerDsl private constructor(simInfo: SimInfo)
134119 }
135120
136121 private suspend fun AutomatedSafeContext.checkBreaks (): Boolean {
137- /* player is standing on top of the block */
138122 if (breakConfig.avoidSupporting) player.supportingBlockPos.getOrNull()?.let { support ->
139123 if (support != pos) return @let
140124 result(BreakResult .PlayerOnTop (pos, state))
141125 return true
142126 }
143127
144- /* liquid needs to be submerged first to be broken */
145128 if (targetState.getState(pos).isAir && ! state.fluidState.isEmpty && state.isReplaceable) {
146129 result(BreakResult .Submerge (pos, state))
147130 return simInfo(pos, state, TargetState .Solid (emptySet()))?.checkPlacements() ? : true
@@ -151,19 +134,16 @@ class BreakChecker @SimCheckerDsl private constructor(simInfo: SimInfo)
151134
152135 if (breakConfig.avoidLiquids && affectsFluids()) return true
153136
154- val voxelShape = state.getOutlineShape(world, pos)
155-
156- val boxes = voxelShape.boundingBoxes.map { it.offset(pos) }
157-
158137 val swapStack = getSwapStack() ? : return true
159138 val instant = instantBreakable(
160139 state, pos,
161140 if (breakConfig.swapMode.isEnabled()) swapStack else player.mainHandStack,
162141 breakConfig.breakThreshold
163142 )
164143
165- /* the player is buried inside the block */
166- if (boxes.any { it.contains(pov) }) {
144+ val shape = state.getOutlineShape(world, pos)
145+
146+ if (shape.boundingBoxes.map { it.offset(pos) }.any { it.contains(pov) }) {
167147 val currentCast = RotationManager .activeRotation.rayCast(buildConfig.interactReach, pov)
168148 currentCast?.blockResult?.let { blockHit ->
169149 val rotationRequest = RotationRequest (lookAtBlock(pos), this )
@@ -181,58 +161,14 @@ class BreakChecker @SimCheckerDsl private constructor(simInfo: SimInfo)
181161 return true
182162 }
183163
184- val validHits = ConcurrentSet <CheckedHit >()
185- val misses = ConcurrentSet <Vec3d >()
186- val reachSq = buildConfig.interactReach.pow(2 )
187-
188- withContext(Dispatchers .Default ) {
189- boxes.map { box ->
190- launch {
191- val sides = if (buildConfig.checkSideVisibility)
192- box.getVisibleSurfaces(pov)
193- else Direction .entries.toSet()
194-
195- scanSurfaces(box, sides, buildConfig.resolution) { side, vec ->
196- if (pov distSq vec > reachSq) {
197- misses.add(vec)
198- return @scanSurfaces
199- }
200-
201- val newRotation = pov.rotationTo(vec)
202-
203- val hit = if (buildConfig.strictRayCast) {
204- newRotation.rayCast(buildConfig.interactReach, pov)?.blockResult
205- } else {
206- val hitVec = newRotation.castBox(box, buildConfig.interactReach, pov)
207- BlockHitResult (hitVec, side, pos, false )
208- } ? : return @scanSurfaces
209-
210- if (hit.blockResult?.blockPos != pos) return @scanSurfaces
211- val checked = CheckedHit (hit, newRotation, buildConfig.interactReach)
212-
213- validHits.add(checked)
214- }
215- }
216- }.joinAll()
217- }
218-
219- if (validHits.isEmpty()) {
220- if (misses.isNotEmpty()) {
221- result(GenericResult .OutOfReach (pos, pov, misses))
222- return true
223- }
224-
225- result(GenericResult .NotVisible (pos, pos, pov.distanceTo(pos.vec3d)))
226- return true
227- }
164+ val validHits = scanShape(pov, shape, pos, Direction .entries.toSet(), preProcessing) ? : return true
228165
229166 val bestHit = buildConfig.pointSelection.select(validHits) ? : return true
230- val blockHit = bestHit.hit.blockResult ? : return true
231167 val target = lookAt(bestHit.targetRotation, 0.001 )
232168 val rotationRequest = RotationRequest (target, this )
233169
234170 val breakContext = BreakContext (
235- blockHit ,
171+ bestHit.hit.blockResult ? : return true ,
236172 rotationRequest,
237173 swapStack.inventoryIndexOrSelected,
238174 stackSelection,
@@ -245,7 +181,7 @@ class BreakChecker @SimCheckerDsl private constructor(simInfo: SimInfo)
245181 return true
246182 }
247183
248- private fun SafeContext .getSwapStack (): ItemStack ? {
184+ private fun AutomatedSafeContext .getSwapStack (): ItemStack ? {
249185 val silentSwapSelection = selectContainer {
250186 ofAnyType(MaterialContainer .Rank .HOTBAR )
251187 }
0 commit comments