@@ -68,11 +68,16 @@ import com.lambda.util.player.copyPlayer
6868import com.lambda.util.player.gamemode
6969import com.lambda.util.world.raycast.RayCastUtils.blockResult
7070import net.minecraft.block.BlockState
71+ import net.minecraft.block.FallingBlock
7172import net.minecraft.block.OperatorBlock
7273import net.minecraft.block.SlabBlock
74+ import net.minecraft.block.Waterloggable
7375import net.minecraft.block.enums.SlabType
7476import net.minecraft.block.pattern.CachedBlockPosition
7577import net.minecraft.enchantment.Enchantments
78+ import net.minecraft.fluid.FlowableFluid
79+ import net.minecraft.fluid.LavaFluid
80+ import net.minecraft.fluid.WaterFluid
7681import net.minecraft.item.BlockItem
7782import net.minecraft.item.Item
7883import net.minecraft.item.ItemPlacementContext
@@ -601,22 +606,76 @@ object BuildSimulator {
601606 return acc
602607 }
603608
604- val adjacentLiquids = Direction .entries.filter {
605- it != Direction . DOWN && ! blockState (pos.offset(it)).fluidState.isEmpty
606- }.map { pos.offset(it) }
609+ if (breaking.avoidLiquids) {
610+ val affectedBlocks = hashSetOf (pos)
611+ val checkQueue = hashSetOf(pos)
607612
608- /* block has liquids next to it that will leak when broken */
609- if (adjacentLiquids.isNotEmpty() && breaking.avoidLiquids) {
610- acc.add(BreakResult .BlockedByLiquid (pos, state))
611- adjacentLiquids.forEach { liquidPos ->
612- val submerge = if (blockState(liquidPos).isReplaceable) {
613- checkPlaceResults(liquidPos, eye, preProcessing, TargetState .Solid , build.placing, interactionConfig, rotation, inventory)
614- } else {
615- checkBreakResults(liquidPos, eye, preProcessing, breaking, interactionConfig, rotation, inventory, build)
613+ while (checkQueue.isNotEmpty()) {
614+ val checkPos = checkQueue.first()
615+ checkQueue.remove(checkPos)
616+ for (offset in Direction .entries) {
617+ val adjacentPos = checkPos.offset(offset)
618+
619+ if (blockState(adjacentPos).block !is FallingBlock ) continue
620+ if (adjacentPos in affectedBlocks) continue
621+
622+ if (offset == Direction .UP || FallingBlock .canFallThrough(blockState(adjacentPos.down()))) {
623+ checkQueue.add(adjacentPos)
624+ affectedBlocks.add(adjacentPos)
625+ }
616626 }
617- acc.addAll(submerge)
618627 }
619- return acc
628+
629+ val affectedFluids = affectedBlocks.fold(hashMapOf<BlockPos , BlockState >()) { accumulator, affectedPos ->
630+ Direction .entries.forEach { offset ->
631+ if (offset == Direction .DOWN ) return @forEach
632+
633+ val offsetPos = affectedPos.offset(offset)
634+ val offsetState = blockState(offsetPos)
635+ val fluidState = offsetState.fluidState
636+ val fluid = fluidState.fluid
637+
638+ if (fluidState.isEmpty || fluid !is FlowableFluid ) return @forEach
639+
640+ if (offset == Direction .UP ) {
641+ accumulator.put(offsetPos, offsetState)
642+ return @fold accumulator
643+ }
644+
645+ if (offsetState.block is Waterloggable && ! fluidState.isEmpty) {
646+ accumulator.put(offsetPos, offsetState)
647+ return @fold accumulator
648+ }
649+
650+ val levelDecreasePerBlock =
651+ when (fluid) {
652+ is WaterFluid -> fluid.getLevelDecreasePerBlock(world)
653+ is LavaFluid -> fluid.getLevelDecreasePerBlock(world)
654+ else -> 0
655+ }
656+
657+ if (fluidState.level - levelDecreasePerBlock > 0 ) {
658+ accumulator.put(offsetPos, offsetState)
659+ return @fold accumulator
660+ }
661+ }
662+
663+ return @fold accumulator
664+ }
665+
666+ /* block has liquids next to it that will leak when broken */
667+ if (affectedFluids.isNotEmpty()) {
668+ acc.add(BreakResult .BlockedByFluid (pos, state))
669+ affectedFluids.entries.forEach { fluid ->
670+ val submerge = if (fluid.value.isReplaceable) {
671+ checkPlaceResults(fluid.key, eye, preProcessing, TargetState .Solid , build.placing, interactionConfig, rotation, inventory)
672+ } else {
673+ checkBreakResults(fluid.key, eye, preProcessing, breaking, interactionConfig, rotation, inventory, build)
674+ }
675+ acc.addAll(submerge)
676+ }
677+ return acc
678+ }
620679 }
621680
622681 val currentRotation = RotationManager .activeRotation
0 commit comments