package net.minecraft.world.level.block; import java.util.function.BiPredicate; import java.util.function.Function; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.block.DoubleBlockCombiner.NeighborCombineResult.Double; import net.minecraft.world.level.block.DoubleBlockCombiner.NeighborCombineResult.Single; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.Property; public class DoubleBlockCombiner { public static DoubleBlockCombiner.NeighborCombineResult combineWithNeigbour( BlockEntityType blockEntityType, Function function, Function function2, Property property, BlockState blockState, LevelAccessor levelAccessor, BlockPos blockPos, BiPredicate biPredicate ) { S blockEntity = blockEntityType.getBlockEntity(levelAccessor, blockPos); if (blockEntity == null) { return DoubleBlockCombiner.Combiner::acceptNone; } else if (biPredicate.test(levelAccessor, blockPos)) { return DoubleBlockCombiner.Combiner::acceptNone; } else { DoubleBlockCombiner.BlockType blockType = (DoubleBlockCombiner.BlockType)function.apply(blockState); boolean bl = blockType == DoubleBlockCombiner.BlockType.SINGLE; boolean bl2 = blockType == DoubleBlockCombiner.BlockType.FIRST; if (bl) { return new Single(blockEntity); } else { BlockPos blockPos2 = blockPos.relative((Direction)function2.apply(blockState)); BlockState blockState2 = levelAccessor.getBlockState(blockPos2); if (blockState2.is(blockState.getBlock())) { DoubleBlockCombiner.BlockType blockType2 = (DoubleBlockCombiner.BlockType)function.apply(blockState2); if (blockType2 != DoubleBlockCombiner.BlockType.SINGLE && blockType != blockType2 && blockState2.getValue(property) == blockState.getValue(property)) { if (biPredicate.test(levelAccessor, blockPos2)) { return DoubleBlockCombiner.Combiner::acceptNone; } S blockEntity2 = blockEntityType.getBlockEntity(levelAccessor, blockPos2); if (blockEntity2 != null) { S blockEntity3 = bl2 ? blockEntity : blockEntity2; S blockEntity4 = bl2 ? blockEntity2 : blockEntity; return new Double(blockEntity3, blockEntity4); } } } return new Single(blockEntity); } } } public static enum BlockType { SINGLE, FIRST, SECOND; } public interface Combiner { T acceptDouble(S first, S second); T acceptSingle(S single); T acceptNone(); } public interface NeighborCombineResult { T apply(DoubleBlockCombiner.Combiner combiner); } }